]> git.baikalelectronics.ru Git - kernel.git/commitdiff
scsi: lpfc: SLI path split: Refactor CT paths
authorJames Smart <jsmart2021@gmail.com>
Fri, 25 Feb 2022 02:23:03 +0000 (18:23 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 15 Mar 2022 17:51:49 +0000 (13:51 -0400)
This patch refactors the CT paths to use SLI-4 as the primary interface.

 - Introduce generic lpfc_sli_prep_gen_req jump table routine

 - Introduce generic lpfc_sli_prep_xmit_seq64 jump table routine

 - Rename lpfcdiag_loop_post_rxbufs to lpfcdiag_sli3_loop_post_rxbufs to
   indicate that it is an SLI3 only path

 - Create new prep_wqe routine for unsolicited ELS rsp WQEs.

 - Conversion away from using SLI-3 iocb structures to set/access fields in
   common routines. Use the new generic get/set routines that were added.
   This move changes code from indirect structure references to using local
   variables with the generic routines.

 - Refactor routines when setting non-generic fields, to have both SLI3 and
   SLI4 specific sections. This replaces the set-as-SLI3 then translate to
   SLI4 behavior of the past.

Link: https://lore.kernel.org/r/20220225022308.16486-13-jsmart2021@gmail.com
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_bsg.c
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_ct.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli.h

index 9400823f09a9c5ab7a2a26de54cea06d3dec6157..bf196fd7c41bdef1ea023350a52a70a4d7980e9f 100644 (file)
@@ -968,6 +968,13 @@ struct lpfc_hba {
                                            struct lpfc_dmabuf *bmp,
                                            u16 cmd_size, u32 did, u32 elscmd,
                                            u8 tmo, u8 expect_rsp);
+       void (*__lpfc_sli_prep_gen_req)(struct lpfc_iocbq *cmdiocbq,
+                                       struct lpfc_dmabuf *bmp, u16 rpi,
+                                       u32 num_entry, u8 tmo);
+       void (*__lpfc_sli_prep_xmit_seq64)(struct lpfc_iocbq *cmdiocbq,
+                                          struct lpfc_dmabuf *bmp, u16 rpi,
+                                          u16 ox_id, u32 num_entry, u8 rctl,
+                                          u8 last_seq, u8 cr_cx_cmd);
 
        /* expedite pool */
        struct lpfc_epd_pool epd_pool;
@@ -1849,6 +1856,15 @@ u16 get_job_rcvoxid(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
                return iocbq->iocb.unsli3.rcvsli3.ox_id;
 }
 
+static inline
+u32 get_job_data_placed(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
+{
+       if (phba->sli_rev == LPFC_SLI_REV4)
+               return iocbq->wcqe_cmpl.total_data_placed;
+       else
+               return iocbq->iocb.un.genreq64.bdl.bdeSize;
+}
+
 static inline
 u32 get_job_els_rsp64_did(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
 {
index 1a97426e72de8e09cf5d4e74d3ba5d4a3a36ea42..8d49e4b2ebfe6fcda846d5a7b540f94db6062247 100644 (file)
@@ -303,13 +303,12 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
        struct bsg_job_data *dd_data;
        struct bsg_job *job;
        struct fc_bsg_reply *bsg_reply;
-       IOCB_t *rsp;
        struct lpfc_dmabuf *bmp, *cmp, *rmp;
        struct lpfc_nodelist *ndlp;
        struct lpfc_bsg_iocb *iocb;
        unsigned long flags;
-       unsigned int rsp_size;
        int rc = 0;
+       u32 ulp_status, ulp_word4, total_data_placed;
 
        dd_data = cmdiocbq->context1;
 
@@ -333,14 +332,16 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
        rmp = iocb->rmp;
        cmp = cmdiocbq->context2;
        bmp = cmdiocbq->context3;
-       rsp = &rspiocbq->iocb;
+       ulp_status = get_job_ulpstatus(phba, rspiocbq);
+       ulp_word4 = get_job_word4(phba, rspiocbq);
+       total_data_placed = get_job_data_placed(phba, rspiocbq);
 
        /* Copy the completed data or set the error status */
 
        if (job) {
-               if (rsp->ulpStatus) {
-                       if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
-                               switch (rsp->un.ulpWord[4] & IOERR_PARAM_MASK) {
+               if (ulp_status) {
+                       if (ulp_status == IOSTAT_LOCAL_REJECT) {
+                               switch (ulp_word4 & IOERR_PARAM_MASK) {
                                case IOERR_SEQUENCE_TIMEOUT:
                                        rc = -ETIMEDOUT;
                                        break;
@@ -355,10 +356,9 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
                                rc = -EACCES;
                        }
                } else {
-                       rsp_size = rsp->un.genreq64.bdl.bdeSize;
                        bsg_reply->reply_payload_rcv_len =
                                lpfc_bsg_copy_data(rmp, &job->reply_payload,
-                                                  rsp_size, 0);
+                                                  total_data_placed, 0);
                }
        }
 
@@ -388,22 +388,21 @@ static int
 lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
 {
        struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
-       struct lpfc_hba *phba = vport->phba;
        struct lpfc_rport_data *rdata = fc_bsg_to_rport(job)->dd_data;
+       struct lpfc_hba *phba = vport->phba;
        struct lpfc_nodelist *ndlp = rdata->pnode;
        struct fc_bsg_reply *bsg_reply = job->reply;
        struct ulp_bde64 *bpl = NULL;
-       uint32_t timeout;
        struct lpfc_iocbq *cmdiocbq = NULL;
-       IOCB_t *cmd;
        struct lpfc_dmabuf *bmp = NULL, *cmp = NULL, *rmp = NULL;
-       int request_nseg;
-       int reply_nseg;
+       int request_nseg, reply_nseg;
+       u32 num_entry;
        struct bsg_job_data *dd_data;
        unsigned long flags;
        uint32_t creg_val;
        int rc = 0;
        int iocb_stat;
+       u16 ulp_context;
 
        /* in case no data is transferred */
        bsg_reply->reply_payload_rcv_len = 0;
@@ -426,8 +425,6 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
                goto free_dd;
        }
 
-       cmd = &cmdiocbq->iocb;
-
        bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
        if (!bmp) {
                rc = -ENOMEM;
@@ -461,29 +458,21 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
                goto free_cmp;
        }
 
-       cmd->un.genreq64.bdl.ulpIoTag32 = 0;
-       cmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
-       cmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
-       cmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
-       cmd->un.genreq64.bdl.bdeSize =
-               (request_nseg + reply_nseg) * sizeof(struct ulp_bde64);
-       cmd->ulpCommand = CMD_GEN_REQUEST64_CR;
-       cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
-       cmd->un.genreq64.w5.hcsw.Dfctl = 0;
-       cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
-       cmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
-       cmd->ulpBdeCount = 1;
-       cmd->ulpLe = 1;
-       cmd->ulpClass = CLASS3;
-       cmd->ulpContext = ndlp->nlp_rpi;
+       num_entry = request_nseg + reply_nseg;
+
        if (phba->sli_rev == LPFC_SLI_REV4)
-               cmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
-       cmd->ulpOwner = OWN_CHIP;
+               ulp_context = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+       else
+               ulp_context = ndlp->nlp_rpi;
+
+       lpfc_sli_prep_gen_req(phba, cmdiocbq, bmp, ulp_context, num_entry,
+                             phba->fc_ratov * 2);
+
+       cmdiocbq->num_bdes = num_entry;
        cmdiocbq->vport = phba->pport;
+       cmdiocbq->context2 = cmp;
        cmdiocbq->context3 = bmp;
        cmdiocbq->cmd_flag |= LPFC_IO_LIBDFC;
-       timeout = phba->fc_ratov * 2;
-       cmd->ulpTimeout = timeout;
 
        cmdiocbq->cmd_cmpl = lpfc_bsg_send_mgmt_cmd_cmp;
        cmdiocbq->context1 = dd_data;
@@ -916,6 +905,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        struct lpfc_bsg_event *evt;
        struct event_data *evt_dat = NULL;
        struct lpfc_iocbq *iocbq;
+       IOCB_t *iocb = NULL;
        size_t offset = 0;
        struct list_head head;
        struct ulp_bde64 *bde;
@@ -923,13 +913,13 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        int i;
        struct lpfc_dmabuf *bdeBuf1 = piocbq->context2;
        struct lpfc_dmabuf *bdeBuf2 = piocbq->context3;
-       struct lpfc_hbq_entry *hbqe;
        struct lpfc_sli_ct_request *ct_req;
        struct bsg_job *job = NULL;
        struct fc_bsg_reply *bsg_reply;
        struct bsg_job_data *dd_data = NULL;
        unsigned long flags;
        int size = 0;
+       u32 bde_count = 0;
 
        INIT_LIST_HEAD(&head);
        list_add_tail(&head, &piocbq->list);
@@ -959,12 +949,17 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
                        /* take accumulated byte count from the last iocbq */
                        iocbq = list_entry(head.prev, typeof(*iocbq), list);
-                       evt_dat->len = iocbq->iocb.unsli3.rcvsli3.acc_len;
+                       if (phba->sli_rev == LPFC_SLI_REV4)
+                               evt_dat->len = iocbq->wcqe_cmpl.total_data_placed;
+                       else
+                               evt_dat->len = iocbq->iocb.unsli3.rcvsli3.acc_len;
                } else {
                        list_for_each_entry(iocbq, &head, list) {
-                               for (i = 0; i < iocbq->iocb.ulpBdeCount; i++)
+                               iocb = &iocbq->iocb;
+                               for (i = 0; i < iocb->ulpBdeCount;
+                                    i++)
                                        evt_dat->len +=
-                                       iocbq->iocb.un.cont64[i].tus.f.bdeSize;
+                                       iocb->un.cont64[i].tus.f.bdeSize;
                        }
                }
 
@@ -986,20 +981,20 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                        if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
                                bdeBuf1 = iocbq->context2;
                                bdeBuf2 = iocbq->context3;
+
                        }
-                       for (i = 0; i < iocbq->iocb.ulpBdeCount; i++) {
+                       if (phba->sli_rev == LPFC_SLI_REV4)
+                               bde_count = iocbq->wcqe_cmpl.word3;
+                       else
+                               bde_count = iocbq->iocb.ulpBdeCount;
+                       for (i = 0; i < bde_count; i++) {
                                if (phba->sli3_options &
                                    LPFC_SLI3_HBQ_ENABLED) {
                                        if (i == 0) {
-                                               hbqe = (struct lpfc_hbq_entry *)
-                                                 &iocbq->iocb.un.ulpWord[0];
-                                               size = hbqe->bde.tus.f.bdeSize;
+                                               size = iocbq->wqe.gen_req.bde.tus.f.bdeSize;
                                                dmabuf = bdeBuf1;
                                        } else if (i == 1) {
-                                               hbqe = (struct lpfc_hbq_entry *)
-                                                       &iocbq->iocb.unsli3.
-                                                       sli3Words[4];
-                                               size = hbqe->bde.tus.f.bdeSize;
+                                               size = iocbq->unsol_rcv_len;
                                                dmabuf = bdeBuf2;
                                        }
                                        if ((offset + size) > evt_dat->len)
@@ -1054,16 +1049,16 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                                                                        dmabuf);
                                                } else {
                                                        lpfc_sli3_post_buffer(phba,
-                                                                        pring,
-                                                                        1);
+                                                                             pring,
+                                                                             1);
                                                }
                                                break;
                                        default:
                                                if (!(phba->sli3_options &
                                                      LPFC_SLI3_HBQ_ENABLED))
                                                        lpfc_sli3_post_buffer(phba,
-                                                                        pring,
-                                                                        1);
+                                                                             pring,
+                                                                             1);
                                                break;
                                        }
                                }
@@ -1086,14 +1081,15 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                                                phba->ct_ctx[
                                                    evt_dat->immed_dat].SID);
                        phba->ct_ctx[evt_dat->immed_dat].rxid =
