Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 939723a4 authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.3.31: Correct point-to-point mode discovery errors on LPe16xxx

parent 27aa1b73
Loading
Loading
Loading
Loading
+77 −16
Original line number Diff line number Diff line
@@ -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)
@@ -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;
@@ -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.
		 */
@@ -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.
@@ -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;
+10 −5
Original line number Diff line number Diff line
@@ -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 */
@@ -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. */
+3 −0
Original line number Diff line number Diff line
@@ -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;
+7 −1
Original line number Diff line number Diff line
@@ -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;
+9 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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