aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSony Chacko <sony.chacko@qlogic.com>2013-05-09 05:25:13 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-11 19:01:15 -0400
commit536faa61825c8e92f520264228388d69783370d3 (patch)
tree0f774d79e234546baceb955629bccf90f7090505 /drivers/net
parentb938662d88264c1a92611ca1b82fdff5a4e87121 (diff)
qlcnic: Fix reset recovery after transmit timeout
o When transmit timeout happens, recovery attempt should start with adapter soft reset. If soft reset fails to resume traffic, firmware dump will be collected and driver will perform a hard reset of the adapter. Reset recovery on 83xx was failing after a hard reset. This patch fixes that issue. Signed-off-by: Sony Chacko <sony.chacko@qlogic.com> Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c22
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c15
2 files changed, 23 insertions, 14 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index ab1d8d99cbd5..c67d1eb35e8f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -435,10 +435,6 @@ static void qlcnic_83xx_idc_attach_driver(struct qlcnic_adapter *adapter)
435 } 435 }
436done: 436done:
437 netif_device_attach(netdev); 437 netif_device_attach(netdev);
438 if (netif_running(netdev)) {
439 netif_carrier_on(netdev);
440 netif_wake_queue(netdev);
441 }
442} 438}
443 439
444static int qlcnic_83xx_idc_enter_failed_state(struct qlcnic_adapter *adapter, 440static int qlcnic_83xx_idc_enter_failed_state(struct qlcnic_adapter *adapter,
@@ -642,15 +638,21 @@ static int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
642 638
643static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter) 639static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter)
644{ 640{
641 struct qlcnic_hardware_context *ahw = adapter->ahw;
642
645 qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1); 643 qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1);
646 clear_bit(__QLCNIC_RESETTING, &adapter->state);
647 set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status); 644 set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
648 qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1); 645 qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
649 set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status); 646 set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
650 adapter->ahw->idc.quiesce_req = 0; 647
651 adapter->ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY; 648 ahw->idc.quiesce_req = 0;
652 adapter->ahw->idc.err_code = 0; 649 ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;
653 adapter->ahw->idc.collect_dump = 0; 650 ahw->idc.err_code = 0;
651 ahw->idc.collect_dump = 0;
652 ahw->reset_context = 0;
653 adapter->tx_timeo_cnt = 0;
654
655 clear_bit(__QLCNIC_RESETTING, &adapter->state);
654} 656}
655 657
656/** 658/**
@@ -851,6 +853,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
851 /* Check for soft reset request */ 853 /* Check for soft reset request */
852 if (ahw->reset_context && 854 if (ahw->reset_context &&
853 !(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) { 855 !(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) {
856 adapter->ahw->reset_context = 0;
854 qlcnic_83xx_idc_tx_soft_reset(adapter); 857 qlcnic_83xx_idc_tx_soft_reset(adapter);
855 return ret; 858 return ret;
856 } 859 }
@@ -914,6 +917,7 @@ static int qlcnic_83xx_idc_need_quiesce_state(struct qlcnic_adapter *adapter)
914static int qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter) 917static int qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter)
915{ 918{
916 dev_err(&adapter->pdev->dev, "%s: please restart!!\n", __func__); 919 dev_err(&adapter->pdev->dev, "%s: please restart!!\n", __func__);
920 clear_bit(__QLCNIC_RESETTING, &adapter->state);
917 adapter->ahw->idc.err_code = -EIO; 921 adapter->ahw->idc.err_code = -EIO;
918 922
919 return 0; 923 return 0;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index d97446a3bf05..8fb836d4129f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2502,12 +2502,17 @@ static void qlcnic_tx_timeout(struct net_device *netdev)
2502 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 2502 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
2503 return; 2503 return;
2504 2504
2505 dev_err(&netdev->dev, "transmit timeout, resetting.\n"); 2505 if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) {
2506 2506 netdev_info(netdev, "Tx timeout, reset the adapter.\n");
2507 if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) 2507 if (qlcnic_82xx_check(adapter))
2508 adapter->need_fw_reset = 1; 2508 adapter->need_fw_reset = 1;
2509 else 2509 else if (qlcnic_83xx_check(adapter))
2510 qlcnic_83xx_idc_request_reset(adapter,
2511 QLCNIC_FORCE_FW_DUMP_KEY);
2512 } else {
2513 netdev_info(netdev, "Tx timeout, reset adapter context.\n");
2510 adapter->ahw->reset_context = 1; 2514 adapter->ahw->reset_context = 1;
2515 }
2511} 2516}
2512 2517
2513static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) 2518static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)