-                               piocbq->iocb.ulpContext;
+                               get_job_ulpcontext(phba, piocbq);
                        phba->ct_ctx[evt_dat->immed_dat].oxid =
-                               piocbq->iocb.unsli3.rcvsli3.ox_id;
+                               get_job_rcvoxid(phba, piocbq);
                        phba->ct_ctx[evt_dat->immed_dat].SID =
-                               piocbq->iocb.un.rcvels.remoteID;
+                               bf_get(wqe_els_did,
+                                      &piocbq->wqe.xmit_els_rsp.wqe_dest);
                        phba->ct_ctx[evt_dat->immed_dat].valid = UNSOL_VALID;
                } else
-                       evt_dat->immed_dat = piocbq->iocb.ulpContext;
+                       evt_dat->immed_dat = get_job_ulpcontext(phba, piocbq);
 
                evt_dat->type = FC_REG_CT_EVENT;
                list_add(&evt_dat->node, &evt->events_to_see);
@@ -1459,13 +1455,13 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag,
                  struct lpfc_dmabuf *cmp, struct lpfc_dmabuf *bmp,
                  int num_entry)
 {
-       IOCB_t *icmd;
        struct lpfc_iocbq *ctiocb = NULL;
        int rc = 0;
        struct lpfc_nodelist *ndlp = NULL;
        struct bsg_job_data *dd_data;
        unsigned long flags;
        uint32_t creg_val;
+       u16 ulp_context, iotag;
 
        ndlp = lpfc_findnode_did(phba->pport, phba->ct_ctx[tag].SID);
        if (!ndlp) {
@@ -1492,62 +1488,36 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag,
                goto no_ctiocb;
        }
 
-       icmd = &ctiocb->iocb;
-       icmd->un.xseq64.bdl.ulpIoTag32 = 0;
-       icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
-       icmd->un.xseq64.bdl.addrLow = putPaddrLow(bmp->phys);
-       icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
-       icmd->un.xseq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64));
-       icmd->un.xseq64.w5.hcsw.Fctl = (LS | LA);
-       icmd->un.xseq64.w5.hcsw.Dfctl = 0;
-       icmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_DD_SOL_CTL;
-       icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_CT;
-
-       /* Fill in rest of iocb */
-       icmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX;
-       icmd->ulpBdeCount = 1;
-       icmd->ulpLe = 1;
-       icmd->ulpClass = CLASS3;
        if (phba->sli_rev == LPFC_SLI_REV4) {
                /* Do not issue unsol response if oxid not marked as valid */
                if (phba->ct_ctx[tag].valid != UNSOL_VALID) {
                        rc = IOCB_ERROR;
                        goto issue_ct_rsp_exit;
                }
-               icmd->ulpContext = phba->ct_ctx[tag].rxid;
-               icmd->unsli3.rcvsli3.ox_id = phba->ct_ctx[tag].oxid;
-               ndlp = lpfc_findnode_did(phba->pport, phba->ct_ctx[tag].SID);
-               if (!ndlp) {
-                       lpfc_printf_log(phba, KERN_WARNING, LOG_ELS,
-                                "2721 ndlp null for oxid %x SID %x\n",
-                                       icmd->ulpContext,
-                                       phba->ct_ctx[tag].SID);
-                       rc = IOCB_ERROR;
-                       goto issue_ct_rsp_exit;
-               }
-
-               /* get a refernece count so the ndlp doesn't go away while
-                * we respond
-                */
-               if (!lpfc_nlp_get(ndlp)) {
-                       rc = IOCB_ERROR;
-                       goto issue_ct_rsp_exit;
-               }
 
-               icmd->un.ulpWord[3] =
-                               phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+               lpfc_sli_prep_xmit_seq64(phba, ctiocb, bmp,
+                                        phba->sli4_hba.rpi_ids[ndlp->nlp_rpi],
+                                        phba->ct_ctx[tag].oxid, num_entry,
+                                        FC_RCTL_DD_SOL_CTL, 1,
+                                        CMD_XMIT_SEQUENCE64_WQE);
 
                /* The exchange is done, mark the entry as invalid */
                phba->ct_ctx[tag].valid = UNSOL_INVALID;
-       } else
-               icmd->ulpContext = (ushort) tag;
+               iotag = get_wqe_reqtag(ctiocb);
+       } else {
+               lpfc_sli_prep_xmit_seq64(phba, ctiocb, bmp, 0, tag, num_entry,
+                                        FC_RCTL_DD_SOL_CTL, 1,
+                                        CMD_XMIT_SEQUENCE64_CX);
+               ctiocb->num_bdes = num_entry;
+               iotag = ctiocb->iocb.ulpIoTag;
+       }
 
-       icmd->ulpTimeout = phba->fc_ratov * 2;
+       ulp_context = get_job_ulpcontext(phba, ctiocb);
 
        /* Xmit CT response on exchange <xid> */
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
-               "2722 Xmit CT response on exchange x%x Data: x%x x%x x%x\n",
-               icmd->ulpContext, icmd->ulpIoTag, tag, phba->link_state);
+                       "2722 Xmit CT response on exchange x%x Data: x%x x%x x%x\n",
+                       ulp_context, iotag, tag, phba->link_state);
 
        ctiocb->cmd_flag |= LPFC_IO_LIBDFC;
        ctiocb->vport = phba->pport;
@@ -2633,7 +2603,6 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi,
 {
        struct lpfc_bsg_event *evt;
        struct lpfc_iocbq *cmdiocbq, *rspiocbq;
-       IOCB_t *cmd, *rsp;
        struct lpfc_dmabuf *dmabuf;
        struct ulp_bde64 *bpl = NULL;
        struct lpfc_sli_ct_request *ctreq = NULL;
@@ -2641,6 +2610,7 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi,
        int time_left;
        int iocb_stat = IOCB_SUCCESS;
        unsigned long flags;
+       u32 status;
 
        *txxri = 0;
        *rxxri = 0;
@@ -2684,9 +2654,6 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi,
                goto err_get_xri_exit;
        }
 
-       cmd = &cmdiocbq->iocb;
-       rsp = &rspiocbq->iocb;
-
        memset(ctreq, 0, ELX_LOOPBACK_HEADER_SZ);
 
        ctreq->RevisionId.bits.Revision = SLI_CT_REVISION;
@@ -2696,36 +2663,24 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi,
        ctreq->CommandResponse.bits.CmdRsp = ELX_LOOPBACK_XRI_SETUP;
        ctreq->CommandResponse.bits.Size = 0;
 
-
-       cmd->un.xseq64.bdl.addrHigh = putPaddrHigh(dmabuf->phys);
-       cmd->un.xseq64.bdl.addrLow = putPaddrLow(dmabuf->phys);
-       cmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
-       cmd->un.xseq64.bdl.bdeSize = sizeof(*bpl);
-
-       cmd->un.xseq64.w5.hcsw.Fctl = LA;
-       cmd->un.xseq64.w5.hcsw.Dfctl = 0;
-       cmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
-       cmd->un.xseq64.w5.hcsw.Type = FC_TYPE_CT;
-
-       cmd->ulpCommand = CMD_XMIT_SEQUENCE64_CR;
-       cmd->ulpBdeCount = 1;
-       cmd->ulpLe = 1;
-       cmd->ulpClass = CLASS3;
-       cmd->ulpContext = rpi;
-
+       cmdiocbq->context3 = dmabuf;
        cmdiocbq->cmd_flag |= LPFC_IO_LIBDFC;
        cmdiocbq->vport = phba->pport;
        cmdiocbq->cmd_cmpl = NULL;
 
+       lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, dmabuf, rpi, 0, 1,
+                                FC_RCTL_DD_SOL_CTL, 0, CMD_XMIT_SEQUENCE64_CR);
+
        iocb_stat = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq,
-                               rspiocbq,
-                               (phba->fc_ratov * 2)
-                               + LPFC_DRVR_TIMEOUT);
-       if ((iocb_stat != IOCB_SUCCESS) || (rsp->ulpStatus != IOSTAT_SUCCESS)) {
+                                            rspiocbq, (phba->fc_ratov * 2)
+                                            + LPFC_DRVR_TIMEOUT);
+
+       status = get_job_ulpstatus(phba, rspiocbq);
+       if (iocb_stat != IOCB_SUCCESS || status != IOCB_SUCCESS) {
                ret_val = -EIO;
                goto err_get_xri_exit;
        }
-       *txxri =  rsp->ulpContext;
+       *txxri = get_job_ulpcontext(phba, rspiocbq);
 
        evt->waiting = 1;
        evt->wait_time_stamp = jiffies;
@@ -2926,7 +2881,7 @@ out:
 }
 
 /**
- * lpfcdiag_loop_post_rxbufs - post the receive buffers for an unsol CT cmd
+ * lpfcdiag_sli3_loop_post_rxbufs - post the receive buffers for an unsol CT cmd
  * @phba: Pointer to HBA context object
  * @rxxri: Receive exchange id
  * @len: Number of data bytes
@@ -2934,8 +2889,8 @@ out:
  * This function allocates and posts a data buffer of sufficient size to receive
  * an unsolicted CT command.
  **/
-static int lpfcdiag_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri,
-                            size_t len)
+static int lpfcdiag_sli3_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri,
+                                         size_t len)
 {
        struct lpfc_sli_ring *pring;
        struct lpfc_iocbq *cmdiocbq;
@@ -2972,7 +2927,6 @@ static int lpfcdiag_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri,
        /* Queue buffers for the receive exchange */
        num_bde = (uint32_t)rxbuffer->flag;
        dmp = &rxbuffer->dma;
-
        cmd = &cmdiocbq->iocb;
        i = 0;
 
@@ -3040,7 +2994,6 @@ static int lpfcdiag_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri,
                        ret_val = -EIO;
                        goto err_post_rxbufs_exit;
                }
