[openwrt/openwrt] qualcommbe: update ipq9574 PCS driver

LEDE Commits lede-commits at lists.infradead.org
Sun Nov 30 07:51:19 PST 2025


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/95bd7a76a138d533c9b6b37bf91c4a006d94b22f

commit 95bd7a76a138d533c9b6b37bf91c4a006d94b22f
Author: Alexandru Gagniuc <mr.nuke.me at gmail.com>
AuthorDate: Thu Nov 6 21:52:11 2025 -0600

    qualcommbe: update ipq9574 PCS driver
    
    Update the ipq9574 PCS driver the version provided by Qualcomm via
    github. The updated driver simplifies link up handling by removing
    unnecessary clock rate changes.
    
    Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
    Link: https://github.com/openwrt/openwrt/pull/20993
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 ...m-ipq9574-Add-PCS-instantiation-and-phyli.patch |  17 +-
 ...m-ipq9574-remove-neg_mode-argument-from-i.patch |  29 --
 ...m-ipq9574-delay-mii-clock-probing-until-i.patch |  82 -----
 ...m-ipq9574-add-changes-not-submitted-upstr.patch | 362 ---------------------
 ...m64-dts-qcom-ipq9574-add-PCS-uniphy-nodes.patch |  30 +-
 ...-10GBASER-interface-mode-support-to-IPQ-U.patch |  94 +++---
 ...-2500BASEX-interface-mode-support-to-IPQ-.patch | 130 +++-----
 ...-1000BASEX-interface-mode-support-to-IPQ-.patch |  71 ++--
 ...-10G_QXGMII-interface-mode-support-to-IPQ.patch | 224 ++++++-------
 ...-uniphy-control-MISC2-register-for-2.5G-s.patch |  42 ++-
 ...-uniphy-keep-autoneg-enabled-in-SGMII-mod.patch |  25 --
 ...cs-ipq-uniphy-fix-USXGMII-link-up-failure.patch |   4 +-
 ...cs-qcom-ipq9574-Update-IPQ9574-PCS-driver.patch | 282 ++++++++++++++++
 13 files changed, 557 insertions(+), 835 deletions(-)

diff --git a/target/linux/qualcommbe/patches-6.12/0316-net-pcs-qcom-ipq9574-Add-PCS-instantiation-and-phyli.patch b/target/linux/qualcommbe/patches-6.12/0316-net-pcs-qcom-ipq9574-Add-PCS-instantiation-and-phyli.patch
index 1e7453a35c..7d071c2e25 100644
--- a/target/linux/qualcommbe/patches-6.12/0316-net-pcs-qcom-ipq9574-Add-PCS-instantiation-and-phyli.patch
+++ b/target/linux/qualcommbe/patches-6.12/0316-net-pcs-qcom-ipq9574-Add-PCS-instantiation-and-phyli.patch
@@ -1,4 +1,4 @@
-From 240ae5e0ca2ed858e25d7da6d5291d9c1f2c660a Mon Sep 17 00:00:00 2001
+From 10b609ddbf4d369c80098efa39451ef3973759b5 Mon Sep 17 00:00:00 2001
 From: Lei Wei <quic_leiwei at quicinc.com>
 Date: Fri, 7 Feb 2025 23:53:14 +0800
 Subject: [PATCH] net: pcs: qcom-ipq9574: Add PCS instantiation and phylink
@@ -14,10 +14,12 @@ MAC.
 c.) PCS phylink operations for SGMII/QSGMII interface modes.
 
 Signed-off-by: Lei Wei <quic_leiwei at quicinc.com>
+Alex G: remove phylink_pcs .neg_mode boolean
+Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 ---
- drivers/net/pcs/pcs-qcom-ipq9574.c   | 469 +++++++++++++++++++++++++++
+ drivers/net/pcs/pcs-qcom-ipq9574.c   | 468 +++++++++++++++++++++++++++
  include/linux/pcs/pcs-qcom-ipq9574.h |  15 +
- 2 files changed, 484 insertions(+)
+ 2 files changed, 483 insertions(+)
  create mode 100644 include/linux/pcs/pcs-qcom-ipq9574.h
 
 --- a/drivers/net/pcs/pcs-qcom-ipq9574.c
