scsi: qla2xxx: Add NVRAM config support for 29xx adapters

Extend the NVRAM read and configuration-apply paths to handle the 29xx
series.  The 29xx NVRAM layout is similar to the 81xx family, so reuse
the existing nvram_81xx parsing while adding 29xx-specific fields and
init-sequence integration.

Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202607141733.w1IF5m43-lkp@intel.com/
Signed-off-by: Manish Rangankar <mrangankar@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-4-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
This commit is contained in:
Manish Rangankar 2026-07-23 10:33:20 +05:30 committed by Martin K. Petersen (Oracle)
parent 3d2e901768
commit 5b5a8cc2a7
4 changed files with 141 additions and 27 deletions

View File

@ -4469,6 +4469,7 @@ struct qla_hw_data {
uint16_t vpd_size;
uint16_t vpd_base;
void *vpd;
struct qla_flash_memo_block *fiv;
uint16_t loop_reset_delay;
uint8_t retry_count;

View File

@ -1676,6 +1676,8 @@ struct qla_flt_location {
#define FLT_REG_VPD_SEC_27XX_2 0xD8
#define FLT_REG_VPD_SEC_27XX_3 0xDA
#define FLT_REG_NVME_PARAMS_27XX 0x21
#define FLT_REG_FMB_PRI 0xDF
#define FLT_REG_FMB_SEC 0x124
/* 28xx */
#define FLT_REG_AUX_IMG_PRI_28XX 0x125
@ -2110,7 +2112,7 @@ struct nvram_81xx {
* BIT 7 = SCM Disabled if BIT is set (1)
* BIT 8-15 = Unused
*/
uint16_t enhanced_features;
__le16 enhanced_features;
uint16_t reserved_24[4];
@ -2338,4 +2340,42 @@ struct qla_fcp_prio_cfg {
#define NVRAM_DUAL_FCP_NVME_FLAG_OFFSET 0x196
struct qla_fmb_version {
uint8_t major;
uint8_t minor;
uint8_t sub;
uint8_t build;
};
struct qla_fmb_upd_time {
__le16 year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint8_t reserved;
};
struct qla_flash_memo_block {
__le32 signature; /* "FMBS" */
#define QLFC_FMB_SIG cpu_to_le32(0x53424D46)
__le32 length;
__le32 version;
#define QLFC_FMB_VERSION 3
__le32 checksum;
struct qla_fmb_version ffv_ver;
struct qla_fmb_version mbi_ver;
struct {
__le16 year;
uint8_t month;
uint8_t day;
uint8_t reserve[4];
} bld_time;
uint8_t tool_id[4];
struct qla_fmb_upd_time upd_time;
struct qla_fmb_version tool_version;
};
#endif

View File

@ -4194,11 +4194,11 @@ qla24xx_detect_sfp(scsi_qla_host_t *vha)
used_nvram = 0;
ha->flags.lr_detected = 0;
if (IS_BPM_RANGE_CAPABLE(ha) &&
(nv->enhanced_features & NEF_LR_DIST_ENABLE)) {
(le16_to_cpu(nv->enhanced_features) & NEF_LR_DIST_ENABLE)) {
used_nvram = 1;
ha->flags.lr_detected = 1;
ha->lr_distance =
(nv->enhanced_features >> LR_DIST_NV_POS)
(le16_to_cpu(nv->enhanced_features) >> LR_DIST_NV_POS)
& LR_DIST_NV_MASK;
}
@ -9306,35 +9306,98 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
if (IS_P3P_TYPE(ha) || IS_QLA8031(ha))
ha->vpd_size = FA_VPD_SIZE_82XX;
if (IS_QLA28XX(ha) || IS_QLA27XX(ha))
qla28xx_get_aux_images(vha, &active_regions);
/* Get VPD data into cache */
ha->vpd = ha->nvram + VPD_OFFSET;
faddr = ha->flt_region_vpd;
if (IS_QLA28XX(ha)) {
if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
faddr = ha->flt_region_vpd_sec;
if (IS_QLA29XX(ha)) {
uint16_t fw_options = 0, r_code;
uint32_t vpd_r[] = {FLT_REG_VPD_0, FLT_REG_VPD_1,
FLT_REG_VPD_2, FLT_REG_VPD_3};
uint32_t nvram_r[] = {FLT_REG_NVRAM_0, FLT_REG_NVRAM_1,
FLT_REG_NVRAM_2, FLT_REG_NVRAM_3};
void *buf;
BUILD_BUG_ON((VPD_OFFSET + FA_NVRAM_VPD_SIZE +
sizeof(struct qla_flash_memo_block)) >
MAX_NVRAM_SIZE);
ha->fiv = (struct qla_flash_memo_block *)
((char *)ha->vpd + ha->vpd_size);
buf = qla29xx_read_optrom_data(vha, FLT_REG_FMB_PRI,
fw_options, ha->fiv, 0,
sizeof(struct qla_flash_memo_block));
if (!buf) {
ql_log(ql_log_info, vha, 0x01be,
"Unable to read Flash Image Version.\n");
} else if (ha->fiv->signature != QLFC_FMB_SIG) {
ql_log(ql_log_warn, vha, 0x01bf,
"Invalid FMB signature %#x, expected %#x.\n",
le32_to_cpu(ha->fiv->signature),
le32_to_cpu(QLFC_FMB_SIG));
ha->fiv = NULL;
} else {
ql_log(ql_log_info, vha, 0x0024,
"Flash Image Version %u.%02u.%02u\n",
ha->fiv->mbi_ver.major,
ha->fiv->mbi_ver.minor,
ha->fiv->mbi_ver.sub);
}
if (ha->port_no >= ARRAY_SIZE(vpd_r)) {
ql_log(ql_log_warn, vha, 0x002e,
"Invalid port number %u, skipping VPD/NVRAM read.\n",
ha->port_no);
goto out_29xx;
}
r_code = vpd_r[ha->port_no];
buf = qla29xx_read_optrom_data(vha, r_code, fw_options,
ha->vpd, 0, ha->vpd_size);
if (!buf)
ql_log(ql_log_info, vha, 0x002d,
"Unable to read VPD info.\n");
r_code = nvram_r[ha->port_no];
buf = qla29xx_read_optrom_data(vha, r_code, fw_options,
ha->nvram, 0, ha->nvram_size);
if (!buf)
ql_log(ql_log_info, vha, 0x0013,
"Unable to read nvram config info.\n");
} else {
if (IS_QLA28XX(ha) || IS_QLA27XX(ha))
qla28xx_get_aux_images(vha, &active_regions);
faddr = ha->flt_region_vpd;
if (IS_QLA28XX(ha)) {
if (active_regions.aux.vpd_nvram ==
QLA27XX_SECONDARY_IMAGE)
faddr = ha->flt_region_vpd_sec;
ql_dbg(ql_dbg_init, vha, 0x0110,
"Loading %s nvram image.\n",
active_regions.aux.vpd_nvram ==
QLA27XX_PRIMARY_IMAGE ?
"primary" : "secondary");
}
ha->isp_ops->read_optrom(vha, ha->vpd, faddr << 2,
ha->vpd_size);
/* Get NVRAM data into cache and calculate checksum. */
faddr = ha->flt_region_nvram;
if (IS_QLA28XX(ha)) {
if (active_regions.aux.vpd_nvram ==
QLA27XX_SECONDARY_IMAGE)
faddr = ha->flt_region_nvram_sec;
}
ql_dbg(ql_dbg_init, vha, 0x0110,
"Loading %s nvram image.\n",
active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
"primary" : "secondary");
ha->isp_ops->read_optrom(vha, ha->nvram, faddr << 2,
ha->nvram_size);
}
ha->isp_ops->read_optrom(vha, ha->vpd, faddr << 2, ha->vpd_size);
/* Get NVRAM data into cache and calculate checksum. */
faddr = ha->flt_region_nvram;
if (IS_QLA28XX(ha)) {
if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
faddr = ha->flt_region_nvram_sec;
}
ql_dbg(ql_dbg_init, vha, 0x0110,
"Loading %s nvram image.\n",
active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
"primary" : "secondary");
ha->isp_ops->read_optrom(vha, ha->nvram, faddr << 2, ha->nvram_size);
out_29xx:
dptr = (__force __le32 *)nv;
for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++)
chksum += le32_to_cpu(*dptr);
@ -9386,7 +9449,10 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
nv->login_timeout = cpu_to_le16(0);
nv->firmware_options_1 =
cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1);
nv->firmware_options_2 = cpu_to_le32(2 << 4);
if (IS_QLA29XX(ha))
nv->firmware_options_2 = cpu_to_le32(BIT_4);
else
nv->firmware_options_2 = cpu_to_le32(BIT_5);
nv->firmware_options_2 |= cpu_to_le32(BIT_12);
nv->firmware_options_3 = cpu_to_le32(2 << 13);
nv->host_p = cpu_to_le32(BIT_11|BIT_10);
@ -9468,9 +9534,13 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
icb->node_name[0] &= 0xF0;
}
if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
if ((nv->enhanced_features & BIT_7) == 0)
/* SCM Enabled in NVRAM */
if (IS_QLA29XX(ha) || IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
if ((le16_to_cpu(nv->enhanced_features) & BIT_7) == 0) {
ql_log(ql_log_info, vha, 0x0062,
"USCM enabled in NVRAM\n");
ha->flags.scm_supported_a = 1;
}
}
/* Set host adapter parameters. */
@ -9546,7 +9616,8 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
/* if not running MSI-X we need handshaking on interrupts */
if (!vha->hw->flags.msix_enabled &&
(IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)))
(IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha) ||
IS_QLA29XX(ha)))
icb->firmware_options_2 |= cpu_to_le32(BIT_22);
/* Enable ZIO. */

View File

@ -4620,6 +4620,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
fail_free_nvram:
kfree(ha->nvram);
ha->nvram = NULL;
ha->fiv = NULL;
fail_free_ctx_mempool:
mempool_destroy(ha->ctx_mempool);
ha->ctx_mempool = NULL;
@ -5085,6 +5086,7 @@ qla2x00_mem_free(struct qla_hw_data *ha)
ha->optrom_buffer = NULL;
kfree(ha->nvram);
ha->nvram = NULL;
ha->fiv = NULL;
kfree(ha->npiv_info);
ha->npiv_info = NULL;
kfree(ha->swl);