Commit f036e4f4 authored by Rajesh Borundia's avatar Rajesh Borundia Committed by David S. Miller
Browse files

qlcnic: VF reset recovery implementation.



o Implement recovery mechanism for VF to recover from
  adapter resets.

Signed-off-by: default avatarManish Chopra <manish.chopra@qlogic.com>
Signed-off-by: default avatarSucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: default avatarRajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 97d8105c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -976,6 +976,7 @@ struct qlcnic_adapter {
	u8 fw_fail_cnt;
	u8 tx_timeo_cnt;
	u8 need_fw_reset;
	u8 reset_ctx_cnt;

	u16 is_up;
	u16 pvid;
+5 −6
Original line number Diff line number Diff line
@@ -339,12 +339,13 @@ inline void qlcnic_83xx_enable_legacy_msix_mbx_intr(struct qlcnic_adapter
	writel(0, adapter->ahw->pci_base0 + mask);
}

inline void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *adapter)
void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *adapter)
{
	u32 mask;

	mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
	writel(1, adapter->ahw->pci_base0 + mask);
	QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, 0);
}

static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
@@ -453,17 +454,15 @@ done:

void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
{
	u32 val = 0, num_msix = adapter->ahw->num_msix - 1;
	u32 num_msix;

	qlcnic_83xx_disable_mbx_intr(adapter);

	if (adapter->flags & QLCNIC_MSIX_ENABLED)
		num_msix = adapter->ahw->num_msix - 1;
	else
		num_msix = 0;

	QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);

	qlcnic_83xx_disable_mbx_intr(adapter);

	msleep(20);
	synchronize_irq(adapter->msix_entries[num_msix].vector);
	free_irq(adapter->msix_entries[num_msix].vector, adapter);
+13 −0
Original line number Diff line number Diff line
@@ -317,6 +317,18 @@ struct qlc_83xx_idc {
	char		**name;
};

/* Device States */
enum qlcnic_83xx_states {
	QLC_83XX_IDC_DEV_UNKNOWN,
	QLC_83XX_IDC_DEV_COLD,
	QLC_83XX_IDC_DEV_INIT,
	QLC_83XX_IDC_DEV_READY,
	QLC_83XX_IDC_DEV_NEED_RESET,
	QLC_83XX_IDC_DEV_NEED_QUISCENT,
	QLC_83XX_IDC_DEV_FAILED,
	QLC_83XX_IDC_DEV_QUISCENT
};

#define QLCNIC_MBX_RSP(reg)		LSW(reg)
#define QLCNIC_MBX_NUM_REGS(reg)	(MSW(reg) & 0x1FF)
#define QLCNIC_MBX_STATUS(reg)		(((reg) >> 25) & 0x7F)
@@ -536,6 +548,7 @@ void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *);
irqreturn_t qlcnic_83xx_handle_aen(int, void *);
int qlcnic_83xx_get_port_info(struct qlcnic_adapter *);
void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *);
void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *);
irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *);
irqreturn_t qlcnic_83xx_intr(int, void *);
irqreturn_t qlcnic_83xx_tmp_intr(int, void *);
+13 −14
Original line number Diff line number Diff line
@@ -115,18 +115,6 @@ static const char *const qlc_83xx_idc_states[] = {
	"Quiesce"
};

/* Device States */
enum qlcnic_83xx_states {
	QLC_83XX_IDC_DEV_UNKNOWN,
	QLC_83XX_IDC_DEV_COLD,
	QLC_83XX_IDC_DEV_INIT,
	QLC_83XX_IDC_DEV_READY,
	QLC_83XX_IDC_DEV_NEED_RESET,
	QLC_83XX_IDC_DEV_NEED_QUISCENT,
	QLC_83XX_IDC_DEV_FAILED,
	QLC_83XX_IDC_DEV_QUISCENT
};

static int
qlcnic_83xx_idc_check_driver_presence_reg(struct qlcnic_adapter *adapter)
{
@@ -162,7 +150,8 @@ static int qlcnic_83xx_idc_update_audit_reg(struct qlcnic_adapter *adapter,
			return -EBUSY;
	}

	val = adapter->portnum & 0xf;
	val = QLCRDX(adapter->ahw, QLC_83XX_IDC_DRV_AUDIT);
	val |= (adapter->portnum & 0xf);
	val |= mode << 7;
	if (mode)
		seconds = jiffies / HZ - adapter->ahw->idc.sec_counter;
@@ -401,14 +390,18 @@ static void qlcnic_83xx_idc_detach_driver(struct qlcnic_adapter *adapter)
	struct net_device *netdev = adapter->netdev;

	netif_device_detach(netdev);

	/* Disable mailbox interrupt */
	QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, 0);
	qlcnic_83xx_disable_mbx_intr(adapter);
	qlcnic_down(adapter, netdev);
	for (i = 0; i < adapter->ahw->num_msix; i++) {
		adapter->ahw->intr_tbl[i].id = i;
		adapter->ahw->intr_tbl[i].enabled = 0;
		adapter->ahw->intr_tbl[i].src = 0;
	}

	if (qlcnic_sriov_pf_check(adapter))
		qlcnic_sriov_pf_reset(adapter);
}

/**
@@ -610,9 +603,15 @@ static int qlcnic_83xx_idc_check_fan_failure(struct qlcnic_adapter *adapter)

static int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
{
	int err;

	/* register for NIC IDC AEN Events */
	qlcnic_83xx_register_nic_idc_func(adapter, 1);

	err = qlcnic_sriov_pf_reinit(adapter);
	if (err)
		return err;

	qlcnic_83xx_enable_mbx_intrpt(adapter);

	if (qlcnic_83xx_configure_opmode(adapter)) {
+1 −1
Original line number Diff line number Diff line
@@ -669,7 +669,7 @@ enum {
#define QLCNIC_CMDPEG_CHECK_RETRY_COUNT	60
#define QLCNIC_CMDPEG_CHECK_DELAY	500
#define QLCNIC_HEARTBEAT_PERIOD_MSECS	200
#define QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT	45
#define QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT	10

#define QLCNIC_MAX_MC_COUNT		38
#define QLCNIC_WATCHDOG_TIMEOUTVALUE	5
Loading