[rdkb][common][bsp][Refactor and sync kernel from openwrt]

[Description]
6b578db5 [kernel][mt7988][hnat][Add WiFi info dump to the hnat_entry command]
df25b07d [kernel][common][eth][Add SGMII regions to the NETSYS dump]
fe483283 [CRITICAL][kernel][common][eth][Fix SRAM allocation error for RX DMAD]
ef645c91 [openwrt][mt7988][crypto][refactor eip-related kernel patches]
95c4c882 [openwrt][mt7988][tops][remove tops]
41ace754 [mt7988][add bananapi bpi-r4 support]
89bbfcd3 [mt7988][add bananapi bpi-r4 device tree support]

[Release-log]

Change-Id: Ic4472f1fa67de5942ec7c02bf038ecf783241252
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dts
new file mode 100644
index 0000000..f07aa6e
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dts
@@ -0,0 +1,703 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#include "mt7988.dtsi"
+
+/ {
+	model = "Bananapi BPI-R4";
+	compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
+	chosen {
+		bootargs = "console=ttyS0,115200n1 loglevel=8  \
+			    earlycon=uart8250,mmio32,0x11000000 \
+			    earlyprintk pci=pcie_bus_perf \
+			    root=PARTLABEL=rootfs rootwait \
+			    rootfstype=squashfs,f2fs";
+	};
+
+	memory {
+		reg = <0 0x40000000 0 0x10000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			linux,code = <BTN_0>;
+			gpios = <&pio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "wps";
+			linux,code = <KEY_WPS_BUTTON>;
+			gpios = <&pio 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		blue {
+			label = "bpi-r4:pio:blue";
+			gpios = <&pio 63 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		green {
+			label = "bpi-r4:pio:green";
+			gpios = <&pio 79 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
+	nmbm_spim_nand {
+		compatible = "generic,nmbm";
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		lower-mtd-device = <&spi_nand>;
+		forced-create;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "BL2";
+				reg = <0x00000 0x0100000>;
+				read-only;
+			};
+
+			partition@100000 {
+				label = "u-boot-env";
+				reg = <0x0100000 0x0080000>;
+			};
+
+			factory: partition@180000 {
+				label = "Factory";
+				reg = <0x180000 0x0400000>;
+			};
+
+			partition@580000 {
+				label = "FIP";
+				reg = <0x580000 0x0200000>;
+			};
+		};
+	};
+
+	wsys_adie: wsys_adie@0 {
+	// fpga cases need to manual change adie_id / sku_type for dvt only
+		compatible = "mediatek,rebb-mt7988-adie";
+		adie_id = <7976>;
+		sku_type = <3000>;
+	};
+
+	sfp_esp0: sfp@0 {
+		compatible = "sff,sfp";
+		i2c-bus = <&i2c2_sfp0>;
+		mod-def0-gpios = <&pio 82 1>;
+		los-gpios = <&pio 54 0>;
+		tx-disable-gpios = <&pio 70 0>;
+		maximum-power-milliwatt = <3000>;
+	};
+
+	sfp_esp1: sfp@1 {
+		compatible = "sff,sfp";
+		i2c-bus = <&i2c2_sfp1>;
+		mod-def0-gpios = <&pio 83 1>;
+		los-gpios = <&pio 2 0>;
+		tx-disable-gpios = <&pio 0 0>;
+		maximum-power-milliwatt = <3000>;
+	};
+
+	reg_1p8v: regulator-1p8v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-1.8V";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&fan {
+	pwms = <&pwm 0 50000 0>;
+	status = "okay";
+};
+
+&pwm {
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins>;
+	status = "disabled";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+	status = "okay";
+
+	rt5190a_64: rt5190a@64 {
+		compatible = "richtek,rt5190a";
+		reg = <0x64>;
+		/*interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;*/
+		vin2-supply = <&rt5190_buck1>;
+		vin3-supply = <&rt5190_buck1>;
+		vin4-supply = <&rt5190_buck1>;
+
+		regulators {
+			rt5190_buck1: buck1 {
+				regulator-name = "rt5190a-buck1";
+				regulator-min-microvolt = <5090000>;
+				regulator-max-microvolt = <5090000>;
+				regulator-allowed-modes =
+				<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+				regulator-boot-on;
+			};
+			buck2 {
+				regulator-name = "vcore";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-boot-on;
+			};
+			buck3 {
+				regulator-name = "proc";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-boot-on;
+			};
+			buck4 {
+				regulator-name = "rt5190a-buck4";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-allowed-modes =
+				<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+				regulator-boot-on;
+			};
+			ldo {
+				regulator-name = "rt5190a-ldo";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-boot-on;
+			};
+		};
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins>;
+	status = "okay";
+
+	pca9545@70 {
+		compatible = "nxp,pca9545";
+		reg = <0x70>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x0>;
+
+			// MAC Address EEPROM
+			eeprom@57 {
+				compatible = "atmel,24c02";
+				reg = <0x57>;
+
+				address-bits = <8>;
+				page-size = <8>;
+				size = <256>;
+			};
+
+			// RTC AT8563
+			rtc@51 {
+				compatible = "nxp,pcf8563";
+				reg = <0x51>;
+			};
+		};
+
+		i2c2_sfp0: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x1>;
+		};
+
+		i2c2_sfp1: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x2>;
+		};
+
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x3>;
+
+			// 5G WIFI MAC Address EEPROM
+			wifi_eeprom@51 {
+				compatible = "atmel,24c02";
+				reg = <0x51>;
+
+				address-bits = <8>;
+				page-size = <8>;
+				size = <256>;
+			};
+
+			// 6G WIFI MAC Address EEPROM
+			wifi_eeprom@52 {
+				compatible = "atmel,24c02";
+				reg = <0x52>;
+
+				address-bits = <8>;
+				page-size = <8>;
+				size = <256>;
+			};
+		};
+	};
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_flash_pins>;
+	status = "okay";
+
+	spi_nand: spi_nand@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "spi-nand";
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <7>;
+		spi-cal-data = /bits/ 8 <0x53 0x50 0x49 0x4E 0x41 0x4E 0x44>;
+		spi-cal-addrlen = <5>;
+		spi-cal-addr = /bits/ 32 <0x0 0x0 0x0 0x0 0x0>;
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+	};
+};
+
+&spi1 {
+	pinctrl-names = "default";
+	/* pin shared with snfi */
+	pinctrl-0 = <&spic_pins>;
+	status = "disabled";
+};
+
+&pcie0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_pins>;
+	status = "okay";
+};
+
+&pcie1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_pins>;
+	status = "okay";
+};
+
+&pcie2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie2_pins>;
+	status = "okay";
+};
+
+&pcie3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie3_pins>;
+	status = "okay";
+};
+
+&pio {
+	/* GPIO 4 WIFI PWREN. output-high: enable, output-low: disable */
+	asm_sel {
+		gpio-hog;
+		gpios = <4 GPIO_ACTIVE_HIGH>;
+		output-high;
+	};
+
+	/* GPIO 5 PCA9545 RST PIN, output-high */
+	pca9545_rst {
+		gpio-hog;
+		gpios = <5 GPIO_ACTIVE_HIGH>;
+		output-high;
+	};
+
+	mdio0_pins: mdio0-pins {
+		mux {
+			function = "mdio";
+			groups = "mdc_mdio0";
+		};
+
+		conf {
+			groups = "mdc_mdio0";
+			drive-strength = <MTK_DRIVE_10mA>;
+		};
+	};
+
+	gbe0_led0_pins: gbe0-pins {
+		mux {
+			function = "led";
+			groups = "gbe0_led0";
+		};
+	};
+
+	gbe1_led0_pins: gbe1-pins {
+		mux {
+			function = "led";
+			groups = "gbe1_led0";
+		};
+	};
+
+	gbe2_led0_pins: gbe2-pins {
+		mux {
+			function = "led";
+			groups = "gbe2_led0";
+		};
+	};
+
+	gbe3_led0_pins: gbe3-pins {
+		mux {
+			function = "led";
+			groups = "gbe3_led0";
+		};
+	};
+
+	i2p5gbe_led0_pins: 2p5gbe-pins {
+		mux {
+			function = "led";
+			groups = "2p5gbe_led0";
+		};
+	};
+
+	pcie0_pins: pcie0-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
+				 "pcie_wake_n0_0";
+		};
+	};
+
+	pcie1_pins: pcie1-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
+				 "pcie_wake_n1_0";
+		};
+	};
+
+	pcie2_pins: pcie2-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
+				 "pcie_wake_n2_0";
+		};
+	};
+
+	pcie3_pins: pcie3-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
+				 "pcie_wake_n3_0";
+		};
+	};
+
+	spi0_flash_pins: spi0-pins {
+		mux {
+			function = "spi";
+			groups = "spi0", "spi0_wp_hold";
+		};
+	};
+
+	spic_pins: spi1-pins {
+		mux {
+			function = "spi";
+			groups = "spi1";
+		};
+	};
+
+	i2c0_pins: i2c0-pins-g0 {
+		mux {
+			function = "i2c";
+			groups = "i2c0_1";
+		};
+	};
+
+	i2c1_pins: i2c1-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c1_0";
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c2_1";
+		};
+	};
+
+	uart1_pins: uart1-pins {
+		mux {
+			function = "uart";
+			groups = "tops_uart1_2";
+		};
+	};
+
+	uart2_pins: uart2-pins {
+		mux {
+			function = "uart";
+			groups = "uart2";
+		};
+	};
+
+	mmc0_pins_default: mmc0-pins-default {
+		mux {
+			function = "flash";
+			groups = "emmc_51";
+		};
+	};
+
+	mmc0_pins_uhs: mmc0-pins-uhs {
+		mux {
+			function = "flash";
+			groups = "emmc_51";
+		};
+	};
+};
+
+&watchdog {
+	status = "disabled";
+};
+
+&xhci0 {
+	status = "disabled";
+};
+
+&eth {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio0_pins>;
+	status = "okay";
+
+	gmac0: mac@0 {
+		compatible = "mediatek,eth-mac";
+		reg = <0>;
+		mac-type = "xgdm";
+		phy-mode = "10gbase-kr";
+
+		fixed-link {
+			speed = <10000>;
+			full-duplex;
+			pause;
+		};
+	};
+
+	gmac1: mac@1 {
+		compatible = "mediatek,eth-mac";
+		reg = <1>;
+		mac-type = "xgdm";
+
+		/* support internal 2.5G PHY Copper */
+		//phy-mode = "xgmii";
+		//phy-handle = <&phy0>;
+
+		/* Support external 10G SFP+ Module */
+		phy-mode = "10gbase-kr";
+		managed = "in-band-status";
+		sfp = <&sfp_esp1>;
+	};
+
+	gmac2: mac@2 {
+		compatible = "mediatek,eth-mac";
+		reg = <2>;
+		mac-type = "xgdm";
+
+		/* Support external 10G SFP+ Module */
+		phy-mode = "10gbase-kr";
+		managed = "in-band-status";
+		sfp = <&sfp_esp0>;
+	};
+
+	mdio: mdio-bus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-frequency = <10500000>;
+
+		phy0: ethernet-phy@0 {
+			pinctrl-names = "i2p5gbe-led";
+			pinctrl-0 = <&i2p5gbe_led0_pins>;
+			reg = <15>;
+			compatible = "ethernet-phy-ieee802.3-c45";
+			phy-mode = "xgmii";
+		};
+
+		switch@0 {
+			compatible = "mediatek,mt7988";
+			reg = <31>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					label = "lan0";
+					phy-mode = "gmii";
+					phy-handle = <&sphy0>;
+				};
+
+				port@1 {
+					reg = <1>;
+					label = "lan1";
+					phy-mode = "gmii";
+					phy-handle = <&sphy1>;
+				};
+
+				port@2 {
+					reg = <2>;
+					label = "lan2";
+					phy-mode = "gmii";
+					phy-handle = <&sphy2>;
+				};
+
+				port@3 {
+					reg = <3>;
+					label = "lan3";
+					phy-mode = "gmii";
+					phy-handle = <&sphy3>;
+				};
+
+				port@6 {
+					reg = <6>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "10gbase-kr";
+
+					fixed-link {
+						speed = <10000>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+
+			mdio {
+				compatible = "mediatek,dsa-slave-mdio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sphy0: switch_phy0@0 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <0>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe0_led0_pins>;
+					nvmem-cells = <&phy_calibration_p0>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+
+				sphy1: switch_phy1@1 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <1>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe1_led0_pins>;
+					nvmem-cells = <&phy_calibration_p1>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+
+				sphy2: switch_phy2@2 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <2>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe2_led0_pins>;
+					nvmem-cells = <&phy_calibration_p2>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+
+				sphy3: switch_phy3@3 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <3>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe3_led0_pins>;
+					nvmem-cells = <&phy_calibration_p3>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+			};
+		};
+	};
+};
+
+&hnat {
+	mtketh-wan = "eth2";
+	mtketh-lan = "lan";
+	mtketh-lan2 = "eth1";
+	mtketh-max-gmac = <3>;
+	status = "okay";
+};
+
+&crypto {
+	status = "disabled";
+};
+
+&slot0 {
+	mt7996@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		device_type = "pci";
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc0_pins_default>;
+	pinctrl-1 = <&mmc0_pins_uhs>;
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	hs400-ds-delay = <0x12814>;
+	vqmmc-supply = <&reg_1p8v>;
+	vmmc-supply = <&reg_3p3v>;
+	non-removable;
+	no-sd;
+	no-sdio;
+	status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-nand.dts
new file mode 100644
index 0000000..f4511b9
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-nand.dts
@@ -0,0 +1,706 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#include "mt7988.dtsi"
+
+/ {
+	model = "Bananapi BPI-R4";
+	compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
+	chosen {
+		bootargs = "console=ttyS0,115200n1 loglevel=8  \
+			    earlycon=uart8250,mmio32,0x11000000 \
+			    pci=pcie_bus_perf";
+	};
+
+	memory {
+		reg = <0 0x40000000 0 0x10000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			linux,code = <BTN_0>;
+			gpios = <&pio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "wps";
+			linux,code = <KEY_WPS_BUTTON>;
+			gpios = <&pio 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		blue {
+			label = "bpi-r4:pio:blue";
+			gpios = <&pio 63 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		green {
+			label = "bpi-r4:pio:green";
+			gpios = <&pio 79 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
+	nmbm_spim_nand {
+		compatible = "generic,nmbm";
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		lower-mtd-device = <&spi_nand>;
+		forced-create;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "BL2";
+				reg = <0x00000 0x0100000>;
+				read-only;
+			};
+
+			partition@100000 {
+				label = "u-boot-env";
+				reg = <0x0100000 0x0080000>;
+			};
+
+			factory: partition@180000 {
+				label = "Factory";
+				reg = <0x180000 0x0400000>;
+			};
+
+			partition@580000 {
+				label = "FIP";
+				reg = <0x580000 0x0200000>;
+			};
+
+			partition@780000 {
+				label = "ubi";
+				reg = <0x780000 0x7080000>;
+			};
+		};
+	};
+
+	wsys_adie: wsys_adie@0 {
+	// fpga cases need to manual change adie_id / sku_type for dvt only
+		compatible = "mediatek,rebb-mt7988-adie";
+		adie_id = <7976>;
+		sku_type = <3000>;
+	};
+
+	sfp_esp0: sfp@0 {
+		compatible = "sff,sfp";
+		i2c-bus = <&i2c2_sfp0>;
+		mod-def0-gpios = <&pio 82 1>;
+		los-gpios = <&pio 54 0>;
+		tx-disable-gpios = <&pio 70 0>;
+		maximum-power-milliwatt = <3000>;
+	};
+
+	sfp_esp1: sfp@1 {
+		compatible = "sff,sfp";
+		i2c-bus = <&i2c2_sfp1>;
+		mod-def0-gpios = <&pio 83 1>;
+		los-gpios = <&pio 2 0>;
+		tx-disable-gpios = <&pio 0 0>;
+		maximum-power-milliwatt = <3000>;
+	};
+
+	reg_1p8v: regulator-1p8v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-1.8V";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&fan {
+	pwms = <&pwm 0 50000 0>;
+	status = "okay";
+};
+
+&pwm {
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins>;
+	status = "disabled";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+	status = "okay";
+
+	rt5190a_64: rt5190a@64 {
+		compatible = "richtek,rt5190a";
+		reg = <0x64>;
+		/*interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;*/
+		vin2-supply = <&rt5190_buck1>;
+		vin3-supply = <&rt5190_buck1>;
+		vin4-supply = <&rt5190_buck1>;
+
+		regulators {
+			rt5190_buck1: buck1 {
+				regulator-name = "rt5190a-buck1";
+				regulator-min-microvolt = <5090000>;
+				regulator-max-microvolt = <5090000>;
+				regulator-allowed-modes =
+				<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+				regulator-boot-on;
+			};
+			buck2 {
+				regulator-name = "vcore";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-boot-on;
+			};
+			buck3 {
+				regulator-name = "proc";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-boot-on;
+			};
+			buck4 {
+				regulator-name = "rt5190a-buck4";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-allowed-modes =
+				<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+				regulator-boot-on;
+			};
+			ldo {
+				regulator-name = "rt5190a-ldo";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-boot-on;
+			};
+		};
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins>;
+	status = "okay";
+
+	pca9545@70 {
+		compatible = "nxp,pca9545";
+		reg = <0x70>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x0>;
+
+			// MAC Address EEPROM
+			eeprom@57 {
+				compatible = "atmel,24c02";
+				reg = <0x57>;
+
+				address-bits = <8>;
+				page-size = <8>;
+				size = <256>;
+			};
+
+			// RTC AT8563
+			rtc@51 {
+				compatible = "nxp,pcf8563";
+				reg = <0x51>;
+			};
+		};
+
+		i2c2_sfp0: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x1>;
+		};
+
+		i2c2_sfp1: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x2>;
+		};
+
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x3>;
+
+			// 5G WIFI MAC Address EEPROM
+			wifi_eeprom@51 {
+				compatible = "atmel,24c02";
+				reg = <0x51>;
+
+				address-bits = <8>;
+				page-size = <8>;
+				size = <256>;
+			};
+
+			// 6G WIFI MAC Address EEPROM
+			wifi_eeprom@52 {
+				compatible = "atmel,24c02";
+				reg = <0x52>;
+
+				address-bits = <8>;
+				page-size = <8>;
+				size = <256>;
+			};
+		};
+	};
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_flash_pins>;
+	status = "okay";
+
+	spi_nand: spi_nand@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "spi-nand";
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <7>;
+		spi-cal-data = /bits/ 8 <0x53 0x50 0x49 0x4E 0x41 0x4E 0x44>;
+		spi-cal-addrlen = <5>;
+		spi-cal-addr = /bits/ 32 <0x0 0x0 0x0 0x0 0x0>;
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+	};
+};
+
+&spi1 {
+	pinctrl-names = "default";
+	/* pin shared with snfi */
+	pinctrl-0 = <&spic_pins>;
+	status = "disabled";
+};
+
+&pcie0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_pins>;
+	status = "okay";
+};
+
+&pcie1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_pins>;
+	status = "okay";
+};
+
+&pcie2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie2_pins>;
+	status = "okay";
+};
+
+&pcie3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie3_pins>;
+	status = "okay";
+};
+
+&pio {
+	/* GPIO 4 WIFI PWREN. output-high: enable, output-low: disable */
+	asm_sel {
+		gpio-hog;
+		gpios = <4 GPIO_ACTIVE_HIGH>;
+		output-high;
+	};
+
+	/* GPIO 5 PCA9545 RST PIN, output-high */
+	pca9545_rst {
+		gpio-hog;
+		gpios = <5 GPIO_ACTIVE_HIGH>;
+		output-high;
+	};
+
+	mdio0_pins: mdio0-pins {
+		mux {
+			function = "mdio";
+			groups = "mdc_mdio0";
+		};
+
+		conf {
+			groups = "mdc_mdio0";
+			drive-strength = <MTK_DRIVE_10mA>;
+		};
+	};
+
+	gbe0_led0_pins: gbe0-pins {
+		mux {
+			function = "led";
+			groups = "gbe0_led0";
+		};
+	};
+
+	gbe1_led0_pins: gbe1-pins {
+		mux {
+			function = "led";
+			groups = "gbe1_led0";
+		};
+	};
+
+	gbe2_led0_pins: gbe2-pins {
+		mux {
+			function = "led";
+			groups = "gbe2_led0";
+		};
+	};
+
+	gbe3_led0_pins: gbe3-pins {
+		mux {
+			function = "led";
+			groups = "gbe3_led0";
+		};
+	};
+
+	i2p5gbe_led0_pins: 2p5gbe-pins {
+		mux {
+			function = "led";
+			groups = "2p5gbe_led0";
+		};
+	};
+
+	pcie0_pins: pcie0-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
+				 "pcie_wake_n0_0";
+		};
+	};
+
+	pcie1_pins: pcie1-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
+				 "pcie_wake_n1_0";
+		};
+	};
+
+	pcie2_pins: pcie2-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
+				 "pcie_wake_n2_0";
+		};
+	};
+
+	pcie3_pins: pcie3-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
+				 "pcie_wake_n3_0";
+		};
+	};
+
+	spi0_flash_pins: spi0-pins {
+		mux {
+			function = "spi";
+			groups = "spi0", "spi0_wp_hold";
+		};
+	};
+
+	spic_pins: spi1-pins {
+		mux {
+			function = "spi";
+			groups = "spi1";
+		};
+	};
+
+	i2c0_pins: i2c0-pins-g0 {
+		mux {
+			function = "i2c";
+			groups = "i2c0_1";
+		};
+	};
+
+	i2c1_pins: i2c1-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c1_0";
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c2_1";
+		};
+	};
+
+	uart1_pins: uart1-pins {
+		mux {
+			function = "uart";
+			groups = "tops_uart1_2";
+		};
+	};
+
+	uart2_pins: uart2-pins {
+		mux {
+			function = "uart";
+			groups = "uart2";
+		};
+	};
+
+	mmc0_pins_default: mmc0-pins-default {
+		mux {
+			function = "flash";
+			groups = "emmc_51";
+		};
+	};
+
+	mmc0_pins_uhs: mmc0-pins-uhs {
+		mux {
+			function = "flash";
+			groups = "emmc_51";
+		};
+	};
+};
+
+&watchdog {
+	status = "disabled";
+};
+
+&xhci0 {
+	status = "disabled";
+};
+
+&eth {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio0_pins>;
+	status = "okay";
+
+	gmac0: mac@0 {
+		compatible = "mediatek,eth-mac";
+		reg = <0>;
+		mac-type = "xgdm";
+		phy-mode = "10gbase-kr";
+
+		fixed-link {
+			speed = <10000>;
+			full-duplex;
+			pause;
+		};
+	};
+
+	gmac1: mac@1 {
+		compatible = "mediatek,eth-mac";
+		reg = <1>;
+		mac-type = "xgdm";
+
+		/* support internal 2.5G PHY Copper */
+		//phy-mode = "xgmii";
+		//phy-handle = <&phy0>;
+
+		/* Support external 10G SFP+ Module */
+		phy-mode = "10gbase-kr";
+		managed = "in-band-status";
+		sfp = <&sfp_esp1>;
+	};
+
+	gmac2: mac@2 {
+		compatible = "mediatek,eth-mac";
+		reg = <2>;
+		mac-type = "xgdm";
+
+		/* Support external 10G SFP+ Module */
+		phy-mode = "10gbase-kr";
+		managed = "in-band-status";
+		sfp = <&sfp_esp0>;
+	};
+
+	mdio: mdio-bus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-frequency = <10500000>;
+
+		phy0: ethernet-phy@0 {
+			pinctrl-names = "i2p5gbe-led";
+			pinctrl-0 = <&i2p5gbe_led0_pins>;
+			reg = <15>;
+			compatible = "ethernet-phy-ieee802.3-c45";
+			phy-mode = "xgmii";
+		};
+
+		switch@0 {
+			compatible = "mediatek,mt7988";
+			reg = <31>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					label = "lan0";
+					phy-mode = "gmii";
+					phy-handle = <&sphy0>;
+				};
+
+				port@1 {
+					reg = <1>;
+					label = "lan1";
+					phy-mode = "gmii";
+					phy-handle = <&sphy1>;
+				};
+
+				port@2 {
+					reg = <2>;
+					label = "lan2";
+					phy-mode = "gmii";
+					phy-handle = <&sphy2>;
+				};
+
+				port@3 {
+					reg = <3>;
+					label = "lan3";
+					phy-mode = "gmii";
+					phy-handle = <&sphy3>;
+				};
+
+				port@6 {
+					reg = <6>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "10gbase-kr";
+
+					fixed-link {
+						speed = <10000>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+
+			mdio {
+				compatible = "mediatek,dsa-slave-mdio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sphy0: switch_phy0@0 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <0>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe0_led0_pins>;
+					nvmem-cells = <&phy_calibration_p0>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+
+				sphy1: switch_phy1@1 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <1>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe1_led0_pins>;
+					nvmem-cells = <&phy_calibration_p1>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+
+				sphy2: switch_phy2@2 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <2>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe2_led0_pins>;
+					nvmem-cells = <&phy_calibration_p2>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+
+				sphy3: switch_phy3@3 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <3>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe3_led0_pins>;
+					nvmem-cells = <&phy_calibration_p3>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+			};
+		};
+	};
+};
+
+&hnat {
+	mtketh-wan = "eth2";
+	mtketh-lan = "lan";
+	mtketh-lan2 = "eth1";
+	mtketh-max-gmac = <3>;
+	status = "okay";
+};
+
+&crypto {
+	status = "disabled";
+};
+
+&slot0 {
+	mt7996@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		device_type = "pci";
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc0_pins_default>;
+	pinctrl-1 = <&mmc0_pins_uhs>;
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	hs400-ds-delay = <0x12814>;
+	vqmmc-supply = <&reg_1p8v>;
+	vmmc-supply = <&reg_3p3v>;
+	non-removable;
+	no-sd;
+	no-sdio;
+	status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dts
new file mode 100644
index 0000000..ef6e6ec
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dts
@@ -0,0 +1,690 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#include "mt7988.dtsi"
+
+/ {
+	model = "Bananapi BPI-R4";
+	compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
+	chosen {
+		bootargs = "console=ttyS0,115200n1 loglevel=8  \
+			    earlycon=uart8250,mmio32,0x11000000 \
+			    earlyprintk pci=pcie_bus_perf \
+			    root=PARTLABEL=rootfs rootwait \
+			    rootfstype=squashfs,f2fs";
+	};
+
+	memory {
+		reg = <0 0x40000000 0 0x10000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			linux,code = <BTN_0>;
+			gpios = <&pio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "wps";
+			linux,code = <KEY_WPS_BUTTON>;
+			gpios = <&pio 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		blue {
+			label = "bpi-r4:pio:blue";
+			gpios = <&pio 63 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		green {
+			label = "bpi-r4:pio:green";
+			gpios = <&pio 79 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
+	nmbm_spim_nand {
+		compatible = "generic,nmbm";
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		lower-mtd-device = <&spi_nand>;
+		forced-create;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "BL2";
+				reg = <0x00000 0x0100000>;
+				read-only;
+			};
+
+			partition@100000 {
+				label = "u-boot-env";
+				reg = <0x0100000 0x0080000>;
+			};
+
+			factory: partition@180000 {
+				label = "Factory";
+				reg = <0x180000 0x0400000>;
+			};
+
+			partition@580000 {
+				label = "FIP";
+				reg = <0x580000 0x0200000>;
+			};
+		};
+	};
+
+	wsys_adie: wsys_adie@0 {
+	// fpga cases need to manual change adie_id / sku_type for dvt only
+		compatible = "mediatek,rebb-mt7988-adie";
+		adie_id = <7976>;
+		sku_type = <3000>;
+	};
+
+	sfp_esp0: sfp@0 {
+		compatible = "sff,sfp";
+		i2c-bus = <&i2c2_sfp0>;
+		mod-def0-gpios = <&pio 82 1>;
+		los-gpios = <&pio 54 0>;
+		tx-disable-gpios = <&pio 70 0>;
+		maximum-power-milliwatt = <3000>;
+	};
+
+	sfp_esp1: sfp@1 {
+		compatible = "sff,sfp";
+		i2c-bus = <&i2c2_sfp1>;
+		mod-def0-gpios = <&pio 83 1>;
+		los-gpios = <&pio 2 0>;
+		tx-disable-gpios = <&pio 0 0>;
+		maximum-power-milliwatt = <3000>;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&fan {
+	pwms = <&pwm 0 50000 0>;
+	status = "okay";
+};
+
+&pwm {
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins>;
+	status = "disabled";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+	status = "okay";
+
+	rt5190a_64: rt5190a@64 {
+		compatible = "richtek,rt5190a";
+		reg = <0x64>;
+		/*interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;*/
+		vin2-supply = <&rt5190_buck1>;
+		vin3-supply = <&rt5190_buck1>;
+		vin4-supply = <&rt5190_buck1>;
+
+		regulators {
+			rt5190_buck1: buck1 {
+				regulator-name = "rt5190a-buck1";
+				regulator-min-microvolt = <5090000>;
+				regulator-max-microvolt = <5090000>;
+				regulator-allowed-modes =
+				<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+				regulator-boot-on;
+			};
+			buck2 {
+				regulator-name = "vcore";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-boot-on;
+			};
+			buck3 {
+				regulator-name = "proc";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-boot-on;
+			};
+			buck4 {
+				regulator-name = "rt5190a-buck4";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-allowed-modes =
+				<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+				regulator-boot-on;
+			};
+			ldo {
+				regulator-name = "rt5190a-ldo";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-boot-on;
+			};
+		};
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins>;
+	status = "okay";
+
+	pca9545@70 {
+		compatible = "nxp,pca9545";
+		reg = <0x70>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x0>;
+
+			// MAC Address EEPROM
+			eeprom@57 {
+				compatible = "atmel,24c02";
+				reg = <0x57>;
+
+				address-bits = <8>;
+				page-size = <8>;
+				size = <256>;
+			};
+
+			// RTC AT8563
+			rtc@51 {
+				compatible = "nxp,pcf8563";
+				reg = <0x51>;
+			};
+		};
+
+		i2c2_sfp0: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x1>;
+		};
+
+		i2c2_sfp1: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x2>;
+		};
+
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x3>;
+
+			// 5G WIFI MAC Address EEPROM
+			wifi_eeprom@51 {
+				compatible = "atmel,24c02";
+				reg = <0x51>;
+
+				address-bits = <8>;
+				page-size = <8>;
+				size = <256>;
+			};
+
+			// 6G WIFI MAC Address EEPROM
+			wifi_eeprom@52 {
+				compatible = "atmel,24c02";
+				reg = <0x52>;
+
+				address-bits = <8>;
+				page-size = <8>;
+				size = <256>;
+			};
+		};
+	};
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_flash_pins>;
+	status = "okay";
+
+	spi_nand: spi_nand@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "spi-nand";
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <7>;
+		spi-cal-data = /bits/ 8 <0x53 0x50 0x49 0x4E 0x41 0x4E 0x44>;
+		spi-cal-addrlen = <5>;
+		spi-cal-addr = /bits/ 32 <0x0 0x0 0x0 0x0 0x0>;
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+	};
+};
+
+&spi1 {
+	pinctrl-names = "default";
+	/* pin shared with snfi */
+	pinctrl-0 = <&spic_pins>;
+	status = "disabled";
+};
+
+&pcie0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_pins>;
+	status = "okay";
+};
+
+&pcie1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_pins>;
+	status = "okay";
+};
+
+&pcie2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie2_pins>;
+	status = "okay";
+};
+
+&pcie3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie3_pins>;
+	status = "okay";
+};
+
+&pio {
+	/* GPIO 4 WIFI PWREN. output-high: enable, output-low: disable */
+	asm_sel {
+		gpio-hog;
+		gpios = <4 GPIO_ACTIVE_HIGH>;
+		output-high;
+	};
+
+	/* GPIO 5 PCA9545 RST PIN, output-high */
+	pca9545_rst {
+		gpio-hog;
+		gpios = <5 GPIO_ACTIVE_HIGH>;
+		output-high;
+	};
+
+	mdio0_pins: mdio0-pins {
+		mux {
+			function = "mdio";
+			groups = "mdc_mdio0";
+		};
+
+		conf {
+			groups = "mdc_mdio0";
+			drive-strength = <MTK_DRIVE_10mA>;
+		};
+	};
+
+	gbe0_led0_pins: gbe0-pins {
+		mux {
+			function = "led";
+			groups = "gbe0_led0";
+		};
+	};
+
+	gbe1_led0_pins: gbe1-pins {
+		mux {
+			function = "led";
+			groups = "gbe1_led0";
+		};
+	};
+
+	gbe2_led0_pins: gbe2-pins {
+		mux {
+			function = "led";
+			groups = "gbe2_led0";
+		};
+	};
+
+	gbe3_led0_pins: gbe3-pins {
+		mux {
+			function = "led";
+			groups = "gbe3_led0";
+		};
+	};
+
+	i2p5gbe_led0_pins: 2p5gbe-pins {
+		mux {
+			function = "led";
+			groups = "2p5gbe_led0";
+		};
+	};
+
+	pcie0_pins: pcie0-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
+				 "pcie_wake_n0_0";
+		};
+	};
+
+	pcie1_pins: pcie1-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
+				 "pcie_wake_n1_0";
+		};
+	};
+
+	pcie2_pins: pcie2-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
+				 "pcie_wake_n2_0";
+		};
+	};
+
+	pcie3_pins: pcie3-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
+				 "pcie_wake_n3_0";
+		};
+	};
+
+	spi0_flash_pins: spi0-pins {
+		mux {
+			function = "spi";
+			groups = "spi0", "spi0_wp_hold";
+		};
+	};
+
+	spic_pins: spi1-pins {
+		mux {
+			function = "spi";
+			groups = "spi1";
+		};
+	};
+
+	i2c0_pins: i2c0-pins-g0 {
+		mux {
+			function = "i2c";
+			groups = "i2c0_1";
+		};
+	};
+
+	i2c1_pins: i2c1-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c1_0";
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c2_1";
+		};
+	};
+
+	uart1_pins: uart1-pins {
+		mux {
+			function = "uart";
+			groups = "tops_uart1_2";
+		};
+	};
+
+	uart2_pins: uart2-pins {
+		mux {
+			function = "uart";
+			groups = "uart2";
+		};
+	};
+
+	mmc0_pins_default: mmc0-pins-default {
+		mux {
+			function = "flash";
+			groups = "sdcard";
+		};
+	};
+
+	mmc0_pins_uhs: mmc0-pins-uhs {
+		mux {
+			function = "flash";
+			groups = "sdcard";
+		};
+	};
+};
+
+&watchdog {
+	status = "disabled";
+};
+
+&xhci0 {
+	status = "disabled";
+};
+
+&eth {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio0_pins>;
+	status = "okay";
+
+	gmac0: mac@0 {
+		compatible = "mediatek,eth-mac";
+		reg = <0>;
+		mac-type = "xgdm";
+		phy-mode = "10gbase-kr";
+
+		fixed-link {
+			speed = <10000>;
+			full-duplex;
+			pause;
+		};
+	};
+
+	gmac1: mac@1 {
+		compatible = "mediatek,eth-mac";
+		reg = <1>;
+		mac-type = "xgdm";
+
+		/* support internal 2.5G PHY Copper */
+		//phy-mode = "xgmii";
+		//phy-handle = <&phy0>;
+
+		/* Support external 10G SFP+ Module */
+		phy-mode = "10gbase-kr";
+		managed = "in-band-status";
+		sfp = <&sfp_esp1>;
+	};
+
+	gmac2: mac@2 {
+		compatible = "mediatek,eth-mac";
+		reg = <2>;
+		mac-type = "xgdm";
+
+		/* Support external 10G SFP+ Module */
+		phy-mode = "10gbase-kr";
+		managed = "in-band-status";
+		sfp = <&sfp_esp0>;
+	};
+
+	mdio: mdio-bus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-frequency = <10500000>;
+
+		phy0: ethernet-phy@0 {
+			pinctrl-names = "i2p5gbe-led";
+			pinctrl-0 = <&i2p5gbe_led0_pins>;
+			reg = <15>;
+			compatible = "ethernet-phy-ieee802.3-c45";
+			phy-mode = "xgmii";
+		};
+
+		switch@0 {
+			compatible = "mediatek,mt7988";
+			reg = <31>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					label = "lan0";
+					phy-mode = "gmii";
+					phy-handle = <&sphy0>;
+				};
+
+				port@1 {
+					reg = <1>;
+					label = "lan1";
+					phy-mode = "gmii";
+					phy-handle = <&sphy1>;
+				};
+
+				port@2 {
+					reg = <2>;
+					label = "lan2";
+					phy-mode = "gmii";
+					phy-handle = <&sphy2>;
+				};
+
+				port@3 {
+					reg = <3>;
+					label = "lan3";
+					phy-mode = "gmii";
+					phy-handle = <&sphy3>;
+				};
+
+				port@6 {
+					reg = <6>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "10gbase-kr";
+
+					fixed-link {
+						speed = <10000>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+
+			mdio {
+				compatible = "mediatek,dsa-slave-mdio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sphy0: switch_phy0@0 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <0>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe0_led0_pins>;
+					nvmem-cells = <&phy_calibration_p0>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+
+				sphy1: switch_phy1@1 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <1>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe1_led0_pins>;
+					nvmem-cells = <&phy_calibration_p1>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+
+				sphy2: switch_phy2@2 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <2>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe2_led0_pins>;
+					nvmem-cells = <&phy_calibration_p2>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+
+				sphy3: switch_phy3@3 {
+					compatible = "ethernet-phy-id03a2.9481";
+					reg = <3>;
+					pinctrl-names = "gbe-led";
+					pinctrl-0 = <&gbe3_led0_pins>;
+					nvmem-cells = <&phy_calibration_p3>;
+					nvmem-cell-names = "phy-cal-data";
+				};
+			};
+		};
+	};
+};
+
+&hnat {
+	mtketh-wan = "eth2";
+	mtketh-lan = "lan";
+	mtketh-lan2 = "eth1";
+	mtketh-max-gmac = <3>;
+	status = "okay";
+};
+
+&crypto {
+	status = "disabled";
+};
+
+&slot0 {
+	mt7996@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		device_type = "pci";
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc0_pins_default>;
+	pinctrl-1 = <&mmc0_pins_uhs>;
+	bus-width = <4>;
+	max-frequency = <52000000>;
+	cap-sd-highspeed;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_3p3v>;
+	no-mmc;
+	no-sdio;
+	status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
index 8f947a3..5a219e1 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
@@ -194,6 +194,27 @@
 	}
 }
 
