Skip to content

Commit

Permalink
[SCSI] bfa: Brocade-1860 Fabric Adapter vHBA support.
Browse files Browse the repository at this point in the history
- Introduced partitioning of the BFA resources.
- Added h/w queue ID in CPE messages, firmware uses h/w queue ID
  from messages to pick a matching RME queue.
- Added message header to bfa_reqq_produce(). h/w queue ID is set
  in the message header and firmware modules use h/w queue ID from
  message header instead of from cpqe event.
- Made changes to allow using all 256 queues of Brocade-1860 asic.
  Previously only a single queue per queue group was used.
- Added function tag to BFI message header. Only used by FC BFI
  messages.  Used to translate host tag to firmware tag. bfa_lpuid()
  is changed to bfa_fn_lpu() that encodes both PCI function and port
  ID in BFI message header.

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 10a0737 commit 3fd4598
Show file tree
Hide file tree
Showing 12 changed files with 278 additions and 118 deletions.
18 changes: 13 additions & 5 deletions drivers/scsi/bfa/bfa.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ void bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m);
((void *)((struct bfi_msg_s *)((__bfa)->iocfc.req_cq_ba[__reqq].kva) \
+ bfa_reqq_pi((__bfa), (__reqq)))))

#define bfa_reqq_produce(__bfa, __reqq) do { \
#define bfa_reqq_produce(__bfa, __reqq, __mh) do { \
(__mh).mtag.h2i.qid = (__bfa)->iocfc.hw_qid[__reqq];\
(__bfa)->iocfc.req_cq_pi[__reqq]++; \
(__bfa)->iocfc.req_cq_pi[__reqq] &= \
((__bfa)->iocfc.cfg.drvcfg.num_reqq_elems - 1); \
Expand Down Expand Up @@ -272,6 +273,7 @@ struct bfa_iocfc_s {
int action;
u32 req_cq_pi[BFI_IOC_MAX_CQS];
u32 rsp_cq_ci[BFI_IOC_MAX_CQS];
u8 hw_qid[BFI_IOC_MAX_CQS];
struct bfa_cb_qe_s init_hcb_qe;
struct bfa_cb_qe_s stop_hcb_qe;
struct bfa_cb_qe_s dis_hcb_qe;
Expand All @@ -294,8 +296,8 @@ struct bfa_iocfc_s {
struct bfa_faa_args_s faa_args;
};

#define bfa_lpuid(__bfa) \
bfa_ioc_portid(&(__bfa)->ioc)
#define bfa_fn_lpu(__bfa) \
bfi_fn_lpu(bfa_ioc_pcifn(&(__bfa)->ioc), bfa_ioc_portid(&(__bfa)->ioc))
#define bfa_msix_init(__bfa, __nvecs) \
((__bfa)->iocfc.hwif.hw_msix_init(__bfa, __nvecs))
#define bfa_msix_ctrl_install(__bfa) \
Expand All @@ -304,11 +306,18 @@ 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_reqq_ack(__bfa, __queue) do { \
if ((__bfa)->iocfc.hwif.hw_reqq_ack) \
(__bfa)->iocfc.hwif.hw_reqq_ack(__bfa, __queue); \
} while (0)
#define bfa_isr_mode_set(__bfa, __msix) do { \
if ((__bfa)->iocfc.hwif.hw_isr_mode_set) \
(__bfa)->iocfc.hwif.hw_isr_mode_set(__bfa, __msix); \
} while (0)

#define bfa_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec) \
((__bfa)->iocfc.hwif.hw_msix_getvecs(__bfa, __vecmap, \
__nvecs, __maxvec))
Expand Down Expand Up @@ -340,7 +349,6 @@ 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_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_ctrl_install(struct bfa_s *bfa);
Expand Down
62 changes: 39 additions & 23 deletions drivers/scsi/bfa/bfa_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
u32 pi, ci;
struct list_head *waitq;

bfa->iocfc.hwif.hw_rspq_ack(bfa, qid);
bfa_isr_rspq_ack(bfa, qid);

ci = bfa_rspq_ci(bfa, qid);
pi = bfa_rspq_pi(bfa, qid);
Expand Down Expand Up @@ -236,9 +236,7 @@ bfa_isr_reqq(struct bfa_s *bfa, int qid)
{
struct list_head *waitq;

qid &= (BFI_IOC_MAX_CQS - 1);

bfa->iocfc.hwif.hw_reqq_ack(bfa, qid);
bfa_isr_reqq_ack(bfa, qid);

/*
* Resume any pending requests in the corresponding reqq.
Expand Down Expand Up @@ -296,16 +294,19 @@ bfa_intx(struct bfa_s *bfa)
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
*/
qintr = intr & __HFN_INT_RME_MASK;
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)) && bfa->queue_process)
bfa_isr_rspq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
if (qintr && bfa->queue_process) {
for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
bfa_isr_rspq(bfa, queue);
}

intr &= ~qintr;
if (!intr)
return BFA_TRUE;
Expand All @@ -314,11 +315,9 @@ bfa_intx(struct bfa_s *bfa)
* CPE completion queue interrupt
*/
qintr = intr & __HFN_INT_CPE_MASK;
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)) && bfa->queue_process)
bfa_isr_reqq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
if (qintr && bfa->queue_process) {
for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
bfa_isr_reqq(bfa, queue);
}
intr &= ~qintr;
if (!intr)
Expand Down Expand Up @@ -542,7 +541,7 @@ bfa_iocfc_send_cfg(void *bfa_arg)
* dma map IOC configuration itself
*/
bfi_h2i_set(cfg_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CFG_REQ,
bfa_lpuid(bfa));
bfa_fn_lpu(bfa));
bfa_dma_be_addr_set(cfg_req.ioc_cfg_dma_addr, iocfc->cfg_info.pa);

