diff mbox series

[RFC,1/2] lib: introduce raw device library

Message ID 1510162854-10171-2-git-send-email-hemant.agrawal@nxp.com
State New
Headers show
Series RAW Device Support | expand

Commit Message

Hemant Agrawal Nov. 8, 2017, 5:40 p.m. UTC
Raw device is a generalized interface for expanding non-generic devices
into DPDK framework. This library provides primitive interfaces which
enable creation of raw devices.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>

---
 lib/librte_rawdev/Makefile               |  53 +++
 lib/librte_rawdev/rte_rawdev.c           | 626 +++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 524 ++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 540 ++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  28 ++
 5 files changed, 1771 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

-- 
2.7.4
diff mbox series

Patch

diff --git a/lib/librte_rawdev/Makefile b/lib/librte_rawdev/Makefile
new file mode 100644
index 0000000..a2b22a1
--- /dev/null
+++ b/lib/librte_rawdev/Makefile
@@ -0,0 +1,53 @@ 
+#   BSD LICENSE
+#
+#   Copyright 2017 NXP
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of NXPnor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+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 -lrte_mempool -lrte_ring -lrte_mbuf
+
+# library source files
+SRCS-y += rte_rawdev.c
+
+# export include files
+SYMLINK-y-include += rte_rawdev.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 0000000..1269193
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -0,0 +1,626 @@ 
+/*
+ *   BSD LICENSE
+ *
+ *   Copyright 2017 NXP
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of NXPnor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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"
+
+#define RTE_RAW_MAX_DEVS	2
+
+struct rte_rawdev rte_rawdevices[RTE_RAW_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;
+
+/* Event dev north bound API implementation */
+
+uint8_t
+rte_rawdev_count(void)
+{
+	return rte_rawdev_globals->nb_devs;
+}
+
+int
+rte_rawdev_get_dev_id(const char *name)
+{
+	int i;
+
+	if (!name)
+		return -EINVAL;
+
+	for (i = 0; i < rte_rawdev_globals->nb_devs; i++)
+		if ((strcmp(rte_rawdevices[i].data->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->data->socket_id;
+}
+
+int
+rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info)
+{
+	struct rte_rawdev *dev;
+
+	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
+	dev = &rte_rawdevs[dev_id];
+
+	if (dev_info == NULL)
+		return -EINVAL;
+
+	memset(dev_info, 0, sizeof(struct rte_rawdev_info));
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
+	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
+
+	dev_info->dev = dev->dev;
+	if (dev->driver)
+		dev_info->driver_name = dev->driver->name;
+	return 0;
+}
+
+static inline int
+rte_rawdev_queue_config(struct rte_rawdev *dev __rte_unused,
+			 uint8_t nb_queues __rte_unused)
+{
+	/* to be done */
+	return 0;
+}
+
+int
+rte_rawdev_configure(uint16_t dev_id, void *dev_conf)
+{
+	struct rte_rawdev *dev;
+	struct rte_rawdev_info info;
+	int diag;
+
+	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_infos_get, -ENOTSUP);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
+
+	if (dev->data->dev_started) {
+		RTE_RDEV_LOG_ERR(
+		    "device %d must be stopped to allow configuration", dev_id);
+		return -EBUSY;
+	}
+
+	if (dev_conf == NULL)
+		return -EINVAL;
+
+	(*dev->dev_ops->dev_infos_get)(dev, &info);
+
+	/* Configure the device */
+	diag = (*dev->dev_ops->dev_configure)(dev);
+	if (diag != 0)
+		RTE_RDEV_LOG_ERR("dev%d dev_configure = %d", dev_id, diag);
+
+	return diag;
+}
+
+int
+rte_rawdev_queue_conf_get(uint16_t dev_id, uint8_t queue_id, void *queue_conf)
+{
+	struct rte_rawdev *dev;
+
+	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
+	dev = &rte_rawdevs[dev_id];
+
+	if (queue_conf == NULL)
+		return -EINVAL;
+
+
+	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, uint8_t queue_id, void *queue_conf)
+{
+	struct rte_rawdev *dev;
+	void *def_conf;
+
+	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
+	dev = &rte_rawdevs[dev_id];
+
+	if (queue_conf == NULL) {
+		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_def_conf,
+					-ENOTSUP);
+		(*dev->dev_ops->queue_def_conf)(dev, queue_id, &def_conf);
+		queue_conf = &def_conf;
+	}
+
+	return (*dev->dev_ops->queue_setup)(dev, queue_id, queue_conf);
+}
+
+uint8_t
+rte_rawdev_queue_count(uint16_t dev_id)
+{
+	struct rte_rawdev *dev;
+
+	dev = &rte_rawdevs[dev_id];
+	return dev->data->nb_queues;
+}
+
+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);
+
+	(*dev->dev_ops->dump)(dev, f);
+	return 0;
+
+}
+
+static int
+xstats_get_count(uint16_t dev_id, enum rte_rawdev_xstats_mode mode,
+		uint8_t queue_port_id)
+{
+	struct rte_rawdev *dev = &rte_rawdevs[dev_id];
+	if (dev->dev_ops->xstats_get_names != NULL)
+		return (*dev->dev_ops->xstats_get_names)(dev, mode,
+							queue_port_id,
+							NULL, NULL, 0);
+	return 0;
+}
+
+int
+rte_rawdev_xstats_names_get(uint16_t dev_id,
+		enum rte_rawdev_xstats_mode mode, uint8_t queue_port_id,
+		struct rte_rawdev_xstats_name *xstats_names,
+		unsigned int *ids, unsigned int size)
+{
+	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV);
+	const int cnt_expected_entries = xstats_get_count(dev_id, mode,
+							  queue_port_id);
+	if (xstats_names == NULL || cnt_expected_entries < 0 ||
+			(int)size < cnt_expected_entries)
+		return cnt_expected_entries;
+
+	/* dev_id checked above */
+	const struct rte_rawdev *dev = &rte_rawdevs[dev_id];
+
+	if (dev->dev_ops->xstats_get_names != NULL)
+		return (*dev->dev_ops->xstats_get_names)(dev, mode,
+				queue_port_id, xstats_names, ids, size);
+
+	return -ENOTSUP;
+}
+
+/* retrieve rawdev extended statistics */
+int
+rte_rawdev_xstats_get(uint16_t dev_id, enum rte_rawdev_xstats_mode mode,
+		uint8_t queue_port_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];
+
+	/* implemented by the driver */
+	if (dev->dev_ops->xstats_get != NULL)
+		return (*dev->dev_ops->xstats_get)(dev, mode, queue_port_id,
+				ids, values, n);
+	return -ENOTSUP;
+}
+
+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; /* ensure driver never gets a NULL value */
+
+	/* implemented by driver */
+	if (dev->dev_ops->xstats_get_by_name != NULL)
+		return (*dev->dev_ops->xstats_get_by_name)(dev, name, id);
+	return -ENOTSUP;
+}
+
+int
+rte_rawdev_xstats_reset(uint16_t dev_id,
+		enum rte_rawdev_xstats_mode mode, int16_t queue_port_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];
+
+	if (dev->dev_ops->xstats_reset != NULL)
+		return (*dev->dev_ops->xstats_reset)(dev, mode, queue_port_id,
+							ids, nb_ids);
+	return -ENOTSUP;
+}
+
+int
+rte_rawdev_firmware_status_get(uint16_t dev_id, void *status_info)
+{
+	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
+	struct rte_rawdev *dev = &rte_rawdevs[dev_id];
+
+	if (dev->dev_ops->firmware_status_get != NULL)
+		return (*dev->dev_ops->firmware_status_get)(dev, status_info);
+
+	return -ENOTSUP;
+}
+
+int
+rte_rawdev_firmware_version_get(uint16_t dev_id, void *version_info)
+{
+	RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
+	struct rte_rawdev *dev = &rte_rawdevs[dev_id];
+
+	if (dev->dev_ops->firmware_version_get != NULL)
+		return (*dev->dev_ops->firmware_status_get)(dev, version_info);
+
+	return -ENOTSUP;
+}
+
+int
+rte_rawdev_firmware_load(uint16_t dev_id, void *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;
+
+	if (dev->dev_ops->firmware_load != NULL)
+		return (*dev->dev_ops->firmware_load)(dev, firmware_image);
+
+	return -ENOTSUP;
+}
+
+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];
+
+	if (dev->dev_ops->firmware_unload != NULL)
+		return (*dev->dev_ops->firmware_unload)(dev);
+
+	return -ENOTSUP;
+}
+
+int
+rte_rawdev_start(uint16_t dev_id)
+{
+	struct rte_rawdev *dev;
+	int diag;
+
+	RTE_RDEV_LOG_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->data->dev_started != 0) {
+		RTE_RDEV_LOG_ERR("Device with dev_id=%" PRIu8 "already started",
+			dev_id);
+		return 0;
+	}
+
+	diag = (*dev->dev_ops->dev_start)(dev);
+	if (diag == 0)
+		dev->data->dev_started = 1;
+	else
+		return diag;
+
+	return 0;
+}
+
+void
+rte_rawdev_stop(uint16_t dev_id)
+{
+	struct rte_rawdev *dev;
+
+	RTE_RDEV_LOG_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->data->dev_started == 0) {
+		RTE_RDEV_LOG_ERR("Device with dev_id=%" PRIu8 "already stopped",
+			dev_id);
+		return;
+	}
+
+	dev->data->dev_started = 0;
+	(*dev->dev_ops->dev_stop)(dev);
+}
+
+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->data->dev_started == 1) {
+		RTE_RDEV_LOG_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);
+
+	/* Device must be stopped before it can be reset */
+	/* XXX: Is forced reset also a possibility? */
+	if (dev->data->dev_started == 1) {
+		RTE_RDEV_LOG_ERR("Device %u must be stopped before resetting",
+				dev_id);
+		return -EBUSY;
+	}
+
+	return (*dev->dev_ops->dev_reset)(dev);
+}
+
+static inline int
+rte_rawdev_data_alloc(uint16_t dev_id, struct rte_rawdev_data **data,
+		int socket_id)
+{
+	char mz_name[RTE_RAWDEV_NAME_MAX_LEN];
+	const struct rte_memzone *mz;
+	int n;
+
+	/* Generate memzone name */
+	n = snprintf(mz_name, sizeof(mz_name), "rte_rawdev_data_%u", dev_id);
+	if (n >= (int)sizeof(mz_name))
+		return -EINVAL;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		mz = rte_memzone_reserve(mz_name,
+				sizeof(struct rte_rawdev_data),
+				socket_id, 0);
+	} else
+		mz = rte_memzone_lookup(mz_name);
+
+	if (mz == NULL)
+		return -ENOMEM;
+
+	*data = mz->addr;
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		memset(*data, 0, sizeof(struct rte_rawdev_data));
+
+	return 0;
+}
+
+static inline uint8_t
+rte_rawdev_find_free_device_index(void)
+{
+	uint16_t dev_id;
+
+	for (dev_id = 0; dev_id < RTE_RAW_MAX_DEVS; dev_id++) {
+		if (rte_rawdevs[dev_id].attached ==
+				RTE_RAWDEV_DETACHED)
+			return dev_id;
+	}
+	return RTE_RAW_MAX_DEVS;
+}
+
+struct rte_rawdev *
+rte_rawdev_pmd_allocate(const char *name, int socket_id)
+{
+	struct rte_rawdev *rawdev;
+	uint16_t dev_id;
+
+	if (rte_rawdev_pmd_get_named_dev(name) != NULL) {
+		RTE_RDEV_LOG_ERR("Event device with name %s already "
+				"allocated!", name);
+		return NULL;
+	}
+
+	dev_id = rte_rawdev_find_free_device_index();
+	if (dev_id == RTE_RAW_MAX_DEVS) {
+		RTE_RDEV_LOG_ERR("Reached maximum number of raw devices");
+		return NULL;
+	}
+
+	rawdev = &rte_rawdevs[dev_id];
+
+	if (rawdev->data == NULL) {
+		struct rte_rawdev_data *rawdev_data = NULL;
+
+		int retval = rte_rawdev_data_alloc(dev_id, &rawdev_data,
+				socket_id);
+
+		if (retval < 0 || rawdev_data == NULL)
+			return NULL;
+
+		rawdev->data = rawdev_data;
+
+		snprintf(rawdev->data->name, RTE_RAWDEV_NAME_MAX_LEN,
+				"%s", name);
+
+		rawdev->data->dev_id = dev_id;
+		rawdev->data->socket_id = socket_id;
+		rawdev->data->dev_started = 0;
+
+		rawdev->attached = RTE_RAWDEV_ATTACHED;
+
+		rawdev_globals.nb_devs++;
+	}
+
+	return rawdev;
+}
+
+int
+rte_rawdev_pmd_release(struct rte_rawdev *rawdev)
+{
+	int ret;
+	char mz_name[RTE_RAWDEV_NAME_MAX_LEN];
+	const struct rte_memzone *mz;
+
+	if (rawdev == NULL)
+		return -EINVAL;
+
+	ret = rte_rawdev_close(rawdev->data->dev_id);
+	if (ret < 0)
+		return ret;
+
+	rawdev->attached = RTE_RAWDEV_DETACHED;
+	rawdev_globals.nb_devs--;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		rte_free(rawdev->data->dev_private);
+
+		/* Generate memzone name */
+		ret = snprintf(mz_name, sizeof(mz_name), "rte_rawdev_data_%u",
+				rawdev->data->dev_id);
+		if (ret >= (int)sizeof(mz_name))
+			return -EINVAL;
+
+		mz = rte_memzone_lookup(mz_name);
+		if (mz == NULL)
+			return -ENOMEM;
+
+		ret = rte_memzone_free(mz);
+		if (ret)
+			return ret;
+	}
+
+	rawdev->data = NULL;
+	return 0;
+}
+
+struct rte_rawdev *
+rte_rawdev_pmd_vdev_init(const char *name, size_t dev_private_size,
+		int socket_id)
+{
+	struct rte_rawdev *rawdev;
+
+	/* Allocate device structure */
+	rawdev = rte_rawdev_pmd_allocate(name, socket_id);
+	if (rawdev == NULL)
+		return NULL;
+
+	/* Allocate private device structure */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		rawdev->data->dev_private =
+				rte_zmalloc_socket("rawdev device private",
+						dev_private_size,
+						RTE_CACHE_LINE_SIZE,
+						socket_id);
+
+		if (rawdev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private device"
+					" data");
+	}
+
+	return rawdev;
+}
+
+int
+rte_rawdev_pmd_vdev_uninit(const char *name)
+{
+	struct rte_rawdev *rawdev;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	rawdev = rte_rawdev_pmd_get_named_dev(name);
+	if (rawdev == NULL)
+		return -ENODEV;
+
+	/* Free the raw device */
+	rte_rawdev_pmd_release(rawdev);
+
+	return 0;
+}
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
new file mode 100644
index 0000000..aec437e
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -0,0 +1,524 @@ 
+/*
+ *   BSD LICENSE
+ *
+ *   Copyright 2017 NXP
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of NXPnor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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>
+
+/** TODO: Revisit this - no specific reason for this limitation */
+#define RTE_RAWDEV_MAX_DEVS	2
+
+/**
+ * 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.
+ */
+int
+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
+ */
+struct rte_rawdev_info {
+	const char *driver_name; /**< Raw driver name */
+	struct rte_device *dev;  /**< Generic device encapsulation */
+	void *info;              /**< Opaque information */
+	int is_attached;         /**< Device state */
+};
+
+/**
+ * Retrieve the contextual information of an 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 an 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 as void - to be interpreted by
+ *   by the given driver.
+ *
+ * @return
+ *   - 0: Success, device configured.
+ *   - <0: Error code returned by the driver configuration function.
+ */
+int
+rte_rawdev_configure(uint16_t dev_id, void *dev_conf);
+
+
+/**
+ * Retrieve the current configuration information of an raw queue designated
+ * by its *queue_id* from the raw driver for an 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, uint8_t queue_id, void *queue_conf);
+
+/**
+ * Allocate and set up an raw queue for an 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_default_conf_get()
+ *
+ * @return
+ *   - 0: Success, raw queue correctly set up.
+ *   - <0: raw queue configuration failed
+ */
+int
+rte_rawdev_queue_setup(uint16_t dev_id, uint8_t queue_id, void *queue_conf);
+
+/**
+ * Get the number of raw queues on a specific raw device
+ *
+ * @param dev_id
+ *   Raw device identifier.
+ * @return
+ *   - The number of configured raw queues
+ */
+uint8_t
+rte_rawdev_queue_count(uint16_t dev_id);
+
+/**
+ * Start an 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 an 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 an 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 resetting
+ */
+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 part, with no function pointers, associated with each device.
+ *
+ * This structure is safe to place in shared memory to be common among
+ * different processes in a multi-process configuration.
+ */
+struct rte_rawdev_data {
+	int socket_id;
+	/**< Socket ID where memory is allocated */
+	uint16_t dev_id;
+	/**< Device ID for this instance */
+	uint8_t nb_queues;
+	/**< Number of raw queues. */
+	void *dev_private;
+	/**< PMD-specific private data */
+
+	RTE_STD_C11
+	uint8_t dev_started : 1;
+	/**< Device state: STARTED(1)/STOPPED(0) */
+
+	char name[RTE_RAWDEV_NAME_MAX_LEN];
+	/**< Unique identifier name */
+} __rte_cache_aligned;
+
+/** @internal The data structure associated with each raw device. */
+struct rte_rawdev {
+	struct rte_rawdev_data *data;
+	/**< Generic device information */
+
+	const struct rte_rawdev_ops *dev_ops;
+	/**< Functions exported by PMD */
+
+	struct rte_device *dev;
+	/**< Device info. supplied by probing */
+
+	struct rte_driver *driver;
+	/**< Device info. supplied by probing */
+
+	RTE_STD_C11
+	uint8_t attached : 1;
+	/**< Flag indicating the device is attached */
+} __rte_cache_aligned;
+
+extern struct rte_rawdev *rte_rawdevs;
+/** @internal The pool of rte_rawdev structures. */
+
+
+/**
+ * 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);
+
+/** Maximum name length for extended statistics counters */
+#define RTE_RAW_DEV_XSTATS_NAME_SIZE 64
+
+/**
+ * Selects the component of the rawdev to retrieve statistics from.
+ */
+enum rte_rawdev_xstats_mode {
+	RTE_RAW_DEV_XSTATS_DEVICE,
+	RTE_RAW_DEV_XSTATS_PORT,
+	RTE_RAW_DEV_XSTATS_QUEUE,
+};
+
+/**
+ * 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 an raw device.
+ *
+ * @param dev_id
+ *   The identifier of the raw device.
+ * @param mode
+ *   The mode of statistics to retrieve. Choices include the device statistics,
+ *   port statistics or queue statistics.
+ * @param queue_port_id
+ *   Used to specify the port or queue number in queue or port mode, and is
+ *   ignored in device mode.
+ * @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[out] ids
+ *   Block of memory to insert ids into. Must be at least size in capacity.
+ *   If set to NULL, function returns required capacity. The id values returned
+ *   can be passed to *rte_rawdev_xstats_get* to select statistics.
+ * @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*
+ *        -EINVAL for invalid mode, queue port or id parameters
+ *        -ENOTSUP if the device doesn't support this function.
+ */
+int
+rte_rawdev_xstats_names_get(uint16_t dev_id,
+			    enum rte_rawdev_xstats_mode mode,
+			    uint8_t queue_port_id,
+			    struct rte_rawdev_xstats_name *xstats_names,
+			    unsigned int *ids,
+			    unsigned int size);
+
+/**
+ * Retrieve extended statistics of an raw device.
+ *
+ * @param dev_id
+ *   The identifier of the device.
+ * @param mode
+ *  The mode of statistics to retrieve. Choices include the device statistics,
+ *  port statistics or queue statistics.
+ * @param queue_port_id
+ *   Used to specify the port or queue number in queue or port mode, and is
+ *   ignored in device mode.
+ * @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*
+ *        -EINVAL for invalid mode, queue port or id parameters
+ *        -ENOTSUP if the device doesn't support this function.
+ */
+int
+rte_rawdev_xstats_get(uint16_t dev_id,
+		      enum rte_rawdev_xstats_mode mode,
+		      uint8_t queue_port_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 mode
+ *   The mode of the statistics to reset. Choose from device, queue or port.
+ * @param queue_port_id
+ *   The queue or port to reset. 0 and positive values select ports and queues,
+ *   while -1 indicates all ports or queues.
+ * @param ids
+ *   Selects specific statistics to be reset. When NULL, all statistics selected
+ *   by *mode* 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,
+			enum rte_rawdev_xstats_mode mode,
+			int16_t queue_port_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, void *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, void *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 successful Load
+ *  !0 for failure to load the provided image, or image incorrect.
+ */
+int
+rte_rawdev_firmware_load(uint16_t dev_id, void *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 0000000..3963523
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -0,0 +1,540 @@ 
+/*
+ *
+ *   Copyright 2017 NXP
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of NXPnor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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"
+
+/* Logging Macros */
+#define RTE_RDEV_LOG_ERR(...) \
+	RTE_LOG(ERR, USER8, \
+		RTE_FMT("%s() line %u: " RTE_FMT_HEAD(__VA_ARGS__,) "\n", \
+			__func__, __LINE__, RTE_FMT_TAIL(__VA_ARGS__,)))
+
+#ifdef RTE_LIBRTE_RAWDEV_DEBUG
+#define RTE_RDEV_LOG_DEBUG(...) \
+	RTE_LOG(DEBUG, USER8, \
+		RTE_FMT("%s() line %u: " RTE_FMT_HEAD(__VA_ARGS__,) "\n", \
+			__func__, __LINE__, RTE_FMT_TAIL(__VA_ARGS__,)))
+#else
+#define RTE_RDEV_LOG_DEBUG(...) (void)0
+#endif
+
+/* 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_LOG_ERR("Invalid dev_id=%d\n", 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_LOG_ERR("Invalid dev_id=%d\n", 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 */
+struct rte_rawdev_global {
+	uint8_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->data->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, void *dev_info);
+
+/**
+ * Configure a device.
+ *
+ * @param dev
+ *   Raw device pointer
+ *
+ * @return
+ *   Returns 0 on success
+ */
+typedef int (*rawdev_configure_t)(const struct rte_rawdev *dev);
+
+/**
+ * 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,
+					uint8_t queue_id,
+					void *queue_conf);
+
+/**
+ * Setup an raw queue.
+ *
+ * @param dev
+ *   Rawdevice 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,
+				    uint8_t queue_id,
+				    void *queue_conf);
+
+/**
+ * Release resources allocated by given raw queue.
+ *
+ * @param dev
+ *   Raw device pointer
+ * @param queue_id
+ *   Raw queue index
+ *
+ */
+typedef void (*rawdev_queue_release_t)(struct rte_rawdev *dev,
+				       uint8_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 deviec pointer
+ * @param bufs
+ *   array of void buffers
+ * @param count
+ *   number of buffers passed
+ */
+typedef int (*rawdev_enqueue_bufs_t)(struct rte_rawdev *dev,
+				     void **bufs,
+				     unsigned int count);
+
+/**
+ * Dequeue an array of raw buffers from the device.
+ *
+ * @param dev
+ *   Raw deviec pointer
+ * @param bufs
+ *   array of void buffers
+ * @return
+ *   >0, ~0: Count of buffers returned
+ *   <0: Error
+ *   XXX: Should error be returned or unsigned? (0 as combined success/failure)
+ */
+typedef int (*rawdev_dequeue_bufs_t)(struct rte_rawdev *dev, void **bufs);
+
+/**
+ * Dump internal information
+ *
+ * @param dev
+ *   Raw device pointer
+ * @param f
+ *   A pointer to a file for output
+ *
+ */
+typedef void (*rawdev_dump_t)(struct rte_rawdev *dev, FILE *f);
+
+/**
+ * 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,
+		enum rte_rawdev_xstats_mode mode, uint8_t queue_port_id,
+		const unsigned int ids[], uint64_t values[], unsigned int n);
+
+/**
+ * Resets the statistic values in xstats for the device, based on mode.
+ */
+typedef int (*rawdev_xstats_reset_t)(struct rte_rawdev *dev,
+		enum rte_rawdev_xstats_mode mode,
+		int16_t queue_port_id,
+		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,
+		enum rte_rawdev_xstats_mode mode, uint8_t queue_port_id,
+		struct rte_rawdev_xstats_name *xstats_names,
+		unsigned int *ids, 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 for future reference.
+ *   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)(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,
+					    void *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,
+					     void *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 successful 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,
+				      void *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_infos_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 can also be supported  */
+
+	rawdev_dump_t dump;
+	/* Dump internal information */
+
+	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 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
+ * @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, int socket_id);
+
+/**
+ * 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 virtual raw device and returns the pointer to that device.
+ *
+ * @param name
+ *   PMD type name
+ * @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_vdev_init(const char *name, size_t dev_private_size,
+		int socket_id);
+
+/**
+ * Destroy the given virtual raw device
+ *
+ * @param name
+ *   PMD type name
+ * @return
+ *   - 0 on success, negative on error
+ */
+int
+rte_rawdev_pmd_vdev_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 0000000..fd9b969
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -0,0 +1,28 @@ 
+EXPERIMENTAL {
+	global:
+
+	rte_rawdev_close;
+	rte_rawdev_configure;
+	rte_rawdev_count;
+	rte_rawdev_firmware_load;
+	rte_rawdev_firmware_status_get;
+	rte_rawdev_firmware_unload;
+	rte_rawdev_firmware_version_get;
+	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_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;
+
+	local: *;
+};