Commit a3a47cfb authored by Russell King (Oracle)'s avatar Russell King (Oracle) Committed by Jakub Kicinski

net: pcs: xpcs: update PCS driver to use neg_mode

Update xpcs to use neg_mode to configure whether inband negotiation
should be used. We need to update sja1105 as well as that directly
calls into the XPCS driver's config function.
Signed-off-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://lore.kernel.org/r/E1qA8Dt-00EaFS-W9@rmk-PC.armlinux.org.ukSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent febf2aaf
...@@ -2314,7 +2314,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv, ...@@ -2314,7 +2314,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
for (i = 0; i < ds->num_ports; i++) { for (i = 0; i < ds->num_ports; i++) {
struct dw_xpcs *xpcs = priv->xpcs[i]; struct dw_xpcs *xpcs = priv->xpcs[i];
unsigned int mode; unsigned int neg_mode;
rc = sja1105_adjust_port_config(priv, i, speed_mbps[i]); rc = sja1105_adjust_port_config(priv, i, speed_mbps[i]);
if (rc < 0) if (rc < 0)
...@@ -2324,17 +2324,15 @@ int sja1105_static_config_reload(struct sja1105_private *priv, ...@@ -2324,17 +2324,15 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
continue; continue;
if (bmcr[i] & BMCR_ANENABLE) if (bmcr[i] & BMCR_ANENABLE)
mode = MLO_AN_INBAND; neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
else if (priv->fixed_link[i])
mode = MLO_AN_FIXED;
else else
mode = MLO_AN_PHY; neg_mode = PHYLINK_PCS_NEG_OUTBAND;
rc = xpcs_do_config(xpcs, priv->phy_mode[i], mode, NULL); rc = xpcs_do_config(xpcs, priv->phy_mode[i], NULL, neg_mode);
if (rc < 0) if (rc < 0)
goto out; goto out;
if (!phylink_autoneg_inband(mode)) { if (neg_mode == PHYLINK_PCS_NEG_OUTBAND) {
int speed = SPEED_UNKNOWN; int speed = SPEED_UNKNOWN;
if (priv->phy_mode[i] == PHY_INTERFACE_MODE_2500BASEX) if (priv->phy_mode[i] == PHY_INTERFACE_MODE_2500BASEX)
...@@ -2346,7 +2344,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv, ...@@ -2346,7 +2344,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
else else
speed = SPEED_10; speed = SPEED_10;
xpcs_link_up(&xpcs->pcs, mode, priv->phy_mode[i], xpcs_link_up(&xpcs->pcs, neg_mode, priv->phy_mode[i],
speed, DUPLEX_FULL); speed, DUPLEX_FULL);
} }
} }
......
...@@ -657,7 +657,8 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) ...@@ -657,7 +657,8 @@ 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, unsigned int mode) static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
unsigned int neg_mode)
{ {
int ret, mdio_ctrl; int ret, mdio_ctrl;
...@@ -707,7 +708,7 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) ...@@ -707,7 +708,7 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
if (ret < 0) if (ret < 0)
return ret; return ret;
if (phylink_autoneg_inband(mode)) if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
ret |= DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; ret |= DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
else else
ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
...@@ -716,14 +717,15 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) ...@@ -716,14 +717,15 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
if (ret < 0) if (ret < 0)
return ret; return ret;
if (phylink_autoneg_inband(mode)) if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
mdio_ctrl | AN_CL37_EN); mdio_ctrl | AN_CL37_EN);
return ret; return ret;
} }
static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs, unsigned int mode, static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs,
unsigned int neg_mode,
const unsigned long *advertising) const unsigned long *advertising)
{ {
phy_interface_t interface = PHY_INTERFACE_MODE_1000BASEX; phy_interface_t interface = PHY_INTERFACE_MODE_1000BASEX;
...@@ -774,8 +776,7 @@ static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs, unsigned int mod ...@@ -774,8 +776,7 @@ static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs, unsigned int mod
if (ret < 0) if (ret < 0)
return ret; return ret;
if (phylink_autoneg_inband(mode) && if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, advertising)) {
ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
mdio_ctrl | AN_CL37_EN); mdio_ctrl | AN_CL37_EN);
if (ret < 0) if (ret < 0)
...@@ -808,7 +809,7 @@ static int xpcs_config_2500basex(struct dw_xpcs *xpcs) ...@@ -808,7 +809,7 @@ static int xpcs_config_2500basex(struct dw_xpcs *xpcs)
} }
int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface, int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
unsigned int mode, const unsigned long *advertising) const unsigned long *advertising, unsigned int neg_mode)
{ {
const struct xpcs_compat *compat; const struct xpcs_compat *compat;
int ret; int ret;
...@@ -821,19 +822,19 @@ int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface, ...@@ -821,19 +822,19 @@ int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
case DW_10GBASER: case DW_10GBASER:
break; break;
case DW_AN_C73: case DW_AN_C73:
if (test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, advertising)) { if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
ret = xpcs_config_aneg_c73(xpcs, compat); ret = xpcs_config_aneg_c73(xpcs, compat);
if (ret) if (ret)
return ret; return ret;
} }
break; break;
case DW_AN_C37_SGMII: case DW_AN_C37_SGMII:
ret = xpcs_config_aneg_c37_sgmii(xpcs, mode); ret = xpcs_config_aneg_c37_sgmii(xpcs, neg_mode);
if (ret) if (ret)
return ret; return ret;
break; break;
case DW_AN_C37_1000BASEX: case DW_AN_C37_1000BASEX:
ret = xpcs_config_aneg_c37_1000basex(xpcs, mode, ret = xpcs_config_aneg_c37_1000basex(xpcs, neg_mode,
advertising); advertising);
if (ret) if (ret)
return ret; return ret;
...@@ -857,14 +858,14 @@ int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface, ...@@ -857,14 +858,14 @@ int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
} }
EXPORT_SYMBOL_GPL(xpcs_do_config); EXPORT_SYMBOL_GPL(xpcs_do_config);
static int xpcs_config(struct phylink_pcs *pcs, unsigned int mode, static int xpcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
phy_interface_t interface, phy_interface_t interface,
const unsigned long *advertising, const unsigned long *advertising,
bool permit_pause_to_mac) bool permit_pause_to_mac)
{ {
struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
return xpcs_do_config(xpcs, interface, mode, advertising); return xpcs_do_config(xpcs, interface, advertising, neg_mode);
} }
static int xpcs_get_state_c73(struct dw_xpcs *xpcs, static int xpcs_get_state_c73(struct dw_xpcs *xpcs,
...@@ -898,7 +899,8 @@ static int xpcs_get_state_c73(struct dw_xpcs *xpcs, ...@@ -898,7 +899,8 @@ static int xpcs_get_state_c73(struct dw_xpcs *xpcs,
state->link = 0; state->link = 0;
return xpcs_do_config(xpcs, state->interface, MLO_AN_INBAND, NULL); return xpcs_do_config(xpcs, state->interface, NULL,
PHYLINK_PCS_NEG_INBAND_ENABLED);
} }
/* There is no point doing anything else if the link is down. */ /* There is no point doing anything else if the link is down. */
...@@ -1046,12 +1048,12 @@ static void xpcs_get_state(struct phylink_pcs *pcs, ...@@ -1046,12 +1048,12 @@ static void xpcs_get_state(struct phylink_pcs *pcs,
} }
} }
static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int mode, static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int neg_mode,
int speed, int duplex) int speed, int duplex)
{ {
int val, ret; int val, ret;
if (phylink_autoneg_inband(mode)) if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
return; return;
val = mii_bmcr_encode_fixed(speed, duplex); val = mii_bmcr_encode_fixed(speed, duplex);
...@@ -1060,12 +1062,12 @@ static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int mode, ...@@ -1060,12 +1062,12 @@ static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int mode,
pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret)); pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret));
} }
static void xpcs_link_up_1000basex(struct dw_xpcs *xpcs, unsigned int mode, static void xpcs_link_up_1000basex(struct dw_xpcs *xpcs, unsigned int neg_mode,
int speed, int duplex) int speed, int duplex)
{ {
int val, ret; int val, ret;
if (phylink_autoneg_inband(mode)) if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
return; return;
switch (speed) { switch (speed) {
...@@ -1089,7 +1091,7 @@ static void xpcs_link_up_1000basex(struct dw_xpcs *xpcs, unsigned int mode, ...@@ -1089,7 +1091,7 @@ static void xpcs_link_up_1000basex(struct dw_xpcs *xpcs, unsigned int mode,
pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret)); pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret));
} }
void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode, void xpcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
phy_interface_t interface, int speed, int duplex) phy_interface_t interface, int speed, int duplex)
{ {
struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
...@@ -1097,9 +1099,9 @@ void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode, ...@@ -1097,9 +1099,9 @@ 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) if (interface == PHY_INTERFACE_MODE_SGMII)
return xpcs_link_up_sgmii(xpcs, mode, speed, duplex); return xpcs_link_up_sgmii(xpcs, neg_mode, speed, duplex);
if (interface == PHY_INTERFACE_MODE_1000BASEX) if (interface == PHY_INTERFACE_MODE_1000BASEX)
return xpcs_link_up_1000basex(xpcs, mode, speed, duplex); return xpcs_link_up_1000basex(xpcs, neg_mode, speed, duplex);
} }
EXPORT_SYMBOL_GPL(xpcs_link_up); EXPORT_SYMBOL_GPL(xpcs_link_up);
...@@ -1283,6 +1285,7 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev, ...@@ -1283,6 +1285,7 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
} }
xpcs->pcs.ops = &xpcs_phylink_ops; xpcs->pcs.ops = &xpcs_phylink_ops;
xpcs->pcs.neg_mode = true;
if (compat->an_mode == DW_10GBASER) if (compat->an_mode == DW_10GBASER)
return xpcs; return xpcs;
......
...@@ -29,10 +29,10 @@ struct dw_xpcs { ...@@ -29,10 +29,10 @@ struct dw_xpcs {
}; };
int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface); int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface);
void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode, void xpcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
phy_interface_t interface, int speed, int duplex); phy_interface_t interface, int speed, int duplex);
int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface, int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
unsigned int mode, const unsigned long *advertising); const unsigned long *advertising, unsigned int neg_mode);
void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces); void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces);
int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
int enable); int enable);
......
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