Add a series of API and implementations that application can
operate on a programmble device. The major functions are download
and upload an image to/from device.

Signed-off-by: Chen Jing D(Mark) <jing.d.c...@intel.com>
Signed-off-by: Gerald Rogers <gerald.rog...@intel.com>
---
 lib/librte_prgdev/rte_prgdev.c |  226 ++++++++++++++++++++++++++++++++++++++++
 lib/librte_prgdev/rte_prgdev.h |  106 +++++++++++++++++++
 2 files changed, 332 insertions(+), 0 deletions(-)

diff --git a/lib/librte_prgdev/rte_prgdev.c b/lib/librte_prgdev/rte_prgdev.c
index 03465f9..558e97b 100644
--- a/lib/librte_prgdev/rte_prgdev.c
+++ b/lib/librte_prgdev/rte_prgdev.c
@@ -231,3 +231,229 @@ struct rte_prgdev *
        return 0;
 }
 
+int
+rte_prgdev_is_valid_dev(uint8_t dev_id)
+{
+       /* Not support secondary process to operate on prgdev */
+       RTE_PRG_PRIMARY_PROC_OR_ERR_RET(-EINVAL);
+       RTE_PRG_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
+
+       if (dev_id >= RTE_PRGDEV_MAX_DEVS ||
+               rte_prgdev_devices[dev_id].attached != PRGDEV_ATTACHED)
+               return 0;
+       else
+               return 1;
+}
+
+uint8_t
+rte_prgdev_count(void)
+{
+       /* Not support secondary process to operate on prgdev */
+       RTE_PRG_PRIMARY_PROC_OR_ERR_RET(-EINVAL);
+
+       return nb_devs;
+}
+
+static inline int
+prgdev_devid_check(uint8_t dev_id, struct rte_prgdev **dev)
+{
+       /* Not support secondary process to operate on prgdev */
+       RTE_PRG_PRIMARY_PROC_OR_ERR_RET(-EINVAL);
+       RTE_PRG_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
+
+       if (dev_id >= nb_devs) {
+               PRG_LOG_ERR("Invalid dev_id=%d", dev_id);
+               return -EINVAL;
+       }
+
+       *dev = &rte_prgdev_devices[dev_id];
+       return 0;
+}
+
+int
+rte_prgdev_info_get(uint8_t dev_id,
+                       struct rte_prgdev_info *info)
+{
+       struct rte_prgdev *dev;
+       int ret;
+
+       ret = prgdev_devid_check(dev_id, &dev);
+       if (ret)
+               return ret;
+
+       memset(info, 0, sizeof(*info));
+
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_infos_get, -ENOTSUP);
+       (*dev->dev_ops->prg_infos_get)(dev, info);
+
+       info->pci_dev = RTE_DEV_TO_PCI(dev->device);
+       if (dev->driver)
+               info->driver_name = dev->driver->pci_drv.driver.name;
+       return 0;
+}
+
+int
+rte_prgdev_open(uint8_t dev_id)
+{
+       struct rte_prgdev *dev;
+       struct rte_prgdev_info dev_info;
+       int ret;
+
+       ret = prgdev_devid_check(dev_id, &dev);
+       if (ret)
+               return ret;
+
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_infos_get, -ENOTSUP);
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_open, -ENOTSUP);
+
+       (*dev->dev_ops->prg_infos_get)(dev, &dev_info);
+
+       if (dev_info.status != RTE_PRG_STAT_READY)
+               return -1;
+
+       return (*dev->dev_ops->prg_open)(dev);
+}
+
+int
+rte_prgdev_img_download(uint8_t dev_id,
+                       uint8_t *buffer_ptr, uint32_t buf_len)
+{
+       struct rte_prgdev *dev;
+       struct rte_prgdev_info dev_info;
+       int ret;
+
+       ret = prgdev_devid_check(dev_id, &dev);
+       if (ret)
+               return ret;
+
+       if (buffer_ptr == NULL || buf_len == 0)
+               return -EINVAL;
+
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_download, -ENOTSUP);
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_infos_get, -ENOTSUP);
+
+       (*dev->dev_ops->prg_infos_get)(dev, &dev_info);
+
+       if (dev_info.status != RTE_PRG_STAT_OPEN)
+               return -1;
+
+       return (*dev->dev_ops->prg_download)(dev, buffer_ptr, buf_len);
+}
+
+int
+rte_prgdev_img_upload(uint8_t dev_id, uint8_t *buffer_ptr,
+               uint32_t buf_len, uint32_t *act_len)
+{
+       struct rte_prgdev *dev;
+       struct rte_prgdev_info dev_info;
+       int ret;
+
+       ret = prgdev_devid_check(dev_id, &dev);
+       if (ret)
+               return ret;
+
+       if (buffer_ptr == NULL || buf_len == 0 || act_len == NULL)
+               return -EINVAL;
+
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_upload, -ENOTSUP);
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_infos_get, -ENOTSUP);
+
+       (*dev->dev_ops->prg_infos_get)(dev, &dev_info);
+
+       if (dev_info.status != RTE_PRG_STAT_OPEN)
+               return -1;
+
+       return (*dev->dev_ops->prg_upload)(dev, buffer_ptr, buf_len, act_len);
+}
+
+int
+rte_prgdev_check_stat(uint8_t dev_id, enum rte_prg_fwstat *stat)
+{
+       struct rte_prgdev *dev;
+       struct rte_prgdev_info dev_info;
+       int ret;
+
+       ret = prgdev_devid_check(dev_id, &dev);
+       if (ret)
+               return ret;
+
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_check_stat, -ENOTSUP);
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_infos_get, -ENOTSUP);
+
+       (*dev->dev_ops->prg_infos_get)(dev, &dev_info);
+
+       /* Only can check downloaded image running status after device is open,
+       * but prgdev doesn't has the capability to check whether an image is
+       * downloaded prior to this operation.
+       */
+       if (dev_info.status != RTE_PRG_STAT_OPEN)
+               return -EINVAL;
+
+       return (*dev->dev_ops->prg_check_stat)(dev, stat);
+}
+
+int
+rte_prgdev_close(uint8_t dev_id)
+{
+       struct rte_prgdev *dev;
+       struct rte_prgdev_info dev_info;
+       int ret;
+
+       ret = prgdev_devid_check(dev_id, &dev);
+       if (ret)
+               return ret;
+
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_infos_get, -ENOTSUP);
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_close, -ENOTSUP);
+
+       (*dev->dev_ops->prg_infos_get)(dev, &dev_info);
+
+       if (dev_info.status != RTE_PRG_STAT_OPEN)
+               return -EINVAL;
+
+       return (*dev->dev_ops->prg_close)(dev);
+}
+
+int
+rte_prgdev_bind(uint8_t dev_id)
+{
+       struct rte_prgdev *dev;
+       struct rte_prgdev_info dev_info;
+       int ret;
+
+       ret = prgdev_devid_check(dev_id, &dev);
+       if (ret)
+               return ret;
+
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_infos_get, -ENOTSUP);
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_bind, -ENOTSUP);
+
+       (*dev->dev_ops->prg_infos_get)(dev, &dev_info);
+
+       if (dev_info.status != RTE_PRG_STAT_READY)
+               return -EINVAL;
+
+       return (*dev->dev_ops->prg_bind)(dev);
+}
+
+int
+rte_prgdev_unbind(uint8_t dev_id)
+{
+       struct rte_prgdev *dev;
+       struct rte_prgdev_info dev_info;
+       int ret;
+
+       ret = prgdev_devid_check(dev_id, &dev);
+       if (ret)
+               return ret;
+
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_infos_get, -ENOTSUP);
+       RTE_PRG_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->prg_unbind, -ENOTSUP);
+
+       (*dev->dev_ops->prg_infos_get)(dev, &dev_info);
+
+       if (dev_info.status != RTE_PRG_STAT_READY)
+               return -EINVAL;
+
+       return (*dev->dev_ops->prg_unbind)(dev);
+}
diff --git a/lib/librte_prgdev/rte_prgdev.h b/lib/librte_prgdev/rte_prgdev.h
index c25cfef..db57512 100644
--- a/lib/librte_prgdev/rte_prgdev.h
+++ b/lib/librte_prgdev/rte_prgdev.h
@@ -288,6 +288,112 @@ int rte_prgdev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_prgdev_release(struct rte_prgdev *prg_dev);
 
