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

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

[SCSI] bfa: Update RME interrupt handling.



- Made changes to always acknowledge RME interrupt and update
  consumer index (CI) when RME interrupt is generated.
- Made changes to have ASIC specific hw_rspq_ack() handler.

Signed-off-by: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 9afbcfab
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ struct bfa_msix_s {
struct bfa_hwif_s {
	void (*hw_reginit)(struct bfa_s *bfa);
	void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
	void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
	void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq, u32 ci);
	void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
	void (*hw_msix_ctrl_install)(struct bfa_s *bfa);
	void (*hw_msix_queue_install)(struct bfa_s *bfa);
@@ -268,10 +268,8 @@ struct bfa_iocfc_s {
	((__bfa)->iocfc.hwif.hw_msix_queue_install(__bfa))
#define bfa_msix_uninstall(__bfa)					\
	((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa))
#define bfa_isr_rspq_ack(__bfa, __queue) do {				\
	if ((__bfa)->iocfc.hwif.hw_rspq_ack)				\
		(__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue);	\
} while (0)
#define bfa_isr_rspq_ack(__bfa, __queue, __ci)				\
	((__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue, __ci))
#define bfa_isr_reqq_ack(__bfa, __queue) do {				\
	if ((__bfa)->iocfc.hwif.hw_reqq_ack)				\
		(__bfa)->iocfc.hwif.hw_reqq_ack(__bfa, __queue);	\
@@ -311,7 +309,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec);
void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);

void bfa_hwcb_reginit(struct bfa_s *bfa);
void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa);
void bfa_hwcb_msix_queue_install(struct bfa_s *bfa);
@@ -324,7 +322,8 @@ void bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start,
void bfa_hwct_reginit(struct bfa_s *bfa);
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_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
void bfa_hwct2_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa);
void bfa_hwct_msix_queue_install(struct bfa_s *bfa);
+9 −16
Original line number Diff line number Diff line
@@ -237,8 +237,6 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
	u32	pi, ci;
	struct list_head *waitq;

	bfa_isr_rspq_ack(bfa, qid);

	ci = bfa_rspq_ci(bfa, qid);
	pi = bfa_rspq_pi(bfa, qid);

@@ -251,11 +249,9 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
	}

	/*
	 * update CI
	 * acknowledge RME completions and update CI
	 */
	bfa_rspq_ci(bfa, qid) = pi;
	writel(pi, bfa->iocfc.bfa_regs.rme_q_ci[qid]);
	mmiowb();
	bfa_isr_rspq_ack(bfa, qid, ci);

	/*
	 * Resume any pending requests in the corresponding reqq.
@@ -325,23 +321,19 @@ bfa_intx(struct bfa_s *bfa)
	int queue;

	intr = readl(bfa->iocfc.bfa_regs.intr_status);
	if (!intr)
		return BFA_FALSE;

	qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK);
	if (qintr)
		writel(qintr, bfa->iocfc.bfa_regs.intr_status);

	/*
	 * RME completion queue interrupt
	 * Unconditional RME completion queue interrupt
	 */
	qintr = intr & __HFN_INT_RME_MASK;
	if (qintr && bfa->queue_process) {
	if (bfa->queue_process) {
		for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
			bfa_isr_rspq(bfa, queue);
	}

	intr &= ~qintr;
	if (!intr)
		return BFA_TRUE;

@@ -432,7 +424,8 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
				   __HFN_INT_MBOX_LPU1_CT2);
		intr    &= __HFN_INT_ERR_MASK_CT2;
	} else {
		halt_isr = intr & __HFN_INT_LL_HALT;
		halt_isr = bfa_asic_id_ct(bfa->ioc.pcidev.device_id) ?
					  (intr & __HFN_INT_LL_HALT) : 0;
		pss_isr  = intr & __HFN_INT_ERR_PSS;
		lpu_isr  = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1);
		intr    &= __HFN_INT_ERR_MASK;
@@ -578,7 +571,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
	} else {
		iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
		iocfc->hwif.hw_reqq_ack = NULL;
		iocfc->hwif.hw_rspq_ack = NULL;
		iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
		iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
		iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install;
		iocfc->hwif.hw_msix_queue_install = bfa_hwcb_msix_queue_install;
@@ -595,7 +588,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
	if (bfa_asic_id_ct2(bfa_ioc_devid(&bfa->ioc))) {
		iocfc->hwif.hw_reginit = bfa_hwct2_reginit;
		iocfc->hwif.hw_isr_mode_set = NULL;
		iocfc->hwif.hw_rspq_ack = NULL;
		iocfc->hwif.hw_rspq_ack = bfa_hwct2_rspq_ack;
	}

	iocfc->hwif.hw_reginit(bfa);
@@ -685,7 +678,7 @@ bfa_iocfc_start_submod(struct bfa_s *bfa)

	bfa->queue_process = BFA_TRUE;
	for (i = 0; i < BFI_IOC_MAX_CQS; i++)
		bfa_isr_rspq_ack(bfa, i);
		bfa_isr_rspq_ack(bfa, i, bfa_rspq_ci(bfa, i));

	for (i = 0; hal_mods[i]; i++)
		hal_mods[i]->start(bfa);
+34 −4
Original line number Diff line number Diff line
@@ -42,11 +42,36 @@ bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
			bfa->iocfc.bfa_regs.intr_status);
}

/*
 * Actions to respond RME Interrupt for Crossbow ASIC:
 * - Write 1 to Interrupt Status register
 *              INTX - done in bfa_intx()
 *              MSIX - done in bfa_hwcb_rspq_ack_msix()
 * - Update CI (only if new CI)
 */
static void
bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq)
bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq, u32 ci)
{
	writel(__HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq),
		bfa->iocfc.bfa_regs.intr_status);

	if (bfa_rspq_ci(bfa, rspq) == ci)
		return;

	bfa_rspq_ci(bfa, rspq) = ci;
	writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
	mmiowb();
}

void
bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
{
	if (bfa_rspq_ci(bfa, rspq) == ci)
		return;

	bfa_rspq_ci(bfa, rspq) = ci;
	writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
	mmiowb();
}

void
@@ -149,8 +174,13 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
void
bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
{
	if (msix) {
		bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
		bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
	} else {
		bfa->iocfc.hwif.hw_reqq_ack = NULL;
		bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
	}
}

void
+24 −1
Original line number Diff line number Diff line
@@ -64,13 +64,36 @@ bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
	writel(r32, bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
}

/*
 * Actions to respond RME Interrupt for Catapult ASIC:
 * - Write 1 to Interrupt Status register (INTx only - done in bfa_intx())
 * - Acknowledge by writing to RME Queue Control register
 * - Update CI
 */
void
bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
{
	u32	r32;

	r32 = readl(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);
	writel(r32, bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);

	bfa_rspq_ci(bfa, rspq) = ci;
	writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
	mmiowb();
}

/*
 * Actions to respond RME Interrupt for Catapult2 ASIC:
 * - Write 1 to Interrupt Status register (INTx only - done in bfa_intx())
 * - Update CI
 */
void
bfa_hwct2_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
{
	bfa_rspq_ci(bfa, rspq) = ci;
	writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
	mmiowb();
}

void