-
                cmd = &cmdiocbq->iocb;
                i = 0;
        }
@@ -3092,7 +3045,7 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job)
        size_t segment_len = 0, segment_offset = 0, current_offset = 0;
        uint16_t rpi = 0;
        struct lpfc_iocbq *cmdiocbq, *rspiocbq = NULL;
-       IOCB_t *cmd, *rsp = NULL;
+       union lpfc_wqe128 *cmdwqe, *rspwqe;
        struct lpfc_sli_ct_request *ctreq;
        struct lpfc_dmabuf *txbmp;
        struct ulp_bde64 *txbpl = NULL;
@@ -3185,7 +3138,7 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job)
                        goto loopback_test_exit;
                }
 
-               rc = lpfcdiag_loop_post_rxbufs(phba, rxxri, full_size);
+               rc = lpfcdiag_sli3_loop_post_rxbufs(phba, rxxri, full_size);
                if (rc) {
                        lpfcdiag_loop_self_unreg(phba, rpi);
                        goto loopback_test_exit;
@@ -3228,9 +3181,12 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job)
                goto err_loopback_test_exit;
        }
 
-       cmd = &cmdiocbq->iocb;
-       if (phba->sli_rev < LPFC_SLI_REV4)
-               rsp = &rspiocbq->iocb;
+       cmdwqe = &cmdiocbq->wqe;
+       memset(cmdwqe, 0, sizeof(union lpfc_wqe));
+       if (phba->sli_rev < LPFC_SLI_REV4) {
+               rspwqe = &rspiocbq->wqe;
+               memset(rspwqe, 0, sizeof(union lpfc_wqe));
+       }
 
        INIT_LIST_HEAD(&head);
        list_add_tail(&head, &txbuffer->dma.list);
@@ -3262,42 +3218,32 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job)
        /* Build the XMIT_SEQUENCE iocb */
        num_bde = (uint32_t)txbuffer->flag;
 
-       cmd->un.xseq64.bdl.addrHigh = putPaddrHigh(txbmp->phys);
-       cmd->un.xseq64.bdl.addrLow = putPaddrLow(txbmp->phys);
-       cmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
-       cmd->un.xseq64.bdl.bdeSize = (num_bde * sizeof(struct ulp_bde64));
-
-       cmd->un.xseq64.w5.hcsw.Fctl = (LS | LA);
-       cmd->un.xseq64.w5.hcsw.Dfctl = 0;
-       cmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
-       cmd->un.xseq64.w5.hcsw.Type = FC_TYPE_CT;
-
-       cmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX;
-       cmd->ulpBdeCount = 1;
-       cmd->ulpLe = 1;
-       cmd->ulpClass = CLASS3;
+       cmdiocbq->num_bdes = num_bde;
+       cmdiocbq->cmd_flag |= LPFC_IO_LIBDFC;
+       cmdiocbq->cmd_flag |= LPFC_IO_LOOPBACK;
+       cmdiocbq->vport = phba->pport;
+       cmdiocbq->cmd_cmpl = NULL;
+       cmdiocbq->context3 = txbmp;
 
        if (phba->sli_rev < LPFC_SLI_REV4) {
-               cmd->ulpContext = txxri;
+               lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, txbmp, 0, txxri,
+                                        num_bde, FC_RCTL_DD_UNSOL_CTL, 1,
+                                        CMD_XMIT_SEQUENCE64_CX);
+
        } else {
-               cmd->un.xseq64.bdl.ulpIoTag32 = 0;
-               cmd->un.ulpWord[3] = phba->sli4_hba.rpi_ids[rpi];
-               cmdiocbq->context3 = txbmp;
+               lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, txbmp,
+                                        phba->sli4_hba.rpi_ids[rpi], 0xffff,
+                                        full_size, FC_RCTL_DD_UNSOL_CTL, 1,
+                                        CMD_XMIT_SEQUENCE64_WQE);
                cmdiocbq->sli4_xritag = NO_XRI;
-               cmd->unsli3.rcvsli3.ox_id = 0xffff;
        }
-       cmdiocbq->cmd_flag |= LPFC_IO_LIBDFC;
-       cmdiocbq->cmd_flag |= LPFC_IO_LOOPBACK;
-       cmdiocbq->vport = phba->pport;
-       cmdiocbq->cmd_cmpl = NULL;
 
        iocb_stat = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq,
                                             rspiocbq, (phba->fc_ratov * 2) +
                                             LPFC_DRVR_TIMEOUT);
-
-       if ((iocb_stat != IOCB_SUCCESS) ||
-           ((phba->sli_rev < LPFC_SLI_REV4) &&
-            (rsp->ulpStatus != IOSTAT_SUCCESS))) {
+       if (iocb_stat != IOCB_SUCCESS ||
+           (phba->sli_rev < LPFC_SLI_REV4 &&
+            (get_job_ulpstatus(phba, rspiocbq) != IOSTAT_SUCCESS))) {
                lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
                                "3126 Failed loopback test issue iocb: "
                                "iocb_stat:x%x\n", iocb_stat);
index 9d2c611c6466db52b7f318c17fded8d8eccab3df..62c37df83f6c919f4d1ef6f299a5c31227de11c5 100644 (file)
@@ -358,6 +358,14 @@ void lpfc_sli_prep_els_req_rsp(struct lpfc_hba *phba,
                               struct lpfc_vport *vport,
                               struct lpfc_dmabuf *bmp, u16 cmd_size, u32 did,
                               u32 elscmd, u8 tmo, u8 expect_rsp);
+void lpfc_sli_prep_gen_req(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocbq,
+                          struct lpfc_dmabuf *bmp, u16 rpi, u32 num_entry,
+                          u8 tmo);
+void lpfc_sli_prep_xmit_seq64(struct lpfc_hba *phba,
+                             struct lpfc_iocbq *cmdiocbq,
+                             struct lpfc_dmabuf *bmp, u16 rpi, u16 ox_id,
+                             u32 num_entry, u8 rctl, u8 last_seq,
+                             u8 cr_cx_cmd);
 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);
index b78823a305ccba725e6f97449dc377dffd6248ec..31f185a11bcb9a31e0eee8c40c7f219f393eaf5f 100644 (file)
@@ -87,12 +87,12 @@ lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
                lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
                                "0146 Ignoring unsolicited CT No HBQ "
                                "status = x%x\n",
-                               piocbq->iocb.ulpStatus);
+                               get_job_ulpstatus(phba, piocbq));
        }
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
                        "0145 Ignoring unsolicted CT HBQ Size:%d "
                        "status = x%x\n",
-                       size, piocbq->iocb.ulpStatus);
+                       size, get_job_ulpstatus(phba, piocbq));
 }
 
 static void
@@ -143,7 +143,7 @@ lpfc_ct_unsol_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
  * lpfc_ct_reject_event - Issue reject for unhandled CT MIB commands
  * @ndlp: pointer to a node-list data structure.
  * @ct_req: pointer to the CT request data structure.
- * @rx_id: rx_id of the received UNSOL CT command
+ * @ulp_context: context of received UNSOL CT command
  * @ox_id: ox_id of the UNSOL CT command
  *
  * This routine is invoked by the lpfc_ct_handle_mibreq routine for sending
@@ -152,7 +152,7 @@ lpfc_ct_unsol_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 static void
 lpfc_ct_reject_event(struct lpfc_nodelist *ndlp,
                     struct lpfc_sli_ct_request *ct_req,
-                    u16 rx_id, u16 ox_id)
+                    u16 ulp_context, u16 ox_id)
 {
        struct lpfc_vport *vport = ndlp->vport;
        struct lpfc_hba *phba = vport->phba;
@@ -161,8 +161,8 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp,
        struct lpfc_dmabuf *bmp = NULL;
        struct lpfc_dmabuf *mp = NULL;
        struct ulp_bde64 *bpl;
-       IOCB_t *icmd;
        u8 rc = 0;
+       u32 tmo;
 
        /* fill in BDEs for command */
        mp = kmalloc(sizeof(*mp), GFP_KERNEL);
@@ -220,43 +220,41 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp,
                goto ct_free_bmpvirt;
        }
 
-       icmd = &cmdiocbq->iocb;
-       icmd->un.genreq64.bdl.ulpIoTag32 = 0;
-       icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
-       icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
-       icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
-       icmd->un.genreq64.bdl.bdeSize = sizeof(struct ulp_bde64);
-       icmd->un.genreq64.w5.hcsw.Fctl = (LS | LA);
-       icmd->un.genreq64.w5.hcsw.Dfctl = 0;
-       icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_SOL_CTL;
-       icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
-       icmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX;
-       icmd->ulpBdeCount = 1;
-       icmd->ulpLe = 1;
-       icmd->ulpClass = CLASS3;
+       if (phba->sli_rev == LPFC_SLI_REV4) {
+               lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, bmp,
+                                        phba->sli4_hba.rpi_ids[ndlp->nlp_rpi],
+                                        ox_id, 1, FC_RCTL_DD_SOL_CTL, 1,
+                                        CMD_XMIT_SEQUENCE64_WQE);
+       } else {
+               lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, bmp, 0, ulp_context, 1,
+                                        FC_RCTL_DD_SOL_CTL, 1,
+                                        CMD_XMIT_SEQUENCE64_CX);
+       }
 
        /* Save for completion so we can release these resources */
-       cmdiocbq->context1 = lpfc_nlp_get(ndlp);
        cmdiocbq->context2 = (uint8_t *)mp;
        cmdiocbq->context3 = (uint8_t *)bmp;
        cmdiocbq->cmd_cmpl = lpfc_ct_unsol_cmpl;
-       icmd->ulpContext = rx_id;  /* Xri / rx_id */
-       icmd->unsli3.rcvsli3.ox_id = ox_id;
-       icmd->un.ulpWord[3] =
-               phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
-       icmd->ulpTimeout = (3 * phba->fc_ratov);
+       tmo = (3 * phba->fc_ratov);
 
        cmdiocbq->retry = 0;
        cmdiocbq->vport = vport;
        cmdiocbq->context_un.ndlp = NULL;
-       cmdiocbq->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
+       cmdiocbq->drvrTimeout = tmo + LPFC_DRVR_TIMEOUT;
+
+       cmdiocbq->context1 = lpfc_nlp_get(ndlp);
+       if (!cmdiocbq->context1)
+               goto ct_no_ndlp;
 
        rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);
-       if (!rc)
-               return;
+       if (rc) {
+               lpfc_nlp_put(ndlp);
+               goto ct_no_ndlp;
+       }
+       return;
 
+ct_no_ndlp:
        rc = 6;
-       lpfc_nlp_put(ndlp);
        lpfc_sli_release_iocbq(phba, cmdiocbq);
 ct_free_bmpvirt:
        lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
