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

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.comCo-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
......@@ -744,7 +744,8 @@ struct lpfc_hba {
#define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */
#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_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 */
......
......@@ -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 */
......
......@@ -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 */
};
/**
......
......@@ -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.
*/
......
......@@ -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,7 +4133,9 @@ 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);
lpfc_issue_els_rdf(vport, 0);
if (!phba->cfg_enable_mi ||
phba->sli4_hba.pc_sli4_params.mi_ver < LPFC_MIB3_SUPPORT)
lpfc_issue_els_rdf(vport, 0);
}
vport->fc_ns_retry = 0;
......
......@@ -1465,7 +1465,7 @@ struct lpfc_fdmi_reg_portattr {
#define LPFC_FDMI2_HBA_ATTR 0x0002efff
/*
* Port Attrubute Types
* Port Attribute Types
*/
#define RPRT_SUPPORTED_FC4_TYPES 0x1 /* 32 byte binary array */
#define RPRT_SUPPORTED_SPEED 0x2 /* 32-bit unsigned int */
......@@ -1483,6 +1483,7 @@ struct lpfc_fdmi_reg_portattr {
#define RPRT_PORT_STATE 0x101 /* 32-bit unsigned int */
#define RPRT_DISC_PORT 0x102 /* 32-bit unsigned int */
#define RPRT_PORT_ID 0x103 /* 32-bit unsigned int */
#define RPRT_VENDOR_MI 0xf047 /* vendor ascii string */
#define RPRT_SMART_SERVICE 0xf100 /* 4 to 256 byte ASCII string */
#define RPRT_SMART_GUID 0xf101 /* 8 byte WWNN + 8 byte WWPN */
#define RPRT_SMART_VERSION 0xf102 /* 4 to 256 byte ASCII string */
......@@ -1515,6 +1516,7 @@ struct lpfc_fdmi_reg_portattr {
#define LPFC_FDMI_SMART_ATTR_port_info 0x00100000 /* Vendor specific */
#define LPFC_FDMI_SMART_ATTR_qos 0x00200000 /* Vendor specific */
#define LPFC_FDMI_SMART_ATTR_security 0x00400000 /* Vendor specific */
#define LPFC_FDMI_VENDOR_ATTR_mi 0x00800000 /* Vendor specific */
/* Bit mask for FDMI-1 defined PORT attributes */
#define LPFC_FDMI1_PORT_ATTR 0x0000003f
......
......@@ -3506,8 +3506,14 @@ struct lpfc_sli4_parameters {
#define cfg_max_tow_xri_MASK 0x0000ffff
#define cfg_max_tow_xri_WORD word20
uint32_t word21; /* RESERVED */
uint32_t word22; /* RESERVED */
uint32_t word21;
#define cfg_mib_bde_cnt_SHIFT 16
#define cfg_mib_bde_cnt_MASK 0x000000ff
#define cfg_mib_bde_cnt_WORD word21
#define cfg_mi_ver_SHIFT 0
#define cfg_mi_ver_MASK 0x0000ffff
#define cfg_mi_ver_WORD word21
uint32_t mib_size;
uint32_t word23; /* RESERVED */
uint32_t word24;
......
......@@ -12314,6 +12314,21 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
else
phba->nsler = 0;
/* Save PB info for use during HBA setup */
sli4_params->mi_ver = bf_get(cfg_mi_ver, mbx_sli4_parameters);
sli4_params->mib_bde_cnt = bf_get(cfg_mib_bde_cnt, mbx_sli4_parameters);
sli4_params->mib_size = mbx_sli4_parameters->mib_size;
sli4_params->mi_value = LPFC_DFLT_MIB_VAL;
/* Next we check for Vendor MIB support */
if (sli4_params->mi_ver && phba->cfg_enable_mi)
phba->cfg_fdmi_on = LPFC_FDMI_SUPPORT;
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"6461 MIB attr %d enable %d FDMI %d buf %d:%d\n",
sli4_params->mi_ver, phba->cfg_enable_mi,
sli4_params->mi_value, sli4_params->mib_bde_cnt,
sli4_params->mib_size);
return 0;
}
......
......@@ -549,6 +549,14 @@ struct lpfc_pc_sli4_params {
uint32_t hdr_pp_align;
uint32_t sgl_pages_max;
uint32_t sgl_pp_align;
uint32_t mib_size;
uint16_t mi_ver;
#define LPFC_MIB1_SUPPORT 1
#define LPFC_MIB2_SUPPORT 2
#define LPFC_MIB3_SUPPORT 3
uint16_t mi_value;
#define LPFC_DFLT_MIB_VAL 2
uint8_t mib_bde_cnt;
uint8_t cqv;
uint8_t mqv;
uint8_t wqv;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment