diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_ct.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 366 |
1 files changed, 246 insertions, 120 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 4b024aa03c1b..9d36b20fb878 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -118,22 +118,22 @@ lpfc_ct_unsol_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp; struct lpfc_dmabuf *mp, *bmp; - ndlp = (struct lpfc_nodelist *)cmdiocb->context1; + ndlp = cmdiocb->ndlp; if (ndlp) lpfc_nlp_put(ndlp); - mp = cmdiocb->context2; - bmp = cmdiocb->context3; + mp = cmdiocb->rsp_dmabuf; + bmp = cmdiocb->bpl_dmabuf; if (mp) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); - cmdiocb->context2 = NULL; + cmdiocb->rsp_dmabuf = NULL; } if (bmp) { lpfc_mbuf_free(phba, bmp->virt, bmp->phys); kfree(bmp); - cmdiocb->context3 = NULL; + cmdiocb->bpl_dmabuf = NULL; } lpfc_sli_release_iocbq(phba, cmdiocb); @@ -232,18 +232,17 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp, } /* Save for completion so we can release these resources */ - cmdiocbq->context2 = (uint8_t *)mp; - cmdiocbq->context3 = (uint8_t *)bmp; + cmdiocbq->rsp_dmabuf = mp; + cmdiocbq->bpl_dmabuf = bmp; cmdiocbq->cmd_cmpl = lpfc_ct_unsol_cmpl; tmo = (3 * phba->fc_ratov); cmdiocbq->retry = 0; cmdiocbq->vport = vport; - cmdiocbq->context_un.ndlp = NULL; cmdiocbq->drvrTimeout = tmo + LPFC_DRVR_TIMEOUT; - cmdiocbq->context1 = lpfc_nlp_get(ndlp); - if (!cmdiocbq->context1) + cmdiocbq->ndlp = lpfc_nlp_get(ndlp); + if (!cmdiocbq->ndlp) goto ct_no_ndlp; rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0); @@ -310,8 +309,8 @@ lpfc_ct_handle_mibreq(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocbq) return; } - ct_req = ((struct lpfc_sli_ct_request *) - (((struct lpfc_dmabuf *)ctiocbq->context2)->virt)); + ct_req = (struct lpfc_sli_ct_request *)ctiocbq->cmd_dmabuf->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); @@ -347,14 +346,14 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, 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; + struct lpfc_dmabuf *bdeBuf1 = ctiocbq->cmd_dmabuf; + struct lpfc_dmabuf *bdeBuf2 = ctiocbq->bpl_dmabuf; u32 status, parameter, bde_count = 0; struct lpfc_wcqe_complete *wcqe_cmpl = NULL; - ctiocbq->context1 = NULL; - ctiocbq->context2 = NULL; - ctiocbq->context3 = NULL; + ctiocbq->cmd_dmabuf = NULL; + ctiocbq->rsp_dmabuf = NULL; + ctiocbq->bpl_dmabuf = NULL; wcqe_cmpl = &ctiocbq->wcqe_cmpl; status = get_job_ulpstatus(phba, ctiocbq); @@ -382,12 +381,11 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, if (bde_count == 0) return; - ctiocbq->context2 = bdeBuf1; + ctiocbq->cmd_dmabuf = bdeBuf1; if (bde_count == 2) - ctiocbq->context3 = bdeBuf2; + ctiocbq->bpl_dmabuf = bdeBuf2; - ct_req = ((struct lpfc_sli_ct_request *) - (((struct lpfc_dmabuf *)ctiocbq->context2)->virt)); + ct_req = (struct lpfc_sli_ct_request *)ctiocbq->cmd_dmabuf->virt; if (ct_req->FsType == SLI_CT_MANAGEMENT_SERVICE && ct_req->FsSubType == SLI_CT_MIB_Subtypes) { @@ -408,8 +406,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, if (!bde_count) continue; - bdeBuf1 = iocb->context2; - iocb->context2 = NULL; + bdeBuf1 = iocb->cmd_dmabuf; + iocb->cmd_dmabuf = NULL; if (phba->sli_rev == LPFC_SLI_REV4) size = iocb->wqe.gen_req.bde.tus.f.bdeSize; else @@ -417,8 +415,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, lpfc_ct_unsol_buffer(phba, ctiocbq, bdeBuf1, size); lpfc_in_buf_free(phba, bdeBuf1); if (bde_count == 2) { - bdeBuf2 = iocb->context3; - iocb->context3 = NULL; + bdeBuf2 = iocb->bpl_dmabuf; + iocb->bpl_dmabuf = NULL; if (phba->sli_rev == LPFC_SLI_REV4) size = iocb->unsol_rcv_len; else @@ -549,24 +547,25 @@ lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb) { struct lpfc_dmabuf *buf_ptr; - /* I/O job is complete so context is now invalid*/ - ctiocb->context_un.ndlp = NULL; - if (ctiocb->context1) { - buf_ptr = (struct lpfc_dmabuf *) ctiocb->context1; + /* IOCBQ job structure gets cleaned during release. Just release + * the dma buffers here. + */ + if (ctiocb->cmd_dmabuf) { + buf_ptr = ctiocb->cmd_dmabuf; lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); kfree(buf_ptr); - ctiocb->context1 = NULL; + ctiocb->cmd_dmabuf = NULL; } - if (ctiocb->context2) { - lpfc_free_ct_rsp(phba, (struct lpfc_dmabuf *) ctiocb->context2); - ctiocb->context2 = NULL; + if (ctiocb->rsp_dmabuf) { + lpfc_free_ct_rsp(phba, ctiocb->rsp_dmabuf); + ctiocb->rsp_dmabuf = NULL; } - if (ctiocb->context3) { - buf_ptr = (struct lpfc_dmabuf *) ctiocb->context3; + if (ctiocb->bpl_dmabuf) { + buf_ptr = ctiocb->bpl_dmabuf; lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); kfree(buf_ptr); - ctiocb->context3 = NULL; + ctiocb->bpl_dmabuf = NULL; } lpfc_sli_release_iocbq(phba, ctiocb); return 0; @@ -605,11 +604,11 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, /* Update the num_entry bde count */ geniocb->num_bdes = num_entry; - geniocb->context3 = (uint8_t *) bmp; + geniocb->bpl_dmabuf = bmp; /* Save for completion so we can release these resources */ - geniocb->context1 = (uint8_t *) inp; - geniocb->context2 = (uint8_t *) outp; + geniocb->cmd_dmabuf = inp; + geniocb->rsp_dmabuf = outp; geniocb->event_tag = event_tag; @@ -635,8 +634,8 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, geniocb->drvrTimeout = tmo + LPFC_DRVR_TIMEOUT; geniocb->vport = vport; geniocb->retry = retry; - geniocb->context_un.ndlp = lpfc_nlp_get(ndlp); - if (!geniocb->context_un.ndlp) + geniocb->ndlp = lpfc_nlp_get(ndlp); + if (!geniocb->ndlp) goto out; rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0); @@ -926,13 +925,12 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, int rc, type; /* First save ndlp, before we overwrite it */ - ndlp = cmdiocb->context_un.ndlp; + ndlp = cmdiocb->ndlp; /* 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; + cmdiocb->rsp_iocb = rspiocb; + inp = cmdiocb->cmd_dmabuf; + outp = cmdiocb->rsp_dmabuf; lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, "GID_FT cmpl: status:x%x/x%x rtry:%d", @@ -962,9 +960,15 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } 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"); + "0226 NS query failed due to link event: " + "ulp_status x%x ulp_word4 x%x fc_flag x%x " + "port_state x%x gidft_inp x%x\n", + ulp_status, ulp_word4, vport->fc_flag, + vport->port_state, vport->gidft_inp); if (vport->fc_flag & FC_RSCN_MODE) lpfc_els_flush_rscn(vport); + if (vport->gidft_inp) + vport->gidft_inp--; goto out; } @@ -1143,12 +1147,12 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, int rc; /* First save ndlp, before we overwrite it */ - ndlp = cmdiocb->context_un.ndlp; + ndlp = cmdiocb->ndlp; /* 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; + cmdiocb->rsp_iocb = rspiocb; + inp = cmdiocb->cmd_dmabuf; + outp = cmdiocb->rsp_dmabuf; lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, "GID_PT cmpl: status:x%x/x%x rtry:%d", @@ -1179,9 +1183,15 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } 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"); + "4166 NS query failed due to link event: " + "ulp_status x%x ulp_word4 x%x fc_flag x%x " + "port_state x%x gidft_inp x%x\n", + ulp_status, ulp_word4, vport->fc_flag, + vport->port_state, vport->gidft_inp); if (vport->fc_flag & FC_RSCN_MODE) lpfc_els_flush_rscn(vport); + if (vport->gidft_inp) + vport->gidft_inp--; goto out; } @@ -1346,8 +1356,8 @@ 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); - struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1; - struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2; + struct lpfc_dmabuf *inp = cmdiocb->cmd_dmabuf; + struct lpfc_dmabuf *outp = cmdiocb->rsp_dmabuf; struct lpfc_sli_ct_request *CTrsp; int did, rc, retry; uint8_t fbits; @@ -1426,7 +1436,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, cmdiocb->retry, did); if (rc == 0) { /* success */ - free_ndlp = cmdiocb->context_un.ndlp; + free_ndlp = cmdiocb->ndlp; lpfc_ct_free_iocb(phba, cmdiocb); lpfc_nlp_put(free_ndlp); return; @@ -1483,7 +1493,7 @@ out: } iocb_free: - free_ndlp = cmdiocb->context_un.ndlp; + free_ndlp = cmdiocb->ndlp; lpfc_ct_free_iocb(phba, cmdiocb); lpfc_nlp_put(free_ndlp); return; @@ -1494,8 +1504,8 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) { struct lpfc_vport *vport = cmdiocb->vport; - struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *)cmdiocb->context1; - struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *)cmdiocb->context2; + struct lpfc_dmabuf *inp = cmdiocb->cmd_dmabuf; + struct lpfc_dmabuf *outp = cmdiocb->rsp_dmabuf; struct lpfc_sli_ct_request *CTrsp; int did; struct lpfc_nodelist *ndlp = NULL; @@ -1519,7 +1529,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; + ns_ndlp = cmdiocb->ndlp; if (ulp_status == IOSTAT_SUCCESS) { /* Good status, continue checking */ @@ -1605,13 +1615,13 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, u32 ulp_word4 = get_job_word4(phba, rspiocb); /* First save ndlp, before we overwrite it */ - ndlp = cmdiocb->context_un.ndlp; + ndlp = cmdiocb->ndlp; /* we pass cmdiocb to state machine which needs rspiocb as well */ - cmdiocb->context_un.rsp_iocb = rspiocb; + cmdiocb->rsp_iocb = rspiocb; - inp = (struct lpfc_dmabuf *) cmdiocb->context1; - outp = (struct lpfc_dmabuf *) cmdiocb->context2; + inp = cmdiocb->cmd_dmabuf; + outp = cmdiocb->rsp_dmabuf; cmdcode = be16_to_cpu(((struct lpfc_sli_ct_request *) inp->virt)-> CommandResponse.bits.CmdRsp); @@ -1672,8 +1682,8 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_dmabuf *outp; struct lpfc_sli_ct_request *CTrsp; - outp = (struct lpfc_dmabuf *) cmdiocb->context2; - CTrsp = (struct lpfc_sli_ct_request *) outp->virt; + outp = cmdiocb->rsp_dmabuf; + CTrsp = (struct lpfc_sli_ct_request *)outp->virt; if (CTrsp->CommandResponse.bits.CmdRsp == be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) vport->ct_flags |= FC_CT_RFT_ID; @@ -1693,7 +1703,7 @@ lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_dmabuf *outp; struct lpfc_sli_ct_request *CTrsp; - outp = (struct lpfc_dmabuf *) cmdiocb->context2; + outp = cmdiocb->rsp_dmabuf; CTrsp = (struct lpfc_sli_ct_request *) outp->virt; if (CTrsp->CommandResponse.bits.CmdRsp == be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) @@ -1714,8 +1724,8 @@ lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_dmabuf *outp; struct lpfc_sli_ct_request *CTrsp; - outp = (struct lpfc_dmabuf *) cmdiocb->context2; - CTrsp = (struct lpfc_sli_ct_request *) outp->virt; + outp = cmdiocb->rsp_dmabuf; + CTrsp = (struct lpfc_sli_ct_request *)outp->virt; if (CTrsp->CommandResponse.bits.CmdRsp == be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) vport->ct_flags |= FC_CT_RSPN_ID; @@ -1735,7 +1745,7 @@ lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_dmabuf *outp; struct lpfc_sli_ct_request *CTrsp; - outp = (struct lpfc_dmabuf *) cmdiocb->context2; + outp = cmdiocb->rsp_dmabuf; CTrsp = (struct lpfc_sli_ct_request *) outp->virt; if (CTrsp->CommandResponse.bits.CmdRsp == be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) @@ -1768,8 +1778,8 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_dmabuf *outp; struct lpfc_sli_ct_request *CTrsp; - outp = (struct lpfc_dmabuf *) cmdiocb->context2; - CTrsp = (struct lpfc_sli_ct_request *) outp->virt; + outp = cmdiocb->rsp_dmabuf; + CTrsp = (struct lpfc_sli_ct_request *)outp->virt; if (CTrsp->CommandResponse.bits.CmdRsp == be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) vport->ct_flags |= FC_CT_RFF_ID; @@ -1865,7 +1875,7 @@ lpfc_get_gidft_type(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb) struct lpfc_dmabuf *mp; uint32_t type; - mp = cmdiocb->context1; + mp = cmdiocb->cmd_dmabuf; if (mp == NULL) return 0; CtReq = (struct lpfc_sli_ct_request *)mp->virt; @@ -2018,28 +2028,30 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, vport->ct_flags &= ~FC_CT_RFT_ID; CtReq->CommandResponse.bits.CmdRsp = cpu_to_be16(SLI_CTNS_RFT_ID); - CtReq->un.rft.PortId = cpu_to_be32(vport->fc_myDID); + CtReq->un.rft.port_id = cpu_to_be32(vport->fc_myDID); + + /* Register Application Services type if vmid enabled. */ + if (phba->cfg_vmid_app_header) + CtReq->un.rft.app_serv_reg = + cpu_to_be32(RFT_APP_SERV_REG); /* Register FC4 FCP type if enabled. */ if (vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH || vport->cfg_enable_fc4_type == LPFC_ENABLE_FCP) - CtReq->un.rft.fcpReg = 1; + CtReq->un.rft.fcp_reg = cpu_to_be32(RFT_FCP_REG); - /* Register NVME type if enabled. Defined LE and swapped. - * rsvd[0] is used as word1 because of the hard-coded - * word0 usage in the ct_request data structure. - */ + /* Register NVME type if enabled. */ if (vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH || vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME) - CtReq->un.rft.rsvd[0] = - cpu_to_be32(LPFC_FC4_TYPE_BITMASK); + CtReq->un.rft.nvme_reg = cpu_to_be32(RFT_NVME_REG); ptr = (uint32_t *)CtReq; lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "6433 Issue RFT (%s %s): %08x %08x %08x %08x " - "%08x %08x %08x %08x\n", - CtReq->un.rft.fcpReg ? "FCP" : " ", - CtReq->un.rft.rsvd[0] ? "NVME" : " ", + "6433 Issue RFT (%s %s %s): %08x %08x %08x " + "%08x %08x %08x %08x %08x\n", + CtReq->un.rft.fcp_reg ? "FCP" : " ", + CtReq->un.rft.nvme_reg ? "NVME" : " ", + CtReq->un.rft.app_serv_reg ? "APPS" : " ", *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3), *(ptr + 4), *(ptr + 5), *(ptr + 6), *(ptr + 7)); @@ -2156,6 +2168,41 @@ ns_cmd_exit: } /** + * lpfc_fdmi_rprt_defer - Check for any deferred FDMI RPRT commands + * @phba: Pointer to HBA context object. + * @mask: Initial port attributes mask + * + * This function checks to see if any vports have deferred their FDMI RPRT. + * A vports RPRT may be deferred if it is issued before the primary ports + * RHBA completes. + */ +static void +lpfc_fdmi_rprt_defer(struct lpfc_hba *phba, uint32_t mask) +{ + struct lpfc_vport **vports; + struct lpfc_vport *vport; + struct lpfc_nodelist *ndlp; + int i; + + phba->hba_flag |= HBA_RHBA_CMPL; + vports = lpfc_create_vport_work_array(phba); + if (vports) { + for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { + vport = vports[i]; + ndlp = lpfc_findnode_did(phba->pport, FDMI_DID); + if (!ndlp) + continue; + if (vport->ct_flags & FC_CT_RPRT_DEFER) { + vport->ct_flags &= ~FC_CT_RPRT_DEFER; + vport->fdmi_port_mask = mask; + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0); + } + } + } + lpfc_destroy_vport_work_array(phba, vports); +} + +/** * lpfc_cmpl_ct_disc_fdmi - Handle a discovery FDMI completion * @phba: Pointer to HBA context object. * @cmdiocb: Pointer to the command IOCBQ. @@ -2169,8 +2216,8 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) { struct lpfc_vport *vport = cmdiocb->vport; - struct lpfc_dmabuf *inp = cmdiocb->context1; - struct lpfc_dmabuf *outp = cmdiocb->context2; + struct lpfc_dmabuf *inp = cmdiocb->cmd_dmabuf; + struct lpfc_dmabuf *outp = cmdiocb->rsp_dmabuf; struct lpfc_sli_ct_request *CTcmd = inp->virt; struct lpfc_sli_ct_request *CTrsp = outp->virt; uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; @@ -2224,7 +2271,7 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ulp_word4); } - free_ndlp = cmdiocb->context_un.ndlp; + free_ndlp = cmdiocb->ndlp; lpfc_ct_free_iocb(phba, cmdiocb); lpfc_nlp_put(free_ndlp); @@ -2236,15 +2283,19 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, cmd = be16_to_cpu(fdmi_cmd); if (fdmi_rsp == cpu_to_be16(SLI_CT_RESPONSE_FS_RJT)) { /* FDMI rsp failed */ - lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY | LOG_ELS, "0220 FDMI cmd failed FS_RJT Data: x%x", cmd); /* Should we fallback to FDMI-2 / FDMI-1 ? */ switch (cmd) { case SLI_MGMT_RHBA: if (vport->fdmi_hba_mask == LPFC_FDMI2_HBA_ATTR) { - /* Fallback to FDMI-1 */ + /* Fallback to FDMI-1 for HBA attributes */ vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR; + + /* If HBA attributes are FDMI1, so should + * port attributes be for consistency. + */ vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR; /* Start over */ lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); @@ -2252,6 +2303,11 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; case SLI_MGMT_RPRT: + if (vport->port_type != LPFC_PHYSICAL_PORT) { + ndlp = lpfc_findnode_did(phba->pport, FDMI_DID); + if (!ndlp) + return; + } if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) { /* Fallback to FDMI-1 */ vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR; @@ -2272,9 +2328,9 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, phba->link_flag &= ~LS_CT_VEN_RPA; if (phba->cmf_active_mode == LPFC_CFG_OFF) return; - lpfc_printf_log(phba, KERN_ERR, + lpfc_printf_log(phba, KERN_WARNING, LOG_DISCOVERY | LOG_ELS, - "6460 VEN FDMI RPA failure\n"); + "6460 VEN FDMI RPA RJT\n"); return; } if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) { @@ -2301,6 +2357,9 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, */ switch (cmd) { case SLI_MGMT_RHBA: + /* Check for any RPRTs deferred till after RHBA completes */ + lpfc_fdmi_rprt_defer(phba, vport->fdmi_port_mask); + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, 0); break; @@ -2309,10 +2368,26 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, break; case SLI_MGMT_DPRT: - if (vport->port_type == LPFC_PHYSICAL_PORT) + if (vport->port_type == LPFC_PHYSICAL_PORT) { lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA, 0); - else - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0); + } else { + ndlp = lpfc_findnode_did(phba->pport, FDMI_DID); + if (!ndlp) + return; + + /* Only issue a RPRT for the vport if the RHBA + * for the physical port completes successfully. + * We may have to defer the RPRT accordingly. + */ + if (phba->hba_flag & HBA_RHBA_CMPL) { + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0); + } else { + lpfc_printf_vlog(vport, KERN_INFO, + LOG_DISCOVERY, + "6078 RPRT deferred\n"); + vport->ct_flags |= FC_CT_RPRT_DEFER; + } + } break; case SLI_MGMT_RPA: if (vport->port_type == LPFC_PHYSICAL_PORT && @@ -2327,7 +2402,8 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, break; } - lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, + lpfc_printf_log(phba, KERN_INFO, + LOG_DISCOVERY | LOG_CGN_MGMT, "6210 Issue Vendor MI FDMI %x\n", phba->sli4_hba.pc_sli4_params.mi_ver); @@ -2396,6 +2472,9 @@ lpfc_fdmi_change_check(struct lpfc_vport *vport) phba->link_flag &= ~LS_CT_VEN_RPA; lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); } else { + ndlp = lpfc_findnode_did(phba->pport, FDMI_DID); + if (!ndlp) + return; lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0); } @@ -2417,6 +2496,9 @@ lpfc_fdmi_change_check(struct lpfc_vport *vport) lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, LPFC_FDMI_PORT_ATTR_num_disc); } else { + ndlp = lpfc_findnode_did(phba->pport, FDMI_DID); + if (!ndlp) + return; lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, LPFC_FDMI_PORT_ATTR_num_disc); } @@ -2830,31 +2912,59 @@ lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, struct lpfc_hba *phba = vport->phba; struct lpfc_fdmi_attr_entry *ae; uint32_t size; + u32 tcfg; + u8 i, cnt; ae = &ad->AttrValue; ae->un.AttrInt = 0; if (!(phba->hba_flag & HBA_FCOE_MODE)) { - if (phba->lmt & LMT_256Gb) - ae->un.AttrInt |= HBA_PORTSPEED_256GFC; - if (phba->lmt & LMT_128Gb) - ae->un.AttrInt |= HBA_PORTSPEED_128GFC; - if (phba->lmt & LMT_64Gb) - ae->un.AttrInt |= HBA_PORTSPEED_64GFC; - if (phba->lmt & LMT_32Gb) - ae->un.AttrInt |= HBA_PORTSPEED_32GFC; - if (phba->lmt & LMT_16Gb) - ae->un.AttrInt |= HBA_PORTSPEED_16GFC; - if (phba->lmt & LMT_10Gb) - ae->un.AttrInt |= HBA_PORTSPEED_10GFC; - if (phba->lmt & LMT_8Gb) - ae->un.AttrInt |= HBA_PORTSPEED_8GFC; - if (phba->lmt & LMT_4Gb) - ae->un.AttrInt |= HBA_PORTSPEED_4GFC; - if (phba->lmt & LMT_2Gb) - ae->un.AttrInt |= HBA_PORTSPEED_2GFC; - if (phba->lmt & LMT_1Gb) - ae->un.AttrInt |= HBA_PORTSPEED_1GFC; + cnt = 0; + if (phba->sli_rev == LPFC_SLI_REV4) { + tcfg = phba->sli4_hba.conf_trunk; + for (i = 0; i < 4; i++, tcfg >>= 1) + if (tcfg & 1) + cnt++; + } + + if (cnt > 2) { /* 4 lane trunk group */ + if (phba->lmt & LMT_64Gb) + ae->un.AttrInt |= HBA_PORTSPEED_256GFC; + if (phba->lmt & LMT_32Gb) + ae->un.AttrInt |= HBA_PORTSPEED_128GFC; + if (phba->lmt & LMT_16Gb) + ae->un.AttrInt |= HBA_PORTSPEED_64GFC; + } else if (cnt) { /* 2 lane trunk group */ + if (phba->lmt & LMT_128Gb) + ae->un.AttrInt |= HBA_PORTSPEED_256GFC; + if (phba->lmt & LMT_64Gb) + ae->un.AttrInt |= HBA_PORTSPEED_128GFC; + if (phba->lmt & LMT_32Gb) + ae->un.AttrInt |= HBA_PORTSPEED_64GFC; + if (phba->lmt & LMT_16Gb) + ae->un.AttrInt |= HBA_PORTSPEED_32GFC; + } else { + if (phba->lmt & LMT_256Gb) + ae->un.AttrInt |= HBA_PORTSPEED_256GFC; + if (phba->lmt & LMT_128Gb) + ae->un.AttrInt |= HBA_PORTSPEED_128GFC; + if (phba->lmt & LMT_64Gb) + ae->un.AttrInt |= HBA_PORTSPEED_64GFC; + if (phba->lmt & LMT_32Gb) + ae->un.AttrInt |= HBA_PORTSPEED_32GFC; + if (phba->lmt & LMT_16Gb) + ae->un.AttrInt |= HBA_PORTSPEED_16GFC; + if (phba->lmt & LMT_10Gb) + ae->un.AttrInt |= HBA_PORTSPEED_10GFC; + if (phba->lmt & LMT_8Gb) + ae->un.AttrInt |= HBA_PORTSPEED_8GFC; + if (phba->lmt & LMT_4Gb) + ae->un.AttrInt |= HBA_PORTSPEED_4GFC; + if (phba->lmt & LMT_2Gb) + ae->un.AttrInt |= HBA_PORTSPEED_2GFC; + if (phba->lmt & LMT_1Gb) + ae->un.AttrInt |= HBA_PORTSPEED_1GFC; + } } else { /* FCoE links support only one speed */ switch (phba->fc_linkspeed) { @@ -3125,6 +3235,7 @@ static int lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) { + struct lpfc_hba *phba = vport->phba; struct lpfc_fdmi_attr_entry *ae; uint32_t size; @@ -3135,7 +3246,8 @@ lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport, ae->un.AttrTypes[7] = 0x01; /* Type 0x20 - CT */ /* Check to see if NVME is configured or not */ - if (vport->phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) + if (vport == phba->pport && + phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) ae->un.AttrTypes[6] = 0x1; /* Type 0x28 - NVME */ size = FOURBYTES + 32; @@ -3459,8 +3571,10 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* FDMI request */ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "0218 FDMI Request Data: x%x x%x x%x\n", - vport->fc_flag, vport->port_state, cmdcode); + "0218 FDMI Request x%x mask x%x Data: x%x x%x x%x\n", + cmdcode, new_mask, vport->fdmi_port_mask, + vport->fc_flag, vport->port_state); + CtReq = (struct lpfc_sli_ct_request *)mp->virt; /* First populate the CT_IU preamble */ @@ -3529,6 +3643,12 @@ hba_out: break; case SLI_MGMT_RPRT: + if (vport->port_type != LPFC_PHYSICAL_PORT) { + ndlp = lpfc_findnode_did(phba->pport, FDMI_DID); + if (!ndlp) + return 0; + } + fallthrough; case SLI_MGMT_RPA: pab = (struct lpfc_fdmi_reg_portattr *)&CtReq->un.PortID; if (cmdcode == SLI_MGMT_RPRT) { @@ -3593,6 +3713,12 @@ port_out: rsp_size = FC_MAX_NS_RSP; fallthrough; case SLI_MGMT_DPRT: + if (vport->port_type != LPFC_PHYSICAL_PORT) { + ndlp = lpfc_findnode_did(phba->pport, FDMI_DID); + if (!ndlp) + return 0; + } + fallthrough; case SLI_MGMT_DPA: pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID; memcpy((uint8_t *)&pe->PortName, @@ -3780,8 +3906,8 @@ lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) { struct lpfc_vport *vport = cmdiocb->vport; - struct lpfc_dmabuf *inp = cmdiocb->context1; - struct lpfc_dmabuf *outp = cmdiocb->context2; + struct lpfc_dmabuf *inp = cmdiocb->cmd_dmabuf; + struct lpfc_dmabuf *outp = cmdiocb->rsp_dmabuf; struct lpfc_sli_ct_request *ctcmd = inp->virt; struct lpfc_sli_ct_request *ctrsp = outp->virt; u16 rsp = ctrsp->CommandResponse.bits.CmdRsp; |