Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: bcmgenet: update UMAC_CMD only when link is detected

When we bring the interface down, phy_stop() will schedule the PHY state
machine to call our link adjustment callback. By the time we do so, we
may have clock gated off the GENET hardware block, and this will cause
bus errors to happen in bcmgenet_mii_setup():

Make sure that we only touch the UMAC_CMD register when there is an
actual link. This is safe to do for two reasons:

- updating the Ethernet MAC registers only make sense when a physical
link is present
- the PHY library state machine first set phydev->link = 0 before
invoking phydev->adjust_link in the PHY_HALTED case

Fixes: 240524089d7a ("net: bcmgenet: only update UMAC_CMD if something changed")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Florian Fainelli and committed by
David S. Miller
c677ba8b cc013fb4

+6 -2
+6 -2
drivers/net/ethernet/broadcom/genet/bcmmii.c
··· 129 129 cmd_bits |= CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE; 130 130 } 131 131 132 - if (status_changed) { 132 + if (!status_changed) 133 + return; 134 + 135 + if (phydev->link) { 133 136 reg = bcmgenet_umac_readl(priv, UMAC_CMD); 134 137 reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) | 135 138 CMD_HD_EN | ··· 140 137 reg |= cmd_bits; 141 138 bcmgenet_umac_writel(priv, reg, UMAC_CMD); 142 139 143 - phy_print_status(phydev); 144 140 } 141 + 142 + phy_print_status(phydev); 145 143 } 146 144 147 145 void bcmgenet_mii_reset(struct net_device *dev)