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

View File

@ -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>
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 <daniel@makrotopia.org>
---
.../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 <daniel@makrotopia.org>
+ - clocks
+ - resets
+
+allOf:
+ - $ref: /schemas/phy/phy-common-props.yaml#
+
+additionalProperties: false
+
+examples:

View File

@ -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>
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 <daniel@makrotopia.org>
---
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 <daniel@makrotopia.org>
M: Daniel Golle <daniel@makrotopia.org>
--- 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 <daniel@makrotopia.org>
+ 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 <daniel@makrotopia.org>
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 <daniel@makrotopia.org>
+#include <linux/of_platform.h>
+#include <linux/reset.h>
+#include <linux/pcs/pcs-provider.h>
+#include <linux/phy/phy-common-props.h>
+#include <linux/phy/phy.h>
+#include <linux/phylink.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_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 <daniel@makrotopia.org>
+ * @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 <daniel@makrotopia.org>
+ 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 <daniel@makrotopia.org>
+ 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 <daniel@makrotopia.org>
+ 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 <daniel@makrotopia.org>
+ 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 <daniel@makrotopia.org>
+ 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 <daniel@makrotopia.org>
+ 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 <daniel@makrotopia.org>
+ rtnl_lock();
+ phylink_release_pcs(&mpcs->pcs);
+ rtnl_unlock();
+
+ fwnode_handle_put(mpcs->fwnode);
+};
+
+static const struct of_device_id mtk_usxgmii_of_mtable[] = {

View File

@ -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;