Commit 8aaa7bcf authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: Add FDMI Vendor MIB support

Created new attribute lpfc_enable_mi, which by default is enabled.

Add command definition bits for SLI-4 parameters that recognize whether the
adapter has MIB information support and what revision of MIB data.  Using
the adapter information, register vendor-specific MIB support with FDMI.
The registration will be done every link up.

During FDMI registration, encountered a couple of errors when reverting to
FDMI rev1. Code needed to exist once reverting. Fixed these.

Link: https://lore.kernel.org/r/20201020202719.54726-8-james.smart@broadcom.com


Co-developed-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 7c30bb62
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -745,6 +745,7 @@ struct lpfc_hba {
#define LS_IGNORE_ERATT       0x4	/* intr handler should ignore ERATT */
#define LS_MDS_LINK_DOWN      0x8	/* MDS Diagnostics Link Down */
#define LS_MDS_LOOPBACK       0x10	/* MDS Diagnostics Link Up (Loopback) */
#define LS_CT_VEN_RPA         0x20	/* Vendor RPA sent to switch */

	uint32_t hba_flag;	/* hba generic flags */
#define HBA_ERATT_HANDLED	0x1 /* This flag is set when eratt handled */
@@ -922,6 +923,7 @@ struct lpfc_hba {
#define LPFC_ENABLE_NVME 2
#define LPFC_ENABLE_BOTH 3
	uint32_t cfg_enable_pbde;
	uint32_t cfg_enable_mi;
	struct nvmet_fc_target_port *targetport;
	lpfc_vpd_t vpd;		/* vital product data */

+10 −0
Original line number Diff line number Diff line
@@ -6134,6 +6134,14 @@ LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
 */
LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");

/*
 * lpfc_enable_mi: Enable FDMI MIB
 *       0  = disabled
 *       1  = enabled (default)
 * Value range is [0,1].
 */
LPFC_ATTR_R(enable_mi, 1, 0, 1, "Enable MI");

struct device_attribute *lpfc_hba_attrs[] = {
	&dev_attr_nvme_info,
	&dev_attr_scsi_stat,
@@ -6251,6 +6259,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
	&dev_attr_lpfc_ras_fwlog_func,
	&dev_attr_lpfc_enable_bbcr,
	&dev_attr_lpfc_enable_dpp,
	&dev_attr_lpfc_enable_mi,
	NULL,
};

@@ -7355,6 +7364,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
	lpfc_irq_chann_init(phba, lpfc_irq_chann);
	lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
	lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
	lpfc_enable_mi_init(phba, lpfc_enable_mi);

	if (phba->sli_rev != LPFC_SLI_REV4) {
		/* NVME only supported on SLI4 */
+60 −0
Original line number Diff line number Diff line
@@ -1959,6 +1959,7 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
				vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;
				/* Start over */
				lpfc_fdmi_cmd(vport, ndlp, cmd, 0);
				return;
			}
			if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) {
				vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
@@ -1968,12 +1969,21 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			return;

		case SLI_MGMT_RPA:
			/* No retry on Vendor RPA */
			if (phba->link_flag & LS_CT_VEN_RPA) {
				lpfc_printf_vlog(vport, KERN_ERR,
						 LOG_DISCOVERY | LOG_ELS,
						 "6460 VEN FDMI RPA failure\n");
				phba->link_flag &= ~LS_CT_VEN_RPA;
				return;
			}
			if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) {
				/* Fallback to FDMI-1 */
				vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR;
				vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;
				/* Start over */
				lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0);
				return;
			}
			if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) {
				vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
@@ -2004,6 +2014,33 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
		else
			lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0);
		break;
	case SLI_MGMT_RPA:
		if (vport->port_type == LPFC_PHYSICAL_PORT &&
		    phba->cfg_enable_mi &&
		    phba->sli4_hba.pc_sli4_params.mi_ver > LPFC_MIB1_SUPPORT) {
			/* mi is only for the phyical port, no vports */
			if (phba->link_flag & LS_CT_VEN_RPA) {
				lpfc_printf_vlog(vport, KERN_INFO,
						 LOG_DISCOVERY | LOG_ELS,
						 "6449 VEN RPA Success\n");
				break;
			}

			if (lpfc_fdmi_cmd(vport, ndlp, cmd,
					  LPFC_FDMI_VENDOR_ATTR_mi) == 0)
				phba->link_flag |= LS_CT_VEN_RPA;
			lpfc_printf_vlog(vport, KERN_INFO,
					LOG_DISCOVERY | LOG_ELS,
					"6458 Send MI FDMI:%x Flag x%x\n",
					phba->sli4_hba.pc_sli4_params.mi_value,
					phba->link_flag);
		} else {
			lpfc_printf_vlog(vport, KERN_INFO,
					 LOG_DISCOVERY | LOG_ELS,
					 "6459 No FDMI VEN MI support - "
					 "RPA Success\n");
		}
		break;
	}
	return;
}
@@ -2974,6 +3011,28 @@ lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport,
	return size;
}

