All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/5] Introduce generic 'rawdevice' support
@ 2018-01-02 12:57 Shreyansh Jain
  2018-01-02 12:57 ` [PATCH v1 1/5] rawdev: introduce raw device library support Shreyansh Jain
                   ` (6 more replies)
  0 siblings, 7 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-02 12:57 UTC (permalink / raw)
  To: dev; +Cc: hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Rawdevice Support in DPDK
-------------------------

RFC [1]: http://dpdk.org/ml/archives/dev/2017-November/081550.html
         (from: hemant.agrawal@nxp.com)

This patchset introduces rawdevices or generic device support in DPDK.

Motivation
==========

In terms of device flavor (type) support, DPDK currently has ethernet
(lib_ether), cryptodev (libcryptodev), eventdev (libeventdev) and vdev
(virtual device) support.

For a new type of device, for example an accelerator, there are not many
options except either of:
1. create another lib/librte_MySpecialDev, driver/MySpecialDrv and use it
   through Bus/PMD model.
2. Or, create a vdev and implement necessary custom APIs which are directly
   exposed from driver layer. However this may still require changes in bus
   code in DPDK.

Either method is unclean (touching lib for specific context) and possibly
non-upstreamable (custom APIs). Applications and customers prefers uniform
device view and programming model.

Scope
=====

The rawdevice implementation is targetted towards various accelerator use cases
which cannot be generalized within existing device models. Aim is to provided a
generalized structure at the cost of portability guarantee. Specific PMDs may
also expose any specific config APIs. Applications built over such devices are
special use-cases involving IP blocks.

The rawdevice may also connect to other standard devices using adapter or other
methods, similar to eventdev adpter for ethernet/crypto devices.

Proposed Solution
=================

Defining a very generic super-set of device type and its device operations that
can be exposed such that any new/upcoming/experimental device can be layered
over it. 'rawdevice' semantic in this patchset represents a device that doesn't
have any flavor/type associated with it which is advertised (like net, crypto
etc).

A *rte_rawdevice* is a raw/generic device without any standard configuration
or input/output method assumption.

Thus, driver for a new accelerator block, which requires operations for
start/stop/enqueue/dequeue, can be quickly strapped over this rawdevice layer.
Thereafter, any appropriate bus can scan for it (assuming device is discoverable
over the Linux interfaces like sysfs) and match it against registered drivers.

Similarly, for a new accelerator or a wireless device, which doesn't fit the eth
type, a driver can be registered with a bus (on which its device would be
scannable) and use this layer for configuring the device.

It can also serve as a staging area for new type of devices till they find some
commonality and can be standardized.

The outline of this proposed library is same as existing ether/crypto devices.

     +-----------------------------------------------------------+
     |                        Application(s)                     |
     +------------------------------.----------------------------+
                                    |
                                    |
     +------------------------------'----------------------------+
     |                     DPDK Framework (APIs)                 |
     +--------------|----|-----------------|---------------------+
                   /      \                 \
            (crypto ops)  (eth ops)      (rawdev ops)        +----+
            /               \                 \              |DrvA|
     +-----'---+        +----`----+        +---'-----+       +----+
     | crypto  |        | ethdev  |        | raw     |
     +--/------+        +---/-----+        +----/----+       +----+
       /\                __/\                  /   ..........|DrvB|
      /  \              /    \                / ../    \     +----+
  +====+ +====+    +====+ +====+            +==/=+      ```Bus Probe 
  |DevA| |DevB|    |DevC| |DevD|            |DevF|
  +====+ +====+    +====+ +====+            +====+
    |      |        |      |                 |    
  ``|``````|````````|``````|`````````````````|````````Bus Scan
   (PCI)   |       (PCI)  (PCI)            (PCI)
         (BusA)

 * It is assumed above that DrvB is a PCI type driver which registers itself
   with PCI Bus
 * Thereafter, when the PCI scan is done, during probe DrvB would match the
   rawdev DevF ID and take control of device
 * Applications can then continue using the device through rawdev API interfaces

Proposed Interfaces
===================

Following broad API categories are exposed by the rawdevice:

1) Device State Operations (start/stop/reset)
2) Communication Channel setup/teardown (queue)
3) Attribute get/set operations (~ioctls)
4) Enqueue/Dequeue Operations (using opaque buffers)
5) Firmware Operations (Load/unload)

Notes:
For (1), other than standard start/stop, reset has been added extra. This is for
cases where device power cycle has various definitions. Semantics of what
stop->start and what reset would mean are still open-ended.

For (2), though currently `queue` has been used a semantic, it would be possible
in implementation to use this with other methods like internally hosted rte_ring.

For (3), applications can pass on an opaque attribute handle/information which
the driver can act upon.

For (4), aim is to allow applications to post buffers (which can be arbit data)
to the device. It is device's responsibility to interpret and handle the buffer.
It can also be expanded to synchronous and async methods of posting buffer.
That would provide broader use-cases.

For (5), Aim is to allow for most basic device firmware management. In this, as
well as other operations, it is expected that those which are not implemneted
would return ENOTSUP allow the application to fail gracefully.

Patchset Information
====================

This patchset includes 5 patches:
* 1~2: Introduce the rawdev library and enable its compilation
* 3~4: Adds a skeleton rawdevice driver, for demonstration purpose.
* 5  : Unittest framewework based on the skeleton driver as backend

Future Work
===========
1. Support for hotplugging and interrupt handling
2. Support for callbacks for enqueue and dequeue of buffers
3. Interfacing with Eth/Crypto/Event type devices for inline offloading

I will be adding a documentation page in v2, shortly.
Maintainers patch would be sent once I have some comments and scope of
getting it IN in 18.02.

References
==========
[1]: http://dpdk.org/ml/archives/dev/2017-November/081550.html

Shreyansh Jain (5):
  rawdev: introduce raw device library support
  config: enable compilation of rawdev library
  drivers/raw: introduce skeleton rawdev driver
  config: enable compilation of rawdev skeleton driver
  test: support for rawdev testcases

 config/common_base                                 |   8 +
 drivers/Makefile                                   |   2 +
 drivers/raw/Makefile                               |   9 +
 drivers/raw/skeleton_rawdev/Makefile               |  25 +
 .../rte_pmd_skeleton_rawdev_version.map            |   4 +
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      | 668 +++++++++++++++++++++
 drivers/raw/skeleton_rawdev/skeleton_rawdev.h      | 130 ++++
 lib/Makefile                                       |   3 +
 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 +
 mk/rte.app.mk                                      |   5 +
 test/test/Makefile                                 |   4 +
 test/test/test_rawdev.c                            | 376 ++++++++++++
 16 files changed, 3008 insertions(+)
 create mode 100644 drivers/raw/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.c
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.h
 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
 create mode 100644 test/test/test_rawdev.c

-- 
2.14.1

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v1 1/5] rawdev: introduce raw device library support
  2018-01-02 12:57 [PATCH v1 0/5] Introduce generic 'rawdevice' support Shreyansh Jain
@ 2018-01-02 12:57 ` Shreyansh Jain
  2018-01-06 13:40   ` Trahe, Fiona
                     ` (2 more replies)
  2018-01-02 12:57 ` [PATCH v1 2/5] config: enable compilation of rawdev library Shreyansh Jain
                   ` (5 subsequent siblings)
  6 siblings, 3 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-02 12:57 UTC (permalink / raw)
  To: dev; +Cc: hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

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@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
+
+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
+ */
+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);
+
+/**
+ * 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

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v1 2/5] config: enable compilation of rawdev library
  2018-01-02 12:57 [PATCH v1 0/5] Introduce generic 'rawdevice' support Shreyansh Jain
  2018-01-02 12:57 ` [PATCH v1 1/5] rawdev: introduce raw device library support Shreyansh Jain
@ 2018-01-02 12:57 ` Shreyansh Jain
  2018-01-14 22:50   ` Thomas Monjalon
  2018-01-02 12:57 ` [PATCH v1 3/5] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-02 12:57 UTC (permalink / raw)
  To: dev; +Cc: hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Add config option CONFIG_RTE_LIBRTE_RAWDEV for toggling rawdev
library support. This patch also enables compilation of the library.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 config/common_base | 7 +++++++
 lib/Makefile       | 3 +++
 mk/rte.app.mk      | 1 +
 3 files changed, 11 insertions(+)

diff --git a/config/common_base b/config/common_base
index e74febef4..3d2e12c31 100644
--- a/config/common_base
+++ b/config/common_base
@@ -792,6 +792,13 @@ CONFIG_RTE_LIBRTE_VHOST=n
 CONFIG_RTE_LIBRTE_VHOST_NUMA=n
 CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
 
+#
+# Compile raw device support
+# EXPERIMENTAL: API may change without prior notice
+#
+CONFIG_RTE_LIBRTE_RAWDEV=y
+CONFIG_RTE_MAX_RAWDEVS=10
+
 #
 # Compile vhost PMD
 # To compile, CONFIG_RTE_LIBRTE_VHOST should be enabled.
diff --git a/lib/Makefile b/lib/Makefile
index dc4e8df70..c75b7a694 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -126,4 +126,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
 endif
 DEPDIRS-librte_kni := librte_eal librte_mempool librte_mbuf librte_ether
 
+DIRS-$(CONFIG_RTE_LIBRTE_RAWDEV) += librte_rawdev
+DEPDIRS-librte_rawdev := librte_eal librte_ether
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 6a6a7452e..d783de2c1 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -104,6 +104,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
+_LDLIBS-$(CONFIG_RTE_LIBRTE_RAWDEV)         += -lrte_rawdev
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v1 3/5] drivers/raw: introduce skeleton rawdev driver
  2018-01-02 12:57 [PATCH v1 0/5] Introduce generic 'rawdevice' support Shreyansh Jain
  2018-01-02 12:57 ` [PATCH v1 1/5] rawdev: introduce raw device library support Shreyansh Jain
  2018-01-02 12:57 ` [PATCH v1 2/5] config: enable compilation of rawdev library Shreyansh Jain
@ 2018-01-02 12:57 ` Shreyansh Jain
  2018-01-14 22:54   ` Thomas Monjalon
  2018-01-02 12:57 ` [PATCH v1 4/5] config: enable compilation of rawdev skeleton driver Shreyansh Jain
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-02 12:57 UTC (permalink / raw)
  To: dev; +Cc: hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Skeleton rawdevice driver, on the lines of eventdev skeleton, is for
showcasing the rawdev library. This driver implements some of the
operations of the library based on which a test module can be
developed.

* Design of skeleton involves a virtual device which is plugged into
  VDEV bus on initialization.
* Enqueue and Dequeue buffers essentially hold a series of buffers for
  a sequence enqueue->dequeue operation. Important in this is use of
  context as parameter to define opaque information (like queue_id)
  transacted between application and driver.
* Device start and stop are dummy-fied operations for enabling and
  disabling the device.
* Firmware operations are not implemented but can be easily extended
  with corresponding test cases in the unittest framework.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/raw/Makefile                               |   9 +
 drivers/raw/skeleton_rawdev/Makefile               |  25 +
 .../rte_pmd_skeleton_rawdev_version.map            |   4 +
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      | 668 +++++++++++++++++++++
 drivers/raw/skeleton_rawdev/skeleton_rawdev.h      | 130 ++++
 5 files changed, 836 insertions(+)
 create mode 100644 drivers/raw/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.c
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.h

diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
new file mode 100644
index 000000000..da7c8b449
--- /dev/null
+++ b/drivers/raw/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2017 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# DIRS-$(<configuration>) += <directory>
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/skeleton_rawdev/Makefile b/drivers/raw/skeleton_rawdev/Makefile
new file mode 100644
index 000000000..4d9b2f804
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/Makefile
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2017 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_skeleton_rawdev.a
+
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_bus_vdev
+
+EXPORT_MAP := rte_pmd_skeleton_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map b/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
new file mode 100644
index 000000000..179140fb8
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_18.02 {
+
+	local: *;
+};
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
new file mode 100644
index 000000000..56e6805df
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
@@ -0,0 +1,668 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_debug.h>
+#include <rte_dev.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_lcore.h>
+#include <rte_bus_vdev.h>
+
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "skeleton_rawdev.h"
+
+/* Dynamic log type identifier */
+int skeleton_pmd_logtype;
+
+#define SKELETON_PMD_RAWDEV_NAME rawdev_skeleton
+/**< Rawdev Skeleton dummy driver name */
+
+static struct rte_vdev_driver skeleton_pmd_drv;
+/**< Skeleton rawdev driver object */
+
+struct queue_buffers {
+	void *bufs[SKELETON_QUEUE_MAX_DEPTH];
+};
+
+static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {0};
+static void clear_queue_bufs(int queue_id);
+
+static void skeleton_rawdev_info_get(struct rte_rawdev *dev,
+				     rte_rawdev_obj_t dev_info)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_conf *skeldev_conf;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev_info) {
+		SKELETON_PMD_ERR("Invalid request");
+		return;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	skeldev_conf = dev_info;
+
+	skeldev_conf->num_queues = skeldev->num_queues;
+	skeldev_conf->capabilities = skeldev->capabilities;
+	skeldev_conf->device_state = skeldev->device_state;
+	skeldev_conf->firmware_state = skeldev->fw.firmware_state;
+}
+
+static int skeleton_rawdev_configure(const struct rte_rawdev *dev,
+				     rte_rawdev_obj_t config)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_conf *skeldev_conf;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	if (!config) {
+		SKELETON_PMD_ERR("Invalid configuration");
+		return -EINVAL;
+	}
+
+	skeldev_conf = config;
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	if (skeldev_conf->num_queues <= SKELETON_MAX_QUEUES)
+		skeldev->num_queues = skeldev_conf->num_queues;
+	else
+		return -EINVAL;
+
+	skeldev->capabilities = skeldev_conf->capabilities;
+	skeldev->num_queues = skeldev_conf->num_queues;
+
+	return 0;
+}
+
+static int skeleton_rawdev_start(struct rte_rawdev *dev)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+	enum skeleton_firmware_state fw_state;
+	enum skeleton_device_state device_state;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	fw_state = skeldev->fw.firmware_state;
+	device_state = skeldev->device_state;
+
+	if (fw_state == SKELETON_FW_LOADED &&
+		device_state == SKELETON_DEV_STOPPED) {
+		skeldev->device_state = SKELETON_DEV_RUNNING;
+	} else {
+		SKELETON_PMD_ERR("Device not ready for starting");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void skeleton_rawdev_stop(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (dev) {
+		skeldev = skeleton_rawdev_get_priv(dev);
+		skeldev->device_state = SKELETON_DEV_STOPPED;
+	}
+}
+
+static void
+reset_queues(struct skeleton_rawdev *skeldev)
+{
+	int i;
+
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
+		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
+		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
+	}
+}
+
+static void
+reset_attribute_table(struct skeleton_rawdev *skeldev)
+{
+	int i;
+
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (skeldev->attr[i].name) {
+			free(skeldev->attr[i].name);
+			skeldev->attr[i].name = NULL;
+		}
+	}
+}
+
+static int skeleton_rawdev_close(struct rte_rawdev *dev)
+{
+	int ret = 0, i;
+	struct skeleton_rawdev *skeldev;
+	enum skeleton_firmware_state fw_state;
+	enum skeleton_device_state device_state;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	fw_state = skeldev->fw.firmware_state;
+	device_state = skeldev->device_state;
+
+	reset_queues(skeldev);
+	reset_attribute_table(skeldev);
+
+	switch (fw_state) {
+	case SKELETON_FW_LOADED:
+		if (device_state == SKELETON_DEV_RUNNING) {
+			SKELETON_PMD_ERR("Cannot close running device");
+			ret = -EINVAL;
+		} else {
+			/* Probably call fw reset here */
+			skeldev->fw.firmware_state = SKELETON_FW_READY;
+		}
+		break;
+	case SKELETON_FW_READY:
+	case SKELETON_FW_ERROR:
+	default:
+		SKELETON_PMD_DEBUG("Device already in stopped state");
+		ret = -EINVAL;
+		break;
+	}
+
+	/* Clear all allocated queues */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
+		clear_queue_bufs(i);
+
+	return ret;
+}
+
+static int skeleton_rawdev_reset(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	SKELETON_PMD_DEBUG("Reseting device");
+	skeldev->fw.firmware_state = SKELETON_FW_READY;
+
+	return 0;
+}
+
+static void skeleton_rawdev_queue_def_conf(struct rte_rawdev *dev,
+					   uint16_t queue_id,
+					   rte_rawdev_obj_t queue_conf)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_queue *skelq;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !queue_conf)
+		return;
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	skelq = &skeldev->queues[queue_id];
+
+	if (queue_id < SKELETON_MAX_QUEUES)
+		rte_memcpy(queue_conf, skelq,
+			sizeof(struct skeleton_rawdev_queue));
+}
+
+static void
+clear_queue_bufs(int queue_id)
+{
+	int i;
+
+	/* Clear buffers for queue_id */
+	for (i = 0; i < SKELETON_QUEUE_MAX_DEPTH; i++)
+		queue_buf[queue_id].bufs[i] = NULL;
+}
+
+static int skeleton_rawdev_queue_setup(struct rte_rawdev *dev,
+				       uint16_t queue_id,
+				       rte_rawdev_obj_t queue_conf)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_queue *q;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !queue_conf)
+		return -EINVAL;
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	q = &skeldev->queues[queue_id];
+
+	if (skeldev->num_queues > queue_id &&
+	    q->depth < SKELETON_QUEUE_MAX_DEPTH) {
+		rte_memcpy(q, queue_conf,
+			   sizeof(struct skeleton_rawdev_queue));
+		clear_queue_bufs(queue_id);
+	} else {
+		SKELETON_PMD_ERR("Invalid queue configuration");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int skeleton_rawdev_queue_release(struct rte_rawdev *dev,
+					 uint16_t queue_id)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	if (skeldev->num_queues > queue_id) {
+		skeldev->queues[queue_id].state = SKELETON_QUEUE_DETACH;
+		skeldev->queues[queue_id].depth = SKELETON_QUEUE_DEF_DEPTH;
+		clear_queue_bufs(queue_id);
+	} else {
+		SKELETON_PMD_ERR("Invalid queue configuration");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int skeleton_rawdev_get_attr(struct rte_rawdev *dev,
+				    const char *attr_name,
+				    uint64_t *attr_value)
+{
+	int i;
+	uint8_t done = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !attr_name || !attr_value) {
+		SKELETON_PMD_ERR("Invalid arguments for getting attributes");
+		return -EINVAL;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (!skeldev->attr[i].name)
+			continue;
+
+		if (!strncmp(skeldev->attr[i].name, attr_name,
+			    SKELETON_ATTRIBUTE_NAME_MAX)) {
+			*attr_value = skeldev->attr[i].value;
+			done = 1;
+			SKELETON_PMD_DEBUG("Attribute (%s) Value (%lu)",
+					   attr_name, *attr_value);
+			break;
+		}
+	}
+
+	if (done)
+		return 0;
+
+	/* Attribute not found */
+	return -EINVAL;
+}
+
+static int skeleton_rawdev_set_attr(struct rte_rawdev *dev,
+				     const char *attr_name,
+				     const uint64_t attr_value)
+{
+	int i;
+	uint8_t done = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !attr_name) {
+		SKELETON_PMD_ERR("Invalid arguments for setting attributes");
+		return -EINVAL;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	/* Check if attribute already exists */
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (!skeldev->attr[i].name)
+			break;
+
+		if (!strncmp(skeldev->attr[i].name, attr_name,
+			     SKELETON_ATTRIBUTE_NAME_MAX)) {
+			/* Update value */
+			skeldev->attr[i].value = attr_value;
+			done = 1;
+			break;
+		}
+	}
+
+	if (!done) {
+		if (i < (SKELETON_MAX_ATTRIBUTES - 1)) {
+			/* There is still space to insert one more */
+			skeldev->attr[i].name = strdup(attr_name);
+			if (!skeldev->attr[i].name)
+				return -ENOMEM;
+
+			skeldev->attr[i].value = attr_value;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int skeleton_rawdev_enqueue_bufs(struct rte_rawdev *dev,
+					struct rte_rawdev_buf **buffers,
+					unsigned int count,
+					rte_rawdev_obj_t context)
+{
+	unsigned int i;
+	uint16_t q_id;
+	RTE_SET_USED(dev);
+
+	/* context is essentially the queue_id which is
+	 * transferred as opaque object through the library layer. This can
+	 * help in complex implementation which require more information than
+	 * just an integer - for example, a queue-pair.
+	 */
+	q_id = *((int *)context);
+
+	for (i = 0; i < count; i++)
+		queue_buf[q_id].bufs[i] = buffers[i]->buf_addr;
+
+	return i;
+}
+
+static int skeleton_rawdev_dequeue_bufs(struct rte_rawdev *dev,
+					struct rte_rawdev_buf **buffers,
+					unsigned int count,
+					rte_rawdev_obj_t context)
+{
+	unsigned int i;
+	uint16_t q_id;
+	RTE_SET_USED(dev);
+
+	/* context is essentially the queue_id which is
+	 * transferred as opaque object through the library layer. This can
+	 * help in complex implementation which require more information than
+	 * just an integer - for example, a queue-pair.
+	 */
+	q_id = *((int *)context);
+
+	for (i = 0; i < count; i++)
+		buffers[i]->buf_addr = queue_buf[q_id].bufs[i];
+
+	return i;
+}
+
+static int skeleton_rawdev_dump(struct rte_rawdev *dev, FILE *f)
+{
+	RTE_SET_USED(dev);
+	RTE_SET_USED(f);
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_status_get(struct rte_rawdev *dev,
+					       rte_rawdev_obj_t status_info)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	if (status_info)
+		memcpy(status_info, &skeldev->fw.firmware_state,
+			sizeof(enum skeleton_firmware_state));
+
+	return 0;
+}
+
+
+static int skeleton_rawdev_firmware_version_get(
+					struct rte_rawdev *dev,
+					rte_rawdev_obj_t version_info)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_firmware_version_info *vi;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	vi = version_info;
+
+	vi->major = skeldev->fw.firmware_version.major;
+	vi->minor = skeldev->fw.firmware_version.minor;
+	vi->subrel = skeldev->fw.firmware_version.subrel;
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_load(struct rte_rawdev *dev,
+					 rte_rawdev_obj_t firmware_buf)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	/* firmware_buf is a mmaped, possibly DMA'able area, buffer. Being
+	 * dummy, all this does is check if firmware_buf is not NULL and
+	 * sets the state of the firmware.
+	 */
+	if (!firmware_buf)
+		return -EINVAL;
+
+	skeldev->fw.firmware_state = SKELETON_FW_LOADED;
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_unload(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	skeldev->fw.firmware_state = SKELETON_FW_READY;
+
+	return 0;
+}
+
+static const struct rte_rawdev_ops skeleton_rawdev_ops = {
+	.dev_info_get = skeleton_rawdev_info_get,
+	.dev_configure = skeleton_rawdev_configure,
+	.dev_start = skeleton_rawdev_start,
+	.dev_stop = skeleton_rawdev_stop,
+	.dev_close = skeleton_rawdev_close,
+	.dev_reset = skeleton_rawdev_reset,
+
+	.queue_def_conf = skeleton_rawdev_queue_def_conf,
+	.queue_setup = skeleton_rawdev_queue_setup,
+	.queue_release = skeleton_rawdev_queue_release,
+
+	.attr_get = skeleton_rawdev_get_attr,
+	.attr_set = skeleton_rawdev_set_attr,
+
+	.enqueue_bufs = skeleton_rawdev_enqueue_bufs,
+	.dequeue_bufs = skeleton_rawdev_dequeue_bufs,
+
+	.dump = skeleton_rawdev_dump,
+
+	.xstats_get = NULL,
+	.xstats_get_names = NULL,
+	.xstats_get_by_name = NULL,
+	.xstats_reset = NULL,
+
+	.firmware_status_get = skeleton_rawdev_firmware_status_get,
+	.firmware_version_get = skeleton_rawdev_firmware_version_get,
+	.firmware_load = skeleton_rawdev_firmware_load,
+	.firmware_unload = skeleton_rawdev_firmware_unload
+};
+
+static int
+skeleton_rawdev_create(const char *name,
+		       struct rte_vdev_device *vdev,
+		       int socket_id)
+{
+	int ret = 0, i;
+	struct rte_rawdev *rawdev = NULL;
+	struct skeleton_rawdev *skeldev = NULL;
+
+	if (!name) {
+		SKELETON_PMD_ERR("Invalid name of the device!");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	/* Allocate device structure */
+	rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct skeleton_rawdev),
+					 socket_id);
+	if (rawdev == NULL) {
+		SKELETON_PMD_ERR("Unable to allocate rawdevice");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	rawdev->dev_ops = &skeleton_rawdev_ops;
+	rawdev->device = &vdev->device;
+	rawdev->driver_name = vdev->device.driver->name;
+
+	skeldev = skeleton_rawdev_get_priv(rawdev);
+
+	skeldev->device_id = SKELETON_DEVICE_ID;
+	skeldev->vendor_id = SKELETON_VENDOR_ID;
+	skeldev->capabilities = SKELETON_DEFAULT_CAPA;
+
+	memset(&skeldev->fw, 0, sizeof(struct skeleton_firmware));
+
+	skeldev->fw.firmware_state = SKELETON_DEV_STOPPED;
+	skeldev->fw.firmware_version.major = SKELETON_MAJOR_VER;
+	skeldev->fw.firmware_version.minor = SKELETON_MINOR_VER;
+	skeldev->fw.firmware_version.subrel = SKELETON_SUB_VER;
+
+	skeldev->device_state = SKELETON_DEV_STOPPED;
+
+	/* Reset/set to default queue configuration for this device */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
+		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
+		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
+	}
+
+	/* Clear all allocated queue buffers */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
+		clear_queue_bufs(i);
+
+	return ret;
+
+cleanup:
+	if (rawdev)
+		rte_rawdev_pmd_release(rawdev);
+
+	return ret;
+}
+
+static int
+skeleton_rawdev_destroy(const char *name)
+{
+	int ret;
+	struct rte_rawdev *rdev;
+
+	if (!name) {
+		SKELETON_PMD_ERR("Invalid device name");
+		return -EINVAL;
+	}
+
+	rdev = rte_rawdev_pmd_get_named_dev(name);
+	if (!rdev) {
+		SKELETON_PMD_ERR("Invalid device name (%s)", name);
+		return -EINVAL;
+	}
+
+	/* rte_rawdev_close is called by pmd_release */
+	ret = rte_rawdev_pmd_release(rdev);
+	if (ret)
+		SKELETON_PMD_DEBUG("Device cleanup failed");
+
+	return 0;
+}
+
+static int
+skeleton_rawdev_probe(struct rte_vdev_device *vdev)
+{
+	const char *name;
+
+	name = rte_vdev_device_name(vdev);
+
+	SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
+
+	return skeleton_rawdev_create(name, vdev, rte_socket_id());
+}
+
+static int
+skeleton_rawdev_remove(struct rte_vdev_device *vdev)
+{
+	const char *name;
+
+	name = rte_vdev_device_name(vdev);
+
+	SKELETON_PMD_INFO("Closing %s on NUMA node %d", name, rte_socket_id());
+
+	return skeleton_rawdev_destroy(name);
+}
+
+static struct rte_vdev_driver skeleton_pmd_drv = {
+	.probe = skeleton_rawdev_probe,
+	.remove = skeleton_rawdev_remove
+};
+
+RTE_PMD_REGISTER_VDEV(SKELETON_PMD_RAWDEV_NAME, skeleton_pmd_drv);
+
+RTE_INIT(skeleton_pmd_init_log);
+
+static void
+skeleton_pmd_init_log(void)
+{
+	skeleton_pmd_logtype = rte_log_register("rawdev.skeleton");
+	if (skeleton_pmd_logtype >= 0)
+		rte_log_set_level(skeleton_pmd_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.h b/drivers/raw/skeleton_rawdev/skeleton_rawdev.h
new file mode 100644
index 000000000..2610d96e6
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.h
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#ifndef __SKELETON_RAWDEV_H__
+#define __SKELETON_RAWDEV_H__
+
+#include <rte_rawdev.h>
+
+extern int skeleton_pmd_logtype;
+
+#define SKELETON_PMD_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, skeleton_pmd_logtype, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#define SKELETON_PMD_FUNC_TRACE() SKELETON_PMD_LOG(DEBUG, ">>")
+
+#define SKELETON_PMD_DEBUG(fmt, args...) \
+	SKELETON_PMD_LOG(DEBUG, fmt, ## args)
+#define SKELETON_PMD_INFO(fmt, args...) \
+	SKELETON_PMD_LOG(INFO, fmt, ## args)
+#define SKELETON_PMD_ERR(fmt, args...) \
+	SKELETON_PMD_LOG(ERR, fmt, ## args)
+#define SKELETON_PMD_WARN(fmt, args...) \
+	SKELETON_PMD_LOG(WARNING, fmt, ## args)
+
+#define SKELETON_VENDOR_ID 0x10
+#define SKELETON_DEVICE_ID 0x01
+
+#define SKELETON_MAJOR_VER 1
+#define SKELETON_MINOR_VER 0
+#define SKELETON_SUB_VER   0
+
+#define SKELETON_MAX_QUEUES 1
+
+enum skeleton_firmware_state {
+	SKELETON_FW_READY,
+	SKELETON_FW_LOADED,
+	SKELETON_FW_ERROR
+};
+
+enum skeleton_device_state {
+	SKELETON_DEV_RUNNING,
+	SKELETON_DEV_STOPPED
+};
+
+enum skeleton_queue_state {
+	SKELETON_QUEUE_DETACH,
+	SKELETON_QUEUE_ATTACH
+};
+
+#define SKELETON_QUEUE_DEF_DEPTH 10
+#define SKELETON_QUEUE_MAX_DEPTH 25
+
+struct skeleton_firmware_version_info {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t subrel;
+};
+
+struct skeleton_firmware {
+	struct skeleton_firmware_version_info firmware_version;
+	/**< Device firmware information */
+	enum skeleton_firmware_state firmware_state;
+	/**< Device state */
+};
+
+#define SKELETON_MAX_ATTRIBUTES 10
+#define SKELETON_ATTRIBUTE_NAME_MAX 20
+
+struct skeleton_rawdev_attributes {
+	char *name;
+	/**< Name of the attribute */
+	uint64_t value;
+	/**< Value or reference of value of attribute */
+};
+
+#define SKELETON_CAPA_FW_LOAD	0x0001
+/**< Device supports firmware loading/unloading */
+#define SKELETON_CAPA_FW_RESET  0x0002
+/**< Device supports firmware reset */
+#define SKELETON_CAPA_QUEUES    0x0004
+/**< Device support queue based communication */
+
+#define SKELETON_DEFAULT_CAPA   0x7
+
+struct skeleton_rawdev_queue {
+	uint8_t state;
+	uint32_t depth;
+};
+
+struct skeleton_rawdev {
+	uint16_t device_id;
+	uint16_t vendor_id;
+	uint16_t num_queues;
+	uint16_t capabilities;
+	/**< One of SKELETON_CAPA_* */
+
+	enum skeleton_device_state device_state;
+	/**< State of device; linked to firmware state */
+
+	struct skeleton_firmware fw;
+	/**< Firmware configuration */
+
+	struct skeleton_rawdev_queue queues[SKELETON_MAX_QUEUES];
+	/**< Collection of all communication channels - which can be referred
+	 *  to as queues.
+	 */
+	struct skeleton_rawdev_attributes attr[SKELETON_MAX_ATTRIBUTES];
+	/**< Global table containing various pre-defined and user-defined
+	 *  attributes.
+	 */
+
+	struct rte_device *device;
+};
+
+struct skeleton_rawdev_conf {
+	uint16_t num_queues;
+	unsigned int capabilities;
+	enum skeleton_device_state device_state;
+	enum skeleton_firmware_state firmware_state;
+};
+
+static inline struct skeleton_rawdev *
+skeleton_rawdev_get_priv(const struct rte_rawdev *rawdev)
+{
+	return rawdev->dev_private;
+}
+
+#endif /* __SKELETON_RAWDEV_H__ */
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v1 4/5] config: enable compilation of rawdev skeleton driver
  2018-01-02 12:57 [PATCH v1 0/5] Introduce generic 'rawdevice' support Shreyansh Jain
                   ` (2 preceding siblings ...)
  2018-01-02 12:57 ` [PATCH v1 3/5] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
@ 2018-01-02 12:57 ` Shreyansh Jain
  2018-01-14 22:55   ` Thomas Monjalon
  2018-01-02 12:57 ` [PATCH v1 5/5] test: support for rawdev testcases Shreyansh Jain
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-02 12:57 UTC (permalink / raw)
  To: dev; +Cc: hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 config/common_base | 1 +
 drivers/Makefile   | 2 ++
 mk/rte.app.mk      | 4 ++++
 3 files changed, 7 insertions(+)

diff --git a/config/common_base b/config/common_base
index 3d2e12c31..5f7dfd9e9 100644
--- a/config/common_base
+++ b/config/common_base
@@ -798,6 +798,7 @@ CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
 #
 CONFIG_RTE_LIBRTE_RAWDEV=y
 CONFIG_RTE_MAX_RAWDEVS=10
+CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
 
 #
 # Compile vhost PMD
diff --git a/drivers/Makefile b/drivers/Makefile
index db0cd76ee..407f22a3c 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -40,5 +40,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
 DEPDIRS-crypto := bus mempool
 DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event
 DEPDIRS-event := bus mempool net
+DIRS-$(CONFIG_RTE_LIBRTE_RAWDEV) += raw
+DEPDIRS-raw := bus mempool net event
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d783de2c1..ce037827b 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -203,6 +203,10 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_OCTEONTX_MEMPOOL) += -lrte_mempool_octeontx
 _LDLIBS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += -lrte_pmd_octeontx
 endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
+ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+endif # CONFIG_RTE_LIBRTE_RAWDEV
+
 ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_bus_fslmc
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_mempool_dpaa2
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v1 5/5] test: support for rawdev testcases
  2018-01-02 12:57 [PATCH v1 0/5] Introduce generic 'rawdevice' support Shreyansh Jain
                   ` (3 preceding siblings ...)
  2018-01-02 12:57 ` [PATCH v1 4/5] config: enable compilation of rawdev skeleton driver Shreyansh Jain
@ 2018-01-02 12:57 ` Shreyansh Jain
  2018-01-14 22:58   ` Thomas Monjalon
  2018-01-14 23:00 ` [PATCH v1 0/5] Introduce generic 'rawdevice' support Thomas Monjalon
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
  6 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-02 12:57 UTC (permalink / raw)
  To: dev; +Cc: hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Patch introduces rawdev unit testcase for validation against the
Skeleton rawdev dummy PMD implementation.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 test/test/Makefile      |   4 +
 test/test/test_rawdev.c | 376 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 380 insertions(+)
 create mode 100644 test/test/test_rawdev.c

diff --git a/test/test/Makefile b/test/test/Makefile
index bb54c9808..038343d38 100644
--- a/test/test/Makefile
+++ b/test/test/Makefile
@@ -214,6 +214,10 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += test_eventdev_sw.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF) += test_eventdev_octeontx.c
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
+SRCS-y += test_rawdev.c
+endif
+
 SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) += test_kvargs.c
 
 CFLAGS += -O3
diff --git a/test/test/test_rawdev.c b/test/test/test_rawdev.c
new file mode 100644
index 000000000..000331387
--- /dev/null
+++ b/test/test/test_rawdev.c
@@ -0,0 +1,376 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#include <rte_common.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_dev.h>
+#include <rte_rawdev.h>
+#include <rte_bus_vdev.h>
+
+#include "test.h"
+
+/* Using relative path as skeleton_rawdev is not part of exported headers */
+#include "../../drivers/raw/skeleton_rawdev/skeleton_rawdev.h"
+
+#define TEST_DEV_ID   0
+#define TEST_DEV_NAME "rawdev_skeleton"
+
+static int
+testsuite_setup(void)
+{
+	uint8_t count;
+	count = rte_rawdev_count();
+	if (!count) {
+		printf("\tNo existing rawdev; Creating 'skeldev_rawdev'\n");
+		return rte_vdev_init(TEST_DEV_NAME, NULL);
+	}
+
+	return TEST_SUCCESS;
+}
+
+static void local_teardown(void);
+
+static void
+testsuite_teardown(void)
+{
+	local_teardown();
+}
+
+static void
+local_teardown(void)
+{
+	rte_vdev_uninit(TEST_DEV_NAME);
+}
+
+static int
+test_rawdev_count(void)
+{
+	uint8_t count;
+	count = rte_rawdev_count();
+	TEST_ASSERT(count > 0, "Invalid rawdev count %" PRIu8, count);
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_get_dev_id(void)
+{
+	int ret;
+	ret = rte_rawdev_get_dev_id("invalid_rawdev_device");
+	TEST_ASSERT_FAIL(ret, "Expected <0 for invalid dev name ret=%d", ret);
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_socket_id(void)
+{
+	int socket_id;
+	socket_id = rte_rawdev_socket_id(TEST_DEV_ID);
+	TEST_ASSERT(socket_id != -EINVAL, "Failed to get socket_id %d",
+				socket_id);
+	socket_id = rte_rawdev_socket_id(RTE_RAWDEV_MAX_DEVS);
+	TEST_ASSERT(socket_id == -EINVAL, "Expected -EINVAL %d", socket_id);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_info_get(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf skel_conf = {0};
+
+	ret = rte_rawdev_info_get(TEST_DEV_ID, NULL);
+	TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
+
+	rdev_info.dev_private = &skel_conf;
+
+	ret = rte_rawdev_info_get(TEST_DEV_ID, &rdev_info);
+	TEST_ASSERT_SUCCESS(ret, "Failed to get raw dev info");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_configure(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_set = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+
+	/* Check invalid configuration */
+	ret = rte_rawdev_configure(TEST_DEV_ID, NULL);
+	TEST_ASSERT(ret == -EINVAL, "Null configure; Expected -EINVAL, got %d",
+		    ret);
+
+	/* Valid configuration test */
+	rdev_conf_set.num_queues = 1;
+	rdev_conf_set.capabilities = SKELETON_CAPA_FW_LOAD |
+				     SKELETON_CAPA_FW_RESET;
+
+	rdev_info.dev_private = &rdev_conf_set;
+	ret = rte_rawdev_configure(TEST_DEV_ID,
+				   (rte_rawdev_obj_t)&rdev_info);
+	TEST_ASSERT_SUCCESS(ret, "Failed to configure rawdev (%d)", ret);
+
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)",
+			    ret);
+
+	TEST_ASSERT_EQUAL(rdev_conf_set.num_queues, rdev_conf_get.num_queues,
+			  "Configuration test failed; num_queues (%d)(%d)",
+			  rdev_conf_set.num_queues, rdev_conf_get.num_queues);
+	TEST_ASSERT_EQUAL(rdev_conf_set.capabilities,
+			  rdev_conf_get.capabilities,
+			  "Configuration test failed; capabilities");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_queue_default_conf_get(void)
+{
+	int ret, i;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+	struct skeleton_rawdev_queue q = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)",
+			    ret);
+
+	/* call to test_rawdev_configure would have set the num_queues = 1 */
+	TEST_ASSERT_SUCCESS(!(rdev_conf_get.num_queues > 0),
+			    "Invalid number of queues (%d). Expected 1",
+			    rdev_conf_get.num_queues);
+	/* All queues by default should have state = DETACH and
+	 * depth = DEF_DEPTH
+	 */
+	for (i = 0; i < rdev_conf_get.num_queues; i++) {
+		rte_rawdev_queue_conf_get(TEST_DEV_ID, i, &q);
+		TEST_ASSERT_EQUAL(q.depth, SKELETON_QUEUE_DEF_DEPTH,
+				  "Invalid default depth of queue (%d)",
+				  q.depth);
+		TEST_ASSERT_EQUAL(q.state, SKELETON_QUEUE_DETACH,
+				  "Invalid default state of queue (%d)",
+				  q.state);
+	}
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_queue_setup(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+	struct skeleton_rawdev_queue qset = {0};
+	struct skeleton_rawdev_queue qget = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)",
+			    ret);
+
+	/* call to test_rawdev_configure would have set the num_queues = 1 */
+	TEST_ASSERT_SUCCESS(!(rdev_conf_get.num_queues > 0),
+			    "Invalid number of queues (%d). Expected 1",
+			    rdev_conf_get.num_queues);
+
+	/* Modify the queue depth for Queue 0 and attach it */
+	qset.depth = 15;
+	qset.state = SKELETON_QUEUE_ATTACH;
+	ret = rte_rawdev_queue_setup(TEST_DEV_ID, 0, &qset);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup queue (%d)", ret);
+
+	/* Now, fetching the queue 0 should show depth as 15 */
+	ret = rte_rawdev_queue_conf_get(TEST_DEV_ID, 0, &qget);
+	TEST_ASSERT_SUCCESS(ret, "Failed to get queue config (%d)", ret);
+
+	TEST_ASSERT_EQUAL(qset.depth, qget.depth,
+			  "Failed to set queue depth: Need(%d), has(%d)",
+			  qset.depth, qget.depth);
+
+	return TEST_SUCCESS;
+}
+
+/* After executing test_rawdev_queue_setup, queue_id=0 would have depth as 15.
+ * Releasing should set it back to default. state would set to DETACH
+ */
+static int
+test_rawdev_queue_release(void)
+{
+	int ret;
+	struct skeleton_rawdev_queue qget = {0};
+
+	/* Now, fetching the queue 0 should show depth as 100 */
+	ret = rte_rawdev_queue_release(TEST_DEV_ID, 0);
+	TEST_ASSERT_SUCCESS(ret, "Failed to release queue 0; (%d)", ret);
+
+	/* Now, fetching the queue 0 should show depth as default */
+	ret = rte_rawdev_queue_conf_get(TEST_DEV_ID, 0, &qget);
+	TEST_ASSERT_SUCCESS(ret, "Failed to get queue config (%d)", ret);
+
+	TEST_ASSERT_EQUAL(qget.depth, SKELETON_QUEUE_DEF_DEPTH,
+			  "Release of Queue 0 failed; (depth)");
+
+	TEST_ASSERT_EQUAL(qget.state, SKELETON_QUEUE_DETACH,
+			  "Release of Queue 0 failed; (state)");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_attr_set_get(void)
+{
+	int ret;
+	int *dummy_value;
+	uint64_t ret_value;
+
+	/* Set an attribute and fetch it */
+	ret = rte_rawdev_set_attr(TEST_DEV_ID, "Test1", 100);
+	TEST_ASSERT(!ret, "Unable to set an attribute (Test1)");
+
+	dummy_value = malloc(sizeof(int));
+	if (!dummy_value)
+		TEST_ASSERT(1, "Unable to allocate memory (dummy_value)");
+
+	*dummy_value = 200;
+	ret = rte_rawdev_set_attr(TEST_DEV_ID, "Test2", (uint64_t)dummy_value);
+
+	/* Check if attributes have been set */
+	ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test1", &ret_value);
+	TEST_ASSERT_EQUAL(ret_value, 100,
+		"Attribute (Test1) not set correctly (%lu)", ret_value);
+
+	ret_value = 0;
+	ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test2", &ret_value);
+	TEST_ASSERT_EQUAL(*((int *)ret_value), 200,
+		"Attribute (Test2) not set correctly (%lu)", ret_value);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_start_stop(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+
+	rte_rawdev_start(TEST_DEV_ID);
+	ret = rte_rawdev_info_get(TEST_DEV_ID, (rte_rawdev_obj_t)&rdev_info);
+	TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)",
+			    ret);
+	TEST_ASSERT_EQUAL(rdev_conf_get.device_state, SKELETON_DEV_RUNNING,
+			  "Device start failed. State is (%d)",
+			  rdev_conf_get.device_state);
+
+	rte_rawdev_stop(TEST_DEV_ID);
+	ret = rte_rawdev_info_get(TEST_DEV_ID, (rte_rawdev_obj_t)&rdev_info);
+	TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)",
+			    ret);
+	TEST_ASSERT_EQUAL(rdev_conf_get.device_state, SKELETON_DEV_STOPPED,
+			  "Device stop failed. State is (%d)",
+			  rdev_conf_get.device_state);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_enqdeq(void)
+{
+	int ret;
+	unsigned int count = 1;
+	uint16_t queue_id = 0;
+	struct rte_rawdev_buf buffers[1];
+	struct rte_rawdev_buf *deq_buffers;
+
+	buffers[0].buf_addr = malloc(strlen(TEST_DEV_NAME) + 3);
+	if (!buffers[0].buf_addr)
+		goto cleanup;
+	snprintf(buffers[0].buf_addr, strlen(TEST_DEV_NAME) + 2, "%s%d",
+		 TEST_DEV_NAME, 0);
+
+	ret = rte_rawdev_enqueue_buffers(TEST_DEV_ID,
+					 (struct rte_rawdev_buf **)&buffers,
+					 count, &queue_id);
+	TEST_ASSERT_EQUAL((unsigned int)ret, count,
+			  "Unable to enqueue buffers");
+
+	deq_buffers = malloc(sizeof(struct rte_rawdev_buf) * count);
+	if (!deq_buffers)
+		goto cleanup;
+
+	ret = rte_rawdev_dequeue_buffers(TEST_DEV_ID,
+					(struct rte_rawdev_buf **)&deq_buffers,
+					count, &queue_id);
+	TEST_ASSERT_EQUAL((unsigned int)ret, count,
+			  "Unable to dequeue buffers");
+
+	if (deq_buffers)
+		free(deq_buffers);
+
+	return TEST_SUCCESS;
+cleanup:
+	if (buffers[0].buf_addr)
+		free(buffers[0].buf_addr);
+	if (deq_buffers)
+		free(deq_buffers);
+
+	return TEST_FAILED;
+}
+
+static struct unit_test_suite rawdev_testsuite  = {
+	.suite_name = "rawdev code unit tests",
+	.setup = testsuite_setup,
+	.teardown = testsuite_teardown,
+	.unit_test_cases = {
+		TEST_CASE_ST(NULL, NULL,
+			test_rawdev_count),
+		TEST_CASE_ST(NULL, NULL,
+			test_rawdev_get_dev_id),
+		TEST_CASE_ST(NULL, NULL,
+			test_rawdev_socket_id),
+		TEST_CASE_ST(NULL, NULL,
+			test_rawdev_info_get),
+		TEST_CASE_ST(NULL, NULL,
+			test_rawdev_configure),
+		TEST_CASE_ST(test_rawdev_configure, NULL,
+			test_rawdev_queue_default_conf_get),
+		TEST_CASE_ST(test_rawdev_configure, NULL,
+			test_rawdev_queue_setup),
+		TEST_CASE_ST(test_rawdev_queue_setup, NULL,
+			test_rawdev_queue_release),
+		TEST_CASE_ST(NULL, NULL,
+			test_rawdev_attr_set_get),
+		TEST_CASE_ST(NULL, NULL,
+			test_rawdev_start_stop),
+		TEST_CASE_ST(test_rawdev_queue_setup, NULL,
+			test_rawdev_enqdeq),
+		TEST_CASES_END() /**< NULL terminate unit test array */
+	}
+};
+
+static int
+test_rawdev(void)
+{
+	return unit_test_suite_runner(&rawdev_testsuite);
+}
+
+REGISTER_TEST_COMMAND(rawdev_autotest, test_rawdev);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 1/5] rawdev: introduce raw device library support
  2018-01-02 12:57 ` [PATCH v1 1/5] rawdev: introduce raw device library support Shreyansh Jain
@ 2018-01-06 13:40   ` Trahe, Fiona
  2018-01-08 14:09     ` Shreyansh Jain
  2018-01-14 22:42   ` Thomas Monjalon
  2018-01-14 22:50   ` Thomas Monjalon
  2 siblings, 1 reply; 67+ messages in thread
From: Trahe, Fiona @ 2018-01-06 13:40 UTC (permalink / raw)
  To: hemant.agrawal, Xu, Rosen, Shreyansh Jain, dev; +Cc: Trahe, Fiona

Hi Shreyansh,

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

> -----Original Message-----
> From: Shreyansh Jain [mailto:shreyansh.jain@nxp.com]
> Sent: Tuesday, January 2, 2018 12:58 PM
> To: dev@dpdk.org
> Cc: hemant.agrawal@nxp.com; Trahe, Fiona <fiona.trahe@intel.com>; Xu, Rosen <rosen.xu@intel.com>;
> Shreyansh Jain <shreyansh.jain@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@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

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 1/5] rawdev: introduce raw device library support
  2018-01-06 13:40   ` Trahe, Fiona
@ 2018-01-08 14:09     ` Shreyansh Jain
  2018-01-08 14:51       ` Trahe, Fiona
  0 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-08 14:09 UTC (permalink / raw)
  To: Trahe, Fiona; +Cc: Hemant Agrawal, Xu, Rosen, dev

Hello Fiona,

On Saturday 06 January 2018 07:10 PM, Trahe, Fiona wrote:
> Hi Shreyansh,
> 
> This looks like a useful generic device, thanks. Some comments below.

Thanks for taking interest and sending your review.
I have some responses inline....
(And I have shortened the original email)

[...]

>> +#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?

This is a stupid mistake by me. It should be only RTE_RAWDEV_MAX_DEVS.
RTE_MAX_RAWDEVS is useless and I will remove RTE_MAX_RAWDEVPORTS.
They are intend the same thing - number of max devices supported.

>   

[...]

>> +
>> +/**
>> + * 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.

Indeed. Thanks for pointing out.
I will fix this.

> 
>> +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

[...]

>> +
>> +/**
>> + * 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?

let me state what I have understood:

There are two types of devices:
1. which are scanned through a bus (PCI ...)
2. which are created through vdev (devargs, vdev_init)

for those which are scanned through a bus, it is easy to append a 
"type_" string during device naming.
for those which are added through command line, this pattern would have 
to be choosen by the application/user.

further, a rawdevice doesn't have a specific type. So, type would be 
purely be defined by the driver (scan) or the device name itself 
(vdev_init).

So, eventually the "type_" field would be left out for driver or 
application to decide. framework (lib/librte_rawdev) would never 
override/append to it.

Is this understanding correct?

I will send a v2 shortly with your comments. I will also try and think 
through your suggestion about name containing "type_" - I do think it is 
useful but not really sure how would it define semantics between driver 
and application.

-
Shreyansh

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 1/5] rawdev: introduce raw device library support
  2018-01-08 14:09     ` Shreyansh Jain
@ 2018-01-08 14:51       ` Trahe, Fiona
  2018-01-12 15:00         ` Shreyansh Jain
  0 siblings, 1 reply; 67+ messages in thread
From: Trahe, Fiona @ 2018-01-08 14:51 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: Hemant Agrawal, Xu, Rosen, dev, Trahe, Fiona



> -----Original Message-----
> From: Shreyansh Jain [mailto:shreyansh.jain@nxp.com]
> Sent: Monday, January 8, 2018 2:10 PM
> To: Trahe, Fiona <fiona.trahe@intel.com>
> Cc: Hemant Agrawal <hemant.agrawal@nxp.com>; Xu, Rosen <rosen.xu@intel.com>; dev@dpdk.org
> Subject: Re: [PATCH v1 1/5] rawdev: introduce raw device library support
> 
> Hello Fiona,
> 
> On Saturday 06 January 2018 07:10 PM, Trahe, Fiona wrote:
> > Hi Shreyansh,
> >
> > This looks like a useful generic device, thanks. Some comments below.
> 
> Thanks for taking interest and sending your review.
> I have some responses inline....
> (And I have shortened the original email)
> 
> [...]
> 
> >> +#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?
> 
> This is a stupid mistake by me. It should be only RTE_RAWDEV_MAX_DEVS.
> RTE_MAX_RAWDEVS is useless and I will remove RTE_MAX_RAWDEVPORTS.
> They are intend the same thing - number of max devices supported.
> 
> >
> 
> [...]
> 
> >> +
> >> +/**
> >> + * 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.
> 
> Indeed. Thanks for pointing out.
> I will fix this.
> 
> >
> >> +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
> 
> [...]
> 
> >> +
> >> +/**
> >> + * 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?
> 
> let me state what I have understood:
> 
> There are two types of devices:
> 1. which are scanned through a bus (PCI ...)
> 2. which are created through vdev (devargs, vdev_init)
> 
> for those which are scanned through a bus, it is easy to append a
> "type_" string during device naming.
> for those which are added through command line, this pattern would have
> to be choosen by the application/user.
> 
> further, a rawdevice doesn't have a specific type. So, type would be
> purely be defined by the driver (scan) or the device name itself
> (vdev_init).
> 
> So, eventually the "type_" field would be left out for driver or
> application to decide. framework (lib/librte_rawdev) would never
> override/append to it.
> 
> Is this understanding correct?
[Fiona] Yes. I'm probably overcomplicating it. 
I was considering scanned devices and e.g. a case where 2 PMDs inadvertently pick the same name.
One idea would be each driver would register a type string with the lib layer and 
all its device names must start with this, thus ensuring that each device name is unique.
With the vdev devices the application can ensure device names are unique.
A driver would not be allowed to use a name starting with a string which another PMD had already registered.

This would allow looser coupling between the applications and the PMDs, as applications 
would not need to know the exact name format of device name, just know the type it wants to use
and search for all devices with names starting with that string.
But I'm probably anticipating issues which wouldn't happen in real world applications. 
i.e. though there may be many PMDs and applications in the dpdk codebase using this lib in future, 
it's likely only a small number will be compiled into any build so such name clashes are unlikely to occur.
And the applications must be tightly coupled with the PMD anyway to make use of the device, so
that's probably not a concern either.

> 
> I will send a v2 shortly with your comments. I will also try and think
> through your suggestion about name containing "type_" - I do think it is
> useful but not really sure how would it define semantics between driver
> and application.
> 
> -
> Shreyansh

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 1/5] rawdev: introduce raw device library support
  2018-01-08 14:51       ` Trahe, Fiona
@ 2018-01-12 15:00         ` Shreyansh Jain
  2018-01-12 19:35           ` Trahe, Fiona
  0 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-12 15:00 UTC (permalink / raw)
  To: Trahe, Fiona; +Cc: Hemant Agrawal, Xu, Rosen, dev

Hello Fiona,

Apologies for delay in my response.
Some comments inline...

On Monday 08 January 2018 08:21 PM, Trahe, Fiona wrote:
> 
> 
>> -----Original Message-----
>> From: Shreyansh Jain [mailto:shreyansh.jain@nxp.com]
>> Sent: Monday, January 8, 2018 2:10 PM
>> To: Trahe, Fiona <fiona.trahe@intel.com>
>> Cc: Hemant Agrawal <hemant.agrawal@nxp.com>; Xu, Rosen <rosen.xu@intel.com>; dev@dpdk.org
>> Subject: Re: [PATCH v1 1/5] rawdev: introduce raw device library support
>>
>> Hello Fiona,
>>
>> On Saturday 06 January 2018 07:10 PM, Trahe, Fiona wrote:
>>> Hi Shreyansh,
>>>
>>> This looks like a useful generic device, thanks. Some comments below.
>>
>> Thanks for taking interest and sending your review.
>> I have some responses inline....
>> (And I have shortened the original email)
>>
>> [...]
>>
>>>> +#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?
>>
>> This is a stupid mistake by me. It should be only RTE_RAWDEV_MAX_DEVS.
>> RTE_MAX_RAWDEVS is useless and I will remove RTE_MAX_RAWDEVPORTS.
>> They are intend the same thing - number of max devices supported.
>>
>>>
>>
>> [...]
>>
>>>> +
>>>> +/**
>>>> + * 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.
>>
>> Indeed. Thanks for pointing out.
>> I will fix this.
>>
>>>
>>>> +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
>>
>> [...]
>>
>>>> +
>>>> +/**
>>>> + * 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?
>>
>> let me state what I have understood:
>>
>> There are two types of devices:
>> 1. which are scanned through a bus (PCI ...)
>> 2. which are created through vdev (devargs, vdev_init)
>>
>> for those which are scanned through a bus, it is easy to append a
>> "type_" string during device naming.
>> for those which are added through command line, this pattern would have
>> to be choosen by the application/user.
>>
>> further, a rawdevice doesn't have a specific type. So, type would be
>> purely be defined by the driver (scan) or the device name itself
>> (vdev_init).
>>
>> So, eventually the "type_" field would be left out for driver or
>> application to decide. framework (lib/librte_rawdev) would never
>> override/append to it.
>>
>> Is this understanding correct?
> [Fiona] Yes. I'm probably overcomplicating it.
> I was considering scanned devices and e.g. a case where 2 PMDs inadvertently pick the same name.
> One idea would be each driver would register a type string with the lib layer and
> all its device names must start with this, thus ensuring that each device name is unique.
> With the vdev devices the application can ensure device names are unique.
> A driver would not be allowed to use a name starting with a string which another PMD had already registered.
> 
> This would allow looser coupling between the applications and the PMDs, as applications
> would not need to know the exact name format of device name, just know the type it wants to use
> and search for all devices with names starting with that string.
> But I'm probably anticipating issues which wouldn't happen in real world applications.
> i.e. though there may be many PMDs and applications in the dpdk codebase using this lib in future,
> it's likely only a small number will be compiled into any build so such name clashes are unlikely to occur.
> And the applications must be tightly coupled with the PMD anyway to make use of the device, so
> that's probably not a concern either.
I agree with the last line that applications have to be tightly coupled 
with PMD in this case. That defines (or prevents defining) a lot of 
semantics.

While creating the patches, even I was thinking of standardizing the 
naming (taking hint from some of Gaetan's work on devargs) but I 
couldn't think of a policy which can be enforced only by the rawlib.

I concur with you that conflicting naming in a real world scenario is 
theoretically possible, irrespective of how rare it might be.

I suggest that we continue as is and expand this in future when we have 
more clarity or even some real-world application samples.

You have any objections to this?

> 
>>
>> I will send a v2 shortly with your comments. I will also try and think
>> through your suggestion about name containing "type_" - I do think it is
>> useful but not really sure how would it define semantics between driver
>> and application.
>>
>> -
>> Shreyansh

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 1/5] rawdev: introduce raw device library support
  2018-01-12 15:00         ` Shreyansh Jain
@ 2018-01-12 19:35           ` Trahe, Fiona
  0 siblings, 0 replies; 67+ messages in thread
From: Trahe, Fiona @ 2018-01-12 19:35 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: Hemant Agrawal, Xu, Rosen, dev, Trahe, Fiona

Hi Shreyansh,

/// snip ///
> > [Fiona] Yes. I'm probably overcomplicating it.
> > I was considering scanned devices and e.g. a case where 2 PMDs inadvertently pick the same name.
> > One idea would be each driver would register a type string with the lib layer and
> > all its device names must start with this, thus ensuring that each device name is unique.
> > With the vdev devices the application can ensure device names are unique.
> > A driver would not be allowed to use a name starting with a string which another PMD had already
> registered.
> >
> > This would allow looser coupling between the applications and the PMDs, as applications
> > would not need to know the exact name format of device name, just know the type it wants to use
> > and search for all devices with names starting with that string.
> > But I'm probably anticipating issues which wouldn't happen in real world applications.
> > i.e. though there may be many PMDs and applications in the dpdk codebase using this lib in future,
> > it's likely only a small number will be compiled into any build so such name clashes are unlikely to occur.
> > And the applications must be tightly coupled with the PMD anyway to make use of the device, so
> > that's probably not a concern either.
> I agree with the last line that applications have to be tightly coupled
> with PMD in this case. That defines (or prevents defining) a lot of
> semantics.
> 
> While creating the patches, even I was thinking of standardizing the
> naming (taking hint from some of Gaetan's work on devargs) but I
> couldn't think of a policy which can be enforced only by the rawlib.
> 
> I concur with you that conflicting naming in a real world scenario is
> theoretically possible, irrespective of how rare it might be.
> 
> I suggest that we continue as is and expand this in future when we have
> more clarity or even some real-world application samples.
> 
> You have any objections to this?
> 
No, I agree, this is the best approach.

Fiona


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 1/5] rawdev: introduce raw device library support
  2018-01-02 12:57 ` [PATCH v1 1/5] rawdev: introduce raw device library support Shreyansh Jain
  2018-01-06 13:40   ` Trahe, Fiona
@ 2018-01-14 22:42   ` Thomas Monjalon
  2018-01-14 22:50   ` Thomas Monjalon
  2 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-14 22:42 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

Hi,

02/01/2018 13:57, Shreyansh Jain:
> A device is DPDK has a flavor to it - ethernet, crypto, event etc.

I don't understand this sentence.
I guess it can be completely removed.

> 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.

You should explain that it uses some opaque pointers.

> Signed-off-by: Shreyansh Jain <shreyansh.jain@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 ++

Please add an entry in MAINTAINERS with EXPERIMENTAL tag.

Sorry, no time to review the code myself.

Thanks

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 1/5] rawdev: introduce raw device library support
  2018-01-02 12:57 ` [PATCH v1 1/5] rawdev: introduce raw device library support Shreyansh Jain
  2018-01-06 13:40   ` Trahe, Fiona
  2018-01-14 22:42   ` Thomas Monjalon
@ 2018-01-14 22:50   ` Thomas Monjalon
  2 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-14 22:50 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

02/01/2018 13:57, Shreyansh Jain:
> --- /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: *;
> +};

It may be more pleasant to review, and more convenient to reference
in the git history later, if it is a bit split in patches.
If possible, I would suggest to split dequeue/enqueue, firmware
and stats in 3 separate patches after the basic skeleton.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 2/5] config: enable compilation of rawdev library
  2018-01-02 12:57 ` [PATCH v1 2/5] config: enable compilation of rawdev library Shreyansh Jain
@ 2018-01-14 22:50   ` Thomas Monjalon
  0 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-14 22:50 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

02/01/2018 13:57, Shreyansh Jain:
> Add config option CONFIG_RTE_LIBRTE_RAWDEV for toggling rawdev
> library support. This patch also enables compilation of the library.
> 
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> ---
>  config/common_base | 7 +++++++
>  lib/Makefile       | 3 +++
>  mk/rte.app.mk      | 1 +
>  3 files changed, 11 insertions(+)

Please merge this patch with the first one (skeleton).

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 3/5] drivers/raw: introduce skeleton rawdev driver
  2018-01-02 12:57 ` [PATCH v1 3/5] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
@ 2018-01-14 22:54   ` Thomas Monjalon
  2018-01-16 10:21     ` Shreyansh Jain
  0 siblings, 1 reply; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-14 22:54 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

02/01/2018 13:57, Shreyansh Jain:
> +struct skeleton_firmware {
> +	struct skeleton_firmware_version_info firmware_version;
> +	/**< Device firmware information */
> +	enum skeleton_firmware_state firmware_state;
> +	/**< Device state */
> +};
> +
> +#define SKELETON_MAX_ATTRIBUTES 10
> +#define SKELETON_ATTRIBUTE_NAME_MAX 20
> +
> +struct skeleton_rawdev_attributes {
> +	char *name;
> +	/**< Name of the attribute */
> +	uint64_t value;
> +	/**< Value or reference of value of attribute */
> +};
> +
> +#define SKELETON_CAPA_FW_LOAD	0x0001
> +/**< Device supports firmware loading/unloading */
> +#define SKELETON_CAPA_FW_RESET  0x0002
> +/**< Device supports firmware reset */
> +#define SKELETON_CAPA_QUEUES    0x0004
> +/**< Device support queue based communication */

Comment about the style. The style is important :)
You are always writing comments after the item.
When comments are on a separate line, I think it is preferred to write
them *before* the item they describe.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 4/5] config: enable compilation of rawdev skeleton driver
  2018-01-02 12:57 ` [PATCH v1 4/5] config: enable compilation of rawdev skeleton driver Shreyansh Jain
@ 2018-01-14 22:55   ` Thomas Monjalon
  0 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-14 22:55 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

