diff options
| author | Serge Semin <fancer.lancer@gmail.com> | 2023-06-11 14:51:26 +0300 |
|---|---|---|
| committer | Serge Semin <fancer.lancer@gmail.com> | 2026-08-13 20:37:49 +0300 |
| commit | 8f1ac2301e0eb597ceaae89f96b4b8bfe560a1c6 (patch) | |
| tree | 6e555158b0eed23c7422249db67bbfb6f72a4470 | |
| parent | 01257fa022a94066cf30e7177a3ed3542c5944c5 (diff) | |
| download | linux-8f1ac2301e0eb597ceaae89f96b4b8bfe560a1c6.tar.gz linux-8f1ac2301e0eb597ceaae89f96b4b8bfe560a1c6.zip | |
net: pcs: xpcs: Add XGMII interface support
Natively DW XPCS (v3.xx) supports two upstream interfaces: XGMII and
GMII/MII. Former one is responsible for the 10G link speed. It's a 32-bits
interface normally connected to MAC and which is supposed to be used for
the PCS-R and 10G PCS-X data paths. Despite of the USXGMII it doesn't
support speed change. So just the only thing what needs to be done is to
add the interface and features for the XGMII interface and rely on the
auto-negotiation procedure to establish the link.
Note DW xGMII PHY-mode support must be added to the STMMAC driver in order
to have DW XGMAC/XPCS chain working correctly.
TODO add some configs to the xpcs_config_xgmii() method.
Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 | ||||
| -rw-r--r-- | drivers/net/pcs/pcs-xpcs.c | 22 |
2 files changed, 34 insertions, 1 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 44a40ff66ced..2fb13d0823ca 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1089,7 +1089,15 @@ static void stmmac_mac_link_up(struct phylink_config *config, old_ctrl = readl(priv->ioaddr + MAC_CTRL_REG); ctrl = old_ctrl & ~priv->hw->link.speed_mask; - if (interface == PHY_INTERFACE_MODE_USXGMII) { + if (interface == PHY_INTERFACE_MODE_XGMII) { + switch (speed) { + case SPEED_10000: + ctrl |= priv->hw->link.xgmii.speed10000; + break; + default: + return; + } + } else if (interface == PHY_INTERFACE_MODE_USXGMII) { switch (speed) { case SPEED_10000: ctrl |= priv->hw->link.xgmii.speed10000; @@ -1100,6 +1108,9 @@ static void stmmac_mac_link_up(struct phylink_config *config, case SPEED_2500: ctrl |= priv->hw->link.xgmii.speed2500; break; + case SPEED_1000: + ctrl |= priv->hw->link.speed1000; + break; default: return; } diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c index cf8c918ce687..43b4fee4a5fd 100644 --- a/drivers/net/pcs/pcs-xpcs.c +++ b/drivers/net/pcs/pcs-xpcs.c @@ -19,6 +19,15 @@ #define phylink_pcs_to_xpcs(pl_pcs) \ container_of((pl_pcs), struct dw_xpcs, pcs) +static const int xpcs_xgmii_features[] = { + ETHTOOL_LINK_MODE_Pause_BIT, + ETHTOOL_LINK_MODE_Asym_Pause_BIT, + ETHTOOL_LINK_MODE_Autoneg_BIT, + ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, + ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, + __ETHTOOL_LINK_MODE_MASK_NBITS, +}; + static const int xpcs_usxgmii_features[] = { ETHTOOL_LINK_MODE_Pause_BIT, ETHTOOL_LINK_MODE_Asym_Pause_BIT, @@ -356,6 +365,11 @@ static int xpcs_read_fault_c73(struct dw_xpcs *xpcs, return 0; } +static void xpcs_link_up_xgmii(struct dw_xpcs *xpcs, int speed) +{ + /* TODO add some XGMII-related configs ...*/ +} + static void xpcs_link_up_usxgmii(struct dw_xpcs *xpcs, int speed) { int ret, speed_sel; @@ -1254,6 +1268,10 @@ static void xpcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); switch (interface) { + case PHY_INTERFACE_MODE_XGMII: + xpcs_link_up_xgmii(xpcs, speed); + break; + case PHY_INTERFACE_MODE_USXGMII: xpcs_link_up_usxgmii(xpcs, speed); break; @@ -1401,6 +1419,10 @@ static int xpcs_read_ids(struct dw_xpcs *xpcs) static const struct dw_xpcs_compat synopsys_xpcs_compat[] = { { + .interface = PHY_INTERFACE_MODE_XGMII, + .supported = xpcs_xgmii_features, + .an_mode = DW_AN_C73, + }, { .interface = PHY_INTERFACE_MODE_USXGMII, .supported = xpcs_usxgmii_features, .an_mode = DW_AN_C73, |
