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

Commit 775c7742 authored by Krishna Gudipati's avatar Krishna Gudipati Committed by James Bottomley
Browse files

[SCSI] bfa: IOC and PLL init changes for Brocade-1860 Fabric Adapter.



- Introduced IOC poll mechanism which replaces current interrupt
  based FW READY method.
- The timer based poll routine in IOC will query the ioc_fwstate
  register to see if there is a state change in FW, and sends the READY event.
- Bug fixes in the new asic PLL initialization.
- Added logic to handle CPE/RME queue interrupts before iocfc config done.
  1. Use the queue_process flag to see if iocfc configuration is done
     in INTX mode.
  2. Split the MSIX handler installation in two - one for IOC intr
     handler and the other for cpe/rme queue handler - and delay
     assigning queue handlers until iocfc config is done in MSIX mode.

Signed-off-by: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent dd5aaf45
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -228,7 +228,8 @@ struct bfa_hwif_s {
	void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
	void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
	void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
	void (*hw_msix_install)(struct bfa_s *bfa);
	void (*hw_msix_ctrl_install)(struct bfa_s *bfa);
	void (*hw_msix_queue_install)(struct bfa_s *bfa);
	void (*hw_msix_uninstall)(struct bfa_s *bfa);
	void (*hw_isr_mode_set)(struct bfa_s *bfa, bfa_boolean_t msix);
	void (*hw_msix_getvecs)(struct bfa_s *bfa, u32 *vecmap,
@@ -271,8 +272,10 @@ struct bfa_iocfc_s {
	bfa_ioc_portid(&(__bfa)->ioc)
#define bfa_msix_init(__bfa, __nvecs)					\
	((__bfa)->iocfc.hwif.hw_msix_init(__bfa, __nvecs))
#define bfa_msix_install(__bfa)						\
	((__bfa)->iocfc.hwif.hw_msix_install(__bfa))
#define bfa_msix_ctrl_install(__bfa)					\
	((__bfa)->iocfc.hwif.hw_msix_ctrl_install(__bfa))
#define bfa_msix_queue_install(__bfa)					\
	((__bfa)->iocfc.hwif.hw_msix_queue_install(__bfa))
#define bfa_msix_uninstall(__bfa)					\
	((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa))
#define bfa_isr_mode_set(__bfa, __msix) do {				\
@@ -314,7 +317,8 @@ void bfa_hwcb_reginit(struct bfa_s *bfa);
void bfa_hwcb_reqq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
void bfa_hwcb_msix_install(struct bfa_s *bfa);
void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa);
void bfa_hwcb_msix_queue_install(struct bfa_s *bfa);
void bfa_hwcb_msix_uninstall(struct bfa_s *bfa);
void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, u32 *nvecs,
@@ -326,7 +330,8 @@ void bfa_hwct2_reginit(struct bfa_s *bfa);
void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
void bfa_hwct_msix_install(struct bfa_s *bfa);
void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa);
void bfa_hwct_msix_queue_install(struct bfa_s *bfa);
void bfa_hwct_msix_uninstall(struct bfa_s *bfa);
void bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
void bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, u32 *nvecs,
+16 −12
Original line number Diff line number Diff line
@@ -248,7 +248,7 @@ bfa_intx(struct bfa_s *bfa)
	writel(qintr, bfa->iocfc.bfa_regs.intr_status);

	for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) {
		if (intr & (__HFN_INT_RME_Q0 << queue))
		if ((intr & (__HFN_INT_RME_Q0 << queue)) && bfa->queue_process)
			bfa_isr_rspq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
	}
	intr &= ~qintr;
@@ -262,7 +262,7 @@ bfa_intx(struct bfa_s *bfa)
	writel(qintr, bfa->iocfc.bfa_regs.intr_status);

	for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) {
		if (intr & (__HFN_INT_CPE_Q0 << queue))
		if ((intr & (__HFN_INT_CPE_Q0 << queue)) && bfa->queue_process)
			bfa_isr_reqq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
	}
	intr &= ~qintr;
