Commit 1feb8204 authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: Enable fw download on if_type=6 devices

Current code is very explicit in what it allows to be downloaded.
The driver checking prevented G7 firmware download. The driver
checking is unnecessary as the device will validate what it receives.

Revise the firmware download interface checking.
Added a little debug support in case there is still a failure.
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 7365f6fd
...@@ -2241,6 +2241,7 @@ struct lpfc_mbx_redisc_fcf_tbl { ...@@ -2241,6 +2241,7 @@ struct lpfc_mbx_redisc_fcf_tbl {
* command. * command.
*/ */
#define ADD_STATUS_OPERATION_ALREADY_ACTIVE 0x67 #define ADD_STATUS_OPERATION_ALREADY_ACTIVE 0x67
#define ADD_STATUS_FW_NOT_SUPPORTED 0xEB
struct lpfc_mbx_sli4_config { struct lpfc_mbx_sli4_config {
struct mbox_header header; struct mbox_header header;
...@@ -4603,10 +4604,6 @@ union lpfc_wqe128 { ...@@ -4603,10 +4604,6 @@ union lpfc_wqe128 {
struct gen_req64_wqe gen_req; struct gen_req64_wqe gen_req;
}; };
#define LPFC_GROUP_OJECT_MAGIC_G5 0xfeaa0001
#define LPFC_GROUP_OJECT_MAGIC_G6 0xfeaa0003
#define LPFC_FILE_TYPE_GROUP 0xf7
#define LPFC_FILE_ID_GROUP 0xa2
struct lpfc_grp_hdr { struct lpfc_grp_hdr {
uint32_t size; uint32_t size;
uint32_t magic_number; uint32_t magic_number;
......
...@@ -11297,6 +11297,27 @@ lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba) ...@@ -11297,6 +11297,27 @@ lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba)
} }
static void
lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset,
uint32_t magic_number, uint32_t ftype, uint32_t fid, uint32_t fsize,
const struct firmware *fw)
{
if (offset == ADD_STATUS_FW_NOT_SUPPORTED)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3030 This firmware version is not supported on "
"this HBA model. Device:%x Magic:%x Type:%x "
"ID:%x Size %d %zd\n",
phba->pcidev->device, magic_number, ftype, fid,
fsize, fw->size);
else
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3022 FW Download failed. Device:%x Magic:%x Type:%x "
"ID:%x Size %d %zd\n",
phba->pcidev->device, magic_number, ftype, fid,
fsize, fw->size);
}
/** /**
* lpfc_write_firmware - attempt to write a firmware image to the port * lpfc_write_firmware - attempt to write a firmware image to the port
* @fw: pointer to firmware image returned from request_firmware. * @fw: pointer to firmware image returned from request_firmware.
...@@ -11324,20 +11345,10 @@ lpfc_write_firmware(const struct firmware *fw, void *context) ...@@ -11324,20 +11345,10 @@ lpfc_write_firmware(const struct firmware *fw, void *context)
magic_number = be32_to_cpu(image->magic_number); magic_number = be32_to_cpu(image->magic_number);
ftype = bf_get_be32(lpfc_grp_hdr_file_type, image); ftype = bf_get_be32(lpfc_grp_hdr_file_type, image);
fid = bf_get_be32(lpfc_grp_hdr_id, image), fid = bf_get_be32(lpfc_grp_hdr_id, image);
fsize = be32_to_cpu(image->size); fsize = be32_to_cpu(image->size);
INIT_LIST_HEAD(&dma_buffer_list); INIT_LIST_HEAD(&dma_buffer_list);
if ((magic_number != LPFC_GROUP_OJECT_MAGIC_G5 &&
magic_number != LPFC_GROUP_OJECT_MAGIC_G6) ||
ftype != LPFC_FILE_TYPE_GROUP || fsize != fw->size) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3022 Invalid FW image found. "
"Magic:%x Type:%x ID:%x Size %d %zd\n",
magic_number, ftype, fid, fsize, fw->size);
rc = -EINVAL;
goto release_out;
}
lpfc_decode_firmware_rev(phba, fwrev, 1); lpfc_decode_firmware_rev(phba, fwrev, 1);
if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) { if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
...@@ -11378,11 +11389,18 @@ lpfc_write_firmware(const struct firmware *fw, void *context) ...@@ -11378,11 +11389,18 @@ lpfc_write_firmware(const struct firmware *fw, void *context)
} }
rc = lpfc_wr_object(phba, &dma_buffer_list, rc = lpfc_wr_object(phba, &dma_buffer_list,
(fw->size - offset), &offset); (fw->size - offset), &offset);
if (rc) if (rc) {
lpfc_log_write_firmware_error(phba, offset,
magic_number, ftype, fid, fsize, fw);
goto release_out; goto release_out;
} }
rc = offset;
} }
rc = offset;
} else
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3029 Skipped Firmware update, Current "
"Version:%s New Version:%s\n",
fwrev, image->revision);
release_out: release_out:
list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) { list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) {
......
...@@ -18871,6 +18871,7 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list, ...@@ -18871,6 +18871,7 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
"status x%x add_status x%x, mbx status x%x\n", "status x%x add_status x%x, mbx status x%x\n",
shdr_status, shdr_add_status, rc); shdr_status, shdr_add_status, rc);
rc = -ENXIO; rc = -ENXIO;
*offset = shdr_add_status;
} else } else
*offset += wr_object->u.response.actual_write_length; *offset += wr_object->u.response.actual_write_length;
return rc; return rc;
......
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