drivers/net/pcs/pcs-lynx.c | 53 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-)
The Lynx PCS setup for 10g-qxgmii and usxgmii programs the
USXGMII replicator advertisement, but does not explicitly enable and
restart in-band autonegotiation or program the replicator link timers.
This leaves the PCS dependent on firmware or bootloader state. Systems
which do not get the USXGMII replicator preconfigured before Linux may
therefore fail to negotiate the link correctly.
After programming the USXGMII device ability, configure the replicator
BMCR with reset, autonegotiation enable and autonegotiation restart. Also
program the replicator link timer registers using the value returned by
phylink_get_link_timer_ns().
Co-developed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Patryk Biel <pbiel7@gmail.com>
---
Changes in v4:
- Fix commit message to reflect the code changes.
- Link to v3: https://lore.kernel.org/r/20260922-b4-fix-pcs-lynx-an-v3-1-dda3ac4e499c@gmail.com
Changes in v3:
- Add separate link timer macro for 10G-QXGMII (1/4 tick rate vs USXGMII).
- Select link timer macro based on interface mode.
- Link to v2: https://lore.kernel.org/r/20260824-b4-fix-pcs-lynx-an-v2-1-9bb1dec96f0b@gmail.com
Changes in v2:
- Reorder local variable declarations in lynx_pcs_config_usxgmii().
- Move USXGMII replicator link timer configuration before the autonegotiation restart.
- Use phylink_get_link_timer_ns() instead of hardcoded USXGMII
replicator link timer values, converting to 3.2 ns register step.
- Link to v1: https://lore.kernel.org/r/20260820-b4-fix-pcs-lynx-an-v1-1-62d66391eaff@gmail.com
---
drivers/net/pcs/pcs-lynx.c | 53 ++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 49 insertions(+), 4 deletions(-)
diff --git a/drivers/net/pcs/pcs-lynx.c b/drivers/net/pcs/pcs-lynx.c
index da4f99059eef7722a5c3bf32df490940cc1135f8..6d94f92a3332959bc4d39969a8ad781ac06951af 100644
--- a/drivers/net/pcs/pcs-lynx.c
+++ b/drivers/net/pcs/pcs-lynx.c
@@ -20,6 +20,12 @@
#define IF_MODE_SPEED_MSK GENMASK(3, 2)
#define IF_MODE_HALF_DUPLEX BIT(4)
+/* USXGMII replicator link timer step is 3.2 ns (312.5M XGMII columns per sec)
+ * for single port mode. For quad port mode, it is 1/4 of that.
+ */
+#define LINK_TIMER_VAL_USXGMII(ns) ((u32)((ns) * 10 / 32))
+#define LINK_TIMER_VAL_10G_QXGMII(ns) ((u32)((ns) * 10 / 128))
+
struct lynx_pcs {
struct phylink_pcs pcs;
struct mdio_device *mdio;
@@ -158,6 +164,9 @@ static int lynx_pcs_config_usxgmii(struct mdio_device *pcs,
{
struct mii_bus *bus = pcs->bus;
int addr = pcs->addr;
+ int link_timer_ns;
+ u32 link_timer;
+ int ret;
if (neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) {
dev_err(&pcs->dev, "%s only supports in-band AN for now\n",
@@ -166,10 +175,46 @@ static int lynx_pcs_config_usxgmii(struct mdio_device *pcs,
}
/* Configure device ability for the USXGMII Replicator */
- return mdiobus_c45_write(bus, addr, MDIO_MMD_VEND2, MII_ADVERTISE,
- MDIO_USXGMII_10G | MDIO_USXGMII_LINK |
- MDIO_USXGMII_FULL_DUPLEX |
- ADVERTISE_SGMII | ADVERTISE_LPACK);
+ ret = mdiobus_c45_write(bus, addr, MDIO_MMD_VEND2, MII_ADVERTISE,
+ MDIO_USXGMII_10G | MDIO_USXGMII_LINK |
+ MDIO_USXGMII_FULL_DUPLEX |
+ ADVERTISE_SGMII | ADVERTISE_LPACK);
+ if (ret < 0) {
+ dev_err(&pcs->dev, "could not set USXGMII replicator config\n");
+ return ret;
+ }
+
+ link_timer_ns = phylink_get_link_timer_ns(interface);
+ if (link_timer_ns > 0) {
+ if (interface == PHY_INTERFACE_MODE_10G_QXGMII)
+ link_timer = LINK_TIMER_VAL_10G_QXGMII(link_timer_ns);
+ else
+ link_timer = LINK_TIMER_VAL_USXGMII(link_timer_ns);
+
+ ret = mdiobus_c45_write(bus, addr, MDIO_MMD_VEND2,
+ LINK_TIMER_LO, link_timer & 0xffff);
+ if (ret < 0) {
+ dev_err(&pcs->dev, "could not set USXGMII Link Timer 1\n");
+ return ret;
+ }
+
+ ret = mdiobus_c45_write(bus, addr, MDIO_MMD_VEND2,
+ LINK_TIMER_HI, (link_timer >> 16) & 0x1f);
+ if (ret < 0) {
+ dev_err(&pcs->dev, "could not set USXGMII Link Timer 2\n");
+ return ret;
+ }
+ }
+
+ /* Configure autonegotiation */
+ ret = mdiobus_c45_write(bus, addr, MDIO_MMD_VEND2, MII_BMCR,
+ BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART);
+ if (ret < 0) {
+ dev_err(&pcs->dev, "could not set USXGMII replicator control config\n");
+ return ret;
+ }
+
+ return ret;
}
static int lynx_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
---
base-commit: 10cfa109c880092df32e396647b4afdca9be8350
change-id: 20260820-b4-fix-pcs-lynx-an-3fd1d5e94ce6
Best regards,
--
Patryk Biel <pbiel7@gmail.com>
On Wed, Sep 23, 2026 at 06:14:12PM +0200, Patryk Biel wrote: > The Lynx PCS setup for 10g-qxgmii and usxgmii programs the > USXGMII replicator advertisement, but does not explicitly enable and > restart in-band autonegotiation or program the replicator link timers. > > This leaves the PCS dependent on firmware or bootloader state. Systems > which do not get the USXGMII replicator preconfigured before Linux may > therefore fail to negotiate the link correctly. > > After programming the USXGMII device ability, configure the replicator > BMCR with reset, autonegotiation enable and autonegotiation restart. Also > program the replicator link timer registers using the value returned by > phylink_get_link_timer_ns(). > > Co-developed-by: Vladimir Oltean <vladimir.oltean@nxp.com> > Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> > Signed-off-by: Patryk Biel <pbiel7@gmail.com> > --- You are supposed to carry over the received tags from previous patch versions. In this case I'll just resend them myself to this version, so you need to do nothing further, just keep that in mind for the future. Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com> Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Hi, On Wed, Sep 23, 2026 at 6:18 PM Vladimir Oltean <vladimir.oltean@nxp.com> wrote: > You are supposed to carry over the received tags from previous patch > versions. In this case I'll just resend them myself to this version, so > you need to do nothing further, just keep that in mind for the future. > > Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com> > Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com> Thanks for the patience. Upstreaming is still something relatively new to me, and I guess it may take me a little while to get used to all the conventions. I'll keep this in mind for future submissions. Thanks again for the review and testing. Best regards Patryk
© 2016 - 2026 Red Hat, Inc.