02/01/2018 13:57, Shreyansh Jain:
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> ---
>  config/common_base | 1 +
>  drivers/Makefile   | 2 ++
>  mk/rte.app.mk      | 4 ++++
>  3 files changed, 7 insertions(+)

Please merge it with the previous patch.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 5/5] test: support for rawdev testcases
  2018-01-02 12:57 ` [PATCH v1 5/5] test: support for rawdev testcases Shreyansh Jain
@ 2018-01-14 22:58   ` Thomas Monjalon
  2018-01-16 10:07     ` Shreyansh Jain
  0 siblings, 1 reply; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-14 22:58 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

02/01/2018 13:57, Shreyansh Jain:
> Patch introduces rawdev unit testcase for validation against the
> Skeleton rawdev dummy PMD implementation.
> 
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> ---
>  test/test/Makefile      |   4 +
>  test/test/test_rawdev.c | 376 ++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 380 insertions(+)

As it is being done for test_eventdev_octeontx.c, I think it is
a good idea to move the PMD unit tests in the PMD directory.
Please check the patches from Pavan, applied in dpdk-next-eventdev.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 0/5] Introduce generic 'rawdevice' support
  2018-01-02 12:57 [PATCH v1 0/5] Introduce generic 'rawdevice' support Shreyansh Jain
                   ` (4 preceding siblings ...)
  2018-01-02 12:57 ` [PATCH v1 5/5] test: support for rawdev testcases Shreyansh Jain
@ 2018-01-14 23:00 ` Thomas Monjalon
  2018-01-15  5:30   ` Shreyansh Jain
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
  6 siblings, 1 reply; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-14 23:00 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

02/01/2018 13:57, Shreyansh Jain:
> This patchset introduces rawdevices or generic device support in DPDK.

This new library has no impact on the existing code,
so it may be integrated later in 18.02-rc2.
It will give you a bit more time for the last details.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 0/5] Introduce generic 'rawdevice' support
  2018-01-14 23:00 ` [PATCH v1 0/5] Introduce generic 'rawdevice' support Thomas Monjalon
@ 2018-01-15  5:30   ` Shreyansh Jain
  0 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-15  5:30 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Hemant Agrawal, fiona.trahe, rosen.xu

Hi Thomas,

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Monday, January 15, 2018 4:31 AM
> To: Shreyansh Jain <shreyansh.jain@nxp.com>
> Cc: dev@dpdk.org; Hemant Agrawal <hemant.agrawal@nxp.com>;
> fiona.trahe@intel.com; rosen.xu@intel.com
> Subject: Re: [dpdk-dev] [PATCH v1 0/5] Introduce generic 'rawdevice' support
> 
> 02/01/2018 13:57, Shreyansh Jain:
> > This patchset introduces rawdevices or generic device support in DPDK.
> 
> This new library has no impact on the existing code,
> so it may be integrated later in 18.02-rc2.
> It will give you a bit more time for the last details.

I will push v2 of the series very soon with some changes including:
1. checkpatch comments
2. Some comments/fixes suggested by Fiona and you
3. Patch restructuring as suggested by you
4. My internal review comments.

Thanks for taking out time to review (even if partially).

-
Shreyansh

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 5/5] test: support for rawdev testcases
  2018-01-14 22:58   ` Thomas Monjalon
@ 2018-01-16 10:07     ` Shreyansh Jain
  2018-01-16 10:32       ` Thomas Monjalon
  0 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-16 10:07 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

On Monday 15 January 2018 04:28 AM, Thomas Monjalon wrote:
> 02/01/2018 13:57, Shreyansh Jain:
>> Patch introduces rawdev unit testcase for validation against the
>> Skeleton rawdev dummy PMD implementation.
>>
>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>> ---
>>   test/test/Makefile      |   4 +
>>   test/test/test_rawdev.c | 376 ++++++++++++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 380 insertions(+)
> 
> As it is being done for test_eventdev_octeontx.c, I think it is
> a good idea to move the PMD unit tests in the PMD directory.
> Please check the patches from Pavan, applied in dpdk-next-eventdev.
> 
> 

I saw the changes done by Pavan in eventdev-next.

Issue I see here is that rte_test.h is currently in eventdev tree. That 
would mean either I don't use those macros, or use it with this series 
as dependency on master absorbing eventdev-next in near rc.

I am assuming that post rc1 rte_test.h would be in master and thus it 
would be OK to apply this series over it during rc2. Is it OK with you?

-
Shreyansh

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 3/5] drivers/raw: introduce skeleton rawdev driver
  2018-01-14 22:54   ` Thomas Monjalon
@ 2018-01-16 10:21     ` Shreyansh Jain
  2018-01-16 10:34       ` Thomas Monjalon
  0 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-16 10:21 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

On Monday 15 January 2018 04:24 AM, Thomas Monjalon wrote:
> 02/01/2018 13:57, Shreyansh Jain:
>> +struct skeleton_firmware {
>> +	struct skeleton_firmware_version_info firmware_version;
>> +	/**< Device firmware information */
>> +	enum skeleton_firmware_state firmware_state;
>> +	/**< Device state */
>> +};
>> +
>> +#define SKELETON_MAX_ATTRIBUTES 10
>> +#define SKELETON_ATTRIBUTE_NAME_MAX 20
>> +
>> +struct skeleton_rawdev_attributes {
>> +	char *name;
>> +	/**< Name of the attribute */
>> +	uint64_t value;
>> +	/**< Value or reference of value of attribute */
>> +};
>> +
>> +#define SKELETON_CAPA_FW_LOAD	0x0001
>> +/**< Device supports firmware loading/unloading */
>> +#define SKELETON_CAPA_FW_RESET  0x0002
>> +/**< Device supports firmware reset */
>> +#define SKELETON_CAPA_QUEUES    0x0004
>> +/**< Device support queue based communication */
> 
> Comment about the style. The style is important :)
> You are always writing comments after the item.

Yes, I was trying to stick to single method - postfix.

> When comments are on a separate line, I think it is preferred to write
> them *before* the item they describe.
> 

Consider this:

struct dummy {
     int a;  /**< a postfix comment */
     /**< a prefix comment */
     int b;
};

Personally, Even I prefer prefix when it comes to full line comments - 
but mixing prefix and postfix can lead to non-readable code.

Anyways - I was referring [1]

[1] 
http://dpdk.org/doc/guides/contributing/documentation.html#doxygen-guidelines

and it seems that I should change all to prefix in case any comment in 
the structure is not fitting into a single line.
I will do that.

Regards,
Shreyansh

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 5/5] test: support for rawdev testcases
  2018-01-16 10:07     ` Shreyansh Jain
@ 2018-01-16 10:32       ` Thomas Monjalon
  0 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-16 10:32 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

16/01/2018 11:07, Shreyansh Jain:
> On Monday 15 January 2018 04:28 AM, Thomas Monjalon wrote:
> > 02/01/2018 13:57, Shreyansh Jain:
> >> Patch introduces rawdev unit testcase for validation against the
> >> Skeleton rawdev dummy PMD implementation.
> >>
> >> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> >> ---
> >>   test/test/Makefile      |   4 +
> >>   test/test/test_rawdev.c | 376 ++++++++++++++++++++++++++++++++++++++++++++++++
> >>   2 files changed, 380 insertions(+)
> > 
> > As it is being done for test_eventdev_octeontx.c, I think it is
> > a good idea to move the PMD unit tests in the PMD directory.
> > Please check the patches from Pavan, applied in dpdk-next-eventdev.
> > 
> > 
> 
> I saw the changes done by Pavan in eventdev-next.
> 
> Issue I see here is that rte_test.h is currently in eventdev tree. That 
> would mean either I don't use those macros, or use it with this series 
> as dependency on master absorbing eventdev-next in near rc.
> 
> I am assuming that post rc1 rte_test.h would be in master and thus it 
> would be OK to apply this series over it during rc2. Is it OK with you?

Yes, you can assume next-eventdev will be pulled in master.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v1 3/5] drivers/raw: introduce skeleton rawdev driver
  2018-01-16 10:21     ` Shreyansh Jain
@ 2018-01-16 10:34       ` Thomas Monjalon
  0 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-16 10:34 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

16/01/2018 11:21, Shreyansh Jain:
> On Monday 15 January 2018 04:24 AM, Thomas Monjalon wrote:
> > 02/01/2018 13:57, Shreyansh Jain:
> >> +struct skeleton_firmware {
> >> +	struct skeleton_firmware_version_info firmware_version;
> >> +	/**< Device firmware information */
> >> +	enum skeleton_firmware_state firmware_state;
> >> +	/**< Device state */
> >> +};
> >> +
> >> +#define SKELETON_MAX_ATTRIBUTES 10
> >> +#define SKELETON_ATTRIBUTE_NAME_MAX 20
> >> +
> >> +struct skeleton_rawdev_attributes {
> >> +	char *name;
> >> +	/**< Name of the attribute */
> >> +	uint64_t value;
> >> +	/**< Value or reference of value of attribute */
> >> +};
> >> +
> >> +#define SKELETON_CAPA_FW_LOAD	0x0001
> >> +/**< Device supports firmware loading/unloading */
> >> +#define SKELETON_CAPA_FW_RESET  0x0002
> >> +/**< Device supports firmware reset */
> >> +#define SKELETON_CAPA_QUEUES    0x0004
> >> +/**< Device support queue based communication */
> > 
> > Comment about the style. The style is important :)
> > You are always writing comments after the item.
> 
> Yes, I was trying to stick to single method - postfix.
> 
> > When comments are on a separate line, I think it is preferred to write
> > them *before* the item they describe.
> > 
> 
> Consider this:
> 
> struct dummy {
>      int a;  /**< a postfix comment */
>      /**< a prefix comment */
>      int b;
> };
> 
> Personally, Even I prefer prefix when it comes to full line comments - 
> but mixing prefix and postfix can lead to non-readable code.
> 
> Anyways - I was referring [1]
> 
> [1] 
> http://dpdk.org/doc/guides/contributing/documentation.html#doxygen-guidelines
> 
> and it seems that I should change all to prefix in case any comment in 
> the structure is not fitting into a single line.
> I will do that.

OK thanks

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v2 00/10] Introduce generic 'rawdevice' support
  2018-01-02 12:57 [PATCH v1 0/5] Introduce generic 'rawdevice' support Shreyansh Jain
                   ` (5 preceding siblings ...)
  2018-01-14 23:00 ` [PATCH v1 0/5] Introduce generic 'rawdevice' support Thomas Monjalon
@ 2018-01-23 13:59 ` Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 01/10] rawdev: introduce raw device library support Shreyansh Jain
                     ` (11 more replies)
  6 siblings, 12 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-23 13:59 UTC (permalink / raw)
  To: fiona.trahe, thomas; +Cc: dev, hemant.agrawal, rosen.xu, Shreyansh Jain

Change History
~~~~~~~~~~~~~~
v2:
 - restructure comments to prefix model
 - split patches pivoted on APIs introduced in library
 - moved test into drivers/rawdev/skeleton from test/test
 - removed unused RTE_MAX_RAWDEVPORTS and RTE_MAX_RAWDEVS
 - merge patch configurations
 - checkpatch fixes

Rawdevice Support in DPDK
-------------------------

RFC [1]
v1: [2]

This patchset introduces rawdevices or generic device support in DPDK.

Motivation
==========

In terms of device flavor (type) support, DPDK currently has ethernet
(lib_ether), cryptodev (libcryptodev), eventdev (libeventdev) and vdev
(virtual device) support.

For a new type of device, for example an accelerator, there are not many
options except either of:
1. create another lib/librte_MySpecialDev, driver/MySpecialDrv and use it
through Bus/PMD model.
2. Or, create a vdev and implement necessary custom APIs which are directly
exposed from driver layer. However this may still require changes in bus code
in DPDK.

Either method is unclean (touching lib for specific context) and possibly
non-upstreamable (custom APIs). Applications and customers prefers uniform
device view and programming model.

Scope
=====

The rawdevice implementation is targetted towards various accelerator use cases
which cannot be generalized within existing device models. Aim is to provided a
generalized structure at the cost of portability guarantee. Specific PMDs may
also expose any specific config APIs. Applications built over such devices are
special use-cases involving IP blocks.

The rawdevice may also connect to other standard devices using adapter or other
methods, similar to eventdev adpter for ethernet/crypto devices.

Proposed Solution
=================

Defining a very generic super-set of device type and its device operations that
can be exposed such that any new/upcoming/experimental device can be layered
over it. 'rawdevice' semantic in this patchset represents a device that doesn't
have any flavor/type associated with it which is advertised (like net, crypto
etc).

A *rte_rawdevice* is a raw/generic device without any standard configuration
or input/output method assumption.

Thus, driver for a new accelerator block, which requires operations for
start/stop/enqueue/dequeue, can be quickly strapped over this rawdevice layer.
Thereafter, any appropriate bus can scan for it (assuming device is discoverable
over the Linux interfaces like sysfs) and match it against registered drivers.

Similarly, for a new accelerator or a wireless device, which doesn't fit the eth
type, a driver can be registered with a bus (on which its device would be
scannable) and use this layer for configuring the device.

It can also serve as a staging area for new type of devices till they find some
commonality and can be standardized.

The outline of this proposed library is same as existing ether/crypto devices.

     +-----------------------------------------------------------+
     |                        Application(s)                     |
     +------------------------------.----------------------------+
                                    |
                                    |
     +------------------------------'----------------------------+
     |                     DPDK Framework (APIs)                 |
     +--------------|----|-----------------|---------------------+
                   /      \                 \
            (crypto ops)  (eth ops)      (rawdev ops)        +----+
            /               \                 \              |DrvA|
     +-----'---+        +----`----+        +---'-----+       +----+
     | crypto  |        | ethdev  |        | raw     |
     +--/------+        +---/-----+        +----/----+       +----+
       /\                __/\                  /   ..........|DrvB|
      /  \              /    \                / ../    \     +----+
  +====+ +====+    +====+ +====+            +==/=+      ```Bus Probe 
  |DevA| |DevB|    |DevC| |DevD|            |DevF|
  +====+ +====+    +====+ +====+            +====+
    |      |        |      |                 |    
  ``|``````|````````|``````|`````````````````|````````Bus Scan
   (PCI)   |       (PCI)  (PCI)            (PCI)
         (BusA)

 * It is assumed above that DrvB is a PCI type driver which registers itself
   with PCI Bus
 * Thereafter, when the PCI scan is done, during probe DrvB would match the
   rawdev DevF ID and take control of device
 * Applications can then continue using the device through rawdev API interfaces

Proposed Interfaces
===================

Following broad API categories are exposed by the rawdevice:

1) Device State Operations (start/stop/reset)
2) Communication Channel setup/teardown (queue)
3) Attribute get/set operations (~ioctls)
4) Enqueue/Dequeue Operations (using opaque buffers)
5) Firmware Operations (Load/unload)

Notes:
For (1), other than standard start/stop, reset has been added extra. This is for
cases where device power cycle has various definitions. Semantics of what
stop->start and what reset would mean are still open-ended.

For (2), though currently `queue` has been used a semantic, it would be possible
in implementation to use this with other methods like internally hosted rte_ring.

For (3), applications can pass on an opaque attribute handle/information which
the driver can act upon.

For (4), aim is to allow applications to post buffers (which can be arbit data)
to the device. It is device's responsibility to interpret and handle the buffer.
It can also be expanded to synchronous and async methods of posting buffer.
That would provide broader use-cases.

For (5), Aim is to allow for most basic device firmware management. In this, as
well as other operations, it is expected that those which are not implemneted
would return ENOTSUP allow the application to fail gracefully.

** following RST files would be added in v3 **
- doc/guides/rawdevs/skeleton_rawdev.rst
- doc/guides/prog_guide/rawdev.rst

Future Work
===========
1. Support for hotplugging and interrupt handling
2. Support for callbacks for enqueue and dequeue of buffers
3. Interfacing with Eth/Crypto/Event type devices for inline offloading

References
==========
[1]: http://dpdk.org/ml/archives/dev/2017-November/081550.html
[2]: http://dpdk.org/ml/archives/dev/2018-January/085121.html

Shreyansh Jain (10):
  rawdev: introduce raw device library support
  rawdev: add attribute get and set support
  rawdev: add buffer stream IO support
  rawdev: support for extended stats
  rawdev: support for firmware management
  rawdev: add self test support
  drivers/raw: introduce skeleton rawdev driver
  drivers/raw: support for rawdev testcases
  test: enable rawdev skeleton test
  maintainers: claim ownership of rawdev

 MAINTAINERS                                        |   6 +
 config/common_base                                 |   8 +
 drivers/Makefile                                   |   2 +
 drivers/raw/Makefile                               |   9 +
 drivers/raw/skeleton_rawdev/Makefile               |  26 +
 .../rte_pmd_skeleton_rawdev_version.map            |   4 +
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      | 754 +++++++++++++++++++++
 drivers/raw/skeleton_rawdev/skeleton_rawdev.h      | 136 ++++
 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c | 431 ++++++++++++
 lib/Makefile                                       |   3 +
 lib/librte_rawdev/Makefile                         |  27 +
 lib/librte_rawdev/rte_rawdev.c                     | 545 +++++++++++++++
 lib/librte_rawdev/rte_rawdev.h                     | 596 ++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h                 | 605 +++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map           |  34 +
 mk/rte.app.mk                                      |   5 +
 test/test/Makefile                                 |   4 +
 test/test/test_rawdev.c                            |  27 +
 18 files changed, 3222 insertions(+)
 create mode 100644 drivers/raw/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.c
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.h
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
 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
 create mode 100644 test/test/test_rawdev.c

-- 
2.14.1

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v2 01/10] rawdev: introduce raw device library support
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
@ 2018-01-23 13:59   ` Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 02/10] rawdev: add attribute get and set support Shreyansh Jain
                     ` (10 subsequent siblings)
  11 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-23 13:59 UTC (permalink / raw)
  To: fiona.trahe, thomas; +Cc: dev, hemant.agrawal, rosen.xu, Shreyansh Jain

Each device in DPDK has a type associated with it - ethernet, crypto,
event etc. This patch introduces 'rawdevice' which is a generic
type of device, not currently handled out-of-the-box by DPDK.

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. Using opaque
data (pointer) as API arguments, library allows a high flexibility
for application and driver implementation.

This patch introduces basic device operations like start, stop, reset,
queue and info support.
Subsequent patches would introduce other operations like buffer
enqueue/dequeue and firmware support.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 config/common_base                       |   7 +
 lib/Makefile                             |   3 +
 lib/librte_rawdev/Makefile               |  27 +++
 lib/librte_rawdev/rte_rawdev.c           | 360 +++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 314 +++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 352 ++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  21 ++
 mk/rte.app.mk                            |   1 +
 8 files changed, 1085 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/config/common_base b/config/common_base
index 170a38939..b8bd25b15 100644
--- a/config/common_base
+++ b/config/common_base
@@ -805,6 +805,13 @@ CONFIG_RTE_LIBRTE_VHOST=n
 CONFIG_RTE_LIBRTE_VHOST_NUMA=n
 CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
 
+#
+# Compile raw device support
+# EXPERIMENTAL: API may change without prior notice
+#
+CONFIG_RTE_LIBRTE_RAWDEV=y
+CONFIG_RTE_RAWDEV_MAX_DEVS=10
+
 #
 # Compile vhost PMD
 # To compile, CONFIG_RTE_LIBRTE_VHOST should be enabled.
diff --git a/lib/Makefile b/lib/Makefile
index 427f34b00..97080a590 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -102,4 +102,7 @@ endif
 DEPDIRS-librte_kni := librte_eal librte_mempool librte_mbuf librte_ether
 DEPDIRS-librte_kni += librte_pci
 
+DIRS-$(CONFIG_RTE_LIBRTE_RAWDEV) += librte_rawdev
+DEPDIRS-librte_rawdev := librte_eal librte_ether
+
 include $(RTE_SDK)/mk/rte.subdir.mk
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..4b89bf07d
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -0,0 +1,360 @@
+/* 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;
+
+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_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);
+}
+
+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_RAWDEV_MAX_DEVS; dev_id++) {
+		if (rte_rawdevs[dev_id].attached ==
+				RTE_RAWDEV_DETACHED)
+			return dev_id;
+	}
+
+	return RTE_RAWDEV_MAX_DEVS;
+}
+
+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_RAWDEV_MAX_DEVS) {
+		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..ef66006f9
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -0,0 +1,314 @@
+/* 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>
+
+/* 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);
+
+/**
+ * Release and deallocate a raw queue from a raw device.
+ *
+ * @param dev_id
+ *   The identifier of the device.
+ * @param queue_id
+ *   The index of the raw queue to release. 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 released.
+ *   - <0: raw queue configuration failed
+ */
+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 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 structure associated with each raw device.
+ * It is a placeholder for PMD specific data, encapsulating only information
+ * related to framework.
+ */
+struct rte_rawdev {
+	/**< Socket ID where memory is allocated */
+	int socket_id;
+	/**< Device ID for this instance */
+	uint16_t dev_id;
+	/**< Functions exported by PMD */
+	const struct rte_rawdev_ops *dev_ops;
+	/**< Device info. supplied during device initialization */
+	struct rte_device *device;
+	/**< Driver info. supplied by probing */
+	const char *driver_name;
+
+	RTE_STD_C11
+	/**< Flag indicating the device is attached */
+	uint8_t attached : 1;
+	/**< Device state: STARTED(1)/STOPPED(0) */
+	uint8_t started : 1;
+
+	/**< PMD-specific private data */
+	rte_rawdev_obj_t dev_private;
+	/**< Device name */
+	char name[RTE_RAWDEV_NAME_MAX_LEN];
+} __rte_cache_aligned;
+
+/** @internal The pool of rte_rawdev structures. */
+extern struct rte_rawdev *rte_rawdevs;
+
+
+struct rte_rawdev_info {
+	/**< Name of driver handling this device */
+	const char *driver_name;
+	/**< Device encapsulation */
+	struct rte_device *device;
+	/**< Socket ID where memory is allocated */
+	int socket_id;
+	/**< PMD-specific private data */
+	rte_rawdev_obj_t dev_private;
+};
+
+struct rte_rawdev_buf {
+	/**< Opaque buffer reference */
+	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);
+
+#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..a5789cf43
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -0,0 +1,352 @@
+/* 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: Can 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 {
+	/**< Number of devices found */
+	uint16_t nb_devs;
+};
+
+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);
+
+/**
+ * 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);
+
+/** Rawdevice operations function pointer table */
+struct rte_rawdev_ops {
+	/**< Get device info. */
+	rawdev_info_get_t dev_info_get;
+	/**< Configure device. */
+	rawdev_configure_t dev_configure;
+	/**< Start device. */
+	rawdev_start_t dev_start;
+	/**< Stop device. */
+	rawdev_stop_t dev_stop;
+	/**< Close device. */
+	rawdev_close_t dev_close;
+	/**< Reset device. */
+	rawdev_reset_t dev_reset;
+
+	/**< Get raw queue configuration. */
+	rawdev_queue_conf_get_t queue_def_conf;
+	/**< Set up an raw queue. */
+	rawdev_queue_setup_t queue_setup;
+	/**< Release an raw queue. */
+	rawdev_queue_release_t queue_release;
+
+	/* Dump internal information */
+	rawdev_dump_t dump;
+};
+
+/**
+ * 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);
+
+/**
+ * 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..64e60d945
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -0,0 +1,21 @@
+EXPERIMENTAL {
+	global:
+
+	rte_rawdev_close;
+	rte_rawdev_configure;
+	rte_rawdev_count;
+	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_rawdevs;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 0169f3f5b..b201e861d 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -105,6 +105,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
+_LDLIBS-$(CONFIG_RTE_LIBRTE_RAWDEV)         += -lrte_rawdev
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 02/10] rawdev: add attribute get and set support
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 01/10] rawdev: introduce raw device library support Shreyansh Jain
@ 2018-01-23 13:59   ` Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 03/10] rawdev: add buffer stream IO support Shreyansh Jain
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-23 13:59 UTC (permalink / raw)
  To: fiona.trahe, thomas; +Cc: dev, hemant.agrawal, rosen.xu, Shreyansh Jain

A rawdevice can have various attributes. This patch introduce support
for transparently setting attribute value or getting current attribute
state. This is done by allowing an opaque set of key and value to be
passed through rawdev library.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           | 28 +++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 43 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 42 +++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  2 ++
 4 files changed, 115 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index 4b89bf07d..427c8a664 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -175,6 +175,34 @@ rte_rawdev_queue_release(uint16_t dev_id, uint16_t queue_id)
 	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_dump(uint16_t dev_id, FILE *f)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index ef66006f9..44a87c01d 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -307,6 +307,49 @@ struct rte_rawdev_buf {
 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);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index a5789cf43..0925d5877 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -262,6 +262,43 @@ typedef int (*rawdev_queue_release_t)(struct rte_rawdev *dev,
  */
 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);
+
 /** Rawdevice operations function pointer table */
 struct rte_rawdev_ops {
 	/**< Get device info. */
@@ -286,6 +323,11 @@ struct rte_rawdev_ops {
 
 	/* Dump internal information */
 	rawdev_dump_t dump;
+
+	/**< Get an attribute managed by the implementation */
+	rawdev_get_attr_t attr_get;
+	/**< Set an attribute managed by the implementation */
+	rawdev_set_attr_t attr_set;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index 64e60d945..d63476e47 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -4,6 +4,7 @@ EXPERIMENTAL {
 	rte_rawdev_close;
 	rte_rawdev_configure;
 	rte_rawdev_count;
+	rte_rawdev_get_attr;
 	rte_rawdev_get_dev_id;
 	rte_rawdev_info_get;
 	rte_rawdev_pmd_allocate;
@@ -12,6 +13,7 @@ EXPERIMENTAL {
 	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;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 03/10] rawdev: add buffer stream IO support
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 01/10] rawdev: introduce raw device library support Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 02/10] rawdev: add attribute get and set support Shreyansh Jain
@ 2018-01-23 13:59   ` Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 04/10] rawdev: support for extended stats Shreyansh Jain
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-23 13:59 UTC (permalink / raw)
  To: fiona.trahe, thomas; +Cc: dev, hemant.agrawal, rosen.xu, Shreyansh Jain

Introduce handlers for raw buffer enqueue and dequeue. A raw buffer
is essentially a void object which is transparently passed via the
library onto the driver.

Using a context field as argument, any arbitrary meta information
can be passed by application to the driver/implementation. This can
be any data on which driver needs to define the operation semantics.
For example, passing along a queue identifier can suggest the driver
the queue context to perform I/O on.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           | 30 +++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 58 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 58 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  2 ++
 4 files changed, 148 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index 427c8a664..0c5204f51 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -203,6 +203,36 @@ rte_rawdev_set_attr(uint16_t dev_id,
 	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)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index 44a87c01d..22f055a40 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -350,6 +350,64 @@ 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);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index 0925d5877..300693f41 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -248,6 +248,58 @@ typedef int (*rawdev_queue_setup_t)(struct rte_rawdev *dev,
 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
  *
@@ -321,6 +373,12 @@ struct rte_rawdev_ops {
 	/**< Release an raw queue. */
 	rawdev_queue_release_t queue_release;
 
+	/**< Enqueue an array of raw buffers to device. */
+	rawdev_enqueue_bufs_t enqueue_bufs;
+	/**< Dequeue an array of raw buffers from device. */
+	/** TODO: Callback based enqueue and dequeue support */
+	rawdev_dequeue_bufs_t dequeue_bufs;
+
 	/* Dump internal information */
 	rawdev_dump_t dump;
 
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index d63476e47..bafe2c5de 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -4,6 +4,8 @@ EXPERIMENTAL {
 	rte_rawdev_close;
 	rte_rawdev_configure;
 	rte_rawdev_count;
+	rte_rawdev_dequeue_buffers;
+	rte_rawdev_enqueue_buffers;
 	rte_rawdev_get_attr;
 	rte_rawdev_get_dev_id;
 	rte_rawdev_info_get;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 04/10] rawdev: support for extended stats
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
                     ` (2 preceding siblings ...)
  2018-01-23 13:59   ` [PATCH v2 03/10] rawdev: add buffer stream IO support Shreyansh Jain
@ 2018-01-23 13:59   ` Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 05/10] rawdev: support for firmware management Shreyansh Jain
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-23 13:59 UTC (permalink / raw)
  To: fiona.trahe, thomas; +Cc: dev, hemant.agrawal, rosen.xu, Shreyansh Jain

Generic rawdev library cannot define a pre-defined set of stats
for devices which are yet to be defined.

This patch introduces the xstats support for rawdev so that any
implementation can create its own statistics.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           |  75 ++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 105 +++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       |  72 +++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |   4 ++
 4 files changed, 256 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index 0c5204f51..3a7800a45 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -245,6 +245,81 @@ rte_rawdev_dump(uint16_t dev_id, FILE *f)
 	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_start(uint16_t dev_id)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index 22f055a40..221f85856 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -408,6 +408,111 @@ rte_rawdev_dequeue_buffers(uint16_t dev_id,
 			   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);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index 300693f41..fd94b39c3 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -351,6 +351,69 @@ 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);
 /** Rawdevice operations function pointer table */
 struct rte_rawdev_ops {
 	/**< Get device info. */
@@ -386,6 +449,15 @@ struct rte_rawdev_ops {
 	rawdev_get_attr_t attr_get;
 	/**< Set an attribute managed by the implementation */
 	rawdev_set_attr_t attr_set;
+
+	/**< Get extended device statistics. */
+	rawdev_xstats_get_t xstats_get;
+	/**< Get names of extended stats. */
+	rawdev_xstats_get_names_t xstats_get_names;
+	/**< Get one value by name. */
+	rawdev_xstats_get_by_name_t xstats_get_by_name;
+	/**< Reset the statistics values in xstats. */
+	rawdev_xstats_reset_t xstats_reset;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index bafe2c5de..469b78d81 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -19,6 +19,10 @@ EXPERIMENTAL {
 	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

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 05/10] rawdev: support for firmware management
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
                     ` (3 preceding siblings ...)
  2018-01-23 13:59   ` [PATCH v2 04/10] rawdev: support for extended stats Shreyansh Jain
@ 2018-01-23 13:59   ` Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 06/10] rawdev: add self test support Shreyansh Jain
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-23 13:59 UTC (permalink / raw)
  To: fiona.trahe, thomas; +Cc: dev, hemant.agrawal, rosen.xu, Shreyansh Jain

Some generic operations for firmware management can loading, unloading,
starting, stopping and querying firmware of a device.

This patch adds support for such generic operations.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           | 43 ++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 64 +++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 70 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  4 ++
 4 files changed, 181 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index 3a7800a45..c1001b34b 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -320,6 +320,49 @@ rte_rawdev_xstats_reset(uint16_t dev_id,
 	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)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index 221f85856..388a24cf0 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -513,6 +513,70 @@ 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 successful 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
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index fd94b39c3..a8da39343 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -414,6 +414,67 @@ typedef int (*rawdev_xstats_get_names_t)(const struct rte_rawdev *dev,
 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 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,
+				      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 {
 	/**< Get device info. */
@@ -458,6 +519,15 @@ struct rte_rawdev_ops {
 	rawdev_xstats_get_by_name_t xstats_get_by_name;
 	/**< Reset the statistics values in xstats. */
 	rawdev_xstats_reset_t xstats_reset;
+
+	/**< Obtainer firmware status */
+	rawdev_firmware_status_get_t firmware_status_get;
+	/**< Obtain firmware version information */
+	rawdev_firmware_version_get_t firmware_version_get;
+	/**< Load firmware */
+	rawdev_firmware_load_t firmware_load;
+	/**< Unload firmware */
+	rawdev_firmware_unload_t firmware_unload;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index 469b78d81..8de9abdc4 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -6,6 +6,10 @@ EXPERIMENTAL {
 	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;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 06/10] rawdev: add self test support
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
                     ` (4 preceding siblings ...)
  2018-01-23 13:59   ` [PATCH v2 05/10] rawdev: support for firmware management Shreyansh Jain
@ 2018-01-23 13:59   ` Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 07/10] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-23 13:59 UTC (permalink / raw)
  To: fiona.trahe, thomas; +Cc: dev, hemant.agrawal, rosen.xu, Shreyansh Jain

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           |  9 +++++++++
 lib/librte_rawdev/rte_rawdev.h           | 12 ++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 11 +++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  1 +
 4 files changed, 33 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index c1001b34b..969244b28 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -363,6 +363,15 @@ rte_rawdev_firmware_unload(uint16_t dev_id)
 	return (*dev->dev_ops->firmware_unload)(dev);
 }
 
+int rte_rawdev_selftest(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->dev_selftest, -ENOTSUP);
+	return (*dev->dev_ops->dev_selftest)();
+}
+
 int
 rte_rawdev_start(uint16_t dev_id)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index 388a24cf0..fd3f7d3d2 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -577,6 +577,18 @@ rte_rawdev_firmware_load(uint16_t dev_id, rte_rawdev_obj_t firmware_image);
 int
 rte_rawdev_firmware_unload(uint16_t dev_id);
 
