Intel-Wired-Lan Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iwl-next v3 0/3] idpf: add devlink info support with selftest
@ 2026-09-04 10:37 Paul Greenwalt
  2026-09-04 10:37 ` [PATCH iwl-next v3 1/3] idpf: clear drvdata in idpf_decfg_device() Paul Greenwalt
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Paul Greenwalt @ 2026-09-04 10:37 UTC (permalink / raw)
  To: intel-wired-lan; +Cc: Paul Greenwalt

Add initial devlink support for idpf and a matching selftest.

Patch 1 consolidates the drvdata clear into idpf_decfg_device(), the
declared inverse of idpf_cfg_device() which sets it.

Patch 2 adds the devlink instance and implements .info_get, reporting:
  - serial_number: PCI Device Serial Number, for NIPA CI identification
  - fw.mgmt.api (running): driver-device communication protocol version

This follows a phased approach and reports stable, readily-available
information. Firmware version support will be added in future patches as
it becomes available through virtchnl.

Patch 3 adds a hardware selftest that logs devlink info in the format
NIPA CI consumes.

The changes in both revisions below address findings from Sashiko AI
review of the series, together with direct review comments on v2.

v2 -> v3:
- Patch 1:
  - Drop the comment above pci_set_drvdata().
- Patch 2 (was patches 2 and 3 in v2, now squashed):
  - Register the instance in idpf_probe() rather than from the reset
    worker, so it stays available for the whole time the driver is
    bound, including when the virtchnl handshake never succeeds. This
    drops the IDPF_DEVLINK_REGISTERED flag added in v2 and no longer
    touches idpf.h or idpf_lib.c.
  - Omit the virtchnl version until it has been negotiated, as the
    instance is now registered before the handshake runs.
  - Read the version fields with READ_ONCE().
  - Include linux/pci.h and linux/unaligned.h directly.
  - Fix the SPDX identifier and copyright style in idpf_devlink.h.
- Patch 3:
  - Report skips through log_test_skip() so that a ksft result line is
    emitted for every exit path.
  - Do not fail when the driver name is absent; whether it appears in
    the JSON depends on the installed iproute2 rather than the kernel.

v1 -> v2:
- Patch 1:
  - Move the drvdata clear into idpf_decfg_device() so it pairs with the
    set in idpf_cfg_device(), instead of adding a second, redundant
    pci_set_drvdata(NULL) at idpf_probe()'s err_free label.
- Patch 2:
  - Select NET_DEVLINK in Kconfig.
  - Omit serial_number when the device reports no PCI DSN, instead of
    reporting an all-zero serial number.
  - Pass the buffer size to the DSN helper rather than hardcoding it.
- Patch 3:
  - Read NETIF from drivers/net/net.config as documented in
    drivers/net/README.rst, in addition to the environment.
  - Skip, rather than fail, devices that report no versions and no serial
    number; implementing devlink info is optional and devlink reports a
    driver name even when info_get is absent.
  - Count and log board.serial_number.
  - Treat a devlink/ethtool driver name difference as informational; it
    is legitimate for e.g. mlx4 and DSA user ports.
  - Do not require ethtool; it is only used for an optional fallback
    handle lookup and the driver name comparison.
  - Query devlink dev info once and validate a single snapshot.
  - Log the reported versions.

Paul Greenwalt (3):
  idpf: clear drvdata in idpf_decfg_device()
  idpf: add devlink support
  selftests: net: hw: add devlink info test

 Documentation/networking/devlink/idpf.rst     |  30 ++++
 Documentation/networking/devlink/index.rst    |   1 +
 drivers/net/ethernet/intel/idpf/Kconfig       |   1 +
 drivers/net/ethernet/intel/idpf/Makefile      |   1 +
 .../net/ethernet/intel/idpf/idpf_devlink.c    |  98 +++++++++++
 .../net/ethernet/intel/idpf/idpf_devlink.h    |  45 +++++
 drivers/net/ethernet/intel/idpf/idpf_main.c   |  16 +-
 .../testing/selftests/drivers/net/hw/Makefile |   1 +
 .../selftests/drivers/net/hw/devlink_info.sh  | 158 ++++++++++++++++++
 9 files changed, 347 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/networking/devlink/idpf.rst
 create mode 100644 drivers/net/ethernet/intel/idpf/idpf_devlink.c
 create mode 100644 drivers/net/ethernet/intel/idpf/idpf_devlink.h
 create mode 100755 tools/testing/selftests/drivers/net/hw/devlink_info.sh

-- 
2.52.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH iwl-next v3 1/3] idpf: clear drvdata in idpf_decfg_device()
  2026-09-04 10:37 [PATCH iwl-next v3 0/3] idpf: add devlink info support with selftest Paul Greenwalt
@ 2026-09-04 10:37 ` Paul Greenwalt
  2026-09-04 10:37 ` [PATCH iwl-next v3 2/3] idpf: add devlink support Paul Greenwalt
  2026-09-04 10:37 ` [PATCH iwl-next v3 3/3] selftests: net: hw: add devlink info test Paul Greenwalt
  2 siblings, 0 replies; 4+ messages in thread
