Skip to content

Commit cd71348

Browse files
jsmart-ghmartinkpetersen
authored andcommitted
scsi: lpfc: Correct speeds on SFP swap
Supported speeds is not updated when SFP is removed or replaced Supported speed is obtained from lmt field in READ_CONFIG mailbox response. Driver updates supported speeds only once from PCI probe path. After that it is never updated. So, supported speeds remains the same till reboot or driver reload. When SFP is removed or inserted, driver gets SLI-Port Event ACQE. If SFP is removed, lmt wil have value 0. If a different SFP is inserted, lmt will have value according to its supported speeds. So, afterr SLI-Port Event ACQE handling path, send READ_CONFIG mailbox and update supported speeds. If READ_CONFIG fails, set supported speeds to unknown and log. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent c47b6f2 commit cd71348

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

drivers/scsi/lpfc/lpfc_init.c

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4102,6 +4102,30 @@ int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time)
41024102
return stat;
41034103
}
41044104

4105+
void lpfc_host_supported_speeds_set(struct Scsi_Host *shost)
4106+
{
4107+
struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4108+
struct lpfc_hba *phba = vport->phba;
4109+
4110+
fc_host_supported_speeds(shost) = 0;
4111+
if (phba->lmt & LMT_64Gb)
4112+
fc_host_supported_speeds(shost) |= FC_PORTSPEED_64GBIT;
4113+
if (phba->lmt & LMT_32Gb)
4114+
fc_host_supported_speeds(shost) |= FC_PORTSPEED_32GBIT;
4115+
if (phba->lmt & LMT_16Gb)
4116+
fc_host_supported_speeds(shost) |= FC_PORTSPEED_16GBIT;
4117+
if (phba->lmt & LMT_10Gb)
4118+
fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT;
4119+
if (phba->lmt & LMT_8Gb)
4120+
fc_host_supported_speeds(shost) |= FC_PORTSPEED_8GBIT;
4121+
if (phba->lmt & LMT_4Gb)
4122+
fc_host_supported_speeds(shost) |= FC_PORTSPEED_4GBIT;
4123+
if (phba->lmt & LMT_2Gb)
4124+
fc_host_supported_speeds(shost) |= FC_PORTSPEED_2GBIT;
4125+
if (phba->lmt & LMT_1Gb)
4126+
fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT;
4127+
}
4128+
41054129
/**
41064130
* lpfc_host_attrib_init - Initialize SCSI host attributes on a FC port
41074131
* @shost: pointer to SCSI host data structure.
@@ -4129,23 +4153,7 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost)
41294153
lpfc_vport_symbolic_node_name(vport, fc_host_symbolic_name(shost),
41304154
sizeof fc_host_symbolic_name(shost));
41314155

4132-
fc_host_supported_speeds(shost) = 0;
4133-
if (phba->lmt & LMT_64Gb)
4134-
fc_host_supported_speeds(shost) |= FC_PORTSPEED_64GBIT;
4135-
if (phba->lmt & LMT_32Gb)
4136-
fc_host_supported_speeds(shost) |= FC_PORTSPEED_32GBIT;
4137-
if (phba->lmt & LMT_16Gb)
4138-
fc_host_supported_speeds(shost) |= FC_PORTSPEED_16GBIT;
4139-
if (phba->lmt & LMT_10Gb)
4140-
fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT;
4141-
if (phba->lmt & LMT_8Gb)
4142-
fc_host_supported_speeds(shost) |= FC_PORTSPEED_8GBIT;
4143-
if (phba->lmt & LMT_4Gb)
4144-
fc_host_supported_speeds(shost) |= FC_PORTSPEED_4GBIT;
4145-
if (phba->lmt & LMT_2Gb)
4146-
fc_host_supported_speeds(shost) |= FC_PORTSPEED_2GBIT;
4147-
if (phba->lmt & LMT_1Gb)
4148-
fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT;
4156+
lpfc_host_supported_speeds_set(shost);
41494157

41504158
fc_host_maxframe_size(shost) =
41514159
(((uint32_t) vport->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) |
@@ -4758,6 +4766,8 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli)
47584766
struct temp_event temp_event_data;
47594767
struct lpfc_acqe_misconfigured_event *misconfigured;
47604768
struct Scsi_Host *shost;
4769+
struct lpfc_vport **vports;
4770+
int rc, i;
47614771

47624772
evt_type = bf_get(lpfc_trailer_type, acqe_sli);
47634773

@@ -4883,6 +4893,25 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli)
48834893
sprintf(message, "Unknown event status x%02x", status);
48844894
break;
48854895
}
4896+
4897+
/* Issue READ_CONFIG mbox command to refresh supported speeds */
4898+
rc = lpfc_sli4_read_config(phba);
4899+
if (rc == -EIO) {
4900+
phba->lmt = 0;
4901+
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
4902+
"3194 Unable to retrieve supported "
4903+
"speeds\n");
4904+
}
4905+
vports = lpfc_create_vport_work_array(phba);
4906+
if (vports != NULL) {
4907+
for (i = 0; i <= phba->max_vports && vports[i] != NULL;
4908+
i++) {
4909+
shost = lpfc_shost_from_vport(vports[i]);
4910+
lpfc_host_supported_speeds_set(shost);
4911+
}
4912+
}
4913+
lpfc_destroy_vport_work_array(phba, vports);
4914+
48864915
phba->sli4_hba.lnk_info.optic_state = status;
48874916
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
48884917
"3176 Port Name %c %s\n", port_name, message);

0 commit comments

Comments
 (0)