raw/ifpga: add APIs to get FPGA information
authorWei Huang <wei.huang@intel.com>
Wed, 3 Mar 2021 02:34:30 +0000 (21:34 -0500)
committerQi Zhang <qi.z.zhang@intel.com>
Fri, 5 Mar 2021 08:56:10 +0000 (09:56 +0100)
There are some information data can be got from FPGA, they are
implemented in below APIs:
1. rte_pmd_ifpga_get_property() get properties of FPGA (include BMC).
2. rte_pmd_ifpga_get_phy_info() get information of PHY connect to FPGA.
3. rte_pmd_ifpga_get_rsu_status() get status of rsu process.

Signed-off-by: Wei Huang <wei.huang@intel.com>
Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
Acked-by: Rosen Xu <rosen.xu@intel.com>
drivers/raw/ifpga/base/ifpga_api.c
drivers/raw/ifpga/base/ifpga_defines.h
drivers/raw/ifpga/base/ifpga_feature_dev.c
drivers/raw/ifpga/base/ifpga_feature_dev.h
drivers/raw/ifpga/base/ifpga_fme.c
drivers/raw/ifpga/base/opae_hw_api.c
drivers/raw/ifpga/base/opae_hw_api.h
drivers/raw/ifpga/base/opae_ifpga_hw_api.h
drivers/raw/ifpga/rte_pmd_ifpga.c
drivers/raw/ifpga/rte_pmd_ifpga.h
drivers/raw/ifpga/version.map

index 1aedf15..4610ef1 100644 (file)
@@ -229,6 +229,13 @@ static int ifpga_mgr_get_board_info(struct opae_manager *mgr,
        return 0;
 }
 
+static int ifpga_mgr_get_uuid(struct opae_manager *mgr, struct uuid *uuid)
+{
+       struct ifpga_fme_hw *fme = mgr->data;
+
+       return fpga_get_pr_uuid(fme, uuid);
+}
+
 static int ifpga_mgr_update_flash(struct opae_manager *mgr, const char *image,
        u64 *status)
 {
@@ -256,6 +263,7 @@ struct opae_manager_ops ifpga_mgr_ops = {
        .get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
        .get_sensor_value = ifpga_mgr_get_sensor_value,
        .get_board_info = ifpga_mgr_get_board_info,
+       .get_uuid = ifpga_mgr_get_uuid,
        .update_flash = ifpga_mgr_update_flash,
        .stop_flash_update = ifpga_mgr_stop_flash_update,
        .reload = ifpga_mgr_reload,
index 9f0147d..dca1518 100644 (file)
@@ -1727,6 +1727,7 @@ struct opae_board_info {
        u8 seu;
        u8 ptp;
 
+       u32 boot_page;
        u32 max10_version;
        u32 nios_fw_version;
        u32 nums_of_retimer;
index 0f852a7..0813513 100644 (file)
@@ -87,6 +87,27 @@ int fpga_get_afu_uuid(struct ifpga_port_hw *port, struct uuid *uuid)
        return 0;
 }
 
+int fpga_get_pr_uuid(struct ifpga_fme_hw *fme, struct uuid *uuid)
+{
+       struct feature_fme_pr *fme_pr;
+       u64 guidl, guidh;
+
+       if (!fme || !uuid)
+               return -EINVAL;
+
+       fme_pr = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_PR_MGMT);
+
+       spinlock_lock(&fme->lock);
+       guidl = readq(&fme_pr->fme_pr_intfc_id_l);
+       guidh = readq(&fme_pr->fme_pr_intfc_id_h);
+       spinlock_unlock(&fme->lock);
+
+       opae_memcpy(uuid->b, &guidl, sizeof(u64));
+       opae_memcpy(uuid->b + 8, &guidh, sizeof(u64));
+
+       return 0;
+}
+
 /* Mask / Unmask Port Errors by the Error Mask register. */
 void port_err_mask(struct ifpga_port_hw *port, bool mask)
 {
index 2b1309b..b355d22 100644 (file)
@@ -103,6 +103,7 @@ is_port_feature_present(struct ifpga_port_hw *port, int index)
 }
 
 int fpga_get_afu_uuid(struct ifpga_port_hw *port, struct uuid *uuid);
+int fpga_get_pr_uuid(struct ifpga_fme_hw *fme, struct uuid *uuid);
 
 int __fpga_port_disable(struct ifpga_port_hw *port);
 void __fpga_port_enable(struct ifpga_port_hw *port);
index 34fd9a8..43c7b9c 100644 (file)
@@ -101,6 +101,24 @@ static int fme_hdr_get_ports_num(struct ifpga_fme_hw *fme, u64 *ports_num)
        return 0;
 }
 
+static int fme_hdr_get_port_type(struct ifpga_fme_hw *fme, u64 *port_type)
+{
+       struct feature_fme_header *fme_hdr
+               = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
+       struct feature_fme_port pt;
+       u32 port = (u32)((*port_type >> 32) & 0xffffffff);
+
+       pt.csr = readq(&fme_hdr->port[port]);
+       if (!pt.port_implemented)
+               return -ENODEV;
+       if (pt.afu_access_control)
+               *port_type |= 0x1;
+       else
+               *port_type &= ~0x1;
+
+       return 0;
+}
+
 static int fme_hdr_get_cache_size(struct ifpga_fme_hw *fme, u64 *cache_size)
 {
        struct feature_fme_header *fme_hdr
@@ -179,6 +197,8 @@ fme_hdr_get_prop(struct ifpga_feature *feature, struct feature_prop *prop)
                return fme_hdr_get_bitstream_id(fme, &prop->data);
        case FME_HDR_PROP_BITSTREAM_METADATA:
                return fme_hdr_get_bitstream_metadata(fme, &prop->data);
+       case FME_HDR_PROP_PORT_TYPE:
+               return fme_hdr_get_port_type(fme, &prop->data);
        }
 
        return -ENOENT;
@@ -891,13 +911,17 @@ static int fme_get_board_interface(struct ifpga_fme_hw *fme)
                        fme->board_info.nums_of_fvl,
                        fme->board_info.ports_per_fvl);
 
+       if (max10_sys_read(fme->max10_dev, FPGA_PAGE_INFO, &val))
+               return -EINVAL;
+       fme->board_info.boot_page = val & 0x7;
+
        if (max10_sys_read(fme->max10_dev, MAX10_BUILD_VER, &val))
                return -EINVAL;
-       fme->board_info.max10_version = val & 0xffffff;
+       fme->board_info.max10_version = val;
 
        if (max10_sys_read(fme->max10_dev, NIOS2_FW_VERSION, &val))
                return -EINVAL;
-       fme->board_info.nios_fw_version = val & 0xffffff;
+       fme->board_info.nios_fw_version = val;
 
        dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n",
                fme->board_info.max10_version,
index 86ad88f..11c9887 100644 (file)
@@ -967,6 +967,24 @@ opae_mgr_get_board_info(struct opae_manager *mgr,
        return -ENOENT;
 }
 
+/**
+ * opae_mgr_get_uuid -  get manager's UUID.
+ * @mgr: targeted manager
+ * @uuid: a pointer to UUID
+ *
+ * Return: 0 on success, otherwise error code.
+ */
+int opae_mgr_get_uuid(struct opae_manager *mgr, struct uuid *uuid)
+{
+       if (!mgr || !uuid)
+               return -EINVAL;
+
+       if (mgr->ops && mgr->ops->get_uuid)
+               return mgr->ops->get_uuid(mgr, uuid);
+
+       return -ENOENT;
+}
+
 /**
  * opae_mgr_update_flash -  update image in flash.
  * @mgr: targeted manager
index 91d26d9..7e04b56 100644 (file)
@@ -55,6 +55,7 @@ struct opae_manager_ops {
                        unsigned int *value);
        int (*get_board_info)(struct opae_manager *mgr,
                        struct opae_board_info **info);
+       int (*get_uuid)(struct opae_manager *mgr, struct uuid *uuid);
        int (*update_flash)(struct opae_manager *mgr, const char *image,
                        u64 *status);
        int (*stop_flash_update)(struct opae_manager *mgr, int force);
@@ -360,6 +361,7 @@ int opae_manager_eth_group_read_reg(struct opae_manager *mgr, u8 group_id,
                u8 type, u8 index, u16 addr, u32 *data);
 int opae_mgr_get_board_info(struct opae_manager *mgr,
                struct opae_board_info **info);
+int opae_mgr_get_uuid(struct opae_manager *mgr, struct uuid *uuid);
 int opae_mgr_update_flash(struct opae_manager *mgr, const char *image,
                uint64_t *status);
 int opae_mgr_stop_flash_update(struct opae_manager *mgr, int force);
index bab3386..ffdbebf 100644 (file)
@@ -61,6 +61,7 @@ struct feature_prop {
 #define FME_HDR_PROP_SOCKET_ID         0x5     /* RDONLY */
 #define FME_HDR_PROP_BITSTREAM_ID              0x6     /* RDONLY */
 #define FME_HDR_PROP_BITSTREAM_METADATA        0x7     /* RDONLY */
+#define FME_HDR_PROP_PORT_TYPE         0x8     /* RDWR */
 
 /* FME error reporting feature's properties */
 /* FME error reporting properties format */
index af6f175..8e04e22 100644 (file)
@@ -8,6 +8,7 @@
 #include <rte_rawdev_pmd.h>
 #include "rte_pmd_ifpga.h"
 #include "ifpga_rawdev.h"
+#include "base/ifpga_api.h"
 #include "base/ifpga_sec_mgr.h"
 
 
@@ -99,6 +100,226 @@ get_share_data(struct opae_adapter *adapter)
        return sd;
 }
 
+int
+rte_pmd_ifpga_get_rsu_status(uint16_t dev_id, uint32_t *stat, uint32_t *prog)
+{
+       struct opae_adapter *adapter = NULL;
+       opae_share_data *sd = NULL;
+
+       adapter = get_opae_adapter(dev_id);
+       if (!adapter)
+               return -ENODEV;
+
+       sd = get_share_data(adapter);
+       if (!sd)
+               return -ENOMEM;
+
+       if (stat)
+               *stat = IFPGA_RSU_GET_STAT(sd->rsu_stat);
+       if (prog)
+               *prog = IFPGA_RSU_GET_PROG(sd->rsu_stat);
+
+       return 0;
+}
+
+static int
+ifpga_is_rebooting(struct opae_adapter *adapter)
+{
+       opae_share_data *sd = NULL;
+
+       sd = get_share_data(adapter);
+       if (!sd)
+               return 1;
+
+       if (IFPGA_RSU_GET_STAT(sd->rsu_stat) == IFPGA_RSU_REBOOT) {
+               IFPGA_RAWDEV_PMD_WARN("Reboot is in progress.");
+               return 1;
+       }
+
+       return 0;
+}
+
+static int
+get_common_property(struct opae_adapter *adapter,
+       rte_pmd_ifpga_common_prop *prop)
+{
+       struct ifpga_fme_hw *fme = NULL;
+       struct opae_board_info *info = NULL;
+       struct feature_prop fp;
+       struct uuid pr_id;
+       int ret = 0;
+
+       if (!adapter || !prop)
+               return -EINVAL;
+
+       if (!adapter->mgr || !adapter->mgr->data) {
+               IFPGA_RAWDEV_PMD_ERR("Manager is not registered.");
+               return -ENODEV;
+       }
+
+       fme = adapter->mgr->data;
+       fp.feature_id = FME_FEATURE_ID_HEADER;
+       fp.prop_id = FME_HDR_PROP_PORTS_NUM;
+       ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
+       if (ret) {
+               IFPGA_RAWDEV_PMD_ERR("Failed to get port number.");
+               return ret;
+       }
+       prop->num_ports = fp.data;
+
+       fp.prop_id = FME_HDR_PROP_BITSTREAM_ID;
+       ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
+       if (ret) {
+               IFPGA_RAWDEV_PMD_ERR("Failed to get bitstream ID.");
+               return ret;
+       }
+       prop->bitstream_id = fp.data;
+
+       fp.prop_id = FME_HDR_PROP_BITSTREAM_METADATA;
+       ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
+       if (ret) {
+               IFPGA_RAWDEV_PMD_ERR("Failed to get bitstream metadata.");
+               return ret;
+       }
+       prop->bitstream_metadata = fp.data;
+
+       ret = opae_mgr_get_uuid(adapter->mgr, &pr_id);
+       if (ret) {
+               IFPGA_RAWDEV_PMD_ERR("Failed to get PR ID.");
+               return ret;
+       }
+       memcpy(prop->pr_id.b, pr_id.b, sizeof(rte_pmd_ifpga_uuid));
+
+       ret = opae_mgr_get_board_info(adapter->mgr, &info);
+       if (ret) {
+               IFPGA_RAWDEV_PMD_ERR("Failed to get board info.");
+               return ret;
+       }
+       prop->boot_page = info->boot_page;
+       prop->bmc_version = info->max10_version;
+       prop->bmc_nios_version = info->nios_fw_version;
+
+       return 0;
+}
+
+static int
+get_port_property(struct opae_adapter *adapter, uint16_t port,
+       rte_pmd_ifpga_port_prop *prop)
+{
+       struct ifpga_fme_hw *fme = NULL;
+       struct feature_prop fp;
+       struct opae_accelerator *acc = NULL;
+       struct uuid afu_id;
+       int ret = 0;
+
+       if (!adapter || !prop)
+               return -EINVAL;
+
+       if (!adapter->mgr || !adapter->mgr->data) {
+               IFPGA_RAWDEV_PMD_ERR("Manager is not registered.");
+               return -ENODEV;
+       }
+
+       fme = adapter->mgr->data;
+       fp.feature_id = FME_FEATURE_ID_HEADER;
+       fp.prop_id = FME_HDR_PROP_PORT_TYPE;
+       fp.data = port;
+       fp.data <<= 32;
+       ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
+       if (ret)
+               return ret;
+       prop->type = fp.data & 0xffffffff;
+
+       if (prop->type == 0) {
+               acc = opae_adapter_get_acc(adapter, port);
+               ret = opae_acc_get_uuid(acc, &afu_id);
+               if (ret) {
+                       IFPGA_RAWDEV_PMD_ERR("Failed to get port%u AFU ID.",
+                               port);
+                       return ret;
+               }
+               memcpy(prop->afu_id.b, afu_id.b, sizeof(rte_pmd_ifpga_uuid));
+       }
+
+       return 0;
+}
+
+int
+rte_pmd_ifpga_get_property(uint16_t dev_id, rte_pmd_ifpga_prop *prop)
+{
+       struct opae_adapter *adapter = NULL;
+       uint32_t i = 0;
+       int ret = 0;
+
+       adapter = get_opae_adapter(dev_id);
+       if (!adapter)
+               return -ENODEV;
+
+       opae_adapter_lock(adapter, -1);
+       if (ifpga_is_rebooting(adapter)) {
+               ret = -EBUSY;
+               goto unlock_dev;
+       }
+
+       ret = get_common_property(adapter, &prop->common);
+       if (ret) {
+               ret = -EIO;
+               goto unlock_dev;
+       }
+
+       for (i = 0; i < prop->common.num_ports; i++) {
+               ret = get_port_property(adapter, i, &prop->port[i]);
+               if (ret) {
+                       ret = -EIO;
+                       break;
+               }
+       }
+
+unlock_dev:
+       opae_adapter_unlock(adapter);
+       return ret;
+}
+
+int
+rte_pmd_ifpga_get_phy_info(uint16_t dev_id, rte_pmd_ifpga_phy_info *info)
+{
+       struct opae_adapter *adapter = NULL;
+       struct opae_retimer_info rtm_info;
+       struct opae_retimer_status rtm_status;
+       int ret = 0;
+
+       adapter = get_opae_adapter(dev_id);
+       if (!adapter)
+               return -ENODEV;
+
+       opae_adapter_lock(adapter, -1);
+       if (ifpga_is_rebooting(adapter)) {
+               ret = -EBUSY;
+               goto unlock_dev;
+       }
+
+       ret = opae_manager_get_retimer_info(adapter->mgr, &rtm_info);
+       if (ret) {
+               IFPGA_RAWDEV_PMD_ERR("Failed to get retimer info.");
+               ret = -EIO;
+               goto unlock_dev;
+       }
+       info->num_retimers = rtm_info.nums_retimer;
+
+       ret = opae_manager_get_retimer_status(adapter->mgr, &rtm_status);
+       if (ret) {
+               IFPGA_RAWDEV_PMD_ERR("Failed to get retimer status.");
+               ret = -EIO;
+               goto unlock_dev;
+       }
+       info->link_speed = rtm_status.speed;
+       info->link_status = rtm_status.line_link_bitmap;
+
+unlock_dev:
+       opae_adapter_unlock(adapter);
+       return ret;
+}
+
 int
 rte_pmd_ifpga_update_flash(uint16_t dev_id, const char *image,
        uint64_t *status)
index 023a011..633f6e9 100644 (file)
 extern "C" {
 #endif
 
+#include <stdint.h>
+
+#define IFPGA_MAX_PORT_NUM   4
+
+/**
+ * UUID data structure.
+ */
+typedef struct {
+       uint8_t b[16];
+} rte_pmd_ifpga_uuid;
+
+/**
+ * FME property data structure.
+ */
+typedef struct {
+       uint32_t num_ports;
+       uint32_t boot_page;
+       uint64_t bitstream_id;
+       uint64_t bitstream_metadata;
+       rte_pmd_ifpga_uuid pr_id;
+       uint32_t bmc_version;
+       uint32_t bmc_nios_version;
+} rte_pmd_ifpga_common_prop;
+
+/**
+ * port property data structure.
+ */
+typedef struct {
+       rte_pmd_ifpga_uuid afu_id;
+       uint32_t type;   /* AFU memory access control type */
+} rte_pmd_ifpga_port_prop;
+
+/**
+ * FPGA property data structure.
+ */
+typedef struct {
+       rte_pmd_ifpga_common_prop  common;
+       rte_pmd_ifpga_port_prop    port[IFPGA_MAX_PORT_NUM];
+} rte_pmd_ifpga_prop;
+
+/**
+ * PHY information data structure.
+ */
+typedef struct {
+       uint32_t num_retimers;
+       uint32_t link_speed;
+       uint32_t link_status;
+} rte_pmd_ifpga_phy_info;
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
@@ -37,6 +86,67 @@ __rte_experimental
 int
 rte_pmd_ifpga_get_dev_id(const char *pci_addr, uint16_t *dev_id);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Get current RSU status of the specified Intel FPGA device
+ *
+ * @param dev_id
+ *    The raw device ID of specified Intel FPGA device.
+ * @param stat
+ *    The buffer to output RSU status.
+ * @param prog
+ *    The buffer to output RSU progress.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if dev_id is invalid.
+ *   - (-ENOMEM) if share data is not initialized.
+ */
+__rte_experimental
+int
+rte_pmd_ifpga_get_rsu_status(uint16_t dev_id, uint32_t *stat, uint32_t *prog);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Get FPGA property of specified Intel FPGA device
+ *
+ * @param dev_id
+ *    The raw device ID of specified Intel FPGA device.
+ * @param prop
+ *    The data pointer of FPGA property buffer.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if dev_id is invalid.
+ *   - (-EBUSY) if FPGA is rebooting.
+ *   - (-EIO) if failed to access hardware.
+ */
+__rte_experimental
+int
+rte_pmd_ifpga_get_property(uint16_t dev_id, rte_pmd_ifpga_prop *prop);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Get PHY information of specified Intel FPGA device
+ *
+ * @param dev_id
+ *    The raw device ID of specified Intel FPGA device.
+ * @param info
+ *    The data pointer of PHY information buffer.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if dev_id is invalid.
+ *   - (-EBUSY) if FPGA is rebooting.
+ *   - (-EIO) if failed to access hardware.
+ */
+__rte_experimental
+int
+rte_pmd_ifpga_get_phy_info(uint16_t dev_id, rte_pmd_ifpga_phy_info *info);
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
index 16584f7..ca6f7f5 100644 (file)
@@ -7,6 +7,9 @@ EXPERIMENTAL {
 
        # added in 21.05
        rte_pmd_ifpga_get_dev_id;
+       rte_pmd_ifpga_get_rsu_status;
+       rte_pmd_ifpga_get_property;
+       rte_pmd_ifpga_get_phy_info;
        rte_pmd_ifpga_update_flash;
        rte_pmd_ifpga_stop_update;
        rte_pmd_ifpga_reboot_try;