e1000/e1000e/igb/ixgb: don't txhang after link down
[safe/jmp/linux-2.6] / drivers / net / e1000e / netdev.c
index c0ff550..ccaaee0 100644 (file)
@@ -621,7 +621,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
        struct e1000_buffer *buffer_info;
        unsigned int i, eop;
        unsigned int count = 0;
-       bool cleaned = false;
        unsigned int total_tx_bytes = 0, total_tx_packets = 0;
 
        i = tx_ring->next_to_clean;
@@ -630,7 +629,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 
        while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
               (count < tx_ring->count)) {
-               for (cleaned = 0; !cleaned; count++) {
+               bool cleaned = false;
+               for (; !cleaned; count++) {
                        tx_desc = E1000_TX_DESC(*tx_ring, i);
                        buffer_info = &tx_ring->buffer_info[i];
                        cleaned = (i == eop);
@@ -661,8 +661,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
        tx_ring->next_to_clean = i;
 
 #define TX_WAKE_THRESHOLD 32
-       if (cleaned && netif_carrier_ok(netdev) &&
-                    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
+       if (count && netif_carrier_ok(netdev) &&
+           e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
                /* Make sure that anybody stopping the queue after this
                 * sees the new next_to_clean.
                 */
@@ -2826,6 +2826,8 @@ int e1000e_up(struct e1000_adapter *adapter)
                e1000_configure_msix(adapter);
        e1000_irq_enable(adapter);
 
+       netif_wake_queue(adapter->netdev);
+
        /* fire a link change interrupt to start the watchdog */
        ew32(ICS, E1000_ICS_LSC);
        return 0;
@@ -2848,7 +2850,7 @@ void e1000e_down(struct e1000_adapter *adapter)
        ew32(RCTL, rctl & ~E1000_RCTL_EN);
        /* flush and sleep below */
 
-       netif_tx_stop_all_queues(netdev);
+       netif_stop_queue(netdev);
 
        /* disable transmits in the hardware */
        tctl = er32(TCTL);
@@ -3130,7 +3132,7 @@ static int e1000_open(struct net_device *netdev)
 
        e1000_irq_enable(adapter);
 
-       netif_tx_start_all_queues(netdev);
+       netif_start_queue(netdev);
 
        /* fire a link status change interrupt to start the watchdog */
        ew32(ICS, E1000_ICS_LSC);
@@ -3600,7 +3602,6 @@ static void e1000_watchdog_task(struct work_struct *work)
                                phy->ops.cfg_on_link_up(hw);
 
                        netif_carrier_on(netdev);
-                       netif_tx_wake_all_queues(netdev);
 
                        if (!test_bit(__E1000_DOWN, &adapter->state))
                                mod_timer(&adapter->phy_info_timer,
@@ -3614,7 +3615,6 @@ static void e1000_watchdog_task(struct work_struct *work)
                        printk(KERN_INFO "e1000e: %s NIC Link is Down\n",
                               adapter->netdev->name);
                        netif_carrier_off(netdev);
-                       netif_tx_stop_all_queues(netdev);
                        if (!test_bit(__E1000_DOWN, &adapter->state))
                                mod_timer(&adapter->phy_info_timer,
                                          round_jiffies(jiffies + 2 * HZ));
@@ -3651,6 +3651,8 @@ link_up:
                         */
                        adapter->tx_timeout_count++;
                        schedule_work(&adapter->reset_task);
+                       /* return immediately since reset is imminent */
+                       return;
                }
        }