[PATCH v3 4/6] pds_core: add PLDM component info display

From: Nikhil P. Rao

Date: Mon Jun 08 2026 - 18:47:48 EST


From: Brett Creeley <brett.creeley@xxxxxxx>

Add detailed component information display via devlink info. This
allows users to see individual firmware components and their versions.
Components are reported as fixed, running, or stored based on their
firmware-provided flags.

Example output:
$ devlink dev info pci/0000:00:05.0
versions:
fixed:
asic.id 0x0
asic.rev 0x0
running:
fw.bootloader 1.2.3
fw.uboot 1.60.0-73
fw.mainfw 1.60.0-73
fw.cpld 3.18
fw 1.60.0-73
stored:
fw.bootloader 1.2.3
fw.uboot 1.60.0-73
fw.uboot.gold 1.50.0-22
fw.mainfw.gold 1.50.0-22
fw.mainfw 1.60.0-73
fw.cpld 3.18

Signed-off-by: Brett Creeley <brett.creeley@xxxxxxx>
---
drivers/net/ethernet/amd/pds_core/devlink.c | 105 +++++++++++++++++++-
1 file changed, 103 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c
index 3b763ee1715e..4be34d0cbb59 100644
--- a/drivers/net/ethernet/amd/pds_core/devlink.c
+++ b/drivers/net/ethernet/amd/pds_core/devlink.c
@@ -93,14 +93,97 @@ int pdsc_dl_flash_update(struct devlink *dl,
return pdsc_firmware_update(pdsc, params, extack);
}

+static int pdsc_dl_report_component(struct devlink_info_req *req,
+ struct pds_core_fw_component_info *info)
+{
+ enum devlink_info_version_type ver_type;
+ u16 flags = le16_to_cpu(info->flags);
+ char *ver = info->version;
+ const char *name;
+ char buf[32];
+
+ name = pdsc_fw_type_to_name(info->component_type);
+ if (!name)
+ return 0;
+
+ if (info->slot_id == PDS_CORE_FW_SLOT_GOLD)
+ snprintf(buf, sizeof(buf), "fw.%s.gold", name);
+ else
+ snprintf(buf, sizeof(buf), "fw.%s", name);
+
+ ver_type = DEVLINK_INFO_VERSION_TYPE_NONE;
+ if (flags & PDS_CORE_FW_COMPONENT_INFO_F_UPDATE_BY_NAME)
+ ver_type = DEVLINK_INFO_VERSION_TYPE_COMPONENT;
+
+ if (flags & PDS_CORE_FW_COMPONENT_INFO_F_FIXED) {
+ int err;
+
+ err = devlink_info_version_fixed_put(req, buf, ver);
+ if (err)
+ return err;
+ }
+
+ if (flags & PDS_CORE_FW_COMPONENT_INFO_F_RUNNING) {
+ int err;
+
+ err = devlink_info_version_running_put_ext(req, buf,
+ ver, ver_type);
+ if (err)
+ return err;
+ }
+
+ if (flags & PDS_CORE_FW_COMPONENT_INFO_F_STARTUP) {
+ int err;
+
+ err = devlink_info_version_stored_put_ext(req, buf,
+ ver, ver_type);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int pdsc_dl_component_info_get(struct devlink *dl,
+ struct devlink_info_req *req,
+ struct netlink_ext_ack *extack)
+{
+ struct pds_core_component_list_info *list_info;
+ struct pdsc *pdsc = devlink_priv(dl);
+ u8 num_components;
+ int err;
+ int i;
+
+ if (!pdsc->fw_components.num_components) {
+ err = pdsc_get_component_info(pdsc);
+ if (err) {
+ dev_err(pdsc->dev, "Failed to get component_info %pe\n",
+ ERR_PTR(err));
+ return err;
+ }
+ }
+
+ list_info = &pdsc->fw_components;
+ num_components = min_t(u16, list_info->num_components,
+ le16_to_cpu(pdsc->dev_ident.max_fw_slots));
+ for (i = 0; i < num_components; i++) {
+ err = pdsc_dl_report_component(req, &list_info->info[i]);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static char *fw_slotnames[] = {
"fw.goldfw",
"fw.mainfwa",
"fw.mainfwb",
};

-int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
- struct netlink_ext_ack *extack)
+static int pdsc_dl_fw_list_info_get(struct devlink *dl,
+ struct devlink_info_req *req,
+ struct netlink_ext_ack *extack)
{
union pds_core_dev_cmd cmd = {
.fw_control.opcode = PDS_CORE_CMD_FW_CONTROL,
@@ -134,6 +217,24 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
return err;
}

+ return 0;
+}
+
+int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
+ struct netlink_ext_ack *extack)
+{
+ struct pdsc *pdsc = devlink_priv(dl);
+ char buf[32];
+ int err;
+
+ if (pdsc->dev_ident.version >= PDS_CORE_IDENTITY_VERSION_2)
+ err = pdsc_dl_component_info_get(dl, req, extack);
+ else
+ err = pdsc_dl_fw_list_info_get(dl, req, extack);
+ if (err)
+ dev_warn_once(pdsc->dev, "Failed to get component info: %pe\n",
+ ERR_PTR(err));
+
err = devlink_info_version_running_put(req,
DEVLINK_INFO_VERSION_GENERIC_FW,
pdsc->dev_info.fw_version);
--
2.43.0