From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by dpdk.org (Postfix) with ESMTP id A51DD2952 for ; Thu, 2 Mar 2017 12:07:26 +0100 (CET) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga105.jf.intel.com with ESMTP; 02 Mar 2017 03:07:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.35,230,1484035200"; d="scan'208";a="231421858" Received: from unknown (HELO localhost.localdomain.sh.intel.com) ([10.239.128.150]) by fmsmga004.fm.intel.com with ESMTP; 02 Mar 2017 03:07:24 -0800 From: "Chen Jing D(Mark)" 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)" Date: Thu, 2 Mar 2017 12:03:56 +0800 Message-Id: <1488427438-13646-5-git-send-email-jing.d.chen@intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1488427438-13646-1-git-send-email-jing.d.chen@intel.com> References: <1488427438-13646-1-git-send-email-jing.d.chen@intel.com> Subject: [dpdk-dev] [PATCH 4/6] prgdev: add prgdev API exposed to application X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Mar 2017 11:07:27 -0000 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) Signed-off-by: Gerald Rogers --- 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