|
@@ -2442,10 +2442,37 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
|
|
|
/* detect a transmit hang in hardware, this serializes the
|
|
|
* check with the clearing of time_stamp and movement of i */
|
|
|
adapter->detect_tx_hung = FALSE;
|
|
|
- if(tx_ring->buffer_info[i].dma &&
|
|
|
- time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ) &&
|
|
|
- !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF))
|
|
|
+ if (tx_ring->buffer_info[i].dma &&
|
|
|
+ time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ)
|
|
|
+ && !(E1000_READ_REG(&adapter->hw, STATUS) &
|
|
|
+ E1000_STATUS_TXOFF)) {
|
|
|
+
|
|
|
+ /* detected Tx unit hang */
|
|
|
+ i = tx_ring->next_to_clean;
|
|
|
+ eop = tx_ring->buffer_info[i].next_to_watch;
|
|
|
+ eop_desc = E1000_TX_DESC(*tx_ring, eop);
|
|
|
+ DPRINTK(TX_ERR, ERR, "Detected Tx Unit Hang\n"
|
|
|
+ " TDH <%x>\n"
|
|
|
+ " TDT <%x>\n"
|
|
|
+ " next_to_use <%x>\n"
|
|
|
+ " next_to_clean <%x>\n"
|
|
|
+ "buffer_info[next_to_clean]\n"
|
|
|
+ " dma <%llx>\n"
|
|
|
+ " time_stamp <%lx>\n"
|
|
|
+ " next_to_watch <%x>\n"
|
|
|
+ " jiffies <%lx>\n"
|
|
|
+ " next_to_watch.status <%x>\n",
|
|
|
+ E1000_READ_REG(&adapter->hw, TDH),
|
|
|
+ E1000_READ_REG(&adapter->hw, TDT),
|
|
|
+ tx_ring->next_to_use,
|
|
|
+ i,
|
|
|
+ tx_ring->buffer_info[i].dma,
|
|
|
+ tx_ring->buffer_info[i].time_stamp,
|
|
|
+ eop,
|
|
|
+ jiffies,
|
|
|
+ eop_desc->upper.fields.status);
|
|
|
netif_stop_queue(netdev);
|
|
|
+ }
|
|
|
}
|
|
|
#ifdef NETIF_F_TSO
|
|
|
|