[rdk-b][common][bsp][Refactor and sync kernel/wifi from Openwrt]

[Description]
Refactor and sync kernel/wifi from Openwrt

[Release-log]
N/A

diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/701-v5.7-net-dsa-Implement-flow-dissection-for-tag_brcm.c.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/701-v5.7-net-dsa-Implement-flow-dissection-for-tag_brcm.c.patch
new file mode 100644
index 0000000..5d7b90f
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/701-v5.7-net-dsa-Implement-flow-dissection-for-tag_brcm.c.patch
@@ -0,0 +1,62 @@
+From 52015366e361a88c569550a285c71f72bb095661 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Sun, 22 Mar 2020 14:09:57 -0700
+Subject: [PATCH] net: dsa: Implement flow dissection for tag_brcm.c
+
+Provide a flow_dissect callback which returns the network offset and
+where to find the skb protocol, given the tags structure a common
+function works for both tagging formats that are supported.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Vivien Didelot <vivien.didelot@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/dsa/tag_brcm.c | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+--- a/net/dsa/tag_brcm.c
++++ b/net/dsa/tag_brcm.c
+@@ -144,6 +144,27 @@ static struct sk_buff *brcm_tag_rcv_ll(s
+ 
+ 	return skb;
+ }
++
++static int brcm_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
++				 int *offset)
++{
++	/* We have been called on the DSA master network device after
++	 * eth_type_trans() which pulled the Ethernet header already.
++	 * Frames have one of these two layouts:
++	 * -----------------------------------
++	 * | MAC DA | MAC SA | 4b tag | Type | DSA_TAG_PROTO_BRCM
++	 * -----------------------------------
++	 * -----------------------------------
++	 * | 4b tag | MAC DA | MAC SA | Type | DSA_TAG_PROTO_BRCM_PREPEND
++	 * -----------------------------------
++	 * skb->data points 2 bytes before the actual Ethernet type field and
++	 * we have an offset of 4bytes between where skb->data and where the
++	 * payload starts.
++	 */
++	*offset = BRCM_TAG_LEN;
++	*proto = ((__be16 *)skb->data)[1];
++	return 0;
++}
+ #endif
+ 
+ #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM)
+@@ -179,6 +200,7 @@ static const struct dsa_device_ops brcm_
+ 	.xmit	= brcm_tag_xmit,
+ 	.rcv	= brcm_tag_rcv,
+ 	.overhead = BRCM_TAG_LEN,
++	.flow_dissect = brcm_tag_flow_dissect,
+ };
+ 
+ DSA_TAG_DRIVER(brcm_netdev_ops);
+@@ -207,6 +229,7 @@ static const struct dsa_device_ops brcm_
+ 	.xmit	= brcm_tag_xmit_prepend,
+ 	.rcv	= brcm_tag_rcv_prepend,
+ 	.overhead = BRCM_TAG_LEN,
++	.flow_dissect = brcm_tag_flow_dissect,
+ };
+ 
+ DSA_TAG_DRIVER(brcm_prepend_netdev_ops);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
index 0ea2cb3..8147d61 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
@@ -198,6 +198,7 @@
     file://610-v5.18-netfilter-flowtable-add-check_dst-in-packet-path.patch \
     file://610-v5.9-net-bridge-clear-bridge-s-private-skb-space-on-xmit.patch \
     file://700-v5.5-net-core-allow-fast-GRO-for-skbs-with-Ethernet-heade.patch \
+    file://701-v5.7-net-dsa-Implement-flow-dissection-for-tag_brcm.c.patch \
     file://716-v5.5-net-sfp-move-fwnode-parsing-into-sfp-bus-layer.patch \
     file://717-v5.5-net-sfp-rework-upstream-interface.patch \
     file://718-v5.5-net-sfp-fix-sfp_bus_put-kernel-documentation.patch \
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/defconfig b/recipes-kernel/linux/linux-mediatek-5.4/generic/defconfig
index d793e06..73faf71 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/defconfig
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/defconfig
@@ -1028,6 +1028,7 @@
 # CONFIG_CRYPTO_DEV_HISI_ZIP is not set
 # CONFIG_CRYPTO_DEV_IMGTEC_HASH is not set
 # CONFIG_CRYPTO_DEV_MARVELL_CESA is not set
+# CONFIG_CRYPTO_DEV_MEDIATEK is not set
 # CONFIG_CRYPTO_DEV_MV_CESA is not set
 # CONFIG_CRYPTO_DEV_MXC_SCC is not set
 # CONFIG_CRYPTO_DEV_MXS_DCP is not set
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/221-module_exports.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/221-module_exports.patch
index 47f40ac..446bf53 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/221-module_exports.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/221-module_exports.patch
@@ -30,7 +30,7 @@
  /* Align . to a 8 byte boundary equals to maximum function alignment. */
  #define ALIGN_FUNCTION()  . = ALIGN(8)
  
-@@ -407,14 +417,14 @@
+@@ -408,14 +418,14 @@
  	/* Kernel symbol table: Normal symbols */			\
  	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\
  		__start___ksymtab = .;					\
@@ -47,7 +47,7 @@
  		__stop___ksymtab_gpl = .;				\
  	}								\
  									\
-@@ -476,7 +486,7 @@
+@@ -477,7 +487,7 @@
  									\
  	/* Kernel symbol table: strings */				\
          __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988-clkitg.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988-clkitg.dtsi
index 1e020d8..14739ac 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988-clkitg.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988-clkitg.dtsi
@@ -76,8 +76,8 @@
 			<&topckgen CK_TOP_EMMC_400M>,
 			<&topckgen CK_TOP_SPI>,
 			<&topckgen CK_TOP_SPIM_MST>,
-			<&topckgen CK_TOP_NFI1X>,
-			<&topckgen CK_TOP_SPINFI_BCK>,
+			<&system_clk>,
+			<&system_clk>,
 			<&topckgen CK_TOP_I2C_BCK>,
 			<&topckgen CK_TOP_USB_SYS>,
 			<&topckgen CK_TOP_USB_SYS_P1>,
@@ -108,8 +108,8 @@
 			<&topckgen CK_TOP_EMMC_400M_SEL>,
 			<&topckgen CK_TOP_SPI_SEL>,
 			<&topckgen CK_TOP_SPIM_MST_SEL>,
-			<&topckgen CK_TOP_NFI1X_SEL>,
-			<&topckgen CK_TOP_SPINFI_SEL>,
+			<&system_clk>,
+			<&system_clk>,
 			<&system_clk>,
 			<&topckgen CK_TOP_I2C_SEL>,
 			<&topckgen CK_TOP_PCIE_MBIST_250M_SEL>,
@@ -179,8 +179,8 @@
 			<&infracfg CK_INFRA_UART_O0>,
 			<&infracfg CK_INFRA_UART_O1>,
 			<&infracfg CK_INFRA_UART_O2>,
-			<&infracfg CK_INFRA_NFI_O>,
-			<&infracfg CK_INFRA_SPINFI_O>,
+			<&system_clk>,
+			<&system_clk>,
 			<&infracfg CK_INFRA_SPI0_O>,
 			<&infracfg CK_INFRA_SPI1_O>,
 			<&infracfg CK_INFRA_LB_MUX_FRTC>,
@@ -231,17 +231,13 @@
 			<&infracfg_ao CK_INFRA_66M_AP_DMA_BCK>,
 			<&infracfg_ao CK_INFRA_66M_SEJ_BCK>,
 			<&infracfg_ao CK_INFRA_PRE_CK_SEJ_F13M>,
-			<&infracfg_ao CK_INFRA_66M_TRNG>,
 			<&system_clk>,
 			<&infracfg_ao CK_INFRA_I2C_BCK>,
-			<&infracfg_ao CK_INFRA_66M_UART0_PCK>,
-			<&infracfg_ao CK_INFRA_66M_UART1_PCK>,
-			<&infracfg_ao CK_INFRA_66M_UART2_PCK>,
 			<&infracfg_ao CK_INFRA_52M_UART0_CK>,
 			<&infracfg_ao CK_INFRA_52M_UART1_CK>,
 			<&infracfg_ao CK_INFRA_52M_UART2_CK>,
-			<&infracfg_ao CK_INFRA_NFI>,
-			<&infracfg_ao CK_INFRA_SPINFI>,
+			<&system_clk>,
+			<&system_clk>,
 			<&infracfg_ao CK_INFRA_66M_NFI_HCK>,
 			<&infracfg_ao CK_INFRA_104M_SPI0>,
 			<&infracfg_ao CK_INFRA_104M_SPI1>,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
index a93f9c2..28e3002 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
@@ -870,15 +870,17 @@
 	};
 
 	snand: snfi@11001000 {
-		compatible = "mediatek,mt7986-snand";
+		compatible = "mediatek,mt7988-snand";
 		reg = <0 0x11001000 0 0x1000>, <0 0x11002000 0 0x1000>;
 		reg-names = "nfi", "ecc";
 		interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&system_clk>,
-			 <&system_clk>,
-			 <&system_clk>,
-			 <&system_clk>;
-		clock-names = "nfi_clk", "pad_clk", "ecc_clk", "nfi_hclk";
+		clocks = <&infracfg_ao CK_INFRA_SPINFI>,
+			 <&infracfg_ao CK_INFRA_NFI>;
+		clock-names = "pad_clk", "nfi_clk";
+		assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>,
+				  <&topckgen CK_TOP_NFI1X_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>,
+					 <&topckgen CK_TOP_CB_M_D8>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/clk/mediatek/clk-mt7988.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/clk/mediatek/clk-mt7988.c
index 6ccd92f..04a680b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/clk/mediatek/clk-mt7988.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/clk/mediatek/clk-mt7988.c
@@ -728,18 +728,10 @@
 		    "infra_66m_mck", 29),
 	GATE_INFRA1(CK_INFRA_PRE_CK_SEJ_F13M, "infra_pre_ck_sej_f13m",
 		    "infra_ck_f26m", 30),
-	GATE_INFRA1(CK_INFRA_66M_TRNG, "infra_hf_66m_trng", "infra_peri_66m_o",
-		    31),
 	/* INFRA2 */
 	GATE_INFRA2(CK_INFRA_26M_THERM_SYSTEM, "infra_hf_26m_therm_system",
 		    "infra_ck_f26m", 0),
 	GATE_INFRA2(CK_INFRA_I2C_BCK, "infra_i2c_bck", "infra_i2c_o", 1),
