From c271123724fc03ce646fb9d79fb439d01becaada Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Mon, 27 Apr 2026 01:46:57 +0100 Subject: [PATCH] generic: 6.18: fix MediaTek USXGMII driver LINK_INBAND_ENABLE isn't valid for 5GBase-R/10GBase-R modes which by definition don't support any in-band an. Correctly report LINK_INBAND_DISABLE to fix 10G fiber SFP modules no longer working. While at it also get rid of downstream pn-swap properties in favor of using the upstream schema. Signed-off-by: Daniel Golle --- ...pcs-add-bindings-for-MediaTek-USXGMI.patch | 13 ++-- ...-add-driver-for-MediaTek-USXGMII-PCS.patch | 69 ++++++++++++++++--- ...pcs-mtk_usxgmii-add-polarity-control.patch | 65 ----------------- 3 files changed, 68 insertions(+), 79 deletions(-) delete mode 100644 target/linux/mediatek/patches-6.18/736-net-pcs-mtk_usxgmii-add-polarity-control.patch diff --git a/target/linux/generic/pending-6.18/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch b/target/linux/generic/pending-6.18/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch index 46694c8534..3bee2f2c6c 100644 --- a/target/linux/generic/pending-6.18/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch +++ b/target/linux/generic/pending-6.18/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch @@ -1,7 +1,7 @@ -From 029c59b9e92776ed1b8f586055d5813132e32f47 Mon Sep 17 00:00:00 2001 +From 3bc50ced1c42f0a31173eb65a61307d657109382 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Tue, 12 Dec 2023 03:47:31 +0000 -Subject: [PATCH 2/4] dt-bindings: net: pcs: add bindings for MediaTek USXGMII +Subject: [PATCH 1/2] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS MediaTek's USXGMII can be found in the MT7988 SoC. We need to access @@ -12,13 +12,13 @@ interface modes are also available. Signed-off-by: Daniel Golle --- - .../bindings/net/pcs/mediatek,usxgmii.yaml | 60 +++++++++++++++++++ - 1 file changed, 60 insertions(+) + .../bindings/net/pcs/mediatek,usxgmii.yaml | 63 +++++++++++++++++++ + 1 file changed, 63 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml --- /dev/null +++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml -@@ -0,0 +1,60 @@ +@@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- @@ -63,6 +63,9 @@ Signed-off-by: Daniel Golle + - clocks + - resets + ++allOf: ++ - $ref: /schemas/phy/phy-common-props.yaml# ++ +additionalProperties: false + +examples: diff --git a/target/linux/generic/pending-6.18/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch b/target/linux/generic/pending-6.18/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch index 83336476d4..385c5c924e 100644 --- a/target/linux/generic/pending-6.18/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch +++ b/target/linux/generic/pending-6.18/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch @@ -1,7 +1,7 @@ -From c33cd256420ed08ffbedf39971882acc60dc184e Mon Sep 17 00:00:00 2001 +From e9d2999f5d9d8e1b895350c569e930918b41ce92 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Tue, 12 Dec 2023 03:47:47 +0000 -Subject: [PATCH 3/4] net: pcs: add driver for MediaTek USXGMII PCS +Subject: [PATCH 2/2] net: pcs: add driver for MediaTek USXGMII PCS Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting USXGMII, 10GBase-R and 5GBase-R interface modes. @@ -9,11 +9,11 @@ USXGMII, 10GBase-R and 5GBase-R interface modes. Signed-off-by: Daniel Golle --- MAINTAINERS | 2 + - drivers/net/pcs/Kconfig | 12 + + drivers/net/pcs/Kconfig | 13 + drivers/net/pcs/Kconfig.orig | 55 ++++ drivers/net/pcs/Makefile | 1 + - drivers/net/pcs/pcs-mtk-usxgmii.c | 440 ++++++++++++++++++++++++++++++ - 5 files changed, 510 insertions(+) + drivers/net/pcs/pcs-mtk-usxgmii.c | 490 ++++++++++++++++++++++++++++++ + 5 files changed, 561 insertions(+) create mode 100644 drivers/net/pcs/Kconfig.orig create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c @@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle M: Daniel Golle --- a/drivers/net/pcs/Kconfig +++ b/drivers/net/pcs/Kconfig -@@ -33,6 +33,18 @@ config PCS_MTK_LYNXI +@@ -33,6 +33,19 @@ config PCS_MTK_LYNXI This module provides helpers to phylink for managing the LynxI PCS which is part of MediaTek's SoC and Ethernet switch ICs. @@ -39,6 +39,7 @@ Signed-off-by: Daniel Golle + tristate "MediaTek USXGMII PCS" + select FWNODE_PCS + select PCS_MTK_LYNXI ++ select PHY_COMMON_PROPS + select PHYLINK + imply PHY_MTK_PEXTP + help @@ -118,7 +119,7 @@ Signed-off-by: Daniel Golle obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o --- /dev/null +++ b/drivers/net/pcs/pcs-mtk-usxgmii.c -@@ -0,0 +1,440 @@ +@@ -0,0 +1,490 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 MediaTek Inc. @@ -135,6 +136,7 @@ Signed-off-by: Daniel Golle +#include +#include +#include ++#include +#include +#include +#include @@ -176,6 +178,12 @@ Signed-off-by: Daniel Golle +#define USXGMII_LPA GENMASK(15, 0) +#define USXGMII_LPA_LATCH BIT(31) + ++/* Register to control SerDes lane polarity */ ++#define RG_PHY_TOP_CTRL0 0x82c ++#define USXGMII_PN_SWAP_MASK GENMASK(1, 0) ++#define USXGMII_PN_SWAP_RX BIT(1) ++#define USXGMII_PN_SWAP_TX BIT(0) ++ +/* Register to read PCS link status */ +#define RG_PCS_RX_STATUS0 0x904 +#define RG_PCS_RX_STATUS_UPDATE BIT(16) @@ -187,6 +195,8 @@ Signed-off-by: Daniel Golle + * @base: IO memory to access PCS hardware + * @clk: Pointer to USXGMII clk + * @reset: Pointer to USXGMII reset control ++ * @fwnode: Firmware node of the PCS, used to look up ++ * rx-polarity / tx-polarity properties + * @interface: Currently selected interface mode + * @neg_mode: Currently used phylink neg_mode + * @node: List node @@ -198,6 +208,7 @@ Signed-off-by: Daniel Golle + struct clk *clk; + struct reset_control *reset; + struct phy *xfi_tphy; ++ struct fwnode_handle *fwnode; + phy_interface_t interface; + unsigned int neg_mode; + struct list_head node; @@ -232,6 +243,36 @@ Signed-off-by: Daniel Golle + mdelay(10); +} + ++static int mtk_usxgmii_config_polarity(struct mtk_usxgmii_pcs *mpcs, ++ phy_interface_t interface) ++{ ++ unsigned int pol; ++ u32 val = 0; ++ int ret; ++ ++ if (!mpcs->fwnode) ++ return 0; ++ ++ ret = phy_get_rx_polarity(mpcs->fwnode, phy_modes(interface), ++ BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT), ++ PHY_POL_NORMAL, &pol); ++ if (ret) ++ return ret; ++ if (pol == PHY_POL_INVERT) ++ val |= USXGMII_PN_SWAP_RX; ++ ++ ret = phy_get_tx_polarity(mpcs->fwnode, phy_modes(interface), ++ BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT), ++ PHY_POL_NORMAL, &pol); ++ if (ret) ++ return ret; ++ if (pol == PHY_POL_INVERT) ++ val |= USXGMII_PN_SWAP_TX; ++ ++ mtk_m32(mpcs, RG_PHY_TOP_CTRL0, USXGMII_PN_SWAP_MASK, val); ++ return 0; ++} ++ +static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, + phy_interface_t interface, + const unsigned long *advertising, @@ -240,6 +281,7 @@ Signed-off-by: Daniel Golle + struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); + unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0; + bool mode_changed = false; ++ int ret; + + if (interface == PHY_INTERFACE_MODE_USXGMII) { + an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE; @@ -278,6 +320,10 @@ Signed-off-by: Daniel Golle + phy_reset(mpcs->xfi_tphy); + mtk_usxgmii_reset(mpcs); + ++ ret = mtk_usxgmii_config_polarity(mpcs, interface); ++ if (ret) ++ return ret; ++ + /* Setup USXGMII AN ctrl */ + mtk_m32(mpcs, RG_PCS_AN_CTRL0, + USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, @@ -467,11 +513,13 @@ Signed-off-by: Daniel Golle + phy_interface_t interface) +{ + switch (interface) { -+ case PHY_INTERFACE_MODE_5GBASER: -+ case PHY_INTERFACE_MODE_10GBASER: + case PHY_INTERFACE_MODE_USXGMII: + return LINK_INBAND_ENABLE; + ++ case PHY_INTERFACE_MODE_5GBASER: ++ case PHY_INTERFACE_MODE_10GBASER: ++ return LINK_INBAND_DISABLE; ++ + default: + return 0; + } @@ -505,6 +553,7 @@ Signed-off-by: Daniel Golle + mpcs->pcs.poll = true; + mpcs->interface = PHY_INTERFACE_MODE_NA; + mpcs->neg_mode = -1; ++ mpcs->fwnode = fwnode_handle_get(dev_fwnode(dev)); + + __set_bit(PHY_INTERFACE_MODE_5GBASER, mpcs->pcs.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_10GBASER, mpcs->pcs.supported_interfaces); @@ -538,6 +587,8 @@ Signed-off-by: Daniel Golle + rtnl_lock(); + phylink_release_pcs(&mpcs->pcs); + rtnl_unlock(); ++ ++ fwnode_handle_put(mpcs->fwnode); +}; + +static const struct of_device_id mtk_usxgmii_of_mtable[] = { diff --git a/target/linux/mediatek/patches-6.18/736-net-pcs-mtk_usxgmii-add-polarity-control.patch b/target/linux/mediatek/patches-6.18/736-net-pcs-mtk_usxgmii-add-polarity-control.patch deleted file mode 100644 index 092cd607e2..0000000000 --- a/target/linux/mediatek/patches-6.18/736-net-pcs-mtk_usxgmii-add-polarity-control.patch +++ /dev/null @@ -1,65 +0,0 @@ -From ddfae94a14bf0fc301505da75825dfe473525a33 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 29 Oct 2024 13:40:11 +0100 -Subject: [PATCH] mediatek: add support for swapping the polarity on usxgmii interfaces - -This patch comes from the MTK SDK. - -Signed-off-by: John Crispin ---- ---- a/drivers/net/pcs/pcs-mtk-usxgmii.c -+++ b/drivers/net/pcs/pcs-mtk-usxgmii.c -@@ -55,6 +55,12 @@ - #define USXGMII_LPA GENMASK(15, 0) - #define USXGMII_LPA_LATCH BIT(31) - -+/* Register to control PCS polarity */ -+#define RG_PHY_TOP_CTRL0 0x82C -+#define USXGMII_PN_SWAP_MASK GENMASK(1, 0) -+#define USXGMII_PN_SWAP_RX BIT(1) -+#define USXGMII_PN_SWAP_TX BIT(0) -+ - /* Register to read PCS link status */ - #define RG_PCS_RX_STATUS0 0x904 - #define RG_PCS_RX_STATUS_UPDATE BIT(16) -@@ -78,6 +84,7 @@ struct mtk_usxgmii_pcs { - struct reset_control *reset; - struct phy *xfi_tphy; - phy_interface_t interface; -+ unsigned int polarity; - unsigned int neg_mode; - struct list_head node; - }; -@@ -157,6 +164,10 @@ static int mtk_usxgmii_pcs_config(struct - phy_reset(mpcs->xfi_tphy); - mtk_usxgmii_reset(mpcs); - -+ /* Configure the interface polarity */ -+ mtk_m32(mpcs, RG_PHY_TOP_CTRL0, -+ USXGMII_PN_SWAP_MASK, mpcs->polarity); -+ - /* Setup USXGMII AN ctrl */ - mtk_m32(mpcs, RG_PCS_AN_CTRL0, - USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, -@@ -369,6 +380,7 @@ static const struct phylink_pcs_ops mtk_ - static int mtk_usxgmii_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; - struct mtk_usxgmii_pcs *mpcs; - - mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL); -@@ -379,6 +391,13 @@ static int mtk_usxgmii_probe(struct plat - if (IS_ERR(mpcs->base)) - return PTR_ERR(mpcs->base); - -+ if (of_property_read_bool(np->parent, "mediatek,pnswap")) -+ mpcs->polarity = USXGMII_PN_SWAP_TX | USXGMII_PN_SWAP_RX; -+ else if (of_property_read_bool(np, "mediatek,pnswap-tx")) -+ mpcs->polarity = USXGMII_PN_SWAP_TX; -+ else if (of_property_read_bool(np, "mediatek,pnswap-rx")) -+ mpcs->polarity = USXGMII_PN_SWAP_RX; -+ - mpcs->dev = dev; - mpcs->pcs.ops = &mtk_usxgmii_pcs_ops; - mpcs->pcs.poll = true;