[SCSI] bfa: Update RME interrupt handling.
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / bfa / bfa_core.c
index 5a00217ee5be55f60aa7fbbbc8b1fbd204b7659c..0c236964c67e26ac42598ddc9bb091e2d312bc1e 100644 (file)
@@ -25,13 +25,14 @@ BFA_TRC_FILE(HAL, CORE);
  * BFA module list terminated by NULL
  */
 static struct bfa_module_s *hal_mods[] = {
+       &hal_mod_fcdiag,
        &hal_mod_sgpg,
        &hal_mod_fcport,
        &hal_mod_fcxp,
        &hal_mod_lps,
        &hal_mod_uf,
        &hal_mod_rport,
-       &hal_mod_fcpim,
+       &hal_mod_fcp,
        NULL
 };
 
@@ -41,7 +42,7 @@ static struct bfa_module_s *hal_mods[] = {
 static bfa_isr_func_t  bfa_isrs[BFI_MC_MAX] = {
        bfa_isr_unhandled,      /* NONE */
        bfa_isr_unhandled,      /* BFI_MC_IOC */
-       bfa_isr_unhandled,      /* BFI_MC_DIAG */
+       bfa_fcdiag_intr,        /* BFI_MC_DIAG */
        bfa_isr_unhandled,      /* BFI_MC_FLASH */
        bfa_isr_unhandled,      /* BFI_MC_CEE */
        bfa_fcport_isr,         /* BFI_MC_FCPORT */
@@ -51,7 +52,7 @@ static bfa_isr_func_t  bfa_isrs[BFI_MC_MAX] = {
        bfa_fcxp_isr,           /* BFI_MC_FCXP */
        bfa_lps_isr,            /* BFI_MC_LPS */
        bfa_rport_isr,          /* BFI_MC_RPORT */
-       bfa_itnim_isr,          /* BFI_MC_ITNIM */
+       bfa_itn_isr,            /* BFI_MC_ITN */
        bfa_isr_unhandled,      /* BFI_MC_IOIM_READ */
        bfa_isr_unhandled,      /* BFI_MC_IOIM_WRITE */
        bfa_isr_unhandled,      /* BFI_MC_IOIM_IO */
@@ -89,23 +90,78 @@ static bfa_ioc_mbox_mcfunc_t  bfa_mbox_isrs[BFI_MC_MAX] = {
 
 
 static void
-bfa_com_port_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi)
+bfa_com_port_attach(struct bfa_s *bfa)
 {
        struct bfa_port_s       *port = &bfa->modules.port;
-       u32                     dm_len;
-       u8                      *dm_kva;
-       u64                     dm_pa;
+       struct bfa_mem_dma_s    *port_dma = BFA_MEM_PORT_DMA(bfa);
 
-       dm_len = bfa_port_meminfo();
-       dm_kva = bfa_meminfo_dma_virt(mi);
-       dm_pa  = bfa_meminfo_dma_phys(mi);
-
-       memset(port, 0, sizeof(struct bfa_port_s));
        bfa_port_attach(port, &bfa->ioc, bfa, bfa->trcmod);
-       bfa_port_mem_claim(port, dm_kva, dm_pa);
+       bfa_port_mem_claim(port, port_dma->kva_curp, port_dma->dma_curp);
+}
+
+/*
+ * ablk module attach
+ */
+static void
+bfa_com_ablk_attach(struct bfa_s *bfa)
+{
+       struct bfa_ablk_s       *ablk = &bfa->modules.ablk;
+       struct bfa_mem_dma_s    *ablk_dma = BFA_MEM_ABLK_DMA(bfa);
+
+       bfa_ablk_attach(ablk, &bfa->ioc);
+       bfa_ablk_memclaim(ablk, ablk_dma->kva_curp, ablk_dma->dma_curp);
+}
+
+static void
+bfa_com_cee_attach(struct bfa_s *bfa)
+{
+       struct bfa_cee_s        *cee = &bfa->modules.cee;
+       struct bfa_mem_dma_s    *cee_dma = BFA_MEM_CEE_DMA(bfa);
+
+       cee->trcmod = bfa->trcmod;
+       bfa_cee_attach(cee, &bfa->ioc, bfa);
+       bfa_cee_mem_claim(cee, cee_dma->kva_curp, cee_dma->dma_curp);
+}
+
+static void
+bfa_com_sfp_attach(struct bfa_s *bfa)
+{
+       struct bfa_sfp_s        *sfp = BFA_SFP_MOD(bfa);
+       struct bfa_mem_dma_s    *sfp_dma = BFA_MEM_SFP_DMA(bfa);
+
+       bfa_sfp_attach(sfp, &bfa->ioc, bfa, bfa->trcmod);
+       bfa_sfp_memclaim(sfp, sfp_dma->kva_curp, sfp_dma->dma_curp);
+}
+
+static void
+bfa_com_flash_attach(struct bfa_s *bfa, bfa_boolean_t mincfg)
+{
+       struct bfa_flash_s      *flash = BFA_FLASH(bfa);
+       struct bfa_mem_dma_s    *flash_dma = BFA_MEM_FLASH_DMA(bfa);
+
+       bfa_flash_attach(flash, &bfa->ioc, bfa, bfa->trcmod, mincfg);
+       bfa_flash_memclaim(flash, flash_dma->kva_curp,
+                          flash_dma->dma_curp, mincfg);
+}
+
+static void
+bfa_com_diag_attach(struct bfa_s *bfa)
+{
+       struct bfa_diag_s       *diag = BFA_DIAG_MOD(bfa);
+       struct bfa_mem_dma_s    *diag_dma = BFA_MEM_DIAG_DMA(bfa);
+
+       bfa_diag_attach(diag, &bfa->ioc, bfa, bfa_fcport_beacon, bfa->trcmod);
+       bfa_diag_memclaim(diag, diag_dma->kva_curp, diag_dma->dma_curp);
+}
 
-       bfa_meminfo_dma_virt(mi) = dm_kva + dm_len;
-       bfa_meminfo_dma_phys(mi) = dm_pa + dm_len;
+static void
+bfa_com_phy_attach(struct bfa_s *bfa, bfa_boolean_t mincfg)
+{
+       struct bfa_phy_s        *phy = BFA_PHY(bfa);
+       struct bfa_mem_dma_s    *phy_dma = BFA_MEM_PHY_DMA(bfa);
+
+       bfa_phy_attach(phy, &bfa->ioc, bfa, bfa->trcmod, mincfg);
+       bfa_phy_memclaim(phy, phy_dma->kva_curp, phy_dma->dma_curp, mincfg);
 }
 
 /*
@@ -122,6 +178,7 @@ enum {
        BFA_IOCFC_ACT_INIT      = 1,
        BFA_IOCFC_ACT_STOP      = 2,
        BFA_IOCFC_ACT_DISABLE   = 3,
+       BFA_IOCFC_ACT_ENABLE    = 4,
 };
 
 #define DEF_CFG_NUM_FABRICS            1
@@ -180,8 +237,6 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
        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);
 
@@ -194,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;
-       writel(pi, bfa->iocfc.bfa_regs.rme_q_ci[qid]);
-       mmiowb();
+       bfa_isr_rspq_ack(bfa, qid, ci);
 
        /*
         * Resume any pending requests in the corresponding reqq.
@@ -213,9 +266,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.
@@ -228,7 +279,39 @@ bfa_isr_reqq(struct bfa_s *bfa, int qid)
 void
 bfa_msix_all(struct bfa_s *bfa, int vec)
 {
-       bfa_intx(bfa);
+       u32     intr, qintr;
+       int     queue;
+
+       intr = readl(bfa->iocfc.bfa_regs.intr_status);
+       if (!intr)
+               return;
+
+       /*
+        * RME completion queue interrupt
+        */
+       qintr = intr & __HFN_INT_RME_MASK;
+       if (qintr && bfa->queue_process) {
+               for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
+                       bfa_isr_rspq(bfa, queue);
+       }
+
+       intr &= ~qintr;
+       if (!intr)
+               return;
+
+       /*
+        * CPE completion queue interrupt
+        */
+       qintr = intr & __HFN_INT_CPE_MASK;
+       if (qintr && bfa->queue_process) {
+               for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
+                       bfa_isr_reqq(bfa, queue);
+       }
+       intr &= ~qintr;
+       if (!intr)
+               return;
+
+       bfa_msix_lpu_err(bfa, intr);
 }
 
 bfa_boolean_t
@@ -238,20 +321,19 @@ bfa_intx(struct bfa_s *bfa)
        int queue;
 
        intr = readl(bfa->iocfc.bfa_regs.intr_status);
-       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
+        * Unconditional 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_isr_rspq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
+       if (bfa->queue_process) {
+               for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
+                       bfa_isr_rspq(bfa, queue);
        }
-       intr &= ~qintr;
+
        if (!intr)
                return BFA_TRUE;
 
@@ -259,11 +341,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_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)
@@ -282,7 +362,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;
@@ -326,9 +406,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);
 }
 