+static void mtk_dump_regmap(struct regmap *pmap, char *name,
+			    u32 offset, u32 range)
+{
+	unsigned int cur = offset;
+	unsigned int val1 = 0, val2 = 0, val3 = 0, val4 = 0;
+
+	if (!pmap)
+		return;
+
+	pr_info("\n============ %s ============\n", name);
+	while (cur < offset + range) {
+		regmap_read(pmap, cur, &val1);
+		regmap_read(pmap, cur + 0x4, &val2);
+		regmap_read(pmap, cur + 0x8, &val3);
+		regmap_read(pmap, cur + 0xc, &val4);
+		pr_info("0x%x: %08x %08x %08x %08x\n",
+			cur, val1, val2, val3, val4);
+		cur += 0x10;
+	}
+}
+
 void mtk_dump_netsys_info(void *_eth)
 {
 	struct mtk_eth *eth = _eth;
@@ -211,13 +232,17 @@
 	mtk_dump_reg(eth, "WDMA", WDMA_BASE(0), 0x600);
 	mtk_dump_reg(eth, "PPE", 0x2200, 0x200);
 	mtk_dump_reg(eth, "GMAC", 0x10000, 0x300);
+	mtk_dump_regmap(eth->sgmii->pcs[0].regmap,
+			"SGMII0", 0, 0x1a0);
+	mtk_dump_regmap(eth->sgmii->pcs[1].regmap,
+			"SGMII1", 0, 0x1a0);
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 		mtk_dump_reg(eth, "XGMAC0", 0x12000, 0x300);
 		mtk_dump_reg(eth, "XGMAC1", 0x13000, 0x300);
-		mtk_dump_usxgmii(eth->usxgmii->pcs[0].regmap,
-			"USXGMII0", 0, 0x1000);
-		mtk_dump_usxgmii(eth->usxgmii->pcs[1].regmap,
-			"USXGMII1", 0, 0x1000);
+		mtk_dump_regmap(eth->usxgmii->pcs[0].regmap,
+				"USXGMII0", 0, 0x1000);
+		mtk_dump_regmap(eth->usxgmii->pcs[1].regmap,
+				"USXGMII1", 0, 0x1000);
 	}
 }
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 126f284..9e64a13 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -2978,10 +2978,12 @@
 					       &ring->phys, GFP_KERNEL);
 	else {
 		struct mtk_tx_ring *tx_ring = &eth->tx_ring;
-		ring->dma = tx_ring->dma + soc->txrx.tx_dma_size *
-			    eth->soc->txrx.txd_size * (ring_no + 1);
-		ring->phys = tx_ring->phys + soc->txrx.tx_dma_size *
-			     (dma_addr_t)eth->soc->txrx.txd_size * (ring_no + 1);
+		ring->dma = tx_ring->dma +
+			    soc->txrx.tx_dma_size * (dma_addr_t)eth->soc->txrx.txd_size +
+			    soc->txrx.rx_dma_size * (dma_addr_t)eth->soc->txrx.rxd_size * ring_no;
+		ring->phys = tx_ring->phys +
+			     soc->txrx.tx_dma_size * (dma_addr_t)eth->soc->txrx.txd_size +
+			     soc->txrx.rx_dma_size * (dma_addr_t)eth->soc->txrx.rxd_size * ring_no;
 	}
 
 	if (!ring->dma)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index c299a9b..d2452be 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1999,7 +1999,6 @@
 struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_usxgmii *ss, int id);
 int mtk_usxgmii_init(struct mtk_eth *eth, struct device_node *r);
 int mtk_toprgu_init(struct mtk_eth *eth, struct device_node *r);
