diff options
-rw-r--r-- | drivers/net/pcs/pcs-xpcs.c | 19 | ||||
-rw-r--r-- | drivers/net/pcs/pcs-xpcs.h | 14 |
2 files changed, 25 insertions, 8 deletions
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c index 634c94bb61ad..92382a277605 100644 --- a/drivers/net/pcs/pcs-xpcs.c +++ b/drivers/net/pcs/pcs-xpcs.c @@ -697,12 +697,10 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, break; } - if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) { - /* Hardware requires it to be PHY side SGMII */ - tx_conf = DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII; - } else { + if (xpcs->sgmii_mode == DW_XPCS_SGMII_MODE_MAC) tx_conf = DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII; - } + else + tx_conf = DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII; val |= FIELD_PREP(DW_VR_MII_TX_CONFIG_MASK, tx_conf); @@ -713,12 +711,16 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, val = 0; mask = DW_VR_MII_DIG_CTRL1_2G5_EN | DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; - if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) - val = DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; + switch (xpcs->sgmii_mode) { + case DW_XPCS_SGMII_MODE_MAC: + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) + val = DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; + break; - if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) { + case DW_XPCS_SGMII_MODE_PHY_HW: mask |= DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL; val |= DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL; + break; } ret = xpcs_modify(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, mask, val); @@ -1507,6 +1509,7 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev) if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) { xpcs->pcs.poll = false; xpcs->sgmii_10_100_8bit = DW_XPCS_SGMII_10_100_8BIT; + xpcs->sgmii_mode = DW_XPCS_SGMII_MODE_PHY_HW; } else { xpcs->need_reset = true; } diff --git a/drivers/net/pcs/pcs-xpcs.h b/drivers/net/pcs/pcs-xpcs.h index 96ee0868ad20..56e0ad8900e2 100644 --- a/drivers/net/pcs/pcs-xpcs.h +++ b/drivers/net/pcs/pcs-xpcs.h @@ -111,6 +111,19 @@ enum dw_xpcs_sgmii_10_100 { DW_XPCS_SGMII_10_100_8BIT }; +/* The SGMII mode: + * DW_XPCS_SGMII_MODE_MAC: the XPCS acts as a MAC, reading and acknowledging + * the config word. + * + * DW_XPCS_SGMII_MODE_PHY_HW: the XPCS acts as a PHY, deriving the tx_config + * bits 15 (link), 12 (duplex) and 11:10 (speed) from hardware inputs to the + * XPCS. + */ +enum dw_xpcs_sgmii_mode { + DW_XPCS_SGMII_MODE_MAC, /* XPCS is MAC on SGMII */ + DW_XPCS_SGMII_MODE_PHY_HW, /* XPCS is PHY, tx_config from hw */ +}; + struct dw_xpcs { struct dw_xpcs_info info; const struct dw_xpcs_desc *desc; @@ -122,6 +135,7 @@ struct dw_xpcs { u8 eee_mult_fact; /* Width of the MII MAC/XPCS interface in 100M and 10M modes */ enum dw_xpcs_sgmii_10_100 sgmii_10_100_8bit; + enum dw_xpcs_sgmii_mode sgmii_mode; }; int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg); |