From: Paul Greenwalt @ 2026-09-04 10:37 UTC (permalink / raw)
  To: intel-wired-lan; +Cc: Paul Greenwalt, Przemek Kitszel, Aleksandr Loktionov

pci_set_drvdata(pdev, adapter) is set as the last step of
idpf_cfg_device(), but its inverse, idpf_decfg_device(), does not
clear it. idpf_remove() open-codes the clear right after calling
idpf_decfg_device(), so the two functions are not true opposites of
each other.

Move the pci_set_drvdata(pdev, NULL) into idpf_decfg_device() so the
set/clear pairing lives in one place, and drop the now-redundant
explicit clear from idpf_remove(). idpf_decfg_device() is also called
from idpf_probe()'s err_init_wq unwind path, which did not previously
clear drvdata at all; it now does too, closing that window for
consistency with the rest of the teardown path. This has no
observable effect: the driver core already clears drvdata via
dev_set_drvdata() when a probe function returns an error, under
device_lock(), before any consumer of drvdata can observe a stale
pointer.

Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
---
 drivers/net/ethernet/intel/idpf/idpf_main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c
index 1e4dd9b713a0a..3dbbe21459990 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_main.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_main.c
@@ -112,6 +112,8 @@ static void idpf_decfg_device(struct idpf_adapter *adapter)
 		pci_disable_ptm(pdev);
 
 	libie_pci_unmap_all_mmio_regions(&adapter->ctlq_ctx.mmio_info);