-int mtk_dump_usxgmii(struct regmap *pmap, char *name, u32 offset, u32 range);
 void mtk_usxgmii_link_poll(struct work_struct *work);
 
 void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
index f909142..6e1f3dd 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
@@ -608,6 +608,15 @@
 			entry->ipv4_hnapt.tport_id,
 			entry->ipv4_hnapt.tops_entry,
 			entry->ipv4_hnapt.cdrt_id);
+		pr_info("usr_info = %d, tid = %d, hf = %d, amsdu = %d\n",
+			entry->ipv4_hnapt.winfo_pao.usr_info,
+			entry->ipv4_hnapt.winfo_pao.tid,
+			entry->ipv4_hnapt.winfo_pao.hf,
+			entry->ipv4_hnapt.winfo_pao.amsdu);
+		pr_info("is_fixedrate = %d, is_prior = %d, is_sp = %d\n",
+			entry->ipv4_hnapt.winfo_pao.is_fixedrate,
+			entry->ipv4_hnapt.winfo_pao.is_prior,
+			entry->ipv4_hnapt.winfo_pao.is_sp);
 #endif
 		pr_info("=========================================\n\n");
 	} else {
@@ -638,17 +647,43 @@
 				entry->ipv6_hnapt.tport_id,
 				entry->ipv6_hnapt.tops_entry,
 				entry->ipv6_hnapt.cdrt_id);