-	GATE_INFRA2(CK_INFRA_66M_UART0_PCK, "infra_hf_66m_uart0_pck",
-		    "infra_66m_mck", 3),
-	GATE_INFRA2(CK_INFRA_66M_UART1_PCK, "infra_hf_66m_uart1_pck",
-		    "infra_66m_mck", 4),
-	GATE_INFRA2(CK_INFRA_66M_UART2_PCK, "infra_hf_66m_uart2_pck",
-		    "infra_66m_mck", 5),
 	GATE_INFRA2(CK_INFRA_52M_UART0_CK, "infra_f_52m_uart0",
 		    "infra_mux_uart0_sel", 3),
 	GATE_INFRA2(CK_INFRA_52M_UART1_CK, "infra_f_52m_uart1",
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-ecc.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-ecc.c
index 885dec3..450e662 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-ecc.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-ecc.c
@@ -99,6 +99,14 @@
 		.errnum_bits = 5,
 		.errnum_shift = 8,
 	},
+	[SNAND_SOC_MT7988] = {
+		.ecc_caps = mt7986_ecc_caps,
+		.num_ecc_cap = ARRAY_SIZE(mt7986_ecc_caps),
+		.regs = mt7986_ecc_regs,
+		.mode_shift = 5,
+		.errnum_bits = 5,
+		.errnum_shift = 8,
+	},
 };
 
 static inline uint32_t ecc_read32(struct mtk_snand *snf, uint32_t reg)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-mtd.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-mtd.c
index e1e0317..09dc34d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-mtd.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-mtd.c
@@ -494,10 +494,17 @@
 	.en_nfi_hclk = true
 };
 
+static struct mtk_snand_of_id mt7988_soc_id = {
+	.soc = SNAND_SOC_MT7988,
+	.en_ecc_clk = false,
+	.en_nfi_hclk = false
+};
+
 static const struct of_device_id mtk_snand_ids[] = {
 	{ .compatible = "mediatek,mt7622-snand", .data = &mt7622_soc_id },
 	{ .compatible = "mediatek,mt7629-snand", .data = &mt7629_soc_id },
 	{ .compatible = "mediatek,mt7986-snand", .data = &mt7986_soc_id },
+	{ .compatible = "mediatek,mt7988-snand", .data = &mt7988_soc_id },
 	{ },
 };
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.c
index a0a50f7..341e8c8 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.c
@@ -215,6 +215,20 @@
 		.latch_lat = 0,
 		.sample_delay = 40
 	},
+	[SNAND_SOC_MT7988] = {
+		.sector_size = 1024,
+		.max_sectors = 16,
+		.fdm_size = 8,
+		.fdm_ecc_size = 1,
+		.fifo_size = 64,
+		.bbm_swap = true,
+		.empty_page_check = true,
+		.mastersta_mask = NFI_MASTERSTA_MASK_7986,
+		.spare_sizes = mt7986_spare_sizes,
+		.num_spare_size = ARRAY_SIZE(mt7986_spare_sizes),
+		.latch_lat = 0,
+		.sample_delay = 40
+	},
 };
 
 static inline uint32_t nfi_read32(struct mtk_snand *snf, uint32_t reg)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.h
index 37bb6e6..a508ea5 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.h
@@ -19,6 +19,7 @@
 	SNAND_SOC_MT7629,
 	SNAND_SOC_MT7981,
 	SNAND_SOC_MT7986,
+	SNAND_SOC_MT7988,
 
 	__SNAND_SOC_MAX
 };
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 5ad8645..69e92db 100755
--- 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
@@ -265,7 +265,7 @@
 {
 	struct mtk_eth *eth = file->private_data;
 	char buf[32], *token, *p = buf;
-	u32 reg, value, phy;
+	unsigned long reg, value, phy;
 	int ret;
 
 	if (!mt7530_exist(eth))
@@ -314,7 +314,7 @@
 {
 	struct mtk_eth *eth = file->private_data;
 	char buf[32], *token, *p = buf;
-	u32 reg, value, phy;
+	unsigned long reg, value, phy;
 	int ret;
 
 	if (*off != 0)
@@ -766,7 +766,8 @@
 	seq_printf(seq, "cpu next free: %d\n", (int)(ring->next_free - ring->dma));
 	seq_printf(seq, "cpu last free: %d\n", (int)(ring->last_free - ring->dma));
 	for (i = 0; i < MTK_DMA_SIZE; i++) {
-		dma_addr_t tmp = ring->phys + i * eth->soc->txrx.txd_size;
+		dma_addr_t tmp = ring->phys +
+				 i * (dma_addr_t)eth->soc->txrx.txd_size;
 
 		tx_ring = ring->dma + i * eth->soc->txrx.txd_size;
 
@@ -807,7 +808,8 @@
 	int i = 0;
 
 	for (i = 0; i < MTK_DMA_SIZE; i++) {
-		dma_addr_t addr = eth->phy_scratch_ring + i * eth->soc->txrx.txd_size;
+		dma_addr_t addr = eth->phy_scratch_ring +
+				  i * (dma_addr_t)eth->soc->txrx.txd_size;
 
 		hwtx_ring = eth->scratch_ring + i * eth->soc->txrx.txd_size;
 
@@ -1062,6 +1064,9 @@
 		agg_cnt = RX_DMA_GET_AGG_CNT(rxd->rxd2);
 	}
 
+	if (idx >= MTK_HW_LRO_RING_NUM)
+		return;
+
 	agg_size = RX_DMA_GET_PLEN0(rxd->rxd2);
 
 	hw_lro_agg_size_cnt[idx][agg_size / 5000]++;
@@ -1084,6 +1089,9 @@
 		flush_reason = RX_DMA_GET_REV(rxd->rxd2);
 	}
 
+	if (idx >= MTK_HW_LRO_RING_NUM)
+		return;
+
 	if ((flush_reason & 0x7) == MTK_HW_LRO_AGG_FLUSH)
 		hw_lro_agg_flush_cnt[idx]++;
 	else if ((flush_reason & 0x7) == MTK_HW_LRO_AGE_FLUSH)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_path.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_path.c
index 04f3f26..c9b1a43 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_path.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_path.c
@@ -204,8 +204,10 @@
 		regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
 		val &= SYSCFG0_SGMII_MASK;
 
-		if ((path == MTK_GMAC1_RGMII && val == SYSCFG0_SGMII_GMAC1) ||
-		    (path == MTK_GMAC2_RGMII && val == SYSCFG0_SGMII_GMAC2))
+		if ((path == MTK_ETH_PATH_GMAC1_RGMII &&
+		     val == SYSCFG0_SGMII_GMAC1) ||
+		    (path == MTK_ETH_PATH_GMAC2_RGMII &&
+		     val == SYSCFG0_SGMII_GMAC2))
 			val = 0;
 		else
 			updated = false;
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 ee9cd47..2d2797d 100755
--- 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
@@ -1143,7 +1143,8 @@
 	if (unlikely(dma_mapping_error(eth->dev, dma_addr)))
 		return -ENOMEM;
 
-	phy_ring_tail = eth->phy_scratch_ring + soc->txrx.txd_size * (cnt - 1);
+	phy_ring_tail = eth->phy_scratch_ring +
+			(dma_addr_t)soc->txrx.txd_size * (cnt - 1);
 
 	for (i = 0; i < cnt; i++) {
 		struct mtk_tx_dma_v2 *txd;
@@ -1738,7 +1739,7 @@
 	while (done < budget) {
 		struct net_device *netdev = NULL;
 		unsigned int pktlen;
-		dma_addr_t dma_addr;
+		dma_addr_t dma_addr = 0;
 		int mac = 0;
 
 		if (eth->hwlro)
@@ -2126,7 +2127,8 @@
 					       &ring->phys, GFP_KERNEL);
 	else {
 		ring->dma =  eth->scratch_ring + MTK_DMA_SIZE * sz;
-		ring->phys = eth->phy_scratch_ring + MTK_DMA_SIZE * sz;
+		ring->phys = eth->phy_scratch_ring +
+			     MTK_DMA_SIZE * (dma_addr_t)sz;
 	}
 
 	if (!ring->dma)
@@ -3068,6 +3070,15 @@
 	}
 }
 
+void mtk_set_pse_drop(u32 config)
+{
+	struct mtk_eth *eth = g_eth;
+
+	if (eth)
+		mtk_w32(eth, config, PSE_PPE0_DROP);
+}
+EXPORT_SYMBOL(mtk_set_pse_drop);
+
 static int mtk_open(struct net_device *dev)
 {
 	struct mtk_mac *mac = netdev_priv(dev);
@@ -3396,16 +3407,15 @@
 		MTK_FE_INT_RFIFO_OV | MTK_FE_INT_RFIFO_UF, MTK_FE_INT_ENABLE);
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-		/* PSE dummy page mechanism */
-		mtk_w32(eth, PSE_DUMMY_WORK_GDM(1) | PSE_DUMMY_WORK_GDM(2) |
-			PSE_DUMMY_WORK_GDM(3) | DUMMY_PAGE_THR, PSE_DUMY_REQ);
-
 		/* PSE should not drop port1, port8 and port9 packets */
 		mtk_w32(eth, 0x00000302, PSE_NO_DROP_CFG);
 
 		/* PSE should drop p8 and p9 packets when WDMA Rx ring full*/
 		mtk_w32(eth, 0x00000300, PSE_PPE0_DROP);
 
+		/* PSE free buffer drop threshold */
+		mtk_w32(eth, 0x00600009, PSE_IQ_REV(8));
+
 		/* GDM and CDM Threshold */
 		mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
 		mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
@@ -4027,8 +4037,13 @@
 					         "ethernet:fixed link", mac);
 			}
 
-			if (!of_property_read_string(to_of_node(fixed_node), "label", &label))
-				strcpy(phylink_priv->label, label);
+			if (!of_property_read_string(to_of_node(fixed_node),
+						     "label", &label)) {
+				if (strlen(label) < 16)
+					strcpy(phylink_priv->label, label);
+				else
+					dev_err(eth->dev, "insufficient space for label!\n");
+			}
 
 			phy_np = of_parse_phandle(to_of_node(fixed_node), "phy-handle", 0);
 			if (phy_np) {
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 1a11af6..00eec80 100755
--- 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
@@ -1601,6 +1601,7 @@
 };
 
 /* the struct describing the SoC. these are declared in the soc_xyz.c files */
