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

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.com


Co-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
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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];
+110 −42
Original line number Diff line number Diff line
@@ -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;
		}
	}
	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;
}
+2 −0
Original line number Diff line number Diff line
@@ -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 {