[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/417-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/417-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch
new file mode 100644
index 0000000..4f5befb
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/417-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch
@@ -0,0 +1,65 @@
+From 63db0cb35e1cb3b3c134906d1062f65513fdda2d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Tue, 4 Oct 2022 10:37:09 +0200
+Subject: [PATCH] mtd: core: simplify (a bit) code find partition-matching
+ dynamic OF node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+1. Don't hardcode "partition-" string twice
+2. Use simpler logic & use ->name to avoid of_property_read_string()
+3. Use mtd_get_of_node() helper
+
+Cc: Christian Marangi <ansuelsmth@gmail.com>
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-1-zajec5@gmail.com
+---
+ drivers/mtd/mtdcore.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -594,18 +594,16 @@ static void mtd_check_of_node(struct mtd
+ 	struct device_node *partitions, *parent_dn, *mtd_dn = NULL;
+ 	const char *pname, *prefix = "partition-";
+ 	int plen, mtd_name_len, offset, prefix_len;
+-	struct mtd_info *parent;
+ 	bool found = false;
+ 
+ 	/* Check if MTD already has a device node */
+-	if (dev_of_node(&mtd->dev))
++	if (mtd_get_of_node(mtd))
+ 		return;
+ 
+ 	/* Check if a partitions node exist */
+ 	if (!mtd_is_partition(mtd))
+ 		return;
+-	parent = mtd_get_master(mtd);
+-	parent_dn = of_node_get(dev_of_node(&parent->dev));
++	parent_dn = of_node_get(mtd_get_of_node(mtd_get_master(mtd)));
+ 	if (!parent_dn)
+ 		return;
+ 
+@@ -618,15 +616,15 @@ static void mtd_check_of_node(struct mtd
+ 
+ 	/* Search if a partition is defined with the same name */
+ 	for_each_child_of_node(partitions, mtd_dn) {
+-		offset = 0;
+-
+ 		/* Skip partition with no/wrong prefix */
+-		if (!of_node_name_prefix(mtd_dn, "partition-"))
++		if (!of_node_name_prefix(mtd_dn, prefix))
+ 			continue;
+ 
+ 		/* Label have priority. Check that first */
+-		if (of_property_read_string(mtd_dn, "label", &pname)) {
+-			of_property_read_string(mtd_dn, "name", &pname);
++		if (!of_property_read_string(mtd_dn, "label", &pname)) {
++			offset = 0;
++		} else {
++			pname = mtd_dn->name;
+ 			offset = prefix_len;
+ 		}
+ 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/417-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/417-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch
new file mode 100644
index 0000000..366492f
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/417-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch
@@ -0,0 +1,84 @@
+From ddb8cefb7af288950447ca6eeeafb09977dab56f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Tue, 4 Oct 2022 10:37:10 +0200
+Subject: [PATCH] mtd: core: try to find OF node for every MTD partition
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+So far this feature was limited to the top-level "nvmem-cells" node.
+There are multiple parsers creating partitions and subpartitions
+dynamically. Extend that code to handle them too.
+
+This allows finding partition-* node for every MTD (sub)partition.
+
+Random example:
+
+partitions {
+	compatible = "brcm,bcm947xx-cfe-partitions";
+
+	partition-firmware {
+		compatible = "brcm,trx";
+
+		partition-loader {
+		};
+	};
+};
+
+Cc: Christian Marangi <ansuelsmth@gmail.com>
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-2-zajec5@gmail.com
+---
+ drivers/mtd/mtdcore.c | 18 ++++++------------
+ 1 file changed, 6 insertions(+), 12 deletions(-)
+
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -594,20 +594,22 @@ static void mtd_check_of_node(struct mtd
+ 	struct device_node *partitions, *parent_dn, *mtd_dn = NULL;
+ 	const char *pname, *prefix = "partition-";
+ 	int plen, mtd_name_len, offset, prefix_len;
+-	bool found = false;
+ 
+ 	/* Check if MTD already has a device node */
+ 	if (mtd_get_of_node(mtd))
+ 		return;
+ 
+-	/* Check if a partitions node exist */
+ 	if (!mtd_is_partition(mtd))
+ 		return;
++
+ 	parent_dn = of_node_get(mtd_get_of_node(mtd_get_master(mtd)));
+ 	if (!parent_dn)
+ 		return;
+ 
+-	partitions = of_get_child_by_name(parent_dn, "partitions");
++	if (mtd_is_partition(mtd_get_master(mtd)))
++		partitions = of_node_get(parent_dn);
++	else
++		partitions = of_get_child_by_name(parent_dn, "partitions");
+ 	if (!partitions)
+ 		goto exit_parent;
+ 
+@@ -631,19 +633,11 @@ static void mtd_check_of_node(struct mtd
+ 		plen = strlen(pname) - offset;
+ 		if (plen == mtd_name_len &&
+ 		    !strncmp(mtd->name, pname + offset, plen)) {
+-			found = true;
++			mtd_set_of_node(mtd, mtd_dn);
+ 			break;
+ 		}
+ 	}
+ 
+-	if (!found)
+-		goto exit_partitions;
+-
+-	/* Set of_node only for nvmem */
+-	if (of_device_is_compatible(mtd_dn, "nvmem-cells"))
+-		mtd_set_of_node(mtd, mtd_dn);
+-
+-exit_partitions:
+ 	of_node_put(partitions);
+ exit_parent:
+ 	of_node_put(parent_dn);
diff --git a/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 1da3a5a..2feb1af 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
@@ -171,6 +171,8 @@
     file://414-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch \
     file://415-v6.0-mtd-core-check-partition-before-dereference.patch \
     file://416-v6.1-mtd-core-add-missing-of_node_get-in-dynamic-partitio.patch \
+    file://417-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch \
+    file://417-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch \
     file://430-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch \
     file://431-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch \
     file://432-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch \
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/480-mtd-set-rootfs-to-be-root-dev.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/480-mtd-set-rootfs-to-be-root-dev.patch
index 2544fa4..53894df 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/480-mtd-set-rootfs-to-be-root-dev.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/480-mtd-set-rootfs-to-be-root-dev.patch
@@ -20,7 +20,7 @@
  #include <linux/nvmem-provider.h>
  
  #include <linux/mtd/mtd.h>
-@@ -762,6 +763,15 @@ int add_mtd_device(struct mtd_info *mtd)
+@@ -754,6 +755,15 @@ int add_mtd_device(struct mtd_info *mtd)
  	   of this try_ nonsense, and no bitching about it
  	   either. :) */
  	__module_get(THIS_MODULE);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/495-mtd-core-add-get_mtd_device_by_node.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/495-mtd-core-add-get_mtd_device_by_node.patch
index ada1415..1b726c3 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/495-mtd-core-add-get_mtd_device_by_node.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/495-mtd-core-add-get_mtd_device_by_node.patch
@@ -17,7 +17,7 @@
 
 --- a/drivers/mtd/mtdcore.c
 +++ b/drivers/mtd/mtdcore.c
-@@ -1144,6 +1144,44 @@ out_unlock:
+@@ -1136,6 +1136,44 @@ out_unlock:
  }
  EXPORT_SYMBOL_GPL(get_mtd_device_nm);
  
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 604f5aa..274f897 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
@@ -348,39 +348,6 @@
 
 	};
 
-	tops: tops@09100000 {
-		compatible = "mediatek,tops";
-		reg = <0 0x09100000 0 0x01000000>;
-		reg-names = "tops-base";
-		clocks = <&topckgen CK_TOP_BUS_TOPS_SEL>,
-			 <&topckgen CK_TOP_TOPS_P2_26M_SEL>,
-			 <&topckgen CK_TOP_NETSYS_TOPS_400M_SEL>,
-			 <&topckgen CK_TOP_NPU_TOPS_SEL>,
-			 <&topckgen CK_TOP_CK_NPU_SEL_CM_TOPS_SEL>;
-		clock-names = "bus", "sram", "xdma", "offload", "mgmt";
-		power-domains = <&topmisc MT7988_POWER_DOMAIN_TOPS0>,
-				<&topmisc MT7988_POWER_DOMAIN_TOPS1>;
-
-		interrupt-parent = <&gic>;
-		interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "tdma-tx-pause", "mbox";
-
-		fe_mem = <&eth>;
-	};
-
-	hpdma1: hpdma@09106000 {
-		compatible = "mediatek,hpdma-top";
-		reg = <0 0x09106000 0 0x1000>;
-		reg-names = "base";
-	};
-
-	hpdma2: hpdma@09606000 {
-		compatible = "mediatek,hpdma-sub";
-		reg = <0 0x09606000 0 0x1000>;
-		reg-names = "base";
-	};
-
 	watchdog: watchdog@1001c000 {
 		compatible = "mediatek,mt7622-wdt",
 			     "mediatek,mt6589-wdt",
@@ -538,6 +505,35 @@
 		status = "okay";
 	};
 
+	afe: audio-controller@11210000 {
+		compatible = "mediatek,mt79xx-audio";
+		reg = <0 0x11210000 0 0x9000>;
+		interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&infracfg_ao CK_INFRA_66M_AUD_SLV_BCK>,
+			 <&infracfg_ao CK_INFRA_AUD_26M>,
+			 <&infracfg_ao CK_INFRA_AUD_L>,
+			 <&infracfg_ao CK_INFRA_AUD_AUD>,
+			 <&infracfg_ao CK_INFRA_AUD_EG2>,
+			 <&topckgen CK_TOP_AUD_SEL>,
+			 <&topckgen CK_TOP_AUD_I2S_M>;
+		clock-names = "aud_bus_ck",
+			      "aud_26m_ck",
+			      "aud_l_ck",
+			      "aud_aud_ck",
+			      "aud_eg2_ck",
+			      "aud_sel",
+			      "aud_i2s_m";
+		assigned-clocks = <&topckgen CK_TOP_AUD_SEL>,
+				  <&topckgen CK_TOP_A1SYS_SEL>,
+				  <&topckgen CK_TOP_AUD_L_SEL>,
+				  <&topckgen CK_TOP_A_TUNER_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_APLL2_196M>,
+					 <&topckgen CK_TOP_CB_APLL2_D4>,
+					 <&topckgen CK_TOP_CB_APLL2_196M>,
+					 <&topckgen CK_TOP_CB_APLL2_D4>;
+		status = "disabled";
+	};
+
 	pcie0: pcie@11300000 {
 		compatible = "mediatek,mt7988-pcie",
 			     "mediatek,mt7986-pcie";
@@ -956,6 +952,7 @@
 			      "dma_ck";
 		#address-cells = <2>;
 		#size-cells = <2>;
+		mediatek,p0_speed_fixup;
 		status = "okay";
 	};
 
@@ -1030,6 +1027,8 @@
 			clocks = <&system_clk>;
 			clock-names = "ref";
 			#phy-cells = <1>;
+			mediatek,usb3-pll-ssc-delta;
+			mediatek,usb3-pll-ssc-delta1;
 			status = "okay";
 		};
 	};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts
index c707291..69f9f2e 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts
@@ -71,6 +71,24 @@
 		adie_id = <7976>;
 		sku_type = <3000>;
 	};
+
+	sound_wm8960 {
+		compatible = "mediatek,mt79xx-wm8960-machine";
+		mediatek,platform = <&afe>;
+		audio-routing = "Headphone", "HP_L",
+				"Headphone", "HP_R",
+				"LINPUT1", "AMIC",
+				"RINPUT1", "AMIC";
+		mediatek,audio-codec = <&wm8960>;
+		status = "disabled";
+	};
+
+	sound_si3218x {
+		compatible = "mediatek,mt79xx-si3218x-machine";
+		mediatek,platform = <&afe>;
+		mediatek,ext-codec = <&proslic_spi>;
+		status = "disabled";
+	};
 };
 
 &fan {
@@ -78,6 +96,12 @@
 	status = "okay";
 };
 
+&afe {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcm_pins>;
+	status = "okay";
+};
+
 &pwm {
 	status = "okay";
 };
@@ -86,6 +110,17 @@
 	status = "okay";
 };
 
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+	status = "okay";
+
+	wm8960: wm8960@1a {
+		compatible = "wlf,wm8960";
+		reg = <0x1a>;
+	};
+};
+
 &spi0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&spi0_flash_pins>;
@@ -113,6 +148,18 @@
 	/* pin shared with snfi */
 	pinctrl-0 = <&spic_pins>;
 	status = "disabled";
+
+	proslic_spi: proslic_spi@0 {
+		compatible = "silabs,proslic_spi";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		spi-cpha = <1>;
+		spi-cpol = <1>;
+		channel_count = <1>;
+		debug_level = <4>;       /* 1 = TRC, 2 = DBG, 4 = ERR */
+		reset_gpio = <&pio 54 0>;
+		ig,enable-spi = <1>;     /* 1: Enable, 0: Disable */
+	};
 };
 
 &pcie0 {
@@ -182,7 +229,28 @@
 	spic_pins: spi1-pins {
 		mux {
 			function = "spi";
-			groups = "spi1_1";
+			groups = "spi1";
+		};
+	};
+
+	i2c1_pins: i2c1-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c1_0";
+		};
+	};
+
+	i2s_pins: i2s-pins {
+		mux {
+			function = "audio";
+			groups = "i2s";
+		};
+	};
+
+	pcm_pins: pcm-pins {
+		mux {
+			function = "audio";
+			groups = "pcm";
 		};
 	};
 };
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts
index ef4cd4d..3153b89 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts
@@ -73,6 +73,15 @@
 		};
 	};
 
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
 	wsys_adie: wsys_adie@0 {
 	// fpga cases need to manual change adie_id / sku_type for dvt only
 		compatible = "mediatek,rebb-mt7988-adie";
@@ -220,6 +229,20 @@
 		};
 	};
 
