]> err.no Git - linux-2.6/commitdiff
ixgb: add tx timeout counter
authorAuke Kok <auke-jan.h.kok@intel.com>
Tue, 23 May 2006 17:35:04 +0000 (10:35 -0700)
committerAuke Kok <juke-jan.h.kok@intel.com>
Tue, 23 May 2006 17:35:04 +0000 (10:35 -0700)
This adds a TX timeout counter to the ethtool stats, a tx timeout
debug message, and sets the timer to 5 seconds.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Signed-off-by: John Ronciak <john.ronciak@intel.com>
drivers/net/ixgb/ixgb.h
drivers/net/ixgb/ixgb_ethtool.c
drivers/net/ixgb/ixgb_main.c

index a687f1210cb028734d20bf25c6492da6325867f1..b9c37fdc84188b7570ba201463c3b73fad259965 100644 (file)
@@ -180,6 +180,7 @@ struct ixgb_adapter {
        uint64_t hw_csum_tx_good;
        uint64_t hw_csum_tx_error;
        uint32_t tx_int_delay;
+       uint32_t tx_timeout_count;
        boolean_t tx_int_delay_enable;
        boolean_t detect_tx_hung;
 
index 560b4b6c79d0a8293022847fa180c51ad0c67d99..6d8192f4314c9911a2056c349dc1b7036ba3e95e 100644 (file)
@@ -78,6 +78,7 @@ static struct ixgb_stats ixgb_gstrings_stats[] = {
        {"tx_heartbeat_errors", IXGB_STAT(net_stats.tx_heartbeat_errors)},
        {"tx_window_errors", IXGB_STAT(net_stats.tx_window_errors)},
        {"tx_deferred_ok", IXGB_STAT(stats.dc)},
+       {"tx_timeout_count", IXGB_STAT(tx_timeout_count) },
        {"rx_long_length_errors", IXGB_STAT(stats.roc)},
        {"rx_short_length_errors", IXGB_STAT(stats.ruc)},
 #ifdef NETIF_F_TSO
index 4115bf360d93c6367d3b7734d49609a08c27075c..da0b91905ffc8df4dde31a230052cc47ef8fc41a 100644 (file)
@@ -428,7 +428,7 @@ ixgb_probe(struct pci_dev *pdev,
        netdev->change_mtu = &ixgb_change_mtu;
        ixgb_set_ethtool_ops(netdev);
        netdev->tx_timeout = &ixgb_tx_timeout;
-       netdev->watchdog_timeo = HZ;
+       netdev->watchdog_timeo = 5 * HZ;
 #ifdef CONFIG_IXGB_NAPI
        netdev->poll = &ixgb_clean;
        netdev->weight = 64;
@@ -1509,6 +1509,7 @@ ixgb_tx_timeout_task(struct net_device *netdev)
 {
        struct ixgb_adapter *adapter = netdev_priv(netdev);
 
+       adapter->tx_timeout_count++;
        ixgb_down(adapter, TRUE);
        ixgb_up(adapter);
 }
@@ -1838,11 +1839,31 @@ ixgb_clean_tx_irq(struct ixgb_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)
+               if (tx_ring->buffer_info[eop].dma &&
+                  time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + HZ)
                   && !(IXGB_READ_REG(&adapter->hw, STATUS) &
-                       IXGB_STATUS_TXOFF))
+                       IXGB_STATUS_TXOFF)) {
+                       /* detected Tx unit hang */
+                       DPRINTK(DRV, 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"
+                                       "  time_stamp           <%lx>\n"
+                                       "  next_to_watch        <%x>\n"
+                                       "  jiffies              <%lx>\n"
+                                       "  next_to_watch.status <%x>\n",
+                               IXGB_READ_REG(&adapter->hw, TDH),
+                               IXGB_READ_REG(&adapter->hw, TDT),
+                               tx_ring->next_to_use,
+                               tx_ring->next_to_clean,
+                               tx_ring->buffer_info[eop].time_stamp,
+                               eop,
+                               jiffies,
+                               eop_desc->status);
                        netif_stop_queue(netdev);
+               }
        }
 
        return cleaned;