diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2014-11-10 21:06:20 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-11 18:23:23 -0500 |
commit | c96e731c93ff0c9f53442c11c68e50fd07929d27 (patch) | |
tree | d3eafd8dd781b00ee660406be1143a94df87e87f | |
parent | 93ecd2607f55f99ec0022f53f8224566c8ec797f (diff) |
net: bcmgenet: connect and disconnect from the PHY state machine
phy_disconnect() is the only way to guarantee that we are not going to
schedule more work on the PHY state machine workqueue for that
particular PHY device.
This fixes an issue where a network interface was suspended prior to a
system suspend/resume cycle and would then be resumed as part of
mdio_bus_resume(), since the GENET interface clocks would have been
disabled, this basically resulted in bus errors to appear since we are
invoking the GENET driver adjust_link() callback.
Fixes: b6e978e50444 ("net: bcmgenet: add suspend/resume callbacks")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/genet/bcmgenet.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 |
3 files changed, 8 insertions, 1 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index fdc9ec09e453..34055fd59c74 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c | |||
@@ -2140,6 +2140,9 @@ static int bcmgenet_open(struct net_device *dev) | |||
2140 | goto err_irq0; | 2140 | goto err_irq0; |
2141 | } | 2141 | } |
2142 | 2142 | ||
2143 | phy_connect_direct(dev, priv->phydev, bcmgenet_mii_setup, | ||
2144 | priv->phy_interface); | ||
2145 | |||
2143 | bcmgenet_netif_start(dev); | 2146 | bcmgenet_netif_start(dev); |
2144 | 2147 | ||
2145 | return 0; | 2148 | return 0; |
@@ -2184,6 +2187,9 @@ static int bcmgenet_close(struct net_device *dev) | |||
2184 | 2187 | ||
2185 | bcmgenet_netif_stop(dev); | 2188 | bcmgenet_netif_stop(dev); |
2186 | 2189 | ||
2190 | /* Really kill the PHY state machine and disconnect from it */ | ||
2191 | phy_disconnect(priv->phydev); | ||
2192 | |||
2187 | /* Disable MAC receive */ | 2193 | /* Disable MAC receive */ |
2188 | umac_enable_set(priv, CMD_RX_EN, false); | 2194 | umac_enable_set(priv, CMD_RX_EN, false); |
2189 | 2195 | ||
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index dbf524ea3b19..44b55b8c220f 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h | |||
@@ -620,6 +620,7 @@ int bcmgenet_mii_init(struct net_device *dev); | |||
620 | int bcmgenet_mii_config(struct net_device *dev); | 620 | int bcmgenet_mii_config(struct net_device *dev); |
621 | void bcmgenet_mii_exit(struct net_device *dev); | 621 | void bcmgenet_mii_exit(struct net_device *dev); |
622 | void bcmgenet_mii_reset(struct net_device *dev); | 622 | void bcmgenet_mii_reset(struct net_device *dev); |
623 | void bcmgenet_mii_setup(struct net_device *dev); | ||
623 | 624 | ||
624 | /* Wake-on-LAN routines */ | 625 | /* Wake-on-LAN routines */ |
625 | void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol); | 626 | void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol); |
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 9ff799a9f801..9c5fee782ccf 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c | |||
@@ -77,7 +77,7 @@ static int bcmgenet_mii_write(struct mii_bus *bus, int phy_id, | |||
77 | /* setup netdev link state when PHY link status change and | 77 | /* setup netdev link state when PHY link status change and |
78 | * update UMAC and RGMII block when link up | 78 | * update UMAC and RGMII block when link up |
79 | */ | 79 | */ |
80 | static void bcmgenet_mii_setup(struct net_device *dev) | 80 | void bcmgenet_mii_setup(struct net_device *dev) |
81 | { | 81 | { |
82 | struct bcmgenet_priv *priv = netdev_priv(dev); | 82 | struct bcmgenet_priv *priv = netdev_priv(dev); |
83 | struct phy_device *phydev = priv->phydev; | 83 | struct phy_device *phydev = priv->phydev; |