qla2xxx: Add support for online flash update for ISP27XX.

Signed-off-by: Sawan Chandak <sawan.chandak@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Sawan Chandak
2016-01-27 12:03:31 -05:00
committed by Martin K. Petersen
parent f198cafaa4
commit 4243c115f4
9 changed files with 266 additions and 6 deletions

View File

@@ -5348,6 +5348,93 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
return (rval);
}
uint8_t qla27xx_find_valid_image(struct scsi_qla_host *vha)
{
struct qla27xx_image_status pri_image_status, sec_image_status;
uint8_t valid_pri_image, valid_sec_image;
uint32_t *wptr;
uint32_t cnt, chksum, size;
struct qla_hw_data *ha = vha->hw;
valid_pri_image = valid_sec_image = 1;
ha->active_image = 0;
size = sizeof(struct qla27xx_image_status) / sizeof(uint32_t);
if (!ha->flt_region_img_status_pri) {
valid_pri_image = 0;
goto check_sec_image;
}
qla24xx_read_flash_data(vha, (uint32_t *)(&pri_image_status),
ha->flt_region_img_status_pri, size);
if (pri_image_status.signature != QLA27XX_IMG_STATUS_SIGN) {
ql_dbg(ql_dbg_init, vha, 0x018b,
"Primary image signature (0x%x) not valid\n",
pri_image_status.signature);
valid_pri_image = 0;
goto check_sec_image;
}
wptr = (uint32_t *)(&pri_image_status);
cnt = size;
for (chksum = 0; cnt; cnt--)
chksum += le32_to_cpu(*wptr++);
if (chksum) {
ql_dbg(ql_dbg_init, vha, 0x018c,
"Checksum validation failed for primary image (0x%x)\n",
chksum);
valid_pri_image = 0;
}
check_sec_image:
if (!ha->flt_region_img_status_sec) {
valid_sec_image = 0;
goto check_valid_image;
}
qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status),
ha->flt_region_img_status_sec, size);
if (sec_image_status.signature != QLA27XX_IMG_STATUS_SIGN) {
ql_dbg(ql_dbg_init, vha, 0x018d,
"Secondary image signature(0x%x) not valid\n",
sec_image_status.signature);
valid_sec_image = 0;
goto check_valid_image;
}
wptr = (uint32_t *)(&sec_image_status);
cnt = size;
for (chksum = 0; cnt; cnt--)
chksum += le32_to_cpu(*wptr++);
if (chksum) {
ql_dbg(ql_dbg_init, vha, 0x018e,
"Checksum validation failed for secondary image (0x%x)\n",
chksum);
valid_sec_image = 0;
}
check_valid_image:
if (valid_pri_image && (pri_image_status.image_status_mask & 0x1))
ha->active_image = QLA27XX_PRIMARY_IMAGE;
if (valid_sec_image && (sec_image_status.image_status_mask & 0x1)) {
if (!ha->active_image ||
pri_image_status.generation_number <
sec_image_status.generation_number)
ha->active_image = QLA27XX_SECONDARY_IMAGE;
}
ql_dbg(ql_dbg_init, vha, 0x018f, "%s image\n",
ha->active_image == 0 ? "default bootld and fw" :
ha->active_image == 1 ? "primary" :
ha->active_image == 2 ? "secondary" :
"Invalid");
return ha->active_image;
}
static int
qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
uint32_t faddr)
@@ -5370,6 +5457,10 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
dcode = (uint32_t *)req->ring;
*srisc_addr = 0;
if (IS_QLA27XX(ha) &&
qla27xx_find_valid_image(vha) == QLA27XX_SECONDARY_IMAGE)
faddr = ha->flt_region_fw_sec;
/* Validate firmware image by checking version. */
qla24xx_read_flash_data(vha, dcode, faddr + 4, 4);
for (i = 0; i < 4; i++)