int
lpfc_fdmi_vendor_attr_mi(struct lpfc_vport *vport,
			  struct lpfc_fdmi_attr_def *ad)
{
	struct lpfc_hba *phba = vport->phba;
	struct lpfc_fdmi_attr_entry *ae;
	uint32_t len, size;
	char mibrevision[16];

	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
	memset(ae, 0, 256);
	sprintf(mibrevision, "ELXE2EM:%04d",
		phba->sli4_hba.pc_sli4_params.mi_value);
	strncpy(ae->un.AttrString, &mibrevision[0], sizeof(ae->un.AttrString));
	len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
	len += (len & 3) ? (4 - (len & 3)) : 4;
	size = FOURBYTES + len;
	ad->AttrLen = cpu_to_be16(size);
	ad->AttrType = cpu_to_be16(RPRT_VENDOR_MI);
	return size;
}

/* RHBA attribute jump table */
int (*lpfc_fdmi_hba_action[])
	(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = {
@@ -3025,6 +3084,7 @@ int (*lpfc_fdmi_port_action[])
	lpfc_fdmi_smart_attr_port_info,     /* bit20  RPRT_SMART_PORT_INFO    */
	lpfc_fdmi_smart_attr_qos,           /* bit21  RPRT_SMART_QOS          */
	lpfc_fdmi_smart_attr_security,      /* bit22  RPRT_SMART_SECURITY     */
	lpfc_fdmi_vendor_attr_mi,           /* bit23  RPRT_VENDOR_MI          */
};

/**
+6 −0
Original line number Diff line number Diff line
@@ -3335,6 +3335,12 @@ lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry)
		lpfc_els_free_iocb(phba, elsiocb);
		return 1;
	}

	/* Only keep the ndlp if RDF is being sent */
	if (!phba->cfg_enable_mi ||
	    phba->sli4_hba.pc_sli4_params.mi_ver < LPFC_MIB3_SUPPORT)
		return 0;

	/* This will cause the callback-function lpfc_cmpl_els_cmd to
	 * trigger the release of node.
	 */
+4 −2
Original line number Diff line number Diff line
@@ -3205,7 +3205,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
	}

	phba->fc_topology = bf_get(lpfc_mbx_read_top_topology, la);
	phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
	phba->link_flag &= ~(LS_NPIV_FAB_SUPPORTED | LS_CT_VEN_RPA);

	shost = lpfc_shost_from_vport(vport);
	if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
@@ -4133,6 +4133,8 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
		/* Issue SCR just before NameServer GID_FT Query */
		lpfc_issue_els_scr(vport, 0);

		if (!phba->cfg_enable_mi ||
		    phba->sli4_hba.pc_sli4_params.mi_ver < LPFC_MIB3_SUPPORT)
			lpfc_issue_els_rdf(vport, 0);
	}

Loading