* [dpdk-dev] [PATCH v16 0/3] raw/ifpga: add extra APIs for Cyborg
@ 2021-03-03 2:34 Wei Huang
2021-03-03 2:34 ` [dpdk-dev] [PATCH v16 1/3] raw/ifpga: add fpga rsu APIs Wei Huang
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Wei Huang @ 2021-03-03 2:34 UTC (permalink / raw
To: dev, rosen.xu, qi.z.zhang; +Cc: stable, tianfei.zhang, ferruh.yigit, Wei Huang
Cyborg is part of OpenStack, it needs some extra APIs to manage
devices with Intel FPGA. These patches add APIs to meet Cyborg
requirement.
Main changes from v15:
- remove example from the patch set
Wei Huang (3):
raw/ifpga: add fpga rsu APIs
raw/ifpga: add APIs to get fpga information
raw/ifpga: add miscellaneous APIs
doc/api/doxy-api-index.md | 3 +-
doc/api/doxy-api.conf.in | 1 +
drivers/raw/ifpga/base/ifpga_api.c | 34 ++
drivers/raw/ifpga/base/ifpga_defines.h | 1 +
drivers/raw/ifpga/base/ifpga_feature_dev.c | 21 +
drivers/raw/ifpga/base/ifpga_feature_dev.h | 1 +
drivers/raw/ifpga/base/ifpga_fme.c | 36 +-
drivers/raw/ifpga/base/ifpga_fme_rsu.c | 428 ++++++++++++++
drivers/raw/ifpga/base/ifpga_hw.h | 1 +
drivers/raw/ifpga/base/ifpga_sec_mgr.c | 639 +++++++++++++++++++++
drivers/raw/ifpga/base/ifpga_sec_mgr.h | 93 +++
drivers/raw/ifpga/base/meson.build | 2 +
drivers/raw/ifpga/base/opae_hw_api.c | 77 +++
drivers/raw/ifpga/base/opae_hw_api.h | 12 +
drivers/raw/ifpga/base/opae_ifpga_hw_api.h | 1 +
drivers/raw/ifpga/base/opae_intel_max10.c | 48 ++
drivers/raw/ifpga/base/opae_intel_max10.h | 44 ++
drivers/raw/ifpga/ifpga_rawdev.c | 30 +
drivers/raw/ifpga/ifpga_rawdev.h | 7 +-
drivers/raw/ifpga/meson.build | 4 +-
drivers/raw/ifpga/rte_pmd_ifpga.c | 429 ++++++++++++++
drivers/raw/ifpga/rte_pmd_ifpga.h | 308 ++++++++++
drivers/raw/ifpga/version.map | 18 +
23 files changed, 2233 insertions(+), 5 deletions(-)
create mode 100644 drivers/raw/ifpga/base/ifpga_fme_rsu.c
create mode 100644 drivers/raw/ifpga/base/ifpga_sec_mgr.c
create mode 100644 drivers/raw/ifpga/base/ifpga_sec_mgr.h
create mode 100644 drivers/raw/ifpga/rte_pmd_ifpga.c
create mode 100644 drivers/raw/ifpga/rte_pmd_ifpga.h
--
2.29.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dpdk-dev] [PATCH v16 1/3] raw/ifpga: add fpga rsu APIs
2021-03-03 2:34 [dpdk-dev] [PATCH v16 0/3] raw/ifpga: add extra APIs for Cyborg Wei Huang
@ 2021-03-03 2:34 ` Wei Huang
2021-03-03 2:34 ` [dpdk-dev] [PATCH v16 2/3] raw/ifpga: add APIs to get fpga information Wei Huang
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Wei Huang @ 2021-03-03 2:34 UTC (permalink / raw
To: dev, rosen.xu, qi.z.zhang; +Cc: stable, tianfei.zhang, ferruh.yigit, Wei Huang
RSU (Remote System Update) depends on secure manager which may be
different on various implementations, so a new secure manager device
is implemented for adapting such difference.
There are five APIs added:
1. rte_pmd_ifpga_get_dev_id() get raw device ID of ifpga device from
PCI address like 'Domain:Bus:Dev.Func'.
2. rte_pmd_ifpga_update_flash() update flash with specific image file.
3. rte_pmd_ifpga_stop_update() abort flash update process.
4. rte_pmd_ifpga_reboot_try() check current ifpga status and change it
to reboot status if it is idle.
5. rte_pmd_ifpga_reload() trigger full reconfiguration of ifpga device.
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>
---
v2: fix coding style issue in ifpga_fme_rsu.c and ifpga_sec_mgr.c
---
v3: fix compilation issues in ifpga_fme_rsu.c
---
v4: fix compilation issues in opae_intel_max10.c
---
v5: implement APIs in rte_pmd_ifpga.c
---
doc/api/doxy-api-index.md | 3 +-
doc/api/doxy-api.conf.in | 1 +
drivers/raw/ifpga/base/ifpga_api.c | 26 +
drivers/raw/ifpga/base/ifpga_fme.c | 8 +
drivers/raw/ifpga/base/ifpga_fme_rsu.c | 428 +++++++++++++++
drivers/raw/ifpga/base/ifpga_hw.h | 1 +
drivers/raw/ifpga/base/ifpga_sec_mgr.c | 639 ++++++++++++++++++++++
drivers/raw/ifpga/base/ifpga_sec_mgr.h | 93 ++++
drivers/raw/ifpga/base/meson.build | 2 +
drivers/raw/ifpga/base/opae_hw_api.c | 59 ++
drivers/raw/ifpga/base/opae_hw_api.h | 10 +
drivers/raw/ifpga/base/opae_intel_max10.c | 48 ++
drivers/raw/ifpga/base/opae_intel_max10.h | 44 ++
drivers/raw/ifpga/meson.build | 4 +-
drivers/raw/ifpga/rte_pmd_ifpga.c | 163 ++++++
drivers/raw/ifpga/rte_pmd_ifpga.h | 132 +++++
drivers/raw/ifpga/version.map | 11 +
17 files changed, 1670 insertions(+), 2 deletions(-)
create mode 100644 drivers/raw/ifpga/base/ifpga_fme_rsu.c
create mode 100644 drivers/raw/ifpga/base/ifpga_sec_mgr.c
create mode 100644 drivers/raw/ifpga/base/ifpga_sec_mgr.h
create mode 100644 drivers/raw/ifpga/rte_pmd_ifpga.c
create mode 100644 drivers/raw/ifpga/rte_pmd_ifpga.h
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 748514e243..8a48af1042 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -56,7 +56,8 @@ The public API headers are grouped by topics:
[dpaa2_qdma] (@ref rte_pmd_dpaa2_qdma.h),
[crypto_scheduler] (@ref rte_cryptodev_scheduler.h),
[dlb] (@ref rte_pmd_dlb.h),
- [dlb2] (@ref rte_pmd_dlb2.h)
+ [dlb2] (@ref rte_pmd_dlb2.h),
+ [ifpga] (@ref rte_pmd_ifpga.h)
- **memory**:
[memseg] (@ref rte_memory.h),
diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
index 5c883b613b..5eb31508fd 100644
--- a/doc/api/doxy-api.conf.in
+++ b/doc/api/doxy-api.conf.in
@@ -23,6 +23,7 @@ INPUT = @TOPDIR@/doc/api/doxy-api-index.md \
@TOPDIR@/drivers/net/softnic \
@TOPDIR@/drivers/raw/dpaa2_cmdif \
@TOPDIR@/drivers/raw/dpaa2_qdma \
+ @TOPDIR@/drivers/raw/ifpga \
@TOPDIR@/drivers/raw/ioat \
@TOPDIR@/lib/librte_eal/include \
@TOPDIR@/lib/librte_eal/include/generic \
diff --git a/drivers/raw/ifpga/base/ifpga_api.c b/drivers/raw/ifpga/base/ifpga_api.c
index 1ff57fa188..1aedf150bc 100644
--- a/drivers/raw/ifpga/base/ifpga_api.c
+++ b/drivers/raw/ifpga/base/ifpga_api.c
@@ -5,6 +5,7 @@
#include "ifpga_api.h"
#include "ifpga_enumerate.h"
#include "ifpga_feature_dev.h"
+#include "ifpga_sec_mgr.h"
#include "opae_hw_api.h"
@@ -228,11 +229,36 @@ static int ifpga_mgr_get_board_info(struct opae_manager *mgr,
return 0;
}
+static int ifpga_mgr_update_flash(struct opae_manager *mgr, const char *image,
+ u64 *status)
+{
+ struct ifpga_fme_hw *fme = mgr->data;
+
+ return fpga_update_flash(fme, image, status);
+}
+
+static int ifpga_mgr_stop_flash_update(struct opae_manager *mgr, int force)
+{
+ struct ifpga_fme_hw *fme = mgr->data;
+
+ return fpga_stop_flash_update(fme, force);
+}
+
+static int ifpga_mgr_reload(struct opae_manager *mgr, int type, int page)
+{
+ struct ifpga_fme_hw *fme = mgr->data;
+
+ return fpga_reload(fme, type, page);
+}
+
struct opae_manager_ops ifpga_mgr_ops = {
.flash = ifpga_mgr_flash,
.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,
+ .update_flash = ifpga_mgr_update_flash,
+ .stop_flash_update = ifpga_mgr_stop_flash_update,
+ .reload = ifpga_mgr_reload,
};
static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset,
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index f29ff3159b..34fd9a818e 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -7,6 +7,7 @@
#include "opae_intel_max10.h"
#include "opae_i2c.h"
#include "opae_at24_eeprom.h"
+#include "ifpga_sec_mgr.h"
#define PWR_THRESHOLD_MAX 0x7F
@@ -1152,6 +1153,12 @@ static int fme_nios_spi_init(struct ifpga_feature *feature)
if (spi_self_checking(max10))
goto spi_fail;
+ ret = init_sec_mgr(fme);
+ if (ret) {
+ dev_err(fme, "security manager init fail\n");
+ goto spi_fail;
+ }
+
return ret;
spi_fail:
@@ -1165,6 +1172,7 @@ static void fme_nios_spi_uinit(struct ifpga_feature *feature)
{
struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
+ release_sec_mgr(fme);
if (fme->max10_dev)
intel_max10_device_remove(fme->max10_dev);
}
diff --git a/drivers/raw/ifpga/base/ifpga_fme_rsu.c b/drivers/raw/ifpga/base/ifpga_fme_rsu.c
new file mode 100644
index 0000000000..28198abd78
--- /dev/null
+++ b/drivers/raw/ifpga/base/ifpga_fme_rsu.c
@@ -0,0 +1,428 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#include "ifpga_sec_mgr.h"
+
+static struct ifpga_sec_mgr *sec_mgr;
+
+static void set_rsu_control(struct ifpga_sec_mgr *smgr, uint32_t ctrl)
+{
+ if (smgr && smgr->rsu_control)
+ *smgr->rsu_control = ctrl;
+}
+
+static uint32_t get_rsu_control(struct ifpga_sec_mgr *smgr)
+{
+ if (smgr && smgr->rsu_control)
+ return *smgr->rsu_control;
+ return 0;
+}
+
+static void set_rsu_status(struct ifpga_sec_mgr *smgr, uint32_t status,
+ uint32_t progress)
+{
+ if (smgr && smgr->rsu_status)
+ *smgr->rsu_status = IFPGA_RSU_STATUS(status, progress);
+}
+
+static void get_rsu_status(struct ifpga_sec_mgr *smgr, uint32_t *status,
+ uint32_t *progress)
+{
+ if (smgr && smgr->rsu_status) {
+ if (status)
+ *status = IFPGA_RSU_GET_STAT(*smgr->rsu_status);
+ if (progress)
+ *progress = IFPGA_RSU_GET_PROG(*smgr->rsu_status);
+ }
+}
+
+static void sig_handler(int sig, siginfo_t *info, void *data)
+{
+ (void)(info);
+ (void)(data);
+
+ switch (sig) {
+ case SIGINT:
+ if (sec_mgr) {
+ dev_info(sec_mgr, "Interrupt secure flash update"
+ " by keyboard\n");
+ set_rsu_control(sec_mgr, IFPGA_RSU_ABORT);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void log_time(time_t t, const char *msg)
+{
+ uint32_t h = 0;
+ uint32_t m = 0;
+ uint32_t s = 0;
+
+ if (t < 60) {
+ s = (uint32_t)t;
+ } else if (t < 3600) {
+ s = (uint32_t)(t % 60);
+ m = (uint32_t)(t / 60);
+ } else {
+ s = (uint32_t)(t % 60);
+ m = (uint32_t)((t % 3600) / 60);
+ h = (uint32_t)(t / 3600);
+ }
+ printf("%s - %02u:%02u:%02u\n", msg, h, m, s);
+}
+
+static int start_flash_update(struct ifpga_sec_mgr *smgr)
+{
+ if (!smgr)
+ return -ENODEV;
+
+ if (!smgr->ops || !smgr->ops->prepare)
+ return -EINVAL;
+
+ return smgr->ops->prepare(smgr);
+}
+
+static int write_flash_image(struct ifpga_sec_mgr *smgr, const char *image,
+ uint32_t offset)
+{
+ void *buf = NULL;
+ int retry = 0;
+ uint32_t length = 0;
+ uint32_t to_transfer = 0;
+ uint32_t one_percent = 0;
+ uint32_t prog = 0;
+ uint32_t old_prog = -1;
+ ssize_t read_size = 0;
+ int fd = -1;
+ int ret = 0;
+
+ if (!smgr)
+ return -ENODEV;
+
+ if (!smgr->ops || !smgr->ops->write_blk)
+ return -EINVAL;
+
+ fd = open(image, O_RDONLY);
+ if (fd < 0) {
+ dev_err(smgr,
+ "Failed to open \'%s\' for RD [e:%s]\n",
+ image, strerror(errno));
+ return -EIO;
+ }
+
+ buf = malloc(IFPGA_RSU_DATA_BLK_SIZE);
+ if (!buf) {
+ dev_err(smgr, "Failed to allocate memory for flash update\n");
+ close(fd);
+ return -ENOMEM;
+ }
+
+ length = smgr->rsu_length;
+ one_percent = length / 100;
+ do {
+ to_transfer = (length > IFPGA_RSU_DATA_BLK_SIZE) ?
+ IFPGA_RSU_DATA_BLK_SIZE : length;
+ lseek(fd, offset, SEEK_SET);
+ read_size = read(fd, buf, to_transfer);
+ if (read_size < 0) {
+ dev_err(smgr, "Failed to read from \'%s\' [e:%s]\n",
+ image, strerror(errno));
+ ret = -EIO;
+ goto end;
+ }
+ if ((uint32_t)read_size != to_transfer) {
+ dev_err(smgr,
+ "Read length %zd is not expected [e:%u]\n",
+ read_size, to_transfer);
+ ret = -EIO;
+ goto end;
+ }
+
+ retry = 0;
+ do {
+ if (get_rsu_control(smgr) == IFPGA_RSU_ABORT) {
+ ret = -EAGAIN;
+ goto end;
+ }
+ ret = smgr->ops->write_blk(smgr, buf, offset,
+ to_transfer);
+ if (ret == 0)
+ break;
+ sleep(1);
+ } while (++retry <= IFPGA_RSU_WRITE_RETRY);
+ if (retry > IFPGA_RSU_WRITE_RETRY) {
+ dev_err(smgr, "Failed to write to staging area 0x%x\n",
+ offset);
+ ret = -EAGAIN;
+ goto end;
+ }
+
+ length -= to_transfer;
+ offset += to_transfer;
+ prog = offset / one_percent;
+ if (prog != old_prog) {
+ printf("\r%d%%", prog);
+ fflush(stdout);
+ set_rsu_status(smgr, IFPGA_RSU_READY, prog);
+ old_prog = prog;
+ }
+ } while (length > 0);
+ set_rsu_status(smgr, IFPGA_RSU_READY, 100);
+ printf("\n");
+
+end:
+ free(buf);
+ close(fd);
+ return ret;
+}
+
+static int apply_flash_update(struct ifpga_sec_mgr *smgr)
+{
+ uint32_t one_percent = 0;
+ uint32_t one_percent_time = 0;
+ uint32_t prog = 0;
+ uint32_t old_prog = -1;
+ uint32_t copy_time = 0;
+ int ret = 0;
+
+ if (!smgr)
+ return -ENODEV;
+
+ if (!smgr->ops || !smgr->ops->write_done || !smgr->ops->check_complete)
+ return -EINVAL;
+
+ if (smgr->ops->write_done(smgr) < 0) {
+ dev_err(smgr, "Failed to apply flash update\n");
+ return -EAGAIN;
+ }
+
+ one_percent = (smgr->rsu_length + 99) / 100;
+ if (smgr->copy_speed == 0) /* avoid zero divide fault */
+ smgr->copy_speed = 1;
+ one_percent_time = (one_percent + smgr->copy_speed - 1) /
+ smgr->copy_speed;
+ if (one_percent_time == 0) /* avoid zero divide fault */
+ one_percent_time = 1;
+
+ do {
+ ret = smgr->ops->check_complete(smgr);
+ if (ret != -EAGAIN)
+ break;
+ sleep(1);
+ copy_time += 1;
+ prog = copy_time / one_percent_time;
+ if (prog >= 100)
+ prog = 99;
+ if (prog != old_prog) {
+ printf("\r%d%%", prog);
+ fflush(stdout);
+ set_rsu_status(smgr, IFPGA_RSU_COPYING, prog);
+ old_prog = prog;
+ }
+ } while (true);
+
+ if (ret < 0) {
+ printf("\n");
+ dev_err(smgr, "Failed to complete secure flash update\n");
+ } else {
+ printf("\r100%%\n");
+ set_rsu_status(smgr, IFPGA_RSU_COPYING, 100);
+ }
+
+ return ret;
+}
+
+static int secure_update_cancel(struct ifpga_sec_mgr *smgr)
+{
+ if (!smgr)
+ return -ENODEV;
+
+ if (!smgr->ops || !smgr->ops->cancel)
+ return -EINVAL;
+
+ return smgr->ops->cancel(smgr);
+}
+
+static int secure_update_status(struct ifpga_sec_mgr *smgr, uint64_t *status)
+{
+ if (!smgr)
+ return -ENODEV;
+
+ if (!smgr->ops || !smgr->ops->get_hw_errinfo)
+ return -EINVAL;
+
+ if (status)
+ *status = smgr->ops->get_hw_errinfo(smgr);
+
+ return 0;
+}
+
+int fpga_update_flash(struct ifpga_fme_hw *fme, const char *image,
+ uint64_t *status)
+{
+ struct ifpga_hw *hw = NULL;
+ struct ifpga_sec_mgr *smgr = NULL;
+ uint32_t rsu_stat = 0;
+ int fd = -1;
+ struct sigaction old_sigint_action;
+ struct sigaction sa;
+ time_t start;
+ int ret = 0;
+
+ if (!fme || !image || !status) {
+ dev_err(fme, "Input parameter of %s is invalid\n", __func__);
+ return -EINVAL;
+ }
+
+ hw = (struct ifpga_hw *)fme->parent;
+ if (!hw) {
+ dev_err(fme, "Parent of FME not found\n");
+ return -ENODEV;
+ }
+
+ smgr = (struct ifpga_sec_mgr *)fme->sec_mgr;
+ if (!smgr || !smgr->max10_dev) {
+ dev_err(smgr, "Security manager not initialized\n");
+ return -ENODEV;
+ }
+
+ opae_adapter_lock(hw->adapter, -1);
+ get_rsu_status(smgr, &rsu_stat, NULL);
+ if (rsu_stat != IFPGA_RSU_IDLE) {
+ opae_adapter_unlock(hw->adapter);
+ if (rsu_stat == IFPGA_RSU_REBOOT)
+ dev_info(smgr, "Reboot is in progress\n");
+ else
+ dev_info(smgr, "Update is in progress\n");
+ return -EAGAIN;
+ }
+ set_rsu_control(smgr, 0);
+ set_rsu_status(smgr, IFPGA_RSU_PREPARE, 0);
+ opae_adapter_unlock(hw->adapter);
+
+ fd = open(image, O_RDONLY);
+ if (fd < 0) {
+ dev_err(smgr,
+ "Failed to open \'%s\' for RD [e:%s]\n",
+ image, strerror(errno));
+ return -EIO;
+ }
+ smgr->rsu_length = lseek(fd, 0, SEEK_END);
+ close(fd);
+
+ if (smgr->max10_dev->staging_area_size < smgr->rsu_length) {
+ dev_err(dev, "Size of staging area is small than image length "
+ "[%u<%u]\n", smgr->max10_dev->staging_area_size,
+ smgr->rsu_length);
+ return -EINVAL;
+ }
+
+ printf("Updating from file \'%s\' with size %u\n",
+ image, smgr->rsu_length);
+
+ sec_mgr = smgr;
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_flags = SA_SIGINFO | SA_RESETHAND;
+ sa.sa_sigaction = sig_handler;
+ ret = sigaction(SIGINT, &sa, &old_sigint_action);
+ if (ret < 0) {
+ dev_warn(dev, "Failed to register signal handler"
+ " [e:%d]\n", ret);
+ sec_mgr = NULL;
+ }
+
+ start = time(NULL);
+ log_time(time(NULL) - start, "Starting secure flash update");
+ ret = start_flash_update(smgr);
+ if (ret < 0)
+ goto end;
+
+ set_rsu_status(smgr, IFPGA_RSU_READY, 0);
+ log_time(time(NULL) - start, "Writing to staging area");
+ ret = write_flash_image(smgr, image, 0);
+ if (ret < 0)
+ goto end;
+
+ set_rsu_status(smgr, IFPGA_RSU_COPYING, 0);
+ log_time(time(NULL) - start, "Applying secure flash update");
+ ret = apply_flash_update(smgr);
+
+end:
+ if (sec_mgr) {
+ sec_mgr = NULL;
+ if (sigaction(SIGINT, &old_sigint_action, NULL) < 0)
+ dev_err(smgr, "Failed to unregister signal handler\n");
+ }
+
+ secure_update_status(smgr, status);
+ if (ret < 0) {
+ log_time(time(NULL) - start, "Secure flash update ERROR");
+ if (ret == -EAGAIN)
+ secure_update_cancel(smgr);
+ } else {
+ log_time(time(NULL) - start, "Secure flash update OK");
+ }
+ set_rsu_status(smgr, IFPGA_RSU_IDLE, 0);
+
+ return ret;
+}
+
+int fpga_stop_flash_update(struct ifpga_fme_hw *fme, int force)
+{
+ struct ifpga_sec_mgr *smgr = NULL;
+ uint32_t status = 0;
+ int retry = IFPGA_RSU_CANCEL_RETRY;
+ int ret = 0;
+
+ if (!fme) {
+ dev_err(fme, "Input parameter of %s is invalid\n", __func__);
+ return -EINVAL;
+ }
+ smgr = (struct ifpga_sec_mgr *)fme->sec_mgr;
+
+ get_rsu_status(smgr, &status, NULL);
+ if (status != IFPGA_RSU_IDLE) {
+ dev_info(smgr, "Cancel secure flash update\n");
+ set_rsu_control(smgr, IFPGA_RSU_ABORT);
+ }
+
+ if (force) {
+ sleep(2);
+ do {
+ get_rsu_status(smgr, &status, NULL);
+ if (status == IFPGA_RSU_IDLE)
+ break;
+ if (secure_update_cancel(smgr) == 0)
+ set_rsu_status(smgr, IFPGA_RSU_IDLE, 0);
+ sleep(1);
+ } while (--retry > 0);
+ if (retry <= 0) {
+ dev_err(smgr, "Failed to stop flash update\n");
+ ret = -EAGAIN;
+ }
+ }
+
+ return ret;
+}
+
+int fpga_reload(struct ifpga_fme_hw *fme, int type, int page)
+{
+ struct ifpga_sec_mgr *smgr = NULL;
+
+ if (!fme) {
+ dev_err(fme, "Input parameter of %s is invalid\n", __func__);
+ return -EINVAL;
+ }
+ smgr = (struct ifpga_sec_mgr *)fme->sec_mgr;
+
+ if (!smgr || !smgr->ops || !smgr->ops->reload)
+ return -EINVAL;
+
+ return smgr->ops->reload(smgr, type, page);
+}
diff --git a/drivers/raw/ifpga/base/ifpga_hw.h b/drivers/raw/ifpga/base/ifpga_hw.h
index 7c3307fe77..ed5edc6016 100644
--- a/drivers/raw/ifpga/base/ifpga_hw.h
+++ b/drivers/raw/ifpga/base/ifpga_hw.h
@@ -91,6 +91,7 @@ struct ifpga_fme_hw {
struct opae_board_info board_info;
int nums_eth_dev;
unsigned int nums_acc_region;
+ void *sec_mgr;
};
enum ifpga_port_state {
diff --git a/drivers/raw/ifpga/base/ifpga_sec_mgr.c b/drivers/raw/ifpga/base/ifpga_sec_mgr.c
new file mode 100644
index 0000000000..4cf1db3049
--- /dev/null
+++ b/drivers/raw/ifpga/base/ifpga_sec_mgr.c
@@ -0,0 +1,639 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#include "ifpga_sec_mgr.h"
+
+
+static const char * const rsu_prog[] = {"IDLE", "PREPARING", "SLEEPING",
+ "READY", "AUTHENTICATING", "COPYING", "CANCELLATION", "PROGRAMMING_KEY",
+ "DONE", "PKVL_DONE"};
+static const char * const rsu_statl[] = {"NORMAL", "TIMEOUT", "AUTH_FAIL",
+ "COPY_FAIL", "FATAL", "PKVL_REJECT", "NON_INCR", "ERASE_FAIL",
+ "WEAROUT"};
+static const char * const rsu_stath[] = {"NIOS_OK", "USER_OK", "FACTORY_OK",
+ "USER_FAIL", "FACTORY_FAIL", "NIOS_FLASH_ERR", "FPGA_FLASH_ERR"};
+
+static const char *rsu_progress_name(uint32_t prog)
+{
+ if (prog > SEC_PROGRESS_PKVL_PROM_DONE)
+ return "UNKNOWN";
+ else
+ return rsu_prog[prog];
+}
+
+static const char *rsu_status_name(uint32_t stat)
+{
+ if (stat >= SEC_STATUS_NIOS_OK) {
+ if (stat > SEC_STATUS_FPGA_FLASH_ERR)
+ return "UNKNOWN";
+ else
+ return rsu_stath[stat-SEC_STATUS_NIOS_OK];
+ } else {
+ if (stat > SEC_STATUS_WEAROUT)
+ return "UNKNOWN";
+ else
+ return rsu_statl[stat];
+ }
+}
+
+static bool secure_start_done(uint32_t doorbell)
+{
+ return (SEC_STATUS_G(doorbell) == SEC_STATUS_ERASE_FAIL ||
+ SEC_STATUS_G(doorbell) == SEC_STATUS_WEAROUT ||
+ (SEC_PROGRESS_G(doorbell) != SEC_PROGRESS_IDLE &&
+ SEC_PROGRESS_G(doorbell) != SEC_PROGRESS_RSU_DONE));
+}
+
+static bool secure_prog_ready(uint32_t doorbell)
+{
+ return (SEC_PROGRESS_G(doorbell) != SEC_PROGRESS_READY);
+}
+
+static int poll_timeout(struct intel_max10_device *dev, uint32_t offset,
+ bool (*cond)(uint32_t), uint32_t interval_ms, uint32_t timeout_ms)
+{
+ uint32_t val = 0;
+ int ret = 0;
+
+ for (;;) {
+ ret = max10_sys_read(dev, offset, &val);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to read max10 register 0x%x [e:%d]\n",
+ offset, ret);
+ break;
+ }
+
+ if (cond(val)) {
+ dev_debug(dev,
+ "Read 0x%08x from max10 register 0x%x "
+ "[poll success]\n", val, offset);
+ ret = 0;
+ break;
+ }
+ if (timeout_ms > interval_ms)
+ timeout_ms -= interval_ms;
+ else
+ timeout_ms = 0;
+ if (timeout_ms == 0) {
+ dev_debug(dev,
+ "Read 0x%08x from max10 register 0x%x "
+ "[poll timeout]\n", val, offset);
+ ret = -ETIMEDOUT;
+ break;
+ }
+ msleep(interval_ms);
+ }
+
+ return ret;
+}
+
+static int n3000_secure_update_start(struct intel_max10_device *dev)
+{
+ uint32_t doorbell = 0;
+ uint32_t prog = 0;
+ uint32_t status = 0;
+ int ret = 0;
+
+ ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to read max10 doorbell register [e:%d]\n",
+ ret);
+ return ret;
+ }
+
+ prog = SEC_PROGRESS_G(doorbell);
+ if ((prog != SEC_PROGRESS_IDLE) && (prog != SEC_PROGRESS_RSU_DONE)) {
+ dev_debug(dev, "Current RSU progress is %s\n",
+ rsu_progress_name(prog));
+ return -EBUSY;
+ }
+
+ ret = max10_sys_update_bits(dev, MAX10_DOORBELL,
+ RSU_REQUEST | HOST_STATUS, RSU_REQUEST);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to updt max10 doorbell register [e:%d]\n",
+ ret);
+ return ret;
+ }
+
+ ret = poll_timeout(dev, MAX10_DOORBELL, secure_start_done,
+ IFPGA_SEC_START_INTERVAL_MS, IFPGA_SEC_START_TIMEOUT_MS);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to poll max10 doorbell register [e:%d]\n",
+ ret);
+ return ret;
+ }
+
+ ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to read max10 doorbell register [e:%d]\n",
+ ret);
+ return ret;
+ }
+
+ status = SEC_STATUS_G(doorbell);
+ if (status == SEC_STATUS_WEAROUT)
+ return -EAGAIN;
+
+ if (status == SEC_STATUS_ERASE_FAIL)
+ return -EIO;
+
+ return 0;
+}
+
+static int n3000_cancel(struct ifpga_sec_mgr *smgr)
+{
+ struct intel_max10_device *dev = NULL;
+ uint32_t doorbell = 0;
+ uint32_t prog = 0;
+ int ret = 0;
+
+ if (!smgr || !smgr->max10_dev)
+ return -ENODEV;
+ dev = (struct intel_max10_device *)smgr->max10_dev;
+
+ ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to read max10 doorbell register [e:%d]\n",
+ ret);
+ return ret;
+ }
+
+ prog = SEC_PROGRESS_G(doorbell);
+ if (prog == SEC_PROGRESS_IDLE)
+ return 0;
+ if (prog != SEC_PROGRESS_READY)
+ return -EBUSY;
+
+ return max10_sys_update_bits(dev, MAX10_DOORBELL, HOST_STATUS,
+ HOST_STATUS_S(HOST_STATUS_ABORT_RSU));
+}
+
+static int n3000_prepare(struct ifpga_sec_mgr *smgr)
+{
+ struct intel_max10_device *dev = NULL;
+ int retry = 0;
+ int ret = 0;
+
+ if (!smgr || !smgr->max10_dev)
+ return -ENODEV;
+ dev = (struct intel_max10_device *)smgr->max10_dev;
+
+ ret = n3000_secure_update_start(dev);
+ if (ret == -EBUSY)
+ n3000_cancel(smgr);
+
+ while (ret) {
+ if (++retry > IFPGA_RSU_START_RETRY)
+ break;
+ msleep(1000);
+ ret = n3000_secure_update_start(dev);
+ }
+ if (retry > IFPGA_RSU_START_RETRY) {
+ dev_err(dev, "Failed to start secure flash update\n");
+ ret = -EAGAIN;
+ }
+
+ return ret;
+}
+
+static int n3000_bulk_write(struct intel_max10_device *dev, uint32_t addr,
+ char *buf, uint32_t len)
+{
+ uint32_t i = 0;
+ uint32_t n = 0;
+ uint32_t v = 0;
+ uint32_t p = 0;
+ int ret = 0;
+
+ if (len & 0x3) {
+ dev_err(dev,
+ "Length of data block is not 4 bytes aligned [e:%u]\n",
+ len);
+ return -EINVAL;
+ }
+
+ n = len >> 2;
+ for (i = 0; i < n; i++) {
+ p = i << 2;
+ v = *(uint32_t *)(buf + p);
+ ret = max10_reg_write(dev, addr + p, v);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to write to staging area 0x%08x [e:%d]\n",
+ addr + p, ret);
+ return ret;
+ }
+ usleep(1);
+ }
+
+ return 0;
+}
+
+static int n3000_write_blk(struct ifpga_sec_mgr *smgr, char *buf,
+ uint32_t offset, uint32_t len)
+{
+ struct intel_max10_device *dev = NULL;
+ uint32_t doorbell = 0;
+ uint32_t prog = 0;
+ uint32_t m = 0;
+ int ret = 0;
+
+ if (!smgr || !smgr->max10_dev)
+ return -ENODEV;
+ dev = (struct intel_max10_device *)smgr->max10_dev;
+
+ if (offset + len > dev->staging_area_size) {
+ dev_err(dev,
+ "Write position would be out of staging area [e:%u]\n",
+ dev->staging_area_size);
+ return -ENOMEM;
+ }
+
+ ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to read max10 doorbell register [e:%d]\n",
+ ret);
+ return ret;
+ }
+
+ prog = SEC_PROGRESS_G(doorbell);
+ if (prog == SEC_PROGRESS_PREPARE)
+ return -EAGAIN;
+ else if (prog != SEC_PROGRESS_READY)
+ return -EBUSY;
+
+ m = len & 0x3;
+ if (m != 0)
+ len += 4 - m; /* make length to 4 bytes align */
+
+ return n3000_bulk_write(dev, dev->staging_area_base + offset, buf, len);
+}
+
+static int n3000_write_done(struct ifpga_sec_mgr *smgr)
+{
+ struct intel_max10_device *dev = NULL;
+ uint32_t doorbell = 0;
+ uint32_t prog = 0;
+ uint32_t status = 0;
+ int ret = 0;
+
+ if (!smgr || !smgr->max10_dev)
+ return -ENODEV;
+ dev = (struct intel_max10_device *)smgr->max10_dev;
+
+ ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to read max10 doorbell register [e:%d]\n",
+ ret);
+ return ret;
+ }
+
+ prog = SEC_PROGRESS_G(doorbell);
+ if (prog != SEC_PROGRESS_READY)
+ return -EBUSY;
+
+ ret = max10_sys_update_bits(dev, MAX10_DOORBELL, HOST_STATUS,
+ HOST_STATUS_S(HOST_STATUS_WRITE_DONE));
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to update max10 doorbell register [e:%d]\n",
+ ret);
+ return ret;
+ }
+
+ ret = poll_timeout(dev, MAX10_DOORBELL, secure_prog_ready,
+ IFPGA_NIOS_HANDSHAKE_INTERVAL_MS,
+ IFPGA_NIOS_HANDSHAKE_TIMEOUT_MS);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to poll max10 doorbell register [e:%d]\n",
+ ret);
+ return ret;
+ }
+
+ ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to read max10 doorbell register [e:%d]\n",
+ ret);
+ return ret;
+ }
+
+ status = SEC_STATUS_G(doorbell);
+ switch (status) {
+ case SEC_STATUS_NORMAL:
+ case SEC_STATUS_NIOS_OK:
+ case SEC_STATUS_USER_OK:
+ case SEC_STATUS_FACTORY_OK:
+ ret = 0;
+ break;
+ default:
+ ret = -EIO;
+ break;
+ }
+
+ return ret;
+}
+
+static int n3000_check_complete(struct ifpga_sec_mgr *smgr)
+{
+ struct intel_max10_device *dev = NULL;
+ uint32_t doorbell = 0;
+ uint32_t status = 0;
+ uint32_t prog = 0;
+ int ret = 0;
+
+ if (!smgr || !smgr->max10_dev)
+ return -ENODEV;
+ dev = (struct intel_max10_device *)smgr->max10_dev;
+
+ ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to read max10 doorbell register [e:%d]\n",
+ ret);
+ return ret;
+ }
+
+ status = SEC_STATUS_G(doorbell);
+ switch (status) {
+ case SEC_STATUS_NORMAL:
+ case SEC_STATUS_NIOS_OK:
+ case SEC_STATUS_USER_OK:
+ case SEC_STATUS_FACTORY_OK:
+ case SEC_STATUS_WEAROUT:
+ break;
+ default:
+ return -EIO;
+ }
+
+ prog = SEC_PROGRESS_G(doorbell);
+ switch (prog) {
+ case SEC_PROGRESS_IDLE:
+ case SEC_PROGRESS_RSU_DONE:
+ return 0;
+ case SEC_PROGRESS_AUTHENTICATING:
+ case SEC_PROGRESS_COPYING:
+ case SEC_PROGRESS_UPDATE_CANCEL:
+ case SEC_PROGRESS_PROGRAM_KEY_HASH:
+ return -EAGAIN;
+ case SEC_PROGRESS_PREPARE:
+ case SEC_PROGRESS_READY:
+ return -EBUSY;
+ default:
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int n3000_reload_fpga(struct intel_max10_device *dev, int page)
+{
+ int ret = 0;
+
+ dev_info(dev, "Reload FPGA\n");
+
+ if (!dev || ((page != 0) && (page != 1))) {
+ dev_err(dev, "Input parameter of %s is invalid\n", __func__);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ if (dev->flags & MAX10_FLAGS_SECURE) {
+ ret = max10_sys_update_bits(dev, FPGA_RECONF_REG,
+ SFPGA_RP_LOAD, 0);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to update max10 reconfig register [e:%d]\n",
+ ret);
+ goto end;
+ }
+ ret = max10_sys_update_bits(dev, FPGA_RECONF_REG,
+ SFPGA_RP_LOAD | SFPGA_RECONF_PAGE,
+ SFPGA_RP_LOAD | SFPGA_PAGE(page));
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to update max10 reconfig register [e:%d]\n",
+ ret);
+ goto end;
+ }
+ } else {
+ ret = max10_sys_update_bits(dev, RSU_REG, FPGA_RP_LOAD, 0);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to update max10 rsu register [e:%d]\n",
+ ret);
+ goto end;
+ }
+ ret = max10_sys_update_bits(dev, RSU_REG,
+ FPGA_RP_LOAD | FPGA_RECONF_PAGE,
+ FPGA_RP_LOAD | FPGA_PAGE(page));
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to update max10 rsu register [e:%d]\n",
+ ret);
+ goto end;
+ }
+ }
+
+ ret = max10_sys_update_bits(dev, FPGA_RECONF_REG, COUNTDOWN_START, 0);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to update max10 reconfig register [e:%d]\n",
+ ret);
+ goto end;
+ }
+
+ ret = max10_sys_update_bits(dev, FPGA_RECONF_REG, COUNTDOWN_START,
+ COUNTDOWN_START);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to update max10 reconfig register [e:%d]\n",
+ ret);
+ }
+end:
+ if (ret < 0)
+ dev_err(dev, "Failed to reload FPGA\n");
+
+ return ret;
+}
+
+static int n3000_reload_bmc(struct intel_max10_device *dev, int page)
+{
+ uint32_t val = 0;
+ int ret = 0;
+
+ dev_info(dev, "Reload BMC\n");
+
+ if (!dev || ((page != 0) && (page != 1))) {
+ dev_err(dev, "Input parameter of %s is invalid\n", __func__);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ if (dev->flags & MAX10_FLAGS_SECURE) {
+ ret = max10_sys_update_bits(dev, MAX10_DOORBELL,
+ CONFIG_SEL | REBOOT_REQ,
+ CONFIG_SEL_S(page) | REBOOT_REQ);
+ } else {
+ val = (page == 0) ? 0x1 : 0x3;
+ ret = max10_reg_write(dev, IFPGA_DUAL_CFG_CTRL1, val);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to write to dual config1 register [e:%d]\n",
+ ret);
+ goto end;
+ }
+
+ ret = max10_reg_write(dev, IFPGA_DUAL_CFG_CTRL0, 0x1);
+ if (ret < 0) {
+ if (ret == -EIO) {
+ ret = 0;
+ goto end;
+ }
+ dev_err(dev,
+ "Failed to write to dual config0 register [e:%d]\n",
+ ret);
+ }
+ }
+
+end:
+ if (ret < 0)
+ dev_err(dev, "Failed to reload BMC\n");
+
+ return ret;
+}
+
+static int n3000_reload(struct ifpga_sec_mgr *smgr, int type, int page)
+{
+ int psel = 0;
+ int ret = 0;
+
+ if (!smgr || !smgr->max10_dev)
+ return -ENODEV;
+
+ if (type == IFPGA_BOOT_TYPE_FPGA) {
+ psel = (page == IFPGA_BOOT_PAGE_FACTORY ? 0 : 1);
+ ret = n3000_reload_fpga(smgr->max10_dev, psel);
+ } else if (type == IFPGA_BOOT_TYPE_BMC) {
+ psel = (page == IFPGA_BOOT_PAGE_FACTORY ? 1 : 0);
+ ret = n3000_reload_bmc(smgr->max10_dev, psel);
+ } else {
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static uint64_t n3000_get_hw_errinfo(struct ifpga_sec_mgr *smgr)
+{
+ struct intel_max10_device *dev = NULL;
+ uint32_t doorbell = 0;
+ uint32_t stat = 0;
+ uint32_t prog = 0;
+ uint32_t auth_result = 0;
+ int ret = 0;
+
+ if (!smgr || !smgr->max10_dev)
+ return -ENODEV;
+ dev = (struct intel_max10_device *)smgr->max10_dev;
+
+ ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
+ if (ret < 0) {
+ dev_err(dev, "Failed to read max10 doorbell register [e:%d]\n",
+ ret);
+ return -1;
+ }
+ stat = SEC_STATUS_G(doorbell);
+ prog = SEC_PROGRESS_G(doorbell);
+ dev_debug(dev, "Current RSU status is %s, progress is %s\n",
+ rsu_status_name(stat), rsu_progress_name(prog));
+
+ ret = max10_sys_read(dev, MAX10_AUTH_RESULT, &auth_result);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to read authenticate result register [e:%d]\n",
+ ret);
+ return -1;
+ }
+
+ return (uint64_t)doorbell << 32 | (uint64_t)auth_result;
+}
+
+static const struct ifpga_sec_ops n3000_sec_ops = {
+ .prepare = n3000_prepare,
+ .write_blk = n3000_write_blk,
+ .write_done = n3000_write_done,
+ .check_complete = n3000_check_complete,
+ .reload = n3000_reload,
+ .cancel = n3000_cancel,
+ .cleanup = NULL,
+ .get_hw_errinfo = n3000_get_hw_errinfo,
+};
+
+int init_sec_mgr(struct ifpga_fme_hw *fme)
+{
+ struct ifpga_hw *hw = NULL;
+ opae_share_data *sd = NULL;
+ struct ifpga_sec_mgr *smgr = NULL;
+
+ if (!fme || !fme->max10_dev)
+ return -ENODEV;
+
+ smgr = (struct ifpga_sec_mgr *)malloc(sizeof(*smgr));
+ if (!smgr) {
+ dev_err(NULL, "Failed to allocate memory for security manager\n");
+ return -ENOMEM;
+ }
+ fme->sec_mgr = smgr;
+
+ hw = (struct ifpga_hw *)fme->parent;
+ if (hw && hw->adapter && hw->adapter->shm.ptr) {
+ sd = (opae_share_data *)hw->adapter->shm.ptr;
+ smgr->rsu_control = &sd->rsu_ctrl;
+ smgr->rsu_status = &sd->rsu_stat;
+ } else {
+ smgr->rsu_control = NULL;
+ smgr->rsu_status = NULL;
+ }
+
+ if ((hw->pci_data->device_id == IFPGA_N3000_DID) &&
+ (hw->pci_data->vendor_id == IFPGA_N3000_VID)) {
+ smgr->ops = &n3000_sec_ops;
+ smgr->copy_speed = IFPGA_N3000_COPY_SPEED;
+ } else {
+ dev_err(NULL, "No operation for security manager\n");
+ smgr->ops = NULL;
+ }
+
+ smgr->fme = fme;
+ smgr->max10_dev = fme->max10_dev;
+
+ return 0;
+}
+
+void release_sec_mgr(struct ifpga_fme_hw *fme)
+{
+ struct ifpga_sec_mgr *smgr = NULL;
+
+ if (fme) {
+ smgr = (struct ifpga_sec_mgr *)fme->sec_mgr;
+ if (smgr) {
+ fme->sec_mgr = NULL;
+ free(smgr);
+ }
+ }
+}
diff --git a/drivers/raw/ifpga/base/ifpga_sec_mgr.h b/drivers/raw/ifpga/base/ifpga_sec_mgr.h
new file mode 100644
index 0000000000..fbeba561f4
--- /dev/null
+++ b/drivers/raw/ifpga/base/ifpga_sec_mgr.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+
+#ifndef _IFPGA_FME_RSU_H_
+#define _IFPGA_FME_RSU_H_
+
+
+#include "ifpga_hw.h"
+
+#define IFPGA_N3000_VID 0x8086
+#define IFPGA_N3000_DID 0x0b30
+
+#define IFPGA_BOOT_TYPE_FPGA 0
+#define IFPGA_BOOT_TYPE_BMC 1
+
+#define IFPGA_BOOT_PAGE_FACTORY 0
+#define IFPGA_BOOT_PAGE_USER 1
+
+#define IFPGA_RSU_DATA_BLK_SIZE 32768
+#define IFPGA_RSU_START_RETRY 120
+#define IFPGA_RSU_WRITE_RETRY 10
+#define IFPGA_RSU_CANCEL_RETRY 30
+
+#define IFPGA_N3000_COPY_SPEED 42700
+
+/* status */
+#define IFPGA_RSU_IDLE 0
+#define IFPGA_RSU_PREPARE 1
+#define IFPGA_RSU_READY 2
+#define IFPGA_RSU_COPYING 3
+#define IFPGA_RSU_REBOOT 4
+
+#define IFPGA_RSU_GET_STAT(v) (((v) >> 16) & 0xffff)
+#define IFPGA_RSU_GET_PROG(v) ((v) & 0xffff)
+#define IFPGA_RSU_STATUS(s, p) ((((s) << 16) & 0xffff0000) | ((p) & 0xffff))
+
+/* control */
+#define IFPGA_RSU_ABORT 1
+
+#define IFPGA_DUAL_CFG_CTRL0 0x200020
+#define IFPGA_DUAL_CFG_CTRL1 0x200024
+
+#define IFPGA_SEC_START_INTERVAL_MS 100
+#define IFPGA_SEC_START_TIMEOUT_MS 20000
+#define IFPGA_NIOS_HANDSHAKE_INTERVAL_MS 100
+#define IFPGA_NIOS_HANDSHAKE_TIMEOUT_MS 5000
+
+#define IFPGA_RSU_ERR_HW_ERROR -1
+#define IFPGA_RSU_ERR_TIMEOUT -2
+#define IFPGA_RSU_ERR_CANCELED -3
+#define IFPGA_RSU_ERR_BUSY -4
+#define IFPGA_RSU_ERR_INVALID_SIZE -5
+#define IFPGA_RSU_ERR_RW_ERROR -6
+#define IFPGA_RSU_ERR_WEAROUT -7
+#define IFPGA_RSU_ERR_FILE_READ -8
+
+struct ifpga_sec_mgr;
+
+struct ifpga_sec_ops {
+ int (*prepare)(struct ifpga_sec_mgr *smgr);
+ int (*write_blk)(struct ifpga_sec_mgr *smgr, char *buf, uint32_t offset,
+ uint32_t size);
+ int (*write_done)(struct ifpga_sec_mgr *smgr);
+ int (*check_complete)(struct ifpga_sec_mgr *smgr);
+ int (*reload)(struct ifpga_sec_mgr *smgr, int type, int page);
+ int (*cancel)(struct ifpga_sec_mgr *smgr);
+ void (*cleanup)(struct ifpga_sec_mgr *smgr);
+ u64 (*get_hw_errinfo)(struct ifpga_sec_mgr *smgr);
+};
+
+struct ifpga_sec_mgr {
+ struct ifpga_fme_hw *fme;
+ struct intel_max10_device *max10_dev;
+ unsigned int rsu_length;
+ /* number of bytes that copied from staging area to working area
+ * in one second, which is calculated by experiment
+ */
+ unsigned int copy_speed;
+ unsigned int *rsu_control;
+ unsigned int *rsu_status;
+ const struct ifpga_sec_ops *ops;
+};
+
+int init_sec_mgr(struct ifpga_fme_hw *fme);
+void release_sec_mgr(struct ifpga_fme_hw *fme);
+int fpga_update_flash(struct ifpga_fme_hw *fme, const char *image,
+ uint64_t *status);
+int fpga_stop_flash_update(struct ifpga_fme_hw *fme, int force);
+int fpga_reload(struct ifpga_fme_hw *fme, int type, int page);
+
+
+#endif /* _IFPGA_FME_RSU_H_ */
diff --git a/drivers/raw/ifpga/base/meson.build b/drivers/raw/ifpga/base/meson.build
index da2d6e33ca..3549afafa1 100644
--- a/drivers/raw/ifpga/base/meson.build
+++ b/drivers/raw/ifpga/base/meson.build
@@ -12,6 +12,8 @@ sources = [
'ifpga_port.c',
'ifpga_port_error.c',
'ifpga_fme_pr.c',
+ 'ifpga_fme_rsu.c',
+ 'ifpga_sec_mgr.c',
'opae_hw_api.c',
'opae_ifpga_hw_api.c',
'opae_debug.c',
diff --git a/drivers/raw/ifpga/base/opae_hw_api.c b/drivers/raw/ifpga/base/opae_hw_api.c
index d5cd5fe608..86ad88f720 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.c
+++ b/drivers/raw/ifpga/base/opae_hw_api.c
@@ -470,6 +470,8 @@ static void opae_adapter_shm_init(struct opae_adapter *adapter)
opae_mutex_init(&sd->i2c_mutex);
sd->ref_cnt = 0;
sd->dtb_size = SHM_BLK_SIZE;
+ sd->rsu_ctrl = 0;
+ sd->rsu_stat = 0;
}
static void *opae_adapter_shm_alloc(struct opae_adapter *adapter)
@@ -964,3 +966,60 @@ opae_mgr_get_board_info(struct opae_manager *mgr,
return -ENOENT;
}
+
+/**
+ * opae_mgr_update_flash - update image in flash.
+ * @mgr: targeted manager
+ * @image: name of image file
+ * @status: status of update
+ *
+ * Return: 0 on success, otherwise error code.
+ */
+int opae_mgr_update_flash(struct opae_manager *mgr, const char *image,
+ uint64_t *status)
+{
+ if (!mgr)
+ return -EINVAL;
+
+ if (mgr->ops && mgr->ops->update_flash)
+ return mgr->ops->update_flash(mgr, image, status);
+
+ return -ENOENT;
+}
+
+/**
+ * opae_stop_flash_update - stop flash update.
+ * @mgr: targeted manager
+ * @force: make sure the update process is stopped
+ *
+ * Return: 0 on success, otherwise error code.
+ */
+int opae_mgr_stop_flash_update(struct opae_manager *mgr, int force)
+{
+ if (!mgr)
+ return -EINVAL;
+
+ if (mgr->ops && mgr->ops->stop_flash_update)
+ return mgr->ops->stop_flash_update(mgr, force);
+
+ return -ENOENT;
+}
+
+/**
+ * opae_mgr_reload - reload FPGA.
+ * @mgr: targeted manager
+ * @type: FPGA type
+ * @page: reload from which page
+ *
+ * Return: 0 on success, otherwise error code.
+ */
+int opae_mgr_reload(struct opae_manager *mgr, int type, int page)
+{
+ if (!mgr)
+ return -EINVAL;
+
+ if (mgr->ops && mgr->ops->reload)
+ return mgr->ops->reload(mgr, type, page);
+
+ return -ENOENT;
+}
diff --git a/drivers/raw/ifpga/base/opae_hw_api.h b/drivers/raw/ifpga/base/opae_hw_api.h
index e99ee4564c..91d26d9b5b 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_hw_api.h
@@ -55,6 +55,10 @@ struct opae_manager_ops {
unsigned int *value);
int (*get_board_info)(struct opae_manager *mgr,
struct opae_board_info **info);
+ int (*update_flash)(struct opae_manager *mgr, const char *image,
+ u64 *status);
+ int (*stop_flash_update)(struct opae_manager *mgr, int force);
+ int (*reload)(struct opae_manager *mgr, int type, int page);
};
/* networking management ops in FME */
@@ -276,6 +280,8 @@ typedef struct {
pthread_mutex_t i2c_mutex;
u32 ref_cnt; /* reference count of shared memory */
u32 dtb_size; /* actual length of DTB data in byte */
+ u32 rsu_ctrl; /* used to control rsu */
+ u32 rsu_stat; /* used to report status for rsu */
};
};
u8 dtb[SHM_BLK_SIZE]; /* DTB data */
@@ -354,4 +360,8 @@ 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_update_flash(struct opae_manager *mgr, const char *image,
+ uint64_t *status);
+int opae_mgr_stop_flash_update(struct opae_manager *mgr, int force);
+int opae_mgr_reload(struct opae_manager *mgr, int type, int page);
#endif /* _OPAE_HW_API_H_*/
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 1a526ea549..443e248fb3 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -51,6 +51,22 @@ int max10_sys_write(struct intel_max10_device *dev,
return max10_reg_write(dev, dev->base + offset, val);
}
+int max10_sys_update_bits(struct intel_max10_device *dev, unsigned int offset,
+ unsigned int msk, unsigned int val)
+{
+ int ret = 0;
+ unsigned int temp = 0;
+
+ ret = max10_sys_read(dev, offset, &temp);
+ if (ret < 0)
+ return ret;
+
+ temp &= ~msk;
+ temp |= val & msk;
+
+ return max10_sys_write(dev, offset, temp);
+}
+
static struct max10_compatible_id max10_id_table[] = {
{.compatible = MAX10_PAC,},
{.compatible = MAX10_PAC_N3000,},
@@ -557,6 +573,36 @@ static int check_max10_version(struct intel_max10_device *dev)
return -ENODEV;
}
+static int max10_staging_area_init(struct intel_max10_device *dev)
+{
+ char *fdt_root = dev->fdt_root;
+ int ret, offset = 0;
+ u64 start, size;
+
+ if (!fdt_root) {
+ dev_debug(dev,
+ "skip staging area init as not find Device Tree\n");
+ return -ENODEV;
+ }
+
+ dev->staging_area_size = 0;
+
+ fdt_for_each_subnode(offset, fdt_root, 0) {
+ if (fdt_node_check_compatible(fdt_root, offset,
+ "ifpga-sec-mgr,staging-area"))
+ continue;
+
+ ret = fdt_get_reg(fdt_root, offset, 0, &start, &size);
+ if (!ret) {
+ dev->staging_area_base = start;
+ dev->staging_area_size = size;
+ }
+ return ret;
+ }
+
+ return -ENODEV;
+}
+
static int
max10_secure_hw_init(struct intel_max10_device *dev)
{
@@ -581,6 +627,8 @@ max10_secure_hw_init(struct intel_max10_device *dev)
max10_sensor_init(dev, sysmgr_offset);
+ max10_staging_area_init(dev);
+
return 0;
}
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index 123cdc48b9..670683f017 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -38,6 +38,8 @@ struct intel_max10_device {
unsigned int base; /* max10 base address */
u16 bus;
struct opae_sensor_list opae_sensor_list;
+ u32 staging_area_base;
+ u32 staging_area_size;
};
/* retimer speed */
@@ -98,6 +100,7 @@ struct opae_retimer_status {
#define MAX10_MAC_COUNT GENMASK(23, 16)
#define RSU_REG 0x2c
#define FPGA_RECONF_PAGE GENMASK(2, 0)
+#define FPGA_PAGE(p) ((p) & 0x1)
#define FPGA_RP_LOAD BIT(3)
#define NIOS2_PRERESET BIT(4)
#define NIOS2_HANG BIT(5)
@@ -106,6 +109,9 @@ struct opae_retimer_status {
#define NIOS2_I2C2_POLL_STOP BIT(13)
#define PKVL_EEPROM_LOAD BIT(31)
#define FPGA_RECONF_REG 0x30
+#define SFPGA_RECONF_PAGE GENMASK(22, 20)
+#define SFPGA_PAGE(p) (((p) & 0x1) << 20)
+#define SFPGA_RP_LOAD BIT(23)
#define MAX10_TEST_REG 0x3c
#define COUNTDOWN_START BIT(18)
#define MAX10_BUILD_VER 0x68
@@ -118,8 +124,44 @@ struct opae_retimer_status {
#define MAX10_DOORBELL 0x400
#define RSU_REQUEST BIT(0)
#define SEC_PROGRESS GENMASK(7, 4)
+#define SEC_PROGRESS_G(v) (((v) >> 4) & 0xf)
+#define SEC_PROGRESS_IDLE 0x0
+#define SEC_PROGRESS_PREPARE 0x1
+#define SEC_PROGRESS_SLEEP 0x2
+#define SEC_PROGRESS_READY 0x3
+#define SEC_PROGRESS_AUTHENTICATING 0x4
+#define SEC_PROGRESS_COPYING 0x5
+#define SEC_PROGRESS_UPDATE_CANCEL 0x6
+#define SEC_PROGRESS_PROGRAM_KEY_HASH 0x7
+#define SEC_PROGRESS_RSU_DONE 0x8
+#define SEC_PROGRESS_PKVL_PROM_DONE 0x9
#define HOST_STATUS GENMASK(11, 8)
+#define HOST_STATUS_S(v) (((v) << 8) & 0xf00)
+#define HOST_STATUS_IDLE 0x0
+#define HOST_STATUS_WRITE_DONE 0x1
+#define HOST_STATUS_ABORT_RSU 0x2
#define SEC_STATUS GENMASK(23, 16)
+#define SEC_STATUS_G(v) (((v) >> 16) & 0xff)
+#define SEC_STATUS_NORMAL 0x0
+#define SEC_STATUS_TIMEOUT 0x1
+#define SEC_STATUS_AUTH_FAIL 0x2
+#define SEC_STATUS_COPY_FAIL 0x3
+#define SEC_STATUS_FATAL 0x4
+#define SEC_STATUS_PKVL_REJECT 0x5
+#define SEC_STATUS_NON_INC 0x6
+#define SEC_STATUS_ERASE_FAIL 0x7
+#define SEC_STATUS_WEAROUT 0x8
+#define SEC_STATUS_NIOS_OK 0x80
+#define SEC_STATUS_USER_OK 0x81
+#define SEC_STATUS_FACTORY_OK 0x82
+#define SEC_STATUS_USER_FAIL 0x83
+#define SEC_STATUS_FACTORY_FAIL 0x84
+#define SEC_STATUS_NIOS_FLASH_ERR 0x85
+#define SEC_STATUS_FPGA_FLASH_ERR 0x86
+#define CONFIG_SEL BIT(28)
+#define CONFIG_SEL_S(v) (((v) & 0x1) << 28)
+#define REBOOT_REQ BIT(29)
+#define MAX10_AUTH_RESULT 0x404
/* PKVL related registers, in system register region */
#define PKVL_POLLING_CTRL 0x80
@@ -149,6 +191,8 @@ int max10_sys_read(struct intel_max10_device *dev,
unsigned int offset, unsigned int *val);
int max10_sys_write(struct intel_max10_device *dev,
unsigned int offset, unsigned int val);
+int max10_sys_update_bits(struct intel_max10_device *dev,
+ unsigned int offset, unsigned int msk, unsigned int val);
struct intel_max10_device *
intel_max10_device_probe(struct altera_spi_device *spi,
int chipselect);
diff --git a/drivers/raw/ifpga/meson.build b/drivers/raw/ifpga/meson.build
index 027ff80562..60ea59ae28 100644
--- a/drivers/raw/ifpga/meson.build
+++ b/drivers/raw/ifpga/meson.build
@@ -13,8 +13,10 @@ objs = [base_objs]
deps += ['ethdev', 'rawdev', 'pci', 'bus_pci', 'kvargs',
'bus_vdev', 'bus_ifpga', 'net', 'net_i40e', 'net_ipn3ke']
-sources = files('ifpga_rawdev.c')
+sources = files('ifpga_rawdev.c', 'rte_pmd_ifpga.c')
includes += include_directories('base')
includes += include_directories('../../net/ipn3ke')
includes += include_directories('../../net/i40e')
+
+headers = files('rte_pmd_ifpga.h')
diff --git a/drivers/raw/ifpga/rte_pmd_ifpga.c b/drivers/raw/ifpga/rte_pmd_ifpga.c
new file mode 100644
index 0000000000..af6f175e98
--- /dev/null
+++ b/drivers/raw/ifpga/rte_pmd_ifpga.c
@@ -0,0 +1,163 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Intel Corporation
+ */
+
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include "rte_pmd_ifpga.h"
+#include "ifpga_rawdev.h"
+#include "base/ifpga_sec_mgr.h"
+
+
+int
+rte_pmd_ifpga_get_dev_id(const char *pci_addr, uint16_t *dev_id)
+{
+ struct rte_pci_addr addr;
+ struct rte_rawdev *rdev = NULL;
+ char rdev_name[RTE_RAWDEV_NAME_MAX_LEN] = {0};
+
+ if (!pci_addr || !dev_id) {
+ IFPGA_RAWDEV_PMD_ERR("Input parameter is invalid.");
+ return -EINVAL;
+ }
+
+ if (strnlen(pci_addr, PCI_PRI_STR_SIZE) == PCI_PRI_STR_SIZE) {
+ IFPGA_RAWDEV_PMD_ERR("PCI address is too long.");
+ return -EINVAL;
+ }
+
+ if (rte_pci_addr_parse(pci_addr, &addr)) {
+ IFPGA_RAWDEV_PMD_ERR("PCI address %s is invalid.", pci_addr);
+ return -EINVAL;
+ }
+
+ snprintf(rdev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%02x:%02x.%x",
+ addr.bus, addr.devid, addr.function);
+ rdev = rte_rawdev_pmd_get_named_dev(rdev_name);
+ if (!rdev) {
+ IFPGA_RAWDEV_PMD_DEBUG("%s is not probed by ifpga driver.",
+ pci_addr);
+ return -ENODEV;
+ }
+ *dev_id = rdev->dev_id;
+
+ return 0;
+}
+
+static struct rte_rawdev *
+get_rte_rawdev(uint16_t dev_id)
+{
+ struct rte_rawdev *dev = NULL;
+
+ if (dev_id >= RTE_RAWDEV_MAX_DEVS)
+ return NULL;
+
+ dev = &rte_rawdevs[dev_id];
+ if (dev->attached == RTE_RAWDEV_ATTACHED)
+ return dev;
+
+ return NULL;
+}
+
+static struct opae_adapter *
+get_opae_adapter(uint16_t dev_id)
+{
+ struct rte_rawdev *dev = NULL;
+ struct opae_adapter *adapter = NULL;
+
+ dev = get_rte_rawdev(dev_id);
+ if (!dev) {
+ IFPGA_RAWDEV_PMD_ERR("Device ID %u is invalid.", dev_id);
+ return NULL;
+ }
+
+ adapter = ifpga_rawdev_get_priv(dev);
+ if (!adapter) {
+ IFPGA_RAWDEV_PMD_ERR("Adapter is not registered.");
+ return NULL;
+ }
+
+ return adapter;
+}
+
+static opae_share_data *
+get_share_data(struct opae_adapter *adapter)
+{
+ opae_share_data *sd = NULL;
+
+ if (!adapter)
+ return NULL;
+
+ sd = (opae_share_data *)adapter->shm.ptr;
+ if (!sd) {
+ IFPGA_RAWDEV_PMD_ERR("Share data is not initialized.");
+ return NULL;
+ }
+
+ return sd;
+}
+
+int
+rte_pmd_ifpga_update_flash(uint16_t dev_id, const char *image,
+ uint64_t *status)
+{
+ struct opae_adapter *adapter = NULL;
+
+ adapter = get_opae_adapter(dev_id);
+ if (!adapter)
+ return -ENODEV;
+
+ return opae_mgr_update_flash(adapter->mgr, image, status);
+}
+
+int
+rte_pmd_ifpga_stop_update(uint16_t dev_id, int force)
+{
+ struct opae_adapter *adapter = NULL;
+
+ adapter = get_opae_adapter(dev_id);
+ if (!adapter)
+ return -ENODEV;
+
+ return opae_mgr_stop_flash_update(adapter->mgr, force);
+}
+
+int
+rte_pmd_ifpga_reboot_try(uint16_t dev_id)
+{
+ 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;
+
+ opae_adapter_lock(adapter, -1);
+ if (IFPGA_RSU_GET_STAT(sd->rsu_stat) != IFPGA_RSU_IDLE) {
+ opae_adapter_unlock(adapter);
+ IFPGA_RAWDEV_PMD_WARN("Update or reboot is in progress.");
+ return -EBUSY;
+ }
+ sd->rsu_stat = IFPGA_RSU_STATUS(IFPGA_RSU_REBOOT, 0);
+ opae_adapter_unlock(adapter);
+
+ return 0;
+}
+
+int
+rte_pmd_ifpga_reload(uint16_t dev_id, int type, int page)
+{
+ struct opae_adapter *adapter = NULL;
+
+ adapter = get_opae_adapter(dev_id);
+ if (!adapter)
+ return -ENODEV;
+
+ return opae_mgr_reload(adapter->mgr, type, page);
+}
diff --git a/drivers/raw/ifpga/rte_pmd_ifpga.h b/drivers/raw/ifpga/rte_pmd_ifpga.h
new file mode 100644
index 0000000000..023a011116
--- /dev/null
+++ b/drivers/raw/ifpga/rte_pmd_ifpga.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Intel Corporation
+ */
+
+#ifndef _RTE_PMD_IFPGA_H_
+#define _RTE_PMD_IFPGA_H_
+
+/**
+ * @file rte_pmd_ifpga.h
+ *
+ * ifpga PMD specific functions.
+ *
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Get raw device ID from PCI address string like 'Domain:Bus:Dev.Func'
+ *
+ * @param pci_addr
+ * The PCI address of specified Intel FPGA device.
+ * @param dev_id
+ * The buffer to output device ID.
+ * @return
+ * - (0) if successful.
+ * - (-EINVAL) if bad parameter.
+ * - (-ENODEV) if FPGA is not probed by ifpga driver.
+ */
+__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
+ *
+ * Update image flash of specified Intel FPGA device
+ *
+ * @param dev_id
+ * The raw device ID of specified Intel FPGA device.
+ * @param image
+ * The image file name string.
+ * @param status
+ * The detailed update status for debug.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if dev_id is invalid.
+ * - (-EINVAL) if bad parameter or staging area is not initialized.
+ * - (-EBUSY) if FPGA is updating or rebooting.
+ * - (-EIO) if failed to open image file.
+ */
+__rte_experimental
+int
+rte_pmd_ifpga_update_flash(uint16_t dev_id, const char *image,
+ uint64_t *status);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Stop flash update of specified Intel FPGA device
+ *
+ * @param dev_id
+ * The raw device ID of specified Intel FPGA device.
+ * @param force
+ * Abort the update process by writing register if set non-zero.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if dev_id is invalid.
+ * - (-EINVAL) if bad parameter.
+ * - (-EAGAIN) if failed with force.
+ */
+__rte_experimental
+int
+rte_pmd_ifpga_stop_update(uint16_t dev_id, int force);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Check current Intel FPGA status and change it to reboot status if it is idle
+ *
+ * @param dev_id
+ * The raw device ID of specified Intel FPGA device.
+ * @return
+ * - (0) if FPGA is ready to reboot.
+ * - (-ENODEV) if dev_id is invalid.
+ * - (-ENOMEM) if share data is not initialized.
+ * - (-EBUSY) if FPGA is updating or rebooting.
+ */
+__rte_experimental
+int
+rte_pmd_ifpga_reboot_try(uint16_t dev_id);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Trigger full reconfiguration of specified Intel FPGA device
+ *
+ * @param dev_id
+ * The raw device ID of specified Intel FPGA device.
+ * @param type
+ * Select reconfiguration type.
+ * 0 - reconfigure FPGA only.
+ * 1 - reboot the whole card including FPGA.
+ * @param page
+ * Select image from which flash partition.
+ * 0 - factory partition.
+ * 1 - user partition.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if dev_id is invalid.
+ * - (-EINVAL) if bad parameter.
+ * - (-EBUSY) if failed to access BMC register.
+ */
+__rte_experimental
+int
+rte_pmd_ifpga_reload(uint16_t dev_id, int type, int page);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PMD_IFPGA_H_ */
diff --git a/drivers/raw/ifpga/version.map b/drivers/raw/ifpga/version.map
index 4a76d1d52d..16584f7fe4 100644
--- a/drivers/raw/ifpga/version.map
+++ b/drivers/raw/ifpga/version.map
@@ -1,3 +1,14 @@
DPDK_21 {
local: *;
};
+
+EXPERIMENTAL {
+ global:
+
+ # added in 21.05
+ rte_pmd_ifpga_get_dev_id;
+ rte_pmd_ifpga_update_flash;
+ rte_pmd_ifpga_stop_update;
+ rte_pmd_ifpga_reboot_try;
+ rte_pmd_ifpga_reload;
+};
--
2.29.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [dpdk-dev] [PATCH v16 2/3] raw/ifpga: add APIs to get fpga information
2021-03-03 2:34 [dpdk-dev] [PATCH v16 0/3] raw/ifpga: add extra APIs for Cyborg Wei Huang
2021-03-03 2:34 ` [dpdk-dev] [PATCH v16 1/3] raw/ifpga: add fpga rsu APIs Wei Huang
@ 2021-03-03 2:34 ` Wei Huang
2021-03-03 2:34 ` [dpdk-dev] [PATCH v16 3/3] raw/ifpga: add miscellaneous APIs Wei Huang
2021-03-05 8:54 ` [dpdk-dev] [PATCH v16 0/3] raw/ifpga: add extra APIs for Cyborg Zhang, Qi Z
3 siblings, 0 replies; 6+ messages in thread
From: Wei Huang @ 2021-03-03 2:34 UTC (permalink / raw
To: dev, rosen.xu, qi.z.zhang; +Cc: stable, tianfei.zhang, ferruh.yigit, Wei Huang
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>
---
v2: implement APIs in rte_pmd_ifpga.c
---
drivers/raw/ifpga/base/ifpga_api.c | 8 +
drivers/raw/ifpga/base/ifpga_defines.h | 1 +
drivers/raw/ifpga/base/ifpga_feature_dev.c | 21 ++
drivers/raw/ifpga/base/ifpga_feature_dev.h | 1 +
drivers/raw/ifpga/base/ifpga_fme.c | 28 ++-
drivers/raw/ifpga/base/opae_hw_api.c | 18 ++
drivers/raw/ifpga/base/opae_hw_api.h | 2 +
drivers/raw/ifpga/base/opae_ifpga_hw_api.h | 1 +
drivers/raw/ifpga/rte_pmd_ifpga.c | 221 +++++++++++++++++++++
drivers/raw/ifpga/rte_pmd_ifpga.h | 110 ++++++++++
drivers/raw/ifpga/version.map | 3 +
11 files changed, 412 insertions(+), 2 deletions(-)
diff --git a/drivers/raw/ifpga/base/ifpga_api.c b/drivers/raw/ifpga/base/ifpga_api.c
index 1aedf150bc..4610ef101e 100644
--- a/drivers/raw/ifpga/base/ifpga_api.c
+++ b/drivers/raw/ifpga/base/ifpga_api.c
@@ -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,
diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index 9f0147d1ed..dca1518a83 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -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;
diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.c b/drivers/raw/ifpga/base/ifpga_feature_dev.c
index 0f852a75ad..08135137ad 100644
--- a/drivers/raw/ifpga/base/ifpga_feature_dev.c
+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.c
@@ -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)
{
diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.h b/drivers/raw/ifpga/base/ifpga_feature_dev.h
index 2b1309b44a..b355d22b0e 100644
--- a/drivers/raw/ifpga/base/ifpga_feature_dev.h
+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.h
@@ -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);
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 34fd9a818e..43c7b9c3dc 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -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,
diff --git a/drivers/raw/ifpga/base/opae_hw_api.c b/drivers/raw/ifpga/base/opae_hw_api.c
index 86ad88f720..11c9887c7f 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.c
+++ b/drivers/raw/ifpga/base/opae_hw_api.c
@@ -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
diff --git a/drivers/raw/ifpga/base/opae_hw_api.h b/drivers/raw/ifpga/base/opae_hw_api.h
index 91d26d9b5b..7e04b56471 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_hw_api.h
@@ -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);
diff --git a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
index bab33862ee..ffdbebf704 100644
--- a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
@@ -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 */
diff --git a/drivers/raw/ifpga/rte_pmd_ifpga.c b/drivers/raw/ifpga/rte_pmd_ifpga.c
index af6f175e98..8e04e22d5f 100644
--- a/drivers/raw/ifpga/rte_pmd_ifpga.c
+++ b/drivers/raw/ifpga/rte_pmd_ifpga.c
@@ -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)
diff --git a/drivers/raw/ifpga/rte_pmd_ifpga.h b/drivers/raw/ifpga/rte_pmd_ifpga.h
index 023a011116..633f6e9d1b 100644
--- a/drivers/raw/ifpga/rte_pmd_ifpga.h
+++ b/drivers/raw/ifpga/rte_pmd_ifpga.h
@@ -18,6 +18,55 @@
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
diff --git a/drivers/raw/ifpga/version.map b/drivers/raw/ifpga/version.map
index 16584f7fe4..ca6f7f5810 100644
--- a/drivers/raw/ifpga/version.map
+++ b/drivers/raw/ifpga/version.map
@@ -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;
--
2.29.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [dpdk-dev] [PATCH v16 3/3] raw/ifpga: add miscellaneous APIs
2021-03-03 2:34 [dpdk-dev] [PATCH v16 0/3] raw/ifpga: add extra APIs for Cyborg Wei Huang
2021-03-03 2:34 ` [dpdk-dev] [PATCH v16 1/3] raw/ifpga: add fpga rsu APIs Wei Huang
2021-03-03 2:34 ` [dpdk-dev] [PATCH v16 2/3] raw/ifpga: add APIs to get fpga information Wei Huang
@ 2021-03-03 2:34 ` Wei Huang
2021-03-05 8:54 ` [dpdk-dev] [PATCH v16 0/3] raw/ifpga: add extra APIs for Cyborg Zhang, Qi Z
3 siblings, 0 replies; 6+ messages in thread
From: Wei Huang @ 2021-03-03 2:34 UTC (permalink / raw
To: dev, rosen.xu, qi.z.zhang; +Cc: stable, tianfei.zhang, ferruh.yigit, Wei Huang
Below miscellaneous APIs are used to implement OPAE application.
1. rte_pmd_ifpga_get_pci_bus() get PCI bus ifpga driver registered.
2. rte_pmd_ifpga_partial_reconfigure() do partial reconfiguration.
3. rte_pmd_ifpga_cleanup() free software resources allocated by driver.
4. rte_pmd_ifpga_set_rsu_status() set 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>
---
v2: implement APIs in rte_pmd_ifpga.c
---
drivers/raw/ifpga/ifpga_rawdev.c | 30 ++++++++++++++
drivers/raw/ifpga/ifpga_rawdev.h | 7 +++-
drivers/raw/ifpga/rte_pmd_ifpga.c | 45 +++++++++++++++++++++
drivers/raw/ifpga/rte_pmd_ifpga.h | 66 +++++++++++++++++++++++++++++++
drivers/raw/ifpga/version.map | 4 ++
5 files changed, 151 insertions(+), 1 deletion(-)
diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index 27129b133e..05d79bfcc2 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -1737,3 +1737,33 @@ RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg,
"ifpga=<string> "
"port=<int> "
"afu_bts=<path>");
+
+struct rte_pci_bus *ifpga_get_pci_bus(void)
+{
+ return rte_ifpga_rawdev_pmd.bus;
+}
+
+int ifpga_rawdev_partial_reconfigure(struct rte_rawdev *dev, int port,
+ const char *file)
+{
+ if (!dev) {
+ IFPGA_RAWDEV_PMD_ERR("Input parameter is invalid");
+ return -EINVAL;
+ }
+
+ return rte_fpga_do_pr(dev, port, file);
+}
+
+void ifpga_rawdev_cleanup(void)
+{
+ struct ifpga_rawdev *dev;
+ unsigned int i;
+
+ for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+ dev = &ifpga_rawdevices[i];
+ if (dev->rawdev) {
+ rte_rawdev_pmd_release(dev->rawdev);
+ dev->rawdev = NULL;
+ }
+ }
+}
diff --git a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
index 7754beb02b..9bbe9a4278 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.h
+++ b/drivers/raw/ifpga/ifpga_rawdev.h
@@ -43,7 +43,7 @@ enum ifpga_rawdev_device_state {
static inline struct opae_adapter *
ifpga_rawdev_get_priv(const struct rte_rawdev *rawdev)
{
- return rawdev->dev_private;
+ return (struct opae_adapter *)rawdev->dev_private;
}
#define IFPGA_RAWDEV_MSIX_IRQ_NUM 7
@@ -76,4 +76,9 @@ int
ifpga_unregister_msix_irq(enum ifpga_irq_type type,
int vec_start, rte_intr_callback_fn handler, void *arg);
+struct rte_pci_bus *ifpga_get_pci_bus(void);
+int ifpga_rawdev_partial_reconfigure(struct rte_rawdev *dev, int port,
+ const char *file);
+void ifpga_rawdev_cleanup(void);
+
#endif /* _IFPGA_RAWDEV_H_ */
diff --git a/drivers/raw/ifpga/rte_pmd_ifpga.c b/drivers/raw/ifpga/rte_pmd_ifpga.c
index 8e04e22d5f..6e23a2581a 100644
--- a/drivers/raw/ifpga/rte_pmd_ifpga.c
+++ b/drivers/raw/ifpga/rte_pmd_ifpga.c
@@ -122,6 +122,25 @@ rte_pmd_ifpga_get_rsu_status(uint16_t dev_id, uint32_t *stat, uint32_t *prog)
return 0;
}
+int
+rte_pmd_ifpga_set_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;
+
+ sd->rsu_stat = IFPGA_RSU_STATUS(stat, prog);
+
+ return 0;
+}
+
static int
ifpga_is_rebooting(struct opae_adapter *adapter)
{
@@ -382,3 +401,29 @@ rte_pmd_ifpga_reload(uint16_t dev_id, int type, int page)
return opae_mgr_reload(adapter->mgr, type, page);
}
+
+const struct rte_pci_bus *
+rte_pmd_ifpga_get_pci_bus(void)
+{
+ return ifpga_get_pci_bus();
+}
+
+int
+rte_pmd_ifpga_partial_reconfigure(uint16_t dev_id, int port, const char *file)
+{
+ struct rte_rawdev *dev = NULL;
+
+ dev = get_rte_rawdev(dev_id);
+ if (!dev) {
+ IFPGA_RAWDEV_PMD_ERR("Device ID %u is invalid.", dev_id);
+ return -EINVAL;
+ }
+
+ return ifpga_rawdev_partial_reconfigure(dev, port, file);
+}
+
+void
+rte_pmd_ifpga_cleanup(void)
+{
+ ifpga_rawdev_cleanup();
+}
diff --git a/drivers/raw/ifpga/rte_pmd_ifpga.h b/drivers/raw/ifpga/rte_pmd_ifpga.h
index 633f6e9d1b..47d66ba655 100644
--- a/drivers/raw/ifpga/rte_pmd_ifpga.h
+++ b/drivers/raw/ifpga/rte_pmd_ifpga.h
@@ -107,6 +107,27 @@ __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
+ *
+ * Set current RSU status of the specified Intel FPGA device
+ *
+ * @param dev_id
+ * The raw device ID of specified Intel FPGA device.
+ * @param stat
+ * The RSU status value to set.
+ * @param prog
+ * The RSU progress value to set.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if dev_id is invalid.
+ * - (-ENOMEM) if share data is not initialized.
+ */
+__rte_experimental
+int
+rte_pmd_ifpga_set_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
@@ -235,6 +256,51 @@ __rte_experimental
int
rte_pmd_ifpga_reload(uint16_t dev_id, int type, int page);
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Get PCI bus the Intel FPGA driver register to
+ *
+ * @return
+ * - (valid pointer) if successful.
+ * - (NULL) if the Intel FPGA driver is not registered to any PCI bus.
+ */
+__rte_experimental
+const struct rte_pci_bus *
+rte_pmd_ifpga_get_pci_bus(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Perform PR (partial reconfiguration) on specified Intel FPGA device
+ *
+ * @param dev_id
+ * The raw device ID of specified Intel FPGA device.
+ * @param port
+ * The port index of the partial reconfiguration area.
+ * @param file
+ * The GBS (Green BitStream) image file name string.
+ * @return
+ * - (0) if successful.
+ * - (-EINVAL) if bad parameter or operation failed.
+ * - (-ENOMEM) if failed to allocate memory.
+ */
+__rte_experimental
+int
+rte_pmd_ifpga_partial_reconfigure(uint16_t dev_id, int port, const char *file);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Free software resources allocated by Intel FPGA PMD
+ */
+__rte_experimental
+void
+rte_pmd_ifpga_cleanup(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/drivers/raw/ifpga/version.map b/drivers/raw/ifpga/version.map
index ca6f7f5810..995c419a9b 100644
--- a/drivers/raw/ifpga/version.map
+++ b/drivers/raw/ifpga/version.map
@@ -8,10 +8,14 @@ EXPERIMENTAL {
# added in 21.05
rte_pmd_ifpga_get_dev_id;
rte_pmd_ifpga_get_rsu_status;
+ rte_pmd_ifpga_set_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;
rte_pmd_ifpga_reload;
+ rte_pmd_ifpga_get_pci_bus;
+ rte_pmd_ifpga_partial_reconfigure;
+ rte_pmd_ifpga_cleanup;
};
--
2.29.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [dpdk-dev] [PATCH v16 0/3] raw/ifpga: add extra APIs for Cyborg
2021-03-03 2:34 [dpdk-dev] [PATCH v16 0/3] raw/ifpga: add extra APIs for Cyborg Wei Huang
` (2 preceding siblings ...)
2021-03-03 2:34 ` [dpdk-dev] [PATCH v16 3/3] raw/ifpga: add miscellaneous APIs Wei Huang
@ 2021-03-05 8:54 ` Zhang, Qi Z
3 siblings, 0 replies; 6+ messages in thread
From: Zhang, Qi Z @ 2021-03-05 8:54 UTC (permalink / raw
To: Huang, Wei, dev@dpdk.org, Xu, Rosen
Cc: stable@dpdk.org, Zhang, Tianfei, Yigit, Ferruh
> -----Original Message-----
> From: Huang, Wei <wei.huang@intel.com>
> Sent: Wednesday, March 3, 2021 10:34 AM
> To: dev@dpdk.org; Xu, Rosen <rosen.xu@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>
> Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>; Yigit, Ferruh
> <ferruh.yigit@intel.com>; Huang, Wei <wei.huang@intel.com>
> Subject: [PATCH v16 0/3] raw/ifpga: add extra APIs for Cyborg
>
> Cyborg is part of OpenStack, it needs some extra APIs to manage devices with
> Intel FPGA. These patches add APIs to meet Cyborg requirement.
>
> Main changes from v15:
> - remove example from the patch set
>
> Wei Huang (3):
> raw/ifpga: add fpga rsu APIs
> raw/ifpga: add APIs to get fpga information
> raw/ifpga: add miscellaneous APIs
>
> doc/api/doxy-api-index.md | 3 +-
> doc/api/doxy-api.conf.in | 1 +
> drivers/raw/ifpga/base/ifpga_api.c | 34 ++
> drivers/raw/ifpga/base/ifpga_defines.h | 1 +
> drivers/raw/ifpga/base/ifpga_feature_dev.c | 21 +
> drivers/raw/ifpga/base/ifpga_feature_dev.h | 1 +
> drivers/raw/ifpga/base/ifpga_fme.c | 36 +-
> drivers/raw/ifpga/base/ifpga_fme_rsu.c | 428 ++++++++++++++
> drivers/raw/ifpga/base/ifpga_hw.h | 1 +
> drivers/raw/ifpga/base/ifpga_sec_mgr.c | 639 +++++++++++++++++++++
> drivers/raw/ifpga/base/ifpga_sec_mgr.h | 93 +++
> drivers/raw/ifpga/base/meson.build | 2 +
> drivers/raw/ifpga/base/opae_hw_api.c | 77 +++
> drivers/raw/ifpga/base/opae_hw_api.h | 12 +
> drivers/raw/ifpga/base/opae_ifpga_hw_api.h | 1 +
> drivers/raw/ifpga/base/opae_intel_max10.c | 48 ++
> drivers/raw/ifpga/base/opae_intel_max10.h | 44 ++
> drivers/raw/ifpga/ifpga_rawdev.c | 30 +
> drivers/raw/ifpga/ifpga_rawdev.h | 7 +-
> drivers/raw/ifpga/meson.build | 4 +-
> drivers/raw/ifpga/rte_pmd_ifpga.c | 429 ++++++++++++++
> drivers/raw/ifpga/rte_pmd_ifpga.h | 308 ++++++++++
> drivers/raw/ifpga/version.map | 18 +
> 23 files changed, 2233 insertions(+), 5 deletions(-) create mode 100644
> drivers/raw/ifpga/base/ifpga_fme_rsu.c
> create mode 100644 drivers/raw/ifpga/base/ifpga_sec_mgr.c
> create mode 100644 drivers/raw/ifpga/base/ifpga_sec_mgr.h
> create mode 100644 drivers/raw/ifpga/rte_pmd_ifpga.c create mode
> 100644 drivers/raw/ifpga/rte_pmd_ifpga.h
>
> --
> 2.29.2
Applied to dpdk-next-net-intel.
Thanks
Qi
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dpdk-dev] [PATCH v16 3/3] raw/ifpga: add miscellaneous APIs
2021-03-17 7:59 Wei Huang
@ 2021-03-17 7:59 ` Wei Huang
0 siblings, 0 replies; 6+ messages in thread
From: Wei Huang @ 2021-03-17 7:59 UTC (permalink / raw
To: dev, rosen.xu, qi.z.zhang; +Cc: stable, tianfei.zhang, Wei Huang
Below miscellaneous APIs are used to implement OPAE application.
1. rte_pmd_ifpga_get_pci_bus() get PCI bus ifpga driver registered.
2. rte_pmd_ifpga_partial_reconfigure() do partial reconfiguration.
3. rte_pmd_ifpga_cleanup() free software resources allocated by driver.
4. rte_pmd_ifpga_set_rsu_status() set 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>
---
v2: implement APIs in rte_pmd_ifpga.c
---
drivers/raw/ifpga/ifpga_rawdev.c | 30 ++++++++++++++
drivers/raw/ifpga/ifpga_rawdev.h | 7 +++-
drivers/raw/ifpga/rte_pmd_ifpga.c | 45 +++++++++++++++++++++
drivers/raw/ifpga/rte_pmd_ifpga.h | 66 +++++++++++++++++++++++++++++++
drivers/raw/ifpga/version.map | 4 ++
5 files changed, 151 insertions(+), 1 deletion(-)
diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index 27129b133e..05d79bfcc2 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -1737,3 +1737,33 @@ RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg,
"ifpga=<string> "
"port=<int> "
"afu_bts=<path>");
+
+struct rte_pci_bus *ifpga_get_pci_bus(void)
+{
+ return rte_ifpga_rawdev_pmd.bus;
+}
+
+int ifpga_rawdev_partial_reconfigure(struct rte_rawdev *dev, int port,
+ const char *file)
+{
+ if (!dev) {
+ IFPGA_RAWDEV_PMD_ERR("Input parameter is invalid");
+ return -EINVAL;
+ }
+
+ return rte_fpga_do_pr(dev, port, file);
+}
+
+void ifpga_rawdev_cleanup(void)
+{
+ struct ifpga_rawdev *dev;
+ unsigned int i;
+
+ for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+ dev = &ifpga_rawdevices[i];
+ if (dev->rawdev) {
+ rte_rawdev_pmd_release(dev->rawdev);
+ dev->rawdev = NULL;
+ }
+ }
+}
diff --git a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
index 7754beb02b..9bbe9a4278 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.h
+++ b/drivers/raw/ifpga/ifpga_rawdev.h
@@ -43,7 +43,7 @@ enum ifpga_rawdev_device_state {
static inline struct opae_adapter *
ifpga_rawdev_get_priv(const struct rte_rawdev *rawdev)
{
- return rawdev->dev_private;
+ return (struct opae_adapter *)rawdev->dev_private;
}
#define IFPGA_RAWDEV_MSIX_IRQ_NUM 7
@@ -76,4 +76,9 @@ int
ifpga_unregister_msix_irq(enum ifpga_irq_type type,
int vec_start, rte_intr_callback_fn handler, void *arg);
+struct rte_pci_bus *ifpga_get_pci_bus(void);
+int ifpga_rawdev_partial_reconfigure(struct rte_rawdev *dev, int port,
+ const char *file);
+void ifpga_rawdev_cleanup(void);
+
#endif /* _IFPGA_RAWDEV_H_ */
diff --git a/drivers/raw/ifpga/rte_pmd_ifpga.c b/drivers/raw/ifpga/rte_pmd_ifpga.c
index 8e04e22d5f..6e23a2581a 100644
--- a/drivers/raw/ifpga/rte_pmd_ifpga.c
+++ b/drivers/raw/ifpga/rte_pmd_ifpga.c
@@ -122,6 +122,25 @@ rte_pmd_ifpga_get_rsu_status(uint16_t dev_id, uint32_t *stat, uint32_t *prog)
return 0;
}
+int
+rte_pmd_ifpga_set_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;
+
+ sd->rsu_stat = IFPGA_RSU_STATUS(stat, prog);
+
+ return 0;
+}
+
static int
ifpga_is_rebooting(struct opae_adapter *adapter)
{
@@ -382,3 +401,29 @@ rte_pmd_ifpga_reload(uint16_t dev_id, int type, int page)
return opae_mgr_reload(adapter->mgr, type, page);
}
+
+const struct rte_pci_bus *
+rte_pmd_ifpga_get_pci_bus(void)
+{
+ return ifpga_get_pci_bus();
+}
+
+int
+rte_pmd_ifpga_partial_reconfigure(uint16_t dev_id, int port, const char *file)
+{
+ struct rte_rawdev *dev = NULL;
+
+ dev = get_rte_rawdev(dev_id);
+ if (!dev) {
+ IFPGA_RAWDEV_PMD_ERR("Device ID %u is invalid.", dev_id);
+ return -EINVAL;
+ }
+
+ return ifpga_rawdev_partial_reconfigure(dev, port, file);
+}
+
+void
+rte_pmd_ifpga_cleanup(void)
+{
+ ifpga_rawdev_cleanup();
+}
diff --git a/drivers/raw/ifpga/rte_pmd_ifpga.h b/drivers/raw/ifpga/rte_pmd_ifpga.h
index 633f6e9d1b..47d66ba655 100644
--- a/drivers/raw/ifpga/rte_pmd_ifpga.h
+++ b/drivers/raw/ifpga/rte_pmd_ifpga.h
@@ -107,6 +107,27 @@ __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
+ *
+ * Set current RSU status of the specified Intel FPGA device
+ *
+ * @param dev_id
+ * The raw device ID of specified Intel FPGA device.
+ * @param stat
+ * The RSU status value to set.
+ * @param prog
+ * The RSU progress value to set.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if dev_id is invalid.
+ * - (-ENOMEM) if share data is not initialized.
+ */
+__rte_experimental
+int
+rte_pmd_ifpga_set_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
@@ -235,6 +256,51 @@ __rte_experimental
int
rte_pmd_ifpga_reload(uint16_t dev_id, int type, int page);
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Get PCI bus the Intel FPGA driver register to
+ *
+ * @return
+ * - (valid pointer) if successful.
+ * - (NULL) if the Intel FPGA driver is not registered to any PCI bus.
+ */
+__rte_experimental
+const struct rte_pci_bus *
+rte_pmd_ifpga_get_pci_bus(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Perform PR (partial reconfiguration) on specified Intel FPGA device
+ *
+ * @param dev_id
+ * The raw device ID of specified Intel FPGA device.
+ * @param port
+ * The port index of the partial reconfiguration area.
+ * @param file
+ * The GBS (Green BitStream) image file name string.
+ * @return
+ * - (0) if successful.
+ * - (-EINVAL) if bad parameter or operation failed.
+ * - (-ENOMEM) if failed to allocate memory.
+ */
+__rte_experimental
+int
+rte_pmd_ifpga_partial_reconfigure(uint16_t dev_id, int port, const char *file);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Free software resources allocated by Intel FPGA PMD
+ */
+__rte_experimental
+void
+rte_pmd_ifpga_cleanup(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/drivers/raw/ifpga/version.map b/drivers/raw/ifpga/version.map
index ca6f7f5810..995c419a9b 100644
--- a/drivers/raw/ifpga/version.map
+++ b/drivers/raw/ifpga/version.map
@@ -8,10 +8,14 @@ EXPERIMENTAL {
# added in 21.05
rte_pmd_ifpga_get_dev_id;
rte_pmd_ifpga_get_rsu_status;
+ rte_pmd_ifpga_set_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;
rte_pmd_ifpga_reload;
+ rte_pmd_ifpga_get_pci_bus;
+ rte_pmd_ifpga_partial_reconfigure;
+ rte_pmd_ifpga_cleanup;
};
--
2.29.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-03-17 8:00 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-03 2:34 [dpdk-dev] [PATCH v16 0/3] raw/ifpga: add extra APIs for Cyborg Wei Huang
2021-03-03 2:34 ` [dpdk-dev] [PATCH v16 1/3] raw/ifpga: add fpga rsu APIs Wei Huang
2021-03-03 2:34 ` [dpdk-dev] [PATCH v16 2/3] raw/ifpga: add APIs to get fpga information Wei Huang
2021-03-03 2:34 ` [dpdk-dev] [PATCH v16 3/3] raw/ifpga: add miscellaneous APIs Wei Huang
2021-03-05 8:54 ` [dpdk-dev] [PATCH v16 0/3] raw/ifpga: add extra APIs for Cyborg Zhang, Qi Z
-- strict thread matches above, loose matches on Subject: below --
2021-03-17 7:59 Wei Huang
2021-03-17 7:59 ` [dpdk-dev] [PATCH v16 3/3] raw/ifpga: add miscellaneous APIs Wei Huang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).