Commit 3bea83b6 authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: SLI path split: Refactor the RSCN/SCR/RDF/EDC/FARPR paths

This patch refactors the SLI3/SLI4 RSCN/SCR/RDF/EDC/FARPR paths to use
SLI-4 as the primary interface:

 - 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-7-jsmart2021@gmail.com


Co-developed-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent cad93a08
Loading
Loading
Loading
Loading
+81 −34
Original line number Diff line number Diff line
@@ -3177,19 +3177,29 @@ lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	struct lpfc_vport *vport = cmdiocb->vport;
	struct lpfc_nodelist *free_ndlp;
	IOCB_t *irsp;
	u32 ulp_status, ulp_word4, tmo, did, iotag;

	ulp_status = get_job_ulpstatus(phba, rspiocb);
	ulp_word4 = get_job_word4(phba, rspiocb);
	did = get_job_els_rsp64_did(phba, cmdiocb);

	if (phba->sli_rev == LPFC_SLI_REV4) {
		tmo = get_wqe_tmo(cmdiocb);
		iotag = get_wqe_reqtag(cmdiocb);
	} else {
		irsp = &rspiocb->iocb;
		tmo = irsp->ulpTimeout;
		iotag = irsp->ulpIoTag;
	}

	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
			      "ELS cmd cmpl:    status:x%x/x%x did:x%x",
			      irsp->ulpStatus, irsp->un.ulpWord[4],
			      irsp->un.elsreq64.remoteID);
			      ulp_status, ulp_word4, did);

	/* ELS cmd tag <ulpIoTag> completes */
	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
			 "0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n",
			 irsp->ulpIoTag, irsp->ulpStatus,
			 irsp->un.ulpWord[4], irsp->ulpTimeout);
			 iotag, ulp_status, ulp_word4, tmo);

	/* Check to see if link went down during discovery */
	lpfc_els_chk_latt(vport);
@@ -3311,20 +3321,29 @@ lpfc_cmpl_els_disc_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	u32 *pdata;
	u32 cmd;
	struct lpfc_nodelist *ndlp = cmdiocb->context1;
	u32 ulp_status, ulp_word4, tmo, did, iotag;

	ulp_status = get_job_ulpstatus(phba, rspiocb);
	ulp_word4 = get_job_word4(phba, rspiocb);
	did = get_job_els_rsp64_did(phba, cmdiocb);

	if (phba->sli_rev == LPFC_SLI_REV4) {
		tmo = get_wqe_tmo(cmdiocb);
		iotag = get_wqe_reqtag(cmdiocb);
	} else {
		irsp = &rspiocb->iocb;
		tmo = irsp->ulpTimeout;
		iotag = irsp->ulpIoTag;
	}

	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
		"ELS cmd cmpl:    status:x%x/x%x did:x%x",
		irsp->ulpStatus, irsp->un.ulpWord[4],
		irsp->un.elsreq64.remoteID);
		ulp_status, ulp_word4, did);

	/* ELS cmd tag <ulpIoTag> completes */
	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT,
			 "0217 ELS cmd tag x%x completes Data: x%x x%x x%x "
			 "x%x\n",
			 irsp->ulpIoTag, irsp->ulpStatus,
			 irsp->un.ulpWord[4], irsp->ulpTimeout,
			 cmdiocb->retry);
			 "0217 ELS cmd tag x%x completes Data: x%x x%x x%x x%x\n",
			 iotag, ulp_status, ulp_word4, tmo, cmdiocb->retry);

	pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
	if (!pcmd)
@@ -3336,8 +3355,8 @@ lpfc_cmpl_els_disc_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	cmd = *pdata;

	/* Only 1 retry for ELS Timeout only */
	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_SEQUENCE_TIMEOUT)) {
		cmdiocb->retry++;
		if (cmdiocb->retry <= 1) {
@@ -3362,11 +3381,11 @@ lpfc_cmpl_els_disc_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
		lpfc_cmpl_els_edc(phba, cmdiocb, rspiocb);
		return;
	}
	if (irsp->ulpStatus) {
	if (ulp_status) {
		/* ELS discovery cmd completes with error */
		lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
		lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS | LOG_CGN_MGMT,
				 "4203 ELS cmd x%x error: x%x x%X\n", cmd,
				 irsp->ulpStatus, irsp->un.ulpWord[4]);
				 ulp_status, ulp_word4);
		goto out;
	}

@@ -3636,7 +3655,7 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
	}

	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
				     ndlp->nlp_DID, ELS_CMD_RNID);
				     ndlp->nlp_DID, ELS_CMD_FARPR);
	if (!elsiocb)
		return 1;

