In xemacps_reinit_for_txtimeout(), do not hold tx_lock when calling
tasklet_disable(). If xemacps_tx_poll() starts to run between acquiring
tx_lock and tasklet_disable(), we are caught in a deadlock because
tasklet_disable() waits until xemacps_tx_poll() has finished.
Also use netif_wake_queue() instead of netif_start_queue(), and don't
forget to update ndev->trans_start.
Signed-off-by: Thomas Betker <thomas.betker@rohde-schwarz.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
int rc;
netif_stop_queue(lp->ndev);
- spin_lock_bh(&lp->tx_lock);
napi_disable(&lp->napi);
tasklet_disable(&lp->tx_bdreclaim_tasklet);
+ spin_lock_bh(&lp->tx_lock);
xemacps_reset_hw(lp);
spin_unlock_bh(&lp->tx_lock);
lp->link = 0;
lp->speed = 0;
lp->duplex = -1;
+
if (lp->phy_dev)
phy_start(lp->phy_dev);
+
napi_enable(&lp->napi);
tasklet_enable(&lp->tx_bdreclaim_tasklet);
- netif_start_queue(lp->ndev);
+ lp->ndev->trans_start = jiffies;
+ netif_wake_queue(lp->ndev);
}
/**