summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/pcs/pcs-xpcs.c19
-rw-r--r--drivers/net/pcs/pcs-xpcs.h14
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);