From: "Chen Jing D(Mark)" <jing.d.chen@intel.com>
To: dev@dpdk.org
Cc: cunming.liang@intel.com, gerald.rogers@intel.com,
keith.wiles@intel.com, bruce.richardson@intel.com,
"Chen Jing D(Mark)" <jing.d.chen@intel.com>
Subject: [dpdk-dev] [PATCH 4/6] prgdev: add prgdev API exposed to application
Date: Thu, 2 Mar 2017 12:03:56 +0800 [thread overview]
Message-ID: <1488427438-13646-5-git-send-email-jing.d.chen@intel.com> (raw)
In-Reply-To: <1488427438-13646-1-git-send-email-jing.d.chen@intel.com>
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.chen@intel.com>
Signed-off-by: Gerald Rogers <gerald.rogers@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
next prev parent reply other threads:[~2017-03-02 11:07 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-02 4:03 [dpdk-dev] [PATCH 0/6] introduce prgdev abstraction library Chen Jing D(Mark)
2017-03-02 4:03 ` [dpdk-dev] [PATCH 1/6] prgdev: introduce new library Chen Jing D(Mark)
2017-03-02 4:03 ` [dpdk-dev] [PATCH 2/6] prgdev: add debug macro for prgdev Chen Jing D(Mark)
2017-03-02 4:03 ` [dpdk-dev] [PATCH 3/6] prgdev: add bus probe and remove functions Chen Jing D(Mark)
2017-03-02 4:03 ` Chen Jing D(Mark) [this message]
2017-03-02 4:03 ` [dpdk-dev] [PATCH 5/6] prgdev: add ABI control info Chen Jing D(Mark)
2017-03-02 4:03 ` [dpdk-dev] [PATCH 6/6] doc: introduction to prgdev Chen Jing D(Mark)
2017-03-06 15:26 ` Thomas Monjalon
2017-03-07 10:34 ` Chen, Jing D
2017-03-07 11:12 ` Bruce Richardson
2017-03-07 13:05 ` Thomas Monjalon
2017-03-07 13:45 ` Chen, Jing D
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1488427438-13646-5-git-send-email-jing.d.chen@intel.com \
--to=jing.d.chen@intel.com \
--cc=bruce.richardson@intel.com \
--cc=cunming.liang@intel.com \
--cc=dev@dpdk.org \
--cc=gerald.rogers@intel.com \
--cc=keith.wiles@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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 NNTP newsgroup(s).