diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 7ae78c421..91991d620 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -4211,6 +4211,7 @@ struct qla_hw_data { uint32_t eeh_flush:2; #define EEH_FLUSH_RDY 1 #define EEH_FLUSH_DONE 2 + uint32_t secure_mcu:1; } flags; uint16_t max_exchg; @@ -4476,6 +4477,8 @@ struct qla_hw_data { ((IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) &&\ (ha->zio_mode == QLA_ZIO_MODE_6)) +#define IS_QLA28XX_SECURED(ha) (IS_QLA28XX(ha) && ha->flags.secure_mcu) + /* HBA serial number */ uint8_t serial0; uint8_t serial1; diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index affd5ebb6..de063ebcd 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -9062,7 +9062,7 @@ qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) qla27xx_get_active_image(vha, &active_regions); /* For 28XXX, always load the flash firmware using rom mbx */ - if (IS_QLA28XX(ha)) { + if (IS_QLA28XX_SECURED(ha)) { rval = qla28xx_load_flash_firmware(vha); if (rval != QLA_SUCCESS) { ql_log(ql_log_fatal, vha, 0x019e, diff --git a/qla2x00t-32gbit/qla_nx.h b/qla2x00t-32gbit/qla_nx.h index 5d1bdc15b..8e7a7f5f0 100644 --- a/qla2x00t-32gbit/qla_nx.h +++ b/qla2x00t-32gbit/qla_nx.h @@ -892,6 +892,7 @@ struct ct6_dsd { #define FA_VPD_SIZE_82XX 0x400 #define FA_FLASH_LAYOUT_ADDR_82 0xFC400 +#define FA_FLASH_MCU_OFF 0x13000 /****************************************************************************** * diff --git a/qla2x00t-32gbit/qla_sup.c b/qla2x00t-32gbit/qla_sup.c index 9e7a407ba..b6c36a8a2 100644 --- a/qla2x00t-32gbit/qla_sup.c +++ b/qla2x00t-32gbit/qla_sup.c @@ -1084,6 +1084,32 @@ qla2xxx_get_idc_param(scsi_qla_host_t *vha) return; } +static int qla28xx_validate_mcu_signature(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + struct req_que *req = ha->req_q_map[0]; + uint32_t *dcode = (uint32_t *)req->ring; + uint32_t signature[2] = {0x000c0000, 0x00050000}; + int ret = QLA_SUCCESS; + + ret = qla24xx_read_flash_data(vha, dcode, FA_FLASH_MCU_OFF >> 2, 2); + if (ret) { + ql_log(ql_log_fatal, vha, 0x01ab, + "-> Failed to read flash mcu signature.\n"); + ret = QLA_FUNCTION_FAILED; + goto done; + } + + ql_dbg(ql_dbg_init, vha, 0x01ac, + "Flash data 0x%08x 0x%08x.\n", dcode[0], dcode[1]); + + if (!(dcode[0] == signature[0] && dcode[1] == signature[1])) + ret = QLA_FUNCTION_FAILED; + +done: + return ret; +} + int qla2xxx_get_flash_info(scsi_qla_host_t *vha) { @@ -1096,6 +1122,9 @@ qla2xxx_get_flash_info(scsi_qla_host_t *vha) !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) return QLA_SUCCESS; + if (IS_QLA28XX(ha) && !qla28xx_validate_mcu_signature(vha)) + ha->flags.secure_mcu = 1; + ret = qla2xxx_find_flt_start(vha, &flt_addr); if (ret != QLA_SUCCESS) return ret;