Commit eeb85c65 authored by Justin Tee's avatar Justin Tee Committed by Martin K. Petersen
Browse files

scsi: lpfc: Support loopback tests with VMID enabled



The VMID feature adds an extra application services header to each frame.
As such, the loopback test path is updated to accommodate the extra
application header.

Changes include filling in APPID and WQES bit fields for XMIT_SEQUENCE64
commands, a special loopback source APPID for verifying received loopback
data matches what is sent, and increasing ELS WQ size to accommodate the
APPID field in loopback test mode.

Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20240912232447.45607-8-justintee8345@gmail.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 1af9af1f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3208,6 +3208,9 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job)
	cmdiocbq->num_bdes = num_bde;
	cmdiocbq->cmd_flag |= LPFC_IO_LIBDFC;
	cmdiocbq->cmd_flag |= LPFC_IO_LOOPBACK;
	if (phba->cfg_vmid_app_header)
		cmdiocbq->cmd_flag |= LPFC_IO_VMID;

	cmdiocbq->vport = phba->pport;
	cmdiocbq->cmd_cmpl = NULL;
	cmdiocbq->bpl_dmabuf = txbmp;
+21 −0
Original line number Diff line number Diff line
@@ -561,6 +561,27 @@ struct fc_vft_header {

#include <uapi/scsi/fc/fc_els.h>

/*
 * Application Header
 */
struct fc_app_header {
	uint32_t dst_app_id;
	uint32_t src_app_id;
#define LOOPBACK_SRC_APPID	0x4321
	uint32_t word2;
	uint32_t word3;
};

/*
 * dfctl optional header definition
 */
enum lpfc_fc_dfctl {
	LPFC_FC_NO_DEVICE_HEADER,
	LPFC_FC_16B_DEVICE_HEADER,
	LPFC_FC_32B_DEVICE_HEADER,
	LPFC_FC_64B_DEVICE_HEADER,
};

/*
 *  Extended Link Service LS_COMMAND codes (Payload Word 0)
 */
+9 −2
Original line number Diff line number Diff line
@@ -10451,6 +10451,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
	struct lpfc_vector_map_info *cpup;
	struct lpfc_vector_map_info *eqcpup;
	struct lpfc_eq_intr_info *eqi;
	u32 wqesize;

	/*
	 * Create HBA Record arrays.
@@ -10670,9 +10671,15 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
	 * Create ELS Work Queues
	 */

	/* Create slow-path ELS Work Queue */
	/*
	 * Create slow-path ELS Work Queue.
	 * Increase the ELS WQ size when WQEs contain an embedded cdb
	 */
	wqesize = (phba->fcp_embed_io) ?
			LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize;

	qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
				      phba->sli4_hba.wq_esize,
				      wqesize,
				      phba->sli4_hba.wq_ecount, cpu);
	if (!qdesc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+37 −2
Original line number Diff line number Diff line
@@ -11093,9 +11093,17 @@ __lpfc_sli_prep_xmit_seq64_s4(struct lpfc_iocbq *cmdiocbq,
	/* Word 9 */
	bf_set(wqe_rcvoxid, &wqe->xmit_sequence.wqe_com, ox_id);
	if (cmdiocbq->cmd_flag & (LPFC_IO_LIBDFC | LPFC_IO_LOOPBACK)) {
		/* Word 10 */
		if (cmdiocbq->cmd_flag & LPFC_IO_VMID) {
			bf_set(wqe_appid, &wqe->xmit_sequence.wqe_com, 1);
			bf_set(wqe_wqes, &wqe->xmit_sequence.wqe_com, 1);
			wqe->words[31] = LOOPBACK_SRC_APPID;
		}
		/* Word 12 */
	if (cmdiocbq->cmd_flag & (LPFC_IO_LIBDFC | LPFC_IO_LOOPBACK))
		wqe->xmit_sequence.xmit_len = full_size;
	}
	else
		wqe->xmit_sequence.xmit_len =
			wqe->xmit_sequence.bde.tus.f.bdeSize;
@@ -18434,6 +18442,7 @@ lpfc_fc_frame_check(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr)
{
	/*  make rctl_names static to save stack space */
	struct fc_vft_header *fc_vft_hdr;
	struct fc_app_header *fc_app_hdr;
	uint32_t *header = (uint32_t *) fc_hdr;
#define FC_RCTL_MDS_DIAGS	0xF4
@@ -18489,6 +18498,32 @@ lpfc_fc_frame_check(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr)
		goto drop;
	}
	if (unlikely(phba->link_flag == LS_LOOPBACK_MODE &&
				phba->cfg_vmid_app_header)) {
		/* Application header is 16B device header */
		if (fc_hdr->fh_df_ctl & LPFC_FC_16B_DEVICE_HEADER) {
			fc_app_hdr = (struct fc_app_header *) (fc_hdr + 1);
			if (be32_to_cpu(fc_app_hdr->src_app_id) !=
					LOOPBACK_SRC_APPID) {
				lpfc_printf_log(phba, KERN_WARNING,
						LOG_ELS | LOG_LIBDFC,
						"1932 Loopback src app id "
						"not matched, app_id:x%x\n",
						be32_to_cpu(fc_app_hdr->src_app_id));
				goto drop;
			}
		} else {
			lpfc_printf_log(phba, KERN_WARNING,
					LOG_ELS | LOG_LIBDFC,
					"1933 Loopback df_ctl bit not set, "
					"df_ctl:x%x\n",
					fc_hdr->fh_df_ctl);
			goto drop;
		}
	}
	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
			"2538 Received frame rctl:x%x, type:x%x, "
			"frame Data:%08x %08x %08x %08x %08x %08x %08x\n",