diff options
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/common.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c | 21 |
5 files changed, 27 insertions, 14 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index ce383f012220..489c06488133 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -277,6 +277,7 @@ struct stmmac_safety_stats { #define FLOW_AUTO (FLOW_TX | FLOW_RX) /* PCS defines */ +#define STMMAC_PCS_RGMII (1 << 0) #define STMMAC_PCS_SGMII (1 << 1) #define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 3714b98cd8c7..323f4c958846 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -35,9 +35,6 @@ static const struct stmmac_pcs_info dwmac1000_pcs_info = { static int dwmac1000_pcs_init(struct stmmac_priv *priv) { - if (!priv->dma_cap.pcs) - return 0; - return stmmac_integrated_pcs_init(priv, &dwmac1000_pcs_info); } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 369bc2535e92..9e1a116a17ee 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -31,9 +31,6 @@ static const struct stmmac_pcs_info dwmac4_pcs_info = { static int dwmac4_pcs_init(struct stmmac_priv *priv) { - if (!priv->dma_cap.pcs) - return 0; - return stmmac_integrated_pcs_init(priv, &dwmac4_pcs_info); } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index fd8bffe9e7d1..44a40ff66ced 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1029,11 +1029,13 @@ static struct phylink_pcs *stmmac_mac_select_pcs(struct phylink_config *config, return pcs; } - /* The PCS control register is only relevant for SGMII, TBI and RTBI - * modes. We no longer support TBI or RTBI, so only configure this - * register when operating in SGMII mode with the integrated PCS. + /* The PCS AN CSRs are only relevant for SGMII, TBI and RTBI modes. + * The in-band link status is available for RGMII and SGMII interfaces. + * We no longer support TBI or RTBI, so use the feature when operating + * in RGMII or SGMII mode with the integrated PCS. */ - if (priv->hw->pcs & STMMAC_PCS_SGMII && priv->integrated_pcs) + if (priv->hw->pcs & (STMMAC_PCS_SGMII | STMMAC_PCS_RGMII) && + priv->integrated_pcs) return &priv->integrated_pcs->pcs; return NULL; @@ -1306,6 +1308,9 @@ static void stmmac_check_pcs_mode(struct stmmac_priv *priv) priv->hw->reverse_sgmii_enable = false; break; } + } else if (phy_interface_mode_is_rgmii(interface)) { + netdev_dbg(priv->dev, "PCS RGMII support enabled\n"); + priv->hw->pcs = STMMAC_PCS_RGMII; } } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c index 23b56a7ae221..8fd6905a6831 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c @@ -57,10 +57,11 @@ static void dwmac_integrated_pcs_get_state(struct phylink_pcs *pcs, rgsmii = field_get(spcs->rgsmii_status_mask, readl(spcs->rgsmii)); - state->link = status & BMSR_LSTATUS && - rgsmii & GMAC_RGSMII_LNKSTS; + state->link = !!(rgsmii & GMAC_RGSMII_LNKSTS); + if (state->interface == PHY_INTERFACE_MODE_SGMII) + state->link = state->link && status & BMSR_LSTATUS; - if (state->link && neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { + if (state->link) { state->duplex = rgsmii & GMAC_RGSMII_LNKMOD ? DUPLEX_FULL : DUPLEX_HALF; switch (FIELD_GET(GMAC_RGSMII_SPEED_MASK, rgsmii)) { @@ -92,6 +93,10 @@ static int dwmac_integrated_pcs_config(struct phylink_pcs *pcs, { struct stmmac_pcs *spcs = phylink_pcs_to_stmmac_pcs(pcs); + /* PCS AN capability isn't applicable for RGMII interface */ + if (phy_interface_mode_is_rgmii(interface)) + return 0; + dwmac_ctrl_ane(spcs->base, 0, 1, spcs->priv->hw->reverse_sgmii_enable); return 0; @@ -146,6 +151,8 @@ int stmmac_integrated_pcs_get_phy_intf_sel(struct phylink_pcs *pcs, { if (interface == PHY_INTERFACE_MODE_SGMII) return PHY_INTF_SEL_SGMII; + else if (phy_interface_mode_is_rgmii(interface)) + return PHY_INTF_SEL_RGMII; return -EINVAL; } @@ -155,6 +162,9 @@ int stmmac_integrated_pcs_init(struct stmmac_priv *priv, { struct stmmac_pcs *spcs; + if (!priv->dma_cap.pcs && priv->dma_cap.actphyif != PHY_INTF_SEL_RGMII) + return 0; + spcs = devm_kzalloc(priv->device, sizeof(*spcs), GFP_KERNEL); if (!spcs) return -ENOMEM; @@ -166,7 +176,10 @@ int stmmac_integrated_pcs_init(struct stmmac_priv *priv, spcs->int_mask = pcs_info->int_mask; spcs->pcs.ops = &dwmac_integrated_pcs_ops; - __set_bit(PHY_INTERFACE_MODE_SGMII, spcs->pcs.supported_interfaces); + if (priv->dma_cap.pcs) + __set_bit(PHY_INTERFACE_MODE_SGMII, spcs->pcs.supported_interfaces); + if (priv->dma_cap.actphyif == PHY_INTF_SEL_RGMII) + phy_interface_set_rgmii(spcs->pcs.supported_interfaces); priv->integrated_pcs = spcs; |
