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

Commit 536faa61 authored by Sony Chacko's avatar Sony Chacko Committed by David S. Miller
Browse files

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: default avatarSony Chacko <sony.chacko@qlogic.com>
Signed-off-by: default avatarShahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b938662d
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -435,10 +435,6 @@ static void qlcnic_83xx_idc_attach_driver(struct qlcnic_adapter *adapter)
	}
done:
	netif_device_attach(netdev);
	if (netif_running(netdev)) {
		netif_carrier_on(netdev);
		netif_wake_queue(netdev);
	}
}

static 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)

static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;

	qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1);
	clear_bit(__QLCNIC_RESETTING, &adapter->state);
	set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
	qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
	set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
	adapter->ahw->idc.quiesce_req = 0;
	adapter->ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;
	adapter->ahw->idc.err_code = 0;
	adapter->ahw->idc.collect_dump = 0;

	ahw->idc.quiesce_req = 0;
	ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;
	ahw->idc.err_code = 0;
	ahw->idc.collect_dump = 0;
	ahw->reset_context = 0;
	adapter->tx_timeo_cnt = 0;

	clear_bit(__QLCNIC_RESETTING, &adapter->state);
}

/**
@@ -851,6 +853,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
	/* Check for soft reset request */
	if (ahw->reset_context &&
	    !(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) {
		adapter->ahw->reset_context = 0;
		qlcnic_83xx_idc_tx_soft_reset(adapter);
		return ret;
	}
@@ -914,6 +917,7 @@ static int qlcnic_83xx_idc_need_quiesce_state(struct qlcnic_adapter *adapter)
static int qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter)
{
	dev_err(&adapter->pdev->dev, "%s: please restart!!\n", __func__);
	clear_bit(__QLCNIC_RESETTING, &adapter->state);
	adapter->ahw->idc.err_code = -EIO;

	return 0;
+10 −5
Original line number Diff line number Diff line
@@ -2502,13 +2502,18 @@ static void qlcnic_tx_timeout(struct net_device *netdev)
	if (test_bit(__QLCNIC_RESETTING, &adapter->state))
		return;

	dev_err(&netdev->dev, "transmit timeout, resetting.\n");

	if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS)
	if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) {
		netdev_info(netdev, "Tx timeout, reset the adapter.\n");
		if (qlcnic_82xx_check(adapter))
			adapter->need_fw_reset = 1;
	else
		else if (qlcnic_83xx_check(adapter))
			qlcnic_83xx_idc_request_reset(adapter,
						      QLCNIC_FORCE_FW_DUMP_KEY);
	} else {
		netdev_info(netdev, "Tx timeout, reset adapter context.\n");
		adapter->ahw->reset_context = 1;
	}
}

static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)
{