diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-12-23 08:41:14 +0100 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-12-23 08:41:14 +0100 |
commit | cfb13c5db08c90311a5defdde9a0328ee788cca5 (patch) | |
tree | 842cb60d1d19b99e550fdbc653723e4b13e51ee5 /drivers/net/ucc_geth.c | |
parent | of/net: Move of_get_mac_address() to a common source file. (diff) | |
parent | Linux 2.6.37-rc7 (diff) | |
download | linux-cfb13c5db08c90311a5defdde9a0328ee788cca5.tar.xz linux-cfb13c5db08c90311a5defdde9a0328ee788cca5.zip |
Merge commit 'v2.6.37-rc7' into devicetree/next
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r-- | drivers/net/ucc_geth.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index f7e370fd8ddc..73a3e0d93237 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -2051,12 +2051,16 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) ugeth_vdbg("%s: IN", __func__); + /* + * Tell the kernel the link is down. + * Must be done before disabling the controller + * or deadlock may happen. + */ + phy_stop(phydev); + /* Disable the controller */ ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); - /* Tell the kernel the link is down */ - phy_stop(phydev); - /* Mask all interrupts */ out_be32(ugeth->uccf->p_uccm, 0x00000000); @@ -2066,9 +2070,6 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) /* Disable Rx and Tx */ clrbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); - phy_disconnect(ugeth->phydev); - ugeth->phydev = NULL; - ucc_geth_memclean(ugeth); } @@ -3551,7 +3552,10 @@ static int ucc_geth_close(struct net_device *dev) napi_disable(&ugeth->napi); + cancel_work_sync(&ugeth->timeout_work); ucc_geth_stop(ugeth); + phy_disconnect(ugeth->phydev); + ugeth->phydev = NULL; free_irq(ugeth->ug_info->uf_info.irq, ugeth->ndev); @@ -3580,8 +3584,12 @@ static void ucc_geth_timeout_work(struct work_struct *work) * Must reset MAC *and* PHY. This is done by reopening * the device. */ - ucc_geth_close(dev); - ucc_geth_open(dev); + netif_tx_stop_all_queues(dev); + ucc_geth_stop(ugeth); + ucc_geth_init_mac(ugeth); + /* Must start PHY here */ + phy_start(ugeth->phydev); + netif_tx_start_all_queues(dev); } netif_tx_schedule_all(dev); @@ -3595,7 +3603,6 @@ static void ucc_geth_timeout(struct net_device *dev) { struct ucc_geth_private *ugeth = netdev_priv(dev); - netif_carrier_off(dev); schedule_work(&ugeth->timeout_work); } |