Commit 16a93e83 authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: Improve firmware download logging

Define additional status fields in mailbox commands to help provide
additional information when downloading new firmware.

Link: https://lore.kernel.org/r/20210707184351.67872-4-jsmart2021@gmail.comCo-developed-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent e8613084
......@@ -959,6 +959,12 @@ union lpfc_sli4_cfg_shdr {
#define lpfc_mbox_hdr_add_status_SHIFT 8
#define lpfc_mbox_hdr_add_status_MASK 0x000000FF
#define lpfc_mbox_hdr_add_status_WORD word7
#define LPFC_ADD_STATUS_INCOMPAT_OBJ 0xA2
#define lpfc_mbox_hdr_add_status_2_SHIFT 16
#define lpfc_mbox_hdr_add_status_2_MASK 0x000000FF
#define lpfc_mbox_hdr_add_status_2_WORD word7
#define LPFC_ADD_STATUS_2_INCOMPAT_FLASH 0x01
#define LPFC_ADD_STATUS_2_INCORRECT_ASIC 0x02
uint32_t response_length;
uint32_t actual_response_length;
} response;
......@@ -3603,6 +3609,9 @@ struct lpfc_controller_attribute {
#define lpfc_cntl_attr_eprom_ver_hi_SHIFT 8
#define lpfc_cntl_attr_eprom_ver_hi_MASK 0x000000ff
#define lpfc_cntl_attr_eprom_ver_hi_WORD word17
#define lpfc_cntl_attr_flash_id_SHIFT 16
#define lpfc_cntl_attr_flash_id_MASK 0x000000ff
#define lpfc_cntl_attr_flash_id_WORD word17
uint32_t mbx_da_struct_ver;
uint32_t ep_fw_da_struct_ver;
uint32_t ncsi_ver_str[3];
......
......@@ -5674,16 +5674,20 @@ lpfc_sli4_get_ctl_attr(struct lpfc_hba *phba)
bf_get(lpfc_cntl_attr_lnk_type, cntl_attr);
phba->sli4_hba.lnk_info.lnk_no =
bf_get(lpfc_cntl_attr_lnk_numb, cntl_attr);
phba->sli4_hba.flash_id = bf_get(lpfc_cntl_attr_flash_id, cntl_attr);
phba->sli4_hba.asic_rev = bf_get(lpfc_cntl_attr_asic_rev, cntl_attr);
memset(phba->BIOSVersion, 0, sizeof(phba->BIOSVersion));
strlcat(phba->BIOSVersion, (char *)cntl_attr->bios_ver_str,
sizeof(phba->BIOSVersion));
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
"3086 lnk_type:%d, lnk_numb:%d, bios_ver:%s\n",
"3086 lnk_type:%d, lnk_numb:%d, bios_ver:%s, "
"flash_id: x%02x, asic_rev: x%02x\n",
phba->sli4_hba.lnk_info.lnk_tp,
phba->sli4_hba.lnk_info.lnk_no,
phba->BIOSVersion);
phba->BIOSVersion, phba->sli4_hba.flash_id,
phba->sli4_hba.asic_rev);
out_free_mboxq:
if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG)
lpfc_sli4_mbox_cmd_free(phba, mboxq);
......@@ -20020,6 +20024,91 @@ lpfc_sli_read_link_ste(struct lpfc_hba *phba)
return;
}
/**
* lpfc_log_fw_write_cmpl - logs firmware write completion status
* @phba: pointer to lpfc hba data structure
* @shdr_status: wr_object rsp's status field
* @shdr_add_status: wr_object rsp's add_status field
* @shdr_add_status_2: wr_object rsp's add_status_2 field
* @shdr_change_status: wr_object rsp's change_status field
* @shdr_csf: wr_object rsp's csf bit
*
* This routine is intended to be called after a firmware write completes.
* It will log next action items to be performed by the user to instantiate
* the newly downloaded firmware or reason for incompatibility.
**/
static void
lpfc_log_fw_write_cmpl(struct lpfc_hba *phba, u32 shdr_status,
u32 shdr_add_status, u32 shdr_add_status_2,
u32 shdr_change_status, u32 shdr_csf)
{
lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
"4198 %s: flash_id x%02x, asic_rev x%02x, "
"status x%02x, add_status x%02x, add_status_2 x%02x, "
"change_status x%02x, csf %01x\n", __func__,
phba->sli4_hba.flash_id, phba->sli4_hba.asic_rev,
shdr_status, shdr_add_status, shdr_add_status_2,
shdr_change_status, shdr_csf);
if (shdr_add_status == LPFC_ADD_STATUS_INCOMPAT_OBJ) {
switch (shdr_add_status_2) {
case LPFC_ADD_STATUS_2_INCOMPAT_FLASH:
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI,
"4199 Firmware write failed: "
"image incompatible with flash x%02x\n",
phba->sli4_hba.flash_id);
break;
case LPFC_ADD_STATUS_2_INCORRECT_ASIC:
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI,
"4200 Firmware write failed: "
"image incompatible with ASIC "
"architecture x%02x\n",
phba->sli4_hba.asic_rev);
break;
default:
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI,
"4210 Firmware write failed: "
"add_status_2 x%02x\n",
shdr_add_status_2);
break;
}
} else if (!shdr_status && !shdr_add_status) {
if (shdr_change_status == LPFC_CHANGE_STATUS_FW_RESET ||
shdr_change_status == LPFC_CHANGE_STATUS_PORT_MIGRATION) {
if (shdr_csf)
shdr_change_status =
LPFC_CHANGE_STATUS_PCI_RESET;
}
switch (shdr_change_status) {
case (LPFC_CHANGE_STATUS_PHYS_DEV_RESET):
lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
"3198 Firmware write complete: System "
"reboot required to instantiate\n");
break;
case (LPFC_CHANGE_STATUS_FW_RESET):
lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
"3199 Firmware write complete: "
"Firmware reset required to "
"instantiate\n");
break;
case (LPFC_CHANGE_STATUS_PORT_MIGRATION):
lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
"3200 Firmware write complete: Port "
"Migration or PCI Reset required to "
"instantiate\n");
break;
case (LPFC_CHANGE_STATUS_PCI_RESET):
lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
"3201 Firmware write complete: PCI "
"Reset required to instantiate\n");
break;
default:
break;
}
}
}
/**
* lpfc_wr_object - write an object to the firmware
* @phba: HBA structure that indicates port to create a queue on.
......@@ -20046,7 +20135,8 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
struct lpfc_mbx_wr_object *wr_object;
LPFC_MBOXQ_t *mbox;
int rc = 0, i = 0;
uint32_t shdr_status, shdr_add_status, shdr_change_status, shdr_csf;
uint32_t shdr_status, shdr_add_status, shdr_add_status_2;
uint32_t shdr_change_status = 0, shdr_csf = 0;
uint32_t mbox_tmo;
struct lpfc_dmabuf *dmabuf;
uint32_t written = 0;
......@@ -20100,58 +20190,36 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
&wr_object->header.cfg_shdr.response);
shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
&wr_object->header.cfg_shdr.response);
shdr_add_status_2 = bf_get(lpfc_mbox_hdr_add_status_2,
&wr_object->header.cfg_shdr.response);
if (check_change_status) {
shdr_change_status = bf_get(lpfc_wr_object_change_status,
&wr_object->u.response);
if (shdr_change_status == LPFC_CHANGE_STATUS_FW_RESET ||
shdr_change_status == LPFC_CHANGE_STATUS_PORT_MIGRATION) {
shdr_csf = bf_get(lpfc_wr_object_csf,
&wr_object->u.response);
if (shdr_csf)
shdr_change_status =
LPFC_CHANGE_STATUS_PCI_RESET;
}
switch (shdr_change_status) {
case (LPFC_CHANGE_STATUS_PHYS_DEV_RESET):
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"3198 Firmware write complete: System "
"reboot required to instantiate\n");
break;
case (LPFC_CHANGE_STATUS_FW_RESET):
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"3199 Firmware write complete: Firmware"
" reset required to instantiate\n");
break;
case (LPFC_CHANGE_STATUS_PORT_MIGRATION):
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"3200 Firmware write complete: Port "
"Migration or PCI Reset required to "
"instantiate\n");
break;
case (LPFC_CHANGE_STATUS_PCI_RESET):
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"3201 Firmware write complete: PCI "
"Reset required to instantiate\n");
break;
default:
break;
}
shdr_csf = bf_get(lpfc_wr_object_csf,
&wr_object->u.response);
}
if (!phba->sli4_hba.intr_enable)
mempool_free(mbox, phba->mbox_mem_pool);
else if (rc != MBX_TIMEOUT)
mempool_free(mbox, phba->mbox_mem_pool);
if (shdr_status || shdr_add_status || rc) {
if (shdr_status || shdr_add_status || shdr_add_status_2 || rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
"3025 Write Object mailbox failed with "
"status x%x add_status x%x, mbx status x%x\n",
shdr_status, shdr_add_status, rc);
"status x%x add_status x%x, add_status_2 x%x, "
"mbx status x%x\n",
shdr_status, shdr_add_status, shdr_add_status_2,
rc);
rc = -ENXIO;
*offset = shdr_add_status;
} else
} else {
*offset += wr_object->u.response.actual_write_length;
}
if (rc || check_change_status)
lpfc_log_fw_write_cmpl(phba, shdr_status, shdr_add_status,
shdr_add_status_2, shdr_change_status,
shdr_csf);
return rc;
}
......
......@@ -978,6 +978,8 @@ struct lpfc_sli4_hba {
#define lpfc_conf_trunk_port3_nd_WORD conf_trunk
#define lpfc_conf_trunk_port3_nd_SHIFT 7
#define lpfc_conf_trunk_port3_nd_MASK 0x1
uint8_t flash_id;
uint8_t asic_rev;
};
enum lpfc_sge_type {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment