[PATCH 05/15] bfa: Brocade-1860 Fabric Adapter vHBA support.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Krishna Gudipati <kgudipat@xxxxxxxxxxx>

Change details:
	- 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@xxxxxxxxxxx>
---
 drivers/scsi/bfa/bfa.h           |   18 +++-
 drivers/scsi/bfa/bfa_core.c      |   62 ++++++++-----
 drivers/scsi/bfa/bfa_fcpim.c     |   64 ++++++++++---
 drivers/scsi/bfa/bfa_fcpim.h     |    4 +
 drivers/scsi/bfa/bfa_fcs.c       |    2 +-
 drivers/scsi/bfa/bfa_fcs_lport.c |    4 +-
 drivers/scsi/bfa/bfa_hw_cb.c     |   10 --
 drivers/scsi/bfa/bfa_ioc_ct.c    |    4 +-
 drivers/scsi/bfa/bfa_svc.c       |  188 ++++++++++++++++++++++++++++---------
 drivers/scsi/bfa/bfa_svc.h       |   11 ++-
 drivers/scsi/bfa/bfi.h           |   10 +-
 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 42769bc..ee072d9 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 f949844..0048fc8 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 76d9a00..eb14fd6 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 e1e3221..bc6b294 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 5332017..5bbb76b 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 479ccbe..942443e 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 694ebf1..e7ffd82 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 77f2b44..d1b8f0c 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 fe99ce2..cfc0b09 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)
 	}
 
 	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ,
-			bfa_lpuid(fcport->bfa));
+			bfa_fn_lpu(fcport->bfa));
 	m->tx_bbcredit = cpu_to_be16((u16)fcport->cfg.tx_bbcredit);
 	m->bb_scn = fcport->cfg.bb_scn;
 
 	/*
 	 * queue I/O message to firmware
 	 */
-	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh);
 }
 
 static void
@@ -3127,8 +3193,8 @@ bfa_fcport_send_stats_get(void *cbarg)
 
 	memset(msg, 0, sizeof(struct bfi_fcport_req_s));
 	bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
-			bfa_lpuid(fcport->bfa));
-	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+			bfa_fn_lpu(fcport->bfa));
+	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, msg->mh);
 }
 
 static void
@@ -3189,8 +3255,8 @@ bfa_fcport_send_stats_clear(void *cbarg)
 
 	memset(msg, 0, sizeof(struct bfi_fcport_req_s));
 	bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
-			bfa_lpuid(fcport->bfa));
-	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+			bfa_fn_lpu(fcport->bfa));
+	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, msg->mh);
 }
 
 /*
@@ -4370,6 +4436,7 @@ bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 
 	INIT_LIST_HEAD(&mod->rp_free_q);
 	INIT_LIST_HEAD(&mod->rp_active_q);
+	INIT_LIST_HEAD(&mod->rp_unused_q);
 
 	rp = (struct bfa_rport_s *) bfa_meminfo_kva(meminfo);
 	mod->rps_list = rp;
@@ -4421,6 +4488,9 @@ bfa_rport_iocdisable(struct bfa_s *bfa)
 	struct bfa_rport_s *rport;
 	struct list_head *qe, *qen;
 
+	/* Enqueue unused rport resources to free_q */
+	list_splice_tail_init(&mod->rp_unused_q, &mod->rp_free_q);
+
 	list_for_each_safe(qe, qen, &mod->rp_active_q) {
 		rport = (struct bfa_rport_s *) qe;
 		bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL);
@@ -4464,11 +4534,11 @@ bfa_rport_send_fwcreate(struct bfa_rport_s *rp)
 	}
 
 	bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ,
-			bfa_lpuid(rp->bfa));
+			bfa_fn_lpu(rp->bfa));
 	m->bfa_handle = rp->rport_tag;
 	m->max_frmsz = cpu_to_be16(rp->rport_info.max_frmsz);
 	m->pid = rp->rport_info.pid;
-	m->lp_tag = rp->rport_info.lp_tag;
+	m->lp_fwtag = bfa_lps_get_fwtag(rp->bfa, (u8)rp->rport_info.lp_tag);
 	m->local_pid = rp->rport_info.local_pid;
 	m->fc_class = rp->rport_info.fc_class;
 	m->vf_en = rp->rport_info.vf_en;
@@ -4478,7 +4548,7 @@ bfa_rport_send_fwcreate(struct bfa_rport_s *rp)
 	/*
 	 * queue I/O message to firmware
 	 */
