diff options
author | James Smart <james.smart@broadcom.com> | 2020-10-20 22:27:17 +0200 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2020-10-27 02:42:39 +0100 |
commit | 8aaa7bcf07a2eea5ffb6d4ee776379c0e0154f6d (patch) | |
tree | 334da3c78e9e8b7d765e0cdd4a93b75a1faf8bab | |
parent | scsi: lpfc: Enlarge max_sectors in scsi host templates (diff) | |
download | linux-8aaa7bcf07a2eea5ffb6d4ee776379c0e0154f6d.tar.xz linux-8aaa7bcf07a2eea5ffb6d4ee776379c0e0154f6d.zip |
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: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <james.smart@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 4 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 10 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 60 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 4 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 10 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 15 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 8 |
9 files changed, 117 insertions, 6 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 93e507677bdc..3c77e02d36b0 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -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 */ diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 2d810474875c..0673d944c2a8 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -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 */ diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index a8bf4d0d58f0..434e39d173da 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -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 */ }; /** diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index b60945182db8..de3a59f2e3df 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -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. */ diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 9746d2f4fcfa..c61eb6032500 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -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 @@ out: /* 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; diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index c20034b3101c..28b8a394f796 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -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 diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 12e4e76233e6..49f5559f5fed 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -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; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index e5879dc0cc8c..aa7931a1750f 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -12314,6 +12314,21 @@ fcponly: 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; } diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 100cb1a94811..26f19c95380f 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -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; |