@@ -282,7 +282,7 @@ bfa_isr_enable(struct bfa_s *bfa)

	bfa_trc(bfa, pci_func);

	bfa_msix_install(bfa);
	bfa_msix_ctrl_install(bfa);

	if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) {
		umsk = __HFN_INT_ERR_MASK_CT2;
@@ -326,9 +326,6 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
void
bfa_msix_rspq(struct bfa_s *bfa, int vec)
{
	if (!bfa->rme_process)
		return;

	bfa_isr_rspq(bfa, vec - bfa->iocfc.hwif.rme_vec_q0);
}

@@ -512,7 +509,8 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
		iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
		iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
		iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
		iocfc->hwif.hw_msix_install = bfa_hwct_msix_install;
		iocfc->hwif.hw_msix_ctrl_install = bfa_hwct_msix_ctrl_install;
		iocfc->hwif.hw_msix_queue_install = bfa_hwct_msix_queue_install;
		iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall;
		iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set;
		iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
@@ -524,7 +522,8 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
		iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack;
		iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
		iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
		iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install;
		iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install;
		iocfc->hwif.hw_msix_queue_install = bfa_hwcb_msix_queue_install;
		iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall;
		iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set;
		iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs;
@@ -640,7 +639,7 @@ bfa_iocfc_start_submod(struct bfa_s *bfa)
{
	int		i;

	bfa->rme_process = BFA_TRUE;
	bfa->queue_process = BFA_TRUE;
	for (i = 0; i < BFI_IOC_MAX_CQS; i++)
		bfa->iocfc.hwif.hw_rspq_ack(bfa, i);

@@ -742,6 +741,11 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
	 */
	bfa_iocfc_qreg(bfa, &cfgrsp->qreg);

	/*
	 * Install MSIX queue handlers
	 */
	bfa_msix_queue_install(bfa);

	/*
	 * Configuration is complete - initialize/start submodules
	 */
@@ -813,7 +817,7 @@ bfa_iocfc_hbfail_cbfn(void *bfa_arg)
{
	struct bfa_s	*bfa = bfa_arg;

	bfa->rme_process = BFA_FALSE;
	bfa->queue_process = BFA_FALSE;

	bfa_isr_disable(bfa);
	bfa_iocfc_disable_submod(bfa);
@@ -917,7 +921,7 @@ bfa_iocfc_stop(struct bfa_s *bfa)
{
	bfa->iocfc.action = BFA_IOCFC_ACT_STOP;

	bfa->rme_process = BFA_FALSE;
	bfa->queue_process = BFA_FALSE;
	bfa_ioc_disable(&bfa->ioc);
}

@@ -1017,7 +1021,7 @@ bfa_iocfc_disable(struct bfa_s *bfa)
		     "IOC Disable");
	bfa->iocfc.action = BFA_IOCFC_ACT_DISABLE;

	bfa->rme_process = BFA_FALSE;
	bfa->queue_process = BFA_FALSE;
	bfa_ioc_disable(&bfa->ioc);
}

+43 −15
Original line number Diff line number Diff line
@@ -85,44 +85,72 @@ bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
	*num_vecs = __HFN_NUMINTS;
}

/*
 * Dummy interrupt handler for handling spurious interrupts.
 */
static void
bfa_hwcb_msix_dummy(struct bfa_s *bfa, int vec)
{
}

/*
 * No special setup required for crossbow -- vector assignments are implicit.
 */
void
bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs)
{
	int i;

	WARN_ON((nvecs != 1) && (nvecs != __HFN_NUMINTS));

	bfa->msix.nvecs = nvecs;
	if (nvecs == 1) {
		for (i = 0; i < BFI_MSIX_CB_MAX; i++)
			bfa->msix.handler[i] = bfa_msix_all;
		return;
	bfa_hwcb_msix_uninstall(bfa);
}

	for (i = BFI_MSIX_CPE_QMIN_CB; i <= BFI_MSIX_CPE_QMAX_CB; i++)
		bfa->msix.handler[i] = bfa_msix_reqq;
void
bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa)
{
	int i;

	for (i = BFI_MSIX_RME_QMIN_CB; i <= BFI_MSIX_RME_QMAX_CB; i++)
		bfa->msix.handler[i] = bfa_msix_rspq;
	if (bfa->msix.nvecs == 0)
		return;

	for (; i < BFI_MSIX_CB_MAX; i++)
	if (bfa->msix.nvecs == 1) {
		for (i = BFI_MSIX_RME_QMAX_CB+1; i < BFI_MSIX_CB_MAX; i++)
			bfa->msix.handler[i] = bfa_msix_all;
		return;
	}

	for (i = BFI_MSIX_RME_QMAX_CB+1; i < BFI_MSIX_CB_MAX; i++)
		bfa->msix.handler[i] = bfa_msix_lpu_err;
}

/*
 * Crossbow -- dummy, interrupts are masked
 */
void
bfa_hwcb_msix_install(struct bfa_s *bfa)
bfa_hwcb_msix_queue_install(struct bfa_s *bfa)
{
	int i;

	if (bfa->msix.nvecs == 0)
		return;

	if (bfa->msix.nvecs == 1) {
		for (i = BFI_MSIX_CPE_QMIN_CB; i <= BFI_MSIX_RME_QMAX_CB; i++)
			bfa->msix.handler[i] = bfa_msix_all;
		return;
	}

	for (i = BFI_MSIX_CPE_QMIN_CB; i <= BFI_MSIX_CPE_QMAX_CB; i++)
		bfa->msix.handler[i] = bfa_msix_reqq;

	for (i = BFI_MSIX_RME_QMIN_CB; i <= BFI_MSIX_RME_QMAX_CB; i++)
		bfa->msix.handler[i] = bfa_msix_rspq;
}

void
bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
{
	int i;

	for (i = 0; i < BFI_MSIX_CB_MAX; i++)
		bfa->msix.handler[i] = bfa_hwcb_msix_dummy;
}

/*
+14 −4
Original line number Diff line number Diff line
@@ -96,7 +96,19 @@ bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs)
}

void
bfa_hwct_msix_install(struct bfa_s *bfa)
bfa_hwct_msix_ctrl_install(struct bfa_s *bfa)
{
	if (bfa->msix.nvecs == 0)
		return;

	if (bfa->msix.nvecs == 1)
		bfa->msix.handler[BFI_MSIX_LPU_ERR_CT] = bfa_msix_all;
	else
		bfa->msix.handler[BFI_MSIX_LPU_ERR_CT] = bfa_msix_lpu_err;
}

void
bfa_hwct_msix_queue_install(struct bfa_s *bfa)
{
	int i;

@@ -104,7 +116,7 @@ bfa_hwct_msix_install(struct bfa_s *bfa)
		return;

	if (bfa->msix.nvecs == 1) {
		for (i = 0; i < BFI_MSIX_CT_MAX; i++)
		for (i = BFI_MSIX_CPE_QMIN_CT; i < BFI_MSIX_CT_MAX; i++)
			bfa->msix.handler[i] = bfa_msix_all;
		return;
	}
@@ -114,8 +126,6 @@ bfa_hwct_msix_install(struct bfa_s *bfa)

	for (i = BFI_MSIX_RME_QMIN_CT; i <= BFI_MSIX_RME_QMAX_CT; i++)
		bfa->msix.handler[i] = bfa_msix_rspq;

	bfa->msix.handler[BFI_MSIX_LPU_ERR_CT] = bfa_msix_lpu_err;
}

void
+57 −73
Original line number Diff line number Diff line
@@ -29,8 +29,8 @@ BFA_TRC_FILE(CNA, IOC);
#define BFA_IOC_TOV		3000	/* msecs */
#define BFA_IOC_HWSEM_TOV	500	/* msecs */
#define BFA_IOC_HB_TOV		500	/* msecs */
#define BFA_IOC_HWINIT_MAX	5
#define BFA_IOC_TOV_RECOVER	 BFA_IOC_HB_TOV
#define BFA_IOC_POLL_TOV	BFA_TIMER_FREQ

#define bfa_ioc_timer_start(__ioc)					\
	bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,	\
@@ -79,6 +79,7 @@ bfa_boolean_t bfa_auto_recover = BFA_TRUE;
static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
static void bfa_ioc_timeout(void *ioc);
static void bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc);
static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc);
static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc);
static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc);
@@ -107,11 +108,10 @@ enum ioc_event {
	IOC_E_ENABLED		= 5,	/*  f/w enabled		*/
	IOC_E_FWRSP_GETATTR	= 6,	/*  IOC get attribute response	*/
	IOC_E_DISABLED		= 7,	/*  f/w disabled		*/
	IOC_E_INITFAILED	= 8,	/*  failure notice by iocpf sm	*/
	IOC_E_PFFAILED		= 9,	/*  failure notice by iocpf sm	*/
	IOC_E_HBFAIL		= 10,	/*  heartbeat failure		*/
	IOC_E_HWERROR		= 11,	/*  hardware error interrupt	*/
	IOC_E_TIMEOUT		= 12,	/*  timeout			*/
	IOC_E_PFFAILED		= 8,	/*  failure notice by iocpf sm	*/
	IOC_E_HBFAIL		= 9,	/*  heartbeat failure		*/
	IOC_E_HWERROR		= 10,	/*  hardware error interrupt	*/
	IOC_E_TIMEOUT		= 11,	/*  timeout			*/
};

bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event);
@@ -145,9 +145,9 @@ static struct bfa_sm_table_s ioc_sm_table[] = {
			bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV)
#define bfa_iocpf_timer_stop(__ioc)	bfa_timer_stop(&(__ioc)->ioc_timer)

#define bfa_iocpf_recovery_timer_start(__ioc)				\
#define bfa_iocpf_poll_timer_start(__ioc)				\
	bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,	\
			bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV_RECOVER)
			bfa_iocpf_poll_timeout, (__ioc), BFA_IOC_POLL_TOV)

#define bfa_sem_timer_start(__ioc)					\
	bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->sem_timer,	\
@@ -159,6 +159,7 @@ static struct bfa_sm_table_s ioc_sm_table[] = {
 */
static void bfa_iocpf_timeout(void *ioc_arg);
static void bfa_iocpf_sem_timeout(void *ioc_arg);
static void bfa_iocpf_poll_timeout(void *ioc_arg);

/*
 * IOCPF state machine events
@@ -316,7 +317,7 @@ bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
		/* !!! fall through !!! */
	case IOC_E_HWERROR:
		ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
		bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
		bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
		if (event != IOC_E_PFFAILED)
			bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
		break;
@@ -368,7 +369,7 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
		/* !!! fall through !!! */
	case IOC_E_TIMEOUT:
		ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
		bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
		bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
		if (event != IOC_E_PFFAILED)
			bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
		break;
@@ -417,13 +418,13 @@ bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
		bfa_hb_timer_stop(ioc);
		/* !!! fall through !!! */
	case IOC_E_HBFAIL:
		bfa_ioc_fail_notify(ioc);

		if (ioc->iocpf.auto_recover)
			bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
		else
			bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);

		bfa_ioc_fail_notify(ioc);

		if (event != IOC_E_PFFAILED)
			bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
		break;
@@ -528,14 +529,11 @@ bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event)
		 * Initialization retry failed.
		 */
		ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
		bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
		if (event != IOC_E_PFFAILED)
			bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
		break;

	case IOC_E_INITFAILED:
		bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
		break;

	case IOC_E_ENABLE:
		break;

@@ -603,7 +601,7 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
static void
bfa_iocpf_sm_reset_entry(struct bfa_iocpf_s *iocpf)
{
	iocpf->retry_count = 0;
	iocpf->fw_mismatch_notified = BFA_FALSE;
	iocpf->auto_recover = bfa_auto_recover;
}

@@ -653,7 +651,6 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
	case IOCPF_E_SEMLOCKED:
		if (bfa_ioc_firmware_lock(ioc)) {
			if (bfa_ioc_sync_start(ioc)) {
				iocpf->retry_count = 0;
				bfa_ioc_sync_join(ioc);
				bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
			} else {
@@ -692,10 +689,10 @@ bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf_s *iocpf)
	/*
	 * Call only the first time sm enters fwmismatch state.
	 */
	if (iocpf->retry_count == 0)
	if (iocpf->fw_mismatch_notified == BFA_FALSE)
		bfa_ioc_pf_fwmismatch(iocpf->ioc);

	iocpf->retry_count++;
	iocpf->fw_mismatch_notified = BFA_TRUE;
	bfa_iocpf_timer_start(iocpf->ioc);
}

@@ -773,7 +770,7 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
static void
bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf)
{
	bfa_iocpf_timer_start(iocpf->ioc);
	iocpf->poll_time = 0;
	bfa_ioc_hwinit(iocpf->ioc, BFA_FALSE);
}

@@ -790,19 +787,11 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event)

	switch (event) {
	case IOCPF_E_FWREADY:
		bfa_iocpf_timer_stop(ioc);
		bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling);
		break;

	case IOCPF_E_INITFAIL:
		bfa_iocpf_timer_stop(ioc);
		/*
		 * !!! fall through !!!
		 */

	case IOCPF_E_TIMEOUT:
		writel(1, ioc->ioc_regs.ioc_sem_reg);
		if (event == IOCPF_E_TIMEOUT)
		bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
		bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
		break;
@@ -823,6 +812,10 @@ static void
bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf)
{
	bfa_iocpf_timer_start(iocpf->ioc);
	/*
	 * Enable Interrupts before sending fw IOC ENABLE cmd.
	 */
	iocpf->ioc->cbfn->reset_cbfn(iocpf->ioc->bfa);
	bfa_ioc_send_enable(iocpf->ioc);
}

