[dpdk-dev] [PATCH v1 1/5] rawdev: introduce raw device library support

Trahe, Fiona fiona.trahe at intel.com
Sat Jan 6 14:40:54 CET 2018


Hi Shreyansh,

This looks like a useful generic device, thanks. Some comments below.

> -----Original Message-----
> From: Shreyansh Jain [mailto:shreyansh.jain at nxp.com]
> Sent: Tuesday, January 2, 2018 12:58 PM
> To: dev at dpdk.org
> Cc: hemant.agrawal at nxp.com; Trahe, Fiona <fiona.trahe at intel.com>; Xu, Rosen <rosen.xu at intel.com>;
> Shreyansh Jain <shreyansh.jain at nxp.com>
> Subject: [PATCH v1 1/5] rawdev: introduce raw device library support
> 
> A device is DPDK has a flavor to it - ethernet, crypto, event etc.
> 
> A rawdevice represents a generic device map-able to a device flavour
> not being currently handled out-of-the-box by DPDK framework.
> A device which can be scanned on an installed bus (pci, fslmc, ...)
> or instantiated through devargs, can be interfaced using
> standardized APIs just like other standardized devices.
> 
> This library introduces an API set which can be plugged on the
> northbound side to the application layer, and on the southbound side
> to the driver layer.
> 
> The APIs of rawdev library exposes some generic operations which can
> enable configuration and I/O with the raw devices.
> 
> Signed-off-by: Shreyansh Jain <shreyansh.jain at nxp.com>
> ---
>  lib/librte_rawdev/Makefile               |  27 ++
>  lib/librte_rawdev/rte_rawdev.c           | 540 ++++++++++++++++++++++++++++
>  lib/librte_rawdev/rte_rawdev.h           | 586 ++++++++++++++++++++++++++++++
>  lib/librte_rawdev/rte_rawdev_pmd.h       | 588 +++++++++++++++++++++++++++++++
>  lib/librte_rawdev/rte_rawdev_version.map |  33 ++
>  5 files changed, 1774 insertions(+)
>  create mode 100644 lib/librte_rawdev/Makefile
>  create mode 100644 lib/librte_rawdev/rte_rawdev.c
>  create mode 100644 lib/librte_rawdev/rte_rawdev.h
>  create mode 100644 lib/librte_rawdev/rte_rawdev_pmd.h
>  create mode 100644 lib/librte_rawdev/rte_rawdev_version.map
> 
> diff --git a/lib/librte_rawdev/Makefile b/lib/librte_rawdev/Makefile
> new file mode 100644
> index 000000000..addb288d7
> --- /dev/null
> +++ b/lib/librte_rawdev/Makefile
> @@ -0,0 +1,27 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright 2017 NXP
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +# library name
> +LIB = librte_rawdev.a
> +
> +# library version
> +LIBABIVER := 1
> +
> +# build flags
> +CFLAGS += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +LDLIBS += -lrte_eal
> +
> +# library source files
> +SRCS-y += rte_rawdev.c
> +
> +# export include files
> +SYMLINK-y-include += rte_rawdev.h
> +SYMLINK-y-include += rte_rawdev_pmd.h
> +
> +# versioning export map
> +EXPORT_MAP := rte_rawdev_version.map
> +
> +include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
> new file mode 100644
> index 000000000..2d34d9b6d
> --- /dev/null
> +++ b/lib/librte_rawdev/rte_rawdev.c
> @@ -0,0 +1,540 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2017 NXP
> + */
> +
> +#include <ctype.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <stdarg.h>
> +#include <errno.h>
> +#include <stdint.h>
> +#include <inttypes.h>
> +#include <sys/types.h>
> +#include <sys/queue.h>
> +
> +#include <rte_byteorder.h>
> +#include <rte_log.h>
> +#include <rte_debug.h>
> +#include <rte_dev.h>
> +#include <rte_memory.h>
> +#include <rte_memcpy.h>
> +#include <rte_memzone.h>
> +#include <rte_eal.h>
> +#include <rte_per_lcore.h>
> +#include <rte_lcore.h>
> +#include <rte_atomic.h>
> +#include <rte_branch_prediction.h>
> +#include <rte_common.h>
> +#include <rte_malloc.h>
> +#include <rte_errno.h>
> +
> +#include "rte_rawdev.h"
> +#include "rte_rawdev_pmd.h"
> +
> +/* dynamic log identifier */
> +int librawdev_logtype;
> +
> +/* Maximum rawdevices supported by system.
> + */
> +#define RTE_MAX_RAWDEVPORTS	10
[Fiona] Typo in comment above? There's RTE_RAWDEV_MAX_DEVS, RTE_MAX_RAWDEVS and RTE_MAX_RAWDEVPORTS. Are all 3 necessary and what's the relationship between ports and devs?
 
