Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95b3890a authored by Himanshu Madhani's avatar Himanshu Madhani Committed by David S. Miller
Browse files

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: default avatarHimanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 72ebe349
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
}
+50 −19
Original line number Diff line number Diff line
@@ -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;
	}
}