mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
net: marvell: mvpp2: fix stuck in-band SGMII negotiation
[ Upstream commit 316734fdcf ]
It appears that the mvpp22 can get stuck with SGMII negotiation. The
symptoms are that in-band negotiation never completes and the partner
(eg, PHY) never reports SGMII link up, or if it supports negotiation
bypass, goes into negotiation bypass mode (which will happen when the
PHY sees that the MAC is alive but gets no response.)
Triggering the PHY end of the link to re-negotiate results in the
bypass bit clearing on the PHY, and then re-setting - indicating that
the problem is at the mvpp22 GMAC end.
Asserting the GMAC reset and de-asserting it resolves the issue.
Arrange to assert the GMAC reset at probe time, and deassert it only
after we have configured the GMAC for the appropriate mode. This
resolves the issue.
Tested-by: Sven Auhagen <sven.auhagen@voleatech.de>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
1f3694865d
commit
a78aae93ba
@@ -1372,13 +1372,9 @@ static void mvpp2_port_reset(struct mvpp2_port *port)
|
||||
for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_regs); i++)
|
||||
mvpp2_read_count(port, &mvpp2_ethtool_regs[i]);
|
||||
|
||||
val = readl(port->base + MVPP2_GMAC_CTRL_2_REG) &
|
||||
~MVPP2_GMAC_PORT_RESET_MASK;
|
||||
val = readl(port->base + MVPP2_GMAC_CTRL_2_REG) |
|
||||
MVPP2_GMAC_PORT_RESET_MASK;
|
||||
writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);
|
||||
|
||||
while (readl(port->base + MVPP2_GMAC_CTRL_2_REG) &
|
||||
MVPP2_GMAC_PORT_RESET_MASK)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Change maximum receive size of the port */
|
||||
@@ -4445,12 +4441,15 @@ static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
u32 an, ctrl0, ctrl2, ctrl4;
|
||||
u32 old_ctrl2;
|
||||
|
||||
an = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
|
||||
ctrl0 = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
|
||||
ctrl2 = readl(port->base + MVPP2_GMAC_CTRL_2_REG);
|
||||
ctrl4 = readl(port->base + MVPP22_GMAC_CTRL_4_REG);
|
||||
|
||||
old_ctrl2 = ctrl2;
|
||||
|
||||
/* Force link down */
|
||||
an &= ~MVPP2_GMAC_FORCE_LINK_PASS;
|
||||
an |= MVPP2_GMAC_FORCE_LINK_DOWN;
|
||||
@@ -4523,6 +4522,12 @@ static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode,
|
||||
writel(ctrl2, port->base + MVPP2_GMAC_CTRL_2_REG);
|
||||
writel(ctrl4, port->base + MVPP22_GMAC_CTRL_4_REG);
|
||||
writel(an, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
|
||||
|
||||
if (old_ctrl2 & MVPP2_GMAC_PORT_RESET_MASK) {
|
||||
while (readl(port->base + MVPP2_GMAC_CTRL_2_REG) &
|
||||
MVPP2_GMAC_PORT_RESET_MASK)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
|
||||
|
||||
Reference in New Issue
Block a user