diff options
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 a4c3f5708246..acbdab3d66ca 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
| @@ -2050,12 +2050,16 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) | |||
| 2050 | 2050 | ||
| 2051 | ugeth_vdbg("%s: IN", __func__); | 2051 | ugeth_vdbg("%s: IN", __func__); |
| 2052 | 2052 | ||
| 2053 | /* | ||
| 2054 | * Tell the kernel the link is down. | ||
| 2055 | * Must be done before disabling the controller | ||
| 2056 | * or deadlock may happen. | ||
| 2057 | */ | ||
| 2058 | phy_stop(phydev); | ||
| 2059 | |||
| 2053 | /* Disable the controller */ | 2060 | /* Disable the controller */ |
| 2054 | ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); | 2061 | ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); |
| 2055 | 2062 | ||
| 2056 | /* Tell the kernel the link is down */ | ||
| 2057 | phy_stop(phydev); | ||
| 2058 | |||
| 2059 | /* Mask all interrupts */ | 2063 | /* Mask all interrupts */ |
| 2060 | out_be32(ugeth->uccf->p_uccm, 0x00000000); | 2064 | out_be32(ugeth->uccf->p_uccm, 0x00000000); |
| 2061 | 2065 | ||
| @@ -2065,9 +2069,6 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) | |||
| 2065 | /* Disable Rx and Tx */ | 2069 | /* Disable Rx and Tx */ |
| 2066 | clrbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); | 2070 | clrbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); |
| 2067 | 2071 | ||
| 2068 | phy_disconnect(ugeth->phydev); | ||
| 2069 | ugeth->phydev = NULL; | ||
| 2070 | |||
| 2071 | ucc_geth_memclean(ugeth); | 2072 | ucc_geth_memclean(ugeth); |
| 2072 | } | 2073 | } |
| 2073 | 2074 | ||
| @@ -3550,7 +3551,10 @@ static int ucc_geth_close(struct net_device *dev) | |||
| 3550 | 3551 | ||
| 3551 | napi_disable(&ugeth->napi); | 3552 | napi_disable(&ugeth->napi); |
| 3552 | 3553 | ||
| 3554 | cancel_work_sync(&ugeth->timeout_work); | ||
| 3553 | ucc_geth_stop(ugeth); | 3555 | ucc_geth_stop(ugeth); |
| 3556 | phy_disconnect(ugeth->phydev); | ||
| 3557 | ugeth->phydev = NULL; | ||
| 3554 | 3558 | ||
| 3555 | free_irq(ugeth->ug_info->uf_info.irq, ugeth->ndev); | 3559 | free_irq(ugeth->ug_info->uf_info.irq, ugeth->ndev); |
| 3556 | 3560 | ||
| @@ -3579,8 +3583,12 @@ static void ucc_geth_timeout_work(struct work_struct *work) | |||
| 3579 | * Must reset MAC *and* PHY. This is done by reopening | 3583 | * Must reset MAC *and* PHY. This is done by reopening |
| 3580 | * the device. | 3584 | * the device. |
| 3581 | */ | 3585 | */ |
| 3582 | ucc_geth_close(dev); | 3586 | netif_tx_stop_all_queues(dev); |
| 3583 | ucc_geth_open(dev); | 3587 | ucc_geth_stop(ugeth); |
| 3588 | ucc_geth_init_mac(ugeth); | ||
| 3589 | /* Must start PHY here */ | ||
| 3590 | phy_start(ugeth->phydev); | ||
| 3591 | netif_tx_start_all_queues(dev); | ||
| 3584 | } | 3592 | } |
| 3585 | 3593 | ||
| 3586 | netif_tx_schedule_all(dev); | 3594 | netif_tx_schedule_all(dev); |
| @@ -3594,7 +3602,6 @@ static void ucc_geth_timeout(struct net_device *dev) | |||
| 3594 | { | 3602 | { |
| 3595 | struct ucc_geth_private *ugeth = netdev_priv(dev); | 3603 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
| 3596 | 3604 | ||
| 3597 | netif_carrier_off(dev); | ||
| 3598 | schedule_work(&ugeth->timeout_work); | 3605 | schedule_work(&ugeth->timeout_work); |
| 3599 | } | 3606 | } |
| 3600 | 3607 | ||
