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: b6e978e504
("net: bcmgenet: add suspend/resume callbacks")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
93ecd2607f
Коммит
c96e731c93
|
@ -2140,6 +2140,9 @@ static int bcmgenet_open(struct net_device *dev)
|
||||||
goto err_irq0;
|
goto err_irq0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
phy_connect_direct(dev, priv->phydev, bcmgenet_mii_setup,
|
||||||
|
priv->phy_interface);
|
||||||
|
|
||||||
bcmgenet_netif_start(dev);
|
bcmgenet_netif_start(dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2184,6 +2187,9 @@ static int bcmgenet_close(struct net_device *dev)
|
||||||
|
|
||||||
bcmgenet_netif_stop(dev);
|
bcmgenet_netif_stop(dev);
|
||||||
|
|
||||||
|
/* Really kill the PHY state machine and disconnect from it */
|
||||||
|
phy_disconnect(priv->phydev);
|
||||||
|
|
||||||
/* Disable MAC receive */
|
/* Disable MAC receive */
|
||||||
umac_enable_set(priv, CMD_RX_EN, false);
|
umac_enable_set(priv, CMD_RX_EN, false);
|
||||||
|
|
||||||
|
|
|
@ -620,6 +620,7 @@ int bcmgenet_mii_init(struct net_device *dev);
|
||||||
int bcmgenet_mii_config(struct net_device *dev);
|
int bcmgenet_mii_config(struct net_device *dev);
|
||||||
void bcmgenet_mii_exit(struct net_device *dev);
|
void bcmgenet_mii_exit(struct net_device *dev);
|
||||||
void bcmgenet_mii_reset(struct net_device *dev);
|
void bcmgenet_mii_reset(struct net_device *dev);
|
||||||
|
void bcmgenet_mii_setup(struct net_device *dev);
|
||||||
|
|
||||||
/* Wake-on-LAN routines */
|
/* Wake-on-LAN routines */
|
||||||
void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
|
void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
|
||||||
|
|
|
@ -77,7 +77,7 @@ static int bcmgenet_mii_write(struct mii_bus *bus, int phy_id,
|
||||||
/* setup netdev link state when PHY link status change and
|
/* setup netdev link state when PHY link status change and
|
||||||
* update UMAC and RGMII block when link up
|
* update UMAC and RGMII block when link up
|
||||||
*/
|
*/
|
||||||
static void bcmgenet_mii_setup(struct net_device *dev)
|
void bcmgenet_mii_setup(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct bcmgenet_priv *priv = netdev_priv(dev);
|
struct bcmgenet_priv *priv = netdev_priv(dev);
|
||||||
struct phy_device *phydev = priv->phydev;
|
struct phy_device *phydev = priv->phydev;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче