lpfc 8.3.31: Correct point-to-point mode discovery errors on LPe16xxx (CR: 130446)
Subsystems (2)
PATCH 15/20 lpfc 8.3.31: Correct point-to-point mode discovery errors on LPe16xxx (CR: 130446)
Correct point-to-point mode discovery errors on LPe16xxx (CR: 130446)
Signed-off-by Alex Iannicelli <[email protected]>
Signed-off-by James Smart <[email protected]>
---
lpfc_els.c | 93 +++++++++++++++++++++++++++++++++++++++++++++---------- lpfc_hbadisc.c | 15 +++++--- lpfc_hw.h | 3 + lpfc_hw4.h | 8 ++++ lpfc_nportdisc.c | 9 +++++ lpfc_sli.c | 70 ++++++++++++++++++++++++++++++++++++----- lpfc_sli4.h | 8 ++++ 7 files changed, 175 insertions(+), 31 deletions(-)
drivers/scsi/lpfc/lpfc_els.c +77 -16
@@ -230,27 +230,43 @@ lpfc_prep_els_iocb(struct lpfc_vport *vpINIT_LIST_HEAD (&pbuflist->list); - 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.addrHigh =putPaddrHigh (pbuflist->phys); + icmd->un.elsreq64.bdl.addrLow =putPaddrLow (pbuflist->phys); + icmd->un.elsreq64.bdl.bdeFlags =BUFF_TYPE_BLP_64 ; 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 ) { - icmd->un.elsreq64.myID = vport->fc_myDID; +/* +* 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]; + } -/* 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 )
@@ -438,9 +454,10 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vpint 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 ;
@@ -820,6 +837,17 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vpmempool_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. */
@@ -4940,8 +4968,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vpreturn 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.
@@ -4980,29 +5006,64 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vpspin_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;
drivers/scsi/lpfc/lpfc_hbadisc.c +10 -5
@@ -2882,9 +2882,14 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *p }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 */
@@ -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. */
drivers/scsi/lpfc/lpfc_hw4.h +7 -1
@@ -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 word4struct wqe_did wqe_dest;struct wqe_common wqe_com;/* words 6-11 */ uint32_t word12;
drivers/scsi/lpfc/lpfc_hw.h +3 -0
@@ -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;
drivers/scsi/lpfc/lpfc_nportdisc.c +9 -0
@@ -367,8 +367,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport,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 );
@@ -382,6 +384,13 @@ lpfc_rcv_plogi(struct lpfc_vport *vport,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); }
drivers/scsi/lpfc/lpfc_sli4.h +8 -0
@@ -75,11 +75,19 @@ (fc_hdr)->fh_s_id[1] << 8 | \ (fc_hdr)->fh_s_id[2]) +#define sli4_did_from_fc_hdr (fc_hdr) \ + ((fc_hdr)->fh_d_id[0] << 16 | \ + (fc_hdr)->fh_d_id[1] << 8 | \ + (fc_hdr)->fh_d_id[2]) +#define sli4_fctl_from_fc_hdr (fc_hdr) \ ((fc_hdr)->fh_f_ctl[0] << 16 | \ (fc_hdr)->fh_f_ctl[1] << 8 | \ (fc_hdr)->fh_f_ctl[2]) +#define sli4_type_from_fc_hdr (fc_hdr) \ + ((fc_hdr)->fh_type) +#define LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT 12000enum lpfc_sli4_queue_type {
drivers/scsi/lpfc/lpfc_sli.c +61 -9
122 lines not on this page · raw message