diff options
author | Russell King (Oracle) <rmk+kernel@armlinux.org.uk> | 2025-02-05 14:08:11 +0000 |
---|---|---|
committer | Russell King (Oracle) <rmk+kernel@armlinux.org.uk> | 2025-02-16 10:59:15 +0000 |
commit | 2e3adbb920aaffda834d43e01f878cee5a8a76c7 (patch) | |
tree | 76474b56245aa6b3a44ae6a46c4a6b358d2f89f2 | |
parent | b21fc06a3526b22e9ccc9b95e55506ac248f0350 (diff) |
net: xpcs: allow 1000BASE-X to work with older XPCS IP
Older XPCS IP requires SGMII_LINK and PHY_SIDE_SGMII to be set when
operating in 1000BASE-X mode even though the XPCS is not configured for
SGMII. An example of a device with older XPCS IP is KSZ9477.
We already don't clear these bits if we switch from SGMII to 1000BASE-X
on TXGBE - which would result in 1000BASE-X with the PHY_SIDE_SGMII bit
left set.
It is currently believed to be safe to set both bits on newer IP
without side-effects.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-rw-r--r-- | drivers/net/pcs/pcs-xpcs.c | 13 | ||||
-rw-r--r-- | drivers/net/pcs/pcs-xpcs.h | 1 |
2 files changed, 12 insertions, 2 deletions
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c index 9ea36929f019..bb16fdf49cab 100644 --- a/drivers/net/pcs/pcs-xpcs.c +++ b/drivers/net/pcs/pcs-xpcs.c @@ -744,9 +744,18 @@ static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs, return ret; } - mask = DW_VR_MII_PCS_MODE_MASK; + /* Older XPCS IP requires PHY_MODE (bit 3) and SGMII_LINK (but 4) to + * be set when operating in 1000BASE-X mode. See page 233 + * https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/KSZ9477S-Data-Sheet-DS00002392C.pdf + * "5.5.9 SGMII AUTO-NEGOTIATION CONTROL REGISTER" + */ + mask = DW_VR_MII_PCS_MODE_MASK | DW_VR_MII_AN_CTRL_SGMII_LINK | + DW_VR_MII_TX_CONFIG_MASK; val = FIELD_PREP(DW_VR_MII_PCS_MODE_MASK, - DW_VR_MII_PCS_MODE_C37_1000BASEX); + DW_VR_MII_PCS_MODE_C37_1000BASEX) | + FIELD_PREP(DW_VR_MII_TX_CONFIG_MASK, + DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII) | + DW_VR_MII_AN_CTRL_SGMII_LINK; if (!xpcs->pcs.poll) { mask |= DW_VR_MII_AN_INTR_EN; diff --git a/drivers/net/pcs/pcs-xpcs.h b/drivers/net/pcs/pcs-xpcs.h index d458e5ba50b2..db52dc619b80 100644 --- a/drivers/net/pcs/pcs-xpcs.h +++ b/drivers/net/pcs/pcs-xpcs.h @@ -61,6 +61,7 @@ #define DW_VR_MII_AN_CTRL 0x8001 #define DW_VR_MII_AN_CTRL_8BIT BIT(8) +#define DW_VR_MII_AN_CTRL_SGMII_LINK BIT(4) #define DW_VR_MII_TX_CONFIG_MASK BIT(3) #define DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII 0x1 #define DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII 0x0 |