struct qed_mcp_link_speed_params *ext_speed;
        struct qed_mcp_link_capabilities *p_caps;
        struct qed_mcp_link_params *link;
+       int i;
 
        /* Read global nvm_cfg address */
        nvm_cfg_addr = qed_rd(p_hwfn, p_ptt, MISC_REG_GEN_PURP_CR0);
                __set_bit(QED_DEV_CAP_ROCE,
                          &p_hwfn->hw_info.device_capabilities);
 
+       /* Read device serial number information from shmem */
+       addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
+               offsetof(struct nvm_cfg1, glob) +
+               offsetof(struct nvm_cfg1_glob, serial_number);
+
+       for (i = 0; i < 4; i++)
+               p_hwfn->hw_info.part_num[i] = qed_rd(p_hwfn, p_ptt, addr + i * 4);
+
        return qed_mcp_fill_shmem_func_info(p_hwfn, p_ptt);
 }
 
 
                             qed_dl_param_get, qed_dl_param_set, NULL),
 };
 
-static const struct devlink_ops qed_dl_ops;
+static int qed_devlink_info_get(struct devlink *devlink,
+                               struct devlink_info_req *req,
+                               struct netlink_ext_ack *extack)
+{
+       struct qed_devlink *qed_dl = devlink_priv(devlink);
+       struct qed_dev *cdev = qed_dl->cdev;
+       struct qed_dev_info *dev_info;
+       char buf[100];
+       int err;
+
+       dev_info = &cdev->common_dev_info;
+
+       err = devlink_info_driver_name_put(req, KBUILD_MODNAME);
+       if (err)
+               return err;
+
+       memcpy(buf, cdev->hwfns[0].hw_info.part_num, sizeof(cdev->hwfns[0].hw_info.part_num));
+       buf[sizeof(cdev->hwfns[0].hw_info.part_num)] = 0;
+
+       if (buf[0]) {
+               err = devlink_info_board_serial_number_put(req, buf);
+               if (err)
+                       return err;
+       }
+
+       snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
+                GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_3),
+                GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_2),
+                GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_1),
+                GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_0));
+
+       err = devlink_info_version_stored_put(req,
+                                             DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, buf);
+       if (err)
+               return err;
+
+       snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
+                dev_info->fw_major,
+                dev_info->fw_minor,
+                dev_info->fw_rev,
+                dev_info->fw_eng);
+
+       return devlink_info_version_running_put(req,
+                                               DEVLINK_INFO_VERSION_GENERIC_FW_APP, buf);
+}
+
+static const struct devlink_ops qed_dl_ops = {
+       .info_get = qed_devlink_info_get,
+};
 
 struct devlink *qed_devlink_register(struct qed_dev *cdev)
 {