diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 9ee6b930a655..c832a7d26e86 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -591,6 +591,10 @@ struct lpfc_io_buf *lpfc_get_io_buf(struct lpfc_hba *phba,
 				int);
 void lpfc_release_io_buf(struct lpfc_hba *phba, struct lpfc_io_buf *ncmd,
 			 struct lpfc_sli4_hdw_queue *qp);
+void lpfc_mode_sense_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *p_io_in,
+			  struct lpfc_iocbq *p_io_out);
+int lpfc_issue_scsi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			struct lpfc_scsi_io_req *cmd_req);
 void lpfc_io_ktime(struct lpfc_hba *phba, struct lpfc_io_buf *ncmd);
 void lpfc_nvme_cmd_template(void);
 void lpfc_nvmet_cmd_template(void);
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 482e4a888dae..42b6327cc3a4 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -115,6 +115,7 @@ struct lpfc_nodelist {
 	u8		nlp_nvme_info;	        /* NVME NSLER Support */
 #define NLP_NVME_NSLER     0x1			/* NVME NSLER device */
 
+	uint32_t        first_burst;	/* First Burst size for ndlp */
 	uint16_t        nlp_usg_map;	/* ndlp management usage bitmap */
 #define NLP_USG_NODE_ACT_BIT	0x1	/* Indicate ndlp is actively used */
 #define NLP_USG_IACT_REQ_BIT	0x2	/* Request to inactivate ndlp */
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 3d670568a276..a7bbe628bc52 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -2425,7 +2425,9 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 		}
 		npr->estabImagePair = 1;
 		npr->readXferRdyDis = 1;
-		if (vport->cfg_first_burst_size)
+		if (phba->sli_rev == LPFC_SLI_REV4 &&
+		    !(phba->hba_flag & HBA_FCOE_MODE) &&
+		    vport->cfg_first_burst_size)
 			npr->writeXferRdyDis = 1;
 
 		/* For FCP support */
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 4084f7f2b821..47259970907d 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -4279,6 +4279,10 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 	/* FCP and NVME Transport interface */
 	if ((old_state == NLP_STE_MAPPED_NODE ||
 	     old_state == NLP_STE_UNMAPPED_NODE)) {
+		/* SCSI-FCP first burst needs to be renegotiated on the
+		 * next successful PRLI completion.
+		 */
+		ndlp->first_burst = 0;
 		if (ndlp->rport) {
 			vport->phba->nport_event_cnt++;
 			lpfc_unregister_remote_port(ndlp);
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index d8501bd959e7..2871c9b0cbfa 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -2160,7 +2160,9 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 	IOCB_t *irsp;
 	PRLI *npr;
 	struct lpfc_nvme_prli *nvpr;
+	struct lpfc_scsi_io_req cmd_req;
 	void *temp_ptr;
+	int ret = 0;
 
 	cmdiocb = (struct lpfc_iocbq *) arg;
 	rspiocb = cmdiocb->context_un.rsp_iocb;
@@ -2200,16 +2202,26 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 				 "6028 FCP NPR PRLI Cmpl Init %d Target %d\n",
 				 npr->initiatorFunc,
 				 npr->targetFunc);
+
 		if (npr->initiatorFunc)
 			ndlp->nlp_type |= NLP_FCP_INITIATOR;
 		if (npr->targetFunc) {
 			ndlp->nlp_type |= NLP_FCP_TARGET;
-			if (npr->writeXferRdyDis)
+			if (npr->writeXferRdyDis) {
 				ndlp->nlp_flag |= NLP_FIRSTBURST;
+				cmd_req.cmd_id = MODE_SENSE;
+				cmd_req.dev_id = CTRL_ID;
+				cmd_req.cmd_cmpl = lpfc_mode_sense_cmpl;
+				ret = lpfc_issue_scsi_cmd(vport, ndlp,
+							  &cmd_req);
+				lpfc_printf_vlog(vport, KERN_INFO,
+						 LOG_FCP | LOG_FCP_ERROR,
+						 "6334 FB issue returns %d\n",
+						 ret);
+			}
 		}
 		if (npr->Retry)
 			ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
-
 	} else if (nvpr &&
 		   (bf_get_be32(prli_acc_rsp_code, nvpr) ==
 		    PRLI_REQ_EXECUTED) &&
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index ad62fb3f3a54..a003b7bf000b 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -2527,7 +2527,6 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba,
 	int prot_group_type = 0;
 	int fcpdl;
 	int ret = 1;
-	struct lpfc_vport *vport = phba->pport;
 
 	/*
 	 * Start the lpfc command prep by bumping the bpl beyond fcp_cmnd
@@ -2649,7 +2648,7 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba,
 	 * length for DIF
 	 */
 	if (iocb_cmd->un.fcpi.fcpi_XRdy &&
-	    (fcpdl < vport->cfg_first_burst_size))
+	    (fcpdl < lpfc_cmd->ndlp->first_burst))
 		iocb_cmd->un.fcpi.fcpi_XRdy = fcpdl;
 
 	return 0;
