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

[Description]
61c5ed8f [HIGH][kernel][mt7988][hnat][Remove unnecessary paths for the keep_ecn/keep_dscp features]
d8bab9e8 [kernel][common][hnt][Add spinlock to protect ETH to ETH or WiFi RX binding process]
4819d283 [MAC80211][misc][Change relayd trigger action]
061d2493 [kernel][common][eth][Fix Fiberstore SFP-10G-T IOT issue]
e306310c [kernel][common][hnat][Fix issue of GDM ingress control forward to PPE setting]
8085563c [kernel][mt7988][eth][Update 36-bit DMA feature to resolve panic issue]
13b52f22 [kernel][common][eth][Add more FE regions to the NETSYS dump]
9d750be1 [openwrt][mt7988][crypto][Add to fill the inner packet info for route-based IPSec]
c30b46e7 [openwrt][mt7988][crypto][Add support for route-based IPSec]
9f168704 [HIGH][kernel][mt7988][eth][Fix panic issue with Gangload mode during the Aquantia firmware download]
ccc3b9d5 [HIGH][kernel][common][hnat][Fix issue nf_conntrack statistics update when dump all_entry]
57722186 [MAC80211][eth][Fix patch conflict issue]
41446009 [kernel][common][hnat][Fix Coverity defects in HNAT]
8fc1960f [kernel][common][eth][Fix Coverity defects in the USXGMII/SGMII]
216d6f51 [kernel][common][eth][Add more PPE regions to the NETSYS dump]
2bcb8ccf [openwrt][change msdc clock source to 208M]
1c1d4082 [MAC80211][misc][Sync OpenWRT config to the internal autobuild]
d291e00f [kernel][common][eth][Add debugfs support for the SFP]
57367c44 [MAC80211][hnat][Fix the traffic stuck issue for fastpath and hwpath in RelayD]
48122e86 [HIGH][kernel][common][eth][Fix the GDM TX/RX packet statistics error issue]
3e8561e3 [MAC80211][hnat][Add foe_entry_size to the SoC private data]
bb16f717 [kernel][mt7981][spi][Add SPI TPM example in dts and fix calibration flow]
fd870459 [kernel][mt7986][spi][dts: Add SPI calibration for NAND/NOR flashes]
d46252bf [kernel][mt7981/mt7986/mt7988][spi][spi-calibration: Fix spi-cal-enable flow]
4f17c6e8 [MAC80211][hnat][Add iptables pkttype rules to skip Multicast binding]
cc9d48d3 [kernel][common][eth][Refactor LRO and RSS configurations to the reg_map method]
afa65d04 [MAC80211][hnat][Fix dscp info didn't fill in ib2 on wifi tx path]
bc65a45f [openwrt][common][bsp][Add readme]
3f799e36 [openwrt-24][common][bsp][Add .gitignore]
28400f24 [openwrt-24][common][bsp][Add initial support for openwrt master filogic target]
03a58907 [Critical][kernel][mt7988][eth][i2.5Gphy: Update firmware to 20240618 version]
ac5fadec [kernel][common][hnat][Refactor HNAT flow to prevent entry modification racing]
a61a1837 [HIGH][kernel][mt7986/mt7981][eth][Fix HW LRO IRQ request error]
159cbe4b [openwrt][MT7981][switch][remove AN8855 image build]
3cb56bd2 [kernel][mt7988][eth][Refactor 8GB_ADDRESSING to the upstream style]
d9b9dc3f [openwrt][MT7981][single DTS supports both MT7531 and AN8855]
7014c79d [kernel][mt7988][hnat][Change PPE entry IPV6_HNAPT condition to support NPTv6]
abcd0f5d [MAC80211][hnat][Add extension wed debugfs]
a9f09e2d [HIGH][kernel][common][eth][Fix incorrect TX DMA buffer length]
2c4ed95a [kernel][mt7628][eth][Remove redundant platform data of MT7628]
0b6689eb [openwrt][app][Fix Coverity defects in the switch utility, Part4]
10ce1caa [openwrt][app][Fix Coverity defects in the switch utility, Part3]
d907bd65 [openwrt][app][Fix Coverity defects in the switch utility, Part2]
60fae9b8 [openwrt][app][Fix Coverity defects in the switch utility, Part1]
15be55dc [kernel][common][eth][Fix warning of return with a value in returning void function]
4f7cc5ca [MAC80211][hnat][Refactor two-way hashing and per-flow accounting features to the upstream style]

[Release-log]

Change-Id: Id87559484a1999276c366c085684d5f98ceea33a
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-2500wan-spim-nand-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-2500wan-spim-nand-rfb.dts
index 5baa16e..45b0481 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-2500wan-spim-nand-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-2500wan-spim-nand-rfb.dts
@@ -193,6 +193,13 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <7>;
+		spi-cal-data = /bits/ 8 <
+			0x53 0x46 0x5F 0x42 0x4F 0x4F 0x54>; /* SF_BOOT */
+		spi-cal-addrlen = <1>;
+		spi-cal-addr = /bits/ 32 <0x0>;
 		reg = <0>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
@@ -203,6 +210,12 @@
 		#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 = <1>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-2500wan-spim-nor-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-2500wan-spim-nor-rfb.dts
index 8cd84b5..334989b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-2500wan-spim-nor-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-2500wan-spim-nor-rfb.dts
@@ -192,6 +192,13 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <7>;
+		spi-cal-data = /bits/ 8 <
+			0x53 0x46 0x5F 0x42 0x4F 0x4F 0x54>; /* SF_BOOT */
+		spi-cal-addrlen = <1>;
+		spi-cal-addr = /bits/ 32 <0x0>;
 		reg = <0>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-spim-nand-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-spim-nand-rfb.dts
index fe853e9..e3e8f48 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-spim-nand-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-spim-nand-rfb.dts
@@ -201,6 +201,13 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <7>;
+		spi-cal-data = /bits/ 8 <
+			0x53 0x46 0x5F 0x42 0x4F 0x4F 0x54>; /* SF_BOOT */
+		spi-cal-addrlen = <1>;
+		spi-cal-addr = /bits/ 32 <0x0>;
 		reg = <0>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
@@ -211,6 +218,12 @@
 		#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 = <1>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-spim-nor-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-spim-nor-rfb.dts
index cf85743..2a2c803 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-spim-nor-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a-spim-nor-rfb.dts
@@ -201,6 +201,13 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <7>;
+		spi-cal-data = /bits/ 8 <
+			0x53 0x46 0x5F 0x42 0x4F 0x4F 0x54>; /* SF_BOOT */
+		spi-cal-addrlen = <1>;
+		spi-cal-addr = /bits/ 32 <0x0>;
 		reg = <0>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-emmc-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-emmc-rfb.dts
index d0f834a..0d16fcf 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-emmc-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-emmc-rfb.dts
@@ -78,7 +78,7 @@
 			nvmem-cell-names = "phy-cal-data";
 		};
 
-		switch@0 {
+		switch@31 {
 			compatible = "mediatek,mt7531";
 			reg = <31>;
 			reset-gpios = <&pio 39 0>;
@@ -121,6 +121,51 @@
 				};
 			};
 		};
+
+		switch@1 {
+			compatible = "airoha,an8855";
+			reg = <1>;
+			reset-gpios = <&pio 39 0>;
+			changesmiaddr = <6>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					label = "lan1";
+				};
+
+				port@1 {
+					reg = <1>;
+					label = "lan2";
+				};
+
+				port@2 {
+					reg = <2>;
+					label = "lan3";
+				};
+
+				port@3 {
+					reg = <3>;
+					label = "lan4";
+				};
+
+				port@5 {
+					reg = <5>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "2500base-x";
+
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+		};
 	};
 };
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-sd-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-sd-rfb.dts
index c181aba..f0d4639 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-sd-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-sd-rfb.dts
@@ -78,7 +78,7 @@
 			nvmem-cell-names = "phy-cal-data";
 		};
 
-		switch@0 {
+		switch@31 {
 			compatible = "mediatek,mt7531";
 			reg = <31>;
 			reset-gpios = <&pio 39 0>;
@@ -121,6 +121,51 @@
 				};
 			};
 		};
+
+		switch@1 {
+			compatible = "airoha,an8855";
+			reg = <1>;
+			reset-gpios = <&pio 39 0>;
+			changesmiaddr = <6>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					label = "lan1";
+				};
+
+				port@1 {
+					reg = <1>;
+					label = "lan2";
+				};
+
+				port@2 {
+					reg = <2>;
+					label = "lan3";
+				};
+
+				port@3 {
+					reg = <3>;
+					label = "lan4";
+				};
+
+				port@5 {
+					reg = <5>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "2500base-x";
+
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+		};
 	};
 };
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-snfi-nand-2500wan-p5.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-snfi-nand-2500wan-p5.dts
index 24eb1d7..8b43039 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-snfi-nand-2500wan-p5.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-snfi-nand-2500wan-p5.dts
@@ -81,23 +81,23 @@
 };
 
 &eth {
-        status = "okay";
+	status = "okay";
 
-        gmac0: mac@0 {
-                compatible = "mediatek,eth-mac";
-                reg = <0>;
-                phy-mode = "2500base-x";
+	gmac0: mac@0 {
+		compatible = "mediatek,eth-mac";
+		reg = <0>;
+		phy-mode = "2500base-x";
 
-                fixed-link {
-                        speed = <2500>;
-                        full-duplex;
-                        pause;
-                };
-        };
+		fixed-link {
+			speed = <2500>;
+			full-duplex;
+			pause;
+		};
+	};
 
-        mdio: mdio-bus {
-                #address-cells = <1>;
-                #size-cells = <0>;
+	mdio: mdio-bus {
+		#address-cells = <1>;
+		#size-cells = <0>;
 
 		phy5: phy@5 {
 			compatible = "ethernet-phy-id67c9.de0a";
@@ -108,62 +108,62 @@
 			phy-mode = "2500base-x";
 		};
 
-                switch@0 {
-                        compatible = "mediatek,mt7531";
-                        reg = <31>;
-                        reset-gpios = <&pio 39 0>;
+		switch@31 {
+			compatible = "mediatek,mt7531";
+			reg = <31>;
+			reset-gpios = <&pio 39 0>;
 
-                        ports {
-                                #address-cells = <1>;
-                                #size-cells = <0>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
 
-                                port@0 {
-                                        reg = <0>;
-                                        label = "lan1";
-                                };
+				port@0 {
+					reg = <0>;
+					label = "lan1";
+				};
 
-                                port@1 {
-                                        reg = <1>;
-                                        label = "lan2";
-                                };
+				port@1 {
+					reg = <1>;
+					label = "lan2";
+				};
 
-                                port@2 {
-                                        reg = <2>;
-                                        label = "lan3";
-                                };
+				port@2 {
+					reg = <2>;
+					label = "lan3";
+				};
 
-                                port@3 {
-                                        reg = <3>;
-                                        label = "lan4";
-                                };
+				port@3 {
+					reg = <3>;
+					label = "lan4";
+				};
 
-                        	port@5 {
-                                	reg = <5>;
-	                                label = "wan";
-        	                        phy-mode = "2500base-x";
+				port@5 {
+					reg = <5>;
+					label = "wan";
+					phy-mode = "2500base-x";
 
-                	                fixed-link {
-                        	                speed = <2500>;
-                                	        full-duplex;
-                                        	pause;
-	                                };
-        	                };
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+						pause;
+					};
+				};
 
-                                port@6 {
-                                        reg = <6>;
-                                        label = "cpu";
-                                        ethernet = <&gmac0>;
-                                        phy-mode = "2500base-x";
+				port@6 {
+					reg = <6>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "2500base-x";
 
-                                        fixed-link {
-                                                speed = <2500>;
-                                                full-duplex;
-                                                pause;
-                                        };
-                                };
-                        };
-                };
-        };
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+		};
+	};
 };
 
 &hnat {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-2500wan-an8855-gsw.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-2500wan-an8855-gsw.dts
deleted file mode 100644
index 3f0bb90..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-2500wan-an8855-gsw.dts
+++ /dev/null
@@ -1,295 +0,0 @@
-/dts-v1/;
-#include "mt7981.dtsi"
-/ {
-	model = "MediaTek MT7981 RFB";
-	compatible = "mediatek,mt7981-spim-snand-2500wan-an8855-gsw-rfb";
-	chosen {
-		bootargs = "console=ttyS0,115200n1 loglevel=8  \
-				earlycon=uart8250,mmio32,0x11002000";
-	};
-
-	memory {
-		// fpga ddr2: 128MB*2
-		reg = <0 0x40000000 0 0x10000000>;
-	};
-
-	gpio-keys {
-			compatible = "gpio-keys";
-				reset {
-					label = "reset";
-					linux,code = <KEY_RESTART>;
-					gpios = <&pio 1 GPIO_ACTIVE_LOW>;
-				};
-
-				wps {
-					label = "wps";
-					linux,code = <KEY_WPS_BUTTON>;
-					gpios = <&pio 0 GPIO_ACTIVE_HIGH>;
-				};
-	};
-
-	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 0x0200000>;
-			};
-
-			partition@380000 {
-				label = "FIP";
-				reg = <0x380000 0x0200000>;
-			};
-
-			partition@580000 {
-				label = "ubi";
-				reg = <0x580000 0x4000000>;
-			};
-		};
-	};
-
-	gsw: gsw@0 {
-		compatible = "airoha,an8855";
-		#mediatek,ethsys = <&ethsys>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
-};
-
-&uart0 {
-	status = "okay";
-};
-
-&watchdog {
-	status = "okay";
-};
-
-&eth {
-	status = "okay";
-
-	gmac0: mac@0 {
-		compatible = "mediatek,eth-mac";
-		reg = <0>;
-		phy-mode = "2500base-x";
-
-		fixed-link {
-			speed = <2500>;
-			full-duplex;
-			pause;
-		};
-	};
-
-	gmac1: mac@1 {
-		compatible = "mediatek,eth-mac";
-		reg = <1>;
-		phy-mode = "2500base-x";
-		phy-handle = <&phy5>;
-	};
-
-	mdio: mdio-bus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		reset-gpios = <&pio 14 1>;
-		reset-delay-us = <600>;
-
-		phy5: phy@5 {
-			compatible = "ethernet-phy-ieee802.3-c45";
-			reg = <5>;
-		};
-	};
-};
-
-&gsw {
-	airoha,mdio = <&mdio>;
-	airoha,portmap = "llllw";
-	airoha,smi-addr = <6>;
-	reset-gpios = <&pio 39 0>;
-	interrupt-parent = <&pio>;
-	interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
-	status = "okay";
-
-	port5: port@5 {
-		compatible = "airoha,an8855-port";
-		reg = <5>;
-		phy-mode = "2500base-x";
-		/* airoha,stag-on = <1>; */
-
-		fixed-link {
-			speed = <2500>;
-			full-duplex;
-		};
-	};
-};
-
-&hnat {
-	mtketh-wan = "eth1";
-	mtketh-lan = "eth0";
-	mtketh-max-gmac = <2>;
-	status = "okay";
-};
-
-&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";
-	pinctrl-0 = <&spic_pins>;
-	status = "disabled";
-
-	slb9670: slb9670@0 {
-		compatible = "infineon,slb9670";
-		reg = <0>; /* CE0 */
-		#address-cells = <1>;
-		#size-cells = <0>;
-		spi-cal-enable;
-		spi-cal-mode = "read-data";
-		spi-cal-datalen = <2>;
-		spi-cal-data = /bits/ 8 <0x00 0x1b>;
-		spi-max-frequency = <20000000>;
-	};
-};
-
-&wbsys {
-	mediatek,mtd-eeprom = <&factory 0x0000>;
-	status = "okay";
-	pinctrl-names = "dbdc";
-	pinctrl-0 = <&wf_dbdc_pins>;
-};
-
-&pio {
-
-	i2c_pins: i2c-pins-g0 {
-		mux {
-			function = "i2c";
-			groups = "i2c0_0";
-		};
-	};
-
-	pcm_pins: pcm-pins-g0 {
-		mux {
-			function = "pcm";
-			groups = "pcm";
-		};
-	};
-
-	pwm0_pin: pwm0-pin-g0 {
-		mux {
-			function = "pwm";
-			groups = "pwm0_0";
-		};
-	};
-
-	pwm1_pin: pwm1-pin-g0 {
-		mux {
-			function = "pwm";
-			groups = "pwm1_0";
-		};
-	};
-
-	pwm2_pin: pwm2-pin {
-		mux {
-			function = "pwm";
-			groups = "pwm2";
-		};
-	};
-
-	spi0_flash_pins: spi0-pins {
-		mux {
-			function = "spi";
-			groups = "spi0", "spi0_wp_hold";
-		};
-
-		conf-pu {
-			pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
-			drive-strength = <MTK_DRIVE_8mA>;
-			bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
-		};
-
-		conf-pd {
-			pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
-			drive-strength = <MTK_DRIVE_8mA>;
-			bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
-		};
-	};
-
-	spic_pins: spi1-pins {
-		mux {
-			function = "spi";
-			groups = "spi1_1";
-		};
-	};
-
-	uart1_pins: uart1-pins-g1 {
-		mux {
-			function = "uart";
-			groups = "uart1_1";
-		};
-	};
-
-	uart2_pins: uart2-pins-g1 {
-		mux {
-			function = "uart";
-			groups = "uart2_1";
-		};
-	};
-
-	wf_dbdc_pins: wf_dbdc-pins {
-		mux {
-			function = "eth";
-			groups = "wf0_mode1";
-		};
-		conf {
-			pins = "WF_HB1", "WF_HB2", "WF_HB3", "WF_HB4",
-			       "WF_HB0", "WF_HB0_B", "WF_HB5", "WF_HB6",
-			       "WF_HB7", "WF_HB8", "WF_HB9", "WF_HB10",
-			       "WF_TOP_CLK", "WF_TOP_DATA", "WF_XO_REQ",
-			       "WF_CBA_RESETB", "WF_DIG_RESETB";
-			drive-strength = <MTK_DRIVE_4mA>;
-		};
-	};
-};
-
-&xhci {
-	status = "okay";
-};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-2500wan-an8855.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-2500wan-an8855.dts
deleted file mode 100644
index 4697ef5..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-2500wan-an8855.dts
+++ /dev/null
@@ -1,310 +0,0 @@
-/dts-v1/;
-#include "mt7981.dtsi"
-/ {
-	model = "MediaTek MT7981 RFB";
-	compatible = "mediatek,mt7981-spim-snand-2500wan-an8855-rfb";
-	chosen {
-		bootargs = "console=ttyS0,115200n1 loglevel=8  \
-				earlycon=uart8250,mmio32,0x11002000";
-	};
-
-	memory {
-		// fpga ddr2: 128MB*2
-		reg = <0 0x40000000 0 0x10000000>;
-	};
-
-	gpio-keys {
-			compatible = "gpio-keys";
-				reset {
-					label = "reset";
-					linux,code = <KEY_RESTART>;
-					gpios = <&pio 1 GPIO_ACTIVE_LOW>;
-				};
-
-				wps {
-					label = "wps";
-					linux,code = <KEY_WPS_BUTTON>;
-					gpios = <&pio 0 GPIO_ACTIVE_HIGH>;
-				};
-	};
-
-	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 0x0200000>;
-			};
-
-			partition@380000 {
-				label = "FIP";
-				reg = <0x380000 0x0200000>;
-			};
-
-			partition@580000 {
-				label = "ubi";
-				reg = <0x580000 0x4000000>;
-			};
-		};
-	};
-};
-
-&uart0 {
-	status = "okay";
-};
-
-&watchdog {
-	status = "okay";
-};
-
-&eth {
-	status = "okay";
-
-	gmac0: mac@0 {
-		compatible = "mediatek,eth-mac";
-		reg = <0>;
-		phy-mode = "2500base-x";
-
-		fixed-link {
-			speed = <2500>;
-			full-duplex;
-			pause;
-		};
-	};
-
-	gmac1: mac@1 {
-		compatible = "mediatek,eth-mac";
-		reg = <1>;
-		phy-mode = "2500base-x";
-		phy-handle = <&phy5>;
-	};
-
-	mdio: mdio-bus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		reset-gpios = <&pio 14 1>;
-		reset-delay-us = <600>;
-
-		phy5: phy@5 {
-			compatible = "ethernet-phy-ieee802.3-c45";
-			reg = <5>;
-		};
-
-		switch@0 {
-			compatible = "airoha,an8855";
-			reg = <1>;
-			reset-gpios = <&pio 39 0>;
-			changesmiaddr = <6>;
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				port@0 {
-					reg = <0>;
-					label = "lan1";
-				};
-
-				port@1 {
-					reg = <1>;
-					label = "lan2";
-				};
-
-				port@2 {
-					reg = <2>;
-					label = "lan3";
-				};
-
-				port@3 {
-					reg = <3>;
-					label = "lan4";
-				};
-
-				port@5 {
-					reg = <5>;
-					label = "cpu";
-					ethernet = <&gmac0>;
-					phy-mode = "2500base-x";
-
-					fixed-link {
-						speed = <2500>;
-						full-duplex;
-						pause;
-					};
-				};
-			};
-		};
-	};
-};
-
-&hnat {
-	mtketh-wan = "eth1";
-	mtketh-lan = "lan";
-	mtketh-max-gmac = <2>;
-	status = "okay";
-};
-
-&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";
-	pinctrl-0 = <&spic_pins>;
-	status = "disabled";
-
-	slb9670: slb9670@0 {
-		compatible = "infineon,slb9670";
-		reg = <0>; /* CE0 */
-		#address-cells = <1>;
-		#size-cells = <0>;
-		spi-cal-enable;
-		spi-cal-mode = "read-data";
-		spi-cal-datalen = <2>;
-		spi-cal-data = /bits/ 8 <0x00 0x1b>;
-		spi-max-frequency = <20000000>;
-	};
-};
-
-&wbsys {
-	mediatek,mtd-eeprom = <&factory 0x0000>;
-	status = "okay";
-	pinctrl-names = "dbdc";
-	pinctrl-0 = <&wf_dbdc_pins>;
-};
-
-&pio {
-
-	i2c_pins: i2c-pins-g0 {
-		mux {
-			function = "i2c";
-			groups = "i2c0_0";
-		};
-	};
-
-	pcm_pins: pcm-pins-g0 {
-		mux {
-			function = "pcm";
-			groups = "pcm";
-		};
-	};
-
-	pwm0_pin: pwm0-pin-g0 {
-		mux {
-			function = "pwm";
-			groups = "pwm0_0";
-		};
-	};
-
-	pwm1_pin: pwm1-pin-g0 {
-		mux {
-			function = "pwm";
-			groups = "pwm1_0";
-		};
-	};
-
-	pwm2_pin: pwm2-pin {
-		mux {
-			function = "pwm";
-			groups = "pwm2";
-		};
-	};
-
-	spi0_flash_pins: spi0-pins {
-		mux {
-			function = "spi";
-			groups = "spi0", "spi0_wp_hold";
-		};
-
-		conf-pu {
-			pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
-			drive-strength = <MTK_DRIVE_8mA>;
-			bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
-		};
-
-		conf-pd {
-			pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
-			drive-strength = <MTK_DRIVE_8mA>;
-			bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
-		};
-	};
-
-	spic_pins: spi1-pins {
-		mux {
-			function = "spi";
-			groups = "spi1_1";
-		};
-	};
-
-	uart1_pins: uart1-pins-g1 {
-		mux {
-			function = "uart";
-			groups = "uart1_1";
-		};
-	};
-
-	uart2_pins: uart2-pins-g1 {
-		mux {
-			function = "uart";
-			groups = "uart2_1";
-		};
-	};
-
-	wf_dbdc_pins: wf_dbdc-pins {
-		mux {
-			function = "eth";
-			groups = "wf0_mode1";
-		};
-		conf {
-			pins = "WF_HB1", "WF_HB2", "WF_HB3", "WF_HB4",
-			       "WF_HB0", "WF_HB0_B", "WF_HB5", "WF_HB6",
-			       "WF_HB7", "WF_HB8", "WF_HB9", "WF_HB10",
-			       "WF_TOP_CLK", "WF_TOP_DATA", "WF_XO_REQ",
-			       "WF_CBA_RESETB", "WF_DIG_RESETB";
-			drive-strength = <MTK_DRIVE_4mA>;
-		};
-	};
-};
-
-&xhci {
-	status = "okay";
-};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-2500wan-gmac2.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-2500wan-gmac2.dts
index e57bba9..cbe7811 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-2500wan-gmac2.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-2500wan-gmac2.dts
@@ -80,30 +80,30 @@
 };
 
 &eth {
-        status = "okay";
+	status = "okay";
 
-        gmac0: mac@0 {
-                compatible = "mediatek,eth-mac";
-                reg = <0>;
-                phy-mode = "2500base-x";
+	gmac0: mac@0 {
+		compatible = "mediatek,eth-mac";
+		reg = <0>;
+		phy-mode = "2500base-x";
 
-                fixed-link {
-                        speed = <2500>;
-                        full-duplex;
-                        pause;
-                };
-        };
+		fixed-link {
+			speed = <2500>;
+			full-duplex;
+			pause;
+		};
+	};
 
-        gmac1: mac@1 {
-                compatible = "mediatek,eth-mac";
-                reg = <1>;
-                phy-mode = "2500base-x";
+	gmac1: mac@1 {
+		compatible = "mediatek,eth-mac";
+		reg = <1>;
+		phy-mode = "2500base-x";
 		phy-handle = <&phy5>;
-        };
+	};
 
-        mdio: mdio-bus {
-                #address-cells = <1>;
-                #size-cells = <0>;
+	mdio: mdio-bus {
+		#address-cells = <1>;
+		#size-cells = <0>;
 
 		reset-gpios = <&pio 14 1>;
 		reset-delay-us = <600>;
@@ -113,49 +113,94 @@
 			reg = <5>;
 		};
 
+		switch@31 {
+			compatible = "mediatek,mt7531";
+			reg = <31>;
+			reset-gpios = <&pio 39 0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
-                switch@0 {
-                        compatible = "mediatek,mt7531";
-                        reg = <31>;
-                        reset-gpios = <&pio 39 0>;
-                        ports {
-                                #address-cells = <1>;
-                                #size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					label = "lan1";
+				};
 
-                                port@0 {
-                                        reg = <0>;
-                                        label = "lan1";
-                                };
+				port@1 {
+					reg = <1>;
+					label = "lan2";
+				};
 
-                                port@1 {
-                                        reg = <1>;
-                                        label = "lan2";
-                                };
+				port@2 {
+					reg = <2>;
+					label = "lan3";
+				};
 
-                                port@2 {
-                                        reg = <2>;
-                                        label = "lan3";
-                                };
+				port@3 {
+					reg = <3>;
+					label = "lan4";
+				};
 
-                                port@3 {
-                                        reg = <3>;
-                                        label = "lan4";
-                                };
+				port@6 {
+					reg = <6>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "2500base-x";
 
-                                port@6 {
-                                        reg = <6>;
-                                        label = "cpu";
-                                        ethernet = <&gmac0>;
-                                        phy-mode = "2500base-x";
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+		};
+
+		switch@1 {
+			compatible = "airoha,an8855";
+			reg = <1>;
+			reset-gpios = <&pio 39 0>;
+			changesmiaddr = <6>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					label = "lan1";
+				};
 
-                                        fixed-link {
-                                                speed = <2500>;
-                                                full-duplex;
-                                                pause;
-                                        };
-                                };
-                        };
-                };
-        };
+				port@1 {
+					reg = <1>;
+					label = "lan2";
+				};
+
+				port@2 {
+					reg = <2>;
+					label = "lan3";
+				};
+
+				port@3 {
+					reg = <3>;
+					label = "lan4";
+				};
+
+				port@5 {
+					reg = <5>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "2500base-x";
+
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+		};
+	};
 };
 
 &hnat {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-gsw.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-gsw.dts
index cad1f45..c7f286d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-gsw.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-gsw.dts
@@ -101,12 +101,19 @@
 		};
 	};
 
-        gsw: gsw@0 {
-                compatible = "mediatek,mt753x";
-                mediatek,ethsys = <&ethsys>;
-                #address-cells = <1>;
-                #size-cells = <0>;
-        };
+	gsw_mt753x: gsw@0 {
+		compatible = "mediatek,mt753x";
+		mediatek,ethsys = <&ethsys>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	gsw_an8855: gsw@1 {
+		compatible = "airoha,an8855";
+		#mediatek,ethsys = <&ethsys>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
 };
 
 &afe {
@@ -135,67 +142,88 @@
 };
 
 &eth {
-        status = "okay";
+	status = "okay";
 
-        gmac0: mac@0 {
-                compatible = "mediatek,eth-mac";
-                reg = <0>;
-                phy-mode = "2500base-x";
+	gmac0: mac@0 {
+		compatible = "mediatek,eth-mac";
+		reg = <0>;
+		phy-mode = "2500base-x";
 
-                fixed-link {
-                        speed = <2500>;
-                        full-duplex;
-                        pause;
-                };
-        };
+		fixed-link {
+			speed = <2500>;
+			full-duplex;
+			pause;
+		};
+	};
 
-        gmac1: mac@1 {
-                compatible = "mediatek,eth-mac";
-                reg = <1>;
-                phy-mode = "gmii";
-                phy-handle = <&phy0>;
-        };
+	gmac1: mac@1 {
+		compatible = "mediatek,eth-mac";
+		reg = <1>;
+		phy-mode = "gmii";
+		phy-handle = <&phy0>;
+	};
 
-        mdio: mdio-bus {
-                #address-cells = <1>;
-                #size-cells = <0>;
+	mdio: mdio-bus {
+		#address-cells = <1>;
+		#size-cells = <0>;
 
-                phy0: ethernet-phy@0 {
-                        compatible = "ethernet-phy-id03a2.9461";
-                        reg = <0>;
-                        phy-mode = "gmii";
-                        nvmem-cells = <&phy_calibration>;
-                        nvmem-cell-names = "phy-cal-data";
-                };
+		phy0: ethernet-phy@0 {
+			compatible = "ethernet-phy-id03a2.9461";
+			reg = <0>;
+			phy-mode = "gmii";
+			nvmem-cells = <&phy_calibration>;
+			nvmem-cell-names = "phy-cal-data";
+		};
+	};
+};
 
-        };
+&gsw_mt753x {
+	mediatek,mdio = <&mdio>;
+	mediatek,portmap = "lllll";
+	mediatek,mdio_master_pinmux = <1>;
+	reset-gpios = <&pio 39 0>;
+	interrupt-parent = <&pio>;
+	interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
+	status = "okay";
+
+	port6: port@6 {
+		compatible = "mediatek,mt753x-port";
+		reg = <6>;
+		phy-mode = "sgmii";
+		fixed-link {
+			speed = <2500>;
+			full-duplex;
+		};
+	};
 };
 
-&gsw {
-        mediatek,mdio = <&mdio>;
-        mediatek,portmap = "llllw";
-        mediatek,mdio_master_pinmux = <1>;
-        reset-gpios = <&pio 39 0>;
-        interrupt-parent = <&pio>;
-        interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
-        status = "okay";
+&gsw_an8855 {
+	airoha,mdio = <&mdio>;
+	airoha,portmap = "lllll";
+	airoha,smi-addr = <6>;
+	reset-gpios = <&pio 39 0>;
+	interrupt-parent = <&pio>;
+	interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
+	status = "okay";
 
-        port6: port@6 {
-                compatible = "mediatek,mt753x-port";
-                reg = <6>;
-                phy-mode = "sgmii";
-                fixed-link {
-                        speed = <2500>;
-                        full-duplex;
-                };
-        };
+	port5: port@5 {
+		compatible = "airoha,an8855-port";
+		reg = <5>;
+		phy-mode = "2500base-x";
+		/* airoha,stag-on = <1>; */
+
+		fixed-link {
+			speed = <2500>;
+			full-duplex;
+		};
+	};
 };
 
 &hnat {
-        mtketh-wan = "eth1";
-        mtketh-lan = "eth0";
-        mtketh-max-gmac = <2>;
-        status = "okay";
+	mtketh-wan = "eth1";
+	mtketh-lan = "eth0";
+	mtketh-max-gmac = <2>;
+	status = "okay";
 };
 
 &spi0 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-rfb.dts
index 21e54f6..36d6ff6 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-rfb.dts
@@ -128,19 +128,19 @@
 };
 
 &eth {
-        status = "okay";
+	status = "okay";
 
-        gmac0: mac@0 {
-                compatible = "mediatek,eth-mac";
-                reg = <0>;
-                phy-mode = "2500base-x";
+	gmac0: mac@0 {
+		compatible = "mediatek,eth-mac";
+		reg = <0>;
+		phy-mode = "2500base-x";
 
-                fixed-link {
-                        speed = <2500>;
-                        full-duplex;
-                        pause;
-                };
-        };
+		fixed-link {
+			speed = <2500>;
+			full-duplex;
+			pause;
+		};
+	};
 
 	gmac1: mac@1 {
 		compatible = "mediatek,eth-mac";
@@ -149,9 +149,9 @@
 		phy-handle = <&phy0>;
 	};
 
-        mdio: mdio-bus {
-                #address-cells = <1>;
-                #size-cells = <0>;
+	mdio: mdio-bus {
+		#address-cells = <1>;
+		#size-cells = <0>;
 
 		phy0: ethernet-phy@0 {
 			compatible = "ethernet-phy-id03a2.9461";
@@ -161,50 +161,95 @@
 			nvmem-cell-names = "phy-cal-data";
 		};
 
-		switch@0 {
-                        compatible = "mediatek,mt7531";
-                        reg = <31>;
-                        reset-gpios = <&pio 39 0>;
+		switch@31 {
+			compatible = "mediatek,mt7531";
+			reg = <31>;
+			reset-gpios = <&pio 39 0>;
 
-                        ports {
-                                #address-cells = <1>;
-                                #size-cells = <0>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
 
-                                port@0 {
-                                        reg = <0>;
-                                        label = "lan1";
-                                };
+				port@0 {
+					reg = <0>;
+					label = "lan1";
+				};
 
-                                port@1 {
-                                        reg = <1>;
-                                        label = "lan2";
-                                };
+				port@1 {
+					reg = <1>;
+					label = "lan2";
+				};
 
-                                port@2 {
-                                        reg = <2>;
-                                        label = "lan3";
-                                };
+				port@2 {
+					reg = <2>;
+					label = "lan3";
+				};
 
-                                port@3 {
-                                        reg = <3>;
-                                        label = "lan4";
-                                };
+				port@3 {
+					reg = <3>;
+					label = "lan4";
+				};
 
-                                port@6 {
-                                        reg = <6>;
-                                        label = "cpu";
-                                        ethernet = <&gmac0>;
-                                        phy-mode = "2500base-x";
+				port@6 {
+					reg = <6>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "2500base-x";
 
-                                        fixed-link {
-                                                speed = <2500>;
-                                                full-duplex;
-                                                pause;
-                                        };
-                                };
-                        };
-                };
-        };
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+		};
+
+		switch@1 {
+			compatible = "airoha,an8855";
+			reg = <1>;
+			reset-gpios = <&pio 39 0>;
+			changesmiaddr = <6>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					label = "lan1";
+				};
+
+				port@1 {
+					reg = <1>;
+					label = "lan2";
+				};
+
+				port@2 {
+					reg = <2>;
+					label = "lan3";
+				};
+
+				port@3 {
+					reg = <3>;
+					label = "lan4";
+				};
+
+				port@5 {
+					reg = <5>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "2500base-x";
+
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+		};
+	};
 };
 
 &hnat {
@@ -245,6 +290,21 @@
 		reset_gpio = <&pio 15 0>;
 		ig,enable-spi = <1>;     /* 1: Enable, 0: Disable */
 	};
+
+	/* Reserved for SLB-9670 & SLB-9672 */
+	/*tpm_spi_tis@0 {
+		compatible = "infineon,slb9670";
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reset-gpios = <&pio 10 GPIO_ACTIVE_LOW>;
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <2>;
+		//spi-cal-data = /bits/ 8 <0x00 0x1b>; // For SLB-9670
+		spi-cal-data = /bits/ 8 <0x00 0x1d>; // For SLB-9672
+		spi-max-frequency = <32000000>;
+	};*/
 };
 
 &wbsys {
@@ -315,6 +375,25 @@
 			function = "spi";
 			groups = "spi1_1";
 		};
+
+		/* Reserved for SLB-9670 & SLB-9672 */
+		/*conf-8mA-pd {
+			pins = "SPI1_CS";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+		};
+
+		conf-14mA-pu {
+			pins = "SPI1_CLK";
+			drive-strength = <MTK_DRIVE_14mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_00>;
+		};
+
+		conf-8mA-pu {
+			pins = "SPI1_MOSI", "SPI1_MISO";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_00>;
+		};*/
 	};
 
 	uart1_pins: uart1-pins-g1 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-sfp.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-sfp.dts
index e0c1165..bdba620 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-sfp.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nand-sfp.dts
@@ -123,7 +123,7 @@
 		reset-gpios = <&pio 14 1>;
 		reset-delay-us = <600>;
 
-		switch@0 {
+		switch@31 {
 			compatible = "mediatek,mt7531";
 			reg = <31>;
 			reset-gpios = <&pio 39 0>;
@@ -165,6 +165,51 @@
 				};
 			};
 		};
+
+		switch@1 {
+			compatible = "airoha,an8855";
+			reg = <1>;
+			reset-gpios = <&pio 39 0>;
+			changesmiaddr = <6>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					label = "lan1";
+				};
+
+				port@1 {
+					reg = <1>;
+					label = "lan2";
+				};
+
+				port@2 {
+					reg = <2>;
+					label = "lan3";
+				};
+
+				port@3 {
+					reg = <3>;
+					label = "lan4";
+				};
+
+				port@5 {
+					reg = <5>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "2500base-x";
+
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+		};
 	};
 };
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts
index 3fa55a0..90823ab 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts
@@ -23,19 +23,19 @@
 };
 
 &eth {
-        status = "okay";
+	status = "okay";
 
-        gmac0: mac@0 {
-                compatible = "mediatek,eth-mac";
-                reg = <0>;
-                phy-mode = "2500base-x";
+	gmac0: mac@0 {
+		compatible = "mediatek,eth-mac";
+		reg = <0>;
+		phy-mode = "2500base-x";
 
-                fixed-link {
-                        speed = <2500>;
-                        full-duplex;
-                        pause;
-                };
-        };
+		fixed-link {
+			speed = <2500>;
+			full-duplex;
+			pause;
+		};
+	};
 
 	gmac1: mac@1 {
 		compatible = "mediatek,eth-mac";
@@ -44,9 +44,9 @@
 		phy-handle = <&phy0>;
 	};
 
-        mdio: mdio-bus {
-                #address-cells = <1>;
-                #size-cells = <0>;
+	mdio: mdio-bus {
+		#address-cells = <1>;
+		#size-cells = <0>;
 
 		phy0: ethernet-phy@0 {
 			compatible = "ethernet-phy-id03a2.9461";
@@ -56,50 +56,95 @@
 			nvmem-cell-names = "phy-cal-data";
 		};
 
+		switch@31 {
+			compatible = "mediatek,mt7531";
+			reg = <31>;
+			reset-gpios = <&pio 39 0>;
+
-		switch@0 {
-                        compatible = "mediatek,mt7531";
-                        reg = <31>;
-                        reset-gpios = <&pio 39 0>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
 
-                        ports {
-                                #address-cells = <1>;
-                                #size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					label = "lan1";
+				};
 
-                                port@0 {
-                                        reg = <0>;
-                                        label = "lan1";
-                                };
+				port@1 {
+					reg = <1>;
+					label = "lan2";
+				};
 
-                                port@1 {
-                                        reg = <1>;
-                                        label = "lan2";
-                                };
+				port@2 {
+					reg = <2>;
+					label = "lan3";
+				};
 
-                                port@2 {
-                                        reg = <2>;
-                                        label = "lan3";
-                                };
+				port@3 {
+					reg = <3>;
+					label = "lan4";
+				};
 
-                                port@3 {
-                                        reg = <3>;
-                                        label = "lan4";
-                                };
+				port@6 {
+					reg = <6>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "2500base-x";
 
-                                port@6 {
-                                        reg = <6>;
-                                        label = "cpu";
-                                        ethernet = <&gmac0>;
-                                        phy-mode = "2500base-x";
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+		};
+
+		switch@1 {
+			compatible = "airoha,an8855";
+			reg = <1>;
+			reset-gpios = <&pio 39 0>;
+			changesmiaddr = <6>;
 
-                                        fixed-link {
-                                                speed = <2500>;
-                                                full-duplex;
-                                                pause;
-                                        };
-                                };
-                        };
-                };
-        };
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					label = "lan1";
+				};
+
+				port@1 {
+					reg = <1>;
+					label = "lan2";
+				};
+
+				port@2 {
+					reg = <2>;
+					label = "lan3";
+				};
+
+				port@3 {
+					reg = <3>;
+					label = "lan4";
+				};
+
+				port@5 {
+					reg = <5>;
+					label = "cpu";
+					ethernet = <&gmac0>;
+					phy-mode = "2500base-x";
+
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+						pause;
+					};
+				};
+			};
+		};
+	};
 };
 
 &hnat {
@@ -208,7 +253,7 @@
 	};
 };
 
-&xhci {  
+&xhci {
         status = "okay";
 };
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-spim-nand-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-spim-nand-rfb.dts
index 5baa16e..45b0481 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-spim-nand-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-spim-nand-rfb.dts
@@ -193,6 +193,13 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <7>;
+		spi-cal-data = /bits/ 8 <
+			0x53 0x46 0x5F 0x42 0x4F 0x4F 0x54>; /* SF_BOOT */
+		spi-cal-addrlen = <1>;
+		spi-cal-addr = /bits/ 32 <0x0>;
 		reg = <0>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
@@ -203,6 +210,12 @@
 		#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 = <1>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-spim-nor-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-spim-nor-rfb.dts
index 8cd84b5..334989b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-spim-nor-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-spim-nor-rfb.dts
@@ -192,6 +192,13 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <7>;
+		spi-cal-data = /bits/ 8 <
+			0x53 0x46 0x5F 0x42 0x4F 0x4F 0x54>; /* SF_BOOT */
+		spi-cal-addrlen = <1>;
+		spi-cal-addr = /bits/ 32 <0x0>;
 		reg = <0>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-spim-nand-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-spim-nand-rfb.dts
index fe853e9..e3e8f48 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-spim-nand-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-spim-nand-rfb.dts
@@ -201,6 +201,13 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <7>;
+		spi-cal-data = /bits/ 8 <
+			0x53 0x46 0x5F 0x42 0x4F 0x4F 0x54>; /* SF_BOOT */
+		spi-cal-addrlen = <1>;
+		spi-cal-addr = /bits/ 32 <0x0>;
 		reg = <0>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
@@ -211,6 +218,12 @@
 		#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 = <1>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-spim-nor-rfb.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-spim-nor-rfb.dts
index cf85743..2a2c803 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-spim-nor-rfb.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-spim-nor-rfb.dts
@@ -201,6 +201,13 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
+		spi-cal-enable;
+		spi-cal-mode = "read-data";
+		spi-cal-datalen = <7>;
+		spi-cal-data = /bits/ 8 <
+			0x53 0x46 0x5F 0x42 0x4F 0x4F 0x54>; /* SF_BOOT */
+		spi-cal-addrlen = <1>;
+		spi-cal-addr = /bits/ 32 <0x0>;
 		reg = <0>;
 		spi-max-frequency = <52000000>;
 		spi-tx-bus-width = <4>;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/clk/mediatek/clk-mt7981.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/clk/mediatek/clk-mt7981.c
index 471fef3..81ec7fc 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/clk/mediatek/clk-mt7981.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/clk/mediatek/clk-mt7981.c
@@ -55,7 +55,7 @@
 	FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", "infra_spi1_sel", 1, 1),

 	FACTOR(CK_INFRA_MUX_SPI2, "infra_mux_spi2", "infra_spi2_sel", 1, 1),

 	FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", "cb_rtc_32k", 1, 1),

-	FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", "emmc_400m", 1, 1),

+	FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", "emmc_208m", 1, 1),

 	FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", "emmc_208m", 1, 1),

 	FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", "sysaxi", 1, 1),

 	FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", "sysaxi", 1, 1),

diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
index ab2e4f5..fca5e3e 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
@@ -141,8 +141,6 @@
 		mt7530_mdio_w32(eth, MTK_MT753X_PMCR_P(i), val);
 	}
 	mt798x_iounmap();
-
-	return;
 }
 
 void mtk_switch_w32(struct mtk_eth *eth, u32 val, unsigned reg)
@@ -1476,7 +1474,7 @@
 
 	for (i = 0; i < MTK_RSS_MAX_INDIRECTION_TABLE / 16; i++)
 		mtk_w32(eth, mtk_rss_indr_table(rss_params, i),
-			MTK_RSS_INDR_TABLE_DW(i));
+			eth->soc->reg_map->pdma.rss_indr_table_dw0 + (i * 0x4));
 
 	return 0;
 }
@@ -1838,49 +1836,67 @@
 
 int hwlro_agg_cnt_ctrl(int cnt)
 {
+	struct mtk_eth *eth = g_eth;
 	int i;
 
+	for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
+		int idx = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2) ? i : i + 1;
+
-	for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++)
-		SET_PDMA_RXRING_MAX_AGG_CNT(g_eth, i, cnt);
+		SET_PDMA_RXRING_MAX_AGG_CNT(eth, idx, cnt);
+	}
 
 	return 0;
 }
 
 int hwlro_agg_time_ctrl(int time)
 {
+	struct mtk_eth *eth = g_eth;
 	int i;
 
+	for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
+		int idx = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2) ? i : i + 1;
+
-	for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++)
-		SET_PDMA_RXRING_AGG_TIME(g_eth, i, time);
+		SET_PDMA_RXRING_AGG_TIME(eth, idx, time);
+	}
 
 	return 0;
 }
 
 int hwlro_age_time_ctrl(int time)
 {
+	struct mtk_eth *eth = g_eth;
 	int i;
 
+	for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
+		int idx = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2) ? i : i + 1;
+
-	for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++)
-		SET_PDMA_RXRING_AGE_TIME(g_eth, i, time);
+		SET_PDMA_RXRING_AGE_TIME(eth, idx, time);
+	}
 
 	return 0;
 }
 
 int hwlro_threshold_ctrl(int bandwidth)
 {
-	SET_PDMA_LRO_BW_THRESHOLD(g_eth, bandwidth);
+	struct mtk_eth *eth = g_eth;
+
+	SET_PDMA_LRO_BW_THRESHOLD(eth, bandwidth);
 
 	return 0;
 }
 
 int hwlro_ring_enable_ctrl(int enable)
 {
+	struct mtk_eth *eth = g_eth;
 	int i;
 
 	pr_info("[%s] %s HW LRO rings\n", __func__, (enable) ? "Enable" : "Disable");
 
-	for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++)
-		SET_PDMA_RXRING_VALID(g_eth, i, enable);
+	for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
+		int idx = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2) ? i : i + 1;
+
+		SET_PDMA_RXRING_VALID(eth, idx, enable);
+	}
 
 	return 0;
 }
@@ -1942,29 +1958,30 @@
 
 void hw_lro_auto_tlb_dump_v1(struct seq_file *seq, u32 index)
 {
-	int i;
+	struct mtk_eth *eth = g_eth;
 	struct mtk_lro_alt_v1 alt;
 	__be32 addr;
 	u32 tlb_info[9];
 	u32 dw_len, cnt, priority;
 	u32 entry;
+	int i;
 
 	if (index > 4)
 		index = index - 1;
 	entry = (index * 9) + 1;
 
 	/* read valid entries of the auto-learn table */
-	mtk_w32(g_eth, entry, MTK_FE_ALT_CF8);
+	mtk_w32(eth, entry, MTK_FE_ALT_CF8);
 
 	for (i = 0; i < 9; i++)
-		tlb_info[i] = mtk_r32(g_eth, MTK_FE_ALT_SEQ_CFC);
+		tlb_info[i] = mtk_r32(eth, MTK_FE_ALT_SEQ_CFC);
 
 	memcpy(&alt, tlb_info, sizeof(struct mtk_lro_alt_v1));
 
 	dw_len = alt.alt_info7.dw_len;
 	cnt = alt.alt_info6.cnt;
 
-	if (mtk_r32(g_eth, MTK_PDMA_LRO_CTRL_DW0) & MTK_LRO_ALT_PKT_CNT_MODE)
+	if (mtk_r32(eth, eth->soc->reg_map->pdma.lro_ctrl_dw0) & MTK_LRO_ALT_PKT_CNT_MODE)
 		priority = cnt;		/* packet count */
 	else
 		priority = dw_len;	/* byte count */
@@ -2000,21 +2017,22 @@
 
 void hw_lro_auto_tlb_dump_v2(struct seq_file *seq, u32 index)
 {
-	int i;
+	struct mtk_eth *eth = g_eth;
 	struct mtk_lro_alt_v2 alt;
 	u32 score = 0, ipv4 = 0;
 	u32 ipv6[4] = { 0 };
 	u32 tlb_info[12];
+	int i;
 
 	/* read valid entries of the auto-learn table */
-	mtk_w32(g_eth, index << MTK_LRO_ALT_INDEX_OFFSET, MTK_LRO_ALT_DBG);
+	mtk_w32(eth, index << MTK_LRO_ALT_INDEX_OFFSET, eth->soc->reg_map->pdma.lro_alt_dbg);
 
 	for (i = 0; i < 11; i++)
-		tlb_info[i] = mtk_r32(g_eth, MTK_LRO_ALT_DBG_DATA);
+		tlb_info[i] = mtk_r32(eth, eth->soc->reg_map->pdma.lro_alt_dbg_data);
 
 	memcpy(&alt, tlb_info, sizeof(struct mtk_lro_alt_v2));
 
-	if (mtk_r32(g_eth, MTK_PDMA_LRO_CTRL_DW0) & MTK_LRO_ALT_PKT_CNT_MODE)
+	if (mtk_r32(eth, eth->soc->reg_map->pdma.lro_ctrl_dw0) & MTK_LRO_ALT_PKT_CNT_MODE)
 		score = 1;	/* packet count */
 	else
 		score = 0;	/* byte count */
@@ -2070,6 +2088,8 @@
 
 int hw_lro_auto_tlb_read(struct seq_file *seq, void *v)
 {
+	struct mtk_eth *eth = g_eth;
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;
 	int i;
 	u32 reg_val;
 	u32 reg_op1, reg_op2, reg_op3, reg_op4;
@@ -2085,13 +2105,13 @@
 	seq_puts(seq, "[4] = hwlro_ring_enable_ctrl\n");
 	seq_puts(seq, "[5] = hwlro_stats_enable_ctrl\n\n");
 
-	if (MTK_HAS_CAPS(g_eth->soc->caps, MTK_NETSYS_RX_V2)) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) {
 		for (i = 1; i <= 8; i++)
 			hw_lro_auto_tlb_dump_v2(seq, i);
 	} else {
 		/* Read valid entries of the auto-learn table */
-		mtk_w32(g_eth, 0, MTK_FE_ALT_CF8);
-		reg_val = mtk_r32(g_eth, MTK_FE_ALT_SEQ_CFC);
+		mtk_w32(eth, 0, MTK_FE_ALT_CF8);
+		reg_val = mtk_r32(eth, MTK_FE_ALT_SEQ_CFC);
 
 		seq_printf(seq,
 			   "HW LRO Auto-learn Table: (MTK_FE_ALT_SEQ_CFC=0x%x)\n",
@@ -2106,11 +2126,13 @@
 	/* Read the agg_time/age_time/agg_cnt of LRO rings */
 	seq_puts(seq, "\nHW LRO Ring Settings\n");
 
-	for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) {
-		reg_op1 = mtk_r32(g_eth, MTK_LRO_CTRL_DW1_CFG(i));
-		reg_op2 = mtk_r32(g_eth, MTK_LRO_CTRL_DW2_CFG(i));
-		reg_op3 = mtk_r32(g_eth, MTK_LRO_CTRL_DW3_CFG(i));
-		reg_op4 = mtk_r32(g_eth, MTK_PDMA_LRO_CTRL_DW2);
+	for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
+		int idx = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2) ? i : i + 1;
+
+		reg_op1 = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 + 0x4 + (idx * 0x40));
+		reg_op2 = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 + 0x8 + (idx * 0x40));
+		reg_op3 = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 + 0xc + (idx * 0x40));
+		reg_op4 = mtk_r32(eth, reg_map->pdma.lro_ctrl_dw0 + 0x8);
 
 		agg_cnt =
 		    ((reg_op3 & 0x3) << 6) |
@@ -2121,9 +2143,7 @@
 		    ((reg_op1 >> MTK_LRO_RING_AGE_TIME_L_OFFSET) & 0x3ff);
 		seq_printf(seq,
 			   "Ring[%d]: MAX_AGG_CNT=%d, AGG_TIME=%d, AGE_TIME=%d, Threshold=%d\n",
-			   !(MTK_HAS_CAPS(g_eth->soc->caps, MTK_NETSYS_RX_V2)) ?
-			   i : i+3,
-			   agg_cnt, agg_time, age_time, reg_op4);
+			   MTK_HW_LRO_RING(i), agg_cnt, agg_time, age_time, reg_op4);
 	}
 
 	seq_puts(seq, "\n");
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
index 9f477bf..5fba9b5 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
@@ -161,51 +161,68 @@
 
 #define SET_PDMA_RXRING_MAX_AGG_CNT(eth, x, y)				\
 {									\
-	u32 reg_val1 = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x));		\
-	u32 reg_val2 = mtk_r32(eth, MTK_LRO_CTRL_DW3_CFG(x));		\
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;		\
+	u32 reg_val1 = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 +	\
+				    0x8 + (x * 0x40));			\
+	u32 reg_val2 = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 +	\
+				    0xc + (x * 0x40));			\
 	reg_val1 &= ~MTK_LRO_RING_AGG_CNT_L_MASK;			\
 	reg_val2 &= ~MTK_LRO_RING_AGG_CNT_H_MASK;			\
 	reg_val1 |= ((y) & 0x3f) << MTK_LRO_RING_AGG_CNT_L_OFFSET;	\
 	reg_val2 |= (((y) >> 6) & 0x03) <<				\
 		     MTK_LRO_RING_AGG_CNT_H_OFFSET;			\
-	mtk_w32(eth, reg_val1, MTK_LRO_CTRL_DW2_CFG(x));		\
-	mtk_w32(eth, reg_val2, MTK_LRO_CTRL_DW3_CFG(x));		\
+	mtk_w32(eth, reg_val1, reg_map->pdma.lro_rx_ctrl_dw0 +		\
+			       0x8 + (x * 0x40));			\
+	mtk_w32(eth, reg_val2, reg_map->pdma.lro_rx_ctrl_dw0 +		\
+			       0xc + (x * 0x40));			\
 }
 
 #define SET_PDMA_RXRING_AGG_TIME(eth, x, y)				\
 {									\
-	u32 reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x));		\
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;		\
+	u32 reg_val = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 +	\
+				   0x8 + (x * 0x40));			\
 	reg_val &= ~MTK_LRO_RING_AGG_TIME_MASK;				\
 	reg_val |= ((y) & 0xffff) << MTK_LRO_RING_AGG_TIME_OFFSET;	\
-	mtk_w32(eth, reg_val, MTK_LRO_CTRL_DW2_CFG(x));			\
+	mtk_w32(eth, reg_val, reg_map->pdma.lro_rx_ctrl_dw0 +		\
+			      0x8 + (x * 0x40));		\
 }
 
 #define SET_PDMA_RXRING_AGE_TIME(eth, x, y)				\
 {									\
-	u32 reg_val1 = mtk_r32(eth, MTK_LRO_CTRL_DW1_CFG(x));		\
-	u32 reg_val2 = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x));		\
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;		\
+	u32 reg_val1 = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 +	\
+				    0x4 + (x * 0x40));			\
+	u32 reg_val2 = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 +	\
+				    0x8 + (x * 0x40));			\
 	reg_val1 &= ~MTK_LRO_RING_AGE_TIME_L_MASK;			\
 	reg_val2 &= ~MTK_LRO_RING_AGE_TIME_H_MASK;			\
 	reg_val1 |= ((y) & 0x3ff) << MTK_LRO_RING_AGE_TIME_L_OFFSET;	\
 	reg_val2 |= (((y) >> 10) & 0x03f) <<				\
 		     MTK_LRO_RING_AGE_TIME_H_OFFSET;			\
-	mtk_w32(eth, reg_val1, MTK_LRO_CTRL_DW1_CFG(x));		\
-	mtk_w32(eth, reg_val2, MTK_LRO_CTRL_DW2_CFG(x));		\
+	mtk_w32(eth, reg_val1, reg_map->pdma.lro_rx_ctrl_dw0 +		\
+			       0x4 + (x * 0x40));			\
+	mtk_w32(eth, reg_val2, reg_map->pdma.lro_rx_ctrl_dw0 +		\
+			       0x8 + (x * 0x40));			\
 }
 
 #define SET_PDMA_LRO_BW_THRESHOLD(eth, x)				\
 {									\
-	u32 reg_val = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW2);		\
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;		\
+	u32 reg_val = mtk_r32(eth, reg_map->pdma.lro_ctrl_dw0 + 0x8);	\
 	reg_val = (x);							\
-	mtk_w32(eth, reg_val, MTK_PDMA_LRO_CTRL_DW2);			\
+	mtk_w32(eth, reg_val, reg_map->pdma.lro_ctrl_dw0 + 0x8);	\
 }
 
 #define SET_PDMA_RXRING_VALID(eth, x, y)				\
 {									\
-	u32 reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x));		\
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;		\
+	u32 reg_val = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 +	\
+				   0x8 + (x * 0x40));			\
 	reg_val &= ~(0x1 << MTK_RX_PORT_VALID_OFFSET);			\
 	reg_val |= ((y) & 0x1) << MTK_RX_PORT_VALID_OFFSET;		\
-	mtk_w32(eth, reg_val, MTK_LRO_CTRL_DW2_CFG(x));			\
+	mtk_w32(eth, reg_val, reg_map->pdma.lro_rx_ctrl_dw0 +		\
+			      0x8 + (x * 0x40));			\
 }
 
 struct mtk_pse_fs_lgc_info_v2 {
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 06d03fc..df23ae3 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
@@ -227,7 +227,8 @@
 	struct mtk_eth *eth = _eth;
 	u32 id = 0;
 
-	mtk_dump_reg(eth, "FE", 0x0, 0x500);
+	mtk_dump_reg(eth, "FE", 0x0, 0x600);
+	mtk_dump_reg(eth, "FE", 0x1400, 0x300);
 	mtk_dump_reg(eth, "ADMA", PDMA_BASE, 0x300);
 	for (id = 0; id < MTK_QDMA_PAGE_NUM; id++){
 		mtk_w32(eth, id, MTK_QDMA_PAGE);
@@ -237,7 +238,11 @@
 	}
 	mtk_dump_reg(eth, "QDMA", MTK_QRX_BASE_PTR0, 0x300);
 	mtk_dump_reg(eth, "WDMA", WDMA_BASE(0), 0x600);
-	mtk_dump_reg(eth, "PPE", 0x2200, 0x200);
+	mtk_dump_reg(eth, "PPE0", PPE_BASE(0), 0x200);
+	if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
+		mtk_dump_reg(eth, "PPE1", PPE_BASE(1), 0x200);
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+		mtk_dump_reg(eth, "PPE2", PPE_BASE(2), 0x200);
 	mtk_dump_reg(eth, "GMAC", 0x10000, 0x300);
 	mtk_dump_regmap(eth->sgmii->pcs[0].regmap,
 			"SGMII0", 0, 0x1a0);
@@ -594,16 +599,15 @@
 	static u32 gdm_cnt[MTK_MAX_DEVS];
 	static u32 pre_fsm[MTK_MAX_DEVS];
 	static u32 pre_ipq[MTK_MAX_DEVS];
-	u32 mib_base = MTK_GDM1_TX_GBCNT;
-	u32 gmac_rxcnt[MTK_MAX_DEVS];
+	static u32 gmac_rxcnt[MTK_MAX_DEVS];
 	u32 is_gmac_rx[MTK_MAX_DEVS];
 	u32 cur_fsm, pse_ipq, err_flag = 0, i;
 
 	for (i = 0; i < MTK_MAX_DEVS; i++) {
+		struct mtk_hw_stats *hw_stats = eth->mac[i]->hw_stats;
+
 		is_gmac_rx[i] = (mtk_r32(eth, MTK_MAC_FSM(i)) & 0xFF0000) != 0x10000;
-		gmac_rxcnt[i] =
-			mtk_r32(eth, mib_base + MTK_GDM_RX_BASE + i * MTK_GDM_CNT_OFFSET);
-		if (is_gmac_rx[i] && (gmac_rxcnt[i] == 0))
+		if (is_gmac_rx[i] && gmac_rxcnt[i] == hw_stats->rx_packets)
 			gmac_cnt[i]++;
 		if (gmac_cnt[i] > 4) {
 			pr_info("GMAC%d Rx Info\n", i+1);
@@ -613,6 +617,8 @@
 			err_flag = 1;
 		} else
 			gmac_cnt[i] = 0;
+
+		gmac_rxcnt[i] = hw_stats->rx_packets;
 	}
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
@@ -658,20 +664,16 @@
 {
 	static u32 err_cnt[MTK_MAX_DEVS];
 	static u32 pre_gdm[MTK_MAX_DEVS];
-	static u32 pre_opq[MTK_WDMA_CNT];
-	static u32 pre_txcnt[MTK_WDMA_CNT];
+	static u32 pre_opq[MTK_MAX_DEVS];
 	static u32 gdm_err_cnt[MTK_MAX_DEVS];
-	u32 gdm_fsm = 0;
-	u32 mib_base = MTK_GDM1_TX_GBCNT;
-	u32 gmac_txcnt[MTK_MAX_DEVS];
+	static u32 gmac_txcnt[MTK_MAX_DEVS];
 	u32 is_gmac_tx[MTK_MAX_DEVS];
+	u32 gdm_fsm = 0;
 	u32 err_flag = 0, i, pse_opq;
 
 	for (i = 0; i < MTK_MAX_DEVS; i++) {
-		is_gmac_tx[i] =
-			(mtk_r32(eth, MTK_MAC_FSM(i)) & 0xFF000000) != 0x1000000;
-		gmac_txcnt[i] =
-			mtk_r32(eth, mib_base + MTK_GDM_TX_BASE + i * MTK_GDM_CNT_OFFSET);
+		struct mtk_hw_stats *hw_stats = eth->mac[i]->hw_stats;
+
 		if (i == 0)
 			pse_opq = (mtk_r32(eth, MTK_PSE_OQ_STA(0)) >> 16) & 0xFFF;
 		else if (i == 1)
@@ -679,7 +681,8 @@
 		else
 			pse_opq = (mtk_r32(eth, MTK_PSE_OQ_STA(7)) >> 16) & 0xFFF;
 
-		if (is_gmac_tx[i] && (gmac_txcnt[i] == 0) && (pse_opq > 0))
+		is_gmac_tx[i] = (mtk_r32(eth, MTK_MAC_FSM(i)) & 0xFF000000) != 0x1000000;
+		if (is_gmac_tx[i] && gmac_txcnt[i] == hw_stats->tx_packets && pse_opq > 0)
 			err_cnt[i]++;
 		if (err_cnt[i] > 4) {
 			pr_info("GMAC%d Tx Info\n", i+1);
@@ -689,13 +692,13 @@
 			err_flag = 1;
 		} else
 			err_cnt[i] = 0;
+
+		gmac_txcnt[i] = hw_stats->tx_packets;
 	}
 
 	for (i = 0; i < MTK_MAX_DEVS; i++) {
 		gdm_fsm = mtk_r32(eth, MTK_FE_GDM_FSM(i)) & 0x1FFF0000;
 		pse_opq = MTK_FE_GDM_OQ(i);
-		pre_txcnt[i] =
-			mtk_r32(eth, mib_base + MTK_GDM_TX_BASE + i * MTK_GDM_CNT_OFFSET);
 		if ((pre_gdm[i] == gdm_fsm) && (gdm_fsm == 0x10330000) &&
 		    (pre_opq[i] == pse_opq) && (pse_opq > 0))
 			gdm_err_cnt[i]++;
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 fab0526..8971a7f 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
@@ -61,6 +61,11 @@
 		.irq_mask	= 0x0a28,
 		.int_grp	= 0x0a50,
 		.int_grp2	= 0x0a54,
+		.lro_ctrl_dw0	= 0x0980,
+		.lro_alt_score_delta	= 0x0a4c,
+		.lro_rx_dly_int	= 0x0a70,
+		.lro_rx_dip_dw0	= 0x0b04,
+		.lro_rx_ctrl_dw0	= 0x0b24,
 	},
 	.qdma = {
 		.qtx_cfg	= 0x1800,
@@ -114,6 +119,11 @@
 		.irq_mask	= 0x0a28,
 		.int_grp	= 0x0a50,
 		.int_grp2	= 0x0a54,
+		.lro_ctrl_dw0	= 0x0980,
+		.lro_alt_score_delta	= 0x0a4c,
+		.lro_rx_dly_int	= 0x0a70,
+		.lro_rx_dip_dw0	= 0x0b04,
+		.lro_rx_ctrl_dw0	= 0x0b24,
 	},
 };
 
@@ -135,6 +145,14 @@
 		.irq_mask	= 0x4228,
 		.int_grp	= 0x4250,
 		.int_grp2	= 0x4254,
+		.lro_ctrl_dw0	= 0x4180,
+		.lro_alt_score_delta	= 0x424c,
+		.lro_rx_dly_int	= 0x4270,
+		.lro_rx_dip_dw0	= 0x4304,
+		.lro_rx_ctrl_dw0	= 0x4324,
+		.rss_glo_cfg    = 0x2800,
+		.rss_hash_key_dw0	= 0x2820,
+		.rss_indr_table_dw0	= 0x2850,
 	},
 	.qdma = {
 		.qtx_cfg	= 0x4400,
@@ -185,10 +203,20 @@
 		.glo_cfg	= 0x6a04,
 		.rst_idx	= 0x6a08,
 		.delay_irq	= 0x6a0c,
+		.rx_cfg		= 0x6a10,
 		.irq_status	= 0x6a20,
 		.irq_mask	= 0x6a28,
 		.int_grp	= 0x6a50,
 		.int_grp2	= 0x6a54,
+		.lro_ctrl_dw0	= 0x6c08,
+		.lro_alt_score_delta	= 0x6c1c,
+		.lro_alt_dbg	= 0x6c40,
+		.lro_alt_dbg_data	= 0x6c44,
+		.lro_rx_dip_dw0	= 0x6c54,
+		.lro_rx_ctrl_dw0	= 0x6c74,
+		.rss_glo_cfg	= 0x7000,
+		.rss_hash_key_dw0	= 0x7020,
+		.rss_indr_table_dw0	= 0x7050,
 	},
 	.qdma = {
 		.qtx_cfg	= 0x4400,
@@ -1699,7 +1727,6 @@
 	dma_addr_t phy_ring_tail;
 	int cnt = soc->txrx.fq_dma_size;
 	dma_addr_t dma_addr;
-	u64 addr64 = 0;
 	int i, j, len;
 
 	if (!eth->soc->has_sram) {
@@ -1739,10 +1766,10 @@
 				txd->txd2 = eth->phy_scratch_ring +
 					(j * MTK_FQ_DMA_LENGTH + i + 1) * soc->txrx.txd_size;
 
-			addr64 = (MTK_HAS_CAPS(eth->soc->caps, MTK_8GB_ADDRESSING)) ?
-				  TX_DMA_SDP1(dma_addr + i * MTK_QDMA_PAGE_SIZE) : 0;
+			txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
+			if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
+				txd->txd3 |= TX_DMA_PREP_ADDR64(dma_addr + i * MTK_QDMA_PAGE_SIZE);
 
-			txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE) | addr64;
 			txd->txd4 = 0;
 
 			if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
@@ -1839,8 +1866,8 @@
 		dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr);
 		dma_unmap_len_set(tx_buf, dma_len0, size);
 	} else {
-		addr64 = (MTK_HAS_CAPS(eth->soc->caps, MTK_8GB_ADDRESSING)) ?
-			  TX_DMA_SDP1(mapped_addr) : 0;
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
+			addr64 = TX_DMA_PREP_ADDR64(mapped_addr);
 
 		if (idx & 1) {
 			txd->txd3 = mapped_addr;
@@ -1957,18 +1984,18 @@
 	struct mtk_mac *mac = netdev_priv(dev);
 	struct mtk_eth *eth = mac->hw;
 	struct mtk_tx_dma_v2 *desc = txd;
-	u64 addr64 = 0;
 	u32 data = 0;
 
-	addr64 = (MTK_HAS_CAPS(eth->soc->caps, MTK_8GB_ADDRESSING)) ?
-		  TX_DMA_SDP1(info->addr) : 0;
-
 	WRITE_ONCE(desc->txd1, info->addr);
 
 	data = TX_DMA_PLEN0(info->size);
 	if (info->last)
 		data |= TX_DMA_LS0;
-	WRITE_ONCE(desc->txd3, data | addr64);
+
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
+		data |= TX_DMA_PREP_ADDR64(info->addr);
+
+	WRITE_ONCE(desc->txd3, data);
 
 	data = ((mac->id == MTK_GMAC3_ID) ?
 		PSE_GDM3_PORT : (mac->id + 1)) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
@@ -2227,7 +2254,7 @@
 	return -ENOMEM;
 }
 
-static inline int mtk_cal_txd_req(struct sk_buff *skb)
+static inline int mtk_cal_txd_req(struct mtk_eth *eth, struct sk_buff *skb)
 {
 	int i, nfrags;
 	skb_frag_t *frag;
@@ -2237,7 +2264,7 @@
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 			frag = &skb_shinfo(skb)->frags[i];
 			nfrags += DIV_ROUND_UP(skb_frag_size(frag),
-						MTK_TX_DMA_BUF_LEN);
+					       eth->soc->txrx.dma_max_len);
 		}
 	} else {
 		nfrags += skb_shinfo(skb)->nr_frags;
@@ -2314,7 +2341,7 @@
 		txq = netdev_get_tx_queue(dev, qid);
 	}
 
-	tx_num = mtk_cal_txd_req(skb);
+	tx_num = mtk_cal_txd_req(eth, skb);
 	if (unlikely(atomic_read(&ring->free_count) <= tx_num)) {
 		if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
 			netif_tx_stop_all_queues(dev);
@@ -2444,8 +2471,8 @@
 			goto release_desc;
 		}
 
-		addr64 = (MTK_HAS_CAPS(eth->soc->caps, MTK_8GB_ADDRESSING)) ?
-			  ((u64)(trxd.rxd2 & 0xf)) << 32 : 0;
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
+			addr64 = RX_DMA_GET_ADDR64(trxd.rxd2);
 
 		dma_unmap_single(eth->dma_dev,
 				 ((u64)(trxd.rxd1) | addr64),
@@ -2532,11 +2559,11 @@
 		rxd->rxd1 = (unsigned int)dma_addr;
 
 release_desc:
-		if (MTK_HAS_CAPS(eth->soc->caps, MTK_8GB_ADDRESSING)) {
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
 			if (unlikely(dma_addr == DMA_MAPPING_ERROR))
-				addr64 = RX_DMA_GET_SDP1(rxd->rxd2);
+				addr64 = FIELD_GET(RX_DMA_ADDR64_MASK, rxd->rxd2);
 			else
-				addr64 = RX_DMA_SDP1(dma_addr);
+				addr64 = RX_DMA_PREP_ADDR64(dma_addr);
 		}
 
 		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
@@ -2952,7 +2979,6 @@
 	struct mtk_rx_ring *ring;
 	int rx_data_len, rx_dma_size;
 	int i;
-	u64 addr64 = 0;
 
 	if (rx_flag == MTK_RX_FLAGS_QDMA) {
 		if (ring_no)
@@ -3024,13 +3050,13 @@
 		rxd = ring->dma + i * eth->soc->txrx.rxd_size;
 		rxd->rxd1 = (unsigned int)dma_addr;
 
-		addr64 = (MTK_HAS_CAPS(eth->soc->caps, MTK_8GB_ADDRESSING)) ?
-			  RX_DMA_SDP1(dma_addr) : 0;
-
 		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
 			rxd->rxd2 = RX_DMA_LSO;
 		else
-			rxd->rxd2 = RX_DMA_PLEN0(ring->buf_size) | addr64;
+			rxd->rxd2 = RX_DMA_PLEN0(ring->buf_size);
+
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
+			rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
 
 		rxd->rxd3 = 0;
 		rxd->rxd4 = 0;
@@ -3093,9 +3119,8 @@
 			if (!rxd->rxd1)
 				continue;
 
-			addr64 = (MTK_HAS_CAPS(eth->soc->caps,
-					       MTK_8GB_ADDRESSING)) ?
-				  ((u64)(rxd->rxd2 & 0xf)) << 32 : 0;
+			if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
+				addr64 = RX_DMA_GET_ADDR64(rxd->rxd2);
 
 			dma_unmap_single(eth->dma_dev,
 					 ((u64)(rxd->rxd1) | addr64),
@@ -3121,6 +3146,7 @@
 
 static int mtk_hwlro_rx_init(struct mtk_eth *eth)
 {
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;
 	int i;
 	u32 val;
 	u32 ring_ctrl_dw1 = 0, ring_ctrl_dw2 = 0, ring_ctrl_dw3 = 0;
@@ -3143,10 +3169,15 @@
 	ring_ctrl_dw2 |= MTK_RING_MAX_AGG_CNT_L;
 	ring_ctrl_dw3 |= MTK_RING_MAX_AGG_CNT_H;
 
-	for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) {
-		mtk_w32(eth, ring_ctrl_dw1, MTK_LRO_CTRL_DW1_CFG(i));
-		mtk_w32(eth, ring_ctrl_dw2, MTK_LRO_CTRL_DW2_CFG(i));
-		mtk_w32(eth, ring_ctrl_dw3, MTK_LRO_CTRL_DW3_CFG(i));
+	for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
+		int idx = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2) ? i : i + 1;
+
+		mtk_w32(eth, ring_ctrl_dw1,
+			reg_map->pdma.lro_rx_ctrl_dw0 + 0x4 + (idx * 0x40));
+		mtk_w32(eth, ring_ctrl_dw2,
+			reg_map->pdma.lro_rx_ctrl_dw0 + 0x8 + (idx * 0x40));
+		mtk_w32(eth, ring_ctrl_dw3,
+			reg_map->pdma.lro_rx_ctrl_dw0 + 0xc + (idx * 0x40));
 	}
 
 	/* IPv4 checksum update enable */
@@ -3156,10 +3187,10 @@
 	lro_ctrl_dw0 |= MTK_LRO_ALT_PKT_CNT_MODE;
 
 	/* bandwidth threshold setting */
-	mtk_w32(eth, MTK_HW_LRO_BW_THRE, MTK_PDMA_LRO_CTRL_DW2);
+	mtk_w32(eth, MTK_HW_LRO_BW_THRE, reg_map->pdma.lro_ctrl_dw0 + 0x8);
 
 	/* auto-learn score delta setting */
-	mtk_w32(eth, MTK_HW_LRO_REPLACE_DELTA, MTK_LRO_ALT_SCORE_DELTA);
+	mtk_w32(eth, MTK_HW_LRO_REPLACE_DELTA, reg_map->pdma.lro_alt_score_delta);
 
 	/* set refresh timer for altering flows to 1 sec. (unit: 20us) */
 	mtk_w32(eth, (MTK_HW_LRO_TIMER_UNIT << 16) | MTK_HW_LRO_REFRESH_TIME,
@@ -3169,9 +3200,9 @@
 	lro_ctrl_dw3 |= MTK_LRO_MIN_RXD_SDL;
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) {
-		val = mtk_r32(eth, MTK_PDMA_RX_CFG);
+		val = mtk_r32(eth, reg_map->pdma.rx_cfg);
 		mtk_w32(eth, val | (MTK_PDMA_LRO_SDL << MTK_RX_CFG_SDL_OFFSET),
-			MTK_PDMA_RX_CFG);
+			reg_map->pdma.rx_cfg);
 
 		lro_ctrl_dw0 |= MTK_PDMA_LRO_SDL << MTK_CTRL_DW0_SDL_OFFSET;
 	} else {
@@ -3185,37 +3216,36 @@
 	/* enable cpu reason black list */
 	lro_ctrl_dw0 |= MTK_LRO_CRSN_BNW;
 
-	mtk_w32(eth, lro_ctrl_dw3, MTK_PDMA_LRO_CTRL_DW3);
-	mtk_w32(eth, lro_ctrl_dw0, MTK_PDMA_LRO_CTRL_DW0);
+	mtk_w32(eth, lro_ctrl_dw3, reg_map->pdma.lro_ctrl_dw0 + 0xc);
+	mtk_w32(eth, lro_ctrl_dw0, reg_map->pdma.lro_ctrl_dw0);
 
 	/* no use PPE cpu reason */
-	mtk_w32(eth, 0xffffffff, MTK_PDMA_LRO_CTRL_DW1);
+	mtk_w32(eth, 0xffffffff, reg_map->pdma.lro_ctrl_dw0 + 0x4);
 
 	/* Set perLRO GRP INT */
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2) ||
-	    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-		mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(1)),
-			MTK_RX_DONE_INT(MTK_HW_LRO_RING(1)), MTK_PDMA_INT_GRP1);
-		mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(2)),
-			MTK_RX_DONE_INT(MTK_HW_LRO_RING(2)), MTK_PDMA_INT_GRP2);
-		mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(3)),
-			MTK_RX_DONE_INT(MTK_HW_LRO_RING(3)), MTK_PDMA_INT_GRP3);
-	}
+	i = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2) ? 1 : 0;
+	mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(i)),
+		MTK_RX_DONE_INT(MTK_HW_LRO_RING(i)), MTK_PDMA_INT_GRP1);
+	mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(i + 1)),
+		MTK_RX_DONE_INT(MTK_HW_LRO_RING(i + 1)), MTK_PDMA_INT_GRP2);
+	mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(i + 2)),
+		MTK_RX_DONE_INT(MTK_HW_LRO_RING(i + 2)), MTK_PDMA_INT_GRP3);
 
 	return 0;
 }
 
 static void mtk_hwlro_rx_uninit(struct mtk_eth *eth)
 {
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;
 	int i;
 	u32 val;
 
 	/* relinquish lro rings, flush aggregated packets */
-	mtk_w32(eth, MTK_LRO_RING_RELINGUISH_REQ, MTK_PDMA_LRO_CTRL_DW0);
+	mtk_w32(eth, MTK_LRO_RING_RELINGUISH_REQ, reg_map->pdma.lro_ctrl_dw0);
 
 	/* wait for relinquishments done */
 	for (i = 0; i < 10; i++) {
-		val = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW0);
+		val = mtk_r32(eth, reg_map->pdma.lro_ctrl_dw0);
 		if (val & MTK_LRO_RING_RELINGUISH_DONE) {
 			mdelay(20);
 			continue;
@@ -3224,44 +3254,43 @@
 	}
 
 	/* invalidate lro rings */
-	for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++)
-		mtk_w32(eth, 0, MTK_LRO_CTRL_DW2_CFG(i));
+	for (i = 0; i < MTK_HW_LRO_RING_NUM; i++)
+		mtk_w32(eth, 0, reg_map->pdma.lro_rx_ctrl_dw0 + 0x8 + (i * 0x40));
 
 	/* disable HW LRO */
-	mtk_w32(eth, 0, MTK_PDMA_LRO_CTRL_DW0);
+	mtk_w32(eth, 0, reg_map->pdma.lro_ctrl_dw0);
 }
 
 static void mtk_hwlro_val_ipaddr(struct mtk_eth *eth, int idx, __be32 ip)
 {
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;
 	u32 reg_val;
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2))
-		idx += 1;
-
-	reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(idx));
+	reg_val = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 + 0x8 + (idx * 0x40));
 
 	/* invalidate the IP setting */
-	mtk_w32(eth, (reg_val & ~MTK_RING_MYIP_VLD), MTK_LRO_CTRL_DW2_CFG(idx));
+	mtk_w32(eth, (reg_val & ~MTK_RING_MYIP_VLD),
+		reg_map->pdma.lro_rx_ctrl_dw0 + 0x8 + (idx * 0x40));
 
-	mtk_w32(eth, ip, MTK_LRO_DIP_DW0_CFG(idx));
+	mtk_w32(eth, ip, reg_map->pdma.lro_rx_dip_dw0 + (idx * 0x40));
 
 	/* validate the IP setting */
-	mtk_w32(eth, (reg_val | MTK_RING_MYIP_VLD), MTK_LRO_CTRL_DW2_CFG(idx));
+	mtk_w32(eth, (reg_val | MTK_RING_MYIP_VLD),
+		reg_map->pdma.lro_rx_ctrl_dw0 + 0x8 + (idx * 0x40));
 }
 
 static void mtk_hwlro_inval_ipaddr(struct mtk_eth *eth, int idx)
 {
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;
 	u32 reg_val;
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2))
-		idx += 1;
-
-	reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(idx));
+	reg_val = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 + 0x8 + (idx * 0x40));
 
 	/* invalidate the IP setting */
-	mtk_w32(eth, (reg_val & ~MTK_RING_MYIP_VLD), MTK_LRO_CTRL_DW2_CFG(idx));
+	mtk_w32(eth, (reg_val & ~MTK_RING_MYIP_VLD),
+		reg_map->pdma.lro_rx_ctrl_dw0 + 0x8 + (idx * 0x40));
 
-	mtk_w32(eth, 0, MTK_LRO_DIP_DW0_CFG(idx));
+	mtk_w32(eth, 0, reg_map->pdma.lro_rx_dip_dw0 + (idx * 0x40));
 }
 
 static int mtk_hwlro_get_ip_cnt(struct mtk_mac *mac)
@@ -3281,36 +3310,34 @@
 {
 	struct mtk_mac *mac = netdev_priv(dev);
 	struct mtk_eth *eth = mac->hw;
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;
 	u32 reg_val;
 	int i;
 
 	/* check for duplicate IP address in the current DIP list */
-	for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) {
-		reg_val = mtk_r32(eth, MTK_LRO_DIP_DW0_CFG(i));
+	for (i = 0; i < MTK_HW_LRO_DIP_NUM; i++) {
+		reg_val = mtk_r32(eth, reg_map->pdma.lro_rx_dip_dw0 + (i * 0x40));
 		if (reg_val == ip4dst)
 			break;
 	}
 
-	if (i <= MTK_HW_LRO_RING_NUM) {
+	if (i < MTK_HW_LRO_DIP_NUM) {
 		netdev_warn(dev, "Duplicate IP address at DIP(%d)!\n", i);
 		return -EEXIST;
 	}
 
 	/* find out available DIP index */
-	for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) {
-		reg_val = mtk_r32(eth, MTK_LRO_DIP_DW0_CFG(i));
+	for (i = 0; i < MTK_HW_LRO_DIP_NUM; i++) {
+		reg_val = mtk_r32(eth, reg_map->pdma.lro_rx_dip_dw0 + (i * 0x40));
 		if (reg_val == 0UL)
 			break;
 	}
 
-	if (i > MTK_HW_LRO_RING_NUM) {
+	if (i >= MTK_HW_LRO_DIP_NUM) {
 		netdev_warn(dev, "DIP index is currently out of resource!\n");
 		return -EBUSY;
 	}
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2))
-		i -= 1;
-
 	return i;
 }
 
@@ -3318,24 +3345,22 @@
 {
 	struct mtk_mac *mac = netdev_priv(dev);
 	struct mtk_eth *eth = mac->hw;
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;
 	u32 reg_val;
 	int i;
 
 	/* find out DIP index that matches the given IP address */
-	for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) {
-		reg_val = mtk_r32(eth, MTK_LRO_DIP_DW0_CFG(i));
+	for (i = 0; i < MTK_HW_LRO_DIP_NUM; i++) {
+		reg_val = mtk_r32(eth, reg_map->pdma.lro_rx_dip_dw0 + (i * 0x40));
 		if (reg_val == ip4dst)
 			break;
 	}
 
-	if (i > MTK_HW_LRO_RING_NUM) {
+	if (i >= MTK_HW_LRO_DIP_NUM) {
 		netdev_warn(dev, "DIP address is not exist!\n");
 		return -ENOENT;
 	}
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2))
-		i -= 1;
-
 	return i;
 }
 
@@ -3490,6 +3515,7 @@
 
 static int mtk_rss_init(struct mtk_eth *eth)
 {
+	const struct mtk_reg_map *reg_map = eth->soc->reg_map;
 	struct mtk_rss_params *rss_params = &eth->rss_params;
 	static u8 hash_key[MTK_RSS_HASH_KEYSIZE] = {
 		0xfa, 0x01, 0xac, 0xbe, 0x3b, 0xb7, 0x42, 0x6a,
@@ -3507,46 +3533,51 @@
 
 	if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) {
 		/* Set RSS rings to PSE modes */
-		val =  mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(1));
-		val |= MTK_RING_PSE_MODE;
-		mtk_w32(eth, val, MTK_LRO_CTRL_DW2_CFG(1));
+		for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) {
+			val = mtk_r32(eth, reg_map->pdma.lro_rx_ctrl_dw0 +
+					   0x8 + (i * 0x40));
+			val |= MTK_RING_PSE_MODE;
+			mtk_w32(eth, val, reg_map->pdma.lro_rx_ctrl_dw0 +
+					  0x8 + (i * 0x40));
+		}
 
 		/* Enable non-lro multiple rx */
-		val = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW0);
+		val = mtk_r32(eth, reg_map->pdma.lro_ctrl_dw0);
 		val |= MTK_NON_LRO_MULTI_EN;
-		mtk_w32(eth, val, MTK_PDMA_LRO_CTRL_DW0);
+		mtk_w32(eth, val, reg_map->pdma.lro_ctrl_dw0);
 
 		/* Enable RSS dly int supoort */
 		val |= MTK_LRO_DLY_INT_EN;
-		mtk_w32(eth, val, MTK_PDMA_LRO_CTRL_DW0);
+		mtk_w32(eth, val, reg_map->pdma.lro_ctrl_dw0);
 	}
 
 	/* Hash Type */
-	val = mtk_r32(eth, MTK_PDMA_RSS_GLO_CFG);
+	val = mtk_r32(eth, reg_map->pdma.rss_glo_cfg);
 	val |= MTK_RSS_IPV4_STATIC_HASH;
 	val |= MTK_RSS_IPV6_STATIC_HASH;
-	mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
+	mtk_w32(eth, val, reg_map->pdma.rss_glo_cfg);
 
 	/* Hash Key */
 	for (i = 0; i < MTK_RSS_HASH_KEYSIZE / sizeof(u32); i++)
-		mtk_w32(eth, rss_params->hash_key[i], MTK_RSS_HASH_KEY_DW(i));
+		mtk_w32(eth, rss_params->hash_key[i],
+			reg_map->pdma.rss_hash_key_dw0 + (i * 0x4));
 
 	/* Select the size of indirection table */
 	for (i = 0; i < MTK_RSS_MAX_INDIRECTION_TABLE / 16; i++)
 		mtk_w32(eth, mtk_rss_indr_table(rss_params, i),
-			MTK_RSS_INDR_TABLE_DW(i));
+			reg_map->pdma.rss_indr_table_dw0 + (i * 0x4));
 
 	/* Pause */
 	val |= MTK_RSS_CFG_REQ;
-	mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
+	mtk_w32(eth, val, reg_map->pdma.rss_glo_cfg);
 
 	/* Enable RSS*/
 	val |= MTK_RSS_EN;
-	mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
+	mtk_w32(eth, val, reg_map->pdma.rss_glo_cfg);
 
 	/* Release pause */
 	val &= ~(MTK_RSS_CFG_REQ);
-	mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
+	mtk_w32(eth, val, reg_map->pdma.rss_glo_cfg);
 
 	/* Set perRSS GRP INT */
 	mtk_m32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(0)),
@@ -3561,9 +3592,9 @@
 
 	/* Enable RSS delay interrupt */
 	if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) {
-		mtk_w32(eth, MTK_MAX_DELAY_INT, MTK_LRO_RX1_DLY_INT);
-		mtk_w32(eth, MTK_MAX_DELAY_INT, MTK_LRO_RX2_DLY_INT);
-		mtk_w32(eth, MTK_MAX_DELAY_INT, MTK_LRO_RX3_DLY_INT);
+		mtk_w32(eth, MTK_MAX_DELAY_INT, reg_map->pdma.lro_rx_dly_int);
+		mtk_w32(eth, MTK_MAX_DELAY_INT, reg_map->pdma.lro_rx_dly_int + 0x4);
+		mtk_w32(eth, MTK_MAX_DELAY_INT, reg_map->pdma.lro_rx_dly_int + 0x8);
 	} else
 		mtk_w32(eth, MTK_MAX_DELAY_INT_V2, MTK_PDMA_RSS_DELAY_INT);
 
@@ -3575,17 +3606,17 @@
 	u32 val;
 
 	/* Pause */
-	val = mtk_r32(eth, MTK_PDMA_RSS_GLO_CFG);
+	val = mtk_r32(eth, eth->soc->reg_map->pdma.rss_glo_cfg);
 	val |= MTK_RSS_CFG_REQ;
-	mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
+	mtk_w32(eth, val, eth->soc->reg_map->pdma.rss_glo_cfg);
 
 	/* Disable RSS*/
 	val &= ~(MTK_RSS_EN);
-	mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
+	mtk_w32(eth, val, eth->soc->reg_map->pdma.rss_glo_cfg);
 
 	/* Release pause */
 	val &= ~(MTK_RSS_CFG_REQ);
-	mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
+	mtk_w32(eth, val, eth->soc->reg_map->pdma.rss_glo_cfg);
 }
 
 static netdev_features_t mtk_fix_features(struct net_device *dev,
@@ -5074,7 +5105,7 @@
 
 		for (i = 0; i < MTK_RSS_HASH_KEYSIZE / sizeof(u32); i++)
 			mtk_w32(eth, rss_params->hash_key[i],
-				MTK_RSS_HASH_KEY_DW(i));
+				eth->soc->reg_map->pdma.rss_hash_key_dw0 + (i * 0x4));
 	}
 
 	if (indir) {
@@ -5083,7 +5114,7 @@
 
 		for (i = 0; i < MTK_RSS_MAX_INDIRECTION_TABLE / 16; i++)
 			mtk_w32(eth, mtk_rss_indr_table(rss_params, i),
-				MTK_RSS_INDR_TABLE_DW(i));
+				eth->soc->reg_map->pdma.rss_indr_table_dw0 + (i * 0x4));
 	}
 
 	return 0;
@@ -5619,7 +5650,7 @@
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
 		eth->ip_align = NET_IP_ALIGN;
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_8GB_ADDRESSING)) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
 		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36));
 		if (!err) {
 			err = dma_set_coherent_mask(&pdev->dev,
@@ -5830,11 +5861,9 @@
 			}
 
 			if (MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO)) {
-				i = (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2) ||
-				     MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) ? 0 : 1;
-				for (; i < MTK_HW_LRO_RING_NUM; i++) {
+				for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
 					err = devm_request_irq(eth->dev,
-							       eth->irq_pdma[i],
+							       eth->irq_pdma[MTK_HW_LRO_IRQ(i)],
 							       mtk_handle_irq_txrx, IRQF_SHARED,
 							       dev_name(eth->dev),
 							       &eth->rx_napi[MTK_HW_LRO_RING(i)]);
@@ -6152,7 +6181,6 @@
 		.rxd_size = sizeof(struct mtk_rx_dma),
 		.tx_dma_size = MTK_DMA_SIZE(2K),
 		.rx_dma_size = MTK_DMA_SIZE(2K),
-		.fq_dma_size = MTK_DMA_SIZE(2K),
 		.rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA,
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
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 66c2a54..198cd0e 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
@@ -227,16 +227,13 @@
 
 /* PDMA HW LRO Control Registers */
 #define BITS(m, n)			(~(BIT(m) - 1) & ((BIT(n) - 1) | BIT(n)))
+#define MTK_HW_LRO_DIP_NUM		(4)
 #if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
 #define MTK_MAX_RX_RING_NUM		(8)
 #define MTK_HW_LRO_RING_NUM		(4)
 #define MTK_HW_LRO_RING(x)		((x) + 4)
+#define MTK_HW_LRO_IRQ(x)		(x)
 #define IS_HW_LRO_RING(ring_no)		(((ring_no) > 3) && ((ring_no) < 8))
-#define MTK_PDMA_LRO_CTRL_DW0		(PDMA_BASE + 0x408)
-#define MTK_LRO_ALT_SCORE_DELTA		(PDMA_BASE + 0x41c)
-#define MTK_LRO_RX_RING0_CTRL_DW1	(PDMA_BASE + 0x438)
-#define MTK_LRO_RX_RING0_CTRL_DW2	(PDMA_BASE + 0x43c)
-#define MTK_LRO_RX_RING0_CTRL_DW3	(PDMA_BASE + 0x440)
 #define MTK_L3_CKS_UPD_EN		BIT(19)
 #define MTK_LRO_CRSN_BNW		BIT(22)
 #define MTK_LRO_RING_RELINGUISH_REQ	(0xf << 24)
@@ -245,12 +242,8 @@
 #define MTK_MAX_RX_RING_NUM		(4)
 #define MTK_HW_LRO_RING_NUM		(3)
 #define MTK_HW_LRO_RING(x)		((x) + 1)
+#define MTK_HW_LRO_IRQ(x)		((x) + 1)
 #define IS_HW_LRO_RING(ring_no)		(((ring_no) > 0) && ((ring_no) < 4))
-#define MTK_PDMA_LRO_CTRL_DW0		(PDMA_BASE + 0x180)
-#define MTK_LRO_ALT_SCORE_DELTA		(PDMA_BASE + 0x24c)
-#define MTK_LRO_RX_RING0_CTRL_DW1	(PDMA_BASE + 0x328)
-#define MTK_LRO_RX_RING0_CTRL_DW2	(PDMA_BASE + 0x32c)
-#define MTK_LRO_RX_RING0_CTRL_DW3	(PDMA_BASE + 0x330)
 #define MTK_LRO_CRSN_BNW		BIT(6)
 #define MTK_L3_CKS_UPD_EN		BIT(7)
 #define MTK_LRO_RING_RELINGUISH_REQ	(0x7 << 26)
@@ -266,18 +259,10 @@
 #define MTK_CTRL_DW0_SDL_OFFSET		(3)
 #define MTK_CTRL_DW0_SDL_MASK		BITS(3, 18)
 
-#define MTK_PDMA_LRO_CTRL_DW1	(MTK_PDMA_LRO_CTRL_DW0 + 0x04)
-#define MTK_PDMA_LRO_CTRL_DW2	(MTK_PDMA_LRO_CTRL_DW0 + 0x08)
-#define MTK_PDMA_LRO_CTRL_DW3	(MTK_PDMA_LRO_CTRL_DW0 + 0x0c)
-#define MTK_ADMA_MODE		BIT(15)
-#define MTK_LRO_MIN_RXD_SDL	(MTK_HW_LRO_SDL_REMAIN_ROOM << 16)
+#define MTK_ADMA_MODE			BIT(15)
+#define MTK_LRO_MIN_RXD_SDL		(MTK_HW_LRO_SDL_REMAIN_ROOM << 16)
 
 /* PDMA RSS Control Registers */
-#if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
-#define MTK_PDMA_RSS_GLO_CFG		(PDMA_BASE + 0x800)
-#else
-#define MTK_PDMA_RSS_GLO_CFG		0x2800
-#endif
 #define MTK_RX_NAPI_NUM			(8)
 #define MTK_RX_RSS_NUM			(3)
 #define MTK_RSS_RING(x)			((x) + 1)
@@ -285,10 +270,6 @@
 #define MTK_RSS_CFG_REQ			BIT(2)
 #define MTK_RSS_IPV6_STATIC_HASH	(0x7 << 8)
 #define MTK_RSS_IPV4_STATIC_HASH	(0x7 << 12)
-#define MTK_RSS_HASH_KEY_DW(x)		(MTK_PDMA_RSS_GLO_CFG + 0x20 +	\
-					 ((x) * 0x4))
-#define MTK_RSS_INDR_TABLE_DW(x)	(MTK_PDMA_RSS_GLO_CFG + 0x50 +	\
-					 ((x) * 0x4))
 
 /* PDMA Global Configuration Register */
 #define MTK_PDMA_GLO_CFG	(PDMA_BASE + 0x204)
@@ -305,7 +286,6 @@
 #define MTK_CHK_DDONE		BIT(10)
 
 /* PDMA RX DMA Configuration Register */
-#define MTK_PDMA_RX_CFG		(PDMA_BASE + 0x210)
 #define MTK_PDMA_LRO_SDL	(0x3000)
 #define MTK_RX_CFG_SDL_OFFSET	(16)
 
@@ -351,32 +331,16 @@
 #else
 #define MTK_PDMA_INT_GRP3	(PDMA_BASE + 0x22c)
 #endif
-#define MTK_LRO_RX1_DLY_INT	(PDMA_BASE + 0x270)
-#define MTK_LRO_RX2_DLY_INT	(PDMA_BASE + 0x274)
-#define MTK_LRO_RX3_DLY_INT	(PDMA_BASE + 0x278)
 #define MTK_MAX_DELAY_INT	0x8f0f
 #define MTK_MAX_DELAY_INT_V2	0x8f0f8f0f
 
 /* PDMA HW LRO IP Setting Registers */
-#if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
-#define MTK_LRO_RX_RING0_DIP_DW0	(PDMA_BASE + 0x414)
-#else
-#define MTK_LRO_RX_RING0_DIP_DW0	(PDMA_BASE + 0x304)
-#endif
-#define MTK_LRO_DIP_DW0_CFG(x)		(MTK_LRO_RX_RING0_DIP_DW0 + (x * 0x40))
 #define MTK_RING_MYIP_VLD		BIT(9)
 
 /* PDMA HW LRO ALT Debug Registers */
-#define MTK_LRO_ALT_DBG			(PDMA_BASE + 0x440)
 #define MTK_LRO_ALT_INDEX_OFFSET	(8)
 
-/* PDMA HW LRO ALT Data Registers */
-#define MTK_LRO_ALT_DBG_DATA		(PDMA_BASE + 0x444)
-
 /* PDMA HW LRO Ring Control Registers */
-#define MTK_LRO_CTRL_DW1_CFG(x)		(MTK_LRO_RX_RING0_CTRL_DW1 + (x * 0x40))
-#define MTK_LRO_CTRL_DW2_CFG(x)		(MTK_LRO_RX_RING0_CTRL_DW2 + (x * 0x40))
-#define MTK_LRO_CTRL_DW3_CFG(x)		(MTK_LRO_RX_RING0_CTRL_DW3 + (x * 0x40))
 #define MTK_RING_AGE_TIME_L		((MTK_HW_LRO_AGE_TIME & 0x3ff) << 22)
 #define MTK_RING_AGE_TIME_H		((MTK_HW_LRO_AGE_TIME >> 10) & 0x3f)
 #define MTK_RING_PSE_MODE        	(1 << 6)
@@ -567,6 +531,7 @@
 
 /* QDMA TX Scheduler Rate Control Register */
 #define MTK_QDMA_TX_4SCH_BASE(x)	(QDMA_BASE + 0x398 + (((x) >> 1) * 0x4))
+#define MTK_QDMA_TX_SCH_MASK		GENMASK(15, 0)
 
 /* WDMA Registers */
 #define MTK_WDMA_CTX_PTR(x)	(WDMA_BASE(x) + 0x8)
@@ -653,7 +618,14 @@
 #define TX_DMA_PLEN1(_x)	((_x) & eth->soc->txrx.dma_max_len)
 #endif
 #define TX_DMA_SWC		BIT(14)
-#define TX_DMA_SDP1(_x)		((((u64)(_x)) >> 32) & 0xf)
+#define TX_DMA_ADDR64_MASK	GENMASK(3, 0)
+#if IS_ENABLED(CONFIG_64BIT)
+# define TX_DMA_GET_ADDR64(x)	(((u64)FIELD_GET(TX_DMA_ADDR64_MASK, (x))) << 32)
+# define TX_DMA_PREP_ADDR64(x)	FIELD_PREP(TX_DMA_ADDR64_MASK, ((x) >> 32))
+#else
+# define TX_DMA_GET_ADDR64(x)	(0)
+# define TX_DMA_PREP_ADDR64(x)	(0)
+#endif
 
 /* PDMA on MT7628 */
 #define TX_DMA_DONE		BIT(31)
@@ -676,8 +648,14 @@
 #define RX_DMA_GET_AGG_CNT(_x)	(((_x) >> 2) & 0xff)
 #define RX_DMA_GET_REV(_x)	(((_x) >> 10) & 0x1f)
 #define RX_DMA_VTAG		BIT(15)
-#define RX_DMA_SDP1(_x)		((((u64)(_x)) >> 32) & 0xf)
-#define RX_DMA_GET_SDP1(_x)	((_x) & 0xf)
+#define RX_DMA_ADDR64_MASK	GENMASK(3, 0)
+#if IS_ENABLED(CONFIG_64BIT)
+# define RX_DMA_GET_ADDR64(x)	(((u64)FIELD_GET(RX_DMA_ADDR64_MASK, (x))) << 32)
+# define RX_DMA_PREP_ADDR64(x)	FIELD_PREP(RX_DMA_ADDR64_MASK, ((x) >> 32))
+#else
+# define RX_DMA_GET_ADDR64(x)	(0)
+# define RX_DMA_PREP_ADDR64(x)	(0)
+#endif
 
 /* QDMA descriptor rxd3 */
 #define RX_DMA_VID(_x)		((_x) & VLAN_VID_MASK)
@@ -1489,7 +1467,7 @@
 	MTK_RSTCTRL_PPE1_BIT,
 	MTK_RSTCTRL_PPE2_BIT,
 	MTK_U3_COPHY_V2_BIT,
-	MTK_8GB_ADDRESSING_BIT,
+	MTK_36BIT_DMA_BIT,
 
 	/* MUX BITS*/
 	MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
@@ -1541,7 +1519,7 @@
 #define MTK_RSTCTRL_PPE1	BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
 #define MTK_RSTCTRL_PPE2	BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
 #define MTK_U3_COPHY_V2		BIT_ULL(MTK_U3_COPHY_V2_BIT)
-#define MTK_8GB_ADDRESSING	BIT_ULL(MTK_8GB_ADDRESSING_BIT)
+#define MTK_36BIT_DMA		BIT_ULL(MTK_36BIT_DMA_BIT)
 
 #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW		\
 	BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
@@ -1655,7 +1633,7 @@
 		       MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII | \
 		       MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII | \
 		       MTK_GMAC2_XGMII | MTK_MUX_GMAC2_TO_XGMII | MTK_RSS | \
-		       MTK_NETSYS_RX_V2 | MTK_8GB_ADDRESSING)
+		       MTK_NETSYS_RX_V2 | MTK_36BIT_DMA)
 
 struct mtk_tx_dma_desc_info {
 	dma_addr_t	addr;
@@ -1683,10 +1661,21 @@
 		u32	glo_cfg;	/* global configuration */
 		u32	rst_idx;	/* reset index */
 		u32	delay_irq;	/* delay interrupt */
+		u32	rx_cfg;		/* rx dma configuration */
 		u32	irq_status;	/* interrupt status */
 		u32	irq_mask;	/* interrupt mask */
 		u32	int_grp;	/* interrupt group1 */
 		u32	int_grp2;	/* interrupt group2 */
+		u32	lro_ctrl_dw0;	/* lro control dword0 */
+		u32	lro_alt_score_delta;	/* lro auto-learn score delta */
+		u32	lro_rx_dly_int;	/* lro rx ring delay interrupt */
+		u32	lro_rx_dip_dw0;	/* lro rx ring dip dword0 */
+		u32	lro_rx_ctrl_dw0;	/* lro rx ring ctrl dword0 */
+		u32	lro_alt_dbg;	/* lro auto-learn debug */
+		u32	lro_alt_dbg_data;	/* lro auto-learn debug data */
+		u32	rss_glo_cfg;	/* rss global configuration */
+		u32	rss_hash_key_dw0;	/* rss hash key dword0 */
+		u32	rss_indr_table_dw0;	/* rss indirection table dword0 */
 	} pdma;
 	struct {
 		u32	qtx_cfg;	/* tx queue configuration */
@@ -2014,7 +2003,7 @@
 u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
 u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg);
 
-struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id);
+struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, unsigned int id);
 int mtk_sgmii_init(struct mtk_eth *eth, struct device_node *np,
 		   u32 ana_rgc3);
 
@@ -2027,7 +2016,7 @@
 void ethsys_reset(struct mtk_eth *eth, u32 reset_bits);
 
 int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id);
-struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_usxgmii *ss, int id);
+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_usxgmii *ss, unsigned 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);
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
index 4a7e14f..011421c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
@@ -190,13 +190,13 @@
 	if (enable) {
 #if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
 		if (CFG_PPE_NUM >= 3 && id == NR_GMAC3_PORT)
-			cr_set_bits(reg, BITS_GDM_ALL_FRC_P_PPE2);
+			cr_set_field(reg, GDM_ALL_FRC_MASK, BITS_GDM_ALL_FRC_P_PPE2);
 		else if (CFG_PPE_NUM >= 2 && id == NR_GMAC2_PORT)
-			cr_set_bits(reg, BITS_GDM_ALL_FRC_P_PPE1);
+			cr_set_field(reg, GDM_ALL_FRC_MASK, BITS_GDM_ALL_FRC_P_PPE1);
 		else
-			cr_set_bits(reg, BITS_GDM_ALL_FRC_P_PPE);
+			cr_set_field(reg, GDM_ALL_FRC_MASK, BITS_GDM_ALL_FRC_P_PPE);
 #else
-		cr_set_bits(reg, BITS_GDM_ALL_FRC_P_PPE);
+		cr_set_field(reg, GDM_ALL_FRC_MASK, BITS_GDM_ALL_FRC_P_PPE);
 #endif
 		return;
 	}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
index a5b578b..f7ca61c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
@@ -18,6 +18,7 @@
 #include <linux/if.h>
 #include <linux/if_ether.h>
 #include <net/netevent.h>
+#include <net/netfilter/nf_conntrack_zones.h>
 #include <linux/mod_devicetable.h>
 #include "hnat_mcast.h"
 #include "nf_hnat_mtk.h"
@@ -388,9 +389,9 @@
 	u32 resv3_1 : 9;
 	u32 eg_keep_ecn : 1;
 	u32 eg_keep_dscp : 1;
-	u32 resv3_2:13;
+	u32 resv3_2 : 13;
 #else
-	u32 resv3:24;
+	u32 resv3 : 24;
 #endif
 	u32 act_dp : 8; /* UDF */
 	u16 vlan1;
@@ -447,12 +448,12 @@
 	u8 priority;    /* in order to consist with Linux kernel (should be 8bits) */
 	u32 hop_limit : 8;
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
-		u32 resv2_1 : 1;
-		u32 eg_keep_ecn : 1;
-		u32 eg_keep_cls : 1;
-		u32 resv2_2 : 13;
+	u32 resv2_1 : 1;
+	u32 eg_keep_ecn : 1;
+	u32 eg_keep_cls : 1;
+	u32 resv2_2 : 13;
 #else
-		u32 resv2 : 16;
+	u32 resv2 : 16;
 #endif
 	u32 act_dp : 8; /* UDF */
 
@@ -888,7 +889,8 @@
 struct hnat_accounting {
 	u64 bytes;
 	u64 packets;
-	u64 nfct; /* For retrieving nf_conn info */
+	struct nf_conntrack_zone zone;
+	u8 dir;
 };
 
 enum mtk_hnat_version {
@@ -1232,7 +1234,7 @@
 #endif
 
 #define UDF_PINGPONG_IFIDX GENMASK(6, 0)
-#define UDF_HNAT_PRE_FILLED BIT(7)
+#define UDF_HNAT_ENTRY_LOCKED BIT(7)
 
 #define HQOS_FLAG(dev, skb, qid)			\
 	((IS_HQOS_UL_MODE && IS_WAN(dev)) ||		\
@@ -1249,7 +1251,7 @@
 extern const struct of_device_id of_hnat_match[];
 extern struct mtk_hnat *hnat_priv;
 
-static inline int is_hnat_pre_filled(struct foe_entry *entry)
+static inline int is_hnat_entry_locked(struct foe_entry *entry)
 {
 	u32 udf = 0;
 
@@ -1258,7 +1260,30 @@
 	else
 		udf = entry->ipv6_5t_route.act_dp;
 
-	return !!(udf & UDF_HNAT_PRE_FILLED);
+	return !!(udf & UDF_HNAT_ENTRY_LOCKED);
+}
+
+static inline void hnat_set_entry_lock(struct foe_entry *entry, bool locked)
+{
+	if (IS_IPV4_GRP(entry)) {
+		if (locked)
+			entry->ipv4_hnapt.act_dp |= UDF_HNAT_ENTRY_LOCKED;
+		else
+			entry->ipv4_hnapt.act_dp &= ~UDF_HNAT_ENTRY_LOCKED;
+	} else {
+		if (locked)
+			entry->ipv6_5t_route.act_dp |= UDF_HNAT_ENTRY_LOCKED;
+		else
+			entry->ipv6_5t_route.act_dp &= ~UDF_HNAT_ENTRY_LOCKED;
+	}
+	/* Ensure the lock has been written to the entry before return */
+	wmb();
+}
+
+static inline void hnat_check_release_entry_lock(struct foe_entry *entry)
+{
+	if (is_hnat_entry_locked(entry))
+		hnat_set_entry_lock(entry, false);
 }
 
 #if defined(CONFIG_NET_DSA_MT7530)
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 d111cb3..3e0d540 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
@@ -20,6 +20,8 @@
 #include <net/ipv6.h>
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_acct.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_tuple.h>
 
 #include "hnat.h"
 #include "nf_hnat_mtk.h"
@@ -978,24 +980,70 @@
 
 }
 
-static int hnat_nfct_counter_update(struct mtk_hnat *h, u32 ppe_id,
-				    u32 index, u64 bytes, u64 packets)
+static int hnat_nf_acct_update(struct mtk_hnat *h, u32 ppe_id,
+			       u32 index, u64 bytes, u64 packets)
 {
-	struct nf_conn *ct;
-	struct nf_conn_acct *acct;
+	struct nf_conntrack_tuple tuple = {0};
+	struct nf_conntrack_tuple_hash *hash;
+	struct nf_conntrack_zone *zone;
 	struct nf_conn_counter *counter;
-	enum ip_conntrack_info ctinfo;
-	u64 nfct;
+	struct nf_conn_acct *acct;
+	struct foe_entry *entry;
+	struct nf_conn *ct;
+	u8 dir;
 
-	nfct = h->acct[ppe_id][index].nfct;
-	ctinfo = nfct & NFCT_INFOMASK;
-	ct = (struct nf_conn *)(nfct & NFCT_PTRMASK);
-	if (ct) {
-		acct = nf_conn_acct_find(ct);
-		if (acct) {
-			counter = acct->counter;
-			atomic64_add(bytes, &counter[CTINFO2DIR(ctinfo)].bytes);
-			atomic64_add(packets, &counter[CTINFO2DIR(ctinfo)].packets);
+	entry = &h->foe_table_cpu[ppe_id][index];
+	zone = &h->acct[ppe_id][index].zone;
+	dir = h->acct[ppe_id][index].dir;
+
+	tuple.dst.protonum = (entry->bfib1.udp) ? IPPROTO_UDP : IPPROTO_TCP;
+
+	switch (entry->bfib1.pkt_type) {
+	case IPV4_HNAT:
+	case IPV4_HNAPT:
+	case IPV4_DSLITE:
+	case IPV4_MAP_T:
+	case IPV4_MAP_E:
+		tuple.src.l3num = AF_INET;
+		tuple.src.u3.ip = htonl(entry->ipv4_hnapt.sip);
+		tuple.dst.u3.ip = htonl(entry->ipv4_hnapt.dip);
+		tuple.src.u.tcp.port = htons(entry->ipv4_hnapt.sport);
+		tuple.dst.u.tcp.port = htons(entry->ipv4_hnapt.dport);
+		break;
+	case IPV6_6RD:
+	case IPV6_HNAT:
+	case IPV6_HNAPT:
+	case IPV6_3T_ROUTE:
+	case IPV6_5T_ROUTE:
+		tuple.src.l3num = AF_INET6;
+
+		tuple.src.u3.in6.s6_addr32[0] = htonl(entry->ipv6_5t_route.ipv6_sip0);
+		tuple.src.u3.in6.s6_addr32[1] = htonl(entry->ipv6_5t_route.ipv6_sip1);
+		tuple.src.u3.in6.s6_addr32[2] = htonl(entry->ipv6_5t_route.ipv6_sip2);
+		tuple.src.u3.in6.s6_addr32[3] = htonl(entry->ipv6_5t_route.ipv6_sip3);
+
+		tuple.dst.u3.in6.s6_addr32[0] = htonl(entry->ipv6_5t_route.ipv6_dip0);
+		tuple.dst.u3.in6.s6_addr32[1] = htonl(entry->ipv6_5t_route.ipv6_dip1);
+		tuple.dst.u3.in6.s6_addr32[2] = htonl(entry->ipv6_5t_route.ipv6_dip2);
+		tuple.dst.u3.in6.s6_addr32[3] = htonl(entry->ipv6_5t_route.ipv6_dip3);
+
+		tuple.src.u.tcp.port = htons(entry->ipv6_5t_route.sport);
+		tuple.dst.u.tcp.port = htons(entry->ipv6_5t_route.dport);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	hash = nf_conntrack_find_get(&init_net, zone, &tuple);
+	if (hash) {
+		ct = nf_ct_tuplehash_to_ctrack(hash);
+		if (ct) {
+			acct = nf_conn_acct_find(ct);
+			if (acct) {
+				counter = acct->counter;
+				atomic64_add(bytes, &counter[dir].bytes);
+				atomic64_add(packets, &counter[dir].packets);
+			}
 		}
 	}
 
@@ -1028,7 +1076,7 @@
 		diff->packets = packets;
 	}
 
-	hnat_nfct_counter_update(h, ppe_id, index, bytes, packets);
+	hnat_nf_acct_update(h, ppe_id, index, bytes, packets);
 
 	return &h->acct[ppe_id][index];
 }
@@ -2129,7 +2177,7 @@
 
 	if (id & 0x1)
 		qdma_tx_sch >>= 16;
-	qdma_tx_sch &= 0xffff;
+	qdma_tx_sch &= MTK_QDMA_TX_SCH_MASK;
 	enable = !!(qdma_tx_sch & BIT(11));
 	scheduling = !!(qdma_tx_sch & BIT(15));
 	max_rate = ((qdma_tx_sch >> 4) & 0x7f);
@@ -2212,7 +2260,7 @@
 	else
 		qdma_tx_sch = readl(h->fe_base + QDMA_TX_2SCH_BASE);
 
-	qdma_tx_sch &= ~(0xffff << shift);
+	qdma_tx_sch &= ~(MTK_QDMA_TX_SCH_MASK << shift);
 	qdma_tx_sch |= val << shift;
 	if (hnat_priv->data->num_of_sch == 4)
 		writel(qdma_tx_sch, h->fe_base + QDMA_TX_4SCH_BASE(id));
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index c34c95a..cbebcd4 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -712,6 +712,17 @@
 		       sizeof(struct hnat_desc));
 }
 
+static int hnat_ipv6_addr_equal(u32 *foe_ipv6_ptr, const struct in6_addr *target)
+{
+	struct in6_addr foe_in6_addr;
+	int i;
+
+	for (i = 0; i < 4; i++)
+		foe_in6_addr.s6_addr32[i] = htonl(foe_ipv6_ptr[i]);
+
+	return ipv6_addr_equal(&foe_in6_addr, target);
+}
+
 static unsigned int is_ppe_support_type(struct sk_buff *skb)
 {
 	struct ethhdr *eth = NULL;
@@ -1160,10 +1171,11 @@
 		} else {
 			entry.ipv4_hnapt.iblk2.mcast = 0;
 		}
-
-		entry.ipv4_hnapt.iblk2.port_ag =
-			(hnat_priv->data->version == MTK_HNAT_V2 ||
-			 hnat_priv->data->version == MTK_HNAT_V3) ? 0xf : 0x3f;
+#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
+		entry.ipv4_hnapt.iblk2.port_ag = 0xf;
+#else
+		entry.ipv4_hnapt.iblk2.port_ag = 0x3f;
+#endif
 		break;
 	case IPV4_DSLITE:
 	case IPV4_MAP_E:
@@ -1183,9 +1195,11 @@
 			entry.ipv6_5t_route.iblk2.mcast = 0;
 		}
 
-		entry.ipv6_5t_route.iblk2.port_ag =
-			(hnat_priv->data->version == MTK_HNAT_V2 ||
-			 hnat_priv->data->version == MTK_HNAT_V3) ? 0xf : 0x3f;
+#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
+		entry.ipv6_5t_route.iblk2.port_ag = 0xf;
+#else
+		entry.ipv6_5t_route.iblk2.port_ag = 0x3f;
+#endif
 		break;
 	}
 	return entry;
@@ -1227,8 +1241,6 @@
 	int mape = 0;
 	struct mtk_mac *mac = netdev_priv(dev);
 
-	ct = nf_ct_get(skb, &ctinfo);
-
 	if (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPIP)
 		/* point to ethernet header for DS-Lite and MapE */
 		eth = get_ipv6_ipip_ethhdr(skb, hw_path);
@@ -1239,9 +1251,6 @@
 	if (!hnat_priv->data->mcast && is_multicast_ether_addr(eth->h_dest))
 		return 0;
 
-	if (whnat && is_hnat_pre_filled(foe))
-		return 0;
-
 	entry.bfib1.pkt_type = foe->udib1.pkt_type; /* Get packte type state*/
 	entry.bfib1.state = foe->udib1.state;
 
@@ -1267,8 +1276,7 @@
 			entry.ipv4_hnapt.etype = htons(ETH_P_IP);
 
 			/* DS-Lite WAN->LAN */
-			if (entry.ipv4_hnapt.bfib1.pkt_type == IPV4_DSLITE ||
-			    entry.ipv4_hnapt.bfib1.pkt_type == IPV4_MAP_E) {
+			if (IS_IPV4_DSLITE(&entry) || IS_IPV4_MAPE(&entry)) {
 				entry.ipv4_dslite.sip = foe->ipv4_dslite.sip;
 				entry.ipv4_dslite.dip = foe->ipv4_dslite.dip;
 				entry.ipv4_dslite.sport =
@@ -1277,7 +1285,7 @@
 					foe->ipv4_dslite.dport;
 
 #if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
-				if (entry.bfib1.pkt_type == IPV4_MAP_E) {
+				if (IS_IPV4_MAPE(&entry)) {
 					pptr = skb_header_pointer(skb,
 								  iph->ihl * 4,
 								  sizeof(_ports),
@@ -1293,10 +1301,6 @@
 							ntohs(pptr->src);
 					entry.ipv4_mape.new_dport =
 							ntohs(pptr->dst);
-#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-					entry.ipv4_mape.eg_keep_ecn = 1;
-					entry.ipv4_mape.eg_keep_dscp = 1;
-#endif
 				}
 #endif
 
@@ -1329,7 +1333,7 @@
 				entry.ipv4_dslite.eg_keep_cls = 1;
 #endif
 
-			} else {
+			} else if (IS_IPV4_GRP(&entry)) {
 				entry.ipv4_hnapt.iblk2.dscp = iph->tos;
 				if (hnat_priv->data->per_flow_accounting)
 					entry.ipv4_hnapt.iblk2.mibf = 1;
@@ -1345,7 +1349,7 @@
 					else
 						entry.ipv4_hnapt.vlan1 =
 							skb->vlan_tci;
-			}
+				}
 
 				entry.ipv4_hnapt.sip = foe->ipv4_hnapt.sip;
 				entry.ipv4_hnapt.dip = foe->ipv4_hnapt.dip;
@@ -1354,25 +1358,27 @@
 
 				entry.ipv4_hnapt.new_sip = ntohl(iph->saddr);
 				entry.ipv4_hnapt.new_dip = ntohl(iph->daddr);
-			}
 
-			entry.ipv4_hnapt.bfib1.udp = udp;
-			if (IS_IPV4_HNAPT(foe)) {
-				pptr = skb_header_pointer(skb, iph->ihl * 4,
-							  sizeof(_ports),
-							  &_ports);
-				if (unlikely(!pptr))
-					return -1;
+				if (IS_IPV4_HNAPT(&entry)) {
+					pptr = skb_header_pointer(skb, iph->ihl * 4,
+								sizeof(_ports),
+								&_ports);
+					if (unlikely(!pptr))
+						return -1;
 
-				entry.ipv4_hnapt.new_sport = ntohs(pptr->src);
-				entry.ipv4_hnapt.new_dport = ntohs(pptr->dst);
-			}
+					entry.ipv4_hnapt.new_sport = ntohs(pptr->src);
+					entry.ipv4_hnapt.new_dport = ntohs(pptr->dst);
+				}
 
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
-			entry.ipv4_hnapt.eg_keep_ecn = 1;
-			entry.ipv4_hnapt.eg_keep_dscp = 1;
+				entry.ipv4_hnapt.eg_keep_ecn = 1;
+				entry.ipv4_hnapt.eg_keep_dscp = 1;
 #endif
+			} else {
+				return 0;
+			}
 
+			entry.ipv4_hnapt.bfib1.udp = udp;
 			break;
 
 		default:
@@ -1410,17 +1416,12 @@
 				entry.ipv6_5t_route.iblk2.mibf = 1;
 			entry.ipv6_5t_route.bfib1.udp = udp;
 
-			if (IS_IPV6_6RD(foe)) {
+			if (IS_IPV6_6RD(&entry)) {
 				entry.ipv6_5t_route.bfib1.rmt = 1;
 				entry.ipv6_6rd.tunnel_sipv4 =
 					foe->ipv6_6rd.tunnel_sipv4;
 				entry.ipv6_6rd.tunnel_dipv4 =
 					foe->ipv6_6rd.tunnel_dipv4;
-
-#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-				entry.ipv6_6rd.eg_keep_ecn = 1;
-				entry.ipv6_6rd.eg_keep_cls = 1;
-#endif
 			}
 
 			entry.ipv6_3t_route.ipv6_sip0 =
@@ -1441,29 +1442,28 @@
 			entry.ipv6_3t_route.ipv6_dip3 =
 				foe->ipv6_3t_route.ipv6_dip3;
 
+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
+			entry.ipv6_3t_route.eg_keep_ecn = 1;
+			entry.ipv6_3t_route.eg_keep_cls = 1;
+#endif
+
-			if (IS_IPV6_3T_ROUTE(foe)) {
+			if (IS_IPV6_3T_ROUTE(&entry)) {
 				entry.ipv6_3t_route.prot =
 					foe->ipv6_3t_route.prot;
 				entry.ipv6_3t_route.hph =
 					foe->ipv6_3t_route.hph;
-#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-				entry.ipv6_3t_route.eg_keep_ecn = 1;
-				entry.ipv6_3t_route.eg_keep_cls = 1;
-#endif
-			}
-
-			if (IS_IPV6_5T_ROUTE(foe) || IS_IPV6_6RD(foe)) {
+			} else if (IS_IPV6_5T_ROUTE(&entry) || IS_IPV6_6RD(&entry)) {
 				entry.ipv6_5t_route.sport =
 					foe->ipv6_5t_route.sport;
 				entry.ipv6_5t_route.dport =
 					foe->ipv6_5t_route.dport;
-#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-				entry.ipv6_5t_route.eg_keep_ecn = 1;
-				entry.ipv6_5t_route.eg_keep_cls = 1;
-#endif
+			} else {
+				return 0;
 			}
 
-			if (ct && (ct->status & IPS_SRC_NAT)) {
+			if (IS_IPV6_5T_ROUTE(&entry) &&
+			    (!hnat_ipv6_addr_equal(&entry.ipv6_5t_route.ipv6_sip0, &ip6h->saddr) ||
+			     !hnat_ipv6_addr_equal(&entry.ipv6_5t_route.ipv6_dip0, &ip6h->daddr))) {
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
 				entry.bfib1.pkt_type = IPV6_HNAPT;
 
@@ -1499,10 +1499,6 @@
 
 				entry.ipv6_hnapt.new_sport = ntohs(pptr->src);
 				entry.ipv6_hnapt.new_dport = ntohs(pptr->dst);
-#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-				entry.ipv6_hnapt.eg_keep_ecn = 1;
-				entry.ipv6_hnapt.eg_keep_cls = 1;
-#endif
 #else
 				return -1;
 #endif
@@ -1570,10 +1566,6 @@
 					entry.ipv4_mape.new_dip = foe->ipv4_mape.new_dip;
 					entry.ipv4_mape.new_sport = foe->ipv4_mape.new_sport;
 					entry.ipv4_mape.new_dport = foe->ipv4_mape.new_dport;
-#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-					entry.ipv4_mape.eg_keep_ecn = 1;
-					entry.ipv4_mape.eg_keep_dscp = 1;
-#endif
 				}
 #endif
 			} else if (mape_toggle &&
@@ -1785,11 +1777,14 @@
 		}
 	}
 
-	if (IS_IPV4_GRP(foe)) {
-		entry.ipv4_hnapt.iblk2.dp = gmac;
+	if (IS_IPV4_GRP(&entry)) {
+		entry.ipv4_hnapt.iblk2.dp = gmac & 0xf;
+#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
+		entry.ipv4_hnapt.iblk2.port_mg = 0;
+#else
 		entry.ipv4_hnapt.iblk2.port_mg =
 			(hnat_priv->data->version == MTK_HNAT_V1_1) ? 0x3f : 0;
-
+#endif
 		if (qos_toggle) {
 			if (hnat_priv->data->version == MTK_HNAT_V2 ||
 			    hnat_priv->data->version == MTK_HNAT_V3) {
@@ -1824,9 +1819,13 @@
 			entry.ipv4_hnapt.iblk2.fqos = 0;
 		}
 	} else {
-		entry.ipv6_5t_route.iblk2.dp = gmac;
+		entry.ipv6_5t_route.iblk2.dp = gmac & 0xf;
+#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
+		entry.ipv6_5t_route.iblk2.port_mg = 0;
+#else
 		entry.ipv6_5t_route.iblk2.port_mg =
 			(hnat_priv->data->version == MTK_HNAT_V1_1) ? 0x3f : 0;
+#endif
 
 		if (qos_toggle) {
 			if (hnat_priv->data->version == MTK_HNAT_V2 ||
@@ -1884,21 +1883,72 @@
 		entry.bfib1.ttl = 1;
 		entry.bfib1.state = BIND;
 	} else {
-		if (IS_IPV4_GRP(foe))
-			entry.ipv4_hnapt.act_dp |= UDF_HNAT_PRE_FILLED;
-		else
-			entry.ipv6_5t_route.act_dp |= UDF_HNAT_PRE_FILLED;
+		if (spin_trylock(&hnat_priv->entry_lock)) {
+			/* If this entry is already lock, we should not modify it right now */
+			if (is_hnat_entry_locked(foe)) {
+				skb_hnat_filled(skb) = HNAT_INFO_FILLED;
+				spin_unlock(&hnat_priv->entry_lock);
+				return 0;
+			}
+
+			/* Final check if the entry is not in UNBIND state,
+			 * we should not modify it right now.
+			 */
+			if (foe->udib1.state != UNBIND) {
+				spin_unlock(&hnat_priv->entry_lock);
+				return 0;
+			}
+
+			/* Keep the entry locked until hook_tx is called */
+			hnat_set_entry_lock(&entry, true);
+
+			/* We must ensure all info has been updated before set to hw */
+			wmb();
+			memcpy(foe, &entry, sizeof(entry));
+
+			skb_hnat_filled(skb) = HNAT_INFO_FILLED;
+			spin_unlock(&hnat_priv->entry_lock);
+		}
+		return 0;
 	}
 
-	wmb();
-	memcpy(foe, &entry, sizeof(entry));
-	/*reset statistic for this entry*/
-	if (hnat_priv->data->per_flow_accounting &&
-	    skb_hnat_entry(skb) < hnat_priv->foe_etry_num &&
-	    skb_hnat_ppe(skb) < CFG_PPE_NUM) {
-		memset(&hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)],
-		       0, sizeof(struct hnat_accounting));
-		hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)].nfct = skb_get_nfct(skb);
+	if (spin_trylock(&hnat_priv->entry_lock)) {
+		/* Final check if the entry is not in UNBIND state,
+		 * we should not modify it right now.
+		 */
+		if (foe->udib1.state != UNBIND) {
+			spin_unlock(&hnat_priv->entry_lock);
+			return 0;
+		}
+
+		/* We must ensure all info has been updated before set to hw */
+		wmb();
+		/* Before entry enter BIND state, write other fields first,
+		 * prevent racing with hardware accesses.
+		 */
+		memcpy(&(foe->ipv6_hnapt.ipv6_sip0), &(entry.ipv6_hnapt.ipv6_sip0),
+		       sizeof(struct foe_entry) - sizeof(entry.bfib1));
+		/* We must ensure all info has been updated before set to hw */
+		wmb();
+		/* After other fields have been written, write info1 to BIND the entry */
+		foe->bfib1 = entry.bfib1;
+
+		/* reset statistic for this entry */
+		if (hnat_priv->data->per_flow_accounting &&
+		    skb_hnat_entry(skb) < hnat_priv->foe_etry_num &&
+		    skb_hnat_ppe(skb) < CFG_PPE_NUM) {
+			memset(&hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)],
+			       0, sizeof(struct hnat_accounting));
+			ct = nf_ct_get(skb, &ctinfo);
+			if (ct) {
+				hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)].zone =
+					ct->zone;
+				hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)].dir =
+					CTINFO2DIR(ctinfo);
+			}
+		}
+
+		spin_unlock(&hnat_priv->entry_lock);
 	}
 
 	return 0;
@@ -1908,11 +1958,27 @@
 {
 	struct foe_entry *hw_entry, entry;
 	struct ethhdr *eth;
+	struct iphdr *iph;
+	struct ipv6hdr *ip6h;
+	struct nf_conn *ct;
+	enum ip_conntrack_info ctinfo;
 
-	if (skb_hnat_alg(skb) ||
-	    !is_magic_tag_valid(skb) || !IS_SPACE_AVAILABLE_HEAD(skb))
+	if (!skb_hnat_is_hashed(skb) || skb_hnat_ppe(skb) >= CFG_PPE_NUM)
 		return NF_ACCEPT;
 
+	hw_entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
+	memcpy(&entry, hw_entry, sizeof(entry));
+
+	if (!is_hnat_entry_locked(&entry))
+		return NF_ACCEPT;
+
+	if (unlikely(entry.bfib1.state != UNBIND))
+		goto check_release_entry_lock;
+
+	if (skb_hnat_alg(skb) || !is_hnat_info_filled(skb) ||
+	    !is_magic_tag_valid(skb) || !IS_SPACE_AVAILABLE_HEAD(skb))
+		goto check_release_entry_lock;
+
 	trace_printk(
 		"[%s]entry=%x reason=%x gmac_no=%x wdmaid=%x rxid=%x wcid=%x bssid=%x\n",
 		__func__, skb_hnat_entry(skb), skb_hnat_reason(skb), gmac_no,
@@ -1921,35 +1987,20 @@
 
 	if ((gmac_no != NR_WDMA0_PORT) && (gmac_no != NR_WDMA1_PORT) &&
 	    (gmac_no != NR_WDMA2_PORT) && (gmac_no != NR_WHNAT_WDMA_PORT))
-		return NF_ACCEPT;
+		goto check_release_entry_lock;
 
 	if (unlikely(!skb_mac_header_was_set(skb)))
-		return NF_ACCEPT;
-
-	if (!skb_hnat_is_hashed(skb))
-		return NF_ACCEPT;
-
-	if (skb_hnat_entry(skb) >= hnat_priv->foe_etry_num ||
-	    skb_hnat_ppe(skb) >= CFG_PPE_NUM)
-		return NF_ACCEPT;
-
-	hw_entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
-	memcpy(&entry, hw_entry, sizeof(entry));
-	if (entry.bfib1.state == BIND)
-		return NF_ACCEPT;
+		goto check_release_entry_lock;
 
 	if (skb_hnat_reason(skb) != HIT_UNBIND_RATE_REACH)
-		return NF_ACCEPT;
-
-	if (!is_hnat_pre_filled(&entry))
-		return NF_ACCEPT;
+		goto check_release_entry_lock;
 
 	eth = eth_hdr(skb);
 
-	/*not bind multicast if PPE mcast not enable*/
+	/* not bind multicast if PPE mcast not enable */
 	if (!hnat_priv->data->mcast) {
 		if (is_multicast_ether_addr(eth->h_dest))
-			return NF_ACCEPT;
+			goto check_release_entry_lock;
 
 		if (IS_IPV4_GRP(&entry))
 			entry.ipv4_hnapt.iblk2.mcast = 0;
@@ -1957,7 +2008,22 @@
 			entry.ipv6_5t_route.iblk2.mcast = 0;
 	}
 
+	/* not bind if IP of entry and skb are different */
+	if (IS_IPV4_HNAPT(&entry)) {
+		iph = ip_hdr(skb);
+		if (!iph ||
+		    entry.ipv4_hnapt.new_sip != ntohl(iph->saddr) ||
+		    entry.ipv4_hnapt.new_dip != ntohl(iph->daddr))
+			goto check_release_entry_lock;
+	} else if (IS_IPV6_5T_ROUTE(&entry)) {
+		ip6h = ipv6_hdr(skb);
+		if (!ip6h ||
+		    !hnat_ipv6_addr_equal(&entry.ipv6_5t_route.ipv6_sip0, &ip6h->saddr) ||
+		    !hnat_ipv6_addr_equal(&entry.ipv6_5t_route.ipv6_dip0, &ip6h->daddr)) {
+			goto check_release_entry_lock;
+		}
+	}
+
-	spin_lock(&hnat_priv->entry_lock);
 	/* Some mt_wifi virtual interfaces, such as apcli,
 	 * will change the smac for specail purpose.
 	 */
@@ -2047,10 +2113,10 @@
 				entry.ipv4_hnapt.iblk2.fqos = 1;
 			}
 		}
-		entry.ipv4_hnapt.iblk2.dp = gmac_no;
+		entry.ipv4_hnapt.iblk2.dp = gmac_no & 0xf;
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
 	} else if (IS_IPV6_HNAPT(&entry) || IS_IPV6_HNAT(&entry)) {
-		entry.ipv6_hnapt.iblk2.dp = gmac_no;
+		entry.ipv6_hnapt.iblk2.dp = gmac_no & 0xf;
 		entry.ipv6_hnapt.iblk2.rxid = skb_hnat_rx_id(skb);
 		entry.ipv6_hnapt.iblk2.winfoi = 1;
 
@@ -2152,18 +2218,43 @@
 				entry.ipv6_5t_route.iblk2.fqos = 1;
 			}
 		}
-		entry.ipv6_5t_route.iblk2.dp = gmac_no;
+		entry.ipv6_5t_route.iblk2.dp = gmac_no & 0xf;
 	}
 
 	entry.bfib1.ttl = 1;
 	entry.bfib1.state = BIND;
-	if (IS_IPV4_GRP(&entry))
-		entry.ipv4_hnapt.act_dp &= ~UDF_HNAT_PRE_FILLED;
-	else
-		entry.ipv6_5t_route.act_dp &= ~UDF_HNAT_PRE_FILLED;
+
+	/* Final check if the entry is not in UNBIND state,
+	 * we should not modify it right now.
+	 */
+	if (hw_entry->udib1.state != UNBIND)
+		goto check_release_entry_lock;
+
+	/* We must ensure all info has been updated before set to hw */
+	wmb();
+	/* Before entry enter BIND state, write other fields first,
+	 * prevent racing with hardware accesses.
+	 */
+	memcpy(&(hw_entry->ipv6_hnapt.ipv6_sip0), &(entry.ipv6_hnapt.ipv6_sip0),
+	       sizeof(struct foe_entry) - sizeof(entry.bfib1));
 	/* We must ensure all info has been updated before set to hw */
 	wmb();
-	memcpy(hw_entry, &entry, sizeof(entry));
+	/* After other fields have been written, write info1 to BIND the entry */
+	hw_entry->bfib1 = entry.bfib1;
+
+	hnat_set_entry_lock(hw_entry, false);
+
+	/* reset statistic for this entry */
+	if (hnat_priv->data->per_flow_accounting) {
+		memset(&hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)],
+			0, sizeof(struct hnat_accounting));
+		ct = nf_ct_get(skb, &ctinfo);
+		if (ct) {
+			hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)].zone = ct->zone;
+			hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)].dir =
+										CTINFO2DIR(ctinfo);
+		}
+	}
 
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
 	if (debug_level >= 7) {
@@ -2218,7 +2309,10 @@
 		}
 	}
 #endif
-	spin_unlock(&hnat_priv->entry_lock);
+	return NF_ACCEPT;
+
+check_release_entry_lock:
+	hnat_check_release_entry_lock(hw_entry);
 	return NF_ACCEPT;
 }
 
@@ -2230,6 +2324,7 @@
 	}
 
 	skb_hnat_alg(skb) = 0;
+	skb_hnat_filled(skb) = 0;
 	skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
 
 	if (skb_hnat_iface(skb) == FOE_MAGIC_WED0)
@@ -2706,9 +2801,7 @@
 		if (fn && fn(skb, arp_dev, &hw_path))
 			break;
 
-		spin_lock(&hnat_priv->entry_lock);
 		skb_to_hnat_info(skb, out, entry, &hw_path);
-		spin_unlock(&hnat_priv->entry_lock);
 		break;
 	case HIT_BIND_KEEPALIVE_DUP_OLD_HDR:
 		/* update hnat count to nf_conntrack by keepalive */
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
index 7892cf2..0c4c7ed 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
@@ -85,6 +85,7 @@
 #define HAS_HQOS_MAGIC_TAG(skb) (qos_toggle && skb->protocol == HQOS_MAGIC_TAG)
 
 #define HNAT_MAGIC_TAG 0x6789
+#define HNAT_INFO_FILLED 0x7
 #define WIFI_INFO_LEN 6
 #define FOE_INFO_LEN (10 + WIFI_INFO_LEN)
 #define IS_SPACE_AVAILABLE_HEAD(skb)                                           \
@@ -134,6 +135,7 @@
 #define set_to_ppe(skb) (HNAT_SKB_CB2(skb)->magic = 0x78681415)
 #define is_from_extge(skb) (HNAT_SKB_CB2(skb)->magic == 0x78786688)
 #define is_magic_tag_valid(skb) (skb_hnat_magic_tag(skb) == HNAT_MAGIC_TAG)
+#define is_hnat_info_filled(skb) (skb_hnat_filled(skb) == HNAT_INFO_FILLED)
 #define set_from_mape(skb) (HNAT_SKB_CB2(skb)->magic = 0x78787788)
 #define is_from_mape(skb) (HNAT_SKB_CB2(skb)->magic == 0x78787788)
 #define is_unreserved_port(hdr)						       \
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
index 745ce8b..8ae7608 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
@@ -689,9 +689,9 @@
 	return 0;
 }
 
-struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id)
+struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, unsigned int id)
 {
-	if (!ss->pcs[id].regmap)
+	if (id >= MTK_MAX_DEVS || !ss->pcs[id].regmap)
 		return NULL;
 
 	return &ss->pcs[id].pcs;
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 b82963b..16ae838 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
@@ -870,9 +870,9 @@
 	return 0;
 }
 
-struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_usxgmii *ss, int id)
+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_usxgmii *ss, unsigned int id)
 {
-	if (!ss->pcs[id].regmap)
+	if (id >= MTK_MAX_DEVS || !ss->pcs[id].regmap)
 		return NULL;
 
 	return &ss->pcs[id].pcs;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3001-mt7622-backport-nf-hw-offload-framework-and-upstream.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3001-mt7622-backport-nf-hw-offload-framework-and-upstream.patch
index 71b7729..b0eb98b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3001-mt7622-backport-nf-hw-offload-framework-and-upstream.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3001-mt7622-backport-nf-hw-offload-framework-and-upstream.patch
@@ -124,7 +124,7 @@
  
 +	if (eth->soc->offload_version) {
 +		err = mtk_ppe_init(&eth->ppe, eth->dev,
-+				   eth->base + MTK_ETH_PPE_BASE, 2);
++				   eth->base + MTK_ETH_PPE_BASE);
 +		if (err)
 +			goto err_free_dev;
 +
@@ -140,7 +140,7 @@
  	.required_clks = MT7623_CLKS_BITMAP,
  	.required_pctl = true,
  	.has_sram = false,
-+	.offload_version = 2,
++	.offload_version = 1,
  	.rss_num = 0,
  	.txrx = {
  		.txd_size = sizeof(struct mtk_tx_dma),
@@ -148,7 +148,7 @@
  	.required_clks = MT7621_CLKS_BITMAP,
  	.required_pctl = false,
  	.has_sram = false,
-+	.offload_version = 2,
++	.offload_version = 1,
  	.rss_num = 0,
  	.txrx = {
  		.txd_size = sizeof(struct mtk_tx_dma),
@@ -164,7 +164,7 @@
  	.required_clks = MT7623_CLKS_BITMAP,
  	.required_pctl = true,
  	.has_sram = false,
-+	.offload_version = 2,
++	.offload_version = 1,
  	.rss_num = 0,
  	.txrx = {
  		.txd_size = sizeof(struct mtk_tx_dma),
@@ -247,7 +247,7 @@
 index 0000000..6965d98
 --- /dev/null
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -0,0 +1,514 @@
+@@ -0,0 +1,513 @@
 +// SPDX-License-Identifier: GPL-2.0-only
 +/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
 +
@@ -616,8 +616,7 @@
 +	return hash;
 +}
 +
-+int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base,
-+		 int version)
++int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base)
 +{
 +	struct mtk_foe_entry *foe;
 +
@@ -626,7 +625,7 @@
 +	 */
 +	ppe->base = base;
 +	ppe->dev = dev;
-+	ppe->version = version;
++	ppe->version = eth->soc->offload_version;
 +
 +	foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe),
 +				  &ppe->foe_phys, GFP_KERNEL);
@@ -767,7 +766,7 @@
 index 0000000..242fb8f
 --- /dev/null
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -0,0 +1,288 @@
+@@ -0,0 +1,287 @@
 +// SPDX-License-Identifier: GPL-2.0-only
 +/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
 +
@@ -1016,8 +1015,7 @@
 +	void *acct_table;
 +};
 +
-+int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base,
-+		 int version);
++int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base);
 +int mtk_ppe_start(struct mtk_ppe *ppe);
 +int mtk_ppe_stop(struct mtk_ppe *ppe);
 +
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3003-add-wed.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3003-add-wed.patch
index 5649350..bfb726a 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3003-add-wed.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3003-add-wed.patch
@@ -1,17 +1,17 @@
-From 357b5ba96ea95a1128858fce7c553a9cbcef7cfa Mon Sep 17 00:00:00 2001
+From dac55eb9abbcf524ce4573db3fbcb480d347adc1 Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Thu, 6 Jun 2024 16:10:49 +0800
+Date: Wed, 26 Jun 2024 23:27:15 +0800
 Subject: [PATCH 04/26] add wed
 
 ---
  arch/arm64/boot/dts/mediatek/mt7622.dtsi      |  32 +-
  drivers/net/ethernet/mediatek/Kconfig         |   4 +
  drivers/net/ethernet/mediatek/Makefile        |   5 +
- drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  65 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h   |   5 +-
- drivers/net/ethernet/mediatek/mtk_ppe.c       | 389 +++++++-
- drivers/net/ethernet/mediatek/mtk_ppe.h       |  90 +-
- .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |   4 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  69 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h   |  15 +-
+ drivers/net/ethernet/mediatek/mtk_ppe.c       | 420 ++++++++-
+ drivers/net/ethernet/mediatek/mtk_ppe.h       |  98 +-
+ .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |   6 +-
  .../net/ethernet/mediatek/mtk_ppe_offload.c   | 167 +++-
  drivers/net/ethernet/mediatek/mtk_wed.c       | 881 ++++++++++++++++++
  drivers/net/ethernet/mediatek/mtk_wed.h       | 135 +++
@@ -21,7 +21,7 @@
  include/linux/netdevice.h                     |   7 +
  include/linux/soc/mediatek/mtk_wed.h          | 131 +++
  net/core/dev.c                                |   4 +
- 17 files changed, 2239 insertions(+), 112 deletions(-)
+ 17 files changed, 2276 insertions(+), 130 deletions(-)
  mode change 100755 => 100644 drivers/net/ethernet/mediatek/Kconfig
  mode change 100755 => 100644 drivers/net/ethernet/mediatek/Makefile
  mode change 100755 => 100644 drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -134,7 +134,7 @@
 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 old mode 100755
 new mode 100644
-index 68453f5..3055e7e
+index 24b5593..15966b8
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 @@ -22,11 +22,13 @@
@@ -151,7 +151,7 @@
  
  #if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE)
  #include "mtk_hnat/nf_hnat_mtk.h"
-@@ -2355,6 +2357,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+@@ -2388,6 +2390,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
  		struct net_device *netdev = NULL;
  		dma_addr_t dma_addr = DMA_MAPPING_ERROR;
  		u64 addr64 = 0;
@@ -159,7 +159,7 @@
  		int mac = 0;
  
  		idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
-@@ -2443,6 +2446,17 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+@@ -2476,6 +2479,17 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
  			skb_checksum_none_assert(skb);
  		skb->protocol = eth_type_trans(skb, netdev);
  
@@ -177,7 +177,7 @@
  		if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
  			if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) {
  				if (trxd.rxd3 & RX_DMA_VTAG_V2)
-@@ -4194,7 +4208,7 @@ static int mtk_stop(struct net_device *dev)
+@@ -4293,7 +4307,7 @@ static int mtk_stop(struct net_device *dev)
  	mtk_dma_free(eth);
  
  	if (eth->soc->offload_version)
@@ -186,7 +186,7 @@
  
  	return 0;
  }
-@@ -5592,6 +5606,22 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5710,6 +5724,22 @@ static int mtk_probe(struct platform_device *pdev)
  		}
  	}
  
@@ -209,7 +209,7 @@
  	if (MTK_HAS_CAPS(eth->soc->caps, MTK_PDMA_INT)) {
  		for (i = 0; i < MTK_PDMA_IRQ_NUM; i++)
  			eth->irq_pdma[i] = platform_get_irq(pdev, i);
-@@ -5608,7 +5638,8 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5726,7 +5756,8 @@ static int mtk_probe(struct platform_device *pdev)
  
  		if (eth->irq_fe[i] < 0) {
  			dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
@@ -219,7 +219,7 @@
  		}
  	}
  
-@@ -5616,12 +5647,15 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5734,12 +5765,15 @@ static int mtk_probe(struct platform_device *pdev)
  		eth->clks[i] = devm_clk_get(eth->dev,
  					    mtk_clks_source_name[i]);
  		if (IS_ERR(eth->clks[i])) {
@@ -238,7 +238,7 @@
  			}
  			eth->clks[i] = NULL;
  		}
-@@ -5632,7 +5666,7 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5750,7 +5784,7 @@ static int mtk_probe(struct platform_device *pdev)
  
  	err = mtk_hw_init(eth, MTK_TYPE_COLD_RESET);
  	if (err)
@@ -247,15 +247,15 @@
  
  	eth->hwlro = MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO);
  
-@@ -5752,14 +5786,15 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5879,14 +5913,15 @@ static int mtk_probe(struct platform_device *pdev)
  	}
  
  	if (eth->soc->offload_version) {
 -		err = mtk_ppe_init(&eth->ppe, eth->dev,
--				   eth->base + MTK_ETH_PPE_BASE, 2);
+-				   eth->base + MTK_ETH_PPE_BASE);
 -		if (err)
 -			goto err_free_dev;
-+		eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2);
++		eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE);
 +		if (!eth->ppe) {
 +			err = -ENOMEM;
 +			goto err_deinit_ppe;
@@ -268,7 +268,7 @@
  	}
  
  	for (i = 0; i < MTK_MAX_DEVS; i++) {
-@@ -5769,7 +5804,7 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5896,7 +5931,7 @@ static int mtk_probe(struct platform_device *pdev)
  		err = register_netdev(eth->netdev[i]);
  		if (err) {
  			dev_err(eth->dev, "error bringing up device\n");
@@ -277,7 +277,7 @@
  		} else
  			netif_info(eth, probe, eth->netdev[i],
  				   "mediatek frame engine at 0x%08lx, irq %d\n",
-@@ -5813,12 +5848,15 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5946,12 +5981,15 @@ static int mtk_probe(struct platform_device *pdev)
  
  	return 0;
  
@@ -294,21 +294,53 @@
  
  	return err;
  }
-@@ -5838,6 +5876,7 @@ static int mtk_remove(struct platform_device *pdev)
+@@ -5971,6 +6009,7 @@ static int mtk_remove(struct platform_device *pdev)
  		phylink_disconnect_phy(mac->phylink);
  	}
  
 +	mtk_wed_exit();
  	mtk_hw_deinit(eth);
  
- 	netif_napi_del(&eth->tx_napi);
+ 	for (i = 0; i < MTK_TX_NAPI_NUM; i++) {
+@@ -6002,6 +6041,7 @@ static const struct mtk_soc_data mt2701_data = {
+ 	.required_pctl = true,
+ 	.has_sram = false,
+ 	.offload_version = 1,
++	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+ 	.rss_num = 0,
+ 	.txrx = {
+ 		.txd_size = sizeof(struct mtk_tx_dma),
+@@ -6023,6 +6063,7 @@ static const struct mtk_soc_data mt7621_data = {
+ 	.required_pctl = false,
+ 	.has_sram = false,
+ 	.offload_version = 1,
++	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+ 	.rss_num = 0,
+ 	.txrx = {
+ 		.txd_size = sizeof(struct mtk_tx_dma),
+@@ -6045,6 +6086,7 @@ static const struct mtk_soc_data mt7622_data = {
+ 	.required_pctl = false,
+ 	.has_sram = false,
+ 	.offload_version = 2,
++	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+ 	.rss_num = 0,
+ 	.txrx = {
+ 		.txd_size = sizeof(struct mtk_tx_dma),
+@@ -6066,6 +6108,7 @@ static const struct mtk_soc_data mt7623_data = {
+ 	.required_pctl = true,
+ 	.has_sram = false,
+ 	.offload_version = 1,
++	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+ 	.rss_num = 0,
+ 	.txrx = {
+ 		.txd_size = sizeof(struct mtk_tx_dma),
 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 old mode 100755
 new mode 100644
-index d5f1a56..0f14aa6
+index c9fb783..b8fd0c9
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -635,6 +635,9 @@
+@@ -638,6 +638,9 @@
  #define RX_DMA_SPORT_MASK       0x7
  #define RX_DMA_SPORT_MASK_V2    0xf
  
@@ -318,7 +350,23 @@
  /* QDMA descriptor txd4 */
  #define TX_DMA_CHKSUM		(0x7 << 29)
  #define TX_DMA_TSO		BIT(28)
-@@ -1954,7 +1957,7 @@ struct mtk_eth {
+@@ -1739,6 +1742,7 @@ struct mtk_reg_map {
+  *				the target SoC
+  * @required_pctl		A bool value to show whether the SoC requires
+  *				the extra setup for those pins used by GMAC.
++ * @foe_entry_size		Foe table entry size.
+  * @txd_size			Tx DMA descriptor size.
+  * @rxd_size			Rx DMA descriptor size.
+  * @rx_dma_l4_valid		Rx DMA valid register mask.
+@@ -1753,6 +1757,7 @@ struct mtk_soc_data {
+ 	u64		required_clks;
+ 	bool		required_pctl;
+ 	u8		offload_version;
++	u16		foe_entry_size;
+ 	netdev_features_t hw_features;
+ 	bool		has_sram;
+ 	struct {
+@@ -1964,7 +1969,7 @@ struct mtk_eth {
  	struct notifier_block		netdevice_notifier;
  	struct timer_list		mtk_dma_monitor_timer;
  
@@ -327,10 +375,25 @@
  	struct rhashtable		flow_table;
  };
  
+@@ -2021,6 +2026,14 @@ extern const struct of_device_id of_mtk_match[];
+ extern u32 mtk_hwlro_stats_ebl;
+ extern u32 dbg_show_level;
+ 
++static inline struct mtk_foe_entry *
++mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
++{
++	const struct mtk_soc_data *soc = ppe->eth->soc;
++
++	return ppe->foe_table + hash * soc->foe_entry_size;
++}
++
+ /* read the hardware status register */
+ void mtk_stats_update_mac(struct mtk_mac *mac);
+ 
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
 old mode 100644
 new mode 100755
-index 6965d98..3b9dc8c
+index 8a1437b..4837a11
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
 @@ -6,9 +6,22 @@
@@ -416,7 +479,7 @@
  		entry->ipv6.ib2 = val;
  		l2 = &entry->ipv6.l2;
  	} else {
-@@ -329,32 +351,168 @@ int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid)
+@@ -329,64 +351,384 @@ int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid)
  	return 0;
  }
  
@@ -481,9 +544,11 @@
 +
 +	hlist_del_init(&entry->list);
 +	if (entry->hash != 0xffff) {
-+		ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE;
-+		ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE,
-+							      MTK_FOE_STATE_INVALID);
++		struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash);
++
++		hwe->ib1 &= ~MTK_FOE_IB1_STATE;
++		hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE,
++				       MTK_FOE_STATE_INVALID);
 +		dma_wmb();
 +		mtk_ppe_cache_clear(ppe);
 +	}
@@ -518,15 +583,25 @@
 -	u32 hash;
 +	struct hlist_node *tmp;
 +	int idle;
-+
+ 
+-	timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP;
+-	entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP;
+-	entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp);
 +	idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
 +	hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_data.list) {
 +		int cur_idle;
 +		u32 ib1;
-+
-+		hwe = &ppe->foe_table[cur->hash];
+ 
+-	hash = mtk_ppe_hash_entry(entry);
+-	hwe = &ppe->foe_table[hash];
+-	if (!mtk_foe_entry_usable(hwe)) {
+-		hwe++;
+-		hash++;
++		hwe = mtk_foe_get_entry(ppe, cur->hash);
 +		ib1 = READ_ONCE(hwe->ib1);
-+
+ 
+-		if (!mtk_foe_entry_usable(hwe))
+-			return -ENOSPC;
 +		if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) {
 +			cur->hash = 0xffff;
 +			__mtk_foe_entry_clear(ppe, cur);
@@ -540,7 +615,7 @@
 +		idle = cur_idle;
 +		entry->data.ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP;
 +		entry->data.ib1 |= hwe->ib1 & MTK_FOE_IB1_BIND_TIMESTAMP;
-+	}
+ 	}
 +}
 +
 +static void
@@ -555,12 +630,12 @@
 +		mtk_flow_entry_update_l2(ppe, entry);
 +		goto out;
 +	}
- 
++
 +	if (entry->hash == 0xffff)
 +		goto out;
 +
-+	hwe = &ppe->foe_table[entry->hash];
-+	memcpy(&foe, hwe, sizeof(foe));
++	hwe = mtk_foe_get_entry(ppe, entry->hash);
++	memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size);
 +	if (!mtk_flow_entry_match(entry, &foe)) {
 +		entry->hash = 0xffff;
 +		goto out;
@@ -576,28 +651,21 @@
 +__mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
 +		       u16 hash)
 +{
++	struct mtk_eth *eth = ppe->eth;
 +	struct mtk_foe_entry *hwe;
 +	u16 timestamp;
 +
 +	timestamp = mtk_eth_timestamp(ppe->eth);
- 	timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP;
- 	entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP;
- 	entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp);
++	timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP;
++	entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP;
++	entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp);
  
--	hash = mtk_ppe_hash_entry(entry);
- 	hwe = &ppe->foe_table[hash];
--	if (!mtk_foe_entry_usable(hwe)) {
--		hwe++;
--		hash++;
--
--		if (!mtk_foe_entry_usable(hwe))
--			return -ENOSPC;
--	}
--
- 	memcpy(&hwe->data, &entry->data, sizeof(hwe->data));
+-	memcpy(&hwe->data, &entry->data, sizeof(hwe->data));
++	hwe = mtk_foe_get_entry(ppe, hash);
++	memcpy(&hwe->data, &entry->data, eth->soc->foe_entry_size - sizeof(hwe->ib1));
  	wmb();
  	hwe->ib1 = entry->ib1;
-@@ -362,32 +520,212 @@ int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
+ 
  	dma_wmb();
  
  	mtk_ppe_cache_clear(ppe);
@@ -635,12 +703,13 @@
 +	spin_unlock_bh(&ppe_lock);
 +
 +	return 0;
-+}
-+
+ }
+ 
+-int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base)
 +static void
 +mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
 +			     u16 hash)
-+{
+ {
 +	struct mtk_flow_entry *flow_info;
 +	struct mtk_foe_entry foe, *hwe;
 +	struct mtk_foe_mac_info *l2;
@@ -658,8 +727,8 @@
 +	hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / 4]);
 +	hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows);
 +
-+	hwe = &ppe->foe_table[hash];
-+	memcpy(&foe, hwe, sizeof(foe));
++	hwe = mtk_foe_get_entry(ppe, hash);
++	memcpy(&foe, hwe, soc->foe_entry_size);
 +	foe.ib1 &= ib1_mask;
 +	foe.ib1 |= entry->data.ib1 & ~ib1_mask;
 +
@@ -680,7 +749,7 @@
 +void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
 +{
 +	struct hlist_head *head = &ppe->foe_flow[hash / 4];
-+	struct mtk_foe_entry *hwe = &ppe->foe_table[hash];
++	struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash);
 +	struct mtk_flow_entry *entry;
 +	struct mtk_foe_bridge key = {};
 +	struct hlist_node *n;
@@ -764,12 +833,10 @@
 +	mtk_flow_entry_update(ppe, entry);
 +
 +	return __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
- }
- 
--int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base,
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
- 		 int version)
- {
++}
++
++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base)
++{
 +	struct device *dev = eth->dev;
  	struct mtk_foe_entry *foe;
 +	struct mtk_ppe *ppe;
@@ -786,9 +853,11 @@
  	ppe->base = base;
 +	ppe->eth = eth;
  	ppe->dev = dev;
- 	ppe->version = version;
+ 	ppe->version = eth->soc->offload_version;
  
- 	foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe),
+-	foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe),
++	foe = dmam_alloc_coherent(ppe->dev,
++				  MTK_PPE_ENTRIES * soc->foe_entry_size,
  				  &ppe->foe_phys, GFP_KERNEL);
  	if (!foe)
 -		return -ENOMEM;
@@ -814,16 +883,33 @@
  }
  
  static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
-@@ -395,7 +733,7 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
+@@ -394,15 +736,21 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
  	static const u8 skip[] = { 12, 25, 38, 51, 76, 89, 102 };
  	int i, k;
  
 -	memset(ppe->foe_table, 0, MTK_PPE_ENTRIES * sizeof(*ppe->foe_table));
-+	memset(ppe->foe_table, 0, MTK_PPE_ENTRIES * sizeof(ppe->foe_table));
++	memset(ppe->foe_table, 0,
++	       MTK_PPE_ENTRIES * ppe->eth->soc->foe_entry_size);
  
  	if (!IS_ENABLED(CONFIG_SOC_MT7621))
  		return;
-@@ -443,7 +781,6 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
+ 
+ 	/* skip all entries that cross the 1024 byte boundary */
+-	for (i = 0; i < MTK_PPE_ENTRIES; i += 128)
+-		for (k = 0; k < ARRAY_SIZE(skip); k++)
+-			ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC;
++	for (i = 0; i < MTK_PPE_ENTRIES; i += 128) {
++		for (k = 0; k < ARRAY_SIZE(skip); k++) {
++			struct mtk_foe_entry *hwe;
++
++			hwe = mtk_foe_get_entry(ppe, i + skip[k]);
++			hwe->ib1 |= MTK_FOE_IB1_STATIC;
++		}
++	}
+ }
+ 
+ int mtk_ppe_start(struct mtk_ppe *ppe)
+@@ -442,7 +790,6 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
  	      MTK_PPE_FLOW_CFG_IP4_NAT |
  	      MTK_PPE_FLOW_CFG_IP4_NAPT |
  	      MTK_PPE_FLOW_CFG_IP4_DSLITE |
@@ -831,8 +917,24 @@
  	      MTK_PPE_FLOW_CFG_IP4_NAT_FRAG;
  	ppe_w32(ppe, MTK_PPE_FLOW_CFG, val);
  
+@@ -487,9 +834,12 @@ int mtk_ppe_stop(struct mtk_ppe *ppe)
+ 	u32 val;
+ 	int i;
+ 
+-	for (i = 0; i < MTK_PPE_ENTRIES; i++)
+-		ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE,
+-						   MTK_FOE_STATE_INVALID);
++	for (i = 0; i < MTK_PPE_ENTRIES; i++) {
++		struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, i);
++
++		hwe->ib1 = FIELD_PREP(MTK_FOE_IB1_STATE,
++				      MTK_FOE_STATE_INVALID);
++	}
+ 
+ 	mtk_ppe_cache_enable(ppe, false);
+ 
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
-index 242fb8f..7f3ddf2 100644
+index 4787447..5891229 100644
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
 @@ -6,6 +6,7 @@
@@ -894,7 +996,16 @@
  	struct mtk_foe_mac_info l2;
  };
  
+@@ -193,6 +191,8 @@ struct mtk_foe_ipv6_6rd {
+ 	struct mtk_foe_mac_info l2;
+ };
+ 
++#define MTK_FOE_ENTRY_V1_SIZE	80
++
+ struct mtk_foe_entry {
+ 	u32 ib1;
+ 
-@@ -235,7 +233,37 @@ enum {
+@@ -235,37 +235,74 @@ enum {
  	MTK_PPE_CPU_REASON_INVALID			= 0x1f,
  };
  
@@ -932,8 +1043,9 @@
  	struct device *dev;
  	void __iomem *base;
  	int version;
-@@ -243,19 +271,36 @@ struct mtk_ppe {
- 	struct mtk_foe_entry *foe_table;
+ 
+-	struct mtk_foe_entry *foe_table;
++	void *foe_table;
  	dma_addr_t foe_phys;
  
 +	u16 foe_check_time[MTK_PPE_ENTRIES];
@@ -944,9 +1056,8 @@
  	void *acct_table;
  };
  
--int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base,
--		 int version);
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version);
+-int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base);
++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base);
 +void mtk_ppe_deinit(struct mtk_eth *eth);
  int mtk_ppe_start(struct mtk_ppe *ppe);
  int mtk_ppe_stop(struct mtk_ppe *ppe);
@@ -959,22 +1070,30 @@
  {
 -	ppe->foe_table[hash].ib1 = 0;
 -	dma_wmb();
+-}
 +	u16 now, diff;
-+
+ 
+-static inline int
+-mtk_foe_entry_timestamp(struct mtk_ppe *ppe, u16 hash)
+-{
+-	u32 ib1 = READ_ONCE(ppe->foe_table[hash].ib1);
 +	if (!ppe)
 +		return;
-+
+ 
+-	if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND)
+-		return -1;
 +	now = (u16)jiffies;
 +	diff = now - ppe->foe_check_time[hash];
 +	if (diff < HZ / 10)
 +		return;
-+
+ 
+-	return FIELD_GET(MTK_FOE_IB1_BIND_TIMESTAMP, ib1);
 +	ppe->foe_check_time[hash] = now;
 +	__mtk_ppe_check_skb(ppe, skb, hash);
  }
  
- static inline int
-@@ -281,8 +326,11 @@ int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry,
+ int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto,
+@@ -280,8 +317,11 @@ int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry,
  int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port);
  int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid);
  int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid);
@@ -989,7 +1108,7 @@
  
  #endif
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-index d4b4823..a591ab1 100644
+index d4b4823..aec99d4 100644
 --- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
 @@ -32,7 +32,6 @@ static const char *mtk_foe_pkt_type_str(int type)
@@ -1000,6 +1119,15 @@
  		[MTK_PPE_PKT_TYPE_IPV4_DSLITE] = "DS-LITE",
  		[MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T] = "IPv6 3T",
  		[MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T] = "IPv6 5T",
+@@ -80,7 +79,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
+ 	int i;
+ 
+ 	for (i = 0; i < MTK_PPE_ENTRIES; i++) {
+-		struct mtk_foe_entry *entry = &ppe->foe_table[i];
++		struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
+ 		struct mtk_foe_mac_info *l2;
+ 		struct mtk_flow_addr_info ai = {};
+ 		unsigned char h_source[ETH_ALEN];
 @@ -207,6 +206,9 @@ int mtk_ppe_debugfs_init(struct mtk_ppe *ppe)
  	struct dentry *root;
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3004-ethernet-update-ppe-from-netsys1-to-netsys2.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3004-ethernet-update-ppe-from-netsys1-to-netsys2.patch
index aef6aa1..a0b98f7 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3004-ethernet-update-ppe-from-netsys1-to-netsys2.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3004-ethernet-update-ppe-from-netsys1-to-netsys2.patch
@@ -1,22 +1,22 @@
-From 07a3ac0ae724c4df67316e01b03432d8ee9f4229 Mon Sep 17 00:00:00 2001
+From 28c15a9659397e5289368d37af5e87a37dcedcf0 Mon Sep 17 00:00:00 2001
 From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
-Date: Mon, 18 Mar 2024 17:56:01 +0800
+Date: Wed, 26 Jun 2024 13:04:15 +0800
 Subject: [PATCH 04/24] ethernet update ppe from netsys1 to netsys2
 
 ---
- drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 19 ++++---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 21 +++++---
  drivers/net/ethernet/mediatek/mtk_eth_soc.h   |  7 ++-
  drivers/net/ethernet/mediatek/mtk_ppe.c       | 29 +++++++++--
  drivers/net/ethernet/mediatek/mtk_ppe.h       | 51 +++++++++++++++++++
  .../net/ethernet/mediatek/mtk_ppe_offload.c   |  8 +++
  drivers/net/ethernet/mediatek/mtk_ppe_regs.h  | 10 ++++
- 6 files changed, 112 insertions(+), 12 deletions(-)
+ 6 files changed, 114 insertions(+), 12 deletions(-)
 
 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index ffaa515..9262227 100644
+index 15966b8..d1cf046 100644
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2447,16 +2447,20 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+@@ -2479,16 +2479,20 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
  			skb_checksum_none_assert(skb);
  		skb->protocol = eth_type_trans(skb, netdev);
  
@@ -44,19 +44,29 @@
  
  		if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
  			if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) {
-@@ -5957,6 +5961,7 @@ static const struct mtk_soc_data mt7986_data = {
+@@ -6151,6 +6155,8 @@ static const struct mtk_soc_data mt7986_data = {
  	.required_clks = MT7986_CLKS_BITMAP,
  	.required_pctl = false,
  	.has_sram = false,
 +	.offload_version = 2,
++	.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
  	.rss_num = 4,
  	.txrx = {
  		.txd_size = sizeof(struct mtk_tx_dma_v2),
+@@ -6172,6 +6178,8 @@ static const struct mtk_soc_data mt7981_data = {
+ 	.required_clks = MT7981_CLKS_BITMAP,
+ 	.required_pctl = false,
+ 	.has_sram = false,
++	.offload_version = 2,
++	.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
+ 	.rss_num = 4,
+ 	.txrx = {
+ 		.txd_size = sizeof(struct mtk_tx_dma_v2),
 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index 41daeb2..910baaf 100644
+index 6fd9702..eaa20ed 100644
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -137,7 +137,7 @@
+@@ -131,7 +131,7 @@
  #define MTK_GDMA_UCS_EN		BIT(20)
  #define MTK_GDMA_STRP_CRC	BIT(16)
  #define MTK_GDMA_TO_PDMA	0x0
@@ -65,7 +75,7 @@
  #define MTK_GDMA_DROP_ALL	0x7777
  
  /* GDM Egress Control Register */
-@@ -680,6 +680,11 @@
+@@ -697,6 +697,11 @@
  #define MTK_RXD4_SRC_PORT	GENMASK(21, 19)
  #define MTK_RXD4_ALG		GENMASK(31, 22)
  
@@ -78,7 +88,7 @@
  #define RX_DMA_L4_VALID		BIT(24)
  #define RX_DMA_L4_VALID_PDMA	BIT(30)		/* when PDMA is used */
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index eeaec1b..e195fb3 100755
+index 82ee67f..66413f2 100755
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
 @@ -122,7 +122,7 @@ static u32 mtk_ppe_hash_entry(struct mtk_foe_entry *e)
@@ -123,7 +133,7 @@
  
  	return 0;
  }
-@@ -746,6 +757,9 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
+@@ -765,6 +776,9 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
  	      MTK_PPE_TB_CFG_AGE_TCP |
  	      MTK_PPE_TB_CFG_AGE_UDP |
  	      MTK_PPE_TB_CFG_AGE_TCP_FIN |
@@ -133,7 +143,7 @@
  	      FIELD_PREP(MTK_PPE_TB_CFG_SEARCH_MISS,
  			 MTK_PPE_SEARCH_MISS_ACTION_FORWARD_BUILD) |
  	      FIELD_PREP(MTK_PPE_TB_CFG_KEEPALIVE,
-@@ -762,15 +776,17 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
+@@ -781,15 +795,17 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
  
  	mtk_ppe_cache_enable(ppe, true);
  
@@ -154,7 +164,7 @@
  	ppe_w32(ppe, MTK_PPE_FLOW_CFG, val);
  
  	val = FIELD_PREP(MTK_PPE_UNBIND_AGE_MIN_PACKETS, 1000) |
-@@ -806,6 +822,11 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
+@@ -825,6 +841,11 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
  
  	ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
  
@@ -167,7 +177,7 @@
  }
  
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
-index 1f5cf1c..7012351 100644
+index 43f2ceb..bae2da5 100644
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
 @@ -8,7 +8,11 @@
@@ -216,7 +226,7 @@
  #define MTK_FOE_IB1_STATE		GENMASK(29, 28)
  #define MTK_FOE_IB1_UDP			BIT(30)
  #define MTK_FOE_IB1_STATIC		BIT(31)
-@@ -44,24 +68,42 @@ enum {
+@@ -44,11 +68,23 @@ enum {
  	MTK_PPE_PKT_TYPE_IPV6_6RD = 7,
  };
  
@@ -240,7 +250,7 @@
  #define MTK_FOE_IB2_WDMA_QID2		GENMASK(13, 12)
  #define MTK_FOE_IB2_WDMA_DEVIDX		BIT(16)
  #define MTK_FOE_IB2_WDMA_WINFO		BIT(17)
- 
+@@ -56,12 +92,18 @@ enum {
  #define MTK_FOE_IB2_PORT_MG		GENMASK(17, 12)
  
  #define MTK_FOE_IB2_PORT_AG		GENMASK(23, 18)
@@ -271,15 +281,20 @@
  };
  
  /* software-only entry type */
-@@ -200,7 +247,11 @@ struct mtk_foe_entry {
+@@ -194,6 +192,7 @@ struct mtk_foe_ipv6_6rd {
+ };
+ 
+ #define MTK_FOE_ENTRY_V1_SIZE	80
++#define MTK_FOE_ENTRY_V2_SIZE	96
+ 
+ struct mtk_foe_entry {
+ 	u32 ib1;
+@@ -201,7 +248,7 @@ struct mtk_foe_entry {
  		struct mtk_foe_ipv4_dslite dslite;
  		struct mtk_foe_ipv6 ipv6;
  		struct mtk_foe_ipv6_6rd ipv6_6rd;
-+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
+-		u32 data[19];
 +		u32 data[23];
-+#else
- 		u32 data[19];
-+#endif
  	};
  };
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3005-flow-offload-add-mkhnat-dual-ppe-new-v2.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3005-flow-offload-add-mkhnat-dual-ppe-new-v2.patch
index 6a4db6e..08b4084 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3005-flow-offload-add-mkhnat-dual-ppe-new-v2.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3005-flow-offload-add-mkhnat-dual-ppe-new-v2.patch
@@ -72,7 +72,7 @@
  	}
  
  	if (eth->soc->offload_version) {
--		eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2);
+-		eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE);
 -		if (!eth->ppe) {
 -			err = -ENOMEM;
 -			goto err_deinit_ppe;
@@ -93,7 +93,7 @@
 +
 +		for (i = 0; i < eth->ppe_num; i++) {
 +			eth->ppe[i] = mtk_ppe_init(eth,
-+					   eth->base + MTK_ETH_PPE_BASE + i * 0x400, 2, i);
++					   eth->base + MTK_ETH_PPE_BASE + i * 0x400, i);
 +			if (!eth->ppe[i]) {
 +				err = -ENOMEM;
 +				goto err_deinit_ppe;
@@ -156,20 +156,19 @@
 index 9dfff1f..854e130 100755
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -696,7 +696,7 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
+@@ -696,6 +696,6 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
  }
  
- struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
--		 int version)
-+		 int version, int id)
+-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base)
++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
  {
  	struct device *dev = eth->dev;
  	struct mtk_foe_entry *foe;
 @@ -715,6 +715,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
  	ppe->eth = eth;
  	ppe->dev = dev;
- 	ppe->version = version;
-+	ppe->id = id;
+ 	ppe->version = eth->soc->offload_version;
++	ppe->id = index;
  
  	foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe),
  				  &ppe->foe_phys, GFP_KERNEL);
@@ -234,8 +233,8 @@
  	void *acct_table;
  };
  
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version);
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int id);
+-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base);
++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
  void mtk_ppe_deinit(struct mtk_eth *eth);
  int mtk_ppe_start(struct mtk_ppe *ppe);
  int mtk_ppe_stop(struct mtk_ppe *ppe);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3010-ethernet-update-ppe-backward-compatible-two-way-hash.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3010-ethernet-update-ppe-backward-compatible-two-way-hash.patch
index d17277a..63b1b0f 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3010-ethernet-update-ppe-backward-compatible-two-way-hash.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3010-ethernet-update-ppe-backward-compatible-two-way-hash.patch
@@ -1,92 +1,99 @@
-From 7feee53fdfd481fc2beb02739ccd0e87f1c96b7a Mon Sep 17 00:00:00 2001
-From: Bc-bocun Chen <bc-bocun.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 11:07:14 +0800
-Subject: [PATCH 10/24] ethernet-update-ppe-backward-compatible-two-way-hash
+From ec9280d5002b6b69179102aa659d0c506c97b466 Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Fri, 7 Jun 2024 10:39:51 +0800
+Subject: [PATCH 1/2] ethernet update ppe backward compatible two way hash
 
 ---
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 ++++++++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h |  1 +
- drivers/net/ethernet/mediatek/mtk_ppe.c     | 24 ++++++++++++++-------
- drivers/net/ethernet/mediatek/mtk_ppe.h     |  5 +++--
- 4 files changed, 29 insertions(+), 11 deletions(-)
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +++++++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  2 ++
+ drivers/net/ethernet/mediatek/mtk_ppe.c     | 26 ++++++++++++++-------
+ drivers/net/ethernet/mediatek/mtk_ppe.h     |  2 +-
+ 4 files changed, 30 insertions(+), 10 deletions(-)
 
 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index a24b223..e8837b6 100644
+index f5b2d22..d086fab 100644
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5799,7 +5799,8 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5826,7 +5826,8 @@ static int mtk_probe(struct platform_device *pdev)
  
  		for (i = 0; i < eth->ppe_num; i++) {
  			eth->ppe[i] = mtk_ppe_init(eth,
--					   eth->base + MTK_ETH_PPE_BASE + i * 0x400, 2, i);
+-					   eth->base + MTK_ETH_PPE_BASE + i * 0x400, i);
 +						   eth->base + MTK_ETH_PPE_BASE + i * 0x400,