+
+	pci_set_drvdata(pdev, NULL);
 }
 
 /**
@@ -182,7 +184,6 @@ static void idpf_remove(struct pci_dev *pdev)
 	mutex_destroy(&adapter->vc_buf_lock);
 
 	idpf_decfg_device(adapter);
-	pci_set_drvdata(pdev, NULL);
 	kfree(adapter);
 }
 
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH iwl-next v3 2/3] idpf: add devlink support
  2026-09-04 10:37 [PATCH iwl-next v3 0/3] idpf: add devlink info support with selftest Paul Greenwalt
  2026-09-04 10:37 ` [PATCH iwl-next v3 1/3] idpf: clear drvdata in idpf_decfg_device() Paul Greenwalt
@ 2026-09-04 10:37 ` Paul Greenwalt
  2026-09-04 10:37 ` [PATCH iwl-next v3 3/3] selftests: net: hw: add devlink info test Paul Greenwalt
  2 siblings, 0 replies; 4+ messages in thread
From: Paul Greenwalt @ 2026-09-04 10:37 UTC (permalink / raw)
  To: intel-wired-lan; +Cc: Paul Greenwalt

Add a devlink instance for the idpf adapter and implement the .info_get
callback, reporting:
  - serial_number: PCI Device Serial Number, for device identification
  - fw.mgmt.api: running version of the driver-device communication
    channel (virtchnl)

This enables NIPA CI and other tools to uniquely identify devices under
test and track device capabilities. This phased implementation initially
focuses on stable, readily available information. Firmware version
information will be added in future patches as support is exposed
through virtchnl and the driver architecture allows reliable retrieval.

The adapter structure is carved out of the devlink private area, so
devlink_alloc() replaces the plain kzalloc_obj() in idpf_probe() and
devlink_free() replaces the corresponding kfree() on both the probe
error path and in idpf_remove(). The instance is registered in
idpf_probe(), before the reset worker that performs the virtchnl
handshake is queued, and unregistered in idpf_remove(), so it stays
available for the whole time the driver is bound.

The serial number is omitted on devices that do not implement the PCI
Device Serial Number extended capability, where pci_get_dsn() returns 0,
rather than reporting an all-zero serial number. The virtchnl version is
omitted until it has been negotiated, as the instance is registered
before the handshake runs.

$ devlink dev show
pci/0000:85:00.0

$ devlink dev info pci/0000:85:00.0
pci/0000:85:00.0:
  driver idpf
  serial_number 00-a0-c9-ff-ff-23-45-67
  versions:
      running:
        fw.mgmt.api 2.0

Link: https://github.com/linux-netdev/nipa/wiki/Netdev-CI-system#device-information
Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
---
 Documentation/networking/devlink/idpf.rst     | 30 ++++++
 Documentation/networking/devlink/index.rst    |  1 +
 drivers/net/ethernet/intel/idpf/Kconfig       |  1 +
 drivers/net/ethernet/intel/idpf/Makefile      |  1 +
 .../net/ethernet/intel/idpf/idpf_devlink.c    | 98 +++++++++++++++++++
 .../net/ethernet/intel/idpf/idpf_devlink.h    | 45 +++++++++
 drivers/net/ethernet/intel/idpf/idpf_main.c   | 13 ++-
 7 files changed, 186 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/networking/devlink/idpf.rst
 create mode 100644 drivers/net/ethernet/intel/idpf/idpf_devlink.c
 create mode 100644 drivers/net/ethernet/intel/idpf/idpf_devlink.h

diff --git a/Documentation/networking/devlink/idpf.rst b/Documentation/networking/devlink/idpf.rst
new file mode 100644
index 0000000000000..5121cffd8f476
--- /dev/null
+++ b/Documentation/networking/devlink/idpf.rst
@@ -0,0 +1,30 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+====================
+idpf devlink support
+====================
+
+This document describes the devlink features implemented by the ``idpf``
+device driver.
+
+Info versions
+=============
+
+The ``idpf`` driver reports the following versions
+
+.. list-table:: devlink info versions implemented
+    :widths: 5 5 5 90
+
+    * - Name
+      - Type
+      - Example
+      - Description
+    * - ``fw.mgmt.api``
+      - running
+      - 2.0
+      - 2-digit version number (major.minor) of the communication channel
+        (virtchnl) used by the device.
+
+The driver also reports the PCI Device Serial Number through the
+``serial_number`` attribute, on devices that implement the PCI Device Serial
+Number extended capability.
diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst
index d4a83fdcff7fe..538494b1051bd 100644
--- a/Documentation/networking/devlink/index.rst
+++ b/Documentation/networking/devlink/index.rst
@@ -85,6 +85,7 @@ parameters, info versions, and other features it supports.
    hns3
    i40e
    ice
+   idpf
    ionic
    iosm
    ixd
diff --git a/drivers/net/ethernet/intel/idpf/Kconfig b/drivers/net/ethernet/intel/idpf/Kconfig
index 586df3a4afe90..4ee8bbc401fe6 100644
--- a/drivers/net/ethernet/intel/idpf/Kconfig
+++ b/drivers/net/ethernet/intel/idpf/Kconfig
@@ -6,6 +6,7 @@ config IDPF
 	depends on PCI_MSI
 	depends on PTP_1588_CLOCK_OPTIONAL
 	select DIMLIB
+	select NET_DEVLINK
 	select LIBIE_CP
 	select LIBETH_XDP
 	help
diff --git a/drivers/net/ethernet/intel/idpf/Makefile b/drivers/net/ethernet/intel/idpf/Makefile
index 4aaafa175ec37..81b27a4067478 100644
--- a/drivers/net/ethernet/intel/idpf/Makefile
+++ b/drivers/net/ethernet/intel/idpf/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_IDPF) += idpf.o
 
 idpf-y := \
 	idpf_dev.o		\
+	idpf_devlink.o		\
 	idpf_ethtool.o		\
 	idpf_idc.o		\
 	idpf_lib.o		\
diff --git a/drivers/net/ethernet/intel/idpf/idpf_devlink.c b/drivers/net/ethernet/intel/idpf/idpf_devlink.c
new file mode 100644
index 0000000000000..afdb5bc2e002c
--- /dev/null
+++ b/drivers/net/ethernet/intel/idpf/idpf_devlink.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (C) 2026 Intel Corporation */
+
+#include <linux/pci.h>
+#include <linux/unaligned.h>
+
+#include "idpf.h"
+#include "idpf_devlink.h"
+
+#define IDPF_DEVLINK_INFO_LEN		128
+
+/**
+ * idpf_info_get_dsn - format the PCI DSN as the device serial number
+ * @adapter: the idpf adapter structure
+ * @buf: buffer to store the formatted serial number
+ * @buf_size: size of @buf
+ *
+ * Return: true if the device reports a DSN, false otherwise.
+ */
+static bool idpf_info_get_dsn(struct idpf_adapter *adapter, char *buf,
+			      size_t buf_size)
+{
+	u64 dsn = pci_get_dsn(adapter->pdev);
+	u8 dsn_be[sizeof(dsn)];
+
+	if (!dsn)
+		return false;
+
+	/* Copy the DSN into an array in Big Endian format */
+	put_unaligned_be64(dsn, dsn_be);
+	snprintf(buf, buf_size, "%8phD", dsn_be);
+
+	return true;
+}
+
+/**
+ * idpf_devlink_info_get - .info_get devlink handler
+ * @devlink: devlink instance structure
+ * @req: the devlink info request
+ * @extack: extended netlink ack structure
+ *
+ * Callback for the devlink .info_get operation. Reports information about the
+ * device. The virtchnl version is only reported once it has been negotiated,
+ * as the instance is registered before the handshake runs.
+ *
+ * Return: zero on success or a negative error code on failure.
+ */
+static int idpf_devlink_info_get(struct devlink *devlink,
+				 struct devlink_info_req *req,
+				 struct netlink_ext_ack *extack)
+{
+	struct idpf_adapter *adapter = devlink_priv(devlink);
+	char buf[IDPF_DEVLINK_INFO_LEN];
+	u32 maj, min;
+	int err;
+
+	if (idpf_info_get_dsn(adapter, buf, sizeof(buf))) {
+		err = devlink_info_serial_number_put(req, buf);
+		if (err)
+			return err;
+	}
+
+	maj = READ_ONCE(adapter->virt_ver_maj);
+	min = READ_ONCE(adapter->virt_ver_min);
+	if (!maj && !min)
+		return 0;
+
+	snprintf(buf, sizeof(buf), "%u.%u", maj, min);
+
+	return devlink_info_version_running_put(req,
+					DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API,
+					buf);
+}
+
+static const struct devlink_ops idpf_devlink_ops = {
+	.info_get = idpf_devlink_info_get,
+};
+
+/**
+ * idpf_adapter_alloc - allocate devlink and return adapter
+ * @dev: IDPF device to allocate for
+ *
+ * Allocate a devlink instance for this device and return the private area as
+ * the adapter structure.
+ *
+ * Return: adapter structure on success, NULL on failure
+ */
+struct idpf_adapter *idpf_adapter_alloc(struct device *dev)
+{
+	struct devlink *devlink;
+
+	devlink = devlink_alloc(&idpf_devlink_ops, sizeof(struct idpf_adapter),
+				dev);
+	if (!devlink)
+		return NULL;
+
+	return devlink_priv(devlink);
+}
diff --git a/drivers/net/ethernet/intel/idpf/idpf_devlink.h b/drivers/net/ethernet/intel/idpf/idpf_devlink.h
new file mode 100644
index 0000000000000..3ace09be8dddf
--- /dev/null
+++ b/drivers/net/ethernet/intel/idpf/idpf_devlink.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (C) 2026 Intel Corporation */
+
+#ifndef _IDPF_DEVLINK_H_
+#define _IDPF_DEVLINK_H_
+#include <net/devlink.h>
+
+struct idpf_adapter;
+
+struct idpf_adapter *idpf_adapter_alloc(struct device *dev);
+
+/**
+ * idpf_devlink_free - teardown the devlink
+ * @adapter: IDPF adapter structure to free
+ */
+static inline void idpf_devlink_free(struct idpf_adapter *adapter)
+{
+	struct devlink *devlink = priv_to_devlink(adapter);
+
+	devlink_free(devlink);
+}
+
+/**
+ * idpf_devlink_register - register the devlink
+ * @adapter: IDPF adapter structure
+ */
+static inline void idpf_devlink_register(struct idpf_adapter *adapter)
+{
+	struct devlink *devlink = priv_to_devlink(adapter);
+
+	devlink_register(devlink);
+}
+
+/**
+ * idpf_devlink_unregister - unregister the devlink
+ * @adapter: IDPF adapter structure
+ */
+static inline void idpf_devlink_unregister(struct idpf_adapter *adapter)
+{
+	struct devlink *devlink = priv_to_devlink(adapter);
+
+	devlink_unregister(devlink);
+}
+
+#endif /* _IDPF_DEVLINK_H_ */
diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c
index 3dbbe21459990..34a69bb2e36bc 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_main.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_main.c
@@ -3,6 +3,7 @@
 
 #include "idpf.h"
 #include "idpf_devids.h"
