Commit f6b588af authored by Jedrzej Jagielski's avatar Jedrzej Jagielski Committed by Tony Nguyen
Browse files

ixgbe: add handler for devlink .info_get()



Provide devlink .info_get() callback implementation to allow the
driver to report detailed version information. The following info
is reported:

 "serial_number" -> The PCI DSN of the adapter
 "fw.bundle_id" -> Unique identifier for the combined flash image
 "fw.undi" -> Version of the Option ROM containing the UEFI driver
 "board.id" -> The PBA ID string

Reviewed-by: default avatarMateusz Polchlopek <mateusz.polchlopek@intel.com>
Tested-by: default avatarBharath R <bharath.r@intel.com>
Signed-off-by: default avatarJedrzej Jagielski <jedrzej.jagielski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent a0285236
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -6,3 +6,35 @@ ixgbe devlink support

This document describes the devlink features implemented by the ``ixgbe``
device driver.

Info versions
=============

The ``ixgbe`` driver reports the following versions

.. list-table:: devlink info versions implemented
    :widths: 5 5 5 90

    * - Name
      - Type
      - Example
      - Description
    * - ``board.id``
      - fixed
      - H49289-000
      - The Product Board Assembly (PBA) identifier of the board.
    * - ``fw.undi``
      - running
      - 1.1937.0
      - Version of the Option ROM containing the UEFI driver. The version is
        reported in ``major.minor.patch`` format. The major version is
        incremented whenever a major breaking change occurs, or when the
        minor version would overflow. The minor version is incremented for
        non-breaking changes and reset to 1 when the major version is
        incremented. The patch version is normally 0 but is incremented when
        a fix is delivered as a patch against an older base Option ROM.
    * - ``fw.bundle_id``
      - running
      - 0x80000d0d
      - Unique identifier of the firmware image file that was loaded onto
        the device. Also referred to as the EETRACK identifier of the NVM.
+101 −0
Original line number Diff line number Diff line
@@ -4,7 +4,108 @@
#include "ixgbe.h"
#include "devlink.h"

struct ixgbe_info_ctx {
	char buf[128];
};

static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter,
			       struct ixgbe_info_ctx *ctx)
{
	u8 dsn[8];

	/* Copy the DSN into an array in Big Endian format */
	put_unaligned_be64(pci_get_dsn(adapter->pdev), dsn);

	snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn);
}

static void ixgbe_info_nvm_ver(struct ixgbe_adapter *adapter,
			       struct ixgbe_info_ctx *ctx)
{
	struct ixgbe_hw *hw = &adapter->hw;
	struct ixgbe_nvm_version nvm_ver;

	ctx->buf[0] = '\0';

	ixgbe_get_oem_prod_version(hw, &nvm_ver);
	if (nvm_ver.oem_valid) {
		snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x",
			 nvm_ver.oem_major, nvm_ver.oem_minor,
			 nvm_ver.oem_release);

		return;
	}

	ixgbe_get_orom_version(hw, &nvm_ver);
	if (nvm_ver.or_valid)
		snprintf(ctx->buf, sizeof(ctx->buf), "%d.%d.%d",
			 nvm_ver.or_major, nvm_ver.or_build, nvm_ver.or_patch);
}

static void ixgbe_info_eetrack(struct ixgbe_adapter *adapter,
			       struct ixgbe_info_ctx *ctx)
{
	struct ixgbe_hw *hw = &adapter->hw;
	struct ixgbe_nvm_version nvm_ver;

	ixgbe_get_oem_prod_version(hw, &nvm_ver);

	/* No ETRACK version for OEM */
	if (nvm_ver.oem_valid) {
		ctx->buf[0] = '\0';
		return;
	}

	ixgbe_get_etk_id(hw, &nvm_ver);
	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm_ver.etk_id);
}

static int ixgbe_devlink_info_get(struct devlink *devlink,
				  struct devlink_info_req *req,
				  struct netlink_ext_ack *extack)
{
	struct ixgbe_adapter *adapter = devlink_priv(devlink);
	struct ixgbe_hw *hw = &adapter->hw;
	struct ixgbe_info_ctx *ctx;
	int err;

	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	ixgbe_info_get_dsn(adapter, ctx);
	err = devlink_info_serial_number_put(req, ctx->buf);
	if (err)
		goto free_ctx;

	err = ixgbe_read_pba_string_generic(hw, ctx->buf, sizeof(ctx->buf));
	if (err)
		goto free_ctx;

	err = devlink_info_version_fixed_put(req,
					     DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
					     ctx->buf);
	if (err)
		goto free_ctx;

	ixgbe_info_nvm_ver(adapter, ctx);
	err = devlink_info_version_running_put(req,
					       DEVLINK_INFO_VERSION_GENERIC_FW_UNDI,
					       ctx->buf);
	if (err)
		goto free_ctx;

	ixgbe_info_eetrack(adapter, ctx);
	err = devlink_info_version_running_put(req,
					       DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
					       ctx->buf);
free_ctx:
	kfree(ctx);
	return err;
}

static const struct devlink_ops ixgbe_devlink_ops = {
	.info_get = ixgbe_devlink_info_get,
};

/**