net: bcmgenet: update UMAC_CMD only when link is detected
authorFlorian Fainelli <f.fainelli@gmail.com>
Mon, 11 Aug 2014 21:50:44 +0000 (14:50 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 11 Aug 2014 22:10:11 +0000 (15:10 -0700)
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>
drivers/net/ethernet/broadcom/genet/bcmmii.c

index b56f1bbb17bf51ea32f30d1fc15e80ffea902459..c88f7ae9963698b97837dc094f96d8b163c512c7 100644 (file)
@@ -129,7 +129,10 @@ static void bcmgenet_mii_setup(struct net_device *dev)
                        cmd_bits |= CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE;
        }
 
-       if (status_changed) {
+       if (!status_changed)
+               return;
+
+       if (phydev->link) {
                reg = bcmgenet_umac_readl(priv, UMAC_CMD);
                reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
                               CMD_HD_EN |
@@ -137,8 +140,9 @@ static void bcmgenet_mii_setup(struct net_device *dev)
                reg |= cmd_bits;
                bcmgenet_umac_writel(priv, reg, UMAC_CMD);
 
-               phy_print_status(phydev);
        }
+
+       phy_print_status(phydev);
 }
 
 void bcmgenet_mii_reset(struct net_device *dev)