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

scsi: lpfc: Add capability to register Platform Name ID to fabric



FC-LS and FC-GS specifications outline fields for registering a platform
name identifier (PNI) to the fabric.  The PNI assists fabrics with
identifying the physical server source of frames in the fabric.

lpfc generates a PNI based partially on the uuid specific for the
system.  Initial attempts to extract a uuid are made from SMBIOS's
System Information 08h uuid entry.  If SMBIOS DMI does not exist, a PNI
is not generated and PNI registration with the fabric is skipped.

The PNI is submitted in FLOGI and FDISC frames.  After successful fabric
login, the RSPNI_PNI CT frame is submitted to the fabric to register the
OS host name tying it to the PNI.

Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Link: https://patch.msgid.link/20251106224639.139176-10-justintee8345@gmail.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 683df5fc
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -633,6 +633,7 @@ struct lpfc_vport {
#define FC_CT_RSPN_ID		0x8	 /* RSPN_ID accepted by switch */
#define FC_CT_RFT_ID		0x10	 /* RFT_ID accepted by switch */
#define FC_CT_RPRT_DEFER	0x20	 /* Defer issuing FDMI RPRT */
#define FC_CT_RSPNI_PNI		0x40	 /* RSPNI_PNI accepted by switch */

	struct list_head fc_nodes;
	spinlock_t fc_nodes_list_lock; /* spinlock for fc_nodes list */
@@ -1077,6 +1078,8 @@ struct lpfc_hba {

	uint32_t nport_event_cnt;	/* timestamp for nlplist entry */

	unsigned long pni;		/* 64-bit Platform Name Identifier */

	uint8_t  wwnn[8];
	uint8_t  wwpn[8];
	uint32_t RandomData[7];
+36 −0
Original line number Diff line number Diff line
@@ -1742,6 +1742,28 @@ lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	return;
}

static void
lpfc_cmpl_ct_cmd_rspni_pni(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			   struct lpfc_iocbq *rspiocb)
{
	struct lpfc_vport *vport;
	struct lpfc_dmabuf *outp;
	struct lpfc_sli_ct_request *ctrsp;
	u32 ulp_status;

	vport = cmdiocb->vport;
	ulp_status = get_job_ulpstatus(phba, rspiocb);

	if (ulp_status == IOSTAT_SUCCESS) {
		outp = cmdiocb->rsp_dmabuf;
		ctrsp = (struct lpfc_sli_ct_request *)outp->virt;
		if (be16_to_cpu(ctrsp->CommandResponse.bits.CmdRsp) ==
		    SLI_CT_RESPONSE_FS_ACC)
			vport->ct_flags |= FC_CT_RSPNI_PNI;
	}
	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
}

static void
lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 struct lpfc_iocbq *rspiocb)
@@ -1956,6 +1978,8 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
		bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;
	else if (cmdcode == SLI_CTNS_RSNN_NN)
		bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
	else if (cmdcode == SLI_CTNS_RSPNI_PNI)
		bpl->tus.f.bdeSize = RSPNI_REQUEST_SZ;
	else if (cmdcode == SLI_CTNS_DA_ID)
		bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;
	else if (cmdcode == SLI_CTNS_RFF_ID)
@@ -2077,6 +2101,18 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
			CtReq->un.rsnn.symbname, size);
		cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
		break;
	case SLI_CTNS_RSPNI_PNI:
		vport->ct_flags &= ~FC_CT_RSPNI_PNI;
		CtReq->CommandResponse.bits.CmdRsp =
		    cpu_to_be16(SLI_CTNS_RSPNI_PNI);
		CtReq->un.rspni.pni = cpu_to_be64(phba->pni);
		scnprintf(CtReq->un.rspni.symbname,
			  sizeof(CtReq->un.rspni.symbname), "OS Host Name::%s",
			  phba->os_host_name);
		CtReq->un.rspni.len = strnlen(CtReq->un.rspni.symbname,
					      sizeof(CtReq->un.rspni.symbname));
		cmpl = lpfc_cmpl_ct_cmd_rspni_pni;
		break;
	case SLI_CTNS_DA_ID:
		/* Implement DA_ID Nameserver request */
		CtReq->CommandResponse.bits.CmdRsp =
+15 −3
Original line number Diff line number Diff line
@@ -650,8 +650,6 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
		ndlp->nlp_class_sup |= FC_COS_CLASS2;
	if (sp->cls3.classValid)
		ndlp->nlp_class_sup |= FC_COS_CLASS3;
	if (sp->cls4.classValid)
		ndlp->nlp_class_sup |= FC_COS_CLASS4;
	ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) |
				sp->cmn.bbRcvSizeLsb;