-+						   2, eth->soc->hash_way, i);
++						   i);
  			if (!eth->ppe[i]) {
  				err = -ENOMEM;
- 				goto err_free_dev;
-@@ -5913,6 +5914,7 @@ static const struct mtk_soc_data mt2701_data = {
- 	.required_clks = MT7623_CLKS_BITMAP,
+ 				goto err_deinit_ppe;
+@@ -5946,6 +5947,7 @@ static const struct mtk_soc_data mt2701_data = {
  	.required_pctl = true,
  	.has_sram = false,
-+	.hash_way = 2,
- 	.offload_version = 2,
+ 	.offload_version = 1,
++	.hash_offset = 2,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
  	.rss_num = 0,
  	.txrx = {
-@@ -5931,6 +5933,7 @@ static const struct mtk_soc_data mt7621_data = {
- 	.required_clks = MT7621_CLKS_BITMAP,
+@@ -5967,6 +5969,7 @@ static const struct mtk_soc_data mt7621_data = {
  	.required_pctl = false,
  	.has_sram = false,
-+	.hash_way = 2,
- 	.offload_version = 2,
+ 	.offload_version = 1,
++	.hash_offset = 2,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
  	.rss_num = 0,
  	.txrx = {
-@@ -5950,6 +5953,7 @@ static const struct mtk_soc_data mt7622_data = {
- 	.required_clks = MT7622_CLKS_BITMAP,
+@@ -5989,6 +5992,7 @@ static const struct mtk_soc_data mt7622_data = {
  	.required_pctl = false,
  	.has_sram = false,
-+	.hash_way = 2,
  	.offload_version = 2,
++	.hash_offset = 2,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
  	.rss_num = 0,
  	.txrx = {
-@@ -5968,6 +5972,7 @@ static const struct mtk_soc_data mt7623_data = {
- 	.required_clks = MT7623_CLKS_BITMAP,
+@@ -6010,6 +6014,7 @@ static const struct mtk_soc_data mt7623_data = {
  	.required_pctl = true,
  	.has_sram = false,
-+	.hash_way = 2,
- 	.offload_version = 2,
+ 	.offload_version = 1,
++	.hash_offset = 2,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
  	.rss_num = 0,
  	.txrx = {
-@@ -6005,6 +6010,7 @@ static const struct mtk_soc_data mt7986_data = {
- 	.required_clks = MT7986_CLKS_BITMAP,
+@@ -6053,6 +6058,7 @@ static const struct mtk_soc_data mt7986_data = {
  	.required_pctl = false,
  	.has_sram = false,
-+	.hash_way = 4,
  	.offload_version = 2,
++	.hash_offset = 4,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
  	.rss_num = 4,
  	.txrx = {
-@@ -6024,6 +6030,8 @@ static const struct mtk_soc_data mt7981_data = {
- 	.required_clks = MT7981_CLKS_BITMAP,
+@@ -6075,6 +6081,7 @@ static const struct mtk_soc_data mt7981_data = {
  	.required_pctl = false,
  	.has_sram = false,
-+	.hash_way = 4,
-+	.offload_version = 2,
+ 	.offload_version = 2,
++	.hash_offset = 4,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
  	.rss_num = 4,
  	.txrx = {
- 		.txd_size = sizeof(struct mtk_tx_dma_v2),
 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index 9099dea..b4f04e2 100644
+index 5019216..8984d38 100644
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1732,6 +1732,7 @@ struct mtk_soc_data {
- 	u64		caps;
+@@ -1739,6 +1739,7 @@ struct mtk_reg_map {
+  *				the target SoC
+  * @required_pctl		A bool value to show whether the SoC requires
+  *				the extra setup for those pins used by GMAC.
++ * @hash_offset			Flow table hash offset.
+  * @foe_entry_size		Foe table entry size.
+  * @txd_size			Tx DMA descriptor size.
+  * @rxd_size			Rx DMA descriptor size.
+@@ -1753,6 +1754,7 @@ struct mtk_soc_data {
  	u64		required_clks;
  	bool		required_pctl;
-+	u8		hash_way;
  	u8		offload_version;
++	u8		hash_offset;
+ 	u16		foe_entry_size;
  	netdev_features_t hw_features;
  	bool		has_sram;
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index c9ee505..569bf34 100755
+index b69de11..550ed7c 100755
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
 @@ -88,7 +88,7 @@ static void mtk_ppe_cache_enable(struct mtk_ppe *ppe, bool enable)
@@ -94,7 +101,7 @@
  }
  
 -static u32 mtk_ppe_hash_entry(struct mtk_foe_entry *e)
-+static u32 mtk_ppe_hash_entry(struct mtk_ppe *ppe, struct mtk_foe_entry *e)
++static u32 mtk_ppe_hash_entry(struct mtk_eth *eth, struct mtk_foe_entry *e)
  {
  	u32 hv1, hv2, hv3;
  	u32 hash;
@@ -103,89 +110,87 @@
  	hash ^= hv1 ^ hv2 ^ hv3;
  	hash ^= hash >> 16;
 -	hash <<= 2;
-+	hash <<= (ffs(ppe->way) - 1);
++	hash <<= (ffs(eth->soc->hash_offset) - 1);
  	hash &= MTK_PPE_ENTRIES - 1;
  
  	return hash;
-@@ -557,10 +557,10 @@ int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
+@@ -551,16 +551,17 @@ mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
+ 
+ int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
+ {
++	const struct mtk_soc_data *soc = ppe->eth->soc;
+ 	int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1);
+ 	u32 hash;
+ 
  	if (type == MTK_PPE_PKT_TYPE_BRIDGE)
  		return mtk_foe_entry_commit_l2(ppe, entry);
  
 -	hash = mtk_ppe_hash_entry(&entry->data);
-+	hash = mtk_ppe_hash_entry(ppe, &entry->data);
++	hash = mtk_ppe_hash_entry(ppe->eth, &entry->data);
  	entry->hash = 0xffff;
  	spin_lock_bh(&ppe_lock);
 -	hlist_add_head(&entry->list, &ppe->foe_flow[hash / 4]);
-+	hlist_add_head(&entry->list, &ppe->foe_flow[hash / ppe->way]);
++	hlist_add_head(&entry->list, &ppe->foe_flow[hash / soc->hash_offset]);
  	spin_unlock_bh(&ppe_lock);
  
  	return 0;
-@@ -584,7 +584,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
+@@ -570,6 +571,7 @@ static void
+ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
+ 			     u16 hash)
+ {
++	const struct mtk_soc_data *soc = ppe->eth->soc;
+ 	struct mtk_flow_entry *flow_info;
+ 	struct mtk_foe_entry foe, *hwe;
+ 	struct mtk_foe_mac_info *l2;
+@@ -584,7 +586,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
  	flow_info->l2_data.base_flow = entry;
  	flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW;
  	flow_info->hash = hash;
 -	hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / 4]);
-+	hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / ppe->way]);
++	hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / soc->hash_offset]);
  	hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows);
  
  	hwe = &ppe->foe_table[hash];
-@@ -608,7 +608,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
+@@ -608,7 +610,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
  
  void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
  {
 -	struct hlist_head *head = &ppe->foe_flow[hash / 4];
-+	struct hlist_head *head = &ppe->foe_flow[hash / ppe->way];
- 	struct mtk_foe_entry *hwe = &ppe->foe_table[hash];
++	const struct mtk_soc_data *soc = ppe->eth->soc;
++	struct hlist_head *head = &ppe->foe_flow[hash / soc->hash_offset];
+ 	struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash);
  	struct mtk_flow_entry *entry;
  	struct mtk_foe_bridge key = {};
-@@ -695,12 +695,12 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
- 	return __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
- }
+@@ -695,9 +698,11 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
  
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
--		 int version, int id)
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int way, int id)
+ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
  {
++	const struct mtk_soc_data *soc = eth->soc;
  	struct device *dev = eth->dev;
  	struct mtk_foe_entry *foe;
  	struct mtk_ppe *ppe;
-+	struct hlist_head *flow;
++	u32 foe_flow_size;
  
  	ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL);
  	if (!ppe)
-@@ -715,6 +715,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
- 	ppe->eth = eth;
- 	ppe->dev = dev;
- 	ppe->version = version;
-+	ppe->way = way;
- 	ppe->id = id;
- 
- 	foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe),
-@@ -724,6 +725,13 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
+@@ -724,6 +728,12 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
  
  	ppe->foe_table = foe;
  
-+	flow = devm_kzalloc(dev, (MTK_PPE_ENTRIES / way) * sizeof(*flow),
-+			    GFP_KERNEL);
-+	if (!flow)
++	foe_flow_size = (MTK_PPE_ENTRIES / soc->hash_offset) *
++			sizeof(*ppe->foe_flow);
++	ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL);
++	if (!ppe->foe_flow)
 +		goto err_free_l2_flows;
 +
-+	ppe->foe_flow = flow;
-+
  	return ppe;
- }
  
+ err_free_l2_flows:
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
-index 86bbac8..feb1a4a 100644
+index 8223710..017e6c5 100644
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -322,19 +322,20 @@ struct mtk_ppe {
- 	void __iomem *base;
- 	int version;
- 	int id;
-+	int way;
- 
- 	struct mtk_foe_entry *foe_table;
+@@ -327,7 +327,7 @@ struct mtk_ppe {
  	dma_addr_t foe_phys;
  
  	u16 foe_check_time[MTK_PPE_ENTRIES];
@@ -194,14 +199,6 @@
  
  	struct rhashtable l2_flows;
  
- 	void *acct_table;
- };
- 
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int id);
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int way, int id);
- void mtk_ppe_deinit(struct mtk_eth *eth);
- int mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
 -- 
 2.18.0
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3011-flow-offload-add-mtkhnat-flow-accounting.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3011-flow-offload-add-mtkhnat-flow-accounting.patch
index 0f76950..1f06821 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3011-flow-offload-add-mtkhnat-flow-accounting.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3011-flow-offload-add-mtkhnat-flow-accounting.patch
@@ -1,66 +1,56 @@
-From 4eaba588e0c730d6188f5f1b667a55d1b9ca0fe6 Mon Sep 17 00:00:00 2001
-From: Bc-bocun Chen <bc-bocun.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 11:09:23 +0800
-Subject: [PATCH 11/24] flow-offload-add-mtkhnat-flow-accounting
+From df1552121137b5c0bda1abdef64ee225739a13ba Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Fri, 7 Jun 2024 12:31:14 +0800
+Subject: [PATCH 2/2] flow-offload-add-mtkhnat-flow-accounting
 
 ---
- drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  11 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c   |   7 +
  drivers/net/ethernet/mediatek/mtk_eth_soc.h   |   1 +
- drivers/net/ethernet/mediatek/mtk_ppe.c       | 131 +++++++++++++++++-
- drivers/net/ethernet/mediatek/mtk_ppe.h       |  23 ++-
+ drivers/net/ethernet/mediatek/mtk_ppe.c       | 129 +++++++++++++++++-
+ drivers/net/ethernet/mediatek/mtk_ppe.h       |  20 +++
  .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |  10 +-
  .../net/ethernet/mediatek/mtk_ppe_offload.c   |   7 +
  drivers/net/ethernet/mediatek/mtk_ppe_regs.h  |  14 ++
- net/netfilter/xt_FLOWOFFLOAD.c                |   2 +-
- 8 files changed, 191 insertions(+), 8 deletions(-)
+ net/netfilter/xt_FLOWOFFLOAD.c                |   3 +-
+ 8 files changed, 186 insertions(+), 5 deletions(-)
 
 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index e8837b6..9cd306d 100644
+index d086fab..88af4b4 100644
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5800,7 +5800,8 @@ static int mtk_probe(struct platform_device *pdev)
- 		for (i = 0; i < eth->ppe_num; i++) {
- 			eth->ppe[i] = mtk_ppe_init(eth,
- 						   eth->base + MTK_ETH_PPE_BASE + i * 0x400,
--						   2, eth->soc->hash_way, i);
-+						   2, eth->soc->hash_way, i,
-+						   eth->soc->has_accounting);
- 			if (!eth->ppe[i]) {
- 				err = -ENOMEM;
- 				goto err_free_dev;
-@@ -5914,6 +5915,7 @@ static const struct mtk_soc_data mt2701_data = {
- 	.required_clks = MT7623_CLKS_BITMAP,
- 	.required_pctl = true,
+@@ -5948,6 +5948,7 @@ static const struct mtk_soc_data mt2701_data = {
  	.has_sram = false,
+ 	.offload_version = 1,
+ 	.hash_offset = 2,
 +	.has_accounting = false,
- 	.hash_way = 2,
- 	.offload_version = 2,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
  	.rss_num = 0,
-@@ -5933,6 +5935,7 @@ static const struct mtk_soc_data mt7621_data = {
- 	.required_clks = MT7621_CLKS_BITMAP,
- 	.required_pctl = false,
+ 	.txrx = {
+@@ -5970,6 +5971,7 @@ static const struct mtk_soc_data mt7621_data = {
  	.has_sram = false,
+ 	.offload_version = 1,
+ 	.hash_offset = 2,
 +	.has_accounting = false,
- 	.hash_way = 2,
- 	.offload_version = 2,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
  	.rss_num = 0,
-@@ -5953,6 +5956,7 @@ static const struct mtk_soc_data mt7622_data = {
- 	.required_clks = MT7622_CLKS_BITMAP,
- 	.required_pctl = false,
+ 	.txrx = {
+@@ -5993,6 +5995,7 @@ static const struct mtk_soc_data mt7622_data = {
  	.has_sram = false,
-+	.has_accounting = true,
- 	.hash_way = 2,
  	.offload_version = 2,
+ 	.hash_offset = 2,
++	.has_accounting = true,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
  	.rss_num = 0,
-@@ -5972,6 +5976,7 @@ static const struct mtk_soc_data mt7623_data = {
- 	.required_clks = MT7623_CLKS_BITMAP,
- 	.required_pctl = true,
+ 	.txrx = {
+@@ -6015,6 +6018,7 @@ static const struct mtk_soc_data mt7623_data = {
  	.has_sram = false,
+ 	.offload_version = 1,
+ 	.hash_offset = 2,
 +	.has_accounting = false,
- 	.hash_way = 2,
- 	.offload_version = 2,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
  	.rss_num = 0,
-@@ -5992,6 +5997,7 @@ static const struct mtk_soc_data mt7629_data = {
+ 	.txrx = {
+@@ -6036,6 +6040,7 @@ static const struct mtk_soc_data mt7629_data = {
  	.required_clks = MT7629_CLKS_BITMAP,
  	.required_pctl = false,
  	.has_sram = false,
@@ -68,36 +58,28 @@
  	.rss_num = 0,
  	.txrx = {
  		.txd_size = sizeof(struct mtk_tx_dma),
-@@ -6010,6 +6016,7 @@ static const struct mtk_soc_data mt7986_data = {
- 	.required_clks = MT7986_CLKS_BITMAP,
- 	.required_pctl = false,
+@@ -6059,6 +6064,7 @@ static const struct mtk_soc_data mt7986_data = {
  	.has_sram = false,
-+	.has_accounting = true,
- 	.hash_way = 4,
  	.offload_version = 2,
+ 	.hash_offset = 4,
++	.has_accounting = true,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
  	.rss_num = 4,
-@@ -6030,6 +6037,7 @@ static const struct mtk_soc_data mt7981_data = {
- 	.required_clks = MT7981_CLKS_BITMAP,
- 	.required_pctl = false,
+ 	.txrx = {
+@@ -6082,6 +6088,7 @@ static const struct mtk_soc_data mt7981_data = {
  	.has_sram = false,
-+	.has_accounting = true,
- 	.hash_way = 4,
  	.offload_version = 2,
+ 	.hash_offset = 4,
++	.has_accounting = true,
+ 	.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
  	.rss_num = 4,
-@@ -6067,6 +6075,7 @@ static const struct mtk_soc_data rt5350_data = {
- 	.required_clks = MT7628_CLKS_BITMAP,
- 	.required_pctl = false,
- 	.has_sram = false,
-+	.has_accounting = false,
- 	.rss_num = 0,
  	.txrx = {
- 		.txd_size = sizeof(struct mtk_tx_dma),
 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index b4f04e2..5f90765 100644
+index 8984d38..1c3b64e 100644
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1736,6 +1736,7 @@ struct mtk_soc_data {
- 	u8		offload_version;
+@@ -1757,6 +1757,7 @@ struct mtk_soc_data {
+ 	u8		hash_offset;
  	netdev_features_t hw_features;
  	bool		has_sram;
 +	bool		has_accounting;
@@ -105,7 +87,7 @@
  		u32	txd_size;
  		u32	rxd_size;
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index 569bf34..94e03b2 100755
+index 550ed7c..9db417c 100755
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
 @@ -74,6 +74,46 @@ static int mtk_ppe_wait_busy(struct mtk_ppe *ppe)
@@ -191,7 +173,7 @@
  	dma_wmb();
  
  	mtk_ppe_cache_clear(ppe);
-@@ -637,8 +699,6 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
+@@ -640,8 +702,6 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
  		}
  
  		if (found || !mtk_flow_entry_match(entry, hwe)) {
@@ -200,11 +182,10 @@
  			continue;
  		}
  
-@@ -695,12 +755,44 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
+@@ -698,12 +758,44 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
  	return __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
  }
  
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int way, int id)
 +struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, struct mtk_foe_accounting *diff)
 +{
 +	struct mtk_foe_accounting *acct, *acct_updated;
@@ -234,29 +215,29 @@
 +	return acct;
 +}
 +
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int way, int id,
-+			     int accounting)
+ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
  {
++	bool accounting = eth->soc->has_accounting;
+ 	const struct mtk_soc_data *soc = eth->soc;
  	struct device *dev = eth->dev;
  	struct mtk_foe_entry *foe;
 +	struct mtk_mib_entry *mib;
  	struct mtk_ppe *ppe;
- 	struct hlist_head *flow;
 +	struct mtk_foe_accounting *acct, *acct_updated;
+ 	u32 foe_flow_size;
  
  	ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL);
- 	if (!ppe)
-@@ -717,6 +809,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int versio
- 	ppe->version = version;
- 	ppe->way = way;
- 	ppe->id = id;
+@@ -720,6 +812,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int versio
+ 	ppe->dev = dev;
+ 	ppe->version = eth->soc->offload_version;
+ 	ppe->id = index;
 +	ppe->accounting = accounting;
  
  	foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe),
  				  &ppe->foe_phys, GFP_KERNEL);
-@@ -732,6 +825,31 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int versio
- 
- 	ppe->foe_flow = flow;
+@@ -734,6 +827,31 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int versio
+ 	if (!ppe->foe_flow)
+ 		goto err_free_l2_flows;
  
 +	if (accounting) {
 +		mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib),
@@ -284,9 +265,9 @@
 +	}
 +
  	return ppe;
- }
  
-@@ -834,6 +952,13 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
+ err_free_l2_flows:
+@@ -851,6 +969,13 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
  	ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
  #endif
  
@@ -301,10 +282,10 @@
  }
  
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
-index feb1a4a..86288b0 100644
+index 017e6c5..dea1b5a 100644
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -316,6 +316,20 @@ struct mtk_flow_entry {
+@@ -316,22 +316,41 @@ struct mtk_flow_entry {
  	unsigned long cookie;
  };
  
@@ -325,13 +306,12 @@
  struct mtk_ppe {
  	struct mtk_eth *eth;
  	struct device *dev;
-@@ -323,19 +337,25 @@ struct mtk_ppe {
+ 	void __iomem *base;
  	int version;
  	int id;
- 	int way;
 +	int accounting;
  
- 	struct mtk_foe_entry *foe_table;
+ 	void *foe_table;
  	dma_addr_t foe_phys;
  
 +	struct mtk_mib_entry *mib_table;
@@ -346,13 +326,8 @@
 +	void *acct_updated_table;
  };
  
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int way, int id);
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int way, int id,
-+			     int accounting);
- void mtk_ppe_deinit(struct mtk_eth *eth);
- int mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
-@@ -386,5 +406,6 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
+ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
+@@ -386,5 +405,6 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
  int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
  void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
  int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
@@ -446,15 +421,23 @@
  #define MTK_PPE_MIB_CACHE_CTL_EN		BIT(0)
  #define MTK_PPE_MIB_CACHE_CTL_FLUSH		BIT(2)
 diff --git a/net/netfilter/xt_FLOWOFFLOAD.c b/net/netfilter/xt_FLOWOFFLOAD.c
-index e4c7db9..aae37f5 100644
+index 9120c60..0676b78 100644
 --- a/net/netfilter/xt_FLOWOFFLOAD.c
 +++ b/net/netfilter/xt_FLOWOFFLOAD.c
-@@ -772,7 +772,7 @@ static int __init xt_flowoffload_tg_init(void)
+@@ -734,6 +734,7 @@ static int init_flowtable(struct xt_flowoffload_table *tbl)
+ {
+ 	INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work);
+ 	tbl->ft.type = &flowtable_inet;
++	tbl->ft.flags = NF_FLOWTABLE_COUNTER;
+ 
+ 	return nf_flow_table_init(&tbl->ft);
+ }
+@@ -752,7 +753,7 @@ static int __init xt_flowoffload_tg_init(void)
  	if (ret)
  		goto cleanup;
  
 -	flowtable[1].ft.flags = NF_FLOWTABLE_HW_OFFLOAD;
-+	flowtable[1].ft.flags = NF_FLOWTABLE_HW_OFFLOAD | NF_FLOWTABLE_COUNTER;
++	flowtable[1].ft.flags |= NF_FLOWTABLE_HW_OFFLOAD;
  
  	ret = xt_register_target(&offload_tg_reg);
  	if (ret)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3012-flow-offload-add-mtkhnat-qdma-qos.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3012-flow-offload-add-mtkhnat-qdma-qos.patch
index 003cb9d..85ea255 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3012-flow-offload-add-mtkhnat-qdma-qos.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3012-flow-offload-add-mtkhnat-qdma-qos.patch
@@ -122,11 +122,10 @@
  /* QDMA TX Forward CPU Pointer Register */
  #define MTK_QTX_CTX_PTR		(QDMA_BASE +0x300)
  
-@@ -578,6 +583,11 @@
- 
+@@ -578,6 +583,10 @@ 
  /* QDMA TX Scheduler Rate Control Register */
  #define MTK_QDMA_TX_4SCH_BASE(x)	(QDMA_BASE + 0x398 + (((x) >> 1) * 0x4))
-+#define MTK_QDMA_TX_SCH_MASK		GENMASK(15, 0)
+ #define MTK_QDMA_TX_SCH_MASK		GENMASK(15, 0)
 +#define MTK_QDMA_TX_SCH_MAX_WFQ		BIT(15)
 +#define MTK_QDMA_TX_SCH_RATE_EN		BIT(11)
 +#define MTK_QDMA_TX_SCH_RATE_MAN	GENMASK(10, 4)
@@ -202,12 +201,12 @@
  		enable * MTK_PPE_CACHE_CTL_EN);
  }
  
--static u32 mtk_ppe_hash_entry(struct mtk_ppe *ppe, struct mtk_foe_entry *e)
-+u32 mtk_ppe_hash_entry(struct mtk_ppe *ppe, struct mtk_foe_entry *e)
+-static u32 mtk_ppe_hash_entry(struct mtk_eth *eth, struct mtk_foe_entry *e)
++u32 mtk_ppe_hash_entry(struct mtk_eth *eth, struct mtk_foe_entry *e)
  {
  	u32 hv1, hv2, hv3;
  	u32 hash;
-@@ -420,12 +420,58 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
+@@ -420,12 +420,59 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
  	return 0;
  }
  
@@ -245,13 +244,14 @@
 +
 +int mtk_foe_entry_set_sp(struct mtk_ppe *ppe, struct mtk_foe_entry *entry)
 +{
++	struct mtk_eth *eth = ppe->eth;
 +	struct mtk_foe_entry *hwe;
 +	u32 hash, sp = 0;
 +	int i;
 +
-+	hash = mtk_ppe_hash_entry(ppe, entry);
-+	for (i = 0; i < ppe->way; i++) {
-+		hwe = &ppe->foe_table[hash + i];
++	hash = mtk_ppe_hash_entry(eth, entry);
++	for (i = 0; i < eth->soc->hash_offset; i++) {
++		hwe = mtk_foe_get_entry(ppe, hash + i);
 +		if (mtk_foe_entry_match(hwe, entry)) {
 +			sp = mtk_get_ib1_sp(ppe->eth, hwe);
 +			break;
@@ -281,7 +281,7 @@
  void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
  int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
  struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, struct mtk_foe_accounting *diff);
-+u32 mtk_ppe_hash_entry(struct mtk_ppe *ppe, struct mtk_foe_entry *e);
++u32 mtk_ppe_hash_entry(struct mtk_eth *eth, struct mtk_foe_entry *e);
  
  #endif
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3015-ethernet-update-ppe-from-netsys2-to-netsys3.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3015-ethernet-update-ppe-from-netsys2-to-netsys3.patch
index 04ef1f6..e2bbd2f 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3015-ethernet-update-ppe-from-netsys2-to-netsys3.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3015-ethernet-update-ppe-from-netsys2-to-netsys3.patch
@@ -1,22 +1,22 @@
-From 2914bec639e2749bbd6d021639b8c3d8c0a2490e Mon Sep 17 00:00:00 2001
+From 4b98f0b6cc16e75436c59a161edca25d3bf464cc Mon Sep 17 00:00:00 2001
 From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
-Date: Mon, 18 Mar 2024 16:35:07 +0800
+Date: Wed, 26 Jun 2024 14:33:27 +0800
 Subject: [PATCH 15/24] ethernet-update-ppe-from-netsys2-to-netsys3
 
 ---
- drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  8 +++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  9 ++++-
  drivers/net/ethernet/mediatek/mtk_eth_soc.h   |  7 ++--
- drivers/net/ethernet/mediatek/mtk_ppe.c       | 35 ++++++++++++++---
- drivers/net/ethernet/mediatek/mtk_ppe.h       | 38 ++++++++++++++++---
+ drivers/net/ethernet/mediatek/mtk_ppe.c       | 35 +++++++++++++++---
+ drivers/net/ethernet/mediatek/mtk_ppe.h       | 37 ++++++++++++++++---
  .../net/ethernet/mediatek/mtk_ppe_offload.c   |  6 ++-
  drivers/net/ethernet/mediatek/mtk_ppe_regs.h  |  7 ++++
  6 files changed, 82 insertions(+), 19 deletions(-)
 
 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index 1be1d43..04968da 100644
+index 42d8cbf..2cc3e4b 100644
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2441,7 +2441,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+@@ -2479,7 +2479,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
  			skb_checksum_none_assert(skb);
  		skb->protocol = eth_type_trans(skb, netdev);
  
@@ -25,31 +25,32 @@
  		hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY_V2;
  		reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON_V2, trxd.rxd5);
  		if (hash != MTK_RXD5_FOE_ENTRY_V2)
-@@ -5829,7 +5829,8 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5953,7 +5953,8 @@ static int mtk_probe(struct platform_device *pdev)
  
  		for (i = 0; i < eth->ppe_num; i++) {
  			eth->ppe[i] = mtk_ppe_init(eth,
 -						   eth->base + MTK_ETH_PPE_BASE + i * 0x400,
 +						   eth->base + MTK_ETH_PPE_BASE +
 +						   (i == 2 ? 0xC00 : i * 0x400),
- 						   2, eth->soc->hash_way, i,
- 						   eth->soc->has_accounting);
+ 						   i);
  			if (!eth->ppe[i]) {
-@@ -6120,6 +6121,9 @@ static const struct mtk_soc_data mt7988_data = {
+ 				err = -ENOMEM;
+@@ -6262,6 +6263,10 @@ static const struct mtk_soc_data mt7988_data = {
  	.required_clks = MT7988_CLKS_BITMAP,
  	.required_pctl = false,
  	.has_sram = true,
-+	.has_accounting = true,
-+	.hash_way = 4,
 +	.offload_version = 2,
++	.hash_offset = 4,
++	.has_accounting = true,
++	.foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
  	.rss_num = 4,
  	.txrx = {
  		.txd_size = sizeof(struct mtk_tx_dma_v2),
 diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index 6ad3468..e882436 100644
+index 4d74144..09becb8 100644
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -136,9 +136,10 @@
+@@ -131,9 +131,10 @@
  #define MTK_GDMA_UCS_EN		BIT(20)
  #define MTK_GDMA_STRP_CRC	BIT(16)
  #define MTK_GDMA_TO_PDMA	0x0
@@ -61,7 +62,7 @@
  #else
  #define MTK_GDMA_TO_PPE0	0x4444
  #endif
-@@ -2023,14 +2024,14 @@ extern u32 dbg_show_level;
+@@ -2059,14 +2060,14 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
  
  static inline void mtk_set_ib1_sp(struct mtk_eth *eth, struct mtk_foe_entry *foe, u32 val)
  {
@@ -79,7 +80,7 @@
  #else
  	return 0;
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index 8388f65..184e29d 100755
+index ba68bfb..ebcdc11 100755
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
 @@ -91,7 +91,7 @@ static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe)
@@ -150,7 +151,7 @@
  
  	return 0;
  }
-@@ -922,13 +938,16 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
+@@ -949,13 +965,16 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
  	mtk_ppe_init_foe_table(ppe);
  	ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys);
  
@@ -169,7 +170,7 @@
  	      MTK_PPE_TB_CFG_INFO_SEL |
  #endif
  	      FIELD_PREP(MTK_PPE_TB_CFG_SEARCH_MISS,
-@@ -988,12 +1007,16 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
+@@ -1015,12 +1034,16 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
  	      MTK_PPE_GLO_CFG_IP4_L4_CS_DROP |
  	      MTK_PPE_GLO_CFG_IP4_CS_DROP |
  	      MTK_PPE_GLO_CFG_MCAST_TB_EN |
@@ -188,7 +189,7 @@
  	ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
  #endif
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
-index 5ab864f..5529d64 100644
+index 4beac4f..5538c1b 100644
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
 @@ -8,7 +8,10 @@
@@ -260,17 +261,23 @@
  	u16 minfo;
  	u16 winfo;
  #endif
-@@ -249,7 +273,9 @@ struct mtk_foe_entry {
+@@ -242,6 +266,7 @@ struct mtk_foe_ipv6_6rd {
+ 
+ #define MTK_FOE_ENTRY_V1_SIZE	80
+ #define MTK_FOE_ENTRY_V2_SIZE	96
++#define MTK_FOE_ENTRY_V3_SIZE	128
+ 
+ struct mtk_foe_entry {
+ 	u32 ib1;
+@@ -252,7 +277,7 @@ struct mtk_foe_entry {
  		struct mtk_foe_ipv4_dslite dslite;
  		struct mtk_foe_ipv6 ipv6;
  		struct mtk_foe_ipv6_6rd ipv6_6rd;
--#if defined(CONFIG_MEDIATEK_NETSYS_V2)
-+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
+-		u32 data[23];
 +		u32 data[31];
-+#elif defined(CONFIG_MEDIATEK_NETSYS_V2)
- 		u32 data[23];
- #else
- 		u32 data[19];
+ 	};
+ };
+ 
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
 index 3bc50a4..f0c63da 100755
 --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3017-flow-offload-add-mtkhnat-dscp.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3017-flow-offload-add-mtkhnat-dscp.patch
index bde5f37..d3ca5a8 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3017-flow-offload-add-mtkhnat-dscp.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3017-flow-offload-add-mtkhnat-dscp.patch
@@ -1,4 +1,4 @@
-From 6c2db9f4385e9eff9667cd41ad4a1b2cd45f030b Mon Sep 17 00:00:00 2001
+From 43ce2ffe89e93f6bcbfa4a512744b14a8b522ac3 Mon Sep 17 00:00:00 2001
 From: Bc-bocun Chen <bc-bocun.chen@mediatek.com>
 Date: Mon, 18 Sep 2023 11:17:24 +0800
 Subject: [PATCH] flow-offload-add-mtkhnat-dscp
@@ -47,7 +47,7 @@
  int mtk_foe_entry_set_sp(struct mtk_ppe *ppe, struct mtk_foe_entry *entry);
  int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-index c1cce76..f362771 100644
+index c1cce76..b9983d7 100644
 --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
 @@ -186,7 +186,7 @@ mtk_flow_get_dsa_port(struct net_device **dev)
@@ -59,15 +59,15 @@
  {
  	struct mtk_wdma_info info = {};
  	int pse_port, dsa_port;
-@@ -207,6 +207,8 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
- 		goto out;
- 	}
+@@ -224,6 +224,8 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
+ 		return -EOPNOTSUPP;
  
+ out:
 +	mtk_foe_entry_set_dscp(foe, dscp);
 +
- 	dsa_port = mtk_flow_get_dsa_port(&dev);
- 	if (dsa_port >= 0)
- 		mtk_foe_entry_set_dsa(foe, dsa_port);
+ 	if (eth->qos_toggle == 1 || (ct->mark & MTK_QDMA_TX_MASK) >= 6) {
+ 		u8 qos_ul_toggle;
+ 
 @@ -262,6 +264,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
  	int wed_index = -1;
  	u16 addr_type = 0;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3020-mtk-wed-add-wed3-ser-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3020-mtk-wed-add-wed3-ser-support.patch
index 7423a6e..2a12855 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3020-mtk-wed-add-wed3-ser-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3020-mtk-wed-add-wed3-ser-support.patch
@@ -1,7 +1,7 @@
-From 67a20e07982e9c43d299679f75fd81638271fc63 Mon Sep 17 00:00:00 2001
+From 5e30837de4270c4ab642da6627dc3163bfa3a79d Mon Sep 17 00:00:00 2001
 From: mtk27745 <rex.lu@mediatek.com>
 Date: Mon, 18 Sep 2023 13:22:44 +0800
-Subject: [PATCH 2/6] mtk wed add wed3 ser support
+Subject: [PATCH] mtk wed add wed3 ser support
 
 ---
  drivers/net/ethernet/mediatek/mtk_wed.c      | 339 ++++++++++++++++---
@@ -10,7 +10,7 @@
  3 files changed, 367 insertions(+), 48 deletions(-)
 
 diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
-index 4b32a82..02c156a 100644
+index a72484c..a9baa16 100644
 --- a/drivers/net/ethernet/mediatek/mtk_wed.c
 +++ b/drivers/net/ethernet/mediatek/mtk_wed.c
 @@ -110,24 +110,88 @@ mtk_wdma_read_reset(struct mtk_wed_device *dev)
@@ -340,8 +340,8 @@
 -	mtk_wed_poll_busy(dev, MTK_WED_CTRL,
 -			  MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
 +	if (mtk_wed_is_v3_or_greater(dev->hw))
-+		mtk_wed_poll_busy(dev, MTK_WED_WPDMA_STATUS,
-+				  MTK_WED_WPDMA_STATUS_TX_DRV);
++		mtk_wed_poll_busy(dev, MTK_WED_WDMA_STATUS,
++				  MTK_WED_WDMA_STATUS_TX_DRV);
 +	else
 +		mtk_wed_poll_busy(dev, MTK_WED_CTRL,
 +				  MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
@@ -484,7 +484,7 @@
  	wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
  		MTK_WED_RRO_MSDU_PG_DRV_CLR);
 diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-index 0af264d..1ee0fe1 100644
+index 0af264d..2bc6854 100644
 --- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
 +++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
 @@ -36,6 +36,8 @@ struct mtk_wdma_desc {
@@ -509,8 +509,8 @@
  #define MTK_WED_STATUS					0x060
  #define MTK_WED_STATUS_TX				GENMASK(15, 8)
  
-+#define MTK_WED_WPDMA_STATUS				0x068
-+#define MTK_WED_WPDMA_STATUS_TX_DRV			GENMASK(15, 8)
++#define MTK_WED_WDMA_STATUS				0x068
++#define MTK_WED_WDMA_STATUS_TX_DRV			GENMASK(15, 8)
 +
 +
  #define MTK_WED_TX_BM_CTRL				0x080
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3021-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3021-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch
index d3747af..0ad8ba7 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3021-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3021-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch
@@ -45,7 +45,7 @@
  				desc->info = 0;
  			} else {
 -				desc->ctrl = cpu_to_le32(token << 16);
-+				ctrl = token << 16 | TX_DMA_SDP1(buf_phys);
++				ctrl = token << 16 | TX_DMA_PREP_ADDR64(buf_phys);
  			}
 +			desc->ctrl = cpu_to_le32(ctrl);
  
@@ -64,7 +64,7 @@
  		buf_phys = page_phys;
  		for (s = 0; s < MTK_WED_RX_PAGE_BUF_PER_PAGE; s++) {
  			desc->buf0 = cpu_to_le32(buf_phys);
-+			desc->token = cpu_to_le32(RX_DMA_SDP1(buf_phys));
++			desc->token = cpu_to_le32(RX_DMA_PREP_ADDR64(buf_phys));
  			desc++;
  			buf += MTK_WED_PAGE_BUF_SIZE;
  			buf_phys += MTK_WED_PAGE_BUF_SIZE;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3025-flow-offload-add-mtkhnat-roaming.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3025-flow-offload-add-mtkhnat-roaming.patch
index adee40a..85030dc 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3025-flow-offload-add-mtkhnat-roaming.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3025-flow-offload-add-mtkhnat-roaming.patch
@@ -108,7 +108,7 @@
 +	int i, j, count = 0;
 +
 +	for (i = 0; i < MTK_PPE_ENTRIES; i++) {
-+		struct mtk_foe_entry *entry = &ppe->foe_table[i];
++		struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
 +		struct flow_offload_tuple tuple;
 +		int type, state;
 +
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3026-extended-wed-debugfs.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3026-extended-wed-debugfs.patch
new file mode 100644
index 0000000..4889ed9
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3026-extended-wed-debugfs.patch
@@ -0,0 +1,874 @@
+From 13e3f150a52aa27abcec11c13e45f755a974e0ab Mon Sep 17 00:00:00 2001
+From: Rex Lu <rex.lu@mediatek.com>
+Date: Wed, 5 Jun 2024 10:30:28 +0800
+Subject: [PATCH] extended wed debugfs
+
+---
+ .../net/ethernet/mediatek/mtk_wed_debugfs.c   | 427 ++++++++++++++++--
+ drivers/net/ethernet/mediatek/mtk_wed_regs.h  |  68 ++-
+ 2 files changed, 444 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
+index 8db7ec5..93563e1 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
+@@ -18,11 +18,15 @@ enum {
+ 	DUMP_TYPE_END,
+ 	DUMP_TYPE_STRING,
+ 	DUMP_TYPE_WED,
++	DUMP_TYPE_WED_RING,
+ 	DUMP_TYPE_WDMA,
++	DUMP_TYPE_WDMA_RX,
+ 	DUMP_TYPE_WPDMA_TX,
+ 	DUMP_TYPE_WPDMA_TXFREE,
+ 	DUMP_TYPE_WPDMA_RX,
+ 	DUMP_TYPE_WED_RRO,
++	DUMP_TYPE_WED_RING_RX_TYPE1,
++	DUMP_TYPE_WED_RING_RX_TYPE2,
+ };
+ 
+ #define DUMP_END() { .type = DUMP_TYPE_END }
+@@ -31,6 +35,14 @@ enum {
+ #define DUMP_REG_MASK(_reg, _mask) { #_mask, MTK_##_reg, DUMP_TYPE_WED, 0, MTK_##_mask }
+ 
+ #define DUMP_RING(_prefix, _base, ...)				\
++	{ _prefix " BASE", _base, __VA_ARGS__ },		\
++	{ _prefix " CNT",  _base + 0x4, __VA_ARGS__ },	\
++	{ _prefix " CIDX", _base + 0x8, __VA_ARGS__ },	\
++	{ _prefix " DIDX", _base + 0xc, __VA_ARGS__ },	\
++	{ _prefix " Qcnt", _base , __VA_ARGS__ }
++
++
++#define DUMP_RRO_DATA_RING(_prefix, _base, ...)			\
+ 	{ _prefix " BASE", _base, __VA_ARGS__ },		\
+ 	{ _prefix " CNT",  _base + 0x4, __VA_ARGS__ },	\
+ 	{ _prefix " CIDX", _base + 0x8, __VA_ARGS__ },	\
+@@ -38,16 +50,23 @@ enum {
+ 
+ #define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED)
+ #define DUMP_WED_MASK(_reg, _mask) DUMP_REG_MASK(_reg, _mask)
+-#define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED)
++#define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED_RING)
++#define DUMP_WED_RING_RX_TYPE1(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED_RING_RX_TYPE1)
++#define DUMP_WED_RING_RX_TYPE2(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED_RING_RX_TYPE2)
++#define DUMP_WED_RRO_DATA_RING(_base) DUMP_RRO_DATA_RING(#_base, MTK_##_base, DUMP_TYPE_WED_RRO)
+ 
+ #define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA)
+ #define DUMP_WDMA_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WDMA)
++#define DUMP_WDMA_RING_RX(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WDMA_RX)
+ 
+ #define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n)
+ #define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE)
+ #define DUMP_WPDMA_RX_RING(_n)	DUMP_RING("WPDMA_RX" #_n, 0, DUMP_TYPE_WPDMA_RX, _n)
+-#define DUMP_WED_RRO_RING(_base)DUMP_RING("WED_RRO_MIOD", MTK_##_base, DUMP_TYPE_WED_RRO)
+-#define DUMP_WED_RRO_FDBK(_base)DUMP_RING("WED_RRO_FDBK", MTK_##_base, DUMP_TYPE_WED_RRO)
++#define DUMP_WED_RRO_RING(_base)DUMP_RING("WED_RRO_MIOD", MTK_##_base, DUMP_TYPE_WED_RING)
++#define DUMP_WED_RRO_FDBK(_base)DUMP_RING("WED_RRO_FDBK", MTK_##_base, DUMP_TYPE_WED_RING)
++#define CAL_TX_QCNT(_cidx, _didx, _cnt) ((_cidx >= _didx) ? (_cidx - _didx) : (_cidx - _didx + _cnt))
++#define CAL_RX_QCNT_TYPE1(_cidx, _didx, _cnt) (_didx > (_cidx & 0xfff) ? (_didx - 1 - (_cidx & 0xfff)) : (_didx - 1 - (_cidx & 0xfff) + _cnt))
++#define CAL_RX_QCNT_TYPE2(_cidx, _didx, _cnt) ((_didx > _cidx) ? (_didx - 1 - _cidx) : (_didx - 1 - _cidx + _cnt))
+ 
+ 
+ static void
+@@ -62,7 +81,7 @@ dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
+ {
+ 	const struct reg_dump **cur_o = regs, *cur;
+ 	bool newline = false;
+-	u32 val;
++	u32 val, cnt, cidx, didx;
+ 
+ 	while (*cur_o) {
+ 		cur = *cur_o;
+@@ -81,16 +100,100 @@ dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
+ 				val = wed_r32(dev, cur->offset);
+ 				break;
+ 			case DUMP_TYPE_WDMA:
+-				val = wdma_r32(dev, cur->offset);
++				if (!strstr(cur->name, "Qcnt"))
++					val = wdma_r32(dev, cur->offset);
++				if (strstr(cur->name, "CNT")){
++					cnt = val;
++				}else if (strstr(cur->name, "CIDX"))
++					cidx = val;
++				else if (strstr(cur->name, "DIDX"))
++					didx = val;
++				if (strstr(cur->name, "Qcnt"))
++					val = CAL_TX_QCNT(cidx, didx, cnt);
++				break;
++			case DUMP_TYPE_WDMA_RX:
++				if (!strstr(cur->name, "Qcnt"))
++					val = wdma_r32(dev, cur->offset);
++				if (strstr(cur->name, "CNT")){
++					cnt = val;
++				}else if (strstr(cur->name, "CIDX"))
++					cidx = val;
++				else if (strstr(cur->name, "DIDX"))
++					didx = val;
++				if (strstr(cur->name, "Qcnt"))
++					val = CAL_RX_QCNT_TYPE2(cidx, didx, cnt);
+ 				break;
+ 			case DUMP_TYPE_WPDMA_TX:
+-				val = wpdma_tx_r32(dev, cur->base, cur->offset);
++				if (!strstr(cur->name, "Qcnt"))
++					val = wpdma_tx_r32(dev, cur->base, cur->offset);
++				if (strstr(cur->name, "CNT"))
++					cnt = val;
++				else if (strstr(cur->name, "CIDX"))
++					cidx = val;
++				else if (strstr(cur->name, "DIDX"))
++					didx = val;
++				if (strstr(cur->name, "Qcnt"))
++					val = CAL_TX_QCNT(cidx, didx, cnt);
+ 				break;
+ 			case DUMP_TYPE_WPDMA_TXFREE:
+-				val = wpdma_txfree_r32(dev, cur->offset);
++				if (!strstr(cur->name, "Qcnt"))
++					val = wpdma_txfree_r32(dev, cur->offset);
++				if (strstr(cur->name, "CNT"))
++					cnt = val;
++				else if (strstr(cur->name, "CIDX"))
++					cidx = val;
++				else if (strstr(cur->name, "DIDX"))
++					didx = val;
++				if (strstr(cur->name, "Qcnt"))
++					val = CAL_RX_QCNT_TYPE2(cidx, didx, cnt);
+ 				break;
+ 			case DUMP_TYPE_WPDMA_RX:
+-				val = wpdma_rx_r32(dev, cur->base, cur->offset);
++				if (!strstr(cur->name, "Qcnt"))
++					val = wpdma_rx_r32(dev, cur->base, cur->offset);
++				if (strstr(cur->name, "CNT"))
++					cnt = val;
++				else if (strstr(cur->name, "CIDX"))
++					cidx = val;
++				else if (strstr(cur->name, "DIDX"))
++					didx = val;
++				if (strstr(cur->name, "Qcnt"))
++					val = CAL_RX_QCNT_TYPE2(cidx, didx, cnt);
++				break;
++			case DUMP_TYPE_WED_RING:
++				if (!strstr(cur->name, "Qcnt"))
++					val = wed_r32(dev, cur->offset);
++				if (strstr(cur->name, "CNT"))
++					cnt = val;
++				else if (strstr(cur->name, "CIDX"))
++					cidx = val;
++				else if (strstr(cur->name, "DIDX"))
++					didx = val;
++				if (strstr(cur->name, "Qcnt"))
++					val = CAL_TX_QCNT(cidx, didx, cnt);
++				break;
++			case DUMP_TYPE_WED_RING_RX_TYPE1:
++				if (!strstr(cur->name, "Qcnt"))
++					val = wed_r32(dev, cur->offset);
++				if (strstr(cur->name, "CNT"))
++					cnt = val;
++				else if (strstr(cur->name, "CIDX"))
++					cidx = val;
++				else if (strstr(cur->name, "DIDX"))
++					didx = val;
++				if (strstr(cur->name, "Qcnt"))
++					val = CAL_RX_QCNT_TYPE1(cidx, didx, cnt);
++				break;
++			case DUMP_TYPE_WED_RING_RX_TYPE2:
++				if (!strstr(cur->name, "Qcnt"))
++					val = wed_r32(dev, cur->offset);
++				if (strstr(cur->name, "CNT"))
++					cnt = val;
++				else if (strstr(cur->name, "CIDX"))
++					cidx = val;
++				else if (strstr(cur->name, "DIDX"))
++					didx = val;
++				if (strstr(cur->name, "Qcnt"))
++					val = CAL_RX_QCNT_TYPE2(cidx, didx, cnt);
+ 				break;
+ 			}
+ 
+@@ -129,49 +232,76 @@ wed_txinfo_show(struct seq_file *s, void *data)
+ 		DUMP_WPDMA_TX_RING(0),
+ 		DUMP_WPDMA_TX_RING(1),
+ 
++		DUMP_STR("WPDMA RX"),
++		DUMP_WPDMA_TXFREE_RING,
++
++		DUMP_STR("WED WPDMA RX (TX FREE)"),
++		DUMP_WED(WED_WPDMA_RX_MIB(0)),
++		DUMP_WED_RING_RX_TYPE1(WED_WPDMA_RING_RX(0)),
++		DUMP_WED(WED_WPDMA_RX_MIB(1)),
++		DUMP_WED_RING_RX_TYPE1(WED_WPDMA_RING_RX(1)),
++		DUMP_WED(WED_WPDMA_RX_COHERENT_MIB),
++		DUMP_WED(WED_WPDMA_RX_EXTC_FRE),
++
++		DUMP_STR("WED RX (TX FREE)"),
++		DUMP_WED(WED_RX_MIB(0)),
++		DUMP_WED_RING_RX_TYPE2(WED_RING_RX(0)),
++
++		DUMP_WED(WED_RX_MIB(1)),
++		DUMP_WED_RING_RX_TYPE2(WED_RING_RX(1)),
++
+ 		DUMP_STR("WED WDMA RX"),
+ 		DUMP_WED(WED_WDMA_RX_MIB(0)),
+-		DUMP_WED_RING(WED_WDMA_RING_RX(0)),
++		DUMP_WED_RING_RX_TYPE1(WED_WDMA_RING_RX(0)),
+ 		DUMP_WED(WED_WDMA_RX_THRES(0)),
+ 		DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(0)),
+ 		DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(0)),
+ 
+ 		DUMP_WED(WED_WDMA_RX_MIB(1)),
+-		DUMP_WED_RING(WED_WDMA_RING_RX(1)),
++		DUMP_WED_RING_RX_TYPE1(WED_WDMA_RING_RX(1)),
+ 		DUMP_WED(WED_WDMA_RX_THRES(1)),
+ 		DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(1)),
+ 		DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(1)),
+ 
+ 		DUMP_STR("WDMA RX"),
+ 		DUMP_WDMA(WDMA_GLO_CFG),
+-		DUMP_WDMA_RING(WDMA_RING_RX(0)),
+-		DUMP_WDMA_RING(WDMA_RING_RX(1)),
++		DUMP_WDMA_RING_RX(WDMA_RING_RX(0)),
++		DUMP_WDMA_RING_RX(WDMA_RING_RX(1)),
+ 
+-		DUMP_STR("WED TX FREE"),
+-		DUMP_WED(WED_RX_MIB(0)),
+-		DUMP_WED_RING(WED_RING_RX(0)),
+-		DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(0)),
++		DUMP_END(),
++	};
+ 
+-		DUMP_WED(WED_RX_MIB(1)),
+-		DUMP_WED_RING(WED_RING_RX(1)),
+-		DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(1)),
+-		DUMP_STR("WED_WPDMA TX FREE"),
+-		DUMP_WED_RING(WED_WPDMA_RING_RX(0)),
+-		DUMP_WED_RING(WED_WPDMA_RING_RX(1)),
++	static const struct reg_dump regs_v3[] = {
++		DUMP_STR("Total Free Tx TKID number"),
++		DUMP_WED(WED_TX_TKID_STATUS),
+ 		DUMP_END(),
+ 	};
+ 
+-	static const struct reg_dump *regs[] = {
++	static const struct reg_dump *regs_com[] = {
++		&regs_common[0],
++		NULL,
++	};
++
++	static const struct reg_dump *regs_new_v3[] = {
+ 		&regs_common[0],
++		&regs_v3[0],
+ 		NULL,
+ 	};
+ 
+ 	struct mtk_wed_hw *hw = s->private;
+ 	struct mtk_wed_device *dev = hw->wed_dev;
+-
++	const struct reg_dump **regs;
+ 	if (!dev)
+ 		return 0;
+ 
++	switch(dev->hw->version) {
++	case 3:
++		regs = regs_new_v3;
++		break;
++	default:
++		regs = regs_com;
++	}
++
+ 	dump_wed_regs(s, dev, regs);
+ 
+ 	return 0;
+@@ -182,22 +312,39 @@ static int
+ wed_rxinfo_show(struct seq_file *s, void *data)
+ {
+ 	static const struct reg_dump regs_common[] = {
++		DUMP_STR("WED RX INT info"),
++		DUMP_WED(WED_PCIE_INT_CTRL),
++		DUMP_WED(WED_PCIE_INT_REC),
++		DUMP_WED(WED_WPDMA_INT_STA_REC),
++		DUMP_WED(WED_WPDMA_INT_MON),
++		DUMP_WED(WED_WPDMA_INT_CTRL),
++		DUMP_WED(WED_WPDMA_INT_CTRL_TX),
++		DUMP_WED(WED_WPDMA_INT_CTRL_RX),
++		DUMP_WED(WED_WPDMA_INT_CTRL_TX_FREE),
++		DUMP_WED(WED_WPDMA_STATUS),
++		DUMP_WED(WED_WPDMA_D_ST),
++		DUMP_WED(WED_WPDMA_RX_D_GLO_CFG),
++
++		DUMP_STR("WED RX"),
++		DUMP_WED_RING_RX_TYPE2(WED_RING_RX_DATA(0)),
++		DUMP_WED_RING_RX_TYPE2(WED_RING_RX_DATA(1)),
++
+ 		DUMP_STR("WPDMA RX"),
+ 		DUMP_WPDMA_RX_RING(0),
+ 		DUMP_WPDMA_RX_RING(1),
+ 
+-		DUMP_STR("WPDMA RX"),
++		DUMP_STR("WED WPDMA RX"),
++		DUMP_WED_RING_RX_TYPE1(WED_WPDMA_RING_RX_DATA(0)),
++		DUMP_WED_RING_RX_TYPE1(WED_WPDMA_RING_RX_DATA(1)),
+ 		DUMP_WED(WED_WPDMA_RX_D_MIB(0)),
+-		DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(0)),
+-		DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(0)),
+ 		DUMP_WED(WED_WPDMA_RX_D_MIB(1)),
+-		DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(1)),
++		DUMP_WED(WED_WPDMA_RX_D_RECYCLE_MIB(0)),
++		DUMP_WED(WED_WPDMA_RX_D_RECYCLE_MIB(1)),
++		DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(0)),
+ 		DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(1)),
+ 		DUMP_WED(WED_WPDMA_RX_D_COHERENT_MIB),
++		DUMP_WED(WED_WPDMA_RX_D_ERR_STATUS),
+ 
+-		DUMP_STR("WED RX"),
+-		DUMP_WED_RING(WED_RING_RX_DATA(0)),
+-		DUMP_WED_RING(WED_RING_RX_DATA(1)),
+ 
+ 		DUMP_STR("WED WO RRO"),
+ 		DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0),
+@@ -205,6 +352,8 @@ wed_rxinfo_show(struct seq_file *s, void *data)
+ 		DUMP_WED(WED_RROQM_MOD_MIB),
+ 		DUMP_WED(WED_RROQM_MOD_COHERENT_MIB),
+ 		DUMP_WED_RRO_FDBK(WED_RROQM_FDBK_CTRL0),
++		DUMP_WED(WED_RROQM_FDBK_MIB),
++		DUMP_WED(WED_RROQM_FDBK_COHERENT_MIB),
+ 		DUMP_WED(WED_RROQM_FDBK_IND_MIB),
+ 		DUMP_WED(WED_RROQM_FDBK_ENQ_MIB),
+ 		DUMP_WED(WED_RROQM_FDBK_ANC_MIB),
+@@ -212,8 +361,8 @@ wed_rxinfo_show(struct seq_file *s, void *data)
+ 
+ 
+ 		DUMP_STR("WED WDMA TX"),
+-		DUMP_WED(WED_WDMA_TX_MIB),
+ 		DUMP_WED_RING(WED_WDMA_RING_TX),
++		DUMP_WED(WED_WDMA_TX_MIB),
+ 
+ 		DUMP_STR("WDMA TX"),
+ 		DUMP_WDMA(WDMA_GLO_CFG),
+@@ -222,14 +371,9 @@ wed_rxinfo_show(struct seq_file *s, void *data)
+ 
+ 		DUMP_STR("WED RX BM"),
+ 		DUMP_WED(WED_RX_BM_BASE),
+-		DUMP_WED(WED_RX_BM_RX_DMAD),
+ 		DUMP_WED(WED_RX_BM_PTR),
+-		DUMP_WED(WED_RX_BM_TKID_MIB),
+-		DUMP_WED(WED_RX_BM_BLEN),
+-		DUMP_WED(WED_RX_BM_STS),
+-		DUMP_WED(WED_RX_BM_INTF2),
+-		DUMP_WED(WED_RX_BM_INTF),
+-		DUMP_WED(WED_RX_BM_ERR_STS),
++		DUMP_WED_MASK(WED_RX_BM_PTR, WED_RX_BM_PTR_HEAD),
++		DUMP_WED_MASK(WED_RX_BM_PTR, WED_RX_BM_PTR_TAIL),
+ 		DUMP_END()
+ 	};
+ 
+@@ -249,30 +393,71 @@ wed_rxinfo_show(struct seq_file *s, void *data)
+ 	};
+ 
+ 	static const struct reg_dump regs_v3[] = {
++		DUMP_STR("WED PG BM"),
++		DUMP_WED(WED_RRO_PG_BM_BASE),
++		DUMP_WED(WED_RRO_PG_BM_ADD_BASE_H),
++		DUMP_WED(WED_RRO_PG_BM_PTR),
++		DUMP_WED_MASK(WED_RRO_PG_BM_PTR, WED_RX_BM_PTR_HEAD),
++		DUMP_WED_MASK(WED_RRO_PG_BM_PTR, WED_RX_BM_PTR_TAIL),
++		DUMP_WED(WED_RRO_PG_BM_STATUS),
++		DUMP_WED(WED_RRO_PG_BM_INTF),
++		DUMP_WED(WED_RRO_PG_BM_ERR_STATUS),
++		DUMP_WED(WED_RRO_PG_BM_OPT_CTRL),
++		DUMP_WED(WED_RRO_PG_BM_TOTAL_DMAD),
++
+ 		DUMP_STR("WED RX RRO DATA"),
+-		DUMP_WED_RING(WED_RRO_RX_D_RX(0)),
+-		DUMP_WED_RING(WED_RRO_RX_D_RX(1)),
++		DUMP_WED_MASK(WED_RRO_RX_D_RX_CNT(0), WED_RRO_RX_D_RX_MAX_CNT),
++		DUMP_WED_MASK(WED_RRO_RX_D_RX_CNT(0), WED_RRO_RX_D_RX_MAGIC_CNT),
++		DUMP_WED_RRO_DATA_RING(WED_RRO_RX_D_RX(0)),
++		DUMP_WED_MASK(WED_RRO_RX_D_RX_CNT(1), WED_RRO_RX_D_RX_MAX_CNT),
++		DUMP_WED_MASK(WED_RRO_RX_D_RX_CNT(1), WED_RRO_RX_D_RX_MAGIC_CNT),
++		DUMP_WED_RRO_DATA_RING(WED_RRO_RX_D_RX(1)),
++		DUMP_WED(WED_RRO_RX_D_CFG(0)),
++		DUMP_WED(WED_RRO_RX_D_CFG(1)),
++		DUMP_WED(WED_RRO_RX_D_CFG(2)),
+ 
+ 		DUMP_STR("WED RX MSDU PAGE"),
+-		DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(0)),
+-		DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(1)),
+-		DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(2)),
++		DUMP_WED(WED_RRO_MSDU_PG_RING_CFG(0)),
++		DUMP_WED(WED_RRO_MSDU_PG_RING_CFG1(0)),
++		DUMP_WED(WED_RRO_MSDU_PG_RING_CFG(1)),
++		DUMP_WED(WED_RRO_MSDU_PG_RING_CFG1(1)),
++		DUMP_WED(WED_RRO_MSDU_PG_RING_CFG(2)),
++		DUMP_WED(WED_RRO_MSDU_PG_RING_CFG1(2)),
++		DUMP_WED(WED_RRO_MSDU_PG_CTRL0(0)),
++		DUMP_WED(WED_RRO_MSDU_PG_CTRL1(0)),
++		DUMP_WED(WED_RRO_MSDU_PG_CTRL2(0)),
++		DUMP_WED(WED_RRO_MSDU_PG_CTRL0(1)),
++		DUMP_WED(WED_RRO_MSDU_PG_CTRL1(1)),
++		DUMP_WED(WED_RRO_MSDU_PG_CTRL2(1)),
++		DUMP_WED(WED_RRO_MSDU_PG_CTRL0(2)),
++		DUMP_WED(WED_RRO_MSDU_PG_CTRL1(2)),
++		DUMP_WED(WED_RRO_MSDU_PG_CTRL2(2)),
+ 
+ 		DUMP_STR("WED RX IND CMD"),
+-		DUMP_WED(WED_IND_CMD_RX_CTRL1),
+-		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL2, WED_IND_CMD_MAX_CNT),
+-		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_PROC_IDX),
++		DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_VLD),
++		DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_MAGIC_CNT),
++		DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_SW_PROC_IDX),
+ 		DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_DMA_IDX),
++		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0,
++			      WED_IND_CMD_MAGIC_CNT_PROC_IDX),
+ 		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_MAGIC_CNT),
+-		DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_MAGIC_CNT),
+ 		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0,
+ 			      WED_IND_CMD_PREFETCH_FREE_CNT),
++		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_PROC_IDX),
++		DUMP_WED(WED_IND_CMD_RX_CTRL1),
++		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL2, WED_IND_CMD_BASE_M),
++		DUMP_WED_MASK(WED_IND_CMD_RX_CTRL2, WED_IND_CMD_MAX_CNT),
++		DUMP_WED(WED_RRO_CFG0),
++		DUMP_WED_MASK(WED_RRO_CFG1, WED_RRO_CFG1_MAX_WIN_SZ),
++		DUMP_WED_MASK(WED_RRO_CFG1, WED_RRO_CFG1_ACK_SN_BASE_M),
+ 		DUMP_WED_MASK(WED_RRO_CFG1, WED_RRO_CFG1_PARTICL_SE_ID),
+ 
+ 		DUMP_STR("WED ADDR ELEM"),
+ 		DUMP_WED(WED_ADDR_ELEM_CFG0),
+ 		DUMP_WED_MASK(WED_ADDR_ELEM_CFG1,
+ 			      WED_ADDR_ELEM_PREFETCH_FREE_CNT),
++		DUMP_WED_MASK(WED_ADDR_ELEM_CFG1,
++			      WED_ADDR_ELEM_PARTICL_SE_ID_BASE_M),
+ 
+ 		DUMP_STR("WED Route QM"),
+ 		DUMP_WED(WED_RTQM_ENQ_I2Q_DMAD_CNT),
+@@ -593,6 +778,21 @@ wed_amsdu_show(struct seq_file *s, void *data)
+ 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID6_QTAIL),
+ 		DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID7_QTAIL),
+ 
++		DUMP_STR("WED HIFTXD BUFF NUM"),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(1)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(2)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(3)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(4)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(5)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(6)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(7)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(8)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(9)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(10)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(11)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(12)),
++		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_BUFF(13)),
++
+ 		DUMP_STR("WED HIFTXD MSDU INFO"),
+ 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(1)),
+ 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(2)),
+@@ -607,6 +807,8 @@ wed_amsdu_show(struct seq_file *s, void *data)
+ 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(11)),
+ 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(12)),
+ 		DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(13)),
++
++		DUMP_END()
+ 	};
+ 
+ 	static const struct reg_dump *regs[] = {
+@@ -732,6 +934,133 @@ wed_rro_show(struct seq_file *s, void *data)
+ }
+ DEFINE_SHOW_ATTRIBUTE(wed_rro);
+ 
++static int
++wed_hw_cfg_show(struct seq_file *s, void *data)
++{
++	static const struct reg_dump regs_common[] = {
++		DUMP_STR("WED basic info"),
++		DUMP_WED(WED_REV_ID),
++		DUMP_WED(WED_CTRL),
++		DUMP_WED(WED_CTRL2),
++		DUMP_WED(WED_EXT_INT_STATUS),
++		DUMP_WED(WED_EXT_INT_MASK),
++		DUMP_WED(WED_STATUS),
++		DUMP_WED(WED_GLO_CFG),
++		DUMP_WED(WED_INT_STATUS),
++		DUMP_WED(WED_INT_MASK),
++		DUMP_WED(WED_AXI_CTRL),
++
++		DUMP_STR("WED TX buf info"),
++		DUMP_WED(WED_BM_STATUS),
++		DUMP_WED(WED_TX_BM_BASE),
++		DUMP_WED(WED_TX_BM_CTRL),
++		DUMP_WED(WED_TX_BM_STATUS),
++		DUMP_WED(WED_TX_BM_DYN_THR),
++		DUMP_WED(WED_TX_BM_RECYC),
++		DUMP_WED(WED_TX_TKID_CTRL),
++		DUMP_WED(WED_TX_TKID_TKID),
++		DUMP_WED(WED_TX_TKID_DYN_THR),
++		DUMP_WED(WED_TX_TKID_INTF),
++		DUMP_WED(WED_TX_TKID_RECYC),
++		DUMP_WED(WED_TX_FREE_TO_TX_TKID_TKID_MIB),
++		DUMP_WED(WED_TX_BM_TO_WDMA_RX_DRV_SKBID_MIB),
++		DUMP_WED(WED_TX_TKID_TO_TX_BM_FREE_SKBID_MIB),
++
++		DUMP_STR("WED RX BM info"),
++		DUMP_WED(WED_RX_BM_RX_DMAD),
++		DUMP_WED(WED_RX_BM_BASE),
++		DUMP_WED(WED_RX_BM_INIT_PTR),
++		DUMP_WED(WED_RX_BM_PTR),
++		DUMP_WED(WED_RX_BM_BLEN),
++		DUMP_WED(WED_RX_BM_STS),
++		DUMP_WED(WED_RX_BM_INTF2),
++		DUMP_WED(WED_RX_BM_INTF),
++		DUMP_WED(WED_RX_BM_ERR_STS),
++
++		DUMP_STR("WED RRO QM"),
++		DUMP_WED(WED_RROQM_GLO_CFG),
++		DUMP_WED(WED_RROQM_MIOD_CTRL0),
++		DUMP_WED(WED_RROQM_MIOD_CTRL1),
++		DUMP_WED(WED_RROQM_MIOD_CTRL2),
++		DUMP_WED(WED_RROQM_MIOD_CTRL3),
++		DUMP_WED(WED_RROQM_FDBK_CTRL0),
++		DUMP_WED(WED_RROQM_FDBK_CTRL1),
++		DUMP_WED(WED_RROQM_FDBK_CTRL2),
++		DUMP_WED(WED_RROQM_FDBK_CTRL3),
++		DUMP_WED(WED_RROQ_BASE_L),
++		DUMP_WED(WED_RROQ_BASE_H),
++		DUMP_WED(WED_RROQM_MIOD_CFG),
++
++		DUMP_STR("WED PCI Host Control"),
++		DUMP_WED(WED_PCIE_CFG_BASE),
++		DUMP_WED(WED_PCIE_CFG_INTM),
++		DUMP_WED(WED_PCIE_INT_TRIGGER),
++		DUMP_WED(WED_PCIE_INT_REC),
++		DUMP_WED(WED_PCIE_INTM_REC),
++		DUMP_WED(WED_PCIE_INT_CTRL),
++
++		DUMP_STR("WED_WPDMA basic info"),
++		DUMP_WED(WED_WPDMA_STATUS),
++		DUMP_WED(WED_WPDMA_INT_STA_REC),
++		DUMP_WED(WED_WPDMA_GLO_CFG),
++		DUMP_WED(WED_WPDMA_CFG_BASE),
++		DUMP_WED(WED_WPDMA_CFG_INT_MASK),
++		DUMP_WED(WED_WPDMA_CFG_TX),
++		DUMP_WED(WED_WPDMA_CFG_TX_FREE),
++		DUMP_WED(WED_WPDMA_CTRL),
++		DUMP_WED(WED_WPDMA_RX_GLO_CFG),
++		DUMP_WED(WED_WPDMA_RX_RING0),
++		DUMP_WED(WED_WPDMA_RX_RING1),
++
++		DUMP_STR("WED_WDMA basic info"),
++		DUMP_WED(WED_WDMA_STATUS),
++		DUMP_WED(WED_WDMA_INFO),
++		DUMP_WED(WED_WDMA_GLO_CFG),
++		DUMP_WED(WED_WDMA_RESET_IDX),
++		DUMP_WED(WED_WDMA_LOAD_DRV_IDX),
++		DUMP_WED(WED_WDMA_LOAD_CRX_IDX),
++		DUMP_WED(WED_WDMA_SPR),
++		DUMP_WED(WED_WDMA_INT_STA_REC),
++		DUMP_WED(WED_WDMA_INT_TRIGGER),
++		DUMP_WED(WED_WDMA_INT_CTRL),
++		DUMP_WED(WED_WDMA_INT_CLR),
++		DUMP_WED(WED_WDMA_CFG_BASE),
++		DUMP_WED(WED_WDMA_OFFSET0),
++		DUMP_WED(WED_WDMA_OFFSET1),
++
++		DUMP_STR("WDMA basic info"),
++		DUMP_WDMA(WDMA_GLO_CFG),
++		DUMP_WDMA(WDMA_INT_MASK),
++		DUMP_WDMA(WDMA_INT_STATUS),
++		DUMP_WDMA(WDMA_INFO),
++		DUMP_WDMA(WDMA_FREEQ_THRES),
++		DUMP_WDMA(WDMA_INT_STS_GRP0),
++		DUMP_WDMA(WDMA_INT_STS_GRP1),
++		DUMP_WDMA(WDMA_INT_STS_GRP2),
++		DUMP_WDMA(WDMA_INT_GRP1),
++		DUMP_WDMA(WDMA_INT_GRP2),
++		DUMP_WDMA(WDMA_SCH_Q01_CFG),
++		DUMP_WDMA(WDMA_SCH_Q23_CFG),
++
++		DUMP_END()
++	};
++
++	static const struct reg_dump *regs[] = {
++		&regs_common[0],
++		NULL,
++	};
++	struct mtk_wed_hw *hw = s->private;
++	struct mtk_wed_device *dev = hw->wed_dev;
++
++	if (!dev)
++		return 0;
++
++	dump_wed_regs(s, dev, regs);
++
++	return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(wed_hw_cfg);
++
+ void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
+ {
+ 	struct dentry *dir;
+@@ -749,6 +1078,8 @@ void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
+ 	if (!mtk_wed_is_v1(hw)) {
+ 		debugfs_create_file_unsafe("rxinfo", 0400, dir, hw,
+ 					   &wed_rxinfo_fops);
++
++		debugfs_create_file_unsafe("cfg", 0600, dir, hw, &wed_hw_cfg_fops);
+ 		wed_wo_mcu_debugfs(hw, dir);
+ 		if (mtk_wed_is_v3_or_greater(hw)) {
+ 			debugfs_create_file_unsafe("amsdu", 0400, dir, hw,
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+index 2bc6854..ed0e560 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+@@ -24,7 +24,7 @@ struct mtk_wdma_desc {
+ 	__le32 info;
+ } __packed __aligned(4);
+ 
+-#if defined(CONFIG_MEDIATEK_NETSYS_V2)
++#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
+ #define MTK_WED_REV_ID					0x004
+ #define MTK_WED_REV_ID_MAJOR				GENMASK(31, 28)
+ #else
+@@ -80,6 +80,9 @@ struct mtk_wdma_desc {
+ #define MTK_WED_CTRL_MIB_READ_CLEAR			BIT(28)
+ #define MTK_WED_CTRL_FLD_MIB_RD_CLR			BIT(28)
+ 
++#define MTK_WED_AXI_CTRL				0x010
++#define MTK_WED_CTRL2					0x01c
++
+ #define MTK_WED_EXT_INT_STATUS				0x020
+ #define MTK_WED_EXT_INT_STATUS_TF_LEN_ERR		BIT(0)
+ #define MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD		BIT(1)
+@@ -119,9 +122,14 @@ struct mtk_wdma_desc {
+ #define MTK_WED_STATUS					0x060
+ #define MTK_WED_STATUS_TX				GENMASK(15, 8)
+ 
++#define MTK_WED_WPDMA_STATUS				0x064
++
+ #define MTK_WED_WDMA_STATUS				0x068
+ #define MTK_WED_WDMA_STATUS_TX_DRV			GENMASK(15, 8)
+ 
++#define MTK_WED_BM_STATUS				0x06c
++ 
++#define MTK_WED_WPDMA_D_ST				0x074
+ 
+ #define MTK_WED_TX_BM_CTRL				0x080
+ #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM			GENMASK(6, 0)
+@@ -140,6 +148,7 @@ struct mtk_wdma_desc {
+ 
+ #define MTK_WED_TX_BM_BUF_LEN				0x08c
+ 
++#define MTK_WED_TX_BM_STATUS				0x090
+ #define MTK_WED_TX_BM_INTF				0x09c
+ #define MTK_WED_TX_BM_INTF_TKID				GENMASK(15, 0)
+ #define MTK_WED_TX_BM_INTF_TKFIFO_FDEP			GENMASK(23, 16)
+@@ -152,6 +161,8 @@ struct mtk_wdma_desc {
+ #define MTK_WED_TX_BM_DYN_THR_HI			GENMASK(22, 16)
+ #define MTK_WED_TX_BM_DYN_THR_HI_V2			GENMASK(24, 16)
+ 
++#define MTK_WED_TX_BM_RECYC				0x0a8
++
+ #define MTK_WED_TX_TKID_CTRL				0x0c0
+ #define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM		GENMASK(6, 0)
+ #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM		GENMASK(22, 16)
+@@ -160,6 +171,8 @@ struct mtk_wdma_desc {
+ #define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3		GENMASK(7, 0)
+ #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3		GENMASK(23, 16)
+ 
++#define MTK_WED_TX_TKID_TKID				0x0c8
++
+ #define MTK_WED_TX_TKID_INTF				0x0dc
+ #define MTK_WED_TX_TKID_INTF_TKFIFO_FDEP		GENMASK(25, 16)
+ 
+@@ -167,6 +180,13 @@ struct mtk_wdma_desc {
+ #define MTK_WED_TX_TKID_DYN_THR_LO			GENMASK(6, 0)
+ #define MTK_WED_TX_TKID_DYN_THR_HI			GENMASK(22, 16)
+ 
++#define MTK_WED_TX_TKID_STATUS				0x0e4
++#define MTK_WED_TX_TKID_RECYC				0x0e8
++
++#define MTK_WED_TX_FREE_TO_TX_TKID_TKID_MIB		0x1c0
++#define MTK_WED_TX_BM_TO_WDMA_RX_DRV_SKBID_MIB		0x1c4
++#define MTK_WED_TX_TKID_TO_TX_BM_FREE_SKBID_MIB		0x1c8
++
+ #define MTK_WED_TXP_DW0					0x120
+ #define MTK_WED_TXP_DW1					0x124
+ #define MTK_WED_WPDMA_WRITE_TXP				GENMASK(31, 16)
+@@ -215,6 +235,7 @@ struct mtk_wdma_desc {
+ 
+ #define MTK_WED_SCR0					0x3c0
+ #define MTK_WED_RX1_CTRL2				0x418
++#define MTK_WED_WPDMA_INT_STA_REC			0x500
+ #define MTK_WED_WPDMA_INT_TRIGGER			0x504
+ #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE		BIT(1)
+ #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE		GENMASK(5, 4)
+@@ -271,6 +292,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WPDMA_INT_CTRL_SRC_SEL			GENMASK(17, 16)
+ 
+ #define MTK_WED_WPDMA_INT_MASK				0x524
++#define MTK_WED_WPDMA_INT_MON				0x52c
+ 
+ #define MTK_WED_WPDMA_INT_CTRL_TX			0x530
+ #define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN 		BIT(0)
+@@ -299,6 +321,9 @@ struct mtk_wdma_desc {
+ #define MTK_WED_PCIE_INT_TRIGGER			0x570
+ #define MTK_WED_PCIE_INT_TRIGGER_STATUS			BIT(16)
+ 
++#define MTK_WED_PCIE_INT_REC				0x574
++#define MTK_WED_PCIE_INTM_REC				0x578
++
+ #define MTK_WED_PCIE_INT_CTRL				0x57c
+ #define MTK_WED_PCIE_INT_CTRL_POLL_EN			GENMASK(13, 12)
+ #define MTK_WED_PCIE_INT_CTRL_SRC_SEL			GENMASK(17, 16)
+@@ -314,7 +339,12 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WPDMA_TX_COHERENT_MIB(_n)		(0x5d0 + (_n) * 4)
+ 
+ #define MTK_WED_WPDMA_RX_MIB(_n)			(0x5e0 + (_n) * 4)
++#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
++#define MTK_WED_WPDMA_RX_COHERENT_MIB			0x5f0
++#define MTK_WED_WPDMA_RX_EXTC_FRE			0x5f8
++#else
+ #define MTK_WED_WPDMA_RX_COHERENT_MIB(_n)		(0x5f0 + (_n) * 4)
++#endif
+ 
+ #define MTK_WED_WPDMA_RING_TX(_n)			(0x600 + (_n) * 0x10)
+ #define MTK_WED_WPDMA_RING_RX(_n)			(0x700 + (_n) * 0x10)
+@@ -342,8 +372,10 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WPDMA_RX_RING1				0x7d8
+ 
+ #define MTK_WED_WPDMA_RX_D_MIB(_n)			(0x774 + (_n) * 4)
++#define MTK_WED_WPDMA_RX_D_RECYCLE_MIB(_n)		(0x77c + (_n) * 4)
+ #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n)		(0x784 + (_n) * 4)
+ #define MTK_WED_WPDMA_RX_D_COHERENT_MIB			0x78c
++#define MTK_WED_WPDMA_RX_D_ERR_STATUS			0x790
+ 
+ #define MTK_WED_WPDMA_RX_D_PREF_CFG			0x7b4
+ #define MTK_WED_WPDMA_RX_D_PREF_EN			BIT(0)
+@@ -381,6 +413,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR		BIT(0)
+ #define MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR		BIT(16)
+ 
++#define MTK_WED_WDMA_INFO				0xa00
+ #define MTK_WED_WDMA_GLO_CFG				0xa04
+ #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN			BIT(0)
+ #define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK		BIT(1)
+@@ -407,6 +440,10 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WDMA_RESET_IDX_RX_ALL			BIT(20)
+ #define MTK_WED_WDMA_RESET_IDX_DRV			GENMASK(25, 24)
+ 
++#define MTK_WED_WDMA_LOAD_DRV_IDX			0xa10
++#define MTK_WED_WDMA_LOAD_CRX_IDX			0xa14
++#define MTK_WED_WDMA_SPR				0xa1c
++#define MTK_WED_WDMA_INT_STA_REC			0xa20
+ #define MTK_WED_WDMA_INT_CLR				0xa24
+ #define MTK_WED_WDMA_INT_CLR_RX_DONE			GENMASK(17, 16)
+ 
+@@ -451,6 +488,7 @@ struct mtk_wdma_desc {
+ #define MTK_WDMA_RING_TX(_n)				(0x000 + (_n) * 0x10)
+ #define MTK_WDMA_RING_RX(_n)				(0x100 + (_n) * 0x10)
+ 
++#define MTK_WDMA_INFO					0x200
+ #define MTK_WDMA_GLO_CFG				0x204
+ #define MTK_WDMA_GLO_CFG_TX_DMA_EN			BIT(0)
+ #define MTK_WDMA_GLO_CFG_TX_DMA_BUSY			BIT(1)
+@@ -463,6 +501,7 @@ struct mtk_wdma_desc {
+ #define MTK_WDMA_RESET_IDX				0x208
+ #define MTK_WDMA_RESET_IDX_TX				GENMASK(3, 0)
+ #define MTK_WDMA_RESET_IDX_RX				GENMASK(17, 16)
++#define MTK_WDMA_FREEQ_THRES				0x210
+ #define MTK_WDMA_INT_STATUS				0x220
+ 
+ #define MTK_WDMA_INT_MASK				0x228
+@@ -489,9 +528,13 @@ struct mtk_wdma_desc {
+ #define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR		BIT(21)
+ 
+ 
+-
++#define MTK_WDMA_INT_STS_GRP0				0x240
++#define MTK_WDMA_INT_STS_GRP1				0x244
++#define MTK_WDMA_INT_STS_GRP2				0x248
+ #define MTK_WDMA_INT_GRP1				0x250
+ #define MTK_WDMA_INT_GRP2				0x254
++#define MTK_WDMA_SCH_Q01_CFG				0x280
++#define MTK_WDMA_SCH_Q23_CFG				0x284
+ 
+ #define MTK_WDMA_PREF_TX_CFG				0x2d0
+ #define MTK_WDMA_PREF_TX_CFG_PREF_EN			BIT(0)
+@@ -617,6 +660,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RROQM_FDBK_CNT				GENMASK(11, 0)
+ 
+ #define MTK_WED_RROQM_FDBK_CTRL2			0xc58
++#define MTK_WED_RROQM_FDBK_CTRL3			0xc5c
+ 
+ #define MTK_WED_RROQ_BASE_L				0xc80
+ #define MTK_WED_RROQ_BASE_H				0xc84
+@@ -651,12 +695,15 @@ struct mtk_wdma_desc {
+ 
+ #define MTK_RRO_IND_CMD_SIGNATURE			0xe00
+ #define MTK_RRO_IND_CMD_DMA_IDX				GENMASK(11, 0)
++#define MTK_RRO_IND_CMD_SW_PROC_IDX			GENMASK(27, 16)
+ #define MTK_RRO_IND_CMD_MAGIC_CNT			GENMASK(30, 28)
++#define MTK_RRO_IND_CMD_VLD				BIT(31)
+ 
+ #define MTK_WED_IND_CMD_RX_CTRL0			0xe04
+ #define MTK_WED_IND_CMD_PROC_IDX			GENMASK(11, 0)
+ #define MTK_WED_IND_CMD_PREFETCH_FREE_CNT		GENMASK(19, 16)
+ #define MTK_WED_IND_CMD_MAGIC_CNT			GENMASK(30, 28)
++#define MTK_WED_IND_CMD_MAGIC_CNT_PROC_IDX		BIT(31)
+ 
+ #define MTK_WED_IND_CMD_RX_CTRL1			0xe08
+ #define MTK_WED_IND_CMD_RX_CTRL2			0xe0c
+@@ -671,6 +718,7 @@ struct mtk_wdma_desc {
+ 
+ #define MTK_WED_ADDR_ELEM_CFG0				0xe18
+ #define MTK_WED_ADDR_ELEM_CFG1				0xe1c
++#define MTK_WED_ADDR_ELEM_PARTICL_SE_ID_BASE_M		GENMASK(3, 0)
+ #define MTK_WED_ADDR_ELEM_PREFETCH_FREE_CNT		GENMASK(19, 16)
+ 
+ #define MTK_WED_ADDR_ELEM_TBL_CFG			0xe20
+@@ -694,6 +742,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_PN_CHECK_IS_FIRST			BIT(17)
+ 
+ #define MTK_WED_RRO_MSDU_PG_RING_CFG(_n)		(0xe44 + (_n) * 0x8)
++#define MTK_WED_RRO_MSDU_PG_RING_CFG1(_n)		(0xe48 + (_n) * 0x8)
+ 
+ #define MTK_WED_RRO_MSDU_PG_RING2_CFG			0xe58
+ #define MTK_WED_RRO_MSDU_PG_DRV_CLR			BIT(26)
+@@ -704,6 +753,9 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RRO_MSDU_PG_CTRL2(_n)			(0xe64 + (_n) * 0xc)
+ 
+ #define MTK_WED_RRO_RX_D_RX(_n)				(0xe80 + (_n) * 0x10)
++#define MTK_WED_RRO_RX_D_RX_CNT(_n)			(0xe84 + (_n) * 0x10)
++#define MTK_WED_RRO_RX_D_RX_MAX_CNT			GENMASK(11, 0)
++#define MTK_WED_RRO_RX_D_RX_MAGIC_CNT			GENMASK(31, 28)
+ 
+ #define MTK_WED_RRO_RX_MAGIC_CNT			BIT(13)
+ 
+@@ -718,6 +770,15 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RRO_PG_BM_INIT_PTR			0xeb8
+ #define MTK_WED_RRO_PG_BM_SW_TAIL_IDX			GENMASK(15, 0)
+ #define MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX		BIT(16)
++#define MTK_WED_RRO_PG_BM_PTR				0xebc
++#define MTK_WED_RRO_PG_BM_PTR_TAIL			GENMASK(15, 0)
++#define MTK_WED_RRO_PG_BM_PTR_HEAD			GENMASK(31, 16)
++#define MTK_WED_RRO_PG_BM_ADD_BASE_H			0xec0
++#define MTK_WED_RRO_PG_BM_STATUS			0xec4
++#define MTK_WED_RRO_PG_BM_INTF				0xecc
++#define MTK_WED_RRO_PG_BM_ERR_STATUS			0xed0
++#define MTK_WED_RRO_PG_BM_OPT_CTRL			0xed4
++#define MTK_WED_RRO_PG_BM_TOTAL_DMAD			0xee8
+ 
+ #define MTK_WED_WPDMA_INT_CTRL_RRO_RX			0xeec
+ #define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN		BIT(0)
+@@ -834,7 +895,8 @@ struct mtk_wdma_desc {
+ #define MTK_WED_AMSDU_QMEM_TID6_QTAIL			GENMASK(27, 16)
+ #define MTK_WED_AMSDU_QMEM_TID7_QTAIL			GENMASK(11, 0)
+ 
+-#define MTK_WED_MON_AMSDU_HIFTXD_FETCH_MSDU(_n)		(0x1ec4 + (_n) * 0x4)
++#define MTK_WED_MON_AMSDU_HIFTXD_FETCH_BUFF(_n)		(0x1e90 + (_n - 1) * 0x4)
++#define MTK_WED_MON_AMSDU_HIFTXD_FETCH_MSDU(_n)		(0x1ec4 + (_n - 1) * 0x4)
+ 
+ #define MTK_WED_PCIE_BASE			0x11280000
+ 
+-- 
+2.18.0
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3027-flow-offload-add-relayd-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3027-flow-offload-add-relayd-support.patch
new file mode 100644
index 0000000..d85e56e
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3027-flow-offload-add-relayd-support.patch
@@ -0,0 +1,27 @@
+From 6d638d1aa90fbff78f26bb1e69d506a8a2023642 Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Wed, 29 May 2024 17:13:09 +0800
+Subject: [PATCH] flow offload add relayd support
+
+---
+ net/netfilter/xt_FLOWOFFLOAD.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/netfilter/xt_FLOWOFFLOAD.c b/net/netfilter/xt_FLOWOFFLOAD.c
+index ecdb2b6..53fca27 100644
+--- a/net/netfilter/xt_FLOWOFFLOAD.c
++++ b/net/netfilter/xt_FLOWOFFLOAD.c
+@@ -368,6 +368,10 @@ static void nf_dev_path_info(const struct net_device_path_stack *stack,
+ 				break;
+ 			}
+ 			break;
++		case DEV_PATH_MTK_WDMA:
++			if (is_zero_ether_addr(info->h_source))
++				memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
++			break;
+ 		default:
+ 			break;
+ 		}
+-- 
+2.18.0
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3099-flow-offload-binding-when-there-is-no-ARP.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3099-flow-offload-binding-when-there-is-no-ARP.patch
index f342f5c..a97fb67 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3099-flow-offload-binding-when-there-is-no-ARP.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3099-flow-offload-binding-when-there-is-no-ARP.patch
@@ -1,45 +1,38 @@
-From 65df61bf369b84c9fbd2145242d09e8a854773e0 Mon Sep 17 00:00:00 2001
+From b512ce1f521f039a73237f70625d11eaa1a725cd Mon Sep 17 00:00:00 2001
 From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
-Date: Tue, 28 May 2024 14:44:58 +0800
+Date: Tue, 4 Jun 2024 23:02:50 +0800
 Subject: [PATCH] flow offload binding when there is no ARP
 
 ---
- net/netfilter/xt_FLOWOFFLOAD.c       | 49 ++++++++++++++++++++--------
- 1 files changed, 34 insertions(+), 15 deletions(-)
+ net/netfilter/xt_FLOWOFFLOAD.c | 35 ++++++++++++++++++++++++----------
+ 1 file changed, 25 insertions(+), 10 deletions(-)
 
 diff --git a/net/netfilter/xt_FLOWOFFLOAD.c b/net/netfilter/xt_FLOWOFFLOAD.c
-index 99fc6a1..fa10d02 100644
+index 53fca27..50cdda1 100644
 --- a/net/netfilter/xt_FLOWOFFLOAD.c
 +++ b/net/netfilter/xt_FLOWOFFLOAD.c
-@@ -395,34 +395,53 @@ static int nf_dev_fill_forward_path(const struct nf_flow_route *route,
- 	if (!nf_is_valid_ether_device(dev))
- 		goto out;
+@@ -369,7 +369,7 @@ static void nf_dev_path_info(const struct net_device_path_stack *stack,
+ 			}
+ 			break;
+ 		case DEV_PATH_MTK_WDMA:
+-			if (is_zero_ether_addr(info->h_source))
++			if (stack->num_paths == 1)
+ 				memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
+ 			break;
+ 		default:
+@@ -405,28 +405,43 @@ static int nf_dev_fill_forward_path(const struct nf_flow_route *route,
  
--	n = dst_neigh_lookup(dst_cache, daddr);
--	if (!n)
--		return -1;
-+	if (ct->status & IPS_NAT_MASK || ct->inet6_mode == CT_INET_MODE_IPV6) {
-+		n = dst_neigh_lookup(dst_cache, daddr);
-+		if (!n)
-+			return -1;
- 
--	read_lock_bh(&n->lock);
--	nud_state = n->nud_state;
+ 	read_lock_bh(&n->lock);
+ 	nud_state = n->nud_state;
 -	ether_addr_copy(ha, n->ha);
--	read_unlock_bh(&n->lock);
--	neigh_release(n);
-+		read_lock_bh(&n->lock);
-+		nud_state = n->nud_state;
++	if (nud_state & NUD_VALID)
 +		ether_addr_copy(ha, n->ha);
-+		read_unlock_bh(&n->lock);
-+		neigh_release(n);
+ 	read_unlock_bh(&n->lock);
+ 	neigh_release(n);
  
 -	if (!(nud_state & NUD_VALID))
 -		return -1;
-+		if (!(nud_state & NUD_VALID))
-+			return -1;
-+	}
- 
+-
  out:
  	return dev_fill_forward_path(dev, ha, stack);
  }
@@ -76,7 +69,7 @@
  	if (nf_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
  		nf_dev_path_info(&stack, &info, ha);
  
-@@ -512,9 +531,9 @@ xt_flowoffload_route_nat(struct sk_buff *skb, const struct nf_conn *ct,
+@@ -516,9 +531,9 @@ xt_flowoffload_route_nat(struct sk_buff *skb, const struct nf_conn *ct,
  
  	if (route->tuple[dir].xmit_type	== FLOW_OFFLOAD_XMIT_NEIGH &&
  	    route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) {
@@ -88,7 +81,7 @@
  			return -1;
  	}
  
-@@ -543,8 +562,8 @@ xt_flowoffload_route_bridge(struct sk_buff *skb, const struct nf_conn *ct,
+@@ -547,8 +562,8 @@ xt_flowoffload_route_bridge(struct sk_buff *skb, const struct nf_conn *ct,
  
  	if (route->tuple[dir].xmit_type	== FLOW_OFFLOAD_XMIT_NEIGH &&
  	    route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1709-v6.2-net-phy-sfp-add-rollball-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1709-v6.10-net-phy-sfp-add-rollball-support.patch
similarity index 90%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1709-v6.2-net-phy-sfp-add-rollball-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1709-v6.10-net-phy-sfp-add-rollball-support.patch
index bac49cf..b044193 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1709-v6.2-net-phy-sfp-add-rollball-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1709-v6.10-net-phy-sfp-add-rollball-support.patch
@@ -1,22 +1,22 @@
-From 1631a36b9ac022ce6ffb58b039a7e85ad3414ed5 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Fri, 2 Jun 2023 13:06:01 +0800
+From 3d251a9986dd10bbc7ae03a9535d4c46d62f0274 Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Fri, 5 Jul 2024 11:37:08 +0800
 Subject: [PATCH] 
  [backport-networking-drivers][999-1709-net-phy-sfp-add-rollball-support.patch]
 
 ---
  drivers/net/phy/marvell.c     |   2 +-
- drivers/net/phy/marvell10g.c  | 168 +++++++++++++--
- drivers/net/phy/mdio-i2c.c    | 309 +++++++++++++++++++++++++++-
- drivers/net/phy/phylink.c     |  74 +++++--
- drivers/net/phy/sfp-bus.c     | 102 +---------
- drivers/net/phy/sfp.c         | 373 +++++++++++++++++++++++++++++-----
+ drivers/net/phy/marvell10g.c  | 168 ++++++++++++-
+ drivers/net/phy/mdio-i2c.c    | 309 +++++++++++++++++++++++-
+ drivers/net/phy/phylink.c     |  74 ++++--
+ drivers/net/phy/sfp-bus.c     | 102 +-------
+ drivers/net/phy/sfp.c         | 428 ++++++++++++++++++++++++++++++----
  drivers/net/phy/sfp.h         |  11 +-
  include/linux/mdio/mdio-i2c.h |  10 +-
- 8 files changed, 874 insertions(+), 175 deletions(-)
+ 8 files changed, 926 insertions(+), 178 deletions(-)
 
 diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
-index 49801c2eb..f25881745 100644
+index 49801c2..f258817 100644
 --- a/drivers/net/phy/marvell.c
 +++ b/drivers/net/phy/marvell.c
 @@ -2175,7 +2175,7 @@ static struct phy_driver marvell_drivers[] = {
@@ -29,7 +29,7 @@
  		.config_init = &m88e1111_config_init,
  		.config_aneg = &marvell_config_aneg,
 diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
-index 1e4631761..7d080d52e 100644
+index 1e46317..7d080d5 100644
 --- a/drivers/net/phy/marvell10g.c
 +++ b/drivers/net/phy/marvell10g.c
 @@ -32,6 +32,15 @@
@@ -302,7 +302,7 @@
  };
  
 diff --git a/drivers/net/phy/mdio-i2c.c b/drivers/net/phy/mdio-i2c.c
-index 09200a70b..85db63c33 100644
+index 09200a7..85db63c 100644
 --- a/drivers/net/phy/mdio-i2c.c
 +++ b/drivers/net/phy/mdio-i2c.c
 @@ -12,6 +12,7 @@
@@ -654,7 +654,7 @@
  }
  EXPORT_SYMBOL_GPL(mdio_i2c_alloc);
 diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
-index f360d9225..67f34ed4c 100644
+index f360d92..67f34ed 100644
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
 @@ -483,62 +483,105 @@ static void phylink_resolve(struct work_struct *w)
@@ -788,7 +788,7 @@
  	if (pl->phydev)
  		phy_start(pl->phydev);
 diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
-index a2f451c31..4be24406b 100644
+index a2f451c..4be2440 100644
 --- a/drivers/net/phy/sfp-bus.c
 +++ b/drivers/net/phy/sfp-bus.c
 @@ -10,12 +10,6 @@
@@ -936,18 +936,19 @@
  	if (ops && ops->module_insert)
  		ret = ops->module_insert(bus->upstream, id);
 diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
-index f8d1742e0..0fdf5d6d4 100644
+index a8eeb57..92c6f1a 100644
 --- a/drivers/net/phy/sfp.c
 +++ b/drivers/net/phy/sfp.c
-@@ -165,6 +165,7 @@ static const enum gpiod_flags gpio_flags[] = {
-  * on board (for a copper SFP) time to initialise.
+@@ -186,7 +186,7 @@ static const enum gpiod_flags gpio_flags[] = {
+  * R_PHY_RETRY is the number of attempts.
   */
- #define T_WAIT			msecs_to_jiffies(50)
-+#define T_WAIT_ROLLBALL		msecs_to_jiffies(25000)
- #define T_START_UP		msecs_to_jiffies(300)
- #define T_START_UP_BAD_GPON	msecs_to_jiffies(60000)
+ #define T_PHY_RETRY		msecs_to_jiffies(50)
+-#define R_PHY_RETRY		12
++#define R_PHY_RETRY		25
  
-@@ -204,8 +205,11 @@ static const enum gpiod_flags gpio_flags[] = {
+ /* SFP module presence detection is poor: the three MOD DEF signals are
+  * the same length on the PCB, which means it's possible for MOD DEF 0 to
+@@ -204,8 +204,11 @@ static const enum gpiod_flags gpio_flags[] = {
  
  /* SFP modules appear to always have their PHY configured for bus address
   * 0x56 (which with mdio-i2c, translates to a PHY address of 22).
@@ -960,7 +961,7 @@
  
  struct sff_data {
  	unsigned int gpios;
-@@ -217,6 +221,7 @@ struct sfp {
+@@ -217,6 +220,7 @@ struct sfp {
  	struct i2c_adapter *i2c;
  	struct mii_bus *i2c_mii;
  	struct sfp_bus *sfp_bus;
@@ -968,7 +969,7 @@
  	struct phy_device *mod_phy;
  	const struct sff_data *type;
  	size_t i2c_block_size;
-@@ -233,6 +238,7 @@ struct sfp {
+@@ -233,6 +237,7 @@ struct sfp {
  	bool need_poll;
  
  	struct mutex st_mutex;			/* Protects state */
@@ -976,11 +977,12 @@
  	unsigned int state_soft_mask;
  	unsigned int state;
  	struct delayed_work poll;
-@@ -249,6 +255,10 @@ struct sfp {
+@@ -249,6 +254,11 @@ struct sfp {
  	struct sfp_eeprom_id id;
  	unsigned int module_power_mW;
  	unsigned int module_t_start_up;
 +	unsigned int module_t_wait;
++	unsigned int phy_t_retry;
 +	bool tx_fault_ignore;
 +
 +	const struct sfp_quirk *quirk;
@@ -1006,7 +1008,7 @@
  	return false;
  }
  
-@@ -303,6 +325,180 @@ static const struct of_device_id sfp_of_match[] = {
+@@ -303,6 +325,224 @@ static const struct of_device_id sfp_of_match[] = {
  };
  MODULE_DEVICE_TABLE(of, sfp_of_match);
  
@@ -1025,6 +1027,42 @@
 +	sfp->mdio_protocol = MDIO_I2C_NONE;
 +}
 +
++// For 10GBASE-T short-reach modules
++static void sfp_fixup_10gbaset_30m(struct sfp *sfp)
++{
++	sfp->id.base.connector = SFF8024_CONNECTOR_RJ45;
++	sfp->id.base.extended_cc = SFF8024_ECC_10GBASE_T_SR;
++}
++
++static void sfp_fixup_rollball(struct sfp *sfp)
++{
++	sfp->mdio_protocol = MDIO_I2C_ROLLBALL;
++
++	/* RollBall modules may disallow access to PHY registers for up to 25
++	 * seconds, and the reads return 0xffff before that. Increase the time
++	 * between PHY probe retries from 50ms to 1s so that we will wait for
++	 * the PHY for a sufficient amount of time.
++	 */
++	sfp->phy_t_retry = msecs_to_jiffies(1000);
++}
++
++static void sfp_fixup_fs_2_5gt(struct sfp *sfp)
++{
++	sfp_fixup_rollball(sfp);
++
++	/* The RollBall fixup is not enough for FS modules, the PHY chip inside
++	 * them does not return 0xffff for PHY ID registers in all MMDs for the
++	 * while initializing. They need a 4 second wait before accessing PHY.
++	 */
++	sfp->module_t_wait = msecs_to_jiffies(4000);
++}
++
++static void sfp_fixup_fs_10gt(struct sfp *sfp)
++{
++	sfp_fixup_10gbaset_30m(sfp);
++	sfp_fixup_fs_2_5gt(sfp);
++}
++
 +static void sfp_fixup_halny_gsfp(struct sfp *sfp)
 +{
 +	/* Ignore the TX_FAULT and LOS signals on this module.
@@ -1034,12 +1072,6 @@
 +	sfp->state_hw_mask &= ~(SFP_F_TX_FAULT | SFP_F_LOS);
 +}
 +
-+static void sfp_fixup_rollball(struct sfp *sfp)
-+{
-+	sfp->mdio_protocol = MDIO_I2C_ROLLBALL;
-+	sfp->module_t_wait = T_WAIT_ROLLBALL;
-+}
-+
 +static void sfp_fixup_rollball_cc(struct sfp *sfp)
 +{
 +	sfp_fixup_rollball(sfp);
@@ -1107,6 +1139,20 @@
 +	SFP_QUIRK("ALCATELLUCENT", "3FE46541AA", '\0', sfp_quirk_2500basex,
 +		  sfp_fixup_long_startup),
 +
++	// Fiberstore SFP-10G-T doesn't identify as copper, uses the Rollball
++	// protocol to talk to the PHY and needs 4 sec wait before probing the
++	// PHY.
++	SFP_QUIRK_F("FS", "SFP-10G-T", '\0', sfp_fixup_fs_10gt),
++
++	// Fiberstore SFP-2.5G-T uses Rollball protocol to talk to the PHY and
++	// needs 4 sec wait before probing the PHY.
++	SFP_QUIRK_F("FS", "SFP-2.5G-T", '\0', sfp_fixup_fs_2_5gt),
++
++	// Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd
++	// NRZ in their EEPROM
++	SFP_QUIRK("FS", "GPON-ONU-34-20BI", '\0', sfp_quirk_2500basex,
++		  sfp_fixup_ignore_tx_fault),
++
 +	SFP_QUIRK_F("HALNy", "HL-GSFP", '\0', sfp_fixup_halny_gsfp),
 +
 +	// Huawei MA5671A can operate at 2500base-X, but report 1.2GBd NRZ in
@@ -1187,7 +1233,7 @@
  static unsigned long poll_jiffies;
  
  static unsigned int sfp_gpio_get_state(struct sfp *sfp)
-@@ -414,9 +610,6 @@ static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
+@@ -414,9 +654,6 @@ static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
  
  static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
  {
@@ -1197,7 +1243,7 @@
  	if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
  		return -EINVAL;
  
-@@ -424,7 +617,15 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
+@@ -424,7 +661,15 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
  	sfp->read = sfp_i2c_read;
  	sfp->write = sfp_i2c_write;
  
@@ -1214,7 +1260,7 @@
  	if (IS_ERR(i2c_mii))
  		return PTR_ERR(i2c_mii);
  
-@@ -442,6 +643,12 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
+@@ -442,6 +687,12 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
  	return 0;
  }
  
@@ -1227,7 +1273,7 @@
  /* Interface */
  static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
  {
-@@ -487,17 +694,18 @@ static void sfp_soft_set_state(struct sfp *sfp, unsigned int state)
+@@ -487,17 +738,18 @@ static void sfp_soft_set_state(struct sfp *sfp, unsigned int state)
  static void sfp_soft_start_poll(struct sfp *sfp)
  {
  	const struct sfp_eeprom_id *id = &sfp->id;
@@ -1255,7 +1301,7 @@
  
  	if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) &&
  	    !sfp->need_poll)
-@@ -511,10 +719,11 @@ static void sfp_soft_stop_poll(struct sfp *sfp)
+@@ -511,10 +763,11 @@ static void sfp_soft_stop_poll(struct sfp *sfp)
  
  static unsigned int sfp_get_state(struct sfp *sfp)
  {
@@ -1270,7 +1316,7 @@
  		state |= sfp_soft_get_state(sfp);
  
  	return state;
-@@ -1448,12 +1657,12 @@ static void sfp_sm_phy_detach(struct sfp *sfp)
+@@ -1448,12 +1701,12 @@ static void sfp_sm_phy_detach(struct sfp *sfp)
  	sfp->mod_phy = NULL;
  }
  
@@ -1285,7 +1331,7 @@
  	if (phy == ERR_PTR(-ENODEV))
  		return PTR_ERR(phy);
  	if (IS_ERR(phy)) {
-@@ -1548,6 +1757,14 @@ static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn)
+@@ -1548,6 +1801,14 @@ static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn)
  	}
  }
  
@@ -1300,7 +1346,7 @@
  /* Probe a SFP for a PHY device if the module supports copper - the PHY
   * normally sits at I2C bus address 0x56, and may either be a clause 22
   * or clause 45 PHY.
-@@ -1563,36 +1780,52 @@ static int sfp_sm_probe_for_phy(struct sfp *sfp)
+@@ -1563,36 +1824,52 @@ static int sfp_sm_probe_for_phy(struct sfp *sfp)
  {
  	int err = 0;
  
@@ -1367,7 +1413,7 @@
  			/* The module appears not to implement bus address
  			 * 0xa2, so assume that the module powers up in the
  			 * indicated mode.
-@@ -1609,13 +1842,21 @@ static int sfp_module_parse_power(struct sfp *sfp)
+@@ -1609,13 +1886,21 @@ static int sfp_module_parse_power(struct sfp *sfp)
  		}
  	}
  
@@ -1391,7 +1437,7 @@
  			 power_mW / 1000, (power_mW / 100) % 10);
  		return 0;
  	}
-@@ -1692,7 +1933,7 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
+@@ -1692,7 +1977,7 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
  {
  	/* SFP module inserted - read I2C data */
  	struct sfp_eeprom_id id;
@@ -1400,7 +1446,7 @@
  	u8 check;
  	int ret;
  
-@@ -1747,10 +1988,16 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
+@@ -1747,10 +2032,16 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
  	 */
  	cotsworks = !memcmp(id.base.vendor_name, "COTSWORKS       ", 16);
  
@@ -1418,7 +1464,7 @@
  			dev_warn(sfp->dev,
  				 "EEPROM base structure checksum failure (0x%02x != 0x%02x)\n",
  				 check, id.base.cc_base);
-@@ -1819,11 +2066,33 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
+@@ -1819,11 +2110,34 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
  	if (ret < 0)
  		return ret;
  
@@ -1436,6 +1482,7 @@
 +
 +	sfp->module_t_start_up = T_START_UP;
 +	sfp->module_t_wait = T_WAIT;
++	sfp->phy_t_retry = T_PHY_RETRY;
 +
 +	sfp->tx_fault_ignore = false;
 +
@@ -1456,7 +1503,7 @@
  
  	return 0;
  }
-@@ -1936,7 +2205,8 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event)
+@@ -1936,7 +2250,8 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event)
  			break;
  
  		/* Report the module insertion to the upstream device */
@@ -1466,7 +1513,7 @@
  		if (err < 0) {
  			sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
  			break;
-@@ -1995,6 +2265,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
+@@ -1995,6 +2310,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
  			sfp_module_stop(sfp->sfp_bus);
  		if (sfp->mod_phy)
  			sfp_sm_phy_detach(sfp);
@@ -1475,7 +1522,7 @@
  		sfp_module_tx_disable(sfp);
  		sfp_soft_stop_poll(sfp);
  		sfp_sm_next(sfp, SFP_S_DOWN, 0);
-@@ -2018,9 +2290,10 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
+@@ -2018,9 +2335,10 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
  
  		/* We need to check the TX_FAULT state, which is not defined
  		 * while TX_DISABLE is asserted. The earliest we want to do
@@ -1488,7 +1535,7 @@
  		break;
  
  	case SFP_S_WAIT:
-@@ -2034,8 +2307,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
+@@ -2034,8 +2352,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
  			 * deasserting.
  			 */
  			timeout = sfp->module_t_start_up;
@@ -1499,7 +1546,7 @@
  			else
  				timeout = 1;
  
-@@ -2057,6 +2330,12 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
+@@ -2057,6 +2375,12 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
  				     sfp->sm_fault_retries == N_FAULT_INIT);
  		} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
  	init_done:
@@ -1512,7 +1559,23 @@
  			sfp->sm_phy_retries = R_PHY_RETRY;
  			goto phy_probe;
  		}
-@@ -2409,6 +2688,8 @@ static int sfp_probe(struct platform_device *pdev)
+@@ -2070,9 +2394,13 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
+ 		 * clear.  Probe for the PHY and check the LOS state.
+ 		 */
+ 		ret = sfp_sm_probe_for_phy(sfp);
+-		if (ret == -ENODEV) {
++		if (ret == -ENODEV || ret == -EINVAL) {
+ 			if (--sfp->sm_phy_retries) {
+-				sfp_sm_next(sfp, SFP_S_INIT_PHY, T_PHY_RETRY);
++				sfp_sm_next(sfp, SFP_S_INIT_PHY,
++					    sfp->phy_t_retry);
++				dev_info(sfp->dev,
++					"no PHY detected, %u tries left\n",
++					sfp->sm_phy_retries);
+ 				break;
+ 			} else {
+ 				dev_info(sfp->dev, "no PHY detected\n");
+@@ -2409,6 +2737,8 @@ static int sfp_probe(struct platform_device *pdev)
  				return PTR_ERR(sfp->gpio[i]);
  		}
  
@@ -1522,7 +1585,7 @@
  	sfp->set_state = sfp_gpio_set_state;
  
 diff --git a/drivers/net/phy/sfp.h b/drivers/net/phy/sfp.h
-index b83f70526..f533e2dd6 100644
+index b83f705..f533e2d 100644
 --- a/drivers/net/phy/sfp.h
 +++ b/drivers/net/phy/sfp.h
 @@ -6,6 +6,14 @@
@@ -1551,7 +1614,7 @@
  int sfp_module_start(struct sfp_bus *bus);
  void sfp_module_stop(struct sfp_bus *bus);
 diff --git a/include/linux/mdio/mdio-i2c.h b/include/linux/mdio/mdio-i2c.h
-index 751dab281..1c2114068 100644
+index 751dab2..1c21140 100644
 --- a/include/linux/mdio/mdio-i2c.h
 +++ b/include/linux/mdio/mdio-i2c.h
 @@ -11,6 +11,14 @@ struct device;
@@ -1571,5 +1634,5 @@
  
  #endif
 -- 
-2.34.1
+2.18.0
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1717-v5.12-net-phy-sfp-add-debugfs-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1717-v5.12-net-phy-sfp-add-debugfs-support.patch
new file mode 100644
index 0000000..6b136a4
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1717-v5.12-net-phy-sfp-add-debugfs-support.patch
@@ -0,0 +1,107 @@
+From 83e56d18e57fc46c3a25f917dbd42fb9b1599ab1 Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Mon, 1 Jul 2024 16:05:32 +0800
+Subject: [PATCH] 
+ [backport-networking-drivers][999-1717-v5.12-net-phy-sfp-add-debugfs-support.patch]
+
+---
+ drivers/net/phy/sfp.c | 55 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 55 insertions(+)
+
+diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
+index d49a825..4bcc2bb 100644
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #include <linux/acpi.h>
+ #include <linux/ctype.h>
++#include <linux/debugfs.h>
+ #include <linux/delay.h>
+ #include <linux/gpio/consumer.h>
+ #include <linux/hwmon.h>
+@@ -268,6 +269,9 @@ struct sfp {
+ 	char *hwmon_name;
+ #endif
+ 
++#if IS_ENABLED(CONFIG_DEBUG_FS)
++	struct dentry *debugfs_dir;
++#endif
+ };
+ 
+ static bool sff_module_supported(const struct sfp_eeprom_id *id)
+@@ -1617,6 +1621,54 @@ static void sfp_module_tx_enable(struct sfp *sfp)
+ 	sfp_set_state(sfp, sfp->state);
+ }
+ 
++#if IS_ENABLED(CONFIG_DEBUG_FS)
++static int sfp_debug_state_show(struct seq_file *s, void *data)
++{
++	struct sfp *sfp = s->private;
++
++	seq_printf(s, "Module state: %s\n",
++		   mod_state_to_str(sfp->sm_mod_state));
++	seq_printf(s, "Module probe attempts: %d %d\n",
++		   R_PROBE_RETRY_INIT - sfp->sm_mod_tries_init,
++		   R_PROBE_RETRY_SLOW - sfp->sm_mod_tries);
++	seq_printf(s, "Device state: %s\n",
++		   dev_state_to_str(sfp->sm_dev_state));
++	seq_printf(s, "Main state: %s\n",
++		   sm_state_to_str(sfp->sm_state));
++	seq_printf(s, "Fault recovery remaining retries: %d\n",
++		   sfp->sm_fault_retries);
++	seq_printf(s, "PHY probe remaining retries: %d\n",
++		   sfp->sm_phy_retries);
++	seq_printf(s, "moddef0: %d\n", !!(sfp->state & SFP_F_PRESENT));
++	seq_printf(s, "rx_los: %d\n", !!(sfp->state & SFP_F_LOS));
++	seq_printf(s, "tx_fault: %d\n", !!(sfp->state & SFP_F_TX_FAULT));
++	seq_printf(s, "tx_disable: %d\n", !!(sfp->state & SFP_F_TX_DISABLE));
++	return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(sfp_debug_state);
++
++static void sfp_debugfs_init(struct sfp *sfp)
++{
++	sfp->debugfs_dir = debugfs_create_dir(dev_name(sfp->dev), NULL);
++
++	debugfs_create_file("state", 0600, sfp->debugfs_dir, sfp,
++			    &sfp_debug_state_fops);
++}
++
++static void sfp_debugfs_exit(struct sfp *sfp)
++{
++	debugfs_remove_recursive(sfp->debugfs_dir);
++}
++#else
++static void sfp_debugfs_init(struct sfp *sfp)
++{
++}
++
++static void sfp_debugfs_exit(struct sfp *sfp)
++{
++}
++#endif
++
+ static void sfp_module_tx_fault_reset(struct sfp *sfp)
+ {
+ 	unsigned int state = sfp->state;
+@@ -2795,6 +2847,8 @@ static int sfp_probe(struct platform_device *pdev)
+ 	if (!sfp->sfp_bus)
+ 		return -ENOMEM;
+ 
++	sfp_debugfs_init(sfp);
++
+ 	return 0;
+ }
+ 
+@@ -2802,6 +2856,7 @@ static int sfp_remove(struct platform_device *pdev)
+ {
+ 	struct sfp *sfp = platform_get_drvdata(pdev);
+ 
++	sfp_debugfs_exit(sfp);
+ 	sfp_unregister_socket(sfp->sfp_bus);
+ 
+ 	rtnl_lock();
+-- 
+2.18.0
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2103-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2103-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch
index 47ac32a..0732a6d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2103-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2103-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch
@@ -10,11 +10,9 @@
  drivers/char/tpm/tpm_tis_spi.c  |  7 +++++++
  3 files changed, 28 insertions(+)
 
-diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
-index 70f785994..b9898a56d 100644
 --- a/drivers/char/tpm/tpm_tis_core.c
 +++ b/drivers/char/tpm/tpm_tis_core.c
-@@ -817,6 +817,21 @@ static const struct tpm_class_ops tpm_tis = {
+@@ -823,6 +823,21 @@ static const struct tpm_class_ops tpm_ti
  	.clk_enable = tpm_tis_clkrun_enable,
  };
  
@@ -36,19 +34,19 @@
  int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
  		      const struct tpm_tis_phy_ops *phy_ops,
  		      acpi_handle acpi_dev_handle)
-@@ -864,6 +879,10 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
+@@ -870,6 +885,12 @@ int tpm_tis_core_init(struct device *dev
  	if (chip->ops->clk_enable != NULL)
  		chip->ops->clk_enable(chip, true);
  
-+	rc = priv->phy_ops->do_calibration(priv, dev);
-+	if (rc)
-+		goto out_err;
++	if (phy_ops->do_calibration) {
++		rc = priv->phy_ops->do_calibration(priv, dev);
++		if (rc)
++			goto out_err;
++	}
 +
  	if (wait_startup(chip, 0) != 0) {
  		rc = -ENODEV;
  		goto out_err;
-diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
-index 7337819f5..7bb0bc8b6 100644
 --- a/drivers/char/tpm/tpm_tis_core.h
 +++ b/drivers/char/tpm/tpm_tis_core.h
 @@ -106,6 +106,7 @@ struct tpm_tis_phy_ops {
@@ -67,11 +65,9 @@
  int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
  		      const struct tpm_tis_phy_ops *phy_ops,
  		      acpi_handle acpi_dev_handle);
-diff --git a/drivers/char/tpm/tpm_tis_spi.c b/drivers/char/tpm/tpm_tis_spi.c
-index 19513e622..3be2d53a5 100644
 --- a/drivers/char/tpm/tpm_tis_spi.c
 +++ b/drivers/char/tpm/tpm_tis_spi.c
-@@ -184,12 +184,19 @@ static int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value)
+@@ -184,12 +184,19 @@ static int tpm_tis_spi_write32(struct tp
  	return rc;
  }
  
@@ -91,6 +87,3 @@
  };
  
  static int tpm_tis_spi_probe(struct spi_device *dev)
--- 
-2.34.1
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2372-drivers-spi-Add-support-for-dynamic-calibration.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2372-drivers-spi-Add-support-for-dynamic-calibration.patch
index d438084..2c6bcef 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2372-drivers-spi-Add-support-for-dynamic-calibration.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2372-drivers-spi-Add-support-for-dynamic-calibration.patch
@@ -9,11 +9,9 @@
  include/linux/spi/spi.h |  42 ++++++++++++
  2 files changed, 183 insertions(+)
 
-diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
-index e562735a3..28bad4a8b 100644
 --- a/drivers/spi/spi.c
 +++ b/drivers/spi/spi.c
-@@ -1109,6 +1109,74 @@ static int spi_transfer_wait(struct spi_controller *ctlr,
+@@ -1109,6 +1109,82 @@ static int spi_transfer_wait(struct spi_
  	return 0;
  }
  
@@ -32,8 +30,13 @@
 +	bool hit;
 +
 +	/* Make sure we can start calibration */
-+	if(!ctlr->cal_target || !ctlr->cal_rule || !ctlr->append_caldata)
++	if(!ctlr->cal_target || !ctlr->cal_rule) {
++		return 0;
++	} else if(!ctlr->append_caldata) {
++		pr_err("%s: calibration is enabled but no controller data.\n",
++		       __func__);
 +		return -EINVAL;
++	}
 +	datalen = ctlr->cal_rule->datalen;
 +	addrlen = ctlr->cal_rule->addrlen;
 +
@@ -70,9 +73,12 @@
 +			*target->cal_item = DIV_ROUND_CLOSEST(hit_val, total_hit);
 +			dev_info(&spi->dev, "calibration result: 0x%x", *target->cal_item);
 +		} else {
++			/* We don't return error in this case because you don't know calibration
++			 * failure is caused by bus error or wrong calibration data provided by
++			 * user or driver.
++			 */
 +			*target->cal_item = origin;
 +			dev_warn(&spi->dev, "calibration failed, fallback to default: 0x%x", origin);
-+			ret = -EIO;
 +		}
 +
 +		list_del(pos);
@@ -88,7 +94,7 @@
  static void _spi_transfer_delay_ns(u32 ns)
  {
  	if (!ns)
-@@ -1720,6 +1788,75 @@ void spi_flush_queue(struct spi_controller *ctlr)
+@@ -1720,6 +1796,75 @@ void spi_flush_queue(struct spi_controll
  /*-------------------------------------------------------------------------*/
  
  #if defined(CONFIG_OF)
@@ -164,7 +170,7 @@
  static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
  			   struct device_node *nc)
  {
-@@ -1841,6 +1978,10 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc)
+@@ -1841,6 +1986,10 @@ of_register_spi_device(struct spi_contro
  	if (rc)
  		goto err_out;
  
@@ -175,8 +181,6 @@
  	/* Store a pointer to the node in the device structure */
  	of_node_get(nc);
  	spi->dev.of_node = nc;
-diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
-index 7067f85ce..5330cd9b0 100644
 --- a/include/linux/spi/spi.h
 +++ b/include/linux/spi/spi.h
 @@ -264,6 +264,40 @@ struct spi_driver {
@@ -232,7 +236,7 @@
  	int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs);
  };
  
-@@ -1369,6 +1408,9 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n)
+@@ -1369,6 +1408,9 @@ spi_register_board_info(struct spi_board
  	{ return 0; }
  #endif
  
@@ -242,6 +246,3 @@
  /* If you're hotplugging an adapter with devices (parport, usb, etc)
   * use spi_new_device() to describe each device.  You can also call
   * spi_unregister_device() to start making that device vanish, but
--- 
-2.34.1
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2719-net-phy-aquantia-add-firmware-download.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2719-net-phy-aquantia-add-firmware-download.patch
index 407896c..3d1f602 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2719-net-phy-aquantia-add-firmware-download.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2719-net-phy-aquantia-add-firmware-download.patch
@@ -153,7 +153,7 @@
 index 000000000..d2828aad4
 --- /dev/null
 +++ b/drivers/net/phy/aquantia_firmware.c
-@@ -0,0 +1,1109 @@
+@@ -0,0 +1,1110 @@
 +// SPDX-License-Identifier: GPL-2.0
 +/* FW download driver for Aquantia PHY
 + */
@@ -1227,7 +1227,6 @@
 +				 PTR_ERR(gangload_kthread));
 +			return PTR_ERR(gangload_kthread);
 +		}
-+		wake_up_process(gangload_kthread);
 +	}
 +
 +	for (i = 0; i < gangload; i++) {
@@ -1250,6 +1249,8 @@
 +	gangload_phydevs[gangload] = phydev;
 +	gangload++;
 +
++	wake_up_process(gangload_kthread);
++
 +	return 0;
 +}
 +
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2727-net-phy-sfp-add-debug-info.patch.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2727-net-phy-sfp-add-debug-info.patch.patch
index 593ddb1..c985f4b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2727-net-phy-sfp-add-debug-info.patch.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2727-net-phy-sfp-add-debug-info.patch.patch
@@ -6,9 +6,9 @@
 ---
  drivers/net/phy/phylink.c     | 11 +++++++-
  drivers/net/phy/sfp-bus.c     |  3 +++
- drivers/net/phy/sfp.c         | 51 +++++++++++++++++++++++++++++------
+ drivers/net/phy/sfp.c         | 50 +++++++++++++++++++++++++++++------
  include/linux/mdio/mdio-i2c.h | 16 +++++++++++
- 4 files changed, 72 insertions(+), 9 deletions(-)
+ 4 files changed, 71 insertions(+), 9 deletions(-)
 
 diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
 index 949e3b8..bb4cd28 100644
@@ -141,11 +141,10 @@
  	err = sfp_add_phy(sfp->sfp_bus, phy);
  	if (err) {
  		phy_device_remove(phy);
-@@ -1779,6 +1810,10 @@ static int sfp_sm_add_mdio_bus(struct sfp *sfp)
+@@ -1779,6 +1810,9 @@ static int sfp_sm_add_mdio_bus(struct sfp *sfp)
  static int sfp_sm_probe_for_phy(struct sfp *sfp)
  {
  	int err = 0;
-+	struct phy_device *phy;
 +
 +	dev_info(sfp->dev, "probing phy device through the [%s] protocol\n",
 +	         mdio_i2c_proto_type(sfp->mdio_protocol));
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
index 8bf5b8b..81a4054 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
@@ -48,7 +48,7 @@
     file://999-1703-v5.18-mxl-gpy-phy-support.patch \
     file://999-1704-v6.2-net-phy-aquantia-add-AQR113C.patch \
     file://999-1708-v6.2-net-phy-add-5GBASER.patch \
-    file://999-1709-v6.2-net-phy-sfp-add-rollball-support.patch \
+    file://999-1709-v6.10-net-phy-sfp-add-rollball-support.patch \
     file://999-1710-v6.2-net-phy-add-phylink-pcs-support.patch;apply=no \
     file://999-1711-v6.2-net-phy-add-phylink-pcs-decode-helper.patch \
     file://999-1712-v6.2-net-phy-add-phylink-rate-matching-support.patch;apply=no \
@@ -56,6 +56,7 @@
     file://999-1714-v5.15-net-dsa-add-netdev_upper_dev_link.patch \
     file://999-1715-v6.2-net-dsa-add-set-queue-mapping.patch \
     file://999-1716-v6.6-net-phy-add-phylink-pcs_enable-and-pcs_disable.patch;apply=no \
+    file://999-1717-v5.12-net-phy-sfp-add-debugfs-support.patch \
     file://999-1750-v5.18-net-macsec-get-ready-to-backport-from-5-18.patch \
     file://999-1751-01-v5.18-net-macsec-move-some-definitions-in-a-dedicated-header.patch \
     file://999-1752-02-v5.18-net-macsec-introduce-the-macsec_context-structure.patch \