diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-13 15:50:35 -0700 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 15:31:31 -0500 |
commit | 111892082ed7a3214bc7a7ec6b8b20e8f847501a (patch) | |
tree | fb4950f69aaf7c2bf07ce8987884bb52aa497ffa /drivers | |
parent | 43ffdf4dfb827babcdca5345a76031598a985dc8 (diff) |
[SCSI] bfa: Brocade-1860 Fabric Adapter Hardware Enablement
- Added support for Brocade-1860 Fabric Adapter.
- Made changes to support single firmware image per asic type.
- Combined bfi_cbreg.h and bfi_ctreg.h defines into bfi_reg.h with
only minimal defines used by host.
- Added changes to setup CPE/RME Queue register offsets based on
firmware response.
- Removed queue register offset initializations and added register offsets
to BFI config response message.
- Added Brocade-1860 asic specific interrupt status definitions and
mailbox interfaces.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/bfa/bfa.h | 14 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_core.c | 209 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_defs.h | 13 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_hw_cb.c | 34 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_hw_ct.c | 75 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc.c | 144 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc.h | 117 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc_cb.c | 56 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc_ct.c | 418 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_port.c | 2 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad.c | 81 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_drv.h | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_im.c | 2 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi.h | 62 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi_cbreg.h | 305 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi_ctreg.h | 636 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi_ms.h | 36 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi_reg.h | 428 |
18 files changed, 1262 insertions, 1371 deletions
diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h index 7be6b5a8114..708bab093c1 100644 --- a/drivers/scsi/bfa/bfa.h +++ b/drivers/scsi/bfa/bfa.h @@ -136,7 +136,6 @@ struct bfa_cb_qe_s { struct list_head qe; bfa_cb_cbfn_t cbfn; bfa_boolean_t once; - u32 rsvd; void *cbarg; }; @@ -205,11 +204,9 @@ struct bfa_iocfc_regs_s { void __iomem *intr_mask; void __iomem *cpe_q_pi[BFI_IOC_MAX_CQS]; void __iomem *cpe_q_ci[BFI_IOC_MAX_CQS]; - void __iomem *cpe_q_depth[BFI_IOC_MAX_CQS]; void __iomem *cpe_q_ctrl[BFI_IOC_MAX_CQS]; void __iomem *rme_q_ci[BFI_IOC_MAX_CQS]; void __iomem *rme_q_pi[BFI_IOC_MAX_CQS]; - void __iomem *rme_q_depth[BFI_IOC_MAX_CQS]; void __iomem *rme_q_ctrl[BFI_IOC_MAX_CQS]; }; @@ -238,6 +235,8 @@ struct bfa_hwif_s { u32 *nvecs, u32 *maxvec); void (*hw_msix_get_rme_range) (struct bfa_s *bfa, u32 *start, u32 *end); + int cpe_vec_q0; + int rme_vec_q0; }; typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status); @@ -257,7 +256,6 @@ struct bfa_iocfc_s { struct bfi_iocfc_cfg_s *cfginfo; struct bfa_dma_s cfgrsp_dma; struct bfi_iocfc_cfgrsp_s *cfgrsp; - struct bfi_iocfc_cfg_reply_s *cfg_reply; struct bfa_dma_s req_cq_ba[BFI_IOC_MAX_CQS]; struct bfa_dma_s req_cq_shadow_ci[BFI_IOC_MAX_CQS]; struct bfa_dma_s rsp_cq_ba[BFI_IOC_MAX_CQS]; @@ -277,8 +275,11 @@ struct bfa_iocfc_s { ((__bfa)->iocfc.hwif.hw_msix_install(__bfa)) #define bfa_msix_uninstall(__bfa) \ ((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa)) -#define bfa_isr_mode_set(__bfa, __msix) \ - ((__bfa)->iocfc.hwif.hw_isr_mode_set(__bfa, __msix)) +#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)) @@ -321,6 +322,7 @@ void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, u32 *nvecs, void bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end); 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_msix_init(struct bfa_s *bfa, int nvecs); diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index 8e496e16a2a..5a00217ee5b 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c @@ -17,7 +17,7 @@ #include "bfad_drv.h" #include "bfa_modules.h" -#include "bfi_ctreg.h" +#include "bfi_reg.h" BFA_TRC_FILE(HAL, CORE); @@ -173,6 +173,58 @@ bfa_reqq_resume(struct bfa_s *bfa, int qid) } } +static inline void +bfa_isr_rspq(struct bfa_s *bfa, int qid) +{ + struct bfi_msg_s *m; + u32 pi, ci; + struct list_head *waitq; + + bfa->iocfc.hwif.hw_rspq_ack(bfa, qid); + + ci = bfa_rspq_ci(bfa, qid); + pi = bfa_rspq_pi(bfa, qid); + + while (ci != pi) { + m = bfa_rspq_elem(bfa, qid, ci); + WARN_ON(m->mhdr.msg_class >= BFI_MC_MAX); + + bfa_isrs[m->mhdr.msg_class] (bfa, m); + CQ_INCR(ci, bfa->iocfc.cfg.drvcfg.num_rspq_elems); + } + + /* + * update CI + */ + bfa_rspq_ci(bfa, qid) = pi; + writel(pi, bfa->iocfc.bfa_regs.rme_q_ci[qid]); + mmiowb(); + + /* + * Resume any pending requests in the corresponding reqq. + */ + waitq = bfa_reqq(bfa, qid); + if (!list_empty(waitq)) + bfa_reqq_resume(bfa, qid); +} + +static inline void +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); + + /* + * Resume any pending requests in the corresponding reqq. + */ + waitq = bfa_reqq(bfa, qid); + if (!list_empty(waitq)) + bfa_reqq_resume(bfa, qid); +} + void bfa_msix_all(struct bfa_s *bfa, int vec) { @@ -197,7 +249,7 @@ bfa_intx(struct bfa_s *bfa) for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) { if (intr & (__HFN_INT_RME_Q0 << queue)) - bfa_msix_rspq(bfa, queue & (BFI_IOC_MAX_CQS - 1)); + bfa_isr_rspq(bfa, queue & (BFI_IOC_MAX_CQS - 1)); } intr &= ~qintr; if (!intr) @@ -211,7 +263,7 @@ bfa_intx(struct bfa_s *bfa) for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) { if (intr & (__HFN_INT_CPE_Q0 << queue)) - bfa_msix_reqq(bfa, queue & (BFI_IOC_MAX_CQS - 1)); + bfa_isr_reqq(bfa, queue & (BFI_IOC_MAX_CQS - 1)); } intr &= ~qintr; if (!intr) @@ -225,32 +277,25 @@ bfa_intx(struct bfa_s *bfa) void bfa_isr_enable(struct bfa_s *bfa) { - u32 intr_unmask; + u32 umsk; int pci_func = bfa_ioc_pcifn(&bfa->ioc); bfa_trc(bfa, pci_func); bfa_msix_install(bfa); - intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | - __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | - __HFN_INT_LL_HALT); - - if (pci_func == 0) - intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 | - __HFN_INT_CPE_Q2 | __HFN_INT_CPE_Q3 | - __HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 | - __HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 | - __HFN_INT_MBOX_LPU0); - else - intr_unmask |= (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 | - __HFN_INT_CPE_Q6 | __HFN_INT_CPE_Q7 | - __HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 | - __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 | - __HFN_INT_MBOX_LPU1); - - writel(intr_unmask, bfa->iocfc.bfa_regs.intr_status); - writel(~intr_unmask, bfa->iocfc.bfa_regs.intr_mask); - bfa->iocfc.intr_mask = ~intr_unmask; + + if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) { + umsk = __HFN_INT_ERR_MASK_CT2; + umsk |= pci_func == 0 ? + __HFN_INT_FN0_MASK_CT2 : __HFN_INT_FN1_MASK_CT2; + } else { + umsk = __HFN_INT_ERR_MASK; + umsk |= pci_func == 0 ? __HFN_INT_FN0_MASK : __HFN_INT_FN1_MASK; + } + + writel(umsk, bfa->iocfc.bfa_regs.intr_status); + writel(~umsk, bfa->iocfc.bfa_regs.intr_mask); + bfa->iocfc.intr_mask = ~umsk; bfa_isr_mode_set(bfa, bfa->msix.nvecs != 0); } @@ -263,20 +308,9 @@ bfa_isr_disable(struct bfa_s *bfa) } void -bfa_msix_reqq(struct bfa_s *bfa, int qid) +bfa_msix_reqq(struct bfa_s *bfa, int vec) { - struct list_head *waitq; - - qid &= (BFI_IOC_MAX_CQS - 1); - - bfa->iocfc.hwif.hw_reqq_ack(bfa, qid); - - /* - * Resume any pending requests in the corresponding reqq. - */ - waitq = bfa_reqq(bfa, qid); - if (!list_empty(waitq)) - bfa_reqq_resume(bfa, qid); + bfa_isr_reqq(bfa, vec - bfa->iocfc.hwif.cpe_vec_q0); } void @@ -290,57 +324,40 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m) } void -bfa_msix_rspq(struct bfa_s *bfa, int qid) +bfa_msix_rspq(struct bfa_s *bfa, int vec) { - struct bfi_msg_s *m; - u32 pi, ci; - struct list_head *waitq; - - qid &= (BFI_IOC_MAX_CQS - 1); - - bfa->iocfc.hwif.hw_rspq_ack(bfa, qid); - - ci = bfa_rspq_ci(bfa, qid); - pi = bfa_rspq_pi(bfa, qid); - - if (bfa->rme_process) { - while (ci != pi) { - m = bfa_rspq_elem(bfa, qid, ci); - bfa_isrs[m->mhdr.msg_class] (bfa, m); - CQ_INCR(ci, bfa->iocfc.cfg.drvcfg.num_rspq_elems); - } - } - - /* - * update CI - */ - bfa_rspq_ci(bfa, qid) = pi; - writel(pi, bfa->iocfc.bfa_regs.rme_q_ci[qid]); - mmiowb(); + if (!bfa->rme_process) + return; - /* - * Resume any pending requests in the corresponding reqq. - */ - waitq = bfa_reqq(bfa, qid); - if (!list_empty(waitq)) - bfa_reqq_resume(bfa, qid); + bfa_isr_rspq(bfa, vec - bfa->iocfc.hwif.rme_vec_q0); } void bfa_msix_lpu_err(struct bfa_s *bfa, int vec) { u32 intr, curr_value; + bfa_boolean_t lpu_isr, halt_isr, pss_isr; intr = readl(bfa->iocfc.bfa_regs.intr_status); - if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1)) - bfa_ioc_mbox_isr(&bfa->ioc); + if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) { + halt_isr = intr & __HFN_INT_CPQ_HALT_CT2; + pss_isr = intr & __HFN_INT_ERR_PSS_CT2; + lpu_isr = intr & (__HFN_INT_MBOX_LPU0_CT2 | + __HFN_INT_MBOX_LPU1_CT2); + intr &= __HFN_INT_ERR_MASK_CT2; + } else { + halt_isr = intr & __HFN_INT_LL_HALT; + pss_isr = intr & __HFN_INT_ERR_PSS; + lpu_isr = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1); + intr &= __HFN_INT_ERR_MASK; + } - intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | - __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT); + if (lpu_isr) + bfa_ioc_mbox_isr(&bfa->ioc); if (intr) { - if (intr & __HFN_INT_LL_HALT) { + if (halt_isr) { /* * If LL_HALT bit is set then FW Init Halt LL Port * Register needs to be cleared as well so Interrupt @@ -351,7 +368,7 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec) writel(curr_value, bfa->ioc.ioc_regs.ll_halt); } - if (intr & __HFN_INT_ERR_PSS) { + if (pss_isr) { /* * ERR_PSS bit needs to be cleared as well in case * interrups are shared so driver's interrupt handler is @@ -359,7 +376,6 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec) */ curr_value = readl( bfa->ioc.ioc_regs.pss_err_status_reg); - curr_value &= __PSS_ERR_STATUS_SET; writel(curr_value, bfa->ioc.ioc_regs.pss_err_status_reg); } @@ -491,7 +507,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, /* * Initialize chip specific handlers. */ - if (bfa_asic_id_ct(bfa_ioc_devid(&bfa->ioc))) { + if (bfa_asic_id_ctc(bfa_ioc_devid(&bfa->ioc))) { iocfc->hwif.hw_reginit = bfa_hwct_reginit; iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack; iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack; @@ -501,6 +517,8 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set; iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs; iocfc->hwif.hw_msix_get_rme_range = bfa_hwct_msix_get_rme_range; + iocfc->hwif.rme_vec_q0 = BFI_MSIX_RME_QMIN_CT; + 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; @@ -511,6 +529,15 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set; iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs; iocfc->hwif.hw_msix_get_rme_range = bfa_hwcb_msix_get_rme_range; + iocfc->hwif.rme_vec_q0 = BFI_MSIX_RME_QMIN_CB + + bfa_ioc_pcifn(&bfa->ioc) * BFI_IOC_MAX_CQS; + iocfc->hwif.cpe_vec_q0 = BFI_MSIX_CPE_QMIN_CB + + bfa_ioc_pcifn(&bfa->ioc) * BFI_IOC_MAX_CQS; + } + + 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_reginit(bfa); @@ -614,6 +641,8 @@ bfa_iocfc_start_submod(struct bfa_s *bfa) int i; bfa->rme_process = BFA_TRUE; + for (i = 0; i < BFI_IOC_MAX_CQS; i++) + bfa->iocfc.hwif.hw_rspq_ack(bfa, i); for (i = 0; hal_mods[i]; i++) hal_mods[i]->start(bfa); @@ -669,6 +698,26 @@ bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl) complete(&bfad->disable_comp); } +/** + * configure queue registers from firmware response + */ +static void +bfa_iocfc_qreg(struct bfa_s *bfa, struct bfi_iocfc_qreg_s *qreg) +{ + int i; + struct bfa_iocfc_regs_s *r = &bfa->iocfc.bfa_regs; + void __iomem *kva = bfa_ioc_bar0(&bfa->ioc); + + for (i = 0; i < BFI_IOC_MAX_CQS; 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]); + r->rme_q_ci[i] = kva + be32_to_cpu(qreg->rme_q_ci_off[i]); + r->rme_q_pi[i] = kva + be32_to_cpu(qreg->rme_q_pi_off[i]); + r->rme_q_ctrl[i] = kva + be32_to_cpu(qreg->rme_qctl_off[i]); + } +} + /* * Update BFA configuration from firmware configuration. */ @@ -689,6 +738,11 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa) iocfc->cfgdone = BFA_TRUE; /* + * configure queue register offsets as learnt from firmware + */ + bfa_iocfc_qreg(bfa, &cfgrsp->qreg); + + /* * Configuration is complete - initialize/start submodules */ bfa_fcport_init(bfa); @@ -879,7 +933,6 @@ bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m) switch (msg->mh.msg_id) { case BFI_IOCFC_I2H_CFG_REPLY: - iocfc->cfg_reply = &msg->cfg_reply; bfa_iocfc_cfgrsp(bfa); break; case BFI_IOCFC_I2H_UPDATEQ_RSP: diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index d85f93aea46..be1ba54fa19 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h @@ -386,11 +386,18 @@ enum { BFA_PCI_DEVICE_ID_FC_8G1P = 0x17, BFA_PCI_DEVICE_ID_CT = 0x14, BFA_PCI_DEVICE_ID_CT_FC = 0x21, + BFA_PCI_DEVICE_ID_CT2 = 0x22, }; -#define bfa_asic_id_ct(devid) \ - ((devid) == BFA_PCI_DEVICE_ID_CT || \ - (devid) == BFA_PCI_DEVICE_ID_CT_FC) +#define bfa_asic_id_cb(__d) \ + ((__d) == BFA_PCI_DEVICE_ID_FC_8G2P || \ + (__d) == BFA_PCI_DEVICE_ID_FC_8G1P) +#define bfa_asic_id_ct(__d) \ + ((__d) == BFA_PCI_DEVICE_ID_CT || \ + (__d) == BFA_PCI_DEVICE_ID_CT_FC) +#define bfa_asic_id_ct2(__d) ((__d) == BFA_PCI_DEVICE_ID_CT2) +#define bfa_asic_id_ctc(__d) \ + (bfa_asic_id_ct(__d) || bfa_asic_id_ct2(__d)) /* * PCI sub-system device and vendor ID information diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c index 977e681ec80..4ef3cf2e7d9 100644 --- a/drivers/scsi/bfa/bfa_hw_cb.c +++ b/drivers/scsi/bfa/bfa_hw_cb.c @@ -17,14 +17,14 @@ #include "bfad_drv.h" #include "bfa_modules.h" -#include "bfi_cbreg.h" +#include "bfi_reg.h" void bfa_hwcb_reginit(struct bfa_s *bfa) { struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs; void __iomem *kva = bfa_ioc_bar0(&bfa->ioc); - int i, q, fn = bfa_ioc_pcifn(&bfa->ioc); + int fn = bfa_ioc_pcifn(&bfa->ioc); if (fn == 0) { bfa_regs->intr_status = (kva + HOSTFN0_INT_STATUS); @@ -33,24 +33,6 @@ bfa_hwcb_reginit(struct bfa_s *bfa) bfa_regs->intr_status = (kva + HOSTFN1_INT_STATUS); bfa_regs->intr_mask = (kva + HOSTFN1_INT_MSK); } - - for (i = 0; i < BFI_IOC_MAX_CQS; i++) { - /* - * CPE registers - */ - q = CPE_Q_NUM(fn, i); - bfa_regs->cpe_q_pi[i] = (kva + CPE_Q_PI(q)); - bfa_regs->cpe_q_ci[i] = (kva + CPE_Q_CI(q)); - bfa_regs->cpe_q_depth[i] = (kva + CPE_Q_DEPTH(q)); - - /* - * RME registers - */ - q = CPE_Q_NUM(fn, i); - bfa_regs->rme_q_pi[i] = (kva + RME_Q_PI(q)); - bfa_regs->rme_q_ci[i] = (kva + RME_Q_CI(q)); - bfa_regs->rme_q_depth[i] = (kva + RME_Q_DEPTH(q)); - } } void @@ -115,18 +97,18 @@ bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs) bfa->msix.nvecs = nvecs; if (nvecs == 1) { - for (i = 0; i < BFA_MSIX_CB_MAX; i++) + for (i = 0; i < BFI_MSIX_CB_MAX; i++) bfa->msix.handler[i] = bfa_msix_all; return; } - for (i = BFA_MSIX_CPE_Q0; i <= BFA_MSIX_CPE_Q7; i++) + for (i = BFI_MSIX_CPE_QMIN_CB; i <= BFI_MSIX_CPE_QMAX_CB; i++) bfa->msix.handler[i] = bfa_msix_reqq; - for (i = BFA_MSIX_RME_Q0; i <= BFA_MSIX_RME_Q7; i++) + for (i = BFI_MSIX_RME_QMIN_CB; i <= BFI_MSIX_RME_QMAX_CB; i++) bfa->msix.handler[i] = bfa_msix_rspq; - for (; i < BFA_MSIX_CB_MAX; i++) + for (; i < BFI_MSIX_CB_MAX; i++) bfa->msix.handler[i] = bfa_msix_lpu_err; } @@ -156,6 +138,6 @@ bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) void bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end) { - *start = BFA_MSIX_RME_Q0; - *end = BFA_MSIX_RME_Q7; + *start = BFI_MSIX_RME_QMIN_CB; + *end = BFI_MSIX_RME_QMAX_CB; } diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c index 21018d98a07..66e2d29ff45 100644 --- a/drivers/scsi/bfa/bfa_hw_ct.c +++ b/drivers/scsi/bfa/bfa_hw_ct.c @@ -17,29 +17,10 @@ #include "bfad_drv.h" #include "bfa_modules.h" -#include "bfi_ctreg.h" +#include "bfi_reg.h" BFA_TRC_FILE(HAL, IOCFC_CT); -static u32 __ct_msix_err_vec_reg[] = { - HOST_MSIX_ERR_INDEX_FN0, - HOST_MSIX_ERR_INDEX_FN1, - HOST_MSIX_ERR_INDEX_FN2, - HOST_MSIX_ERR_INDEX_FN3, -}; - -static void -bfa_hwct_msix_lpu_err_set(struct bfa_s *bfa, bfa_boolean_t msix, int vec) -{ - int fn = bfa_ioc_pcifn(&bfa->ioc); - void __iomem *kva = bfa_ioc_bar0(&bfa->ioc); - - if (msix) - writel(vec, kva + __ct_msix_err_vec_reg[fn]); - else - writel(0, kva + __ct_msix_err_vec_reg[fn]); -} - /* * Dummy interrupt handler for handling spurious interrupt during chip-reinit. */ @@ -53,7 +34,7 @@ bfa_hwct_reginit(struct bfa_s *bfa) { struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs; void __iomem *kva = bfa_ioc_bar0(&bfa->ioc); - int i, q, fn = bfa_ioc_pcifn(&bfa->ioc); + int fn = bfa_ioc_pcifn(&bfa->ioc); if (fn == 0) { bfa_regs->intr_status = (kva + HOSTFN0_INT_STATUS); @@ -62,26 +43,16 @@ bfa_hwct_reginit(struct bfa_s *bfa) bfa_regs->intr_status = (kva + HOSTFN1_INT_STATUS); bfa_regs->intr_mask = (kva + HOSTFN1_INT_MSK); } +} - for (i = 0; i < BFI_IOC_MAX_CQS; i++) { - /* - * CPE registers - */ - q = CPE_Q_NUM(fn, i); - bfa_regs->cpe_q_pi[i] = (kva + CPE_PI_PTR_Q(q << 5)); - bfa_regs->cpe_q_ci[i] = (kva + CPE_CI_PTR_Q(q << 5)); - bfa_regs->cpe_q_depth[i] = (kva + CPE_DEPTH_Q(q << 5)); - bfa_regs->cpe_q_ctrl[i] = (kva + CPE_QCTRL_Q(q << 5)); - - /* - * RME registers - */ - q = CPE_Q_NUM(fn, i); - bfa_regs->rme_q_pi[i] = (kva + RME_PI_PTR_Q(q << 5)); - bfa_regs->rme_q_ci[i] = (kva + RME_CI_PTR_Q(q << 5)); - bfa_regs->rme_q_depth[i] = (kva + RME_DEPTH_Q(q << 5)); - bfa_regs->rme_q_ctrl[i] = (kva + RME_QCTRL_Q(q << 5)); - } +void +bfa_hwct2_reginit(struct bfa_s *bfa) +{ + struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs; + void __iomem *kva = bfa_ioc_bar0(&bfa->ioc); + + bfa_regs->intr_status = (kva + CT2_HOSTFN_INT_STATUS); + bfa_regs->intr_mask = (kva + CT2_HOSTFN_INTR_MASK); } void @@ -106,9 +77,9 @@ void bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap, u32 *num_vecs, u32 *max_vec_bit) { - *msix_vecs_bmap = (1 << BFA_MSIX_CT_MAX) - 1; - *max_vec_bit = (1 << (BFA_MSIX_CT_MAX - 1)); - *num_vecs = BFA_MSIX_CT_MAX; + *msix_vecs_bmap = (1 << BFI_MSIX_CT_MAX) - 1; + *max_vec_bit = (1 << (BFI_MSIX_CT_MAX - 1)); + *num_vecs = BFI_MSIX_CT_MAX; } /* @@ -117,7 +88,7 @@ bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap, void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs) { - WARN_ON((nvecs != 1) && (nvecs != BFA_MSIX_CT_MAX)); + WARN_ON((nvecs != 1) && (nvecs != BFI_MSIX_CT_MAX)); bfa_trc(bfa, nvecs); bfa->msix.nvecs = nvecs; @@ -133,19 +104,18 @@ bfa_hwct_msix_install(struct bfa_s *bfa) return; if (bfa->msix.nvecs == 1) { - for (i = 0; i < BFA_MSIX_CT_MAX; i++) + for (i = 0; i < BFI_MSIX_CT_MAX; i++) bfa->msix.handler[i] = bfa_msix_all; return; } - for (i = BFA_MSIX_CPE_Q0; i <= BFA_MSIX_CPE_Q3; i++) + for (i = BFI_MSIX_CPE_QMIN_CT; i <= BFI_MSIX_CPE_QMAX_CT; i++) bfa->msix.handler[i] = bfa_msix_reqq; - for (; i <= BFA_MSIX_RME_Q3; i++) + for (i = BFI_MSIX_RME_QMIN_CT; i <= BFI_MSIX_RME_QMAX_CT; i++) bfa->msix.handler[i] = bfa_msix_rspq; - WARN_ON(i != BFA_MSIX_LPU_ERR); - bfa->msix.handler[BFA_MSIX_LPU_ERR] = bfa_msix_lpu_err; + bfa->msix.handler[BFI_MSIX_LPU_ERR_CT] = bfa_msix_lpu_err; } void @@ -153,7 +123,7 @@ bfa_hwct_msix_uninstall(struct bfa_s *bfa) { int i; - for (i = 0; i < BFA_MSIX_CT_MAX; i++) + for (i = 0; i < BFI_MSIX_CT_MAX; i++) bfa->msix.handler[i] = bfa_hwct_msix_dummy; } @@ -164,13 +134,12 @@ void bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) { bfa_trc(bfa, 0); - bfa_hwct_msix_lpu_err_set(bfa, msix, BFA_MSIX_LPU_ERR); bfa_ioc_isr_mode_set(&bfa->ioc, msix); } void bfa_hwct_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end) { - *start = BFA_MSIX_RME_Q0; - *end = BFA_MSIX_RME_Q3; + *start = BFI_MSIX_RME_QMIN_CT; + *end = BFI_MSIX_RME_QMAX_CT; } diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index d215168ab8b..3d336c279c4 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -17,7 +17,7 @@ #include "bfad_drv.h" #include "bfa_ioc.h" -#include "bfi_ctreg.h" +#include "bfi_reg.h" #include "bfa_defs.h" #include "bfa_defs_svc.h" @@ -1219,13 +1219,13 @@ bfa_ioc_sem_get(void __iomem *sem_reg) r32 = readl(sem_reg); - while (r32 && (cnt < BFA_SEM_SPINCNT)) { + while ((r32 & 1) && (cnt < BFA_SEM_SPINCNT)) { cnt++; udelay(2); r32 = readl(sem_reg); } - if (r32 == 0) + if (!(r32 & 1)) return BFA_TRUE; WARN_ON(cnt >= BFA_SEM_SPINCNT); @@ -1242,7 +1242,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc) * will return 1. Semaphore is released by writing 1 to the register */ r32 = readl(ioc->ioc_regs.ioc_sem_reg); - if (r32 == 0) { + if (!(r32 & 1)) { bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED); return; } @@ -1351,7 +1351,7 @@ bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) int i; drv_fwhdr = (struct bfi_ioc_image_hdr_s *) - bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); + bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0); for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) { if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) { @@ -1377,7 +1377,7 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env) bfa_ioc_fwver_get(ioc, &fwhdr); drv_fwhdr = (struct bfi_ioc_image_hdr_s *) - bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); + bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0); if (fwhdr.signature != drv_fwhdr->signature) { bfa_trc(ioc, fwhdr.signature); @@ -1385,8 +1385,8 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env) return BFA_FALSE; } - if (swab32(fwhdr.param) != boot_env) { - bfa_trc(ioc, fwhdr.param); + if (swab32(fwhdr.bootenv) != boot_env) { + bfa_trc(ioc, fwhdr.bootenv); bfa_trc(ioc, boot_env); return BFA_FALSE; } @@ -1422,8 +1422,8 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force) bfa_trc(ioc, ioc_fwstate); - boot_type = BFI_BOOT_TYPE_NORMAL; - boot_env = BFI_BOOT_LOADER_OS; + boot_type = BFI_FWBOOT_TYPE_NORMAL; + boot_env = BFI_FWBOOT_ENV_OS; /* * check if firmware is valid @@ -1580,25 +1580,26 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, u32 loff = 0; u32 chunkno = 0; u32 i; + u32 asicmode; /* * Initialize LMEM first before code download */ bfa_ioc_lmem_init(ioc); - bfa_trc(ioc, bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc))); - fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno); + bfa_trc(ioc, bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc))); + fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno); pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff); pgoff = PSS_SMEM_PGOFF(loff); writel(pgnum, ioc->ioc_regs.host_page_num_fn); - for (i = 0; i < bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) { + for (i = 0; i < bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)); i++) { if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { chunkno = BFA_IOC_FLASH_CHUNK_NO(i); - fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), + fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); } @@ -1624,11 +1625,15 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, ioc->ioc_regs.host_page_num_fn); /* - * Set boot type and boot param at the end. - */ - bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_TYPE_OFF, + * Set boot type and device mode at the end. + */ + asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode, + ioc->port0_mode, ioc->port1_mode); + bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_DEVMODE_OFF, + swab32(asicmode)); + bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_TYPE_OFF, swab32(boot_type)); - bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_LOADER_OFF, + bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_ENV_OFF, swab32(boot_env)); } @@ -1879,8 +1884,6 @@ bfa_ioc_pll_init(struct bfa_ioc_s *ioc) void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env) { - void __iomem *rb; - bfa_ioc_stats(ioc, ioc_boots); if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK) @@ -1889,13 +1892,12 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env) /* * Initialize IOC state of all functions on a chip reset. */ - rb = ioc->pcidev.pci_bar_kva; - if (boot_type == BFI_BOOT_TYPE_MEMTEST) { - writel(BFI_IOC_MEMTEST, (rb + BFA_IOC0_STATE_REG)); - writel(BFI_IOC_MEMTEST, (rb + BFA_IOC1_STATE_REG)); + if (boot_type == BFI_FWBOOT_TYPE_MEMTEST) { + writel(BFI_IOC_MEMTEST, ioc->ioc_regs.ioc_fwstate); + writel(BFI_IOC_MEMTEST, ioc->ioc_regs.alt_ioc_fwstate); } else { - writel(BFI_IOC_INITING, (rb + BFA_IOC0_STATE_REG)); - writel(BFI_IOC_INITING, (rb + BFA_IOC1_STATE_REG)); + writel(BFI_IOC_INITING, ioc->ioc_regs.ioc_fwstate); + writel(BFI_IOC_INITING, ioc->ioc_regs.alt_ioc_fwstate); } bfa_ioc_msgflush(ioc); @@ -1935,13 +1937,17 @@ bfa_ioc_is_initialized(struct bfa_ioc_s *ioc) (r32 != BFI_IOC_MEMTEST)); } -void +bfa_boolean_t bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg) { __be32 *msgp = mbmsg; u32 r32; int i; + r32 = readl(ioc->ioc_regs.lpu_mbox_cmd); + if ((r32 & 1) == 0) + return BFA_FALSE; + /* * read the MBOX msg */ @@ -1957,6 +1963,8 @@ bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg) */ writel(1, ioc->ioc_regs.lpu_mbox_cmd); readl(ioc->ioc_regs.lpu_mbox_cmd); + + return BFA_TRUE; } void @@ -2040,16 +2048,55 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev, { ioc->clscode = clscode; ioc->pcidev = *pcidev; - ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id); - ioc->cna = ioc->ctdev && !ioc->fcmode; + + /* + * Initialize IOC and device personality + */ + ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_FC; + ioc->asic_mode = BFI_ASIC_MODE_FC; + + switch (pcidev->device_id) { + case BFA_PCI_DEVICE_ID_FC_8G1P: + case BFA_PCI_DEVICE_ID_FC_8G2P: + ioc->asic_gen = BFI_ASIC_GEN_CB; + break; + + case BFA_PCI_DEVICE_ID_CT: + ioc->asic_gen = BFI_ASIC_GEN_CT; + ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH; + ioc->asic_mode = BFI_ASIC_MODE_ETH; + break; + + case BFA_PCI_DEVICE_ID_CT_FC: + ioc->asic_gen = BFI_ASIC_GEN_CT; + break; + + case BFA_PCI_DEVICE_ID_CT2: + ioc->asic_gen = BFI_ASIC_GEN_CT2; + if (clscode == BFI_PCIFN_CLASS_FC) + ioc->asic_mode = BFI_ASIC_MODE_FC16; + else { + ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH; + ioc->asic_mode = BFI_ASIC_MODE_ETH; + } + break; + + default: + WARN_ON(1); + } /* * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c */ - if (ioc->ctdev) - bfa_ioc_set_ct_hwif(ioc); - else + if (ioc->asic_gen == BFI_ASIC_GEN_CB) bfa_ioc_set_cb_hwif(ioc); + else if (ioc->asic_gen == BFI_ASIC_GEN_CT) + bfa_ioc_set_ct_hwif(ioc); + else { + WARN_ON(ioc->asic_gen != BFI_ASIC_GEN_CT2); + bfa_ioc_set_ct2_hwif(ioc); + bfa_ioc_ct2_poweron(ioc); + } bfa_ioc_map_port(ioc); bfa_ioc_reg_init(ioc); @@ -2175,7 +2222,8 @@ bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc) struct bfi_mbmsg_s m; int mc; - bfa_ioc_msgget(ioc, &m); + if (!bfa_ioc_msgget(ioc, &m)) + return; /* * Treat IOC message class as special. @@ -2202,7 +2250,6 @@ void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc) { ioc->fcmode = BFA_TRUE; - ioc->port_id = bfa_ioc_pcifn(ioc); } /* @@ -2242,17 +2289,16 @@ bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc) { u32 ioc_state; - void __iomem *rb = ioc->pcidev.pci_bar_kva; if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled)) return BFA_FALSE; - ioc_state = readl(rb + BFA_IOC0_STATE_REG); + ioc_state = readl(ioc->ioc_regs.ioc_fwstate); if (!bfa_ioc_state_disabled(ioc_state)) return BFA_FALSE; if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_FC_8G1P) { - ioc_state = readl(rb + BFA_IOC1_STATE_REG); + ioc_state = readl(ioc->ioc_regs.alt_ioc_fwstate); if (!bfa_ioc_state_disabled(ioc_state)) return BFA_FALSE; } @@ -2311,22 +2357,24 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver); - ad_attr->cna_capable = ioc->cna; - ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna && - !ad_attr->is_mezz; + ad_attr->cna_capable = bfa_ioc_is_cna(ioc); + ad_attr->trunk_capable = (ad_attr->nports > 1) && + !bfa_ioc_is_cna(ioc) && !ad_attr->is_mezz; } enum bfa_ioc_type_e bfa_ioc_get_type(struct bfa_ioc_ |