-	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
+	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh);
 	return BFA_TRUE;
 }
 
@@ -4497,13 +4567,13 @@ bfa_rport_send_fwdelete(struct bfa_rport_s *rp)
 	}
 
 	bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ,
-			bfa_lpuid(rp->bfa));
+			bfa_fn_lpu(rp->bfa));
 	m->fw_handle = rp->fw_handle;
 
 	/*
 	 * queue I/O message to firmware
 	 */
-	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
+	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh);
 	return BFA_TRUE;
 }
 
@@ -4522,14 +4592,14 @@ bfa_rport_send_fwspeed(struct bfa_rport_s *rp)
 	}
 
 	bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ,
-			bfa_lpuid(rp->bfa));
+			bfa_fn_lpu(rp->bfa));
 	m->fw_handle = rp->fw_handle;
 	m->speed = (u8)rp->rport_info.speed;
 
 	/*
 	 * queue I/O message to firmware
 	 */
-	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
+	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh);
 	return BFA_TRUE;
 }
 
@@ -4579,7 +4649,18 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
 	}
 }
 
+void
+bfa_rport_res_recfg(struct bfa_s *bfa, u16 num_rport_fw)
+{
+	struct bfa_rport_mod_s	*mod = BFA_RPORT_MOD(bfa);
+	struct list_head	*qe;
+	int	i;
 
+	for (i = 0; i < (mod->num_rports - num_rport_fw); i++) {
+		bfa_q_deq_tail(&mod->rp_free_q, &qe);
+		list_add_tail(qe, &mod->rp_unused_q);
+	}
+}
 
 /*
  *  bfa_rport_api
@@ -4880,7 +4961,7 @@ claim_uf_post_msgs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
 		buf_len = sizeof(struct bfa_uf_buf_s);
 		uf_bp_msg->buf_len = cpu_to_be16(buf_len);
 		bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST,
-			    bfa_lpuid(ufm->bfa));
+			    bfa_fn_lpu(ufm->bfa));
 		bfa_alen_set(&uf_bp_msg->alen, buf_len, ufm_pbs_pa(ufm, i));
 	}
 
@@ -4957,6 +5038,7 @@ bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 	ufm->num_ufs = cfg->fwcfg.num_uf_bufs;
 	INIT_LIST_HEAD(&ufm->uf_free_q);
 	INIT_LIST_HEAD(&ufm->uf_posted_q);
+	INIT_LIST_HEAD(&ufm->uf_unused_q);
 
 	uf_mem_claim(ufm, meminfo);
 }
@@ -4992,7 +5074,7 @@ bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf)
 
 	memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag],
 		      sizeof(struct bfi_uf_buf_post_s));
-	bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP);
+	bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP, uf_post_msg->mh);
 
 	bfa_trc(ufm->bfa, uf->uf_tag);
 
@@ -5061,6 +5143,9 @@ bfa_uf_iocdisable(struct bfa_s *bfa)
 	struct bfa_uf_s *uf;
 	struct list_head *qe, *qen;
 
+	/* Enqueue unused uf resources to free_q */
+	list_splice_tail_init(&ufm->uf_unused_q, &ufm->uf_free_q);
+
 	list_for_each_safe(qe, qen, &ufm->uf_posted_q) {
 		uf = (struct bfa_uf_s *) qe;
 		list_del(&uf->qe);
@@ -5125,4 +5210,15 @@ bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
 	}
 }
 
+void
+bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw)
+{
+	struct bfa_uf_mod_s	*mod = BFA_UF_MOD(bfa);
+	struct list_head	*qe;
+	int	i;
 
+	for (i = 0; i < (mod->num_ufs - num_uf_fw); i++) {
+		bfa_q_deq_tail(&mod->uf_free_q, &qe);
+		list_add_tail(qe, &mod->uf_unused_q);
+	}
+}
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h
index acb30ef..6df1492 100644
--- a/drivers/scsi/bfa/bfa_svc.h
+++ b/drivers/scsi/bfa/bfa_svc.h
@@ -93,6 +93,7 @@ struct bfa_fcxp_mod_s {
 	void		*rsp_pld_list_kva;	/* list of FCXP resp pld */
 	u64	rsp_pld_list_pa;	/* list of FCXP resp pld */
 	struct list_head  wait_q;		/* wait queue for free fcxp */
+	struct list_head fcxp_unused_q; /* unused fcxps */
 	u32	req_pld_sz;
 	u32	rsp_pld_sz;
 };