@@ -347,7 +424,8 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
                                   __HFN_INT_MBOX_LPU1_CT2);
                intr    &= __HFN_INT_ERR_MASK_CT2;
        } 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;
                lpu_isr  = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1);
                intr    &= __HFN_INT_ERR_MASK;
@@ -393,41 +471,6 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
  *  BFA IOC private functions
  */
 
-static void
-bfa_iocfc_cqs_sz(struct bfa_iocfc_cfg_s *cfg, u32 *dm_len)
-{
-       int             i, per_reqq_sz, per_rspq_sz;
-
-       per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),
-                                 BFA_DMA_ALIGN_SZ);
-       per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),
-                                 BFA_DMA_ALIGN_SZ);
-
-       /*
-        * Calculate CQ size
-        */
-       for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
-               *dm_len = *dm_len + per_reqq_sz;
-               *dm_len = *dm_len + per_rspq_sz;
-       }
-
-       /*
-        * Calculate Shadow CI/PI size
-        */
-       for (i = 0; i < cfg->fwcfg.num_cqs; i++)
-               *dm_len += (2 * BFA_CACHELINE_SZ);
-}
-
-static void
-bfa_iocfc_fw_cfg_sz(struct bfa_iocfc_cfg_s *cfg, u32 *dm_len)
-{
-       *dm_len +=
-               BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
-       *dm_len +=
-               BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
-                           BFA_CACHELINE_SZ);
-}
-
 /*
  * Use the Mailbox interface to send BFI_IOCFC_H2I_CFG_REQ
  */
