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 <daniel@makrotopia.org>
This commit is contained in:
Daniel Golle
2026-04-27 01:46:57 +01:00
parent 793ceff149
commit c271123724
3 changed files with 68 additions and 79 deletions
@@ -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 <daniel@makrotopia.org> From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 12 Dec 2023 03:47:31 +0000 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 PCS
MediaTek's USXGMII can be found in the MT7988 SoC. We need to access 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 <daniel@makrotopia.org> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- ---
.../bindings/net/pcs/mediatek,usxgmii.yaml | 60 +++++++++++++++++++ .../bindings/net/pcs/mediatek,usxgmii.yaml | 63 +++++++++++++++++++
1 file changed, 60 insertions(+) 1 file changed, 63 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
--- /dev/null --- /dev/null
+++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml +++ 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) +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2 +%YAML 1.2
+--- +---
@@ -63,6 +63,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ - clocks + - clocks
+ - resets + - resets
+ +
+allOf:
+ - $ref: /schemas/phy/phy-common-props.yaml#
+
+additionalProperties: false +additionalProperties: false
+ +
+examples: +examples:
@@ -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 <daniel@makrotopia.org> From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 12 Dec 2023 03:47:47 +0000 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 Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting
USXGMII, 10GBase-R and 5GBase-R interface modes. 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 <daniel@makrotopia.org> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- ---
MAINTAINERS | 2 + MAINTAINERS | 2 +
drivers/net/pcs/Kconfig | 12 + drivers/net/pcs/Kconfig | 13 +
drivers/net/pcs/Kconfig.orig | 55 ++++ drivers/net/pcs/Kconfig.orig | 55 ++++
drivers/net/pcs/Makefile | 1 + drivers/net/pcs/Makefile | 1 +
drivers/net/pcs/pcs-mtk-usxgmii.c | 440 ++++++++++++++++++++++++++++++ drivers/net/pcs/pcs-mtk-usxgmii.c | 490 ++++++++++++++++++++++++++++++
5 files changed, 510 insertions(+) 5 files changed, 561 insertions(+)
create mode 100644 drivers/net/pcs/Kconfig.orig create mode 100644 drivers/net/pcs/Kconfig.orig
create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c
@@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
M: Daniel Golle <daniel@makrotopia.org> M: Daniel Golle <daniel@makrotopia.org>
--- a/drivers/net/pcs/Kconfig --- a/drivers/net/pcs/Kconfig
+++ b/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 This module provides helpers to phylink for managing the LynxI PCS
which is part of MediaTek's SoC and Ethernet switch ICs. which is part of MediaTek's SoC and Ethernet switch ICs.
@@ -39,6 +39,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ tristate "MediaTek USXGMII PCS" + tristate "MediaTek USXGMII PCS"
+ select FWNODE_PCS + select FWNODE_PCS
+ select PCS_MTK_LYNXI + select PCS_MTK_LYNXI
+ select PHY_COMMON_PROPS
+ select PHYLINK + select PHYLINK
+ imply PHY_MTK_PEXTP + imply PHY_MTK_PEXTP
+ help + help
@@ -118,7 +119,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o
--- /dev/null --- /dev/null
+++ b/drivers/net/pcs/pcs-mtk-usxgmii.c +++ b/drivers/net/pcs/pcs-mtk-usxgmii.c
@@ -0,0 +1,440 @@ @@ -0,0 +1,490 @@
+// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0
+/* +/*
+ * Copyright (c) 2023 MediaTek Inc. + * Copyright (c) 2023 MediaTek Inc.
@@ -135,6 +136,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+#include <linux/of_platform.h> +#include <linux/of_platform.h>
+#include <linux/reset.h> +#include <linux/reset.h>
+#include <linux/pcs/pcs-provider.h> +#include <linux/pcs/pcs-provider.h>
+#include <linux/phy/phy-common-props.h>
+#include <linux/phy/phy.h> +#include <linux/phy/phy.h>
+#include <linux/phylink.h> +#include <linux/phylink.h>
+#include <linux/platform_device.h> +#include <linux/platform_device.h>
@@ -176,6 +178,12 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+#define USXGMII_LPA GENMASK(15, 0) +#define USXGMII_LPA GENMASK(15, 0)
+#define USXGMII_LPA_LATCH BIT(31) +#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 */ +/* Register to read PCS link status */
+#define RG_PCS_RX_STATUS0 0x904 +#define RG_PCS_RX_STATUS0 0x904
+#define RG_PCS_RX_STATUS_UPDATE BIT(16) +#define RG_PCS_RX_STATUS_UPDATE BIT(16)
@@ -187,6 +195,8 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ * @base: IO memory to access PCS hardware + * @base: IO memory to access PCS hardware
+ * @clk: Pointer to USXGMII clk + * @clk: Pointer to USXGMII clk
+ * @reset: Pointer to USXGMII reset control + * @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 + * @interface: Currently selected interface mode
+ * @neg_mode: Currently used phylink neg_mode + * @neg_mode: Currently used phylink neg_mode
+ * @node: List node + * @node: List node
@@ -198,6 +208,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ struct clk *clk; + struct clk *clk;
+ struct reset_control *reset; + struct reset_control *reset;
+ struct phy *xfi_tphy; + struct phy *xfi_tphy;
+ struct fwnode_handle *fwnode;
+ phy_interface_t interface; + phy_interface_t interface;
+ unsigned int neg_mode; + unsigned int neg_mode;
+ struct list_head node; + struct list_head node;
@@ -232,6 +243,36 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ mdelay(10); + 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, +static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+ phy_interface_t interface, + phy_interface_t interface,
+ const unsigned long *advertising, + const unsigned long *advertising,
@@ -240,6 +281,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); + 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; + unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
+ bool mode_changed = false; + bool mode_changed = false;
+ int ret;
+ +
+ if (interface == PHY_INTERFACE_MODE_USXGMII) { + if (interface == PHY_INTERFACE_MODE_USXGMII) {
+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE; + an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE;
@@ -278,6 +320,10 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ phy_reset(mpcs->xfi_tphy); + phy_reset(mpcs->xfi_tphy);
+ mtk_usxgmii_reset(mpcs); + mtk_usxgmii_reset(mpcs);
+ +
+ ret = mtk_usxgmii_config_polarity(mpcs, interface);
+ if (ret)
+ return ret;
+
+ /* Setup USXGMII AN ctrl */ + /* Setup USXGMII AN ctrl */
+ mtk_m32(mpcs, RG_PCS_AN_CTRL0, + mtk_m32(mpcs, RG_PCS_AN_CTRL0,
+ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, + USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
@@ -467,11 +513,13 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ phy_interface_t interface) + phy_interface_t interface)
+{ +{
+ switch (interface) { + switch (interface) {
+ case PHY_INTERFACE_MODE_5GBASER:
+ case PHY_INTERFACE_MODE_10GBASER:
+ case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_USXGMII:
+ return LINK_INBAND_ENABLE; + return LINK_INBAND_ENABLE;
+ +
+ case PHY_INTERFACE_MODE_5GBASER:
+ case PHY_INTERFACE_MODE_10GBASER:
+ return LINK_INBAND_DISABLE;
+
+ default: + default:
+ return 0; + return 0;
+ } + }
@@ -505,6 +553,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ mpcs->pcs.poll = true; + mpcs->pcs.poll = true;
+ mpcs->interface = PHY_INTERFACE_MODE_NA; + mpcs->interface = PHY_INTERFACE_MODE_NA;
+ mpcs->neg_mode = -1; + 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_5GBASER, mpcs->pcs.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_10GBASER, mpcs->pcs.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_10GBASER, mpcs->pcs.supported_interfaces);
@@ -538,6 +587,8 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ rtnl_lock(); + rtnl_lock();
+ phylink_release_pcs(&mpcs->pcs); + phylink_release_pcs(&mpcs->pcs);
+ rtnl_unlock(); + rtnl_unlock();
+
+ fwnode_handle_put(mpcs->fwnode);
+}; +};
+ +
+static const struct of_device_id mtk_usxgmii_of_mtable[] = { +static const struct of_device_id mtk_usxgmii_of_mtable[] = {
@@ -1,65 +0,0 @@
From ddfae94a14bf0fc301505da75825dfe473525a33 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
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 <john@phrozen.org>
---
--- 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;