@@ -3265,7 +3264,6 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba,
 	int prot_group_type = 0;
 	int fcpdl;
 	int ret = 1;
-	struct lpfc_vport *vport = phba->pport;
 
 	/*
 	 * Start the lpfc command prep by bumping the sgl beyond fcp_cmnd
@@ -3402,7 +3400,7 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba,
 	 * length for DIF
 	 */
 	if (iocb_cmd->un.fcpi.fcpi_XRdy &&
-	    (fcpdl < vport->cfg_first_burst_size))
+	    (fcpdl < lpfc_cmd->ndlp->first_burst))
 		iocb_cmd->un.fcpi.fcpi_XRdy = fcpdl;
 
 	/*
@@ -4127,14 +4125,12 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd,
 		if (datadir == DMA_TO_DEVICE) {
 			iocb_cmd->ulpCommand = CMD_FCP_IWRITE64_CR;
 			iocb_cmd->ulpPU = PARM_READ_CHECK;
-			if (vport->cfg_first_burst_size &&
+			if (pnode->first_burst &&
 			    (pnode->nlp_flag & NLP_FIRSTBURST)) {
+				u32 xrdy_len;
 				fcpdl = scsi_bufflen(scsi_cmnd);
-				if (fcpdl < vport->cfg_first_burst_size)
-					piocbq->iocb.un.fcpi.fcpi_XRdy = fcpdl;
-				else
-					piocbq->iocb.un.fcpi.fcpi_XRdy =
-						vport->cfg_first_burst_size;
+				xrdy_len = min(fcpdl, pnode->first_burst);
+				piocbq->iocb.un.fcpi.fcpi_XRdy = xrdy_len;
 			}
 			fcp_cmnd->fcpCntl3 = WRITE_DATA;
 			if (hdwq)
@@ -4708,6 +4704,286 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
 	return 0;
 }
 
+/* lpfc_mode_sense_cmpl.
+ *
+ * This is the completion routine for a driver-issued mode sense
+ * used to determine if an FCP target supports first_burst.  This
+ * routine could be used for other mode sense data values.
+ */
+void
+lpfc_mode_sense_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *p_io_in,
+		       struct lpfc_iocbq *p_io_out)
+{
+	struct lpfc_io_buf *lpfc_cmd = p_io_in->context1;
+	u32 resp_info = lpfc_cmd->fcp_rsp->rspStatus2;
+	struct sli4_sge *sgl;
+	struct lpfc_nodelist *ndlp = lpfc_cmd->ndlp;
+	u32 status = p_io_out->iocb.ulpStatus;
+	u32 result = p_io_out->iocb.un.ulpWord[4] & IOERR_PARAM_MASK;
+	u32 fb = 0;
+	int ret_val;
+	struct lpfc_first_burst_page *p_data;
+
+	/* Make sure the driver's remoteport state is still valid. If the
+	 * reference put results in an invalid remoteport, just exit.
+	 */
+	ret_val = lpfc_nlp_put(ndlp);
+	if (ret_val) {
+		ret_val = -ENOMEM;
+		goto out;
+	}
+
+	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) ||
+	    ndlp->nlp_state != NLP_STE_MAPPED_NODE) {
+		ret_val = -ENXIO;
+		goto out;
+	}
+
+	/* Only accept a successful IO or an IO with an underflow status
+	 * because any other FCP RSP error indicates the IO had some other
+	 * error.
+	 */
+	if (status &&
+	    !(status == IOSTAT_FCP_RSP_ERROR && resp_info & RESID_UNDER)) {
+		ret_val = -EIO;
+		goto out;
+	}
+
+	/* No errors.  clear the return value. */
+	ret_val = 0;
+
+	/* Skip over the SGEs and headers to get the response data region. */
+	sgl = (struct sli4_sge *)lpfc_cmd->dma_sgl;
+	sgl += 4;
+	p_data = (struct lpfc_first_burst_page *)(((u32 *)sgl) + 3);
+
+	/* Validate the correct page code response and the number of bytes
+	 * available before reading the first burst size. Initialize
+	 * the first_burst in case the response doesn't have a value.
+	 */
+	ndlp->first_burst = 0;
+	if (p_data->page_code == 0x2 && p_data->page_len == 0xe) {
+		fb = be16_to_cpu(p_data->first_burst);
+		ndlp->first_burst = min((u32)(fb * 512), (u32)LPFC_FCP_FB_MAX);
+	} else {
+		lpfc_printf_vlog(phba->pport, KERN_INFO,
+				 LOG_FCP | LOG_FCP_ERROR,
+				 "6332 Clear first burst value "
+				 "Code x%x Len x%x\n", p_data->page_code,
+				 p_data->page_len);
+	}
+
+	lpfc_printf_vlog(phba->pport, KERN_INFO,
+			 LOG_FCP | LOG_FCP_ERROR,
+			 "6336 FB Rsp: DID x%x Data: x%x x%x x%x x%x x%x x%x "
+			 "x%x\n", ndlp->nlp_DID, fb, ndlp->first_burst,
+			 status, result, resp_info,
+			 lpfc_cmd->cur_iocbq.iocb_flag, ret_val);
+
+	/* Pick up SLI4 exhange busy status from HBA */
+	if (p_io_out->iocb_flag & LPFC_EXCHANGE_BUSY)
+		lpfc_cmd->flags |= LPFC_SBUF_XBUSY;
+	else
+		lpfc_cmd->flags &= ~LPFC_SBUF_XBUSY;
+
+ out:
+	/* Push a driver message only if the IO completion is in error. */
+	if (ret_val)
+		lpfc_printf_vlog(phba->pport, KERN_INFO,
+				 LOG_FCP_UNDER | LOG_FCP_ERROR,
+				 "6331 FB err %d  <x%x/x%x> resp_info x%x\n",
+				 ret_val, status, result, resp_info);
+
+	p_io_in->context2 = NULL;
+	lpfc_cmd->cur_iocbq.iocb_flag &= ~LPFC_IO_DRVR_INIT;
+	lpfc_release_scsi_buf(phba, lpfc_cmd);
+}
+
+/**
+ * lpfc_init_scsi_cmd - Initiatize SCSI command-specific fields.
+ * @vport: The virtual port for which this call being executed.
+ * @lpfc_cmd: The lpfc_io_buf containing this command.
+ * @dev_id - device identifier for this command
+ * @cmd_id:  SCSI command used to format the driver io and CDB
+ * @data_len: Number of bytes available for data.
+ *
+ * This routine initializes an lpfc_io_buf for the specified @cmd_id to
+ * the specified @dev_id for @data_len bytes.
+ *
+ * Returns:
+ *   0 - on success
+ *   A negative error value in the form -Exxxx otherwise.
+ *
+ **/
+static int
+lpfc_init_scsi_cmd(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd,
+		   struct lpfc_scsi_io_req *cmd_req, u32 data_len)
+{
+	int ret = 0;
+	IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
+
+	/* Set command-independent values. */
+	lpfc_cmd->fcp_cmnd->fcpCdb[0] = cmd_req->cmd_id;
+	lpfc_cmd->fcp_cmnd->fcpCdb[4] = data_len;
+	lpfc_cmd->cur_iocbq.iocb_cmpl = cmd_req->cmd_cmpl;
+	lpfc_cmd->fcp_cmnd->fcpDl = cpu_to_be32(data_len);
+	int_to_scsilun(cmd_req->dev_id, &lpfc_cmd->fcp_cmnd->fcp_lun);
+
+	/* SCSI Command specific initialization. */
+	switch (cmd_req->cmd_id) {
+	case MODE_SENSE:
+		/* Send the DISCONNECT-RECONNECT page code */
+		lpfc_cmd->fcp_cmnd->fcpCdb[2] = 0x2;
+		lpfc_cmd->fcp_cmnd->fcpCntl3 = READ_DATA;
+		lpfc_cmd->cur_iocbq.context2 = NULL;
+		iocb_cmd->ulpCommand = CMD_FCP_IREAD64_CR;
+		iocb_cmd->ulpPU = PARM_READ_CHECK;
+		break;
+	default:
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP | LOG_FCP_ERROR,
+				 "6335 Unsupported CMD x%x\n", cmd_req->cmd_id);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+/**
+ * lpfc_issue_scsi_cmd - Send a driver initiated SCSI cmd
+ * @vport: The virtual port for which this call being executed.
+ * @ndlp - Pointer to lpfc_nodelist instance.
+ * @scsi_io_req - pointer to a job structure with the command, device ids,
+ *                and the associated completion routine.
+ *
+ * The driver calls this function to dynamically determine if an FCP
+ * target suppports a particular feature.  The caller needs to specify
+ * what command is needed to what device.
+ *
+ * Returns:
+ *   0 - on success
+ *   A negative error value in the form -Exxxx otherwise.
+ *
+ **/
+int
+lpfc_issue_scsi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+		    struct lpfc_scsi_io_req *cmd_req)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_io_buf *lpfc_cmd = NULL;
+	struct sli4_sge *sgl;
+	dma_addr_t pdma_phys_data;
+	IOCB_t *iocb_cmd;
+	int err = 0;
+
+	/* Requirements must be met. */
+	if (phba->sli_rev != LPFC_SLI_REV4 ||
+	    phba->hba_flag == HBA_FCOE_MODE ||
+	    !phba->pport->cfg_first_burst_size)
+		return -EPERM;
+
+	/* Because the driver potentially sends an FCP and NVME PRLI, the
+	 * caller is required to ensure an FCP PRLI has been successfully
+	 * completed.
+	 */
+	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
+		return -EINVAL;
+
+	lpfc_cmd = lpfc_get_scsi_buf(phba, ndlp, NULL);
+	if (!lpfc_cmd)
+		return -EIO;
+
+	/*
+	 * Every lpfc_io_buf is partially setup for the IO - an FCP Cmd SGE
+	 * and an FCP RSP SGE.  This routine configures two more - one for
+	 * this scsi command and an empty SGE. A 256 byte data area follows
+	 * for the command payload data.
+	 */
+	sgl = (struct sli4_sge *)lpfc_cmd->dma_sgl;
+	sgl++;
+	bf_set(lpfc_sli4_sge_last, sgl, 0);
+	sgl++;
+
+	/* SGE for the SCSI command */
+	pdma_phys_data = lpfc_cmd->dma_handle + (4 * sizeof(struct sli4_sge));
+	sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_data));
+	sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_data));
+	sgl->word2 = le32_to_cpu(sgl->word2);
+	bf_set(lpfc_sli4_sge_last, sgl, 1);
+	bf_set(lpfc_sli4_sge_offset, sgl, 0);
+	bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA);
+	sgl->word2 = cpu_to_le32(sgl->word2);
+	sgl->sge_len = cpu_to_le32(LPFC_DATA_SIZE);
+	sgl++;
+
+	/* Empty SGE.  Clear to prevent stale data errors. */
+	sgl->addr_hi = 0;
+	sgl->addr_lo = 0;
+	sgl->word2 = 0;
+	sgl->sge_len = 0;
+
+	/* Finish prepping the command, response and scsi command. */
+	memset(lpfc_cmd->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
+	memset((void *)lpfc_cmd->fcp_rsp, 0, sizeof(struct fcp_rsp));
+	err = lpfc_init_scsi_cmd(vport, lpfc_cmd, cmd_req, LPFC_DATA_SIZE);
+	if (err) {
+		err = -EPERM;
+		goto out_err;
+	}
+
+	/* This is an FCP IO the driver tracks so don't let it stay
+	 * outstanding forever - provide a generous 16 sec TMO.
+	 */
+	lpfc_cmd->cur_iocbq.iocb_flag |= LPFC_IO_FCP;
+	lpfc_cmd->cur_iocbq.context1 = lpfc_cmd;
+	lpfc_cmd->cur_iocbq.vport = vport;
+	lpfc_cmd->timeout = LPFC_DRVR_TIMEOUT;
+	lpfc_cmd->pCmd = NULL;
+	lpfc_cmd->seg_cnt = 1;
+
+	/* Get an ndlp reference.  Ignore rdata as this IO is driver owned. */
+	lpfc_cmd->ndlp = lpfc_nlp_get(ndlp);
+	if (!lpfc_cmd->ndlp) {
+		err = -EINVAL;
+		goto out_err;
+	}
+
+	iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
+	iocb_cmd->un.fcpi.fcpi_parm = LPFC_DATA_SIZE;
+	iocb_cmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+	if (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)
+		iocb_cmd->ulpFCP2Rcvy = 1;
+	iocb_cmd->ulpClass = (ndlp->nlp_fcp_info & 0x0f);
+	iocb_cmd->ulpTimeout = lpfc_cmd->timeout;
+
+	err = lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, &lpfc_cmd->cur_iocbq,
+				  SLI_IOCB_RET_IOCB);
+	if (err) {
+		err = -EIO;
+		lpfc_nlp_put(ndlp);
+		goto out_err;
+	}
+
+	lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP | LOG_FCP_ERROR,
+			 "6333 Issue cmd x%x to 0x%06x status %d "
+			 "flag x%x iotag x%x xri x%x\n",
+			 cmd_req->cmd_id, ndlp->nlp_DID, err,
+			 lpfc_cmd->cur_iocbq.iocb_flag,
+			 lpfc_cmd->cur_iocbq.iotag,
+			 lpfc_cmd->cur_iocbq.sli4_xritag);
+
+	if (phba->cfg_xri_rebalancing)
+		lpfc_keep_pvt_pool_above_lowwm(phba, lpfc_cmd->hdwq_no);
+	return 0;
+
+ out_err:
+	lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP | LOG_FCP_ERROR,
+			 "6337 Could not issue cmd x%x err %d\n",
+			 cmd_req->cmd_id, err);
+	lpfc_cmd->cur_iocbq.iocb_flag &= ~LPFC_IO_DRVR_INIT;
+	lpfc_cmd->rdata = NULL;
+	lpfc_release_scsi_buf(phba, lpfc_cmd);
+	return err;
+}
 
 /**
  * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h
index f76667b7da7b..964d0081fbb2 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.h
+++ b/drivers/scsi/lpfc/lpfc_scsi.h
@@ -24,6 +24,9 @@
 
 struct lpfc_hba;
 #define LPFC_FCP_CDB_LEN 16
+#define CTRL_ID 0
+#define LPFC_DATA_SIZE 255
+#define LPFC_FCP_FB_MAX 65536
 
 #define list_remove_head(list, entry, type, member)		\
 	do {							\
@@ -130,6 +133,27 @@ struct lpfc_scsicmd_bkt {
 	uint32_t cmd_count;
 };
 
+struct lpfc_scsi_io_req {
+	u32 dev_id;
+	u32 cmd_id;
+	void (*cmd_cmpl)(struct lpfc_hba *phba, struct lpfc_iocbq *p_io_in,
+			 struct lpfc_iocbq *p_io_out);
+};
+
+struct lpfc_first_burst_page {
+	u8 page_code;
+	u8 page_len;
+	u8 buf_full_r;
+	u8 buf_mt_r;
+	__be16 bus_inact_lmt;
+	__be16 disc_tmo;
+	__be16 conn_tmo;
+	__be16 max_burst;
+	u8 byte12;
+	u8 rsvd;
+	__be16 first_burst;
+};
+
 #define LPFC_SCSI_DMA_EXT_SIZE	264
 #define LPFC_BPL_SIZE		1024
 #define MDAC_DIRECT_CMD		0x22
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 1575fccc8b0c..3c61a6d72a1a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -9467,6 +9467,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 	struct lpfc_nodelist *ndlp;
 	uint32_t *pcmd;
 	uint32_t if_type;
+	struct lpfc_io_buf *lpfc_cmd;
 
 	fip = phba->hba_flag & HBA_FIP_SUPPORT;
 	/* The fcp commands will set command type */