+/*
+*  Query what personality is in the device.
+*
+*  @param device_id
+*   The port identifier of the programmable device.
+*  @param info
+*   A pointer to a structure of type *rte_prg_dev_info* to be filled with
+*   the information of the programmable device.
+*/
+int rte_prgdev_info_get(uint8_t device_id,
+                       struct rte_prgdev_info *info);
+
+/**
+ * Check if dev_id of device is attached
+ *
+ * @param dev_id
+ *   The device identifier of the programmable device
+ * @return
+ *   - 0 if device is out of range or not attached
+ *   - 1 if device is attached
+ */
+int rte_prgdev_is_valid_dev(uint8_t dev_id);
+
+/**
+ * Get the total number of programmable devices that have been successfully
+ * initialized.
+ * If the application unplugs a device using hotplug function, The enabled
+ * device numbers may be noncontiguous. In the case, the applications need to
+ * manage enabled port by themselves.
+ *
+ * @return
+ *   - The total number of usable programmable devices.
+ */
+uint8_t rte_prgdev_count(void);
+
+/*
+*  Open device for programming, acquiring on-die image, etc.
+*  Need to call this function first
+*  prior to calling other functionalities.
+*  In case the device is performing some tasks, it's device's decision on
+*  what result is returned.
+*/
+int rte_prgdev_open(uint8_t device_id);
+
+/*
+* Download image from host to programmable device.
+*
+* @param device_id
+*   The port identifier of the programmable device.
+* @param buffer_ptr
+*   A pointer to a buffer that stored the image ready downloading to device
+* @param buf_len
+*   the total image length in bytes.
+*/
+
+int rte_prgdev_img_download(uint8_t device_id,
+                       uint8_t *buffer_ptr, uint32_t buf_len);
+
+/*
+* Upload image from programmable device to host.
+*
+* @param device_id
+*   The port identifier of the programmable device.
+* @param buffer_ptr
+*   A pointer to a buffer that store uploaded image
+* @param buf_len
+*   the total buffer length in bytes.
+* @param act_len
+*   pointer to the actual image length in bytes.
+*/
+
+int rte_prgdev_img_upload(uint8_t device_id, uint8_t *buffer_ptr,
+               uint32_t buf_len, uint32_t *act_len);
+
+/*
+*  Check if the downloaded image running on die works in expected way, optional
+*   function.
+* @param device_id
+* @param stat: pointer to image status. Output parameters.
+*   The port identifier of the programmable device.
+*/
+int rte_prgdev_check_stat(uint8_t device_id, enum rte_prg_fwstat *stat);
+
+/*
+* Called to free up resources or whatever to do to hardware
+* after an erase or load of the program.
+* @param device_id
+*   The device identifier of the programmable device.
+*/
+int rte_prgdev_close(uint8_t device_id);
+
+/*
+* Called to bind a programmable device with drivers after close function is
+* called.
+* @param device_id
+*   The device identifier of the programmable device.
+*/
+int rte_prgdev_bind(uint8_t device_id);
+
+/*
+* Called to unbind all functions except prgdev from drivers.
+* @param device_id
+*   The device identifier of the programmable device.
+*/
+int rte_prgdev_unbind(uint8_t device_id);
+
 #ifdef __cplusplus
 }
 #endif
-- 
1.7.7.6

Reply via email to