Skip to content

Commit 191da2c

Browse files
Justin Teemartinkpetersen
authored andcommitted
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: Justin Tee <justin.tee@broadcom.com> Link: https://patch.msgid.link/20251106224639.139176-10-justintee8345@gmail.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 683df5f commit 191da2c

7 files changed

Lines changed: 150 additions & 8 deletions

File tree

drivers/scsi/lpfc/lpfc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ struct lpfc_vport {
633633
#define FC_CT_RSPN_ID 0x8 /* RSPN_ID accepted by switch */
634634
#define FC_CT_RFT_ID 0x10 /* RFT_ID accepted by switch */
635635
#define FC_CT_RPRT_DEFER 0x20 /* Defer issuing FDMI RPRT */
636+
#define FC_CT_RSPNI_PNI 0x40 /* RSPNI_PNI accepted by switch */
636637

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

10781079
uint32_t nport_event_cnt; /* timestamp for nlplist entry */
10791080

1081+
unsigned long pni; /* 64-bit Platform Name Identifier */
1082+
10801083
uint8_t wwnn[8];
10811084
uint8_t wwpn[8];
10821085
uint32_t RandomData[7];

drivers/scsi/lpfc/lpfc_ct.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,6 +1742,28 @@ lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
17421742
return;
17431743
}
17441744

1745+
static void
1746+
lpfc_cmpl_ct_cmd_rspni_pni(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1747+
struct lpfc_iocbq *rspiocb)
1748+
{
1749+
struct lpfc_vport *vport;
1750+
struct lpfc_dmabuf *outp;
1751+
struct lpfc_sli_ct_request *ctrsp;
1752+
u32 ulp_status;
1753+
1754+
vport = cmdiocb->vport;
1755+
ulp_status = get_job_ulpstatus(phba, rspiocb);
1756+
1757+
if (ulp_status == IOSTAT_SUCCESS) {
1758+
outp = cmdiocb->rsp_dmabuf;
1759+
ctrsp = (struct lpfc_sli_ct_request *)outp->virt;
1760+
if (be16_to_cpu(ctrsp->CommandResponse.bits.CmdRsp) ==
1761+
SLI_CT_RESPONSE_FS_ACC)
1762+
vport->ct_flags |= FC_CT_RSPNI_PNI;
1763+
}
1764+
lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
1765+
}
1766+
17451767
static void
17461768
lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
17471769
struct lpfc_iocbq *rspiocb)
@@ -1956,6 +1978,8 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
19561978
bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;
19571979
else if (cmdcode == SLI_CTNS_RSNN_NN)
19581980
bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
1981+
else if (cmdcode == SLI_CTNS_RSPNI_PNI)
1982+
bpl->tus.f.bdeSize = RSPNI_REQUEST_SZ;
19591983
else if (cmdcode == SLI_CTNS_DA_ID)
19601984
bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;
19611985
else if (cmdcode == SLI_CTNS_RFF_ID)
@@ -2077,6 +2101,18 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
20772101
CtReq->un.rsnn.symbname, size);
20782102
cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
20792103
break;
2104+
case SLI_CTNS_RSPNI_PNI:
2105+
vport->ct_flags &= ~FC_CT_RSPNI_PNI;
2106+
CtReq->CommandResponse.bits.CmdRsp =
2107+
cpu_to_be16(SLI_CTNS_RSPNI_PNI);
2108+
CtReq->un.rspni.pni = cpu_to_be64(phba->pni);
2109+
scnprintf(CtReq->un.rspni.symbname,
2110+
sizeof(CtReq->un.rspni.symbname), "OS Host Name::%s",
2111+
phba->os_host_name);
2112+
CtReq->un.rspni.len = strnlen(CtReq->un.rspni.symbname,
2113+
sizeof(CtReq->un.rspni.symbname));
2114+
cmpl = lpfc_cmpl_ct_cmd_rspni_pni;
2115+
break;
20802116
case SLI_CTNS_DA_ID:
20812117
/* Implement DA_ID Nameserver request */
20822118
CtReq->CommandResponse.bits.CmdRsp =

drivers/scsi/lpfc/lpfc_els.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,8 +650,6 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
650650
ndlp->nlp_class_sup |= FC_COS_CLASS2;
651651
if (sp->cls3.classValid)
652652
ndlp->nlp_class_sup |= FC_COS_CLASS3;
653-
if (sp->cls4.classValid)
654-
ndlp->nlp_class_sup |= FC_COS_CLASS4;
655653
ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) |
656654
sp->cmn.bbRcvSizeLsb;
657655

@@ -1356,6 +1354,14 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
13561354
/* Can't do SLI4 class2 without support sequence coalescing */
13571355
sp->cls2.classValid = 0;
13581356
sp->cls2.seqDelivery = 0;
1357+
1358+
/* Fill out Auxiliary Parameter Data */
1359+
if (phba->pni) {
1360+
sp->aux.flags =
1361+
AUX_PARM_DATA_VALID | AUX_PARM_PNI_VALID;
1362+
sp->aux.pni = cpu_to_be64(phba->pni);
1363+
sp->aux.npiv_cnt = cpu_to_be16(phba->max_vpi - 1);
1364+
}
13591365
} else {
13601366
/* Historical, setting sequential-delivery bit for SLI3 */
13611367
sp->cls2.seqDelivery = (sp->cls2.classValid) ? 1 : 0;
@@ -5657,7 +5663,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
56575663
sp->cls1.classValid = 0;
56585664
sp->cls2.classValid = 0;
56595665
sp->cls3.classValid = 0;
5660-
sp->cls4.classValid = 0;
56615666

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

11518+
/* Fill out Auxiliary Parameter Data */
11519+
if (phba->pni) {
11520+
sp->aux.flags =
11521+
AUX_PARM_DATA_VALID | AUX_PARM_PNI_VALID;
11522+
sp->aux.pni = cpu_to_be64(phba->pni);
11523+
}
11524+
1151311525
pcmd += sizeof(uint32_t); /* CSP Word 2 */
1151411526
pcmd += sizeof(uint32_t); /* CSP Word 3 */
1151511527
pcmd += sizeof(uint32_t); /* CSP Word 4 */

drivers/scsi/lpfc/lpfc_hbadisc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4373,6 +4373,8 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
43734373
lpfc_ns_cmd(vport, SLI_CTNS_RNN_ID, 0, 0);
43744374
lpfc_ns_cmd(vport, SLI_CTNS_RSNN_NN, 0, 0);
43754375
lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
4376+
if (phba->pni)
4377+
lpfc_ns_cmd(vport, SLI_CTNS_RSPNI_PNI, 0, 0);
43764378
lpfc_ns_cmd(vport, SLI_CTNS_RFT_ID, 0, 0);
43774379

43784380
if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||

drivers/scsi/lpfc/lpfc_hw.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,11 @@ struct lpfc_sli_ct_request {
168168
uint8_t len;
169169
uint8_t symbname[255];
170170
} rspn;
171+
struct rspni { /* For RSPNI_PNI requests */
172+
__be64 pni;
173+
u8 len;
174+
u8 symbname[255];
175+
} rspni;
171176
struct gff {
172177
uint32_t PortId;
173178
} gff;
@@ -213,6 +218,8 @@ struct lpfc_sli_ct_request {
213218
sizeof(struct da_id))
214219
#define RSPN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
215220
sizeof(struct rspn))
221+
#define RSPNI_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
222+
sizeof(struct rspni))
216223

217224
/*
218225
* FsType Definitions
@@ -309,6 +316,7 @@ struct lpfc_sli_ct_request {
309316
#define SLI_CTNS_RIP_NN 0x0235
310317
#define SLI_CTNS_RIPA_NN 0x0236
311318
#define SLI_CTNS_RSNN_NN 0x0239
319+
#define SLI_CTNS_RSPNI_PNI 0x0240
312320
#define SLI_CTNS_DA_ID 0x0300
313321

314322
/*
@@ -512,14 +520,29 @@ struct class_parms {
512520
uint8_t word3Reserved2; /* Fc Word 3, bit 0: 7 */
513521
};
514522