@@ -238,6 +239,7 @@ struct bfa_rport_mod_s {
 	struct bfa_rport_s *rps_list;	/*  list of rports	*/
 	struct list_head	rp_free_q;	/*  free bfa_rports	*/
 	struct list_head	rp_active_q;	/*  free bfa_rports	*/
+	struct list_head	rp_unused_q;	/*  unused bfa rports  */
 	u16	num_rports;	/*  number of rports	*/
 };
 
@@ -254,6 +256,7 @@ struct bfa_rport_mod_s {
  * protected functions
  */
 void	bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
+void	bfa_rport_res_recfg(struct bfa_s *bfa, u16 num_rport_fw);
 
 /*
  *	BFA rport information.
@@ -332,6 +335,7 @@ struct bfa_uf_mod_s {
 	u16	num_ufs;	/*  num unsolicited rx frames */
 	struct list_head	uf_free_q;	/*  free UFs */
 	struct list_head	uf_posted_q;	/*  UFs posted to IOC */
+	struct list_head	uf_unused_q;	/*  unused UF's */
 	struct bfa_uf_buf_s *uf_pbs_kva;	/*  list UF bufs request pld */
 	u64	uf_pbs_pa;	/*  phy addr for UF bufs */
 	struct bfi_uf_buf_post_s *uf_buf_posts;
@@ -346,6 +350,7 @@ struct bfa_uf_mod_s {
 	((_ufmod)->uf_pbs_pa + sizeof(struct bfa_uf_buf_s) * (_uftag))
 
 void	bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
+void	bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw);
 
 #define BFA_UF_BUFSZ	(2 * 1024 + 256)
 
@@ -364,7 +369,8 @@ struct bfa_lps_s {
 	struct list_head	qe;	/*  queue element		*/
 	struct bfa_s	*bfa;		/*  parent bfa instance	*/
 	bfa_sm_t	sm;		/*  finite state machine	*/
-	u8		lp_tag;		/*  lport tag			*/
+	u8		bfa_tag;	/*  lport tag		*/
+	u8		fw_tag;		/*  lport fw tag                */
 	u8		reqq;		/*  lport request queue	*/
 	u8		alpa;		/*  ALPA for loop topologies	*/
 	u32	lp_pid;		/*  lport port ID		*/
@@ -397,6 +403,7 @@ struct bfa_lps_s {
 struct bfa_lps_mod_s {
 	struct list_head		lps_free_q;
 	struct list_head		lps_active_q;
+	struct list_head		lps_login_q;
 	struct bfa_lps_s	*lps_arr;
 	int			num_lps;
 };
@@ -583,6 +590,7 @@ void bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
 bfa_status_t bfa_fcxp_abort(struct bfa_fcxp_s *fcxp);
 u32 bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp);
 u32 bfa_fcxp_get_maxrsp(struct bfa_s *bfa);
+void bfa_fcxp_res_recfg(struct bfa_s *bfa, u16 num_fcxp_fw);
 
 static inline void *
 bfa_uf_get_frmbuf(struct bfa_uf_s *uf)
@@ -617,6 +625,7 @@ void bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz,
 		   wwn_t pwwn, wwn_t nwwn);
 void bfa_lps_fdisclogo(struct bfa_lps_s *lps);
 void bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, u32 n2n_pid);
+u8 bfa_lps_get_fwtag(struct bfa_s *bfa, u8 lp_tag);
 u32 bfa_lps_get_base_pid(struct bfa_s *bfa);
 u8 bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid);
 void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status);
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h
index 3fb2e83..40002f4 100644
--- a/drivers/scsi/bfa/bfi.h
+++ b/drivers/scsi/bfa/bfi.h
@@ -38,18 +38,20 @@ struct bfi_mhdr_s {
 	union {
 		struct {
 			u8	qid;
-			u8	lpu_id;	/*  msg destination		    */
+			u8	fn_lpu;	/*  msg destination		    */
 		} h2i;
 		u16	i2htok;	/*  token in msgs to host	    */
 	} mtag;
 };
 
-#define bfi_mhdr_2_qid(_mh)	((_mh)->mtag.h2i.qid)
+#define bfi_fn_lpu(__fn, __lpu)	((__fn) << 1 | (__lpu))
+#define bfi_mhdr_2_fn(_mh)	((_mh)->mtag.h2i.fn_lpu >> 1)
+#define bfi_mhdr_2_qid(_m)	((_mh)->mtag.h2i.qid)
 
-#define bfi_h2i_set(_mh, _mc, _op, _lpuid) do {		\
+#define bfi_h2i_set(_mh, _mc, _op, _fn_lpu) do {		\
 	(_mh).msg_class		= (_mc);      \
 	(_mh).msg_id		= (_op);      \
-	(_mh).mtag.h2i.lpu_id	= (_lpuid);      \
+	(_mh).mtag.h2i.fn_lpu	= (_fn_lpu);      \
 } while (0)
 
 #define bfi_i2h_set(_mh, _mc, _op, _i2htok) do {		\
diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h
index 8c19734..0727c75 100644
--- a/drivers/scsi/bfa/bfi_ms.h
+++ b/drivers/scsi/bfa/bfi_ms.h
@@ -88,6 +88,7 @@ struct bfi_iocfc_qreg_s {
 	u32	rme_q_ci_off[BFI_IOC_MAX_CQS];
 	u32	rme_q_pi_off[BFI_IOC_MAX_CQS];
 	u32	rme_qctl_off[BFI_IOC_MAX_CQS];
+	u8	hw_qid[BFI_IOC_MAX_CQS];
 };
 
 struct bfi_iocfc_cfgrsp_s {
@@ -348,7 +349,7 @@ struct bfi_fcxp_send_req_s {
 	u8	 class;		/*  FC class used for req/rsp	    */
 	u8	 rsp_timeout;	/*  timeout in secs, 0-no response */
 	u8	 cts;		/*  continue sequence		    */
-	u8	 lp_tag;	/*  lport tag			    */
+	u8	 lp_fwtag;	/*  lport tag			    */
 	struct fchs_s	fchs;	/*  request FC header structure    */
 	__be32	req_len;	/*  request payload length	    */
 	__be32	rsp_maxlen;	/*  max response length expected   */
@@ -408,7 +409,7 @@ enum bfi_lps_i2h_msgs {
 
 struct bfi_lps_login_req_s {
 	struct bfi_mhdr_s  mh;		/*  common msg header		*/
-	u8		lp_tag;
+	u8		bfa_tag;
 	u8		alpa;
 	__be16		pdu_size;
 	wwn_t		pwwn;
@@ -421,7 +422,7 @@ struct bfi_lps_login_req_s {
 
 struct bfi_lps_login_rsp_s {
 	struct bfi_mhdr_s  mh;		/*  common msg header		*/
-	u8		lp_tag;
+	u8		fw_tag;
 	u8		status;
 	u8		lsrjt_rsn;
 	u8		lsrjt_expl;
@@ -437,32 +438,32 @@ struct bfi_lps_login_rsp_s {
 	u8		ext_status;
 	u8		brcd_switch;	/*  attached peer is brcd switch */
 	u8		bb_scn;		/* atatched port's bb_scn */
-	u8		resvd;
+	u8		bfa_tag;
 };
 
 struct bfi_lps_logout_req_s {
 	struct bfi_mhdr_s  mh;		/*  common msg header		*/
-	u8		lp_tag;
+	u8		fw_tag;
 	u8		rsvd[3];
 	wwn_t		port_name;
 };
 
 struct bfi_lps_logout_rsp_s {
 	struct bfi_mhdr_s  mh;		/*  common msg header		*/
-	u8		lp_tag;
+	u8		bfa_tag;
 	u8		status;
 	u8		rsvd[2];
 };
 
 struct bfi_lps_cvl_event_s {
 	struct bfi_mhdr_s  mh;		/*  common msg header		*/
-	u8		lp_tag;
+	u8		bfa_tag;
 	u8		rsvd[3];
 };
 
 struct bfi_lps_n2n_pid_req_s {
 	struct bfi_mhdr_s	mh;	/*  common msg header		*/
-	u8	lp_tag;
+	u8	fw_tag;
 	u32	lp_pid:24;
 };
 
@@ -497,7 +498,7 @@ struct bfi_rport_create_req_s {
 	u16	bfa_handle;	/*  host rport handle		*/
 	__be16	max_frmsz;	/*  max rcv pdu size		*/
 	u32	pid:24,	/*  remote port ID		*/
-		lp_tag:8;	/*  local port tag		*/
+		lp_fwtag:8;	/*  local port tag		*/
 	u32	local_pid:24,	/*  local port ID		*/
 		cisc:8;
 	u8	fc_class;	/*  supported FC classes	*/
-- 
1.7.3.rc1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux