Applications determine loop support in part by querying the 'pls' sysfs node. Reporting of 'pls' (Private Loop Support) is derived from the descriptor returned by the COMMON_GET_SLI4_PARAMETERS mailbox command, which is issued during initialization or after a reset. The value of this field may change if there is a dynamic SFP change. The driver currently will not pick up the change as there was no reset scenario. Rework to commonize the sending of the COMMON_GET_SLI4_PARAMETERS command. Add the calling of the routine after receipt of an async event indicating an SFP change. Co-developed-by: Justin Tee <justin.tee@xxxxxxxxxxxx> Signed-off-by: Justin Tee <justin.tee@xxxxxxxxxxxx> Signed-off-by: James Smart <jsmart2021@xxxxxxxxx> --- drivers/scsi/lpfc/lpfc_crtn.h | 1 + drivers/scsi/lpfc/lpfc_init.c | 50 +++++++++++++++++++++++++++++++++++ drivers/scsi/lpfc/lpfc_sli.c | 25 +++--------------- 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index c512f4199142..f0bcfeecd161 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -205,6 +205,7 @@ void lpfc_delayed_disc_timeout_handler(struct lpfc_vport *); int lpfc_config_port_prep(struct lpfc_hba *); void lpfc_update_vport_wwn(struct lpfc_vport *vport); int lpfc_config_port_post(struct lpfc_hba *); +int lpfc_sli4_refresh_params(struct lpfc_hba *phba); int lpfc_hba_down_prep(struct lpfc_hba *); int lpfc_hba_down_post(struct lpfc_hba *); void lpfc_hba_init(struct lpfc_hba *, uint32_t *); diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 5e959c4f05c2..744da35b5074 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -662,6 +662,50 @@ lpfc_config_port_post(struct lpfc_hba *phba) return 0; } +/** + * lpfc_sli4_refresh_params - update driver copy of params. + * @phba: Pointer to HBA context object. + * + * This is called to refresh driver copy of dynamic fields from the + * common_get_sli4_parameters descriptor. + **/ +int +lpfc_sli4_refresh_params(struct lpfc_hba *phba) +{ + LPFC_MBOXQ_t *mboxq; + struct lpfc_mqe *mqe; + struct lpfc_sli4_parameters *mbx_sli4_parameters; + int length, rc; + + mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mboxq) + return -ENOMEM; + + mqe = &mboxq->u.mqe; + /* Read the port's SLI4 Config Parameters */ + length = (sizeof(struct lpfc_mbx_get_sli4_parameters) - + sizeof(struct lpfc_sli4_cfg_mhdr)); + lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, + LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS, + length, LPFC_SLI4_MBX_EMBED); + + rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); + if (unlikely(rc)) { + mempool_free(mboxq, phba->mbox_mem_pool); + return rc; + } + mbx_sli4_parameters = &mqe->un.get_sli4_parameters.sli4_parameters; + phba->sli4_hba.pc_sli4_params.mi_ver = + bf_get(cfg_mi_ver, mbx_sli4_parameters); + phba->sli4_hba.pc_sli4_params.cmf = + bf_get(cfg_cmf, mbx_sli4_parameters); + phba->sli4_hba.pc_sli4_params.pls = + bf_get(cfg_pvl, mbx_sli4_parameters); + + mempool_free(mboxq, phba->mbox_mem_pool); + return rc; +} + /** * lpfc_hba_init_link - Initialize the FC link * @phba: pointer to lpfc hba data structure. @@ -6455,6 +6499,12 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) "3194 Unable to retrieve supported " "speeds, rc = 0x%x\n", rc); } + rc = lpfc_sli4_refresh_params(phba); + if (rc) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "3174 Unable to update pls support, " + "rc x%x\n", rc); + } vports = lpfc_create_vport_work_array(phba); if (vports != NULL) { for (i = 0; i <= phba->max_vports && vports[i] != NULL; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 244e7d68428e..f82f809617a0 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -7891,36 +7891,19 @@ static int lpfc_cmf_setup(struct lpfc_hba *phba) { LPFC_MBOXQ_t *mboxq; - struct lpfc_mqe *mqe; struct lpfc_dmabuf *mp; struct lpfc_pc_sli4_params *sli4_params; - struct lpfc_sli4_parameters *mbx_sli4_parameters; - int length; int rc, cmf, mi_ver; + rc = lpfc_sli4_refresh_params(phba); + if (unlikely(rc)) + return rc; + mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mboxq) return -ENOMEM; - mqe = &mboxq->u.mqe; - - /* Read the port's SLI4 Config Parameters */ - length = (sizeof(struct lpfc_mbx_get_sli4_parameters) - - sizeof(struct lpfc_sli4_cfg_mhdr)); - lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, - LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS, - length, LPFC_SLI4_MBX_EMBED); - - rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); - if (unlikely(rc)) { - mempool_free(mboxq, phba->mbox_mem_pool); - return rc; - } - /* Gather info on CMF and MI support */ sli4_params = &phba->sli4_hba.pc_sli4_params; - mbx_sli4_parameters = &mqe->un.get_sli4_parameters.sli4_parameters; - sli4_params->mi_ver = bf_get(cfg_mi_ver, mbx_sli4_parameters); - sli4_params->cmf = bf_get(cfg_cmf, mbx_sli4_parameters); /* Are we forcing MI off via module parameter? */ if (!phba->cfg_enable_mi) -- 2.26.2