523+
enum aux_parm_flags {
524+
AUX_PARM_PNI_VALID = 0x20, /* FC Word 0, bit 29 */
525+
AUX_PARM_DATA_VALID = 0x40, /* FC Word 0, bit 30 */
526+
};
527+
528+
struct aux_parm {
529+
u8 flags; /* FC Word 0, bit 31:24 */
530+
u8 ext_feat[3]; /* FC Word 0, bit 23:0 */
531+
532+
__be64 pni; /* FC Word 1 and 2, platform name identifier */
533+
534+
__be16 rsvd; /* FC Word 3, bit 31:16 */
535+
__be16 npiv_cnt; /* FC Word 3, bit 15:0 */
536+
} __packed;
537+
515538
struct serv_parm { /* Structure is in Big Endian format */
516539
struct csp cmn;
517540
struct lpfc_name portName;
518541
struct lpfc_name nodeName;
519542
struct class_parms cls1;
520543
struct class_parms cls2;
521544
struct class_parms cls3;
522-
struct class_parms cls4;
545+
struct aux_parm aux;
523546
union {
524547
uint8_t vendorVersion[16];
525548
struct {

drivers/scsi/lpfc/lpfc_nportdisc.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,6 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
432432
ndlp->nlp_class_sup |= FC_COS_CLASS2;
433433
if (sp->cls3.classValid)
434434
ndlp->nlp_class_sup |= FC_COS_CLASS3;
435-
if (sp->cls4.classValid)
436-
ndlp->nlp_class_sup |= FC_COS_CLASS4;
437435
ndlp->nlp_maxframe =
438436
((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
439437
/* if already logged in, do implicit logout */
@@ -1417,8 +1415,6 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
14171415
ndlp->nlp_class_sup |= FC_COS_CLASS2;
14181416
if (sp->cls3.classValid)
14191417
ndlp->nlp_class_sup |= FC_COS_CLASS3;
1420-
if (sp->cls4.classValid)
1421-
ndlp->nlp_class_sup |= FC_COS_CLASS4;
14221418
ndlp->nlp_maxframe =
14231419
((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
14241420

drivers/scsi/lpfc/lpfc_sli.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include <linux/delay.h>
2828
#include <linux/slab.h>
2929
#include <linux/lockdep.h>
30+
#include <linux/dmi.h>
31+
#include <linux/of.h>
3032

3133
#include <scsi/scsi.h>
3234
#include <scsi/scsi_cmnd.h>
@@ -8446,6 +8448,70 @@ lpfc_set_host_tm(struct lpfc_hba *phba)
84468448
return rc;
84478449
}
84488450

8451+
/**
8452+
* lpfc_get_platform_uuid - Attempts to extract a platform uuid
8453+
* @phba: pointer to lpfc hba data structure.
8454+
*
8455+
* This routine attempts to first read SMBIOS DMI data for the System
8456+
* Information structure offset 08h called System UUID. Else, no platform
8457+
* UUID will be advertised.
8458+
**/
8459+
static void
8460+
lpfc_get_platform_uuid(struct lpfc_hba *phba)
8461+
{
8462+
int rc;
8463+
const char *uuid;
8464+
char pni[17] = {0}; /* 16 characters + '\0' */
8465+
bool is_ff = true, is_00 = true;
8466+
u8 i;
8467+
8468+
/* First attempt SMBIOS DMI */
8469+
uuid = dmi_get_system_info(DMI_PRODUCT_UUID);
8470+
if (uuid) {
8471+
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
8472+
"2088 SMBIOS UUID %s\n",
8473+
uuid);
8474+
} else {
8475+
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
8476+
"2099 Could not extract UUID\n");
8477+
}
8478+
8479+
if (uuid && uuid_is_valid(uuid)) {
8480+
/* Generate PNI from UUID format.
8481+
*
8482+
* 1.) Extract lower 64 bits from UUID format.
8483+
* 2.) Set 3h for NAA Locally Assigned Name Identifier format.
8484+
*
8485+
* e.g. xxxxxxxx-xxxx-xxxx-yyyy-yyyyyyyyyyyy
8486+
*
8487+
* extract the yyyy-yyyyyyyyyyyy portion
8488+
* final PNI 3yyyyyyyyyyyyyyy
8489+
*/
8490+
scnprintf(pni, sizeof(pni), "3%c%c%c%s",
8491+
uuid[20], uuid[21], uuid[22], &uuid[24]);
8492+
8493+
/* Sanitize the converted PNI */
8494+
for (i = 1; i < 16 && (is_ff || is_00); i++) {
8495+
if (pni[i] != '0')
8496+
is_00 = false;
8497+
if (pni[i] != 'f' && pni[i] != 'F')
8498+
is_ff = false;
8499+
}
8500+
8501+
/* Convert from char* to unsigned long */
8502+
rc = kstrtoul(pni, 16, &phba->pni);
8503+
if (!rc && !is_ff && !is_00) {
8504+
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
8505+
"2100 PNI 0x%016lx\n", phba->pni);
8506+
} else {
8507+
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
8508+
"2101 PNI %s generation status %d\n",
8509+
pni, rc);
8510+
phba->pni = 0;
8511+
}
8512+
}
8513+
}
8514+
84498515
/**
84508516
* lpfc_sli4_hba_setup - SLI4 device initialization PCI function
84518517
* @phba: Pointer to HBA context object.
@@ -8529,6 +8595,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
85298595
clear_bit(HBA_FCOE_MODE, &phba->hba_flag);
85308596
}
85318597

8598+
/* Obtain platform UUID, only for SLI4 FC adapters */
8599+
if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag))
8600+
lpfc_get_platform_uuid(phba);
8601+
85328602
if (bf_get(lpfc_mbx_rd_rev_cee_ver, &mqe->un.read_rev) ==
85338603
LPFC_DCBX_CEE_MODE)
85348604
set_bit(HBA_FIP_SUPPORT, &phba->hba_flag);

0 commit comments

Comments
 (0)