diff options
author | 2022-04-12 15:20:04 -0700 | |
---|---|---|
committer | 2022-04-18 22:48:47 -0400 | |
commit | 1b6f71f7fcb685970aa1c4ecca3dd60ed37a32ea (patch) | |
tree | bc22a12bdb0b681f0f76d147b20614579d6c7739 /drivers/scsi/lpfc/lpfc_init.c | |
parent | scsi: lpfc: Refactor cleanup of mailbox commands (diff) | |
download | linux-dev-1b6f71f7fcb685970aa1c4ecca3dd60ed37a32ea.tar.xz linux-dev-1b6f71f7fcb685970aa1c4ecca3dd60ed37a32ea.zip |
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>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 72 |
1 files changed, 55 insertions, 17 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index fad7ad90c57f..39267016f339 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -350,8 +350,7 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) void lpfc_update_vport_wwn(struct lpfc_vport *vport) { - uint8_t vvvl = vport->fc_sparam.cmn.valid_vendor_ver_level; - u32 *fawwpn_key = (u32 *)&vport->fc_sparam.un.vendorVersion[0]; + struct lpfc_hba *phba = vport->phba; /* * If the name is empty or there exists a soft name @@ -370,21 +369,32 @@ lpfc_update_vport_wwn(struct lpfc_vport *vport) */ if (vport->fc_portname.u.wwn[0] != 0 && memcmp(&vport->fc_portname, &vport->fc_sparam.portName, - sizeof(struct lpfc_name))) + sizeof(struct lpfc_name))) { vport->vport_flag |= FAWWPN_PARAM_CHG; - if (vport->fc_portname.u.wwn[0] == 0 || - (vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR) || - vport->vport_flag & FAWWPN_SET) { - memcpy(&vport->fc_portname, &vport->fc_sparam.portName, - 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 (phba->sli_rev == LPFC_SLI_REV4 && + vport->port_type == LPFC_PHYSICAL_PORT && + 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, + sizeof(struct lpfc_name)); + } } + + if (vport->fc_portname.u.wwn[0] == 0) + memcpy(&vport->fc_portname, &vport->fc_sparam.portName, + sizeof(struct lpfc_name)); else 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: /* Misconfigured WWN. Reports that the SLI Port is configured * 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 + * This event only happens on the physical port. */ - lpfc_log_msg(phba, KERN_WARNING, LOG_SLI, - "2699 Misconfigured FA-WWN - Attached device does " - "not support FA-WWN\n"); + lpfc_log_msg(phba, KERN_WARNING, LOG_SLI | LOG_DISCOVERY, + "2699 Misconfigured FA-PWWN - Attached device " + "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; case LPFC_SLI_EVENT_TYPE_EEPROM_FAILURE: /* 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); if (unlikely(rc)) 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); if (unlikely(rc)) goto out_free_bsmbx; @@ -9807,7 +9832,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) struct lpfc_rsrc_desc_fcfcoe *desc; char *pdesc_0; uint16_t forced_link_speed; - uint32_t if_type, qmin; + uint32_t if_type, qmin, fawwpn; int length, i, rc = 0, rc2; 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; } + 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 = bf_get(lpfc_mbx_rd_conf_trunk, rd_config); phba->sli4_hba.extents_in_use = bf_get(lpfc_mbx_rd_conf_extnts_inuse, rd_config); + phba->sli4_hba.max_cfg_param.max_xri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config); /* Reduce resource usage in kdump environment */ |