@@ -449,8 +492,13 @@ bfa_iocfc_send_cfg(void *bfa_arg)
        /*
         * initialize IOC configuration info
         */
+       cfg_info->single_msix_vec = 0;
+       if (bfa->msix.nvecs == 1)
+               cfg_info->single_msix_vec = 1;
        cfg_info->endian_sig = BFI_IOC_ENDIAN_SIG;
        cfg_info->num_cqs = cfg->fwcfg.num_cqs;
+       cfg_info->num_ioim_reqs = cpu_to_be16(cfg->fwcfg.num_ioim_reqs);
+       cfg_info->num_fwtio_reqs = cpu_to_be16(cfg->fwcfg.num_fwtio_reqs);
 
        bfa_dma_be_addr_set(cfg_info->cfgrsp_addr, iocfc->cfgrsp_dma.pa);
        /*
@@ -485,7 +533,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,
@@ -512,7 +560,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;
@@ -521,10 +570,11 @@ 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_reqq_ack = NULL;
                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;
@@ -538,6 +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))) {
                iocfc->hwif.hw_reginit = bfa_hwct2_reginit;
                iocfc->hwif.hw_isr_mode_set = NULL;
+               iocfc->hwif.hw_rspq_ack = bfa_hwct2_rspq_ack;
        }
 
        iocfc->hwif.hw_reginit(bfa);
@@ -545,48 +596,42 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 }
 
 static void
-bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
-                   struct bfa_meminfo_s *meminfo)
+bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg)
 {
-       u8             *dm_kva;
-       u64     dm_pa;
-       int             i, per_reqq_sz, per_rspq_sz;
+       u8      *dm_kva = NULL;
+       u64     dm_pa = 0;
+       int     i, per_reqq_sz, per_rspq_sz, dbgsz;
        struct bfa_iocfc_s  *iocfc = &bfa->iocfc;
-       int             dbgsz;
-
-       dm_kva = bfa_meminfo_dma_virt(meminfo);
-       dm_pa = bfa_meminfo_dma_phys(meminfo);
+       struct bfa_mem_dma_s *ioc_dma = BFA_MEM_IOC_DMA(bfa);
+       struct bfa_mem_dma_s *iocfc_dma = BFA_MEM_IOCFC_DMA(bfa);
+       struct bfa_mem_dma_s *reqq_dma, *rspq_dma;
 
-       /*
-        * First allocate dma memory for IOC.
-        */
-       bfa_ioc_mem_claim(&bfa->ioc, dm_kva, dm_pa);
-       dm_kva += BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
-       dm_pa  += BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
+       /* First allocate dma memory for IOC */
+       bfa_ioc_mem_claim(&bfa->ioc, bfa_mem_dma_virt(ioc_dma),
+                       bfa_mem_dma_phys(ioc_dma));
 
-       /*
-        * Claim DMA-able memory for the request/response queues and for shadow
-        * ci/pi registers
-        */
+       /* Claim DMA-able memory for the request/response queues */
        per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),
-                                 BFA_DMA_ALIGN_SZ);
+                               BFA_DMA_ALIGN_SZ);
        per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),
-                                 BFA_DMA_ALIGN_SZ);
+                               BFA_DMA_ALIGN_SZ);
 
        for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
-               iocfc->req_cq_ba[i].kva = dm_kva;
-               iocfc->req_cq_ba[i].pa = dm_pa;
-               memset(dm_kva, 0, per_reqq_sz);
-               dm_kva += per_reqq_sz;
-               dm_pa += per_reqq_sz;
-
-               iocfc->rsp_cq_ba[i].kva = dm_kva;
-               iocfc->rsp_cq_ba[i].pa = dm_pa;
-               memset(dm_kva, 0, per_rspq_sz);
-               dm_kva += per_rspq_sz;
-               dm_pa += per_rspq_sz;
+               reqq_dma = BFA_MEM_REQQ_DMA(bfa, i);
+               iocfc->req_cq_ba[i].kva = bfa_mem_dma_virt(reqq_dma);
+               iocfc->req_cq_ba[i].pa = bfa_mem_dma_phys(reqq_dma);
+               memset(iocfc->req_cq_ba[i].kva, 0, per_reqq_sz);
+
+               rspq_dma = BFA_MEM_RSPQ_DMA(bfa, i);
+               iocfc->rsp_cq_ba[i].kva = bfa_mem_dma_virt(rspq_dma);
+               iocfc->rsp_cq_ba[i].pa = bfa_mem_dma_phys(rspq_dma);
+               memset(iocfc->rsp_cq_ba[i].kva, 0, per_rspq_sz);
        }
 
+       /* Claim IOCFC dma memory - for shadow CI/PI */
+       dm_kva = bfa_mem_dma_virt(iocfc_dma);
+       dm_pa  = bfa_mem_dma_phys(iocfc_dma);
+
        for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
                iocfc->req_cq_shadow_ci[i].kva = dm_kva;
                iocfc->req_cq_shadow_ci[i].pa = dm_pa;
@@ -599,36 +644,27 @@ bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
                dm_pa += BFA_CACHELINE_SZ;
        }
 
-       /*
-        * Claim DMA-able memory for the config info page
-        */
+       /* Claim IOCFC dma memory - for the config info page */
        bfa->iocfc.cfg_info.kva = dm_kva;
        bfa->iocfc.cfg_info.pa = dm_pa;
        bfa->iocfc.cfginfo = (struct bfi_iocfc_cfg_s *) dm_kva;
        dm_kva += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
        dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
 
-       /*
-        * Claim DMA-able memory for the config response
-        */
+       /* Claim IOCFC dma memory - for the config response */
        bfa->iocfc.cfgrsp_dma.kva = dm_kva;
        bfa->iocfc.cfgrsp_dma.pa = dm_pa;
        bfa->iocfc.cfgrsp = (struct bfi_iocfc_cfgrsp_s *) dm_kva;
-
-       dm_kva +=
-               BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
-                           BFA_CACHELINE_SZ);
+       dm_kva += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
+                       BFA_CACHELINE_SZ);
        dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
-                            BFA_CACHELINE_SZ);
-
-
-       bfa_meminfo_dma_virt(meminfo) = dm_kva;
-       bfa_meminfo_dma_phys(meminfo) = dm_pa;
+                       BFA_CACHELINE_SZ);
 
+       /* Claim IOCFC kva memory */
        dbgsz = (bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
        if (dbgsz > 0) {
-               bfa_ioc_debug_memclaim(&bfa->ioc, bfa_meminfo_kva(meminfo));
-               bfa_meminfo_kva(meminfo) += dbgsz;
+               bfa_ioc_debug_memclaim(&bfa->ioc, bfa_mem_kva_curp(iocfc));
+               bfa_mem_kva_curp(iocfc) += dbgsz;
        }
 }
 
@@ -640,9 +676,9 @@ 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);
+               bfa_isr_rspq_ack(bfa, i, bfa_rspq_ci(bfa, i));
 
        for (i = 0; hal_mods[i]; i++)
                hal_mods[i]->start(bfa);
@@ -688,6 +724,16 @@ bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl)
                bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
 }
 
+static void
+bfa_iocfc_enable_cb(void *bfa_arg, bfa_boolean_t compl)
+{
+       struct bfa_s    *bfa = bfa_arg;
+       struct bfad_s *bfad = bfa->bfad;
+
+       if (compl)
+               complete(&bfad->enable_comp);
+}
+
 static void
 bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl)
 {
@@ -709,6 +755,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]);
@@ -718,6 +765,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.
  */
@@ -730,6 +787,7 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
 
        fwcfg->num_cqs        = fwcfg->num_cqs;
        fwcfg->num_ioim_reqs  = be16_to_cpu(fwcfg->num_ioim_reqs);
