scsi: lpfc: Correct sysfs reporting of loop support after SFP status change
authorJames Smart <jsmart2021@gmail.com>
Wed, 20 Oct 2021 21:14:12 +0000 (14:14 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 21 Oct 2021 03:33:45 +0000 (23:33 -0400)
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.

Link: https://lore.kernel.org/r/20211020211417.88754-4-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>
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli.c

index ad4a954ecc09ec50059be8191b8ed07971a21116..87cffbc382aac1b88ef8d9d07f498e3bb02663cb 100644 (file)
@@ -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 *);
index 469045b0cd7df60e1d9ce54e7a941d77e7d77ae8..fc58384f7fc83f4e6c59d2dd60c4ad568e4d8ace 100644 (file)
@@ -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;
index 244e7d68428e6114172fb3dd72b525ea13e0bb91..f82f809617a003e352b0cf824d1f63a977df6cb3 100644 (file)
@@ -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)