+	mmc0_pins_default: mmc0-pins-default {
+		mux {
+			function = "flash";
+			groups = "emmc_45";
+		};
+	};
+
+	mmc0_pins_uhs: mmc0-pins-uhs {
+		mux {
+			function = "flash";
+			groups = "emmc_45";
+		};
+	};
+
 	pcie0_pins: pcie0-pins {
 		mux {
 			function = "pcie";
@@ -393,3 +416,17 @@
 		};
 	};
 };
+
+&mmc0 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc0_pins_default>;
+	pinctrl-1 = <&mmc0_pins_uhs>;
+	bus-width = <4>;
+	max-frequency = <52000000>;
+	cap-sd-highspeed;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_3p3v>;
+	no-mmc;
+	no-sdio;
+	status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
index 2a672cb..b1ecae9 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
@@ -330,6 +330,11 @@
 		cr_set_bits(hnat_priv->ppe_base[ppe_id] + PPE_FLOW_CFG,
 			    BIT_IPV4_MAPE_EN | BIT_IPV4_MAPT_EN);
 
+	if (hnat_priv->data->version == MTK_HNAT_V5)
+		cr_set_bits(hnat_priv->ppe_base[ppe_id] + PPE_FLOW_CFG,
+			    BIT_IPV6_NAT_EN | BIT_IPV6_NAPT_EN |
+			    BIT_CS0_RM_ALL_IP6_IP_EN);
+
 	/* setup FOE aging */
 	cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, NTU_AGE, 1);
 	cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, UNBD_AGE, 1);
@@ -525,6 +530,11 @@
 		cr_clr_bits(hnat_priv->ppe_base[ppe_id] + PPE_FLOW_CFG,
 			    BIT_IPV4_MAPE_EN | BIT_IPV4_MAPT_EN);
 
+	if (hnat_priv->data->version == MTK_HNAT_V5)
+		cr_clr_bits(hnat_priv->ppe_base[ppe_id] + PPE_FLOW_CFG,
+			    BIT_IPV6_NAT_EN | BIT_IPV6_NAPT_EN |
+			    BIT_CS0_RM_ALL_IP6_IP_EN);
+
 	/* disable FOE aging */
 	cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, NTU_AGE, 0);
 	cr_set_field(hnat_priv->ppe_base[ppe_id] + PPE_TB_CFG, UNBD_AGE, 0);
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 b8ec87a..9005ab2 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
@@ -712,21 +712,75 @@
 	u32 resv4 : 2;
 	u32 tport_id : 4;
 	u32 resv5 : 12;
-	u32 resv6;
-	u32 resv7;
-	u32 resv8;
-	u32 resv9;
-	u32 resv10;
-	u32 resv11;
-	u32 resv12;
-	u32 resv13;
 #elif defined(CONFIG_MEDIATEK_NETSYS_V2)
 	u16 minfo;
 	struct hnat_winfo winfo;
+#endif
+} __packed;
+
+struct hnat_ipv6_hnapt {
+	union {
+		struct hnat_bind_info_blk bfib1;
+		struct hnat_unbind_info_blk udib1;
+		u32 info_blk1;
+	};
+	u32 ipv6_sip0;
+	u32 ipv6_sip1;
+	u32 ipv6_sip2;
+	u32 ipv6_sip3;
+	u32 ipv6_dip0;
+	u32 ipv6_dip1;
+	u32 ipv6_dip2;
+	u32 ipv6_dip3;
+	u16 dport;
+	u16 sport;
+
+	u32 resv1;
+	u32 resv2;
 	u32 resv3;
-	u32 resv4;
+	u32 resv4 : 8;
+	u32 eg_ipv6_dir : 1;
+	u32 eg_keep_ecn : 1;
+	u32 eg_keep_cls : 1;
+	u32 resv5 : 15;
+	u32 act_dp : 6; /* UDF */
+
+	union {
+		struct hnat_info_blk2 iblk2;
+		struct hnat_info_blk2_whnat iblk2w;
+		u32 info_blk2;
+	};
+
+	u16 vlan1;
+	u16 etype;
+	u32 dmac_hi;
+	u16 vlan2;
+	u16 dmac_lo;
+	u32 smac_hi;
+	u16 pppoe_id;
+	u16 smac_lo;
+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
+	u16 minfo;
+	u16 resv6;
+	u32 new_ipv6_ip0;
+	u32 new_ipv6_ip1;
+	u32 new_ipv6_ip2;
+	u32 new_ipv6_ip3;
 	u16 new_dport;
 	u16 new_sport;
+	struct hnat_winfo winfo;
+	struct hnat_winfo_pao winfo_pao;
+	u32 cdrt_id : 8;
+	u32 tops_entry : 6;
+	u32 resv7 : 2;
+	u32 tport_id : 4;
+	u32 resv8 : 12;
+	u32 resv9;
+	u32 resv10;
+	u32 resv11;
+#elif defined(CONFIG_MEDIATEK_NETSYS_V2)
+	u16 minfo;
+	struct hnat_winfo winfo;
 #endif
 } __packed;
 
@@ -740,6 +794,7 @@
 		struct hnat_ipv6_3t_route ipv6_3t_route;
 		struct hnat_ipv6_5t_route ipv6_5t_route;
 		struct hnat_ipv6_6rd ipv6_6rd;
+		struct hnat_ipv6_hnapt ipv6_hnapt;
 	};
 };
 
@@ -856,13 +911,10 @@
 	IPV6_3T_ROUTE = 4,
 	IPV6_5T_ROUTE = 5,
 	IPV6_6RD = 7,
-#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
 	IPV4_MAP_T = 8,
 	IPV4_MAP_E = 9,
-#else
-	IPV4_MAP_T = 6,
-	IPV4_MAP_E = 6,
-#endif
+	IPV6_HNAPT = 10,
+	IPV6_HNAT = 11,
 };
 
 /*--------------------------------------------------------------------------*/
@@ -908,6 +960,9 @@
 #define BIT_IPV6_HASH_GREK BIT(20)
 #define BIT_IPV4_MAPE_EN BIT(21)
 #define BIT_IPV4_MAPT_EN BIT(22)
+#define BIT_IPV6_NAT_EN BIT(23)
+#define BIT_IPV6_NAPT_EN BIT(24)
+#define BIT_CS0_RM_ALL_IP6_IP_EN BIT(25)
 
 /*GDMA_FWD_CFG value*/
 #define BITS_GDM_UFRC_P_PPE (NR_PPE0_PORT << 12)
@@ -1038,9 +1093,12 @@
 #define IS_IPV6_3T_ROUTE(x) (((x)->bfib1.pkt_type == IPV6_3T_ROUTE) ? 1 : 0)
 #define IS_IPV6_5T_ROUTE(x) (((x)->bfib1.pkt_type == IPV6_5T_ROUTE) ? 1 : 0)
 #define IS_IPV6_6RD(x) (((x)->bfib1.pkt_type == IPV6_6RD) ? 1 : 0)
+#define IS_IPV6_HNAPT(x) (((x)->bfib1.pkt_type == IPV6_HNAPT) ? 1 : 0)
+#define IS_IPV6_HNAT(x) (((x)->bfib1.pkt_type == IPV6_HNAT) ? 1 : 0)
 #define IS_IPV6_GRP(x)                                                         \
 	(IS_IPV6_3T_ROUTE(x) | IS_IPV6_5T_ROUTE(x) | IS_IPV6_6RD(x) |          \
-	 IS_IPV4_DSLITE(x) | IS_IPV4_MAPE(x) | IS_IPV4_MAPT(x))
+	 IS_IPV4_DSLITE(x) | IS_IPV4_MAPE(x) | IS_IPV4_MAPT(x) |	       \
+	 IS_IPV6_HNAPT(x) | IS_IPV6_HNAT(x))
 #define IS_BOND_MODE (!strncmp(LAN_DEV_NAME, "bond", 4))
 #define IS_GMAC1_MODE ((hnat_priv->gmac_num == 1) ? 1 : 0)
 #define IS_HQOS_MODE (qos_toggle == 1)
@@ -1076,6 +1134,8 @@
 #define NONE_DSA_PORT 0xff
 #define MAX_CRSN_NUM 32
 #define IPV6_HDR_LEN 40
+#define IPV6_SNAT	0
+#define IPV6_DNAT	1
 
 /*QDMA_PAGE value*/
 #define NUM_OF_Q_PER_PAGE 16
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 e41e859..726a154 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
@@ -35,7 +35,7 @@
 static const char * const packet_type[] = {
 	"IPV4_HNAPT",    "IPV4_HNAT",     "IPV6_1T_ROUTE", "IPV4_DSLITE",
 	"IPV6_3T_ROUTE", "IPV6_5T_ROUTE", "REV",	   "IPV6_6RD",
-	"IPV4_MAP_T",    "IPV4_MAP_E",
+	"IPV4_MAP_T",    "IPV4_MAP_E",    "IPV6_HNAPT",    "IPV6_HNAT",
 };
 
 static uint8_t *show_cpu_reason(struct sk_buff *skb)
@@ -465,7 +465,92 @@
 			entry->ipv6_6rd.sport, entry->ipv6_6rd.ipv6_dip0,
 			entry->ipv6_6rd.ipv6_dip1, entry->ipv6_6rd.ipv6_dip2,
 			entry->ipv6_6rd.ipv6_dip3, entry->ipv6_6rd.dport);
+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
+	} else if (IS_IPV6_HNAPT(entry)) {
+		pr_info("Information Block 2: %08X (FP=%d FQOS=%d QID=%d)",
+			entry->ipv6_hnapt.info_blk2,
+			entry->ipv6_hnapt.iblk2.dp,
+			entry->ipv6_hnapt.iblk2.fqos,
+			entry->ipv6_hnapt.iblk2.qid);
+		pr_info("Create IPv6 HNAPT entry\n");
+		pr_info("IPv6 Org IP/Port: %08X:%08X:%08X:%08X:%d -> %08X:%08X:%08X:%08X:%d",
+			entry->ipv6_hnapt.ipv6_sip0,
+			entry->ipv6_hnapt.ipv6_sip1,
+			entry->ipv6_hnapt.ipv6_sip2,
+			entry->ipv6_hnapt.ipv6_sip3,
+			entry->ipv6_hnapt.sport,
+			entry->ipv6_hnapt.ipv6_dip0,
+			entry->ipv6_hnapt.ipv6_dip1,
+			entry->ipv6_hnapt.ipv6_dip2,
+			entry->ipv6_hnapt.ipv6_dip3,
+			entry->ipv6_hnapt.dport);
+
+		if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_SNAT) {
+			pr_info("IPv6 New IP/Port: %08X:%08X:%08X:%08X:%d -> %08X:%08X:%08X:%08X:%d\n",
+				entry->ipv6_hnapt.new_ipv6_ip0,
+				entry->ipv6_hnapt.new_ipv6_ip1,
+				entry->ipv6_hnapt.new_ipv6_ip2,
+				entry->ipv6_hnapt.new_ipv6_ip3,
+				entry->ipv6_hnapt.new_sport,
+				entry->ipv6_hnapt.ipv6_dip0,
+				entry->ipv6_hnapt.ipv6_dip1,
+				entry->ipv6_hnapt.ipv6_dip2,
+				entry->ipv6_hnapt.ipv6_dip3,
+				entry->ipv6_hnapt.new_dport);
+		} else if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_DNAT) {
+			pr_info("IPv6 New IP/Port: %08X:%08X:%08X:%08X:%d -> %08X:%08X:%08X:%08X:%d\n",
+				entry->ipv6_hnapt.ipv6_sip0,
+				entry->ipv6_hnapt.ipv6_sip1,
+				entry->ipv6_hnapt.ipv6_sip2,
+				entry->ipv6_hnapt.ipv6_sip3,
+				entry->ipv6_hnapt.new_sport,
+				entry->ipv6_hnapt.new_ipv6_ip0,
+				entry->ipv6_hnapt.new_ipv6_ip1,
+				entry->ipv6_hnapt.new_ipv6_ip2,
+				entry->ipv6_hnapt.new_ipv6_ip3,
+				entry->ipv6_hnapt.new_dport);
+		}
+	} else if (IS_IPV6_HNAT(entry)) {
+		pr_info("Information Block 2: %08X (FP=%d FQOS=%d QID=%d)",
+			entry->ipv6_hnapt.info_blk2,
+			entry->ipv6_hnapt.iblk2.dp,
+			entry->ipv6_hnapt.iblk2.fqos,
+			entry->ipv6_hnapt.iblk2.qid);
+		pr_info("Create IPv6 HNAT entry\n");
+		pr_info("IPv6 Org IP: %08X:%08X:%08X:%08X -> %08X:%08X:%08X:%08X",
+			entry->ipv6_hnapt.ipv6_sip0,
+			entry->ipv6_hnapt.ipv6_sip1,
+			entry->ipv6_hnapt.ipv6_sip2,
+			entry->ipv6_hnapt.ipv6_sip3,
+			entry->ipv6_hnapt.ipv6_dip0,
+			entry->ipv6_hnapt.ipv6_dip1,
+			entry->ipv6_hnapt.ipv6_dip2,
+			entry->ipv6_hnapt.ipv6_dip3);
+
+		if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_SNAT) {
+			pr_info("IPv6 New IP: %08X:%08X:%08X:%08X -> %08X:%08X:%08X:%08X\n",
+				entry->ipv6_hnapt.new_ipv6_ip0,
+				entry->ipv6_hnapt.new_ipv6_ip1,
+				entry->ipv6_hnapt.new_ipv6_ip2,
+				entry->ipv6_hnapt.new_ipv6_ip3,
+				entry->ipv6_hnapt.ipv6_dip0,
+				entry->ipv6_hnapt.ipv6_dip1,
+				entry->ipv6_hnapt.ipv6_dip2,
+				entry->ipv6_hnapt.ipv6_dip3);
+		} else if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_DNAT) {
+			pr_info("IPv6 New IP: %08X:%08X:%08X:%08X -> %08X:%08X:%08X:%08X\n",
+				entry->ipv6_hnapt.ipv6_sip0,
+				entry->ipv6_hnapt.ipv6_sip1,
+				entry->ipv6_hnapt.ipv6_sip2,
+				entry->ipv6_hnapt.ipv6_sip3,
+				entry->ipv6_hnapt.new_ipv6_ip0,
+				entry->ipv6_hnapt.new_ipv6_ip1,
+				entry->ipv6_hnapt.new_ipv6_ip2,
+				entry->ipv6_hnapt.new_ipv6_ip3);
+		}
+#endif
 	}
