From 95b3890ae39f60ad1d446b02f9439d12f01066be Mon Sep 17 00:00:00 2001 From: Himanshu Madhani Date: Thu, 23 Jan 2014 17:18:29 -0500 Subject: [PATCH] qlcnic: Enhance Tx timeout debugging. o Dump each Tx queue details with all descriptors, queue indices and Tx queue stats to imporve data colletion in situations where Tx timeout occurs. Signed-off-by: Himanshu Madhani Signed-off-by: David S. Miller --- .../ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 2 +- .../net/ethernet/qlogic/qlcnic/qlcnic_main.c | 69 ++++++++++++++----- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index f19cec860695..90a2dda351ec 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -383,7 +383,7 @@ static int qlcnic_83xx_idc_tx_soft_reset(struct qlcnic_adapter *adapter) qlcnic_up(adapter, netdev); netif_device_attach(netdev); clear_bit(__QLCNIC_RESETTING, &adapter->state); - dev_err(&adapter->pdev->dev, "%s:\n", __func__); + netdev_info(adapter->netdev, "%s: soft reset complete.\n", __func__); return 0; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index e2ee2bb5cd5c..39b631049b77 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2007,7 +2007,7 @@ qlcnic_reset_hw_context(struct qlcnic_adapter *adapter) netif_device_attach(netdev); clear_bit(__QLCNIC_RESETTING, &adapter->state); - dev_err(&adapter->pdev->dev, "%s:\n", __func__); + netdev_info(adapter->netdev, "%s: soft reset complete\n", __func__); return 0; } @@ -2747,12 +2747,58 @@ int qlcnic_check_temp(struct qlcnic_adapter *adapter) return rv; } -static void qlcnic_tx_timeout(struct net_device *netdev) +static inline void dump_tx_ring_desc(struct qlcnic_host_tx_ring *tx_ring) { - struct qlcnic_adapter *adapter = netdev_priv(netdev); + int i; + struct cmd_desc_type0 *tx_desc_info; + + for (i = 0; i < tx_ring->num_desc; i++) { + tx_desc_info = &tx_ring->desc_head[i]; + pr_info("TX Desc: %d\n", i); + print_hex_dump(KERN_INFO, "TX: ", DUMP_PREFIX_OFFSET, 16, 1, + &tx_ring->desc_head[i], + sizeof(struct cmd_desc_type0), true); + } +} + +static void qlcnic_dump_tx_rings(struct qlcnic_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; struct qlcnic_host_tx_ring *tx_ring; int ring; + if (!netdev || !netif_running(netdev)) + return; + + for (ring = 0; ring < adapter->drv_tx_rings; ring++) { + tx_ring = &adapter->tx_ring[ring]; + netdev_info(netdev, "Tx ring=%d Context Id=0x%x\n", + ring, tx_ring->ctx_id); + netdev_info(netdev, + "xmit_finished=%llu, xmit_called=%llu, xmit_on=%llu, xmit_off=%llu\n", + tx_ring->tx_stats.xmit_finished, + tx_ring->tx_stats.xmit_called, + tx_ring->tx_stats.xmit_on, + tx_ring->tx_stats.xmit_off); + netdev_info(netdev, + "crb_intr_mask=%d, hw_producer=%d, sw_producer=%d sw_consumer=%d, hw_consumer=%d\n", + readl(tx_ring->crb_intr_mask), + readl(tx_ring->crb_cmd_producer), + tx_ring->producer, tx_ring->sw_consumer, + le32_to_cpu(*(tx_ring->hw_consumer))); + + netdev_info(netdev, "Total desc=%d, Available desc=%d\n", + tx_ring->num_desc, qlcnic_tx_avail(tx_ring)); + + if (netif_msg_tx_done(adapter->ahw)) + dump_tx_ring_desc(tx_ring); + } +} + +static void qlcnic_tx_timeout(struct net_device *netdev) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + if (test_bit(__QLCNIC_RESETTING, &adapter->state)) return; @@ -2765,22 +2811,7 @@ static void qlcnic_tx_timeout(struct net_device *netdev) QLCNIC_FORCE_FW_DUMP_KEY); } else { netdev_info(netdev, "Tx timeout, reset adapter context.\n"); - for (ring = 0; ring < adapter->drv_tx_rings; ring++) { - tx_ring = &adapter->tx_ring[ring]; - netdev_info(netdev, "Tx ring=%d\n", ring); - netdev_info(netdev, - "crb_intr_mask=%d, producer=%d, sw_consumer=%d, hw_consumer=%d\n", - readl(tx_ring->crb_intr_mask), - readl(tx_ring->crb_cmd_producer), - tx_ring->sw_consumer, - le32_to_cpu(*(tx_ring->hw_consumer))); - netdev_info(netdev, - "xmit_finished=%llu, xmit_called=%llu, xmit_on=%llu, xmit_off=%llu\n", - tx_ring->tx_stats.xmit_finished, - tx_ring->tx_stats.xmit_called, - tx_ring->tx_stats.xmit_on, - tx_ring->tx_stats.xmit_off); - } + qlcnic_dump_tx_rings(adapter); adapter->ahw->reset_context = 1; } } -- 2.45.2