@@ -9481,6 +9482,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		memset(wqe, 0, sizeof(union lpfc_wqe128));
 	/* Some of the fields are in the right position already */
 	memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe));
+
 	/* The ct field has moved so reset */
 	wqe->generic.wqe_com.word7 = 0;
 	wqe->generic.wqe_com.word10 = 0;
@@ -9625,6 +9627,14 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		bf_set(wqe_ebde_cnt, &wqe->xmit_bcast64.wqe_com, 0);
 		break;
 	case CMD_FCP_IWRITE64_CR:
+		lpfc_cmd = iocbq->context1;
+
+		/* The ndlp indicates if first burst support is supported. */
+		if (iocbq->iocb_flag & LPFC_IO_LIBDFC)
+			ndlp = iocbq->context_un.ndlp;
+		else
+			ndlp = lpfc_cmd->ndlp;
+
 		command_type = FCP_COMMAND_DATA_OUT;
 		/* word3 iocb=iotag wqe=payload_offset_len */
 		/* Add the FCP_CMD and FCP_RSP sizes to get the offset */
@@ -9632,8 +9642,19 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		       xmit_len + sizeof(struct fcp_rsp));
 		bf_set(cmd_buff_len, &wqe->fcp_iwrite,
 		       0);
-		/* word4 iocb=parameter wqe=total_xfer_length memcpy */
-		/* word5 iocb=initial_xfer_len wqe=initial_xfer_len memcpy */
+
+		/* Set first-burst provided it was successfully negotiated */
+		if (phba->sli_rev == LPFC_SLI_REV4 &&
+		    iocbq->iocb_flag & LPFC_IO_FCP &&
+		    !(phba->hba_flag & HBA_FCOE_MODE) && ndlp->first_burst) {
+			u32 init_len;
+
+			total_len = be32_to_cpu(lpfc_cmd->fcp_cmnd->fcpDl);
+			init_len = min(total_len, ndlp->first_burst);
+			wqe->fcp_iwrite.initial_xfer_len = init_len;
+			wqe->fcp_iwrite.total_xfer_len = total_len;
+		}
+
 		bf_set(wqe_erp, &wqe->fcp_iwrite.wqe_com,
 		       iocbq->iocb.ulpFCP2Rcvy);
 		bf_set(wqe_lnk, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpXS);
@@ -9663,7 +9684,6 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 			bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 0);
 
 		if (phba->fcp_embed_io) {
-			struct lpfc_io_buf *lpfc_cmd;
 			struct sli4_sge *sgl;
 			struct fcp_cmnd *fcp_cmnd;
 			uint32_t *ptr;
@@ -10031,6 +10051,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 	bf_set(wqe_cmnd, &wqe->generic.wqe_com, cmnd);
 	bf_set(wqe_class, &wqe->generic.wqe_com, iocbq->iocb.ulpClass);
 	bf_set(wqe_cqid, &wqe->generic.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
+
 	return 0;
 }
 
@@ -20452,6 +20473,10 @@ void lpfc_release_io_buf(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_ncmd,
 	lpfc_ncmd->cur_iocbq.wqe_cmpl = NULL;
 	lpfc_ncmd->cur_iocbq.iocb_cmpl = NULL;
 
+	/* First Burst initial and total transfer length must be zeroed. */
+	lpfc_ncmd->cur_iocbq.wqe.words[4] = 0;
+	lpfc_ncmd->cur_iocbq.wqe.words[5] = 0;
+
 	if (phba->cfg_xpsgl && !phba->nvmet_support &&
 	    !list_empty(&lpfc_ncmd->dma_sgl_xtra_list))
 		lpfc_put_sgl_per_hdwq(phba, lpfc_ncmd);
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 93d976ea8c5d..d6207974abf4 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -100,6 +100,7 @@ struct lpfc_iocbq {
 #define LPFC_IO_NVME	        0x200000 /* NVME FCP command */
 #define LPFC_IO_NVME_LS		0x400000 /* NVME LS command */
 #define LPFC_IO_NVMET		0x800000 /* NVMET command */
+#define LPFC_IO_DRVR_INIT       0x80000000
 
 	uint32_t drvrTimeout;	/* driver timeout in seconds */
 	struct lpfc_vport *vport;/* virtual port pointer */