+extern struct mtk_eth *g_eth;
 extern const struct of_device_id of_mtk_match[];
 extern u32 mtk_hwlro_stats_ebl;
 
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 b1ecae9..5312a0b 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
@@ -408,7 +408,7 @@
 {
 	u32 foe_table_sz;
 	u32 foe_mib_tb_sz;
-	u32 etry_num_cfg;
+	int etry_num_cfg;
 
 	if (ppe_id >= CFG_PPE_NUM)
 		return -EINVAL;
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 32711b3..dd31560 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
@@ -43,6 +43,7 @@
 static uint8_t *show_cpu_reason(struct sk_buff *skb)
 {
 	static u8 buf[32];
+	int ret;
 
 	switch (skb_hnat_reason(skb)) {
 	case TTL_0:
@@ -91,8 +92,12 @@
 		return "Pre bind\n";
 	}
 
-	sprintf(buf, "CPU Reason Error - %X\n", skb_hnat_entry(skb));
-	return buf;
+	ret = snprintf(buf, sizeof(buf), "CPU Reason Error - %X\n",
+		       skb_hnat_entry(skb));
+	if (ret == strlen(buf))
+		return buf;
+	else
+		return "CPU Reason Error\n";
 }
 
 uint32_t foe_dump_pkt(struct sk_buff *skb)
@@ -829,7 +834,8 @@
 		*packets = cnt_r2 + ((u64)cnt_r3 << 32);
 	} else {
 		*bytes = cnt_r0 + ((u64)(cnt_r1 & 0xffff) << 32);
-		*packets = ((cnt_r1 & 0xffff0000) >> 16) + ((cnt_r2 & 0xffffff) << 16);
+		*packets = ((cnt_r1 & 0xffff0000) >> 16) +
+			   ((u64)(cnt_r2 & 0xffffff) << 16);
 	}
 
 	return 0;
@@ -845,6 +851,9 @@
 	if (ppe_id >= CFG_PPE_NUM)
 		return NULL;
 
+	if (index >= hnat_priv->foe_etry_num)
+		return NULL;
+
 	if (!hnat_priv->data->per_flow_accounting)
 		return NULL;
 
@@ -853,7 +862,7 @@
 
 	h->acct[ppe_id][index].bytes += bytes;
 	h->acct[ppe_id][index].packets += packets;
-	
+
 	if (diff) {
 		diff->bytes = bytes;
 		diff->packets = packets;
@@ -2159,6 +2168,15 @@
 
 	line[length] = '\0';
 
+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
+	if (max_rate > 100000000 || max_rate < 0 ||
+	    min_rate > 100000000 || min_rate < 0)
+#else
+	if (max_rate > 10000000 || max_rate < 0 ||
+	    min_rate > 10000000 || min_rate < 0)
+#endif
+		return -EINVAL;
+
 	while (max_rate > 127) {
 		max_rate /= 10;
 		max_exp++;
@@ -2477,7 +2495,7 @@
 static ssize_t hnat_qos_toggle_write(struct file *file, const char __user *buffer,
 				     size_t count, loff_t *data)
 {
-	char buf[32], tmp[32];
+	char buf[32] = {0}, tmp[32];
 	int len = count;
 	char *p_buf = NULL, *p_token = NULL;
 
@@ -2670,25 +2688,26 @@
 
 	buf[len] = '\0';
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
-	sscanf(buf, "%d %x %x %x %hx %hx %x %x %x %hx %hx %s %s %x %x %x",
-	       &hash,
-	       &entry.ipv4_hnapt.info_blk1,
-	       &entry.ipv4_hnapt.sip,
-	       &entry.ipv4_hnapt.dip,
-	       &entry.ipv4_hnapt.sport,
-	       &entry.ipv4_hnapt.dport,
-	       &entry.ipv4_hnapt.info_blk2,
-	       &entry.ipv4_hnapt.new_sip,
-	       &entry.ipv4_hnapt.new_dip,
-	       &entry.ipv4_hnapt.new_sport,
-	       &entry.ipv4_hnapt.new_dport,
-	       dmac_str, smac_str, &tport_id, &tops_entry, &cdrt_id);
+	if (sscanf(buf, "%d %x %x %x %hx %hx %x %x %x %hx %hx %s %s %x %x %x",
+		   &hash,
+		   &entry.ipv4_hnapt.info_blk1,
+		   &entry.ipv4_hnapt.sip,
+		   &entry.ipv4_hnapt.dip,
+		   &entry.ipv4_hnapt.sport,
+		   &entry.ipv4_hnapt.dport,
+		   &entry.ipv4_hnapt.info_blk2,
+		   &entry.ipv4_hnapt.new_sip,
+		   &entry.ipv4_hnapt.new_dip,
+		   &entry.ipv4_hnapt.new_sport,
+		   &entry.ipv4_hnapt.new_dport,
+		   dmac_str, smac_str, &tport_id, &tops_entry, &cdrt_id) != 16)
+		return -EFAULT;
 
 	entry.ipv4_hnapt.tport_id = tport_id;
 	entry.ipv4_hnapt.tops_entry = tops_entry;
 	entry.ipv4_hnapt.cdrt_id = cdrt_id;
 
-	if ((hash > 8192) || (hash < -1) || (hash % 4 != 0) ||
+	if ((hash >= hnat_priv->foe_etry_num) || (hash < -1) ||
 	    (tport_id > 16) || (tport_id < 0) ||
 	    (tops_entry > 64) || (tops_entry < 0) ||
 	    (cdrt_id > 255) || (cdrt_id < 0) ||
@@ -2701,24 +2720,25 @@
 	    (entry.ipv4_hnapt.new_dport > 65535) ||
 	    (entry.ipv4_hnapt.new_dport < 0)) {
 		hnat_static_entry_help();
-		return -EINVAL;
+		return -EFAULT;
 	}
 #else
-	sscanf(buf, "%d %x %x %x %hx %hx %x %x %x %hx %hx %s %s",
-	       &hash,
-	       &entry.ipv4_hnapt.info_blk1,
-	       &entry.ipv4_hnapt.sip,
-	       &entry.ipv4_hnapt.dip,
-	       &entry.ipv4_hnapt.sport,
-	       &entry.ipv4_hnapt.dport,
-	       &entry.ipv4_hnapt.info_blk2,
-	       &entry.ipv4_hnapt.new_sip,
-	       &entry.ipv4_hnapt.new_dip,
-	       &entry.ipv4_hnapt.new_sport,
-	       &entry.ipv4_hnapt.new_dport,
-	       dmac_str, smac_str);
+	if (sscanf(buf, "%d %x %x %x %hx %hx %x %x %x %hx %hx %s %s",
+		   &hash,
+		   &entry.ipv4_hnapt.info_blk1,
+		   &entry.ipv4_hnapt.sip,
+		   &entry.ipv4_hnapt.dip,
+		   &entry.ipv4_hnapt.sport,
+		   &entry.ipv4_hnapt.dport,
+		   &entry.ipv4_hnapt.info_blk2,
+		   &entry.ipv4_hnapt.new_sip,
+		   &entry.ipv4_hnapt.new_dip,
+		   &entry.ipv4_hnapt.new_sport,
+		   &entry.ipv4_hnapt.new_dport,
+		   dmac_str, smac_str) != 13)
+		return -EFAULT;
 
-	if ((hash > 8192) || (hash < -1) || (hash % 4 != 0) ||
+	if ((hash >= hnat_priv->foe_etry_num) || (hash < -1) ||
 	    (entry.ipv4_hnapt.sport > 65535) ||
 	    (entry.ipv4_hnapt.sport < 0) ||
 	    (entry.ipv4_hnapt.dport > 65535) ||
@@ -2728,7 +2748,7 @@
 	    (entry.ipv4_hnapt.new_dport > 65535) ||
 	    (entry.ipv4_hnapt.new_dport < 0)) {
 		hnat_static_entry_help();
-		return -EINVAL;
+		return -EFAULT;
 	}
 #endif
 
@@ -2884,7 +2904,11 @@
 		h->regset[i]->nregs = ARRAY_SIZE(hnat_regs);
 		h->regset[i]->base = h->ppe_base[i];
 
-		snprintf(name, sizeof(name), "regdump%ld", i);
+		ret = snprintf(name, sizeof(name), "regdump%ld", i);
+		if (ret != strlen(name)) {
+			ret = -ENOMEM;
+			goto err1;
+		}
 		file = debugfs_create_regset32(name, 0444,
 					       root, h->regset[i]);
 		if (!file) {
@@ -2921,13 +2945,21 @@
 			    &hnat_static_fops);
 
 	for (i = 0; i < hnat_priv->data->num_of_sch; i++) {
-		snprintf(name, sizeof(name), "qdma_sch%ld", i);
+		ret = snprintf(name, sizeof(name), "qdma_sch%ld", i);
+		if (ret != strlen(name)) {
+			ret = -ENOMEM;
+			goto err1;
+		}
 		debugfs_create_file(name, 0444, root, (void *)i,
 				    &hnat_sched_fops);
 	}
 
 	for (i = 0; i < MTK_QDMA_TX_NUM; i++) {
-		snprintf(name, sizeof(name), "qdma_txq%ld", i);
+		ret = snprintf(name, sizeof(name), "qdma_txq%ld", i);
+		if (ret != strlen(name)) {
+			ret = -ENOMEM;
+			goto err1;
+		}
 		debugfs_create_file(name, 0444, root, (void *)i,
 				    &hnat_queue_fops);
 	}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.c
index 512c845..210b191 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_mcast.c
@@ -297,11 +297,11 @@
 	INIT_WORK(&pmcast->work, hnat_mcast_nlmsg_handler);
 	pmcast->queue = create_singlethread_workqueue("ppe_mcast");
 	if (!pmcast->queue)
-		goto err;
+		goto err1;
 
 	pmcast->msock = hnat_mcast_netlink_open(&init_net);
 	if (!pmcast->msock)
-		goto err;
+		goto err2;
 
 	hnat_priv->pmcast = pmcast;
 
@@ -325,11 +325,10 @@
 	cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_MCAST_PPSE, MC_P3_PPSE, 5);
 
 	return 0;
-err:
+err2:
 	if (pmcast->queue)
 		destroy_workqueue(pmcast->queue);
-	if (pmcast->msock)
-		sock_release(pmcast->msock);
+err1:
 	kfree(pmcast);
 
 	return -1;
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 ddc8bb5..24350c9 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
@@ -421,6 +421,10 @@
 	trace_printk("%s: vlan_prot=0x%x, vlan_tci=%x\n", __func__,
 		     ntohs(skb->vlan_proto), skb->vlan_tci);
 
+	if (skb_hnat_entry(skb) >= hnat_priv->foe_etry_num ||
+	    skb_hnat_ppe(skb) >= CFG_PPE_NUM)
+		return -1;
+
 	dev = get_dev_from_index(skb->vlan_tci & VLAN_VID_MASK);
 
 	if (dev) {
@@ -479,6 +483,10 @@
 	struct foe_entry *entry;
 	struct net_device *dev;
 
+	if (skb_hnat_entry(skb) >= hnat_priv->foe_etry_num ||
+	    skb_hnat_ppe(skb) >= CFG_PPE_NUM)
+		return -1;
+
 	entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
 
 	if (IS_IPV4_GRP(entry))
@@ -730,6 +738,9 @@
 mtk_hnat_ipv6_nf_pre_routing(void *priv, struct sk_buff *skb,
 			     const struct nf_hook_state *state)
 {
+	if (!skb)
+		goto drop;
+
 	if (!is_ppe_support_type(skb)) {
 		hnat_set_head_frags(state, skb, 1, hnat_set_alg);
 		return NF_ACCEPT;
@@ -743,8 +754,6 @@
 	if (do_ext2ge_fast_try(state->in, skb)) {
 		if (!do_hnat_ext_to_ge(skb, state->in, __func__))
 			return NF_STOLEN;
-		if (!skb)
-			goto drop;
 		return NF_ACCEPT;
 	}
 
@@ -772,12 +781,14 @@
 #endif
 	return NF_ACCEPT;
 drop:
-	printk_ratelimited(KERN_WARNING
-				"%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x, sport=0x%x, reason=0x%x, alg=0x%x)\n",
-				__func__, state->in->name, skb_hnat_iface(skb),
-				HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
-				skb_hnat_sport(skb), skb_hnat_reason(skb),
-				skb_hnat_alg(skb));
+	if (skb)
+		printk_ratelimited(KERN_WARNING
+			"%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x,\n"
+			"sport=0x%x, reason=0x%x, alg=0x%x)\n",
+			__func__, state->in->name, skb_hnat_iface(skb),
+			HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
+			skb_hnat_sport(skb), skb_hnat_reason(skb),
+			skb_hnat_alg(skb));
 
 	return NF_DROP;
 }
@@ -786,6 +797,9 @@
 mtk_hnat_ipv4_nf_pre_routing(void *priv, struct sk_buff *skb,
 			     const struct nf_hook_state *state)
 {
+	if (!skb)
+		goto drop;
+
 	if (!is_ppe_support_type(skb)) {
 		hnat_set_head_frags(state, skb, 1, hnat_set_alg);
 		return NF_ACCEPT;
@@ -799,8 +813,6 @@
 	if (do_ext2ge_fast_try(state->in, skb)) {
 		if (!do_hnat_ext_to_ge(skb, state->in, __func__))
 			return NF_STOLEN;
-		if (!skb)
-			goto drop;
 		return NF_ACCEPT;
 	}
 
@@ -815,12 +827,14 @@
 
 	return NF_ACCEPT;
 drop:
-	printk_ratelimited(KERN_WARNING
-				"%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x, sport=0x%x, reason=0x%x, alg=0x%x)\n",
-				__func__, state->in->name, skb_hnat_iface(skb),
-				HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
-				skb_hnat_sport(skb), skb_hnat_reason(skb),
-				skb_hnat_alg(skb));
+	if (skb)
+		printk_ratelimited(KERN_WARNING
+			"%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x,\n"
+			"sport=0x%x, reason=0x%x, alg=0x%x)\n",
+			__func__, state->in->name, skb_hnat_iface(skb),
+			HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
+			skb_hnat_sport(skb), skb_hnat_reason(skb),
+			skb_hnat_alg(skb));
 
 	return NF_DROP;
 }
@@ -831,6 +845,9 @@
 {
 	struct vlan_ethhdr *veth;
 
+	if (!skb)
+		goto drop;
+
 	if (IS_HQOS_MODE && hnat_priv->data->whnat) {
 		veth = (struct vlan_ethhdr *)skb_mac_header(skb);
 
@@ -863,8 +880,6 @@
 
 		if (!do_hnat_ext_to_ge(skb, state->in, __func__))
 			return NF_STOLEN;
-		if (!skb)
-			goto drop;
 		return NF_ACCEPT;
 	}
 
@@ -899,12 +914,14 @@
 #endif
 	return NF_ACCEPT;
 drop:
-	printk_ratelimited(KERN_WARNING
-				"%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x, sport=0x%x, reason=0x%x, alg=0x%x)\n",
-				__func__, state->in->name, skb_hnat_iface(skb),
-				HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
-				skb_hnat_sport(skb), skb_hnat_reason(skb),
-				skb_hnat_alg(skb));
+	if (skb)
+		printk_ratelimited(KERN_WARNING
+			"%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x,\n"
+			"sport=0x%x, reason=0x%x, alg=0x%x)\n",
+			__func__, state->in->name, skb_hnat_iface(skb),
+			HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
+			skb_hnat_sport(skb), skb_hnat_reason(skb),
+			skb_hnat_alg(skb));
 
 	return NF_DROP;
 }
@@ -1686,7 +1703,9 @@
 	wmb();
 	memcpy(foe, &entry, sizeof(entry));
 	/*reset statistic for this entry*/
-	if (hnat_priv->data->per_flow_accounting)
+	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 mib_entry));
 
@@ -2105,6 +2124,10 @@
 	trace_printk("[%s] case hit, %x-->%s, reason=%x\n", __func__,
 		     skb_hnat_iface(skb), out->name, skb_hnat_reason(skb));
 
+	if (skb_hnat_entry(skb) >= hnat_priv->foe_etry_num ||
+	    skb_hnat_ppe(skb) >= CFG_PPE_NUM)
+		return -1;
+
 	entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
 
 	switch (skb_hnat_reason(skb)) {
@@ -2168,6 +2191,10 @@
 	if (unlikely(!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;
+
 	entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
 	if (skb_hnat_reason(skb) == HIT_UNBIND_RATE_REACH) {
 		ip6h = ipv6_hdr(skb);
@@ -2223,17 +2250,24 @@
 mtk_hnat_ipv6_nf_post_routing(void *priv, struct sk_buff *skb,
 			      const struct nf_hook_state *state)
 {
+	if (!skb)
+		goto drop;
+
 	post_routing_print(skb, state->in, state->out, __func__);
 
 	if (!mtk_hnat_nf_post_routing(skb, state->out, hnat_ipv6_get_nexthop,
 				      __func__))
 		return NF_ACCEPT;
 
-	trace_printk(
-		"%s:drop (iif=0x%x, out_dev=%s, CB2=0x%x, ppe_hash=0x%x, sport=0x%x, reason=0x%x, alg=0x%x)\n",
-		__func__, skb_hnat_iface(skb), state->out->name, HNAT_SKB_CB2(skb)->magic,
-		skb_hnat_entry(skb), skb_hnat_sport(skb), skb_hnat_reason(skb),
-		skb_hnat_alg(skb));
+drop:
+	if (skb)
+		trace_printk(
+			"%s:drop (iif=0x%x, out_dev=%s, CB2=0x%x, ppe_hash=0x%x,\n"
+			"sport=0x%x, reason=0x%x, alg=0x%x)\n",
+			__func__, skb_hnat_iface(skb), state->out->name,
+			HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
+			skb_hnat_sport(skb), skb_hnat_reason(skb),
+			skb_hnat_alg(skb));
 
 	return NF_DROP;
 }
@@ -2242,17 +2276,24 @@
 mtk_hnat_ipv4_nf_post_routing(void *priv, struct sk_buff *skb,
 			      const struct nf_hook_state *state)
 {
+	if (!skb)
+		goto drop;
+
 	post_routing_print(skb, state->in, state->out, __func__);
 
 	if (!mtk_hnat_nf_post_routing(skb, state->out, hnat_ipv4_get_nexthop,
 				      __func__))
 		return NF_ACCEPT;
 
-	trace_printk(
-		"%s:drop (iif=0x%x, out_dev=%s, CB2=0x%x, ppe_hash=0x%x, sport=0x%x, reason=0x%x, alg=0x%x)\n",
-		__func__, skb_hnat_iface(skb), state->out->name, HNAT_SKB_CB2(skb)->magic,
-		skb_hnat_entry(skb), skb_hnat_sport(skb), skb_hnat_reason(skb),
-		skb_hnat_alg(skb));
+drop:
+	if (skb)
+		trace_printk(
+			"%s:drop (iif=0x%x, out_dev=%s, CB2=0x%x, ppe_hash=0x%x,\n"
+			"sport=0x%x, reason=0x%x, alg=0x%x)\n",
+			__func__, skb_hnat_iface(skb), state->out->name,
+			HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
+			skb_hnat_sport(skb), skb_hnat_reason(skb),
+			skb_hnat_alg(skb));
 
 	return NF_DROP;
 }
@@ -2287,13 +2328,16 @@
 	}
 
 	return NF_ACCEPT;
+
 drop:
-	printk_ratelimited(KERN_WARNING
-				"%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x, sport=0x%x, reason=0x%x, alg=0x%x)\n",
-				__func__, state->in->name, skb_hnat_iface(skb),
-				HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
-				skb_hnat_sport(skb), skb_hnat_reason(skb),
-				skb_hnat_alg(skb));
+	if (skb)
+		printk_ratelimited(KERN_WARNING
+			"%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x,\n"
+			"sport=0x%x, reason=0x%x, alg=0x%x)\n",
+			__func__, state->in->name, skb_hnat_iface(skb),
+			HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
+			skb_hnat_sport(skb), skb_hnat_reason(skb),
+			skb_hnat_alg(skb));
 
 	return NF_DROP;
 }
@@ -2302,16 +2346,23 @@
 mtk_hnat_br_nf_local_out(void *priv, struct sk_buff *skb,
 			 const struct nf_hook_state *state)
 {
+	if (!skb)
+		goto drop;
+
 	post_routing_print(skb, state->in, state->out, __func__);
 
 	if (!mtk_hnat_nf_post_routing(skb, state->out, 0, __func__))
 		return NF_ACCEPT;
 
-	trace_printk(
-		"%s:drop (iif=0x%x, out_dev=%s, CB2=0x%x, ppe_hash=0x%x, sport=0x%x, reason=0x%x, alg=0x%x)\n",
-		__func__, skb_hnat_iface(skb), state->out->name, HNAT_SKB_CB2(skb)->magic,
-		skb_hnat_entry(skb), skb_hnat_sport(skb), skb_hnat_reason(skb),
-		skb_hnat_alg(skb));
+drop:
+	if (skb)
+		trace_printk(
+			"%s:drop (iif=0x%x, out_dev=%s, CB2=0x%x, ppe_hash=0x%x,\n"
+			"sport=0x%x, reason=0x%x, alg=0x%x)\n",
+			__func__, skb_hnat_iface(skb), state->out->name,
+			HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
+			skb_hnat_sport(skb), skb_hnat_reason(skb),
+			skb_hnat_alg(skb));
 
 	return NF_DROP;
 }
@@ -2327,6 +2378,10 @@
 	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;
+
 	entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
 
 	if (unlikely(skb_headroom(skb) < FOE_INFO_LEN)) {
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 d200b16..872c27e 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
@@ -102,7 +102,7 @@
 {
 	u32 id = mtk_mac2xgmii_id(ss->eth, mac_id);
 
-	if (id < 0 || id >= MTK_MAX_DEVS ||
+	if (id >= MTK_MAX_DEVS ||
 	    !ss->regmap_sgmii[id] || !ss->regmap_pextp[id])
 		return;
 
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 7d4a3ed..bdd5231 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
@@ -118,7 +118,7 @@
 {
 	u32 id = mtk_mac2xgmii_id(ss->eth, mac_id);
 
-	if (id < 0 || id >= MTK_MAX_DEVS ||
+	if (id >= MTK_MAX_DEVS ||
 	    !ss->regmap_usxgmii[id] || !ss->regmap_pextp[id])
 		return;
 
@@ -189,7 +189,7 @@
 	unsigned int val;
 	u32 id = mtk_mac2xgmii_id(ss->eth, mac_id);
 
-	if (id < 0 || id >= MTK_MAX_DEVS ||
+	if (id >= MTK_MAX_DEVS ||
 	    !ss->regmap_usxgmii[id] || !ss->regmap_pextp[id])
 		return;
 
@@ -292,7 +292,7 @@
 	struct mtk_eth *eth = ss->eth;
 	u32 id = mtk_mac2xgmii_id(eth, mac_id);
 
-	if (id < 0 || id >= MTK_MAX_DEVS || !eth->toprgu)
+	if (id >= MTK_MAX_DEVS || !eth->toprgu)
 		return;
 
 	switch (mac_id) {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/include/dt-bindings/clock/mt7988-clk.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/include/dt-bindings/clock/mt7988-clk.h
index fb97122..3ba1f16 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/include/dt-bindings/clock/mt7988-clk.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/include/dt-bindings/clock/mt7988-clk.h
@@ -109,69 +109,65 @@
 #define CK_INFRA_66M_AP_DMA_BCK		38
 #define CK_INFRA_66M_SEJ_BCK		39
 #define CK_INFRA_PRE_CK_SEJ_F13M	40
-#define CK_INFRA_66M_TRNG		41
-#define CK_INFRA_26M_THERM_SYSTEM	42
-#define CK_INFRA_I2C_BCK		43
-#define CK_INFRA_66M_UART0_PCK		44
-#define CK_INFRA_66M_UART1_PCK		45
-#define CK_INFRA_66M_UART2_PCK		46
-#define CK_INFRA_52M_UART0_CK		47
-#define CK_INFRA_52M_UART1_CK		48
-#define CK_INFRA_52M_UART2_CK		49
-#define CK_INFRA_NFI			50
-#define CK_INFRA_SPINFI			51
-#define CK_INFRA_66M_NFI_HCK		52
-#define CK_INFRA_104M_SPI0		53
-#define CK_INFRA_104M_SPI1		54
-#define CK_INFRA_104M_SPI2_BCK		55
-#define CK_INFRA_66M_SPI0_HCK		56
-#define CK_INFRA_66M_SPI1_HCK		57
-#define CK_INFRA_66M_SPI2_HCK		58
-#define CK_INFRA_66M_FLASHIF_AXI	59
-#define CK_INFRA_RTC			60
-#define CK_INFRA_26M_ADC_BCK		61
-#define CK_INFRA_RC_ADC			62
-#define CK_INFRA_MSDC400		63
-#define CK_INFRA_MSDC2_HCK		64
-#define CK_INFRA_133M_MSDC_0_HCK	65
-#define CK_INFRA_66M_MSDC_0_HCK		66
-#define CK_INFRA_133M_CPUM_BCK		67
-#define CK_INFRA_BIST2FPC		68
-#define CK_INFRA_I2C_X16W_MCK_CK_P1	69
-#define CK_INFRA_I2C_X16W_PCK_CK_P1	70
-#define CK_INFRA_133M_USB_HCK		71
-#define CK_INFRA_133M_USB_HCK_CK_P1	72
-#define CK_INFRA_66M_USB_HCK		73
-#define CK_INFRA_66M_USB_HCK_CK_P1	74
-#define CK_INFRA_USB_SYS		75
-#define CK_INFRA_USB_SYS_CK_P1		76
-#define CK_INFRA_USB_REF		77
-#define CK_INFRA_USB_CK_P1		78
-#define CK_INFRA_USB_FRMCNT		79
-#define CK_INFRA_USB_FRMCNT_CK_P1	80
-#define CK_INFRA_USB_PIPE		81
-#define CK_INFRA_USB_PIPE_CK_P1		82
-#define CK_INFRA_USB_UTMI		83
-#define CK_INFRA_USB_UTMI_CK_P1		84
-#define CK_INFRA_USB_XHCI		85
-#define CK_INFRA_USB_XHCI_CK_P1		86
-#define CK_INFRA_PCIE_GFMUX_TL_P0	87
-#define CK_INFRA_PCIE_GFMUX_TL_P1	88
-#define CK_INFRA_PCIE_GFMUX_TL_P2	89
-#define CK_INFRA_PCIE_GFMUX_TL_P3	90
-#define CK_INFRA_PCIE_PIPE_P0		91
-#define CK_INFRA_PCIE_PIPE_P1		92
-#define CK_INFRA_PCIE_PIPE_P2		93
-#define CK_INFRA_PCIE_PIPE_P3		94
-#define CK_INFRA_133M_PCIE_CK_P0	95
-#define CK_INFRA_133M_PCIE_CK_P1	96
-#define CK_INFRA_133M_PCIE_CK_P2	97
-#define CK_INFRA_133M_PCIE_CK_P3	98
-#define CK_INFRA_PCIE_PERI_26M_CK_P0	99
-#define CK_INFRA_PCIE_PERI_26M_CK_P1	100
-#define CK_INFRA_PCIE_PERI_26M_CK_P2	101
-#define CK_INFRA_PCIE_PERI_26M_CK_P3	102
-#define CLK_INFRA_AO_NR_CLK		103
+#define CK_INFRA_26M_THERM_SYSTEM	41
+#define CK_INFRA_I2C_BCK		42
+#define CK_INFRA_52M_UART0_CK		43
+#define CK_INFRA_52M_UART1_CK		44
+#define CK_INFRA_52M_UART2_CK		45
+#define CK_INFRA_NFI			46
+#define CK_INFRA_SPINFI			47
+#define CK_INFRA_66M_NFI_HCK		48
+#define CK_INFRA_104M_SPI0		49
+#define CK_INFRA_104M_SPI1		50
+#define CK_INFRA_104M_SPI2_BCK		51
+#define CK_INFRA_66M_SPI0_HCK		52
+#define CK_INFRA_66M_SPI1_HCK		53
+#define CK_INFRA_66M_SPI2_HCK		54
+#define CK_INFRA_66M_FLASHIF_AXI	55
+#define CK_INFRA_RTC			56
+#define CK_INFRA_26M_ADC_BCK		57
+#define CK_INFRA_RC_ADC			58
+#define CK_INFRA_MSDC400		59
+#define CK_INFRA_MSDC2_HCK		60
+#define CK_INFRA_133M_MSDC_0_HCK	61
+#define CK_INFRA_66M_MSDC_0_HCK		62
+#define CK_INFRA_133M_CPUM_BCK		63
+#define CK_INFRA_BIST2FPC		64
+#define CK_INFRA_I2C_X16W_MCK_CK_P1	65
+#define CK_INFRA_I2C_X16W_PCK_CK_P1	66
+#define CK_INFRA_133M_USB_HCK		67
+#define CK_INFRA_133M_USB_HCK_CK_P1	68
+#define CK_INFRA_66M_USB_HCK		69
+#define CK_INFRA_66M_USB_HCK_CK_P1	70
+#define CK_INFRA_USB_SYS		71
+#define CK_INFRA_USB_SYS_CK_P1		72
+#define CK_INFRA_USB_REF		73
+#define CK_INFRA_USB_CK_P1		74
+#define CK_INFRA_USB_FRMCNT		75
+#define CK_INFRA_USB_FRMCNT_CK_P1	76
+#define CK_INFRA_USB_PIPE		77
+#define CK_INFRA_USB_PIPE_CK_P1		78
+#define CK_INFRA_USB_UTMI		79
+#define CK_INFRA_USB_UTMI_CK_P1		80
+#define CK_INFRA_USB_XHCI		81
+#define CK_INFRA_USB_XHCI_CK_P1		82
+#define CK_INFRA_PCIE_GFMUX_TL_P0	83
+#define CK_INFRA_PCIE_GFMUX_TL_P1	84
+#define CK_INFRA_PCIE_GFMUX_TL_P2	85
+#define CK_INFRA_PCIE_GFMUX_TL_P3	86
+#define CK_INFRA_PCIE_PIPE_P0		87
+#define CK_INFRA_PCIE_PIPE_P1		88
+#define CK_INFRA_PCIE_PIPE_P2		89
+#define CK_INFRA_PCIE_PIPE_P3		90
+#define CK_INFRA_133M_PCIE_CK_P0	91
+#define CK_INFRA_133M_PCIE_CK_P1	92
+#define CK_INFRA_133M_PCIE_CK_P2	93
+#define CK_INFRA_133M_PCIE_CK_P3	94
+#define CK_INFRA_PCIE_PERI_26M_CK_P0	95
+#define CK_INFRA_PCIE_PERI_26M_CK_P1	96
+#define CK_INFRA_PCIE_PERI_26M_CK_P2	97
+#define CK_INFRA_PCIE_PERI_26M_CK_P3	98
+#define CLK_INFRA_AO_NR_CLK		99
 
 /* TOPCKGEN */
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9993-add-wed.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9993-add-wed.patch
index b3ecebe..2d27d90 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9993-add-wed.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9993-add-wed.patch
@@ -243,7 +243,7 @@
 @@ -1384,6 +1387,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
  		struct net_device *netdev;
  		unsigned int pktlen;
- 		dma_addr_t dma_addr;
+ 		dma_addr_t dma_addr = 0;
 +		u32 hash, reason;
  		int mac = 0;
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9997-add-wed-rx-support-for-mt7896.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9997-add-wed-rx-support-for-mt7896.patch
index b05f862..053a4da 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9997-add-wed-rx-support-for-mt7896.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9997-add-wed-rx-support-for-mt7896.patch
@@ -8,7 +8,7 @@
  arch/arm64/boot/dts/mediatek/mt7986a.dtsi     |  42 +-
  arch/arm64/boot/dts/mediatek/mt7986b.dtsi     |  42 +-
  drivers/net/ethernet/mediatek/Makefile        |   2 +-
- drivers/net/ethernet/mediatek/mtk_wed.c       | 625 ++++++++++++++++--
+ drivers/net/ethernet/mediatek/mtk_wed.c       | 639 ++++++++++++++++--
  drivers/net/ethernet/mediatek/mtk_wed.h       |  51 ++
  drivers/net/ethernet/mediatek/mtk_wed_ccif.c  | 133 ++++
  drivers/net/ethernet/mediatek/mtk_wed_ccif.h  |  45 ++
@@ -18,7 +18,7 @@
  drivers/net/ethernet/mediatek/mtk_wed_regs.h  | 144 +++-
  drivers/net/ethernet/mediatek/mtk_wed_wo.c    | 564 ++++++++++++++++
  drivers/net/ethernet/mediatek/mtk_wed_wo.h    | 324 +++++++++
- include/linux/soc/mediatek/mtk_wed.h          | 101 ++-
+ include/linux/soc/mediatek/mtk_wed.h          | 126 +++-
  14 files changed, 2796 insertions(+), 75 deletions(-)
  create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_ccif.c
  create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_ccif.h
@@ -280,7 +280,7 @@
 +
 +	mtk_wed_reset(dev, MTK_WED_RESET_WED);
 +
-+	mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WED_WO_CHANGE_STATE,
++	mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE,
 +			     &state, sizeof(state), false);
 +
 +	do {
@@ -369,7 +369,7 @@
 +	dev->rx_buf_ring.desc = desc;
 +	dev->rx_buf_ring.desc_phys = desc_phys;
 +
-+	dev->wlan.init_rx_buf(dev, dev->wlan.rx_pkt);
++	dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt);
 +	return 0;
 +}
 +
@@ -588,7 +588,7 @@
  	wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
  	wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
  	wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
-@@ -417,8 +641,19 @@ mtk_wed_detach(struct mtk_wed_device *dev)
+@@ -417,10 +641,21 @@ mtk_wed_detach(struct mtk_wed_device *dev)
  
  	mtk_wed_reset(dev, MTK_WED_RESET_WED);
  
@@ -606,8 +606,20 @@
 +
 +	mtk_wdma_rx_reset(dev);
  
- 	if (dev->wlan.bus_type == MTK_BUS_TYPE_PCIE) {
+-	if (dev->wlan.bus_type == MTK_BUS_TYPE_PCIE) {
++	if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
  		wlan_node = dev->wlan.pci_dev->dev.of_node;
+ 		if (of_dma_is_coherent(wlan_node))
+ 			regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
+@@ -443,7 +678,7 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
+ {
+ #define PCIE_BASE_ADDR0 0x11280000
+ 
+-	if (dev->wlan.bus_type == MTK_BUS_TYPE_PCIE) {
++	if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
+ 		struct device_node *node;
+ 		void __iomem * base_addr;
+ 		u32 value = 0;
 @@ -477,7 +712,6 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
  		value = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
  		value = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
@@ -616,6 +628,15 @@
  		wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
  		wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER);
  
+@@ -485,7 +719,7 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
+ 		value = wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
+ 		wed_set(dev, MTK_WED_PCIE_INT_CTRL,
+ 			MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
+-	} else if (dev->wlan.bus_type == MTK_BUS_TYPE_AXI) {
++	} else if (dev->wlan.bus_type == MTK_WED_BUS_AXI) {
+ 		wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
+ 			MTK_WED_WPDMA_INT_CTRL_SIG_SRC |
+ 			FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_SRC_SEL, 0));
 @@ -501,6 +735,9 @@ mtk_wed_set_wpdma(struct mtk_wed_device *dev)
  		wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK,  dev->wlan.wpdma_mask);
  		wed_w32(dev, MTK_WED_WPDMA_CFG_TX,  dev->wlan.wpdma_tx);
@@ -636,12 +657,12 @@
 +mtk_wed_rx_bm_hw_init(struct mtk_wed_device *dev)
 +{
 +	wed_w32(dev, MTK_WED_RX_BM_RX_DMAD,
-+		FIELD_PREP(MTK_WED_RX_BM_RX_DMAD_SDL0,  dev->wlan.rx_pkt_size));
++		FIELD_PREP(MTK_WED_RX_BM_RX_DMAD_SDL0,  dev->wlan.rx_size));
 +
 +	wed_w32(dev, MTK_WED_RX_BM_BASE, dev->rx_buf_ring.desc_phys);
 +
 +	wed_w32(dev, MTK_WED_RX_BM_INIT_PTR, MTK_WED_RX_BM_INIT_SW_TAIL |
-+		FIELD_PREP(MTK_WED_RX_BM_SW_TAIL, dev->wlan.rx_pkt));
++		FIELD_PREP(MTK_WED_RX_BM_SW_TAIL, dev->wlan.rx_npkt));
 +
 +	wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH,
 +		FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff));
@@ -733,7 +754,7 @@
  static void
 -mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size, int scale)
 +mtk_wed_rx_hw_init(struct mtk_wed_device *dev)
-+{
+ {
 +	wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
 +		MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
 +		MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
@@ -760,7 +781,7 @@
 +
 +static void
 +mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size, int scale, bool tx)
- {
++{
 +	__le32 ctrl;
  	int i;
  
@@ -937,7 +958,7 @@
 +		.wed = 0,
 +	};
 +
-+	return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WED_WO_CFG,
++	return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_WED_CFG,
 +				    &req, sizeof(req), true);
 +}
 +
@@ -1014,7 +1035,28 @@
  
  	mtk_wed_dma_enable(dev);
  	dev->running = true;
-@@ -847,9 +1336,17 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+@@ -809,6 +1298,7 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ 	__releases(RCU)
+ {
+ 	struct mtk_wed_hw *hw;
++	struct device *device;
+ 	u16 ver;
+ 	int ret = 0;
+ 
+@@ -829,6 +1319,12 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ 		goto out;
+ 	}
+ 
++	device = dev->wlan.bus_type == MTK_WED_BUS_PCIE
++	? &dev->wlan.pci_dev->dev
++	: &dev->wlan.platform_dev->dev;
++	dev_info(device, "attaching wed device %d version %d\n",
++		 hw->index, hw->ver);
++
+ 	dev->hw = hw;
+ 	dev->dev = hw->dev;
+ 	dev->irq = hw->irq;
+@@ -847,9 +1343,17 @@ mtk_wed_attach(struct mtk_wed_device *dev)
  	dev->rev_id = ((dev->ver << 28) | ver << 16);
  
  	ret = mtk_wed_buffer_alloc(dev);
@@ -1035,7 +1077,7 @@
  	}
  
  	mtk_wed_hw_init_early(dev);
-@@ -857,7 +1354,12 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+@@ -857,7 +1361,12 @@ mtk_wed_attach(struct mtk_wed_device *dev)
  	if (dev->ver == MTK_WED_V1)
  		regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
  				   BIT(hw->index), 0);
@@ -1048,7 +1090,7 @@
  out:
  	mutex_unlock(&hw_lock);
  
-@@ -883,10 +1385,10 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
+@@ -883,10 +1392,10 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
  
  	BUG_ON(idx > ARRAY_SIZE(dev->tx_ring));
  
@@ -1061,7 +1103,7 @@
  		return -ENOMEM;
  
  	ring->reg_base = MTK_WED_RING_TX(idx);
-@@ -933,6 +1435,35 @@ mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
+@@ -933,6 +1442,35 @@ mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
  	return 0;
  }
  
@@ -1097,7 +1139,7 @@
  static u32
  mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
  {
-@@ -1020,6 +1551,8 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+@@ -1020,6 +1558,8 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
  		.attach = mtk_wed_attach,
  		.tx_ring_setup = mtk_wed_tx_ring_setup,
  		.txfree_ring_setup = mtk_wed_txfree_ring_setup,
@@ -1106,7 +1148,7 @@
  		.start = mtk_wed_start,
  		.stop = mtk_wed_stop,
  		.reset_dma = mtk_wed_reset_dma,
-@@ -1028,6 +1561,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+@@ -1028,6 +1568,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
  		.irq_get = mtk_wed_irq_get,
  		.irq_set_mask = mtk_wed_irq_set_mask,
  		.detach = mtk_wed_detach,
@@ -1114,7 +1156,15 @@
  	};
  	struct device_node *eth_np = eth->dev->of_node;
  	struct platform_device *pdev;
-@@ -1083,6 +1617,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+@@ -1067,6 +1608,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ 	hw->wdma_phy = wdma_phy;
+ 	hw->index = index;
+ 	hw->irq = irq;
++	hw->ver = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
+ 
+ 	if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ 		hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
+@@ -1083,6 +1625,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
  			regmap_write(hw->mirror, 0, 0);
  			regmap_write(hw->mirror, 4, 0);
  		}
@@ -1227,7 +1277,7 @@
  #endif
 diff --git a/drivers/net/ethernet/mediatek/mtk_wed_ccif.c b/drivers/net/ethernet/mediatek/mtk_wed_ccif.c
 new file mode 100644
-index 0000000..22ef337
+index 0000000..951278b
 --- /dev/null
 +++ b/drivers/net/ethernet/mediatek/mtk_wed_ccif.c
 @@ -0,0 +1,133 @@
@@ -1558,7 +1608,7 @@
  }
 diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
 new file mode 100644
-index 0000000..723bdfd
+index 0000000..96e30a3
 --- /dev/null
 +++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
 @@ -0,0 +1,586 @@
@@ -1711,7 +1761,7 @@
 +	req.arg0 = (u32)exp->phys;
 +	req.arg1 = (u32)exp->log_size;
 +
-+	return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WED_WO_EXCEPTION_INIT,
++	return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_EXCEPTION_INIT,
 +				    &req, sizeof(req), false);
 +
 +free:
@@ -1742,7 +1792,7 @@
 +	struct mtk_wed_device *wed = wo->hw->wed_dev;
 +	struct wed_cmd_hdr *hdr = (struct wed_cmd_hdr *)skb->data;
 +	struct wed_wo_log *record;
-+	struct wo_cmd_rxcnt_t *rxcnt;
++	struct mtk_wed_wo_rx_stats *rxcnt;
 +	char *msg = (char *)(skb->data + sizeof(struct wed_cmd_hdr));
 +	u16 msg_len = skb->len - sizeof(struct wed_cmd_hdr);
 +	u32 i, cnt = 0;
@@ -1770,11 +1820,11 @@
 +		break;
 +	case WO_EVT_RXCNT_INFO:
 +		cnt = *(u32 *)msg;
-+		rxcnt = (struct wo_cmd_rxcnt_t *)((u32 *)msg+1);
++		rxcnt = (struct mtk_wed_wo_rx_stats *)((u32 *)msg+1);
 +
 +		for (i = 0; i < cnt; i++)
-+			if (wed->wlan.update_wo_rxcnt)
-+				wed->wlan.update_wo_rxcnt(wed, &rxcnt[i]);
++			if (wed->wlan.update_wo_rx_stats)
++				wed->wlan.update_wo_rx_stats(wed, &rxcnt[i]);
 +		break;
 +	default:
 +		break;
@@ -1948,7 +1998,7 @@
 +{
 +	struct mtk_wed_device *wed = wo->hw->wed_dev;
 +	struct wed_cmd_hdr  *hdr;
-+	struct wo_cmd_rxcnt_t *rxcnt = NULL;
++	struct mtk_wed_wo_rx_stats *rxcnt = NULL;
 +	u32 i, cnt = 0;
 +
 +	if (!skb) {
@@ -1967,13 +2017,13 @@
 +	skb_pull(skb, sizeof(struct wed_cmd_hdr));
 +
 +	switch (cmd) {
-+	case WED_WO_RXCNT_INFO:
++	case MTK_WED_WO_CMD_RXCNT_INFO:
 +		cnt = *(u32 *)skb->data;
-+		rxcnt = (struct wo_cmd_rxcnt_t *)((u32 *)skb->data+1);
++		rxcnt = (struct mtk_wed_wo_rx_stats *)((u32 *)skb->data+1);
 +
 +		for (i = 0; i < cnt; i++)
-+			if (wed->wlan.update_wo_rxcnt)
-+				wed->wlan.update_wo_rxcnt(wed, &rxcnt[i]);
++			if (wed->wlan.update_wo_rx_stats)
++				wed->wlan.update_wo_rx_stats(wed, &rxcnt[i]);
 +		break;
 +	default:
 +		break;
@@ -2057,22 +2107,22 @@
 +	cmd = input[0];
 +	if (input_total == 1 && cmd) {
 +		if (strncmp(cmd, "bainfo", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_BA_INFO_DUMP;
++			cmd_id = MTK_WED_WO_CMD_BA_INFO_DUMP;
 +		} else if (strncmp(cmd, "bactrl", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_BA_CTRL_DUMP;
++			cmd_id = MTK_WED_WO_CMD_BA_CTRL_DUMP;
 +		} else if (strncmp(cmd, "fbcmdq", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_FBCMD_Q_DUMP;
++			cmd_id = MTK_WED_WO_CMD_FBCMD_Q_DUMP;
 +		} else if (strncmp(cmd, "logflush", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_LOG_FLUSH;
++			cmd_id = MTK_WED_WO_CMD_LOG_FLUSH;
 +		} else if (strncmp(cmd, "cpustat.dump", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_CPU_STATS_DUMP;
++			cmd_id = MTK_WED_WO_CMD_CPU_STATS_DUMP;
 +		} else if (strncmp(cmd, "state", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_RX_STAT;
++			cmd_id = MTK_WED_WO_CMD_WED_RX_STAT;
 +		} else if (strncmp(cmd, "prof_hit_dump", strlen(cmd)) == 0) {
 +			//wo_profiling_report();
 +			return count;
 +		} else if (strncmp(cmd, "rxcnt_info", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_RXCNT_INFO;
++			cmd_id = MTK_WED_WO_CMD_RXCNT_INFO;
 +			wait = true;
 +		} else {
 +			pr_info("(%s) unknown comand string(%s)!\n", __func__, cmd);
@@ -2088,23 +2138,23 @@
 +			}
 +		}
 +		if(strncmp(cmd, "devinfo", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_DEV_INFO_DUMP;
++			cmd_id = MTK_WED_WO_CMD_DEV_INFO_DUMP;
 +		} else if (strncmp(cmd, "bssinfo", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_BSS_INFO_DUMP;
++			cmd_id = MTK_WED_WO_CMD_BSS_INFO_DUMP;
 +		} else if (strncmp(cmd, "starec", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_STA_REC_DUMP;
++			cmd_id = MTK_WED_WO_CMD_STA_REC_DUMP;
 +		} else if (strncmp(cmd, "starec_ba", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_STA_BA_DUMP;
++			cmd_id = MTK_WED_WO_CMD_STA_BA_DUMP;
 +		} else if (strncmp(cmd, "logctrl", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_FW_LOG_CTRL;
++			cmd_id = MTK_WED_WO_CMD_FW_LOG_CTRL;
 +		} else if (strncmp(cmd, "cpustat.en", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_CPU_STATS_ENABLE;
++			cmd_id = MTK_WED_WO_CMD_CPU_STATS_ENABLE;
 +		} else if (strncmp(cmd, "prof_conf", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_PROF_CTRL;
++			cmd_id = MTK_WED_WO_CMD_PROF_CTRL;
 +		} else if (strncmp(cmd, "rxcnt_ctrl", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_RXCNT_CTRL;
++			cmd_id = MTK_WED_WO_CMD_RXCNT_CTRL;
 +		} else if (strncmp(cmd, "dbg_set", strlen(cmd)) == 0) {
-+			cmd_id = WED_WO_DBG_INFO;
++			cmd_id = MTK_WED_WO_CMD_DBG_INFO;
 +		}
 +	} else {
 +		dev_info(hw->dev, "usage: echo cmd='cmd_str' > wo_write\n");
@@ -2150,7 +2200,7 @@
 +
 diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.h b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
 new file mode 100644
-index 0000000..6a5ac76
+index 0000000..19e1199
 --- /dev/null
 +++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
 @@ -0,0 +1,96 @@
@@ -2507,7 +2557,7 @@
  #endif
 diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.c b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
 new file mode 100644
-index 0000000..8434272
+index 0000000..54b7787
 --- /dev/null
 +++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
 @@ -0,0 +1,564 @@
@@ -3077,7 +3127,7 @@
 +}
 diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.h b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
 new file mode 100644
-index 0000000..5824f39
+index 0000000..548b38e
 --- /dev/null
 +++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
 @@ -0,0 +1,324 @@
@@ -3406,47 +3456,64 @@
 +#endif
 +
 diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
-index e914cb4..cfa1120 100644
+index e914cb4..e8fca31 100644
 --- a/include/linux/soc/mediatek/mtk_wed.h
 +++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -7,6 +7,36 @@
+@@ -6,7 +6,39 @@
+ #include <linux/regmap.h>
  #include <linux/pci.h>
  
++#define WED_WO_STA_REC			0x6
++
  #define MTK_WED_TX_QUEUES		2
 +#define MTK_WED_RX_QUEUES		2
 +
-+enum wo_cmd_id {
-+	WED_WO_CFG = 0,
-+	WED_WO_RX_STAT,
-+	WED_WO_RRO_SER,
-+	WED_WO_DBG_INFO,
-+	WED_WO_DEV_INFO,
-+	WED_WO_BSS_INFO,
-+	WED_WO_STA_REC,
-+	WED_WO_DEV_INFO_DUMP,
-+	WED_WO_BSS_INFO_DUMP,
-+	WED_WO_STA_REC_DUMP,
-+	WED_WO_BA_INFO_DUMP,
-+	WED_WO_FBCMD_Q_DUMP,
-+	WED_WO_FW_LOG_CTRL,
-+	WED_WO_LOG_FLUSH,
-+	WED_WO_CHANGE_STATE,
-+	WED_WO_CPU_STATS_ENABLE,
-+	WED_WO_CPU_STATS_DUMP,
-+	WED_WO_EXCEPTION_INIT,
-+	WED_WO_PROF_CTRL,
-+	WED_WO_STA_BA_DUMP,
-+	WED_WO_BA_CTRL_DUMP,
-+	WED_WO_RXCNT_CTRL,
-+	WED_WO_RXCNT_INFO,
-+	WED_WO_SET_CAP,
-+	WED_WO_CCIF_RING_DUMP,
-+	WED_WO_WED_END
++enum mtk_wed_wo_cmd {
++	MTK_WED_WO_CMD_WED_CFG,
++	MTK_WED_WO_CMD_WED_RX_STAT,
++	MTK_WED_WO_CMD_RRO_SER,
++	MTK_WED_WO_CMD_DBG_INFO,
++	MTK_WED_WO_CMD_DEV_INFO,
++	MTK_WED_WO_CMD_BSS_INFO,
++	MTK_WED_WO_CMD_STA_REC,
++	MTK_WED_WO_CMD_DEV_INFO_DUMP,
++	MTK_WED_WO_CMD_BSS_INFO_DUMP,
++	MTK_WED_WO_CMD_STA_REC_DUMP,
++	MTK_WED_WO_CMD_BA_INFO_DUMP,
++	MTK_WED_WO_CMD_FBCMD_Q_DUMP,
++	MTK_WED_WO_CMD_FW_LOG_CTRL,
++	MTK_WED_WO_CMD_LOG_FLUSH,
++	MTK_WED_WO_CMD_CHANGE_STATE,
++	MTK_WED_WO_CMD_CPU_STATS_ENABLE,
++	MTK_WED_WO_CMD_CPU_STATS_DUMP,
++	MTK_WED_WO_CMD_EXCEPTION_INIT,
++	MTK_WED_WO_CMD_PROF_CTRL,
++	MTK_WED_WO_CMD_STA_BA_DUMP,
++	MTK_WED_WO_CMD_BA_CTRL_DUMP,
++	MTK_WED_WO_CMD_RXCNT_CTRL,
++	MTK_WED_WO_CMD_RXCNT_INFO,
++	MTK_WED_WO_CMD_SET_CAP,
++	MTK_WED_WO_CMD_CCIF_RING_DUMP,
++	MTK_WED_WO_CMD_WED_END
 +};
  
  enum {
  	MTK_NO_WED,
-@@ -33,6 +63,33 @@ struct mtk_wed_ring {
+@@ -15,10 +47,9 @@ enum {
+ 	MTK_WED_VMAX
+ };
+ 
+-enum {
+-	MTK_BUS_TYPE_PCIE,
+-	MTK_BUS_TYPE_AXI,
+-	MTK_BUS_TYPE_MAX
++enum mtk_wed_bus_tye {
++	MTK_WED_BUS_PCIE,
++	MTK_WED_BUS_AXI,
+ };
+ 
+ struct mtk_wed_hw;
+@@ -33,6 +64,33 @@ struct mtk_wed_ring {
  	void __iomem *wpdma;
  };
  
@@ -3468,19 +3535,19 @@
 +	dma_addr_t desc_phys;
 +};
 +
-+struct wo_cmd_rxcnt_t {
-+	u16 wlan_idx;
-+	u16 tid;
-+	u32 rx_pkt_cnt;
-+	u32 rx_byte_cnt;
-+	u32 rx_err_cnt;
-+	u32 rx_drop_cnt;
++struct mtk_wed_wo_rx_stats {
++	__le16 wlan_idx;
++	__le16 tid;
++	__le32 rx_pkt_cnt;
++	__le32 rx_byte_cnt;
++	__le32 rx_err_cnt;
++	__le32 rx_drop_cnt;
 +};
 +
  struct mtk_wed_device {
  #ifdef CONFIG_NET_MEDIATEK_SOC_WED
  	const struct mtk_wed_ops *ops;
-@@ -47,37 +104,56 @@ struct mtk_wed_device {
+@@ -47,37 +105,64 @@ struct mtk_wed_device {
  	struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
  	struct mtk_wed_ring txfree_ring;
  	struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
@@ -3488,15 +3555,18 @@
 +	struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
 +
 +	struct dma_buf buf_ring;
-+	struct dma_entry rx_buf_ring;
-+	struct page_frag_cache rx_page;
  
  	struct {
--		int size;
+ 		int size;
 -		void **pages;
 -		struct mtk_wdma_desc *desc;
--		dma_addr_t desc_phys;
++		struct page_frag_cache rx_page;
++		struct mtk_rxbm_desc *desc;
+ 		dma_addr_t desc_phys;
 -	} buf_ring;
++	} rx_buf_ring;
++
++	struct {
 +		struct mtk_wed_ring rro_ring;
 +		void __iomem *rro_desc;
 +		dma_addr_t miod_desc_phys;
@@ -3506,7 +3576,11 @@
  
  	/* filled by driver: */
  	struct {
- 		struct pci_dev *pci_dev;
+-		struct pci_dev *pci_dev;
++		union {
++			struct platform_device *platform_dev;
++			struct pci_dev *pci_dev;
++		};
  		void __iomem *base;
  		u32 bus_type;
 +		u32 phy_base;
@@ -3526,8 +3600,8 @@
  		u16 token_start;
  		unsigned int nbuf;
 +		unsigned int rx_nbuf;
-+		unsigned int rx_pkt;
-+		unsigned int rx_pkt_size;
++		unsigned int rx_npkt;
++		unsigned int rx_size;
  
  		bool wcid_512;
  
@@ -3537,12 +3611,12 @@
 +		u32 (*init_rx_buf)(struct mtk_wed_device *wed,
 +				   int pkt_num);
 +		void (*release_rx_buf)(struct mtk_wed_device *wed);
-+		void (*update_wo_rxcnt)(struct  mtk_wed_device *wed,
-+				struct wo_cmd_rxcnt_t *rxcnt);
++		void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
++					   struct mtk_wed_wo_rx_stats *stats);
  	} wlan;
  #endif
  };
-@@ -88,6 +164,10 @@ struct mtk_wed_ops {
+@@ -88,6 +173,10 @@ struct mtk_wed_ops {
  			     void __iomem *regs);
  	int (*txfree_ring_setup)(struct mtk_wed_device *dev,
  				 void __iomem *regs);
@@ -3553,7 +3627,7 @@
  	void (*detach)(struct mtk_wed_device *dev);
  
  	void (*stop)(struct mtk_wed_device *dev);
-@@ -99,6 +179,8 @@ struct mtk_wed_ops {
+@@ -99,6 +188,8 @@ struct mtk_wed_ops {
  
  	u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask);
  	void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
@@ -3562,7 +3636,24 @@
  };
  
  extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
-@@ -131,6 +213,10 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
+@@ -123,6 +214,16 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
+ 	return ret;
+ }
+ 
++static inline bool
++mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
++{
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++	return dev->ver != 1;
++#else
++	return false;
++#endif
++}
++
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ #define mtk_wed_device_active(_dev) !!(_dev)->ops
+ #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
+@@ -131,6 +232,10 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
  	(_dev)->ops->tx_ring_setup(_dev, _ring, _regs)
  #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \
  	(_dev)->ops->txfree_ring_setup(_dev, _regs)
@@ -3573,7 +3664,7 @@
  #define mtk_wed_device_reg_read(_dev, _reg) \
  	(_dev)->ops->reg_read(_dev, _reg)
  #define mtk_wed_device_reg_write(_dev, _reg, _val) \
-@@ -139,6 +225,8 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
+@@ -139,6 +244,8 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
  	(_dev)->ops->irq_get(_dev, _mask)
  #define mtk_wed_device_irq_set_mask(_dev, _mask) \
  	(_dev)->ops->irq_set_mask(_dev, _mask)
@@ -3582,7 +3673,7 @@
  #else
  static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
  {
-@@ -148,10 +236,13 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+@@ -148,10 +255,13 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
  #define mtk_wed_device_start(_dev, _mask) do {} while (0)
  #define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV
  #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-add-wed-ser-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-add-wed-ser-support.patch
index d97d4c1..df34806 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-add-wed-ser-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-add-wed-ser-support.patch
@@ -201,7 +201,7 @@
  
 -	mtk_wdma_rx_reset(dev);
 -
- 	if (dev->wlan.bus_type == MTK_BUS_TYPE_PCIE) {
+ 	if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
  		wlan_node = dev->wlan.pci_dev->dev.of_node;
  		if (of_dma_is_coherent(wlan_node))
 @@ -748,7 +754,7 @@ mtk_wed_hw_init_early(struct mtk_wed_device *dev)
@@ -268,7 +268,7 @@
 +	bool busy = false;
 +	int i;
 +
-+	mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WED_WO_CHANGE_STATE,
++	mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE,
 +			     &state, sizeof(state), true);
 +
 +	wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
@@ -345,7 +345,7 @@
 +
 +	/* wo change to enable state */
 +	state = WO_STATE_ENABLE;
-+	mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WED_WO_CHANGE_STATE,
++	mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE,
 +			     &state, sizeof(state), true);
 +
 +	/* wed_rx_ring_reset */
@@ -702,12 +702,10 @@
 index 9a9cc1b..31f4a26 100644
 --- a/include/linux/soc/mediatek/mtk_wed.h
 +++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -114,25 +114,29 @@ struct mtk_wed_device {
- 		u32 (*init_rx_buf)(struct mtk_wed_device *wed,
- 				   int pkt_num);
+@@ -161,23 +161,27 @@ struct mtk_wed_device {
  		void (*release_rx_buf)(struct mtk_wed_device *wed);
- 		void (*update_wo_rxcnt)(struct  mtk_wed_device *wed,
- 				struct wo_cmd_rxcnt_t *rxcnt);
+ 		void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
+ 					   struct mtk_wed_wo_rx_stats *stats);
 +		void (*ser_trigger)(struct mtk_wed_device *wed);
  	} wlan;
 +	struct completion fe_reset_done;
@@ -735,7 +733,7 @@
  	void (*start)(struct mtk_wed_device *dev, u32 irq_mask);
  	void (*reset_dma)(struct mtk_wed_device *dev);
  
-@@ -169,12 +173,13 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
+@@ -226,12 +230,13 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
  #define mtk_wed_device_active(_dev) !!(_dev)->ops
  #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
  #define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask)
@@ -753,7 +751,7 @@
  #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
  	(_dev)->ops->msg_update(_dev, _id, _msg, _len)
  #define mtk_wed_device_reg_read(_dev, _reg) \
-@@ -185,6 +190,8 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
+@@ -242,6 +247,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
  	(_dev)->ops->irq_get(_dev, _mask)
  #define mtk_wed_device_irq_set_mask(_dev, _mask) \
  	(_dev)->ops->irq_set_mask(_dev, _mask)
@@ -762,7 +760,7 @@
  #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
  	(_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
  #else
-@@ -194,14 +201,15 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+@@ -251,14 +258,15 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
  }
  #define mtk_wed_device_detach(_dev) do {} while (0)
  #define mtk_wed_device_start(_dev, _mask) do {} while (0)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
index 94fd3d1..c78b0b7 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
@@ -3,6 +3,7 @@
 # CONFIG_AIROHA_EN8801SC_PHY is not set
 # CONFIG_AIROHA_EN8801S_PHY is not set
 CONFIG_AQUANTIA_PHY=y
+# CONFIG_AQUANTIA_PHY_MDI_SWAP is not set
 CONFIG_AQUANTIA_PHY_FW_DOWNLOAD=y
 CONFIG_AQUANTIA_PHY_FW_DOWNLOAD_GANG=y
 # CONFIG_AQUANTIA_PHY_FW_DOWNLOAD_SINGLE is not set
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch
index 64b5560..a25c845 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch
@@ -19,7 +19,7 @@
  	},
  	[PORT_NPCM] = {
  		.name		= "Nuvoton 16550",
-@@ -2612,6 +2612,11 @@ serial8250_do_set_termios(struct uart_po
+@@ -2615,6 +2615,11 @@ serial8250_do_set_termios(struct uart_po
  	unsigned long flags;
  	unsigned int baud, quot, frac = 0;
  
diff --git a/recipes-kernel/linux/linux-mediatek_5.4.bb b/recipes-kernel/linux/linux-mediatek_5.4.bb
index 9a51c17..583f5d5 100644
--- a/recipes-kernel/linux/linux-mediatek_5.4.bb
+++ b/recipes-kernel/linux/linux-mediatek_5.4.bb
@@ -7,8 +7,8 @@
 
 KBRANCH ?= "linux-5.4.y"
 
-LINUX_VERSION ?= "5.4.224"
-SRCREV_machine ?= "771a8acbb84145b943bd608ba376e104ebfa9664"
+LINUX_VERSION ?= "5.4.225"
+SRCREV_machine ?= "4d2a309b5c28a2edc0900542d22fec3a5a22243b"
 KMETA = "kernel-meta"
 SRCREV_meta ?= "feeb59687bc0f054af837a5061f8d413ec7c93e9"