void lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *, LPFC_MBOXQ_t *);
 int lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t,
                        struct lpfc_iocbq *, uint32_t);
-int lpfc_sli4_issue_wqe(struct lpfc_hba *phba, uint32_t rnum,
-                       struct lpfc_iocbq *iocbq);
+int lpfc_sli4_issue_wqe(struct lpfc_hba *phba, struct lpfc_sli4_hdw_queue *qp,
+                       struct lpfc_iocbq *pwqe);
 struct lpfc_sglq *__lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xri);
 struct lpfc_sglq *__lpfc_sli_get_nvmet_sglq(struct lpfc_hba *phba,
                                            struct lpfc_iocbq *piocbq);
 
                                return cnt;
                        cnt++;
                        qp = &phba->sli4_hba.hdwq[idx];
-                       lpfc_cmd->hdwq = idx;
+                       lpfc_cmd->hdwq_no = idx;
+                       lpfc_cmd->hdwq = qp;
                        lpfc_cmd->cur_iocbq.wqe_cmpl = NULL;
                        lpfc_cmd->cur_iocbq.iocb_cmpl = NULL;
                        spin_lock(&qp->io_buf_list_put_lock);
 
        lpfc_nvmeio_data(phba, "NVME LS  XMIT: xri x%x iotag x%x to x%06x\n",
                         genwqe->sli4_xritag, genwqe->iotag, ndlp->nlp_DID);
 
-       rc = lpfc_sli4_issue_wqe(phba, LPFC_ELS_RING, genwqe);
+       rc = lpfc_sli4_issue_wqe(phba, &phba->sli4_hba.hdwq[0], genwqe);
        if (rc) {
                lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
                                 "6045 Issue GEN REQ WQE to NPORT x%x "
                         lpfc_ncmd->cur_iocbq.sli4_xritag,
                         lpfc_queue_info->index, ndlp->nlp_DID);
 
