mirror of
https://github.com/torvalds/linux
synced 2024-10-28 06:09:03 +00:00
net: systemport: fix UniMAC reset logic
The UniMAC CMD_SW_RESET bit is not a self-clearing bit, so we need to assert it, wait a bit and clear it manually. As a result, umac_reset() is updated not to return any value. The previous version of the code simply wrote 0 to the CMD register, which would make the busy-waiting loop exit immediately, having zero effect. By writing 0 to the CMD register, we were clearing all bits in the CMD register, and not using the hardware reset default values which are set on purpose. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3b140a6788
commit
412bce83ac
|
@ -1254,28 +1254,17 @@ static inline void umac_enable_set(struct bcm_sysport_priv *priv,
|
||||||
usleep_range(1000, 2000);
|
usleep_range(1000, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int umac_reset(struct bcm_sysport_priv *priv)
|
static inline void umac_reset(struct bcm_sysport_priv *priv)
|
||||||
{
|
{
|
||||||
unsigned int timeout = 0;
|
|
||||||
u32 reg;
|
u32 reg;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
umac_writel(priv, 0, UMAC_CMD);
|
|
||||||
while (timeout++ < 1000) {
|
|
||||||
reg = umac_readl(priv, UMAC_CMD);
|
reg = umac_readl(priv, UMAC_CMD);
|
||||||
if (!(reg & CMD_SW_RESET))
|
reg |= CMD_SW_RESET;
|
||||||
break;
|
umac_writel(priv, reg, UMAC_CMD);
|
||||||
|
udelay(10);
|
||||||
udelay(1);
|
reg = umac_readl(priv, UMAC_CMD);
|
||||||
}
|
reg &= ~CMD_SW_RESET;
|
||||||
|
umac_writel(priv, reg, UMAC_CMD);
|
||||||
if (timeout == 1000) {
|
|
||||||
dev_err(&priv->pdev->dev,
|
|
||||||
"timeout waiting for MAC to come out of reset\n");
|
|
||||||
ret = -ETIMEDOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void umac_set_hw_addr(struct bcm_sysport_priv *priv,
|
static void umac_set_hw_addr(struct bcm_sysport_priv *priv,
|
||||||
|
@ -1303,11 +1292,7 @@ static int bcm_sysport_open(struct net_device *dev)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Reset UniMAC */
|
/* Reset UniMAC */
|
||||||
ret = umac_reset(priv);
|
umac_reset(priv);
|
||||||
if (ret) {
|
|
||||||
netdev_err(dev, "UniMAC reset failed\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Flush TX and RX FIFOs at TOPCTRL level */
|
/* Flush TX and RX FIFOs at TOPCTRL level */
|
||||||
topctrl_flush(priv);
|
topctrl_flush(priv);
|
||||||
|
|
Loading…
Reference in a new issue