@@ -88,7 +90,7 @@ Signed-off-by: Lei Wei <quic_leiwei at quicinc.com>
  /* PCS private data */
  struct ipq_pcs {
  	struct device *dev;
-@@ -31,8 +77,359 @@ struct ipq_pcs {
+@@ -31,8 +77,358 @@ struct ipq_pcs {
  	struct clk_hw rx_hw;
  	/* TX clock supplied to NSSCC */
  	struct clk_hw tx_hw;
@@ -310,7 +312,7 @@ Signed-off-by: Lei Wei <quic_leiwei at quicinc.com>
 +	clk_disable_unprepare(qpcs_mii->tx_clk);
 +}
 +
-+static void ipq_pcs_get_state(struct phylink_pcs *pcs, unsigned int neg_mode,
++static void ipq_pcs_get_state(struct phylink_pcs *pcs,
 +			      struct phylink_link_state *state)
 +{
 +	struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs);
@@ -422,7 +424,6 @@ Signed-off-by: Lei Wei <quic_leiwei at quicinc.com>
 +		qpcs_mii->qpcs = qpcs;
 +		qpcs_mii->index = index;
 +		qpcs_mii->pcs.ops = &ipq_pcs_phylink_ops;
-+		qpcs_mii->pcs.neg_mode = true;
 +		qpcs_mii->pcs.poll = true;
 +
 +		qpcs_mii->rx_clk = devm_get_clk_from_child(dev, mii_np, "rx");
@@ -448,7 +449,7 @@ Signed-off-by: Lei Wei <quic_leiwei at quicinc.com>
  static unsigned long ipq_pcs_clk_rate_get(struct ipq_pcs *qpcs)
  {
  	switch (qpcs->interface) {
-@@ -219,6 +616,10 @@ static int ipq9574_pcs_probe(struct plat
+@@ -219,6 +615,10 @@ static int ipq9574_pcs_probe(struct plat
  	if (ret)
  		return ret;
  
@@ -459,7 +460,7 @@ Signed-off-by: Lei Wei <quic_leiwei at quicinc.com>
  	platform_set_drvdata(pdev, qpcs);
  
  	return 0;
-@@ -230,6 +631,74 @@ static const struct of_device_id ipq9574
+@@ -230,6 +630,74 @@ static const struct of_device_id ipq9574
  };
  MODULE_DEVICE_TABLE(of, ipq9574_pcs_of_mtable);
  
diff --git a/target/linux/qualcommbe/patches-6.12/0319-net-pcs-qcom-ipq9574-remove-neg_mode-argument-from-i.patch b/target/linux/qualcommbe/patches-6.12/0319-net-pcs-qcom-ipq9574-remove-neg_mode-argument-from-i.patch
deleted file mode 100644
index 6fc9652f08..0000000000
--- a/target/linux/qualcommbe/patches-6.12/0319-net-pcs-qcom-ipq9574-remove-neg_mode-argument-from-i.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From ffe2a80fb76ccdc1781f817f6bbc9a8aa919816e Mon Sep 17 00:00:00 2001
-From: Alexandru Gagniuc <mr.nuke.me at gmail.com>
-Date: Mon, 12 May 2025 09:11:05 -0500
-Subject: [PATCH] net: pcs: qcom-ipq9574: remove "neg_mode" argument from
- ipq_pcs_get_state
-
-Since commit c6739623c91bb ("net: phylink: pass neg_mode into
-.pcs_get_state() method"), the "neg_mode" parameter is part of the
-argument list of .pcs_get_state(). This is available starting with
-v6.14. However, we want to use the backported IPQ9574 driver on v6.12.
-Remove this parameter from ipq_pcs_get_state(), as it is not part of
-.pcs_get_state() in v6.12.
-
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -457,7 +457,7 @@ static void ipq_pcs_disable(struct phyli
- 	clk_disable_unprepare(qpcs_mii->tx_clk);
- }
- 
--static void ipq_pcs_get_state(struct phylink_pcs *pcs, unsigned int neg_mode,
-+static void ipq_pcs_get_state(struct phylink_pcs *pcs,
- 			      struct phylink_link_state *state)
- {
- 	struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs);
diff --git a/target/linux/qualcommbe/patches-6.12/0320-net-pcs-qcom-ipq9574-delay-mii-clock-probing-until-i.patch b/target/linux/qualcommbe/patches-6.12/0320-net-pcs-qcom-ipq9574-delay-mii-clock-probing-until-i.patch
deleted file mode 100644
index ac4c44a720..0000000000
--- a/target/linux/qualcommbe/patches-6.12/0320-net-pcs-qcom-ipq9574-delay-mii-clock-probing-until-i.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 5b2f02ccca7b9496f0a8da6ade063b82810c75e7 Mon Sep 17 00:00:00 2001
-From: Alexandru Gagniuc <mr.nuke.me at gmail.com>
-Date: Mon, 12 May 2025 09:27:17 -0500
-Subject: [PATCH] net: pcs: qcom-ipq9574: delay mii clock probing until
- ipq_pcs_get()
-
-NSSCC generates the SYS and AHB clocks for the PCS block The PCS then
-feeds the uniphy clocks back to the NSSCC, which are in turn, used to
-feed the PCS MII clocks. This works fine in hardware:
-
-    GCC -> NSSCC -> PCS -> NSSCC -> PCS(MII)
-
-However, when the PCS MII clocks are probed within the .probe() of
-the PCS block, it creates a circular dependency. The MII clocks depend
-on the uniphy clocks, which depend on the PCS block being probed.
-Since we are in the process of probing the PCS block, this results in
-both blocks returning with -EPROBE_DEFER:
-
-    platform 39b00000.clock-controller: deferred probe pending: platform: supplier 7a00000.ethernet-pcs not ready
-    mdio_bus 90000.mdio-1:18: deferred probe pending: mdio_bus: supplier 7a20000.ethernet-pcs not ready
-    mdio_bus 90000.mdio-1:00: deferred probe pending: mdio_bus: supplier 90000.mdio-1:18 not ready
-    mdio_bus 90000.mdio-1:01: deferred probe pending: mdio_bus: supplier 90000.mdio-1:18 not ready
-    mdio_bus 90000.mdio-1:02: deferred probe pending: mdio_bus: supplier 90000.mdio-1:18 not ready
-    mdio_bus 90000.mdio-1:03: deferred probe pending: mdio_bus: supplier 90000.mdio-1:18 not ready
-    platform 7a00000.ethernet-pcs: deferred probe pending: ipq9574_pcs: Failed to get MII 0 RX clock
-    platform 7a20000.ethernet-pcs: deferred probe pending: ipq9574_pcs: Failed to get MII 0 RX clock
-    platform 3a000000.qcom-ppe: deferred probe pending: platform: supplier 39b00000.clock-controller not ready
-
-To break this dependency, let the PCS block probe, and only probe the
-PCS MII clocks from ipq_pcs_get().
-
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c | 30 ++++++++++++++++--------------
- 1 file changed, 16 insertions(+), 14 deletions(-)
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -580,20 +580,6 @@ static int ipq_pcs_create_miis(struct ip
- 		qpcs_mii->pcs.neg_mode = true;
- 		qpcs_mii->pcs.poll = true;
- 
--		qpcs_mii->rx_clk = devm_get_clk_from_child(dev, mii_np, "rx");
--		if (IS_ERR(qpcs_mii->rx_clk)) {
--			of_node_put(mii_np);
--			return dev_err_probe(dev, PTR_ERR(qpcs_mii->rx_clk),
--					     "Failed to get MII %d RX clock\n", index);
--		}
--
--		qpcs_mii->tx_clk = devm_get_clk_from_child(dev, mii_np, "tx");
--		if (IS_ERR(qpcs_mii->tx_clk)) {
--			of_node_put(mii_np);
--			return dev_err_probe(dev, PTR_ERR(qpcs_mii->tx_clk),
--					     "Failed to get MII %d TX clock\n", index);
--		}
--
- 		qpcs->qpcs_mii[index] = qpcs_mii;
- 	}
- 
-@@ -848,6 +834,22 @@ struct phylink_pcs *ipq_pcs_get(struct d
- 		return ERR_PTR(-ENOENT);
- 	}
- 
-+	qpcs_mii->rx_clk = devm_get_clk_from_child(&pdev->dev, np, "rx");
-+	if (IS_ERR(qpcs_mii->rx_clk)) {
-+		put_device(&pdev->dev);
-+		return dev_err_ptr_probe(&pdev->dev, PTR_ERR(qpcs_mii->rx_clk),
-+					 "Failed to get MII %d RX clock\n",
-+					 index);
-+	}
-+
-+	qpcs_mii->tx_clk = devm_get_clk_from_child(&pdev->dev, np, "tx");
-+	if (IS_ERR(qpcs_mii->tx_clk)) {
-+		put_device(&pdev->dev);
-+		return dev_err_ptr_probe(&pdev->dev, PTR_ERR(qpcs_mii->tx_clk),
-+					 "Failed to get MII %d TX clock\n",
-+					 index);
-+	}
-+
- 	return &qpcs_mii->pcs;
- }
- EXPORT_SYMBOL(ipq_pcs_get);
diff --git a/target/linux/qualcommbe/patches-6.12/0321-net-pcs-qcom-ipq9574-add-changes-not-submitted-upstr.patch b/target/linux/qualcommbe/patches-6.12/0321-net-pcs-qcom-ipq9574-add-changes-not-submitted-upstr.patch
deleted file mode 100644
index 64a5bf6229..0000000000
--- a/target/linux/qualcommbe/patches-6.12/0321-net-pcs-qcom-ipq9574-add-changes-not-submitted-upstr.patch
+++ /dev/null
@@ -1,362 +0,0 @@
-From 7de372abe7a4b5b380fdbeedd268445f234990c8 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei at quicinc.com>
-Date: Mon, 29 Jan 2024 11:39:36 +0800
-Subject: [PATCH] net: pcs: qcom-ipq9574: add changes not submitted upstream
-
-Was ("net: pcs: Add driver for Qualcomm IPQ UNIPHY PCS").
-
-The UNIPHY hardware block in Qualcomm's IPQ SoC based boards enables
-PCS and XPCS functions, and helps in interfacing the Ethernet MAC in
-IPQ SoC to external PHYs.
-
-This patch adds the PCS driver support for the UNIPHY hardware used in
-IPQ SoC based boards. Support for SGMII/QSGMII/PSGMII and USXGMII
-interface modes are added in the driver.
-
-Change-Id: Id2c8f993f121098f7b02186b53770b75bb539a93
-Signed-off-by: Lei Wei <quic_leiwei at quicinc.com>
-Alex G: Rebase original patch on top of 20250207 uniphy submission
-        Remove mutex that is not required according to
-        https://lore.kernel.org/lkml/Z3ZwURgIErzpzpEr@shell.armlinux.org.uk/
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c      | 180 +++++++++++++++++++++++-
- include/linux/pcs/pcs-qcom-ipq-uniphy.h |  13 ++
- 2 files changed, 192 insertions(+), 1 deletion(-)
- create mode 100644 include/linux/pcs/pcs-qcom-ipq-uniphy.h
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -9,10 +9,12 @@
- #include <linux/of.h>
- #include <linux/of_platform.h>
- #include <linux/pcs/pcs-qcom-ipq9574.h>
-+#include <linux/pcs/pcs-qcom-ipq-uniphy.h>
- #include <linux/phy.h>
- #include <linux/phylink.h>
- #include <linux/platform_device.h>
- #include <linux/regmap.h>
-+#include <linux/reset.h>
- 
- #include <dt-bindings/net/qcom,ipq9574-pcs.h>
- 
-@@ -26,6 +28,7 @@
- #define PCS_MODE_SEL_MASK		GENMASK(12, 8)
- #define PCS_MODE_SGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
- #define PCS_MODE_QSGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x1)
-+#define PCS_MODE_PSGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x2)
- #define PCS_MODE_XPCS			FIELD_PREP(PCS_MODE_SEL_MASK, 0x10)
- 
- #define PCS_MII_CTRL(x)			(0x480 + 0x18 * (x))
-@@ -43,6 +46,8 @@
- #define PCS_MII_STS_SPEED_10		0
- #define PCS_MII_STS_SPEED_100		1
- #define PCS_MII_STS_SPEED_1000		2
-+#define PCS_MII_STS_PAUSE_TX_EN		BIT(1)
-+#define PCS_MII_STS_PAUSE_RX_EN		BIT(0)
- 
- #define PCS_PLL_RESET			0x780
- #define PCS_ANA_SW_RESET		BIT(6)
-@@ -95,12 +100,35 @@ struct ipq_pcs_mii {
- 	struct clk *tx_clk;
- };
- 
-+/* UNIPHY PCS reset ID */
-+enum {
-+	PCS_SYS_RESET,
-+	PCS_AHB_RESET,
-+	XPCS_RESET,
-+	PCS_RESET_MAX
-+};
-+
-+/* UNIPHY PCS reset name */
-+static const char *const pcs_reset_name[PCS_RESET_MAX] = {
-+	"sys",
-+	"ahb",
-+	"xpcs",
-+};
-+
-+/* UNIPHY PCS channel clock ID */
-+enum {
-+	PCS_CH_RX_CLK,
-+	PCS_CH_TX_CLK,
-+	PCS_CH_CLK_MAX
-+};
-+
- /* PCS private data */
- struct ipq_pcs {
- 	struct device *dev;
- 	void __iomem *base;
- 	struct regmap *regmap;
- 	phy_interface_t interface;
-+	struct reset_control *reset[PCS_RESET_MAX];
- 
- 	/* RX clock supplied to NSSCC */
- 	struct clk_hw rx_hw;
-@@ -150,6 +178,11 @@ static void ipq_pcs_get_state_sgmii(stru
- 		state->duplex = DUPLEX_FULL;
- 	else
- 		state->duplex = DUPLEX_HALF;
-+
-+	if (val & PCS_MII_STS_PAUSE_TX_EN)
-+		state->pause |= MLO_PAUSE_TX;
-+	if (val & PCS_MII_STS_PAUSE_RX_EN)
-+		state->pause |= MLO_PAUSE_RX;
- }
- 
- static void ipq_pcs_get_state_usxgmii(struct ipq_pcs *qpcs,
-@@ -203,6 +236,9 @@ static int ipq_pcs_config_mode(struct ip
- 	unsigned int val;
- 	int ret;
- 
-+	/* Assert XPCS reset */
-+	reset_control_assert(qpcs->reset[XPCS_RESET]);
-+
- 	/* Configure PCS interface mode */
- 	switch (interface) {
- 	case PHY_INTERFACE_MODE_SGMII:
-@@ -211,11 +247,16 @@ static int ipq_pcs_config_mode(struct ip
- 	case PHY_INTERFACE_MODE_QSGMII:
- 		val = PCS_MODE_QSGMII;
- 		break;
-+	case PHY_INTERFACE_MODE_PSGMII:
-+		val = PCS_MODE_PSGMII;
-+		break;
- 	case PHY_INTERFACE_MODE_USXGMII:
- 		val = PCS_MODE_XPCS;
- 		rate = 312500000;
- 		break;
- 	default:
-+		dev_err(qpcs->dev,
-+			"interface %s not supported\n", phy_modes(interface));
- 		return -EOPNOTSUPP;
- 	}
- 
-@@ -300,6 +341,9 @@ static int ipq_pcs_config_usxgmii(struct
- 	if (ret)
- 		return ret;
- 
-+	/* Deassert XPCS and configure XPCS USXGMII */
-+	reset_control_deassert(qpcs->reset[XPCS_RESET]);
-+
- 	ret = regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_USXG_EN);
- 	if (ret)
- 		return ret;
-@@ -311,6 +355,91 @@ static int ipq_pcs_config_usxgmii(struct
- 	return regmap_set_bits(qpcs->regmap, XPCS_MII_CTRL, XPCS_MII_AN_EN);
- }
- 
-+static unsigned long ipq_unipcs_clock_rate_get_gmii(int speed)
-+{
-+	unsigned long rate = 0;
-+
-+	switch (speed) {
-+	case SPEED_1000:
-+		rate = 125000000;
-+		break;
-+	case SPEED_100:
-+		rate = 25000000;
-+		break;
-+	case SPEED_10:
-+		rate = 2500000;
-+		break;
-+	default:
-+		break;
-+	}
-+
-+	return rate;
-+}
-+
-+static unsigned long ipq_unipcs_clock_rate_get_xgmii(int speed)
-+{
-+	unsigned long rate = 0;
-+
-+	switch (speed) {
-+	case SPEED_10000:
-+		rate = 312500000;
-+		break;
-+	case SPEED_5000:
-+		rate = 156250000;
-+		break;
-+	case SPEED_2500:
-+		rate = 78125000;
-+		break;
-+	case SPEED_1000:
-+		rate = 125000000;
-+		break;
-+	case SPEED_100:
-+		rate = 12500000;
-+		break;
-+	case SPEED_10:
-+		rate = 1250000;
-+		break;
-+	default:
-+		break;
-+	}
-+
-+	return rate;
-+}
-+
-+static void
-+ipq_unipcs_link_up_clock_rate_set(struct ipq_pcs_mii *qunipcs_ch,
-+				  phy_interface_t interface,
-+				  int speed)
-+{
-+	struct ipq_pcs *qpcs = qunipcs_ch->qpcs;
-+	unsigned long rate = 0;
-+
-+	switch (interface) {
-+	case PHY_INTERFACE_MODE_SGMII:
-+	case PHY_INTERFACE_MODE_QSGMII:
-+	case PHY_INTERFACE_MODE_PSGMII:
-+		rate = ipq_unipcs_clock_rate_get_gmii(speed);
-+		break;
-+	case PHY_INTERFACE_MODE_USXGMII:
-+		rate = ipq_unipcs_clock_rate_get_xgmii(speed);
-+		break;
-+	default:
-+		dev_err(qpcs->dev,
-+			"interface %s not supported\n", phy_modes(interface));
-+		return;
-+	}
-+
-+	if (rate == 0) {
-+		dev_err(qpcs->dev, "Invalid PCS clock rate\n");
-+		return;
-+	}
-+
-+	clk_set_rate(qunipcs_ch->rx_clk, rate);
-+	clk_set_rate(qunipcs_ch->tx_clk, rate);
-+
-+	fsleep(10000);
-+}
-+
- static int ipq_pcs_link_up_config_sgmii(struct ipq_pcs *qpcs,
- 					int index,
- 					unsigned int neg_mode,
-@@ -467,6 +596,7 @@ static void ipq_pcs_get_state(struct phy
- 	switch (state->interface) {
- 	case PHY_INTERFACE_MODE_SGMII:
- 	case PHY_INTERFACE_MODE_QSGMII:
-+	case PHY_INTERFACE_MODE_PSGMII:
- 		ipq_pcs_get_state_sgmii(qpcs, index, state);
- 		break;
- 	case PHY_INTERFACE_MODE_USXGMII:
-@@ -497,10 +627,13 @@ static int ipq_pcs_config(struct phylink
- 	switch (interface) {
- 	case PHY_INTERFACE_MODE_SGMII:
- 	case PHY_INTERFACE_MODE_QSGMII:
-+	case PHY_INTERFACE_MODE_PSGMII:
- 		return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface);
- 	case PHY_INTERFACE_MODE_USXGMII:
- 		return ipq_pcs_config_usxgmii(qpcs);
- 	default:
-+		dev_err(qpcs->dev,
-+			"interface %s not supported\n", phy_modes(interface));
- 		return -EOPNOTSUPP;
- 	};
- }
-@@ -515,9 +648,14 @@ static void ipq_pcs_link_up(struct phyli
- 	int index = qpcs_mii->index;
- 	int ret;
- 
-+	/* Configure PCS channel interface clock rate */
-+	ipq_unipcs_link_up_clock_rate_set(qpcs_mii, interface, speed);
-+
-+	/* Configure PCS speed and reset PCS adapter */
- 	switch (interface) {
- 	case PHY_INTERFACE_MODE_SGMII:
- 	case PHY_INTERFACE_MODE_QSGMII:
-+	case PHY_INTERFACE_MODE_PSGMII:
- 		ret = ipq_pcs_link_up_config_sgmii(qpcs, index,
- 						   neg_mode, speed);
- 		break;
-@@ -525,6 +663,8 @@ static void ipq_pcs_link_up(struct phyli
- 		ret = ipq_pcs_link_up_config_usxgmii(qpcs, speed);
- 		break;
- 	default:
-+		dev_err(qpcs->dev,
-+			"interface %s not supported\n", phy_modes(interface));
- 		return;
- 	}
- 
-@@ -735,12 +875,38 @@ static const struct regmap_config ipq_pc
- 	.fast_io = true,
- };
- 
-+/**
-+ * ipq_unipcs_create() - Create Qualcomm IPQ UNIPHY PCS
-+ * @np: Device tree node to the PCS
-+ *
-+ * Description: Create a phylink PCS instance for a PCS node @np.
-+ *
-+ * Return: A pointer to the phylink PCS instance or an error-pointer value.
-+ */
-+struct phylink_pcs *ipq_unipcs_create(struct device_node *np)
-+{
-+	return ipq_pcs_get(np);
-+}
-+EXPORT_SYMBOL(ipq_unipcs_create);
-+
-+/**
-+ * ipq_unipcs_destroy() - Destroy Qualcomm IPQ UNIPHY PCS
-+ * @pcs: PCS instance
-+ *
-+ * Description: Destroy a phylink PCS instance.
-+ */
-+void ipq_unipcs_destroy(struct phylink_pcs *pcs)
-+{
-+	ipq_pcs_put(pcs);
-+}
-+EXPORT_SYMBOL(ipq_unipcs_destroy);
-+
- static int ipq9574_pcs_probe(struct platform_device *pdev)
- {
- 	struct device *dev = &pdev->dev;
- 	struct ipq_pcs *qpcs;
- 	struct clk *clk;
--	int ret;
-+	int i, ret;
- 
- 	qpcs = devm_kzalloc(dev, sizeof(*qpcs), GFP_KERNEL);
- 	if (!qpcs)
-@@ -762,11 +928,23 @@ static int ipq9574_pcs_probe(struct plat
- 	if (IS_ERR(clk))
- 		return dev_err_probe(dev, PTR_ERR(clk),
- 				     "Failed to enable SYS clock\n");
-+	clk_set_rate(clk, 24000000);
- 
- 	clk = devm_clk_get_enabled(dev, "ahb");
- 	if (IS_ERR(clk))
- 		return dev_err_probe(dev, PTR_ERR(clk),
- 				     "Failed to enable AHB clock\n");
-+	clk_set_rate(clk, 100000000);
-+
-+	for (i = 0; i < PCS_RESET_MAX; i++) {
-+		qpcs->reset[i] =
-+			devm_reset_control_get_optional_exclusive(dev,
-+								  pcs_reset_name[i]);
-+
-+		if (IS_ERR(qpcs->reset[i]))
-+			dev_err(dev, "Failed to get the reset ID %s\n",
-+				pcs_reset_name[i]);
-+	}
- 
- 	ret = ipq_pcs_clk_register(qpcs);
- 	if (ret)
---- /dev/null
-+++ b/include/linux/pcs/pcs-qcom-ipq-uniphy.h
-@@ -0,0 +1,13 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ *
-+ */
-+
-+#ifndef __LINUX_PCS_QCOM_IPQ_UNIPHY_H
-+#define __LINUX_PCS_QCOM_IPQ_UNIPHY_H
-+
-+struct phylink_pcs *ipq_unipcs_create(struct device_node *np);
-+void ipq_unipcs_destroy(struct phylink_pcs *pcs);
-+
-+#endif /* __LINUX_PCS_QCOM_IPQ_UNIPHY_H */
diff --git a/target/linux/qualcommbe/patches-6.12/0322-arm64-dts-qcom-ipq9574-add-PCS-uniphy-nodes.patch b/target/linux/qualcommbe/patches-6.12/0322-arm64-dts-qcom-ipq9574-add-PCS-uniphy-nodes.patch
index 29c20a240a..8196ff601c 100644
--- a/target/linux/qualcommbe/patches-6.12/0322-arm64-dts-qcom-ipq9574-add-PCS-uniphy-nodes.patch
+++ b/target/linux/qualcommbe/patches-6.12/0322-arm64-dts-qcom-ipq9574-add-PCS-uniphy-nodes.patch
@@ -1,4 +1,4 @@
-From 8c02b6438167e1b73b908040c4ec3d4877c16f83 Mon Sep 17 00:00:00 2001
+From d6f184181b076cbb54f152994f5bc73ce524a67e Mon Sep 17 00:00:00 2001
 From: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 Date: Sun, 11 May 2025 18:21:00 -0500
 Subject: [PATCH] arm64: dts: qcom: ipq9574: add PCS uniphy nodes
@@ -11,8 +11,8 @@ feed back to the NSSCC node.
 
 Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 ---
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 116 ++++++++++++++++++++++++--
- 1 file changed, 110 insertions(+), 6 deletions(-)
+ arch/arm64/boot/dts/qcom/ipq9574.dtsi | 100 ++++++++++++++++++++++++--
+ 1 file changed, 94 insertions(+), 6 deletions(-)
 
 --- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
 +++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -43,7 +43,7 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
  				 <&gcc GCC_NSSCC_CLK>;
  			clock-names = "xo",
  				      "nss_1200",
-@@ -1269,6 +1270,109 @@
+@@ -1269,6 +1270,93 @@
  			#reset-cells = <1>;
  			#interconnect-cells = <1>;
  		};
@@ -57,13 +57,7 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 +				 <&gcc GCC_UNIPHY0_AHB_CLK>;
 +			clock-names = "sys",
 +				      "ahb";
-+			resets = <&gcc GCC_UNIPHY0_SYS_RESET>,
-+				 <&gcc GCC_UNIPHY0_AHB_RESET>,
-+				 <&gcc GCC_UNIPHY0_XPCS_RESET>;
-+			reset-names = "sys",
-+				      "ahb",
-+				      "xpcs";
-+
++			resets = <&gcc GCC_UNIPHY0_XPCS_RESET>;
 +			#clock-cells = <1>;
 +
 +			pcs0_ch0: pcs-mii at 0 {
@@ -108,12 +102,7 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 +				 <&gcc GCC_UNIPHY1_AHB_CLK>;
 +			clock-names = "sys",
 +				      "ahb";
-+			resets = <&gcc GCC_UNIPHY1_SYS_RESET>,
-+				 <&gcc GCC_UNIPHY1_AHB_RESET>,
-+				 <&gcc GCC_UNIPHY1_XPCS_RESET>;
-+			reset-names = "sys",
-+				      "ahb",
-+				      "xpcs";
++			resets = <&gcc GCC_UNIPHY1_XPCS_RESET>;
 +			#clock-cells = <1>;
 +
 +			pcs1_ch0: pcs-mii at 0 {
@@ -134,12 +123,7 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 +				 <&gcc GCC_UNIPHY2_AHB_CLK>;
 +			clock-names = "sys",
 +				      "ahb";
-+			resets = <&gcc GCC_UNIPHY2_SYS_RESET>,
-+				 <&gcc GCC_UNIPHY2_AHB_RESET>,
-+				 <&gcc GCC_UNIPHY2_XPCS_RESET>;
-+			reset-names = "sys",
-+				      "ahb",
-+				      "xpcs";
++			resets = <&gcc GCC_UNIPHY2_XPCS_RESET>;
 +			#clock-cells = <1>;
 +
 +			pcs2_ch0: pcs-mii at 0 {
diff --git a/target/linux/qualcommbe/patches-6.12/0361-net-pcs-Add-10GBASER-interface-mode-support-to-IPQ-U.patch b/target/linux/qualcommbe/patches-6.12/0361-net-pcs-Add-10GBASER-interface-mode-support-to-IPQ-U.patch
index 157f5b62c6..5bdf3e9299 100644
--- a/target/linux/qualcommbe/patches-6.12/0361-net-pcs-Add-10GBASER-interface-mode-support-to-IPQ-U.patch
+++ b/target/linux/qualcommbe/patches-6.12/0361-net-pcs-Add-10GBASER-interface-mode-support-to-IPQ-U.patch
@@ -1,4 +1,4 @@
-From e770b36f0353fd11c4628360fe412acb7f02f346 Mon Sep 17 00:00:00 2001
+From 432c2a2da1e0f4a8e2c0fea191361832a7f90f36 Mon Sep 17 00:00:00 2001
 From: Lei Wei <quic_leiwei at quicinc.com>
 Date: Wed, 6 Mar 2024 17:40:52 +0800
 Subject: [PATCH] net: pcs: Add 10GBASER interface mode support to IPQ UNIPHY
@@ -9,40 +9,41 @@ Subject: [PATCH] net: pcs: Add 10GBASER interface mode support to IPQ UNIPHY
 Change-Id: Ifc3c3bb23811807a9b34e88771aab2c830c2327c
 Signed-off-by: Lei Wei <quic_leiwei at quicinc.com>
 Alex G: Use regmap to read/write registers
+        Remove xpcs_reset deassert logic (to be implemented later)
 Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 ---
- drivers/net/pcs/pcs-qcom-ipq9574.c | 57 ++++++++++++++++++++++++++++++
- 1 file changed, 57 insertions(+)
+ drivers/net/pcs/pcs-qcom-ipq9574.c | 47 ++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
 
 --- a/drivers/net/pcs/pcs-qcom-ipq9574.c
 +++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -60,6 +60,9 @@
+@@ -55,6 +55,9 @@
  					 FIELD_PREP(GENMASK(9, 2), \
  					 FIELD_GET(XPCS_INDIRECT_ADDR_L, reg)))
  
-+#define XPCS_10GBASER_STS		0x30020
-+#define XPCS_10GBASER_LINK_STS		BIT(12)
++#define XPCS_KR_STS			0x30020
++#define XPCS_KR_LINK_STS		BIT(12)
 +
  #define XPCS_DIG_CTRL			0x38000
  #define XPCS_USXG_ADPT_RESET		BIT(10)
  #define XPCS_USXG_EN			BIT(9)
-@@ -229,6 +232,28 @@ static void ipq_pcs_get_state_usxgmii(st
+@@ -196,6 +199,28 @@ static void ipq_pcs_get_state_usxgmii(st
  	state->duplex = DUPLEX_FULL;
  }
  
-+static void ipq_unipcs_get_state_10gbaser(struct ipq_pcs *qpcs,
-+					  struct phylink_link_state *state)
++static void ipq_pcs_get_state_10gbaser(struct ipq_pcs *qpcs,
++				       struct phylink_link_state *state)
 +{
 +	unsigned int val;
 +	int ret;
 +
-+	ret = regmap_read(qpcs->regmap, XPCS_10GBASER_STS, &val);
++	ret = regmap_read(qpcs->regmap, XPCS_KR_STS, &val);
 +	if (ret) {
 +		state->link = 0;
 +		return;
 +	}
 +
-+	state->link = !!(val & XPCS_10GBASER_LINK_STS);
++	state->link = !!(val & XPCS_KR_LINK_STS);
 +
 +	if (!state->link)
 +		return;
@@ -55,49 +56,31 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
  static int ipq_pcs_config_mode(struct ipq_pcs *qpcs,
  			       phy_interface_t interface)
  {
-@@ -251,6 +276,7 @@ static int ipq_pcs_config_mode(struct ip
- 		val = PCS_MODE_PSGMII;
+@@ -212,6 +237,7 @@ static int ipq_pcs_config_mode(struct ip
+ 		val = PCS_MODE_QSGMII;
  		break;
  	case PHY_INTERFACE_MODE_USXGMII:
 +	case PHY_INTERFACE_MODE_10GBASER:
  		val = PCS_MODE_XPCS;
  		rate = 312500000;
  		break;
-@@ -355,6 +381,25 @@ static int ipq_pcs_config_usxgmii(struct
+@@ -311,6 +337,15 @@ static int ipq_pcs_config_usxgmii(struct
  	return regmap_set_bits(qpcs->regmap, XPCS_MII_CTRL, XPCS_MII_AN_EN);
  }
  
-+static int ipq_unipcs_config_10gbaser(struct ipq_pcs *qpcs,
-+				      phy_interface_t interface)
++static int ipq_pcs_config_10gbaser(struct ipq_pcs *qpcs)
 +{
-+	int ret;
-+
-+	if (qpcs->interface != interface) {
-+		ret = ipq_pcs_config_mode(qpcs, interface);
-+		if (ret)
-+			return ret;
-+
-+		/* Deassert XPCS */
-+		reset_control_deassert(qpcs->reset[XPCS_RESET]);
-+
-+		qpcs->interface = interface;
-+	}
++	/* Configure 10GBASER mode if required */
++	if (qpcs->interface == PHY_INTERFACE_MODE_10GBASER)
++		return 0;
 +
-+	return 0;
++	return ipq_pcs_config_mode(qpcs, PHY_INTERFACE_MODE_10GBASER);
 +}
 +
- static unsigned long ipq_unipcs_clock_rate_get_gmii(int speed)
- {
- 	unsigned long rate = 0;
-@@ -421,6 +466,7 @@ ipq_unipcs_link_up_clock_rate_set(struct
- 		rate = ipq_unipcs_clock_rate_get_gmii(speed);
- 		break;
- 	case PHY_INTERFACE_MODE_USXGMII:
-+	case PHY_INTERFACE_MODE_10GBASER:
- 		rate = ipq_unipcs_clock_rate_get_xgmii(speed);
- 		break;
- 	default:
-@@ -528,6 +574,7 @@ static int ipq_pcs_validate(struct phyli
+ static int ipq_pcs_link_up_config_sgmii(struct ipq_pcs *qpcs,
+ 					int index,
+ 					unsigned int neg_mode,
+@@ -399,6 +434,7 @@ static int ipq_pcs_validate(struct phyli
  	switch (state->interface) {
  	case PHY_INTERFACE_MODE_SGMII:
  	case PHY_INTERFACE_MODE_QSGMII:
@@ -105,44 +88,45 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
  		return 0;
  	case PHY_INTERFACE_MODE_USXGMII:
  		/* USXGMII only supports full duplex mode */
-@@ -546,6 +593,7 @@ static unsigned int ipq_pcs_inband_caps(
- 	case PHY_INTERFACE_MODE_SGMII:
+@@ -418,6 +454,8 @@ static unsigned int ipq_pcs_inband_caps(
  	case PHY_INTERFACE_MODE_QSGMII:
  	case PHY_INTERFACE_MODE_USXGMII:
-+	case PHY_INTERFACE_MODE_10GBASER:
  		return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
++	case PHY_INTERFACE_MODE_10GBASER:
++		return LINK_INBAND_DISABLE;
  	default:
  		return 0;
-@@ -602,6 +650,9 @@ static void ipq_pcs_get_state(struct phy
+ 	}
+@@ -472,6 +510,9 @@ static void ipq_pcs_get_state(struct phy
  	case PHY_INTERFACE_MODE_USXGMII:
  		ipq_pcs_get_state_usxgmii(qpcs, state);
  		break;
 +	case PHY_INTERFACE_MODE_10GBASER:
-+		ipq_unipcs_get_state_10gbaser(qpcs, state);
++		ipq_pcs_get_state_10gbaser(qpcs, state);
 +		break;
  	default:
  		break;
  	}
-@@ -631,6 +682,8 @@ static int ipq_pcs_config(struct phylink
+@@ -500,6 +541,8 @@ static int ipq_pcs_config(struct phylink
  		return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface);
  	case PHY_INTERFACE_MODE_USXGMII:
  		return ipq_pcs_config_usxgmii(qpcs);
 +	case PHY_INTERFACE_MODE_10GBASER:
-+		return ipq_unipcs_config_10gbaser(qpcs, interface);
++		return ipq_pcs_config_10gbaser(qpcs);
  	default:
- 		dev_err(qpcs->dev,
- 			"interface %s not supported\n", phy_modes(interface));
-@@ -662,6 +715,9 @@ static void ipq_pcs_link_up(struct phyli
+ 		return -EOPNOTSUPP;
+ 	};
+@@ -524,6 +567,9 @@ static void ipq_pcs_link_up(struct phyli
  	case PHY_INTERFACE_MODE_USXGMII:
  		ret = ipq_pcs_link_up_config_usxgmii(qpcs, speed);
  		break;
 +	case PHY_INTERFACE_MODE_10GBASER:
 +		/* Nothing to do here */
-+		break;
++		return;
  	default:
- 		dev_err(qpcs->dev,
- 			"interface %s not supported\n", phy_modes(interface));
-@@ -730,6 +786,7 @@ static unsigned long ipq_pcs_clk_rate_ge
+ 		return;
+ 	}
+@@ -603,6 +649,7 @@ static unsigned long ipq_pcs_clk_rate_ge
  {
  	switch (qpcs->interface) {
  	case PHY_INTERFACE_MODE_USXGMII:
diff --git a/target/linux/qualcommbe/patches-6.12/0362-net-pcs-Add-2500BASEX-interface-mode-support-to-IPQ-.patch b/target/linux/qualcommbe/patches-6.12/0362-net-pcs-Add-2500BASEX-interface-mode-support-to-IPQ-.patch
index dff74f0224..fbdebec13a 100644
--- a/target/linux/qualcommbe/patches-6.12/0362-net-pcs-Add-2500BASEX-interface-mode-support-to-IPQ-.patch
+++ b/target/linux/qualcommbe/patches-6.12/0362-net-pcs-Add-2500BASEX-interface-mode-support-to-IPQ-.patch
@@ -1,4 +1,4 @@
-From a2e687df29e457621616d5d769688e6c972f9ac6 Mon Sep 17 00:00:00 2001
+From 0d3a93e3a5544daec59d8f10ac5ccab39849536e Mon Sep 17 00:00:00 2001
 From: Lei Wei <quic_leiwei at quicinc.com>
 Date: Tue, 2 Apr 2024 18:28:42 +0800
 Subject: [PATCH] net: pcs: Add 2500BASEX interface mode support to IPQ UNIPHY
@@ -12,33 +12,33 @@ connects with a 2.5G SFP module.
 Change-Id: I3fe61113c1b3685debc20659736a9488216a029d
 Signed-off-by: Lei Wei <quic_leiwei at quicinc.com>
 Alex G: use regmap to read/write registers
+        's/ipq_unipcs/ipq_pcs/' in function names as suggested by Luo Jie
 Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 ---
- drivers/net/pcs/pcs-qcom-ipq9574.c | 95 ++++++++++++++++++++++++++++++
- 1 file changed, 95 insertions(+)
+ drivers/net/pcs/pcs-qcom-ipq9574.c | 67 ++++++++++++++++++++++++++++++
+ 1 file changed, 67 insertions(+)
 
 --- a/drivers/net/pcs/pcs-qcom-ipq9574.c
 +++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -29,6 +29,7 @@
+@@ -26,6 +26,7 @@
+ #define PCS_MODE_SEL_MASK		GENMASK(12, 8)
  #define PCS_MODE_SGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
  #define PCS_MODE_QSGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x1)
- #define PCS_MODE_PSGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x2)
-+#define PCS_MODE_SGMII_PLUS		FIELD_PREP(PCS_MODE_SEL_MASK, 0x8)
++#define PCS_MODE_2500BASEX		FIELD_PREP(PCS_MODE_SEL_MASK, 0x8)
  #define PCS_MODE_XPCS			FIELD_PREP(PCS_MODE_SEL_MASK, 0x10)
  
  #define PCS_MII_CTRL(x)			(0x480 + 0x18 * (x))
-@@ -188,6 +189,30 @@ static void ipq_pcs_get_state_sgmii(stru
- 		state->pause |= MLO_PAUSE_RX;
+@@ -155,6 +156,29 @@ static void ipq_pcs_get_state_sgmii(stru
+ 		state->duplex = DUPLEX_HALF;
  }
  
-+static void ipq_unipcs_get_state_2500basex(struct ipq_pcs *qpcs,
-+					   int index,
-+					   struct phylink_link_state *state)
++static void ipq_pcs_get_state_2500basex(struct ipq_pcs *qpcs,
++					struct phylink_link_state *state)
 +{
-+		unsigned int val;
++	unsigned int val;
 +	int ret;
 +
-+	ret = regmap_read(qpcs->regmap, PCS_MII_STS(index), &val);
++	ret = regmap_read(qpcs->regmap, PCS_MII_STS(0), &val);
 +	if (ret) {
 +		state->link = 0;
 +		return;
@@ -58,99 +58,57 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
  static void ipq_pcs_get_state_usxgmii(struct ipq_pcs *qpcs,
  				      struct phylink_link_state *state)
  {
-@@ -272,6 +297,10 @@ static int ipq_pcs_config_mode(struct ip
+@@ -236,6 +260,10 @@ static int ipq_pcs_config_mode(struct ip
  	case PHY_INTERFACE_MODE_QSGMII:
  		val = PCS_MODE_QSGMII;
  		break;
 +	case PHY_INTERFACE_MODE_2500BASEX:
-+		val = PCS_MODE_SGMII_PLUS;
++		val = PCS_MODE_2500BASEX;
 +		rate = 312500000;
 +		break;
- 	case PHY_INTERFACE_MODE_PSGMII:
- 		val = PCS_MODE_PSGMII;
- 		break;
-@@ -355,6 +384,22 @@ static int ipq_pcs_config_sgmii(struct i
+ 	case PHY_INTERFACE_MODE_USXGMII:
+ 	case PHY_INTERFACE_MODE_10GBASER:
+ 		val = PCS_MODE_XPCS;
+@@ -314,6 +342,15 @@ static int ipq_pcs_config_sgmii(struct i
  			       PCS_MII_CTRL(index), PCS_MII_FORCE_MODE);
  }
  
-+static int ipq_unipcs_config_2500basex(struct ipq_pcs *qpcs,
-+				       phy_interface_t interface)
++static int ipq_pcs_config_2500basex(struct ipq_pcs *qpcs)
 +{
-+	int ret;
-+
-+	if (qpcs->interface != interface) {
-+		ret = ipq_pcs_config_mode(qpcs, interface);
-+		if (ret)
-+			return ret;
-+
-+		qpcs->interface = interface;
-+	}
++	/* Configure PCS for 2500BASEX mode if required */
++	if (qpcs->interface == PHY_INTERFACE_MODE_2500BASEX)
++		return 0;
 +
-+	return 0;
++	return ipq_pcs_config_mode(qpcs, PHY_INTERFACE_MODE_2500BASEX);
 +}
 +
  static int ipq_pcs_config_usxgmii(struct ipq_pcs *qpcs)
  {
  	int ret;
-@@ -421,6 +466,21 @@ static unsigned long ipq_unipcs_clock_ra
- 	return rate;
- }
- 
-+static unsigned long ipq_unipcs_clock_rate_get_gmiiplus(int speed)
-+{
-+	unsigned long rate = 0;
-+
-+	switch (speed) {
-+	case SPEED_2500:
-+		rate = 312500000;
-+		break;
-+	default:
-+		break;
-+	}
-+
-+	return rate;
-+}
-+
- static unsigned long ipq_unipcs_clock_rate_get_xgmii(int speed)
- {
- 	unsigned long rate = 0;
-@@ -465,6 +525,9 @@ ipq_unipcs_link_up_clock_rate_set(struct
- 	case PHY_INTERFACE_MODE_PSGMII:
- 		rate = ipq_unipcs_clock_rate_get_gmii(speed);
- 		break;
-+	case PHY_INTERFACE_MODE_2500BASEX:
-+		rate = ipq_unipcs_clock_rate_get_gmiiplus(speed);
-+		break;
- 	case PHY_INTERFACE_MODE_USXGMII:
- 	case PHY_INTERFACE_MODE_10GBASER:
- 		rate = ipq_unipcs_clock_rate_get_xgmii(speed);
-@@ -528,6 +591,25 @@ static int ipq_pcs_link_up_config_sgmii(
+@@ -388,6 +425,22 @@ static int ipq_pcs_link_up_config_sgmii(
  			       PCS_MII_CTRL(index), PCS_MII_ADPT_RESET);
  }
  
-+static int ipq_unipcs_link_up_config_2500basex(struct ipq_pcs *qpcs,
-+						int index,
-+						int speed)
++static int ipq_pcs_link_up_config_2500basex(struct ipq_pcs *qpcs, int speed)
 +{
-+	unsigned int val;
 +	int ret;
 +
-+	/* 2500BASEX do not support autoneg and do not need to
-+	 * configure PCS speed, only reset PCS adapter here.
++	/* 2500BASEX does not support autoneg and does not need to
++	 * configure PCS speed. Only reset PCS adapter here.
 +	 */
 +	ret = regmap_clear_bits(qpcs->regmap,
-+				PCS_MII_CTRL(index), PCS_MII_ADPT_RESET);
++				PCS_MII_CTRL(0), PCS_MII_ADPT_RESET);
 +	if (ret)
 +		return ret;
 +
 +	return regmap_set_bits(qpcs->regmap,
-+			       PCS_MII_CTRL(index), PCS_MII_ADPT_RESET);
++			       PCS_MII_CTRL(0), PCS_MII_ADPT_RESET);
 +}
 +
  static int ipq_pcs_link_up_config_usxgmii(struct ipq_pcs *qpcs, int speed)
  {
  	unsigned int val;
-@@ -576,6 +658,10 @@ static int ipq_pcs_validate(struct phyli
+@@ -436,6 +489,10 @@ static int ipq_pcs_validate(struct phyli
  	case PHY_INTERFACE_MODE_QSGMII:
  	case PHY_INTERFACE_MODE_10GBASER:
  		return 0;
@@ -161,36 +119,44 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
  	case PHY_INTERFACE_MODE_USXGMII:
  		/* USXGMII only supports full duplex mode */
  		phylink_clear(supported, 100baseT_Half);
-@@ -647,6 +733,9 @@ static void ipq_pcs_get_state(struct phy
- 	case PHY_INTERFACE_MODE_PSGMII:
+@@ -454,6 +511,7 @@ static unsigned int ipq_pcs_inband_caps(
+ 	case PHY_INTERFACE_MODE_QSGMII:
+ 	case PHY_INTERFACE_MODE_USXGMII:
+ 		return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
++	case PHY_INTERFACE_MODE_2500BASEX:
+ 	case PHY_INTERFACE_MODE_10GBASER:
+ 		return LINK_INBAND_DISABLE;
+ 	default:
+@@ -507,6 +565,9 @@ static void ipq_pcs_get_state(struct phy
+ 	case PHY_INTERFACE_MODE_QSGMII:
  		ipq_pcs_get_state_sgmii(qpcs, index, state);
  		break;
 +	case PHY_INTERFACE_MODE_2500BASEX:
-+		ipq_unipcs_get_state_2500basex(qpcs, index, state);
++		ipq_pcs_get_state_2500basex(qpcs, state);
 +		break;
  	case PHY_INTERFACE_MODE_USXGMII:
  		ipq_pcs_get_state_usxgmii(qpcs, state);
  		break;
-@@ -680,6 +769,8 @@ static int ipq_pcs_config(struct phylink
+@@ -539,6 +600,8 @@ static int ipq_pcs_config(struct phylink
+ 	case PHY_INTERFACE_MODE_SGMII:
  	case PHY_INTERFACE_MODE_QSGMII:
- 	case PHY_INTERFACE_MODE_PSGMII:
  		return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface);
 +	case PHY_INTERFACE_MODE_2500BASEX:
-+		return ipq_unipcs_config_2500basex(qpcs, interface);
++		return ipq_pcs_config_2500basex(qpcs);
  	case PHY_INTERFACE_MODE_USXGMII:
  		return ipq_pcs_config_usxgmii(qpcs);
  	case PHY_INTERFACE_MODE_10GBASER:
-@@ -712,6 +803,9 @@ static void ipq_pcs_link_up(struct phyli
+@@ -564,6 +627,9 @@ static void ipq_pcs_link_up(struct phyli
  		ret = ipq_pcs_link_up_config_sgmii(qpcs, index,
  						   neg_mode, speed);
  		break;
 +	case PHY_INTERFACE_MODE_2500BASEX:
-+		ret = ipq_unipcs_link_up_config_2500basex(qpcs, index, speed);
++		ret = ipq_pcs_link_up_config_2500basex(qpcs, speed);
 +		break;
  	case PHY_INTERFACE_MODE_USXGMII:
  		ret = ipq_pcs_link_up_config_usxgmii(qpcs, speed);
  		break;
-@@ -785,6 +879,7 @@ static int ipq_pcs_create_miis(struct ip
+@@ -648,6 +714,7 @@ static int ipq_pcs_create_miis(struct ip
  static unsigned long ipq_pcs_clk_rate_get(struct ipq_pcs *qpcs)
  {
  	switch (qpcs->interface) {
diff --git a/target/linux/qualcommbe/patches-6.12/0363-net-pcs-Add-1000BASEX-interface-mode-support-to-IPQ-.patch b/target/linux/qualcommbe/patches-6.12/0363-net-pcs-Add-1000BASEX-interface-mode-support-to-IPQ-.patch
index 9c6bfabc45..37aa60d8ff 100644
--- a/target/linux/qualcommbe/patches-6.12/0363-net-pcs-Add-1000BASEX-interface-mode-support-to-IPQ-.patch
+++ b/target/linux/qualcommbe/patches-6.12/0363-net-pcs-Add-1000BASEX-interface-mode-support-to-IPQ-.patch
@@ -1,4 +1,4 @@
-From 07f9bb8eb006e9664d651089a1f422d045e093e3 Mon Sep 17 00:00:00 2001
+From d82953614a4f09dd7479e1d3904351ff85d1d088 Mon Sep 17 00:00:00 2001
 From: Lei Wei <quic_leiwei at quicinc.com>
 Date: Tue, 9 Apr 2024 01:07:22 +0800
 Subject: [PATCH] net: pcs: Add 1000BASEX interface mode support to IPQ UNIPHY
@@ -10,70 +10,75 @@ Change-Id: Ied7298de3c1ecba74e6457a07fdd6b3ceab79728
 Signed-off-by: Lei Wei <quic_leiwei at quicinc.com>
 Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 ---
- drivers/net/pcs/pcs-qcom-ipq9574.c | 19 +++++++++++++++++--
- 1 file changed, 17 insertions(+), 2 deletions(-)
+ drivers/net/pcs/pcs-qcom-ipq9574.c | 21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
 
 --- a/drivers/net/pcs/pcs-qcom-ipq9574.c
 +++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -31,6 +31,9 @@
- #define PCS_MODE_PSGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x2)
- #define PCS_MODE_SGMII_PLUS		FIELD_PREP(PCS_MODE_SEL_MASK, 0x8)
+@@ -28,6 +28,9 @@
+ #define PCS_MODE_QSGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x1)
+ #define PCS_MODE_2500BASEX		FIELD_PREP(PCS_MODE_SEL_MASK, 0x8)
  #define PCS_MODE_XPCS			FIELD_PREP(PCS_MODE_SEL_MASK, 0x10)
-+#define PCS_MODE_SGMII_CTRL_MASK	GENMASK(6, 4)
-+#define PCS_MODE_SGMII_CTRL_1000BASEX	FIELD_PREP(PCS_MODE_SGMII_CTRL_MASK, \
++#define PCS_MODE_SGMII_MODE_MASK	GENMASK(6, 4)
++#define PCS_MODE_SGMII_MODE_1000BASEX	FIELD_PREP(PCS_MODE_SGMII_MODE_MASK, \
 +						   0x0)
  
  #define PCS_MII_CTRL(x)			(0x480 + 0x18 * (x))
  #define PCS_MII_ADPT_RESET		BIT(11)
-@@ -283,7 +286,7 @@ static int ipq_pcs_config_mode(struct ip
+@@ -249,10 +252,11 @@ static int ipq_pcs_config_mode(struct ip
  			       phy_interface_t interface)
  {
  	unsigned long rate = 125000000;
 -	unsigned int val;
-+	unsigned int val, mask = PCS_MODE_SEL_MASK;
++	unsigned int val, mask;
  	int ret;
  
- 	/* Assert XPCS reset */
-@@ -297,6 +300,10 @@ static int ipq_pcs_config_mode(struct ip
+ 	/* Configure PCS interface mode */
++	mask = PCS_MODE_SEL_MASK;
+ 	switch (interface) {
+ 	case PHY_INTERFACE_MODE_SGMII:
+ 		val = PCS_MODE_SGMII;
+@@ -260,6 +264,10 @@ static int ipq_pcs_config_mode(struct ip
  	case PHY_INTERFACE_MODE_QSGMII:
  		val = PCS_MODE_QSGMII;
  		break;
 +	case PHY_INTERFACE_MODE_1000BASEX:
-+		mask |= PCS_MODE_SGMII_CTRL_MASK;
-+		val = PCS_MODE_SGMII | PCS_MODE_SGMII_CTRL_1000BASEX;
++		mask |= PCS_MODE_SGMII_MODE_MASK;
++		val = PCS_MODE_SGMII | PCS_MODE_SGMII_MODE_1000BASEX;
 +		break;
  	case PHY_INTERFACE_MODE_2500BASEX:
- 		val = PCS_MODE_SGMII_PLUS;
+ 		val = PCS_MODE_2500BASEX;
  		rate = 312500000;
-@@ -316,7 +323,7 @@ static int ipq_pcs_config_mode(struct ip
+@@ -273,8 +281,7 @@ static int ipq_pcs_config_mode(struct ip
+ 		return -EOPNOTSUPP;
  	}
  
- 	ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL,
+-	ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL,
 -				 PCS_MODE_SEL_MASK, val);
-+				 mask, val);
++	ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL, mask, val);
  	if (ret)
  		return ret;
  
-@@ -523,6 +530,7 @@ ipq_unipcs_link_up_clock_rate_set(struct
+@@ -487,6 +494,7 @@ static int ipq_pcs_validate(struct phyli
+ 	switch (state->interface) {
  	case PHY_INTERFACE_MODE_SGMII:
  	case PHY_INTERFACE_MODE_QSGMII:
- 	case PHY_INTERFACE_MODE_PSGMII:
 +	case PHY_INTERFACE_MODE_1000BASEX:
- 		rate = ipq_unipcs_clock_rate_get_gmii(speed);
- 		break;
+ 	case PHY_INTERFACE_MODE_10GBASER:
+ 		return 0;
  	case PHY_INTERFACE_MODE_2500BASEX:
-@@ -657,6 +665,7 @@ static int ipq_pcs_validate(struct phyli
+@@ -509,6 +517,7 @@ static unsigned int ipq_pcs_inband_caps(
+ 	switch (interface) {
  	case PHY_INTERFACE_MODE_SGMII:
  	case PHY_INTERFACE_MODE_QSGMII:
- 	case PHY_INTERFACE_MODE_10GBASER:
 +	case PHY_INTERFACE_MODE_1000BASEX:
- 		return 0;
+ 	case PHY_INTERFACE_MODE_USXGMII:
+ 		return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
  	case PHY_INTERFACE_MODE_2500BASEX:
- 		/* In-band autoneg is not supported for 2500BASEX */
-@@ -731,6 +740,10 @@ static void ipq_pcs_get_state(struct phy
+@@ -563,6 +572,10 @@ static void ipq_pcs_get_state(struct phy
+ 	switch (state->interface) {
  	case PHY_INTERFACE_MODE_SGMII:
  	case PHY_INTERFACE_MODE_QSGMII:
- 	case PHY_INTERFACE_MODE_PSGMII:
 +	case PHY_INTERFACE_MODE_1000BASEX:
 +		/* SGMII and 1000BASEX in-band autoneg word format are decoded
 +		 * by PCS hardware and both placed to the same status register.
@@ -81,18 +86,18 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
  		ipq_pcs_get_state_sgmii(qpcs, index, state);
  		break;
  	case PHY_INTERFACE_MODE_2500BASEX:
-@@ -768,6 +781,7 @@ static int ipq_pcs_config(struct phylink
+@@ -599,6 +612,7 @@ static int ipq_pcs_config(struct phylink
+ 	switch (interface) {
  	case PHY_INTERFACE_MODE_SGMII:
  	case PHY_INTERFACE_MODE_QSGMII:
- 	case PHY_INTERFACE_MODE_PSGMII:
 +	case PHY_INTERFACE_MODE_1000BASEX:
  		return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface);
  	case PHY_INTERFACE_MODE_2500BASEX:
- 		return ipq_unipcs_config_2500basex(qpcs, interface);
-@@ -800,6 +814,7 @@ static void ipq_pcs_link_up(struct phyli
+ 		return ipq_pcs_config_2500basex(qpcs);
+@@ -624,6 +638,7 @@ static void ipq_pcs_link_up(struct phyli
+ 	switch (interface) {
  	case PHY_INTERFACE_MODE_SGMII:
  	case PHY_INTERFACE_MODE_QSGMII:
- 	case PHY_INTERFACE_MODE_PSGMII:
 +	case PHY_INTERFACE_MODE_1000BASEX:
  		ret = ipq_pcs_link_up_config_sgmii(qpcs, index,
  						   neg_mode, speed);
diff --git a/target/linux/qualcommbe/patches-6.12/0364-net-pcs-Add-10G_QXGMII-interface-mode-support-to-IPQ.patch b/target/linux/qualcommbe/patches-6.12/0364-net-pcs-Add-10G_QXGMII-interface-mode-support-to-IPQ.patch
index 03fa4dffef..2563ac8396 100644
--- a/target/linux/qualcommbe/patches-6.12/0364-net-pcs-Add-10G_QXGMII-interface-mode-support-to-IPQ.patch
+++ b/target/linux/qualcommbe/patches-6.12/0364-net-pcs-Add-10G_QXGMII-interface-mode-support-to-IPQ.patch
@@ -1,4 +1,4 @@
-From 77462c0d74e51a24408062b93c3fcc0256909d33 Mon Sep 17 00:00:00 2001
+From fc26c6f6c69149ce87c88d6878ae929b2a138063 Mon Sep 17 00:00:00 2001
 From: Lei Wei <quic_leiwei at quicinc.com>
 Date: Mon, 15 Apr 2024 11:06:02 +0800
 Subject: [PATCH] net: pcs: Add 10G_QXGMII interface mode support to IPQ UNIPHY
@@ -11,14 +11,14 @@ Change-Id: If3dc92a07ac3e51f7c9473fb05fa0668617916fb
 Signed-off-by: Lei Wei <quic_leiwei at quicinc.com>
 Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 ---
- drivers/net/pcs/pcs-qcom-ipq9574.c | 112 +++++++++++++++++++++++------
- 1 file changed, 91 insertions(+), 21 deletions(-)
+ drivers/net/pcs/pcs-qcom-ipq9574.c | 109 +++++++++++++++++++++++------
+ 1 file changed, 87 insertions(+), 22 deletions(-)
 
 --- a/drivers/net/pcs/pcs-qcom-ipq9574.c
 +++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -53,6 +53,9 @@
- #define PCS_MII_STS_PAUSE_TX_EN		BIT(1)
- #define PCS_MII_STS_PAUSE_RX_EN		BIT(0)
+@@ -48,6 +48,9 @@
+ #define PCS_MII_STS_SPEED_100		1
+ #define PCS_MII_STS_SPEED_1000		2
  
 +#define PCS_QP_USXG_OPTION		0x584
 +#define PCS_QP_USXG_GMII_SRC_XPCS	BIT(0)
@@ -26,8 +26,8 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
  #define PCS_PLL_RESET			0x780
  #define PCS_ANA_SW_RESET		BIT(6)
  
-@@ -68,10 +71,22 @@
- #define XPCS_10GBASER_LINK_STS		BIT(12)
+@@ -63,10 +66,23 @@
+ #define XPCS_KR_LINK_STS		BIT(12)
  
  #define XPCS_DIG_CTRL			0x38000
 +#define XPCS_SOFT_RESET			BIT(15)
@@ -41,82 +41,89 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 +#define XPCS_DIG_STS			0x3800a
 +#define XPCS_DIG_STS_AM_COUNT		GENMASK(14, 0)
 +
-+#define XPCS_CHANNEL_DIG_CTRL(x)	(0x1a8000 + 0x10000 * ((x) - 1))
-+#define XPCS_CHANNEL_USXG_ADPT_RESET	BIT(5)
++/* DIG control for MII1 - MII3 */
++#define XPCS_MII1_DIG_CTRL(x)		(0x1a8000 + 0x10000 * ((x) - 1))
++#define XPCS_MII1_USXG_ADPT_RESET	BIT(5)
 +
  #define XPCS_MII_CTRL			0x1f0000
-+#define XPCS_CHANNEL_MII_CTRL(x)	(0x1a0000 + 0x10000 * ((x) - 1))
++#define XPCS_MII1_CTRL(x)		(0x1a0000 + 0x10000 * ((x) - 1))
  #define XPCS_MII_AN_EN			BIT(12)
  #define XPCS_DUPLEX_FULL		BIT(8)
  #define XPCS_SPEED_MASK			(BIT(13) | BIT(6) | BIT(5))
-@@ -83,9 +98,11 @@
+@@ -78,9 +94,11 @@
  #define XPCS_SPEED_10			0
  
  #define XPCS_MII_AN_CTRL		0x1f8001
-+#define XPCS_CHANNEL_MII_AN_CTRL(x)	(0x1a8001 + 0x10000 * ((x) - 1))
++#define XPCS_MII1_AN_CTRL(x)		(0x1a8001 + 0x10000 * ((x) - 1))
  #define XPCS_MII_AN_8BIT		BIT(8)
  
  #define XPCS_MII_AN_INTR_STS		0x1f8002
-+#define XPCS_CHANNEL_MII_AN_INTR_STS(x)	(0x1a8002 + 0x10000 * ((x) - 1))
++#define XPCS_MII1_AN_INTR_STS(x)	(0x1a8002 + 0x10000 * ((x) - 1))
  #define XPCS_USXG_AN_LINK_STS		BIT(14)
  #define XPCS_USXG_AN_SPEED_MASK		GENMASK(12, 10)
  #define XPCS_USXG_AN_SPEED_10		0
-@@ -95,6 +112,10 @@
+@@ -90,6 +108,10 @@
  #define XPCS_USXG_AN_SPEED_5000		5
  #define XPCS_USXG_AN_SPEED_10000	3
  
 +#define XPCS_XAUI_MODE_CTRL		0x1f8004
-+#define XPCS_CHANNEL_XAUI_MODE_CTRL(x)	(0x1a8004 + 0x10000 * ((x) - 1))
++#define XPCS_MII1_XAUI_MODE_CTRL(x)	(0x1a8004 + 0x10000 * ((x) - 1))
 +#define XPCS_TX_IPG_CHECK_DIS		BIT(0)
 +
  /* Per PCS MII private data */
  struct ipq_pcs_mii {
  	struct ipq_pcs *qpcs;
-@@ -217,12 +238,16 @@ static void ipq_unipcs_get_state_2500bas
+@@ -182,13 +204,14 @@ static void ipq_pcs_get_state_2500basex(
+ 	state->pause |= MLO_PAUSE_TXRX_MASK;
  }
  
- static void ipq_pcs_get_state_usxgmii(struct ipq_pcs *qpcs,
-+				      int index,
+-static void ipq_pcs_get_state_usxgmii(struct ipq_pcs *qpcs,
++static void ipq_pcs_get_state_usxgmii(struct ipq_pcs *qpcs, int index,
  				      struct phylink_link_state *state)
  {
- 	unsigned int val;
--	int ret;
-+	int ret, reg;
-+
-+	reg = (index == 0) ? XPCS_MII_AN_INTR_STS :
-+			     XPCS_CHANNEL_MII_AN_INTR_STS(index);
+-	unsigned int val;
++	unsigned int reg, val;
+ 	int ret;
  
 -	ret = regmap_read(qpcs->regmap, XPCS_MII_AN_INTR_STS, &val);
++	reg = (index == 0) ? XPCS_MII_AN_INTR_STS : XPCS_MII1_AN_INTR_STS(index);
 +	ret = regmap_read(qpcs->regmap, reg, &val);
  	if (ret) {
  		state->link = 0;
  		return;
-@@ -316,6 +341,14 @@ static int ipq_pcs_config_mode(struct ip
- 		val = PCS_MODE_XPCS;
+@@ -273,6 +296,7 @@ static int ipq_pcs_config_mode(struct ip
  		rate = 312500000;
  		break;
+ 	case PHY_INTERFACE_MODE_USXGMII:
 +	case PHY_INTERFACE_MODE_10G_QXGMII:
-+		val = PCS_MODE_XPCS;
-+		rate = 312500000;
+ 	case PHY_INTERFACE_MODE_10GBASER:
+ 		val = PCS_MODE_XPCS;
+ 		rate = 312500000;
+@@ -285,6 +309,13 @@ static int ipq_pcs_config_mode(struct ip
+ 	if (ret)
+ 		return ret;
+ 
++	if (interface == PHY_INTERFACE_MODE_10G_QXGMII) {
 +		ret = regmap_set_bits(qpcs->regmap, PCS_QP_USXG_OPTION,
 +				      PCS_QP_USXG_GMII_SRC_XPCS);
 +		if (ret)
 +			return ret;
-+		break;
- 	default:
- 		dev_err(qpcs->dev,
- 			"interface %s not supported\n", phy_modes(interface));
-@@ -407,30 +440,55 @@ static int ipq_unipcs_config_2500basex(s
- 	return 0;
++	}
++
+ 	/* PCS PLL reset */
+ 	ret = regmap_clear_bits(qpcs->regmap, PCS_PLL_RESET, PCS_ANA_SW_RESET);
+ 	if (ret)
+@@ -358,27 +389,51 @@ static int ipq_pcs_config_2500basex(stru
+ 	return ipq_pcs_config_mode(qpcs, PHY_INTERFACE_MODE_2500BASEX);
  }
  
 -static int ipq_pcs_config_usxgmii(struct ipq_pcs *qpcs)
 +static int ipq_pcs_config_usxgmii(struct ipq_pcs *qpcs,
-+				     int index,
-+				     phy_interface_t interface)
++				  int index,
++				  phy_interface_t interface)
  {
--	int ret;
-+	int ret, reg;
++	unsigned int reg;
+ 	int ret;
  
  	/* Configure the XPCS for USXGMII mode if required */
 -	if (qpcs->interface == PHY_INTERFACE_MODE_USXGMII)
@@ -129,87 +136,66 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 +		ret = ipq_pcs_config_mode(qpcs, interface);
 +		if (ret)
 +			return ret;
-+	}
- 
--	/* Deassert XPCS and configure XPCS USXGMII */
-+	/* Deassert XPCS and configure XPCS USXGMII or 10G_QXGMII */
- 	reset_control_deassert(qpcs->reset[XPCS_RESET]);
- 
- 	ret = regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_USXG_EN);
- 	if (ret)
- 		return ret;
  
--	ret = regmap_set_bits(qpcs->regmap, XPCS_MII_AN_CTRL, XPCS_MII_AN_8BIT);
-+	if (interface == PHY_INTERFACE_MODE_10G_QXGMII) {
-+		regmap_update_bits(qpcs->regmap, XPCS_KR_CTRL,
-+				   XPCS_USXG_MODE_MASK, XPCS_10G_QXGMII_MODE);
+-	ret = regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_USXG_EN);
+-	if (ret)
+-		return ret;
++		if (interface == PHY_INTERFACE_MODE_10G_QXGMII) {
++			ret = regmap_update_bits(qpcs->regmap, XPCS_KR_CTRL,
++						 XPCS_USXG_MODE_MASK, XPCS_10G_QXGMII_MODE);
++			if (ret)
++				return ret;
 +
-+		/* Set Alignment Marker Interval */
-+		regmap_update_bits(qpcs->regmap, XPCS_DIG_STS,
-+				   XPCS_DIG_STS_AM_COUNT, 0x6018);
++			/* Set Alignment Marker Interval value as 0x6018 */
++			ret = regmap_update_bits(qpcs->regmap, XPCS_DIG_STS,
++						 XPCS_DIG_STS_AM_COUNT, 0x6018);
++			if (ret)
++				return ret;
 +
-+		regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_SOFT_RESET);
++			ret = regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_SOFT_RESET);
++			if (ret)
++				return ret;
 +	}
 +
-+	qpcs->interface = interface;
-+
 +	/* Disable Tx IPG check for 10G_QXGMII */
 +	if (interface == PHY_INTERFACE_MODE_10G_QXGMII) {
-+		reg = (index == 0) ? XPCS_XAUI_MODE_CTRL :
-+			XPCS_CHANNEL_XAUI_MODE_CTRL(index);
-+
-+		regmap_set_bits(qpcs->regmap, reg, XPCS_TX_IPG_CHECK_DIS);
++		reg = (index == 0) ? XPCS_XAUI_MODE_CTRL : XPCS_MII1_XAUI_MODE_CTRL(index);
++		ret = regmap_set_bits(qpcs->regmap, reg, XPCS_TX_IPG_CHECK_DIS);
++		if (ret)
++			return ret;
 +	}
-+
-+	/* Enable autoneg */
-+	reg = (index == 0) ? XPCS_MII_AN_CTRL : XPCS_CHANNEL_MII_AN_CTRL(index);
+ 
+-	ret = regmap_set_bits(qpcs->regmap, XPCS_MII_AN_CTRL, XPCS_MII_AN_8BIT);
++	reg = (index == 0) ? XPCS_MII_AN_CTRL : XPCS_MII1_AN_CTRL(index);
 +	ret = regmap_set_bits(qpcs->regmap, reg, XPCS_MII_AN_8BIT);
  	if (ret)
  		return ret;
  
 -	return regmap_set_bits(qpcs->regmap, XPCS_MII_CTRL, XPCS_MII_AN_EN);
-+	reg = (index == 0) ? XPCS_MII_CTRL : XPCS_CHANNEL_MII_CTRL(index);
++	reg = (index == 0) ? XPCS_MII_CTRL : XPCS_MII1_CTRL(index);
 +	return regmap_set_bits(qpcs->regmap, reg, XPCS_MII_AN_EN);
  }
  
- static int ipq_unipcs_config_10gbaser(struct ipq_pcs *qpcs,
-@@ -538,6 +596,7 @@ ipq_unipcs_link_up_clock_rate_set(struct
- 		break;
- 	case PHY_INTERFACE_MODE_USXGMII:
- 	case PHY_INTERFACE_MODE_10GBASER:
-+	case PHY_INTERFACE_MODE_10G_QXGMII:
- 		rate = ipq_unipcs_clock_rate_get_xgmii(speed);
- 		break;
- 	default:
-@@ -603,7 +662,6 @@ static int ipq_unipcs_link_up_config_250
- 						int index,
- 						int speed)
- {
--	unsigned int val;
- 	int ret;
- 
- 	/* 2500BASEX do not support autoneg and do not need to
-@@ -618,10 +676,12 @@ static int ipq_unipcs_link_up_config_250
- 			       PCS_MII_CTRL(index), PCS_MII_ADPT_RESET);
+ static int ipq_pcs_config_10gbaser(struct ipq_pcs *qpcs)
+@@ -448,9 +503,10 @@ static int ipq_pcs_link_up_config_2500ba
+ 			       PCS_MII_CTRL(0), PCS_MII_ADPT_RESET);
  }
  
 -static int ipq_pcs_link_up_config_usxgmii(struct ipq_pcs *qpcs, int speed)
 +static int ipq_pcs_link_up_config_usxgmii(struct ipq_pcs *qpcs,
-+					      int channel,
-+					      int speed)
++					  int index, int speed)
  {
- 	unsigned int val;
--	int ret;
-+	int ret, reg;
+-	unsigned int val;
++	unsigned int reg, val;
+ 	int ret;
  
  	switch (speed) {
- 	case SPEED_10000:
-@@ -648,14 +708,19 @@ static int ipq_pcs_link_up_config_usxgmi
+@@ -478,14 +534,17 @@ static int ipq_pcs_link_up_config_usxgmi
  	}
  
  	/* Configure XPCS speed */
 -	ret = regmap_update_bits(qpcs->regmap, XPCS_MII_CTRL,
-+	reg = (channel == 0) ? XPCS_MII_CTRL : XPCS_CHANNEL_MII_CTRL(channel);
++	reg = (index == 0) ? XPCS_MII_CTRL : XPCS_MII1_CTRL(index);
 +	ret = regmap_update_bits(qpcs->regmap, reg,
  				 XPCS_SPEED_MASK, val | XPCS_DUPLEX_FULL);
  	if (ret)
@@ -217,25 +203,32 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
  
  	/* XPCS adapter reset */
 -	return regmap_set_bits(qpcs->regmap,
-+	if (channel == 0)
-+		return regmap_set_bits(qpcs->regmap,
- 			       XPCS_DIG_CTRL, XPCS_USXG_ADPT_RESET);
-+	else
-+		return regmap_set_bits(qpcs->regmap, XPCS_CHANNEL_DIG_CTRL(channel),
-+					XPCS_CHANNEL_USXG_ADPT_RESET);
+-			       XPCS_DIG_CTRL, XPCS_USXG_ADPT_RESET);
++	reg = (index == 0) ? XPCS_DIG_CTRL : XPCS_MII1_DIG_CTRL(index);
++	val = (index == 0) ? XPCS_USXG_ADPT_RESET : XPCS_MII1_USXG_ADPT_RESET;
++	return regmap_set_bits(qpcs->regmap, reg, val);
++
  }
  
  static int ipq_pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
-@@ -671,6 +736,7 @@ static int ipq_pcs_validate(struct phyli
- 		/* In-band autoneg is not supported for 2500BASEX */
+@@ -502,6 +561,7 @@ static int ipq_pcs_validate(struct phyli
  		phylink_clear(supported, Autoneg);
  		return 0;
-+	case PHY_INTERFACE_MODE_10G_QXGMII:
  	case PHY_INTERFACE_MODE_USXGMII:
++	case PHY_INTERFACE_MODE_10G_QXGMII:
  		/* USXGMII only supports full duplex mode */
  		phylink_clear(supported, 100baseT_Half);
-@@ -750,7 +816,8 @@ static void ipq_pcs_get_state(struct phy
- 		ipq_unipcs_get_state_2500basex(qpcs, index, state);
+ 		phylink_clear(supported, 10baseT_Half);
+@@ -519,6 +579,7 @@ static unsigned int ipq_pcs_inband_caps(
+ 	case PHY_INTERFACE_MODE_QSGMII:
+ 	case PHY_INTERFACE_MODE_1000BASEX:
+ 	case PHY_INTERFACE_MODE_USXGMII:
++	case PHY_INTERFACE_MODE_10G_QXGMII:
+ 		return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
+ 	case PHY_INTERFACE_MODE_2500BASEX:
+ 	case PHY_INTERFACE_MODE_10GBASER:
+@@ -582,7 +643,8 @@ static void ipq_pcs_get_state(struct phy
+ 		ipq_pcs_get_state_2500basex(qpcs, state);
  		break;
  	case PHY_INTERFACE_MODE_USXGMII:
 -		ipq_pcs_get_state_usxgmii(qpcs, state);
@@ -243,20 +236,19 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 +		ipq_pcs_get_state_usxgmii(qpcs, index, state);
  		break;
  	case PHY_INTERFACE_MODE_10GBASER:
- 		ipq_unipcs_get_state_10gbaser(qpcs, state);
-@@ -786,7 +853,9 @@ static int ipq_pcs_config(struct phylink
+ 		ipq_pcs_get_state_10gbaser(qpcs, state);
+@@ -617,7 +679,8 @@ static int ipq_pcs_config(struct phylink
  	case PHY_INTERFACE_MODE_2500BASEX:
- 		return ipq_unipcs_config_2500basex(qpcs, interface);
+ 		return ipq_pcs_config_2500basex(qpcs);
  	case PHY_INTERFACE_MODE_USXGMII:
 -		return ipq_pcs_config_usxgmii(qpcs);
 +	case PHY_INTERFACE_MODE_10G_QXGMII:
-+		return ipq_pcs_config_usxgmii(qpcs, index,
-+					      interface);
++		return ipq_pcs_config_usxgmii(qpcs, index, interface);
  	case PHY_INTERFACE_MODE_10GBASER:
- 		return ipq_unipcs_config_10gbaser(qpcs, interface);
+ 		return ipq_pcs_config_10gbaser(qpcs);
  	default:
-@@ -822,7 +891,8 @@ static void ipq_pcs_link_up(struct phyli
- 		ret = ipq_unipcs_link_up_config_2500basex(qpcs, index, speed);
+@@ -646,7 +709,8 @@ static void ipq_pcs_link_up(struct phyli
+ 		ret = ipq_pcs_link_up_config_2500basex(qpcs, speed);
  		break;
  	case PHY_INTERFACE_MODE_USXGMII:
 -		ret = ipq_pcs_link_up_config_usxgmii(qpcs, speed);
@@ -265,3 +257,11 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
  		break;
  	case PHY_INTERFACE_MODE_10GBASER:
  		/* Nothing to do here */
+@@ -731,6 +795,7 @@ static unsigned long ipq_pcs_clk_rate_ge
+ 	switch (qpcs->interface) {
+ 	case PHY_INTERFACE_MODE_2500BASEX:
+ 	case PHY_INTERFACE_MODE_USXGMII:
++	case PHY_INTERFACE_MODE_10G_QXGMII:
+ 	case PHY_INTERFACE_MODE_10GBASER:
+ 		return 312500000;
+ 	default:
diff --git a/target/linux/qualcommbe/patches-6.12/0365-net-pcs-ipq-uniphy-control-MISC2-register-for-2.5G-s.patch b/target/linux/qualcommbe/patches-6.12/0365-net-pcs-ipq-uniphy-control-MISC2-register-for-2.5G-s.patch
index b34dd837ab..6ec8f2634e 100644
--- a/target/linux/qualcommbe/patches-6.12/0365-net-pcs-ipq-uniphy-control-MISC2-register-for-2.5G-s.patch
+++ b/target/linux/qualcommbe/patches-6.12/0365-net-pcs-ipq-uniphy-control-MISC2-register-for-2.5G-s.patch
@@ -1,8 +1,7 @@
-From 930203b9bb94dc4ea9342f1ce176851918758ed7 Mon Sep 17 00:00:00 2001
+From 87da3bbd25eb0a17e2c698120528e76c26b326d0 Mon Sep 17 00:00:00 2001
 From: Mantas Pucka <mantas at 8devices.com>
 Date: Mon, 2 Jun 2025 17:18:13 +0300
-Subject: [PATCH] net: pcs: ipq-uniphy: control MISC2 register for 2.5G 
- support
+Subject: [PATCH] net: pcs: ipq-uniphy: control MISC2 register for 2.5G support
 
 When 2500base-x mode is enabled MISC2 regsister needs to have different
 value than for other 1G modes.
@@ -14,7 +13,7 @@ Signed-off-by: Mantas Pucka <mantas at 8devices.com>
 
 --- a/drivers/net/pcs/pcs-qcom-ipq9574.c
 +++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -24,6 +24,11 @@
+@@ -22,6 +22,11 @@
  #define PCS_CALIBRATION			0x1e0
  #define PCS_CALIBRATION_DONE		BIT(7)
  
@@ -26,16 +25,16 @@ Signed-off-by: Mantas Pucka <mantas at 8devices.com>
  #define PCS_MODE_CTRL			0x46c
  #define PCS_MODE_SEL_MASK		GENMASK(12, 8)
  #define PCS_MODE_SGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
-@@ -311,7 +316,7 @@ static int ipq_pcs_config_mode(struct ip
+@@ -275,7 +280,7 @@ static int ipq_pcs_config_mode(struct ip
  			       phy_interface_t interface)
  {
  	unsigned long rate = 125000000;
--	unsigned int val, mask = PCS_MODE_SEL_MASK;
-+	unsigned int val, misc2 = 0, mask = PCS_MODE_SEL_MASK;
+-	unsigned int val, mask;
++	unsigned int val, mask, misc2 = 0;
  	int ret;
  
- 	/* Assert XPCS reset */
-@@ -321,6 +326,7 @@ static int ipq_pcs_config_mode(struct ip
+ 	/* Configure PCS interface mode */
+@@ -283,6 +288,7 @@ static int ipq_pcs_config_mode(struct ip
  	switch (interface) {
  	case PHY_INTERFACE_MODE_SGMII:
  		val = PCS_MODE_SGMII;
@@ -43,30 +42,29 @@ Signed-off-by: Mantas Pucka <mantas at 8devices.com>
  		break;
  	case PHY_INTERFACE_MODE_QSGMII:
  		val = PCS_MODE_QSGMII;
-@@ -328,10 +334,12 @@ static int ipq_pcs_config_mode(struct ip
+@@ -290,9 +296,11 @@ static int ipq_pcs_config_mode(struct ip
  	case PHY_INTERFACE_MODE_1000BASEX:
- 		mask |= PCS_MODE_SGMII_CTRL_MASK;
- 		val = PCS_MODE_SGMII | PCS_MODE_SGMII_CTRL_1000BASEX;
+ 		mask |= PCS_MODE_SGMII_MODE_MASK;
+ 		val = PCS_MODE_SGMII | PCS_MODE_SGMII_MODE_1000BASEX;
 +		misc2 = PCS_MISC2_MODE_SGMII;
  		break;
  	case PHY_INTERFACE_MODE_2500BASEX:
- 		val = PCS_MODE_SGMII_PLUS;
- 		rate = 312500000;
+ 		val = PCS_MODE_2500BASEX;
 +		misc2 = PCS_MISC2_MODE_SGMII_PLUS;
+ 		rate = 312500000;
  		break;
- 	case PHY_INTERFACE_MODE_PSGMII:
- 		val = PCS_MODE_PSGMII;
-@@ -360,6 +368,13 @@ static int ipq_pcs_config_mode(struct ip
- 	if (ret)
- 		return ret;
- 
+ 	case PHY_INTERFACE_MODE_USXGMII:
+@@ -315,6 +323,13 @@ static int ipq_pcs_config_mode(struct ip
+ 		if (ret)
+ 			return ret;
+ 	}
++
 +	if (misc2) {
 +		ret = regmap_update_bits(qpcs->regmap, PCS_MISC2,
 +					 PCS_MISC2_MODE_MASK, misc2);
 +		if (ret)
 +			return ret;
 +	}
-+
+ 
  	/* PCS PLL reset */
  	ret = regmap_clear_bits(qpcs->regmap, PCS_PLL_RESET, PCS_ANA_SW_RESET);
- 	if (ret)
diff --git a/target/linux/qualcommbe/patches-6.12/0366-net-pcs-ipq-uniphy-keep-autoneg-enabled-in-SGMII-mod.patch b/target/linux/qualcommbe/patches-6.12/0366-net-pcs-ipq-uniphy-keep-autoneg-enabled-in-SGMII-mod.patch
deleted file mode 100644
index 58e2be35f4..0000000000
--- a/target/linux/qualcommbe/patches-6.12/0366-net-pcs-ipq-uniphy-keep-autoneg-enabled-in-SGMII-mod.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From ccdfd293f9e948f0f62ac4e9924d72539a4e81ee Mon Sep 17 00:00:00 2001
-From: Mantas Pucka <mantas at 8devices.com>
-Date: Mon, 2 Jun 2025 17:19:45 +0300
-Subject: [PATCH] net: pcs: ipq-uniphy: keep autoneg enabled in SGMII mode
-
-For PHYs that don't use in-band-status (e.g. 2.5G PHY swiching between
-SGMII and 2500base-x), SGMII autoneg still must be enabled. Only mode
-that should use forced speed is 1000base-x
-
-Signed-off-by: Mantas Pucka <mantas at 8devices.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -431,7 +431,7 @@ static int ipq_pcs_config_sgmii(struct i
- 	/* Nothing to do here as in-band autoneg mode is enabled
- 	 * by default for each PCS MII port.
- 	 */
--	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
-+	if (interface != PHY_INTERFACE_MODE_1000BASEX)
- 		return 0;
- 
- 	/* Set force speed mode */
diff --git a/target/linux/qualcommbe/patches-6.12/0367-net-pcs-ipq-uniphy-fix-USXGMII-link-up-failure.patch b/target/linux/qualcommbe/patches-6.12/0367-net-pcs-ipq-uniphy-fix-USXGMII-link-up-failure.patch
index 980b8d0379..b02782e7b3 100644
--- a/target/linux/qualcommbe/patches-6.12/0367-net-pcs-ipq-uniphy-fix-USXGMII-link-up-failure.patch
+++ b/target/linux/qualcommbe/patches-6.12/0367-net-pcs-ipq-uniphy-fix-USXGMII-link-up-failure.patch
@@ -1,4 +1,4 @@
-From 0cff1d9bb695bdc0ad7bad234b92eddf849ce88f Mon Sep 17 00:00:00 2001
+From bedf56b46ae53c4abb21eebb3e1d5a7483926dda Mon Sep 17 00:00:00 2001
 From: Mantas Pucka <mantas at 8devices.com>
 Date: Mon, 2 Jun 2025 17:20:58 +0300
 Subject: [PATCH] net: pcs: ipq-uniphy: fix USXGMII link-up failure
@@ -13,7 +13,7 @@ Signed-off-by: Mantas Pucka <mantas at 8devices.com>
 
 --- a/drivers/net/pcs/pcs-qcom-ipq9574.c
 +++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -380,7 +380,7 @@ static int ipq_pcs_config_mode(struct ip
+@@ -336,7 +336,7 @@ static int ipq_pcs_config_mode(struct ip
  	if (ret)
  		return ret;
  
diff --git a/target/linux/qualcommbe/patches-6.12/0368-net-pcs-qcom-ipq9574-Update-IPQ9574-PCS-driver.patch b/target/linux/qualcommbe/patches-6.12/0368-net-pcs-qcom-ipq9574-Update-IPQ9574-PCS-driver.patch
new file mode 100644
index 0000000000..63a523ae1c
--- /dev/null
+++ b/target/linux/qualcommbe/patches-6.12/0368-net-pcs-qcom-ipq9574-Update-IPQ9574-PCS-driver.patch
@@ -0,0 +1,282 @@
+From b4e07a8a3ec3dc5f676238987556e2aff0b14028 Mon Sep 17 00:00:00 2001
+From: Lei Wei <quic_leiwei at quicinc.com>
+Date: Mon, 29 Jan 2024 11:39:36 +0800
+Subject: [PATCH] net: pcs: qcom-ipq9574: Update IPQ9574 PCS driver
+
+Keep the PCS driver synced with the latest version posted to the kernel
+community and add the XPCS reset support.
+
+Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
+Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
+---
+ .../bindings/net/pcs/qcom,ipq9574-pcs.yaml    |  7 ++
+ drivers/net/pcs/pcs-qcom-ipq9574.c            | 68 +++++++++++++++----
+ 2 files changed, 63 insertions(+), 12 deletions(-)
+
+--- a/Documentation/devicetree/bindings/net/pcs/qcom,ipq9574-pcs.yaml
++++ b/Documentation/devicetree/bindings/net/pcs/qcom,ipq9574-pcs.yaml
+@@ -98,6 +98,10 @@ properties:
+       - const: sys
+       - const: ahb
+ 
++  resets:
++    maxItems: 1
++    description: XPCS reset
++
+   '#clock-cells':
+     const: 1
+     description: See include/dt-bindings/net/qcom,ipq9574-pcs.h for constants
+@@ -137,6 +141,7 @@ required:
+   - '#size-cells'
+   - clocks
+   - clock-names
++  - resets
+   - '#clock-cells'
+ 
+ additionalProperties: false
+@@ -144,6 +149,7 @@ additionalProperties: false
+ examples:
+   - |
+     #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
++    #include <dt-bindings/reset/qcom,ipq9574-gcc.h>
+ 
+     ethernet-pcs at 7a00000 {
+         compatible = "qcom,ipq9574-pcs";
+@@ -154,6 +160,7 @@ examples:
+                  <&gcc GCC_UNIPHY0_AHB_CLK>;
+         clock-names = "sys",
+                       "ahb";
++        resets = <&gcc GCC_UNIPHY0_XPCS_RESET>;
+         #clock-cells = <1>;
+ 
+         pcs-mii at 0 {
+--- a/drivers/net/pcs/pcs-qcom-ipq9574.c
++++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
+@@ -13,6 +13,7 @@
+ #include <linux/phylink.h>
+ #include <linux/platform_device.h>
+ #include <linux/regmap.h>
++#include <linux/reset.h>
+ 
+ #include <dt-bindings/net/qcom,ipq9574-pcs.h>
+ 
+@@ -31,9 +32,12 @@
+ #define PCS_MODE_SEL_MASK		GENMASK(12, 8)
+ #define PCS_MODE_SGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
+ #define PCS_MODE_QSGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x1)
++#define PCS_MODE_PSGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x2)
+ #define PCS_MODE_2500BASEX		FIELD_PREP(PCS_MODE_SEL_MASK, 0x8)
+ #define PCS_MODE_XPCS			FIELD_PREP(PCS_MODE_SEL_MASK, 0x10)
+ #define PCS_MODE_SGMII_MODE_MASK	GENMASK(6, 4)
++#define PCS_MODE_SGMII_MODE_MAC		FIELD_PREP(PCS_MODE_SGMII_MODE_MASK, \
++						   0x2)
+ #define PCS_MODE_SGMII_MODE_1000BASEX	FIELD_PREP(PCS_MODE_SGMII_MODE_MASK, \
+ 						   0x0)
+ 
+@@ -52,6 +56,8 @@
+ #define PCS_MII_STS_SPEED_10		0
+ #define PCS_MII_STS_SPEED_100		1
+ #define PCS_MII_STS_SPEED_1000		2
++#define PCS_MII_STS_PAUSE_TX_EN		BIT(1)
++#define PCS_MII_STS_PAUSE_RX_EN		BIT(0)
+ 
+ #define PCS_QP_USXG_OPTION		0x584
+ #define PCS_QP_USXG_GMII_SRC_XPCS	BIT(0)
+@@ -142,6 +148,7 @@ struct ipq_pcs {
+ 	struct clk_hw tx_hw;
+ 
+ 	struct ipq_pcs_mii *qpcs_mii[PCS_MAX_MII_NRS];
++	struct reset_control *xpcs_rstc;
+ };
+ 
+ #define phylink_pcs_to_qpcs_mii(_pcs)	\
+@@ -184,6 +191,11 @@ static void ipq_pcs_get_state_sgmii(stru
+ 		state->duplex = DUPLEX_FULL;
+ 	else
+ 		state->duplex = DUPLEX_HALF;
++
++	if (val & PCS_MII_STS_PAUSE_TX_EN)
++		state->pause |= MLO_PAUSE_TX;
++	if (val & PCS_MII_STS_PAUSE_RX_EN)
++		state->pause |= MLO_PAUSE_RX;
+ }
+ 
+ static void ipq_pcs_get_state_2500basex(struct ipq_pcs *qpcs,
+@@ -198,7 +210,6 @@ static void ipq_pcs_get_state_2500basex(
+ 		return;
+ 	}
+ 
+-
+ 	state->link = !!(val & PCS_MII_LINK_STS);
+ 
+ 	if (!state->link)
+@@ -281,17 +292,27 @@ static int ipq_pcs_config_mode(struct ip
+ {
+ 	unsigned long rate = 125000000;
+ 	unsigned int val, mask, misc2 = 0;
++	bool xpcs_mode = false;
+ 	int ret;
+ 
++	/* Assert XPCS reset */
++	reset_control_assert(qpcs->xpcs_rstc);
++
+ 	/* Configure PCS interface mode */
+ 	mask = PCS_MODE_SEL_MASK;
+ 	switch (interface) {
+ 	case PHY_INTERFACE_MODE_SGMII:
+-		val = PCS_MODE_SGMII;
++		mask |= PCS_MODE_SGMII_MODE_MASK;
++		val = PCS_MODE_SGMII | PCS_MODE_SGMII_MODE_MAC;
+ 		misc2 = PCS_MISC2_MODE_SGMII;
+ 		break;
+ 	case PHY_INTERFACE_MODE_QSGMII:
+-		val = PCS_MODE_QSGMII;
++		mask |= PCS_MODE_SGMII_MODE_MASK;
++		val = PCS_MODE_QSGMII | PCS_MODE_SGMII_MODE_MAC;
++		break;
++	case PHY_INTERFACE_MODE_PSGMII:
++		mask |= PCS_MODE_SGMII_MODE_MASK;
++		val = PCS_MODE_PSGMII | PCS_MODE_SGMII_MODE_MAC;
+ 		break;
+ 	case PHY_INTERFACE_MODE_1000BASEX:
+ 		mask |= PCS_MODE_SGMII_MODE_MASK;
+@@ -308,6 +329,7 @@ static int ipq_pcs_config_mode(struct ip
+ 	case PHY_INTERFACE_MODE_10GBASER:
+ 		val = PCS_MODE_XPCS;
+ 		rate = 312500000;
++		xpcs_mode = true;
+ 		break;
+ 	default:
+ 		return -EOPNOTSUPP;
+@@ -367,6 +389,10 @@ static int ipq_pcs_config_mode(struct ip
+ 		return ret;
+ 	}
+ 
++	/* Deassert XPCS */
++	if (xpcs_mode)
++		reset_control_deassert(qpcs->xpcs_rstc);
++
+ 	return 0;
+ }
+ 
+@@ -384,15 +410,13 @@ static int ipq_pcs_config_sgmii(struct i
+ 			return ret;
+ 	}
+ 
+-	/* Nothing to do here as in-band autoneg mode is enabled
+-	 * by default for each PCS MII port.
+-	 */
++	/* Set AN mode or force mode */
+ 	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
+-		return 0;
+-
+-	/* Set force speed mode */
+-	return regmap_set_bits(qpcs->regmap,
+-			       PCS_MII_CTRL(index), PCS_MII_FORCE_MODE);
++		return regmap_clear_bits(qpcs->regmap,
++					 PCS_MII_CTRL(index), PCS_MII_FORCE_MODE);
++	else
++		return regmap_set_bits(qpcs->regmap,
++				       PCS_MII_CTRL(index), PCS_MII_FORCE_MODE);
+ }
+ 
+ static int ipq_pcs_config_2500basex(struct ipq_pcs *qpcs)
+@@ -417,6 +441,10 @@ static int ipq_pcs_config_usxgmii(struct
+ 		if (ret)
+ 			return ret;
+ 
++		ret = regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_USXG_EN);
++		if (ret)
++			return ret;
++
+ 		if (interface == PHY_INTERFACE_MODE_10G_QXGMII) {
+ 			ret = regmap_update_bits(qpcs->regmap, XPCS_KR_CTRL,
+ 						 XPCS_USXG_MODE_MASK, XPCS_10G_QXGMII_MODE);
+@@ -432,6 +460,7 @@ static int ipq_pcs_config_usxgmii(struct
+ 			ret = regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_SOFT_RESET);
+ 			if (ret)
+ 				return ret;
++		}
+ 	}
+ 
+ 	/* Disable Tx IPG check for 10G_QXGMII */
+@@ -559,7 +588,6 @@ static int ipq_pcs_link_up_config_usxgmi
+ 	reg = (index == 0) ? XPCS_DIG_CTRL : XPCS_MII1_DIG_CTRL(index);
+ 	val = (index == 0) ? XPCS_USXG_ADPT_RESET : XPCS_MII1_USXG_ADPT_RESET;
+ 	return regmap_set_bits(qpcs->regmap, reg, val);
+-
+ }
+ 
+ static int ipq_pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
+@@ -568,6 +596,7 @@ static int ipq_pcs_validate(struct phyli
+ 	switch (state->interface) {
+ 	case PHY_INTERFACE_MODE_SGMII:
+ 	case PHY_INTERFACE_MODE_QSGMII:
++	case PHY_INTERFACE_MODE_PSGMII:
+ 	case PHY_INTERFACE_MODE_1000BASEX:
+ 	case PHY_INTERFACE_MODE_10GBASER:
+ 		return 0;
+@@ -592,6 +621,7 @@ static unsigned int ipq_pcs_inband_caps(
+ 	switch (interface) {
+ 	case PHY_INTERFACE_MODE_SGMII:
+ 	case PHY_INTERFACE_MODE_QSGMII:
++	case PHY_INTERFACE_MODE_PSGMII:
+ 	case PHY_INTERFACE_MODE_1000BASEX:
+ 	case PHY_INTERFACE_MODE_USXGMII:
+ 	case PHY_INTERFACE_MODE_10G_QXGMII:
+@@ -648,6 +678,7 @@ static void ipq_pcs_get_state(struct phy
+ 	switch (state->interface) {
+ 	case PHY_INTERFACE_MODE_SGMII:
+ 	case PHY_INTERFACE_MODE_QSGMII:
++	case PHY_INTERFACE_MODE_PSGMII:
+ 	case PHY_INTERFACE_MODE_1000BASEX:
+ 		/* SGMII and 1000BASEX in-band autoneg word format are decoded
+ 		 * by PCS hardware and both placed to the same status register.
+@@ -689,6 +720,7 @@ static int ipq_pcs_config(struct phylink
+ 	switch (interface) {
+ 	case PHY_INTERFACE_MODE_SGMII:
+ 	case PHY_INTERFACE_MODE_QSGMII:
++	case PHY_INTERFACE_MODE_PSGMII:
+ 	case PHY_INTERFACE_MODE_1000BASEX:
+ 		return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface);
+ 	case PHY_INTERFACE_MODE_2500BASEX:
+@@ -703,6 +735,11 @@ static int ipq_pcs_config(struct phylink
+ 	};
+ }
+ 
++static void ipq_pcs_an_restart(struct phylink_pcs *pcs)
++{
++	/* Currently not used */
++}
++
+ static void ipq_pcs_link_up(struct phylink_pcs *pcs,
+ 			    unsigned int neg_mode,
+ 			    phy_interface_t interface,
+@@ -716,6 +753,7 @@ static void ipq_pcs_link_up(struct phyli
+ 	switch (interface) {
+ 	case PHY_INTERFACE_MODE_SGMII:
+ 	case PHY_INTERFACE_MODE_QSGMII:
++	case PHY_INTERFACE_MODE_PSGMII:
+ 	case PHY_INTERFACE_MODE_1000BASEX:
+ 		ret = ipq_pcs_link_up_config_sgmii(qpcs, index,
+ 						   neg_mode, speed);
+@@ -746,6 +784,7 @@ static const struct phylink_pcs_ops ipq_
+ 	.pcs_disable = ipq_pcs_disable,
+ 	.pcs_get_state = ipq_pcs_get_state,
+ 	.pcs_config = ipq_pcs_config,
++	.pcs_an_restart = ipq_pcs_an_restart,
+ 	.pcs_link_up = ipq_pcs_link_up,
+ };
+ 
+@@ -990,6 +1029,11 @@ static int ipq9574_pcs_probe(struct plat
+ 		return dev_err_probe(dev, PTR_ERR(clk),
+ 				     "Failed to enable AHB clock\n");
+ 
++	qpcs->xpcs_rstc = devm_reset_control_get_optional(dev, NULL);
++	if (IS_ERR_OR_NULL(qpcs->xpcs_rstc))
++		return dev_err_probe(dev, PTR_ERR(qpcs->xpcs_rstc),
++				     "Failed to get XPCS reset\n");
++
+ 	ret = ipq_pcs_clk_register(qpcs);
+ 	if (ret)
+ 		return ret;




More information about the lede-commits mailing list