summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c13
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c21
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;