> +
> +struct rte_rawdev rte_rawdevices[RTE_RAWDEV_MAX_DEVS];
> +
> +struct rte_rawdev *rte_rawdevs = &rte_rawdevices[0];
> +
> +static struct rte_rawdev_global rawdev_globals = {
> +	.nb_devs		= 0
> +};
> +
> +struct rte_rawdev_global *rte_rawdev_globals = &rawdev_globals;
> +
> +/* Raw device, northbound API implementation */
> +uint8_t
> +rte_rawdev_count(void)
> +{
> +	return rte_rawdev_globals->nb_devs;
> +}
> +
> +uint16_t
> +rte_rawdev_get_dev_id(const char *name)
> +{
> +	uint16_t i;
> +
> +	if (!name)
> +		return -EINVAL;
> +
> +	for (i = 0; i < rte_rawdev_globals->nb_devs; i++)
> +		if ((strcmp(rte_rawdevices[i].name, name)
> +				== 0) &&
> +				(rte_rawdevices[i].attached ==
> +						RTE_RAWDEV_ATTACHED))
> +			return i;
> +	return -ENODEV;
> +}
> +
> +int
> +rte_rawdev_socket_id(uint16_t dev_id)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	return dev->socket_id;
> +}
> +
> +int
> +rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info)
> +{
> +	struct rte_rawdev *rawdev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	RTE_FUNC_PTR_OR_ERR_RET(dev_info, -EINVAL);
> +
> +	if (dev_info == NULL)
> +		return -EINVAL;
> +
> +	rawdev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*rawdev->dev_ops->dev_info_get, -ENOTSUP);
> +	(*rawdev->dev_ops->dev_info_get)(rawdev, dev_info->dev_private);
> +
> +	if (dev_info) {
> +
> +		dev_info->driver_name = rawdev->driver_name;
> +		dev_info->device = rawdev->device;
> +	}
> +
> +	return 0;
> +}
> +
> +int
> +rte_rawdev_configure(uint16_t dev_id, struct rte_rawdev_info *dev_conf)
> +{
> +	struct rte_rawdev *dev;
> +	int diag;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	RTE_FUNC_PTR_OR_ERR_RET(dev_conf, -EINVAL);
> +
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
> +
> +	if (dev->started) {
> +		RTE_RDEV_ERR(
> +		   "device %d must be stopped to allow configuration", dev_id);
> +		return -EBUSY;
> +	}
> +
> +	/* Configure the device */
> +	diag = (*dev->dev_ops->dev_configure)(dev, dev_conf->dev_private);
> +	if (diag != 0)
> +		RTE_RDEV_ERR("dev%d dev_configure = %d", dev_id, diag);
> +	else
> +		dev->attached = 1;
> +
> +	return diag;
> +}
> +
> +int
> +rte_rawdev_queue_conf_get(uint16_t dev_id,
> +			  uint16_t queue_id,
> +			  rte_rawdev_obj_t queue_conf)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_def_conf, -ENOTSUP);
> +	(*dev->dev_ops->queue_def_conf)(dev, queue_id, queue_conf);
> +	return 0;
> +}
> +
> +int
> +rte_rawdev_queue_setup(uint16_t dev_id,
> +		       uint16_t queue_id,
> +		       rte_rawdev_obj_t queue_conf)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_setup, -ENOTSUP);
> +	return (*dev->dev_ops->queue_setup)(dev, queue_id, queue_conf);
> +}
> +
> +int
> +rte_rawdev_queue_release(uint16_t dev_id, uint16_t queue_id)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_release, -ENOTSUP);
> +	return (*dev->dev_ops->queue_release)(dev, queue_id);
> +}
> +
> +int
> +rte_rawdev_get_attr(uint16_t dev_id,
> +		    const char *attr_name,
> +		    uint64_t *attr_value)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->attr_get, -ENOTSUP);
> +	return (*dev->dev_ops->attr_get)(dev, attr_name, attr_value);
> +}
> +
> +int
> +rte_rawdev_set_attr(uint16_t dev_id,
> +		    const char *attr_name,
> +		    const uint64_t attr_value)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->attr_set, -ENOTSUP);
> +	return (*dev->dev_ops->attr_set)(dev, attr_name, attr_value);
> +}
> +
> +int
> +rte_rawdev_enqueue_buffers(uint16_t dev_id,
> +			   struct rte_rawdev_buf **buffers,
> +			   unsigned int count,
> +			   rte_rawdev_obj_t context)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->enqueue_bufs, -ENOTSUP);
> +	return (*dev->dev_ops->enqueue_bufs)(dev, buffers, count, context);
> +}
> +
> +int
> +rte_rawdev_dequeue_buffers(uint16_t dev_id,
> +			   struct rte_rawdev_buf **buffers,
> +			   unsigned int count,
> +			   rte_rawdev_obj_t context)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dequeue_bufs, -ENOTSUP);
> +	return (*dev->dev_ops->dequeue_bufs)(dev, buffers, count, context);
> +}
> +
> +int
> +rte_rawdev_dump(uint16_t dev_id, FILE *f)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dump, -ENOTSUP);
> +	return (*dev->dev_ops->dump)(dev, f);
> +}
> +
> +static int
> +xstats_get_count(uint16_t dev_id)
> +{
> +	struct rte_rawdev *dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_names, -ENOTSUP);
> +	return (*dev->dev_ops->xstats_get_names)(dev, NULL, 0);
> +}
> +
> +int
> +rte_rawdev_xstats_names_get(uint16_t dev_id,
> +		struct rte_rawdev_xstats_name *xstats_names,
> +		unsigned int size)
> +{
> +	const struct rte_rawdev *dev;
> +	int cnt_expected_entries;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV);
> +
> +	cnt_expected_entries = xstats_get_count(dev_id);
> +
> +	if (xstats_names == NULL || cnt_expected_entries < 0 ||
> +	    (int)size < cnt_expected_entries || size <= 0)
> +		return cnt_expected_entries;
> +
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_names, -ENOTSUP);
> +	return (*dev->dev_ops->xstats_get_names)(dev, xstats_names, size);
> +}
> +
> +/* retrieve rawdev extended statistics */
> +int
> +rte_rawdev_xstats_get(uint16_t dev_id,
> +		      const unsigned int ids[],
> +		      uint64_t values[],
> +		      unsigned int n)
> +{
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV);
> +	const struct rte_rawdev *dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get, -ENOTSUP);
> +	return (*dev->dev_ops->xstats_get)(dev, ids, values, n);
> +}
> +
> +uint64_t
> +rte_rawdev_xstats_by_name_get(uint16_t dev_id,
> +			      const char *name,
> +			      unsigned int *id)
> +{
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, 0);
> +	const struct rte_rawdev *dev = &rte_rawdevs[dev_id];
> +	unsigned int temp = -1;
> +
> +	if (id != NULL)
> +		*id = (unsigned int)-1;
> +	else
> +		id = &temp; /* driver never gets a NULL value */
> +
> +	/* implemented by driver */
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_by_name, -ENOTSUP);
> +	return (*dev->dev_ops->xstats_get_by_name)(dev, name, id);
> +}
> +
> +int
> +rte_rawdev_xstats_reset(uint16_t dev_id,
> +			const uint32_t ids[], uint32_t nb_ids)
> +{
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	struct rte_rawdev *dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_reset, -ENOTSUP);
> +	return (*dev->dev_ops->xstats_reset)(dev, ids, nb_ids);
> +}
> +
> +int
> +rte_rawdev_firmware_status_get(uint16_t dev_id, rte_rawdev_obj_t status_info)
> +{
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	struct rte_rawdev *dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_status_get, -ENOTSUP);
> +	return (*dev->dev_ops->firmware_status_get)(dev, status_info);
> +}
> +
> +int
> +rte_rawdev_firmware_version_get(uint16_t dev_id, rte_rawdev_obj_t version_info)
> +{
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	struct rte_rawdev *dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_version_get, -ENOTSUP);
> +	return (*dev->dev_ops->firmware_version_get)(dev, version_info);
> +}
> +
> +int
> +rte_rawdev_firmware_load(uint16_t dev_id, rte_rawdev_obj_t firmware_image)
> +{
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	struct rte_rawdev *dev = &rte_rawdevs[dev_id];
> +
> +	if (!firmware_image)
> +		return -EINVAL;
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_load, -ENOTSUP);
> +	return (*dev->dev_ops->firmware_load)(dev, firmware_image);
> +}
> +
> +int
> +rte_rawdev_firmware_unload(uint16_t dev_id)
> +{
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	struct rte_rawdev *dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_load, -ENOTSUP);
> +	return (*dev->dev_ops->firmware_unload)(dev);
> +}
> +
> +int
> +rte_rawdev_start(uint16_t dev_id)
> +{
> +	struct rte_rawdev *dev;
> +	int diag;
> +
> +	RTE_RDEV_DEBUG("Start dev_id=%" PRIu8, dev_id);
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
> +
> +	if (dev->started != 0) {
> +		RTE_RDEV_ERR("Device with dev_id=%" PRIu8 "already started",
> +			     dev_id);
> +		return 0;
> +	}
> +
> +	diag = (*dev->dev_ops->dev_start)(dev);
> +	if (diag == 0)
> +		dev->started = 1;
> +	else
> +		return diag;
> +
> +	return 0;
> +}
> +
> +void
> +rte_rawdev_stop(uint16_t dev_id)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RDEV_DEBUG("Stop dev_id=%" PRIu8, dev_id);
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_RET(dev_id);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_stop);
> +
> +	if (dev->started == 0) {
> +		RTE_RDEV_ERR("Device with dev_id=%" PRIu8 "already stopped",
> +			dev_id);
> +		return;
> +	}
> +
> +	(*dev->dev_ops->dev_stop)(dev);
> +	dev->started = 0;
> +}
> +
> +int
> +rte_rawdev_close(uint16_t dev_id)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
> +	/* Device must be stopped before it can be closed */
> +	if (dev->started == 1) {
> +		RTE_RDEV_ERR("Device %u must be stopped before closing",
> +			     dev_id);
> +		return -EBUSY;
> +	}
> +
> +	return (*dev->dev_ops->dev_close)(dev);
> +}
> +
> +int
> +rte_rawdev_reset(uint16_t dev_id)
> +{
> +	struct rte_rawdev *dev;
> +
> +	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> +	dev = &rte_rawdevs[dev_id];
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP);
> +	/* Reset is not dependent on state of the device */
> +	return (*dev->dev_ops->dev_reset)(dev);
> +}
> +
> +static inline uint8_t
> +rte_rawdev_find_free_device_index(void)
> +{
> +	uint16_t dev_id;
> +
> +	for (dev_id = 0; dev_id < RTE_MAX_RAWDEVPORTS; dev_id++) {
> +		if (rte_rawdevs[dev_id].attached ==
> +				RTE_RAWDEV_DETACHED)
> +			return dev_id;
> +	}
> +
> +	return RTE_MAX_RAWDEVPORTS;
> +}
> +
> +struct rte_rawdev *
> +rte_rawdev_pmd_allocate(const char *name, size_t dev_priv_size, int socket_id)
> +{
> +	struct rte_rawdev *rawdev;
> +	uint16_t dev_id;
> +
> +	if (rte_rawdev_pmd_get_named_dev(name) != NULL) {
> +		RTE_RDEV_ERR("Event device with name %s already allocated!",
> +			     name);
> +		return NULL;
> +	}
> +
> +	dev_id = rte_rawdev_find_free_device_index();
> +	if (dev_id == RTE_MAX_RAWDEVPORTS) {
> +		RTE_RDEV_ERR("Reached maximum number of raw devices");
> +		return NULL;
> +	}
> +
> +	rawdev = &rte_rawdevs[dev_id];
> +
> +	rawdev->dev_private = rte_zmalloc_socket("rawdev private",
> +				     dev_priv_size,
> +				     RTE_CACHE_LINE_SIZE,
> +				     socket_id);
> +	if (!rawdev->dev_private) {
> +		RTE_RDEV_ERR("Unable to allocate memory to Skeleton dev");
> +		return NULL;
> +	}
> +
> +
> +	rawdev->dev_id = dev_id;
> +	rawdev->socket_id = socket_id;
> +	rawdev->started = 0;
> +	snprintf(rawdev->name, RTE_RAWDEV_NAME_MAX_LEN, "%s", name);
> +
> +	rawdev->attached = RTE_RAWDEV_ATTACHED;
> +	rawdev_globals.nb_devs++;
> +
> +	return rawdev;
> +}
> +
> +int
> +rte_rawdev_pmd_release(struct rte_rawdev *rawdev)
> +{
> +	int ret;
> +
> +	if (rawdev == NULL)
> +		return -EINVAL;
> +
> +	ret = rte_rawdev_close(rawdev->dev_id);
> +	if (ret < 0)
> +		return ret;
> +
> +	rawdev->attached = RTE_RAWDEV_DETACHED;
> +	rawdev_globals.nb_devs--;
> +
> +	rawdev->dev_id = 0;
> +	rawdev->socket_id = 0;
> +	rawdev->dev_ops = NULL;
> +	if (rawdev->dev_private) {
> +		rte_free(rawdev->dev_private);
> +		rawdev->dev_private = NULL;
> +	}
> +
> +	return 0;
> +}
> +
> +RTE_INIT(librawdev_init_log);
> +
> +static void
> +librawdev_init_log(void)
> +{
> +	librawdev_logtype = rte_log_register("librte.rawdev");
> +	if (librawdev_logtype >= 0)
> +		rte_log_set_level(librawdev_logtype, RTE_LOG_INFO);
> +}
> diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
> new file mode 100644
> index 000000000..d199819d4
> --- /dev/null
> +++ b/lib/librte_rawdev/rte_rawdev.h
> @@ -0,0 +1,586 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2017 NXP
> + */
> +
> +#ifndef _RTE_RAWDEV_H_
> +#define _RTE_RAWDEV_H_
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <rte_common.h>
> +#include <rte_memory.h>
> +#include <rte_errno.h>
> +
> +#define RTE_RAWDEV_MAX_DEVS	RTE_MAX_RAWDEVS
> +
> +/* Rawdevice object - essentially a void to be typecasted by implementation */
> +typedef void *rte_rawdev_obj_t;
> +
> +/**
> + * Get the total number of raw devices that have been successfully
> + * initialised.
> + *
> + * @return
> + *   The total number of usable raw devices.
> + */
> +uint8_t
> +rte_rawdev_count(void);
> +
> +/**
> + * Get the device identifier for the named raw device.
> + *
> + * @param name
> + *   Raw device name to select the raw device identifier.
> + *
> + * @return
> + *   Returns raw device identifier on success.
> + *   - <0: Failure to find named raw device.
> + */
> +uint16_t
> +rte_rawdev_get_dev_id(const char *name);
> +
> +/**
> + * Return the NUMA socket to which a device is connected.
> + *
> + * @param dev_id
> + *   The identifier of the device.
> + * @return
> + *   The NUMA socket id to which the device is connected or
> + *   a default of zero if the socket could not be determined.
> + *   -(-EINVAL)  dev_id value is out of range.
> + */
> +int
> +rte_rawdev_socket_id(uint16_t dev_id);
> +
> +/**
> + * Raw device information forward declaration
> + */
> +struct rte_rawdev_info;
> +
> +/**
> + * Retrieve the contextual information of a raw device.
> + *
> + * @param dev_id
> + *   The identifier of the device.
> + *
> + * @param[out] dev_info
> + *   A pointer to a structure of type *rte_rawdev_info* to be filled with the
> + *   contextual information of the device.
> + *
> + * @return
> + *   - 0: Success, driver updates the contextual information of the raw device
> + *   - <0: Error code returned by the driver info get function.
> + *
> + */
> +int
> +rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info);
> +
> +/**
> + * Configure a raw device.
> + *
> + * This function must be invoked first before any other function in the
> + * API. This function can also be re-invoked when a device is in the
> + * stopped state.
> + *
> + * The caller may use rte_rawdev_info_get() to get the capability of each
> + * resources available for this raw device.
> + *
> + * @param dev_id
> + *   The identifier of the device to configure.
> + * @param dev_conf
> + *   The raw device configuration structure encapsulated into rte_rawdev_info
> + *   object.
> + *   It is assumed that the opaque object has enough information which the
> + *   driver/implementation can use to configure the device. It is also assumed
> + *   that once the configuration is done, a `queue_id` type field can be used
> + *   to refer to some arbitrary internal representation of a queue.
> + *
> + * @return
> + *   - 0: Success, device configured.
> + *   - <0: Error code returned by the driver configuration function.
> + */
> +int
> +rte_rawdev_configure(uint16_t dev_id, struct rte_rawdev_info *dev_conf);
> +
> +
> +/**
> + * Retrieve the current configuration information of a raw queue designated
> + * by its *queue_id* from the raw driver for a raw device.
> + *
> + * This function intended to be used in conjunction with rte_raw_queue_setup()
> + * where caller needs to set up the queue by overriding few default values.
> + *
> + * @param dev_id
> + *   The identifier of the device.
> + * @param queue_id
> + *   The index of the raw queue to get the configuration information.
> + *   The value must be in the range [0, nb_raw_queues - 1]
> + *   previously supplied to rte_rawdev_configure().
> + * @param[out] queue_conf
> + *   The pointer to the default raw queue configuration data.
> + * @return
> + *   - 0: Success, driver updates the default raw queue configuration data.
> + *   - <0: Error code returned by the driver info get function.
> + *
> + * @see rte_raw_queue_setup()
> + *
> + */
> +int
> +rte_rawdev_queue_conf_get(uint16_t dev_id,
> +			  uint16_t queue_id,
> +			  rte_rawdev_obj_t queue_conf);
> +
> +/**
> + * Allocate and set up a raw queue for a raw device.
> + *
> + * @param dev_id
> + *   The identifier of the device.
> + * @param queue_id
> + *   The index of the raw queue to setup. The value must be in the range
> + *   [0, nb_raw_queues - 1] previously supplied to rte_rawdev_configure().
> + * @param queue_conf
> + *   The pointer to the configuration data to be used for the raw queue.
> + *   NULL value is allowed, in which case default configuration	used.
> + *
> + * @see rte_rawdev_queue_conf_get()
> + *
> + * @return
> + *   - 0: Success, raw queue correctly set up.
> + *   - <0: raw queue configuration failed
> + */
> +int
> +rte_rawdev_queue_setup(uint16_t dev_id,
> +		       uint16_t queue_id,
> +		       rte_rawdev_obj_t queue_conf);
> +
> +/**
> + * Allocate and set up a raw queue for a raw device.
> + *
> + * @param dev_id
> + *   The identifier of the device.
> + * @param queue_id
> + *   The index of the raw queue to setup. The value must be in the range
> + *   [0, nb_raw_queues - 1] previously supplied to rte_rawdev_configure().
> + *
> + * @see rte_rawdev_queue_conf_get()
> + *
> + * @return
> + *   - 0: Success, raw queue correctly set up.
> + *   - <0: raw queue configuration failed
> + */
[Fiona] cut and paste error above - should be release.

> +int
> +rte_rawdev_queue_release(uint16_t dev_id, uint16_t queue_id);
> +/**
> + * Get the number of raw queues on a specific raw device
> + *
> + * @param dev_id
> + *   Raw device identifier.
> + * @return
> + *   - The number of configured raw queues
> + */
> +uint16_t
> +rte_rawdev_queue_count(uint16_t dev_id);
> +
> +/**
> + * Start a raw device.
> + *
> + * The device start step is the last one and consists of setting the raw
> + * queues to start accepting the raws and schedules to raw ports.
> + *
> + * On success, all basic functions exported by the API (raw enqueue,
> + * raw dequeue and so on) can be invoked.
> + *
> + * @param dev_id
> + *   Raw device identifier
> + * @return
> + *   - 0: Success, device started.
> + *   < 0: Failure
> + */
> +int
> +rte_rawdev_start(uint16_t dev_id);
> +
> +/**
> + * Stop a raw device. The device can be restarted with a call to
> + * rte_rawdev_start()
> + *
> + * @param dev_id
> + *   Raw device identifier.
> + */
> +void
> +rte_rawdev_stop(uint16_t dev_id);
> +
> +/**
> + * Close a raw device. The device cannot be restarted after this call.
> + *
> + * @param dev_id
> + *   Raw device identifier
> + *
> + * @return
> + *  - 0 on successfully closing device
> + *  - <0 on failure to close device
> + *  - (-EAGAIN) if device is busy
> + */
> +int
> +rte_rawdev_close(uint16_t dev_id);
> +
> +/**
> + * Reset a raw device.
> + * This is different from cycle of rte_rawdev_start->rte_rawdev_stop in the
> + * sense similar to hard or soft reset.
> + *
> + * @param dev_id
> + *   Raw device identifiers
> + * @return
> + *   0 for sucessful reset,
> + *  !0 for failure in reseting
> + */
> +int
> +rte_rawdev_reset(uint16_t dev_id);
> +
> +#define RTE_RAWDEV_NAME_MAX_LEN	(64)
> +/**< @internal Max length of name of raw PMD */
> +
> +
> +
> +/** @internal
> + * The data structure associated with each raw device.
> + * It is a placeholder for PMD specific data, encapsulating only information
> + * related to framework.
> + */
> +struct rte_rawdev {
> +	int socket_id;
> +	/**< Socket ID where memory is allocated */
> +	uint16_t dev_id;
> +	/**< Device ID for this instance */
> +
> +	const struct rte_rawdev_ops *dev_ops;
> +	/**< Functions exported by PMD */
> +
> +	struct rte_device *device;
> +	/**< Device info. supplied during device initialization */
> +	const char *driver_name;
> +	/**< Driver info. supplied by probing */
> +
> +	RTE_STD_C11
> +	uint8_t attached : 1;
> +	/**< Flag indicating the device is attached */
> +	uint8_t started : 1;
> +	/**< Device state: STARTED(1)/STOPPED(0) */
> +
> +	rte_rawdev_obj_t dev_private;
> +	/**< PMD-specific private data */
> +
> +	char name[RTE_RAWDEV_NAME_MAX_LEN];
> +} __rte_cache_aligned;
> +
> +extern struct rte_rawdev *rte_rawdevs;
> +/** @internal The pool of rte_rawdev structures. */
> +
> +struct rte_rawdev_info {
> +	const char *driver_name; /**< Name of driver handling this device */
> +	struct rte_device *device;  /**< Device encapsulation */
> +
> +	int socket_id;
> +	/**< Socket ID where memory is allocated */
> +
> +	rte_rawdev_obj_t dev_private;
> +	/**< PMD-specific private data */
> +};
> +
> +struct rte_rawdev_buf {
> +	void *buf_addr;
> +};
> +
> +/**
> + * Dump internal information about *dev_id* to the FILE* provided in *f*.
> + *
> + * @param dev_id
> + *   The identifier of the device.
> + *
> + * @param f
> + *   A pointer to a file for output
> + *
> + * @return
> + *   - 0: on success
> + *   - <0: on failure.
> + */
> +int
> +rte_rawdev_dump(uint16_t dev_id, FILE *f);
> +
> +/**
> + * Get an attribute value from implementation.
> + * Attribute is an opaque handle agreed upon between application and PMD.
> + *
> + * Implementations are expected to maintain an array of attribute-value pairs
> + * based on application calls. Memory management for this structure is
> + * shared responsibility of implementation and application.
> + *
> + * @param dev_id
> + *   The identifier of the device to configure.
> + * @attr_name
> + *   Opaque object representing an attribute in implementation.
> + * @attr_value [out]
> + *   Opaque response to the attribute value. In case of error, this remains
> + *   untouched. This is double pointer of void type.
> + * @return
> + *   0 for success
> + *  !0 Error; attr_value remains untouched in case of error.
> + */
> +int
> +rte_rawdev_get_attr(uint16_t dev_id,
> +		    const char *attr_name,
> +		    uint64_t *attr_value);
> +
> +/**
> + * Set an attribute value.
> + * Attribute is an opaque handle agreed upon between application and PMD.
> + *
> + * @param dev_id
> + *   The identifier of the device to configure.
> + * @attr_name
> + *   Opaque object representing an attribute in implementation.
> + * @attr_value
> + *   Value of the attribute represented by attr_name
> + * @return
> + *   0 for success
> + *  !0 Error
> + */
> +int
> +rte_rawdev_set_attr(uint16_t dev_id,
> +		    const char *attr_name,
> +		    const uint64_t attr_value);
> +
> +/**
> + * Enqueue a stream of buffers to the device.
> + *
> + * Rather than specifying a queue, this API passes along an opaque object
> + * to the driver implementation. That object can be a queue or any other
> + * contextual information necessary for the device to enqueue buffers.
> + *
> + * @param dev_id
> + *   The identifier of the device to configure.
> + * @param bufs
> + *   Collection of buffers for enqueueing
> + * @param count
> + *   Count of buffers to enqueue
> + * @param context
> + *   Opaque context information.
> + * @return
> + *   >=0 for buffers enqueued
> + *  !0 for failure.
> + *  Whether partial enqueue is failure or success is defined between app
> + *  and driver implementation.
> + */
> +int
> +rte_rawdev_enqueue_buffers(uint16_t dev_id,
> +			   struct rte_rawdev_buf **buffers,
> +			   unsigned int count,
> +			   rte_rawdev_obj_t context);
> +
> +/**
> + * Dequeue a stream of buffers from the device.
> + *
> + * Rather than specifying a queue, this API passes along an opaque object
> + * to the driver implementation. That object can be a queue or any other
> + * contextual information necessary for the device to dequeue buffers.
> + *
> + * Application should have allocated enough space to store `count` response
> + * buffers.
> + * Releasing buffers dequeued is responsibility of the application.
> + *
> + * @param dev_id
> + *   The identifier of the device to configure.
> + * @param bufs
> + *   Collection of buffers dequeued
> + * @param count
> + *   Max buffers expected to be dequeued
> + * @param context
> + *   Opaque context information.
> + * @return
> + *   >=0 for buffers dequeued
> + *  !0 for failure.
> + *  Whether partial enqueue is failure or success is defined between app
> + *  and driver implementation.
> + */
> +int
> +rte_rawdev_dequeue_buffers(uint16_t dev_id,
> +			   struct rte_rawdev_buf **buffers,
> +			   unsigned int count,
> +			   rte_rawdev_obj_t context);
> +
> +/** Maximum name length for extended statistics counters */
> +#define RTE_RAW_DEV_XSTATS_NAME_SIZE 64
> +
> +/**
> + * A name-key lookup element for extended statistics.
> + *
> + * This structure is used to map between names and ID numbers
> + * for extended ethdev statistics.
> + */
> +struct rte_rawdev_xstats_name {
> +	char name[RTE_RAW_DEV_XSTATS_NAME_SIZE];
> +};
> +
> +/**
> + * Retrieve names of extended statistics of a raw device.
> + *
> + * @param dev_id
> + *   The identifier of the raw device.
> + * @param[out] xstats_names
> + *   Block of memory to insert names into. Must be at least size in capacity.
> + *   If set to NULL, function returns required capacity.
> + * @param size
> + *   Capacity of xstats_names (number of names).
> + * @return
> + *   - positive value lower or equal to size: success. The return value
> + *     is the number of entries filled in the stats table.
> + *   - positive value higher than size: error, the given statistics table
> + *     is too small. The return value corresponds to the size that should
> + *     be given to succeed. The entries in the table are not valid and
> + *     shall not be used by the caller.
> + *   - negative value on error:
> + *        -ENODEV for invalid *dev_id*
> + *        -ENOTSUP if the device doesn't support this function.
> + */
> +int
> +rte_rawdev_xstats_names_get(uint16_t dev_id,
> +			    struct rte_rawdev_xstats_name *xstats_names,
> +			    unsigned int size);
> +
> +/**
> + * Retrieve extended statistics of a raw device.
> + *
> + * @param dev_id
> + *   The identifier of the device.
> + * @param ids
> + *   The id numbers of the stats to get. The ids can be got from the stat
> + *   position in the stat list from rte_rawdev_get_xstats_names(), or
> + *   by using rte_rawdev_get_xstats_by_name()
> + * @param[out] values
> + *   The values for each stats request by ID.
> + * @param n
> + *   The number of stats requested
> + * @return
> + *   - positive value: number of stat entries filled into the values array
> + *   - negative value on error:
> + *        -ENODEV for invalid *dev_id*
> + *        -ENOTSUP if the device doesn't support this function.
> + */
> +int
> +rte_rawdev_xstats_get(uint16_t dev_id,
> +		      const unsigned int ids[],
> +		      uint64_t values[],
> +		      unsigned int n);
> +
> +/**
> + * Retrieve the value of a single stat by requesting it by name.
> + *
> + * @param dev_id
> + *   The identifier of the device
> + * @param name
> + *   The stat name to retrieve
> + * @param[out] id
> + *   If non-NULL, the numerical id of the stat will be returned, so that further
> + *   requests for the stat can be got using rte_rawdev_xstats_get, which will
> + *   be faster as it doesn't need to scan a list of names for the stat.
> + *   If the stat cannot be found, the id returned will be (unsigned)-1.
> + * @return
> + *   - positive value or zero: the stat value
> + *   - negative value: -EINVAL if stat not found, -ENOTSUP if not supported.
> + */
> +uint64_t
> +rte_rawdev_xstats_by_name_get(uint16_t dev_id,
> +			      const char *name,
> +			      unsigned int *id);
> +
> +/**
> + * Reset the values of the xstats of the selected component in the device.
> + *
> + * @param dev_id
> + *   The identifier of the device
> + * @param ids
> + *   Selects specific statistics to be reset. When NULL, all statistics
> + *   will be reset. If non-NULL, must point to array of at least
> + *   *nb_ids* size.
> + * @param nb_ids
> + *   The number of ids available from the *ids* array. Ignored when ids is NULL.
> + * @return
> + *   - zero: successfully reset the statistics to zero
> + *   - negative value: -EINVAL invalid parameters, -ENOTSUP if not supported.
> + */
> +int
> +rte_rawdev_xstats_reset(uint16_t dev_id,
> +			const uint32_t ids[],
> +			uint32_t nb_ids);
> +
> +/**
> + * Get Firmware status of the device..
> + * Returns a memory allocated by driver/implementation containing status
> + * information block. It is responsibility of caller to release the buffer.
> + *
> + * @param dev_id
> + *   Raw device identifier
> + * @param status_info
> + *   Pointer to status information area. Caller is responsible for releasing
> + *   the memory associated.
> + * @return
> + *   0 for success,
> + *  !0 for failure, `status_info` argument state is undefined
> + */
> +int
> +rte_rawdev_firmware_status_get(uint16_t dev_id,
> +			       rte_rawdev_obj_t status_info);
> +
> +/**
> + * Get Firmware version of the device.
> + * Returns a memory allocated by driver/implementation containing version
> + * information block. It is responsibility of caller to release the buffer.
> + *
> + * @param dev_id
> + *   Raw device identifier
> + * @param version_info
> + *   Pointer to version information area. Caller is responsible for releasing
> + *   the memory associated.
> + * @return
> + *   0 for success,
> + *  !0 for failure, `version_info` argument state is undefined
> + */
> +int
> +rte_rawdev_firmware_version_get(uint16_t dev_id,
> +				rte_rawdev_obj_t version_info);
> +
> +/**
> + * Load firmware on the device.
> + * TODO: In future, methods like directly flashing from file too can be
> + * supported.
> + *
> + * @param dev_id
> + *   Raw device identifier
> + * @param firmware_image
> + *   Pointer to buffer containing image binary data
> + * @return
> + *   0 for successfull Load
> + *  !0 for failure to load the provided image, or image incorrect.
> + */
> +int
> +rte_rawdev_firmware_load(uint16_t dev_id, rte_rawdev_obj_t firmware_image);
> +
> +/**
> + * Unload firmware from the device.
> + *
> + * @param dev_id
> + *   Raw device identifiers
> + * @return
> + *   0 for successful Unload
> + *  !0 for failure in unloading
> + */
> +int
> +rte_rawdev_firmware_unload(uint16_t dev_id);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_RAWDEV_H_ */
> diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
> new file mode 100644
> index 000000000..0147ef72f
> --- /dev/null
> +++ b/lib/librte_rawdev/rte_rawdev_pmd.h
> @@ -0,0 +1,588 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2017 NXP
> + */
> +
> +#ifndef _RTE_RAWDEV_PMD_H_
> +#define _RTE_RAWDEV_PMD_H_
> +
> +/** @file
> + * RTE RAW PMD APIs
> + *
> + * @note
> + * Driver facing APIs for a raw device. These are not to be called directly by
> + * any application.
> + * @b EXPERIMENTAL: this API may change without prior notice
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <string.h>
> +
> +#include <rte_dev.h>
> +#include <rte_malloc.h>
> +#include <rte_log.h>
> +#include <rte_common.h>
> +
> +#include "rte_rawdev.h"
> +
> +extern int librawdev_logtype;
> +
> +/* Logging Macros */
> +#define RTE_RDEV_LOG(level, fmt, args...) \
> +	rte_log(RTE_LOG_ ## level, librawdev_logtype, "%s(): " fmt "\n", \
> +		__func__, ##args)
> +
> +#define RTE_RDEV_ERR(fmt, args...) \
> +	RTE_RDEV_LOG(ERR, fmt, ## args)
> +#define RTE_RDEV_DEBUG(fmt, args...) \
> +	RTE_RDEV_LOG(DEBUG, fmt, ## args)
> +#define RTE_RDEV_INFO(fmt, args...) \
> +	RTE_RDEV_LOG(INFO, fmt, ## args)
> +
> +
> +/* Macros to check for valid device */
> +#define RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, retval) do { \
> +	if (!rte_rawdev_pmd_is_valid_dev((dev_id))) { \
> +		RTE_RDEV_ERR("Invalid dev_id=%d", dev_id); \
> +		return retval; \
> +	} \
> +} while (0)
> +
> +#define RTE_RAWDEV_VALID_DEVID_OR_RET(dev_id) do { \
> +	if (!rte_rawdev_pmd_is_valid_dev((dev_id))) { \
> +		RTE_RDEV_ERR("Invalid dev_id=%d", dev_id); \
> +		return; \
> +	} \
> +} while (0)
> +
> +#define RTE_RAWDEV_DETACHED  (0)
> +#define RTE_RAWDEV_ATTACHED  (1)
> +
> +/* Global structure used for maintaining state of allocated raw devices.
> + *
> + * TODO: Should be expanded to <type of raw device>:<count> in future.
> + *       Applications should be able to select from a number of type of raw
> + *       devices which were detected or attached to this DPDK instance.
> + */
> +struct rte_rawdev_global {
> +	uint16_t nb_devs;	/**< Number of devices found */
> +};
> +
> +extern struct rte_rawdev_global *rte_rawdev_globals;
> +/** Pointer to global raw devices data structure. */
> +extern struct rte_rawdev *rte_rawdevs;
> +/** The pool of rte_rawdev structures. */
> +
> +/**
> + * Get the rte_rawdev structure device pointer for the named device.
> + *
> + * @param name
> + *   device name to select the device structure.
> + *
> + * @return
> + *   - The rte_rawdev structure pointer for the given device ID.
> + */
> +static inline struct rte_rawdev *
> +rte_rawdev_pmd_get_named_dev(const char *name)
> +{
> +	struct rte_rawdev *dev;
> +	unsigned int i;
> +
> +	if (name == NULL)
> +		return NULL;
> +
> +	for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++) {
> +		dev = &rte_rawdevs[i];
> +		if ((dev->attached == RTE_RAWDEV_ATTACHED) &&
> +		   (strcmp(dev->name, name) == 0))
> +			return dev;
> +	}
> +
> +	return NULL;
> +}
> +
> +/**
> + * Validate if the raw device index is a valid attached raw device.
> + *
> + * @param dev_id
> + *   raw device index.
> + *
> + * @return
> + *   - If the device index is valid (1) or not (0).
> + */
> +static inline unsigned
> +rte_rawdev_pmd_is_valid_dev(uint8_t dev_id)
> +{
> +	struct rte_rawdev *dev;
> +
> +	if (dev_id >= RTE_RAWDEV_MAX_DEVS)
> +		return 0;
> +
> +	dev = &rte_rawdevs[dev_id];
> +	if (dev->attached != RTE_RAWDEV_ATTACHED)
> +		return 0;
> +	else
> +		return 1;
> +}
> +
> +/**
> + * Definitions of all functions exported by a driver through the
> + * the generic structure of type *rawdev_ops* supplied in the
> + * *rte_rawdev* structure associated with a device.
> + */
> +
> +/**
> + * Get device information of a device.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param dev_info
> + *   Raw device information structure
> + *
> + * @return
> + *   Returns 0 on success
> + */
> +typedef void (*rawdev_info_get_t)(struct rte_rawdev *dev,
> +				  rte_rawdev_obj_t dev_info);
> +
> +/**
> + * Configure a device.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param config
> + *   Void object containing device specific configuration
> + *
> + * @return
> + *   Returns 0 on success
> + */
> +typedef int (*rawdev_configure_t)(const struct rte_rawdev *dev,
> +				  rte_rawdev_obj_t config);
> +
> +/**
> + * Start a configured device.
> + *
> + * @param dev
> + *   Raw device pointer
> + *
> + * @return
> + *   Returns 0 on success
> + */
> +typedef int (*rawdev_start_t)(struct rte_rawdev *dev);
> +
> +/**
> + * Stop a configured device.
> + *
> + * @param dev
> + *   Raw device pointer
> + */
> +typedef void (*rawdev_stop_t)(struct rte_rawdev *dev);
> +
> +/**
> + * Close a configured device.
> + *
> + * @param dev
> + *   Raw device pointer
> + *
> + * @return
> + * - 0 on success
> + * - (-EAGAIN) if can't close as device is busy
> + */
> +typedef int (*rawdev_close_t)(struct rte_rawdev *dev);
> +
> +/**
> + * Reset a configured device.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @return
> + *   0 for success
> + *   !0 for failure
> + */
> +typedef int (*rawdev_reset_t)(struct rte_rawdev *dev);
> +
> +/**
> + * Retrieve the current raw queue configuration.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param queue_id
> + *   Raw device queue index
> + * @param[out] queue_conf
> + *   Raw device queue configuration structure
> + *
> + */
> +typedef void (*rawdev_queue_conf_get_t)(struct rte_rawdev *dev,
> +					uint16_t queue_id,
> +					rte_rawdev_obj_t queue_conf);
> +
> +/**
> + * Setup an raw queue.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param queue_id
> + *   Rawqueue index
> + * @param queue_conf
> + *   Rawqueue configuration structure
> + *
> + * @return
> + *   Returns 0 on success.
> + */
> +typedef int (*rawdev_queue_setup_t)(struct rte_rawdev *dev,
> +				    uint16_t queue_id,
> +				    rte_rawdev_obj_t queue_conf);
> +
> +/**
> + * Release resources allocated by given raw queue.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param queue_id
> + *   Raw queue index
> + *
> + */
> +typedef int (*rawdev_queue_release_t)(struct rte_rawdev *dev,
> +				      uint16_t queue_id);
> +
> +/**
> + * Enqueue an array of raw buffers to the device.
> + *
> + * Buffer being used is opaque - it can be obtained from mempool or from
> + * any other source. Interpretation of buffer is responsibility of driver.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param bufs
> + *   array of buffers
> + * @param count
> + *   number of buffers passed
> + * @context
> + *   an opaque object representing context of the call; for example, an
> + *   application can pass information about the queues on which enqueue needs
> + *   to be done. Or, the enqueue operation might be passed reference to an
> + *   object containing a callback (agreed upon between applicatio and driver).
> + *
> + * @return
> + *   >=0 Count of buffers successfully enqueued (0: no buffers enqueued)
> + *   <0 Error count in case of error
> + */
> +typedef int (*rawdev_enqueue_bufs_t)(struct rte_rawdev *dev,
> +				     struct rte_rawdev_buf **buffers,
> +				     unsigned int count,
> +				     rte_rawdev_obj_t context);
> +
> +/**
> + * Dequeue an array of raw buffers from the device.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param bufs
> + *   array of buffers
> + * @param count
> + *   Max buffers expected to be dequeued
> + * @context
> + *   an opaque object representing context of the call. Based on this object,
> + *   the application and driver can coordinate for dequeue operation involving
> + *   agreed upon semantics. For example, queue information/id on which Dequeue
> + *   needs to be performed.
> + * @return
> + *   >0, ~0: Count of buffers returned
> + *   <0: Error
> + *   Whether short dequeue is success or failure is decided between app and
> + *   driver.
> + */
> +typedef int (*rawdev_dequeue_bufs_t)(struct rte_rawdev *dev,
> +				     struct rte_rawdev_buf **buffers,
> +				     unsigned int count,
> +				     rte_rawdev_obj_t context);
> +
> +/**
> + * Dump internal information
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param f
> + *   A pointer to a file for output
> + * @return
> + *   0 for success,
> + *   !0 Error
> + *
> + */
> +typedef int (*rawdev_dump_t)(struct rte_rawdev *dev, FILE *f);
> +
> +/**
> + * Get an attribute value from implementation.
> + * Attribute is an opaque handle agreed upon between application and PMD.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @attr_name
> + *   Opaque object representing an attribute in implementation.
> + * @attr_value [out]
> + *   Opaque response to the attribute value. In case of error, this remains
> + *   untouched. This is double pointer of void type.
> + * @return
> + *   0 for success
> + *  !0 Error; attr_value remains untouched in case of error.
> + */
> +typedef int (*rawdev_get_attr_t)(struct rte_rawdev *dev,
> +				 const char *attr_name,
> +				 uint64_t *attr_value);
> +
> +/**
> + * Set an attribute value.
> + * Attribute is an opaque handle agreed upon between application and PMD.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @attr_name
> + *   Opaque object representing an attribute in implementation.
> + * @attr_value
> + *   Value of the attribute represented by attr_name
> + * @return
> + *   0 for success
> + *  !0 Error
> + */
> +typedef int (*rawdev_set_attr_t)(struct rte_rawdev *dev,
> +				 const char *attr_name,
> +				 const uint64_t attr_value);
> +
> +/**
> + * Retrieve a set of statistics from device.
> + * Note: Being a raw device, the stats are specific to the device being
> + * implemented thus represented as xstats.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param ids
> + *   The stat ids to retrieve
> + * @param values
> + *   The returned stat values
> + * @param n
> + *   The number of id values and entries in the values array
> + * @return
> + *   The number of stat values successfully filled into the values array
> + */
> +typedef int (*rawdev_xstats_get_t)(const struct rte_rawdev *dev,
> +		const unsigned int ids[], uint64_t values[], unsigned int n);
> +
> +/**
> + * Resets the statistic values in xstats for the device.
> + */
> +typedef int (*rawdev_xstats_reset_t)(struct rte_rawdev *dev,
> +		const uint32_t ids[],
> +		uint32_t nb_ids);
> +
> +/**
> + * Get names of extended stats of an raw device
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param xstats_names
> + *   Array of name values to be filled in
> + * @param size
> + *   Number of values in the xstats_names array
> + * @return
> + *   When size >= the number of stats, return the number of stat values filled
> + *   into the array.
> + *   When size < the number of available stats, return the number of stats
> + *   values, and do not fill in any data into xstats_names.
> + */
> +typedef int (*rawdev_xstats_get_names_t)(const struct rte_rawdev *dev,
> +		struct rte_rawdev_xstats_name *xstats_names,
> +		unsigned int size);
> +
> +/**
> + * Get value of one stats and optionally return its id
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param name
> + *   The name of the stat to retrieve
> + * @param id
> + *   Pointer to an unsigned int where we store the stat-id.
> + *   This pointer may be null if the id is not required.
> + * @return
> + *   The value of the stat, or (uint64_t)-1 if the stat is not found.
> + *   If the stat is not found, the id value will be returned as (unsigned)-1,
> + *   if id pointer is non-NULL
> + */
> +typedef uint64_t (*rawdev_xstats_get_by_name_t)(const struct rte_rawdev *dev,
> +						const char *name,
> +						unsigned int *id);
> +
> +/**
> + * Get firmware/device-stack status.
> + * Implementation to allocate buffer for returning information.
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param status
> + *   void block containing device specific status information
> + * @return
> + *   0 for success,
> + *   !0 for failure, with undefined value in `status_info`
> + */
> +typedef int (*rawdev_firmware_status_get_t)(struct rte_rawdev *dev,
> +					    rte_rawdev_obj_t status_info);
> +
> +/**
> + * Get firmware version information
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param version_info
> + *   void pointer to version information returned by device
> + * @return
> + *   0 for success,
> + *   !0 for failure, with undefined value in `version_info`
> + */
> +typedef int (*rawdev_firmware_version_get_t)(struct rte_rawdev *dev,
> +					     rte_rawdev_obj_t version_info);
> +
> +/**
> + * Load firwmare from a buffer (DMA'able)
> + *
> + * @param dev
> + *   Raw device pointer
> + * @param firmware_file
> + *   file pointer to firmware area
> + * @return
> + *   >0, ~0: for successfull load
> + *   <0: for failure
> + *
> + * @see Application may use 'firmware_version_get` for ascertaining successful
> + * load
> + */
> +typedef int (*rawdev_firmware_load_t)(struct rte_rawdev *dev,
> +				      rte_rawdev_obj_t firmware_buf);
> +
> +/**
> + * Unload firwmare
> + *
> + * @param dev
> + *   Raw device pointer
> + * @return
> + *   >0, ~0 for successful unloading
> + *   <0 for failure in unloading
> + *
> + * Note: Application can use the `firmware_status_get` or
> + * `firmware_version_get` to get result of unload.
> + */
> +typedef int (*rawdev_firmware_unload_t)(struct rte_rawdev *dev);
> +
> +
> +/** Rawdevice operations function pointer table */
> +struct rte_rawdev_ops {
> +	rawdev_info_get_t dev_info_get;  /**< Get device info. */
> +	rawdev_configure_t dev_configure; /**< Configure device. */
> +	rawdev_start_t dev_start;         /**< Start device. */
> +	rawdev_stop_t dev_stop;           /**< Stop device. */
> +	rawdev_close_t dev_close;         /**< Close device. */
> +	rawdev_reset_t dev_reset;         /**< Reset device. */
> +
> +	rawdev_queue_conf_get_t queue_def_conf;
> +	/**< Get raw queue configuration. */
> +	rawdev_queue_setup_t queue_setup;
> +	/**< Set up an raw queue. */
> +	rawdev_queue_release_t queue_release;
> +	/**< Release an raw queue. */
> +
> +	rawdev_enqueue_bufs_t enqueue_bufs;
> +	/**< Enqueue an array of raw buffers to device. */
> +	rawdev_dequeue_bufs_t dequeue_bufs;
> +	/**< Dequeue an array of raw buffers from device. */
> +	/** TODO: Callback based enqueue and dequeue support */
> +
> +	rawdev_dump_t dump;
> +	/* Dump internal information */
> +
> +	rawdev_get_attr_t attr_get;
> +	/**< Get an attribute managed by the implementation */
> +	rawdev_set_attr_t attr_set;
> +	/**< Set an attribute managed by the implementation */
> +
> +	rawdev_xstats_get_t xstats_get;
> +	/**< Get extended device statistics. */
> +	rawdev_xstats_get_names_t xstats_get_names;
> +	/**< Get names of extended stats. */
> +	rawdev_xstats_get_by_name_t xstats_get_by_name;
> +	/**< Get one value by name. */
> +	rawdev_xstats_reset_t xstats_reset;
> +	/**< Reset the statistics values in xstats. */
> +
> +	rawdev_firmware_status_get_t firmware_status_get;
> +	/**< Obtainer firmware status */
> +	rawdev_firmware_version_get_t firmware_version_get;
> +	/**< Obtain firmware version information */
> +	rawdev_firmware_load_t firmware_load;
> +	/**< Load firmware */
> +	rawdev_firmware_unload_t firmware_unload;
> +	/**< Unload firmware */
> +};
> +
> +/**
> + * Allocates a new rawdev slot for an raw device and returns the pointer
> + * to that slot for the driver to use.
> + *
> + * @param name
> + *   Unique identifier name for each device
> + * @dev_priv_size
> + *   Private data allocated within rte_rawdev object.
> + * @param socket_id
> + *   Socket to allocate resources on.
> + * @return
> + *   - Slot in the rte_dev_devices array for a new device;
> + */
> +struct rte_rawdev *
> +rte_rawdev_pmd_allocate(const char *name, size_t dev_private_size,
> +			int socket_id);
[Fiona] The driver must allocate a unique name for each device, and the application presumably must search through all devices using dev_count and dev_info_get for each
until it finds a name it expects? But will the application always know the name chosen by the PMD? e.g. driver type xyz might find 10 devices and call them xyz_0, xyz_1, xyz_2, etc
The application wants to look for any or all xyz devices so must know the naming format used by the PMD. 
Would it be useful to have 2 parts to the name, a type and an instance, to facilitate finding all devices of a specific type?

> +
> +/**
> + * Release the specified rawdev device.
> + *
> + * @param rawdev
> + * The *rawdev* pointer is the address of the *rte_rawdev* structure.
> + * @return
> + *   - 0 on success, negative on error
> + */
> +int
> +rte_rawdev_pmd_release(struct rte_rawdev *rawdev);
> +
> +/**
> + * Creates a new raw device and returns the pointer to that device.
> + *
> + * @param name
> + *   Pointer to a character array containing name of the device
> + * @param dev_private_size
> + *   Size of raw PMDs private data
> + * @param socket_id
> + *   Socket to allocate resources on.
> + *
> + * @return
> + *   - Raw device pointer if device is successfully created.
> + *   - NULL if device cannot be created.
> + */
> +struct rte_rawdev *
> +rte_rawdev_pmd_init(const char *name, size_t dev_private_size,
> +		    int socket_id);
> +
> +/**
> + * Destroy a raw device
> + *
> + * @param name
> + *   Name of the device
> + * @return
> + *   - 0 on success, negative on error
> + */
> +int
> +rte_rawdev_pmd_uninit(const char *name);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_RAWDEV_PMD_H_ */
> diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
> new file mode 100644
> index 000000000..8de9abdc4
> --- /dev/null
> +++ b/lib/librte_rawdev/rte_rawdev_version.map
> @@ -0,0 +1,33 @@
> +EXPERIMENTAL {
> +	global:
> +
> +	rte_rawdev_close;
> +	rte_rawdev_configure;
> +	rte_rawdev_count;
> +	rte_rawdev_dequeue_buffers;
> +	rte_rawdev_enqueue_buffers;
> +	rte_rawdev_firmware_load;
> +	rte_rawdev_firmware_status_get;
> +	rte_rawdev_firmware_unload;
> +	rte_rawdev_firmware_version_get;
> +	rte_rawdev_get_attr;
> +	rte_rawdev_get_dev_id;
> +	rte_rawdev_info_get;
> +	rte_rawdev_pmd_allocate;
> +	rte_rawdev_pmd_release;
> +	rte_rawdev_queue_conf_get;
> +	rte_rawdev_queue_setup;
> +	rte_rawdev_queue_release;
> +	rte_rawdev_reset;
> +	rte_rawdev_set_attr;
> +	rte_rawdev_socket_id;
> +	rte_rawdev_start;
> +	rte_rawdev_stop;
> +	rte_rawdev_xstats_by_name_get;
> +	rte_rawdev_xstats_get;
> +	rte_rawdev_xstats_names_get;
> +	rte_rawdev_xstats_reset;
> +	rte_rawdevs;
> +
> +	local: *;
> +};
> --
> 2.14.1



More information about the dev mailing list