+       fwcfg->num_fwtio_reqs = be16_to_cpu(fwcfg->num_fwtio_reqs);
        fwcfg->num_tskim_reqs = be16_to_cpu(fwcfg->num_tskim_reqs);
        fwcfg->num_fcxp_reqs  = be16_to_cpu(fwcfg->num_fcxp_reqs);
        fwcfg->num_uf_bufs    = be16_to_cpu(fwcfg->num_uf_bufs);
@@ -742,6 +800,16 @@ 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);
+
        /*
         * Configuration is complete - initialize/start submodules
         */
@@ -749,8 +817,12 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
 
        if (iocfc->action == BFA_IOCFC_ACT_INIT)
                bfa_cb_queue(bfa, &iocfc->init_hcb_qe, bfa_iocfc_init_cb, bfa);
-       else
+       else {
+               if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE)
+                       bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe,
+                                       bfa_iocfc_enable_cb, bfa);
                bfa_iocfc_start_submod(bfa);
+       }
 }
 void
 bfa_iocfc_reset_queues(struct bfa_s *bfa)
@@ -765,6 +837,181 @@ bfa_iocfc_reset_queues(struct bfa_s *bfa)
        }
 }
 
+/* Fabric Assigned Address specific functions */
+
+/*
+ *     Check whether IOC is ready before sending command down
+ */
+static bfa_status_t
+bfa_faa_validate_request(struct bfa_s *bfa)
+{
+       enum bfa_ioc_type_e     ioc_type = bfa_get_type(bfa);
+       u32     card_type = bfa->ioc.attr->card_type;
+
+       if (bfa_ioc_is_operational(&bfa->ioc)) {
+               if ((ioc_type != BFA_IOC_TYPE_FC) || bfa_mfg_is_mezz(card_type))
+                       return BFA_STATUS_FEATURE_NOT_SUPPORTED;
+       } else {
+               if (!bfa_ioc_is_acq_addr(&bfa->ioc))
+                       return BFA_STATUS_IOC_NON_OP;
+       }
+
+       return BFA_STATUS_OK;
+}
+
+bfa_status_t
+bfa_faa_enable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn, void *cbarg)
+{
+       struct bfi_faa_en_dis_s faa_enable_req;
+       struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
+       bfa_status_t            status;
+
+       iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
+       iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
+
+       status = bfa_faa_validate_request(bfa);
+       if (status != BFA_STATUS_OK)
+               return status;
+
+       if (iocfc->faa_args.busy == BFA_TRUE)
+               return BFA_STATUS_DEVBUSY;
+
+       if (iocfc->faa_args.faa_state == BFA_FAA_ENABLED)
+               return BFA_STATUS_FAA_ENABLED;
+
+       if (bfa_fcport_is_trunk_enabled(bfa))
+               return BFA_STATUS_ERROR_TRUNK_ENABLED;
+
+       bfa_fcport_cfg_faa(bfa, BFA_FAA_ENABLED);
+       iocfc->faa_args.busy = BFA_TRUE;
+
+       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_fn_lpu(bfa));
+
+       bfa_ioc_mbox_send(&bfa->ioc, &faa_enable_req,
+                       sizeof(struct bfi_faa_en_dis_s));
+
+       return BFA_STATUS_OK;
+}
+
+bfa_status_t
+bfa_faa_disable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn,
+               void *cbarg)
+{
+       struct bfi_faa_en_dis_s faa_disable_req;
+       struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
+       bfa_status_t            status;
+
+       iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
+       iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
+
+       status = bfa_faa_validate_request(bfa);
+       if (status != BFA_STATUS_OK)
+               return status;
+
+       if (iocfc->faa_args.busy == BFA_TRUE)
+               return BFA_STATUS_DEVBUSY;
+
+       if (iocfc->faa_args.faa_state == BFA_FAA_DISABLED)
+               return BFA_STATUS_FAA_DISABLED;
+
+       bfa_fcport_cfg_faa(bfa, BFA_FAA_DISABLED);
+       iocfc->faa_args.busy = BFA_TRUE;
+
+       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_fn_lpu(bfa));
+
+       bfa_ioc_mbox_send(&bfa->ioc, &faa_disable_req,
+               sizeof(struct bfi_faa_en_dis_s));
+
+       return BFA_STATUS_OK;
+}
+
+bfa_status_t
+bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr,
+               bfa_cb_iocfc_t cbfn, void *cbarg)
+{
+       struct bfi_faa_query_s  faa_attr_req;
+       struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
+       bfa_status_t            status;
+
+       iocfc->faa_args.faa_attr = attr;
+       iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
+       iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
+
+       status = bfa_faa_validate_request(bfa);
+       if (status != BFA_STATUS_OK)
+               return status;
+
+       if (iocfc->faa_args.busy == BFA_TRUE)
+               return BFA_STATUS_DEVBUSY;
+
+       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_fn_lpu(bfa));
+
+       bfa_ioc_mbox_send(&bfa->ioc, &faa_attr_req,
+               sizeof(struct bfi_faa_query_s));
+
+       return BFA_STATUS_OK;
+}
+
+/*
+ *     FAA enable response
+ */
+static void
+bfa_faa_enable_reply(struct bfa_iocfc_s *iocfc,
+               struct bfi_faa_en_dis_rsp_s *rsp)
+{
+       void    *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
+       bfa_status_t    status = rsp->status;
+
+       WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
+
+       iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
+       iocfc->faa_args.busy = BFA_FALSE;
+}
+
+/*
+ *     FAA disable response
+ */
+static void
+bfa_faa_disable_reply(struct bfa_iocfc_s *iocfc,
+               struct bfi_faa_en_dis_rsp_s *rsp)
+{
+       void    *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
+       bfa_status_t    status = rsp->status;
+
+       WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
+
+       iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
+       iocfc->faa_args.busy = BFA_FALSE;
+}
+
+/*
+ *     FAA query response
+ */
+static void
+bfa_faa_query_reply(struct bfa_iocfc_s *iocfc,
+               bfi_faa_query_rsp_t *rsp)
+{
+       void    *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
+
+       if (iocfc->faa_args.faa_attr) {
+               iocfc->faa_args.faa_attr->faa = rsp->faa;
+               iocfc->faa_args.faa_attr->faa_state = rsp->faa_status;
+               iocfc->faa_args.faa_attr->pwwn_source = rsp->addr_source;
+       }
+
+       WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
+
+       iocfc->faa_args.faa_cb.faa_cbfn(cbarg, BFA_STATUS_OK);
+       iocfc->faa_args.busy = BFA_FALSE;
+}
+
 /*
  * IOC enable request is complete
  */
@@ -773,11 +1020,20 @@ bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
 {
        struct bfa_s    *bfa = bfa_arg;
 
+       if (status == BFA_STATUS_FAA_ACQ_ADDR) {
+               bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
+                               bfa_iocfc_init_cb, bfa);
+               return;
+       }
+
        if (status != BFA_STATUS_OK) {
                bfa_isr_disable(bfa);
                if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
                        bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
                                     bfa_iocfc_init_cb, bfa);
+               else if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE)
+                       bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe,
+                                       bfa_iocfc_enable_cb, bfa);
                return;
        }
 
@@ -813,7 +1069,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);
@@ -840,15 +1096,47 @@ bfa_iocfc_reset_cbfn(void *bfa_arg)
  * Query IOC memory requirement information.
  */
 void
-bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
-                 u32 *dm_len)
+bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
+                 struct bfa_s *bfa)
 {
-       /* dma memory for IOC */
-       *dm_len += BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
+       int q, per_reqq_sz, per_rspq_sz;
+       struct bfa_mem_dma_s *ioc_dma = BFA_MEM_IOC_DMA(bfa);
+       struct bfa_mem_dma_s *iocfc_dma = BFA_MEM_IOCFC_DMA(bfa);
+       struct bfa_mem_kva_s *iocfc_kva = BFA_MEM_IOCFC_KVA(bfa);
+       u32     dm_len = 0;
+
+       /* dma memory setup for IOC */
+       bfa_mem_dma_setup(meminfo, ioc_dma,
+               BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ));
+
+       /* dma memory setup for REQ/RSP queues */
+       per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),
+                               BFA_DMA_ALIGN_SZ);
+       per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),
+                               BFA_DMA_ALIGN_SZ);
+
+       for (q = 0; q < cfg->fwcfg.num_cqs; q++) {
+               bfa_mem_dma_setup(meminfo, BFA_MEM_REQQ_DMA(bfa, q),
+                               per_reqq_sz);
+               bfa_mem_dma_setup(meminfo, BFA_MEM_RSPQ_DMA(bfa, q),
+                               per_rspq_sz);
+       }
 
-       bfa_iocfc_fw_cfg_sz(cfg, dm_len);
-       bfa_iocfc_cqs_sz(cfg, dm_len);
-       *km_len += (bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
+       /* IOCFC dma memory - calculate Shadow CI/PI size */
+       for (q = 0; q < cfg->fwcfg.num_cqs; q++)
+               dm_len += (2 * BFA_CACHELINE_SZ);
+
+       /* IOCFC dma memory - calculate config info / rsp size */
+       dm_len += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
+       dm_len += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
+                       BFA_CACHELINE_SZ);
+
+       /* dma memory setup for IOCFC */
+       bfa_mem_dma_setup(meminfo, iocfc_dma, dm_len);
+
+       /* kva memory setup for IOCFC */
+       bfa_mem_kva_setup(meminfo, iocfc_kva,
+                       ((bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0));
 }
 
 /*
@@ -856,7 +1144,7 @@ bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
  */
 void
 bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
-                struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
+                struct bfa_pcidev_s *pcidev)
 {
        int             i;
        struct bfa_ioc_s *ioc = &bfa->ioc;
@@ -869,17 +1157,11 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        ioc->trcmod = bfa->trcmod;
        bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod);
 
-       /*
-        * Set FC mode for BFA_PCI_DEVICE_ID_CT_FC.
-        */
-       if (pcidev->device_id == BFA_PCI_DEVICE_ID_CT_FC)
-               bfa_ioc_set_fcmode(&bfa->ioc);
-
        bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_PCIFN_CLASS_FC);
        bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
 
        bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
-       bfa_iocfc_mem_claim(bfa, cfg, meminfo);
+       bfa_iocfc_mem_claim(bfa, cfg);
        INIT_LIST_HEAD(&bfa->timer_mod.timer_q);
 
        INIT_LIST_HEAD(&bfa->comp_q);
@@ -917,7 +1199,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);
 }
 
@@ -938,6 +1220,17 @@ bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m)
        case BFI_IOCFC_I2H_UPDATEQ_RSP:
                iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK);
                break;
+       case BFI_IOCFC_I2H_FAA_ENABLE_RSP:
+               bfa_faa_enable_reply(iocfc,
+                       (struct bfi_faa_en_dis_rsp_s *)msg);
+               break;
+       case BFI_IOCFC_I2H_FAA_DISABLE_RSP:
+               bfa_faa_disable_reply(iocfc,
+                       (struct bfi_faa_en_dis_rsp_s *)msg);
+               break;
+       case BFI_IOCFC_I2H_FAA_QUERY_RSP:
+               bfa_faa_query_reply(iocfc, (bfi_faa_query_rsp_t *)msg);
+               break;
        default:
                WARN_ON(1);
        }
@@ -979,7 +1272,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;
@@ -987,17 +1280,17 @@ 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;
 }
 
 void
-bfa_iocfc_set_snsbase(struct bfa_s *bfa, u64 snsbase_pa)
+bfa_iocfc_set_snsbase(struct bfa_s *bfa, int seg_no, u64 snsbase_pa)
 {
        struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
 
        iocfc->cfginfo->sense_buf_len = (BFI_IOIM_SNSLEN - 1);
-       bfa_dma_be_addr_set(iocfc->cfginfo->ioim_snsbase, snsbase_pa);
+       bfa_dma_be_addr_set(iocfc->cfginfo->ioim_snsbase[seg_no], snsbase_pa);
 }
 /*
  * Enable IOC after it is disabled.
@@ -1007,6 +1300,7 @@ bfa_iocfc_enable(struct bfa_s *bfa)
 {
        bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
                     "IOC Enable");
+       bfa->iocfc.action = BFA_IOCFC_ACT_ENABLE;
        bfa_ioc_enable(&bfa->ioc);
 }
 
@@ -1017,7 +1311,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);
 }
 
@@ -1086,33 +1380,49 @@ bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)
  *                     starting address for each block and provide the same
  *                     structure as input parameter to bfa_attach() call.
  *
+ * @param[in] bfa -    pointer to the bfa structure, used while fetching the
+ *                     dma, kva memory information of the bfa sub-modules.
+ *
  * @return void
  *
  * Special Considerations: @note
  */
 void
-bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo)
+bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
+               struct bfa_s *bfa)
 {
        int             i;
-       u32     km_len = 0, dm_len = 0;
+       struct bfa_mem_dma_s *port_dma = BFA_MEM_PORT_DMA(bfa);
+       struct bfa_mem_dma_s *ablk_dma = BFA_MEM_ABLK_DMA(bfa);
+       struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa);
+       struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa);
+       struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa);
+       struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa);
+       struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa);
 
        WARN_ON((cfg == NULL) || (meminfo == NULL));
 
        memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));
-       meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_type =
-               BFA_MEM_TYPE_KVA;
-       meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_type =
-               BFA_MEM_TYPE_DMA;
 
