Skip to content

Commit

Permalink
[SCSI] bfa: IOC and PLL init changes for Brocade-1860 Fabric Adapter.
Browse files Browse the repository at this point in the history
- 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: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Krishna Gudipati authored and James Bottomley committed Jun 29, 2011
1 parent dd5aaf4 commit 775c774
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 137 deletions.
15 changes: 10 additions & 5 deletions drivers/scsi/bfa/bfa.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 { \
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
28 changes: 16 additions & 12 deletions drivers/scsi/bfa/bfa_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}

Expand Down
58 changes: 43 additions & 15 deletions drivers/scsi/bfa/bfa_hw_cb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_hwcb_msix_uninstall(bfa);
}

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

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

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_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;

for (; i < BFI_MSIX_CB_MAX; i++)
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;
}

/*
Expand Down
18 changes: 14 additions & 4 deletions drivers/scsi/bfa/bfa_hw_ct.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,27 @@ 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;

if (bfa->msix.nvecs == 0)
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;
}
Expand All @@ -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
Expand Down
Loading

0 comments on commit 775c774

Please sign in to comment.