Commit 13ee7d49 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlxsw-Add-support-for-devlink-info-command'



Ido Schimmel says:

====================
mlxsw: Add support for devlink info command

Shalom says:

Expose the following ASIC information via devlink info command:
  - Driver name
  - Hardware revision
  - Firmware PSID
  - Running firmware version

Standard output example:
  $ devlink dev info pci/0000:03:00.0
  pci/0000:03:00.0:
    versions:
        fixed:
          hw.revision A0
          fw.psid MT_2750110033
        running:
          fw.version 13.1910.622

Pretty JSON example:
  $ devlink -jp dev info pci/0000:03:00.0
  {
      "info": {
          "pci/0000:03:00.0": {
              "versions": {
                  "fixed": {
                      "hw.revision": "A0",
                      "fw.psid": "MT_2750110033"
                  },
                  "running": {
                      "fw.version": "13.1910.622"
                  }
              }
          }
      }
  }

v2:
  - Add fw.psid documentation
  - Add driver name
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e4bf6348 be0faac9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -41,3 +41,8 @@ fw.ncsi

Version of the software responsible for supporting/handling the
Network Controller Sideband Interface.

fw.psid
=======

Unique identifier of the firmware parameter set.
+41 −0
Original line number Diff line number Diff line
@@ -934,6 +934,46 @@ mlxsw_devlink_sb_occ_tc_port_bind_get(struct devlink_port *devlink_port,
						     pool_type, p_cur, p_max);
}

static int
mlxsw_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
		       struct netlink_ext_ack *extack)
{
	struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
	char fw_info_psid[MLXSW_REG_MGIR_FW_INFO_PSID_SIZE];
	u32 hw_rev, fw_major, fw_minor, fw_sub_minor;
	char mgir_pl[MLXSW_REG_MGIR_LEN];
	char buf[32];
	int err;

	err = devlink_info_driver_name_put(req,
					   mlxsw_core->bus_info->device_kind);
	if (err)
		return err;

	mlxsw_reg_mgir_pack(mgir_pl);
	err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mgir), mgir_pl);
	if (err)
		return err;
	mlxsw_reg_mgir_unpack(mgir_pl, &hw_rev, fw_info_psid, &fw_major,
			      &fw_minor, &fw_sub_minor);

	sprintf(buf, "%X", hw_rev);
	err = devlink_info_version_fixed_put(req, "hw.revision", buf);
	if (err)
		return err;

	err = devlink_info_version_fixed_put(req, "fw.psid", fw_info_psid);
	if (err)
		return err;

	sprintf(buf, "%d.%d.%d", fw_major, fw_minor, fw_sub_minor);
	err = devlink_info_version_running_put(req, "fw.version", buf);
	if (err)
		return err;

	return 0;
}

static int mlxsw_devlink_core_bus_device_reload(struct devlink *devlink,
						struct netlink_ext_ack *extack)
{
@@ -968,6 +1008,7 @@ static const struct devlink_ops mlxsw_devlink_ops = {
	.sb_occ_max_clear		= mlxsw_devlink_sb_occ_max_clear,
	.sb_occ_port_pool_get		= mlxsw_devlink_sb_occ_port_pool_get,
	.sb_occ_tc_port_bind_get	= mlxsw_devlink_sb_occ_tc_port_bind_get,
	.info_get			= mlxsw_devlink_info_get,
};

static int
+55 −0
Original line number Diff line number Diff line
@@ -8534,6 +8534,60 @@ static inline void mlxsw_reg_mpar_pack(char *payload, u8 local_port,
	mlxsw_reg_mpar_pa_id_set(payload, pa_id);
}

/* MGIR - Management General Information Register
 * ----------------------------------------------
 * MGIR register allows software to query the hardware and firmware general
 * information.
 */
#define MLXSW_REG_MGIR_ID 0x9020
#define MLXSW_REG_MGIR_LEN 0x9C

MLXSW_REG_DEFINE(mgir, MLXSW_REG_MGIR_ID, MLXSW_REG_MGIR_LEN);

/* reg_mgir_hw_info_device_hw_revision
 * Access: RO
 */
MLXSW_ITEM32(reg, mgir, hw_info_device_hw_revision, 0x0, 16, 16);

#define MLXSW_REG_MGIR_FW_INFO_PSID_SIZE 16

/* reg_mgir_fw_info_psid
 * PSID (ASCII string).
 * Access: RO
 */
MLXSW_ITEM_BUF(reg, mgir, fw_info_psid, 0x30, MLXSW_REG_MGIR_FW_INFO_PSID_SIZE);

/* reg_mgir_fw_info_extended_major
 * Access: RO
 */
MLXSW_ITEM32(reg, mgir, fw_info_extended_major, 0x44, 0, 32);

/* reg_mgir_fw_info_extended_minor
 * Access: RO
 */
MLXSW_ITEM32(reg, mgir, fw_info_extended_minor, 0x48, 0, 32);

/* reg_mgir_fw_info_extended_sub_minor
 * Access: RO
 */
MLXSW_ITEM32(reg, mgir, fw_info_extended_sub_minor, 0x4C, 0, 32);

static inline void mlxsw_reg_mgir_pack(char *payload)
{
	MLXSW_REG_ZERO(mgir, payload);
}

static inline void
mlxsw_reg_mgir_unpack(char *payload, u32 *hw_rev, char *fw_info_psid,
		      u32 *fw_major, u32 *fw_minor, u32 *fw_sub_minor)
{
	*hw_rev = mlxsw_reg_mgir_hw_info_device_hw_revision_get(payload);
	mlxsw_reg_mgir_fw_info_psid_memcpy_from(payload, fw_info_psid);
	*fw_major = mlxsw_reg_mgir_fw_info_extended_major_get(payload);
	*fw_minor = mlxsw_reg_mgir_fw_info_extended_minor_get(payload);
	*fw_sub_minor = mlxsw_reg_mgir_fw_info_extended_sub_minor_get(payload);
}

/* MRSR - Management Reset and Shutdown Register
 * ---------------------------------------------
 * MRSR register is used to reset or shutdown the switch or
@@ -9958,6 +10012,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
	MLXSW_REG(mcia),
	MLXSW_REG(mpat),
	MLXSW_REG(mpar),
	MLXSW_REG(mgir),
	MLXSW_REG(mrsr),
	MLXSW_REG(mlcr),
	MLXSW_REG(mpsc),