@@ -863,10 +856,6 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
		bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
		break;

	case IOCPF_E_FWREADY:
		bfa_ioc_send_enable(ioc);
		break;

	default:
		bfa_sm_fault(ioc, event);
	}
@@ -898,16 +887,6 @@ bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
		bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
		break;

	case IOCPF_E_FWREADY:
		if (bfa_ioc_is_operational(ioc)) {
			bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
			bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
		} else {
			bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
			bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
		}
		break;

	default:
		bfa_sm_fault(ioc, event);
	}
@@ -932,7 +911,6 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)

	switch (event) {
	case IOCPF_E_FWRSP_DISABLE:
	case IOCPF_E_FWREADY:
		bfa_iocpf_timer_stop(ioc);
		bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
		break;
@@ -1005,7 +983,6 @@ bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event)

	switch (event) {
	case IOCPF_E_ENABLE:
		iocpf->retry_count = 0;
		bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
		break;

@@ -1038,20 +1015,10 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
	switch (event) {
	case IOCPF_E_SEMLOCKED:
		bfa_ioc_notify_fail(ioc);
		bfa_ioc_sync_ack(ioc);
		iocpf->retry_count++;
		if (iocpf->retry_count >= BFA_IOC_HWINIT_MAX) {
		bfa_ioc_sync_leave(ioc);
		writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
		writel(1, ioc->ioc_regs.ioc_sem_reg);
		bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
		} else {
			if (bfa_ioc_sync_complete(ioc))
				bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
			else {
				writel(1, ioc->ioc_regs.ioc_sem_reg);
				bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
			}
		}
		break;

	case IOCPF_E_DISABLE:
@@ -1076,7 +1043,6 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
static void
bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf)
{
	bfa_fsm_send_event(iocpf->ioc, IOC_E_INITFAILED);
}

/*
@@ -1129,11 +1095,11 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)

	switch (event) {
	case IOCPF_E_SEMLOCKED:
		iocpf->retry_count = 0;
		bfa_ioc_sync_ack(ioc);
		bfa_ioc_notify_fail(ioc);
		if (!iocpf->auto_recover) {
			bfa_ioc_sync_leave(ioc);
			writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
			writel(1, ioc->ioc_regs.ioc_sem_reg);
			bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
		} else {
@@ -1441,7 +1407,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
	 * just wait for an initialization completion interrupt.
	 */
	if (ioc_fwstate == BFI_IOC_INITING) {
		ioc->cbfn->reset_cbfn(ioc->bfa);
		bfa_ioc_poll_fwinit(ioc);
		return;
	}

@@ -1460,7 +1426,6 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
		 * be flushed. Otherwise MSI-X interrupts are not delivered.
		 */
		bfa_ioc_msgflush(ioc);
		ioc->cbfn->reset_cbfn(ioc->bfa);
		bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
		return;
	}
@@ -1902,11 +1867,6 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env)

	bfa_ioc_msgflush(ioc);
	bfa_ioc_download_fw(ioc, boot_type, boot_env);

	/*
	 * Enable interrupts just before starting LPU
	 */
	ioc->cbfn->reset_cbfn(ioc->bfa);
	bfa_ioc_lpu_start(ioc);
}

@@ -1981,10 +1941,6 @@ bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
	case BFI_IOC_I2H_HBEAT:
		break;

	case BFI_IOC_I2H_READY_EVENT:
		bfa_fsm_send_event(iocpf, IOCPF_E_FWREADY);
		break;

	case BFI_IOC_I2H_ENABLE_REPLY:
		bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
		break;
@@ -2752,6 +2708,34 @@ bfa_iocpf_sem_timeout(void *ioc_arg)
	bfa_ioc_hw_sem_get(ioc);
}

static void
bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc)
{
	u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate);

	bfa_trc(ioc, fwstate);

	if (fwstate == BFI_IOC_DISABLED) {
		bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
		return;
	}

	if (ioc->iocpf.poll_time >= BFA_IOC_TOV)
		bfa_iocpf_timeout(ioc);
	else {
		ioc->iocpf.poll_time += BFA_IOC_POLL_TOV;
		bfa_iocpf_poll_timer_start(ioc);
	}
}

static void
bfa_iocpf_poll_timeout(void *ioc_arg)
{
	struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg;

	bfa_ioc_poll_fwinit(ioc);
}

/*
 *  bfa timer function
 */
Loading