@@ -286,25 +284,17 @@ lpfc_ct_handle_mibreq(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocbq)
 {
        struct lpfc_sli_ct_request *ct_req;
        struct lpfc_nodelist *ndlp = NULL;
-       struct lpfc_vport *vport = NULL;
-       IOCB_t *icmd = &ctiocbq->iocb;
-       u32 mi_cmd, vpi;
-       u32 did = 0;
-
-       vpi = ctiocbq->iocb.unsli3.rcvsli3.vpi;
-       vport = lpfc_find_vport_by_vpid(phba, vpi);
-       if (!vport) {
-               lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
-                               "6437 Unsol CT: VPORT NULL vpi : x%x\n",
-                               vpi);
-               return;
-       }
-
-       did = ctiocbq->iocb.un.rcvels.remoteID;
-       if (icmd->ulpStatus) {
+       struct lpfc_vport *vport = ctiocbq->vport;
+       u32 ulp_status = get_job_ulpstatus(phba, ctiocbq);
+       u32 ulp_word4 = get_job_word4(phba, ctiocbq);
+       u32 did;
+       u32 mi_cmd;
+
+       did = bf_get(els_rsp64_sid, &ctiocbq->wqe.xmit_els_rsp);
+       if (ulp_status) {
                lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
                                 "6438 Unsol CT: status:x%x/x%x did : x%x\n",
-                                icmd->ulpStatus, icmd->un.ulpWord[4], did);
+                                ulp_status, ulp_word4, did);
                return;
        }
 
@@ -322,13 +312,14 @@ lpfc_ct_handle_mibreq(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocbq)
 
        ct_req = ((struct lpfc_sli_ct_request *)
                 (((struct lpfc_dmabuf *)ctiocbq->context2)->virt));
-
        mi_cmd = ct_req->CommandResponse.bits.CmdRsp;
        lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
                         "6442 : MI Cmd : x%x Not Supported\n", mi_cmd);
        lpfc_ct_reject_event(ndlp, ct_req,
-                            ctiocbq->iocb.ulpContext,
-                            ctiocbq->iocb.unsli3.rcvsli3.ox_id);
+                            bf_get(wqe_ctxt_tag,
+                                   &ctiocbq->wqe.xmit_els_rsp.wqe_com),
+                            bf_get(wqe_rcvoxid,
+                                   &ctiocbq->wqe.xmit_els_rsp.wqe_com));
 }
 
 /**
@@ -351,21 +342,32 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        IOCB_t *icmd = &ctiocbq->iocb;
        int i;
        struct lpfc_iocbq *iocbq;
+       struct lpfc_iocbq *iocb;
        dma_addr_t dma_addr;
        uint32_t size;
        struct list_head head;
        struct lpfc_sli_ct_request *ct_req;
        struct lpfc_dmabuf *bdeBuf1 = ctiocbq->context2;
        struct lpfc_dmabuf *bdeBuf2 = ctiocbq->context3;
+       u32 status, parameter, bde_count = 0;
+       struct lpfc_wcqe_complete *wcqe_cmpl = NULL;
 
        ctiocbq->context1 = NULL;
        ctiocbq->context2 = NULL;
        ctiocbq->context3 = NULL;
 
-       if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
+       wcqe_cmpl = &ctiocbq->wcqe_cmpl;
+       status = get_job_ulpstatus(phba, ctiocbq);
+       parameter = get_job_word4(phba, ctiocbq);
+       if (phba->sli_rev == LPFC_SLI_REV4)
+               bde_count = wcqe_cmpl->word3;
+       else
+               bde_count = icmd->ulpBdeCount;
+
+       if (unlikely(status == IOSTAT_NEED_BUFFER)) {
                lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
-       } else if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
-                  ((icmd->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+       } else if ((status == IOSTAT_LOCAL_REJECT) &&
+                  ((parameter & IOERR_PARAM_MASK) ==
                   IOERR_RCV_BUFFER_WAITING)) {
                /* Not enough posted buffers; Try posting more buffers */
                phba->fc_stat.NoRcvBuf++;
@@ -377,26 +379,12 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        /* If there are no BDEs associated
         * with this IOCB, there is nothing to do.
         */
-       if (icmd->ulpBdeCount == 0)
+       if (bde_count == 0)
                return;
 
-       if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
-               ctiocbq->context2 = bdeBuf1;
-               if (icmd->ulpBdeCount == 2)
-                       ctiocbq->context3 = bdeBuf2;
-       } else {
-               dma_addr = getPaddr(icmd->un.cont64[0].addrHigh,
-                                   icmd->un.cont64[0].addrLow);
-               ctiocbq->context2 = lpfc_sli_ringpostbuf_get(phba, pring,
-                                                            dma_addr);
-               if (icmd->ulpBdeCount == 2) {
-                       dma_addr = getPaddr(icmd->un.cont64[1].addrHigh,
-                                           icmd->un.cont64[1].addrLow);
-                       ctiocbq->context3 = lpfc_sli_ringpostbuf_get(phba,
-                                                                    pring,
-                                                                    dma_addr);
-               }
-       }
+       ctiocbq->context2 = bdeBuf1;
+       if (bde_count == 2)
+               ctiocbq->context3 = bdeBuf2;
 
        ct_req = ((struct lpfc_sli_ct_request *)
                 (((struct lpfc_dmabuf *)ctiocbq->context2)->virt));
@@ -412,19 +400,29 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
                INIT_LIST_HEAD(&head);
                list_add_tail(&head, &ctiocbq->list);
-               list_for_each_entry(iocbq, &head, list) {
-                       icmd = &iocbq->iocb;
-                       if (icmd->ulpBdeCount == 0)
+               list_for_each_entry(iocb, &head, list) {
+                       if (phba->sli_rev == LPFC_SLI_REV4)
+                               bde_count = iocb->wcqe_cmpl.word3;
+                       else
+                               bde_count = iocb->iocb.ulpBdeCount;
+
+                       if (!bde_count)
                                continue;
-                       bdeBuf1 = iocbq->context2;
-                       iocbq->context2 = NULL;
-                       size  = icmd->un.cont64[0].tus.f.bdeSize;
+                       bdeBuf1 = iocb->context2;
+                       iocb->context2 = NULL;
+                       if (phba->sli_rev == LPFC_SLI_REV4)
+                               size = iocb->wqe.gen_req.bde.tus.f.bdeSize;
+                       else
+                               size  = iocb->iocb.un.cont64[0].tus.f.bdeSize;
                        lpfc_ct_unsol_buffer(phba, ctiocbq, bdeBuf1, size);
                        lpfc_in_buf_free(phba, bdeBuf1);
-                       if (icmd->ulpBdeCount == 2) {
-                               bdeBuf2 = iocbq->context3;
-                               iocbq->context3 = NULL;
-                               size  = icmd->unsli3.rcvsli3.bde2.tus.f.bdeSize;
+                       if (bde_count == 2) {
+                               bdeBuf2 = iocb->context3;
+                               iocb->context3 = NULL;
+                               if (phba->sli_rev == LPFC_SLI_REV4)
+                                       size = iocb->unsol_rcv_len;
+                               else
+                                       size = iocb->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize;
                                lpfc_ct_unsol_buffer(phba, ctiocbq, bdeBuf2,
                                                     size);
                                lpfc_in_buf_free(phba, bdeBuf2);
@@ -588,15 +586,15 @@ lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb)
 static int
 lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
             struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp,
-            void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
-                    struct lpfc_iocbq *),
+            void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *,
+                         struct lpfc_iocbq *),
             struct lpfc_nodelist *ndlp, uint32_t event_tag, uint32_t num_entry,
             uint32_t tmo, uint8_t retry)
 {
        struct lpfc_hba  *phba = vport->phba;
-       IOCB_t *icmd;
        struct lpfc_iocbq *geniocb;
        int rc;
+       u16 ulp_context;
 
        /* Allocate buffer for  command iocb */
        geniocb = lpfc_sli_get_iocbq(phba);
@@ -604,12 +602,8 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
        if (geniocb == NULL)
                return 1;
 
-       icmd = &geniocb->iocb;
-       icmd->un.genreq64.bdl.ulpIoTag32 = 0;
-       icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
-       icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
-       icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
-       icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64));
+       /* Update the num_entry bde count */
+       geniocb->num_bdes = num_entry;
 
        geniocb->context3 = (uint8_t *) bmp;
 
@@ -619,41 +613,26 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
 
        geniocb->event_tag = event_tag;
 
-       /* Fill in payload, bp points to frame payload */
-       icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
-
-       /* Fill in rest of iocb */
-       icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
-       icmd->un.genreq64.w5.hcsw.Dfctl = 0;
-       icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
-       icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
-
        if (!tmo) {
                 /* FC spec states we need 3 * ratov for CT requests */
                tmo = (3 * phba->fc_ratov);
        }
-       icmd->ulpTimeout = tmo;
-       icmd->ulpBdeCount = 1;
-       icmd->ulpLe = 1;
-       icmd->ulpClass = CLASS3;
-       icmd->ulpContext = ndlp->nlp_rpi;
+
        if (phba->sli_rev == LPFC_SLI_REV4)
-               icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+               ulp_context = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+       else
+               ulp_context = ndlp->nlp_rpi;
 
-       if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
-               /* For GEN_REQUEST64_CR, use the RPI */
-               icmd->ulpCt_h = 0;
-               icmd->ulpCt_l = 0;
-       }
+       lpfc_sli_prep_gen_req(phba, geniocb, bmp, ulp_context, num_entry, tmo);
 
        /* Issue GEN REQ IOCB for NPORT <did> */
        lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
                         "0119 Issue GEN REQ IOCB to NPORT x%x "
                         "Data: x%x x%x\n",
-                        ndlp->nlp_DID, icmd->ulpIoTag,
+                        ndlp->nlp_DID, geniocb->iotag,
                         vport->port_state);
        geniocb->cmd_cmpl = cmpl;
-       geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
+       geniocb->drvrTimeout = tmo + LPFC_DRVR_TIMEOUT;
        geniocb->vport = vport;
        geniocb->retry = retry;
        geniocb->context_un.ndlp = lpfc_nlp_get(ndlp);
@@ -661,9 +640,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
                goto out;
 
        rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0);
-
        if (rc == IOCB_ERROR) {
-               geniocb->context_un.ndlp = NULL;
                lpfc_nlp_put(ndlp);
                goto out;
        }