-
+			pr_info("usr_info = %d, tid = %d, hf = %d, amsdu = %d\n",
+				entry->ipv6_hnapt.winfo_pao.usr_info,
+				entry->ipv6_hnapt.winfo_pao.tid,
+				entry->ipv6_hnapt.winfo_pao.hf,
+				entry->ipv6_hnapt.winfo_pao.amsdu);
+			pr_info("is_fixedrate = %d, is_prior = %d, is_sp = %d\n",
+				entry->ipv6_hnapt.winfo_pao.is_fixedrate,
+				entry->ipv6_hnapt.winfo_pao.is_prior,
+				entry->ipv6_hnapt.winfo_pao.is_sp);
 		} else if (IS_IPV4_MAPE(entry) || IS_IPV4_MAPT(entry)) {
 			pr_info("tport_id = %d, tops_entry = %d, cdrt_id = %d\n",
 				entry->ipv4_mape.tport_id,
 				entry->ipv4_mape.tops_entry,
 				entry->ipv4_mape.cdrt_id);
+			pr_info("usr_info = %d, tid = %d, hf = %d, amsdu = %d\n",
+				entry->ipv4_mape.winfo_pao.usr_info,
+				entry->ipv4_mape.winfo_pao.tid,
+				entry->ipv4_mape.winfo_pao.hf,
+				entry->ipv4_mape.winfo_pao.amsdu);
+			pr_info("is_fixedrate = %d, is_prior = %d, is_sp = %d\n",
+				entry->ipv4_mape.winfo_pao.is_fixedrate,
+				entry->ipv4_mape.winfo_pao.is_prior,
+				entry->ipv4_mape.winfo_pao.is_sp);
 		} else {
 			pr_info("tport_id = %d, tops_entry = %d, cdrt_id = %d\n",
 				entry->ipv6_5t_route.tport_id,
 				entry->ipv6_5t_route.tops_entry,
 				entry->ipv6_5t_route.cdrt_id);
+			pr_info("usr_info = %d, tid = %d, hf = %d, amsdu = %d\n",
+				entry->ipv6_5t_route.winfo_pao.usr_info,
+				entry->ipv6_5t_route.winfo_pao.tid,
+				entry->ipv6_5t_route.winfo_pao.hf,
+				entry->ipv6_5t_route.winfo_pao.amsdu);
+			pr_info("is_fixedrate = %d, is_prior = %d, is_sp = %d\n",
+				entry->ipv6_5t_route.winfo_pao.is_fixedrate,
+				entry->ipv6_5t_route.winfo_pao.is_prior,
+				entry->ipv6_5t_route.winfo_pao.is_sp);
 		}
 #endif
 		pr_info("=========================================\n\n");
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
index 6acd9f8..40eb309 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
@@ -847,23 +847,3 @@
 
 	return &ss->pcs[id].pcs;
 }
-
-int mtk_dump_usxgmii(struct regmap *pmap, char *name, u32 offset, u32 range)
-{
-	unsigned int cur = offset;
-	unsigned int val1 = 0, val2 = 0, val3 = 0, val4 = 0;
-
-	pr_info("\n============ %s ============ pmap:%lx\n",
-		name, (unsigned long)pmap);
-	while (cur < offset + range) {
-		regmap_read(pmap, cur, &val1);
-		regmap_read(pmap, cur + 0x4, &val2);
-		regmap_read(pmap, cur + 0x8, &val3);
-		regmap_read(pmap, cur + 0xc, &val4);
-		pr_info("0x%x: %08x %08x %08x %08x\n", cur,
-			val1, val2, val3, val4);
-		cur += 0x10;
-	}
-	return 0;
-}
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
index 8241edf..c93cce9 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
@@ -244,6 +244,8 @@
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MT65XX=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
 CONFIG_ICPLUS_PHY=y
 CONFIG_IIO=y
 CONFIG_IIO_BUFFER=y
@@ -329,6 +331,7 @@
 # CONFIG_NET_DSA_AN8855 is not set
 CONFIG_NET_DSA_MT7530=y
 # CONFIG_NET_DSA_TAG_ARHT is not set
+# CONFIG_NET_DSA_TAG_AIROHA is not set
 CONFIG_NET_DSA_TAG_MTK=y
 CONFIG_NET_FLOW_LIMIT=y
 CONFIG_NET_MEDIATEK_SOC=y
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4100-mtk-tunnel-offload-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4100-mtk-tunnel-offload-support.patch
deleted file mode 100644
index 6c26c22..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4100-mtk-tunnel-offload-support.patch
+++ /dev/null
@@ -1,488 +0,0 @@
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -245,6 +245,9 @@ static const char * const mtk_clks_sourc
- 	"top_netsys_warp_sel",
- };
- 
-+struct net_device *(*mtk_get_tnl_dev)(int tnl_idx) = NULL;
-+EXPORT_SYMBOL(mtk_get_tnl_dev);
-+
- void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
- {
- 	__raw_writel(val, eth->base + reg);
-@@ -2168,6 +2171,7 @@ static int mtk_poll_rx(struct napi_struc
- 	u64 addr64 = 0;
- 	u8 *data, *new_data;
- 	struct mtk_rx_dma_v2 *rxd, trxd;
-+	int tnl_idx = 0;
- 	int done = 0;
- 
- 	if (unlikely(!ring))
-@@ -2205,11 +2209,20 @@ static int mtk_poll_rx(struct napi_struc
- 				      0 : RX_DMA_GET_SPORT(trxd.rxd4) - 1;
- 		}
- 
--		if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
--			     !eth->netdev[mac]))
--			goto release_desc;
-+		tnl_idx = RX_DMA_GET_TOPS_CRSN(trxd.rxd6);
-+		if (mtk_get_tnl_dev && tnl_idx) {
-+			netdev = mtk_get_tnl_dev(tnl_idx);
-+			if (unlikely(IS_ERR(netdev)))
-+				netdev = NULL;
-+		}
- 
--		netdev = eth->netdev[mac];
-+		if (!netdev) {
-+			if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
-+				     !eth->netdev[mac]))
-+				goto release_desc;
-+
-+			netdev = eth->netdev[mac];
-+		}
- 
- 		if (unlikely(test_bit(MTK_RESETTING, &eth->state)))
- 			goto release_desc;
-@@ -2294,6 +2307,8 @@ static int mtk_poll_rx(struct napi_struc
- 		skb_hnat_alg(skb) = 0;
- 		skb_hnat_filled(skb) = 0;
- 		skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
-+		skb_hnat_set_tops(skb, 0);
-+		skb_hnat_set_is_decap(skb, 0);
- 
- 		if (skb_hnat_reason(skb) == HIT_BIND_FORCE_TO_CPU) {
- 			trace_printk("[%s] reason=0x%x(force to CPU) from WAN to Ext\n",
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1915,6 +1915,9 @@ extern const struct of_device_id of_mtk_
- extern u32 mtk_hwlro_stats_ebl;
- extern u32 dbg_show_level;
- 
-+/* tunnel offload related */
-+extern struct net_device *(*mtk_get_tnl_dev)(int tnl_idx);
-+
- /* read the hardware status register */
- void mtk_stats_update_mac(struct mtk_mac *mac);
- 
---- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
-@@ -43,6 +43,12 @@ void (*ppe_dev_register_hook)(struct net
- EXPORT_SYMBOL(ppe_dev_register_hook);
- void (*ppe_dev_unregister_hook)(struct net_device *dev) = NULL;
- EXPORT_SYMBOL(ppe_dev_unregister_hook);
-+int (*mtk_tnl_encap_offload)(struct sk_buff *skb) = NULL;
-+EXPORT_SYMBOL(mtk_tnl_encap_offload);
-+int (*mtk_tnl_decap_offload)(struct sk_buff *skb) = NULL;
-+EXPORT_SYMBOL(mtk_tnl_decap_offload);
-+bool (*mtk_tnl_decap_offloadable)(struct sk_buff *skb) = NULL;
-+EXPORT_SYMBOL(mtk_tnl_decap_offloadable);
- 
- static void hnat_sma_build_entry(struct timer_list *t)
- {
-@@ -53,6 +59,16 @@ static void hnat_sma_build_entry(struct
- 			     SMA, SMA_FWD_CPU_BUILD_ENTRY);
- }
- 
-+struct foe_entry *hnat_get_foe_entry(u32 ppe_id, u32 index)
-+{
-+	if (index == 0x7fff || index >= hnat_priv->foe_etry_num
-+	    || ppe_id >= CFG_PPE_NUM)
-+		return ERR_PTR(-EINVAL);
-+
-+	return &hnat_priv->foe_table_cpu[ppe_id][index];
-+}
-+EXPORT_SYMBOL(hnat_get_foe_entry);
-+
- void hnat_cache_ebl(int enable)
- {
- 	int i;
-@@ -63,6 +79,7 @@ void hnat_cache_ebl(int enable)
- 		cr_set_field(hnat_priv->ppe_base[i] + PPE_CAH_CTRL, CAH_EN, enable);
- 	}
- }
-+EXPORT_SYMBOL(hnat_cache_ebl);
- 
- static void hnat_reset_timestamp(struct timer_list *t)
- {
---- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
-@@ -1140,6 +1140,8 @@ enum FoeIpAct {
- #define NR_WDMA1_PORT 9
- #define NR_WDMA2_PORT 13
- #define NR_GMAC3_PORT 15
-+#define NR_TDMA_TPORT 4
-+#define NR_TDMA_QDMA_TPORT 5
- #define LAN_DEV_NAME hnat_priv->lan
- #define LAN2_DEV_NAME hnat_priv->lan2
- #define IS_WAN(dev)                                                            \
-@@ -1269,6 +1271,8 @@ static inline bool hnat_dsa_is_enable(st
- }
- #endif
- 
-+struct foe_entry *hnat_get_foe_entry(u32 ppe_id, u32 index);
-+
- void hnat_deinit_debugfs(struct mtk_hnat *h);
- int hnat_init_debugfs(struct mtk_hnat *h);
- int hnat_register_nf_hooks(void);
-@@ -1285,6 +1289,9 @@ extern int qos_ul_toggle;
- extern int hook_toggle;
- extern int mape_toggle;
- extern int qos_toggle;
-+extern int (*mtk_tnl_encap_offload)(struct sk_buff *skb);
-+extern int (*mtk_tnl_decap_offload)(struct sk_buff *skb);
-+extern bool (*mtk_tnl_decap_offloadable)(struct sk_buff *skb);
- 
- int ext_if_add(struct extdev_entry *ext_entry);
- int ext_if_del(struct extdev_entry *ext_entry);
---- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
-@@ -728,10 +728,14 @@ static unsigned int is_ppe_support_type(
- 	case ETH_P_IP:
- 		iph = ip_hdr(skb);
- 
--		/* do not accelerate non tcp/udp traffic */
--		if ((iph->protocol == IPPROTO_TCP) ||
-+		if (mtk_tnl_decap_offloadable && mtk_tnl_decap_offloadable(skb)) {
-+			/* tunnel protocol is offloadable */
-+			skb_hnat_set_is_decap(skb, 1);
-+			return 1;
-+		} else if ((iph->protocol == IPPROTO_TCP) ||
- 		    (iph->protocol == IPPROTO_UDP) ||
- 		    (iph->protocol == IPPROTO_IPV6)) {
-+			/* do not accelerate non tcp/udp traffic */
- 			return 1;
- 		}
- 
-@@ -848,6 +852,13 @@ mtk_hnat_ipv4_nf_pre_routing(void *priv,
- 
- 	hnat_set_head_frags(state, skb, -1, hnat_set_iif);
- 
-+	if (skb_hnat_tops(skb) && skb_hnat_is_decap(skb)
-+	    && is_magic_tag_valid(skb)
-+	    && skb_hnat_iface(skb) == FOE_MAGIC_GE_VIRTUAL
-+	    && mtk_tnl_decap_offload && mtk_tnl_decap_offload(skb)) {
-+		return NF_ACCEPT;
-+	}
-+
- 	/*
- 	 * Avoid mistakenly binding of outer IP, ports in SW L2TP decap flow.
- 	 * In pre-routing, if dev is virtual iface, TOPS module is not loaded,
-@@ -923,6 +934,13 @@ mtk_hnat_br_nf_local_in(void *priv, stru
- 
- 	hnat_set_head_frags(state, skb, -1, hnat_set_iif);
- 
-+	if (skb_hnat_tops(skb) && skb_hnat_is_decap(skb)
-+	    && is_magic_tag_valid(skb)
-+	    && skb_hnat_iface(skb) == FOE_MAGIC_GE_VIRTUAL
-+	    && mtk_tnl_decap_offload && mtk_tnl_decap_offload(skb)) {
-+		return NF_ACCEPT;
-+	}
-+
- 	pre_routing_print(skb, state->in, state->out, __func__);
- 
- 	if (unlikely(debug_level >= 7)) {
-@@ -1075,8 +1093,22 @@ static unsigned int hnat_ipv4_get_nextho
- 		return -1;
- 	}
- 
-+	/*
-+	 * if this packet is a tunnel packet and is about to construct
-+	 * outer header, we must update its outer mac header pointer
-+	 * before filling outer mac or it may screw up inner mac
-+	 */
-+	if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) {
-+		skb_push(skb, sizeof(struct ethhdr));
-+		skb_reset_mac_header(skb);
-+	}
-+
- 	memcpy(eth_hdr(skb)->h_dest, neigh->ha, ETH_ALEN);
- 	memcpy(eth_hdr(skb)->h_source, out->dev_addr, ETH_ALEN);
-+	eth_hdr(skb)->h_proto = htons(ETH_P_IP);
-+
-+	if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb))
-+		skb_pull(skb, sizeof(struct ethhdr));
- 
- 	rcu_read_unlock_bh();
- 
-@@ -1203,6 +1235,81 @@ static struct ethhdr *get_ipv6_ipip_ethh
- 	return eth;
- }
- 
-+static inline void hnat_get_filled_unbind_entry(struct sk_buff *skb,
-+						struct foe_entry *entry)
-+{
-+	if (unlikely(!skb || !entry))
-+		return;
-+
-+	memcpy(entry,
-+	       &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)],
-+	       sizeof(*entry));
-+
-+#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
-+	entry->bfib1.mc = 0;
-+#endif /* defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3) */
-+	entry->bfib1.ka = 0;
-+	entry->bfib1.vlan_layer = 0;
-+	entry->bfib1.psn = 0;
-+	entry->bfib1.vpm = 0;
-+	entry->bfib1.ps = 0;
-+}
-+
-+static inline void hnat_qos_tnl(u32 id, const struct net_device *dev)
-+{
-+	u32 cfg;
-+	u32 max_man = 0;
-+	u32 max_exp = 0;
-+	const struct mtk_mac *mac;
-+
-+	if (!dev)
-+		return;
-+	mac = netdev_priv(dev);
-+
-+	switch (mac->speed) {
-+	case SPEED_100:
-+	case SPEED_1000:
-+	case SPEED_2500:
-+	case SPEED_5000:
-+	case SPEED_10000:
-+		max_man = mac->speed / SPEED_100;
-+		max_exp = 5;
-+		break;
-+	default:
-+		return;
-+	}
-+
-+	cfg = QTX_SCH_MIN_RATE_EN | QTX_SCH_MAX_RATE_EN;
-+	cfg |= (1 << QTX_SCH_MIN_RATE_MAN_OFFSET) |
-+	       (4 << QTX_SCH_MIN_RATE_EXP_OFFSET) |
-+	       (max_man << QTX_SCH_MAX_RATE_MAN_OFFSET) |
-+	       (max_exp << QTX_SCH_MAX_RATE_EXP_OFFSET) |
-+	       (4 << QTX_SCH_MAX_RATE_WGHT_OFFSET);
-+	writel(cfg, hnat_priv->fe_base + QTX_SCH(id % NUM_OF_Q_PER_PAGE));
-+}
-+
-+static inline void hnat_fill_offload_engine_entry(struct sk_buff *skb,
-+						  struct foe_entry *entry,
-+						  const struct net_device *dev)
-+{
-+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-+	if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) {
-+		/*
-+		 * if skb_hnat_tops(skb) is setup for encapsulation,
-+		 * we fill in hnat tport and tops_entry for tunnel encapsulation
-+		 * offloading
-+		 */
-+		entry->ipv4_hnapt.tport_id = NR_TDMA_QDMA_TPORT;
-+		entry->ipv4_hnapt.tops_entry = skb_hnat_tops(skb);
-+	} else {
-+		return;
-+	}
-+
-+	entry->ipv4_hnapt.iblk2.qid = 12; /* offload engine use QID 12 */
-+	hnat_qos_tnl(12, dev); /* set rate limit to line rate */
-+#endif /* defined(CONFIG_MEDIATEK_NETSYS_V3) */
-+}
-+
- static unsigned int skb_to_hnat_info(struct sk_buff *skb,
- 				     const struct net_device *dev,
- 				     struct foe_entry *foe,
-@@ -1240,6 +1347,11 @@ static unsigned int skb_to_hnat_info(str
- 	if (whnat && is_hnat_pre_filled(foe))
- 		return 0;
- 
-+	if (skb_hnat_tops(skb) && !(hw_path->flags & FLOW_OFFLOAD_PATH_TNL)) {
-+		hnat_get_filled_unbind_entry(skb, &entry);
-+		goto hnat_entry_bind;
-+	}
-+
- 	entry.bfib1.pkt_type = foe->udib1.pkt_type; /* Get packte type state*/
- 	entry.bfib1.state = foe->udib1.state;
- 
-@@ -1683,6 +1795,10 @@ static unsigned int skb_to_hnat_info(str
- 	/* Fill Layer2 Info.*/
- 	entry = ppe_fill_L2_info(eth, entry, hw_path);
- 
-+	if (skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL)
-+		goto hnat_entry_skip_bind;
-+
-+hnat_entry_bind:
- 	/* Fill Info Blk*/
- 	entry = ppe_fill_info_blk(eth, entry, hw_path);
- 
-@@ -1881,7 +1997,20 @@ static unsigned int skb_to_hnat_info(str
- 			entry.ipv6_5t_route.act_dp |= UDF_HNAT_PRE_FILLED;
- 	}
- 
-+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-+	hnat_fill_offload_engine_entry(skb, &entry, dev);
-+#endif
-+
-+hnat_entry_skip_bind:
- 	wmb();
-+
-+	/*
-+	 * final check before we write BIND info.
-+	 * If this entry is already bound, we should not modify it right now
-+	 */
-+	if (entry_hnat_is_bound(foe))
-+		return 0;
-+
- 	memcpy(foe, &entry, sizeof(entry));
- 	/*reset statistic for this entry*/
- 	if (hnat_priv->data->per_flow_accounting &&
-@@ -1953,6 +2082,12 @@ int mtk_sw_nat_hook_tx(struct sk_buff *s
- 	switch ((int)entry.bfib1.pkt_type) {
- 	case IPV4_HNAPT:
- 	case IPV4_HNAT:
-+		/*
-+		 * skip if packet is an encap tnl packet or it may
-+		 * screw up inner mac header
-+		 */
-+		if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb))
-+			break;
- 		entry.ipv4_hnapt.smac_hi = swab32(*((u32 *)eth->h_source));
- 		entry.ipv4_hnapt.smac_lo = swab16(*((u16 *)&eth->h_source[4]));
- 		break;
-@@ -2144,6 +2279,10 @@ int mtk_sw_nat_hook_tx(struct sk_buff *s
- 		entry.ipv6_5t_route.iblk2.dp = gmac_no;
- 	}
- 
-+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-+	hnat_fill_offload_engine_entry(skb, &entry, NULL);
-+#endif
-+
- 	entry.bfib1.ttl = 1;
- 	entry.bfib1.state = BIND;
- 	if (IS_IPV4_GRP(&entry))
-@@ -2219,6 +2358,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s
- 	}
- 
- 	skb_hnat_alg(skb) = 0;
-+	skb_hnat_set_tops(skb, 0);
- 	skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
- 
- 	if (skb_hnat_iface(skb) == FOE_MAGIC_WED0)
-@@ -2672,6 +2812,7 @@ static unsigned int mtk_hnat_nf_post_rou
- 	struct flow_offload_hw_path hw_path = { .dev = (struct net_device*)out,
- 						.virt_dev = (struct net_device*)out };
- 	const struct net_device *arp_dev = out;
-+	bool is_virt_dev = false;
- 
- 	if (xlat_toggle && !mtk_464xlat_post_process(skb, out))
- 		return 0;
-@@ -2691,10 +2832,29 @@ static unsigned int mtk_hnat_nf_post_rou
- 
- 	if (out->netdev_ops->ndo_flow_offload_check) {
- 		out->netdev_ops->ndo_flow_offload_check(&hw_path);
-+
- 		out = (IS_GMAC1_MODE) ? hw_path.virt_dev : hw_path.dev;
-+		if (hw_path.flags & FLOW_OFFLOAD_PATH_TNL && mtk_tnl_encap_offload) {
-+			if (ntohs(skb->protocol) == ETH_P_IP
-+			    && ip_hdr(skb)->protocol == IPPROTO_TCP) {
-+				skb_hnat_set_tops(skb, hw_path.tnl_type + 1);
-+			} else {
-+				/*
-+				 * we are not support protocols other than IPv4 TCP
-+				 * for tunnel protocol offload yet
-+				 */
-+				skb_hnat_alg(skb) = 1;
-+				return 0;
-+			}
-+		}
- 	}
- 
- 	if (!IS_LAN_GRP(out) && !IS_WAN(out) && !IS_EXT(out))
-+		is_virt_dev = true;
-+
-+	if (is_virt_dev
-+	    && !(skb_hnat_tops(skb) && skb_hnat_is_encap(skb)
-+		 && (hw_path.flags & FLOW_OFFLOAD_PATH_TNL)))
- 		return 0;
- 
- 	trace_printk("[%s] case hit, %x-->%s, reason=%x\n", __func__,
-@@ -2714,9 +2874,18 @@ static unsigned int mtk_hnat_nf_post_rou
- 		if (fn && !mtk_hnat_accel_type(skb))
- 			break;
- 
--		if (fn && fn(skb, arp_dev, &hw_path))
-+		if (!is_virt_dev && fn && fn(skb, arp_dev, &hw_path))
- 			break;
- 
-+		/* skb_hnat_tops(skb) is updated in mtk_tnl_offload() */
-+		if (skb_hnat_tops(skb)) {
-+			if (skb_hnat_is_encap(skb) && !is_virt_dev
-+			    && mtk_tnl_encap_offload && mtk_tnl_encap_offload(skb))
-+				break;
-+			if (skb_hnat_is_decap(skb))
-+				break;
-+		}
-+
- 		spin_lock(&hnat_priv->entry_lock);
- 		skb_to_hnat_info(skb, out, entry, &hw_path);
- 		spin_unlock(&hnat_priv->entry_lock);
-@@ -2989,7 +3158,7 @@ mtk_hnat_ipv4_nf_local_out(void *priv, s
- 	if (iph->protocol == IPPROTO_IPV6) {
- 		entry->udib1.pkt_type = IPV6_6RD;
- 		hnat_set_head_frags(state, skb, 0, hnat_set_alg);
--	} else {
-+	} else if (!skb_hnat_tops(skb)) {
- 		hnat_set_head_frags(state, skb, 1, hnat_set_alg);
- 	}
- 
---- a/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
-@@ -44,7 +44,9 @@ struct hnat_desc {
- 	u32 is_sp : 1;
- 	u32 hf : 1;
- 	u32 amsdu : 1;
--	u32 resv3 : 19;
-+	u32 tops : 6;
-+	u32 is_decap : 1;
-+	u32 resv3 : 12;
- 	u32 magic_tag_protect : 16;
- } __packed;
- #elif defined(CONFIG_MEDIATEK_NETSYS_RX_V2)
-@@ -91,6 +93,19 @@ struct hnat_desc {
- 	((((skb_headroom(skb) >= FOE_INFO_LEN) ? 1 : 0)))
- 
- #define skb_hnat_info(skb) ((struct hnat_desc *)(skb->head))
-+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-+#define skb_hnat_tops(skb) (((struct hnat_desc *)((skb)->head))->tops)
-+#define skb_hnat_is_decap(skb) (((struct hnat_desc *)((skb)->head))->is_decap)
-+#define skb_hnat_is_encap(skb) (!skb_hnat_is_decap(skb))
-+#define skb_hnat_set_tops(skb, tops) ((skb_hnat_tops(skb)) = (tops))
-+#define skb_hnat_set_is_decap(skb, is_decap) ((skb_hnat_is_decap(skb)) = (is_decap))
-+#else /* !defined(CONFIG_MEDIATEK_NETSYS_V3) */
-+#define skb_hnat_tops(skb) (0)
-+#define skb_hnat_is_decap(skb) (0)
-+#define skb_hnat_is_encap(skb) (0)
-+#define skb_hnat_set_tops(skb, tops)
-+#define skb_hnat_set_is_decap(skb, is_decap)
-+#endif /* defined(CONFIG_MEDIATEK_NETSYS_V3) */
- #define skb_hnat_magic(skb) (((struct hnat_desc *)(skb->head))->magic)
- #define skb_hnat_reason(skb) (((struct hnat_desc *)(skb->head))->crsn)
- #define skb_hnat_entry(skb) (((struct hnat_desc *)(skb->head))->entry)
---- a/include/net/netfilter/nf_flow_table.h
-+++ b/include/net/netfilter/nf_flow_table.h
-@@ -98,10 +98,21 @@ struct flow_offload {
- #define FLOW_OFFLOAD_PATH_6RD		BIT(5)
- #define FLOW_OFFLOAD_PATH_TNL		BIT(6)
- 
-+enum flow_offload_tnl {
-+	FLOW_OFFLOAD_TNL_GRETAP,
-+	FLOW_OFFLOAD_TNL_PPTP,
-+	FLOW_OFFLOAD_TNL_L2TP_V2,
-+	FLOW_OFFLOAD_TNL_L2TP_V3,
-+	FLOW_OFFLOAD_VXLAN,
-+	FLOW_OFFLOAD_NATT,
-+	__FLOW_OFFLOAD_MAX,
-+};
-+
- struct flow_offload_hw_path {
- 	struct net_device *dev;
- 	struct net_device *virt_dev;
- 	u32 flags;
-+	u32 tnl_type;
- 
- 	u8 eth_src[ETH_ALEN];
- 	u8 eth_dest[ETH_ALEN];
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4101-mtk-tunnel-network-service-error-recover-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4101-mtk-tunnel-network-service-error-recover-support.patch
deleted file mode 100644
index a2579c0..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4101-mtk-tunnel-network-service-error-recover-support.patch
+++ /dev/null
@@ -1,49 +0,0 @@
---- a/drivers/net/ethernet/mediatek/mtk_eth_reset.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_reset.c
-@@ -635,6 +635,9 @@ static int mtk_eth_netdevice_event(struc
- 				   unsigned long event, void *ptr)
- {
- 	switch (event) {
-+	case MTK_TOPS_DUMP_DONE:
-+		complete(&wait_tops_done);
-+		break;
- 	case MTK_WIFI_RESET_DONE:
- 	case MTK_FE_STOP_TRAFFIC_DONE:
- 		pr_info("%s rcv done event:%lx\n", __func__, event);
---- a/drivers/net/ethernet/mediatek/mtk_eth_reset.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_reset.h
-@@ -13,6 +13,7 @@
- #define MTK_WIFI_RESET_DONE	0x2002
- #define MTK_WIFI_CHIP_ONLINE 	0x2003
- #define MTK_WIFI_CHIP_OFFLINE 	0x2004
-+#define MTK_TOPS_DUMP_DONE	0x3001
- #define MTK_FE_RESET_NAT_DONE	0x4001
- 
- #define MTK_FE_STOP_TRAFFIC	(0x2005)
-@@ -67,6 +68,7 @@ enum mtk_reset_event_id {
- 
- extern struct notifier_block mtk_eth_netdevice_nb __read_mostly;
- extern struct completion wait_ser_done;
-+extern struct completion wait_tops_done;
- extern char* mtk_reset_event_name[32];
- extern atomic_t reset_lock;
- extern struct completion wait_nat_done;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -38,6 +38,7 @@ atomic_t force = ATOMIC_INIT(0);
- module_param_named(msg_level, mtk_msg_level, int, 0);
- MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
- DECLARE_COMPLETION(wait_ser_done);
-+DECLARE_COMPLETION(wait_tops_done);
- 
- #define MTK_ETHTOOL_STAT(x) { #x, \
- 			      offsetof(struct mtk_hw_stats, x) / sizeof(u64) }
-@@ -4178,6 +4179,8 @@ static void mtk_pending_work(struct work
- 				}
- 			pr_warn("wait for MTK_FE_START_RESET\n");
- 		}
-+		if (!try_wait_for_completion(&wait_tops_done))
-+			pr_warn("wait for MTK_TOPS_DUMP_DONE\n");
- 		rtnl_lock();
- 		break;
- 	}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4102-mtk-crypto-offload-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4102-mtk-crypto-offload-support.patch
index 0ca0e3a..67ed9da 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4102-mtk-crypto-offload-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4102-mtk-crypto-offload-support.patch
@@ -1,46 +1,53 @@
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1992,6 +1992,17 @@ static void mtk_tx_set_dma_desc_v3(struc
+@@ -1996,6 +1996,7 @@ static void mtk_tx_set_dma_desc_v3(struc
+ 	u32 data = 0;
+ 	u8 tops_entry  = 0;
+ 	u8 tport = 0;
++	u8 cdrt = 0;
+ 
+ 	addr64 = (MTK_HAS_CAPS(eth->soc->caps, MTK_8GB_ADDRESSING)) ?
+ 		  TX_DMA_SDP1(info->addr) : 0;
+@@ -2019,11 +2020,25 @@ static void mtk_tx_set_dma_desc_v3(struc
  	trace_printk("[%s] skb_shinfo(skb)->nr_frags=%x HNAT_SKB_CB2(skb)->magic=%x txd4=%x<-----\n",
  		     __func__, skb_shinfo(skb)->nr_frags, HNAT_SKB_CB2(skb)->magic, data);
  #endif
-+
-+	/* forward to eip197 if this packet is going to encrypt */
-+#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE)
-+	if (unlikely(skb->inner_protocol == IPPROTO_ESP && skb_hnat_cdrt(skb) && is_magic_tag_valid(skb)))
-+#else
-+	if (unlikely(skb->inner_protocol == IPPROTO_ESP && skb_tnl_cdrt(skb) && is_tnl_tag_valid(skb)))
-+#endif // hnat
-+	{
-+		data &= ((~TX_DMA_TPORT_MASK) << TX_DMA_TPORT_SHIFT);
-+		data |= (EIP197_QDMA_TPORT & TX_DMA_TPORT_MASK) << TX_DMA_TPORT_SHIFT;
-+	}
- 	WRITE_ONCE(desc->txd4, data);
- 
- 	data = 0;
-@@ -2014,6 +2025,21 @@ static void mtk_tx_set_dma_desc_v3(struc
+-	if (mtk_get_tnl_netsys_params && skb) {
++	if (mtk_get_tnl_netsys_params && skb && !(skb->inner_protocol == IPPROTO_ESP)) {
+ 		u32 params = mtk_get_tnl_netsys_params(skb);
  
- 	WRITE_ONCE(desc->txd7, 0);
- 	WRITE_ONCE(desc->txd8, 0);
-+
+ 		tops_entry = params & 0x000000FF;
+ 		tport = (params & 0x0000FF00) >> 8;
++		cdrt = (params & 0x00FF0000) >> 16;
++	}
++	/* forward to eip197 if this packet is going to encrypt */
 +#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE)
-+	if (unlikely(skb->inner_protocol == IPPROTO_ESP && skb_hnat_cdrt(skb) && is_magic_tag_valid(skb))) {
++	else if (unlikely(skb->inner_protocol == IPPROTO_ESP && skb_hnat_cdrt(skb) && is_magic_tag_valid(skb))) {
 +		/* carry cdrt index for encryption */
-+		data = (skb_hnat_cdrt(skb) & TX_DMA_CDRT_MASK) << TX_DMA_CDRT_SHIFT;
-+		WRITE_ONCE(desc->txd8, data);
++		cdrt = skb_hnat_cdrt(skb);
 +		skb_hnat_magic_tag(skb) = 0;
-+	}
 +#else
-+	if (unlikely(skb->inner_protocol == IPPROTO_ESP && skb_tnl_cdrt(skb) && is_tnl_tag_valid(skb))) {
-+		data = (skb_tnl_cdrt(skb) & TX_DMA_CDRT_MASK) << TX_DMA_CDRT_SHIFT;
-+		WRITE_ONCE(desc->txd8, data);
++	else if (unlikely(skb->inner_protocol == IPPROTO_ESP && skb_tnl_cdrt(skb) && is_tnl_tag_valid(skb))) {
++		cdrt = skb_tnl_cdrt(skb);
 +		skb_tnl_magic_tag(skb) = 0;
++#endif
++		tport = EIP197_QDMA_TPORT;
+ 	}
+ 
+ 	if (tport) {
+@@ -2060,6 +2075,11 @@ static void mtk_tx_set_dma_desc_v3(struc
+ 		data |= (tops_entry & TX_DMA_TOPS_ENTRY_MASK) << TX_DMA_TOPS_ENTRY_SHIFT;
+ 	}
+ 
++	if (cdrt) {
++		data &= ~(TX_DMA_CDRT_MASK << TX_DMA_CDRT_SHIFT);
++		data |= (cdrt & TX_DMA_CDRT_MASK) << TX_DMA_CDRT_SHIFT;
 +	}
-+#endif // hnat
++
+ 	WRITE_ONCE(desc->txd8, data);
  }
  
- static void mtk_tx_set_pdma_desc(struct sk_buff *skb, struct net_device *dev, void *txd,
-@@ -2491,6 +2517,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2538,6 +2558,7 @@ static int mtk_poll_rx(struct napi_struc
  
  		skb_hnat_alg(skb) = 0;
  		skb_hnat_filled(skb) = 0;
@@ -50,7 +57,7 @@
  		skb_hnat_set_is_decap(skb, 0);
 --- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
 +++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
-@@ -1078,6 +1078,9 @@ static unsigned int hnat_ipv4_get_nextho
+@@ -1079,6 +1079,9 @@ static unsigned int hnat_ipv4_get_nextho
  		return 0;
  	}
  
@@ -60,7 +67,7 @@
  	rcu_read_lock_bh();
  	nexthop = (__force u32)rt_nexthop(rt, ip_hdr(skb)->daddr);
  	neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
-@@ -1302,6 +1305,9 @@ static inline void hnat_fill_offload_eng
+@@ -1303,6 +1306,9 @@ static inline void hnat_fill_offload_eng
  		 */
  		entry->ipv4_hnapt.tport_id = NR_TDMA_QDMA_TPORT;
  		entry->ipv4_hnapt.tops_entry = skb_hnat_tops(skb);
@@ -70,7 +77,7 @@
  	} else {
  		return;
  	}
-@@ -1311,6 +1317,79 @@ static inline void hnat_fill_offload_eng
+@@ -1312,6 +1318,79 @@ static inline void hnat_fill_offload_eng
  #endif /* defined(CONFIG_MEDIATEK_NETSYS_V3) */
  }
  
@@ -150,7 +157,7 @@
  static unsigned int skb_to_hnat_info(struct sk_buff *skb,
  				     const struct net_device *dev,
  				     struct foe_entry *foe,
-@@ -2363,6 +2442,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s
+@@ -2365,6 +2444,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s
  
  	skb_hnat_alg(skb) = 0;
  	skb_hnat_set_tops(skb, 0);
@@ -158,7 +165,7 @@
  	skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
  
  	if (skb_hnat_iface(skb) == FOE_MAGIC_WED0)
-@@ -2449,7 +2529,8 @@ static unsigned int mtk_hnat_accel_type(
+@@ -2451,7 +2531,8 @@ static unsigned int mtk_hnat_accel_type(
  	 * is from local_out which is also filtered in sanity check.
  	 */
  	dst = skb_dst(skb);
@@ -168,7 +175,7 @@
  		return 0;
  
  	ct = nf_ct_get(skb, &ctinfo);
-@@ -2853,6 +2934,14 @@ static unsigned int mtk_hnat_nf_post_rou
+@@ -2855,6 +2936,14 @@ static unsigned int mtk_hnat_nf_post_rou
  		}
  	}
  
@@ -183,7 +190,7 @@
  	if (!IS_LAN_GRP(out) && !IS_WAN(out) && !IS_EXT(out))
  		is_virt_dev = true;
  
-@@ -3162,7 +3251,10 @@ mtk_hnat_ipv4_nf_local_out(void *priv, s
+@@ -3164,7 +3253,10 @@ mtk_hnat_ipv4_nf_local_out(void *priv, s
  	if (iph->protocol == IPPROTO_IPV6) {
  		entry->udib1.pkt_type = IPV6_6RD;
  		hnat_set_head_frags(state, skb, 0, hnat_set_alg);
@@ -257,28 +264,24 @@
  int ext_if_del(struct extdev_entry *ext_entry);
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -592,6 +592,10 @@
- #define MTK_QDMA_GMAC2_QID	8
+@@ -594,6 +594,8 @@
  #define MTK_QDMA_GMAC3_QID	6
  
-+/* QDMA V2 descriptor txd8 */
-+#define TX_DMA_CDRT_SHIFT 	0
-+#define TX_DMA_CDRT_MASK	0xff
-+
- /* QDMA V2 descriptor txd6 */
- #define TX_DMA_INS_VLAN_V2         BIT(16)
+ /* QDMA V2 descriptor txd8 */
++#define TX_DMA_CDRT_SHIFT          0
++#define TX_DMA_CDRT_MASK           0xff
+ #define TX_DMA_TOPS_ENTRY_SHIFT    8
+ #define TX_DMA_TOPS_ENTRY_MASK     0x3f
  
-@@ -601,6 +605,9 @@
+@@ -606,6 +608,7 @@
  #define TX_DMA_SPTAG_V3            BIT(27)
  
  /* QDMA V2 descriptor txd4 */
 +#define EIP197_QDMA_TPORT          3
-+#define TX_DMA_TPORT_SHIFT         0
-+#define TX_DMA_TPORT_MASK          0xf
+ #define TX_DMA_TPORT_SHIFT         0
+ #define TX_DMA_TPORT_MASK          0xf
  #define TX_DMA_FPORT_SHIFT_V2      8
- #define TX_DMA_FPORT_MASK_V2       0xf
- #define TX_DMA_SWC_V2              BIT(30)
-@@ -1063,6 +1070,43 @@
+@@ -1070,6 +1073,43 @@
  #define MT7628_SDM_MAC_ADRL	(MT7628_SDM_OFFSET + 0x0c)
  #define MT7628_SDM_MAC_ADRH	(MT7628_SDM_OFFSET + 0x10)
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4103-mtk-tunnel-crypto-offload-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4103-mtk-tunnel-crypto-offload-support.patch
deleted file mode 100644
index b96f080..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4103-mtk-tunnel-crypto-offload-support.patch
+++ /dev/null
@@ -1,202 +0,0 @@
---- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
-@@ -1144,6 +1144,8 @@ enum FoeIpAct {
- #define NR_EIP197_QDMA_TPORT 3
- #define NR_TDMA_TPORT 4
- #define NR_TDMA_QDMA_TPORT 5
-+#define NR_TDMA_EIP197_TPORT 8
-+#define NR_TDMA_EIP197_QDMA_TPORT 9
- #define LAN_DEV_NAME hnat_priv->lan
- #define LAN2_DEV_NAME hnat_priv->lan2
- #define IS_WAN(dev)                                                            \
---- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
-@@ -1101,7 +1101,8 @@ static unsigned int hnat_ipv4_get_nextho
- 	 * outer header, we must update its outer mac header pointer
- 	 * before filling outer mac or it may screw up inner mac
- 	 */
--	if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) {
-+	if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb))
-+	    || (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb))) {
- 		skb_push(skb, sizeof(struct ethhdr));
- 		skb_reset_mac_header(skb);
- 	}
-@@ -1110,7 +1111,8 @@ static unsigned int hnat_ipv4_get_nextho
- 	memcpy(eth_hdr(skb)->h_source, out->dev_addr, ETH_ALEN);
- 	eth_hdr(skb)->h_proto = htons(ETH_P_IP);
- 
--	if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb))
-+	if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb))
-+	    || (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb)))
- 		skb_pull(skb, sizeof(struct ethhdr));
- 
- 	rcu_read_unlock_bh();
-@@ -1258,6 +1260,38 @@ static inline void hnat_get_filled_unbin
- 	entry->bfib1.ps = 0;
- }
- 
-+/*
-+ * check offload engine data is prepared
-+ * return 0 for packets not related to offload engine
-+ * return positive value for offload engine prepared data done
-+ * return negative value for data is still constructing
-+ */
-+static inline int hnat_offload_engine_done(struct sk_buff *skb,
-+					   struct flow_offload_hw_path *hw_path)
-+{
-+	struct dst_entry *dst = skb_dst(skb);
-+
-+	if ((skb_hnat_tops(skb) && !(hw_path->flags & FLOW_OFFLOAD_PATH_TNL))) {
-+		/* tunnel encap'ed */
-+		if (dst && dst_xfrm(dst))
-+			/*
-+			 * skb not ready to bind since it is still needs
-+			 * to be encrypted
-+			 */
-+			return -1;
-+
-+		/* nothing need to be done further for this skb */
-+		return 1;
-+	}
-+
-+	if (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb) && dst && !dst_xfrm(dst))
-+		/* crypto encrypted done */
-+		return 1;
-+
-+	/* no need for tunnel encapsulation or crypto encryption */
-+	return 0;
-+}
-+
- static inline void hnat_qos_tnl(u32 id, const struct net_device *dev)
- {
- 	u32 cfg;
-@@ -1302,9 +1336,15 @@ static inline void hnat_fill_offload_eng
- 		 * we fill in hnat tport and tops_entry for tunnel encapsulation
- 		 * offloading
- 		 */
--		entry->ipv4_hnapt.tport_id = NR_TDMA_QDMA_TPORT;
-+		if (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb)) {
-+			entry->ipv4_hnapt.tport_id = NR_TDMA_EIP197_QDMA_TPORT;
-+			entry->ipv4_hnapt.cdrt_id = skb_hnat_cdrt(skb);
-+		} else {
-+			entry->ipv4_hnapt.tport_id = NR_TDMA_QDMA_TPORT;
-+		}
- 		entry->ipv4_hnapt.tops_entry = skb_hnat_tops(skb);
--	} else if (skb_hnat_cdrt(skb)) {
-+
-+	} else if (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb)) {
- 		entry->ipv4_hnapt.tport_id = NR_EIP197_QDMA_TPORT;
- 		entry->ipv4_hnapt.cdrt_id = skb_hnat_cdrt(skb);
- 	} else {
-@@ -1405,6 +1445,7 @@ static unsigned int skb_to_hnat_info(str
- 	u32 port_id = 0;
- 	u32 payload_len = 0;
- 	int mape = 0;
-+	int ret;
- 	struct mtk_mac *mac = netdev_priv(dev);
- 
- 	ct = nf_ct_get(skb, &ctinfo);
-@@ -1422,9 +1463,12 @@ static unsigned int skb_to_hnat_info(str
- 	if (whnat && is_hnat_pre_filled(foe))
- 		return 0;
- 
--	if (skb_hnat_tops(skb) && !(hw_path->flags & FLOW_OFFLOAD_PATH_TNL)) {
-+	ret = hnat_offload_engine_done(skb, hw_path);
-+	if (ret == 1) {
- 		hnat_get_filled_unbind_entry(skb, &entry);
- 		goto hnat_entry_bind;
-+	} else if (ret == -1) {
-+		return 0;
- 	}
- 
- 	entry.bfib1.pkt_type = foe->udib1.pkt_type; /* Get packte type state*/
-@@ -1870,7 +1914,9 @@ static unsigned int skb_to_hnat_info(str
- 	/* Fill Layer2 Info.*/
- 	entry = ppe_fill_L2_info(eth, entry, hw_path);
- 
--	if (skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL)
-+	if ((skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL)
-+	    || (!skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb)
-+		&& skb_dst(skb) && dst_xfrm(skb_dst(skb))))
- 		goto hnat_entry_skip_bind;
- 
- hnat_entry_bind:
-@@ -2435,6 +2481,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s
- 	skb_hnat_alg(skb) = 0;
- 	skb_hnat_set_tops(skb, 0);
- 	skb_hnat_set_cdrt(skb, 0);
-+	skb_hnat_set_is_decrypt(skb, 0);
- 	skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
- 
- 	if (skb_hnat_iface(skb) == FOE_MAGIC_WED0)
-@@ -3244,7 +3291,8 @@ mtk_hnat_ipv4_nf_local_out(void *priv, s
- 		entry->udib1.pkt_type = IPV6_6RD;
- 		hnat_set_head_frags(state, skb, 0, hnat_set_alg);
- 	} else if (is_magic_tag_valid(skb)
--		   && (skb_hnat_cdrt(skb) || skb_hnat_tops(skb))) {
-+		   && ((skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb))
-+		       || skb_hnat_tops(skb))) {
- 		hnat_set_head_frags(state, skb, 0, hnat_set_alg);
- 	} else {
- 		hnat_set_head_frags(state, skb, 1, hnat_set_alg);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2324,10 +2324,11 @@ static int mtk_poll_rx(struct napi_struc
- 
- 		skb_hnat_alg(skb) = 0;
- 		skb_hnat_filled(skb) = 0;
--		skb_hnat_set_cdrt(skb, 0);
-+		skb_hnat_set_cdrt(skb, RX_DMA_GET_CDRT(trxd.rxd7));
- 		skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
- 		skb_hnat_set_tops(skb, 0);
- 		skb_hnat_set_is_decap(skb, 0);
-+		skb_hnat_set_is_decrypt(skb, (skb_hnat_cdrt(skb) ? 1 : 0));
- 
- 		if (skb_hnat_reason(skb) == HIT_BIND_FORCE_TO_CPU) {
- 			trace_printk("[%s] reason=0x%x(force to CPU) from WAN to Ext\n",
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -656,6 +656,9 @@
- #define RX_DMA_GET_AGG_CNT_V2(_x)	(((_x) >> 16) & 0xff)
- #define RX_DMA_GET_TOPS_CRSN(_x)	(((_x) >> 24) & 0xff)
- 
-+/* PDMA V2 descriptor rxd7 */
-+#define RX_DMA_GET_CDRT(_x)		(((_x) >> 8) & 0xff)
-+
- /* PHY Polling and SMI Master Control registers */
- #define MTK_PPSC		0x10000
- #define PPSC_MDC_CFG		GENMASK(29, 24)
---- a/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
-@@ -47,7 +47,8 @@ struct hnat_desc {
- 	u32 tops : 6;
- 	u32 is_decap : 1;
- 	u32 cdrt : 8;
--	u32 resv3 : 4;
-+	u32 is_decrypt : 1;
-+	u32 resv3 : 3;
- 	u32 magic_tag_protect : 16;
- } __packed;
- #elif defined(CONFIG_MEDIATEK_NETSYS_RX_V2)
-@@ -101,7 +102,10 @@ struct hnat_desc {
- #define skb_hnat_set_tops(skb, tops) ((skb_hnat_tops(skb)) = (tops))
- #define skb_hnat_set_is_decap(skb, is_decap) ((skb_hnat_is_decap(skb)) = (is_decap))
- #define skb_hnat_cdrt(skb) (((struct hnat_desc *)((skb)->head))->cdrt)
-+#define skb_hnat_is_decrypt(skb) (((struct hnat_desc *)((skb)->head))->is_decrypt)
-+#define skb_hnat_is_encrypt(skb) (!skb_hnat_is_decrypt(skb))
- #define skb_hnat_set_cdrt(skb, cdrt) ((skb_hnat_cdrt(skb)) = (cdrt))
-+#define skb_hnat_set_is_decrypt(skb, is_dec) ((skb_hnat_is_decrypt(skb)) = is_dec)
- #else /* !defined(CONFIG_MEDIATEK_NETSYS_V3) */
- #define skb_hnat_tops(skb) (0)
- #define skb_hnat_is_decap(skb) (0)
-@@ -109,7 +113,10 @@ struct hnat_desc {
- #define skb_hnat_set_tops(skb, tops)
- #define skb_hnat_set_is_decap(skb, is_decap)
- #define skb_hnat_cdrt(skb) (0)
-+#define skb_hnat_is_decrypt(skb) (0)
-+#define skb_hnat_is_encrypt(skb) (0)
- #define skb_hnat_set_cdrt(skb, cdrt)
-+#define skb_hnat_set_is_decrypt(skb, is_dec)
- #endif /* defined(CONFIG_MEDIATEK_NETSYS_V3) */
- #define skb_hnat_magic(skb) (((struct hnat_desc *)(skb->head))->magic)
- #define skb_hnat_reason(skb) (((struct hnat_desc *)(skb->head))->crsn)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-gre-offload-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-gre-offload-support.patch
deleted file mode 100644
index 3833fa0..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-gre-offload-support.patch
+++ /dev/null
@@ -1,45 +0,0 @@
---- a/net/ipv4/ip_gre.c
-+++ b/net/ipv4/ip_gre.c
-@@ -39,6 +39,7 @@
- #include <net/inet_ecn.h>
- #include <net/xfrm.h>
- #include <net/net_namespace.h>
-+#include <net/netfilter/nf_flow_table.h>
- #include <net/netns/generic.h>
- #include <net/rtnetlink.h>
- #include <net/gre.h>
-@@ -901,6 +902,24 @@ static int ipgre_close(struct net_device
- }
- #endif
- 
-+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
-+static int gre_dev_flow_offload_check(struct flow_offload_hw_path *path)
-+{
-+	struct net_device *dev = path->dev;
-+	struct ip_tunnel *tunnel = netdev_priv(dev);
-+
-+	if (path->flags & FLOW_OFFLOAD_PATH_TNL)
-+		return -EEXIST;
-+
-+	path->flags |= FLOW_OFFLOAD_PATH_TNL;
-+	path->tnl_type = FLOW_OFFLOAD_TNL_GRETAP;
-+	path->virt_dev = dev;
-+	path->dev = tunnel->dev;
-+
-+	return 0;
-+}
-+#endif /* CONFIG_NF_FLOW_TABLE */
-+
- static const struct net_device_ops ipgre_netdev_ops = {
- 	.ndo_init		= ipgre_tunnel_init,
- 	.ndo_uninit		= ip_tunnel_uninit,
-@@ -1264,6 +1283,9 @@ static const struct net_device_ops gre_t
- 	.ndo_get_stats64	= ip_tunnel_get_stats64,
- 	.ndo_get_iflink		= ip_tunnel_get_iflink,
- 	.ndo_fill_metadata_dst	= gre_fill_metadata_dst,
-+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
-+	.ndo_flow_offload_check = gre_dev_flow_offload_check,
-+#endif
- };
- 
- static int erspan_tunnel_init(struct net_device *dev)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-ppp-offload-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-ppp-offload-support.patch
deleted file mode 100644
index 1409f9f..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-ppp-offload-support.patch
+++ /dev/null
@@ -1,65 +0,0 @@
---- a/drivers/net/ppp/ppp_generic.c
-+++ b/drivers/net/ppp/ppp_generic.c
-@@ -296,6 +296,9 @@ static void unit_put(struct idr *p, int
- static void *unit_find(struct idr *p, int n);
- static void ppp_setup(struct net_device *dev);
- 
-+struct sock *ppp_netdev_get_sock(struct net_device *dev);
-+EXPORT_SYMBOL(ppp_netdev_get_sock);
-+
- static const struct net_device_ops ppp_netdev_ops;
- 
- static struct class *ppp_class;
-@@ -1660,6 +1663,40 @@ ppp_send_frame(struct ppp *ppp, struct s
- 	++ppp->dev->stats.tx_errors;
- }
- 
-+struct sock *ppp_netdev_get_sock(struct net_device *dev)
-+{
-+	struct list_head *list;
-+	struct channel *pch;
-+	struct ppp *ppp;
-+	struct sock *sk;
-+
-+	if (!dev)
-+		return ERR_PTR(-EINVAL);
-+
-+	ppp = netdev_priv(dev);
-+
-+	list = &ppp->channels;
-+	if (list_empty(list))
-+		 /* nowhere to send the packet */
-+		return ERR_PTR(-EINVAL);
-+
-+	if (ppp->flags & SC_MULTILINK)
-+		/* not doing multilink: send it down the first channel */
-+		return ERR_PTR(-EPERM);
-+
-+	list = list->next;
-+	pch = list_entry(list, struct channel, clist);
-+
-+	spin_lock(&pch->downl);
-+	if (pch->chan)
-+		sk = (struct sock *)pch->chan->private;
-+	else
-+		sk = ERR_PTR(-EINVAL);
-+	spin_unlock(&pch->downl);
-+
-+	return sk;
-+}
-+
- /*
-  * Try to send the frame in xmit_pending.
-  * The caller should have the xmit path locked.
---- a/include/linux/ppp_channel.h
-+++ b/include/linux/ppp_channel.h
-@@ -75,6 +75,9 @@ extern int ppp_unit_number(struct ppp_ch
- /* Get the device name associated with a channel, or NULL if none */
- extern char *ppp_dev_name(struct ppp_channel *);
- 
-+/* Get the socket structure of a given ppp netdev */
-+extern struct sock *ppp_netdev_get_sock(struct net_device *dev);
-+
- /*
-  * SMP locking notes:
-  * The channel code must ensure that when it calls ppp_unregister_channel,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4501-mtk-l2tp-offload-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4501-mtk-l2tp-offload-support.patch
deleted file mode 100644
index 5e16ba8..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4501-mtk-l2tp-offload-support.patch
+++ /dev/null
@@ -1,35 +0,0 @@
---- a/net/l2tp/l2tp_core.c
-+++ b/net/l2tp/l2tp_core.c
-@@ -1068,6 +1068,10 @@ int l2tp_xmit_skb(struct l2tp_session *s
- 	int udp_len;
- 	int ret = NET_XMIT_SUCCESS;
- 
-+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
-+	skb_reset_inner_headers(skb);
-+#endif
-+
- 	/* Check that there's enough headroom in the skb to insert IP,
- 	 * UDP and L2TP headers. If not enough, expand it to
- 	 * make room. Adjust truesize.
---- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
-@@ -865,7 +865,8 @@ mtk_hnat_ipv4_nf_pre_routing(void *priv,
- 	 * and it's L2TP flow, then do not bind.
- 	 */
- 	if (skb_hnat_iface(skb) == FOE_MAGIC_GE_VIRTUAL
--	    && skb->dev->netdev_ops->ndo_flow_offload_check) {
-+	    && skb->dev->netdev_ops->ndo_flow_offload_check
-+	    && !mtk_tnl_decap_offload) {
- 		skb->dev->netdev_ops->ndo_flow_offload_check(&hw_path);
- 
- 		if (hw_path.flags & FLOW_OFFLOAD_PATH_TNL)
---- a/net/l2tp/l2tp_ppp.c
-+++ b/net/l2tp/l2tp_ppp.c
-@@ -356,6 +356,7 @@ static int l2tp_ppp_flow_offload_check(s
- 		return -EINVAL;
- 
- 	path->flags |= FLOW_OFFLOAD_PATH_TNL;
-+	path->tnl_type = FLOW_OFFLOAD_TNL_L2TP_V2;
- 
- 	return 0;
- }
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4501-mtk-pptp-offload-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4501-mtk-pptp-offload-support.patch
deleted file mode 100644
index ec218e1..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4501-mtk-pptp-offload-support.patch
+++ /dev/null
@@ -1,100 +0,0 @@
---- a/drivers/net/ppp/pptp.c
-+++ b/drivers/net/ppp/pptp.c
-@@ -33,6 +33,7 @@
- #include <net/route.h>
- #include <net/gre.h>
- #include <net/pptp.h>
-+#include <net/netfilter/nf_flow_table.h>
- 
- #include <linux/uaccess.h>
- 
-@@ -40,6 +41,9 @@
- 
- #define MAX_CALLID 65535
- 
-+int (*mtk_pptp_seq_next)(u16 call_id, u32 *val) = NULL;
-+EXPORT_SYMBOL(mtk_pptp_seq_next);
-+
- static DECLARE_BITMAP(callid_bitmap, MAX_CALLID + 1);
- static struct pppox_sock __rcu **callid_sock;
- 
-@@ -128,6 +132,26 @@ static void del_chan(struct pppox_sock *
- 	spin_unlock(&chan_lock);
- }
- 
-+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
-+static int pptp_flow_offload_check(struct ppp_channel *chan,
-+				   struct flow_offload_hw_path *path)
-+{
-+	struct sock *sk = (struct sock *)chan->private;
-+	struct pppox_sock *po = pppox_sk(sk);
-+
-+	if (path->flags & FLOW_OFFLOAD_PATH_TNL)
-+		return -EEXIST;
-+
-+	if (sk_pppox(po)->sk_state & PPPOX_DEAD)
-+		return -EINVAL;
-+
-+	path->flags |= FLOW_OFFLOAD_PATH_TNL;
-+	path->tnl_type = FLOW_OFFLOAD_TNL_PPTP;
-+
-+	return 0;
-+}
-+#endif /* IS_ENABLED(CONFIG_NF_FLOW_TABLE) */
-+
- static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
- {
- 	struct sock *sk = (struct sock *) chan->private;
-@@ -140,6 +164,7 @@ static int pptp_xmit(struct ppp_channel
- 	int islcp;
- 	int len;
- 	unsigned char *data;
-+	u32 seq_sent_hw;
- 	__u32 seq_recv;
- 
- 
-@@ -204,7 +229,14 @@ static int pptp_xmit(struct ppp_channel
- 	hdr->gre_hd.protocol = GRE_PROTO_PPP;
- 	hdr->call_id = htons(opt->dst_addr.call_id);
- 
--	hdr->seq = htonl(++opt->seq_sent);
-+	if (mtk_pptp_seq_next && !mtk_pptp_seq_next(opt->dst_addr.call_id,
-+						    &seq_sent_hw)) {
-+		opt->seq_sent = seq_sent_hw;
-+		hdr->seq = htonl(opt->seq_sent);
-+	} else {
-+		hdr->seq = htonl(++opt->seq_sent);
-+	}
-+
- 	if (opt->ack_sent != seq_recv)	{
- 		/* send ack with this message */
- 		hdr->gre_hd.flags |= GRE_ACK;
-@@ -598,6 +630,9 @@ static int pptp_ppp_ioctl(struct ppp_cha
- static const struct ppp_channel_ops pptp_chan_ops = {
- 	.start_xmit = pptp_xmit,
- 	.ioctl      = pptp_ppp_ioctl,
-+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
-+	.flow_offload_check = pptp_flow_offload_check,
-+#endif /* IS_ENABLED(CONFIG_NF_FLOW_TABLE) */
- };
- 
- static struct proto pptp_sk_proto __read_mostly = {
---- a/include/net/pptp.h
-+++ b/include/net/pptp.h
-@@ -2,6 +2,8 @@
- #ifndef _NET_PPTP_H
- #define _NET_PPTP_H
- 
-+#include <net/gre.h>
-+
- #define PPP_LCP_ECHOREQ 0x09
- #define PPP_LCP_ECHOREP 0x0A
- #define SC_RCV_BITS     (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
-@@ -20,5 +22,7 @@ struct pptp_gre_header {
- 	__be32 ack;
- } __packed;
- 
-+/* symbol exported from linux kernel driver/net/ppp/pptp.c */
-+extern int (*mtk_pptp_seq_next)(uint16_t call_id, uint32_t *val);
- 
- #endif