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

[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
...@@ -177,7 +177,7 @@ struct bfa_msix_s { ...@@ -177,7 +177,7 @@ struct bfa_msix_s {
struct bfa_hwif_s { struct bfa_hwif_s {
void (*hw_reginit)(struct bfa_s *bfa); void (*hw_reginit)(struct bfa_s *bfa);
void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq); 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_init)(struct bfa_s *bfa, int nvecs);
void (*hw_msix_ctrl_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_queue_install)(struct bfa_s *bfa);
...@@ -268,10 +268,8 @@ struct bfa_iocfc_s { ...@@ -268,10 +268,8 @@ struct bfa_iocfc_s {
((__bfa)->iocfc.hwif.hw_msix_queue_install(__bfa)) ((__bfa)->iocfc.hwif.hw_msix_queue_install(__bfa))
#define bfa_msix_uninstall(__bfa) \ #define bfa_msix_uninstall(__bfa) \
((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa)) ((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa))
#define bfa_isr_rspq_ack(__bfa, __queue) do { \ #define bfa_isr_rspq_ack(__bfa, __queue, __ci) \
if ((__bfa)->iocfc.hwif.hw_rspq_ack) \ ((__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue, __ci))
(__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue); \
} while (0)
#define bfa_isr_reqq_ack(__bfa, __queue) do { \ #define bfa_isr_reqq_ack(__bfa, __queue) do { \
if ((__bfa)->iocfc.hwif.hw_reqq_ack) \ if ((__bfa)->iocfc.hwif.hw_reqq_ack) \
(__bfa)->iocfc.hwif.hw_reqq_ack(__bfa, __queue); \ (__bfa)->iocfc.hwif.hw_reqq_ack(__bfa, __queue); \
...@@ -311,7 +309,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec); ...@@ -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_msix_lpu_err(struct bfa_s *bfa, int vec);
void bfa_hwcb_reginit(struct bfa_s *bfa); 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_init(struct bfa_s *bfa, int nvecs);
void bfa_hwcb_msix_ctrl_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_queue_install(struct bfa_s *bfa);
...@@ -324,7 +322,8 @@ void bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start, ...@@ -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_hwct_reginit(struct bfa_s *bfa);
void bfa_hwct2_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_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_init(struct bfa_s *bfa, int nvecs);
void bfa_hwct_msix_ctrl_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_queue_install(struct bfa_s *bfa);
......
...@@ -237,8 +237,6 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid) ...@@ -237,8 +237,6 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
u32 pi, ci; u32 pi, ci;
struct list_head *waitq; struct list_head *waitq;
bfa_isr_rspq_ack(bfa, qid);
ci = bfa_rspq_ci(bfa, qid); ci = bfa_rspq_ci(bfa, qid);
pi = bfa_rspq_pi(bfa, qid); pi = bfa_rspq_pi(bfa, qid);
...@@ -251,11 +249,9 @@ bfa_isr_rspq(struct bfa_s *bfa, int 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; bfa_isr_rspq_ack(bfa, qid, ci);
writel(pi, bfa->iocfc.bfa_regs.rme_q_ci[qid]);
mmiowb();
/* /*
* Resume any pending requests in the corresponding reqq. * Resume any pending requests in the corresponding reqq.
...@@ -325,23 +321,19 @@ bfa_intx(struct bfa_s *bfa) ...@@ -325,23 +321,19 @@ bfa_intx(struct bfa_s *bfa)
int queue; int queue;
intr = readl(bfa->iocfc.bfa_regs.intr_status); intr = readl(bfa->iocfc.bfa_regs.intr_status);
if (!intr)
return BFA_FALSE;
qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK); qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK);
if (qintr) if (qintr)
writel(qintr, bfa->iocfc.bfa_regs.intr_status); writel(qintr, bfa->iocfc.bfa_regs.intr_status);
/* /*
* RME completion queue interrupt * Unconditional RME completion queue interrupt
*/ */
qintr = intr & __HFN_INT_RME_MASK; if (bfa->queue_process) {
if (qintr && bfa->queue_process) {
for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++) for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
bfa_isr_rspq(bfa, queue); bfa_isr_rspq(bfa, queue);
} }
intr &= ~qintr;
if (!intr) if (!intr)
return BFA_TRUE; return BFA_TRUE;
...@@ -432,7 +424,8 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec) ...@@ -432,7 +424,8 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
__HFN_INT_MBOX_LPU1_CT2); __HFN_INT_MBOX_LPU1_CT2);
intr &= __HFN_INT_ERR_MASK_CT2; intr &= __HFN_INT_ERR_MASK_CT2;
} else { } 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; pss_isr = intr & __HFN_INT_ERR_PSS;
lpu_isr = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1); lpu_isr = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1);
intr &= __HFN_INT_ERR_MASK; 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, ...@@ -578,7 +571,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
} else { } else {
iocfc->hwif.hw_reginit = bfa_hwcb_reginit; iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
iocfc->hwif.hw_reqq_ack = NULL; 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_init = bfa_hwcb_msix_init;
iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_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_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, ...@@ -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))) { if (bfa_asic_id_ct2(bfa_ioc_devid(&bfa->ioc))) {
iocfc->hwif.hw_reginit = bfa_hwct2_reginit; iocfc->hwif.hw_reginit = bfa_hwct2_reginit;
iocfc->hwif.hw_isr_mode_set = NULL; 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); iocfc->hwif.hw_reginit(bfa);
...@@ -685,7 +678,7 @@ bfa_iocfc_start_submod(struct bfa_s *bfa) ...@@ -685,7 +678,7 @@ bfa_iocfc_start_submod(struct bfa_s *bfa)
bfa->queue_process = BFA_TRUE; bfa->queue_process = BFA_TRUE;
for (i = 0; i < BFI_IOC_MAX_CQS; i++) 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++) for (i = 0; hal_mods[i]; i++)
hal_mods[i]->start(bfa); hal_mods[i]->start(bfa);
......
...@@ -42,11 +42,36 @@ bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq) ...@@ -42,11 +42,36 @@ bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
bfa->iocfc.bfa_regs.intr_status); 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 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), writel(__HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq),
bfa->iocfc.bfa_regs.intr_status); 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 void
...@@ -149,8 +174,13 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa) ...@@ -149,8 +174,13 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
void void
bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
{ {
bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix; if (msix) {
bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_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 void
......
...@@ -64,13 +64,36 @@ bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq) ...@@ -64,13 +64,36 @@ bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
writel(r32, bfa->iocfc.bfa_regs.cpe_q_ctrl[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 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; u32 r32;
r32 = readl(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]); r32 = readl(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);
writel(r32, 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 void
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment