Commit 2031c09e authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller

net: pcs: xpcs: add support for sgmii with no inband AN

In fixed-link use cases, the XPCS can disable the clause 37 in-band
autoneg process, disable the "Automatic Speed Mode Change after CL37 AN"
setting, and force operation in a speed dictated by management.

Add support for this operating mode.
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d4433d5b
...@@ -690,7 +690,7 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) ...@@ -690,7 +690,7 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
} }
EXPORT_SYMBOL_GPL(xpcs_config_eee); EXPORT_SYMBOL_GPL(xpcs_config_eee);
static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs) static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
{ {
int ret; int ret;
...@@ -726,7 +726,10 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs) ...@@ -726,7 +726,10 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret |= DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; if (phylink_autoneg_inband(mode))
ret |= DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
else
ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
} }
...@@ -772,7 +775,7 @@ static int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface, ...@@ -772,7 +775,7 @@ static int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
} }
break; break;
case DW_AN_C37_SGMII: case DW_AN_C37_SGMII:
ret = xpcs_config_aneg_c37_sgmii(xpcs); ret = xpcs_config_aneg_c37_sgmii(xpcs, mode);
if (ret) if (ret)
return ret; return ret;
break; break;
...@@ -905,6 +908,36 @@ static void xpcs_get_state(struct phylink_pcs *pcs, ...@@ -905,6 +908,36 @@ static void xpcs_get_state(struct phylink_pcs *pcs,
} }
} }
static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int mode,
int speed, int duplex)
{
int val, ret;
if (phylink_autoneg_inband(mode))
return;
switch (speed) {
case SPEED_1000:
val = BMCR_SPEED1000;
break;
case SPEED_100:
val = BMCR_SPEED100;
break;
case SPEED_10:
val = BMCR_SPEED10;
break;
default:
return;
}
if (duplex == DUPLEX_FULL)
val |= BMCR_FULLDPLX;
ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val);
if (ret)
pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret));
}
static void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode, static void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
phy_interface_t interface, int speed, int duplex) phy_interface_t interface, int speed, int duplex)
{ {
...@@ -912,6 +945,8 @@ static void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode, ...@@ -912,6 +945,8 @@ static void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
if (interface == PHY_INTERFACE_MODE_USXGMII) if (interface == PHY_INTERFACE_MODE_USXGMII)
return xpcs_config_usxgmii(xpcs, speed); return xpcs_config_usxgmii(xpcs, speed);
if (interface == PHY_INTERFACE_MODE_SGMII)
return xpcs_link_up_sgmii(xpcs, mode, speed, duplex);
} }
static u32 xpcs_get_id(struct dw_xpcs *xpcs) static u32 xpcs_get_id(struct dw_xpcs *xpcs)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment