mirror of https://gitee.com/openkylin/linux.git
qlcnic: Enhance Tx timeout debug data collection.
- Collect a firmware dump on first Tx timeout if netif_msg_tx_err() is set - Log Receive and Status ring info on Tx timeout, in addition to Tx ring info - Log additional Tx ring info if netif_msg_tx_err() is set Signed-off-by: Harish Patil <harish.patil@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
fb0d164cc1
commit
665d1eca03
|
@ -2980,17 +2980,43 @@ static inline void dump_tx_ring_desc(struct qlcnic_host_tx_ring *tx_ring)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qlcnic_dump_tx_rings(struct qlcnic_adapter *adapter)
|
static void qlcnic_dump_rings(struct qlcnic_adapter *adapter)
|
||||||
{
|
{
|
||||||
|
struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
|
||||||
struct net_device *netdev = adapter->netdev;
|
struct net_device *netdev = adapter->netdev;
|
||||||
|
struct qlcnic_host_rds_ring *rds_ring;
|
||||||
|
struct qlcnic_host_sds_ring *sds_ring;
|
||||||
struct qlcnic_host_tx_ring *tx_ring;
|
struct qlcnic_host_tx_ring *tx_ring;
|
||||||
int ring;
|
int ring;
|
||||||
|
|
||||||
if (!netdev || !netif_running(netdev))
|
if (!netdev || !netif_running(netdev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
|
||||||
|
rds_ring = &recv_ctx->rds_rings[ring];
|
||||||
|
if (!rds_ring)
|
||||||
|
continue;
|
||||||
|
netdev_info(netdev,
|
||||||
|
"rds_ring=%d crb_rcv_producer=%d producer=%u num_desc=%u\n",
|
||||||
|
ring, readl(rds_ring->crb_rcv_producer),
|
||||||
|
rds_ring->producer, rds_ring->num_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
|
||||||
|
sds_ring = &(recv_ctx->sds_rings[ring]);
|
||||||
|
if (!sds_ring)
|
||||||
|
continue;
|
||||||
|
netdev_info(netdev,
|
||||||
|
"sds_ring=%d crb_sts_consumer=%d consumer=%u crb_intr_mask=%d num_desc=%u\n",
|
||||||
|
ring, readl(sds_ring->crb_sts_consumer),
|
||||||
|
sds_ring->consumer, readl(sds_ring->crb_intr_mask),
|
||||||
|
sds_ring->num_desc);
|
||||||
|
}
|
||||||
|
|
||||||
for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
|
for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
|
||||||
tx_ring = &adapter->tx_ring[ring];
|
tx_ring = &adapter->tx_ring[ring];
|
||||||
|
if (!tx_ring)
|
||||||
|
continue;
|
||||||
netdev_info(netdev, "Tx ring=%d Context Id=0x%x\n",
|
netdev_info(netdev, "Tx ring=%d Context Id=0x%x\n",
|
||||||
ring, tx_ring->ctx_id);
|
ring, tx_ring->ctx_id);
|
||||||
netdev_info(netdev,
|
netdev_info(netdev,
|
||||||
|
@ -3013,9 +3039,10 @@ static void qlcnic_dump_tx_rings(struct qlcnic_adapter *adapter)
|
||||||
netdev_info(netdev, "Total desc=%d, Available desc=%d\n",
|
netdev_info(netdev, "Total desc=%d, Available desc=%d\n",
|
||||||
tx_ring->num_desc, qlcnic_tx_avail(tx_ring));
|
tx_ring->num_desc, qlcnic_tx_avail(tx_ring));
|
||||||
|
|
||||||
if (netif_msg_tx_done(adapter->ahw))
|
if (netif_msg_tx_err(adapter->ahw))
|
||||||
dump_tx_ring_desc(tx_ring);
|
dump_tx_ring_desc(tx_ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qlcnic_tx_timeout(struct net_device *netdev)
|
static void qlcnic_tx_timeout(struct net_device *netdev)
|
||||||
|
@ -3025,16 +3052,18 @@ static void qlcnic_tx_timeout(struct net_device *netdev)
|
||||||
if (test_bit(__QLCNIC_RESETTING, &adapter->state))
|
if (test_bit(__QLCNIC_RESETTING, &adapter->state))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) {
|
qlcnic_dump_rings(adapter);
|
||||||
netdev_info(netdev, "Tx timeout, reset the adapter.\n");
|
|
||||||
|
if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS ||
|
||||||
|
netif_msg_tx_err(adapter->ahw)) {
|
||||||
|
netdev_err(netdev, "Tx timeout, reset the adapter.\n");
|
||||||
if (qlcnic_82xx_check(adapter))
|
if (qlcnic_82xx_check(adapter))
|
||||||
adapter->need_fw_reset = 1;
|
adapter->need_fw_reset = 1;
|
||||||
else if (qlcnic_83xx_check(adapter))
|
else if (qlcnic_83xx_check(adapter))
|
||||||
qlcnic_83xx_idc_request_reset(adapter,
|
qlcnic_83xx_idc_request_reset(adapter,
|
||||||
QLCNIC_FORCE_FW_DUMP_KEY);
|
QLCNIC_FORCE_FW_DUMP_KEY);
|
||||||
} else {
|
} else {
|
||||||
netdev_info(netdev, "Tx timeout, reset adapter context.\n");
|
netdev_err(netdev, "Tx timeout, reset adapter context.\n");
|
||||||
qlcnic_dump_tx_rings(adapter);
|
|
||||||
adapter->ahw->reset_context = 1;
|
adapter->ahw->reset_context = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue