Commit e3cf002d authored by Wong Vee Khee's avatar Wong Vee Khee Committed by David S. Miller

net: pcs: xpcs: fix incorrect CL37 AN sequence

According to Synopsys DesignWare Cores Ethernet PCS databook, it is
required to disable Clause 37 auto-negotiation by programming bit-12
(AN_ENABLE) to 0 if it is already enabled, before programming various
fields of VR_MII_AN_CTRL registers.

After all these programming are done, it is then required to enable
Clause 37 auto-negotiation by programming bit-12 (AN_ENABLE) to 1.

Fixes: b97b5331 ("net: pcs: add C37 SGMII AN support for intel mGbE controller")
Cc: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarWong Vee Khee <vee.khee.wong@linux.intel.com>
Reviewed-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 25a9da66
...@@ -697,14 +697,17 @@ EXPORT_SYMBOL_GPL(xpcs_config_eee); ...@@ -697,14 +697,17 @@ 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 mode)
{ {
int ret; int ret, mdio_ctrl;
/* For AN for C37 SGMII mode, the settings are :- /* For AN for C37 SGMII mode, the settings are :-
* 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN) * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case
* 2) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII) it is already enabled)
* 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
* 3) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
* DW xPCS used with DW EQoS MAC is always MAC side SGMII. * DW xPCS used with DW EQoS MAC is always MAC side SGMII.
* 3) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic
* speed/duplex mode change by HW after SGMII AN complete) * speed/duplex mode change by HW after SGMII AN complete)
* 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN)
* *
* Note: Since it is MAC side SGMII, there is no need to set * Note: Since it is MAC side SGMII, there is no need to set
* SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from * SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from
...@@ -712,6 +715,17 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) ...@@ -712,6 +715,17 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
* between PHY and Link Partner. There is also no need to * between PHY and Link Partner. There is also no need to
* trigger AN restart for MAC-side SGMII. * trigger AN restart for MAC-side SGMII.
*/ */
mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
if (mdio_ctrl < 0)
return mdio_ctrl;
if (mdio_ctrl & AN_CL37_EN) {
ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
mdio_ctrl & ~AN_CL37_EN);
if (ret < 0)
return ret;
}
ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL); ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -736,7 +750,15 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) ...@@ -736,7 +750,15 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
else else
ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
if (ret < 0)
return ret;
if (phylink_autoneg_inband(mode))
ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
mdio_ctrl | AN_CL37_EN);
return ret;
} }
static int xpcs_config_2500basex(struct dw_xpcs *xpcs) static int xpcs_config_2500basex(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