+
 	if (IS_IPV4_HNAPT(entry) || IS_IPV4_HNAT(entry)) {
 		*((u32 *)h_source) = swab32(entry->ipv4_hnapt.smac_hi);
 		*((u16 *)&h_source[4]) = swab16(entry->ipv4_hnapt.smac_lo);
@@ -936,6 +1021,138 @@
 				   ntohs(entry->ipv6_5t_route.etype),
 				   entry->ipv6_5t_route.info_blk1,
 				   entry->ipv6_5t_route.info_blk2);
+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
+		} else if (IS_IPV6_HNAPT(entry)) {
+			u32 ipv6_sip0 = entry->ipv6_hnapt.ipv6_sip0;
+			u32 ipv6_sip1 = entry->ipv6_hnapt.ipv6_sip1;
+			u32 ipv6_sip2 = entry->ipv6_hnapt.ipv6_sip2;
+			u32 ipv6_sip3 = entry->ipv6_hnapt.ipv6_sip3;
+			u32 ipv6_dip0 = entry->ipv6_hnapt.ipv6_dip0;
+			u32 ipv6_dip1 = entry->ipv6_hnapt.ipv6_dip1;
+			u32 ipv6_dip2 = entry->ipv6_hnapt.ipv6_dip2;
+			u32 ipv6_dip3 = entry->ipv6_hnapt.ipv6_dip3;
+			u32 new_ipv6_ip0 = entry->ipv6_hnapt.new_ipv6_ip0;
+			u32 new_ipv6_ip1 = entry->ipv6_hnapt.new_ipv6_ip1;
+			u32 new_ipv6_ip2 = entry->ipv6_hnapt.new_ipv6_ip2;
+			u32 new_ipv6_ip3 = entry->ipv6_hnapt.new_ipv6_ip3;
+
+			*((u32 *)h_source) = swab32(entry->ipv6_hnapt.smac_hi);
+			*((u16 *)&h_source[4]) =
+				swab16(entry->ipv6_hnapt.smac_lo);
+			*((u32 *)h_dest) = swab32(entry->ipv6_hnapt.dmac_hi);
+			*((u16 *)&h_dest[4]) =
+				swab16(entry->ipv6_hnapt.dmac_lo);
+			PRINT_COUNT(m, acct);
+
+			if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_SNAT) {
+				seq_printf(m,
+					   "addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x(sp=%d)->DIP=%08x:%08x:%08x:%08x(dp=%d)|NEW_SIP=%08x:%08x:%08x:%08x(sp=%d)->NEW_DIP=%08x:%08x:%08x:%08x(dp=%d)|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n",
+					   entry, ppe_id, ei(entry, end),
+					   es(entry), pt(entry),
+					   ipv6_sip0, ipv6_sip1,
+					   ipv6_sip2, ipv6_sip3,
+					   entry->ipv6_hnapt.sport,
+					   ipv6_dip0, ipv6_dip1,
+					   ipv6_dip2, ipv6_dip3,
+					   entry->ipv6_hnapt.dport,
+					   new_ipv6_ip0, new_ipv6_ip1,
+					   new_ipv6_ip2, new_ipv6_ip3,
+					   entry->ipv6_hnapt.new_sport,
+					   ipv6_dip0, ipv6_dip1,
+					   ipv6_dip2, ipv6_dip3,
+					   entry->ipv6_hnapt.new_dport,
+					   h_source, h_dest,
+					   ntohs(entry->ipv6_hnapt.etype),
+					   entry->ipv6_hnapt.info_blk1,
+					   entry->ipv6_hnapt.info_blk2,
+					   entry->ipv6_hnapt.vlan1,
+					   entry->ipv6_hnapt.vlan2);
+			} else if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_DNAT) {
+				seq_printf(m,
+					   "addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x(sp=%d)->DIP=%08x:%08x:%08x:%08x(dp=%d)|NEW_SIP=%08x:%08x:%08x:%08x(sp=%d)->NEW_DIP=%08x:%08x:%08x:%08x(dp=%d)|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n",
+					   entry, ppe_id, ei(entry, end),
+					   es(entry), pt(entry),
+					   ipv6_sip0, ipv6_sip1,
+					   ipv6_sip2, ipv6_sip3,
+					   entry->ipv6_hnapt.sport,
+					   ipv6_dip0, ipv6_dip1,
+					   ipv6_dip2, ipv6_dip3,
+					   entry->ipv6_hnapt.dport,
+					   ipv6_sip0, ipv6_sip1,
+					   ipv6_sip2, ipv6_sip3,
+					   entry->ipv6_hnapt.new_sport,
+					   new_ipv6_ip0, new_ipv6_ip1,
+					   new_ipv6_ip2, new_ipv6_ip3,
+					   entry->ipv6_hnapt.new_dport,
+					   h_source, h_dest,
+					   ntohs(entry->ipv6_hnapt.etype),
+					   entry->ipv6_hnapt.info_blk1,
+					   entry->ipv6_hnapt.info_blk2,
+					   entry->ipv6_hnapt.vlan1,
+					   entry->ipv6_hnapt.vlan2);
+			}
+		} else if (IS_IPV6_HNAT(entry)) {
+			u32 ipv6_sip0 = entry->ipv6_hnapt.ipv6_sip0;
+			u32 ipv6_sip1 = entry->ipv6_hnapt.ipv6_sip1;
+			u32 ipv6_sip2 = entry->ipv6_hnapt.ipv6_sip2;
+			u32 ipv6_sip3 = entry->ipv6_hnapt.ipv6_sip3;
+			u32 ipv6_dip0 = entry->ipv6_hnapt.ipv6_dip0;
+			u32 ipv6_dip1 = entry->ipv6_hnapt.ipv6_dip1;
+			u32 ipv6_dip2 = entry->ipv6_hnapt.ipv6_dip2;
+			u32 ipv6_dip3 = entry->ipv6_hnapt.ipv6_dip3;
+			u32 new_ipv6_ip0 = entry->ipv6_hnapt.new_ipv6_ip0;
+			u32 new_ipv6_ip1 = entry->ipv6_hnapt.new_ipv6_ip1;
+			u32 new_ipv6_ip2 = entry->ipv6_hnapt.new_ipv6_ip2;
+			u32 new_ipv6_ip3 = entry->ipv6_hnapt.new_ipv6_ip3;
+
+			*((u32 *)h_source) = swab32(entry->ipv6_hnapt.smac_hi);
+			*((u16 *)&h_source[4]) =
+				swab16(entry->ipv6_hnapt.smac_lo);
+			*((u32 *)h_dest) = swab32(entry->ipv6_hnapt.dmac_hi);
+			*((u16 *)&h_dest[4]) =
+				swab16(entry->ipv6_hnapt.dmac_lo);
+			PRINT_COUNT(m, acct);
+
+			if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_SNAT) {
+				seq_printf(m,
+					   "addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x->DIP=%08x:%08x:%08x:%08x|NEW_SIP=%08x:%08x:%08x:%08x->NEW_DIP=%08x:%08x:%08x:%08x|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n",
+					   entry, ppe_id, ei(entry, end),
+					   es(entry), pt(entry),
+					   ipv6_sip0, ipv6_sip1,
+					   ipv6_sip2, ipv6_sip3,
+					   ipv6_dip0, ipv6_dip1,
+					   ipv6_dip2, ipv6_dip3,
+					   new_ipv6_ip0, new_ipv6_ip1,
+					   new_ipv6_ip2, new_ipv6_ip3,
+					   ipv6_dip0, ipv6_dip1,
+					   ipv6_dip2, ipv6_dip3,
+					   h_source, h_dest,
+					   ntohs(entry->ipv6_hnapt.etype),
+					   entry->ipv6_hnapt.info_blk1,
+					   entry->ipv6_hnapt.info_blk2,
+					   entry->ipv6_hnapt.vlan1,
+					   entry->ipv6_hnapt.vlan2);
+			} else if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_DNAT) {
+				seq_printf(m,
+					   "addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x->DIP=%08x:%08x:%08x:%08x|NEW_SIP=%08x:%08x:%08x:%08x->NEW_DIP=%08x:%08x:%08x:%08x|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n",
+					   entry, ppe_id, ei(entry, end),
+					   es(entry), pt(entry),
+					   ipv6_sip0, ipv6_sip1,
+					   ipv6_sip2, ipv6_sip3,
+					   ipv6_dip0, ipv6_dip1,
+					   ipv6_dip2, ipv6_dip3,
+					   ipv6_sip0, ipv6_sip1,
+					   ipv6_sip2, ipv6_sip3,
+					   new_ipv6_ip0, new_ipv6_ip1,
+					   new_ipv6_ip2, new_ipv6_ip3,
+					   h_source, h_dest,
+					   ntohs(entry->ipv6_hnapt.etype),
+					   entry->ipv6_hnapt.info_blk1,
+					   entry->ipv6_hnapt.info_blk2,
+					   entry->ipv6_hnapt.vlan1,
+					   entry->ipv6_hnapt.vlan2);
+			}
+#endif
 		} else if (IS_IPV4_DSLITE(entry)) {
 			__be32 saddr = htonl(entry->ipv4_hnapt.sip);
 			__be32 daddr = htonl(entry->ipv4_hnapt.dip);
@@ -1304,6 +1521,96 @@
 			   entry->ipv6_6rd.ipv6_dip0, entry->ipv6_6rd.ipv6_dip1,
 			   entry->ipv6_6rd.ipv6_dip2, entry->ipv6_6rd.ipv6_dip3,
 			   entry->ipv6_6rd.dport);
+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
+	} else if (IS_IPV6_HNAPT(entry)) {
+		if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_SNAT) {
+			seq_printf(m,
+				   "IPv6_HNAPT(%d): %08X:%08X:%08X:%08X:%d->%08X:%08X:%08X:%08X:%d => %08X:%08X:%08X:%08X:%d -> %08X:%08X:%08X:%08X:%d\n",
+				   index, entry->ipv6_hnapt.ipv6_sip0,
+				   entry->ipv6_hnapt.ipv6_sip1,
+				   entry->ipv6_hnapt.ipv6_sip2,
+				   entry->ipv6_hnapt.ipv6_sip3,
+				   entry->ipv6_hnapt.sport,
+				   entry->ipv6_hnapt.ipv6_dip0,
+				   entry->ipv6_hnapt.ipv6_dip1,
+				   entry->ipv6_hnapt.ipv6_dip2,
+				   entry->ipv6_hnapt.ipv6_dip3,
+				   entry->ipv6_hnapt.dport,
+				   entry->ipv6_hnapt.new_ipv6_ip0,
+				   entry->ipv6_hnapt.new_ipv6_ip1,
+				   entry->ipv6_hnapt.new_ipv6_ip2,
+				   entry->ipv6_hnapt.new_ipv6_ip3,
+				   entry->ipv6_hnapt.new_sport,
+				   entry->ipv6_hnapt.ipv6_dip0,
+				   entry->ipv6_hnapt.ipv6_dip1,
+				   entry->ipv6_hnapt.ipv6_dip2,
+				   entry->ipv6_hnapt.ipv6_dip3,
+				   entry->ipv6_hnapt.new_dport);
+		} else if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_DNAT) {
+			seq_printf(m,
+				   "IPv6_HNAPT(%d): %08X:%08X:%08X:%08X:%d->%08X:%08X:%08X:%08X:%d => %08X:%08X:%08X:%08X:%d -> %08X:%08X:%08X:%08X:%d\n",
+				   index, entry->ipv6_hnapt.ipv6_sip0,
+				   entry->ipv6_hnapt.ipv6_sip1,
+				   entry->ipv6_hnapt.ipv6_sip2,
+				   entry->ipv6_hnapt.ipv6_sip3,
+				   entry->ipv6_hnapt.sport,
+				   entry->ipv6_hnapt.ipv6_dip0,
+				   entry->ipv6_hnapt.ipv6_dip1,
+				   entry->ipv6_hnapt.ipv6_dip2,
+				   entry->ipv6_hnapt.ipv6_dip3,
+				   entry->ipv6_hnapt.dport,
+				   entry->ipv6_hnapt.ipv6_sip0,
+				   entry->ipv6_hnapt.ipv6_sip1,
+				   entry->ipv6_hnapt.ipv6_sip2,
+				   entry->ipv6_hnapt.ipv6_sip3,
+				   entry->ipv6_hnapt.new_sport,
+				   entry->ipv6_hnapt.new_ipv6_ip0,
+				   entry->ipv6_hnapt.new_ipv6_ip1,
+				   entry->ipv6_hnapt.new_ipv6_ip2,
+				   entry->ipv6_hnapt.new_ipv6_ip3,
+				   entry->ipv6_hnapt.new_dport);
+		}
+	} else if (IS_IPV6_HNAT(entry)) {
+		if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_SNAT) {
+			seq_printf(m,
+				   "IPv6_HNAT(%d): %08X:%08X:%08X:%08X->%08X:%08X:%08X:%08X => %08X:%08X:%08X:%08X -> %08X:%08X:%08X:%08X\n",
+				   index, entry->ipv6_hnapt.ipv6_sip0,
+				   entry->ipv6_hnapt.ipv6_sip1,
+				   entry->ipv6_hnapt.ipv6_sip2,
+				   entry->ipv6_hnapt.ipv6_sip3,
+				   entry->ipv6_hnapt.ipv6_dip0,
+				   entry->ipv6_hnapt.ipv6_dip1,
+				   entry->ipv6_hnapt.ipv6_dip2,
+				   entry->ipv6_hnapt.ipv6_dip3,
+				   entry->ipv6_hnapt.new_ipv6_ip0,
+				   entry->ipv6_hnapt.new_ipv6_ip1,
+				   entry->ipv6_hnapt.new_ipv6_ip2,
+				   entry->ipv6_hnapt.new_ipv6_ip3,
+				   entry->ipv6_hnapt.ipv6_dip0,
+				   entry->ipv6_hnapt.ipv6_dip1,
+				   entry->ipv6_hnapt.ipv6_dip2,
+				   entry->ipv6_hnapt.ipv6_dip3);
+		} else if (entry->ipv6_hnapt.eg_ipv6_dir == IPV6_DNAT) {
+			seq_printf(m,
+				   "IPv6_HNAT(%d): %08X:%08X:%08X:%08X->%08X:%08X:%08X:%08X => %08X:%08X:%08X:%08X -> %08X:%08X:%08X:%08X\n",
+				   index, entry->ipv6_hnapt.ipv6_sip0,
+				   entry->ipv6_hnapt.ipv6_sip1,
+				   entry->ipv6_hnapt.ipv6_sip2,
+				   entry->ipv6_hnapt.ipv6_sip3,
+				   entry->ipv6_hnapt.ipv6_dip0,
+				   entry->ipv6_hnapt.ipv6_dip1,
+				   entry->ipv6_hnapt.ipv6_dip2,
+				   entry->ipv6_hnapt.ipv6_dip3,
+				   entry->ipv6_hnapt.ipv6_sip0,
+				   entry->ipv6_hnapt.ipv6_sip1,
+				   entry->ipv6_hnapt.ipv6_sip2,
+				   entry->ipv6_hnapt.ipv6_sip3,
+				   entry->ipv6_hnapt.new_ipv6_ip0,
+				   entry->ipv6_hnapt.new_ipv6_ip1,
+				   entry->ipv6_hnapt.new_ipv6_ip2,
+				   entry->ipv6_hnapt.new_ipv6_ip3);
+		}
+#endif
 	}
 }
 
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 8221cbc..0de1740 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
@@ -1020,7 +1020,7 @@
 struct foe_entry ppe_fill_L2_info(struct ethhdr *eth, struct foe_entry entry,
 				  struct flow_offload_hw_path *hw_path)
 {
-	switch (entry.bfib1.pkt_type) {
+	switch ((int)entry.bfib1.pkt_type) {
 	case IPV4_HNAPT:
 	case IPV4_HNAT:
 		entry.ipv4_hnapt.dmac_hi = swab32(*((u32 *)eth->h_dest));
@@ -1034,6 +1034,8 @@
 	case IPV6_6RD:
 	case IPV6_5T_ROUTE:
 	case IPV6_3T_ROUTE:
+	case IPV6_HNAPT:
+	case IPV6_HNAT:
 		entry.ipv6_5t_route.dmac_hi = swab32(*((u32 *)eth->h_dest));
 		entry.ipv6_5t_route.dmac_lo = swab16(*((u16 *)&eth->h_dest[4]));
 		entry.ipv6_5t_route.smac_hi = swab32(*((u32 *)eth->h_source));
@@ -1057,7 +1059,7 @@
 		readl(hnat_priv->fe_base + 0x0010) & (0xFF) :
 		readl(hnat_priv->fe_base + 0x0010) & (0x7FFF);
 
-	switch (entry.bfib1.pkt_type) {
+	switch ((int)entry.bfib1.pkt_type) {
 	case IPV4_HNAPT:
 	case IPV4_HNAT:
 		if (hnat_priv->data->mcast &&
@@ -1080,6 +1082,8 @@
 	case IPV6_6RD:
 	case IPV6_5T_ROUTE:
 	case IPV6_3T_ROUTE:
+	case IPV6_HNAPT:
+	case IPV6_HNAT:
 		if (hnat_priv->data->mcast &&
 		    is_multicast_ether_addr(&eth->h_dest[0])) {
 			entry.ipv6_5t_route.iblk2.mcast = 1;
@@ -1111,12 +1115,16 @@
 	struct ipv6hdr *ip6h;
 	struct tcpudphdr _ports;
 	const struct tcpudphdr *pptr;
+	struct nf_conn *ct;
+	enum ip_conntrack_info ctinfo;
 	u32 gmac = NR_DISCARD;
 	int udp = 0;
 	u32 qid = 0;
 	u32 port_id = 0;
 	int mape = 0;
 
+	ct = nf_ct_get(skb, &ctinfo);
+
 	if (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPIP)
 		/* point to ethernet header for DS-Lite and MapE */
 		eth = (struct ethhdr *)(skb->data - ETH_HLEN);
@@ -1311,6 +1319,46 @@
 				entry.ipv6_5t_route.dport =
 					foe->ipv6_5t_route.dport;
 			}
+
+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
+			if (ct && (ct->status & IPS_SRC_NAT)) {
+				entry.bfib1.pkt_type = IPV6_HNAPT;
+
+				if (IS_WAN(dev) || IS_DSA_WAN(dev)) {
+					entry.ipv6_hnapt.eg_ipv6_dir =
+						IPV6_SNAT;
+					entry.ipv6_hnapt.new_ipv6_ip0 =
+						ntohl(ip6h->saddr.s6_addr32[0]);
+					entry.ipv6_hnapt.new_ipv6_ip1 =
+						ntohl(ip6h->saddr.s6_addr32[1]);
+					entry.ipv6_hnapt.new_ipv6_ip2 =
+						ntohl(ip6h->saddr.s6_addr32[2]);
+					entry.ipv6_hnapt.new_ipv6_ip3 =
+						ntohl(ip6h->saddr.s6_addr32[3]);
+				} else {
+					entry.ipv6_hnapt.eg_ipv6_dir =
+						IPV6_DNAT;
+					entry.ipv6_hnapt.new_ipv6_ip0 =
+						ntohl(ip6h->daddr.s6_addr32[0]);
+					entry.ipv6_hnapt.new_ipv6_ip1 =
+						ntohl(ip6h->daddr.s6_addr32[1]);
+					entry.ipv6_hnapt.new_ipv6_ip2 =
+						ntohl(ip6h->daddr.s6_addr32[2]);
+					entry.ipv6_hnapt.new_ipv6_ip3 =
+						ntohl(ip6h->daddr.s6_addr32[3]);
+				}
+
+				pptr = skb_header_pointer(skb, IPV6_HDR_LEN,
+							  sizeof(_ports),
+							  &_ports);
+				if (unlikely(!pptr))
+					return -1;
+
+				entry.ipv6_hnapt.new_sport = ntohs(pptr->src);
+				entry.ipv6_hnapt.new_dport = ntohs(pptr->dst);
+			}
+#endif
+
 			entry.ipv6_5t_route.iblk2.dscp =
 				(ip6h->priority << 4 |
 				 (ip6h->flow_lbl[0] >> 4));
@@ -1681,7 +1729,7 @@
 	/* Some mt_wifi virtual interfaces, such as apcli,
 	 * will change the smac for specail purpose.
 	 */
-	switch (bfib1_tx.pkt_type) {
+	switch ((int)bfib1_tx.pkt_type) {
 	case IPV4_HNAPT:
 	case IPV4_HNAT:
 		entry->ipv4_hnapt.smac_hi = swab32(*((u32 *)eth->h_source));
@@ -1692,6 +1740,8 @@
 	case IPV6_6RD:
 	case IPV6_5T_ROUTE:
 	case IPV6_3T_ROUTE:
+	case IPV6_HNAPT:
+	case IPV6_HNAT:
 		entry->ipv6_5t_route.smac_hi = swab32(*((u32 *)eth->h_source));
 		entry->ipv6_5t_route.smac_lo = swab16(*((u16 *)&eth->h_source[4]));
 		break;
@@ -1765,6 +1815,24 @@
 			}
 		}
 		entry->ipv4_hnapt.iblk2.dp = gmac_no;
+#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.rxid = skb_hnat_rx_id(skb);
+		entry->ipv6_hnapt.iblk2.winfoi = 1;
+
+		entry->ipv6_hnapt.winfo.bssid = skb_hnat_bss_id(skb);
+		entry->ipv6_hnapt.winfo.wcid = skb_hnat_wc_id(skb);
+		entry->ipv6_hnapt.winfo_pao.usr_info = skb_hnat_usr_info(skb);
+		entry->ipv6_hnapt.winfo_pao.tid = skb_hnat_tid(skb);
+		entry->ipv6_hnapt.winfo_pao.is_fixedrate =
+			skb_hnat_is_fixedrate(skb);
+		entry->ipv6_hnapt.winfo_pao.is_prior = skb_hnat_is_prior(skb);
+		entry->ipv6_hnapt.winfo_pao.is_sp = skb_hnat_is_sp(skb);
+		entry->ipv6_hnapt.winfo_pao.hf = skb_hnat_hf(skb);
+		entry->ipv6_hnapt.winfo_pao.amsdu = skb_hnat_amsdu(skb);
+		entry->ipv6_hnapt.tport_id = (IS_HQOS_MODE) ? 1 : 0;
+#endif
 	} else {
 		entry->ipv6_5t_route.iblk2.fqos = 0;
 		if ((hnat_priv->data->version == MTK_HNAT_V2 &&
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c
index 251a412..d292dbe 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c
@@ -74,7 +74,10 @@
 	if (ret)
 		return ret;
 
-	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+	/* We don't support HDX at MAC layer on mt798x.
+	 * So mask phy's HDX capabilities, too.
+	 */
+	linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
 			 phydev->supported);
 	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
 			 phydev->supported);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c
index 7521c14..fcb33a0 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c
@@ -722,48 +722,30 @@
 static int mt7988_int_usxgmii_funcs[] = { 3, 3 };
 
 /* pwm */
-static int mt7988_pwm7_0_pins[] = { 4 };
-static int mt7988_pwm7_0_funcs[] = { 3 };
-
-static int mt7988_pwm1_pins[] = { 21 };
-static int mt7988_pwm1_funcs[] = { 1 };
-
 static int mt7988_pwm0_pins[] = { 57 };
 static int mt7988_pwm0_funcs[] = { 1 };
 
-static int mt7988_pwm2_pins[] = { 58 };
-static int mt7988_pwm2_funcs[] = { 5 };
+static int mt7988_pwm1_pins[] = { 21 };
+static int mt7988_pwm1_funcs[] = { 1 };
 
-static int mt7988_pwm3_pins[] = { 59 };
-static int mt7988_pwm3_funcs[] = { 5 };
+static int mt7988_pwm2_pins[] = { 80 };
+static int mt7988_pwm2_funcs[] = { 2 };
 
-static int mt7988_pwm4_pins[] = { 60 };
-static int mt7988_pwm4_funcs[] = { 5 };
+static int mt7988_pwm3_pins[] = { 81 };
+static int mt7988_pwm3_funcs[] = { 2 };
 
-static int mt7988_pwm5_pins[] = { 61 };
-static int mt7988_pwm5_funcs[] = { 5 };
+static int mt7988_pwm4_pins[] = { 82 };
+static int mt7988_pwm4_funcs[] = { 2 };
 
-static int mt7988_pwm6_0_pins[] = { 62 };
-static int mt7988_pwm6_0_funcs[] = { 5 };
+static int mt7988_pwm5_pins[] = { 83 };
+static int mt7988_pwm5_funcs[] = { 2 };
 
-static int mt7988_pwm6_1_pins[] = { 69 };
-static int mt7988_pwm6_1_funcs[] = { 3 };
+static int mt7988_pwm6_pins[] = { 69 };
+static int mt7988_pwm6_funcs[] = { 3 };
 
 static int mt7988_pwm7_pins[] = { 70 };
 static int mt7988_pwm7_funcs[] = { 3 };
 
-static int mt7988_pwm2_1_pins[] = { 80 };
-static int mt7988_pwm2_1_funcs[] = { 2 };
-
-static int mt7988_pwm3_1_pins[] = { 81 };
-static int mt7988_pwm3_1_funcs[] = { 2 };
-
-static int mt7988_pwm4_1_pins[] = { 82 };
-static int mt7988_pwm4_1_funcs[] = { 2 };
-
-static int mt7988_pwm5_1_pins[] = { 83 };
-static int mt7988_pwm5_1_funcs[] = { 2 };
-
 /* dfd */
 static int mt7988_dfd_pins[] = { 0, 1, 2, 3, 4 };
 static int mt7988_dfd_funcs[] = { 4, 4, 4, 4, 4 };
@@ -1061,8 +1043,6 @@
 	PINCTRL_PIN_GROUP("tops_jtag0_0", mt7988_tops_jtag0_0),
 	/*  @GPIO(2,3): int_usxgmii */
 	PINCTRL_PIN_GROUP("int_usxgmii", mt7988_int_usxgmii),
-	/*  @GPIO(4): pwm7_0 */
-	PINCTRL_PIN_GROUP("pwm7_0", mt7988_pwm7_0),
 	/*  @GPIO(0,1,2,3,4): dfd */
 	PINCTRL_PIN_GROUP("dfd", mt7988_dfd),
 	/*  @GPIO(0,1): xfi_phy0_i2c0 */
@@ -1209,16 +1189,6 @@
 	PINCTRL_PIN_GROUP("uart2_3", mt7988_uart2_3),
 	/*  @GPIO(58,59,60,61) uart1_1 */
 	PINCTRL_PIN_GROUP("uart1_1", mt7988_uart1_1),
-	/*  @GPIO(58) pwm2 */
-	PINCTRL_PIN_GROUP("pwm2", mt7988_pwm2),
-	/*  @GPIO(59) pwm3 */
-	PINCTRL_PIN_GROUP("pwm3", mt7988_pwm3),
-	/*  @GPIO(60) pwm4 */
-	PINCTRL_PIN_GROUP("pwm4", mt7988_pwm4),
-	/*  @GPIO(61) pwm5 */
-	PINCTRL_PIN_GROUP("pwm5", mt7988_pwm5),
-	/*  @GPIO(62) pwm6_0 */
-	PINCTRL_PIN_GROUP("pwm6_0", mt7988_pwm6_0),
 	/*  @GPIO(58,59,60,61) gbe_led1 */
 	PINCTRL_PIN_GROUP("gbe_led1", mt7988_gbe_led1),
 	/*  @GPIO(62) 2p5gbe_led1 */
@@ -1235,8 +1205,8 @@
 	PINCTRL_PIN_GROUP("mdc_mdio1", mt7988_mdc_mdio1),
 	/*  @GPIO(69, 70) i2c1_2 */
 	PINCTRL_PIN_GROUP("i2c1_2", mt7988_i2c1_2),
-	/*  @GPIO(69) pwm6_1 */
-	PINCTRL_PIN_GROUP("pwm6_1", mt7988_pwm6_1),
+	/*  @GPIO(69) pwm6 */
+	PINCTRL_PIN_GROUP("pwm6", mt7988_pwm6),
 	/*  @GPIO(70) pwm7 */
 	PINCTRL_PIN_GROUP("pwm7", mt7988_pwm7),
 	/*  @GPIO(69,70) i2c2_0 */
@@ -1261,14 +1231,14 @@
 	PINCTRL_PIN_GROUP("pcie_wake_n2_1", mt7988_pcie_wake_n2_1),
 	/*  @GPIO(80,81,82,83) uart1_2 */
 	PINCTRL_PIN_GROUP("uart1_2", mt7988_uart1_2),
-	/*  @GPIO(80) pwm2_1 */
-	PINCTRL_PIN_GROUP("pwm2_1", mt7988_pwm2_1),
-	/*  @GPIO(81) pwm3_1 */
-	PINCTRL_PIN_GROUP("pwm3_1", mt7988_pwm3_1),
-	/*  @GPIO(82) pwm4_1 */
-	PINCTRL_PIN_GROUP("pwm4_1", mt7988_pwm4_1),
-	/*  @GPIO(83) pwm5_1 */
-	PINCTRL_PIN_GROUP("pwm5_1", mt7988_pwm5_1),
+	/*  @GPIO(80) pwm2 */
+	PINCTRL_PIN_GROUP("pwm2", mt7988_pwm2),
+	/*  @GPIO(81) pwm3 */
+	PINCTRL_PIN_GROUP("pwm3", mt7988_pwm3),
+	/*  @GPIO(82) pwm4 */
+	PINCTRL_PIN_GROUP("pwm4", mt7988_pwm4),
+	/*  @GPIO(83) pwm5 */
+	PINCTRL_PIN_GROUP("pwm5", mt7988_pwm5),
 	/*  @GPIO(80) net_wo0_uart_txd_0 */
 	PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0),
 	/*  @GPIO(81) net_wo1_uart_txd_0 */
@@ -1296,8 +1266,7 @@
 	"int_usxgmii",
 };
 static const char * const mt7988_pwm_groups[] = {
-	"pwm7_0", "pwm1",   "pwm0", "pwm2",   "pwm3",	"pwm4",	  "pwm5",
-	"pwm6_0", "pwm6_1", "pwm7", "pwm2_1", "pwm3_1", "pwm4_1", "pwm5_1"
+	"pwm0", "pwm1", "pwm2", "pwm3", "pwm4",	"pwm5",	"pwm6", "pwm7"
 };
 static const char * const mt7988_dfd_groups[] = {
 	"dfd",
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/soc/mediatek/mt7988-pm-domains.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/soc/mediatek/mt7988-pm-domains.h
index f7db02c..4497fd7 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/soc/mediatek/mt7988-pm-domains.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/soc/mediatek/mt7988-pm-domains.h
@@ -75,7 +75,7 @@
 		.sram_2nd_pdn_bit = BIT(8),
 		.sram_2nd_clk_dis_bit = BIT(5),
 		.sram_2nd_ctrl_offs = 0x060,
-		.caps = MTK_SCPD_CLAMP_PROTECTION,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
 
 	},
 
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 00909d5..b05f862 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
@@ -14,11 +14,11 @@
  drivers/net/ethernet/mediatek/mtk_wed_ccif.h  |  45 ++
  .../net/ethernet/mediatek/mtk_wed_debugfs.c   |  90 +++
  drivers/net/ethernet/mediatek/mtk_wed_mcu.c   | 586 ++++++++++++++++
- drivers/net/ethernet/mediatek/mtk_wed_mcu.h   | 125 ++++
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.h   |  96 +++
  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          |  74 ++-
+ include/linux/soc/mediatek/mtk_wed.h          | 101 ++-
  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, WO_CMD_CHANGE_STATE,
++	mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WED_WO_CHANGE_STATE,
 +			     &state, sizeof(state), false);
 +
 +	do {
@@ -937,7 +937,7 @@
 +		.wed = 0,
 +	};
 +
-+	return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WO_CMD_WED_CFG,
++	return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WED_WO_CFG,
 +				    &req, sizeof(req), true);
 +}
 +
@@ -1711,7 +1711,7 @@
 +	req.arg0 = (u32)exp->phys;
 +	req.arg1 = (u32)exp->log_size;
 +
-+	return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WO_CMD_EXCEPTION_INIT,
++	return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WED_WO_EXCEPTION_INIT,
 +				    &req, sizeof(req), false);
 +
 +free:
