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