mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
scsi: lpfc: Change FA-PWWN detection methodology
Do not rely on vendor version field of the CSPs to determine if we are in a FA-PWWN environment. Instead, use the following procedure: First, during HBA initialization, driver does a READ_CONFIG to determine if FA-PWWN is configured on the HBA. A LPFC_FAWWPN_CONFIG hba_flag is set accordingly. Next, when the link comes up before the driver gets a link up event, the firmware logs into the fabric with FA-PWWN. If the fabric port does not support FA-PWWN, the driver will get a Misconfigured FA-WWN async event before the link up. A LPFC_FAWWPN_FABRIC hba_flag will be set accordingly. Finally, if the fabric supports FA-PWWN, the firmware will replace its CSPs WWN with the Fabric Assigned ones. Then after link up, the driver will retrieve the Fabric Assigned WWN when it does a READ_SPARAM mbox command. Link: https://lore.kernel.org/r/20220412222008.126521-23-jsmart2021@gmail.com Co-developed-by: Justin Tee <justin.tee@broadcom.com> Signed-off-by: Justin Tee <justin.tee@broadcom.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
ef47575fd9
commit
1b6f71f7fc
8 changed files with 86 additions and 26 deletions
|
@ -739,9 +739,8 @@ struct lpfc_vport {
|
||||||
struct list_head rcv_buffer_list;
|
struct list_head rcv_buffer_list;
|
||||||
unsigned long rcv_buffer_time_stamp;
|
unsigned long rcv_buffer_time_stamp;
|
||||||
uint32_t vport_flag;
|
uint32_t vport_flag;
|
||||||
#define STATIC_VPORT 1
|
#define STATIC_VPORT 0x1
|
||||||
#define FAWWPN_SET 2
|
#define FAWWPN_PARAM_CHG 0x2
|
||||||
#define FAWWPN_PARAM_CHG 4
|
|
||||||
|
|
||||||
uint16_t fdmi_num_disc;
|
uint16_t fdmi_num_disc;
|
||||||
uint32_t fdmi_hba_mask;
|
uint32_t fdmi_hba_mask;
|
||||||
|
|
|
@ -1120,14 +1120,24 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
|
||||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
len += scnprintf(buf + len, PAGE_SIZE-len,
|
||||||
" Private Loop\n");
|
" Private Loop\n");
|
||||||
} else {
|
} else {
|
||||||
if (vport->fc_flag & FC_FABRIC)
|
if (vport->fc_flag & FC_FABRIC) {
|
||||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
if (phba->sli_rev == LPFC_SLI_REV4 &&
|
||||||
" Fabric\n");
|
vport->port_type == LPFC_PHYSICAL_PORT &&
|
||||||
|
phba->sli4_hba.fawwpn_flag &
|
||||||
|
LPFC_FAWWPN_FABRIC)
|
||||||
|
len += scnprintf(buf + len,
|
||||||
|
PAGE_SIZE - len,
|
||||||
|
" Fabric FA-PWWN\n");
|
||||||
else
|
else
|
||||||
|
len += scnprintf(buf + len,
|
||||||
|
PAGE_SIZE - len,
|
||||||
|
" Fabric\n");
|
||||||
|
} else {
|
||||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
len += scnprintf(buf + len, PAGE_SIZE-len,
|
||||||
" Point-2-Point\n");
|
" Point-2-Point\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((phba->sli_rev == LPFC_SLI_REV4) &&
|
if ((phba->sli_rev == LPFC_SLI_REV4) &&
|
||||||
((bf_get(lpfc_sli_intf_if_type,
|
((bf_get(lpfc_sli_intf_if_type,
|
||||||
|
|
|
@ -1183,6 +1183,7 @@ lpfc_port_link_failure(struct lpfc_vport *vport)
|
||||||
void
|
void
|
||||||
lpfc_linkdown_port(struct lpfc_vport *vport)
|
lpfc_linkdown_port(struct lpfc_vport *vport)
|
||||||
{
|
{
|
||||||
|
struct lpfc_hba *phba = vport->phba;
|
||||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||||
|
|
||||||
if (vport->cfg_enable_fc4_type != LPFC_ENABLE_NVME)
|
if (vport->cfg_enable_fc4_type != LPFC_ENABLE_NVME)
|
||||||
|
@ -1200,6 +1201,13 @@ lpfc_linkdown_port(struct lpfc_vport *vport)
|
||||||
vport->fc_flag &= ~FC_DISC_DELAYED;
|
vport->fc_flag &= ~FC_DISC_DELAYED;
|
||||||
spin_unlock_irq(shost->host_lock);
|
spin_unlock_irq(shost->host_lock);
|
||||||
del_timer_sync(&vport->delayed_disc_tmo);
|
del_timer_sync(&vport->delayed_disc_tmo);
|
||||||
|
|
||||||
|
if (phba->sli_rev == LPFC_SLI_REV4 &&
|
||||||
|
vport->port_type == LPFC_PHYSICAL_PORT &&
|
||||||
|
phba->sli4_hba.fawwpn_flag & LPFC_FAWWPN_CONFIG) {
|
||||||
|
/* Assume success on link up */
|
||||||
|
phba->sli4_hba.fawwpn_flag |= LPFC_FAWWPN_FABRIC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -511,8 +511,6 @@ struct class_parms {
|
||||||
uint8_t word3Reserved2; /* Fc Word 3, bit 0: 7 */
|
uint8_t word3Reserved2; /* Fc Word 3, bit 0: 7 */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FAPWWN_KEY_VENDOR 0x42524344 /*valid vendor version fawwpn key*/
|
|
||||||
|
|
||||||
struct serv_parm { /* Structure is in Big Endian format */
|
struct serv_parm { /* Structure is in Big Endian format */
|
||||||
struct csp cmn;
|
struct csp cmn;
|
||||||
struct lpfc_name portName;
|
struct lpfc_name portName;
|
||||||
|
|
|
@ -2893,6 +2893,9 @@ struct lpfc_mbx_read_config {
|
||||||
#define lpfc_mbx_rd_conf_extnts_inuse_SHIFT 31
|
#define lpfc_mbx_rd_conf_extnts_inuse_SHIFT 31
|
||||||
#define lpfc_mbx_rd_conf_extnts_inuse_MASK 0x00000001
|
#define lpfc_mbx_rd_conf_extnts_inuse_MASK 0x00000001
|
||||||
#define lpfc_mbx_rd_conf_extnts_inuse_WORD word1
|
#define lpfc_mbx_rd_conf_extnts_inuse_WORD word1
|
||||||
|
#define lpfc_mbx_rd_conf_fawwpn_SHIFT 30
|
||||||
|
#define lpfc_mbx_rd_conf_fawwpn_MASK 0x00000001
|
||||||
|
#define lpfc_mbx_rd_conf_fawwpn_WORD word1
|
||||||
#define lpfc_mbx_rd_conf_wcs_SHIFT 28 /* warning signaling */
|
#define lpfc_mbx_rd_conf_wcs_SHIFT 28 /* warning signaling */
|
||||||
#define lpfc_mbx_rd_conf_wcs_MASK 0x00000001
|
#define lpfc_mbx_rd_conf_wcs_MASK 0x00000001
|
||||||
#define lpfc_mbx_rd_conf_wcs_WORD word1
|
#define lpfc_mbx_rd_conf_wcs_WORD word1
|
||||||
|
|
|
@ -350,8 +350,7 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
|
||||||
void
|
void
|
||||||
lpfc_update_vport_wwn(struct lpfc_vport *vport)
|
lpfc_update_vport_wwn(struct lpfc_vport *vport)
|
||||||
{
|
{
|
||||||
uint8_t vvvl = vport->fc_sparam.cmn.valid_vendor_ver_level;
|
struct lpfc_hba *phba = vport->phba;
|
||||||
u32 *fawwpn_key = (u32 *)&vport->fc_sparam.un.vendorVersion[0];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the name is empty or there exists a soft name
|
* If the name is empty or there exists a soft name
|
||||||
|
@ -370,18 +369,29 @@ lpfc_update_vport_wwn(struct lpfc_vport *vport)
|
||||||
*/
|
*/
|
||||||
if (vport->fc_portname.u.wwn[0] != 0 &&
|
if (vport->fc_portname.u.wwn[0] != 0 &&
|
||||||
memcmp(&vport->fc_portname, &vport->fc_sparam.portName,
|
memcmp(&vport->fc_portname, &vport->fc_sparam.portName,
|
||||||
sizeof(struct lpfc_name)))
|
sizeof(struct lpfc_name))) {
|
||||||
vport->vport_flag |= FAWWPN_PARAM_CHG;
|
vport->vport_flag |= FAWWPN_PARAM_CHG;
|
||||||
|
|
||||||
if (vport->fc_portname.u.wwn[0] == 0 ||
|
if (phba->sli_rev == LPFC_SLI_REV4 &&
|
||||||
(vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR) ||
|
vport->port_type == LPFC_PHYSICAL_PORT &&
|
||||||
vport->vport_flag & FAWWPN_SET) {
|
phba->sli4_hba.fawwpn_flag & LPFC_FAWWPN_FABRIC) {
|
||||||
|
lpfc_printf_log(phba, KERN_INFO,
|
||||||
|
LOG_SLI | LOG_DISCOVERY | LOG_ELS,
|
||||||
|
"2701 FA-PWWN change WWPN from %llx to "
|
||||||
|
"%llx: vflag x%x fawwpn_flag x%x\n",
|
||||||
|
wwn_to_u64(vport->fc_portname.u.wwn),
|
||||||
|
wwn_to_u64
|
||||||
|
(vport->fc_sparam.portName.u.wwn),
|
||||||
|
vport->vport_flag,
|
||||||
|
phba->sli4_hba.fawwpn_flag);
|
||||||
memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
|
memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
|
||||||
sizeof(struct lpfc_name));
|
sizeof(struct lpfc_name));
|
||||||
vport->vport_flag &= ~FAWWPN_SET;
|
|
||||||
if (vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR)
|
|
||||||
vport->vport_flag |= FAWWPN_SET;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vport->fc_portname.u.wwn[0] == 0)
|
||||||
|
memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
|
||||||
|
sizeof(struct lpfc_name));
|
||||||
else
|
else
|
||||||
memcpy(&vport->fc_sparam.portName, &vport->fc_portname,
|
memcpy(&vport->fc_sparam.portName, &vport->fc_portname,
|
||||||
sizeof(struct lpfc_name));
|
sizeof(struct lpfc_name));
|
||||||
|
@ -6542,12 +6552,15 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli)
|
||||||
case LPFC_SLI_EVENT_TYPE_MISCONF_FAWWN:
|
case LPFC_SLI_EVENT_TYPE_MISCONF_FAWWN:
|
||||||
/* Misconfigured WWN. Reports that the SLI Port is configured
|
/* Misconfigured WWN. Reports that the SLI Port is configured
|
||||||
* to use FA-WWN, but the attached device doesn’t support it.
|
* to use FA-WWN, but the attached device doesn’t support it.
|
||||||
* No driver action is required.
|
|
||||||
* Event Data1 - N.A, Event Data2 - N.A
|
* Event Data1 - N.A, Event Data2 - N.A
|
||||||
|
* This event only happens on the physical port.
|
||||||
*/
|
*/
|
||||||
lpfc_log_msg(phba, KERN_WARNING, LOG_SLI,
|
lpfc_log_msg(phba, KERN_WARNING, LOG_SLI | LOG_DISCOVERY,
|
||||||
"2699 Misconfigured FA-WWN - Attached device does "
|
"2699 Misconfigured FA-PWWN - Attached device "
|
||||||
"not support FA-WWN\n");
|
"does not support FA-PWWN\n");
|
||||||
|
phba->sli4_hba.fawwpn_flag &= ~LPFC_FAWWPN_FABRIC;
|
||||||
|
memset(phba->pport->fc_portname.u.wwn, 0,
|
||||||
|
sizeof(struct lpfc_name));
|
||||||
break;
|
break;
|
||||||
case LPFC_SLI_EVENT_TYPE_EEPROM_FAILURE:
|
case LPFC_SLI_EVENT_TYPE_EEPROM_FAILURE:
|
||||||
/* EEPROM failure. No driver action is required */
|
/* EEPROM failure. No driver action is required */
|
||||||
|
@ -8004,6 +8017,18 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
|
||||||
rc = lpfc_sli4_read_config(phba);
|
rc = lpfc_sli4_read_config(phba);
|
||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
goto out_free_bsmbx;
|
goto out_free_bsmbx;
|
||||||
|
|
||||||
|
if (phba->sli4_hba.fawwpn_flag & LPFC_FAWWPN_CONFIG) {
|
||||||
|
/* Right now the link is down, if FA-PWWN is configured the
|
||||||
|
* firmware will try FLOGI before the driver gets a link up.
|
||||||
|
* If it fails, the driver should get a MISCONFIGURED async
|
||||||
|
* event which will clear this flag. The only notification
|
||||||
|
* the driver gets is if it fails, if it succeeds there is no
|
||||||
|
* notification given. Assume success.
|
||||||
|
*/
|
||||||
|
phba->sli4_hba.fawwpn_flag |= LPFC_FAWWPN_FABRIC;
|
||||||
|
}
|
||||||
|
|
||||||
rc = lpfc_mem_alloc_active_rrq_pool_s4(phba);
|
rc = lpfc_mem_alloc_active_rrq_pool_s4(phba);
|
||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
goto out_free_bsmbx;
|
goto out_free_bsmbx;
|
||||||
|
@ -9807,7 +9832,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
|
||||||
struct lpfc_rsrc_desc_fcfcoe *desc;
|
struct lpfc_rsrc_desc_fcfcoe *desc;
|
||||||
char *pdesc_0;
|
char *pdesc_0;
|
||||||
uint16_t forced_link_speed;
|
uint16_t forced_link_speed;
|
||||||
uint32_t if_type, qmin;
|
uint32_t if_type, qmin, fawwpn;
|
||||||
int length, i, rc = 0, rc2;
|
int length, i, rc = 0, rc2;
|
||||||
|
|
||||||
pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||||
|
@ -9849,10 +9874,23 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
|
||||||
phba->sli4_hba.bbscn_params.word0 = rd_config->word8;
|
phba->sli4_hba.bbscn_params.word0 = rd_config->word8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fawwpn = bf_get(lpfc_mbx_rd_conf_fawwpn, rd_config);
|
||||||
|
|
||||||
|
if (fawwpn) {
|
||||||
|
lpfc_printf_log(phba, KERN_INFO,
|
||||||
|
LOG_INIT | LOG_DISCOVERY,
|
||||||
|
"2702 READ_CONFIG: FA-PWWN is "
|
||||||
|
"configured on\n");
|
||||||
|
phba->sli4_hba.fawwpn_flag |= LPFC_FAWWPN_CONFIG;
|
||||||
|
} else {
|
||||||
|
phba->sli4_hba.fawwpn_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
phba->sli4_hba.conf_trunk =
|
phba->sli4_hba.conf_trunk =
|
||||||
bf_get(lpfc_mbx_rd_conf_trunk, rd_config);
|
bf_get(lpfc_mbx_rd_conf_trunk, rd_config);
|
||||||
phba->sli4_hba.extents_in_use =
|
phba->sli4_hba.extents_in_use =
|
||||||
bf_get(lpfc_mbx_rd_conf_extnts_inuse, rd_config);
|
bf_get(lpfc_mbx_rd_conf_extnts_inuse, rd_config);
|
||||||
|
|
||||||
phba->sli4_hba.max_cfg_param.max_xri =
|
phba->sli4_hba.max_cfg_param.max_xri =
|
||||||
bf_get(lpfc_mbx_rd_conf_xri_count, rd_config);
|
bf_get(lpfc_mbx_rd_conf_xri_count, rd_config);
|
||||||
/* Reduce resource usage in kdump environment */
|
/* Reduce resource usage in kdump environment */
|
||||||
|
|
|
@ -5265,6 +5265,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba)
|
||||||
phba->pport->stopped = 0;
|
phba->pport->stopped = 0;
|
||||||
phba->link_state = LPFC_INIT_START;
|
phba->link_state = LPFC_INIT_START;
|
||||||
phba->hba_flag = 0;
|
phba->hba_flag = 0;
|
||||||
|
phba->sli4_hba.fawwpn_flag = 0;
|
||||||
spin_unlock_irq(&phba->hbalock);
|
spin_unlock_irq(&phba->hbalock);
|
||||||
|
|
||||||
memset(&psli->lnk_stat_offsets, 0, sizeof(psli->lnk_stat_offsets));
|
memset(&psli->lnk_stat_offsets, 0, sizeof(psli->lnk_stat_offsets));
|
||||||
|
|
|
@ -981,6 +981,9 @@ struct lpfc_sli4_hba {
|
||||||
#define lpfc_conf_trunk_port3_nd_MASK 0x1
|
#define lpfc_conf_trunk_port3_nd_MASK 0x1
|
||||||
uint8_t flash_id;
|
uint8_t flash_id;
|
||||||
uint8_t asic_rev;
|
uint8_t asic_rev;
|
||||||
|
uint16_t fawwpn_flag; /* FA-WWPN support state */
|
||||||
|
#define LPFC_FAWWPN_CONFIG 0x1 /* FA-PWWN is configured */
|
||||||
|
#define LPFC_FAWWPN_FABRIC 0x2 /* FA-PWWN success with Fabric */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum lpfc_sge_type {
|
enum lpfc_sge_type {
|
||||||
|
|
Loading…
Add table
Reference in a new issue