-       ret = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, &lpfc_ncmd->cur_iocbq);
+       ret = lpfc_sli4_issue_wqe(phba, lpfc_ncmd->hdwq, &lpfc_ncmd->cur_iocbq);
        if (ret) {
                atomic_inc(&lport->xmt_fcp_wqerr);
                lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR,
        abts_buf->hba_wqidx = nvmereq_wqe->hba_wqidx;
        abts_buf->vport = vport;
        abts_buf->wqe_cmpl = lpfc_nvme_abort_fcreq_cmpl;
-       ret_val = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, abts_buf);
+       ret_val = lpfc_sli4_issue_wqe(phba, lpfc_nbuf->hdwq, abts_buf);
        spin_unlock_irqrestore(&phba->hbalock, flags);
        if (ret_val) {
                lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_ABTS,
                pwqeq->wqe_cmpl = lpfc_nvme_io_cmd_wqe_cmpl;
                lpfc_ncmd->start_time = jiffies;
                lpfc_ncmd->flags = 0;
-               lpfc_ncmd->hdwq = idx;
+               lpfc_ncmd->hdwq = qp;
+               lpfc_ncmd->hdwq_no = idx;
 
                /* Rsp SGE will be filled in when we rcv an IO
                 * from the NVME Layer to be sent.
        lpfc_ncmd->ndlp = NULL;
        lpfc_ncmd->flags &= ~LPFC_BUMP_QDEPTH;
 
-       qp = &phba->sli4_hba.hdwq[lpfc_ncmd->hdwq];
+       qp = lpfc_ncmd->hdwq;
        if (lpfc_ncmd->flags & LPFC_SBUF_XBUSY) {
                lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS,
                                "6310 XB release deferred for "
 
        dma_addr_t dma_phys_sgl;
        struct sli4_sge *dma_sgl;
        struct lpfc_iocbq cur_iocbq;
-       uint16_t hdwq;
+       struct lpfc_sli4_hdw_queue *hdwq;
+       uint16_t hdwq_no;
        uint16_t cpu;
 
        /* NVME specific fields */
 
        lpfc_nvmeio_data(phba, "NVMET LS  RESP: xri x%x wqidx x%x len x%x\n",
                         ctxp->oxid, nvmewqeq->hba_wqidx, rsp->rsplen);
 
-       rc = lpfc_sli4_issue_wqe(phba, LPFC_ELS_RING, nvmewqeq);
+       rc = lpfc_sli4_issue_wqe(phba, ctxp->hdwq, nvmewqeq);
        if (rc == WQE_SUCCESS) {
                /*
                 * Okay to repost buffer here, but wait till cmpl
                else
                        ctxp->ts_nvme_data = ktime_get_ns();
        }
+
+       /* Setup the hdw queue if not already set */
+       if (!ctxp->hdwq)
+               ctxp->hdwq = &phba->sli4_hba.hdwq[rsp->hwqid];
+
        if (phba->cpucheck_on & LPFC_CHECK_NVMET_IO) {
                int id = smp_processor_id();
                if (id < LPFC_CHECK_CPU_CNT) {
                         ctxp->oxid, rsp->op, rsp->rsplen);
 
        ctxp->flag |= LPFC_NVMET_IO_INP;
-       rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, nvmewqeq);
+       rc = lpfc_sli4_issue_wqe(phba, ctxp->hdwq, nvmewqeq);
        if (rc == WQE_SUCCESS) {
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
                if (!ctxp->ts_cmd_nvme)
                 * WQE release CQE
                 */
                ctxp->flag |= LPFC_NVMET_DEFER_WQFULL;
-               wq = phba->sli4_hba.hdwq[rsp->hwqid].nvme_wq;
+               wq = ctxp->hdwq->nvme_wq;
                pring = wq->pring;
                spin_lock_irqsave(&pring->ring_lock, iflags);
                list_add_tail(&nvmewqeq->list, &wq->wqfull_list);
        if (phba->pport->load_flag & FC_UNLOADING)
                return;
 
+       if (!ctxp->hdwq)
+               ctxp->hdwq = &phba->sli4_hba.hdwq[0];
+
        lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS,
                        "6103 NVMET Abort op: oxri x%x flg x%x ste %d\n",
                        ctxp->oxid, ctxp->flag, ctxp->state);
        if (ctxp->flag & LPFC_NVMET_DEFER_WQFULL) {
                lpfc_nvmet_unsol_fcp_issue_abort(phba, ctxp, ctxp->sid,
                                                 ctxp->oxid);
-               wq = phba->sli4_hba.hdwq[ctxp->wqeq->hba_wqidx].nvme_wq;
+               wq = ctxp->hdwq->nvme_wq;
                spin_unlock_irqrestore(&ctxp->ctxlock, flags);
                lpfc_nvmet_wqfull_flush(phba, wq, ctxp);
                return;
 #if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
        struct lpfc_sli_ring *pring;
        struct lpfc_iocbq *nvmewqeq;
+       struct lpfc_nvmet_rcv_ctx *ctxp;
        unsigned long iflags;
        int rc;
 
                list_remove_head(&wq->wqfull_list, nvmewqeq, struct lpfc_iocbq,
                                 list);
                spin_unlock_irqrestore(&pring->ring_lock, iflags);
-               rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, nvmewqeq);
+               ctxp = (struct lpfc_nvmet_rcv_ctx *)nvmewqeq->context2;
+               rc = lpfc_sli4_issue_wqe(phba, ctxp->hdwq, nvmewqeq);
                spin_lock_irqsave(&pring->ring_lock, iflags);
                if (rc == -EBUSY) {
                        /* WQ was full again, so put it back on the list */
        ctxp->state = LPFC_NVMET_STE_LS_RCV;
        ctxp->entry_cnt = 1;
        ctxp->rqb_buffer = (void *)nvmebuf;
+       ctxp->hdwq = &phba->sli4_hba.hdwq[0];
 
        lpfc_nvmeio_data(phba, "NVMET LS   RCV: xri x%x sz %d from %06x\n",
                         oxid, size, sid);
        ctxp->flag = 0;
        ctxp->ctxbuf = ctx_buf;
        ctxp->rqb_buffer = (void *)nvmebuf;
+       ctxp->hdwq = NULL;
        spin_lock_init(&ctxp->ctxlock);
 
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
        abts_wqeq->iocb_flag |= LPFC_IO_NVME;
        abts_wqeq->context2 = ctxp;
        abts_wqeq->vport = phba->pport;
-       rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, abts_wqeq);
+       if (!ctxp->hdwq)
+               ctxp->hdwq = &phba->sli4_hba.hdwq[abts_wqeq->hba_wqidx];
+
+       rc = lpfc_sli4_issue_wqe(phba, ctxp->hdwq, abts_wqeq);
        spin_unlock_irqrestore(&phba->hbalock, flags);
        if (rc == WQE_SUCCESS) {
                atomic_inc(&tgtp->xmt_abort_sol);
        abts_wqeq->wqe_cmpl = lpfc_nvmet_unsol_fcp_abort_cmp;
        abts_wqeq->iocb_cmpl = NULL;
        abts_wqeq->iocb_flag |= LPFC_IO_NVMET;
-       rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, abts_wqeq);
+       if (!ctxp->hdwq)
+               ctxp->hdwq = &phba->sli4_hba.hdwq[abts_wqeq->hba_wqidx];
+
+       rc = lpfc_sli4_issue_wqe(phba, ctxp->hdwq, abts_wqeq);
        spin_unlock_irqrestore(&phba->hbalock, flags);
        if (rc == WQE_SUCCESS) {
                return 0;
        abts_wqeq->wqe_cmpl = lpfc_nvmet_xmt_ls_abort_cmp;
        abts_wqeq->iocb_cmpl = 0;
        abts_wqeq->iocb_flag |=  LPFC_IO_NVME_LS;
-       rc = lpfc_sli4_issue_wqe(phba, LPFC_ELS_RING, abts_wqeq);
+       rc = lpfc_sli4_issue_wqe(phba, ctxp->hdwq, abts_wqeq);
        spin_unlock_irqrestore(&phba->hbalock, flags);
        if (rc == WQE_SUCCESS) {
                atomic_inc(&tgtp->xmt_abort_unsol);
 
 #define LPFC_NVMET_DEFER_WQFULL                0x40  /* Waiting on a free WQE */
        struct rqb_dmabuf *rqb_buffer;
        struct lpfc_nvmet_ctxbuf *ctxbuf;
+       struct lpfc_sli4_hdw_queue *hdwq;
 
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
        uint64_t ts_isr_cmd;
 
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
        lpfc_cmd->prot_data_type = 0;
 #endif
-       lpfc_cmd->hdwq = idx;
+       lpfc_cmd->hdwq = qp;
+       lpfc_cmd->hdwq_no = idx;
 
        lpfc_cmd->fcp_cmnd = (lpfc_cmd->data + sgl_size);
        lpfc_cmd->fcp_rsp = (struct fcp_rsp *)((uint8_t *)lpfc_cmd->fcp_cmnd +
        psb->seg_cnt = 0;
        psb->prot_seg_cnt = 0;
 
-       qp = &phba->sli4_hba.hdwq[psb->hdwq];
+       qp = psb->hdwq;
        if (psb->exch_busy) {
                spin_lock_irqsave(&qp->abts_scsi_buf_list_lock, iflag);
                psb->pCmd = NULL;
 
        sli4 = (phba->sli_rev == LPFC_SLI_REV4);
        piocbq->iocb.un.fcpi.fcpi_XRdy = 0;
-       idx = lpfc_cmd->hdwq;
+       idx = lpfc_cmd->hdwq_no;
        if (phba->sli4_hba.hdwq)
                hdwq = &phba->sli4_hba.hdwq[idx];
 
        return 0;
 
  out_host_busy_free_buf:
-       idx = lpfc_cmd->hdwq;
+       idx = lpfc_cmd->hdwq_no;
        lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
        if (phba->sli4_hba.hdwq) {
                switch (lpfc_cmd->fcp_cmnd->fcpCntl3) {
 
        dma_addr_t dma_phys_sgl;
        struct ulp_bde64 *dma_sgl;
        struct lpfc_iocbq cur_iocbq;
-       uint16_t hdwq;
+       struct lpfc_sli4_hdw_queue *hdwq;
+       uint16_t hdwq_no;
        uint16_t cpu;
 
        /* SCSI specific fields */
 
                 */
                if (!(piocb->iocb_flag & LPFC_USE_FCPWQIDX)) {
                        lpfc_cmd = (struct lpfc_scsi_buf *)piocb->context1;
-                       piocb->hba_wqidx = lpfc_cmd->hdwq;
+                       piocb->hba_wqidx = lpfc_cmd->hdwq_no;
                }
                return phba->sli4_hba.hdwq[piocb->hba_wqidx].fcp_wq->pring;
        } else {
        struct lpfc_iocbq *abtsiocbp;
        union lpfc_wqe128 *abts_wqe;
        int retval;
+       int idx = cmdiocb->hba_wqidx;
 
        /*
         * There are certain command types we don't want to abort.  And we
        abtsiocbp->iocb_flag |= LPFC_IO_NVME;
        abtsiocbp->vport = vport;
        abtsiocbp->wqe_cmpl = lpfc_nvme_abort_fcreq_cmpl;
-       retval = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, abtsiocbp);
+       retval = lpfc_sli4_issue_wqe(phba, &phba->sli4_hba.hdwq[idx],
+                                    abtsiocbp);
        if (retval) {
                lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME,
                                 "6147 Failed abts issue_wqe with status x%x "
  * @pwqe: Pointer to command WQE.
  **/
 int
-lpfc_sli4_issue_wqe(struct lpfc_hba *phba, uint32_t ring_number,
+lpfc_sli4_issue_wqe(struct lpfc_hba *phba, struct lpfc_sli4_hdw_queue *qp,
                    struct lpfc_iocbq *pwqe)
 {
        union lpfc_wqe128 *wqe = &pwqe->wqe;
        /* NVME_FCREQ and NVME_ABTS requests */
        if (pwqe->iocb_flag & LPFC_IO_NVME) {
                /* Get the IO distribution (hba_wqidx) for WQ assignment. */
-               pring = phba->sli4_hba.hdwq[pwqe->hba_wqidx].nvme_wq->pring;
+               wq = qp->nvme_wq;
+               pring = wq->pring;
+
+               bf_set(wqe_cqid, &wqe->generic.wqe_com, qp->nvme_cq_map);
 
                spin_lock_irqsave(&pring->ring_lock, iflags);
-               wq = phba->sli4_hba.hdwq[pwqe->hba_wqidx].nvme_wq;
-               bf_set(wqe_cqid, &wqe->generic.wqe_com,
-                     phba->sli4_hba.hdwq[pwqe->hba_wqidx].nvme_cq->queue_id);
                ret = lpfc_sli4_wq_put(wq, wqe);
                if (ret) {
                        spin_unlock_irqrestore(&pring->ring_lock, iflags);
        /* NVMET requests */
        if (pwqe->iocb_flag & LPFC_IO_NVMET) {
                /* Get the IO distribution (hba_wqidx) for WQ assignment. */
-               pring = phba->sli4_hba.hdwq[pwqe->hba_wqidx].nvme_wq->pring;
+               wq = qp->nvme_wq;
+               pring = wq->pring;
 
-               spin_lock_irqsave(&pring->ring_lock, iflags);
                ctxp = pwqe->context2;
                sglq = ctxp->ctxbuf->sglq;
                if (pwqe->sli4_xritag ==  NO_XRI) {
                }
                bf_set(wqe_xri_tag, &pwqe->wqe.xmit_bls_rsp.wqe_com,
                       pwqe->sli4_xritag);
-               wq = phba->sli4_hba.hdwq[pwqe->hba_wqidx].nvme_wq;
-               bf_set(wqe_cqid, &wqe->generic.wqe_com,
-                     phba->sli4_hba.hdwq[pwqe->hba_wqidx].nvme_cq->queue_id);
+               bf_set(wqe_cqid, &wqe->generic.wqe_com, qp->nvme_cq_map);
+
+               spin_lock_irqsave(&pring->ring_lock, iflags);
                ret = lpfc_sli4_wq_put(wq, wqe);
                if (ret) {
                        spin_unlock_irqrestore(&pring->ring_lock, iflags);