@@ -3938,7 +3957,7 @@ static void
lpfc_cmpl_els_edc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
		  struct lpfc_iocbq *rspiocb)
{
	IOCB_t *irsp;
	IOCB_t *irsp_iocb;
	struct fc_els_edc_resp *edc_rsp;
	struct fc_tlv_desc *tlv;
	struct fc_diag_cg_sig_desc *pcgd;
@@ -3949,20 +3968,31 @@ lpfc_cmpl_els_edc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	int desc_cnt = 0, bytes_remain;
	bool rcv_cap_desc = false;
	struct lpfc_nodelist *ndlp;
	u32 ulp_status, ulp_word4, tmo, did, iotag;

	irsp = &rspiocb->iocb;
	ndlp = cmdiocb->context1;

	ulp_status = get_job_ulpstatus(phba, rspiocb);
	ulp_word4 = get_job_word4(phba, rspiocb);
	did = get_job_els_rsp64_did(phba, rspiocb);

	if (phba->sli_rev == LPFC_SLI_REV4) {
		tmo = get_wqe_tmo(rspiocb);
		iotag = get_wqe_reqtag(rspiocb);
	} else {
		irsp_iocb = &rspiocb->iocb;
		tmo = irsp_iocb->ulpTimeout;
		iotag = irsp_iocb->ulpIoTag;
	}

	lpfc_debugfs_disc_trc(phba->pport, LPFC_DISC_TRC_ELS_CMD,
			      "EDC cmpl:    status:x%x/x%x did:x%x",
			      irsp->ulpStatus, irsp->un.ulpWord[4],
			      irsp->un.elsreq64.remoteID);
			      ulp_status, ulp_word4, did);

	/* ELS cmd tag <ulpIoTag> completes */
	lpfc_printf_log(phba, KERN_INFO, LOG_ELS | LOG_CGN_MGMT,
			"4201 EDC cmd tag x%x completes Data: x%x x%x x%x\n",
			irsp->ulpIoTag, irsp->ulpStatus,
			irsp->un.ulpWord[4], irsp->ulpTimeout);
			iotag, ulp_status, ulp_word4, tmo);

	pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
	if (!pcmd)
@@ -3973,7 +4003,7 @@ lpfc_cmpl_els_edc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
		goto out;

	/* Need to clear signal values, send features MB and RDF with FPIN. */
	if (irsp->ulpStatus)
	if (ulp_status)
		goto out;

	prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
@@ -6268,11 +6298,17 @@ lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data,
		      struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
{
	struct lpfc_hba  *phba = vport->phba;
	IOCB_t *icmd, *oldcmd;
	union lpfc_wqe128 *wqe;
	struct lpfc_iocbq *elsiocb;
	uint8_t *pcmd;
	uint16_t cmdsize;
	int rc;
	u32 ulp_context;

	if (phba->sli_rev == LPFC_SLI_REV4)
		cmdsize = oldiocb->wcqe_cmpl.total_data_placed;
	else
		cmdsize = oldiocb->iocb.unsli3.rcvsli3.acc_len;

	/* The accumulated length can exceed the BPL_SIZE.  For
@@ -6285,13 +6321,26 @@ lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data,
	if (!elsiocb)
		return 1;

	elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext;  /* Xri / rx_id */
	elsiocb->iocb.unsli3.rcvsli3.ox_id = oldiocb->iocb.unsli3.rcvsli3.ox_id;
	if (phba->sli_rev == LPFC_SLI_REV4) {
		wqe = &elsiocb->wqe;
		bf_set(wqe_ctxt_tag, &wqe->generic.wqe_com,
		       get_job_ulpcontext(phba, oldiocb)); /* Xri / rx_id */
		ulp_context = get_job_ulpcontext(phba, elsiocb);
		bf_set(wqe_rcvoxid, &wqe->xmit_els_rsp.wqe_com,
		       get_job_rcvoxid(phba, oldiocb));
	} else {
		icmd = &elsiocb->iocb;
		oldcmd = &oldiocb->iocb;
		icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */
		ulp_context = elsiocb->iocb.ulpContext;
		icmd->unsli3.rcvsli3.ox_id =
			oldcmd->unsli3.rcvsli3.ox_id;
	}

	/* Xmit ECHO ACC response tag <ulpIoTag> */
	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
			 "2876 Xmit ECHO ACC response tag x%x xri x%x\n",
			 elsiocb->iotag, elsiocb->iocb.ulpContext);
			 elsiocb->iotag, ulp_context);
	pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
	*((uint32_t *) (pcmd)) = ELS_CMD_ACC;
	pcmd += sizeof(uint32_t);
@@ -8850,11 +8899,9 @@ lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
{
	struct lpfc_dmabuf *pcmd;
	uint32_t *lp;
	IOCB_t *icmd;
	uint32_t did;

	icmd = &cmdiocb->iocb;
	did = icmd->un.elsreq64.remoteID;
	did = get_job_els_rsp64_did(vport->phba, cmdiocb);
	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
	lp = (uint32_t *) pcmd->virt;