Loading drivers/scsi/lpfc/lpfc_els.c +77 −16 Original line number Diff line number Diff line Loading @@ -230,27 +230,43 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, INIT_LIST_HEAD(&pbuflist->list); if (expectRsp) { icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys); icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys); icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; icmd->un.elsreq64.remoteID = did; /* DID */ if (expectRsp) { icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64)); icmd->un.elsreq64.remoteID = did; /* DID */ icmd->ulpCommand = CMD_ELS_REQUEST64_CR; icmd->ulpTimeout = phba->fc_ratov * 2; } else { icmd->un.elsreq64.bdl.bdeSize = sizeof(struct ulp_bde64); icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys); icmd->un.xseq64.bdl.addrLow = putPaddrLow(pbuflist->phys); icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; icmd->un.xseq64.bdl.bdeSize = sizeof(struct ulp_bde64); icmd->un.xseq64.xmit_els_remoteID = did; /* DID */ icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX; } icmd->ulpBdeCount = 1; icmd->ulpLe = 1; icmd->ulpClass = CLASS3; if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { /* * If we have NPIV enabled, we want to send ELS traffic by VPI. * For SLI4, since the driver controls VPIs we also want to include * all ELS pt2pt protocol traffic as well. */ if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) || ((phba->sli_rev == LPFC_SLI_REV4) && (vport->fc_flag & FC_PT2PT))) { if (expectRsp) { icmd->un.elsreq64.myID = vport->fc_myDID; /* For ELS_REQUEST64_CR, use the VPI by default */ icmd->ulpContext = phba->vpi_ids[vport->vpi]; } icmd->ulpCt_h = 0; /* The CT field must be 0=INVALID_RPI for the ECHO cmd */ if (elscmd == ELS_CMD_ECHO) Loading Loading @@ -438,9 +454,10 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport) int rc = 0; sp = &phba->fc_fabparam; /* move forward in case of SLI4 FC port loopback test */ /* move forward in case of SLI4 FC port loopback test and pt2pt mode */ if ((phba->sli_rev == LPFC_SLI_REV4) && !(phba->link_flag & LS_LOOPBACK_MODE)) { !(phba->link_flag & LS_LOOPBACK_MODE) && !(vport->fc_flag & FC_PT2PT)) { ndlp = lpfc_findnode_did(vport, Fabric_DID); if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { rc = -ENODEV; Loading Loading @@ -820,6 +837,17 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, mempool_free(mbox, phba->mbox_mem_pool); goto fail; } /* * For SLI4, the VFI/VPI are registered AFTER the * Nport with the higher WWPN sends the PLOGI with * an assigned NPortId. */ /* not equal */ if ((phba->sli_rev == LPFC_SLI_REV4) && rc) lpfc_issue_reg_vfi(vport); /* Decrement ndlp reference count indicating that ndlp can be * safely released when other references to it are done. */ Loading Loading @@ -4940,8 +4968,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 1; } did = Fabric_DID; if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) { /* For a FLOGI we accept, then if our portname is greater * then the remote portname we initiate Nport login. Loading Loading @@ -4980,29 +5006,64 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_PT2PT_PLOGI; spin_unlock_irq(shost->host_lock); /* If we have the high WWPN we can assign our own * myDID; otherwise, we have to WAIT for a PLOGI * from the remote NPort to find out what it * will be. */ vport->fc_myDID = PT2PT_LocalID; } else vport->fc_myDID = PT2PT_RemoteID; vport->port_state = LPFC_FLOGI; } /* * The vport state should go to LPFC_FLOGI only * AFTER we issue a FLOGI, not receive one. */ spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_PT2PT; vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); spin_unlock_irq(shost->host_lock); /* * We temporarily set fc_myDID to make it look like we are * a Fabric. This is done just so we end up with the right * did / sid on the FLOGI ACC rsp. */ did = vport->fc_myDID; vport->fc_myDID = Fabric_DID; } else { /* Reject this request because invalid parameters */ stat.un.b.lsRjtRsvd0 = 0; stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; stat.un.b.vendorUnique = 0; /* * We temporarily set fc_myDID to make it look like we are * a Fabric. This is done just so we end up with the right * did / sid on the FLOGI LS_RJT rsp. */ did = vport->fc_myDID; vport->fc_myDID = Fabric_DID; lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); /* Now lets put fc_myDID back to what its supposed to be */ vport->fc_myDID = did; return 1; } /* Send back ACC */ lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL); /* Now lets put fc_myDID back to what its supposed to be */ vport->fc_myDID = did; if (!(vport->fc_flag & FC_PT2PT_PLOGI)) { mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) goto fail; Loading drivers/scsi/lpfc/lpfc_hbadisc.c +10 −5 Original line number Diff line number Diff line Loading @@ -2882,9 +2882,14 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) } if (vport->port_state == LPFC_FABRIC_CFG_LINK) { /* For private loop just start discovery and we are done. */ if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && !(vport->fc_flag & FC_PUBLIC_LOOP)) { /* * For private loop or for NPort pt2pt, * just start discovery and we are done. */ if ((vport->fc_flag & FC_PT2PT) || ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && !(vport->fc_flag & FC_PUBLIC_LOOP))) { /* Use loop map to make discovery list */ lpfc_disc_list_loopmap(vport); /* Start discovery */ Loading Loading @@ -5491,9 +5496,9 @@ lpfc_nlp_release(struct kref *kref) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, "0279 lpfc_nlp_release: ndlp:x%p " "0279 lpfc_nlp_release: ndlp:x%p did %x " "usgmap:x%x refcnt:%d\n", (void *)ndlp, ndlp->nlp_usg_map, (void *)ndlp, ndlp->nlp_DID, ndlp->nlp_usg_map, atomic_read(&ndlp->kref.refcount)); /* remove ndlp from action. */ Loading drivers/scsi/lpfc/lpfc_hw.h +3 −0 Original line number Diff line number Diff line Loading @@ -3374,6 +3374,9 @@ typedef struct { WORD5 w5; /* Header control/status word */ } XMT_SEQ_FIELDS64; /* This word is remote ports D_ID for XMIT_ELS_RSP64 */ #define xmit_els_remoteID xrsqRo /* IOCB Command template for 64 bit RCV_SEQUENCE64 */ typedef struct { struct ulp_bde64 rcvBde; Loading drivers/scsi/lpfc/lpfc_hw4.h +7 −1 Original line number Diff line number Diff line Loading @@ -3295,7 +3295,13 @@ struct els_request64_wqe { struct xmit_els_rsp64_wqe { struct ulp_bde64 bde; uint32_t response_payload_len; uint32_t rsvd4; uint32_t word4; #define els_rsp64_sid_SHIFT 0 #define els_rsp64_sid_MASK 0x00FFFFFF #define els_rsp64_sid_WORD word4 #define els_rsp64_sp_SHIFT 24 #define els_rsp64_sp_MASK 0x00000001 #define els_rsp64_sp_WORD word4 struct wqe_did wqe_dest; struct wqe_common wqe_com; /* words 6-11 */ uint32_t word12; Loading drivers/scsi/lpfc/lpfc_nportdisc.c +9 −0 Original line number Diff line number Diff line Loading @@ -367,8 +367,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 1; } /* Check for Nport to NPort pt2pt protocol */ if ((vport->fc_flag & FC_PT2PT) && !(vport->fc_flag & FC_PT2PT_PLOGI)) { /* rcv'ed PLOGI decides what our NPortId will be */ vport->fc_myDID = icmd->un.rcvels.parmRo; mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); Loading @@ -382,6 +384,13 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, mempool_free(mbox, phba->mbox_mem_pool); goto out; } /* * For SLI4, the VFI/VPI are registered AFTER the * Nport with the higher WWPN sends us a PLOGI with * our assigned NPortId. */ if (phba->sli_rev == LPFC_SLI_REV4) lpfc_issue_reg_vfi(vport); lpfc_can_disctmo(vport); } Loading Loading
drivers/scsi/lpfc/lpfc_els.c +77 −16 Original line number Diff line number Diff line Loading @@ -230,27 +230,43 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, INIT_LIST_HEAD(&pbuflist->list); if (expectRsp) { icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys); icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys); icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; icmd->un.elsreq64.remoteID = did; /* DID */ if (expectRsp) { icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64)); icmd->un.elsreq64.remoteID = did; /* DID */ icmd->ulpCommand = CMD_ELS_REQUEST64_CR; icmd->ulpTimeout = phba->fc_ratov * 2; } else { icmd->un.elsreq64.bdl.bdeSize = sizeof(struct ulp_bde64); icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys); icmd->un.xseq64.bdl.addrLow = putPaddrLow(pbuflist->phys); icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; icmd->un.xseq64.bdl.bdeSize = sizeof(struct ulp_bde64); icmd->un.xseq64.xmit_els_remoteID = did; /* DID */ icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX; } icmd->ulpBdeCount = 1; icmd->ulpLe = 1; icmd->ulpClass = CLASS3; if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { /* * If we have NPIV enabled, we want to send ELS traffic by VPI. * For SLI4, since the driver controls VPIs we also want to include * all ELS pt2pt protocol traffic as well. */ if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) || ((phba->sli_rev == LPFC_SLI_REV4) && (vport->fc_flag & FC_PT2PT))) { if (expectRsp) { icmd->un.elsreq64.myID = vport->fc_myDID; /* For ELS_REQUEST64_CR, use the VPI by default */ icmd->ulpContext = phba->vpi_ids[vport->vpi]; } icmd->ulpCt_h = 0; /* The CT field must be 0=INVALID_RPI for the ECHO cmd */ if (elscmd == ELS_CMD_ECHO) Loading Loading @@ -438,9 +454,10 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport) int rc = 0; sp = &phba->fc_fabparam; /* move forward in case of SLI4 FC port loopback test */ /* move forward in case of SLI4 FC port loopback test and pt2pt mode */ if ((phba->sli_rev == LPFC_SLI_REV4) && !(phba->link_flag & LS_LOOPBACK_MODE)) { !(phba->link_flag & LS_LOOPBACK_MODE) && !(vport->fc_flag & FC_PT2PT)) { ndlp = lpfc_findnode_did(vport, Fabric_DID); if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { rc = -ENODEV; Loading Loading @@ -820,6 +837,17 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, mempool_free(mbox, phba->mbox_mem_pool); goto fail; } /* * For SLI4, the VFI/VPI are registered AFTER the * Nport with the higher WWPN sends the PLOGI with * an assigned NPortId. */ /* not equal */ if ((phba->sli_rev == LPFC_SLI_REV4) && rc) lpfc_issue_reg_vfi(vport); /* Decrement ndlp reference count indicating that ndlp can be * safely released when other references to it are done. */ Loading Loading @@ -4940,8 +4968,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 1; } did = Fabric_DID; if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) { /* For a FLOGI we accept, then if our portname is greater * then the remote portname we initiate Nport login. Loading Loading @@ -4980,29 +5006,64 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_PT2PT_PLOGI; spin_unlock_irq(shost->host_lock); /* If we have the high WWPN we can assign our own * myDID; otherwise, we have to WAIT for a PLOGI * from the remote NPort to find out what it * will be. */ vport->fc_myDID = PT2PT_LocalID; } else vport->fc_myDID = PT2PT_RemoteID; vport->port_state = LPFC_FLOGI; } /* * The vport state should go to LPFC_FLOGI only * AFTER we issue a FLOGI, not receive one. */ spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_PT2PT; vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); spin_unlock_irq(shost->host_lock); /* * We temporarily set fc_myDID to make it look like we are * a Fabric. This is done just so we end up with the right * did / sid on the FLOGI ACC rsp. */ did = vport->fc_myDID; vport->fc_myDID = Fabric_DID; } else { /* Reject this request because invalid parameters */ stat.un.b.lsRjtRsvd0 = 0; stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; stat.un.b.vendorUnique = 0; /* * We temporarily set fc_myDID to make it look like we are * a Fabric. This is done just so we end up with the right * did / sid on the FLOGI LS_RJT rsp. */ did = vport->fc_myDID; vport->fc_myDID = Fabric_DID; lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); /* Now lets put fc_myDID back to what its supposed to be */ vport->fc_myDID = did; return 1; } /* Send back ACC */ lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL); /* Now lets put fc_myDID back to what its supposed to be */ vport->fc_myDID = did; if (!(vport->fc_flag & FC_PT2PT_PLOGI)) { mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) goto fail; Loading
drivers/scsi/lpfc/lpfc_hbadisc.c +10 −5 Original line number Diff line number Diff line Loading @@ -2882,9 +2882,14 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) } if (vport->port_state == LPFC_FABRIC_CFG_LINK) { /* For private loop just start discovery and we are done. */ if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && !(vport->fc_flag & FC_PUBLIC_LOOP)) { /* * For private loop or for NPort pt2pt, * just start discovery and we are done. */ if ((vport->fc_flag & FC_PT2PT) || ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && !(vport->fc_flag & FC_PUBLIC_LOOP))) { /* Use loop map to make discovery list */ lpfc_disc_list_loopmap(vport); /* Start discovery */ Loading Loading @@ -5491,9 +5496,9 @@ lpfc_nlp_release(struct kref *kref) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, "0279 lpfc_nlp_release: ndlp:x%p " "0279 lpfc_nlp_release: ndlp:x%p did %x " "usgmap:x%x refcnt:%d\n", (void *)ndlp, ndlp->nlp_usg_map, (void *)ndlp, ndlp->nlp_DID, ndlp->nlp_usg_map, atomic_read(&ndlp->kref.refcount)); /* remove ndlp from action. */ Loading
drivers/scsi/lpfc/lpfc_hw.h +3 −0 Original line number Diff line number Diff line Loading @@ -3374,6 +3374,9 @@ typedef struct { WORD5 w5; /* Header control/status word */ } XMT_SEQ_FIELDS64; /* This word is remote ports D_ID for XMIT_ELS_RSP64 */ #define xmit_els_remoteID xrsqRo /* IOCB Command template for 64 bit RCV_SEQUENCE64 */ typedef struct { struct ulp_bde64 rcvBde; Loading
drivers/scsi/lpfc/lpfc_hw4.h +7 −1 Original line number Diff line number Diff line Loading @@ -3295,7 +3295,13 @@ struct els_request64_wqe { struct xmit_els_rsp64_wqe { struct ulp_bde64 bde; uint32_t response_payload_len; uint32_t rsvd4; uint32_t word4; #define els_rsp64_sid_SHIFT 0 #define els_rsp64_sid_MASK 0x00FFFFFF #define els_rsp64_sid_WORD word4 #define els_rsp64_sp_SHIFT 24 #define els_rsp64_sp_MASK 0x00000001 #define els_rsp64_sp_WORD word4 struct wqe_did wqe_dest; struct wqe_common wqe_com; /* words 6-11 */ uint32_t word12; Loading
drivers/scsi/lpfc/lpfc_nportdisc.c +9 −0 Original line number Diff line number Diff line Loading @@ -367,8 +367,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 1; } /* Check for Nport to NPort pt2pt protocol */ if ((vport->fc_flag & FC_PT2PT) && !(vport->fc_flag & FC_PT2PT_PLOGI)) { /* rcv'ed PLOGI decides what our NPortId will be */ vport->fc_myDID = icmd->un.rcvels.parmRo; mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); Loading @@ -382,6 +384,13 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, mempool_free(mbox, phba->mbox_mem_pool); goto out; } /* * For SLI4, the VFI/VPI are registered AFTER the * Nport with the higher WWPN sends us a PLOGI with * our assigned NPortId. */ if (phba->sli_rev == LPFC_SLI_REV4) lpfc_issue_reg_vfi(vport); lpfc_can_disctmo(vport); } Loading