net/mlx5: Added devlink info callback

The callback is invoked using 'devlink dev info <pci>' command and returns
the running and pending firmware version of the HCA and the name of the
kernel driver.

If there is a pending firmware version (a new version is burned but the
HCA still runs with the previous) it is returned as the stored
firmware version. Otherwise, the running version is returned for this
field.

Output example:
$ devlink dev info pci/0000:00:06.0
pci/0000:00:06.0:
  driver mlx5_core
  versions:
      fixed:
        fw.psid MT_0000000009
      running:
        fw.version 16.26.0100
      stored:
        fw.version 16.26.0100

Signed-off-by: Shay Agroskin <shayag@mellanox.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
此提交包含在:
Shay Agroskin
2019-07-02 23:55:11 +00:00
提交者 Saeed Mahameed
父節點 9c86b07e30
當前提交 8338d93788
共有 2 個檔案被更改,包括 79 行新增0 行删除

查看文件

@@ -25,6 +25,65 @@ static int mlx5_devlink_flash_update(struct devlink *devlink,
return mlx5_firmware_flash(dev, fw, extack);
}
static u8 mlx5_fw_ver_major(u32 version)
{
return (version >> 24) & 0xff;
}
static u8 mlx5_fw_ver_minor(u32 version)
{
return (version >> 16) & 0xff;
}
static u16 mlx5_fw_ver_subminor(u32 version)
{
return version & 0xffff;
}
#define DEVLINK_FW_STRING_LEN 32
static int
mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
struct netlink_ext_ack *extack)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
char version_str[DEVLINK_FW_STRING_LEN];
u32 running_fw, stored_fw;
int err;
err = devlink_info_driver_name_put(req, DRIVER_NAME);
if (err)
return err;
err = devlink_info_version_fixed_put(req, "fw.psid", dev->board_id);
if (err)
return err;
err = mlx5_fw_version_query(dev, &running_fw, &stored_fw);
if (err)
return err;
snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
mlx5_fw_ver_major(running_fw), mlx5_fw_ver_minor(running_fw),
mlx5_fw_ver_subminor(running_fw));
err = devlink_info_version_running_put(req, "fw.version", version_str);
if (err)
return err;
/* no pending version, return running (stored) version */
if (stored_fw == 0)
stored_fw = running_fw;
snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
mlx5_fw_ver_major(stored_fw), mlx5_fw_ver_minor(stored_fw),
mlx5_fw_ver_subminor(stored_fw));
err = devlink_info_version_stored_put(req, "fw.version", version_str);
if (err)
return err;
return 0;
}
static const struct devlink_ops mlx5_devlink_ops = {
#ifdef CONFIG_MLX5_ESWITCH
.eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
@@ -35,6 +94,7 @@ static const struct devlink_ops mlx5_devlink_ops = {
.eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
#endif
.flash_update = mlx5_devlink_flash_update,
.info_get = mlx5_devlink_info_get,
};
struct devlink *mlx5_devlink_alloc(void)