-       bfa_iocfc_meminfo(cfg, &km_len, &dm_len);
+       /* Initialize the DMA & KVA meminfo queues */
+       INIT_LIST_HEAD(&meminfo->dma_info.qe);
+       INIT_LIST_HEAD(&meminfo->kva_info.qe);
 
-       for (i = 0; hal_mods[i]; i++)
-               hal_mods[i]->meminfo(cfg, &km_len, &dm_len);
+       bfa_iocfc_meminfo(cfg, meminfo, bfa);
 
-       dm_len += bfa_port_meminfo();
-
-       meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_len = km_len;
-       meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len;
+       for (i = 0; hal_mods[i]; i++)
+               hal_mods[i]->meminfo(cfg, meminfo, bfa);
+
+       /* dma info setup */
+       bfa_mem_dma_setup(meminfo, port_dma, bfa_port_meminfo());
+       bfa_mem_dma_setup(meminfo, ablk_dma, bfa_ablk_meminfo());
+       bfa_mem_dma_setup(meminfo, cee_dma, bfa_cee_meminfo());
+       bfa_mem_dma_setup(meminfo, sfp_dma, bfa_sfp_meminfo());
+       bfa_mem_dma_setup(meminfo, flash_dma,
+                         bfa_flash_meminfo(cfg->drvcfg.min_cfg));
+       bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo());
+       bfa_mem_dma_setup(meminfo, phy_dma,
+                         bfa_phy_meminfo(cfg->drvcfg.min_cfg));
 }
 
 /*
@@ -1145,28 +1455,46 @@ void
 bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
               struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
 {
-       int                     i;
-       struct bfa_mem_elem_s   *melem;
+       int     i;
+       struct bfa_mem_dma_s *dma_info, *dma_elem;
+       struct bfa_mem_kva_s *kva_info, *kva_elem;
+       struct list_head *dm_qe, *km_qe;
 
        bfa->fcs = BFA_FALSE;
 
        WARN_ON((cfg == NULL) || (meminfo == NULL));
 
-       /*
-        * initialize all memory pointers for iterative allocation
-        */
-       for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
-               melem = meminfo->meminfo + i;
-               melem->kva_curp = melem->kva;
-               melem->dma_curp = melem->dma;
+       /* Initialize memory pointers for iterative allocation */
+       dma_info = &meminfo->dma_info;
+       dma_info->kva_curp = dma_info->kva;
+       dma_info->dma_curp = dma_info->dma;
+
+       kva_info = &meminfo->kva_info;
+       kva_info->kva_curp = kva_info->kva;
+
+       list_for_each(dm_qe, &dma_info->qe) {
+               dma_elem = (struct bfa_mem_dma_s *) dm_qe;
+               dma_elem->kva_curp = dma_elem->kva;
+               dma_elem->dma_curp = dma_elem->dma;
        }
 
-       bfa_iocfc_attach(bfa, bfad, cfg, meminfo, pcidev);
+       list_for_each(km_qe, &kva_info->qe) {
+               kva_elem = (struct bfa_mem_kva_s *) km_qe;
+               kva_elem->kva_curp = kva_elem->kva;
+       }
 
-       for (i = 0; hal_mods[i]; i++)
-               hal_mods[i]->attach(bfa, bfad, cfg, meminfo, pcidev);
+       bfa_iocfc_attach(bfa, bfad, cfg, pcidev);
 
-       bfa_com_port_attach(bfa, meminfo);
+       for (i = 0; hal_mods[i]; i++)
+               hal_mods[i]->attach(bfa, bfad, cfg, pcidev);
+
+       bfa_com_port_attach(bfa);
+       bfa_com_ablk_attach(bfa);
+       bfa_com_cee_attach(bfa);
+       bfa_com_sfp_attach(bfa);
+       bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg);
+       bfa_com_diag_attach(bfa);
+       bfa_com_phy_attach(bfa, cfg->drvcfg.min_cfg);
 }
 
 /*
@@ -1268,6 +1596,7 @@ bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg)
        cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS;
        cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS;
        cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS;
+       cfg->fwcfg.num_fwtio_reqs = 0;
 
        cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS;
        cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS;
@@ -1289,6 +1618,7 @@ bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg)
        cfg->fwcfg.num_fcxp_reqs   = BFA_FCXP_MIN;
        cfg->fwcfg.num_uf_bufs     = BFA_UF_MIN;
        cfg->fwcfg.num_rports      = BFA_RPORT_MIN;
+       cfg->fwcfg.num_fwtio_reqs = 0;
 
        cfg->drvcfg.num_sgpgs      = BFA_SGPG_MIN;
        cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN;