From 40c578ceaeecb59c0e277d3bcf39c9af071b5592 Mon Sep 17 00:00:00 2001 From: "Jan Havran (Advantech Czech)" Date: Mon, 7 Sep 2026 15:48:16 +0200 Subject: [PATCH 1/2] net: dsa: mxl-gsw1xx: set SerDes NCO rate before SGMII reset gsw1xx_pcs_config() releases the SGMII shell from reset via gsw1xx_pcs_reset() and only afterwards programs NCO_CTRL to select the SerDes clock rate (1G NCO1 vs 2.5G NCO2). The chip boot loader uses the other order: NCO_CTRL -> RST_REQ -> SGMII_PHY_HWBU_CTRL (GSW145 data sheet, section 3.2.8, table 13). Program NCO_CTRL before gsw1xx_pcs_reset() to follow that order. On an Armada 7040 board driving a GSW145 whose switch comes up at 2.5G (pin strap PS_SUBTYPE_MD[2] = 1, pin LED42 / PS1 bit 14; GSW145 data sheet tables 23 and 25), a 1 Gbps SGMII link only carried traffic with this change. It matters when the rate the switch is left at - by the straps or by the boot loader - differs from the rate the driver selects, which is likely why it has not been seen before. Cc: stable+noautosel@kernel.org # never worked Signed-off-by: Jan Havran (Advantech Czech) Reviewed-by: Daniel Golle Reviewed-by: Maxime Chevallier Link: https://patch.msgid.link/20260907134818.16670-2-havran.jan@email.cz Signed-off-by: Jakub Kicinski --- drivers/net/dsa/lantiq/mxl-gsw1xx.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/net/dsa/lantiq/mxl-gsw1xx.c b/drivers/net/dsa/lantiq/mxl-gsw1xx.c index 347e16e9fdc1..66bf7e331905 100644 --- a/drivers/net/dsa/lantiq/mxl-gsw1xx.c +++ b/drivers/net/dsa/lantiq/mxl-gsw1xx.c @@ -352,8 +352,22 @@ static int gsw1xx_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, /* mark PCS configuration as incomplete */ priv->tbi_interface = PHY_INTERFACE_MODE_NA; - if (!reconf) + if (!reconf) { + /* setup SerDes clock speed */ + if (interface == PHY_INTERFACE_MODE_2500BASEX) + nco_ctrl = GSW1XX_SGMII_2G5 | GSW1XX_SGMII_2G5_NCO2; + else + nco_ctrl = GSW1XX_SGMII_1G | GSW1XX_SGMII_1G_NCO1; + + ret = regmap_update_bits(priv->clk, GSW1XX_CLK_NCO_CTRL, + GSW1XX_SGMII_HSP_MASK | + GSW1XX_SGMII_SEL, + nco_ctrl); + if (ret) + return ret; + ret = gsw1xx_pcs_reset(priv, interface); + } if (ret) return ret; @@ -423,19 +437,6 @@ static int gsw1xx_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, return ret; if (!reconf) { - /* setup SerDes clock speed */ - if (interface == PHY_INTERFACE_MODE_2500BASEX) - nco_ctrl = GSW1XX_SGMII_2G5 | GSW1XX_SGMII_2G5_NCO2; - else - nco_ctrl = GSW1XX_SGMII_1G | GSW1XX_SGMII_1G_NCO1; - - ret = regmap_update_bits(priv->clk, GSW1XX_CLK_NCO_CTRL, - GSW1XX_SGMII_HSP_MASK | - GSW1XX_SGMII_SEL, - nco_ctrl); - if (ret) - return ret; - ret = gsw1xx_pcs_phy_xaui_write(priv, 0x30, 0x80); if (ret) return ret; From 6b597ba4c2f67ed268b229c2c7c71f542cf27289 Mon Sep 17 00:00:00 2001 From: "Jan Havran (Advantech Czech)" Date: Mon, 7 Sep 2026 15:48:17 +0200 Subject: [PATCH 2/2] net: dsa: lantiq_gswip: handle SPEED_2500 in gswip_port_set_speed() The mxl-gsw1xx driver advertises 2500BASE-X on its SGMII port (via supports_2500m and gsw1xx_phylink_get_caps()), but the shared gswip_port_set_speed() has no SPEED_2500 case: at 2.5G every field keeps its initializer, so mdio_phy = 0 pins the MDIO speed override to 10 Mbps and no data passes. At the MAC/MDIO level 2500BASE-X is identical to 1 Gbps (same wide GMII datapath, same speed override); the rate itself is set in the PCS and SerDes, not here. This matches the boot loader's PHY_ADDR_4 = 0x32A4 for the 2.5G strap ("1 Gbps or above"), whose SPEED field is GSWIP_MDIO_PHY_SPEED_G1 (the field has no encoding above G1). Share the SPEED_1000 arm via a stacked case label. Its mii_cfg value is a no-op for 2.5G: gswip_mii_mask_cfg() writes it only for the RGMII port (mii_cfg[SGMII port] == -1), which cannot reach 2.5G anyway. Cc: stable+noautosel@kernel.org # never worked Signed-off-by: Jan Havran (Advantech Czech) Reviewed-by: Daniel Golle Reviewed-by: Maxime Chevallier Link: https://patch.msgid.link/20260907134818.16670-3-havran.jan@email.cz Signed-off-by: Jakub Kicinski --- drivers/net/dsa/lantiq/lantiq_gswip_common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/dsa/lantiq/lantiq_gswip_common.c b/drivers/net/dsa/lantiq/lantiq_gswip_common.c index 0e8eedf64d3a..6150dc3ffb64 100644 --- a/drivers/net/dsa/lantiq/lantiq_gswip_common.c +++ b/drivers/net/dsa/lantiq/lantiq_gswip_common.c @@ -1339,6 +1339,7 @@ static void gswip_port_set_speed(struct gswip_priv *priv, int port, int speed, break; case SPEED_1000: + case SPEED_2500: mdio_phy = GSWIP_MDIO_PHY_SPEED_G1; mii_cfg = GSWIP_MII_CFG_RATE_M125;