diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-24 20:24:08 -0700 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 17:02:28 -0500 |
commit | 3fd459804ff8e002db2671900debd0fc6dc6c443 (patch) | |
tree | 34d71220521bedb451182ae98a32c16906881503 /drivers/scsi/bfa | |
parent | 10a07379247078448c076690657a076076bf89aa (diff) |
[SCSI] bfa: Brocade-1860 Fabric Adapter vHBA support.
- 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>
Diffstat (limited to 'drivers/scsi/bfa')
-rw-r--r-- | drivers/scsi/bfa/bfa.h | 18 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_core.c | 62 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcpim.c | 64 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcpim.h | 4 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs_lport.c | 4 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_hw_cb.c | 10 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc_ct.c | 4 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.c | 188 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.h | 11 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi.h | 10 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi_ms.h | 19 |
12 files changed, 278 insertions, 118 deletions
diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h index 42769bc07ff4..ee072d99b8f9 100644 --- a/drivers/scsi/bfa/bfa.h +++ b/drivers/scsi/bfa/bfa.h @@ -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); \ @@ -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; @@ -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) \ @@ -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)) @@ -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); diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index f949844aa110..0048fc8646b4 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c @@ -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); @@ -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. @@ -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; @@ -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) @@ -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, @@ -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; @@ -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); @@ -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); @@ -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]); @@ -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. */ @@ -803,6 +814,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 */ bfa_msix_queue_install(bfa); @@ -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)); @@ -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)); @@ -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)); @@ -1230,7 +1246,7 @@ 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; @@ -1238,7 +1254,7 @@ bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr) 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; } diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c index 76d9a00ffb6a..eb14fd6193a0 100644 --- a/drivers/scsi/bfa/bfa_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcpim.c @@ -340,6 +340,9 @@ bfa_fcpim_iocdisable(struct bfa_fcp_mod_s *fcp) struct bfa_itnim_s *itnim; struct list_head *qe, *qen; + /* Enqueue unused ioim resources to free_q */ + list_splice_tail_init(&fcpim->tskim_unused_q, &fcpim->tskim_free_q); + list_for_each_safe(qe, qen, &fcpim->itnim_q) { itnim = (struct bfa_itnim_s *) qe; bfa_itnim_iocdisable(itnim); @@ -1036,7 +1039,7 @@ bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim) } bfi_h2i_set(m->mh, BFI_MC_ITN, BFI_ITN_H2I_CREATE_REQ, - bfa_lpuid(itnim->bfa)); + bfa_fn_lpu(itnim->bfa)); m->fw_handle = itnim->rport->fw_handle; m->class = FC_CLASS_3; m->seq_rec = itnim->seq_rec; @@ -1046,7 +1049,7 @@ bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim) /* * queue I/O message to firmware */ - bfa_reqq_produce(itnim->bfa, itnim->reqq); + bfa_reqq_produce(itnim->bfa, itnim->reqq, m->mh); return BFA_TRUE; } @@ -1065,14 +1068,14 @@ bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim) } bfi_h2i_set(m->mh, BFI_MC_ITN, BFI_ITN_H2I_DELETE_REQ, - bfa_lpuid(itnim->bfa)); + bfa_fn_lpu(itnim->bfa)); m->fw_handle = itnim->rport->fw_handle; bfa_stats(itnim, fw_delete); /* * queue I/O message to firmware */ - bfa_reqq_produce(itnim->bfa, itnim->reqq); + bfa_reqq_produce(itnim->bfa, itnim->reqq, m->mh); return BFA_TRUE; } @@ -2171,12 +2174,12 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim) */ switch (m->cmnd.iodir) { case FCP_IODIR_READ: - bfi_h2i_set(m->mh, BFI_MC_IOIM_READ, 0, bfa_lpuid(ioim->bfa)); + bfi_h2i_set(m->mh, BFI_MC_IOIM_READ, 0, bfa_fn_lpu(ioim->bfa)); bfa_stats(itnim, input_reqs); ioim->itnim->stats.rd_throughput += fcp_dl; break; case FCP_IODIR_WRITE: - bfi_h2i_set(m->mh, BFI_MC_IOIM_WRITE, 0, bfa_lpuid(ioim->bfa)); + bfi_h2i_set(m->mh, BFI_MC_IOIM_WRITE, 0, bfa_fn_lpu(ioim->bfa)); bfa_stats(itnim, output_reqs); ioim->itnim->stats.wr_throughput += fcp_dl; break; @@ -2184,16 +2187,16 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim) bfa_stats(itnim, input_reqs); bfa_stats(itnim, output_reqs); default: - bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa)); + bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_fn_lpu(ioim->bfa)); } if (itnim->seq_rec || (scsi_bufflen(cmnd) & (sizeof(u32) - 1))) - bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa)); + bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_fn_lpu(ioim->bfa)); /* * queue I/O message to firmware */ - bfa_reqq_produce(ioim->bfa, ioim->reqq); + bfa_reqq_produce(ioim->bfa, ioim->reqq, m->mh); return BFA_TRUE; } @@ -2251,14 +2254,14 @@ bfa_ioim_send_abort(struct bfa_ioim_s *ioim) else msgop = BFI_IOIM_H2I_IOCLEANUP_REQ; - bfi_h2i_set(m->mh, BFI_MC_IOIM, msgop, bfa_lpuid(ioim->bfa)); + bfi_h2i_set(m->mh, BFI_MC_IOIM, msgop, bfa_fn_lpu(ioim->bfa)); m->io_tag = cpu_to_be16(ioim->iotag); m->abort_tag = ++ioim->abort_tag; /* * queue I/O message to firmware */ - bfa_reqq_produce(ioim->bfa, ioim->reqq); + bfa_reqq_produce(ioim->bfa, ioim->reqq, m->mh); return BFA_TRUE; } @@ -2998,7 +3001,7 @@ bfa_tskim_send(struct bfa_tskim_s *tskim) * build i/o request message next */ bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_TM_REQ, - bfa_lpuid(tskim->bfa)); + bfa_fn_lpu(tskim->bfa)); m->tsk_tag = cpu_to_be16(tskim->tsk_tag); m->itn_fhdl = tskim->itnim->rport->fw_handle; @@ -3009,7 +3012,7 @@ bfa_tskim_send(struct bfa_tskim_s *tskim) /* * queue I/O message to firmware */ - bfa_reqq_produce(tskim->bfa, itnim->reqq); + bfa_reqq_produce(tskim->bfa, itnim->reqq, m->mh); return BFA_TRUE; } @@ -3033,14 +3036,14 @@ bfa_tskim_send_abort(struct bfa_tskim_s *tskim) * build i/o request message next */ bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_ABORT_REQ, - bfa_lpuid(tskim->bfa)); + bfa_fn_lpu(tskim->bfa)); m->tsk_tag = cpu_to_be16(tskim->tsk_tag); /* * queue I/O message to firmware */ - bfa_reqq_produce(tskim->bfa, itnim->reqq); + bfa_reqq_produce(tskim->bfa, itnim->reqq, m->mh); return BFA_TRUE; } @@ -3112,6 +3115,7 @@ bfa_tskim_attach(struct bfa_fcpim_s *fcpim, struct bfa_meminfo_s *minfo) u16 i; INIT_LIST_HEAD(&fcpim->tskim_free_q); + INIT_LIST_HEAD(&fcpim->tskim_unused_q); tskim = (struct bfa_tskim_s *) bfa_meminfo_kva(minfo); fcpim->tskim_arr = tskim; @@ -3211,6 +3215,19 @@ bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim, bfa_sm_send_event(tskim, BFA_TSKIM_SM_START); } +void +bfa_tskim_res_recfg(struct bfa_s *bfa, u16 num_tskim_fw) +{ + struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); + struct list_head *qe; + int i; + + for (i = 0; i < (fcpim->num_tskim_reqs - num_tskim_fw); i++) { + bfa_q_deq_tail(&fcpim->tskim_free_q, &qe); + list_add_tail(qe, &fcpim->tskim_unused_q); + } +} + /* BFA FCP module - parent module for fcpim */ BFA_MODULE(fcp); @@ -3303,10 +3320,26 @@ bfa_fcp_iocdisable(struct bfa_s *bfa) { struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa); + /* Enqueue unused ioim resources to free_q */ + list_splice_tail_init(&fcp->iotag_unused_q, &fcp->iotag_ioim_free_q); + bfa_fcpim_iocdisable(fcp); } void +bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw) +{ + struct bfa_fcp_mod_s *mod = BFA_FCP_MOD(bfa); + struct list_head *qe; + int i; + + for (i = 0; i < (mod->num_ioim_reqs - num_ioim_fw); i++) { + bfa_q_deq_tail(&mod->iotag_ioim_free_q, &qe); + list_add_tail(qe, &mod->iotag_unused_q); + } +} + +void bfa_itn_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void (*isr)(struct bfa_s *bfa, struct bfi_msg_s *m)) { @@ -3347,6 +3380,7 @@ bfa_iotag_attach(struct bfa_fcp_mod_s *fcp, struct bfa_meminfo_s *minfo) INIT_LIST_HEAD(&fcp->iotag_ioim_free_q); INIT_LIST_HEAD(&fcp->iotag_tio_free_q); + INIT_LIST_HEAD(&fcp->iotag_unused_q); num_io_req = fcp->num_ioim_reqs + fcp->num_fwtio_reqs; for (i = 0; i < num_io_req; i++, iotag++) { diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h index e1e3221fda43..bc6b294426ec 100644 --- a/drivers/scsi/bfa/bfa_fcpim.h +++ b/drivers/scsi/bfa/bfa_fcpim.h @@ -42,6 +42,7 @@ void bfa_itn_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void (*isr)(struct bfa_s *bfa, struct bfi_msg_s *m)); void bfa_itn_isr(struct bfa_s *bfa, struct bfi_msg_s *m); void bfa_iotag_attach(struct bfa_fcp_mod_s *fcp, struct bfa_meminfo_s *minfo); +void bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw); #define BFA_FCP_MOD(_hal) (&(_hal)->modules.fcp_mod) #define BFA_IOTAG_FROM_TAG(_fcp, _tag) \ @@ -118,6 +119,7 @@ struct bfa_fcpim_s { struct list_head ioim_resfree_q; /* IOs waiting for f/w */ struct list_head ioim_comp_q; /* IO global comp Q */ struct list_head tskim_free_q; + struct list_head tskim_unused_q; /* Unused tskim Q */ u32 ios_active; /* current active IOs */ u32 delay_comp; struct bfa_fcpim_del_itn_stats_s del_itn_stats; @@ -132,6 +134,7 @@ struct bfa_fcp_mod_s { struct bfa_s *bfa; struct list_head iotag_ioim_free_q; /* free IO resources */ struct list_head iotag_tio_free_q; /* free IO resources */ + struct list_head iotag_unused_q; /* unused IO resources*/ struct bfa_iotag_s *iotag_arr; struct bfa_itn_s *itn_arr; int num_ioim_reqs; @@ -270,6 +273,7 @@ void bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); void bfa_tskim_iodone(struct bfa_tskim_s *tskim); void bfa_tskim_iocdisable(struct bfa_tskim_s *tskim); void bfa_tskim_cleanup(struct bfa_tskim_s *tskim); +void bfa_tskim_res_recfg(struct bfa_s *bfa, u16 num_tskim_fw); void bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len, u32 *dm_len); diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 5332017f07e9..5bbb76b8e2ec 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -1298,7 +1298,7 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric) bfa_fcport_get_rx_bbcredit(bfa), bfa_fcs_fabric_oper_bbscn(fabric)); - bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->lp_tag, + bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->bfa_tag, BFA_FALSE, FC_CLASS_3, reqlen, &fchs, bfa_fcs_fabric_flogiacc_comp, fabric, FC_MAX_PDUSZ, 0); diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 479ccbe901b5..942443e711e5 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -898,8 +898,8 @@ bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs, lport->fcs = fcs; lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); lport->vport = vport; - lport->lp_tag = (vport) ? vport->lps->lp_tag : - lport->fabric->lps->lp_tag; + lport->lp_tag = (vport) ? vport->lps->bfa_tag : + lport->fabric->lps->bfa_tag; INIT_LIST_HEAD(&lport->rport_q); lport->num_rports = 0; diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c index 694ebf1b0bd1..e7ffd8205dc7 100644 --- a/drivers/scsi/bfa/bfa_hw_cb.c +++ b/drivers/scsi/bfa/bfa_hw_cb.c @@ -35,11 +35,6 @@ bfa_hwcb_reginit(struct bfa_s *bfa) } } -void -bfa_hwcb_reqq_ack(struct bfa_s *bfa, int reqq) -{ -} - static void bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq) { @@ -47,11 +42,6 @@ bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq) bfa->iocfc.bfa_regs.intr_status); } -void -bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq) -{ -} - static void bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq) { diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index 77f2b4470a69..d1b8f0caaa79 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -561,9 +561,9 @@ bfa_ioc_set_ct2_hwif(struct bfa_ioc_s *ioc) } /* - * Temporary workaround for MSI-X resource allocation for catapult-2. + * Workaround for MSI-X resource allocation for catapult-2 with no asic block */ -#define HOSTFN_MSIX_DEFAULT 16 +#define HOSTFN_MSIX_DEFAULT 64 #define HOSTFN_MSIX_VT_INDEX_MBOX_ERR 0x30138 #define HOSTFN_MSIX_VT_OFST_NUMVT 0x3013c #define __MSIX_VT_NUMVT__MK 0x003ff800 diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index fe99ce20ec28..cfc0b09465ec 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -125,6 +125,7 @@ static void bfa_lps_stop(struct bfa_s *bfa); static void bfa_lps_iocdisable(struct bfa_s *bfa); static void bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp); +static void bfa_lps_no_res(struct bfa_lps_s *first_lps, u8 count); static void bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp); static void bfa_lps_reqq_resume(void *lps_arg); @@ -475,6 +476,7 @@ claim_fcxps_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi) INIT_LIST_HEAD(&mod->fcxp_free_q); INIT_LIST_HEAD(&mod->fcxp_active_q); + INIT_LIST_HEAD(&mod->fcxp_unused_q); mod->fcxp_list = fcxp; @@ -561,6 +563,9 @@ bfa_fcxp_iocdisable(struct bfa_s *bfa) struct bfa_fcxp_s *fcxp; struct list_head *qe, *qen; + /* Enqueue unused fcxp resources to free_q */ + list_splice_tail_init(&mod->fcxp_unused_q, &mod->fcxp_free_q); + list_for_each_safe(qe, qen, &mod->fcxp_active_q) { fcxp = (struct bfa_fcxp_s *) qe; if (fcxp->caller == NULL) { @@ -829,7 +834,7 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req) struct bfa_rport_s *rport = reqi->bfa_rport; bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ, - bfa_lpuid(bfa)); + bfa_fn_lpu(bfa)); send_req->fcxp_tag = cpu_to_be16(fcxp->fcxp_tag); if (rport) { @@ -843,7 +848,7 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req) } send_req->vf_id = cpu_to_be16(reqi->vf_id); - send_req->lp_tag = reqi->lp_tag; + send_req->lp_fwtag = bfa_lps_get_fwtag(bfa, reqi->lp_tag); send_req->class = reqi->class; send_req->rsp_timeout = rspi->rsp_timeout; send_req->cts = reqi->cts; @@ -891,7 +896,7 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req) hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs); - bfa_reqq_produce(bfa, BFA_REQQ_FCXP); + bfa_reqq_produce(bfa, BFA_REQQ_FCXP, send_req->mh); bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP)); bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP)); @@ -1160,6 +1165,18 @@ bfa_fcxp_get_maxrsp(struct bfa_s *bfa) return mod->rsp_pld_sz; } +void +bfa_fcxp_res_recfg(struct bfa_s *bfa, u16 num_fcxp_fw) +{ + struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); + struct list_head *qe; + int i; + + for (i = 0; i < (mod->num_fcxps - num_fcxp_fw); i++) { + bfa_q_deq_tail(&mod->fcxp_free_q, &qe); + list_add_tail(qe, &mod->fcxp_unused_q); + } +} /* * BFA LPS state machine functions @@ -1171,7 +1188,7 @@ bfa_fcxp_get_maxrsp(struct bfa_s *bfa) static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) { - bfa_trc(lps->bfa, lps->lp_tag); + bfa_trc(lps->bfa, lps->bfa_tag); bfa_trc(lps->bfa, event); switch (event) { @@ -1223,7 +1240,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) { - bfa_trc(lps->bfa, lps->lp_tag); + bfa_trc(lps->bfa, lps->bfa_tag); bfa_trc(lps->bfa, event); switch (event) { @@ -1277,7 +1294,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) { - bfa_trc(lps->bfa, lps->lp_tag); + bfa_trc(lps->bfa, lps->bfa_tag); bfa_trc(lps->bfa, event); switch (event) { @@ -1310,7 +1327,7 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) { - bfa_trc(lps->bfa, lps->lp_tag); + bfa_trc(lps->bfa, lps->bfa_tag); bfa_trc(lps->bfa, event); switch (event) { @@ -1359,7 +1376,7 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) static void bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event) { - bfa_trc(lps->bfa, lps->lp_tag); + bfa_trc(lps->bfa, lps->bfa_tag); bfa_trc(lps->bfa, event); switch (event) { @@ -1401,7 +1418,7 @@ bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event) static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event) { - bfa_trc(lps->bfa, lps->lp_tag); + bfa_trc(lps->bfa, lps->bfa_tag); bfa_trc(lps->bfa, event); switch (event) { @@ -1426,7 +1443,7 @@ bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event) static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event) { - bfa_trc(lps->bfa, lps->lp_tag); + bfa_trc(lps->bfa, lps->bfa_tag); bfa_trc(lps->bfa, event); switch (event) { @@ -1488,10 +1505,11 @@ bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, INIT_LIST_HEAD(&mod->lps_free_q); INIT_LIST_HEAD(&mod->lps_active_q); + INIT_LIST_HEAD(&mod->lps_login_q); for (i = 0; i < mod->num_lps; i++, lps++) { lps->bfa = bfa; - lps->lp_tag = (u8) i; + lps->bfa_tag = (u8) i; lps->reqq = BFA_REQQ_LPS; bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps); list_add_tail(&lps->qe, &mod->lps_free_q); @@ -1527,6 +1545,11 @@ bfa_lps_iocdisable(struct bfa_s *bfa) lps = (struct bfa_lps_s *) qe; bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); } + list_for_each_safe(qe, qen, &mod->lps_login_q) { + lps = (struct bfa_lps_s *) qe; + bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); + } + list_splice_tail_init(&mod->lps_login_q, &mod->lps_active_q); } /* @@ -1538,12 +1561,13 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp) struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); struct bfa_lps_s *lps; - WARN_ON(rsp->lp_tag >= mod->num_lps); - lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag); + WARN_ON(rsp->bfa_tag >= mod->num_lps); + lps = BFA_LPS_FROM_TAG(mod, rsp->bfa_tag); lps->status = rsp->status; switch (rsp->status) { case BFA_STATUS_OK: + lps->fw_tag = rsp->fw_tag; lps->fport = rsp->f_port; if (lps->fport) lps->lp_pid = rsp->lp_pid; @@ -1570,14 +1594,46 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp) break; + case BFA_STATUS_VPORT_MAX: + if (!rsp->ext_status) + bfa_lps_no_res(lps, rsp->ext_status); + break; + default: /* Nothing to do with other status */ break; } + list_del(&lps->qe); + list_add_tail(&lps->qe, &mod->lps_active_q); bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); } +static void +bfa_lps_no_res(struct bfa_lps_s *first_lps, u8 count) +{ + struct bfa_s *bfa = first_lps->bfa; + struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); + struct list_head *qe, *qe_next; + struct bfa_lps_s *lps; + + bfa_trc(bfa, count); + + qe = bfa_q_next(first_lps); + + while (count && qe) { + qe_next = bfa_q_next(qe); + lps = (struct bfa_lps_s *)qe; + bfa_trc(bfa, lps->bfa_tag); + lps->status = first_lps->status; + list_del(&lps->qe); + list_add_tail(&lps->qe, &mod->lps_active_q); + bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); + qe = qe_next; + count--; + } +} + /* * Firmware logout response */ @@ -1587,8 +1643,8 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp) struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); struct bfa_lps_s *lps; - WARN_ON(rsp->lp_tag >= mod->num_lps); - lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag); + WARN_ON(rsp->bfa_tag >= mod->num_lps); + lps = BFA_LPS_FROM_TAG(mod, rsp->bfa_tag); bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); } @@ -1602,7 +1658,7 @@ bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl) struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); struct bfa_lps_s *lps; - lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag); + lps = BFA_LPS_FROM_TAG(mod, cvl->bfa_tag); bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL); } @@ -1637,15 +1693,16 @@ bfa_lps_free(struct bfa_lps_s *lps) static void bfa_lps_send_login(struct bfa_lps_s *lps) { + struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa); struct bfi_lps_login_req_s *m; m = bfa_reqq_next(lps->bfa, lps->reqq); WARN_ON(!m); bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ, - bfa_lpuid(lps->bfa)); + bfa_fn_lpu(lps->bfa)); - m->lp_tag = lps->lp_tag; + m->bfa_tag = lps->bfa_tag; m->alpa = lps->alpa; m->pdu_size = cpu_to_be16(lps->pdusz); m->pwwn = lps->pwwn; @@ -1654,7 +1711,9 @@ bfa_lps_send_login(struct bfa_lps_s *lps) m->auth_en = lps->auth_en; m->bb_scn = lps->bb_scn; - bfa_reqq_produce(lps->bfa, lps->reqq); + bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); + list_del(&lps->qe); + list_add_tail(&lps->qe, &mod->lps_login_q); } /* @@ -1669,11 +1728,11 @@ bfa_lps_send_logout(struct bfa_lps_s *lps) WARN_ON(!m); bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGOUT_REQ, - bfa_lpuid(lps->bfa)); + bfa_fn_lpu(lps->bfa)); - m->lp_tag = lps->lp_tag; + m->fw_tag = lps->fw_tag; m->port_name = lps->pwwn; - bfa_reqq_produce(lps->bfa, lps->reqq); + bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); } /* @@ -1688,11 +1747,11 @@ bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps) WARN_ON(!m); bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ, - bfa_lpuid(lps->bfa)); + bfa_fn_lpu(lps->bfa)); - m->lp_tag = lps->lp_tag; + m->fw_tag = lps->fw_tag; m->lp_pid = lps->lp_pid; - bfa_reqq_produce(lps->bfa, lps->reqq); + bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); } /* @@ -1884,6 +1943,13 @@ bfa_lps_fdisclogo(struct bfa_lps_s *lps) bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT); } +u8 +bfa_lps_get_fwtag(struct bfa_s *bfa, u8 lp_tag) +{ + struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); + + return BFA_LPS_FROM_TAG(mod, lp_tag)->fw_tag; +} /* * Return lport services tag given the pid @@ -1897,7 +1963,7 @@ bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid) for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) { if (lps->lp_pid == pid) - return lps->lp_tag; + return lps->bfa_tag; } /* Return base port tag anyway */ @@ -1922,7 +1988,7 @@ bfa_lps_get_base_pid(struct bfa_s *bfa) void bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, uint32_t n2n_pid) { - bfa_trc(lps->bfa, lps->lp_tag); + bfa_trc(lps->bfa, lps->bfa_tag); bfa_trc(lps->bfa, n2n_pid); lps->lp_pid = n2n_pid; @@ -2935,7 +3001,7 @@ bfa_fcport_send_enable(struct bfa_fcport_s *fcport) } bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ, - bfa_lpuid(fcport->bfa)); + bfa_fn_lpu(fcport->bfa)); m->nwwn = fcport->nwwn; m->pwwn = fcport->pwwn; m->port_cfg = fcport->cfg; @@ -2949,7 +3015,7 @@ bfa_fcport_send_enable(struct bfa_fcport_s *fcport) /* * queue I/O message to firmware */ - bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh); return BFA_TRUE; } @@ -2978,13 +3044,13 @@ bfa_fcport_send_disable(struct bfa_fcport_s *fcport) } bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ, - bfa_lpuid(fcport->bfa)); + bfa_fn_lpu(fcport->bfa)); m->msgtag = fcport->msgtag; /* * queue I/O message to firmware */ - bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh); return BFA_TRUE; } @@ -3016,14 +3082,14 @@ bfa_fcport_send_txcredit(void *port_cbarg) |