@@ -1774,7 +1774,7 @@
 +
 +		for (i = 0; i < cnt; i++)
 +			if (wed->wlan.update_wo_rxcnt)
-+				wed->wlan.update_wo_rxcnt(wed, rxcnt);
++				wed->wlan.update_wo_rxcnt(wed, &rxcnt[i]);
 +		break;
 +	default:
 +		break;
@@ -1967,13 +1967,13 @@
 +	skb_pull(skb, sizeof(struct wed_cmd_hdr));
 +
 +	switch (cmd) {
-+	case WO_CMD_RXCNT_INFO:
++	case WED_WO_RXCNT_INFO:
 +		cnt = *(u32 *)skb->data;
 +		rxcnt = (struct wo_cmd_rxcnt_t *)((u32 *)skb->data+1);
 +
 +		for (i = 0; i < cnt; i++)
 +			if (wed->wlan.update_wo_rxcnt)
-+				wed->wlan.update_wo_rxcnt(wed, rxcnt);
++				wed->wlan.update_wo_rxcnt(wed, &rxcnt[i]);
 +		break;
 +	default:
 +		break;
@@ -2057,22 +2057,22 @@
 +	cmd = input[0];
 +	if (input_total == 1 && cmd) {
 +		if (strncmp(cmd, "bainfo", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_BA_INFO_DUMP;
++			cmd_id = WED_WO_BA_INFO_DUMP;
 +		} else if (strncmp(cmd, "bactrl", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_BA_CTRL_DUMP;
++			cmd_id = WED_WO_BA_CTRL_DUMP;
 +		} else if (strncmp(cmd, "fbcmdq", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_FBCMD_Q_DUMP;
++			cmd_id = WED_WO_FBCMD_Q_DUMP;
 +		} else if (strncmp(cmd, "logflush", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_LOG_FLUSH;
++			cmd_id = WED_WO_LOG_FLUSH;
 +		} else if (strncmp(cmd, "cpustat.dump", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_CPU_STATS_DUMP;
++			cmd_id = WED_WO_CPU_STATS_DUMP;
 +		} else if (strncmp(cmd, "state", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_WED_RX_STAT;
++			cmd_id = WED_WO_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 = WO_CMD_RXCNT_INFO;
++			cmd_id = WED_WO_RXCNT_INFO;
 +			wait = true;
 +		} else {
 +			pr_info("(%s) unknown comand string(%s)!\n", __func__, cmd);
@@ -2088,23 +2088,23 @@
 +			}
 +		}
 +		if(strncmp(cmd, "devinfo", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_DEV_INFO_DUMP;
++			cmd_id = WED_WO_DEV_INFO_DUMP;
 +		} else if (strncmp(cmd, "bssinfo", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_BSS_INFO_DUMP;
++			cmd_id = WED_WO_BSS_INFO_DUMP;
 +		} else if (strncmp(cmd, "starec", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_STA_REC_DUMP;
++			cmd_id = WED_WO_STA_REC_DUMP;
 +		} else if (strncmp(cmd, "starec_ba", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_STA_BA_DUMP;
++			cmd_id = WED_WO_STA_BA_DUMP;
 +		} else if (strncmp(cmd, "logctrl", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_FW_LOG_CTRL;
++			cmd_id = WED_WO_FW_LOG_CTRL;
 +		} else if (strncmp(cmd, "cpustat.en", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_CPU_STATS_ENABLE;
++			cmd_id = WED_WO_CPU_STATS_ENABLE;
 +		} else if (strncmp(cmd, "prof_conf", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_PROF_CTRL;
++			cmd_id = WED_WO_PROF_CTRL;
 +		} else if (strncmp(cmd, "rxcnt_ctrl", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_RXCNT_CTRL;
++			cmd_id = WED_WO_RXCNT_CTRL;
 +		} else if (strncmp(cmd, "dbg_set", strlen(cmd)) == 0) {
-+			cmd_id = WO_CMD_DBG_INFO;
++			cmd_id = WED_WO_DBG_INFO;
 +		}
 +	} else {
 +		dev_info(hw->dev, "usage: echo cmd='cmd_str' > wo_write\n");
@@ -2153,7 +2153,7 @@
 index 0000000..6a5ac76
 --- /dev/null
 +++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
-@@ -0,0 +1,125 @@
+@@ -0,0 +1,96 @@
 +// SPDX-License-Identifier: GPL-2.0-only
 +
 +#ifndef __MTK_WED_MCU_H
@@ -2209,35 +2209,6 @@
 +	WO_EVT_RXCNT_INFO = 0x3
 +};
 +
-+enum wo_cmd_id {
-+	WO_CMD_WED_CFG = 0,
-+	WO_CMD_WED_RX_STAT,
-+	WO_CMD_RRO_SER,
-+	WO_CMD_DBG_INFO,
-+	WO_CMD_DEV_INFO,
-+	WO_CMD_BSS_INFO,
-+	WO_CMD_STA_REC,
-+	WO_CMD_DEV_INFO_DUMP,
-+	WO_CMD_BSS_INFO_DUMP,
-+	WO_CMD_STA_REC_DUMP,
-+	WO_CMD_BA_INFO_DUMP,
-+	WO_CMD_FBCMD_Q_DUMP,
-+	WO_CMD_FW_LOG_CTRL,
-+	WO_CMD_LOG_FLUSH,
-+	WO_CMD_CHANGE_STATE,
-+	WO_CMD_CPU_STATS_ENABLE,
-+	WO_CMD_CPU_STATS_DUMP,
-+	WO_CMD_EXCEPTION_INIT,
-+	WO_CMD_PROF_CTRL,
-+	WO_CMD_STA_BA_DUMP,
-+	WO_CMD_BA_CTRL_DUMP,
-+	WO_CMD_RXCNT_CTRL,
-+	WO_CMD_RXCNT_INFO,
-+	WO_CMD_SET_CAP,
-+	WO_CMD_CCIF_RING_DUMP,
-+	WO_CMD_WED_END
-+};
-+
 +enum wo_state {
 +	WO_STATE_UNDEFINED 	= 0x0,
 +	WO_STATE_INIT 		= 0x1,
@@ -3438,17 +3409,44 @@
 index e914cb4..cfa1120 100644
 --- a/include/linux/soc/mediatek/mtk_wed.h
 +++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -7,6 +7,9 @@
+@@ -7,6 +7,36 @@
  #include <linux/pci.h>
  
  #define MTK_WED_TX_QUEUES		2
 +#define MTK_WED_RX_QUEUES		2
 +
-+#define WED_WO_STA_REC			0x6
++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_NO_WED,
-@@ -33,6 +36,33 @@ struct mtk_wed_ring {
+@@ -33,6 +63,33 @@ struct mtk_wed_ring {
  	void __iomem *wpdma;
  };
  
@@ -3482,7 +3480,7 @@
  struct mtk_wed_device {
  #ifdef CONFIG_NET_MEDIATEK_SOC_WED
  	const struct mtk_wed_ops *ops;
-@@ -47,37 +77,56 @@ struct mtk_wed_device {
+@@ -47,37 +104,56 @@ 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];
@@ -3544,7 +3542,7 @@
  	} wlan;
  #endif
  };
-@@ -88,6 +137,10 @@ struct mtk_wed_ops {
+@@ -88,6 +164,10 @@ struct mtk_wed_ops {
  			     void __iomem *regs);
  	int (*txfree_ring_setup)(struct mtk_wed_device *dev,
  				 void __iomem *regs);
@@ -3555,7 +3553,7 @@
  	void (*detach)(struct mtk_wed_device *dev);
  
  	void (*stop)(struct mtk_wed_device *dev);
-@@ -99,6 +152,8 @@ struct mtk_wed_ops {
+@@ -99,6 +179,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);
@@ -3564,7 +3562,7 @@
  };
  
  extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
-@@ -131,6 +186,10 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
+@@ -131,6 +213,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)
@@ -3575,7 +3573,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 +198,8 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
+@@ -139,6 +225,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)
@@ -3584,7 +3582,7 @@
  #else
  static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
  {
-@@ -148,10 +209,13 @@ 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)
  #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 32daccb..94956b3 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
@@ -269,7 +269,7 @@
 +	bool busy = false;
 +	int i;
 +
-+	mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WO_CMD_CHANGE_STATE,
++	mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WED_WO_CHANGE_STATE,
 +			     &state, sizeof(state), true);
 +
 +	wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
@@ -346,7 +346,7 @@
 +
 +	/* wo change to enable state */
 +	state = WO_STATE_ENABLE;
-+	mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WO_CMD_CHANGE_STATE,
++	mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, WED_WO_CHANGE_STATE,
 +			     &state, sizeof(state), true);
 +
 +	/* wed_rx_ring_reset */
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 75db83e..b22e359 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
@@ -168,7 +168,7 @@
 CONFIG_DM_BUFIO=y
 # CONFIG_DM_CRYPT is not set
 # CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set
-# CONFIG_DM_INIT is not set
+CONFIG_DM_INIT=y
 # CONFIG_DM_MIRROR is not set
 # CONFIG_DM_SNAPSHOT is not set
 CONFIG_DM_VERITY=y
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0505-crypto-add-eip197-inside-secure-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0505-crypto-add-eip197-inside-secure-support.patch
index eff209b..8b9ccce 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0505-crypto-add-eip197-inside-secure-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0505-crypto-add-eip197-inside-secure-support.patch
@@ -28,7 +28,17 @@
  	else
  		return -ENODEV;
  
-@@ -592,6 +597,11 @@
+@@ -442,6 +447,9 @@
+ 
+ 	ipuesz = eip197_write_firmware(priv, fw[FW_IPUE]);
+ 
++	for (j = 0; j < i; j++)
++		release_firmware(fw[j]);
++
+ 	if (eip197_start_firmware(priv, ipuesz, ifppsz, minifw)) {
+ 		dev_dbg(priv->dev, "Firmware loaded successfully\n");
+ 		return 0;
+@@ -592,6 +600,11 @@
  	 */
  	if (priv->flags & SAFEXCEL_HW_EIP197) {
  		val = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
@@ -40,7 +50,7 @@
  		val |= EIP197_MST_CTRL_TX_MAX_CMD(5);
  		writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
  	}
-@@ -792,6 +802,12 @@
+@@ -792,6 +805,12 @@
  			return ret;
  	}
  
@@ -53,7 +63,7 @@
  	return safexcel_hw_setup_cdesc_rings(priv) ?:
  	       safexcel_hw_setup_rdesc_rings(priv) ?:
  	       0;
-@@ -1498,6 +1514,9 @@
+@@ -1498,6 +1517,9 @@
  	hwopt = readl(EIP197_GLOBAL(priv) + EIP197_OPTIONS);
  	hiaopt = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_OPTIONS);
  
@@ -63,7 +73,7 @@
  	if (priv->flags & SAFEXCEL_HW_EIP197) {
  		/* EIP197 */
  		peopt = readl(EIP197_PE(priv) + EIP197_PE_OPTIONS(0));
-@@ -1516,8 +1535,37 @@
+@@ -1516,8 +1538,37 @@
  					    EIP197_N_RINGS_MASK;
  		if (hiaopt & EIP197_HIA_OPT_HAS_PE_ARB)
  			priv->flags |= EIP197_PE_ARB;
@@ -102,7 +112,7 @@
  		/* If not a full TRC, then assume simple TRC */
  		if (!(hwopt & EIP197_OPT_HAS_TRC))
  			priv->flags |= EIP197_SIMPLE_TRC;
-@@ -1555,13 +1603,14 @@
+@@ -1555,13 +1606,14 @@
  				    EIP197_PE_EIP96_OPTIONS(0));
  
  	/* Print single info line describing what we just detected */
@@ -119,7 +129,7 @@
  
  	safexcel_configure(priv);
  
-@@ -1690,6 +1739,7 @@
+@@ -1690,6 +1742,7 @@
  {
  	struct device *dev = &pdev->dev;
  	struct safexcel_crypto_priv *priv;
@@ -127,7 +137,7 @@
  	int ret;
  
  	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-@@ -1701,7 +1751,11 @@
+@@ -1701,7 +1754,11 @@
  
  	platform_set_drvdata(pdev, priv);
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8000-PATCH-1-4-tphy-support-type-switch-by-pericfg.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8000-PATCH-1-4-tphy-support-type-switch-by-pericfg.patch
index 4ae4991..032ef35 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8000-PATCH-1-4-tphy-support-type-switch-by-pericfg.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8000-PATCH-1-4-tphy-support-type-switch-by-pericfg.patch
@@ -1,7 +1,7 @@
-From ddeda571f3d79dcccef6541b6413cb184de40afd Mon Sep 17 00:00:00 2001
+From 34687407776d46f08926b91f118adc484c4ac231 Mon Sep 17 00:00:00 2001
 From: Zhanyong Wang <zhanyong.wang@mediatek.com>
 Date: Fri, 17 Sep 2021 15:56:53 +0800
-Subject: [PATCH] phy: phy-mtk-tphy: support type switch by pericfg
+Subject: [PATCH 1/8] phy: phy-mtk-tphy: support type switch by pericfg
 
 Add support type switch between USB3, PCIe, SATA and SGMII by
 pericfg register, this is used to take the place of efuse or
@@ -11,14 +11,14 @@
 Signed-off-by: Vinod Koul <vkoul@kernel.org>
 Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
 ---
- drivers/phy/mediatek/phy-mtk-tphy.c | 84 +++++++++++++++++++++++++++--
- 1 file changed, 81 insertions(+), 3 deletions(-)
+ drivers/phy/mediatek/phy-mtk-tphy.c | 83 ++++++++++++++++++++++++++++-
+ 1 file changed, 81 insertions(+), 2 deletions(-)
 
 diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
-index d1ecf088032b..759e1c0c370a 100644
+index cb2ed3b25068..a59fe65f69e5 100644
 --- a/drivers/phy/mediatek/phy-mtk-tphy.c
 +++ b/drivers/phy/mediatek/phy-mtk-tphy.c
-@@ -10,12 +10,12 @@
+@@ -10,6 +10,7 @@
  #include <linux/delay.h>
  #include <linux/io.h>
  #include <linux/iopoll.h>
@@ -26,15 +26,9 @@
  #include <linux/module.h>
  #include <linux/of_address.h>
  #include <linux/of_device.h>
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
--#include <linux/mfd/syscon.h>
- #include <linux/regmap.h>
- 
- /* version V1 sub-banks offset base address */
-@@ -268,6 +268,14 @@
- #define HIF_SYSCFG1			0x14
- #define HIF_SYSCFG1_PHY2_MASK		(0x3 << 20)
+@@ -263,6 +264,14 @@
+ #define RG_CDR_BIRLTD0_GEN3_MSK		GENMASK(4, 0)
+ #define RG_CDR_BIRLTD0_GEN3_VAL(x)	(0x1f & (x))
  
 +/* PHY switch between pcie/usb3/sgmii/sata */
 +#define USB_PHY_SWITCH_CTRL	0x0
@@ -47,7 +41,7 @@
  enum mtk_phy_version {
  	MTK_PHY_V1 = 1,
  	MTK_PHY_V2,
-@@ -301,7 +309,10 @@ struct mtk_phy_instance {
+@@ -296,7 +305,10 @@ struct mtk_phy_instance {
  	};
  	struct clk *ref_clk;	/* reference clock of anolog phy */
  	u32 index;
@@ -59,7 +53,7 @@
  	int eye_src;
  	int eye_vrt;
  	int eye_term;
-@@ -900,6 +911,64 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
+@@ -890,6 +902,64 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
  	}
  }
  
@@ -124,7 +118,7 @@
  static int mtk_phy_init(struct phy *phy)
  {
  	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
-@@ -932,6 +1001,9 @@ static int mtk_phy_init(struct phy *phy)
+@@ -922,6 +992,9 @@ static int mtk_phy_init(struct phy *phy)
  	case PHY_TYPE_SATA:
  		sata_phy_instance_init(tphy, instance);
  		break;
@@ -134,7 +128,7 @@
  	default:
  		dev_err(tphy->dev, "incompatible PHY type\n");
  		return -EINVAL;
-@@ -1020,7 +1092,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+@@ -1010,7 +1083,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
  	if (!(instance->type == PHY_TYPE_USB2 ||
  	      instance->type == PHY_TYPE_USB3 ||
  	      instance->type == PHY_TYPE_PCIE ||
@@ -144,7 +138,7 @@
  		dev_err(dev, "unsupported device type: %d\n", instance->type);
  		return ERR_PTR(-EINVAL);
  	}
-@@ -1035,6 +1108,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+@@ -1025,6 +1099,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
  	}
  
  	phy_parse_property(tphy, instance);
@@ -152,7 +146,7 @@
  
  	return instance->phy;
  }
-@@ -1183,6 +1257,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
+@@ -1163,6 +1238,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
  			retval = PTR_ERR(instance->ref_clk);
  			goto put_child;
  		}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8006-phy-phy-mtk-tphy-add-support-efuse-setting.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8006-phy-phy-mtk-tphy-add-support-efuse-setting.patch
index 5cc8a65..05eb738 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8006-phy-phy-mtk-tphy-add-support-efuse-setting.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8006-phy-phy-mtk-tphy-add-support-efuse-setting.patch
@@ -1,7 +1,7 @@
-From afb123e0f9992d35d0fb28ed875f2b7b7884652f Mon Sep 17 00:00:00 2001
+From a2eaa93a5887ddd20af0373244481139627d0d77 Mon Sep 17 00:00:00 2001
 From: Zhanyong Wang <zhanyong.wang@mediatek.com>
 Date: Mon, 8 Nov 2021 14:51:38 +0800
-Subject: [PATCH 3/5] phy: phy-mtk-tphy: add support efuse setting
+Subject: [PATCH 2/8] phy: phy-mtk-tphy: add support efuse setting
 
 Due to some SoCs have a bit shift issue that will drop a bit for usb3
 phy or pcie phy, fix it by adding software efuse reading and setting,
@@ -11,22 +11,22 @@
 Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
 Change-Id: Ibf88868668b3889f18c7930531981400cac732f1
 ---
- drivers/phy/mediatek/phy-mtk-tphy.c | 194 ++++++++++++++++++++++++++++
- 1 file changed, 194 insertions(+)
+ drivers/phy/mediatek/phy-mtk-tphy.c | 195 ++++++++++++++++++++++++++++
+ 1 file changed, 195 insertions(+)
 
 diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
-index cb2ed3b25068..05a1ad4ff334 100644
+index a59fe65f69e5..ce2731b2f5ff 100644
 --- a/drivers/phy/mediatek/phy-mtk-tphy.c
 +++ b/drivers/phy/mediatek/phy-mtk-tphy.c
-@@ -11,6 +11,7 @@
- #include <linux/io.h>
+@@ -12,6 +12,7 @@
  #include <linux/iopoll.h>
+ #include <linux/mfd/syscon.h>
  #include <linux/module.h>
 +#include <linux/nvmem-consumer.h>
  #include <linux/of_address.h>
  #include <linux/of_device.h>
  #include <linux/phy/phy.h>
-@@ -38,11 +39,16 @@
+@@ -39,11 +40,16 @@
  #define SSUSB_SIFSLV_V2_U3PHYD		0x200
  #define SSUSB_SIFSLV_V2_U3PHYA		0x400
  
@@ -43,7 +43,7 @@
  #define PA1_RG_VRT_SEL			GENMASK(14, 12)
  #define PA1_RG_VRT_SEL_VAL(x)	((0x7 & (x)) << 12)
  #define PA1_RG_TERM_SEL		GENMASK(10, 8)
-@@ -114,6 +120,8 @@
+@@ -115,6 +121,8 @@
  #define P3C_RG_SWRST_U3_PHYD_FORCE_EN	BIT(24)
  
  #define U3P_U3_PHYA_REG0	0x000
@@ -52,7 +52,7 @@
  #define P3A_RG_CLKDRV_OFF		GENMASK(3, 2)
  #define P3A_RG_CLKDRV_OFF_VAL(x)	((0x3 & (x)) << 2)
  
-@@ -168,6 +176,25 @@
+@@ -169,6 +177,25 @@
  #define P3D_RG_FWAKE_TH		GENMASK(21, 16)
  #define P3D_RG_FWAKE_TH_VAL(x)	((0x3f & (x)) << 16)
  
@@ -78,7 +78,7 @@
  #define U3P_U3_PHYD_CDR1		0x05c
  #define P3D_RG_CDR_BIR_LTD1		GENMASK(28, 24)
  #define P3D_RG_CDR_BIR_LTD1_VAL(x)	((0x1f & (x)) << 24)
-@@ -266,11 +293,23 @@
+@@ -275,11 +302,23 @@
  enum mtk_phy_version {
  	MTK_PHY_V1 = 1,
  	MTK_PHY_V2,
@@ -102,7 +102,7 @@
  	enum mtk_phy_version version;
  };
  
-@@ -295,6 +334,10 @@ struct mtk_phy_instance {
+@@ -304,6 +343,10 @@ struct mtk_phy_instance {
  		struct u3phy_banks u3_banks;
  	};
  	struct clk *ref_clk;	/* reference clock of anolog phy */
@@ -111,10 +111,10 @@
 +	u32 efuse_tx_imp;
 +	u32 efuse_rx_imp;
  	u32 index;
- 	u8 type;
- 	int eye_src;
-@@ -890,6 +933,138 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
- 	}
+ 	u32 type;
+ 	struct regmap *type_sw;
+@@ -960,6 +1003,139 @@ static int phy_type_set(struct mtk_phy_instance *instance)
+ 	return 0;
  }
  
 +static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
@@ -249,10 +249,11 @@
 +	}
 +}
 +
++
  static int mtk_phy_init(struct phy *phy)
  {
  	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
-@@ -908,6 +1083,8 @@ static int mtk_phy_init(struct phy *phy)
+@@ -978,6 +1154,8 @@ static int mtk_phy_init(struct phy *phy)
  		return ret;
  	}
  
@@ -261,7 +262,7 @@
  	switch (instance->type) {
  	case PHY_TYPE_USB2:
  		u2_phy_instance_init(tphy, instance);
-@@ -989,6 +1166,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+@@ -1062,6 +1240,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
  	struct mtk_phy_instance *instance = NULL;
  	struct device_node *phy_np = args->np;
  	int index;
@@ -269,7 +270,7 @@
  
  	if (args->args_count != 1) {
  		dev_err(dev, "invalid number of cells in 'phy' property\n");
-@@ -1024,6 +1202,10 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+@@ -1098,6 +1277,10 @@ static struct phy *mtk_phy_xlate(struct device *dev,
  		return ERR_PTR(-EINVAL);
  	}
  
@@ -278,9 +279,9 @@
 +		return ERR_PTR(ret);
 +
  	phy_parse_property(tphy, instance);
+ 	phy_type_set(instance);
  
- 	return instance->phy;
-@@ -1045,14 +1227,26 @@ static const struct mtk_phy_pdata tphy_v1_pdata = {
+@@ -1120,14 +1303,26 @@ static const struct mtk_phy_pdata tphy_v1_pdata = {
  
  static const struct mtk_phy_pdata tphy_v2_pdata = {
  	.avoid_rx_sen_degradation = false,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8007-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8007-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch
index b710695..1c6711f 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8007-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8007-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch
@@ -1,7 +1,7 @@
-From 41ffe32e7ec23f592e21c508b5108899ad393059 Mon Sep 17 00:00:00 2001
+From 2abe803824f0331c42eb9853199d5f147cee3a06 Mon Sep 17 00:00:00 2001
 From: Zhanyong Wang <zhanyong.wang@mediatek.com>
 Date: Tue, 25 Jan 2022 16:50:47 +0800
-Subject: [PATCH 4/5] phy: phy-mtk-tphy: Add PCIe 2 lane efuse support
+Subject: [PATCH 3/8] phy: phy-mtk-tphy: Add PCIe 2 lane efuse support
 
 Add PCIe 2 lane efuse support in tphy driver.
 
@@ -12,10 +12,10 @@
  1 file changed, 140 insertions(+)
 
 diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
-index 05a1ad4..59d6ac3 100644
+index ce2731b2f5ff..b855e759b0da 100644
 --- a/drivers/phy/mediatek/phy-mtk-tphy.c
 +++ b/drivers/phy/mediatek/phy-mtk-tphy.c
-@@ -39,6 +39,15 @@
+@@ -40,6 +40,15 @@
  #define SSUSB_SIFSLV_V2_U3PHYD		0x200
  #define SSUSB_SIFSLV_V2_U3PHYA		0x400
  
@@ -31,7 +31,7 @@
  #define U3P_MISC_REG1		0x04
  #define MR1_EFUSE_AUTO_LOAD_DIS		BIT(6)
  
-@@ -294,6 +303,7 @@ enum mtk_phy_version {
+@@ -303,6 +312,7 @@ enum mtk_phy_version {
  	MTK_PHY_V1 = 1,
  	MTK_PHY_V2,
  	MTK_PHY_V3,
@@ -39,7 +39,7 @@
  };
  
  struct mtk_phy_pdata {
-@@ -338,6 +348,9 @@ struct mtk_phy_instance {
+@@ -347,6 +357,9 @@ struct mtk_phy_instance {
  	u32 efuse_intr;
  	u32 efuse_tx_imp;
  	u32 efuse_rx_imp;
@@ -47,9 +47,9 @@
 +	u32 efuse_tx_imp_ln1;
 +	u32 efuse_rx_imp_ln1;
  	u32 index;
- 	u8 type;
- 	int eye_src;
-@@ -878,6 +891,36 @@ static void phy_v2_banks_init(struct mtk_tphy *tphy,
+ 	u32 type;
+ 	struct regmap *type_sw;
+@@ -890,6 +903,36 @@ static void phy_v2_banks_init(struct mtk_tphy *tphy,
  	}
  }
  
@@ -86,7 +86,7 @@
  static void phy_parse_property(struct mtk_tphy *tphy,
  				struct mtk_phy_instance *instance)
  {
-@@ -1002,6 +1045,40 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
+@@ -1072,6 +1115,40 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
  		dev_info(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n",
  			 instance->efuse_intr, instance->efuse_rx_imp,
  			 instance->efuse_tx_imp);
@@ -127,7 +127,7 @@
  		break;
  	default:
  		dev_err(dev, "no sw efuse for type %d\n", instance->type);
-@@ -1035,6 +1112,31 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1105,6 +1182,31 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
  
  		break;
  	case PHY_TYPE_USB3:
@@ -159,7 +159,7 @@
  	case PHY_TYPE_PCIE:
  		tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
  		tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
-@@ -1059,6 +1161,35 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1129,6 +1231,35 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
  		pr_err("%s set efuse, tx_imp %x, rx_imp %x intr %x\n",
  			__func__, instance->efuse_tx_imp,
  			instance->efuse_rx_imp, instance->efuse_intr);
@@ -195,7 +195,7 @@
  		break;
  	default:
  		dev_warn(dev, "no sw efuse for type %d\n", instance->type);
-@@ -1197,6 +1328,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+@@ -1272,6 +1403,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
  		phy_v1_banks_init(tphy, instance);
  	} else if (tphy->pdata->version == MTK_PHY_V2) {
  		phy_v2_banks_init(tphy, instance);
@@ -204,7 +204,7 @@
  	} else {
  		dev_err(dev, "phy version is not supported\n");
  		return ERR_PTR(-EINVAL);
-@@ -1247,12 +1380,19 @@ static const struct mtk_phy_pdata mt8195_pdata = {
+@@ -1323,12 +1456,19 @@ static const struct mtk_phy_pdata mt8195_pdata = {
  	.version = MTK_PHY_V3,
  };
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8008-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8008-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch
index 1223fb6..e84ca6c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8008-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8008-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch
@@ -1,7 +1,7 @@
-From 1d5819e90f2ef6dead11809744372a9863227a92 Mon Sep 17 00:00:00 2001
+From 355e7f114a47819c3c6545a97ad308d627da5d1a Mon Sep 17 00:00:00 2001
 From: Zhanyong Wang <zhanyong.wang@mediatek.com>
 Date: Tue, 25 Jan 2022 19:03:34 +0800
-Subject: [PATCH 5/5] phy: phy-mtk-tphy: add auto-load-valid check mechanism
+Subject: [PATCH 4/8] phy: phy-mtk-tphy: add auto-load-valid check mechanism
  support
 
 add auto-load-valid check mechanism support
@@ -12,10 +12,10 @@
  1 file changed, 64 insertions(+), 3 deletions(-)
 
 diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
-index 59d6ac3..4adc505 100644
+index b855e759b0da..a5b17a1aed5c 100644
 --- a/drivers/phy/mediatek/phy-mtk-tphy.c
 +++ b/drivers/phy/mediatek/phy-mtk-tphy.c
-@@ -345,9 +345,13 @@ struct mtk_phy_instance {
+@@ -354,9 +354,13 @@ struct mtk_phy_instance {
  	};
  	struct clk *ref_clk;	/* reference clock of anolog phy */
  	u32 efuse_sw_en;
@@ -29,7 +29,7 @@
  	u32 efuse_intr_ln1;
  	u32 efuse_tx_imp_ln1;
  	u32 efuse_rx_imp_ln1;
-@@ -980,6 +984,7 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
+@@ -1050,6 +1054,7 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
  {
  	struct device *dev = &instance->phy->dev;
  	int ret = 0;
@@ -37,7 +37,7 @@
  
  	dev_err(dev, "try to get sw efuse\n");
  
-@@ -998,6 +1003,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
+@@ -1068,6 +1073,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
  
  	switch (instance->type) {
  	case PHY_TYPE_USB2:
@@ -58,7 +58,7 @@
  		ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
  		if (ret) {
  			dev_err(dev, "fail to get u2 intr efuse, %d\n", ret);
-@@ -1015,6 +1034,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
+@@ -1085,6 +1104,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
  		break;
  	case PHY_TYPE_USB3:
  	case PHY_TYPE_PCIE:
@@ -79,7 +79,7 @@
  		ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
  		if (ret) {
  			dev_err(dev, "fail to get u3 intr efuse, %d\n", ret);
-@@ -1049,6 +1082,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
+@@ -1119,6 +1152,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
  		if (tphy->pdata->version != MTK_PHY_V4)
  			break;
  
@@ -100,7 +100,7 @@
  		ret = nvmem_cell_read_variable_le_u32(dev, "intr_ln1", &instance->efuse_intr_ln1);
  		if (ret) {
  			dev_err(dev, "fail to get u3 lane1 intr efuse, %d\n", ret);
-@@ -1100,6 +1147,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1170,6 +1217,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
  
  	switch (instance->type) {
  	case PHY_TYPE_USB2:
@@ -111,7 +111,7 @@
  		tmp = readl(u2_banks->misc + U3P_MISC_REG1);
  		tmp |= MR1_EFUSE_AUTO_LOAD_DIS;
  		writel(tmp, u2_banks->misc + U3P_MISC_REG1);
-@@ -1112,6 +1163,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1182,6 +1233,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
  
  		break;
  	case PHY_TYPE_USB3:
@@ -122,7 +122,7 @@
  		tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
  		tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
  		writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RSV);
-@@ -1138,6 +1193,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1208,6 +1263,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
  
  		break;
  	case PHY_TYPE_PCIE:
@@ -133,7 +133,7 @@
  		tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
  		tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
  		writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RSV);
-@@ -1162,9 +1221,11 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1232,9 +1291,11 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
  			__func__, instance->efuse_tx_imp,
  			instance->efuse_rx_imp, instance->efuse_intr);
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8009-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8009-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch
new file mode 100644
index 0000000..5bf48b2
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8009-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch
@@ -0,0 +1,51 @@
+From 917388b73b89f2859d795d800a296151d77e6ece Mon Sep 17 00:00:00 2001
+From: Zhanyong Wang <zhanyong.wang@mediatek.com>
+Date: Sat, 15 Oct 2022 17:38:54 +0800
+Subject: [PATCH 5/8] tphy: one setting of TTSSC-Freq-Dev for all IC cases
+
+try to use one setting of TTSSC-Freq-Dev to covery all IC cases
+
+Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
+---
+ drivers/phy/mediatek/phy-mtk-tphy.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
+index a5b17a1aed5c..a38c50f4529f 100644
+--- a/drivers/phy/mediatek/phy-mtk-tphy.c
++++ b/drivers/phy/mediatek/phy-mtk-tphy.c
+@@ -219,6 +219,14 @@
+ #define P3D_RG_RXDET_STB2_SET_P3	GENMASK(8, 0)
+ #define P3D_RG_RXDET_STB2_SET_P3_VAL(x)	(0x1ff & (x))
+ 
++#define U3P_U3_PHYD_REG19		0x338
++#define P3D_RG_PLL_SSC_DELTA1           GENMASK(15, 0)
++#define P3D_RG_PLL_SSC_DELTA1_VAL(x)	(0xffff & (x))
++
++#define U3P_U3_PHYD_REG21		0x340
++#define P3D_RG_PLL_SSC_DELTA            GENMASK(31, 16)
++#define P3D_RG_PLL_SSC_DELTA_VAL(x)	((0xffff & (x)) << 16)
++
+ #define U3P_SPLLC_XTALCTL3		0x018
+ #define XC3_RG_U3_XTAL_RX_PWD		BIT(9)
+ #define XC3_RG_U3_FRC_XTAL_RX_PWD	BIT(8)
+@@ -514,6 +522,16 @@ static void u3_phy_instance_init(struct mtk_tphy *tphy,
+ 	tmp |= P3D_RG_RXDET_STB2_SET_P3_VAL(0x10);
+ 	writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET2);
+ 
++	tmp = readl(u3_banks->phyd + U3P_U3_PHYD_REG19);
++	tmp &= ~P3D_RG_PLL_SSC_DELTA1;
++	tmp |= P3D_RG_PLL_SSC_DELTA1_VAL(0x1c3);
++	writel(tmp, u3_banks->phyd + U3P_U3_PHYD_REG19);
++
++	tmp = readl(u3_banks->phyd + U3P_U3_PHYD_REG21);
++	tmp &= ~P3D_RG_PLL_SSC_DELTA;
++	tmp |= P3D_RG_PLL_SSC_DELTA_VAL(0x1c3);
++	writel(tmp, u3_banks->phyd + U3P_U3_PHYD_REG21);
++
+ 	dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
+ }
+ 
+-- 
+2.18.0
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9000-PATCH-1-1-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9000-PATCH-1-1-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch
index e82e1bc..9d1ca10 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9000-PATCH-1-1-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9000-PATCH-1-1-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch
@@ -1,24 +1,26 @@
-From 5f8c12ffa661e3707790f59827a45ff4102f2886 Mon Sep 17 00:00:00 2001
-From: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Date: Mon, 15 Aug 2022 14:13:50 +0800
-Subject: [PATCH] xHCI: change compliance mode de-emphasis default as gen1
+From 0df9413c8ff0df4ed69b6e1577d7cd5fd2d72e5e Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Tue, 25 Oct 2022 18:25:25 +0800
+Subject: [PATCH 1/3] xHCI: change compliance mode de-emphasis default as gen1
 
 Port0 is using Gen2 Phy for 10GHz, and Port0 is running
 on 5GHz actually. hence to change compliance mode de-
 emphasis default as Gen1.
 
 Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
 ---
- drivers/usb/host/xhci-mtk.c | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
+ drivers/usb/host/xhci-mtk.c | 18 +++++++++++++++++-
+ drivers/usb/host/xhci-mtk.h |  1 +
+ 2 files changed, 18 insertions(+), 1 deletion(-)
 
 diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
-index 2a4b73a658f9..b1201fb65fd6 100644
+index 5c0eb35cd007..77ddb8c05500 100644
 --- a/drivers/usb/host/xhci-mtk.c
 +++ b/drivers/usb/host/xhci-mtk.c
-@@ -24,6 +24,11 @@
+@@ -22,6 +22,11 @@
+ #include "xhci.h"
  #include "xhci-mtk.h"
- #include "xhci-mtk-test.h"
  
 +/* COMPLIANCE_CP5_CP7_TXDEEMPH_10G register */
 +#define COMPLIANCE_CP5_CP7_TXDEEMPH_10G  0x2428
@@ -28,7 +30,7 @@
  /* ip_pw_ctrl0 register */
  #define CTRL0_IP_SW_RST	BIT(0)
  
-@@ -415,6 +420,7 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
+@@ -413,6 +418,7 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
  {
  	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
  	int ret;
@@ -36,12 +38,12 @@
  
  	if (usb_hcd_is_primary_hcd(hcd)) {
  		ret = xhci_mtk_ssusb_config(mtk);
-@@ -432,6 +438,15 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
+@@ -430,6 +436,15 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
  			return ret;
  	}
  
 +	/* change COMPLIANCE_CP5_CP7_TXDEEMPH_10G  as Gen1 instead Gen2 */
-+	if (hcd->rsrc_start == 0x11190000ULL) {
++	if (mtk->p0_speed_fixup) {
 +		val  = readl(mtk->hcd->regs + COMPLIANCE_CP5_CP7_TXDEEMPH_10G);
 +		val &= ~CP5_CP7_TXDEEMPH_10G;
 +		val |= 0x00001;
@@ -52,6 +54,28 @@
  	return ret;
  }
  
+@@ -475,7 +490,8 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+ 	/* optional property, ignore the error if it does not exist */
+ 	of_property_read_u32(node, "mediatek,u3p-dis-msk",
+ 			     &mtk->u3p_dis_msk);
+-
++	mtk->p0_speed_fixup = of_property_read_bool(node,
++						    "mediatek,p0_speed_fixup");
+ 	ret = usb_wakeup_of_property_parse(mtk, node);
+ 	if (ret) {
+ 		dev_err(dev, "failed to parse uwk property\n");
+diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
+index 2f702342de66..8a884e7b481b 100644
+--- a/drivers/usb/host/xhci-mtk.h
++++ b/drivers/usb/host/xhci-mtk.h
+@@ -156,6 +156,7 @@ struct xhci_hcd_mtk {
+ 	struct regmap *uwk;
+ 	u32 uwk_reg_base;
+ 	u32 uwk_vers;
++	bool p0_speed_fixup;
+ };
+ 
+ static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd)
 -- 
 2.18.0
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9001-PATCH-1-2-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9001-PATCH-1-2-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch
index 0b3bf3c..07b87fc 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9001-PATCH-1-2-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9001-PATCH-1-2-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch
@@ -1,4 +1,4 @@
-From 4d19c233a01598a28fdc528ebaeb7a1b4bb6884f Mon Sep 17 00:00:00 2001
+From 083b79c977495cafc70c5d044db1f3f6c0587b1c Mon Sep 17 00:00:00 2001
 From: Zhanyong Wang <zhanyong.wang@mediatek.com>
 Date: Mon, 15 Aug 2022 12:40:22 +0800
 Subject: [PATCH 2/3] xHCI: MT79xx USB 2.0 USBIF compliance toolkit
@@ -9,11 +9,11 @@
 ---
  drivers/usb/host/Kconfig    |  9 +++++++++
  drivers/usb/host/Makefile   | 10 ++++++++++
- drivers/usb/host/xhci-mtk.c |  5 ++++-
+ drivers/usb/host/xhci-mtk.c |  6 ++++--
  drivers/usb/host/xhci-mtk.h |  7 +++++++
  drivers/usb/host/xhci.c     |  2 +-
  drivers/usb/host/xhci.h     |  1 +
- 6 files changed, 32 insertions(+), 2 deletions(-)
+ 6 files changed, 32 insertions(+), 3 deletions(-)
 
 diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
 index 79b2e79dddd0..12b1bf9aa043 100644
@@ -57,10 +57,10 @@
  
  xhci-plat-hcd-y := xhci-plat.o
 diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
-index 104296fdd03e..d4345657945d 100644
+index 77ddb8c05500..7a200793169b 100644
 --- a/drivers/usb/host/xhci-mtk.c
 +++ b/drivers/usb/host/xhci-mtk.c
-@@ -19,9 +19,10 @@
+@@ -18,10 +18,10 @@
  #include <linux/pm_runtime.h>
  #include <linux/regmap.h>
  #include <linux/regulator/consumer.h>
@@ -68,11 +68,12 @@
 +#include <linux/usb/of.h>
  #include "xhci.h"
  #include "xhci-mtk.h"
+-
 +#include "xhci-mtk-test.h"
- 
- /* ip_pw_ctrl0 register */
- #define CTRL0_IP_SW_RST	BIT(0)
-@@ -581,6 +582,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+ /* COMPLIANCE_CP5_CP7_TXDEEMPH_10G register */
+ #define COMPLIANCE_CP5_CP7_TXDEEMPH_10G  0x2428
+ #define CP5_CP7_TXDEEMPH_10G		 GENMASK(17, 0)
+@@ -586,6 +586,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
  	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
  	if (ret)
  		goto dealloc_usb2_hcd;
@@ -80,7 +81,7 @@
  
  	return 0;
  
-@@ -615,6 +617,7 @@ static int xhci_mtk_remove(struct platform_device *dev)
+@@ -620,6 +621,7 @@ static int xhci_mtk_remove(struct platform_device *dev)
  	struct usb_hcd	*hcd = mtk->hcd;
  	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
  	struct usb_hcd  *shared_hcd = xhci->shared_hcd;
@@ -89,13 +90,13 @@
  	pm_runtime_put_noidle(&dev->dev);
  	pm_runtime_disable(&dev->dev);
 diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
-index 985e7a19f6f6..1540c66799d7 100644
+index 8a884e7b481b..e815d7091acc 100644
 --- a/drivers/usb/host/xhci-mtk.h
 +++ b/drivers/usb/host/xhci-mtk.h
-@@ -158,6 +158,13 @@ struct xhci_hcd_mtk {
- 	struct regmap *uwk;
+@@ -157,6 +157,13 @@ struct xhci_hcd_mtk {
  	u32 uwk_reg_base;
  	u32 uwk_vers;
+ 	bool p0_speed_fixup;
 +
 +#ifdef CONFIG_USB_XHCI_MTK_DEBUGFS
 +	int     test_mode;
@@ -107,10 +108,10 @@
  
  static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd)
 diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
-index 9fe35bb67731..4f62eddce6ab 100644
+index 5ce16a259e61..b6f8383f7371 100644
 --- a/drivers/usb/host/xhci.c
 +++ b/drivers/usb/host/xhci.c
-@@ -711,7 +711,7 @@ EXPORT_SYMBOL_GPL(xhci_run);
+@@ -713,7 +713,7 @@ EXPORT_SYMBOL_GPL(xhci_run);
   * Disable device contexts, disable IRQs, and quiesce the HC.
   * Reset the HC, finish any completed transactions, and cleanup memory.
   */
@@ -120,7 +121,7 @@
  	u32 temp;
  	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
-index a9031f494984..b54be4833ef7 100644
+index 0dc448630197..80b3124c43e2 100644
 --- a/drivers/usb/host/xhci.h
 +++ b/drivers/usb/host/xhci.h
 @@ -2070,6 +2070,7 @@ int xhci_halt(struct xhci_hcd *xhci);
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 01c12d3..8f6b290 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
@@ -119,6 +119,7 @@
     file://8006-phy-phy-mtk-tphy-add-support-efuse-setting.patch \
     file://8007-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch \
     file://8008-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch \
+    file://8009-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch \
     file://8010-ovs-support-flow-offload.patch \
     file://8010-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch \
     file://8011-ovs-add-multicast-to-unicast-support.patch \