+#include "idpf_devlink.h"
 #include "idpf_lan_vf_regs.h"
 #include "idpf_virtchnl.h"
 
@@ -127,12 +128,15 @@ static void idpf_remove(struct pci_dev *pdev)
 
 	set_bit(IDPF_REMOVE_IN_PROG, adapter->flags);
 
+	idpf_devlink_unregister(adapter);
+
 	/* Wait until vc_event_task is done to consider if any hard reset is
 	 * in progress else we may go ahead and release the resources but the
 	 * thread doing the hard reset might continue the init path and
 	 * end up in bad state.
 	 */
 	cancel_delayed_work_sync(&adapter->vc_event_task);
+
 	if (adapter->num_vfs)
 		idpf_sriov_configure(pdev, 0);
 
@@ -184,7 +188,8 @@ static void idpf_remove(struct pci_dev *pdev)
 	mutex_destroy(&adapter->vc_buf_lock);
 
 	idpf_decfg_device(adapter);
-	kfree(adapter);
+
+	idpf_devlink_free(adapter);
 }
 
 /**
@@ -263,7 +268,7 @@ static int idpf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct idpf_adapter *adapter;
 	int err;
 
-	adapter = kzalloc_obj(*adapter);
+	adapter = idpf_adapter_alloc(dev);
 	if (!adapter)
 		return -ENOMEM;
 
@@ -349,6 +354,8 @@ static int idpf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	INIT_DELAYED_WORK(&adapter->stats_task, idpf_statistics_task);
 	INIT_DELAYED_WORK(&adapter->vc_event_task, idpf_vc_event_task);
 
+	idpf_devlink_register(adapter);
+
 	adapter->dev_ops.reg_ops.reset_reg_init(adapter);
 	set_bit(IDPF_HR_DRV_LOAD, adapter->flags);
 	queue_delayed_work(adapter->vc_event_wq, &adapter->vc_event_task,
@@ -367,7 +374,7 @@ static int idpf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 err_init_wq:
 	idpf_decfg_device(adapter);
 err_free:
-	kfree(adapter);
+	idpf_devlink_free(adapter);
 	return err;
 }
 
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH iwl-next v3 3/3] selftests: net: hw: add devlink info test
  2026-09-04 10:37 [PATCH iwl-next v3 0/3] idpf: add devlink info support with selftest Paul Greenwalt
  2026-09-04 10:37 ` [PATCH iwl-next v3 1/3] idpf: clear drvdata in idpf_decfg_device() Paul Greenwalt
  2026-09-04 10:37 ` [PATCH iwl-next v3 2/3] idpf: add devlink support Paul Greenwalt
@ 2026-09-04 10:37 ` Paul Greenwalt
  2 siblings, 0 replies; 4+ messages in thread
From: Paul Greenwalt @ 2026-09-04 10:37 UTC (permalink / raw)
  To: intel-wired-lan; +Cc: Paul Greenwalt

Add a selftest that logs the device information a driver reports through
the devlink info interface: the driver name, serial numbers and every
reported version, in the format NIPA CI consumes for device regression
tracking. This helps maintainers identify pass/fail status changes
caused by FW updates.

Every devlink info field is optional, so the test reports what a device
provides rather than requiring any particular field. devlink reports the
driver name for every registered instance, even when the driver does not
implement info_get, so a device that reports no versions and no serial
number is skipped, as are devices with no devlink instance. Whether the
driver name itself appears in the JSON depends on the installed
iproute2, so it is logged when present but not required.

The devlink 'driver' attribute names the driver bound to the parent
device, which may legitimately differ from the netdev's ethtool driver -
mlx4 reports mlx4_core and mlx4_en, and DSA user ports report dsa - so a
difference is logged rather than failed. ethtool is only used for an
optional fallback handle lookup and that comparison, so it is not
required to run the test.

NETIF is read from the environment or from drivers/net/net.config as
described in drivers/net/README.rst. net.config is sourced before
net/lib.sh so that it cannot clobber the framework's globals. The test
needs only a single local interface, so it sources net/lib.sh rather
than the forwarding library, which requires NUM_NETIFS and a configured
remote host.

Example usage:

  NETIF=eth0 ./tools/testing/selftests/drivers/net/hw/devlink_info.sh

  INFO: driver: idpf
  INFO: serial_number: 00-a0-c9-ff-ff-23-45-67
  INFO: fw.mgmt.api (running): 2.0
  TEST: devlink info                                                  [ OK ]

Link: https://github.com/linux-netdev/nipa/wiki/Netdev-CI-system#device-information
Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
Assisted-by: Claude:claude-opus-5
---
 .../testing/selftests/drivers/net/hw/Makefile |   1 +
 .../selftests/drivers/net/hw/devlink_info.sh  | 158 ++++++++++++++++++
 2 files changed, 159 insertions(+)
 create mode 100755 tools/testing/selftests/drivers/net/hw/devlink_info.sh

diff --git a/tools/testing/selftests/drivers/net/hw/Makefile b/tools/testing/selftests/drivers/net/hw/Makefile
index 78bb0169350b2..edd353f27a396 100644
--- a/tools/testing/selftests/drivers/net/hw/Makefile
+++ b/tools/testing/selftests/drivers/net/hw/Makefile
@@ -19,6 +19,7 @@ TEST_GEN_FILES := \
 
 TEST_PROGS = \
 	csum.py \
+	devlink_info.sh \
 	devlink_rate_cross_esw.py \
 	devlink_rate_tc_bw.py \
 	devmem.py \
diff --git a/tools/testing/selftests/drivers/net/hw/devlink_info.sh b/tools/testing/selftests/drivers/net/hw/devlink_info.sh
new file mode 100755
index 0000000000000..7516297b27d80
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/hw/devlink_info.sh
@@ -0,0 +1,158 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Test devlink info support
+#
+# This test logs the device information a driver reports through the devlink
+# info interface, in the format NIPA CI consumes for regression tracking (see
+# the Device information section at
+# https://github.com/linux-netdev/nipa/wiki/Netdev-CI-system).
+#
+# Implementing devlink info is optional, so a device whose driver reports no
+# versions and no serial number is skipped rather than failed.
+#
+# Usage:
+#   NETIF=eth0 ./devlink_info.sh
+
+ALL_TESTS="devlink_info_test"
+
+lib_dir=$(dirname "$0")
+
+# NETIF may also be provided through drivers/net/net.config, as documented in
+# drivers/net/README.rst. Source it before lib.sh so that a stray assignment
+# cannot clobber the framework's globals.
+if [[ -z "$NETIF" && -f "$lib_dir/../net.config" ]]; then
+	source "$lib_dir/../net.config"
+fi
+
+source "$lib_dir"/../../../net/lib.sh
+
+require_command devlink
+require_command jq
+
+DL_HANDLE=
+DL_INFO=
+
+setup_prepare()
+{
+	local err
+
+	if [[ -z "$NETIF" ]]; then
+		log_test_skip "devlink info" "NETIF is not configured"
+		exit "$EXIT_STATUS"
+	fi
+
+	# Try to get the devlink handle from the devlink port first.
+	DL_HANDLE=$(devlink -j port show 2>/dev/null |
+		jq -r --arg netif "$NETIF" \
+			'.port | to_entries[] |
+			 select(.value.netdev == $netif) | .key' 2>/dev/null |
+		head -n 1 |
+		cut -d/ -f1-2)
+
+	# Fall back to the PCI address reported by ethtool. Devices on other
+	# buses are only found through the devlink port lookup above.
+	if [[ -z "$DL_HANDLE" ]] && command -v ethtool >/dev/null; then
+		local bus_info
+
+		bus_info=$(ethtool -i "$NETIF" 2>/dev/null |
+			awk '/^bus-info:/ {print $2}')
+		if [[ -n "$bus_info" ]] &&
+		   devlink dev show "pci/$bus_info" &>/dev/null; then
+			DL_HANDLE="pci/$bus_info"
+		fi
+	fi
+
+	if [[ -z "$DL_HANDLE" ]]; then
+		log_test_skip "devlink info" "no devlink handle for $NETIF"
+		exit "$EXIT_STATUS"
+	fi
+
+	# Query once so that a single snapshot is validated throughout.
+	DL_INFO=$(devlink -j dev info "$DL_HANDLE" 2>/dev/null)
+	err=$?
+	if ((err)); then
+		log_test_skip "devlink info" "devlink dev info failed for $DL_HANDLE"
+		exit "$EXIT_STATUS"
+	fi
+}
+
+# jq's "// empty" maps a missing or null field to no output, so callers get an
+# empty string rather than the literal text "null".
+info_get()
+{
+	local name=$1
+
+	jq -r --arg name "$name" '.[][][$name] // empty' <<<"$DL_INFO"
+}
+
+log_versions()
+{
+	local versions line
+
+	versions=$(jq -r '.[][].versions // {} | to_entries[] | .key as $type |
+			  .value | to_entries[] |
+			  "\(.key) (\($type)): \(.value)"' <<<"$DL_INFO" \
+			  2>/dev/null)
+
+	while IFS= read -r line; do
+		[[ -n "$line" ]] && log_info "$line"
+	done <<<"$versions"
+}
+
+has_any_version()
+{
+	jq -e '.[][].versions // {} | [.[] | to_entries[]] | length > 0' \
+		<<<"$DL_INFO" &>/dev/null
+}
+
+devlink_info_test()
+{
+	RET=0
+
+	local driver serial board_serial
+
+	driver=$(info_get "driver")
+	serial=$(info_get "serial_number")
+	board_serial=$(info_get "board.serial_number")
+
+	# devlink reports the driver name for every registered instance, even
+	# when the driver does not implement info_get. Everything else is
+	# optional, so a device with nothing further to report is not a
+	# failure.
+	if ! has_any_version && [[ -z "$serial" && -z "$board_serial" ]]; then
+		log_test_skip "devlink info" "no info reported for $DL_HANDLE"
+		return
+	fi
+
+	# Whether the driver name appears in the JSON depends on the installed
+	# iproute2, so report it when present but do not require it.
+	[[ -n "$driver" ]] && log_info "driver: $driver"
+
+	# devlink names the driver bound to the parent device, which can
+	# legitimately differ from the netdev's ethtool driver, so report a
+	# difference without failing.
+	if command -v ethtool >/dev/null; then
+		local ethtool_driver
+
+		ethtool_driver=$(ethtool -i "$NETIF" 2>/dev/null |
+			awk '/^driver:/ {print $2}')
+		if [[ -n "$driver" && -n "$ethtool_driver" &&
+		      "$driver" != "$ethtool_driver" ]]; then
+			log_info "driver mismatch: devlink='$driver' ethtool='$ethtool_driver'"
+		fi
+	fi
+
+	[[ -n "$serial" ]] && log_info "serial_number: $serial"
+	[[ -n "$board_serial" ]] && log_info "board.serial_number: $board_serial"
+
+	log_versions
+
+	log_test "devlink info"
+}
+
+setup_prepare
+
+tests_run
+
+exit "$EXIT_STATUS"
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-09-04 18:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04 10:37 [PATCH iwl-next v3 0/3] idpf: add devlink info support with selftest Paul Greenwalt
2026-09-04 10:37 ` [PATCH iwl-next v3 1/3] idpf: clear drvdata in idpf_decfg_device() Paul Greenwalt
2026-09-04 10:37 ` [PATCH iwl-next v3 2/3] idpf: add devlink support Paul Greenwalt
2026-09-04 10:37 ` [PATCH iwl-next v3 3/3] selftests: net: hw: add devlink info test Paul Greenwalt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox