| From f61f3dc4a4daf1e41b7f2350cd52b7f0b98851dc Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 30 Mar 2026 22:40:14 +0300 |
| Subject: net/mlx5: Avoid "No data available" when FW version queries fail |
| |
| From: Saeed Mahameed <saeedm@nvidia.com> |
| |
| [ Upstream commit 10dc35f6a443d488f219d1a1e3fb8f8dac422070 ] |
| |
| Avoid printing the misleading "kernel answers: No data available" devlink |
| output when querying firmware or pending firmware version fails |
| (e.g. MLX5 fw state errors / flash failures). |
| |
| FW can fail on loading the pending flash image and get its version due |
| to various reasons, examples: |
| |
| mlxfw: Firmware flash failed: key not applicable, err (7) |
| mlx5_fw_image_pending: can't read pending fw version while fw state is 1 |
| |
| and the resulting: |
| $ devlink dev info |
| kernel answers: No data available |
| |
| Instead, just report 0 or 0xfff.. versions in case of failure to indicate |
| a problem, and let other information be shown. |
| |
| after the fix: |
| $ devlink dev info |
| pci/0000:00:06.0: |
| driver mlx5_core |
| serial_number xxx... |
| board.serial_number MT2225300179 |
| versions: |
| fixed: |
| fw.psid MT_0000000436 |
| running: |
| fw.version 22.41.0188 |
| fw 22.41.0188 |
| stored: |
| fw.version 255.255.65535 |
| fw 255.255.65535 |
| |
| Fixes: 9c86b07e3069 ("net/mlx5: Added fw version query command") |
| Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> |
| Reviewed-by: Moshe Shemesh <moshe@nvidia.com> |
| Signed-off-by: Tariq Toukan <tariqt@nvidia.com> |
| Link: https://patch.msgid.link/20260330194015.53585-3-tariqt@nvidia.com |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| .../net/ethernet/mellanox/mlx5/core/devlink.c | 4 +- |
| drivers/net/ethernet/mellanox/mlx5/core/fw.c | 53 ++++++++++++------- |
| .../ethernet/mellanox/mlx5/core/mlx5_core.h | 4 +- |
| 3 files changed, 37 insertions(+), 24 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c |
| index ea77fbd98396a..055ee020c56f4 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c |
| @@ -107,9 +107,7 @@ mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, |
| if (err) |
| return err; |
| |
| - err = mlx5_fw_version_query(dev, &running_fw, &stored_fw); |
| - if (err) |
| - return err; |
| + mlx5_fw_version_query(dev, &running_fw, &stored_fw); |
| |
| snprintf(version_str, sizeof(version_str), "%d.%d.%04d", |
| mlx5_fw_ver_major(running_fw), mlx5_fw_ver_minor(running_fw), |
| diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw.c b/drivers/net/ethernet/mellanox/mlx5/core/fw.c |
| index eeb4437975f20..c1f220e5fe185 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/fw.c |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/fw.c |
| @@ -822,48 +822,63 @@ mlx5_fw_image_pending(struct mlx5_core_dev *dev, |
| return 0; |
| } |
| |
| -int mlx5_fw_version_query(struct mlx5_core_dev *dev, |
| - u32 *running_ver, u32 *pending_ver) |
| +void mlx5_fw_version_query(struct mlx5_core_dev *dev, |
| + u32 *running_ver, u32 *pending_ver) |
| { |
| u32 reg_mcqi_version[MLX5_ST_SZ_DW(mcqi_version)] = {}; |
| bool pending_version_exists; |
| int component_index; |
| int err; |
| |
| + *running_ver = 0; |
| + *pending_ver = 0; |
| + |
| if (!MLX5_CAP_GEN(dev, mcam_reg) || !MLX5_CAP_MCAM_REG(dev, mcqi) || |
| !MLX5_CAP_MCAM_REG(dev, mcqs)) { |
| mlx5_core_warn(dev, "fw query isn't supported by the FW\n"); |
| - return -EOPNOTSUPP; |
| + return; |
| } |
| |
| component_index = mlx5_get_boot_img_component_index(dev); |
| - if (component_index < 0) |
| - return component_index; |
| + if (component_index < 0) { |
| + mlx5_core_warn(dev, "fw query failed to find boot img component index, err %d\n", |
| + component_index); |
| + return; |
| + } |
| |
| + *running_ver = U32_MAX; /* indicate failure */ |
| err = mlx5_reg_mcqi_version_query(dev, component_index, |
| MCQI_FW_RUNNING_VERSION, |
| reg_mcqi_version); |
| - if (err) |
| - return err; |
| - |
| - *running_ver = MLX5_GET(mcqi_version, reg_mcqi_version, version); |
| - |
| + if (!err) |
| + *running_ver = MLX5_GET(mcqi_version, reg_mcqi_version, |
| + version); |
| + else |
| + mlx5_core_warn(dev, "failed to query running version, err %d\n", |
| + err); |
| + |
| + *pending_ver = U32_MAX; /* indicate failure */ |
| err = mlx5_fw_image_pending(dev, component_index, &pending_version_exists); |
| - if (err) |
| - return err; |
| + if (err) { |
| + mlx5_core_warn(dev, "failed to query pending image, err %d\n", |
| + err); |
| + return; |
| + } |
| |
| if (!pending_version_exists) { |
| *pending_ver = 0; |
| - return 0; |
| + return; |
| } |
| |
| err = mlx5_reg_mcqi_version_query(dev, component_index, |
| MCQI_FW_STORED_VERSION, |
| reg_mcqi_version); |
| - if (err) |
| - return err; |
| - |
| - *pending_ver = MLX5_GET(mcqi_version, reg_mcqi_version, version); |
| - |
| - return 0; |
| + if (!err) |
| + *pending_ver = MLX5_GET(mcqi_version, reg_mcqi_version, |
| + version); |
| + else |
| + mlx5_core_warn(dev, "failed to query pending version, err %d\n", |
| + err); |
| + |
| + return; |
| } |
| diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h |
| index f2d74382fb85d..c048839f07d6d 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h |
| @@ -392,8 +392,8 @@ int mlx5_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); |
| |
| int mlx5_firmware_flash(struct mlx5_core_dev *dev, const struct firmware *fw, |
| struct netlink_ext_ack *extack); |
| -int mlx5_fw_version_query(struct mlx5_core_dev *dev, |
| - u32 *running_ver, u32 *stored_ver); |
| +void mlx5_fw_version_query(struct mlx5_core_dev *dev, u32 *running_ver, |
| + u32 *stored_ver); |
| |
| #ifdef CONFIG_MLX5_CORE_EN |
| int mlx5e_init(void); |
| -- |
| 2.53.0 |
| |