@@ -939,12 +916,13 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 {
        struct lpfc_vport *vport = cmdiocb->vport;
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
-       IOCB_t *irsp;
        struct lpfc_dmabuf *outp;
        struct lpfc_dmabuf *inp;
        struct lpfc_sli_ct_request *CTrsp;
        struct lpfc_sli_ct_request *CTreq;
        struct lpfc_nodelist *ndlp;
+       u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
+       u32 ulp_word4 = get_job_word4(phba, rspiocb);
        int rc, type;
 
        /* First save ndlp, before we overwrite it */
@@ -952,13 +930,13 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 
        /* we pass cmdiocb to state machine which needs rspiocb as well */
        cmdiocb->context_un.rsp_iocb = rspiocb;
+
        inp = (struct lpfc_dmabuf *) cmdiocb->context1;
        outp = (struct lpfc_dmabuf *) cmdiocb->context2;
-       irsp = &rspiocb->iocb;
 
        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
                 "GID_FT cmpl:     status:x%x/x%x rtry:%d",
-               irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_ns_retry);
+               ulp_status, ulp_word4, vport->fc_ns_retry);
 
        /* Ignore response if link flipped after this request was made */
        if (cmdiocb->event_tag != phba->fc_eventTag) {
@@ -982,7 +960,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                lpfc_vport_set_state(vport, FC_VPORT_FAILED);
                goto out;
        }
-       if (lpfc_error_lost_link(irsp->ulpStatus, irsp->un.ulpWord[4])) {
+       if (lpfc_error_lost_link(ulp_status, ulp_word4)) {
                lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
                                 "0226 NS query failed due to link event\n");
                if (vport->fc_flag & FC_RSCN_MODE)
@@ -1014,11 +992,11 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        }
        spin_unlock_irq(shost->host_lock);
 
-       if (irsp->ulpStatus) {
+       if (ulp_status) {
                /* Check for retry */
                if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
-                       if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
-                           (irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
+                       if (ulp_status != IOSTAT_LOCAL_REJECT ||
+                           (ulp_word4 & IOERR_PARAM_MASK) !=
                            IOERR_NO_RESOURCES)
                                vport->fc_ns_retry++;
 
@@ -1041,7 +1019,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                lpfc_vport_set_state(vport, FC_VPORT_FAILED);
                lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
                                 "0257 GID_FT Query error: 0x%x 0x%x\n",
-                                irsp->ulpStatus, vport->fc_ns_retry);
+                                ulp_status, vport->fc_ns_retry);
        } else {
                /* Good status, continue checking */
                CTreq = (struct lpfc_sli_ct_request *) inp->virt;
@@ -1055,12 +1033,12 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                                         CTreq->un.gid.Fc4Type,
                                         vport->num_disc_nodes,
                                         vport->gidft_inp,
-                                        irsp->un.genreq64.bdl.bdeSize);
+                                        get_job_data_placed(phba, rspiocb));
 
                        lpfc_ns_rsp(vport,
                                    outp,
                                    CTreq->un.gid.Fc4Type,
-                                   (uint32_t) (irsp->un.genreq64.bdl.bdeSize));
+                                   get_job_data_placed(phba, rspiocb));
                } else if (CTrsp->CommandResponse.bits.CmdRsp ==
                           be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
                        /* NameServer Rsp Error */
@@ -1155,12 +1133,13 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 {
        struct lpfc_vport *vport = cmdiocb->vport;
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
-       IOCB_t *irsp;
        struct lpfc_dmabuf *outp;
        struct lpfc_dmabuf *inp;
        struct lpfc_sli_ct_request *CTrsp;
        struct lpfc_sli_ct_request *CTreq;
        struct lpfc_nodelist *ndlp;
+       u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
+       u32 ulp_word4 = get_job_word4(phba, rspiocb);
        int rc;
 
        /* First save ndlp, before we overwrite it */
@@ -1170,11 +1149,10 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        cmdiocb->context_un.rsp_iocb = rspiocb;
        inp = (struct lpfc_dmabuf *)cmdiocb->context1;
        outp = (struct lpfc_dmabuf *)cmdiocb->context2;
-       irsp = &rspiocb->iocb;
 
        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
                              "GID_PT cmpl:     status:x%x/x%x rtry:%d",
-                             irsp->ulpStatus, irsp->un.ulpWord[4],
+                             ulp_status, ulp_word4,
                              vport->fc_ns_retry);
 
        /* Ignore response if link flipped after this request was made */
@@ -1199,7 +1177,7 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                lpfc_vport_set_state(vport, FC_VPORT_FAILED);
                goto out;
        }
-       if (lpfc_error_lost_link(irsp->ulpStatus, irsp->un.ulpWord[4])) {
+       if (lpfc_error_lost_link(ulp_status, ulp_word4)) {
                lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
                                 "4166 NS query failed due to link event\n");
                if (vport->fc_flag & FC_RSCN_MODE)
@@ -1231,11 +1209,11 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        }
        spin_unlock_irq(shost->host_lock);
 
-       if (irsp->ulpStatus) {
+       if (ulp_status) {
                /* Check for retry */
                if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
-                       if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
-                           (irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
+                       if (ulp_status != IOSTAT_LOCAL_REJECT ||
+                           (ulp_word4 & IOERR_PARAM_MASK) !=
                            IOERR_NO_RESOURCES)
                                vport->fc_ns_retry++;
 
@@ -1254,7 +1232,7 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                lpfc_vport_set_state(vport, FC_VPORT_FAILED);
                lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
                                 "4103 GID_FT Query error: 0x%x 0x%x\n",
-                                irsp->ulpStatus, vport->fc_ns_retry);
+                                ulp_status, vport->fc_ns_retry);
        } else {
                /* Good status, continue checking */
                CTreq = (struct lpfc_sli_ct_request *)inp->virt;
@@ -1268,12 +1246,12 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                                         CTreq->un.gid.Fc4Type,
                                         vport->num_disc_nodes,
                                         vport->gidft_inp,
-                                        irsp->un.genreq64.bdl.bdeSize);
+                                        get_job_data_placed(phba, rspiocb));
 
                        lpfc_ns_rsp(vport,
                                    outp,
                                    CTreq->un.gid.Fc4Type,
-                                   (uint32_t)(irsp->un.genreq64.bdl.bdeSize));
+                                   get_job_data_placed(phba, rspiocb));
                } else if (CTrsp->CommandResponse.bits.CmdRsp ==
                           be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
                        /* NameServer Rsp Error */
@@ -1368,20 +1346,21 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 {
        struct lpfc_vport *vport = cmdiocb->vport;
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
-       IOCB_t *irsp = &rspiocb->iocb;
        struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1;
        struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2;
        struct lpfc_sli_ct_request *CTrsp;
        int did, rc, retry;
        uint8_t fbits;
        struct lpfc_nodelist *ndlp = NULL, *free_ndlp = NULL;
+       u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
+       u32 ulp_word4 = get_job_word4(phba, rspiocb);
 
        did = ((struct lpfc_sli_ct_request *) inp->virt)->un.gff.PortId;
        did = be32_to_cpu(did);
 
        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
                "GFF_ID cmpl:     status:x%x/x%x did:x%x",
-               irsp->ulpStatus, irsp->un.ulpWord[4], did);
+               ulp_status, ulp_word4, did);
 
        /* Ignore response if link flipped after this request was made */
        if (cmdiocb->event_tag != phba->fc_eventTag) {
@@ -1390,7 +1369,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                goto iocb_free;
        }
 
-       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+       if (ulp_status == IOSTAT_SUCCESS) {
                /* Good status, continue checking */
                CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
                fbits = CTrsp->un.gff_acc.fbits[FCP_TYPE_FEATURE_OFFSET];
@@ -1420,8 +1399,8 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                /* Check for retry */
                if (cmdiocb->retry < LPFC_MAX_NS_RETRY) {
                        retry = 1;
-                       if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
-                               switch ((irsp->un.ulpWord[4] &
+                       if (ulp_status == IOSTAT_LOCAL_REJECT) {
+                               switch ((ulp_word4 &
                                        IOERR_PARAM_MASK)) {
 
                                case IOERR_NO_RESOURCES:
@@ -1457,7 +1436,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
                                 "0267 NameServer GFF Rsp "
                                 "x%x Error (%d %d) Data: x%x x%x\n",
-                                did, irsp->ulpStatus, irsp->un.ulpWord[4],
+                                did, ulp_status, ulp_word4,
                                 vport->fc_flag, vport->fc_rscn_id_cnt);
        }
 
@@ -1512,10 +1491,9 @@ iocb_free:
 
 static void
 lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
-                               struct lpfc_iocbq *rspiocb)
+                       struct lpfc_iocbq *rspiocb)
 {
        struct lpfc_vport *vport = cmdiocb->vport;
-       IOCB_t *irsp = &rspiocb->iocb;
        struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *)cmdiocb->context1;
        struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *)cmdiocb->context2;
        struct lpfc_sli_ct_request *CTrsp;
@@ -1523,13 +1501,15 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        struct lpfc_nodelist *ndlp = NULL;
        struct lpfc_nodelist *ns_ndlp = NULL;
        uint32_t fc4_data_0, fc4_data_1;
+       u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
+       u32 ulp_word4 = get_job_word4(phba, rspiocb);
 
        did = ((struct lpfc_sli_ct_request *)inp->virt)->un.gft.PortId;
        did = be32_to_cpu(did);
 
        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
                              "GFT_ID cmpl: status:x%x/x%x did:x%x",
-                             irsp->ulpStatus, irsp->un.ulpWord[4], did);
+                             ulp_status, ulp_word4, did);
 
        /* Ignore response if link flipped after this request was made */
        if ((uint32_t) cmdiocb->event_tag != phba->fc_eventTag) {
@@ -1541,7 +1521,7 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        /* Preserve the nameserver node to release the reference. */
        ns_ndlp = cmdiocb->context_un.ndlp;
 
-       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+       if (ulp_status == IOSTAT_SUCCESS) {
                /* Good status, continue checking */
                CTrsp = (struct lpfc_sli_ct_request *)outp->virt;
                fc4_data_0 = be32_to_cpu(CTrsp->un.gft_acc.fc4_types[0]);
@@ -1602,7 +1582,7 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                }
        } else
                lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
-                                "3065 GFT_ID failed x%08x\n", irsp->ulpStatus);
+                                "3065 GFT_ID failed x%08x\n", ulp_status);
 
 out:
        lpfc_ct_free_iocb(phba, cmdiocb);
@@ -1616,12 +1596,13 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        struct lpfc_vport *vport = cmdiocb->vport;
        struct lpfc_dmabuf *inp;
        struct lpfc_dmabuf *outp;
-       IOCB_t *irsp;
        struct lpfc_sli_ct_request *CTrsp;
        struct lpfc_nodelist *ndlp;
        int cmdcode, rc;
        uint8_t retry;
        uint32_t latt;
+       u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
+       u32 ulp_word4 = get_job_word4(phba, rspiocb);
 
        /* First save ndlp, before we overwrite it */
        ndlp = cmdiocb->context_un.ndlp;
@@ -1631,7 +1612,6 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 
        inp = (struct lpfc_dmabuf *) cmdiocb->context1;
        outp = (struct lpfc_dmabuf *) cmdiocb->context2;
-       irsp = &rspiocb->iocb;
 
        cmdcode = be16_to_cpu(((struct lpfc_sli_ct_request *) inp->virt)->
                                        CommandResponse.bits.CmdRsp);
@@ -1639,28 +1619,28 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 
        latt = lpfc_els_chk_latt(vport);
 
-       /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */
+       /* RFT request completes status <ulp_status> CmdRsp <CmdRsp> */
        lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
                         "0209 CT Request completes, latt %d, "
-                        "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n",
-                        latt, irsp->ulpStatus,
+                        "ulp_status x%x CmdRsp x%x, Context x%x, Tag x%x\n",
+                        latt, ulp_status,
                         CTrsp->CommandResponse.bits.CmdRsp,
-                        cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag);
+                        get_job_ulpcontext(phba, cmdiocb), cmdiocb->iotag);
 
        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
                "CT cmd cmpl:     status:x%x/x%x cmd:x%x",
-               irsp->ulpStatus, irsp->un.ulpWord[4], cmdcode);
+               ulp_status, ulp_word4, cmdcode);
 
-       if (irsp->ulpStatus) {
+       if (ulp_status) {
                lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
                                 "0268 NS cmd x%x Error (x%x x%x)\n",
-                                cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4]);
+                                cmdcode, ulp_status, ulp_word4);
 
-               if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
-                       (((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
-                         IOERR_SLI_DOWN) ||
-                        ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
-                         IOERR_SLI_ABORTED)))
+               if (ulp_status == IOSTAT_LOCAL_REJECT &&
+                   (((ulp_word4 & IOERR_PARAM_MASK) ==
+                     IOERR_SLI_DOWN) ||
+                    ((ulp_word4 & IOERR_PARAM_MASK) ==
+                     IOERR_SLI_ABORTED)))
                        goto out;
 
                retry = cmdiocb->retry;