bfa_ioc_mbox_send(&bfa->ioc, &cfg_req,
Expand Down Expand Up @@ -579,8 +578,8 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
iocfc->hwif.cpe_vec_q0 = BFI_MSIX_CPE_QMIN_CT;
} else {
iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack;
iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
iocfc->hwif.hw_reqq_ack = NULL;
iocfc->hwif.hw_rspq_ack = NULL;
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;
Expand All @@ -597,6 +596,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_reginit(bfa);
Expand Down Expand Up @@ -701,7 +701,7 @@ bfa_iocfc_start_submod(struct bfa_s *bfa)

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

for (i = 0; hal_mods[i]; i++)
hal_mods[i]->start(bfa);
Expand Down Expand Up @@ -768,6 +768,7 @@ bfa_iocfc_qreg(struct bfa_s *bfa, struct bfi_iocfc_qreg_s *qreg)
void __iomem *kva = bfa_ioc_bar0(&bfa->ioc);

for (i = 0; i < BFI_IOC_MAX_CQS; i++) {
bfa->iocfc.hw_qid[i] = qreg->hw_qid[i];
r->cpe_q_ci[i] = kva + be32_to_cpu(qreg->cpe_q_ci_off[i]);
r->cpe_q_pi[i] = kva + be32_to_cpu(qreg->cpe_q_pi_off[i]);
r->cpe_q_ctrl[i] = kva + be32_to_cpu(qreg->cpe_qctl_off[i]);
Expand All @@ -777,6 +778,16 @@ bfa_iocfc_qreg(struct bfa_s *bfa, struct bfi_iocfc_qreg_s *qreg)
}
}

static void
bfa_iocfc_res_recfg(struct bfa_s *bfa, struct bfa_iocfc_fwcfg_s *fwcfg)
{
bfa_fcxp_res_recfg(bfa, fwcfg->num_fcxp_reqs);
bfa_uf_res_recfg(bfa, fwcfg->num_uf_bufs);
bfa_rport_res_recfg(bfa, fwcfg->num_rports);
bfa_fcp_res_recfg(bfa, fwcfg->num_ioim_reqs);
bfa_tskim_res_recfg(bfa, fwcfg->num_tskim_reqs);
}

/*
* Update BFA configuration from firmware configuration.
*/
Expand All @@ -802,6 +813,11 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
*/
bfa_iocfc_qreg(bfa, &cfgrsp->qreg);

/*
* Re-configure resources as learnt from Firmware
*/
bfa_iocfc_res_recfg(bfa, fwcfg);

/*
* Install MSIX queue handlers
*/
Expand Down Expand Up @@ -880,7 +896,7 @@ bfa_faa_enable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn, void *cbarg)

memset(&faa_enable_req, 0, sizeof(struct bfi_faa_en_dis_s));
bfi_h2i_set(faa_enable_req.mh, BFI_MC_IOCFC,
BFI_IOCFC_H2I_FAA_ENABLE_REQ, bfa_lpuid(bfa));
BFI_IOCFC_H2I_FAA_ENABLE_REQ, bfa_fn_lpu(bfa));

bfa_ioc_mbox_send(&bfa->ioc, &faa_enable_req,
sizeof(struct bfi_faa_en_dis_s));
Expand Down Expand Up @@ -914,7 +930,7 @@ bfa_faa_disable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn,

memset(&faa_disable_req, 0, sizeof(struct bfi_faa_en_dis_s));
bfi_h2i_set(faa_disable_req.mh, BFI_MC_IOCFC,
BFI_IOCFC_H2I_FAA_DISABLE_REQ, bfa_lpuid(bfa));
BFI_IOCFC_H2I_FAA_DISABLE_REQ, bfa_fn_lpu(bfa));

bfa_ioc_mbox_send(&bfa->ioc, &faa_disable_req,
sizeof(struct bfi_faa_en_dis_s));
Expand Down Expand Up @@ -944,7 +960,7 @@ bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr,
iocfc->faa_args.busy = BFA_TRUE;
memset(&faa_attr_req, 0, sizeof(struct bfi_faa_query_s));
bfi_h2i_set(faa_attr_req.mh, BFI_MC_IOCFC,
BFI_IOCFC_H2I_FAA_QUERY_REQ, bfa_lpuid(bfa));
BFI_IOCFC_H2I_FAA_QUERY_REQ, bfa_fn_lpu(bfa));

bfa_ioc_mbox_send(&bfa->ioc, &faa_attr_req,
sizeof(struct bfi_faa_query_s));
Expand Down Expand Up @@ -1230,15 +1246,15 @@ bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr)
return BFA_STATUS_DEVBUSY;

bfi_h2i_set(m->mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_SET_INTR_REQ,
bfa_lpuid(bfa));
bfa_fn_lpu(bfa));
m->coalesce = iocfc->cfginfo->intr_attr.coalesce;
m->delay = iocfc->cfginfo->intr_attr.delay;
m->latency = iocfc->cfginfo->intr_attr.latency;

bfa_trc(bfa, attr->delay);
bfa_trc(bfa, attr->latency);

bfa_reqq_produce(bfa, BFA_REQQ_IOC);
bfa_reqq_produce(bfa, BFA_REQQ_IOC, m->mh);
return BFA_STATUS_OK;
}

Expand Down
Loading

0 comments on commit 3fd4598

Please sign in to comment.