net/mlx5: Added devlink info callback
authorShay Agroskin <shayag@mellanox.com>
Tue, 2 Jul 2019 23:55:11 +0000 (23:55 +0000)
committerSaeed Mahameed <saeedm@mellanox.com>
Thu, 4 Jul 2019 20:43:16 +0000 (16:43 -0400)
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>
Documentation/networking/device_drivers/mellanox/mlx5.rst
drivers/net/ethernet/mellanox/mlx5/core/devlink.c

index 4eeef2df912f40c8330a817114f044be3791514d..214325897732f5846fb68a2de85feb4cbfca6e3d 100644 (file)
@@ -10,6 +10,7 @@ Contents
 ========
 
 - `Enabling the driver and kconfig options`_
+- `Devlink info`_
 - `Devlink health reporters`_
 
 Enabling the driver and kconfig options
@@ -101,6 +102,24 @@ Enabling the driver and kconfig options
 - CONFIG_VXLAN: When chosen, mlx5 vxaln support will be enabled.
 - CONFIG_MLXFW: When chosen, mlx5 firmware flashing support will be enabled (via devlink and ethtool).
 
+Devlink info
+============
+
+The devlink info reports the running and stored firmware versions on device.
+It also prints the device PSID which represents the HCA board type ID.
+
+User command 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
 
 Devlink health reporters
 ========================
index 1533c657220be60863259cca690d44c30de9e7ec..a400f4430c28574ce550e88aa86befaa00618fb9 100644 (file)
@@ -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)