@@ -1685,10 +1665,10 @@ static void
 lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        struct lpfc_iocbq *rspiocb)
 {
-       IOCB_t *irsp = &rspiocb->iocb;
        struct lpfc_vport *vport = cmdiocb->vport;
+       u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
 
-       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+       if (ulp_status == IOSTAT_SUCCESS) {
                struct lpfc_dmabuf *outp;
                struct lpfc_sli_ct_request *CTrsp;
 
@@ -1706,10 +1686,10 @@ static void
 lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        struct lpfc_iocbq *rspiocb)
 {
-       IOCB_t *irsp = &rspiocb->iocb;
        struct lpfc_vport *vport = cmdiocb->vport;
+       u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
 
-       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+       if (ulp_status == IOSTAT_SUCCESS) {
                struct lpfc_dmabuf *outp;
                struct lpfc_sli_ct_request *CTrsp;
 
@@ -1727,10 +1707,10 @@ static void
 lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                         struct lpfc_iocbq *rspiocb)
 {
-       IOCB_t *irsp = &rspiocb->iocb;
        struct lpfc_vport *vport = cmdiocb->vport;
+       u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
 
-       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+       if (ulp_status == IOSTAT_SUCCESS) {
                struct lpfc_dmabuf *outp;
                struct lpfc_sli_ct_request *CTrsp;
 
@@ -1748,10 +1728,10 @@ static void
 lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                         struct lpfc_iocbq *rspiocb)
 {
-       IOCB_t *irsp = &rspiocb->iocb;
        struct lpfc_vport *vport = cmdiocb->vport;
+       u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
 
-       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+       if (ulp_status == IOSTAT_SUCCESS) {
                struct lpfc_dmabuf *outp;
                struct lpfc_sli_ct_request *CTrsp;
 
@@ -1781,10 +1761,10 @@ static void
 lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        struct lpfc_iocbq *rspiocb)
 {
-       IOCB_t *irsp = &rspiocb->iocb;
        struct lpfc_vport *vport = cmdiocb->vport;
+       u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
 
-       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+       if (ulp_status == IOSTAT_SUCCESS) {
                struct lpfc_dmabuf *outp;
                struct lpfc_sli_ct_request *CTrsp;
 
@@ -2195,20 +2175,21 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        struct lpfc_sli_ct_request *CTrsp = outp->virt;
        uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
        uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;
-       IOCB_t *irsp = &rspiocb->iocb;
        struct lpfc_nodelist *ndlp, *free_ndlp = NULL;
        uint32_t latt, cmd, err;
+       u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
+       u32 ulp_word4 = get_job_word4(phba, rspiocb);
 
        latt = lpfc_els_chk_latt(vport);
        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
                "FDMI cmpl:       status:x%x/x%x latt:%d",
-               irsp->ulpStatus, irsp->un.ulpWord[4], latt);
+               ulp_status, ulp_word4, latt);
 
-       if (latt || irsp->ulpStatus) {
+       if (latt || ulp_status) {
 
                /* Look for a retryable error */
-               if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
-                       switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) {
+               if (ulp_status == IOSTAT_LOCAL_REJECT) {
+                       switch ((ulp_word4 & IOERR_PARAM_MASK)) {
                        case IOERR_SLI_ABORTED:
                        case IOERR_SLI_DOWN:
                                /* Driver aborted this IO.  No retry as error
@@ -2238,9 +2219,9 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 
                lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
                                 "0229 FDMI cmd %04x failed, latt = %d "
-                                "ulpStatus: x%x, rid x%x\n",
-                                be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus,
-                                irsp->un.ulpWord[4]);
+                                "ulp_status: x%x, rid x%x\n",
+                                be16_to_cpu(fdmi_cmd), latt, ulp_status,
+                                ulp_word4);
        }
 
        free_ndlp = cmdiocb->context_un.ndlp;
index 89a0f8cea1ff870ff5459cad4b6afa541937eb71..8c031fc8891d71af2465a0c183fb6abb45398ac6 100644 (file)
@@ -1255,20 +1255,15 @@ __lpfc_sli_get_els_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq)
        struct lpfc_sglq *start_sglq = NULL;
        struct lpfc_io_buf *lpfc_cmd;
        struct lpfc_nodelist *ndlp;
-       struct lpfc_sli_ring *pring = NULL;
        int found = 0;
+       u8 cmnd;
 
-       if (piocbq->cmd_flag & LPFC_IO_NVME_LS)
-               pring =  phba->sli4_hba.nvmels_wq->pring;
-       else
-               pring = lpfc_phba_elsring(phba);
-
-       lockdep_assert_held(&pring->ring_lock);
+       cmnd = get_job_cmnd(phba, piocbq);
 
        if (piocbq->cmd_flag &  LPFC_IO_FCP) {
                lpfc_cmd = (struct lpfc_io_buf *) piocbq->context1;
                ndlp = lpfc_cmd->rdata->pnode;
-       } else  if ((piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) &&
+       } else  if ((cmnd == CMD_GEN_REQUEST64_CR) &&
                        !(piocbq->cmd_flag & LPFC_IO_LIBDFC)) {
                ndlp = piocbq->context_un.ndlp;
        } else  if (piocbq->cmd_flag & LPFC_IO_LIBDFC) {
@@ -3367,6 +3362,56 @@ lpfc_complete_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        return 0;
 }
 
+static void
+lpfc_sli_prep_unsol_wqe(struct lpfc_hba *phba,
+                       struct lpfc_iocbq *saveq)
+{
+       IOCB_t *irsp;
+       union lpfc_wqe128 *wqe;
+       u16 i = 0;
+
+       irsp = &saveq->iocb;
+       wqe = &saveq->wqe;
+
+       /* Fill wcqe with the IOCB status fields */
+       bf_set(lpfc_wcqe_c_status, &saveq->wcqe_cmpl, irsp->ulpStatus);
+       saveq->wcqe_cmpl.word3 = irsp->ulpBdeCount;
+       saveq->wcqe_cmpl.parameter = irsp->un.ulpWord[4];
+       saveq->wcqe_cmpl.total_data_placed = irsp->unsli3.rcvsli3.acc_len;
+
+       /* Source ID */
+       bf_set(els_rsp64_sid, &wqe->xmit_els_rsp, irsp->un.rcvels.parmRo);
+
+       /* rx-id of the response frame */
+       bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com, irsp->ulpContext);
+
+       /* ox-id of the frame */
+       bf_set(wqe_rcvoxid, &wqe->xmit_els_rsp.wqe_com,
+              irsp->unsli3.rcvsli3.ox_id);
+
+       /* DID */
+       bf_set(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest,
+              irsp->un.rcvels.remoteID);
+
+       /* unsol data len */
+       for (i = 0; i < irsp->ulpBdeCount; i++) {
+               struct lpfc_hbq_entry *hbqe = NULL;
+
+               if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
+                       if (i == 0) {
+                               hbqe = (struct lpfc_hbq_entry *)
+                                       &irsp->un.ulpWord[0];
+                               saveq->wqe.gen_req.bde.tus.f.bdeSize =
+                                       hbqe->bde.tus.f.bdeSize;
+                       } else if (i == 1) {
+                               hbqe = (struct lpfc_hbq_entry *)
+                                       &irsp->unsli3.sli3Words[4];
+                               saveq->unsol_rcv_len = hbqe->bde.tus.f.bdeSize;
+                       }
+               }
+       }
+}
+
 /**
  * lpfc_sli_process_unsol_iocb - Unsolicited iocb handler
  * @phba: Pointer to HBA context object.
@@ -3387,11 +3432,13 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 {
        IOCB_t           * irsp;
        WORD5            * w5p;
+       dma_addr_t       paddr;
        uint32_t           Rctl, Type;
        struct lpfc_iocbq *iocbq;
        struct lpfc_dmabuf *dmzbuf;
 
-       irsp = &(saveq->iocb);
+       irsp = &saveq->iocb;
+       saveq->vport = phba->pport;
 
        if (irsp->ulpCommand == CMD_ASYNC_STATUS) {
                if (pring->lpfc_sli_rcv_async_status)
@@ -3409,22 +3456,22 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        }
 
        if ((irsp->ulpCommand == CMD_IOCB_RET_XRI64_CX) &&
-               (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) {
+           (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) {
                if (irsp->ulpBdeCount > 0) {
                        dmzbuf = lpfc_sli_get_buff(phba, pring,
-                                       irsp->un.ulpWord[3]);
+                                                  irsp->un.ulpWord[3]);
                        lpfc_in_buf_free(phba, dmzbuf);
                }
 
                if (irsp->ulpBdeCount > 1) {
                        dmzbuf = lpfc_sli_get_buff(phba, pring,
-                                       irsp->unsli3.sli3Words[3]);
+                                                  irsp->unsli3.sli3Words[3]);
                        lpfc_in_buf_free(phba, dmzbuf);
                }
 
                if (irsp->ulpBdeCount > 2) {
                        dmzbuf = lpfc_sli_get_buff(phba, pring,
-                               irsp->unsli3.sli3Words[7]);
+                                                  irsp->unsli3.sli3Words[7]);
                        lpfc_in_buf_free(phba, dmzbuf);
                }
 
@@ -3457,9 +3504,10 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                                        irsp->unsli3.sli3Words[7]);
                }
                list_for_each_entry(iocbq, &saveq->list, list) {
-                       irsp = &(iocbq->iocb);
+                       irsp = &iocbq->iocb;
                        if (irsp->ulpBdeCount != 0) {
-                               iocbq->context2 = lpfc_sli_get_buff(phba, pring,
+                               iocbq->context2 = lpfc_sli_get_buff(phba,
+                                                       pring,
                                                        irsp->un.ulpWord[3]);
                                if (!iocbq->context2)
                                        lpfc_printf_log(phba,
@@ -3471,7 +3519,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                                                irsp->un.ulpWord[3]);
                        }
                        if (irsp->ulpBdeCount == 2) {
-                               iocbq->context3 = lpfc_sli_get_buff(phba, pring,
+                               iocbq->context3 = lpfc_sli_get_buff(phba,
+                                               pring,
                                                irsp->unsli3.sli3Words[7]);
                                if (!iocbq->context3)
                                        lpfc_printf_log(phba,
@@ -3484,7 +3533,20 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                                                irsp->unsli3.sli3Words[7]);
                        }
                }
+       } else {
+               paddr = getPaddr(irsp->un.cont64[0].addrHigh,
+                                irsp->un.cont64[0].addrLow);
+               saveq->context2 = lpfc_sli_ringpostbuf_get(phba, pring,
+                                                            paddr);
+               if (irsp->ulpBdeCount == 2) {
+                       paddr = getPaddr(irsp->un.cont64[1].addrHigh,
+                                        irsp->un.cont64[1].addrLow);
+                       saveq->context3 = lpfc_sli_ringpostbuf_get(phba,
+                                                                  pring,
+                                                                  paddr);
+               }
        }
+
        if (irsp->ulpBdeCount != 0 &&
            (irsp->ulpCommand == CMD_IOCB_RCV_CONT64_CX ||
             irsp->ulpStatus == IOSTAT_INTERMED_RSP)) {
@@ -3502,12 +3564,14 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                if (!found)
                        list_add_tail(&saveq->clist,
                                      &pring->iocb_continue_saveq);
+
                if (saveq->iocb.ulpStatus != IOSTAT_INTERMED_RSP) {
                        list_del_init(&iocbq->clist);
                        saveq = iocbq;
-                       irsp = &(saveq->iocb);
-               } else
+                       irsp = &saveq->iocb;
+               } else {
                        return 0;
+               }
        }
        if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX) ||
            (irsp->ulpCommand == CMD_RCV_ELS_REQ_CX) ||
@@ -3530,6 +3594,19 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                }
        }
 
+       if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
+           (irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX ||
+           irsp->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
+               if (irsp->unsli3.rcvsli3.vpi == 0xffff)
+                       saveq->vport = phba->pport;
+               else
+                       saveq->vport = lpfc_find_vport_by_vpid(phba,
+                                              irsp->unsli3.rcvsli3.vpi);
+       }
+
+       /* Prepare WQE with Unsol frame */
+       lpfc_sli_prep_unsol_wqe(phba, saveq);
+
        if (!lpfc_complete_unsol_iocb(phba, pring, saveq, Rctl, Type))
                lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
                                "0313 Ring %d handler: unexpected Rctl x%x "
@@ -10570,6 +10647,195 @@ lpfc_sli_prep_els_req_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocbq,
                                          elscmd, tmo, expect_rsp);
 }
 
+static void
+__lpfc_sli_prep_gen_req_s3(struct lpfc_iocbq *cmdiocbq, struct lpfc_dmabuf *bmp,
+                          u16 rpi, u32 num_entry, u8 tmo)
+{
+       IOCB_t *cmd;
+
+       cmd = &cmdiocbq->iocb;
+       memset(cmd, 0, sizeof(*cmd));
+
+       cmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
+       cmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
+       cmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
+       cmd->un.genreq64.bdl.bdeSize = num_entry * sizeof(struct ulp_bde64);
+
+       cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
+       cmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
+       cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
+
+       cmd->ulpContext = rpi;
+       cmd->ulpClass = CLASS3;
+       cmd->ulpCommand = CMD_GEN_REQUEST64_CR;
+       cmd->ulpBdeCount = 1;
+       cmd->ulpLe = 1;
+       cmd->ulpOwner = OWN_CHIP;
+       cmd->ulpTimeout = tmo;
+}
+
+static void
+__lpfc_sli_prep_gen_req_s4(struct lpfc_iocbq *cmdiocbq, struct lpfc_dmabuf *bmp,
+                          u16 rpi, u32 num_entry, u8 tmo)
+{
+       union lpfc_wqe128 *cmdwqe;
+       struct ulp_bde64_le *bde, *bpl;
+       u32 xmit_len = 0, total_len = 0, size, type, i;
+
+       cmdwqe = &cmdiocbq->wqe;
+       memset(cmdwqe, 0, sizeof(*cmdwqe));
+
+       /* Calculate total_len and xmit_len */
+       bpl = (struct ulp_bde64_le *)bmp->virt;
+       for (i = 0; i < num_entry; i++) {
+               size = le32_to_cpu(bpl[i].type_size) & ULP_BDE64_SIZE_MASK;
+               total_len += size;
+       }
+       for (i = 0; i < num_entry; i++) {
+               size = le32_to_cpu(bpl[i].type_size) & ULP_BDE64_SIZE_MASK;
+               type = le32_to_cpu(bpl[i].type_size) & ULP_BDE64_TYPE_MASK;
+               if (type != ULP_BDE64_TYPE_BDE_64)
+                       break;
+               xmit_len += size;
+       }
+
+       /* Words 0 - 2 */
+       bde = (struct ulp_bde64_le *)&cmdwqe->generic.bde;
+       bde->addr_low = cpu_to_le32(putPaddrLow(bmp->phys));
+       bde->addr_high = cpu_to_le32(putPaddrHigh(bmp->phys));
+       bde->type_size = cpu_to_le32(xmit_len);
+       bde->type_size |= cpu_to_le32(ULP_BDE64_TYPE_BLP_64);
+
+       /* Word 3 */
+       cmdwqe->gen_req.request_payload_len = xmit_len;
+
+       /* Word 5 */
+       bf_set(wqe_type, &cmdwqe->gen_req.wge_ctl, FC_TYPE_CT);
+       bf_set(wqe_rctl, &cmdwqe->gen_req.wge_ctl, FC_RCTL_DD_UNSOL_CTL);
+       bf_set(wqe_si, &cmdwqe->gen_req.wge_ctl, 1);
+       bf_set(wqe_la, &cmdwqe->gen_req.wge_ctl, 1);
+
+       /* Word 6 */
+       bf_set(wqe_ctxt_tag, &cmdwqe->gen_req.wqe_com, rpi);
+
+       /* Word 7 */
+       bf_set(wqe_tmo, &cmdwqe->gen_req.wqe_com, tmo);
+       bf_set(wqe_class, &cmdwqe->gen_req.wqe_com, CLASS3);
+       bf_set(wqe_cmnd, &cmdwqe->gen_req.wqe_com, CMD_GEN_REQUEST64_CR);
+       bf_set(wqe_ct, &cmdwqe->gen_req.wqe_com, SLI4_CT_RPI);
+
+       /* Word 12 */
+       cmdwqe->gen_req.max_response_payload_len = total_len - xmit_len;
+}
+
+void
+lpfc_sli_prep_gen_req(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocbq,
+                     struct lpfc_dmabuf *bmp, u16 rpi, u32 num_entry, u8 tmo)
+{
+       phba->__lpfc_sli_prep_gen_req(cmdiocbq, bmp, rpi, num_entry, tmo);
+}
+
+static void
+__lpfc_sli_prep_xmit_seq64_s3(struct lpfc_iocbq *cmdiocbq,
+                             struct lpfc_dmabuf *bmp, u16 rpi, u16 ox_id,
+                             u32 num_entry, u8 rctl, u8 last_seq, u8 cr_cx_cmd)
+{
+       IOCB_t *icmd;
+
+       icmd = &cmdiocbq->iocb;
+       memset(icmd, 0, sizeof(*icmd));
+
+       icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
+       icmd->un.xseq64.bdl.addrLow = putPaddrLow(bmp->phys);
+       icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
+       icmd->un.xseq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64));
+       icmd->un.xseq64.w5.hcsw.Fctl = LA;
+       if (last_seq)
+               icmd->un.xseq64.w5.hcsw.Fctl |= LS;
+       icmd->un.xseq64.w5.hcsw.Dfctl = 0;
+       icmd->un.xseq64.w5.hcsw.Rctl = rctl;
+       icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_CT;
+
+       icmd->ulpBdeCount = 1;
+       icmd->ulpLe = 1;
+       icmd->ulpClass = CLASS3;
+
+       switch (cr_cx_cmd) {
+       case CMD_XMIT_SEQUENCE64_CR:
+               icmd->ulpContext = rpi;
+               icmd->ulpCommand = CMD_XMIT_SEQUENCE64_CR;
+               break;
+       case CMD_XMIT_SEQUENCE64_CX:
+               icmd->ulpContext = ox_id;
+               icmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX;
+               break;
+       default:
+               break;
+       }
+}
+
+static void
+__lpfc_sli_prep_xmit_seq64_s4(struct lpfc_iocbq *cmdiocbq,
+                             struct lpfc_dmabuf *bmp, u16 rpi, u16 ox_id,
+                             u32 full_size, u8 rctl, u8 last_seq, u8 cr_cx_cmd)
+{
+       union lpfc_wqe128 *wqe;
+       struct ulp_bde64 *bpl;
+       struct ulp_bde64_le *bde;
+
+       wqe = &cmdiocbq->wqe;
+       memset(wqe, 0, sizeof(*wqe));
+
+       /* Words 0 - 2 */
+       bpl = (struct ulp_bde64 *)bmp->virt;
+       if (cmdiocbq->cmd_flag & (LPFC_IO_LIBDFC | LPFC_IO_LOOPBACK)) {
+               wqe->xmit_sequence.bde.addrHigh = bpl->addrHigh;
+               wqe->xmit_sequence.bde.addrLow = bpl->addrLow;
+               wqe->xmit_sequence.bde.tus.w = bpl->tus.w;
+       } else {
+               bde = (struct ulp_bde64_le *)&wqe->xmit_sequence.bde;
+               bde->addr_low = cpu_to_le32(putPaddrLow(bmp->phys));
+               bde->addr_high = cpu_to_le32(putPaddrHigh(bmp->phys));
+               bde->type_size = cpu_to_le32(bpl->tus.f.bdeSize);
+               bde->type_size |= cpu_to_le32(ULP_BDE64_TYPE_BDE_64);
+       }
+
+       /* Word 5 */
+       bf_set(wqe_ls, &wqe->xmit_sequence.wge_ctl, last_seq);
+       bf_set(wqe_la, &wqe->xmit_sequence.wge_ctl, 1);
+       bf_set(wqe_dfctl, &wqe->xmit_sequence.wge_ctl, 0);
+       bf_set(wqe_rctl, &wqe->xmit_sequence.wge_ctl, rctl);
+       bf_set(wqe_type, &wqe->xmit_sequence.wge_ctl, FC_TYPE_CT);
+
+       /* Word 6 */
+       bf_set(wqe_ctxt_tag, &wqe->xmit_sequence.wqe_com, rpi);
+
+       bf_set(wqe_cmnd, &wqe->xmit_sequence.wqe_com,
+              CMD_XMIT_SEQUENCE64_WQE);
+
+       /* Word 7 */
+       bf_set(wqe_class, &wqe->xmit_sequence.wqe_com, CLASS3);
+
+       /* Word 9 */
+       bf_set(wqe_rcvoxid, &wqe->xmit_sequence.wqe_com, ox_id);
+
+       /* Word 12 */
+       if (cmdiocbq->cmd_flag & (LPFC_IO_LIBDFC | LPFC_IO_LOOPBACK))
+               wqe->xmit_sequence.xmit_len = full_size;
+       else
+               wqe->xmit_sequence.xmit_len =
+                       wqe->xmit_sequence.bde.tus.f.bdeSize;
+}
+
+void
+lpfc_sli_prep_xmit_seq64(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocbq,
+                        struct lpfc_dmabuf *bmp, u16 rpi, u16 ox_id,
+                        u32 num_entry, u8 rctl, u8 last_seq, u8 cr_cx_cmd)
+{
+       phba->__lpfc_sli_prep_xmit_seq64(cmdiocbq, bmp, rpi, ox_id, num_entry,
+                                        rctl, last_seq, cr_cx_cmd);
+}
+
 /**
  * lpfc_sli_api_table_setup - Set up sli api function jump table
  * @phba: The hba struct for which this call is being executed.
@@ -10589,12 +10855,16 @@ lpfc_sli_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
                phba->__lpfc_sli_release_iocbq = __lpfc_sli_release_iocbq_s3;
                phba->__lpfc_sli_issue_fcp_io = __lpfc_sli_issue_fcp_io_s3;
                phba->__lpfc_sli_prep_els_req_rsp = __lpfc_sli_prep_els_req_rsp_s3;
+               phba->__lpfc_sli_prep_gen_req = __lpfc_sli_prep_gen_req_s3;
+               phba->__lpfc_sli_prep_xmit_seq64 = __lpfc_sli_prep_xmit_seq64_s3;
                break;
        case LPFC_PCI_DEV_OC:
                phba->__lpfc_sli_issue_iocb = __lpfc_sli_issue_iocb_s4;
                phba->__lpfc_sli_release_iocbq = __lpfc_sli_release_iocbq_s4;
                phba->__lpfc_sli_issue_fcp_io = __lpfc_sli_issue_fcp_io_s4;
                phba->__lpfc_sli_prep_els_req_rsp = __lpfc_sli_prep_els_req_rsp_s4;
+               phba->__lpfc_sli_prep_gen_req = __lpfc_sli_prep_gen_req_s4;
+               phba->__lpfc_sli_prep_xmit_seq64 = __lpfc_sli_prep_xmit_seq64_s4;
                break;
        default:
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -18469,7 +18739,6 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
        struct fc_frame_header *fc_hdr;
        uint32_t sid;
        uint32_t len, tot_len;
-       struct ulp_bde64 *pbde;
 
        fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt;
        /* remove from receive buffer list */
@@ -18482,40 +18751,40 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
        first_iocbq = lpfc_sli_get_iocbq(vport->phba);
        if (first_iocbq) {
                /* Initialize the first IOCB. */
-               first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0;
-               first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS;
+               first_iocbq->wcqe_cmpl.total_data_placed = 0;
+               bf_set(lpfc_wcqe_c_status, &first_iocbq->wcqe_cmpl,
+                      IOSTAT_SUCCESS);
                first_iocbq->vport = vport;
 
                /* Check FC Header to see what TYPE of frame we are rcv'ing */
                if (sli4_type_from_fc_hdr(fc_hdr) == FC_TYPE_ELS) {
-                       first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_ELS64_CX;
-                       first_iocbq->iocb.un.rcvels.parmRo =
-                               sli4_did_from_fc_hdr(fc_hdr);
-                       first_iocbq->iocb.ulpPU = PARM_NPIV_DID;
-               } else
-                       first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX;
-               first_iocbq->iocb.ulpContext = NO_XRI;
-               first_iocbq->iocb.unsli3.rcvsli3.ox_id =
-                       be16_to_cpu(fc_hdr->fh_ox_id);
-               /* iocbq is prepped for internal consumption.  Physical vpi. */
-               first_iocbq->iocb.unsli3.rcvsli3.vpi =
-                       vport->phba->vpi_ids[vport->vpi];
-               /* put the first buffer into the first IOCBq */
+                       bf_set(els_rsp64_sid, &first_iocbq->wqe.xmit_els_rsp,
+                              sli4_did_from_fc_hdr(fc_hdr));
+               }
+
+               bf_set(wqe_ctxt_tag, &first_iocbq->wqe.xmit_els_rsp.wqe_com,
+                      NO_XRI);
+               bf_set(wqe_rcvoxid, &first_iocbq->wqe.xmit_els_rsp.wqe_com,
+                      be16_to_cpu(fc_hdr->fh_ox_id));
+
+               /* put the first buffer into the first iocb */
                tot_len = bf_get(lpfc_rcqe_length,
-                                      &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
+                                &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
 
                first_iocbq->context2 = &seq_dmabuf->dbuf;
                first_iocbq->context3 = NULL;
-               first_iocbq->iocb.ulpBdeCount = 1;
+               /* Keep track of the BDE count */
+               first_iocbq->wcqe_cmpl.word3 = 1;
+
                if (tot_len > LPFC_DATA_BUF_SIZE)
-                       first_iocbq->iocb.un.cont64[0].tus.f.bdeSize =
-                                                       LPFC_DATA_BUF_SIZE;
+                       first_iocbq->wqe.gen_req.bde.tus.f.bdeSize =
+                               LPFC_DATA_BUF_SIZE;
                else
-                       first_iocbq->iocb.un.cont64[0].tus.f.bdeSize = tot_len;
+                       first_iocbq->wqe.gen_req.bde.tus.f.bdeSize = tot_len;
 
-               first_iocbq->iocb.un.rcvels.remoteID = sid;
-
-               first_iocbq->iocb.unsli3.rcvsli3.acc_len = tot_len;
+               first_iocbq->wcqe_cmpl.total_data_placed = tot_len;
+               bf_set(wqe_els_did, &first_iocbq->wqe.xmit_els_rsp.wqe_dest,
+                      sid);
        }
        iocbq = first_iocbq;
        /*
@@ -18529,28 +18798,23 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
                }
                if (!iocbq->context3) {
                        iocbq->context3 = d_buf;
-                       iocbq->iocb.ulpBdeCount++;
+                       iocbq->wcqe_cmpl.word3++;
                        /* We need to get the size out of the right CQE */
                        hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
                        len = bf_get(lpfc_rcqe_length,
                                       &hbq_buf->cq_event.cqe.rcqe_cmpl);
-                       pbde = (struct ulp_bde64 *)
-                                       &iocbq->iocb.unsli3.sli3Words[4];
-                       if (len > LPFC_DATA_BUF_SIZE)
-                               pbde->tus.f.bdeSize = LPFC_DATA_BUF_SIZE;
-                       else
-                               pbde->tus.f.bdeSize = len;
-
-                       iocbq->iocb.unsli3.rcvsli3.acc_len += len;
+                       iocbq->unsol_rcv_len = len;
+                       iocbq->wcqe_cmpl.total_data_placed += len;
                        tot_len += len;
                } else {
                        iocbq = lpfc_sli_get_iocbq(vport->phba);
                        if (!iocbq) {
                                if (first_iocbq) {
-                                       first_iocbq->iocb.ulpStatus =
-                                                       IOSTAT_FCP_RSP_ERROR;
-                                       first_iocbq->iocb.un.ulpWord[4] =
-                                                       IOERR_NO_RESOURCES;
+                                       bf_set(lpfc_wcqe_c_status,
+                                              &first_iocbq->wcqe_cmpl,
+                                              IOSTAT_SUCCESS);
+                                       first_iocbq->wcqe_cmpl.parameter =
+                                               IOERR_NO_RESOURCES;
                                }
                                lpfc_in_buf_free(vport->phba, d_buf);
                                continue;
@@ -18561,17 +18825,19 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
                                       &hbq_buf->cq_event.cqe.rcqe_cmpl);
                        iocbq->context2 = d_buf;
                        iocbq->context3 = NULL;
-                       iocbq->iocb.ulpBdeCount = 1;
+                       iocbq->wcqe_cmpl.word3 = 1;
+
                        if (len > LPFC_DATA_BUF_SIZE)
-                               iocbq->iocb.un.cont64[0].tus.f.bdeSize =
-                                                       LPFC_DATA_BUF_SIZE;
+                               iocbq->wqe.xmit_els_rsp.bde.tus.f.bdeSize =
+                                       LPFC_DATA_BUF_SIZE;
                        else
-                               iocbq->iocb.un.cont64[0].tus.f.bdeSize = len;
+                               iocbq->wqe.xmit_els_rsp.bde.tus.f.bdeSize =
+                                       len;
 
                        tot_len += len;
-                       iocbq->iocb.unsli3.rcvsli3.acc_len = tot_len;
-
-                       iocbq->iocb.un.rcvels.remoteID = sid;
+                       iocbq->wcqe_cmpl.total_data_placed = tot_len;
+                       bf_set(wqe_els_did, &iocbq->wqe.xmit_els_rsp.wqe_dest,
+                              sid);
                        list_add_tail(&iocbq->list, &first_iocbq->list);
                }
        }
index 06682ad8bbe15434a68813c4f20ad4dd96ba8f10..9f5b6574e63832f82a4bc737a2e7e030466f52bd 100644 (file)
@@ -75,6 +75,7 @@ struct lpfc_iocbq {
        IOCB_t iocb;            /* SLI-3 */
        struct lpfc_wcqe_complete wcqe_cmpl;    /* WQE cmpl */
 
+       u32 unsol_rcv_len;      /* Receive len in usol path */
        uint8_t num_bdes;
        uint8_t abort_bls;      /* ABTS by initiator or responder */