+/**
+ * Trigger the rawdev self test.
+ *
+ * @param dev_id
+ *   The identifier of the device
+ * @return
+ *   - 0: Selftest successful
+ *   - -ENOTSUP if the device doesn't support selftest
+ *   - other values < 0 on failure.
+ */
+int rte_rawdev_selftest(uint16_t dev_id);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index a8da39343..dd5c26d57 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -475,6 +475,14 @@ typedef int (*rawdev_firmware_load_t)(struct rte_rawdev *dev,
  */
 typedef int (*rawdev_firmware_unload_t)(struct rte_rawdev *dev);
 
+/**
+ * Start rawdev selftest
+ *
+ * @return
+ *   Return 0 on success
+ */
+typedef int (*rawdev_selftest_t)(void);
+
 /** Rawdevice operations function pointer table */
 struct rte_rawdev_ops {
 	/**< Get device info. */
@@ -528,6 +536,9 @@ struct rte_rawdev_ops {
 	rawdev_firmware_load_t firmware_load;
 	/**< Unload firmware */
 	rawdev_firmware_unload_t firmware_unload;
+
+	/**< Device selftest function */
+	rawdev_selftest_t dev_selftest;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index 8de9abdc4..af4465e26 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -19,6 +19,7 @@ EXPERIMENTAL {
 	rte_rawdev_queue_setup;
 	rte_rawdev_queue_release;
 	rte_rawdev_reset;
+	rte_rawdev_selftest;
 	rte_rawdev_set_attr;
 	rte_rawdev_socket_id;
 	rte_rawdev_start;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 07/10] drivers/raw: introduce skeleton rawdev driver
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
                     ` (5 preceding siblings ...)
  2018-01-23 13:59   ` [PATCH v2 06/10] rawdev: add self test support Shreyansh Jain
@ 2018-01-23 13:59   ` Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 08/10] drivers/raw: support for rawdev testcases Shreyansh Jain
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-23 13:59 UTC (permalink / raw)
  To: fiona.trahe, thomas; +Cc: dev, hemant.agrawal, rosen.xu, Shreyansh Jain

Skeleton rawdevice driver, on the lines of eventdev skeleton, is for
showcasing the rawdev library. This driver implements some of the
operations of the library based on which a test module can be
developed.

Design of skeleton involves a virtual device which is plugged into
VDEV bus on initialization.

Also, enable compilation of rawdev skeleton driver.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 config/common_base                                 |   1 +
 drivers/Makefile                                   |   2 +
 drivers/raw/Makefile                               |   9 +
 drivers/raw/skeleton_rawdev/Makefile               |  25 +
 .../rte_pmd_skeleton_rawdev_version.map            |   4 +
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      | 690 +++++++++++++++++++++
 drivers/raw/skeleton_rawdev/skeleton_rawdev.h      | 136 ++++
 mk/rte.app.mk                                      |   4 +
 8 files changed, 871 insertions(+)
 create mode 100644 drivers/raw/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.c
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.h

diff --git a/config/common_base b/config/common_base
index b8bd25b15..b0f6042d3 100644
--- a/config/common_base
+++ b/config/common_base
@@ -811,6 +811,7 @@ CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
 #
 CONFIG_RTE_LIBRTE_RAWDEV=y
 CONFIG_RTE_RAWDEV_MAX_DEVS=10
+CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
 
 #
 # Compile vhost PMD
diff --git a/drivers/Makefile b/drivers/Makefile
index e0488aa2b..ee65c87b0 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -14,5 +14,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
 DEPDIRS-crypto := bus mempool
 DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event
 DEPDIRS-event := bus mempool net
+DIRS-$(CONFIG_RTE_LIBRTE_RAWDEV) += raw
+DEPDIRS-raw := bus mempool net event
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
new file mode 100644
index 000000000..da7c8b449
--- /dev/null
+++ b/drivers/raw/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2017 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# DIRS-$(<configuration>) += <directory>
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/skeleton_rawdev/Makefile b/drivers/raw/skeleton_rawdev/Makefile
new file mode 100644
index 000000000..4d9b2f804
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/Makefile
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2017 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_skeleton_rawdev.a
+
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_bus_vdev
+
+EXPORT_MAP := rte_pmd_skeleton_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map b/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
new file mode 100644
index 000000000..179140fb8
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_18.02 {
+
+	local: *;
+};
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
new file mode 100644
index 000000000..b38188e11
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
@@ -0,0 +1,690 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_debug.h>
+#include <rte_dev.h>
+#include <rte_eal.h>
+#include <rte_kvargs.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_lcore.h>
+#include <rte_bus_vdev.h>
+
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "skeleton_rawdev.h"
+
+/* Dynamic log type identifier */
+int skeleton_pmd_logtype;
+
+/* Count of instances */
+uint16_t skeldev_init_once;
+
+/**< Rawdev Skeleton dummy driver name */
+#define SKELETON_PMD_RAWDEV_NAME rawdev_skeleton
+
+/**< Skeleton rawdev driver object */
+static struct rte_vdev_driver skeleton_pmd_drv;
+
+struct queue_buffers {
+	void *bufs[SKELETON_QUEUE_MAX_DEPTH];
+};
+
+static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {0};
+static void clear_queue_bufs(int queue_id);
+
+static void skeleton_rawdev_info_get(struct rte_rawdev *dev,
+				     rte_rawdev_obj_t dev_info)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_conf *skeldev_conf;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev_info) {
+		SKELETON_PMD_ERR("Invalid request");
+		return;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	skeldev_conf = dev_info;
+
+	skeldev_conf->num_queues = skeldev->num_queues;
+	skeldev_conf->capabilities = skeldev->capabilities;
+	skeldev_conf->device_state = skeldev->device_state;
+	skeldev_conf->firmware_state = skeldev->fw.firmware_state;
+}
+
+static int skeleton_rawdev_configure(const struct rte_rawdev *dev,
+				     rte_rawdev_obj_t config)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_conf *skeldev_conf;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	if (!config) {
+		SKELETON_PMD_ERR("Invalid configuration");
+		return -EINVAL;
+	}
+
+	skeldev_conf = config;
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	if (skeldev_conf->num_queues <= SKELETON_MAX_QUEUES)
+		skeldev->num_queues = skeldev_conf->num_queues;
+	else
+		return -EINVAL;
+
+	skeldev->capabilities = skeldev_conf->capabilities;
+	skeldev->num_queues = skeldev_conf->num_queues;
+
+	return 0;
+}
+
+static int skeleton_rawdev_start(struct rte_rawdev *dev)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+	enum skeleton_firmware_state fw_state;
+	enum skeleton_device_state device_state;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	fw_state = skeldev->fw.firmware_state;
+	device_state = skeldev->device_state;
+
+	if (fw_state == SKELETON_FW_LOADED &&
+		device_state == SKELETON_DEV_STOPPED) {
+		skeldev->device_state = SKELETON_DEV_RUNNING;
+	} else {
+		SKELETON_PMD_ERR("Device not ready for starting");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void skeleton_rawdev_stop(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (dev) {
+		skeldev = skeleton_rawdev_get_priv(dev);
+		skeldev->device_state = SKELETON_DEV_STOPPED;
+	}
+}
+
+static void
+reset_queues(struct skeleton_rawdev *skeldev)
+{
+	int i;
+
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
+		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
+		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
+	}
+}
+
+static void
+reset_attribute_table(struct skeleton_rawdev *skeldev)
+{
+	int i;
+
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (skeldev->attr[i].name) {
+			free(skeldev->attr[i].name);
+			skeldev->attr[i].name = NULL;
+		}
+	}
+}
+
+static int skeleton_rawdev_close(struct rte_rawdev *dev)
+{
+	int ret = 0, i;
+	struct skeleton_rawdev *skeldev;
+	enum skeleton_firmware_state fw_state;
+	enum skeleton_device_state device_state;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	fw_state = skeldev->fw.firmware_state;
+	device_state = skeldev->device_state;
+
+	reset_queues(skeldev);
+	reset_attribute_table(skeldev);
+
+	switch (fw_state) {
+	case SKELETON_FW_LOADED:
+		if (device_state == SKELETON_DEV_RUNNING) {
+			SKELETON_PMD_ERR("Cannot close running device");
+			ret = -EINVAL;
+		} else {
+			/* Probably call fw reset here */
+			skeldev->fw.firmware_state = SKELETON_FW_READY;
+		}
+		break;
+	case SKELETON_FW_READY:
+	case SKELETON_FW_ERROR:
+	default:
+		SKELETON_PMD_DEBUG("Device already in stopped state");
+		ret = -EINVAL;
+		break;
+	}
+
+	/* Clear all allocated queues */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
+		clear_queue_bufs(i);
+
+	return ret;
+}
+
+static int skeleton_rawdev_reset(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	SKELETON_PMD_DEBUG("Reseting device");
+	skeldev->fw.firmware_state = SKELETON_FW_READY;
+
+	return 0;
+}
+
+static void skeleton_rawdev_queue_def_conf(struct rte_rawdev *dev,
+					   uint16_t queue_id,
+					   rte_rawdev_obj_t queue_conf)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_queue *skelq;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !queue_conf)
+		return;
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	skelq = &skeldev->queues[queue_id];
+
+	if (queue_id < SKELETON_MAX_QUEUES)
+		rte_memcpy(queue_conf, skelq,
+			sizeof(struct skeleton_rawdev_queue));
+}
+
+static void
+clear_queue_bufs(int queue_id)
+{
+	int i;
+
+	/* Clear buffers for queue_id */
+	for (i = 0; i < SKELETON_QUEUE_MAX_DEPTH; i++)
+		queue_buf[queue_id].bufs[i] = NULL;
+}
+
+static int skeleton_rawdev_queue_setup(struct rte_rawdev *dev,
+				       uint16_t queue_id,
+				       rte_rawdev_obj_t queue_conf)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_queue *q;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !queue_conf)
+		return -EINVAL;
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	q = &skeldev->queues[queue_id];
+
+	if (skeldev->num_queues > queue_id &&
+	    q->depth < SKELETON_QUEUE_MAX_DEPTH) {
+		rte_memcpy(q, queue_conf,
+			   sizeof(struct skeleton_rawdev_queue));
+		clear_queue_bufs(queue_id);
+	} else {
+		SKELETON_PMD_ERR("Invalid queue configuration");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int skeleton_rawdev_queue_release(struct rte_rawdev *dev,
+					 uint16_t queue_id)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	if (skeldev->num_queues > queue_id) {
+		skeldev->queues[queue_id].state = SKELETON_QUEUE_DETACH;
+		skeldev->queues[queue_id].depth = SKELETON_QUEUE_DEF_DEPTH;
+		clear_queue_bufs(queue_id);
+	} else {
+		SKELETON_PMD_ERR("Invalid queue configuration");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int skeleton_rawdev_get_attr(struct rte_rawdev *dev,
+				    const char *attr_name,
+				    uint64_t *attr_value)
+{
+	int i;
+	uint8_t done = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !attr_name || !attr_value) {
+		SKELETON_PMD_ERR("Invalid arguments for getting attributes");
+		return -EINVAL;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (!skeldev->attr[i].name)
+			continue;
+
+		if (!strncmp(skeldev->attr[i].name, attr_name,
+			    SKELETON_ATTRIBUTE_NAME_MAX)) {
+			*attr_value = skeldev->attr[i].value;
+			done = 1;
+			SKELETON_PMD_DEBUG("Attribute (%s) Value (%lu)",
+					   attr_name, *attr_value);
+			break;
+		}
+	}
+
+	if (done)
+		return 0;
+
+	/* Attribute not found */
+	return -EINVAL;
+}
+
+static int skeleton_rawdev_set_attr(struct rte_rawdev *dev,
+				     const char *attr_name,
+				     const uint64_t attr_value)
+{
+	int i;
+	uint8_t done = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !attr_name) {
+		SKELETON_PMD_ERR("Invalid arguments for setting attributes");
+		return -EINVAL;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	/* Check if attribute already exists */
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (!skeldev->attr[i].name)
+			break;
+
+		if (!strncmp(skeldev->attr[i].name, attr_name,
+			     SKELETON_ATTRIBUTE_NAME_MAX)) {
+			/* Update value */
+			skeldev->attr[i].value = attr_value;
+			done = 1;
+			break;
+		}
+	}
+
+	if (!done) {
+		if (i < (SKELETON_MAX_ATTRIBUTES - 1)) {
+			/* There is still space to insert one more */
+			skeldev->attr[i].name = strdup(attr_name);
+			if (!skeldev->attr[i].name)
+				return -ENOMEM;
+
+			skeldev->attr[i].value = attr_value;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int skeleton_rawdev_enqueue_bufs(struct rte_rawdev *dev,
+					struct rte_rawdev_buf **buffers,
+					unsigned int count,
+					rte_rawdev_obj_t context)
+{
+	unsigned int i;
+	uint16_t q_id;
+	RTE_SET_USED(dev);
+
+	/* context is essentially the queue_id which is
+	 * transferred as opaque object through the library layer. This can
+	 * help in complex implementation which require more information than
+	 * just an integer - for example, a queue-pair.
+	 */
+	q_id = *((int *)context);
+
+	for (i = 0; i < count; i++)
+		queue_buf[q_id].bufs[i] = buffers[i]->buf_addr;
+
+	return i;
+}
+
+static int skeleton_rawdev_dequeue_bufs(struct rte_rawdev *dev,
+					struct rte_rawdev_buf **buffers,
+					unsigned int count,
+					rte_rawdev_obj_t context)
+{
+	unsigned int i;
+	uint16_t q_id;
+	RTE_SET_USED(dev);
+
+	/* context is essentially the queue_id which is
+	 * transferred as opaque object through the library layer. This can
+	 * help in complex implementation which require more information than
+	 * just an integer - for example, a queue-pair.
+	 */
+	q_id = *((int *)context);
+
+	for (i = 0; i < count; i++)
+		buffers[i]->buf_addr = queue_buf[q_id].bufs[i];
+
+	return i;
+}
+
+static int skeleton_rawdev_dump(struct rte_rawdev *dev, FILE *f)
+{
+	RTE_SET_USED(dev);
+	RTE_SET_USED(f);
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_status_get(struct rte_rawdev *dev,
+					       rte_rawdev_obj_t status_info)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	if (status_info)
+		memcpy(status_info, &skeldev->fw.firmware_state,
+			sizeof(enum skeleton_firmware_state));
+
+	return 0;
+}
+
+
+static int skeleton_rawdev_firmware_version_get(
+					struct rte_rawdev *dev,
+					rte_rawdev_obj_t version_info)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_firmware_version_info *vi;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	vi = version_info;
+
+	vi->major = skeldev->fw.firmware_version.major;
+	vi->minor = skeldev->fw.firmware_version.minor;
+	vi->subrel = skeldev->fw.firmware_version.subrel;
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_load(struct rte_rawdev *dev,
+					 rte_rawdev_obj_t firmware_buf)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	/* firmware_buf is a mmaped, possibly DMA'able area, buffer. Being
+	 * dummy, all this does is check if firmware_buf is not NULL and
+	 * sets the state of the firmware.
+	 */
+	if (!firmware_buf)
+		return -EINVAL;
+
+	skeldev->fw.firmware_state = SKELETON_FW_LOADED;
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_unload(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	skeldev->fw.firmware_state = SKELETON_FW_READY;
+
+	return 0;
+}
+
+static const struct rte_rawdev_ops skeleton_rawdev_ops = {
+	.dev_info_get = skeleton_rawdev_info_get,
+	.dev_configure = skeleton_rawdev_configure,
+	.dev_start = skeleton_rawdev_start,
+	.dev_stop = skeleton_rawdev_stop,
+	.dev_close = skeleton_rawdev_close,
+	.dev_reset = skeleton_rawdev_reset,
+
+	.queue_def_conf = skeleton_rawdev_queue_def_conf,
+	.queue_setup = skeleton_rawdev_queue_setup,
+	.queue_release = skeleton_rawdev_queue_release,
+
+	.attr_get = skeleton_rawdev_get_attr,
+	.attr_set = skeleton_rawdev_set_attr,
+
+	.enqueue_bufs = skeleton_rawdev_enqueue_bufs,
+	.dequeue_bufs = skeleton_rawdev_dequeue_bufs,
+
+	.dump = skeleton_rawdev_dump,
+
+	.xstats_get = NULL,
+	.xstats_get_names = NULL,
+	.xstats_get_by_name = NULL,
+	.xstats_reset = NULL,
+
+	.firmware_status_get = skeleton_rawdev_firmware_status_get,
+	.firmware_version_get = skeleton_rawdev_firmware_version_get,
+	.firmware_load = skeleton_rawdev_firmware_load,
+	.firmware_unload = skeleton_rawdev_firmware_unload,
+};
+
+static int
+skeleton_rawdev_create(const char *name,
+		       struct rte_vdev_device *vdev,
+		       int socket_id)
+{
+	int ret = 0, i;
+	struct rte_rawdev *rawdev = NULL;
+	struct skeleton_rawdev *skeldev = NULL;
+
+	if (!name) {
+		SKELETON_PMD_ERR("Invalid name of the device!");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	/* Allocate device structure */
+	rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct skeleton_rawdev),
+					 socket_id);
+	if (rawdev == NULL) {
+		SKELETON_PMD_ERR("Unable to allocate rawdevice");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	rawdev->dev_ops = &skeleton_rawdev_ops;
+	rawdev->device = &vdev->device;
+	rawdev->driver_name = vdev->device.driver->name;
+
+	skeldev = skeleton_rawdev_get_priv(rawdev);
+
+	skeldev->device_id = SKELETON_DEVICE_ID;
+	skeldev->vendor_id = SKELETON_VENDOR_ID;
+	skeldev->capabilities = SKELETON_DEFAULT_CAPA;
+
+	memset(&skeldev->fw, 0, sizeof(struct skeleton_firmware));
+
+	skeldev->fw.firmware_state = SKELETON_DEV_STOPPED;
+	skeldev->fw.firmware_version.major = SKELETON_MAJOR_VER;
+	skeldev->fw.firmware_version.minor = SKELETON_MINOR_VER;
+	skeldev->fw.firmware_version.subrel = SKELETON_SUB_VER;
+
+	skeldev->device_state = SKELETON_DEV_STOPPED;
+
+	/* Reset/set to default queue configuration for this device */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
+		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
+		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
+	}
+
+	/* Clear all allocated queue buffers */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
+		clear_queue_bufs(i);
+
+	return ret;
+
+cleanup:
+	if (rawdev)
+		rte_rawdev_pmd_release(rawdev);
+
+	return ret;
+}
+
+static int
+skeleton_rawdev_destroy(const char *name)
+{
+	int ret;
+	struct rte_rawdev *rdev;
+
+	if (!name) {
+		SKELETON_PMD_ERR("Invalid device name");
+		return -EINVAL;
+	}
+
+	rdev = rte_rawdev_pmd_get_named_dev(name);
+	if (!rdev) {
+		SKELETON_PMD_ERR("Invalid device name (%s)", name);
+		return -EINVAL;
+	}
+
+	/* rte_rawdev_close is called by pmd_release */
+	ret = rte_rawdev_pmd_release(rdev);
+	if (ret)
+		SKELETON_PMD_DEBUG("Device cleanup failed");
+
+	return 0;
+}
+
+static int
+skeleton_rawdev_probe(struct rte_vdev_device *vdev)
+{
+	const char *name;
+	int ret = 0;
+
+
+	name = rte_vdev_device_name(vdev);
+	/* More than one instance is not supported */
+	if (skeldev_init_once) {
+		SKELETON_PMD_ERR("Multiple instance not supported for %s",
+				 name);
+		return -EINVAL;
+	}
+
+	SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
+
+	ret = skeleton_rawdev_create(name, vdev, rte_socket_id());
+
+	/* Device instance created; Second instance not posible */
+	skeldev_init_once = 1;
+
+	return ret;
+}
+
+static int
+skeleton_rawdev_remove(struct rte_vdev_device *vdev)
+{
+	const char *name;
+	int ret;
+
+	name = rte_vdev_device_name(vdev);
+
+	SKELETON_PMD_INFO("Closing %s on NUMA node %d", name, rte_socket_id());
+
+	ret = skeleton_rawdev_destroy(name);
+	if (!ret)
+		skeldev_init_once = 0;
+
+	return ret;
+}
+
+static struct rte_vdev_driver skeleton_pmd_drv = {
+	.probe = skeleton_rawdev_probe,
+	.remove = skeleton_rawdev_remove
+};
+
+RTE_PMD_REGISTER_VDEV(SKELETON_PMD_RAWDEV_NAME, skeleton_pmd_drv);
+
+RTE_INIT(skeleton_pmd_init_log);
+
+static void
+skeleton_pmd_init_log(void)
+{
+	skeleton_pmd_logtype = rte_log_register("rawdev.skeleton");
+	if (skeleton_pmd_logtype >= 0)
+		rte_log_set_level(skeleton_pmd_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.h b/drivers/raw/skeleton_rawdev/skeleton_rawdev.h
new file mode 100644
index 000000000..5045b5922
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#ifndef __SKELETON_RAWDEV_H__
+#define __SKELETON_RAWDEV_H__
+
+#include <rte_rawdev.h>
+
+extern int skeleton_pmd_logtype;
+
+#define SKELETON_PMD_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, skeleton_pmd_logtype, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#define SKELETON_PMD_FUNC_TRACE() SKELETON_PMD_LOG(DEBUG, ">>")
+
+#define SKELETON_PMD_DEBUG(fmt, args...) \
+	SKELETON_PMD_LOG(DEBUG, fmt, ## args)
+#define SKELETON_PMD_INFO(fmt, args...) \
+	SKELETON_PMD_LOG(INFO, fmt, ## args)
+#define SKELETON_PMD_ERR(fmt, args...) \
+	SKELETON_PMD_LOG(ERR, fmt, ## args)
+#define SKELETON_PMD_WARN(fmt, args...) \
+	SKELETON_PMD_LOG(WARNING, fmt, ## args)
+/* Macros for self test application */
+#define SKELETON_TEST_INFO	SKELETON_PMD_INFO
+#define SKELETON_TEST_DEBUG	SKELETON_PMD_DEBUG
+#define SKELETON_TEST_ERR	SKELETON_PMD_ERR
+#define SKELETON_TEST_WARN	SKELETON_PMD_WARN
+
+#define SKELETON_SELFTEST_ARG   ("selftest")
+
+#define SKELETON_VENDOR_ID 0x10
+#define SKELETON_DEVICE_ID 0x01
+
+#define SKELETON_MAJOR_VER 1
+#define SKELETON_MINOR_VER 0
+#define SKELETON_SUB_VER   0
+
+#define SKELETON_MAX_QUEUES 1
+
+enum skeleton_firmware_state {
+	SKELETON_FW_READY,
+	SKELETON_FW_LOADED,
+	SKELETON_FW_ERROR
+};
+
+enum skeleton_device_state {
+	SKELETON_DEV_RUNNING,
+	SKELETON_DEV_STOPPED
+};
+
+enum skeleton_queue_state {
+	SKELETON_QUEUE_DETACH,
+	SKELETON_QUEUE_ATTACH
+};
+
+#define SKELETON_QUEUE_DEF_DEPTH 10
+#define SKELETON_QUEUE_MAX_DEPTH 25
+
+struct skeleton_firmware_version_info {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t subrel;
+};
+
+struct skeleton_firmware {
+	/**< Device firmware information */
+	struct skeleton_firmware_version_info firmware_version;
+	/**< Device state */
+	enum skeleton_firmware_state firmware_state;
+
+};
+
+#define SKELETON_MAX_ATTRIBUTES 10
+#define SKELETON_ATTRIBUTE_NAME_MAX 20
+
+struct skeleton_rawdev_attributes {
+	/**< Name of the attribute */
+	char *name;
+	/**< Value or reference of value of attribute */
+	uint64_t value;
+};
+
+/**< Device supports firmware loading/unloading */
+#define SKELETON_CAPA_FW_LOAD	0x0001
+/**< Device supports firmware reset */
+#define SKELETON_CAPA_FW_RESET  0x0002
+/**< Device support queue based communication */
+#define SKELETON_CAPA_QUEUES    0x0004
+/**< Default Capabilities: FW_LOAD, FW_RESET, QUEUES */
+#define SKELETON_DEFAULT_CAPA   0x7
+
+struct skeleton_rawdev_queue {
+	uint8_t state;
+	uint32_t depth;
+};
+
+struct skeleton_rawdev {
+	uint16_t device_id;
+	uint16_t vendor_id;
+	uint16_t num_queues;
+	/**< One of SKELETON_CAPA_* */
+	uint16_t capabilities;
+	/**< State of device; linked to firmware state */
+	enum skeleton_device_state device_state;
+	/**< Firmware configuration */
+	struct skeleton_firmware fw;
+	/**< Collection of all communication channels - which can be referred
+	 *  to as queues.
+	 */
+	struct skeleton_rawdev_queue queues[SKELETON_MAX_QUEUES];
+	/**< Global table containing various pre-defined and user-defined
+	 * attributes.
+	 */
+	struct skeleton_rawdev_attributes attr[SKELETON_MAX_ATTRIBUTES];
+	struct rte_device *device;
+};
+
+struct skeleton_rawdev_conf {
+	uint16_t num_queues;
+	unsigned int capabilities;
+	enum skeleton_device_state device_state;
+	enum skeleton_firmware_state firmware_state;
+};
+
+static inline struct skeleton_rawdev *
+skeleton_rawdev_get_priv(const struct rte_rawdev *rawdev)
+{
+	return rawdev->dev_private;
+}
+
+int test_rawdev_skeldev(void);
+
+#endif /* __SKELETON_RAWDEV_H__ */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index b201e861d..c3f4db46f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -220,6 +220,10 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += -lrte_pmd_octeontx
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OPDL_EVENTDEV) += -lrte_pmd_opdl_event
 endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
+ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+endif # CONFIG_RTE_LIBRTE_RAWDEV
+
 ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_bus_fslmc
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_mempool_dpaa2
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 08/10] drivers/raw: support for rawdev testcases
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
                     ` (6 preceding siblings ...)
  2018-01-23 13:59   ` [PATCH v2 07/10] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
@ 2018-01-23 13:59   ` Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 09/10] test: enable rawdev skeleton test Shreyansh Jain
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-23 13:59 UTC (permalink / raw)
  To: fiona.trahe, thomas; +Cc: dev, hemant.agrawal, rosen.xu, Shreyansh Jain

Patch introduces rawdev unit testcase for validation against the
Skeleton rawdev dummy PMD implementation.

Test cases are added along with the skeleton driver implementation.
It can be enabled by using vdev argument to any DPDK binary:

  --vdev="rawdev_skeleton,self_test=1"

In case 'self_test=1' is not provided, autotest doesn't execute the
test cases but the vdev is still available for application use.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/raw/skeleton_rawdev/Makefile               |   1 +
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      |  66 +++-
 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c | 431 +++++++++++++++++++++
 3 files changed, 497 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c

diff --git a/drivers/raw/skeleton_rawdev/Makefile b/drivers/raw/skeleton_rawdev/Makefile
index 4d9b2f804..d5e34361a 100644
--- a/drivers/raw/skeleton_rawdev/Makefile
+++ b/drivers/raw/skeleton_rawdev/Makefile
@@ -21,5 +21,6 @@ LIBABIVER := 1
 # all source are stored in SRCS-y
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev_test.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
index b38188e11..2dfba0081 100644
--- a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
@@ -541,6 +541,8 @@ static const struct rte_rawdev_ops skeleton_rawdev_ops = {
 	.firmware_version_get = skeleton_rawdev_firmware_version_get,
 	.firmware_load = skeleton_rawdev_firmware_load,
 	.firmware_unload = skeleton_rawdev_firmware_unload,
+
+	.dev_selftest = test_rawdev_skeldev,
 };
 
 static int
@@ -630,11 +632,62 @@ skeleton_rawdev_destroy(const char *name)
 	return 0;
 }
 
+static int
+skeldev_get_selftest(const char *key __rte_unused,
+		     const char *value,
+		     void *opaque)
+{
+	int *flag = opaque;
+	*flag = atoi(value);
+	return 0;
+}
+
+static int
+skeldev_parse_vdev_args(struct rte_vdev_device *vdev)
+{
+	int selftest = 0;
+	const char *name;
+	const char *params;
+
+	static const char *const args[] = {
+		SKELETON_SELFTEST_ARG,
+		NULL
+	};
+
+	name = rte_vdev_device_name(vdev);
+
+	params = rte_vdev_device_args(vdev);
+	if (params != NULL && params[0] != '\0') {
+		struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
+
+		if (!kvlist) {
+			SKELETON_PMD_INFO(
+				"Ignoring unsupported params supplied '%s'",
+				name);
+		} else {
+			int ret = rte_kvargs_process(kvlist,
+					SKELETON_SELFTEST_ARG,
+					skeldev_get_selftest, &selftest);
+			if (ret != 0 || (selftest < 0 || selftest > 1)) {
+				SKELETON_PMD_ERR("%s: Error in parsing args",
+						 name);
+				rte_kvargs_free(kvlist);
+				ret = -1; /* enforce if selftest is invalid */
+				return ret;
+			}
+		}
+
+		rte_kvargs_free(kvlist);
+	}
+
+	return selftest;
+}
+
 static int
 skeleton_rawdev_probe(struct rte_vdev_device *vdev)
 {
 	const char *name;
-	int ret = 0;
+	int selftest = 0, ret = 0;
 
 
 	name = rte_vdev_device_name(vdev);
@@ -647,7 +700,18 @@ skeleton_rawdev_probe(struct rte_vdev_device *vdev)
 
 	SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
 
+	selftest = skeldev_parse_vdev_args(vdev);
+	/* In case of invalid argument, selftest != 1; ignore other values */
+
 	ret = skeleton_rawdev_create(name, vdev, rte_socket_id());
+	if (!ret) {
+		/* In case command line argument for 'selftest' was passed;
+		 * if invalid arguments were passed, execution continues but
+		 * without selftest.
+		 */
+		if (selftest == 1)
+			test_rawdev_skeldev();
+	}
 
 	/* Device instance created; Second instance not posible */
 	skeldev_init_once = 1;
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
new file mode 100644
index 000000000..5c6abc13c
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
@@ -0,0 +1,431 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#include <rte_common.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_dev.h>
+#include <rte_rawdev.h>
+#include <rte_bus_vdev.h>
+#include <rte_test.h>
+
+/* Using relative path as skeleton_rawdev is not part of exported headers */
+#include "skeleton_rawdev.h"
+
+#define TEST_DEV_ID   0
+#define TEST_DEV_NAME "rawdev_skeleton"
+
+#define SKELDEV_LOGS(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, skeleton_pmd_logtype, fmt "\n", \
+		##args)
+
+#define SKELDEV_TEST_INFO(fmt, args...) \
+	SKELDEV_LOGS(INFO, fmt, ## args)
+#define SKELDEV_TEST_DEBUG(fmt, args...) \
+	SKELDEV_LOGS(DEBUG, fmt, ## args)
+
+#define SKELDEV_TEST_RUN(setup, teardown, test) \
+	skeldev_test_run(setup, teardown, test, #test)
+
+#define TEST_SUCCESS 0
+#define TEST_FAILED  -1
+
+static int total;
+static int passed;
+static int failed;
+static int unsupported;
+
+static int
+testsuite_setup(void)
+{
+	uint8_t count;
+	count = rte_rawdev_count();
+	if (!count) {
+		SKELDEV_TEST_INFO("\tNo existing rawdev; "
+				  "Creating 'skeldev_rawdev'");
+		return rte_vdev_init(TEST_DEV_NAME, NULL);
+	}
+
+	return TEST_SUCCESS;
+}
+
+static void local_teardown(void);
+
+static void
+testsuite_teardown(void)
+{
+	local_teardown();
+}
+
+static void
+local_teardown(void)
+{
+	rte_vdev_uninit(TEST_DEV_NAME);
+}
+
+static int
+test_rawdev_count(void)
+{
+	uint8_t count;
+	count = rte_rawdev_count();
+	RTE_TEST_ASSERT(count > 0, "Invalid rawdev count %" PRIu8, count);
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_get_dev_id(void)
+{
+	int ret;
+	ret = rte_rawdev_get_dev_id("invalid_rawdev_device");
+	RTE_TEST_ASSERT_FAIL(ret, "Expected <0 for invalid dev name ret=%d",
+			     ret);
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_socket_id(void)
+{
+	int socket_id;
+	socket_id = rte_rawdev_socket_id(TEST_DEV_ID);
+	RTE_TEST_ASSERT(socket_id != -EINVAL,
+			"Failed to get socket_id %d", socket_id);
+	socket_id = rte_rawdev_socket_id(RTE_RAWDEV_MAX_DEVS);
+	RTE_TEST_ASSERT(socket_id == -EINVAL,
+			"Expected -EINVAL %d", socket_id);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_info_get(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf skel_conf = {0};
+
+	ret = rte_rawdev_info_get(TEST_DEV_ID, NULL);
+	RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
+
+	rdev_info.dev_private = &skel_conf;
+
+	ret = rte_rawdev_info_get(TEST_DEV_ID, &rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get raw dev info");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_configure(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_set = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+
+	/* Check invalid configuration */
+	ret = rte_rawdev_configure(TEST_DEV_ID, NULL);
+	RTE_TEST_ASSERT(ret == -EINVAL,
+			"Null configure; Expected -EINVAL, got %d", ret);
+
+	/* Valid configuration test */
+	rdev_conf_set.num_queues = 1;
+	rdev_conf_set.capabilities = SKELETON_CAPA_FW_LOAD |
+				     SKELETON_CAPA_FW_RESET;
+
+	rdev_info.dev_private = &rdev_conf_set;
+	ret = rte_rawdev_configure(TEST_DEV_ID,
+				   (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure rawdev (%d)", ret);
+
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_set.num_queues,
+			      rdev_conf_get.num_queues,
+			      "Configuration test failed; num_queues (%d)(%d)",
+			      rdev_conf_set.num_queues,
+			      rdev_conf_get.num_queues);
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_set.capabilities,
+			  rdev_conf_get.capabilities,
+			  "Configuration test failed; capabilities");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_queue_default_conf_get(void)
+{
+	int ret, i;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+	struct skeleton_rawdev_queue q = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)",
+				ret);
+
+	/* call to test_rawdev_configure would have set the num_queues = 1 */
+	RTE_TEST_ASSERT_SUCCESS(!(rdev_conf_get.num_queues > 0),
+				"Invalid number of queues (%d). Expected 1",
+				rdev_conf_get.num_queues);
+	/* All queues by default should have state = DETACH and
+	 * depth = DEF_DEPTH
+	 */
+	for (i = 0; i < rdev_conf_get.num_queues; i++) {
+		rte_rawdev_queue_conf_get(TEST_DEV_ID, i, &q);
+		RTE_TEST_ASSERT_EQUAL(q.depth, SKELETON_QUEUE_DEF_DEPTH,
+				      "Invalid default depth of queue (%d)",
+				      q.depth);
+		RTE_TEST_ASSERT_EQUAL(q.state, SKELETON_QUEUE_DETACH,
+				      "Invalid default state of queue (%d)",
+				      q.state);
+	}
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_queue_setup(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+	struct skeleton_rawdev_queue qset = {0};
+	struct skeleton_rawdev_queue qget = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+
+	/* call to test_rawdev_configure would have set the num_queues = 1 */
+	RTE_TEST_ASSERT_SUCCESS(!(rdev_conf_get.num_queues > 0),
+				"Invalid number of queues (%d). Expected 1",
+				rdev_conf_get.num_queues);
+
+	/* Modify the queue depth for Queue 0 and attach it */
+	qset.depth = 15;
+	qset.state = SKELETON_QUEUE_ATTACH;
+	ret = rte_rawdev_queue_setup(TEST_DEV_ID, 0, &qset);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup queue (%d)", ret);
+
+	/* Now, fetching the queue 0 should show depth as 15 */
+	ret = rte_rawdev_queue_conf_get(TEST_DEV_ID, 0, &qget);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get queue config (%d)", ret);
+
+	RTE_TEST_ASSERT_EQUAL(qset.depth, qget.depth,
+			      "Failed to set queue depth: Need(%d), has(%d)",
+			      qset.depth, qget.depth);
+
+	return TEST_SUCCESS;
+}
+
+/* After executing test_rawdev_queue_setup, queue_id=0 would have depth as 15.
+ * Releasing should set it back to default. state would set to DETACH
+ */
+static int
+test_rawdev_queue_release(void)
+{
+	int ret;
+	struct skeleton_rawdev_queue qget = {0};
+
+	/* Now, fetching the queue 0 should show depth as 100 */
+	ret = rte_rawdev_queue_release(TEST_DEV_ID, 0);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to release queue 0; (%d)", ret);
+
+	/* Now, fetching the queue 0 should show depth as default */
+	ret = rte_rawdev_queue_conf_get(TEST_DEV_ID, 0, &qget);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get queue config (%d)", ret);
+
+	RTE_TEST_ASSERT_EQUAL(qget.depth, SKELETON_QUEUE_DEF_DEPTH,
+			      "Release of Queue 0 failed; (depth)");
+
+	RTE_TEST_ASSERT_EQUAL(qget.state, SKELETON_QUEUE_DETACH,
+			      "Release of Queue 0 failed; (state)");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_attr_set_get(void)
+{
+	int ret;
+	int *dummy_value;
+	uint64_t ret_value;
+
+	/* Set an attribute and fetch it */
+	ret = rte_rawdev_set_attr(TEST_DEV_ID, "Test1", 100);
+	RTE_TEST_ASSERT(!ret, "Unable to set an attribute (Test1)");
+
+	dummy_value = malloc(sizeof(int));
+	if (!dummy_value)
+		RTE_TEST_ASSERT(1, "Unable to allocate memory (dummy_value)");
+
+	*dummy_value = 200;
+	ret = rte_rawdev_set_attr(TEST_DEV_ID, "Test2", (uint64_t)dummy_value);
+
+	/* Check if attributes have been set */
+	ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test1", &ret_value);
+	RTE_TEST_ASSERT_EQUAL(ret_value, 100,
+			      "Attribute (Test1) not set correctly (%lu)",
+			      ret_value);
+
+	ret_value = 0;
+	ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test2", &ret_value);
+	RTE_TEST_ASSERT_EQUAL(*((int *)ret_value), 200,
+			      "Attribute (Test2) not set correctly (%lu)",
+			      ret_value);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_start_stop(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+
+	rte_rawdev_start(TEST_DEV_ID);
+	ret = rte_rawdev_info_get(TEST_DEV_ID, (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_get.device_state, SKELETON_DEV_RUNNING,
+			      "Device start failed. State is (%d)",
+			      rdev_conf_get.device_state);
+
+	rte_rawdev_stop(TEST_DEV_ID);
+	ret = rte_rawdev_info_get(TEST_DEV_ID, (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_get.device_state, SKELETON_DEV_STOPPED,
+			      "Device stop failed. State is (%d)",
+			      rdev_conf_get.device_state);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_enqdeq(void)
+{
+	int ret;
+	unsigned int count = 1;
+	uint16_t queue_id = 0;
+	struct rte_rawdev_buf buffers[1];
+	struct rte_rawdev_buf *deq_buffers;
+
+	buffers[0].buf_addr = malloc(strlen(TEST_DEV_NAME) + 3);
+	if (!buffers[0].buf_addr)
+		goto cleanup;
+	snprintf(buffers[0].buf_addr, strlen(TEST_DEV_NAME) + 2, "%s%d",
+		 TEST_DEV_NAME, 0);
+
+	ret = rte_rawdev_enqueue_buffers(TEST_DEV_ID,
+					 (struct rte_rawdev_buf **)&buffers,
+					 count, &queue_id);
+	RTE_TEST_ASSERT_EQUAL((unsigned int)ret, count,
+			      "Unable to enqueue buffers");
+
+	deq_buffers = malloc(sizeof(struct rte_rawdev_buf) * count);
+	if (!deq_buffers)
+		goto cleanup;
+
+	ret = rte_rawdev_dequeue_buffers(TEST_DEV_ID,
+					(struct rte_rawdev_buf **)&deq_buffers,
+					count, &queue_id);
+	RTE_TEST_ASSERT_EQUAL((unsigned int)ret, count,
+			      "Unable to dequeue buffers");
+
+	if (deq_buffers)
+		free(deq_buffers);
+
+	return TEST_SUCCESS;
+cleanup:
+	if (buffers[0].buf_addr)
+		free(buffers[0].buf_addr);
+	if (deq_buffers)
+		free(deq_buffers);
+
+	return TEST_FAILED;
+}
+
+static void skeldev_test_run(int (*setup)(void),
+			     void (*teardown)(void),
+			     int (*test)(void),
+			     const char *name)
+{
+	int ret = 0;
+
+	if (setup) {
+		ret = setup();
+		if (ret < 0) {
+			SKELDEV_TEST_INFO("Error setting up test %s", name);
+			unsupported++;
+		}
+	}
+
+	if (test) {
+		ret = test();
+		if (ret < 0) {
+			failed++;
+			SKELDEV_TEST_INFO("%s Failed", name);
+		} else {
+			passed++;
+			SKELDEV_TEST_DEBUG("%s Passed", name);
+		}
+	}
+
+	if (teardown)
+		teardown();
+
+	total++;
+}
+
+int
+test_rawdev_skeldev(void)
+{
+	testsuite_setup();
+
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_count);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_get_dev_id);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_socket_id);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_info_get);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_configure);
+	SKELDEV_TEST_RUN(test_rawdev_configure, NULL,
+			 test_rawdev_queue_default_conf_get);
+	SKELDEV_TEST_RUN(test_rawdev_configure, NULL, test_rawdev_queue_setup);
+	SKELDEV_TEST_RUN(test_rawdev_queue_setup, NULL,
+			 test_rawdev_queue_release);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_attr_set_get);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_start_stop);
+	SKELDEV_TEST_RUN(test_rawdev_queue_setup, NULL, test_rawdev_enqdeq);
+
+	testsuite_teardown();
+
+	SKELDEV_TEST_INFO("Total tests   : %d", total);
+	SKELDEV_TEST_INFO("Passed        : %d", passed);
+	SKELDEV_TEST_INFO("Failed        : %d", failed);
+	SKELDEV_TEST_INFO("Not supported : %d", unsupported);
+
+	if (failed)
+		return -1;
+
+	return 0;
+};
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 09/10] test: enable rawdev skeleton test
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
                     ` (7 preceding siblings ...)
  2018-01-23 13:59   ` [PATCH v2 08/10] drivers/raw: support for rawdev testcases Shreyansh Jain
@ 2018-01-23 13:59   ` Shreyansh Jain
  2018-01-23 13:59   ` [PATCH v2 10/10] maintainers: claim ownership of rawdev Shreyansh Jain
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-23 13:59 UTC (permalink / raw)
  To: fiona.trahe, thomas; +Cc: dev, hemant.agrawal, rosen.xu, Shreyansh Jain

Skeleton rawdevice test cases are part of driver layer. This patch
allows test cases to be executed using 'rawdev_autotest' command
in test framework.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 test/test/Makefile      |  4 ++++
 test/test/test_rawdev.c | 27 +++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 test/test/test_rawdev.c

diff --git a/test/test/Makefile b/test/test/Makefile
index 5ba5a9ac7..8dfb122bb 100644
--- a/test/test/Makefile
+++ b/test/test/Makefile
@@ -184,6 +184,10 @@ SRCS-y += test_event_ring.c
 SRCS-y += test_event_eth_rx_adapter.c
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
+SRCS-y += test_rawdev.c
+endif
+
 SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) += test_kvargs.c
 
 CFLAGS += -O3
diff --git a/test/test/test_rawdev.c b/test/test/test_rawdev.c
new file mode 100644
index 000000000..043a38a13
--- /dev/null
+++ b/test/test/test_rawdev.c
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+#include <rte_common.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_dev.h>
+#include <rte_rawdev.h>
+#include <rte_bus_vdev.h>
+
+#include "test.h"
+
+static int
+test_rawdev_selftest_impl(const char *pmd, const char *opts)
+{
+	rte_vdev_init(pmd, opts);
+	return rte_rawdev_selftest(rte_rawdev_get_dev_id(pmd));
+}
+
+static int
+test_rawdev_selftest_skeleton(void)
+{
+	return test_rawdev_selftest_impl("rawdev_skeleton", "");
+}
+
+REGISTER_TEST_COMMAND(rawdev_autotest, test_rawdev_selftest_skeleton);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 10/10] maintainers: claim ownership of rawdev
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
                     ` (8 preceding siblings ...)
  2018-01-23 13:59   ` [PATCH v2 09/10] test: enable rawdev skeleton test Shreyansh Jain
@ 2018-01-23 13:59   ` Shreyansh Jain
  2018-01-25 22:21   ` [PATCH v2 00/10] Introduce generic 'rawdevice' support Thomas Monjalon
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
  11 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-23 13:59 UTC (permalink / raw)
  To: fiona.trahe, thomas; +Cc: dev, hemant.agrawal, rosen.xu, Shreyansh Jain

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5788ea004..c3a8769a2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -302,6 +302,12 @@ F: lib/librte_eventdev/*eth_rx_adapter*
 F: test/test/test_event_eth_rx_adapter.c
 F: doc/guides/prog_guide/event_ethernet_rx_adapter.rst
 
+Rawdev API - EXPERIMENTAL
+M: Shreyansh Jain <shreyansh.jain@nxp.com>
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+F: lib/librte_rawdev/*
+F: test/test/test_rawdev.c
+F: drivers/rawdev/skeleton/*
 
 Bus Drivers
 -----------
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* Re: [PATCH v2 00/10] Introduce generic 'rawdevice' support
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
                     ` (9 preceding siblings ...)
  2018-01-23 13:59   ` [PATCH v2 10/10] maintainers: claim ownership of rawdev Shreyansh Jain
@ 2018-01-25 22:21   ` Thomas Monjalon
  2018-01-29 23:49     ` Thomas Monjalon
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
  11 siblings, 1 reply; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-25 22:21 UTC (permalink / raw)
  To: dev
  Cc: Shreyansh Jain, fiona.trahe, hemant.agrawal, rosen.xu,
	bruce.richardson, konstantin.ananyev, olivier.matz, jerin.jacob

23/01/2018 14:59, Shreyansh Jain:
> Defining a very generic super-set of device type and its device operations that
> can be exposed such that any new/upcoming/experimental device can be layered
> over it. 'rawdevice' semantic in this patchset represents a device that doesn't
> have any flavor/type associated with it which is advertised (like net, crypto
> etc).
> 
> A *rte_rawdevice* is a raw/generic device without any standard configuration
> or input/output method assumption.

Please HELP!
Some reviews would be more than welcome :)

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v2 00/10] Introduce generic 'rawdevice' support
  2018-01-25 22:21   ` [PATCH v2 00/10] Introduce generic 'rawdevice' support Thomas Monjalon
@ 2018-01-29 23:49     ` Thomas Monjalon
  2018-01-30  6:31       ` Shreyansh Jain
  0 siblings, 1 reply; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-29 23:49 UTC (permalink / raw)
  To: Shreyansh Jain
  Cc: dev, fiona.trahe, hemant.agrawal, rosen.xu, bruce.richardson,
	konstantin.ananyev, olivier.matz, jerin.jacob, Neil Horman,
	ferruh.yigit

25/01/2018 23:21, Thomas Monjalon:
> 23/01/2018 14:59, Shreyansh Jain:
> > Defining a very generic super-set of device type and its device operations that
> > can be exposed such that any new/upcoming/experimental device can be layered
> > over it. 'rawdevice' semantic in this patchset represents a device that doesn't
> > have any flavor/type associated with it which is advertised (like net, crypto
> > etc).
> > 
> > A *rte_rawdevice* is a raw/generic device without any standard configuration
> > or input/output method assumption.
> 
> Please HELP!
> Some reviews would be more than welcome :)

No review at all of this new driver class?


Shreyansh, please could you rebase on latest master and add the
__rte_experimental tag as done in this commit:
	http://dpdk.org/commit/77b7b81e32e
Thanks

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v2 00/10] Introduce generic 'rawdevice' support
  2018-01-29 23:49     ` Thomas Monjalon
@ 2018-01-30  6:31       ` Shreyansh Jain
  0 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30  6:31 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, fiona.trahe, hemant.agrawal, rosen.xu, bruce.richardson,
	konstantin.ananyev, olivier.matz, jerin.jacob, Neil Horman,
	ferruh.yigit

On Tuesday 30 January 2018 05:19 AM, Thomas Monjalon wrote:
> 25/01/2018 23:21, Thomas Monjalon:
>> 23/01/2018 14:59, Shreyansh Jain:
>>> Defining a very generic super-set of device type and its device operations that
>>> can be exposed such that any new/upcoming/experimental device can be layered
>>> over it. 'rawdevice' semantic in this patchset represents a device that doesn't
>>> have any flavor/type associated with it which is advertised (like net, crypto
>>> etc).
>>>
>>> A *rte_rawdevice* is a raw/generic device without any standard configuration
>>> or input/output method assumption.
>>
>> Please HELP!
>> Some reviews would be more than welcome :)
> 
> No review at all of this new driver class?
> 
> 
> Shreyansh, please could you rebase on latest master and add the
> __rte_experimental tag as done in this commit:
> 	http://dpdk.org/commit/77b7b81e32e
> Thanks
> 

OK. I will do that - thanks for reference.
I will send a v3 along with some documentation support as well.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v3 00/11] Introduce generic 'rawdevice' support
  2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
                     ` (10 preceding siblings ...)
  2018-01-25 22:21   ` [PATCH v2 00/10] Introduce generic 'rawdevice' support Thomas Monjalon
@ 2018-01-30 14:56   ` Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 01/11] rawdev: introduce raw device library support Shreyansh Jain
                       ` (12 more replies)
  11 siblings, 13 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:56 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Change History
~~~~~~~~~~~~~~
v3:
 - rebased over master (367bc2a9fd)
 - added __rte_experimental flag
 - added initial documentation
 
v2:
 - restructure comments to prefix model
 - split patches pivoted on APIs introduced in library
 - moved test into drivers/rawdev/skeleton from test/test
 - removed unused RTE_MAX_RAWDEVPORTS and RTE_MAX_RAWDEVS
 - merge patch configurations
 - checkpatch fixes

Rawdevice Support in DPDK
-------------------------

RFC [1]
v1: [2]
v2: [3]

This patchset introduces rawdevices or generic device support in DPDK.

Motivation
==========

In terms of device flavor (type) support, DPDK currently has ethernet
(lib_ether), cryptodev (libcryptodev), eventdev (libeventdev) and vdev
(virtual device) support.

For a new type of device, for example an accelerator, there are not many
options except either of:
1. create another lib/librte_MySpecialDev, driver/MySpecialDrv and use it
through Bus/PMD model.
2. Or, create a vdev and implement necessary custom APIs which are directly
exposed from driver layer. However this may still require changes in bus code
in DPDK.

Either method is unclean (touching lib for specific context) and possibly
non-upstreamable (custom APIs). Applications and customers prefers uniform
device view and programming model.

Scope
=====

The rawdevice implementation is targetted towards various accelerator use cases
which cannot be generalized within existing device models. Aim is to provided a
generalized structure at the cost of portability guarantee. Specific PMDs may
also expose any specific config APIs. Applications built over such devices are
special use-cases involving IP blocks.

The rawdevice may also connect to other standard devices using adapter or other
methods, similar to eventdev adpter for ethernet/crypto devices.

Proposed Solution
=================

Defining a very generic super-set of device type and its device operations that
can be exposed such that any new/upcoming/experimental device can be layered
over it. 'rawdevice' semantic in this patchset represents a device that doesn't
have any flavor/type associated with it which is advertised (like net, crypto
etc).

A *rte_rawdevice* is a raw/generic device without any standard configuration
or input/output method assumption.

Thus, driver for a new accelerator block, which requires operations for
start/stop/enqueue/dequeue, can be quickly strapped over this rawdevice layer.
Thereafter, any appropriate bus can scan for it (assuming device is discoverable
over the Linux interfaces like sysfs) and match it against registered drivers.

Similarly, for a new accelerator or a wireless device, which doesn't fit the eth
type, a driver can be registered with a bus (on which its device would be
scannable) and use this layer for configuring the device.

It can also serve as a staging area for new type of devices till they find some
commonality and can be standardized.

The outline of this proposed library is same as existing ether/crypto devices.

     +-----------------------------------------------------------+
     |                        Application(s)                     |
     +------------------------------.----------------------------+
                                    |
                                    |
     +------------------------------'----------------------------+
     |                     DPDK Framework (APIs)                 |
     +--------------|----|-----------------|---------------------+
                   /      \                 \
            (crypto ops)  (eth ops)      (rawdev ops)        +----+
            /               \                 \              |DrvA|
     +-----'---+        +----`----+        +---'-----+       +----+
     | crypto  |        | ethdev  |        | raw     |
     +--/------+        +---/-----+        +----/----+       +----+
       /\                __/\                  /   ..........|DrvB|
      /  \              /    \                / ../    \     +----+
  +====+ +====+    +====+ +====+            +==/=+      ```Bus Probe 
  |DevA| |DevB|    |DevC| |DevD|            |DevF|
  +====+ +====+    +====+ +====+            +====+
    |      |        |      |                 |    
  ``|``````|````````|``````|`````````````````|````````Bus Scan
   (PCI)   |       (PCI)  (PCI)            (PCI)
         (BusA)

 * It is assumed above that DrvB is a PCI type driver which registers itself
   with PCI Bus
 * Thereafter, when the PCI scan is done, during probe DrvB would match the
   rawdev DevF ID and take control of device
 * Applications can then continue using the device through rawdev API interfaces

Proposed Interfaces
===================

Following broad API categories are exposed by the rawdevice:

1) Device State Operations (start/stop/reset)
2) Communication Channel setup/teardown (queue)
3) Attribute get/set operations (~ioctls)
4) Enqueue/Dequeue Operations (using opaque buffers)
5) Firmware Operations (Load/unload)

Notes:
For (1), other than standard start/stop, reset has been added extra. This is for
cases where device power cycle has various definitions. Semantics of what
stop->start and what reset would mean are still open-ended.

For (2), though currently `queue` has been used a semantic, it would be possible
in implementation to use this with other methods like internally hosted rte_ring.

For (3), applications can pass on an opaque attribute handle/information which
the driver can act upon.

For (4), aim is to allow applications to post buffers (which can be arbit data)
to the device. It is device's responsibility to interpret and handle the buffer.
It can also be expanded to synchronous and async methods of posting buffer.
That would provide broader use-cases.

For (5), Aim is to allow for most basic device firmware management. In this, as
well as other operations, it is expected that those which are not implemneted
would return ENOTSUP allow the application to fail gracefully.

Future Work
===========
1. Support for hotplugging and interrupt handling
2. Support for callbacks for enqueue and dequeue of buffers
3. Interfacing with Eth/Crypto/Event type devices for inline offloading

References
==========
[1]: http://dpdk.org/ml/archives/dev/2017-November/081550.html
[2]: http://dpdk.org/ml/archives/dev/2018-January/085121.html
[3]: http://dpdk.org/ml/archives/dev/2018-January/088723.html

Shreyansh Jain (11):
  rawdev: introduce raw device library support
  rawdev: add attribute get and set support
  rawdev: add buffer stream IO support
  rawdev: support for extended stats
  rawdev: support for firmware management
  rawdev: add self test support
  drivers/raw: introduce skeleton rawdev driver
  drivers/raw: support for rawdev testcases
  test: enable rawdev skeleton test
  maintainers: claim ownership of rawdev
  doc: add rawdev library page

 MAINTAINERS                                        |   6 +
 config/common_base                                 |   8 +
 doc/guides/prog_guide/index.rst                    |   1 +
 doc/guides/prog_guide/rawdev_lib.rst               |  83 +++
 drivers/Makefile                                   |   2 +
 drivers/raw/Makefile                               |   9 +
 drivers/raw/skeleton_rawdev/Makefile               |  28 +
 .../rte_pmd_skeleton_rawdev_version.map            |   4 +
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      | 754 +++++++++++++++++++++
 drivers/raw/skeleton_rawdev/skeleton_rawdev.h      | 136 ++++
 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c | 431 ++++++++++++
 lib/Makefile                                       |   3 +
 lib/librte_rawdev/Makefile                         |  28 +
 lib/librte_rawdev/rte_rawdev.c                     | 546 +++++++++++++++
 lib/librte_rawdev/rte_rawdev.h                     | 597 ++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h                 | 605 +++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map           |  34 +
 mk/rte.app.mk                                      |   5 +
 test/test/Makefile                                 |   4 +
 test/test/test_rawdev.c                            |  27 +
 20 files changed, 3311 insertions(+)
 create mode 100644 doc/guides/prog_guide/rawdev_lib.rst
 create mode 100644 drivers/raw/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.c
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.h
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
 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
 create mode 100644 test/test/test_rawdev.c

-- 
2.14.1

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v3 01/11] rawdev: introduce raw device library support
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
@ 2018-01-30 14:57     ` Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 02/11] rawdev: add attribute get and set support Shreyansh Jain
                       ` (11 subsequent siblings)
  12 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:57 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Each device in DPDK has a type associated with it - ethernet, crypto,
event etc. This patch introduces 'rawdevice' which is a generic
type of device, not currently handled out-of-the-box by DPDK.

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. Using opaque
data (pointer) as API arguments, library allows a high flexibility
for application and driver implementation.

This patch introduces basic device operations like start, stop, reset,
queue and info support.
Subsequent patches would introduce other operations like buffer
enqueue/dequeue and firmware support.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 config/common_base                       |   7 +
 lib/Makefile                             |   3 +
 lib/librte_rawdev/Makefile               |  28 +++
 lib/librte_rawdev/rte_rawdev.c           | 360 +++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 314 +++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 352 ++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  21 ++
 mk/rte.app.mk                            |   1 +
 8 files changed, 1086 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/config/common_base b/config/common_base
index c560b73da..812cff129 100644
--- a/config/common_base
+++ b/config/common_base
@@ -805,6 +805,13 @@ CONFIG_RTE_LIBRTE_VHOST=n
 CONFIG_RTE_LIBRTE_VHOST_NUMA=n
 CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
 
+#
+# Compile raw device support
+# EXPERIMENTAL: API may change without prior notice
+#
+CONFIG_RTE_LIBRTE_RAWDEV=y
+CONFIG_RTE_RAWDEV_MAX_DEVS=10
+
 #
 # Compile vhost PMD
 # To compile, CONFIG_RTE_LIBRTE_VHOST should be enabled.
diff --git a/lib/Makefile b/lib/Makefile
index 427f34b00..97080a590 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -102,4 +102,7 @@ endif
 DEPDIRS-librte_kni := librte_eal librte_mempool librte_mbuf librte_ether
 DEPDIRS-librte_kni += librte_pci
 
+DIRS-$(CONFIG_RTE_LIBRTE_RAWDEV) += librte_rawdev
+DEPDIRS-librte_rawdev := librte_eal librte_ether
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/lib/librte_rawdev/Makefile b/lib/librte_rawdev/Makefile
new file mode 100644
index 000000000..b9105b060
--- /dev/null
+++ b/lib/librte_rawdev/Makefile
@@ -0,0 +1,28 @@
+# 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 += -DALLOW_EXPERIMENTAL_API
+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..46353a4eb
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -0,0 +1,360 @@
+/* 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;
+
+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_experimental
+rte_rawdev_count(void)
+{
+	return rte_rawdev_globals->nb_devs;
+}
+
+uint16_t __rte_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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);
+}
+
+int __rte_experimental
+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_experimental
+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_experimental
+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_experimental
+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_RAWDEV_MAX_DEVS; dev_id++) {
+		if (rte_rawdevs[dev_id].attached ==
+				RTE_RAWDEV_DETACHED)
+			return dev_id;
+	}
+
+	return RTE_RAWDEV_MAX_DEVS;
+}
+
+struct rte_rawdev * __rte_experimental
+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_RAWDEV_MAX_DEVS) {
+		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_experimental
+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("lib.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..e13b11400
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -0,0 +1,314 @@
+/* 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>
+
+/* 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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+rte_rawdev_queue_setup(uint16_t dev_id,
+		       uint16_t queue_id,
+		       rte_rawdev_obj_t queue_conf);
+
+/**
+ * Release and deallocate a raw queue from a raw device.
+ *
+ * @param dev_id
+ *   The identifier of the device.
+ * @param queue_id
+ *   The index of the raw queue to release. 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 released.
+ *   - <0: raw queue configuration failed
+ */
+int __rte_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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 {
+	/**< Socket ID where memory is allocated */
+	int socket_id;
+	/**< Device ID for this instance */
+	uint16_t dev_id;
+	/**< Functions exported by PMD */
+	const struct rte_rawdev_ops *dev_ops;
+	/**< Device info. supplied during device initialization */
+	struct rte_device *device;
+	/**< Driver info. supplied by probing */
+	const char *driver_name;
+
+	RTE_STD_C11
+	/**< Flag indicating the device is attached */
+	uint8_t attached : 1;
+	/**< Device state: STARTED(1)/STOPPED(0) */
+	uint8_t started : 1;
+
+	/**< PMD-specific private data */
+	rte_rawdev_obj_t dev_private;
+	/**< Device name */
+	char name[RTE_RAWDEV_NAME_MAX_LEN];
+} __rte_cache_aligned;
+
+/** @internal The pool of rte_rawdev structures. */
+extern struct rte_rawdev *rte_rawdevs;
+
+
+struct rte_rawdev_info {
+	/**< Name of driver handling this device */
+	const char *driver_name;
+	/**< Device encapsulation */
+	struct rte_device *device;
+	/**< Socket ID where memory is allocated */
+	int socket_id;
+	/**< PMD-specific private data */
+	rte_rawdev_obj_t dev_private;
+};
+
+struct rte_rawdev_buf {
+	/**< Opaque buffer reference */
+	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_experimental
+rte_rawdev_dump(uint16_t dev_id, FILE *f);
+
+#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..ca6e6a1c8
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -0,0 +1,352 @@
+/* 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: Can 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 {
+	/**< Number of devices found */
+	uint16_t nb_devs;
+};
+
+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);
+
+/**
+ * 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);
+
+/** Rawdevice operations function pointer table */
+struct rte_rawdev_ops {
+	/**< Get device info. */
+	rawdev_info_get_t dev_info_get;
+	/**< Configure device. */
+	rawdev_configure_t dev_configure;
+	/**< Start device. */
+	rawdev_start_t dev_start;
+	/**< Stop device. */
+	rawdev_stop_t dev_stop;
+	/**< Close device. */
+	rawdev_close_t dev_close;
+	/**< Reset device. */
+	rawdev_reset_t dev_reset;
+
+	/**< Get raw queue configuration. */
+	rawdev_queue_conf_get_t queue_def_conf;
+	/**< Set up an raw queue. */
+	rawdev_queue_setup_t queue_setup;
+	/**< Release an raw queue. */
+	rawdev_queue_release_t queue_release;
+
+	/* Dump internal information */
+	rawdev_dump_t dump;
+};
+
+/**
+ * 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_experimental
+rte_rawdev_pmd_allocate(const char *name, size_t dev_private_size,
+			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_experimental
+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_experimental
+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_experimental
+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..64e60d945
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -0,0 +1,21 @@
+EXPERIMENTAL {
+	global:
+
+	rte_rawdev_close;
+	rte_rawdev_configure;
+	rte_rawdev_count;
+	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_rawdevs;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 0169f3f5b..b201e861d 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -105,6 +105,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
+_LDLIBS-$(CONFIG_RTE_LIBRTE_RAWDEV)         += -lrte_rawdev
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 02/11] rawdev: add attribute get and set support
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 01/11] rawdev: introduce raw device library support Shreyansh Jain
@ 2018-01-30 14:57     ` Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 03/11] rawdev: add buffer stream IO support Shreyansh Jain
                       ` (10 subsequent siblings)
  12 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:57 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

A rawdevice can have various attributes. This patch introduce support
for transparently setting attribute value or getting current attribute
state. This is done by allowing an opaque set of key and value to be
passed through rawdev library.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           | 28 +++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 43 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 42 +++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  2 ++
 4 files changed, 115 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index 46353a4eb..08dd982a4 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -175,6 +175,34 @@ rte_rawdev_queue_release(uint16_t dev_id, uint16_t queue_id)
 	return (*dev->dev_ops->queue_release)(dev, queue_id);
 }
 
+int __rte_experimental
+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_experimental
+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_experimental
 rte_rawdev_dump(uint16_t dev_id, FILE *f)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index e13b11400..bfcbe1270 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -307,6 +307,49 @@ struct rte_rawdev_buf {
 int __rte_experimental
 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_experimental
+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_experimental
+rte_rawdev_set_attr(uint16_t dev_id,
+		    const char *attr_name,
+		    const uint64_t attr_value);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index ca6e6a1c8..aa67c4f39 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -262,6 +262,43 @@ typedef int (*rawdev_queue_release_t)(struct rte_rawdev *dev,
  */
 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);
+
 /** Rawdevice operations function pointer table */
 struct rte_rawdev_ops {
 	/**< Get device info. */
@@ -286,6 +323,11 @@ struct rte_rawdev_ops {
 
 	/* Dump internal information */
 	rawdev_dump_t dump;
+
+	/**< Get an attribute managed by the implementation */
+	rawdev_get_attr_t attr_get;
+	/**< Set an attribute managed by the implementation */
+	rawdev_set_attr_t attr_set;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index 64e60d945..d63476e47 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -4,6 +4,7 @@ EXPERIMENTAL {
 	rte_rawdev_close;
 	rte_rawdev_configure;
 	rte_rawdev_count;
+	rte_rawdev_get_attr;
 	rte_rawdev_get_dev_id;
 	rte_rawdev_info_get;
 	rte_rawdev_pmd_allocate;
@@ -12,6 +13,7 @@ EXPERIMENTAL {
 	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;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 03/11] rawdev: add buffer stream IO support
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 01/11] rawdev: introduce raw device library support Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 02/11] rawdev: add attribute get and set support Shreyansh Jain
@ 2018-01-30 14:57     ` Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 04/11] rawdev: support for extended stats Shreyansh Jain
                       ` (9 subsequent siblings)
  12 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:57 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Introduce handlers for raw buffer enqueue and dequeue. A raw buffer
is essentially a void object which is transparently passed via the
library onto the driver.

Using a context field as argument, any arbitrary meta information
can be passed by application to the driver/implementation. This can
be any data on which driver needs to define the operation semantics.
For example, passing along a queue identifier can suggest the driver
the queue context to perform I/O on.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           | 30 +++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 58 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 58 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  2 ++
 4 files changed, 148 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index 08dd982a4..a6d937c34 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -203,6 +203,36 @@ rte_rawdev_set_attr(uint16_t dev_id,
 	return (*dev->dev_ops->attr_set)(dev, attr_name, attr_value);
 }
 
+int __rte_experimental
+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_experimental
+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_experimental
 rte_rawdev_dump(uint16_t dev_id, FILE *f)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index bfcbe1270..b4f9aee37 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -350,6 +350,64 @@ 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_experimental
+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_experimental
+rte_rawdev_dequeue_buffers(uint16_t dev_id,
+			   struct rte_rawdev_buf **buffers,
+			   unsigned int count,
+			   rte_rawdev_obj_t context);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index aa67c4f39..da891dc4d 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -248,6 +248,58 @@ typedef int (*rawdev_queue_setup_t)(struct rte_rawdev *dev,
 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
  *
@@ -321,6 +373,12 @@ struct rte_rawdev_ops {
 	/**< Release an raw queue. */
 	rawdev_queue_release_t queue_release;
 
+	/**< Enqueue an array of raw buffers to device. */
+	rawdev_enqueue_bufs_t enqueue_bufs;
+	/**< Dequeue an array of raw buffers from device. */
+	/** TODO: Callback based enqueue and dequeue support */
+	rawdev_dequeue_bufs_t dequeue_bufs;
+
 	/* Dump internal information */
 	rawdev_dump_t dump;
 
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index d63476e47..bafe2c5de 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -4,6 +4,8 @@ EXPERIMENTAL {
 	rte_rawdev_close;
 	rte_rawdev_configure;
 	rte_rawdev_count;
+	rte_rawdev_dequeue_buffers;
+	rte_rawdev_enqueue_buffers;
 	rte_rawdev_get_attr;
 	rte_rawdev_get_dev_id;
 	rte_rawdev_info_get;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 04/11] rawdev: support for extended stats
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
                       ` (2 preceding siblings ...)
  2018-01-30 14:57     ` [PATCH v3 03/11] rawdev: add buffer stream IO support Shreyansh Jain
@ 2018-01-30 14:57     ` Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 05/11] rawdev: support for firmware management Shreyansh Jain
                       ` (8 subsequent siblings)
  12 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:57 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Generic rawdev library cannot define a pre-defined set of stats
for devices which are yet to be defined.

This patch introduces the xstats support for rawdev so that any
implementation can create its own statistics.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           |  75 ++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 105 +++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       |  72 +++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |   4 ++
 4 files changed, 256 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index a6d937c34..d6c284554 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -245,6 +245,81 @@ rte_rawdev_dump(uint16_t dev_id, FILE *f)
 	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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
 rte_rawdev_start(uint16_t dev_id)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index b4f9aee37..8e3d72273 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -408,6 +408,111 @@ rte_rawdev_dequeue_buffers(uint16_t dev_id,
 			   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_experimental
+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_experimental
+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_experimental
+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_experimental
+rte_rawdev_xstats_reset(uint16_t dev_id,
+			const uint32_t ids[],
+			uint32_t nb_ids);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index da891dc4d..2ef380988 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -351,6 +351,69 @@ 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);
 /** Rawdevice operations function pointer table */
 struct rte_rawdev_ops {
 	/**< Get device info. */
@@ -386,6 +449,15 @@ struct rte_rawdev_ops {
 	rawdev_get_attr_t attr_get;
 	/**< Set an attribute managed by the implementation */
 	rawdev_set_attr_t attr_set;
+
+	/**< Get extended device statistics. */
+	rawdev_xstats_get_t xstats_get;
+	/**< Get names of extended stats. */
+	rawdev_xstats_get_names_t xstats_get_names;
+	/**< Get one value by name. */
+	rawdev_xstats_get_by_name_t xstats_get_by_name;
+	/**< Reset the statistics values in xstats. */
+	rawdev_xstats_reset_t xstats_reset;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index bafe2c5de..469b78d81 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -19,6 +19,10 @@ EXPERIMENTAL {
 	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

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 05/11] rawdev: support for firmware management
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
                       ` (3 preceding siblings ...)
  2018-01-30 14:57     ` [PATCH v3 04/11] rawdev: support for extended stats Shreyansh Jain
@ 2018-01-30 14:57     ` Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 06/11] rawdev: add self test support Shreyansh Jain
                       ` (7 subsequent siblings)
  12 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:57 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Some generic operations for firmware management can loading, unloading,
starting, stopping and querying firmware of a device.

This patch adds support for such generic operations.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           | 43 ++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 64 +++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 70 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  4 ++
 4 files changed, 181 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index d6c284554..b52293c47 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -320,6 +320,49 @@ rte_rawdev_xstats_reset(uint16_t dev_id,
 	return (*dev->dev_ops->xstats_reset)(dev, ids, nb_ids);
 }
 
+int __rte_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
 rte_rawdev_start(uint16_t dev_id)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index 8e3d72273..8eab3974f 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -513,6 +513,70 @@ 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_experimental
+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_experimental
+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 successful load
+ *  !0 for failure to load the provided image, or image incorrect.
+ */
+int __rte_experimental
+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_experimental
+rte_rawdev_firmware_unload(uint16_t dev_id);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index 2ef380988..f74bf171a 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -414,6 +414,67 @@ typedef int (*rawdev_xstats_get_names_t)(const struct rte_rawdev *dev,
 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 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,
+				      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 {
 	/**< Get device info. */
@@ -458,6 +519,15 @@ struct rte_rawdev_ops {
 	rawdev_xstats_get_by_name_t xstats_get_by_name;
 	/**< Reset the statistics values in xstats. */
 	rawdev_xstats_reset_t xstats_reset;
+
+	/**< Obtainer firmware status */
+	rawdev_firmware_status_get_t firmware_status_get;
+	/**< Obtain firmware version information */
+	rawdev_firmware_version_get_t firmware_version_get;
+	/**< Load firmware */
+	rawdev_firmware_load_t firmware_load;
+	/**< Unload firmware */
+	rawdev_firmware_unload_t firmware_unload;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index 469b78d81..8de9abdc4 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -6,6 +6,10 @@ EXPERIMENTAL {
 	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;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 06/11] rawdev: add self test support
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
                       ` (4 preceding siblings ...)
  2018-01-30 14:57     ` [PATCH v3 05/11] rawdev: support for firmware management Shreyansh Jain
@ 2018-01-30 14:57     ` Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 07/11] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
                       ` (6 subsequent siblings)
  12 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:57 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           | 10 ++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 13 +++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 11 +++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  1 +
 4 files changed, 35 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index b52293c47..d314ef96b 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -363,6 +363,16 @@ rte_rawdev_firmware_unload(uint16_t dev_id)
 	return (*dev->dev_ops->firmware_unload)(dev);
 }
 
+int __rte_experimental
+rte_rawdev_selftest(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->dev_selftest, -ENOTSUP);
+	return (*dev->dev_ops->dev_selftest)();
+}
+
 int __rte_experimental
 rte_rawdev_start(uint16_t dev_id)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index 8eab3974f..5946ea67c 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -577,6 +577,19 @@ rte_rawdev_firmware_load(uint16_t dev_id, rte_rawdev_obj_t firmware_image);
 int __rte_experimental
 rte_rawdev_firmware_unload(uint16_t dev_id);
 
+/**
+ * Trigger the rawdev self test.
+ *
+ * @param dev_id
+ *   The identifier of the device
+ * @return
+ *   - 0: Selftest successful
+ *   - -ENOTSUP if the device doesn't support selftest
+ *   - other values < 0 on failure.
+ */
+int __rte_experimental
+rte_rawdev_selftest(uint16_t dev_id);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index f74bf171a..eb8f68b8b 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -475,6 +475,14 @@ typedef int (*rawdev_firmware_load_t)(struct rte_rawdev *dev,
  */
 typedef int (*rawdev_firmware_unload_t)(struct rte_rawdev *dev);
 
+/**
+ * Start rawdev selftest
+ *
+ * @return
+ *   Return 0 on success
+ */
+typedef int (*rawdev_selftest_t)(void);
+
 /** Rawdevice operations function pointer table */
 struct rte_rawdev_ops {
 	/**< Get device info. */
@@ -528,6 +536,9 @@ struct rte_rawdev_ops {
 	rawdev_firmware_load_t firmware_load;
 	/**< Unload firmware */
 	rawdev_firmware_unload_t firmware_unload;
+
+	/**< Device selftest function */
+	rawdev_selftest_t dev_selftest;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index 8de9abdc4..af4465e26 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -19,6 +19,7 @@ EXPERIMENTAL {
 	rte_rawdev_queue_setup;
 	rte_rawdev_queue_release;
 	rte_rawdev_reset;
+	rte_rawdev_selftest;
 	rte_rawdev_set_attr;
 	rte_rawdev_socket_id;
 	rte_rawdev_start;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 07/11] drivers/raw: introduce skeleton rawdev driver
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
                       ` (5 preceding siblings ...)
  2018-01-30 14:57     ` [PATCH v3 06/11] rawdev: add self test support Shreyansh Jain
@ 2018-01-30 14:57     ` Shreyansh Jain
  2018-01-30 16:48       ` Thomas Monjalon
  2018-01-30 14:57     ` [PATCH v3 08/11] drivers/raw: support for rawdev testcases Shreyansh Jain
                       ` (5 subsequent siblings)
  12 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:57 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Skeleton rawdevice driver, on the lines of eventdev skeleton, is for
showcasing the rawdev library. This driver implements some of the
operations of the library based on which a test module can be
developed.

Design of skeleton involves a virtual device which is plugged into
VDEV bus on initialization.

Also, enable compilation of rawdev skeleton driver.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 config/common_base                                 |   1 +
 drivers/Makefile                                   |   2 +
 drivers/raw/Makefile                               |   9 +
 drivers/raw/skeleton_rawdev/Makefile               |  27 +
 .../rte_pmd_skeleton_rawdev_version.map            |   4 +
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      | 690 +++++++++++++++++++++
 drivers/raw/skeleton_rawdev/skeleton_rawdev.h      | 136 ++++
 mk/rte.app.mk                                      |   4 +
 8 files changed, 873 insertions(+)
 create mode 100644 drivers/raw/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.c
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.h

diff --git a/config/common_base b/config/common_base
index 812cff129..0002f83a2 100644
--- a/config/common_base
+++ b/config/common_base
@@ -811,6 +811,7 @@ CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
 #
 CONFIG_RTE_LIBRTE_RAWDEV=y
 CONFIG_RTE_RAWDEV_MAX_DEVS=10
+CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
 
 #
 # Compile vhost PMD
diff --git a/drivers/Makefile b/drivers/Makefile
index e0488aa2b..ee65c87b0 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -14,5 +14,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
 DEPDIRS-crypto := bus mempool
 DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event
 DEPDIRS-event := bus mempool net
+DIRS-$(CONFIG_RTE_LIBRTE_RAWDEV) += raw
+DEPDIRS-raw := bus mempool net event
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
new file mode 100644
index 000000000..da7c8b449
--- /dev/null
+++ b/drivers/raw/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2017 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# DIRS-$(<configuration>) += <directory>
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/skeleton_rawdev/Makefile b/drivers/raw/skeleton_rawdev/Makefile
new file mode 100644
index 000000000..6318359d1
--- /dev/null
+++ b/drivers/raw/skeleton_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_pmd_skeleton_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_bus_vdev
+
+EXPORT_MAP := rte_pmd_skeleton_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map b/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
new file mode 100644
index 000000000..179140fb8
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_18.02 {
+
+	local: *;
+};
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
new file mode 100644
index 000000000..b38188e11
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
@@ -0,0 +1,690 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_debug.h>
+#include <rte_dev.h>
+#include <rte_eal.h>
+#include <rte_kvargs.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_lcore.h>
+#include <rte_bus_vdev.h>
+
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "skeleton_rawdev.h"
+
+/* Dynamic log type identifier */
+int skeleton_pmd_logtype;
+
+/* Count of instances */
+uint16_t skeldev_init_once;
+
+/**< Rawdev Skeleton dummy driver name */
+#define SKELETON_PMD_RAWDEV_NAME rawdev_skeleton
+
+/**< Skeleton rawdev driver object */
+static struct rte_vdev_driver skeleton_pmd_drv;
+
+struct queue_buffers {
+	void *bufs[SKELETON_QUEUE_MAX_DEPTH];
+};
+
+static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {0};
+static void clear_queue_bufs(int queue_id);
+
+static void skeleton_rawdev_info_get(struct rte_rawdev *dev,
+				     rte_rawdev_obj_t dev_info)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_conf *skeldev_conf;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev_info) {
+		SKELETON_PMD_ERR("Invalid request");
+		return;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	skeldev_conf = dev_info;
+
+	skeldev_conf->num_queues = skeldev->num_queues;
+	skeldev_conf->capabilities = skeldev->capabilities;
+	skeldev_conf->device_state = skeldev->device_state;
+	skeldev_conf->firmware_state = skeldev->fw.firmware_state;
+}
+
+static int skeleton_rawdev_configure(const struct rte_rawdev *dev,
+				     rte_rawdev_obj_t config)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_conf *skeldev_conf;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	if (!config) {
+		SKELETON_PMD_ERR("Invalid configuration");
+		return -EINVAL;
+	}
+
+	skeldev_conf = config;
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	if (skeldev_conf->num_queues <= SKELETON_MAX_QUEUES)
+		skeldev->num_queues = skeldev_conf->num_queues;
+	else
+		return -EINVAL;
+
+	skeldev->capabilities = skeldev_conf->capabilities;
+	skeldev->num_queues = skeldev_conf->num_queues;
+
+	return 0;
+}
+
+static int skeleton_rawdev_start(struct rte_rawdev *dev)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+	enum skeleton_firmware_state fw_state;
+	enum skeleton_device_state device_state;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	fw_state = skeldev->fw.firmware_state;
+	device_state = skeldev->device_state;
+
+	if (fw_state == SKELETON_FW_LOADED &&
+		device_state == SKELETON_DEV_STOPPED) {
+		skeldev->device_state = SKELETON_DEV_RUNNING;
+	} else {
+		SKELETON_PMD_ERR("Device not ready for starting");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void skeleton_rawdev_stop(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (dev) {
+		skeldev = skeleton_rawdev_get_priv(dev);
+		skeldev->device_state = SKELETON_DEV_STOPPED;
+	}
+}
+
+static void
+reset_queues(struct skeleton_rawdev *skeldev)
+{
+	int i;
+
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
+		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
+		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
+	}
+}
+
+static void
+reset_attribute_table(struct skeleton_rawdev *skeldev)
+{
+	int i;
+
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (skeldev->attr[i].name) {
+			free(skeldev->attr[i].name);
+			skeldev->attr[i].name = NULL;
+		}
+	}
+}
+
+static int skeleton_rawdev_close(struct rte_rawdev *dev)
+{
+	int ret = 0, i;
+	struct skeleton_rawdev *skeldev;
+	enum skeleton_firmware_state fw_state;
+	enum skeleton_device_state device_state;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	fw_state = skeldev->fw.firmware_state;
+	device_state = skeldev->device_state;
+
+	reset_queues(skeldev);
+	reset_attribute_table(skeldev);
+
+	switch (fw_state) {
+	case SKELETON_FW_LOADED:
+		if (device_state == SKELETON_DEV_RUNNING) {
+			SKELETON_PMD_ERR("Cannot close running device");
+			ret = -EINVAL;
+		} else {
+			/* Probably call fw reset here */
+			skeldev->fw.firmware_state = SKELETON_FW_READY;
+		}
+		break;
+	case SKELETON_FW_READY:
+	case SKELETON_FW_ERROR:
+	default:
+		SKELETON_PMD_DEBUG("Device already in stopped state");
+		ret = -EINVAL;
+		break;
+	}
+
+	/* Clear all allocated queues */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
+		clear_queue_bufs(i);
+
+	return ret;
+}
+
+static int skeleton_rawdev_reset(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	SKELETON_PMD_DEBUG("Reseting device");
+	skeldev->fw.firmware_state = SKELETON_FW_READY;
+
+	return 0;
+}
+
+static void skeleton_rawdev_queue_def_conf(struct rte_rawdev *dev,
+					   uint16_t queue_id,
+					   rte_rawdev_obj_t queue_conf)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_queue *skelq;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !queue_conf)
+		return;
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	skelq = &skeldev->queues[queue_id];
+
+	if (queue_id < SKELETON_MAX_QUEUES)
+		rte_memcpy(queue_conf, skelq,
+			sizeof(struct skeleton_rawdev_queue));
+}
+
+static void
+clear_queue_bufs(int queue_id)
+{
+	int i;
+
+	/* Clear buffers for queue_id */
+	for (i = 0; i < SKELETON_QUEUE_MAX_DEPTH; i++)
+		queue_buf[queue_id].bufs[i] = NULL;
+}
+
+static int skeleton_rawdev_queue_setup(struct rte_rawdev *dev,
+				       uint16_t queue_id,
+				       rte_rawdev_obj_t queue_conf)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_queue *q;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !queue_conf)
+		return -EINVAL;
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	q = &skeldev->queues[queue_id];
+
+	if (skeldev->num_queues > queue_id &&
+	    q->depth < SKELETON_QUEUE_MAX_DEPTH) {
+		rte_memcpy(q, queue_conf,
+			   sizeof(struct skeleton_rawdev_queue));
+		clear_queue_bufs(queue_id);
+	} else {
+		SKELETON_PMD_ERR("Invalid queue configuration");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int skeleton_rawdev_queue_release(struct rte_rawdev *dev,
+					 uint16_t queue_id)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	if (skeldev->num_queues > queue_id) {
+		skeldev->queues[queue_id].state = SKELETON_QUEUE_DETACH;
+		skeldev->queues[queue_id].depth = SKELETON_QUEUE_DEF_DEPTH;
+		clear_queue_bufs(queue_id);
+	} else {
+		SKELETON_PMD_ERR("Invalid queue configuration");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int skeleton_rawdev_get_attr(struct rte_rawdev *dev,
+				    const char *attr_name,
+				    uint64_t *attr_value)
+{
+	int i;
+	uint8_t done = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !attr_name || !attr_value) {
+		SKELETON_PMD_ERR("Invalid arguments for getting attributes");
+		return -EINVAL;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (!skeldev->attr[i].name)
+			continue;
+
+		if (!strncmp(skeldev->attr[i].name, attr_name,
+			    SKELETON_ATTRIBUTE_NAME_MAX)) {
+			*attr_value = skeldev->attr[i].value;
+			done = 1;
+			SKELETON_PMD_DEBUG("Attribute (%s) Value (%lu)",
+					   attr_name, *attr_value);
+			break;
+		}
+	}
+
+	if (done)
+		return 0;
+
+	/* Attribute not found */
+	return -EINVAL;
+}
+
+static int skeleton_rawdev_set_attr(struct rte_rawdev *dev,
+				     const char *attr_name,
+				     const uint64_t attr_value)
+{
+	int i;
+	uint8_t done = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !attr_name) {
+		SKELETON_PMD_ERR("Invalid arguments for setting attributes");
+		return -EINVAL;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	/* Check if attribute already exists */
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (!skeldev->attr[i].name)
+			break;
+
+		if (!strncmp(skeldev->attr[i].name, attr_name,
+			     SKELETON_ATTRIBUTE_NAME_MAX)) {
+			/* Update value */
+			skeldev->attr[i].value = attr_value;
+			done = 1;
+			break;
+		}
+	}
+
+	if (!done) {
+		if (i < (SKELETON_MAX_ATTRIBUTES - 1)) {
+			/* There is still space to insert one more */
+			skeldev->attr[i].name = strdup(attr_name);
+			if (!skeldev->attr[i].name)
+				return -ENOMEM;
+
+			skeldev->attr[i].value = attr_value;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int skeleton_rawdev_enqueue_bufs(struct rte_rawdev *dev,
+					struct rte_rawdev_buf **buffers,
+					unsigned int count,
+					rte_rawdev_obj_t context)
+{
+	unsigned int i;
+	uint16_t q_id;
+	RTE_SET_USED(dev);
+
+	/* context is essentially the queue_id which is
+	 * transferred as opaque object through the library layer. This can
+	 * help in complex implementation which require more information than
+	 * just an integer - for example, a queue-pair.
+	 */
+	q_id = *((int *)context);
+
+	for (i = 0; i < count; i++)
+		queue_buf[q_id].bufs[i] = buffers[i]->buf_addr;
+
+	return i;
+}
+
+static int skeleton_rawdev_dequeue_bufs(struct rte_rawdev *dev,
+					struct rte_rawdev_buf **buffers,
+					unsigned int count,
+					rte_rawdev_obj_t context)
+{
+	unsigned int i;
+	uint16_t q_id;
+	RTE_SET_USED(dev);
+
+	/* context is essentially the queue_id which is
+	 * transferred as opaque object through the library layer. This can
+	 * help in complex implementation which require more information than
+	 * just an integer - for example, a queue-pair.
+	 */
+	q_id = *((int *)context);
+
+	for (i = 0; i < count; i++)
+		buffers[i]->buf_addr = queue_buf[q_id].bufs[i];
+
+	return i;
+}
+
+static int skeleton_rawdev_dump(struct rte_rawdev *dev, FILE *f)
+{
+	RTE_SET_USED(dev);
+	RTE_SET_USED(f);
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_status_get(struct rte_rawdev *dev,
+					       rte_rawdev_obj_t status_info)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	if (status_info)
+		memcpy(status_info, &skeldev->fw.firmware_state,
+			sizeof(enum skeleton_firmware_state));
+
+	return 0;
+}
+
+
+static int skeleton_rawdev_firmware_version_get(
+					struct rte_rawdev *dev,
+					rte_rawdev_obj_t version_info)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_firmware_version_info *vi;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	vi = version_info;
+
+	vi->major = skeldev->fw.firmware_version.major;
+	vi->minor = skeldev->fw.firmware_version.minor;
+	vi->subrel = skeldev->fw.firmware_version.subrel;
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_load(struct rte_rawdev *dev,
+					 rte_rawdev_obj_t firmware_buf)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	/* firmware_buf is a mmaped, possibly DMA'able area, buffer. Being
+	 * dummy, all this does is check if firmware_buf is not NULL and
+	 * sets the state of the firmware.
+	 */
+	if (!firmware_buf)
+		return -EINVAL;
+
+	skeldev->fw.firmware_state = SKELETON_FW_LOADED;
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_unload(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	skeldev->fw.firmware_state = SKELETON_FW_READY;
+
+	return 0;
+}
+
+static const struct rte_rawdev_ops skeleton_rawdev_ops = {
+	.dev_info_get = skeleton_rawdev_info_get,
+	.dev_configure = skeleton_rawdev_configure,
+	.dev_start = skeleton_rawdev_start,
+	.dev_stop = skeleton_rawdev_stop,
+	.dev_close = skeleton_rawdev_close,
+	.dev_reset = skeleton_rawdev_reset,
+
+	.queue_def_conf = skeleton_rawdev_queue_def_conf,
+	.queue_setup = skeleton_rawdev_queue_setup,
+	.queue_release = skeleton_rawdev_queue_release,
+
+	.attr_get = skeleton_rawdev_get_attr,
+	.attr_set = skeleton_rawdev_set_attr,
+
+	.enqueue_bufs = skeleton_rawdev_enqueue_bufs,
+	.dequeue_bufs = skeleton_rawdev_dequeue_bufs,
+
+	.dump = skeleton_rawdev_dump,
+
+	.xstats_get = NULL,
+	.xstats_get_names = NULL,
+	.xstats_get_by_name = NULL,
+	.xstats_reset = NULL,
+
+	.firmware_status_get = skeleton_rawdev_firmware_status_get,
+	.firmware_version_get = skeleton_rawdev_firmware_version_get,
+	.firmware_load = skeleton_rawdev_firmware_load,
+	.firmware_unload = skeleton_rawdev_firmware_unload,
+};
+
+static int
+skeleton_rawdev_create(const char *name,
+		       struct rte_vdev_device *vdev,
+		       int socket_id)
+{
+	int ret = 0, i;
+	struct rte_rawdev *rawdev = NULL;
+	struct skeleton_rawdev *skeldev = NULL;
+
+	if (!name) {
+		SKELETON_PMD_ERR("Invalid name of the device!");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	/* Allocate device structure */
+	rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct skeleton_rawdev),
+					 socket_id);
+	if (rawdev == NULL) {
+		SKELETON_PMD_ERR("Unable to allocate rawdevice");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	rawdev->dev_ops = &skeleton_rawdev_ops;
+	rawdev->device = &vdev->device;
+	rawdev->driver_name = vdev->device.driver->name;
+
+	skeldev = skeleton_rawdev_get_priv(rawdev);
+
+	skeldev->device_id = SKELETON_DEVICE_ID;
+	skeldev->vendor_id = SKELETON_VENDOR_ID;
+	skeldev->capabilities = SKELETON_DEFAULT_CAPA;
+
+	memset(&skeldev->fw, 0, sizeof(struct skeleton_firmware));
+
+	skeldev->fw.firmware_state = SKELETON_DEV_STOPPED;
+	skeldev->fw.firmware_version.major = SKELETON_MAJOR_VER;
+	skeldev->fw.firmware_version.minor = SKELETON_MINOR_VER;
+	skeldev->fw.firmware_version.subrel = SKELETON_SUB_VER;
+
+	skeldev->device_state = SKELETON_DEV_STOPPED;
+
+	/* Reset/set to default queue configuration for this device */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
+		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
+		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
+	}
+
+	/* Clear all allocated queue buffers */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
+		clear_queue_bufs(i);
+
+	return ret;
+
+cleanup:
+	if (rawdev)
+		rte_rawdev_pmd_release(rawdev);
+
+	return ret;
+}
+
+static int
+skeleton_rawdev_destroy(const char *name)
+{
+	int ret;
+	struct rte_rawdev *rdev;
+
+	if (!name) {
+		SKELETON_PMD_ERR("Invalid device name");
+		return -EINVAL;
+	}
+
+	rdev = rte_rawdev_pmd_get_named_dev(name);
+	if (!rdev) {
+		SKELETON_PMD_ERR("Invalid device name (%s)", name);
+		return -EINVAL;
+	}
+
+	/* rte_rawdev_close is called by pmd_release */
+	ret = rte_rawdev_pmd_release(rdev);
+	if (ret)
+		SKELETON_PMD_DEBUG("Device cleanup failed");
+
+	return 0;
+}
+
+static int
+skeleton_rawdev_probe(struct rte_vdev_device *vdev)
+{
+	const char *name;
+	int ret = 0;
+
+
+	name = rte_vdev_device_name(vdev);
+	/* More than one instance is not supported */
+	if (skeldev_init_once) {
+		SKELETON_PMD_ERR("Multiple instance not supported for %s",
+				 name);
+		return -EINVAL;
+	}
+
+	SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
+
+	ret = skeleton_rawdev_create(name, vdev, rte_socket_id());
+
+	/* Device instance created; Second instance not posible */
+	skeldev_init_once = 1;
+
+	return ret;
+}
+
+static int
+skeleton_rawdev_remove(struct rte_vdev_device *vdev)
+{
+	const char *name;
+	int ret;
+
+	name = rte_vdev_device_name(vdev);
+
+	SKELETON_PMD_INFO("Closing %s on NUMA node %d", name, rte_socket_id());
+
+	ret = skeleton_rawdev_destroy(name);
+	if (!ret)
+		skeldev_init_once = 0;
+
+	return ret;
+}
+
+static struct rte_vdev_driver skeleton_pmd_drv = {
+	.probe = skeleton_rawdev_probe,
+	.remove = skeleton_rawdev_remove
+};
+
+RTE_PMD_REGISTER_VDEV(SKELETON_PMD_RAWDEV_NAME, skeleton_pmd_drv);
+
+RTE_INIT(skeleton_pmd_init_log);
+
+static void
+skeleton_pmd_init_log(void)
+{
+	skeleton_pmd_logtype = rte_log_register("rawdev.skeleton");
+	if (skeleton_pmd_logtype >= 0)
+		rte_log_set_level(skeleton_pmd_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.h b/drivers/raw/skeleton_rawdev/skeleton_rawdev.h
new file mode 100644
index 000000000..5045b5922
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#ifndef __SKELETON_RAWDEV_H__
+#define __SKELETON_RAWDEV_H__
+
+#include <rte_rawdev.h>
+
+extern int skeleton_pmd_logtype;
+
+#define SKELETON_PMD_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, skeleton_pmd_logtype, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#define SKELETON_PMD_FUNC_TRACE() SKELETON_PMD_LOG(DEBUG, ">>")
+
+#define SKELETON_PMD_DEBUG(fmt, args...) \
+	SKELETON_PMD_LOG(DEBUG, fmt, ## args)
+#define SKELETON_PMD_INFO(fmt, args...) \
+	SKELETON_PMD_LOG(INFO, fmt, ## args)
+#define SKELETON_PMD_ERR(fmt, args...) \
+	SKELETON_PMD_LOG(ERR, fmt, ## args)
+#define SKELETON_PMD_WARN(fmt, args...) \
+	SKELETON_PMD_LOG(WARNING, fmt, ## args)
+/* Macros for self test application */
+#define SKELETON_TEST_INFO	SKELETON_PMD_INFO
+#define SKELETON_TEST_DEBUG	SKELETON_PMD_DEBUG
+#define SKELETON_TEST_ERR	SKELETON_PMD_ERR
+#define SKELETON_TEST_WARN	SKELETON_PMD_WARN
+
+#define SKELETON_SELFTEST_ARG   ("selftest")
+
+#define SKELETON_VENDOR_ID 0x10
+#define SKELETON_DEVICE_ID 0x01
+
+#define SKELETON_MAJOR_VER 1
+#define SKELETON_MINOR_VER 0
+#define SKELETON_SUB_VER   0
+
+#define SKELETON_MAX_QUEUES 1
+
+enum skeleton_firmware_state {
+	SKELETON_FW_READY,
+	SKELETON_FW_LOADED,
+	SKELETON_FW_ERROR
+};
+
+enum skeleton_device_state {
+	SKELETON_DEV_RUNNING,
+	SKELETON_DEV_STOPPED
+};
+
+enum skeleton_queue_state {
+	SKELETON_QUEUE_DETACH,
+	SKELETON_QUEUE_ATTACH
+};
+
+#define SKELETON_QUEUE_DEF_DEPTH 10
+#define SKELETON_QUEUE_MAX_DEPTH 25
+
+struct skeleton_firmware_version_info {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t subrel;
+};
+
+struct skeleton_firmware {
+	/**< Device firmware information */
+	struct skeleton_firmware_version_info firmware_version;
+	/**< Device state */
+	enum skeleton_firmware_state firmware_state;
+
+};
+
+#define SKELETON_MAX_ATTRIBUTES 10
+#define SKELETON_ATTRIBUTE_NAME_MAX 20
+
+struct skeleton_rawdev_attributes {
+	/**< Name of the attribute */
+	char *name;
+	/**< Value or reference of value of attribute */
+	uint64_t value;
+};
+
+/**< Device supports firmware loading/unloading */
+#define SKELETON_CAPA_FW_LOAD	0x0001
+/**< Device supports firmware reset */
+#define SKELETON_CAPA_FW_RESET  0x0002
+/**< Device support queue based communication */
+#define SKELETON_CAPA_QUEUES    0x0004
+/**< Default Capabilities: FW_LOAD, FW_RESET, QUEUES */
+#define SKELETON_DEFAULT_CAPA   0x7
+
+struct skeleton_rawdev_queue {
+	uint8_t state;
+	uint32_t depth;
+};
+
+struct skeleton_rawdev {
+	uint16_t device_id;
+	uint16_t vendor_id;
+	uint16_t num_queues;
+	/**< One of SKELETON_CAPA_* */
+	uint16_t capabilities;
+	/**< State of device; linked to firmware state */
+	enum skeleton_device_state device_state;
+	/**< Firmware configuration */
+	struct skeleton_firmware fw;
+	/**< Collection of all communication channels - which can be referred
+	 *  to as queues.
+	 */
+	struct skeleton_rawdev_queue queues[SKELETON_MAX_QUEUES];
+	/**< Global table containing various pre-defined and user-defined
+	 * attributes.
+	 */
+	struct skeleton_rawdev_attributes attr[SKELETON_MAX_ATTRIBUTES];
+	struct rte_device *device;
+};
+
+struct skeleton_rawdev_conf {
+	uint16_t num_queues;
+	unsigned int capabilities;
+	enum skeleton_device_state device_state;
+	enum skeleton_firmware_state firmware_state;
+};
+
+static inline struct skeleton_rawdev *
+skeleton_rawdev_get_priv(const struct rte_rawdev *rawdev)
+{
+	return rawdev->dev_private;
+}
+
+int test_rawdev_skeldev(void);
+
+#endif /* __SKELETON_RAWDEV_H__ */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index b201e861d..c3f4db46f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -220,6 +220,10 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += -lrte_pmd_octeontx
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OPDL_EVENTDEV) += -lrte_pmd_opdl_event
 endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
+ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+endif # CONFIG_RTE_LIBRTE_RAWDEV
+
 ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_bus_fslmc
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_mempool_dpaa2
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 08/11] drivers/raw: support for rawdev testcases
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
                       ` (6 preceding siblings ...)
  2018-01-30 14:57     ` [PATCH v3 07/11] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
@ 2018-01-30 14:57     ` Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 09/11] test: enable rawdev skeleton test Shreyansh Jain
                       ` (4 subsequent siblings)
  12 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:57 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Patch introduces rawdev unit testcase for validation against the
Skeleton rawdev dummy PMD implementation.

Test cases are added along with the skeleton driver implementation.
It can be enabled by using vdev argument to any DPDK binary:

  --vdev="rawdev_skeleton,self_test=1"

In case 'self_test=1' is not provided, autotest doesn't execute the
test cases but the vdev is still available for application use.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/raw/skeleton_rawdev/Makefile               |   1 +
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      |  66 +++-
 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c | 431 +++++++++++++++++++++
 3 files changed, 497 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c

diff --git a/drivers/raw/skeleton_rawdev/Makefile b/drivers/raw/skeleton_rawdev/Makefile
index 6318359d1..379cb9d17 100644
--- a/drivers/raw/skeleton_rawdev/Makefile
+++ b/drivers/raw/skeleton_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
 # all source are stored in SRCS-y
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev_test.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
index b38188e11..2dfba0081 100644
--- a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
@@ -541,6 +541,8 @@ static const struct rte_rawdev_ops skeleton_rawdev_ops = {
 	.firmware_version_get = skeleton_rawdev_firmware_version_get,
 	.firmware_load = skeleton_rawdev_firmware_load,
 	.firmware_unload = skeleton_rawdev_firmware_unload,
+
+	.dev_selftest = test_rawdev_skeldev,
 };
 
 static int
@@ -630,11 +632,62 @@ skeleton_rawdev_destroy(const char *name)
 	return 0;
 }
 
+static int
+skeldev_get_selftest(const char *key __rte_unused,
+		     const char *value,
+		     void *opaque)
+{
+	int *flag = opaque;
+	*flag = atoi(value);
+	return 0;
+}
+
+static int
+skeldev_parse_vdev_args(struct rte_vdev_device *vdev)
+{
+	int selftest = 0;
+	const char *name;
+	const char *params;
+
+	static const char *const args[] = {
+		SKELETON_SELFTEST_ARG,
+		NULL
+	};
+
+	name = rte_vdev_device_name(vdev);
+
+	params = rte_vdev_device_args(vdev);
+	if (params != NULL && params[0] != '\0') {
+		struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
+
+		if (!kvlist) {
+			SKELETON_PMD_INFO(
+				"Ignoring unsupported params supplied '%s'",
+				name);
+		} else {
+			int ret = rte_kvargs_process(kvlist,
+					SKELETON_SELFTEST_ARG,
+					skeldev_get_selftest, &selftest);
+			if (ret != 0 || (selftest < 0 || selftest > 1)) {
+				SKELETON_PMD_ERR("%s: Error in parsing args",
+						 name);
+				rte_kvargs_free(kvlist);
+				ret = -1; /* enforce if selftest is invalid */
+				return ret;
+			}
+		}
+
+		rte_kvargs_free(kvlist);
+	}
+
+	return selftest;
+}
+
 static int
 skeleton_rawdev_probe(struct rte_vdev_device *vdev)
 {
 	const char *name;
-	int ret = 0;
+	int selftest = 0, ret = 0;
 
 
 	name = rte_vdev_device_name(vdev);
@@ -647,7 +700,18 @@ skeleton_rawdev_probe(struct rte_vdev_device *vdev)
 
 	SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
 
+	selftest = skeldev_parse_vdev_args(vdev);
+	/* In case of invalid argument, selftest != 1; ignore other values */
+
 	ret = skeleton_rawdev_create(name, vdev, rte_socket_id());
+	if (!ret) {
+		/* In case command line argument for 'selftest' was passed;
+		 * if invalid arguments were passed, execution continues but
+		 * without selftest.
+		 */
+		if (selftest == 1)
+			test_rawdev_skeldev();
+	}
 
 	/* Device instance created; Second instance not posible */
 	skeldev_init_once = 1;
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
new file mode 100644
index 000000000..5c6abc13c
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
@@ -0,0 +1,431 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#include <rte_common.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_dev.h>
+#include <rte_rawdev.h>
+#include <rte_bus_vdev.h>
+#include <rte_test.h>
+
+/* Using relative path as skeleton_rawdev is not part of exported headers */
+#include "skeleton_rawdev.h"
+
+#define TEST_DEV_ID   0
+#define TEST_DEV_NAME "rawdev_skeleton"
+
+#define SKELDEV_LOGS(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, skeleton_pmd_logtype, fmt "\n", \
+		##args)
+
+#define SKELDEV_TEST_INFO(fmt, args...) \
+	SKELDEV_LOGS(INFO, fmt, ## args)
+#define SKELDEV_TEST_DEBUG(fmt, args...) \
+	SKELDEV_LOGS(DEBUG, fmt, ## args)
+
+#define SKELDEV_TEST_RUN(setup, teardown, test) \
+	skeldev_test_run(setup, teardown, test, #test)
+
+#define TEST_SUCCESS 0
+#define TEST_FAILED  -1
+
+static int total;
+static int passed;
+static int failed;
+static int unsupported;
+
+static int
+testsuite_setup(void)
+{
+	uint8_t count;
+	count = rte_rawdev_count();
+	if (!count) {
+		SKELDEV_TEST_INFO("\tNo existing rawdev; "
+				  "Creating 'skeldev_rawdev'");
+		return rte_vdev_init(TEST_DEV_NAME, NULL);
+	}
+
+	return TEST_SUCCESS;
+}
+
+static void local_teardown(void);
+
+static void
+testsuite_teardown(void)
+{
+	local_teardown();
+}
+
+static void
+local_teardown(void)
+{
+	rte_vdev_uninit(TEST_DEV_NAME);
+}
+
+static int
+test_rawdev_count(void)
+{
+	uint8_t count;
+	count = rte_rawdev_count();
+	RTE_TEST_ASSERT(count > 0, "Invalid rawdev count %" PRIu8, count);
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_get_dev_id(void)
+{
+	int ret;
+	ret = rte_rawdev_get_dev_id("invalid_rawdev_device");
+	RTE_TEST_ASSERT_FAIL(ret, "Expected <0 for invalid dev name ret=%d",
+			     ret);
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_socket_id(void)
+{
+	int socket_id;
+	socket_id = rte_rawdev_socket_id(TEST_DEV_ID);
+	RTE_TEST_ASSERT(socket_id != -EINVAL,
+			"Failed to get socket_id %d", socket_id);
+	socket_id = rte_rawdev_socket_id(RTE_RAWDEV_MAX_DEVS);
+	RTE_TEST_ASSERT(socket_id == -EINVAL,
+			"Expected -EINVAL %d", socket_id);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_info_get(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf skel_conf = {0};
+
+	ret = rte_rawdev_info_get(TEST_DEV_ID, NULL);
+	RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
+
+	rdev_info.dev_private = &skel_conf;
+
+	ret = rte_rawdev_info_get(TEST_DEV_ID, &rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get raw dev info");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_configure(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_set = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+
+	/* Check invalid configuration */
+	ret = rte_rawdev_configure(TEST_DEV_ID, NULL);
+	RTE_TEST_ASSERT(ret == -EINVAL,
+			"Null configure; Expected -EINVAL, got %d", ret);
+
+	/* Valid configuration test */
+	rdev_conf_set.num_queues = 1;
+	rdev_conf_set.capabilities = SKELETON_CAPA_FW_LOAD |
+				     SKELETON_CAPA_FW_RESET;
+
+	rdev_info.dev_private = &rdev_conf_set;
+	ret = rte_rawdev_configure(TEST_DEV_ID,
+				   (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure rawdev (%d)", ret);
+
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_set.num_queues,
+			      rdev_conf_get.num_queues,
+			      "Configuration test failed; num_queues (%d)(%d)",
+			      rdev_conf_set.num_queues,
+			      rdev_conf_get.num_queues);
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_set.capabilities,
+			  rdev_conf_get.capabilities,
+			  "Configuration test failed; capabilities");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_queue_default_conf_get(void)
+{
+	int ret, i;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+	struct skeleton_rawdev_queue q = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)",
+				ret);
+
+	/* call to test_rawdev_configure would have set the num_queues = 1 */
+	RTE_TEST_ASSERT_SUCCESS(!(rdev_conf_get.num_queues > 0),
+				"Invalid number of queues (%d). Expected 1",
+				rdev_conf_get.num_queues);
+	/* All queues by default should have state = DETACH and
+	 * depth = DEF_DEPTH
+	 */
+	for (i = 0; i < rdev_conf_get.num_queues; i++) {
+		rte_rawdev_queue_conf_get(TEST_DEV_ID, i, &q);
+		RTE_TEST_ASSERT_EQUAL(q.depth, SKELETON_QUEUE_DEF_DEPTH,
+				      "Invalid default depth of queue (%d)",
+				      q.depth);
+		RTE_TEST_ASSERT_EQUAL(q.state, SKELETON_QUEUE_DETACH,
+				      "Invalid default state of queue (%d)",
+				      q.state);
+	}
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_queue_setup(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+	struct skeleton_rawdev_queue qset = {0};
+	struct skeleton_rawdev_queue qget = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+
+	/* call to test_rawdev_configure would have set the num_queues = 1 */
+	RTE_TEST_ASSERT_SUCCESS(!(rdev_conf_get.num_queues > 0),
+				"Invalid number of queues (%d). Expected 1",
+				rdev_conf_get.num_queues);
+
+	/* Modify the queue depth for Queue 0 and attach it */
+	qset.depth = 15;
+	qset.state = SKELETON_QUEUE_ATTACH;
+	ret = rte_rawdev_queue_setup(TEST_DEV_ID, 0, &qset);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup queue (%d)", ret);
+
+	/* Now, fetching the queue 0 should show depth as 15 */
+	ret = rte_rawdev_queue_conf_get(TEST_DEV_ID, 0, &qget);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get queue config (%d)", ret);
+
+	RTE_TEST_ASSERT_EQUAL(qset.depth, qget.depth,
+			      "Failed to set queue depth: Need(%d), has(%d)",
+			      qset.depth, qget.depth);
+
+	return TEST_SUCCESS;
+}
+
+/* After executing test_rawdev_queue_setup, queue_id=0 would have depth as 15.
+ * Releasing should set it back to default. state would set to DETACH
+ */
+static int
+test_rawdev_queue_release(void)
+{
+	int ret;
+	struct skeleton_rawdev_queue qget = {0};
+
+	/* Now, fetching the queue 0 should show depth as 100 */
+	ret = rte_rawdev_queue_release(TEST_DEV_ID, 0);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to release queue 0; (%d)", ret);
+
+	/* Now, fetching the queue 0 should show depth as default */
+	ret = rte_rawdev_queue_conf_get(TEST_DEV_ID, 0, &qget);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get queue config (%d)", ret);
+
+	RTE_TEST_ASSERT_EQUAL(qget.depth, SKELETON_QUEUE_DEF_DEPTH,
+			      "Release of Queue 0 failed; (depth)");
+
+	RTE_TEST_ASSERT_EQUAL(qget.state, SKELETON_QUEUE_DETACH,
+			      "Release of Queue 0 failed; (state)");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_attr_set_get(void)
+{
+	int ret;
+	int *dummy_value;
+	uint64_t ret_value;
+
+	/* Set an attribute and fetch it */
+	ret = rte_rawdev_set_attr(TEST_DEV_ID, "Test1", 100);
+	RTE_TEST_ASSERT(!ret, "Unable to set an attribute (Test1)");
+
+	dummy_value = malloc(sizeof(int));
+	if (!dummy_value)
+		RTE_TEST_ASSERT(1, "Unable to allocate memory (dummy_value)");
+
+	*dummy_value = 200;
+	ret = rte_rawdev_set_attr(TEST_DEV_ID, "Test2", (uint64_t)dummy_value);
+
+	/* Check if attributes have been set */
+	ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test1", &ret_value);
+	RTE_TEST_ASSERT_EQUAL(ret_value, 100,
+			      "Attribute (Test1) not set correctly (%lu)",
+			      ret_value);
+
+	ret_value = 0;
+	ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test2", &ret_value);
+	RTE_TEST_ASSERT_EQUAL(*((int *)ret_value), 200,
+			      "Attribute (Test2) not set correctly (%lu)",
+			      ret_value);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_start_stop(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+
+	rte_rawdev_start(TEST_DEV_ID);
+	ret = rte_rawdev_info_get(TEST_DEV_ID, (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_get.device_state, SKELETON_DEV_RUNNING,
+			      "Device start failed. State is (%d)",
+			      rdev_conf_get.device_state);
+
+	rte_rawdev_stop(TEST_DEV_ID);
+	ret = rte_rawdev_info_get(TEST_DEV_ID, (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_get.device_state, SKELETON_DEV_STOPPED,
+			      "Device stop failed. State is (%d)",
+			      rdev_conf_get.device_state);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_enqdeq(void)
+{
+	int ret;
+	unsigned int count = 1;
+	uint16_t queue_id = 0;
+	struct rte_rawdev_buf buffers[1];
+	struct rte_rawdev_buf *deq_buffers;
+
+	buffers[0].buf_addr = malloc(strlen(TEST_DEV_NAME) + 3);
+	if (!buffers[0].buf_addr)
+		goto cleanup;
+	snprintf(buffers[0].buf_addr, strlen(TEST_DEV_NAME) + 2, "%s%d",
+		 TEST_DEV_NAME, 0);
+
+	ret = rte_rawdev_enqueue_buffers(TEST_DEV_ID,
+					 (struct rte_rawdev_buf **)&buffers,
+					 count, &queue_id);
+	RTE_TEST_ASSERT_EQUAL((unsigned int)ret, count,
+			      "Unable to enqueue buffers");
+
+	deq_buffers = malloc(sizeof(struct rte_rawdev_buf) * count);
+	if (!deq_buffers)
+		goto cleanup;
+
+	ret = rte_rawdev_dequeue_buffers(TEST_DEV_ID,
+					(struct rte_rawdev_buf **)&deq_buffers,
+					count, &queue_id);
+	RTE_TEST_ASSERT_EQUAL((unsigned int)ret, count,
+			      "Unable to dequeue buffers");
+
+	if (deq_buffers)
+		free(deq_buffers);
+
+	return TEST_SUCCESS;
+cleanup:
+	if (buffers[0].buf_addr)
+		free(buffers[0].buf_addr);
+	if (deq_buffers)
+		free(deq_buffers);
+
+	return TEST_FAILED;
+}
+
+static void skeldev_test_run(int (*setup)(void),
+			     void (*teardown)(void),
+			     int (*test)(void),
+			     const char *name)
+{
+	int ret = 0;
+
+	if (setup) {
+		ret = setup();
+		if (ret < 0) {
+			SKELDEV_TEST_INFO("Error setting up test %s", name);
+			unsupported++;
+		}
+	}
+
+	if (test) {
+		ret = test();
+		if (ret < 0) {
+			failed++;
+			SKELDEV_TEST_INFO("%s Failed", name);
+		} else {
+			passed++;
+			SKELDEV_TEST_DEBUG("%s Passed", name);
+		}
+	}
+
+	if (teardown)
+		teardown();
+
+	total++;
+}
+
+int
+test_rawdev_skeldev(void)
+{
+	testsuite_setup();
+
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_count);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_get_dev_id);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_socket_id);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_info_get);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_configure);
+	SKELDEV_TEST_RUN(test_rawdev_configure, NULL,
+			 test_rawdev_queue_default_conf_get);
+	SKELDEV_TEST_RUN(test_rawdev_configure, NULL, test_rawdev_queue_setup);
+	SKELDEV_TEST_RUN(test_rawdev_queue_setup, NULL,
+			 test_rawdev_queue_release);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_attr_set_get);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_start_stop);
+	SKELDEV_TEST_RUN(test_rawdev_queue_setup, NULL, test_rawdev_enqdeq);
+
+	testsuite_teardown();
+
+	SKELDEV_TEST_INFO("Total tests   : %d", total);
+	SKELDEV_TEST_INFO("Passed        : %d", passed);
+	SKELDEV_TEST_INFO("Failed        : %d", failed);
+	SKELDEV_TEST_INFO("Not supported : %d", unsupported);
+
+	if (failed)
+		return -1;
+
+	return 0;
+};
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 09/11] test: enable rawdev skeleton test
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
                       ` (7 preceding siblings ...)
  2018-01-30 14:57     ` [PATCH v3 08/11] drivers/raw: support for rawdev testcases Shreyansh Jain
@ 2018-01-30 14:57     ` Shreyansh Jain
  2018-01-30 14:57     ` [PATCH v3 10/11] maintainers: claim ownership of rawdev Shreyansh Jain
                       ` (3 subsequent siblings)
  12 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:57 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Skeleton rawdevice test cases are part of driver layer. This patch
allows test cases to be executed using 'rawdev_autotest' command
in test framework.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 test/test/Makefile      |  4 ++++
 test/test/test_rawdev.c | 27 +++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 test/test/test_rawdev.c

diff --git a/test/test/Makefile b/test/test/Makefile
index cb3884a69..a88cc38bf 100644
--- a/test/test/Makefile
+++ b/test/test/Makefile
@@ -187,6 +187,10 @@ SRCS-y += test_event_ring.c
 SRCS-y += test_event_eth_rx_adapter.c
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
+SRCS-y += test_rawdev.c
+endif
+
 SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) += test_kvargs.c
 
 CFLAGS += -DALLOW_EXPERIMENTAL_API
diff --git a/test/test/test_rawdev.c b/test/test/test_rawdev.c
new file mode 100644
index 000000000..043a38a13
--- /dev/null
+++ b/test/test/test_rawdev.c
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+#include <rte_common.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_dev.h>
+#include <rte_rawdev.h>
+#include <rte_bus_vdev.h>
+
+#include "test.h"
+
+static int
+test_rawdev_selftest_impl(const char *pmd, const char *opts)
+{
+	rte_vdev_init(pmd, opts);
+	return rte_rawdev_selftest(rte_rawdev_get_dev_id(pmd));
+}
+
+static int
+test_rawdev_selftest_skeleton(void)
+{
+	return test_rawdev_selftest_impl("rawdev_skeleton", "");
+}
+
+REGISTER_TEST_COMMAND(rawdev_autotest, test_rawdev_selftest_skeleton);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 10/11] maintainers: claim ownership of rawdev
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
                       ` (8 preceding siblings ...)
  2018-01-30 14:57     ` [PATCH v3 09/11] test: enable rawdev skeleton test Shreyansh Jain
@ 2018-01-30 14:57     ` Shreyansh Jain
  2018-01-30 16:50       ` Thomas Monjalon
  2018-01-30 14:57     ` [PATCH v3 11/11] doc: add rawdev library page Shreyansh Jain
                       ` (2 subsequent siblings)
  12 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:57 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5afa9cc6e..e422c871c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -306,6 +306,12 @@ F: lib/librte_eventdev/*eth_rx_adapter*
 F: test/test/test_event_eth_rx_adapter.c
 F: doc/guides/prog_guide/event_ethernet_rx_adapter.rst
 
+Rawdev API - EXPERIMENTAL
+M: Shreyansh Jain <shreyansh.jain@nxp.com>
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+F: lib/librte_rawdev/*
+F: test/test/test_rawdev.c
+F: drivers/rawdev/skeleton/*
 
 Bus Drivers
 -----------
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 11/11] doc: add rawdev library page
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
                       ` (9 preceding siblings ...)
  2018-01-30 14:57     ` [PATCH v3 10/11] maintainers: claim ownership of rawdev Shreyansh Jain
@ 2018-01-30 14:57     ` Shreyansh Jain
  2018-01-30 16:55     ` [PATCH v3 00/11] Introduce generic 'rawdevice' support Thomas Monjalon
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
  12 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-30 14:57 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 doc/guides/prog_guide/index.rst      |  1 +
 doc/guides/prog_guide/rawdev_lib.rst | 83 ++++++++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+)
 create mode 100644 doc/guides/prog_guide/rawdev_lib.rst

diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index af5f65a33..beead3105 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -75,6 +75,7 @@ Programmer's Guide
     vhost_lib
     metrics_lib
     port_hotplug_framework
+    rawdev_lib
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
diff --git a/doc/guides/prog_guide/rawdev_lib.rst b/doc/guides/prog_guide/rawdev_lib.rst
new file mode 100644
index 000000000..d21d284ca
--- /dev/null
+++ b/doc/guides/prog_guide/rawdev_lib.rst
@@ -0,0 +1,83 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+Rawdevice Library
+=================
+
+Introduction
+------------
+
+In terms of device flavor (type) support, DPDK currently has ethernet
+(lib_ether), cryptodev (libcryptodev), eventdev (libeventdev) and vdev
+(virtual device) support.
+
+For a new type of device, for example an accelerator, there are not many
+options except:
+1. create another lib/librte_MySpecialDev, driver/MySpecialDrv and use it
+through Bus/PMD model.
+2. Or, create a vdev and implement necessary custom APIs which are directly
+exposed from driver layer. However this may still require changes in bus code
+in DPDK.
+
+The DPDK Rawdev library is an abstraction that provides the DPDK framework a
+way to manage such devices in a generic manner without expecting changes to
+library or EAL for each device type. This library provides a generic set of
+operations and APIs for framework and Applications to use, respectively, for
+interfacing with such type of devices.
+
+Design
+------
+
+Key factors guiding design of the Rawdevice library:
+
+1. Following are some generic operations which can be treated as applicable
+   to a large subset of device types. None of the operations are mandatory to
+   be implemented by a driver. Application should also be design for proper
+   handling for unsupported APIs.
+
+  * Device Start/Stop - In some cases, 'reset' might also be required which
+    has different semantics than a start-stop-start cycle.
+  * Configuration - Device, Queue or any other sub-system configuration
+  * I/O - Sending a series of buffers which can enclose any arbitrary data
+  * Statistics - Fetch arbitrary device statistics
+  * Firmware Management - Firmware load/unload/status
+
+2. Application API should be able to pass along arbitrary state information
+   to/fro device driver. This can be achieved by maintaining context
+   information through opaque data or pointers.
+
+Figure below outlines the layout of the rawdevice library and device vis-a-vis
+other well known device types like eth and crypto:
+
+.. code-block:: console
+
+     +-----------------------------------------------------------+
+     |                        Application(s)                     |
+     +------------------------------.----------------------------+
+                                    |
+                                    |
+     +------------------------------'----------------------------+
+     |                     DPDK Framework (APIs)                 |
+     +--------------|----|-----------------|---------------------+
+                   /      \                 \
+            (crypto ops)  (eth ops)      (rawdev ops)        +----+
+            /               \                 \              |DrvA|
+     +-----'---+        +----`----+        +---'-----+       +----+
+     | crypto  |        | ethdev  |        | raw     |
+     +--/------+        +---/-----+        +----/----+       +----+
+       /\                __/\                  /   ..........|DrvB|
+      /  \              /    \                / ../    \     +----+
+  +====+ +====+    +====+ +====+            +==/=+      ```Bus Probe
+  |DevA| |DevB|    |DevC| |DevD|            |DevF|
+  +====+ +====+    +====+ +====+            +====+
+    |      |        |      |                 |
+  ``|``````|````````|``````|`````````````````|````````Bus Scan
+   (PCI)   |       (PCI)  (PCI)            (PCI)
+         (BusA)
+
+ * It is assumed above that DrvB is a PCI type driver which registers itself
+   with PCI Bus
+ * Thereafter, when the PCI scan is done, during probe DrvB would match the
+   rawdev DevF ID and take control of device
+ * Applications can then continue using the device through rawdev API
+   interfaces
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 07/11] drivers/raw: introduce skeleton rawdev driver
  2018-01-30 14:57     ` [PATCH v3 07/11] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
@ 2018-01-30 16:48       ` Thomas Monjalon
  0 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-30 16:48 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

There is a compilation error with clang-5.0:

30/01/2018 15:57, Shreyansh Jain:
> +struct queue_buffers {
> +	void *bufs[SKELETON_QUEUE_MAX_DEPTH];
> +};
> +
> +static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {0};

drivers/raw/skeleton_rawdev/skeleton_rawdev.c:46:63: fatal error:
suggest braces around initialization of subobject [-Wmissing-braces]
static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {0};

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 10/11] maintainers: claim ownership of rawdev
  2018-01-30 14:57     ` [PATCH v3 10/11] maintainers: claim ownership of rawdev Shreyansh Jain
@ 2018-01-30 16:50       ` Thomas Monjalon
  0 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-30 16:50 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

30/01/2018 15:57, Shreyansh Jain:
> +Rawdev API - EXPERIMENTAL
> +M: Shreyansh Jain <shreyansh.jain@nxp.com>
> +M: Hemant Agrawal <hemant.agrawal@nxp.com>
> +F: lib/librte_rawdev/*
> +F: test/test/test_rawdev.c
> +F: drivers/rawdev/skeleton/*
>  
>  Bus Drivers
>  -----------

One blank line is missing.

You should update MAINTAINERS in the patches adding the files.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 00/11] Introduce generic 'rawdevice' support
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
                       ` (10 preceding siblings ...)
  2018-01-30 14:57     ` [PATCH v3 11/11] doc: add rawdev library page Shreyansh Jain
@ 2018-01-30 16:55     ` Thomas Monjalon
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
  12 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-30 16:55 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

30/01/2018 15:56, Shreyansh Jain:
> Shreyansh Jain (11):
>   rawdev: introduce raw device library support
>   rawdev: add attribute get and set support
>   rawdev: add buffer stream IO support
>   rawdev: support for extended stats
>   rawdev: support for firmware management
>   rawdev: add self test support
>   drivers/raw: introduce skeleton rawdev driver
>   drivers/raw: support for rawdev testcases
>   test: enable rawdev skeleton test
>   maintainers: claim ownership of rawdev
>   doc: add rawdev library page

Unfortunately, there is a compilation issue (see my comment on patch 7).

While at it, you should update doxygen config and .so lib in release notes.
As an example, please check the last new lib bbdev in the git history,
nothing was missing.
Thanks

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v4 00/10] Introduce generic 'rawdevice' support
  2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
                       ` (11 preceding siblings ...)
  2018-01-30 16:55     ` [PATCH v3 00/11] Introduce generic 'rawdevice' support Thomas Monjalon
@ 2018-01-31  9:13     ` Shreyansh Jain
  2018-01-31  9:13       ` [PATCH v4 01/10] rawdev: introduce raw device library support Shreyansh Jain
                         ` (10 more replies)
  12 siblings, 11 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-31  9:13 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Change History
~~~~~~~~~~~~~~
v4:
 - Fix CLANG build issues
 - enable doxygen
 - add 18.02 release note and library entry
 - Merge MAINTAINERS with respective patch
 - fix doxygen comment over APIs

v3:
 - rebased over master (367bc2a9fd)
 - added __rte_experimental flag
 - added initial documentation
 
v2:
 - restructure comments to prefix model
 - split patches pivoted on APIs introduced in library
 - moved test into drivers/rawdev/skeleton from test/test
 - removed unused RTE_MAX_RAWDEVPORTS and RTE_MAX_RAWDEVS
 - merge patch configurations
 - checkpatch fixes

Rawdevice Support in DPDK
-------------------------

RFC [1]
v1: [2]
v2: [3]
v3: [4]

This patchset introduces rawdevices or generic device support in DPDK.

Motivation
==========

In terms of device flavor (type) support, DPDK currently has ethernet
(lib_ether), cryptodev (libcryptodev), eventdev (libeventdev) and vdev
(virtual device) support.

For a new type of device, for example an accelerator, there are not many
options except either of:
1. create another lib/librte_MySpecialDev, driver/MySpecialDrv and use it
through Bus/PMD model.
2. Or, create a vdev and implement necessary custom APIs which are directly
exposed from driver layer. However this may still require changes in bus code
in DPDK.

Either method is unclean (touching lib for specific context) and possibly
non-upstreamable (custom APIs). Applications and customers prefers uniform
device view and programming model.

Scope
=====

The rawdevice implementation is targetted towards various accelerator use cases
which cannot be generalized within existing device models. Aim is to provided a
generalized structure at the cost of portability guarantee. Specific PMDs may
also expose any specific config APIs. Applications built over such devices are
special use-cases involving IP blocks.

The rawdevice may also connect to other standard devices using adapter or other
methods, similar to eventdev adpter for ethernet/crypto devices.

Proposed Solution
=================

Defining a very generic super-set of device type and its device operations that
can be exposed such that any new/upcoming/experimental device can be layered
over it. 'rawdevice' semantic in this patchset represents a device that doesn't
have any flavor/type associated with it which is advertised (like net, crypto
etc).

A *rte_rawdevice* is a raw/generic device without any standard configuration
or input/output method assumption.

Thus, driver for a new accelerator block, which requires operations for
start/stop/enqueue/dequeue, can be quickly strapped over this rawdevice layer.
Thereafter, any appropriate bus can scan for it (assuming device is discoverable
over the Linux interfaces like sysfs) and match it against registered drivers.

Similarly, for a new accelerator or a wireless device, which doesn't fit the eth
type, a driver can be registered with a bus (on which its device would be
scannable) and use this layer for configuring the device.

It can also serve as a staging area for new type of devices till they find some
commonality and can be standardized.

The outline of this proposed library is same as existing ether/crypto devices.

     +-----------------------------------------------------------+
     |                        Application(s)                     |
     +------------------------------.----------------------------+
                                    |
                                    |
     +------------------------------'----------------------------+
     |                     DPDK Framework (APIs)                 |
     +--------------|----|-----------------|---------------------+
                   /      \                 \
            (crypto ops)  (eth ops)      (rawdev ops)        +----+
            /               \                 \              |DrvA|
     +-----'---+        +----`----+        +---'-----+       +----+
     | crypto  |        | ethdev  |        | raw     |
     +--/------+        +---/-----+        +----/----+       +----+
       /\                __/\                  /   ..........|DrvB|
      /  \              /    \                / ../    \     +----+
  +====+ +====+    +====+ +====+            +==/=+      ```Bus Probe 
  |DevA| |DevB|    |DevC| |DevD|            |DevF|
  +====+ +====+    +====+ +====+            +====+
    |      |        |      |                 |    
  ``|``````|````````|``````|`````````````````|````````Bus Scan
   (PCI)   |       (PCI)  (PCI)            (PCI)
         (BusA)

 * It is assumed above that DrvB is a PCI type driver which registers itself
   with PCI Bus
 * Thereafter, when the PCI scan is done, during probe DrvB would match the
   rawdev DevF ID and take control of device
 * Applications can then continue using the device through rawdev API interfaces

Proposed Interfaces
===================

Following broad API categories are exposed by the rawdevice:

1) Device State Operations (start/stop/reset)
2) Communication Channel setup/teardown (queue)
3) Attribute get/set operations (~ioctls)
4) Enqueue/Dequeue Operations (using opaque buffers)
5) Firmware Operations (Load/unload)

Notes:
For (1), other than standard start/stop, reset has been added extra. This is for
cases where device power cycle has various definitions. Semantics of what
stop->start and what reset would mean are still open-ended.

For (2), though currently `queue` has been used a semantic, it would be possible
in implementation to use this with other methods like internally hosted rte_ring.

For (3), applications can pass on an opaque attribute handle/information which
the driver can act upon.

For (4), aim is to allow applications to post buffers (which can be arbit data)
to the device. It is device's responsibility to interpret and handle the buffer.
It can also be expanded to synchronous and async methods of posting buffer.
That would provide broader use-cases.

For (5), Aim is to allow for most basic device firmware management. In this, as
well as other operations, it is expected that those which are not implemneted
would return ENOTSUP allow the application to fail gracefully.

Future Work
===========
1. Support for hotplugging and interrupt handling
2. Support for callbacks for enqueue and dequeue of buffers
3. Interfacing with Eth/Crypto/Event type devices for inline offloading

References
==========
[1]: http://dpdk.org/ml/archives/dev/2017-November/081550.html
[2]: http://dpdk.org/ml/archives/dev/2018-January/085121.html
[3]: http://dpdk.org/ml/archives/dev/2018-January/088723.html
[4]: http://dpdk.org/ml/archives/dev/2018-January/089608.html

Shreyansh Jain (10):
  rawdev: introduce raw device library support
  rawdev: add attribute get and set support
  rawdev: add buffer stream IO support
  rawdev: support for extended stats
  rawdev: support for firmware management
  rawdev: add self test support
  drivers/raw: introduce skeleton rawdev driver
  drivers/raw: support for rawdev testcases
  test: enable rawdev skeleton test
  doc: add rawdev library page and support Doxygen

 MAINTAINERS                                        |   8 +
 config/common_base                                 |   8 +
 doc/api/doxy-api-index.md                          |   1 +
 doc/api/doxy-api.conf                              |   1 +
 doc/guides/prog_guide/index.rst                    |   1 +
 doc/guides/prog_guide/rawdev_lib.rst               | 107 +++
 doc/guides/rel_notes/release_18_02.rst             |  12 +
 drivers/Makefile                                   |   2 +
 drivers/raw/Makefile                               |   9 +
 drivers/raw/skeleton_rawdev/Makefile               |  28 +
 .../rte_pmd_skeleton_rawdev_version.map            |   4 +
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      | 754 +++++++++++++++++++++
 drivers/raw/skeleton_rawdev/skeleton_rawdev.h      | 136 ++++
 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c | 431 ++++++++++++
 lib/Makefile                                       |   3 +
 lib/librte_rawdev/Makefile                         |  28 +
 lib/librte_rawdev/rte_rawdev.c                     | 546 +++++++++++++++
 lib/librte_rawdev/rte_rawdev.h                     | 609 +++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h                 | 607 +++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map           |  34 +
 mk/rte.app.mk                                      |   5 +
 test/test/Makefile                                 |   4 +
 test/test/test_rawdev.c                            |  27 +
 23 files changed, 3365 insertions(+)
 create mode 100644 doc/guides/prog_guide/rawdev_lib.rst
 create mode 100644 drivers/raw/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.c
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.h
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
 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
 create mode 100644 test/test/test_rawdev.c

-- 
2.14.1

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v4 01/10] rawdev: introduce raw device library support
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
@ 2018-01-31  9:13       ` Shreyansh Jain
  2018-01-31  9:13       ` [PATCH v4 02/10] rawdev: add attribute get and set support Shreyansh Jain
                         ` (9 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-31  9:13 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Each device in DPDK has a type associated with it - ethernet, crypto,
event etc. This patch introduces 'rawdevice' which is a generic
type of device, not currently handled out-of-the-box by DPDK.

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. Using opaque
data (pointer) as API arguments, library allows a high flexibility
for application and driver implementation.

This patch introduces basic device operations like start, stop, reset,
queue and info support.
Subsequent patches would introduce other operations like buffer
enqueue/dequeue and firmware support.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS                              |   5 +
 config/common_base                       |   7 +
 lib/Makefile                             |   3 +
 lib/librte_rawdev/Makefile               |  28 +++
 lib/librte_rawdev/rte_rawdev.c           | 360 +++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 326 ++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 354 ++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  21 ++
 mk/rte.app.mk                            |   1 +
 9 files changed, 1105 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/MAINTAINERS b/MAINTAINERS
index acd056134..fdaefb1df 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -315,6 +315,11 @@ F: lib/librte_eventdev/*eth_rx_adapter*
 F: test/test/test_event_eth_rx_adapter.c
 F: doc/guides/prog_guide/event_ethernet_rx_adapter.rst
 
+Rawdev API - EXPERIMENTAL
+M: Shreyansh Jain <shreyansh.jain@nxp.com>
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+F: lib/librte_rawdev/*
+
 
 Bus Drivers
 -----------
diff --git a/config/common_base b/config/common_base
index c560b73da..812cff129 100644
--- a/config/common_base
+++ b/config/common_base
@@ -805,6 +805,13 @@ CONFIG_RTE_LIBRTE_VHOST=n
 CONFIG_RTE_LIBRTE_VHOST_NUMA=n
 CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
 
+#
+# Compile raw device support
+# EXPERIMENTAL: API may change without prior notice
+#
+CONFIG_RTE_LIBRTE_RAWDEV=y
+CONFIG_RTE_RAWDEV_MAX_DEVS=10
+
 #
 # Compile vhost PMD
 # To compile, CONFIG_RTE_LIBRTE_VHOST should be enabled.
diff --git a/lib/Makefile b/lib/Makefile
index 427f34b00..97080a590 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -102,4 +102,7 @@ endif
 DEPDIRS-librte_kni := librte_eal librte_mempool librte_mbuf librte_ether
 DEPDIRS-librte_kni += librte_pci
 
+DIRS-$(CONFIG_RTE_LIBRTE_RAWDEV) += librte_rawdev
+DEPDIRS-librte_rawdev := librte_eal librte_ether
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/lib/librte_rawdev/Makefile b/lib/librte_rawdev/Makefile
new file mode 100644
index 000000000..b9105b060
--- /dev/null
+++ b/lib/librte_rawdev/Makefile
@@ -0,0 +1,28 @@
+# 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 += -DALLOW_EXPERIMENTAL_API
+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..46353a4eb
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -0,0 +1,360 @@
+/* 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;
+
+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_experimental
+rte_rawdev_count(void)
+{
+	return rte_rawdev_globals->nb_devs;
+}
+
+uint16_t __rte_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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);
+}
+
+int __rte_experimental
+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_experimental
+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_experimental
+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_experimental
+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_RAWDEV_MAX_DEVS; dev_id++) {
+		if (rte_rawdevs[dev_id].attached ==
+				RTE_RAWDEV_DETACHED)
+			return dev_id;
+	}
+
+	return RTE_RAWDEV_MAX_DEVS;
+}
+
+struct rte_rawdev * __rte_experimental
+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_RAWDEV_MAX_DEVS) {
+		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_experimental
+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("lib.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..76a533e06
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -0,0 +1,326 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#ifndef _RTE_RAWDEV_H_
+#define _RTE_RAWDEV_H_
+
+/**
+ * @file rte_rawdev.h
+ *
+ * Generic device abstraction APIs.
+ *
+ * This API allow applications to configure and use generic devices having
+ * no specific type already available in DPDK.
+ *
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+/* 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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+rte_rawdev_queue_setup(uint16_t dev_id,
+		       uint16_t queue_id,
+		       rte_rawdev_obj_t queue_conf);
+
+/**
+ * Release and deallocate a raw queue from a raw device.
+ *
+ * @param dev_id
+ *   The identifier of the device.
+ * @param queue_id
+ *   The index of the raw queue to release. 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 released.
+ *   - <0: raw queue configuration failed
+ */
+int __rte_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
+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 {
+	/**< Socket ID where memory is allocated */
+	int socket_id;
+	/**< Device ID for this instance */
+	uint16_t dev_id;
+	/**< Functions exported by PMD */
+	const struct rte_rawdev_ops *dev_ops;
+	/**< Device info. supplied during device initialization */
+	struct rte_device *device;
+	/**< Driver info. supplied by probing */
+	const char *driver_name;
+
+	RTE_STD_C11
+	/**< Flag indicating the device is attached */
+	uint8_t attached : 1;
+	/**< Device state: STARTED(1)/STOPPED(0) */
+	uint8_t started : 1;
+
+	/**< PMD-specific private data */
+	rte_rawdev_obj_t dev_private;
+	/**< Device name */
+	char name[RTE_RAWDEV_NAME_MAX_LEN];
+} __rte_cache_aligned;
+
+/** @internal The pool of rte_rawdev structures. */
+extern struct rte_rawdev *rte_rawdevs;
+
+
+struct rte_rawdev_info {
+	/**< Name of driver handling this device */
+	const char *driver_name;
+	/**< Device encapsulation */
+	struct rte_device *device;
+	/**< Socket ID where memory is allocated */
+	int socket_id;
+	/**< PMD-specific private data */
+	rte_rawdev_obj_t dev_private;
+};
+
+struct rte_rawdev_buf {
+	/**< Opaque buffer reference */
+	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_experimental
+rte_rawdev_dump(uint16_t dev_id, FILE *f);
+
+#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..aeb371152
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -0,0 +1,354 @@
+/* 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.
+ *
+ * @warning
+ * @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: Can 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 {
+	/**< Number of devices found */
+	uint16_t nb_devs;
+};
+
+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);
+
+/**
+ * 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);
+
+/** Rawdevice operations function pointer table */
+struct rte_rawdev_ops {
+	/**< Get device info. */
+	rawdev_info_get_t dev_info_get;
+	/**< Configure device. */
+	rawdev_configure_t dev_configure;
+	/**< Start device. */
+	rawdev_start_t dev_start;
+	/**< Stop device. */
+	rawdev_stop_t dev_stop;
+	/**< Close device. */
+	rawdev_close_t dev_close;
+	/**< Reset device. */
+	rawdev_reset_t dev_reset;
+
+	/**< Get raw queue configuration. */
+	rawdev_queue_conf_get_t queue_def_conf;
+	/**< Set up an raw queue. */
+	rawdev_queue_setup_t queue_setup;
+	/**< Release an raw queue. */
+	rawdev_queue_release_t queue_release;
+
+	/* Dump internal information */
+	rawdev_dump_t dump;
+};
+
+/**
+ * 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 dev_private_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_experimental
+rte_rawdev_pmd_allocate(const char *name, size_t dev_private_size,
+			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_experimental
+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_experimental
+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_experimental
+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..64e60d945
--- /dev/null
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -0,0 +1,21 @@
+EXPERIMENTAL {
+	global:
+
+	rte_rawdev_close;
+	rte_rawdev_configure;
+	rte_rawdev_count;
+	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_rawdevs;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 0169f3f5b..b201e861d 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -105,6 +105,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
+_LDLIBS-$(CONFIG_RTE_LIBRTE_RAWDEV)         += -lrte_rawdev
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 02/10] rawdev: add attribute get and set support
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
  2018-01-31  9:13       ` [PATCH v4 01/10] rawdev: introduce raw device library support Shreyansh Jain
@ 2018-01-31  9:13       ` Shreyansh Jain
  2018-01-31  9:13       ` [PATCH v4 03/10] rawdev: add buffer stream IO support Shreyansh Jain
                         ` (8 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-31  9:13 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

A rawdevice can have various attributes. This patch introduce support
for transparently setting attribute value or getting current attribute
state. This is done by allowing an opaque set of key and value to be
passed through rawdev library.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           | 28 +++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 43 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 42 +++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  2 ++
 4 files changed, 115 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index 46353a4eb..08dd982a4 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -175,6 +175,34 @@ rte_rawdev_queue_release(uint16_t dev_id, uint16_t queue_id)
 	return (*dev->dev_ops->queue_release)(dev, queue_id);
 }
 
+int __rte_experimental
+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_experimental
+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_experimental
 rte_rawdev_dump(uint16_t dev_id, FILE *f)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index 76a533e06..a58abc3ca 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -319,6 +319,49 @@ struct rte_rawdev_buf {
 int __rte_experimental
 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.
+ * @param attr_name
+ *   Opaque object representing an attribute in implementation.
+ * @param 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_experimental
+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.
+ * @param attr_name
+ *   Opaque object representing an attribute in implementation.
+ * @param attr_value
+ *   Value of the attribute represented by attr_name
+ * @return
+ *   0 for success
+ *  !0 Error
+ */
+int __rte_experimental
+rte_rawdev_set_attr(uint16_t dev_id,
+		    const char *attr_name,
+		    const uint64_t attr_value);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index aeb371152..3e643691d 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -264,6 +264,43 @@ typedef int (*rawdev_queue_release_t)(struct rte_rawdev *dev,
  */
 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
+ * @param attr_name
+ *   Opaque object representing an attribute in implementation.
+ * @param 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
+ * @param attr_name
+ *   Opaque object representing an attribute in implementation.
+ * @param 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);
+
 /** Rawdevice operations function pointer table */
 struct rte_rawdev_ops {
 	/**< Get device info. */
@@ -288,6 +325,11 @@ struct rte_rawdev_ops {
 
 	/* Dump internal information */
 	rawdev_dump_t dump;
+
+	/**< Get an attribute managed by the implementation */
+	rawdev_get_attr_t attr_get;
+	/**< Set an attribute managed by the implementation */
+	rawdev_set_attr_t attr_set;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index 64e60d945..d63476e47 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -4,6 +4,7 @@ EXPERIMENTAL {
 	rte_rawdev_close;
 	rte_rawdev_configure;
 	rte_rawdev_count;
+	rte_rawdev_get_attr;
 	rte_rawdev_get_dev_id;
 	rte_rawdev_info_get;
 	rte_rawdev_pmd_allocate;
@@ -12,6 +13,7 @@ EXPERIMENTAL {
 	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;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 03/10] rawdev: add buffer stream IO support
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
  2018-01-31  9:13       ` [PATCH v4 01/10] rawdev: introduce raw device library support Shreyansh Jain
  2018-01-31  9:13       ` [PATCH v4 02/10] rawdev: add attribute get and set support Shreyansh Jain
@ 2018-01-31  9:13       ` Shreyansh Jain
  2018-01-31  9:13       ` [PATCH v4 04/10] rawdev: support for extended stats Shreyansh Jain
                         ` (7 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-31  9:13 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Introduce handlers for raw buffer enqueue and dequeue. A raw buffer
is essentially a void object which is transparently passed via the
library onto the driver.

Using a context field as argument, any arbitrary meta information
can be passed by application to the driver/implementation. This can
be any data on which driver needs to define the operation semantics.
For example, passing along a queue identifier can suggest the driver
the queue context to perform I/O on.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           | 30 +++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 58 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 58 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  2 ++
 4 files changed, 148 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index 08dd982a4..a6d937c34 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -203,6 +203,36 @@ rte_rawdev_set_attr(uint16_t dev_id,
 	return (*dev->dev_ops->attr_set)(dev, attr_name, attr_value);
 }
 
+int __rte_experimental
+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_experimental
+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_experimental
 rte_rawdev_dump(uint16_t dev_id, FILE *f)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index a58abc3ca..3820ff08d 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -362,6 +362,64 @@ 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_experimental
+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_experimental
+rte_rawdev_dequeue_buffers(uint16_t dev_id,
+			   struct rte_rawdev_buf **buffers,
+			   unsigned int count,
+			   rte_rawdev_obj_t context);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index 3e643691d..fe9cc6722 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -250,6 +250,58 @@ typedef int (*rawdev_queue_setup_t)(struct rte_rawdev *dev,
 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
+ * @param 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
+ * @param 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
  *
@@ -323,6 +375,12 @@ struct rte_rawdev_ops {
 	/**< Release an raw queue. */
 	rawdev_queue_release_t queue_release;
 
+	/**< Enqueue an array of raw buffers to device. */
+	rawdev_enqueue_bufs_t enqueue_bufs;
+	/**< Dequeue an array of raw buffers from device. */
+	/** TODO: Callback based enqueue and dequeue support */
+	rawdev_dequeue_bufs_t dequeue_bufs;
+
 	/* Dump internal information */
 	rawdev_dump_t dump;
 
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index d63476e47..bafe2c5de 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -4,6 +4,8 @@ EXPERIMENTAL {
 	rte_rawdev_close;
 	rte_rawdev_configure;
 	rte_rawdev_count;
+	rte_rawdev_dequeue_buffers;
+	rte_rawdev_enqueue_buffers;
 	rte_rawdev_get_attr;
 	rte_rawdev_get_dev_id;
 	rte_rawdev_info_get;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 04/10] rawdev: support for extended stats
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
                         ` (2 preceding siblings ...)
  2018-01-31  9:13       ` [PATCH v4 03/10] rawdev: add buffer stream IO support Shreyansh Jain
@ 2018-01-31  9:13       ` Shreyansh Jain
  2018-01-31  9:13       ` [PATCH v4 05/10] rawdev: support for firmware management Shreyansh Jain
                         ` (6 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-31  9:13 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Generic rawdev library cannot define a pre-defined set of stats
for devices which are yet to be defined.

This patch introduces the xstats support for rawdev so that any
implementation can create its own statistics.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           |  75 ++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 105 +++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       |  72 +++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |   4 ++
 4 files changed, 256 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index a6d937c34..d6c284554 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -245,6 +245,81 @@ rte_rawdev_dump(uint16_t dev_id, FILE *f)
 	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_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
 rte_rawdev_start(uint16_t dev_id)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index 3820ff08d..28bf9e0ff 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -420,6 +420,111 @@ rte_rawdev_dequeue_buffers(uint16_t dev_id,
 			   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_experimental
+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_experimental
+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_experimental
+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_experimental
+rte_rawdev_xstats_reset(uint16_t dev_id,
+			const uint32_t ids[],
+			uint32_t nb_ids);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index fe9cc6722..abc7c15c5 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -353,6 +353,69 @@ 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);
 /** Rawdevice operations function pointer table */
 struct rte_rawdev_ops {
 	/**< Get device info. */
@@ -388,6 +451,15 @@ struct rte_rawdev_ops {
 	rawdev_get_attr_t attr_get;
 	/**< Set an attribute managed by the implementation */
 	rawdev_set_attr_t attr_set;
+
+	/**< Get extended device statistics. */
+	rawdev_xstats_get_t xstats_get;
+	/**< Get names of extended stats. */
+	rawdev_xstats_get_names_t xstats_get_names;
+	/**< Get one value by name. */
+	rawdev_xstats_get_by_name_t xstats_get_by_name;
+	/**< Reset the statistics values in xstats. */
+	rawdev_xstats_reset_t xstats_reset;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index bafe2c5de..469b78d81 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -19,6 +19,10 @@ EXPERIMENTAL {
 	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

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 05/10] rawdev: support for firmware management
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
                         ` (3 preceding siblings ...)
  2018-01-31  9:13       ` [PATCH v4 04/10] rawdev: support for extended stats Shreyansh Jain
@ 2018-01-31  9:13       ` Shreyansh Jain
  2018-01-31  9:13       ` [PATCH v4 06/10] rawdev: add self test support Shreyansh Jain
                         ` (5 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-31  9:13 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Some generic operations for firmware management can loading, unloading,
starting, stopping and querying firmware of a device.

This patch adds support for such generic operations.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           | 43 ++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 64 +++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 70 ++++++++++++++++++++++++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  4 ++
 4 files changed, 181 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index d6c284554..b52293c47 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -320,6 +320,49 @@ rte_rawdev_xstats_reset(uint16_t dev_id,
 	return (*dev->dev_ops->xstats_reset)(dev, ids, nb_ids);
 }
 
+int __rte_experimental
+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_experimental
+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_experimental
+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_experimental
+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_experimental
 rte_rawdev_start(uint16_t dev_id)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index 28bf9e0ff..389b009d7 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -525,6 +525,70 @@ 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_experimental
+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_experimental
+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 successful load
+ *  !0 for failure to load the provided image, or image incorrect.
+ */
+int __rte_experimental
+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_experimental
+rte_rawdev_firmware_unload(uint16_t dev_id);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index abc7c15c5..41b3a3b5f 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -416,6 +416,67 @@ typedef int (*rawdev_xstats_get_names_t)(const struct rte_rawdev *dev,
 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 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,
+				      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 {
 	/**< Get device info. */
@@ -460,6 +521,15 @@ struct rte_rawdev_ops {
 	rawdev_xstats_get_by_name_t xstats_get_by_name;
 	/**< Reset the statistics values in xstats. */
 	rawdev_xstats_reset_t xstats_reset;
+
+	/**< Obtainer firmware status */
+	rawdev_firmware_status_get_t firmware_status_get;
+	/**< Obtain firmware version information */
+	rawdev_firmware_version_get_t firmware_version_get;
+	/**< Load firmware */
+	rawdev_firmware_load_t firmware_load;
+	/**< Unload firmware */
+	rawdev_firmware_unload_t firmware_unload;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index 469b78d81..8de9abdc4 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -6,6 +6,10 @@ EXPERIMENTAL {
 	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;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 06/10] rawdev: add self test support
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
                         ` (4 preceding siblings ...)
  2018-01-31  9:13       ` [PATCH v4 05/10] rawdev: support for firmware management Shreyansh Jain
@ 2018-01-31  9:13       ` Shreyansh Jain
  2018-01-31  9:13       ` [PATCH v4 07/10] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
                         ` (4 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-31  9:13 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_rawdev/rte_rawdev.c           | 10 ++++++++++
 lib/librte_rawdev/rte_rawdev.h           | 13 +++++++++++++
 lib/librte_rawdev/rte_rawdev_pmd.h       | 11 +++++++++++
 lib/librte_rawdev/rte_rawdev_version.map |  1 +
 4 files changed, 35 insertions(+)

diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c
index b52293c47..d314ef96b 100644
--- a/lib/librte_rawdev/rte_rawdev.c
+++ b/lib/librte_rawdev/rte_rawdev.c
@@ -363,6 +363,16 @@ rte_rawdev_firmware_unload(uint16_t dev_id)
 	return (*dev->dev_ops->firmware_unload)(dev);
 }
 
+int __rte_experimental
+rte_rawdev_selftest(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->dev_selftest, -ENOTSUP);
+	return (*dev->dev_ops->dev_selftest)();
+}
+
 int __rte_experimental
 rte_rawdev_start(uint16_t dev_id)
 {
diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h
index 389b009d7..4170a618e 100644
--- a/lib/librte_rawdev/rte_rawdev.h
+++ b/lib/librte_rawdev/rte_rawdev.h
@@ -589,6 +589,19 @@ rte_rawdev_firmware_load(uint16_t dev_id, rte_rawdev_obj_t firmware_image);
 int __rte_experimental
 rte_rawdev_firmware_unload(uint16_t dev_id);
 
+/**
+ * Trigger the rawdev self test.
+ *
+ * @param dev_id
+ *   The identifier of the device
+ * @return
+ *   - 0: Selftest successful
+ *   - -ENOTSUP if the device doesn't support selftest
+ *   - other values < 0 on failure.
+ */
+int __rte_experimental
+rte_rawdev_selftest(uint16_t dev_id);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h
index 41b3a3b5f..408adf0fd 100644
--- a/lib/librte_rawdev/rte_rawdev_pmd.h
+++ b/lib/librte_rawdev/rte_rawdev_pmd.h
@@ -477,6 +477,14 @@ typedef int (*rawdev_firmware_load_t)(struct rte_rawdev *dev,
  */
 typedef int (*rawdev_firmware_unload_t)(struct rte_rawdev *dev);
 
+/**
+ * Start rawdev selftest
+ *
+ * @return
+ *   Return 0 on success
+ */
+typedef int (*rawdev_selftest_t)(void);
+
 /** Rawdevice operations function pointer table */
 struct rte_rawdev_ops {
 	/**< Get device info. */
@@ -530,6 +538,9 @@ struct rte_rawdev_ops {
 	rawdev_firmware_load_t firmware_load;
 	/**< Unload firmware */
 	rawdev_firmware_unload_t firmware_unload;
+
+	/**< Device selftest function */
+	rawdev_selftest_t dev_selftest;
 };
 
 /**
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index 8de9abdc4..af4465e26 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -19,6 +19,7 @@ EXPERIMENTAL {
 	rte_rawdev_queue_setup;
 	rte_rawdev_queue_release;
 	rte_rawdev_reset;
+	rte_rawdev_selftest;
 	rte_rawdev_set_attr;
 	rte_rawdev_socket_id;
 	rte_rawdev_start;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 07/10] drivers/raw: introduce skeleton rawdev driver
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
                         ` (5 preceding siblings ...)
  2018-01-31  9:13       ` [PATCH v4 06/10] rawdev: add self test support Shreyansh Jain
@ 2018-01-31  9:13       ` Shreyansh Jain
  2018-01-31 13:20         ` Thomas Monjalon
  2018-01-31  9:13       ` [PATCH v4 08/10] drivers/raw: support for rawdev testcases Shreyansh Jain
                         ` (3 subsequent siblings)
  10 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-31  9:13 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Skeleton rawdevice driver, on the lines of eventdev skeleton, is for
showcasing the rawdev library. This driver implements some of the
operations of the library based on which a test module can be
developed.

Design of skeleton involves a virtual device which is plugged into
VDEV bus on initialization.

Also, enable compilation of rawdev skeleton driver.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS                                        |   1 +
 config/common_base                                 |   1 +
 drivers/Makefile                                   |   2 +
 drivers/raw/Makefile                               |   9 +
 drivers/raw/skeleton_rawdev/Makefile               |  27 +
 .../rte_pmd_skeleton_rawdev_version.map            |   4 +
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      | 690 +++++++++++++++++++++
 drivers/raw/skeleton_rawdev/skeleton_rawdev.h      | 136 ++++
 mk/rte.app.mk                                      |   4 +
 9 files changed, 874 insertions(+)
 create mode 100644 drivers/raw/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/Makefile
 create mode 100644 drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.c
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.h

diff --git a/MAINTAINERS b/MAINTAINERS
index fdaefb1df..320bcf9a4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -319,6 +319,7 @@ Rawdev API - EXPERIMENTAL
 M: Shreyansh Jain <shreyansh.jain@nxp.com>
 M: Hemant Agrawal <hemant.agrawal@nxp.com>
 F: lib/librte_rawdev/*
+F: drivers/rawdev/skeleton/*
 
 
 Bus Drivers
diff --git a/config/common_base b/config/common_base
index 812cff129..0002f83a2 100644
--- a/config/common_base
+++ b/config/common_base
@@ -811,6 +811,7 @@ CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
 #
 CONFIG_RTE_LIBRTE_RAWDEV=y
 CONFIG_RTE_RAWDEV_MAX_DEVS=10
+CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
 
 #
 # Compile vhost PMD
diff --git a/drivers/Makefile b/drivers/Makefile
index e0488aa2b..ee65c87b0 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -14,5 +14,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
 DEPDIRS-crypto := bus mempool
 DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event
 DEPDIRS-event := bus mempool net
+DIRS-$(CONFIG_RTE_LIBRTE_RAWDEV) += raw
+DEPDIRS-raw := bus mempool net event
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
new file mode 100644
index 000000000..da7c8b449
--- /dev/null
+++ b/drivers/raw/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2017 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# DIRS-$(<configuration>) += <directory>
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/skeleton_rawdev/Makefile b/drivers/raw/skeleton_rawdev/Makefile
new file mode 100644
index 000000000..6318359d1
--- /dev/null
+++ b/drivers/raw/skeleton_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_pmd_skeleton_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_bus_vdev
+
+EXPORT_MAP := rte_pmd_skeleton_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map b/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
new file mode 100644
index 000000000..179140fb8
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_18.02 {
+
+	local: *;
+};
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
new file mode 100644
index 000000000..062d732ec
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
@@ -0,0 +1,690 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_debug.h>
+#include <rte_dev.h>
+#include <rte_eal.h>
+#include <rte_kvargs.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_lcore.h>
+#include <rte_bus_vdev.h>
+
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "skeleton_rawdev.h"
+
+/* Dynamic log type identifier */
+int skeleton_pmd_logtype;
+
+/* Count of instances */
+uint16_t skeldev_init_once;
+
+/**< Rawdev Skeleton dummy driver name */
+#define SKELETON_PMD_RAWDEV_NAME rawdev_skeleton
+
+/**< Skeleton rawdev driver object */
+static struct rte_vdev_driver skeleton_pmd_drv;
+
+struct queue_buffers {
+	void *bufs[SKELETON_QUEUE_MAX_DEPTH];
+};
+
+static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {};
+static void clear_queue_bufs(int queue_id);
+
+static void skeleton_rawdev_info_get(struct rte_rawdev *dev,
+				     rte_rawdev_obj_t dev_info)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_conf *skeldev_conf;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev_info) {
+		SKELETON_PMD_ERR("Invalid request");
+		return;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	skeldev_conf = dev_info;
+
+	skeldev_conf->num_queues = skeldev->num_queues;
+	skeldev_conf->capabilities = skeldev->capabilities;
+	skeldev_conf->device_state = skeldev->device_state;
+	skeldev_conf->firmware_state = skeldev->fw.firmware_state;
+}
+
+static int skeleton_rawdev_configure(const struct rte_rawdev *dev,
+				     rte_rawdev_obj_t config)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_conf *skeldev_conf;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	if (!config) {
+		SKELETON_PMD_ERR("Invalid configuration");
+		return -EINVAL;
+	}
+
+	skeldev_conf = config;
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	if (skeldev_conf->num_queues <= SKELETON_MAX_QUEUES)
+		skeldev->num_queues = skeldev_conf->num_queues;
+	else
+		return -EINVAL;
+
+	skeldev->capabilities = skeldev_conf->capabilities;
+	skeldev->num_queues = skeldev_conf->num_queues;
+
+	return 0;
+}
+
+static int skeleton_rawdev_start(struct rte_rawdev *dev)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+	enum skeleton_firmware_state fw_state;
+	enum skeleton_device_state device_state;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	fw_state = skeldev->fw.firmware_state;
+	device_state = skeldev->device_state;
+
+	if (fw_state == SKELETON_FW_LOADED &&
+		device_state == SKELETON_DEV_STOPPED) {
+		skeldev->device_state = SKELETON_DEV_RUNNING;
+	} else {
+		SKELETON_PMD_ERR("Device not ready for starting");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void skeleton_rawdev_stop(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (dev) {
+		skeldev = skeleton_rawdev_get_priv(dev);
+		skeldev->device_state = SKELETON_DEV_STOPPED;
+	}
+}
+
+static void
+reset_queues(struct skeleton_rawdev *skeldev)
+{
+	int i;
+
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
+		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
+		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
+	}
+}
+
+static void
+reset_attribute_table(struct skeleton_rawdev *skeldev)
+{
+	int i;
+
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (skeldev->attr[i].name) {
+			free(skeldev->attr[i].name);
+			skeldev->attr[i].name = NULL;
+		}
+	}
+}
+
+static int skeleton_rawdev_close(struct rte_rawdev *dev)
+{
+	int ret = 0, i;
+	struct skeleton_rawdev *skeldev;
+	enum skeleton_firmware_state fw_state;
+	enum skeleton_device_state device_state;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	fw_state = skeldev->fw.firmware_state;
+	device_state = skeldev->device_state;
+
+	reset_queues(skeldev);
+	reset_attribute_table(skeldev);
+
+	switch (fw_state) {
+	case SKELETON_FW_LOADED:
+		if (device_state == SKELETON_DEV_RUNNING) {
+			SKELETON_PMD_ERR("Cannot close running device");
+			ret = -EINVAL;
+		} else {
+			/* Probably call fw reset here */
+			skeldev->fw.firmware_state = SKELETON_FW_READY;
+		}
+		break;
+	case SKELETON_FW_READY:
+	case SKELETON_FW_ERROR:
+	default:
+		SKELETON_PMD_DEBUG("Device already in stopped state");
+		ret = -EINVAL;
+		break;
+	}
+
+	/* Clear all allocated queues */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
+		clear_queue_bufs(i);
+
+	return ret;
+}
+
+static int skeleton_rawdev_reset(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	SKELETON_PMD_DEBUG("Reseting device");
+	skeldev->fw.firmware_state = SKELETON_FW_READY;
+
+	return 0;
+}
+
+static void skeleton_rawdev_queue_def_conf(struct rte_rawdev *dev,
+					   uint16_t queue_id,
+					   rte_rawdev_obj_t queue_conf)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_queue *skelq;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !queue_conf)
+		return;
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	skelq = &skeldev->queues[queue_id];
+
+	if (queue_id < SKELETON_MAX_QUEUES)
+		rte_memcpy(queue_conf, skelq,
+			sizeof(struct skeleton_rawdev_queue));
+}
+
+static void
+clear_queue_bufs(int queue_id)
+{
+	int i;
+
+	/* Clear buffers for queue_id */
+	for (i = 0; i < SKELETON_QUEUE_MAX_DEPTH; i++)
+		queue_buf[queue_id].bufs[i] = NULL;
+}
+
+static int skeleton_rawdev_queue_setup(struct rte_rawdev *dev,
+				       uint16_t queue_id,
+				       rte_rawdev_obj_t queue_conf)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_rawdev_queue *q;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !queue_conf)
+		return -EINVAL;
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	q = &skeldev->queues[queue_id];
+
+	if (skeldev->num_queues > queue_id &&
+	    q->depth < SKELETON_QUEUE_MAX_DEPTH) {
+		rte_memcpy(q, queue_conf,
+			   sizeof(struct skeleton_rawdev_queue));
+		clear_queue_bufs(queue_id);
+	} else {
+		SKELETON_PMD_ERR("Invalid queue configuration");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int skeleton_rawdev_queue_release(struct rte_rawdev *dev,
+					 uint16_t queue_id)
+{
+	int ret = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	if (skeldev->num_queues > queue_id) {
+		skeldev->queues[queue_id].state = SKELETON_QUEUE_DETACH;
+		skeldev->queues[queue_id].depth = SKELETON_QUEUE_DEF_DEPTH;
+		clear_queue_bufs(queue_id);
+	} else {
+		SKELETON_PMD_ERR("Invalid queue configuration");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int skeleton_rawdev_get_attr(struct rte_rawdev *dev,
+				    const char *attr_name,
+				    uint64_t *attr_value)
+{
+	int i;
+	uint8_t done = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !attr_name || !attr_value) {
+		SKELETON_PMD_ERR("Invalid arguments for getting attributes");
+		return -EINVAL;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (!skeldev->attr[i].name)
+			continue;
+
+		if (!strncmp(skeldev->attr[i].name, attr_name,
+			    SKELETON_ATTRIBUTE_NAME_MAX)) {
+			*attr_value = skeldev->attr[i].value;
+			done = 1;
+			SKELETON_PMD_DEBUG("Attribute (%s) Value (%lu)",
+					   attr_name, *attr_value);
+			break;
+		}
+	}
+
+	if (done)
+		return 0;
+
+	/* Attribute not found */
+	return -EINVAL;
+}
+
+static int skeleton_rawdev_set_attr(struct rte_rawdev *dev,
+				     const char *attr_name,
+				     const uint64_t attr_value)
+{
+	int i;
+	uint8_t done = 0;
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	if (!dev || !attr_name) {
+		SKELETON_PMD_ERR("Invalid arguments for setting attributes");
+		return -EINVAL;
+	}
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	/* Check if attribute already exists */
+	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
+		if (!skeldev->attr[i].name)
+			break;
+
+		if (!strncmp(skeldev->attr[i].name, attr_name,
+			     SKELETON_ATTRIBUTE_NAME_MAX)) {
+			/* Update value */
+			skeldev->attr[i].value = attr_value;
+			done = 1;
+			break;
+		}
+	}
+
+	if (!done) {
+		if (i < (SKELETON_MAX_ATTRIBUTES - 1)) {
+			/* There is still space to insert one more */
+			skeldev->attr[i].name = strdup(attr_name);
+			if (!skeldev->attr[i].name)
+				return -ENOMEM;
+
+			skeldev->attr[i].value = attr_value;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int skeleton_rawdev_enqueue_bufs(struct rte_rawdev *dev,
+					struct rte_rawdev_buf **buffers,
+					unsigned int count,
+					rte_rawdev_obj_t context)
+{
+	unsigned int i;
+	uint16_t q_id;
+	RTE_SET_USED(dev);
+
+	/* context is essentially the queue_id which is
+	 * transferred as opaque object through the library layer. This can
+	 * help in complex implementation which require more information than
+	 * just an integer - for example, a queue-pair.
+	 */
+	q_id = *((int *)context);
+
+	for (i = 0; i < count; i++)
+		queue_buf[q_id].bufs[i] = buffers[i]->buf_addr;
+
+	return i;
+}
+
+static int skeleton_rawdev_dequeue_bufs(struct rte_rawdev *dev,
+					struct rte_rawdev_buf **buffers,
+					unsigned int count,
+					rte_rawdev_obj_t context)
+{
+	unsigned int i;
+	uint16_t q_id;
+	RTE_SET_USED(dev);
+
+	/* context is essentially the queue_id which is
+	 * transferred as opaque object through the library layer. This can
+	 * help in complex implementation which require more information than
+	 * just an integer - for example, a queue-pair.
+	 */
+	q_id = *((int *)context);
+
+	for (i = 0; i < count; i++)
+		buffers[i]->buf_addr = queue_buf[q_id].bufs[i];
+
+	return i;
+}
+
+static int skeleton_rawdev_dump(struct rte_rawdev *dev, FILE *f)
+{
+	RTE_SET_USED(dev);
+	RTE_SET_USED(f);
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_status_get(struct rte_rawdev *dev,
+					       rte_rawdev_obj_t status_info)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
+
+	if (status_info)
+		memcpy(status_info, &skeldev->fw.firmware_state,
+			sizeof(enum skeleton_firmware_state));
+
+	return 0;
+}
+
+
+static int skeleton_rawdev_firmware_version_get(
+					struct rte_rawdev *dev,
+					rte_rawdev_obj_t version_info)
+{
+	struct skeleton_rawdev *skeldev;
+	struct skeleton_firmware_version_info *vi;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+	vi = version_info;
+
+	vi->major = skeldev->fw.firmware_version.major;
+	vi->minor = skeldev->fw.firmware_version.minor;
+	vi->subrel = skeldev->fw.firmware_version.subrel;
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_load(struct rte_rawdev *dev,
+					 rte_rawdev_obj_t firmware_buf)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	/* firmware_buf is a mmaped, possibly DMA'able area, buffer. Being
+	 * dummy, all this does is check if firmware_buf is not NULL and
+	 * sets the state of the firmware.
+	 */
+	if (!firmware_buf)
+		return -EINVAL;
+
+	skeldev->fw.firmware_state = SKELETON_FW_LOADED;
+
+	return 0;
+}
+
+static int skeleton_rawdev_firmware_unload(struct rte_rawdev *dev)
+{
+	struct skeleton_rawdev *skeldev;
+
+	SKELETON_PMD_FUNC_TRACE();
+
+	skeldev = skeleton_rawdev_get_priv(dev);
+
+	skeldev->fw.firmware_state = SKELETON_FW_READY;
+
+	return 0;
+}
+
+static const struct rte_rawdev_ops skeleton_rawdev_ops = {
+	.dev_info_get = skeleton_rawdev_info_get,
+	.dev_configure = skeleton_rawdev_configure,
+	.dev_start = skeleton_rawdev_start,
+	.dev_stop = skeleton_rawdev_stop,
+	.dev_close = skeleton_rawdev_close,
+	.dev_reset = skeleton_rawdev_reset,
+
+	.queue_def_conf = skeleton_rawdev_queue_def_conf,
+	.queue_setup = skeleton_rawdev_queue_setup,
+	.queue_release = skeleton_rawdev_queue_release,
+
+	.attr_get = skeleton_rawdev_get_attr,
+	.attr_set = skeleton_rawdev_set_attr,
+
+	.enqueue_bufs = skeleton_rawdev_enqueue_bufs,
+	.dequeue_bufs = skeleton_rawdev_dequeue_bufs,
+
+	.dump = skeleton_rawdev_dump,
+
+	.xstats_get = NULL,
+	.xstats_get_names = NULL,
+	.xstats_get_by_name = NULL,
+	.xstats_reset = NULL,
+
+	.firmware_status_get = skeleton_rawdev_firmware_status_get,
+	.firmware_version_get = skeleton_rawdev_firmware_version_get,
+	.firmware_load = skeleton_rawdev_firmware_load,
+	.firmware_unload = skeleton_rawdev_firmware_unload,
+};
+
+static int
+skeleton_rawdev_create(const char *name,
+		       struct rte_vdev_device *vdev,
+		       int socket_id)
+{
+	int ret = 0, i;
+	struct rte_rawdev *rawdev = NULL;
+	struct skeleton_rawdev *skeldev = NULL;
+
+	if (!name) {
+		SKELETON_PMD_ERR("Invalid name of the device!");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	/* Allocate device structure */
+	rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct skeleton_rawdev),
+					 socket_id);
+	if (rawdev == NULL) {
+		SKELETON_PMD_ERR("Unable to allocate rawdevice");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	rawdev->dev_ops = &skeleton_rawdev_ops;
+	rawdev->device = &vdev->device;
+	rawdev->driver_name = vdev->device.driver->name;
+
+	skeldev = skeleton_rawdev_get_priv(rawdev);
+
+	skeldev->device_id = SKELETON_DEVICE_ID;
+	skeldev->vendor_id = SKELETON_VENDOR_ID;
+	skeldev->capabilities = SKELETON_DEFAULT_CAPA;
+
+	memset(&skeldev->fw, 0, sizeof(struct skeleton_firmware));
+
+	skeldev->fw.firmware_state = SKELETON_FW_READY;
+	skeldev->fw.firmware_version.major = SKELETON_MAJOR_VER;
+	skeldev->fw.firmware_version.minor = SKELETON_MINOR_VER;
+	skeldev->fw.firmware_version.subrel = SKELETON_SUB_VER;
+
+	skeldev->device_state = SKELETON_DEV_STOPPED;
+
+	/* Reset/set to default queue configuration for this device */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
+		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
+		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
+	}
+
+	/* Clear all allocated queue buffers */
+	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
+		clear_queue_bufs(i);
+
+	return ret;
+
+cleanup:
+	if (rawdev)
+		rte_rawdev_pmd_release(rawdev);
+
+	return ret;
+}
+
+static int
+skeleton_rawdev_destroy(const char *name)
+{
+	int ret;
+	struct rte_rawdev *rdev;
+
+	if (!name) {
+		SKELETON_PMD_ERR("Invalid device name");
+		return -EINVAL;
+	}
+
+	rdev = rte_rawdev_pmd_get_named_dev(name);
+	if (!rdev) {
+		SKELETON_PMD_ERR("Invalid device name (%s)", name);
+		return -EINVAL;
+	}
+
+	/* rte_rawdev_close is called by pmd_release */
+	ret = rte_rawdev_pmd_release(rdev);
+	if (ret)
+		SKELETON_PMD_DEBUG("Device cleanup failed");
+
+	return 0;
+}
+
+static int
+skeleton_rawdev_probe(struct rte_vdev_device *vdev)
+{
+	const char *name;
+	int ret = 0;
+
+
+	name = rte_vdev_device_name(vdev);
+	/* More than one instance is not supported */
+	if (skeldev_init_once) {
+		SKELETON_PMD_ERR("Multiple instance not supported for %s",
+				 name);
+		return -EINVAL;
+	}
+
+	SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
+
+	ret = skeleton_rawdev_create(name, vdev, rte_socket_id());
+
+	/* Device instance created; Second instance not posible */
+	skeldev_init_once = 1;
+
+	return ret;
+}
+
+static int
+skeleton_rawdev_remove(struct rte_vdev_device *vdev)
+{
+	const char *name;
+	int ret;
+
+	name = rte_vdev_device_name(vdev);
+
+	SKELETON_PMD_INFO("Closing %s on NUMA node %d", name, rte_socket_id());
+
+	ret = skeleton_rawdev_destroy(name);
+	if (!ret)
+		skeldev_init_once = 0;
+
+	return ret;
+}
+
+static struct rte_vdev_driver skeleton_pmd_drv = {
+	.probe = skeleton_rawdev_probe,
+	.remove = skeleton_rawdev_remove
+};
+
+RTE_PMD_REGISTER_VDEV(SKELETON_PMD_RAWDEV_NAME, skeleton_pmd_drv);
+
+RTE_INIT(skeleton_pmd_init_log);
+
+static void
+skeleton_pmd_init_log(void)
+{
+	skeleton_pmd_logtype = rte_log_register("rawdev.skeleton");
+	if (skeleton_pmd_logtype >= 0)
+		rte_log_set_level(skeleton_pmd_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.h b/drivers/raw/skeleton_rawdev/skeleton_rawdev.h
new file mode 100644
index 000000000..5045b5922
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#ifndef __SKELETON_RAWDEV_H__
+#define __SKELETON_RAWDEV_H__
+
+#include <rte_rawdev.h>
+
+extern int skeleton_pmd_logtype;
+
+#define SKELETON_PMD_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, skeleton_pmd_logtype, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#define SKELETON_PMD_FUNC_TRACE() SKELETON_PMD_LOG(DEBUG, ">>")
+
+#define SKELETON_PMD_DEBUG(fmt, args...) \
+	SKELETON_PMD_LOG(DEBUG, fmt, ## args)
+#define SKELETON_PMD_INFO(fmt, args...) \
+	SKELETON_PMD_LOG(INFO, fmt, ## args)
+#define SKELETON_PMD_ERR(fmt, args...) \
+	SKELETON_PMD_LOG(ERR, fmt, ## args)
+#define SKELETON_PMD_WARN(fmt, args...) \
+	SKELETON_PMD_LOG(WARNING, fmt, ## args)
+/* Macros for self test application */
+#define SKELETON_TEST_INFO	SKELETON_PMD_INFO
+#define SKELETON_TEST_DEBUG	SKELETON_PMD_DEBUG
+#define SKELETON_TEST_ERR	SKELETON_PMD_ERR
+#define SKELETON_TEST_WARN	SKELETON_PMD_WARN
+
+#define SKELETON_SELFTEST_ARG   ("selftest")
+
+#define SKELETON_VENDOR_ID 0x10
+#define SKELETON_DEVICE_ID 0x01
+
+#define SKELETON_MAJOR_VER 1
+#define SKELETON_MINOR_VER 0
+#define SKELETON_SUB_VER   0
+
+#define SKELETON_MAX_QUEUES 1
+
+enum skeleton_firmware_state {
+	SKELETON_FW_READY,
+	SKELETON_FW_LOADED,
+	SKELETON_FW_ERROR
+};
+
+enum skeleton_device_state {
+	SKELETON_DEV_RUNNING,
+	SKELETON_DEV_STOPPED
+};
+
+enum skeleton_queue_state {
+	SKELETON_QUEUE_DETACH,
+	SKELETON_QUEUE_ATTACH
+};
+
+#define SKELETON_QUEUE_DEF_DEPTH 10
+#define SKELETON_QUEUE_MAX_DEPTH 25
+
+struct skeleton_firmware_version_info {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t subrel;
+};
+
+struct skeleton_firmware {
+	/**< Device firmware information */
+	struct skeleton_firmware_version_info firmware_version;
+	/**< Device state */
+	enum skeleton_firmware_state firmware_state;
+
+};
+
+#define SKELETON_MAX_ATTRIBUTES 10
+#define SKELETON_ATTRIBUTE_NAME_MAX 20
+
+struct skeleton_rawdev_attributes {
+	/**< Name of the attribute */
+	char *name;
+	/**< Value or reference of value of attribute */
+	uint64_t value;
+};
+
+/**< Device supports firmware loading/unloading */
+#define SKELETON_CAPA_FW_LOAD	0x0001
+/**< Device supports firmware reset */
+#define SKELETON_CAPA_FW_RESET  0x0002
+/**< Device support queue based communication */
+#define SKELETON_CAPA_QUEUES    0x0004
+/**< Default Capabilities: FW_LOAD, FW_RESET, QUEUES */
+#define SKELETON_DEFAULT_CAPA   0x7
+
+struct skeleton_rawdev_queue {
+	uint8_t state;
+	uint32_t depth;
+};
+
+struct skeleton_rawdev {
+	uint16_t device_id;
+	uint16_t vendor_id;
+	uint16_t num_queues;
+	/**< One of SKELETON_CAPA_* */
+	uint16_t capabilities;
+	/**< State of device; linked to firmware state */
+	enum skeleton_device_state device_state;
+	/**< Firmware configuration */
+	struct skeleton_firmware fw;
+	/**< Collection of all communication channels - which can be referred
+	 *  to as queues.
+	 */
+	struct skeleton_rawdev_queue queues[SKELETON_MAX_QUEUES];
+	/**< Global table containing various pre-defined and user-defined
+	 * attributes.
+	 */
+	struct skeleton_rawdev_attributes attr[SKELETON_MAX_ATTRIBUTES];
+	struct rte_device *device;
+};
+
+struct skeleton_rawdev_conf {
+	uint16_t num_queues;
+	unsigned int capabilities;
+	enum skeleton_device_state device_state;
+	enum skeleton_firmware_state firmware_state;
+};
+
+static inline struct skeleton_rawdev *
+skeleton_rawdev_get_priv(const struct rte_rawdev *rawdev)
+{
+	return rawdev->dev_private;
+}
+
+int test_rawdev_skeldev(void);
+
+#endif /* __SKELETON_RAWDEV_H__ */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index b201e861d..c3f4db46f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -220,6 +220,10 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += -lrte_pmd_octeontx
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OPDL_EVENTDEV) += -lrte_pmd_opdl_event
 endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
+ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+endif # CONFIG_RTE_LIBRTE_RAWDEV
+
 ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_bus_fslmc
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD)      += -lrte_mempool_dpaa2
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 08/10] drivers/raw: support for rawdev testcases
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
                         ` (6 preceding siblings ...)
  2018-01-31  9:13       ` [PATCH v4 07/10] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
@ 2018-01-31  9:13       ` Shreyansh Jain
  2018-01-31 14:01         ` Thomas Monjalon
  2018-01-31  9:13       ` [PATCH v4 09/10] test: enable rawdev skeleton test Shreyansh Jain
                         ` (2 subsequent siblings)
  10 siblings, 1 reply; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-31  9:13 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Patch introduces rawdev unit testcase for validation against the
Skeleton rawdev dummy PMD implementation.

Test cases are added along with the skeleton driver implementation.
It can be enabled by using vdev argument to any DPDK binary:

  --vdev="rawdev_skeleton,self_test=1"

In case 'self_test=1' is not provided, autotest doesn't execute the
test cases but the vdev is still available for application use.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/raw/skeleton_rawdev/Makefile               |   1 +
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      |  66 +++-
 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c | 431 +++++++++++++++++++++
 3 files changed, 497 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c

diff --git a/drivers/raw/skeleton_rawdev/Makefile b/drivers/raw/skeleton_rawdev/Makefile
index 6318359d1..379cb9d17 100644
--- a/drivers/raw/skeleton_rawdev/Makefile
+++ b/drivers/raw/skeleton_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
 # all source are stored in SRCS-y
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev_test.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
index 062d732ec..53c8c13e0 100644
--- a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
@@ -541,6 +541,8 @@ static const struct rte_rawdev_ops skeleton_rawdev_ops = {
 	.firmware_version_get = skeleton_rawdev_firmware_version_get,
 	.firmware_load = skeleton_rawdev_firmware_load,
 	.firmware_unload = skeleton_rawdev_firmware_unload,
+
+	.dev_selftest = test_rawdev_skeldev,
 };
 
 static int
@@ -630,11 +632,62 @@ skeleton_rawdev_destroy(const char *name)
 	return 0;
 }
 
+static int
+skeldev_get_selftest(const char *key __rte_unused,
+		     const char *value,
+		     void *opaque)
+{
+	int *flag = opaque;
+	*flag = atoi(value);
+	return 0;
+}
+
+static int
+skeldev_parse_vdev_args(struct rte_vdev_device *vdev)
+{
+	int selftest = 0;
+	const char *name;
+	const char *params;
+
+	static const char *const args[] = {
+		SKELETON_SELFTEST_ARG,
+		NULL
+	};
+
+	name = rte_vdev_device_name(vdev);
+
+	params = rte_vdev_device_args(vdev);
+	if (params != NULL && params[0] != '\0') {
+		struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
+
+		if (!kvlist) {
+			SKELETON_PMD_INFO(
+				"Ignoring unsupported params supplied '%s'",
+				name);
+		} else {
+			int ret = rte_kvargs_process(kvlist,
+					SKELETON_SELFTEST_ARG,
+					skeldev_get_selftest, &selftest);
+			if (ret != 0 || (selftest < 0 || selftest > 1)) {
+				SKELETON_PMD_ERR("%s: Error in parsing args",
+						 name);
+				rte_kvargs_free(kvlist);
+				ret = -1; /* enforce if selftest is invalid */
+				return ret;
+			}
+		}
+
+		rte_kvargs_free(kvlist);
+	}
+
+	return selftest;
+}
+
 static int
 skeleton_rawdev_probe(struct rte_vdev_device *vdev)
 {
 	const char *name;
-	int ret = 0;
+	int selftest = 0, ret = 0;
 
 
 	name = rte_vdev_device_name(vdev);
@@ -647,7 +700,18 @@ skeleton_rawdev_probe(struct rte_vdev_device *vdev)
 
 	SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
 
+	selftest = skeldev_parse_vdev_args(vdev);
+	/* In case of invalid argument, selftest != 1; ignore other values */
+
 	ret = skeleton_rawdev_create(name, vdev, rte_socket_id());
+	if (!ret) {
+		/* In case command line argument for 'selftest' was passed;
+		 * if invalid arguments were passed, execution continues but
+		 * without selftest.
+		 */
+		if (selftest == 1)
+			test_rawdev_skeldev();
+	}
 
 	/* Device instance created; Second instance not posible */
 	skeldev_init_once = 1;
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
new file mode 100644
index 000000000..3e62b1d16
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
@@ -0,0 +1,431 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#include <rte_common.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_dev.h>
+#include <rte_rawdev.h>
+#include <rte_bus_vdev.h>
+#include <rte_test.h>
+
+/* Using relative path as skeleton_rawdev is not part of exported headers */
+#include "skeleton_rawdev.h"
+
+#define TEST_DEV_ID   0
+#define TEST_DEV_NAME "rawdev_skeleton"
+
+#define SKELDEV_LOGS(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, skeleton_pmd_logtype, fmt "\n", \
+		##args)
+
+#define SKELDEV_TEST_INFO(fmt, args...) \
+	SKELDEV_LOGS(INFO, fmt, ## args)
+#define SKELDEV_TEST_DEBUG(fmt, args...) \
+	SKELDEV_LOGS(DEBUG, fmt, ## args)
+
+#define SKELDEV_TEST_RUN(setup, teardown, test) \
+	skeldev_test_run(setup, teardown, test, #test)
+
+#define TEST_SUCCESS 0
+#define TEST_FAILED  -1
+
+static int total;
+static int passed;
+static int failed;
+static int unsupported;
+
+static int
+testsuite_setup(void)
+{
+	uint8_t count;
+	count = rte_rawdev_count();
+	if (!count) {
+		SKELDEV_TEST_INFO("\tNo existing rawdev; "
+				  "Creating 'skeldev_rawdev'");
+		return rte_vdev_init(TEST_DEV_NAME, NULL);
+	}
+
+	return TEST_SUCCESS;
+}
+
+static void local_teardown(void);
+
+static void
+testsuite_teardown(void)
+{
+	local_teardown();
+}
+
+static void
+local_teardown(void)
+{
+	rte_vdev_uninit(TEST_DEV_NAME);
+}
+
+static int
+test_rawdev_count(void)
+{
+	uint8_t count;
+	count = rte_rawdev_count();
+	RTE_TEST_ASSERT(count > 0, "Invalid rawdev count %" PRIu8, count);
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_get_dev_id(void)
+{
+	int ret;
+	ret = rte_rawdev_get_dev_id("invalid_rawdev_device");
+	RTE_TEST_ASSERT_FAIL(ret, "Expected <0 for invalid dev name ret=%d",
+			     ret);
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_socket_id(void)
+{
+	int socket_id;
+	socket_id = rte_rawdev_socket_id(TEST_DEV_ID);
+	RTE_TEST_ASSERT(socket_id != -EINVAL,
+			"Failed to get socket_id %d", socket_id);
+	socket_id = rte_rawdev_socket_id(RTE_RAWDEV_MAX_DEVS);
+	RTE_TEST_ASSERT(socket_id == -EINVAL,
+			"Expected -EINVAL %d", socket_id);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_info_get(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf skel_conf = {0};
+
+	ret = rte_rawdev_info_get(TEST_DEV_ID, NULL);
+	RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
+
+	rdev_info.dev_private = &skel_conf;
+
+	ret = rte_rawdev_info_get(TEST_DEV_ID, &rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get raw dev info");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_configure(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_set = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+
+	/* Check invalid configuration */
+	ret = rte_rawdev_configure(TEST_DEV_ID, NULL);
+	RTE_TEST_ASSERT(ret == -EINVAL,
+			"Null configure; Expected -EINVAL, got %d", ret);
+
+	/* Valid configuration test */
+	rdev_conf_set.num_queues = 1;
+	rdev_conf_set.capabilities = SKELETON_CAPA_FW_LOAD |
+				     SKELETON_CAPA_FW_RESET;
+
+	rdev_info.dev_private = &rdev_conf_set;
+	ret = rte_rawdev_configure(TEST_DEV_ID,
+				   (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure rawdev (%d)", ret);
+
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_set.num_queues,
+			      rdev_conf_get.num_queues,
+			      "Configuration test failed; num_queues (%d)(%d)",
+			      rdev_conf_set.num_queues,
+			      rdev_conf_get.num_queues);
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_set.capabilities,
+			  rdev_conf_get.capabilities,
+			  "Configuration test failed; capabilities");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_queue_default_conf_get(void)
+{
+	int ret, i;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+	struct skeleton_rawdev_queue q = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)",
+				ret);
+
+	/* call to test_rawdev_configure would have set the num_queues = 1 */
+	RTE_TEST_ASSERT_SUCCESS(!(rdev_conf_get.num_queues > 0),
+				"Invalid number of queues (%d). Expected 1",
+				rdev_conf_get.num_queues);
+	/* All queues by default should have state = DETACH and
+	 * depth = DEF_DEPTH
+	 */
+	for (i = 0; i < rdev_conf_get.num_queues; i++) {
+		rte_rawdev_queue_conf_get(TEST_DEV_ID, i, &q);
+		RTE_TEST_ASSERT_EQUAL(q.depth, SKELETON_QUEUE_DEF_DEPTH,
+				      "Invalid default depth of queue (%d)",
+				      q.depth);
+		RTE_TEST_ASSERT_EQUAL(q.state, SKELETON_QUEUE_DETACH,
+				      "Invalid default state of queue (%d)",
+				      q.state);
+	}
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_queue_setup(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+	struct skeleton_rawdev_queue qset = {0};
+	struct skeleton_rawdev_queue qget = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+	ret = rte_rawdev_info_get(TEST_DEV_ID,
+				  (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+
+	/* call to test_rawdev_configure would have set the num_queues = 1 */
+	RTE_TEST_ASSERT_SUCCESS(!(rdev_conf_get.num_queues > 0),
+				"Invalid number of queues (%d). Expected 1",
+				rdev_conf_get.num_queues);
+
+	/* Modify the queue depth for Queue 0 and attach it */
+	qset.depth = 15;
+	qset.state = SKELETON_QUEUE_ATTACH;
+	ret = rte_rawdev_queue_setup(TEST_DEV_ID, 0, &qset);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup queue (%d)", ret);
+
+	/* Now, fetching the queue 0 should show depth as 15 */
+	ret = rte_rawdev_queue_conf_get(TEST_DEV_ID, 0, &qget);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get queue config (%d)", ret);
+
+	RTE_TEST_ASSERT_EQUAL(qset.depth, qget.depth,
+			      "Failed to set queue depth: Need(%d), has(%d)",
+			      qset.depth, qget.depth);
+
+	return TEST_SUCCESS;
+}
+
+/* After executing test_rawdev_queue_setup, queue_id=0 would have depth as 15.
+ * Releasing should set it back to default. state would set to DETACH
+ */
+static int
+test_rawdev_queue_release(void)
+{
+	int ret;
+	struct skeleton_rawdev_queue qget = {0};
+
+	/* Now, fetching the queue 0 should show depth as 100 */
+	ret = rte_rawdev_queue_release(TEST_DEV_ID, 0);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to release queue 0; (%d)", ret);
+
+	/* Now, fetching the queue 0 should show depth as default */
+	ret = rte_rawdev_queue_conf_get(TEST_DEV_ID, 0, &qget);
+	RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get queue config (%d)", ret);
+
+	RTE_TEST_ASSERT_EQUAL(qget.depth, SKELETON_QUEUE_DEF_DEPTH,
+			      "Release of Queue 0 failed; (depth)");
+
+	RTE_TEST_ASSERT_EQUAL(qget.state, SKELETON_QUEUE_DETACH,
+			      "Release of Queue 0 failed; (state)");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_attr_set_get(void)
+{
+	int ret;
+	int *dummy_value;
+	uint64_t ret_value;
+
+	/* Set an attribute and fetch it */
+	ret = rte_rawdev_set_attr(TEST_DEV_ID, "Test1", 100);
+	RTE_TEST_ASSERT(!ret, "Unable to set an attribute (Test1)");
+
+	dummy_value = malloc(sizeof(int));
+	if (!dummy_value)
+		RTE_TEST_ASSERT(1, "Unable to allocate memory (dummy_value)");
+
+	*dummy_value = 200;
+	ret = rte_rawdev_set_attr(TEST_DEV_ID, "Test2", (uint64_t)dummy_value);
+
+	/* Check if attributes have been set */
+	ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test1", &ret_value);
+	RTE_TEST_ASSERT_EQUAL(ret_value, 100,
+			      "Attribute (Test1) not set correctly (%lu)",
+			      ret_value);
+
+	ret_value = 0;
+	ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test2", &ret_value);
+	RTE_TEST_ASSERT_EQUAL(*((int *)ret_value), 200,
+			      "Attribute (Test2) not set correctly (%lu)",
+			      ret_value);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_start_stop(void)
+{
+	int ret;
+	struct rte_rawdev_info rdev_info = {0};
+	struct skeleton_rawdev_conf rdev_conf_get = {0};
+
+	/* Get the current configuration */
+	rdev_info.dev_private = &rdev_conf_get;
+
+	rte_rawdev_start(TEST_DEV_ID);
+	ret = rte_rawdev_info_get(TEST_DEV_ID, (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_get.device_state, SKELETON_DEV_RUNNING,
+			      "Device start failed. State is (%d)",
+			      rdev_conf_get.device_state);
+
+	rte_rawdev_stop(TEST_DEV_ID);
+	ret = rte_rawdev_info_get(TEST_DEV_ID, (rte_rawdev_obj_t)&rdev_info);
+	RTE_TEST_ASSERT_SUCCESS(ret,
+				"Failed to obtain rawdev configuration (%d)",
+				ret);
+	RTE_TEST_ASSERT_EQUAL(rdev_conf_get.device_state, SKELETON_DEV_STOPPED,
+			      "Device stop failed. State is (%d)",
+			      rdev_conf_get.device_state);
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_rawdev_enqdeq(void)
+{
+	int ret;
+	unsigned int count = 1;
+	uint16_t queue_id = 0;
+	struct rte_rawdev_buf buffers[1];
+	struct rte_rawdev_buf *deq_buffers = NULL;
+
+	buffers[0].buf_addr = malloc(strlen(TEST_DEV_NAME) + 3);
+	if (!buffers[0].buf_addr)
+		goto cleanup;
+	snprintf(buffers[0].buf_addr, strlen(TEST_DEV_NAME) + 2, "%s%d",
+		 TEST_DEV_NAME, 0);
+
+	ret = rte_rawdev_enqueue_buffers(TEST_DEV_ID,
+					 (struct rte_rawdev_buf **)&buffers,
+					 count, &queue_id);
+	RTE_TEST_ASSERT_EQUAL((unsigned int)ret, count,
+			      "Unable to enqueue buffers");
+
+	deq_buffers = malloc(sizeof(struct rte_rawdev_buf) * count);
+	if (!deq_buffers)
+		goto cleanup;
+
+	ret = rte_rawdev_dequeue_buffers(TEST_DEV_ID,
+					(struct rte_rawdev_buf **)&deq_buffers,
+					count, &queue_id);
+	RTE_TEST_ASSERT_EQUAL((unsigned int)ret, count,
+			      "Unable to dequeue buffers");
+
+	if (deq_buffers)
+		free(deq_buffers);
+
+	return TEST_SUCCESS;
+cleanup:
+	if (buffers[0].buf_addr)
+		free(buffers[0].buf_addr);
+	if (deq_buffers)
+		free(deq_buffers);
+
+	return TEST_FAILED;
+}
+
+static void skeldev_test_run(int (*setup)(void),
+			     void (*teardown)(void),
+			     int (*test)(void),
+			     const char *name)
+{
+	int ret = 0;
+
+	if (setup) {
+		ret = setup();
+		if (ret < 0) {
+			SKELDEV_TEST_INFO("Error setting up test %s", name);
+			unsupported++;
+		}
+	}
+
+	if (test) {
+		ret = test();
+		if (ret < 0) {
+			failed++;
+			SKELDEV_TEST_INFO("%s Failed", name);
+		} else {
+			passed++;
+			SKELDEV_TEST_DEBUG("%s Passed", name);
+		}
+	}
+
+	if (teardown)
+		teardown();
+
+	total++;
+}
+
+int
+test_rawdev_skeldev(void)
+{
+	testsuite_setup();
+
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_count);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_get_dev_id);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_socket_id);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_info_get);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_configure);
+	SKELDEV_TEST_RUN(test_rawdev_configure, NULL,
+			 test_rawdev_queue_default_conf_get);
+	SKELDEV_TEST_RUN(test_rawdev_configure, NULL, test_rawdev_queue_setup);
+	SKELDEV_TEST_RUN(test_rawdev_queue_setup, NULL,
+			 test_rawdev_queue_release);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_attr_set_get);
+	SKELDEV_TEST_RUN(NULL, NULL, test_rawdev_start_stop);
+	SKELDEV_TEST_RUN(test_rawdev_queue_setup, NULL, test_rawdev_enqdeq);
+
+	testsuite_teardown();
+
+	SKELDEV_TEST_INFO("Total tests   : %d", total);
+	SKELDEV_TEST_INFO("Passed        : %d", passed);
+	SKELDEV_TEST_INFO("Failed        : %d", failed);
+	SKELDEV_TEST_INFO("Not supported : %d", unsupported);
+
+	if (failed)
+		return -1;
+
+	return 0;
+};
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 09/10] test: enable rawdev skeleton test
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
                         ` (7 preceding siblings ...)
  2018-01-31  9:13       ` [PATCH v4 08/10] drivers/raw: support for rawdev testcases Shreyansh Jain
@ 2018-01-31  9:13       ` Shreyansh Jain
  2018-01-31  9:13       ` [PATCH v4 10/10] doc: add rawdev library page and support Doxygen Shreyansh Jain
  2018-01-31 14:45       ` [PATCH v4 00/10] Introduce generic 'rawdevice' support Thomas Monjalon
  10 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-31  9:13 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Skeleton rawdevice test cases are part of driver layer. This patch
allows test cases to be executed using 'rawdev_autotest' command
in test framework.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS             |  1 +
 test/test/Makefile      |  4 ++++
 test/test/test_rawdev.c | 27 +++++++++++++++++++++++++++
 3 files changed, 32 insertions(+)
 create mode 100644 test/test/test_rawdev.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 320bcf9a4..42ddfbd8c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -320,6 +320,7 @@ M: Shreyansh Jain <shreyansh.jain@nxp.com>
 M: Hemant Agrawal <hemant.agrawal@nxp.com>
 F: lib/librte_rawdev/*
 F: drivers/rawdev/skeleton/*
+F: test/test/test_rawdev.c
 
 
 Bus Drivers
diff --git a/test/test/Makefile b/test/test/Makefile
index cb3884a69..a88cc38bf 100644
--- a/test/test/Makefile
+++ b/test/test/Makefile
@@ -187,6 +187,10 @@ SRCS-y += test_event_ring.c
 SRCS-y += test_event_eth_rx_adapter.c
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
+SRCS-y += test_rawdev.c
+endif
+
 SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) += test_kvargs.c
 
 CFLAGS += -DALLOW_EXPERIMENTAL_API
diff --git a/test/test/test_rawdev.c b/test/test/test_rawdev.c
new file mode 100644
index 000000000..043a38a13
--- /dev/null
+++ b/test/test/test_rawdev.c
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+#include <rte_common.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_dev.h>
+#include <rte_rawdev.h>
+#include <rte_bus_vdev.h>
+
+#include "test.h"
+
+static int
+test_rawdev_selftest_impl(const char *pmd, const char *opts)
+{
+	rte_vdev_init(pmd, opts);
+	return rte_rawdev_selftest(rte_rawdev_get_dev_id(pmd));
+}
+
+static int
+test_rawdev_selftest_skeleton(void)
+{
+	return test_rawdev_selftest_impl("rawdev_skeleton", "");
+}
+
+REGISTER_TEST_COMMAND(rawdev_autotest, test_rawdev_selftest_skeleton);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 10/10] doc: add rawdev library page and support Doxygen
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
                         ` (8 preceding siblings ...)
  2018-01-31  9:13       ` [PATCH v4 09/10] test: enable rawdev skeleton test Shreyansh Jain
@ 2018-01-31  9:13       ` Shreyansh Jain
  2018-01-31 14:45       ` [PATCH v4 00/10] Introduce generic 'rawdevice' support Thomas Monjalon
  10 siblings, 0 replies; 67+ messages in thread
From: Shreyansh Jain @ 2018-01-31  9:13 UTC (permalink / raw)
  To: thomas; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu, Shreyansh Jain

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS                            |   1 +
 doc/api/doxy-api-index.md              |   1 +
 doc/api/doxy-api.conf                  |   1 +
 doc/guides/prog_guide/index.rst        |   1 +
 doc/guides/prog_guide/rawdev_lib.rst   | 107 +++++++++++++++++++++++++++++++++
 doc/guides/rel_notes/release_18_02.rst |  12 ++++
 6 files changed, 123 insertions(+)
 create mode 100644 doc/guides/prog_guide/rawdev_lib.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 42ddfbd8c..7ab7728f4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -321,6 +321,7 @@ M: Hemant Agrawal <hemant.agrawal@nxp.com>
 F: lib/librte_rawdev/*
 F: drivers/rawdev/skeleton/*
 F: test/test/test_rawdev.c
+F: doc/guides/prog_guide/rawdev_lib.rst
 
 
 Bus Drivers
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 59281a109..4259b517a 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -43,6 +43,7 @@ The public API headers are grouped by topics:
   [rte_tm]             (@ref rte_tm.h),
   [rte_mtr]            (@ref rte_mtr.h),
   [bbdev]              (@ref rte_bbdev.h),
+  [rawdev]             (@ref rte_rawdev.h),
   [cryptodev]          (@ref rte_cryptodev.h),
   [security]           (@ref rte_security.h),
   [eventdev]           (@ref rte_eventdev.h),
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index d4a72abc6..cda52fdfb 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -71,6 +71,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           lib/librte_pipeline \
                           lib/librte_port \
                           lib/librte_power \
+                          lib/librte_rawdev \
                           lib/librte_reorder \
                           lib/librte_ring \
                           lib/librte_sched \
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index af5f65a33..beead3105 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -75,6 +75,7 @@ Programmer's Guide
     vhost_lib
     metrics_lib
     port_hotplug_framework
+    rawdev_lib
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
diff --git a/doc/guides/prog_guide/rawdev_lib.rst b/doc/guides/prog_guide/rawdev_lib.rst
new file mode 100644
index 000000000..54bffc585
--- /dev/null
+++ b/doc/guides/prog_guide/rawdev_lib.rst
@@ -0,0 +1,107 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+Rawdevice Library
+=================
+
+Introduction
+------------
+
+In terms of device flavor (type) support, DPDK currently has ethernet
+(lib_ether), cryptodev (libcryptodev), eventdev (libeventdev) and vdev
+(virtual device) support.
+
+For a new type of device, for example an accelerator, there are not many
+options except:
+1. create another lib/librte_MySpecialDev, driver/MySpecialDrv and use it
+through Bus/PMD model.
+2. Or, create a vdev and implement necessary custom APIs which are directly
+exposed from driver layer. However this may still require changes in bus code
+in DPDK.
+
+The DPDK Rawdev library is an abstraction that provides the DPDK framework a
+way to manage such devices in a generic manner without expecting changes to
+library or EAL for each device type. This library provides a generic set of
+operations and APIs for framework and Applications to use, respectively, for
+interfacing with such type of devices.
+
+Design
+------
+
+Key factors guiding design of the Rawdevice library:
+
+1. Following are some generic operations which can be treated as applicable
+   to a large subset of device types. None of the operations are mandatory to
+   be implemented by a driver. Application should also be design for proper
+   handling for unsupported APIs.
+
+  * Device Start/Stop - In some cases, 'reset' might also be required which
+    has different semantics than a start-stop-start cycle.
+  * Configuration - Device, Queue or any other sub-system configuration
+  * I/O - Sending a series of buffers which can enclose any arbitrary data
+  * Statistics - Fetch arbitrary device statistics
+  * Firmware Management - Firmware load/unload/status
+
+2. Application API should be able to pass along arbitrary state information
+   to/fro device driver. This can be achieved by maintaining context
+   information through opaque data or pointers.
+
+Figure below outlines the layout of the rawdevice library and device vis-a-vis
+other well known device types like eth and crypto:
+
+.. code-block:: console
+
+     +-----------------------------------------------------------+
+     |                        Application(s)                     |
+     +------------------------------.----------------------------+
+                                    |
+                                    |
+     +------------------------------'----------------------------+
+     |                     DPDK Framework (APIs)                 |
+     +--------------|----|-----------------|---------------------+
+                   /      \                 \
+            (crypto ops)  (eth ops)      (rawdev ops)        +----+
+            /               \                 \              |DrvA|
+     +-----'---+        +----`----+        +---'-----+       +----+
+     | crypto  |        | ethdev  |        | raw     |
+     +--/------+        +---/-----+        +----/----+       +----+
+       /\                __/\                  /   ..........|DrvB|
+      /  \              /    \                / ../    \     +----+
+  +====+ +====+    +====+ +====+            +==/=+      ```Bus Probe
+  |DevA| |DevB|    |DevC| |DevD|            |DevF|
+  +====+ +====+    +====+ +====+            +====+
+    |      |        |      |                 |
+  ``|``````|````````|``````|`````````````````|````````Bus Scan
+   (PCI)   |       (PCI)  (PCI)            (PCI)
+         (BusA)
+
+ * It is assumed above that DrvB is a PCI type driver which registers itself
+   with PCI Bus
+ * Thereafter, when the PCI scan is done, during probe DrvB would match the
+   rawdev DevF ID and take control of device
+ * Applications can then continue using the device through rawdev API
+   interfaces
+
+
+Device Identification
+~~~~~~~~~~~~~~~~~~~~~
+
+Physical rawdev devices are discovered during the Bus scan executed at DPDK
+initialization, based on their identification and probing with corresponding
+driver. Thus, a generic device needs to have an identifier and a driver
+capable of identifying it through this identifier.
+
+Virtual devices can be created by two mechanisms, either using the EAL command
+line options or from within the application using an EAL API directly.
+
+From the command line using the --vdev EAL option
+
+.. code-block:: console
+
+   --vdev 'rawdev_dev1'
+
+Our using the rte_vdev_init API within the application code.
+
+.. code-block:: c
+
+    rte_vdev_init("rawdev_dev1", NULL)
diff --git a/doc/guides/rel_notes/release_18_02.rst b/doc/guides/rel_notes/release_18_02.rst
index 84e0ad068..ce5ccaf9d 100644
--- a/doc/guides/rel_notes/release_18_02.rst
+++ b/doc/guides/rel_notes/release_18_02.rst
@@ -192,6 +192,17 @@ New Features
     is unaffected by these changes, and can continue to be used for this
     and subsequent releases until such time as it's deprecation is announced.
 
+* **Added Rawdev, a generic device support library.**
+
+  Rawdev library provides support for integrating any generic device type with
+  DPDK framework. Generic devices are those which do not have a pre-defined
+  type within DPDK, for example, ethernet, crypto, event etc.
+  A set of northbound APIs have been defined which encompass a generic set of
+  operations by allowing applications to interact with device using opaque
+  structures/buffers. Also, southbound APIs provide APIs for integrating device
+  either as as part of a physical bus (PCI, FSLMC etc) or through ``vdev``.
+
+  See the :doc:`../prog_guide/rawdev_lib` programmer's guide for more details.
 
 API Changes
 -----------
@@ -308,6 +319,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_pmd_vhost.so.2
      librte_port.so.3
      librte_power.so.1
+     librte_rawdev.so.1
      librte_reorder.so.1
      librte_ring.so.1
      librte_sched.so.1
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 07/10] drivers/raw: introduce skeleton rawdev driver
  2018-01-31  9:13       ` [PATCH v4 07/10] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
@ 2018-01-31 13:20         ` Thomas Monjalon
  2018-01-31 13:31           ` Thomas Monjalon
  0 siblings, 1 reply; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-31 13:20 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

31/01/2018 10:13, Shreyansh Jain:
> Skeleton rawdevice driver, on the lines of eventdev skeleton, is for
> showcasing the rawdev library. This driver implements some of the
> operations of the library based on which a test module can be
> developed.
> 
> Design of skeleton involves a virtual device which is plugged into
> VDEV bus on initialization.
> 
> Also, enable compilation of rawdev skeleton driver.
> 
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> ---

It does not compile on 32-bit:

drivers/raw/skeleton_rawdev/skeleton_rawdev.h:13:51: error:
	format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 6 has type ‘uint64_t {aka long long unsigned int}’ [-Werror=format=]
  rte_log(RTE_LOG_ ## level, skeleton_pmd_logtype, "%s(): " fmt "\n", \

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 07/10] drivers/raw: introduce skeleton rawdev driver
  2018-01-31 13:20         ` Thomas Monjalon
@ 2018-01-31 13:31           ` Thomas Monjalon
  0 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-31 13:31 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

31/01/2018 14:20, Thomas Monjalon:
> 31/01/2018 10:13, Shreyansh Jain:
> > Skeleton rawdevice driver, on the lines of eventdev skeleton, is for
> > showcasing the rawdev library. This driver implements some of the
> > operations of the library based on which a test module can be
> > developed.
> > 
> > Design of skeleton involves a virtual device which is plugged into
> > VDEV bus on initialization.
> > 
> > Also, enable compilation of rawdev skeleton driver.
> > 
> > Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> > ---
> 
> It does not compile on 32-bit:
> 
> drivers/raw/skeleton_rawdev/skeleton_rawdev.h:13:51: error:
> 	format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 6 has type ‘uint64_t {aka long long unsigned int}’ [-Werror=format=]
>   rte_log(RTE_LOG_ ## level, skeleton_pmd_logtype, "%s(): " fmt "\n", \

Fixed when applying:

--- a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
@@ -7,6 +7,7 @@
 #include <stdbool.h>
 #include <errno.h>
 #include <stdint.h>
+#include <inttypes.h>
 #include <string.h>
 
 #include <rte_byteorder.h>
@@ -329,7 +330,7 @@ static int skeleton_rawdev_get_attr(struct rte_rawdev *dev,
                            SKELETON_ATTRIBUTE_NAME_MAX)) {
                        *attr_value = skeldev->attr[i].value;
                        done = 1;
-                       SKELETON_PMD_DEBUG("Attribute (%s) Value (%lu)",
+                       SKELETON_PMD_DEBUG("Attribute (%s) Value (%" PRIu64 ")",
                                           attr_name, *attr_value);
                        break;
                }

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 08/10] drivers/raw: support for rawdev testcases
  2018-01-31  9:13       ` [PATCH v4 08/10] drivers/raw: support for rawdev testcases Shreyansh Jain
@ 2018-01-31 14:01         ` Thomas Monjalon
  0 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-31 14:01 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

31/01/2018 10:13, Shreyansh Jain:
> Patch introduces rawdev unit testcase for validation against the
> Skeleton rawdev dummy PMD implementation.
> 
> Test cases are added along with the skeleton driver implementation.
> It can be enabled by using vdev argument to any DPDK binary:
> 
>   --vdev="rawdev_skeleton,self_test=1"
> 
> In case 'self_test=1' is not provided, autotest doesn't execute the
> test cases but the vdev is still available for application use.
> 
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

More compilation errors on 32-bit:

drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c:277:50: error:
cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
  ret = rte_rawdev_set_attr(TEST_DEV_ID, "Test2", (uint64_t)dummy_value);

drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c:283:19: error:
format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 6 has type ‘uint64_t {aka long long unsigned int}’ [-Werror=format=]
          ret_value);

skeleton_rawdev.o: In function `skeleton_rawdev_probe':
skeleton_rawdev.c:(.text+0x75c): undefined reference to `rte_kvargs_parse'
skeleton_rawdev.c:(.text+0x782): undefined reference to `rte_kvargs_process'
skeleton_rawdev.c:(.text+0x799): undefined reference to `rte_kvargs_free'
skeleton_rawdev.c:(.text+0x814): undefined reference to `rte_kvargs_free'


Fixed:

--- a/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
@@ -274,18 +274,18 @@ test_rawdev_attr_set_get(void)
                RTE_TEST_ASSERT(1, "Unable to allocate memory (dummy_value)");
 
        *dummy_value = 200;
-       ret = rte_rawdev_set_attr(TEST_DEV_ID, "Test2", (uint64_t)dummy_value);
+       ret = rte_rawdev_set_attr(TEST_DEV_ID, "Test2", (uintptr_t)dummy_value);
 
        /* Check if attributes have been set */
        ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test1", &ret_value);
        RTE_TEST_ASSERT_EQUAL(ret_value, 100,
-                             "Attribute (Test1) not set correctly (%lu)",
+                             "Attribute (Test1) not set correctly (%" PRIu64 ")",
                              ret_value);
 
        ret_value = 0;
        ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test2", &ret_value);
-       RTE_TEST_ASSERT_EQUAL(*((int *)ret_value), 200,
-                             "Attribute (Test2) not set correctly (%lu)",
+       RTE_TEST_ASSERT_EQUAL(*((int *)(uintptr_t)ret_value), 200,
+                             "Attribute (Test2) not set correctly (%" PRIu64 ")",
                              ret_value);

And in previous patch:

--- a/drivers/raw/skeleton_rawdev/Makefile
+++ b/drivers/raw/skeleton_rawdev/Makefile
@@ -14,6 +14,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal
 LDLIBS += -lrte_rawdev
 LDLIBS += -lrte_bus_vdev
+LDLIBS += -lrte_kvargs

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 00/10] Introduce generic 'rawdevice' support
  2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
                         ` (9 preceding siblings ...)
  2018-01-31  9:13       ` [PATCH v4 10/10] doc: add rawdev library page and support Doxygen Shreyansh Jain
@ 2018-01-31 14:45       ` Thomas Monjalon
  10 siblings, 0 replies; 67+ messages in thread
From: Thomas Monjalon @ 2018-01-31 14:45 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, fiona.trahe, rosen.xu

31/01/2018 10:13, Shreyansh Jain:
> The rawdevice implementation is targetted towards various accelerator use cases
> which cannot be generalized within existing device models. Aim is to provided a
> generalized structure at the cost of portability guarantee. Specific PMDs may
> also expose any specific config APIs. Applications built over such devices are
> special use-cases involving IP blocks.

Applied with minor changes, doxygen fixes and compilation fixes.

^ permalink raw reply	[flat|nested] 67+ messages in thread

end of thread, other threads:[~2018-01-31 14:46 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-02 12:57 [PATCH v1 0/5] Introduce generic 'rawdevice' support Shreyansh Jain
2018-01-02 12:57 ` [PATCH v1 1/5] rawdev: introduce raw device library support Shreyansh Jain
2018-01-06 13:40   ` Trahe, Fiona
2018-01-08 14:09     ` Shreyansh Jain
2018-01-08 14:51       ` Trahe, Fiona
2018-01-12 15:00         ` Shreyansh Jain
2018-01-12 19:35           ` Trahe, Fiona
2018-01-14 22:42   ` Thomas Monjalon
2018-01-14 22:50   ` Thomas Monjalon
2018-01-02 12:57 ` [PATCH v1 2/5] config: enable compilation of rawdev library Shreyansh Jain
2018-01-14 22:50   ` Thomas Monjalon
2018-01-02 12:57 ` [PATCH v1 3/5] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
2018-01-14 22:54   ` Thomas Monjalon
2018-01-16 10:21     ` Shreyansh Jain
2018-01-16 10:34       ` Thomas Monjalon
2018-01-02 12:57 ` [PATCH v1 4/5] config: enable compilation of rawdev skeleton driver Shreyansh Jain
2018-01-14 22:55   ` Thomas Monjalon
2018-01-02 12:57 ` [PATCH v1 5/5] test: support for rawdev testcases Shreyansh Jain
2018-01-14 22:58   ` Thomas Monjalon
2018-01-16 10:07     ` Shreyansh Jain
2018-01-16 10:32       ` Thomas Monjalon
2018-01-14 23:00 ` [PATCH v1 0/5] Introduce generic 'rawdevice' support Thomas Monjalon
2018-01-15  5:30   ` Shreyansh Jain
2018-01-23 13:59 ` [PATCH v2 00/10] " Shreyansh Jain
2018-01-23 13:59   ` [PATCH v2 01/10] rawdev: introduce raw device library support Shreyansh Jain
2018-01-23 13:59   ` [PATCH v2 02/10] rawdev: add attribute get and set support Shreyansh Jain
2018-01-23 13:59   ` [PATCH v2 03/10] rawdev: add buffer stream IO support Shreyansh Jain
2018-01-23 13:59   ` [PATCH v2 04/10] rawdev: support for extended stats Shreyansh Jain
2018-01-23 13:59   ` [PATCH v2 05/10] rawdev: support for firmware management Shreyansh Jain
2018-01-23 13:59   ` [PATCH v2 06/10] rawdev: add self test support Shreyansh Jain
2018-01-23 13:59   ` [PATCH v2 07/10] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
2018-01-23 13:59   ` [PATCH v2 08/10] drivers/raw: support for rawdev testcases Shreyansh Jain
2018-01-23 13:59   ` [PATCH v2 09/10] test: enable rawdev skeleton test Shreyansh Jain
2018-01-23 13:59   ` [PATCH v2 10/10] maintainers: claim ownership of rawdev Shreyansh Jain
2018-01-25 22:21   ` [PATCH v2 00/10] Introduce generic 'rawdevice' support Thomas Monjalon
2018-01-29 23:49     ` Thomas Monjalon
2018-01-30  6:31       ` Shreyansh Jain
2018-01-30 14:56   ` [PATCH v3 00/11] " Shreyansh Jain
2018-01-30 14:57     ` [PATCH v3 01/11] rawdev: introduce raw device library support Shreyansh Jain
2018-01-30 14:57     ` [PATCH v3 02/11] rawdev: add attribute get and set support Shreyansh Jain
2018-01-30 14:57     ` [PATCH v3 03/11] rawdev: add buffer stream IO support Shreyansh Jain
2018-01-30 14:57     ` [PATCH v3 04/11] rawdev: support for extended stats Shreyansh Jain
2018-01-30 14:57     ` [PATCH v3 05/11] rawdev: support for firmware management Shreyansh Jain
2018-01-30 14:57     ` [PATCH v3 06/11] rawdev: add self test support Shreyansh Jain
2018-01-30 14:57     ` [PATCH v3 07/11] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
2018-01-30 16:48       ` Thomas Monjalon
2018-01-30 14:57     ` [PATCH v3 08/11] drivers/raw: support for rawdev testcases Shreyansh Jain
2018-01-30 14:57     ` [PATCH v3 09/11] test: enable rawdev skeleton test Shreyansh Jain
2018-01-30 14:57     ` [PATCH v3 10/11] maintainers: claim ownership of rawdev Shreyansh Jain
2018-01-30 16:50       ` Thomas Monjalon
2018-01-30 14:57     ` [PATCH v3 11/11] doc: add rawdev library page Shreyansh Jain
2018-01-30 16:55     ` [PATCH v3 00/11] Introduce generic 'rawdevice' support Thomas Monjalon
2018-01-31  9:13     ` [PATCH v4 00/10] " Shreyansh Jain
2018-01-31  9:13       ` [PATCH v4 01/10] rawdev: introduce raw device library support Shreyansh Jain
2018-01-31  9:13       ` [PATCH v4 02/10] rawdev: add attribute get and set support Shreyansh Jain
2018-01-31  9:13       ` [PATCH v4 03/10] rawdev: add buffer stream IO support Shreyansh Jain
2018-01-31  9:13       ` [PATCH v4 04/10] rawdev: support for extended stats Shreyansh Jain
2018-01-31  9:13       ` [PATCH v4 05/10] rawdev: support for firmware management Shreyansh Jain
2018-01-31  9:13       ` [PATCH v4 06/10] rawdev: add self test support Shreyansh Jain
2018-01-31  9:13       ` [PATCH v4 07/10] drivers/raw: introduce skeleton rawdev driver Shreyansh Jain
2018-01-31 13:20         ` Thomas Monjalon
2018-01-31 13:31           ` Thomas Monjalon
2018-01-31  9:13       ` [PATCH v4 08/10] drivers/raw: support for rawdev testcases Shreyansh Jain
2018-01-31 14:01         ` Thomas Monjalon
2018-01-31  9:13       ` [PATCH v4 09/10] test: enable rawdev skeleton test Shreyansh Jain
2018-01-31  9:13       ` [PATCH v4 10/10] doc: add rawdev library page and support Doxygen Shreyansh Jain
2018-01-31 14:45       ` [PATCH v4 00/10] Introduce generic 'rawdevice' support Thomas Monjalon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.