--- /dev/null
+.. SPDX-License-Identifier: GPL-2.0+
+
+=====================================
+Meta Platforms Host Network Interface
+=====================================
+
+Firmware Versions
+-----------------
+
+fbnic has three components stored on the flash which are provided in one PLDM
+image:
+
+1. fw - The control firmware used to view and modify firmware settings, request
+   firmware actions, and retrieve firmware counters outside of the data path.
+   This is the firmware which fbnic_fw.c interacts with.
+2. bootloader - The firmware which validate firmware security and control basic
+   operations including loading and updating the firmware. This is also known
+   as the cmrt firmware.
+3. undi - This is the UEFI driver which is based on the Linux driver.
+
+fbnic stores two copies of these three components on flash. This allows fbnic
+to fall back to an older version of firmware automatically in case firmware
+fails to boot. Version information for both is provided as running and stored.
+The undi is only provided in stored as it is not actively running once the Linux
+driver takes over.
+
+devlink dev info provides version information for all three components. In
+addition to the version the hg commit hash of the build is included as a
+separate entry.
 
 
 #define FBNIC_SN_STR_LEN       24
 
+static int fbnic_version_running_put(struct devlink_info_req *req,
+                                    struct fbnic_fw_ver *fw_ver,
+                                    char *ver_name)
+{
+       char running_ver[FBNIC_FW_VER_MAX_SIZE];
+       int err;
+
+       fbnic_mk_fw_ver_str(fw_ver->version, running_ver);
+       err = devlink_info_version_running_put(req, ver_name, running_ver);
+       if (err)
+               return err;
+
+       if (strlen(fw_ver->commit) > 0) {
+               char commit_name[FBNIC_SN_STR_LEN];
+
+               snprintf(commit_name, FBNIC_SN_STR_LEN, "%s.commit", ver_name);
+               err = devlink_info_version_running_put(req, commit_name,
+                                                      fw_ver->commit);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
+static int fbnic_version_stored_put(struct devlink_info_req *req,
+                                   struct fbnic_fw_ver *fw_ver,
+                                   char *ver_name)
+{
+       char stored_ver[FBNIC_FW_VER_MAX_SIZE];
+       int err;
+
+       fbnic_mk_fw_ver_str(fw_ver->version, stored_ver);
+       err = devlink_info_version_stored_put(req, ver_name, stored_ver);
+       if (err)
+               return err;
+
+       if (strlen(fw_ver->commit) > 0) {
+               char commit_name[FBNIC_SN_STR_LEN];
+
+               snprintf(commit_name, FBNIC_SN_STR_LEN, "%s.commit", ver_name);
+               err = devlink_info_version_stored_put(req, commit_name,
+                                                     fw_ver->commit);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
 static int fbnic_devlink_info_get(struct devlink *devlink,
                                  struct devlink_info_req *req,
                                  struct netlink_ext_ack *extack)
        struct fbnic_dev *fbd = devlink_priv(devlink);
        int err;
 
+       err = fbnic_version_running_put(req, &fbd->fw_cap.running.mgmt,
+                                       DEVLINK_INFO_VERSION_GENERIC_FW);
+       if (err)
+               return err;
+
+       err = fbnic_version_running_put(req, &fbd->fw_cap.running.bootloader,
+                                       DEVLINK_INFO_VERSION_GENERIC_FW_BOOTLOADER);
+       if (err)
+               return err;
+
+       err = fbnic_version_stored_put(req, &fbd->fw_cap.stored.mgmt,
+                                      DEVLINK_INFO_VERSION_GENERIC_FW);
+       if (err)
+               return err;
+
+       err = fbnic_version_stored_put(req, &fbd->fw_cap.stored.bootloader,
+                                      DEVLINK_INFO_VERSION_GENERIC_FW_BOOTLOADER);
+       if (err)
+               return err;
+
+       err = fbnic_version_stored_put(req, &fbd->fw_cap.stored.undi,
+                                      DEVLINK_INFO_VERSION_GENERIC_FW_UNDI);
+       if (err)
+               return err;
+
        if (fbd->dsn) {
                unsigned char serial[FBNIC_SN_STR_LEN];
                u8 dsn[8];