@@ -1356,6 +1354,14 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
		/* Can't do SLI4 class2 without support sequence coalescing */
		sp->cls2.classValid = 0;
		sp->cls2.seqDelivery = 0;

		/* Fill out Auxiliary Parameter Data */
		if (phba->pni) {
			sp->aux.flags =
				AUX_PARM_DATA_VALID | AUX_PARM_PNI_VALID;
			sp->aux.pni = cpu_to_be64(phba->pni);
			sp->aux.npiv_cnt = cpu_to_be16(phba->max_vpi - 1);
		}
	} else {
		/* Historical, setting sequential-delivery bit for SLI3 */
		sp->cls2.seqDelivery = (sp->cls2.classValid) ? 1 : 0;
@@ -5657,7 +5663,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
			sp->cls1.classValid = 0;
			sp->cls2.classValid = 0;
			sp->cls3.classValid = 0;
			sp->cls4.classValid = 0;

			/* Copy our worldwide names */
			memcpy(&sp->portName, &vport->fc_sparam.portName,
@@ -11510,6 +11515,13 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
	sp->cls2.seqDelivery = 1;
	sp->cls3.seqDelivery = 1;

	/* Fill out Auxiliary Parameter Data */
	if (phba->pni) {
		sp->aux.flags =
			AUX_PARM_DATA_VALID | AUX_PARM_PNI_VALID;
		sp->aux.pni = cpu_to_be64(phba->pni);
	}

	pcmd += sizeof(uint32_t); /* CSP Word 2 */
	pcmd += sizeof(uint32_t); /* CSP Word 3 */
	pcmd += sizeof(uint32_t); /* CSP Word 4 */
+2 −0
Original line number Diff line number Diff line
@@ -4373,6 +4373,8 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
		lpfc_ns_cmd(vport, SLI_CTNS_RNN_ID, 0, 0);
		lpfc_ns_cmd(vport, SLI_CTNS_RSNN_NN, 0, 0);
		lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
		if (phba->pni)
			lpfc_ns_cmd(vport, SLI_CTNS_RSPNI_PNI, 0, 0);
		lpfc_ns_cmd(vport, SLI_CTNS_RFT_ID, 0, 0);

		if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
+24 −1
Original line number Diff line number Diff line
@@ -168,6 +168,11 @@ struct lpfc_sli_ct_request {
			uint8_t len;
			uint8_t symbname[255];
		} rspn;
		struct rspni {	/* For RSPNI_PNI requests */
			__be64 pni;
			u8 len;
			u8 symbname[255];
		} rspni;
		struct gff {
			uint32_t PortId;
		} gff;
@@ -213,6 +218,8 @@ struct lpfc_sli_ct_request {
			  sizeof(struct da_id))
#define  RSPN_REQUEST_SZ  (offsetof(struct lpfc_sli_ct_request, un) + \
			   sizeof(struct rspn))
#define  RSPNI_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
			   sizeof(struct rspni))

/*
 * FsType Definitions
@@ -309,6 +316,7 @@ struct lpfc_sli_ct_request {
#define  SLI_CTNS_RIP_NN      0x0235
#define  SLI_CTNS_RIPA_NN     0x0236
#define  SLI_CTNS_RSNN_NN     0x0239
#define  SLI_CTNS_RSPNI_PNI   0x0240
#define  SLI_CTNS_DA_ID       0x0300

/*
@@ -512,6 +520,21 @@ struct class_parms {
	uint8_t word3Reserved2;	/* Fc Word 3, bit  0: 7 */
};

enum aux_parm_flags {
	AUX_PARM_PNI_VALID = 0x20,	/* FC Word 0, bit 29 */
	AUX_PARM_DATA_VALID = 0x40,	/* FC Word 0, bit 30 */
};

struct aux_parm {
	u8 flags;	/* FC Word 0, bit 31:24 */
	u8 ext_feat[3];	/* FC Word 0, bit 23:0 */

	__be64 pni;	/* FC Word 1 and 2, platform name identifier */

	__be16 rsvd;	/* FC Word 3, bit 31:16 */
	__be16 npiv_cnt;	/* FC Word 3, bit 15:0 */
} __packed;

struct serv_parm {	/* Structure is in Big Endian format */
	struct csp cmn;
	struct lpfc_name portName;
@@ -519,7 +542,7 @@ struct serv_parm { /* Structure is in Big Endian format */
	struct class_parms cls1;
	struct class_parms cls2;
	struct class_parms cls3;
	struct class_parms cls4;
	struct aux_parm aux;
	union {
		uint8_t vendorVersion[16];
		struct {
Loading