get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/31990/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 31990,
    "url": "https://patches.dpdk.org/api/patches/31990/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1512682857-79467-1-git-send-email-amr.mokhtar@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1512682857-79467-1-git-send-email-amr.mokhtar@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1512682857-79467-1-git-send-email-amr.mokhtar@intel.com",
    "date": "2017-12-07T21:40:52",
    "name": "[dpdk-dev,v3,1/5] bbdev: librte_bbdev library",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "2dbf3d670f4a422400a6b4e583e37c687657d3d0",
    "submitter": {
        "id": 807,
        "url": "https://patches.dpdk.org/api/people/807/?format=api",
        "name": "Mokhtar, Amr",
        "email": "amr.mokhtar@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1512682857-79467-1-git-send-email-amr.mokhtar@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/31990/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/31990/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 0AEFC37A2;\n\tThu,  7 Dec 2017 22:41:07 +0100 (CET)",
            "from mga18.intel.com (mga18.intel.com [134.134.136.126])\n\tby dpdk.org (Postfix) with ESMTP id D5B151D8E\n\tfor <dev@dpdk.org>; Thu,  7 Dec 2017 22:41:04 +0100 (CET)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n\tby orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t07 Dec 2017 13:41:02 -0800",
            "from silpixa00391537.ir.intel.com (HELO\n\tsilpixa00391537.ger.corp.intel.com) ([10.237.222.189])\n\tby fmsmga005.fm.intel.com with ESMTP; 07 Dec 2017 13:40:59 -0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.45,374,1508828400\"; d=\"scan'208\";a=\"184674717\"",
        "From": "Amr Mokhtar <amr.mokhtar@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "thomas@monjalon.net, anatoly.burakov@intel.com,\n\tpablo.de.lara.guarch@intel.com, niall.power@intel.com,\n\tchris.macnamara@intel.com, Amr Mokhtar <amr.mokhtar@intel.com>",
        "Date": "Thu,  7 Dec 2017 21:40:52 +0000",
        "Message-Id": "<1512682857-79467-1-git-send-email-amr.mokhtar@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "Subject": "[dpdk-dev] [PATCH v3 1/5] bbdev: librte_bbdev library",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "- BBDEV library files\n- BBDEV is tagged as EXPERIMENTAL\n- Makefiles and configuration macros definition\n- The bbdev framework and the 'null' driver are enabled by default\n- The bbdev test framework is enabled by default\n- Release Notes of the initial version and MAINTAINERS\n\nSigned-off-by: Amr Mokhtar <amr.mokhtar@intel.com>\n---\n MAINTAINERS                            |   11 +\n config/common_base                     |   18 +\n doc/guides/rel_notes/release_18_02.rst |   10 +\n lib/Makefile                           |    3 +\n lib/librte_bbdev/Makefile              |   56 ++\n lib/librte_bbdev/rte_bbdev.c           | 1095 ++++++++++++++++++++++++++++++++\n lib/librte_bbdev/rte_bbdev.h           |  741 +++++++++++++++++++++\n lib/librte_bbdev/rte_bbdev_op.h        |  532 ++++++++++++++++\n lib/librte_bbdev/rte_bbdev_op_ldpc.h   |  545 ++++++++++++++++\n lib/librte_bbdev/rte_bbdev_pmd.h       |  223 +++++++\n lib/librte_bbdev/rte_bbdev_version.map |   37 ++\n mk/rte.app.mk                          |   13 +\n 12 files changed, 3284 insertions(+)\n create mode 100644 lib/librte_bbdev/Makefile\n create mode 100644 lib/librte_bbdev/rte_bbdev.c\n create mode 100644 lib/librte_bbdev/rte_bbdev.h\n create mode 100644 lib/librte_bbdev/rte_bbdev_op.h\n create mode 100644 lib/librte_bbdev/rte_bbdev_op_ldpc.h\n create mode 100644 lib/librte_bbdev/rte_bbdev_pmd.h\n create mode 100644 lib/librte_bbdev/rte_bbdev_version.map",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex f0baeb4..696f048 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -272,6 +272,17 @@ F: lib/librte_cryptodev/\n F: test/test/test_cryptodev*\n F: examples/l2fwd-crypto/\n \n+BBDEV API - EXPERIMENTAL\n+M: Amr Mokhtar <amr.mokhtar@intel.com>\n+F: lib/librte_bbdev/\n+F: drivers/bbdev/\n+F: app/test-bbdev\n+F: examples/bbdev_app/\n+F: doc/guides/bbdevs/\n+F: doc/guides/prog_guide/bbdev.rst\n+F: doc/guides/sample_app_ug/bbdev_app.rst\n+F: doc/guides/tools/testbbdev.rst\n+\n Security API - EXPERIMENTAL\n M: Akhil Goyal <akhil.goyal@nxp.com>\n M: Declan Doherty <declan.doherty@intel.com>\ndiff --git a/config/common_base b/config/common_base\nindex e74febe..5243e0f 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -593,6 +593,24 @@ CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV_DEBUG=n\n CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF=y\n CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF_DEBUG=n\n \n+# Compile generic wireless base band device library\n+# EXPERIMENTAL: API may change without prior notice\n+#\n+CONFIG_RTE_LIBRTE_BBDEV=y\n+CONFIG_RTE_LIBRTE_BBDEV_DEBUG=n\n+CONFIG_RTE_BBDEV_MAX_DEVS=128\n+CONFIG_RTE_BBDEV_NAME_MAX_LEN=64\n+\n+#\n+# Compile PMD for NULL bbdev device\n+#\n+CONFIG_RTE_LIBRTE_PMD_BBDEV_NULL=y\n+\n+#\n+# Compile PMD for turbo software bbdev device\n+#\n+CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW=n\n+\n #\n # Compile librte_ring\n #\ndiff --git a/doc/guides/rel_notes/release_18_02.rst b/doc/guides/rel_notes/release_18_02.rst\nindex 24b67bb..3e5a8de 100644\n--- a/doc/guides/rel_notes/release_18_02.rst\n+++ b/doc/guides/rel_notes/release_18_02.rst\n@@ -41,6 +41,16 @@ New Features\n      Also, make sure to start the actual text at the margin.\n      =========================================================\n \n+* **Added Wireless Base Band Device (bbdev).**\n+\n+  The Wireless Baseband Device library is an acceleration abstraction\n+  framework for 3gpp Layer 1 processing functions that provides a common\n+  programming interface for seamless opeartion on integrated or discrete\n+  hardware accelerators or using optimized software libraries for signal\n+  processing.\n+  The current release only supports 4G Turbo Code FEC function.\n+\n+  See the :doc:`../prog_guide/bbdev` programmer's guide for more details.\n \n API Changes\n -----------\ndiff --git a/lib/Makefile b/lib/Makefile\nindex dc4e8df..8e5bd7c 100644\n--- a/lib/Makefile\n+++ b/lib/Makefile\n@@ -58,6 +58,9 @@ DEPDIRS-librte_security += librte_ether\n DEPDIRS-librte_security += librte_cryptodev\n DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += librte_eventdev\n DEPDIRS-librte_eventdev := librte_eal librte_ring librte_ether librte_hash\n+DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev\n+DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_ring librte_mbuf\n+DEPDIRS-librte_bbdev += librte_kvargs\n DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += librte_vhost\n DEPDIRS-librte_vhost := librte_eal librte_mempool librte_mbuf librte_ether\n DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash\ndiff --git a/lib/librte_bbdev/Makefile b/lib/librte_bbdev/Makefile\nnew file mode 100644\nindex 0000000..8d59564\n--- /dev/null\n+++ b/lib/librte_bbdev/Makefile\n@@ -0,0 +1,56 @@\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2017 Intel Corporation. All rights reserved.\n+#\n+#   Redistribution and use in source and binary forms, with or without\n+#   modification, are permitted provided that the following conditions\n+#   are met:\n+#\n+#     * Redistributions of source code must retain the above copyright\n+#       notice, this list of conditions and the following disclaimer.\n+#     * Redistributions in binary form must reproduce the above copyright\n+#       notice, this list of conditions and the following disclaimer in\n+#       the documentation and/or other materials provided with the\n+#       distribution.\n+#     * Neither the name of Intel Corporation nor the names of its\n+#       contributors may be used to endorse or promote products derived\n+#       from this software without specific prior written permission.\n+#\n+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+#   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+# library name\n+LIB = librte_bbdev.a\n+\n+# library version\n+LIBABIVER := 1\n+\n+# build flags\n+CFLAGS += -O3\n+CFLAGS += $(WERROR_FLAGS)\n+LDLIBS += -lrte_eal -lrte_mempool -lrte_ring -lrte_mbuf\n+LDLIBS += -lrte_kvargs\n+\n+# library source files\n+SRCS-y += rte_bbdev.c\n+\n+# export include files\n+SYMLINK-y-include += rte_bbdev_op.h\n+SYMLINK-y-include += rte_bbdev.h\n+SYMLINK-y-include += rte_bbdev_pmd.h\n+\n+# versioning export map\n+EXPORT_MAP := rte_bbdev_version.map\n+\n+include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/lib/librte_bbdev/rte_bbdev.c b/lib/librte_bbdev/rte_bbdev.c\nnew file mode 100644\nindex 0000000..9565d03\n--- /dev/null\n+++ b/lib/librte_bbdev/rte_bbdev.c\n@@ -0,0 +1,1095 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <stdint.h>\n+#include <string.h>\n+#include <stdbool.h>\n+\n+#include <rte_common.h>\n+#include <rte_errno.h>\n+#include <rte_log.h>\n+#include <rte_debug.h>\n+#include <rte_eal.h>\n+#include <rte_malloc.h>\n+#include <rte_mempool.h>\n+#include <rte_memzone.h>\n+#include <rte_lcore.h>\n+#include <rte_dev.h>\n+#include <rte_spinlock.h>\n+#include <rte_tailq.h>\n+#include <rte_interrupts.h>\n+\n+#include \"rte_bbdev_op.h\"\n+#include \"rte_bbdev.h\"\n+#include \"rte_bbdev_pmd.h\"\n+\n+#define DEV_NAME \"BBDEV\"\n+\n+\n+/* Helper macro to check dev_id is valid */\n+#define VALID_DEV_OR_RET_ERR(dev, dev_id) do { \\\n+\tif (dev == NULL) { \\\n+\t\trte_bbdev_log(ERR, \"device %u is invalid\", dev_id); \\\n+\t\treturn -ENODEV; \\\n+\t} \\\n+} while (0)\n+\n+/* Helper macro to check dev_ops is valid */\n+#define VALID_DEV_OPS_OR_RET_ERR(dev, dev_id) do { \\\n+\tif (dev->dev_ops == NULL) { \\\n+\t\trte_bbdev_log(ERR, \"NULL dev_ops structure in device %u\", \\\n+\t\t\t\tdev_id); \\\n+\t\treturn -ENODEV; \\\n+\t} \\\n+} while (0)\n+\n+/* Helper macro to check that driver implements required function pointer */\n+#define VALID_FUNC_OR_RET_ERR(func, dev_id) do { \\\n+\tif (func == NULL) { \\\n+\t\trte_bbdev_log(ERR, \"device %u does not support %s\", \\\n+\t\t\t\tdev_id, #func); \\\n+\t\treturn -ENOTSUP; \\\n+\t} \\\n+} while (0)\n+\n+/* Helper macro to check that queue is valid */\n+#define VALID_QUEUE_OR_RET_ERR(queue_id, dev) do { \\\n+\tif (queue_id >= dev->data->num_queues) { \\\n+\t\trte_bbdev_log(ERR, \"Invalid queue_id %u for device %u\", \\\n+\t\t\t\tqueue_id, dev->data->dev_id); \\\n+\t\treturn -ERANGE; \\\n+\t} \\\n+} while (0)\n+\n+/* List of callback functions registered by an application */\n+struct rte_bbdev_callback {\n+\tTAILQ_ENTRY(rte_bbdev_callback) next;  /* Callbacks list */\n+\trte_bbdev_cb_fn cb_fn;  /* Callback address */\n+\tvoid *cb_arg;  /* Parameter for callback */\n+\tvoid *ret_param;  /* Return parameter */\n+\tenum rte_bbdev_event_type event; /* Interrupt event type */\n+\tuint32_t active; /* Callback is executing */\n+};\n+\n+/* spinlock for bbdev device callbacks */\n+static rte_spinlock_t rte_bbdev_cb_lock = RTE_SPINLOCK_INITIALIZER;\n+\n+/* Global array of all devices. This is not static because it's used by the\n+ * inline enqueue and dequeue functions\n+ */\n+struct rte_bbdev rte_bbdev_devices[RTE_BBDEV_MAX_DEVS];\n+\n+/* Global array with rte_bbdev_data structures */\n+static struct rte_bbdev_data *rte_bbdev_data;\n+\n+/* Memzone name for global bbdev data pool */\n+static const char *MZ_RTE_BBDEV_DATA = \"rte_bbdev_data\";\n+\n+/* Number of currently valid devices */\n+static uint16_t num_devs;\n+\n+/* Return pointer to device structure, with validity check */\n+static struct rte_bbdev *\n+get_dev(uint16_t dev_id)\n+{\n+\tif (rte_bbdev_is_valid(dev_id))\n+\t\treturn &rte_bbdev_devices[dev_id];\n+\treturn NULL;\n+}\n+\n+/* Allocate global data array */\n+static void\n+rte_bbdev_data_alloc(void)\n+{\n+\tconst unsigned int flags = 0;\n+\tconst struct rte_memzone *mz;\n+\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n+\t\tmz = rte_memzone_reserve(MZ_RTE_BBDEV_DATA,\n+\t\t\t\tRTE_BBDEV_MAX_DEVS * sizeof(*rte_bbdev_data),\n+\t\t\t\trte_socket_id(), flags);\n+\t} else\n+\t\tmz = rte_memzone_lookup(MZ_RTE_BBDEV_DATA);\n+\tif (mz == NULL)\n+\t\trte_panic(\"Cannot allocate memzone for bbdev port data\\n\");\n+\n+\trte_bbdev_data = mz->addr;\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n+\t\tmemset(rte_bbdev_data, 0,\n+\t\t\t\tRTE_BBDEV_MAX_DEVS * sizeof(*rte_bbdev_data));\n+}\n+\n+/* Find lowest device id with no attached device */\n+static uint16_t\n+find_free_dev_id(void)\n+{\n+\tuint16_t i;\n+\tfor (i = 0; i < RTE_BBDEV_MAX_DEVS; i++) {\n+\t\tif (rte_bbdev_devices[i].state == RTE_BBDEV_UNUSED)\n+\t\t\treturn i;\n+\t}\n+\treturn RTE_BBDEV_MAX_DEVS;\n+}\n+\n+struct rte_bbdev *\n+rte_bbdev_allocate(const char *name)\n+{\n+\tint ret;\n+\tstruct rte_bbdev *bbdev;\n+\tuint16_t dev_id;\n+\n+\tif (name == NULL) {\n+\t\trte_bbdev_log(ERR, \"Invalid null device name\");\n+\t\treturn NULL;\n+\t}\n+\n+\tif (rte_bbdev_get_named_dev(name) != NULL) {\n+\t\trte_bbdev_log(ERR, \"Device \\\"%s\\\" is already allocated\", name);\n+\t\treturn NULL;\n+\t}\n+\n+\tdev_id = find_free_dev_id();\n+\tif (dev_id == RTE_BBDEV_MAX_DEVS) {\n+\t\trte_bbdev_log(ERR, \"Reached maximum number of devices\");\n+\t\treturn NULL;\n+\t}\n+\n+\tbbdev = &rte_bbdev_devices[dev_id];\n+\n+\tif (rte_bbdev_data == NULL)\n+\t\trte_bbdev_data_alloc();\n+\n+\tbbdev->data = &rte_bbdev_data[dev_id];\n+\tmemset(bbdev->data, 0, sizeof(*bbdev->data));\n+\n+\tbbdev->data->dev_id = dev_id;\n+\tbbdev->state = RTE_BBDEV_INITIALIZED;\n+\n+\tret = snprintf(bbdev->data->name, RTE_BBDEV_NAME_MAX_LEN, \"%s\", name);\n+\tif ((ret < 0) || (ret >= RTE_BBDEV_NAME_MAX_LEN)) {\n+\t\trte_bbdev_log(ERR, \"Copying device name \\\"%s\\\" failed\", name);\n+\t\treturn NULL;\n+\t}\n+\n+\t/* init user callbacks */\n+\tTAILQ_INIT(&(bbdev->list_cbs));\n+\n+\tnum_devs++;\n+\n+\trte_bbdev_log_debug(\"Initialised device %s (id = %u). Num devices = %u\",\n+\t\t\tname, dev_id, num_devs);\n+\n+\treturn bbdev;\n+}\n+\n+int\n+rte_bbdev_release(struct rte_bbdev *bbdev)\n+{\n+\tuint16_t dev_id;\n+\tstruct rte_bbdev_callback *cb, *next;\n+\n+\tif (bbdev == NULL) {\n+\t\trte_bbdev_log(ERR, \"NULL bbdev\");\n+\t\treturn -ENODEV;\n+\t}\n+\tdev_id = bbdev->data->dev_id;\n+\n+\t/* free all callbacks from the device's list */\n+\tfor (cb = TAILQ_FIRST(&bbdev->list_cbs); cb != NULL; cb = next) {\n+\n+\t\tnext = TAILQ_NEXT(cb, next);\n+\t\tTAILQ_REMOVE(&(bbdev->list_cbs), cb, next);\n+\t\trte_free(cb);\n+\t}\n+\n+\tmemset(bbdev, 0, sizeof(*bbdev));\n+\tnum_devs--;\n+\tbbdev->state = RTE_BBDEV_UNUSED;\n+\n+\trte_bbdev_log_debug(\n+\t\t\t\"Un-initialised device id = %u. Num devices = %u\",\n+\t\t\tdev_id, num_devs);\n+\treturn 0;\n+}\n+\n+struct rte_bbdev *\n+rte_bbdev_get_named_dev(const char *name)\n+{\n+\tunsigned int i;\n+\n+\tif (name == NULL) {\n+\t\trte_bbdev_log(ERR, \"NULL driver name\");\n+\t\treturn NULL;\n+\t}\n+\n+\tfor (i = 0; i < RTE_BBDEV_MAX_DEVS; i++) {\n+\t\tstruct rte_bbdev *dev = get_dev(i);\n+\t\tif (dev && (strncmp(dev->data->name,\n+\t\t\t\tname, RTE_BBDEV_NAME_MAX_LEN) == 0))\n+\t\t\treturn dev;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+uint16_t\n+rte_bbdev_count(void)\n+{\n+\treturn num_devs;\n+}\n+\n+bool\n+rte_bbdev_is_valid(uint16_t dev_id)\n+{\n+\tif ((dev_id < RTE_BBDEV_MAX_DEVS) &&\n+\t\trte_bbdev_devices[dev_id].state == RTE_BBDEV_INITIALIZED)\n+\t\treturn true;\n+\treturn false;\n+}\n+\n+uint16_t\n+rte_bbdev_find_next(uint16_t dev_id)\n+{\n+\tdev_id++;\n+\tfor (; dev_id < RTE_BBDEV_MAX_DEVS; dev_id++)\n+\t\tif (rte_bbdev_is_valid(dev_id))\n+\t\t\tbreak;\n+\treturn dev_id;\n+}\n+\n+int\n+rte_bbdev_setup_queues(uint16_t dev_id, uint16_t num_queues, int socket_id)\n+{\n+\tunsigned int i;\n+\tint ret;\n+\tstruct rte_bbdev_driver_info dev_info;\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\n+\tif (dev->data->started) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Device %u cannot be configured when started\",\n+\t\t\t\tdev_id);\n+\t\treturn -EBUSY;\n+\t}\n+\n+\t/* Get device driver information to get max number of queues */\n+\tVALID_FUNC_OR_RET_ERR(dev->dev_ops->info_get, dev_id);\n+\tmemset(&dev_info, 0, sizeof(dev_info));\n+\tdev->dev_ops->info_get(dev, &dev_info);\n+\n+\tif ((num_queues == 0) || (num_queues > dev_info.max_num_queues)) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Device %u supports 0 < N <= %u queues, not %u\",\n+\t\t\t\tdev_id, dev_info.max_num_queues, num_queues);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* If re-configuration, get driver to free existing internal memory */\n+\tif (dev->data->queues != NULL) {\n+\t\tVALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_release, dev_id);\n+\t\tfor (i = 0; i < dev->data->num_queues; i++) {\n+\t\t\tint ret = dev->dev_ops->queue_release(dev, i);\n+\t\t\tif (ret < 0) {\n+\t\t\t\trte_bbdev_log(ERR,\n+\t\t\t\t\t\t\"Device %u queue %u release failed\",\n+\t\t\t\t\t\tdev_id, i);\n+\t\t\t\treturn ret;\n+\t\t\t}\n+\t\t}\n+\t\t/* Call optional device close */\n+\t\tif (dev->dev_ops->close) {\n+\t\t\tret = dev->dev_ops->close(dev);\n+\t\t\tif (ret < 0) {\n+\t\t\t\trte_bbdev_log(ERR,\n+\t\t\t\t\t\t\"Device %u couldn't be closed\",\n+\t\t\t\t\t\tdev_id);\n+\t\t\t\treturn ret;\n+\t\t\t}\n+\t\t}\n+\t\trte_free(dev->data->queues);\n+\t}\n+\n+\t/* Allocate queue pointers */\n+\tdev->data->queues = rte_calloc_socket(DEV_NAME, num_queues,\n+\t\t\tsizeof(dev->data->queues[0]), RTE_CACHE_LINE_SIZE,\n+\t\t\t\tdev->data->socket_id);\n+\tif (dev->data->queues == NULL) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"calloc of %u queues for device %u on socket %i failed\",\n+\t\t\t\tnum_queues, dev_id, dev->data->socket_id);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tdev->data->num_queues = num_queues;\n+\n+\t/* Call optional device configuration */\n+\tif (dev->dev_ops->setup_queues) {\n+\t\tret = dev->dev_ops->setup_queues(dev, num_queues, socket_id);\n+\t\tif (ret < 0) {\n+\t\t\trte_bbdev_log(ERR,\n+\t\t\t\t\t\"Device %u memory configuration failed\",\n+\t\t\t\t\tdev_id);\n+\t\t\tgoto error;\n+\t\t}\n+\t}\n+\n+\trte_bbdev_log_debug(\"Device %u set up with %u queues\", dev_id,\n+\t\t\tnum_queues);\n+\treturn 0;\n+\n+error:\n+\tdev->data->num_queues = 0;\n+\trte_free(dev->data->queues);\n+\tdev->data->queues = NULL;\n+\treturn ret;\n+}\n+\n+int\n+rte_bbdev_intr_enable(uint16_t dev_id)\n+{\n+\tint ret;\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\n+\tif (dev->data->started) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Device %u cannot be configured when started\",\n+\t\t\t\tdev_id);\n+\t\treturn -EBUSY;\n+\t}\n+\n+\tif (dev->dev_ops->intr_enable) {\n+\t\tret = dev->dev_ops->intr_enable(dev);\n+\t\tif (ret < 0) {\n+\t\t\trte_bbdev_log(ERR,\n+\t\t\t\t\t\"Device %u interrupts configuration failed\",\n+\t\t\t\t\tdev_id);\n+\t\t\treturn ret;\n+\t\t}\n+\t\trte_bbdev_log_debug(\"Enabled interrupts for dev %u\", dev_id);\n+\t\treturn 0;\n+\t}\n+\n+\trte_bbdev_log(ERR, \"Device %u doesn't support interrupts\", dev_id);\n+\treturn -ENOTSUP;\n+}\n+\n+int\n+rte_bbdev_queue_configure(uint16_t dev_id, uint16_t queue_id,\n+\t\tconst struct rte_bbdev_queue_conf *conf)\n+{\n+\tint ret = 0;\n+\tstruct rte_bbdev_driver_info dev_info;\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tconst struct rte_bbdev_op_cap *p;\n+\tstruct rte_bbdev_queue_conf *stored_conf;\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_QUEUE_OR_RET_ERR(queue_id, dev);\n+\n+\tif (dev->data->queues[queue_id].started || dev->data->started) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Queue %u of device %u cannot be configured when started\",\n+\t\t\t\tqueue_id, dev_id);\n+\t\treturn -EBUSY;\n+\t}\n+\n+\tVALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_release, dev_id);\n+\tVALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_setup, dev_id);\n+\n+\t/* Get device driver information to verify config is valid */\n+\tVALID_FUNC_OR_RET_ERR(dev->dev_ops->info_get, dev_id);\n+\tmemset(&dev_info, 0, sizeof(dev_info));\n+\tdev->dev_ops->info_get(dev, &dev_info);\n+\n+\t/* Check configuration is valid */\n+\tif (conf != NULL) {\n+\t\tif ((conf->op_type == RTE_BBDEV_OP_NONE) &&\n+\t\t\t\t(dev_info.capabilities[0].type ==\n+\t\t\t\tRTE_BBDEV_OP_NONE)) {\n+\t\t\tret = 1;\n+\t\t} else\n+\t\t\tfor (p = dev_info.capabilities;\n+\t\t\t\t\tp->type != RTE_BBDEV_OP_NONE; p++) {\n+\t\t\t\tif (conf->op_type == p->type) {\n+\t\t\t\t\tret = 1;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t}\n+\t\tif (ret == 0) {\n+\t\t\trte_bbdev_log(ERR, \"Invalid operation type\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tif (conf->queue_size > dev_info.queue_size_lim) {\n+\t\t\trte_bbdev_log(ERR,\n+\t\t\t\t\t\"Size (%u) of queue %u of device %u must be: <= %u\",\n+\t\t\t\t\tconf->queue_size, queue_id, dev_id,\n+\t\t\t\t\tdev_info.queue_size_lim);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tif (!rte_is_power_of_2(conf->queue_size)) {\n+\t\t\trte_bbdev_log(ERR,\n+\t\t\t\t\t\"Size (%u) of queue %u of device %u must be a power of 2\",\n+\t\t\t\t\tconf->queue_size, queue_id, dev_id);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tif (conf->priority > dev_info.max_queue_priority) {\n+\t\t\trte_bbdev_log(ERR,\n+\t\t\t\t\t\"Priority (%u) of queue %u of bdev %u must be <= %u\",\n+\t\t\t\t\tconf->priority, queue_id, dev_id,\n+\t\t\t\t\tdev_info.max_queue_priority);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\t/* Release existing queue (in case of queue reconfiguration) */\n+\tif (dev->data->queues[queue_id].queue_private != NULL) {\n+\t\tret = dev->dev_ops->queue_release(dev, queue_id);\n+\t\tif (ret < 0) {\n+\t\t\trte_bbdev_log(ERR, \"Device %u queue %u release failed\",\n+\t\t\t\t\tdev_id, queue_id);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\t/* Get driver to setup the queue */\n+\tret = dev->dev_ops->queue_setup(dev, queue_id, (conf != NULL) ?\n+\t\t\tconf : &dev_info.default_queue_conf);\n+\tif (ret < 0) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Device %u queue %u setup failed\", dev_id,\n+\t\t\t\tqueue_id);\n+\t\treturn ret;\n+\t}\n+\n+\t/* Store configuration */\n+\tstored_conf = &dev->data->queues[queue_id].conf;\n+\tmemcpy(stored_conf,\n+\t\t\t(conf != NULL) ? conf : &dev_info.default_queue_conf,\n+\t\t\tsizeof(*stored_conf));\n+\n+\trte_bbdev_log_debug(\"Configured dev%uq%u (size=%u, type=%s, prio=%u)\",\n+\t\t\tdev_id, queue_id, stored_conf->queue_size,\n+\t\t\trte_bbdev_op_type_str(stored_conf->op_type),\n+\t\t\tstored_conf->priority);\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_bbdev_start(uint16_t dev_id)\n+{\n+\tint i;\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\n+\tif (dev->data->started) {\n+\t\trte_bbdev_log_debug(\"Device %u is already started\", dev_id);\n+\t\treturn 0;\n+\t}\n+\n+\tif (dev->dev_ops->start) {\n+\t\tint ret = dev->dev_ops->start(dev);\n+\t\tif (ret < 0) {\n+\t\t\trte_bbdev_log(ERR, \"Device %u start failed\", dev_id);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\t/* Store new state */\n+\tfor (i = 0; i < dev->data->num_queues; i++)\n+\t\tif (!dev->data->queues[i].conf.deferred_start)\n+\t\t\tdev->data->queues[i].started = true;\n+\tdev->data->started = true;\n+\n+\trte_bbdev_log_debug(\"Started device %u\", dev_id);\n+\treturn 0;\n+}\n+\n+int\n+rte_bbdev_stop(uint16_t dev_id)\n+{\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\n+\tif (!dev->data->started) {\n+\t\trte_bbdev_log_debug(\"Device %u is already stopped\", dev_id);\n+\t\treturn 0;\n+\t}\n+\n+\tif (dev->dev_ops->stop)\n+\t\tdev->dev_ops->stop(dev);\n+\tdev->data->started = false;\n+\n+\trte_bbdev_log_debug(\"Stopped device %u\", dev_id);\n+\treturn 0;\n+}\n+\n+int\n+rte_bbdev_close(uint16_t dev_id)\n+{\n+\tint ret;\n+\tuint16_t i;\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\n+\tif (dev->data->started) {\n+\t\tret = rte_bbdev_stop(dev_id);\n+\t\tif (ret < 0) {\n+\t\t\trte_bbdev_log(ERR, \"Device %u stop failed\", dev_id);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\t/* Free memory used by queues */\n+\tfor (i = 0; i < dev->data->num_queues; i++) {\n+\t\tret = dev->dev_ops->queue_release(dev, i);\n+\t\tif (ret < 0) {\n+\t\t\trte_bbdev_log(ERR, \"Device %u queue %u release failed\",\n+\t\t\t\t\tdev_id, i);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\trte_free(dev->data->queues);\n+\n+\tif (dev->dev_ops->close) {\n+\t\tret = dev->dev_ops->close(dev);\n+\t\tif (ret < 0) {\n+\t\t\trte_bbdev_log(ERR, \"Device %u close failed\", dev_id);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\t/* Clear configuration */\n+\tdev->data->queues = NULL;\n+\tdev->data->num_queues = 0;\n+\n+\trte_bbdev_log_debug(\"Closed device %u\", dev_id);\n+\treturn 0;\n+}\n+\n+int\n+rte_bbdev_queue_start(uint16_t dev_id, uint16_t queue_id)\n+{\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_QUEUE_OR_RET_ERR(queue_id, dev);\n+\n+\tif (dev->data->queues[queue_id].started) {\n+\t\trte_bbdev_log_debug(\"Queue %u of device %u already started\",\n+\t\t\t\tqueue_id, dev_id);\n+\t\treturn 0;\n+\t}\n+\n+\tif (dev->dev_ops->queue_start) {\n+\t\tint ret = dev->dev_ops->queue_start(dev, queue_id);\n+\t\tif (ret < 0) {\n+\t\t\trte_bbdev_log(ERR, \"Device %u queue %u start failed\",\n+\t\t\t\t\tdev_id, queue_id);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\tdev->data->queues[queue_id].started = true;\n+\n+\trte_bbdev_log_debug(\"Started queue %u of device %u\", queue_id, dev_id);\n+\treturn 0;\n+}\n+\n+int\n+rte_bbdev_queue_stop(uint16_t dev_id, uint16_t queue_id)\n+{\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_QUEUE_OR_RET_ERR(queue_id, dev);\n+\n+\tif (!dev->data->queues[queue_id].started) {\n+\t\trte_bbdev_log_debug(\"Queue %u of device %u already stopped\",\n+\t\t\t\tqueue_id, dev_id);\n+\t\treturn 0;\n+\t}\n+\n+\tif (dev->dev_ops->queue_stop) {\n+\t\tint ret = dev->dev_ops->queue_stop(dev, queue_id);\n+\t\tif (ret < 0) {\n+\t\t\trte_bbdev_log(ERR, \"Device %u queue %u stop failed\",\n+\t\t\t\t\tdev_id, queue_id);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\tdev->data->queues[queue_id].started = false;\n+\n+\trte_bbdev_log_debug(\"Stopped queue %u of device %u\", queue_id, dev_id);\n+\treturn 0;\n+}\n+\n+/* Get device statistics */\n+static void\n+get_stats_from_queues(struct rte_bbdev *dev, struct rte_bbdev_stats *stats)\n+{\n+\tunsigned int q_id;\n+\tfor (q_id = 0; q_id < dev->data->num_queues; q_id++) {\n+\t\tstruct rte_bbdev_stats *q_stats =\n+\t\t\t\t&dev->data->queues[q_id].queue_stats;\n+\n+\t\tstats->enqueued_count += q_stats->enqueued_count;\n+\t\tstats->dequeued_count += q_stats->dequeued_count;\n+\t\tstats->enqueue_err_count += q_stats->enqueue_err_count;\n+\t\tstats->dequeue_err_count += q_stats->dequeue_err_count;\n+\t}\n+\trte_bbdev_log_debug(\"Got stats on %u\", dev->data->dev_id);\n+}\n+\n+static void\n+reset_stats_in_queues(struct rte_bbdev *dev)\n+{\n+\tunsigned int q_id;\n+\tfor (q_id = 0; q_id < dev->data->num_queues; q_id++) {\n+\t\tstruct rte_bbdev_stats *q_stats =\n+\t\t\t\t&dev->data->queues[q_id].queue_stats;\n+\n+\t\tmemset(q_stats, 0, sizeof(*q_stats));\n+\t}\n+\trte_bbdev_log_debug(\"Reset stats on %u\", dev->data->dev_id);\n+}\n+\n+int\n+rte_bbdev_stats_get(uint16_t dev_id, struct rte_bbdev_stats *stats)\n+{\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\n+\tif (stats == NULL) {\n+\t\trte_bbdev_log(ERR, \"NULL stats structure\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemset(stats, 0, sizeof(*stats));\n+\tif (dev->dev_ops->stats_get != NULL)\n+\t\tdev->dev_ops->stats_get(dev, stats);\n+\telse\n+\t\tget_stats_from_queues(dev, stats);\n+\n+\trte_bbdev_log_debug(\"Retrieved stats of device %u\", dev_id);\n+\treturn 0;\n+}\n+\n+int\n+rte_bbdev_stats_reset(uint16_t dev_id)\n+{\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\n+\tif (dev->dev_ops->stats_reset != NULL)\n+\t\tdev->dev_ops->stats_reset(dev);\n+\telse\n+\t\treset_stats_in_queues(dev);\n+\n+\trte_bbdev_log_debug(\"Reset stats of device %u\", dev_id);\n+\treturn 0;\n+}\n+\n+int\n+rte_bbdev_info_get(uint16_t dev_id, struct rte_bbdev_info *dev_info)\n+{\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_FUNC_OR_RET_ERR(dev->dev_ops->info_get, dev_id);\n+\n+\tif (dev_info == NULL) {\n+\t\trte_bbdev_log(ERR, \"NULL dev info structure\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Copy data maintained by device interface layer */\n+\tmemset(dev_info, 0, sizeof(*dev_info));\n+\tdev_info->dev_name = dev->data->name;\n+\tdev_info->num_queues = dev->data->num_queues;\n+\tdev_info->bus = rte_bus_find_by_device(dev->device);\n+\tdev_info->socket_id = dev->data->socket_id;\n+\tdev_info->started = dev->data->started;\n+\n+\t/* Copy data maintained by device driver layer */\n+\tdev->dev_ops->info_get(dev, &dev_info->drv);\n+\n+\trte_bbdev_log_debug(\"Retrieved info of device %u\", dev_id);\n+\treturn 0;\n+}\n+\n+int\n+rte_bbdev_queue_info_get(uint16_t dev_id, uint16_t queue_id,\n+\t\tstruct rte_bbdev_queue_info *dev_info)\n+{\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tVALID_QUEUE_OR_RET_ERR(queue_id, dev);\n+\n+\tif (dev_info == NULL) {\n+\t\trte_bbdev_log(ERR, \"NULL queue info structure\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Copy data to output */\n+\tmemset(dev_info, 0, sizeof(*dev_info));\n+\tdev_info->conf = dev->data->queues[queue_id].conf;\n+\tdev_info->started = dev->data->queues[queue_id].started;\n+\n+\trte_bbdev_log_debug(\"Retrieved info of queue %u of device %u\",\n+\t\t\tqueue_id, dev_id);\n+\treturn 0;\n+}\n+\n+/* Calculate size needed to store bbdev_op, depending on type */\n+static unsigned int\n+get_bbdev_op_size(enum rte_bbdev_op_type type)\n+{\n+\tunsigned int result = 0;\n+\tswitch (type) {\n+\tcase RTE_BBDEV_OP_NONE:\n+\t\tresult = RTE_MAX(sizeof(struct rte_bbdev_dec_op),\n+\t\t\t\tsizeof(struct rte_bbdev_enc_op));\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_TURBO_DEC:\n+\t\tresult = sizeof(struct rte_bbdev_dec_op);\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_TURBO_ENC:\n+\t\tresult = sizeof(struct rte_bbdev_enc_op);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn result;\n+}\n+\n+/* Initialise a bbdev_op structure */\n+static void\n+bbdev_op_init(struct rte_mempool *mempool, void *arg, void *element,\n+\t\t__rte_unused unsigned int n)\n+{\n+\tenum rte_bbdev_op_type type = *(enum rte_bbdev_op_type *)arg;\n+\n+\tif (type == RTE_BBDEV_OP_TURBO_DEC) {\n+\t\tstruct rte_bbdev_dec_op *op = element;\n+\t\tmemset(op, 0, mempool->elt_size);\n+\t\top->mempool = mempool;\n+\t} else if (type == RTE_BBDEV_OP_TURBO_ENC) {\n+\t\tstruct rte_bbdev_enc_op *op = element;\n+\t\tmemset(op, 0, mempool->elt_size);\n+\t\top->mempool = mempool;\n+\t}\n+}\n+\n+struct rte_mempool *\n+rte_bbdev_op_pool_create(const char *name, enum rte_bbdev_op_type type,\n+\t\tunsigned int num_elements, unsigned int cache_size,\n+\t\tint socket_id)\n+{\n+\tstruct rte_bbdev_op_pool_private *priv;\n+\tstruct rte_mempool *mp;\n+\n+\tif (name == NULL) {\n+\t\trte_bbdev_log(ERR, \"NULL name for op pool\");\n+\t\treturn NULL;\n+\t}\n+\n+\tif (type >= RTE_BBDEV_OP_TYPE_COUNT) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Invalid op type (%u), should be less than %u\",\n+\t\t\t\ttype, RTE_BBDEV_OP_TYPE_COUNT);\n+\t\treturn NULL;\n+\t}\n+\n+\tmp = rte_mempool_create(name, num_elements, get_bbdev_op_size(type),\n+\t\t\tcache_size, sizeof(struct rte_bbdev_op_pool_private),\n+\t\t\tNULL, NULL, bbdev_op_init, &type, socket_id, 0);\n+\tif (mp == NULL) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Failed to create op pool %s (num ops=%u, op size=%u) with error: %s\",\n+\t\t\t\tname, num_elements, get_bbdev_op_size(type),\n+\t\t\t\trte_strerror(rte_errno));\n+\t\treturn NULL;\n+\t}\n+\n+\trte_bbdev_log_debug(\n+\t\t\t\"Op pool %s created for %u ops (type=%s, cache=%u, socket=%u, size=%u)\",\n+\t\t\tname, num_elements, rte_bbdev_op_type_str(type),\n+\t\t\tcache_size, socket_id, get_bbdev_op_size(type));\n+\n+\tpriv = (struct rte_bbdev_op_pool_private *)rte_mempool_get_priv(mp);\n+\tpriv->type = type;\n+\n+\treturn mp;\n+}\n+\n+int\n+rte_bbdev_callback_register(uint16_t dev_id, enum rte_bbdev_event_type event,\n+\t\trte_bbdev_cb_fn cb_fn, void *cb_arg)\n+{\n+\tstruct rte_bbdev_callback *user_cb;\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tif (event >= RTE_BBDEV_EVENT_MAX) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Invalid event type (%u), should be less than %u\",\n+\t\t\t\tevent, RTE_BBDEV_EVENT_MAX);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (cb_fn == NULL) {\n+\t\trte_bbdev_log(ERR, \"NULL callback function\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\trte_spinlock_lock(&rte_bbdev_cb_lock);\n+\n+\tTAILQ_FOREACH(user_cb, &(dev->list_cbs), next) {\n+\t\tif (user_cb->cb_fn == cb_fn &&\n+\t\t\t\tuser_cb->cb_arg == cb_arg &&\n+\t\t\t\tuser_cb->event == event)\n+\t\t\tbreak;\n+\t}\n+\n+\t/* create a new callback. */\n+\tif (user_cb == NULL) {\n+\t\tuser_cb = rte_zmalloc(\"INTR_USER_CALLBACK\",\n+\t\t\t\tsizeof(struct rte_bbdev_callback), 0);\n+\t\tif (user_cb != NULL) {\n+\t\t\tuser_cb->cb_fn = cb_fn;\n+\t\t\tuser_cb->cb_arg = cb_arg;\n+\t\t\tuser_cb->event = event;\n+\t\t\tTAILQ_INSERT_TAIL(&(dev->list_cbs), user_cb, next);\n+\t\t}\n+\t}\n+\n+\trte_spinlock_unlock(&rte_bbdev_cb_lock);\n+\treturn (user_cb == NULL) ? -ENOMEM : 0;\n+}\n+\n+int\n+rte_bbdev_callback_unregister(uint16_t dev_id, enum rte_bbdev_event_type event,\n+\t\trte_bbdev_cb_fn cb_fn, void *cb_arg)\n+{\n+\tint ret = 0;\n+\tstruct rte_bbdev_callback *cb, *next;\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\n+\tif (event >= RTE_BBDEV_EVENT_MAX) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Invalid event type (%u), should be less than %u\",\n+\t\t\t\tevent, RTE_BBDEV_EVENT_MAX);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (cb_fn == NULL) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"NULL callback function cannot be unregistered\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tdev = &rte_bbdev_devices[dev_id];\n+\trte_spinlock_lock(&rte_bbdev_cb_lock);\n+\n+\tfor (cb = TAILQ_FIRST(&dev->list_cbs); cb != NULL; cb = next) {\n+\n+\t\tnext = TAILQ_NEXT(cb, next);\n+\n+\t\tif (cb->cb_fn != cb_fn || cb->event != event ||\n+\t\t\t\t(cb_arg != (void *)-1 && cb->cb_arg != cb_arg))\n+\t\t\tcontinue;\n+\n+\t\t/* If this callback is not executing right now, remove it. */\n+\t\tif (cb->active == 0) {\n+\t\t\tTAILQ_REMOVE(&(dev->list_cbs), cb, next);\n+\t\t\trte_free(cb);\n+\t\t} else\n+\t\t\tret = -EAGAIN;\n+\t}\n+\n+\trte_spinlock_unlock(&rte_bbdev_cb_lock);\n+\treturn ret;\n+}\n+\n+void\n+rte_bbdev_pmd_callback_process(struct rte_bbdev *dev,\n+\tenum rte_bbdev_event_type event, void *ret_param)\n+{\n+\tstruct rte_bbdev_callback *cb_lst;\n+\tstruct rte_bbdev_callback dev_cb;\n+\n+\tif (dev == NULL) {\n+\t\trte_bbdev_log(ERR, \"NULL device\");\n+\t\treturn;\n+\t}\n+\n+\tif (dev->data == NULL) {\n+\t\trte_bbdev_log(ERR, \"NULL data structure\");\n+\t\treturn;\n+\t}\n+\n+\tif (event >= RTE_BBDEV_EVENT_MAX) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Invalid event type (%u), should be less than %u\",\n+\t\t\t\tevent, RTE_BBDEV_EVENT_MAX);\n+\t\treturn;\n+\t}\n+\n+\trte_spinlock_lock(&rte_bbdev_cb_lock);\n+\tTAILQ_FOREACH(cb_lst, &(dev->list_cbs), next) {\n+\t\tif (cb_lst->cb_fn == NULL || cb_lst->event != event)\n+\t\t\tcontinue;\n+\t\tdev_cb = *cb_lst;\n+\t\tcb_lst->active = 1;\n+\t\tif (ret_param != NULL)\n+\t\t\tdev_cb.ret_param = ret_param;\n+\n+\t\trte_spinlock_unlock(&rte_bbdev_cb_lock);\n+\t\tdev_cb.cb_fn(dev->data->dev_id, dev_cb.event,\n+\t\t\t\tdev_cb.cb_arg, dev_cb.ret_param);\n+\t\trte_spinlock_lock(&rte_bbdev_cb_lock);\n+\t\tcb_lst->active = 0;\n+\t}\n+\trte_spinlock_unlock(&rte_bbdev_cb_lock);\n+}\n+\n+int\n+rte_bbdev_queue_intr_enable(uint16_t dev_id, uint16_t queue_id)\n+{\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\tVALID_QUEUE_OR_RET_ERR(queue_id, dev);\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\tVALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_intr_enable, dev_id);\n+\treturn dev->dev_ops->queue_intr_enable(dev, queue_id);\n+}\n+\n+int\n+rte_bbdev_queue_intr_disable(uint16_t dev_id, uint16_t queue_id)\n+{\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\tVALID_QUEUE_OR_RET_ERR(queue_id, dev);\n+\tVALID_DEV_OPS_OR_RET_ERR(dev, dev_id);\n+\tVALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_intr_disable, dev_id);\n+\treturn dev->dev_ops->queue_intr_disable(dev, queue_id);\n+}\n+\n+int\n+rte_bbdev_queue_intr_ctl(uint16_t dev_id, uint16_t queue_id, int epfd, int op,\n+\t\tvoid *data)\n+{\n+\tuint32_t vec;\n+\tstruct rte_bbdev *dev = get_dev(dev_id);\n+\tstruct rte_intr_handle *intr_handle;\n+\tint ret;\n+\n+\tVALID_DEV_OR_RET_ERR(dev, dev_id);\n+\tVALID_QUEUE_OR_RET_ERR(queue_id, dev);\n+\n+\tintr_handle = dev->intr_handle;\n+\tif (!intr_handle || !intr_handle->intr_vec) {\n+\t\trte_bbdev_log(ERR, \"Device %u intr handle unset\\n\", dev_id);\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\tif (queue_id >= RTE_MAX_RXTX_INTR_VEC_ID) {\n+\t\trte_bbdev_log(ERR, \"Device %u queue_id %u is too big\\n\",\n+\t\t\t\tdev_id, queue_id);\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\tvec = intr_handle->intr_vec[queue_id];\n+\tret = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data);\n+\tif (ret && (ret != -EEXIST)) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"dev %u q %u int ctl error op %d epfd %d vec %u\\n\",\n+\t\t\t\tdev_id, queue_id, op, epfd, vec);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+\n+const char *\n+rte_bbdev_op_type_str(enum rte_bbdev_op_type op_type)\n+{\n+\tstatic const char * const op_types[] = {\n+\t\t\"RTE_BBDEV_OP_NONE\",\n+\t\t\"RTE_BBDEV_OP_TURBO_DEC\",\n+\t\t\"RTE_BBDEV_OP_TURBO_ENC\",\n+\t};\n+\n+\tif (op_type < RTE_BBDEV_OP_TYPE_COUNT)\n+\t\treturn op_types[op_type];\n+\n+\trte_bbdev_log(ERR, \"Invalid operation type\");\n+\treturn \"\";\n+}\n+\n+\n+int bbdev_logtype;\n+\n+RTE_INIT(rte_bbdev_init_log);\n+static void\n+rte_bbdev_init_log(void)\n+{\n+\tbbdev_logtype = rte_log_register(\"lib.bbdev\");\n+\tif (bbdev_logtype >= 0)\n+\t\trte_log_set_level(bbdev_logtype, RTE_LOG_NOTICE);\n+}\ndiff --git a/lib/librte_bbdev/rte_bbdev.h b/lib/librte_bbdev/rte_bbdev.h\nnew file mode 100644\nindex 0000000..4774ae8\n--- /dev/null\n+++ b/lib/librte_bbdev/rte_bbdev.h\n@@ -0,0 +1,741 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _RTE_BBDEV_H_\n+#define _RTE_BBDEV_H_\n+\n+/**\n+ * @file rte_bbdev.h\n+ *\n+ * Wireless base band device application APIs.\n+ *\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ *\n+ * This API allows an application to discover, configure and use a device to\n+ * process operations. An asynchronous API (enqueue, followed by later dequeue)\n+ * is used for processing operations.\n+ *\n+ * The functions in this API are not thread-safe when called on the same\n+ * target object (a device, or a queue on a device), with the exception that\n+ * one thread can enqueue operations to a queue while another thread dequeues\n+ * from the same queue.\n+ */\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#include <stdint.h>\n+#include <stdbool.h>\n+#include <string.h>\n+\n+#include <rte_bus.h>\n+#include <rte_cpuflags.h>\n+#include <rte_memory.h>\n+\n+#include \"rte_bbdev_op.h\"\n+\n+#ifndef RTE_BBDEV_MAX_DEVS\n+#define RTE_BBDEV_MAX_DEVS 128  /**< Max number of devices */\n+#endif\n+\n+/** Flags indiciate current state of BBDEV device */\n+enum rte_bbdev_state {\n+\tRTE_BBDEV_UNUSED,\n+\tRTE_BBDEV_INITIALIZED\n+};\n+\n+/**\n+ * Get the total number of devices that have been successfully initialised.\n+ *\n+ * @return\n+ *   The total number of usable devices.\n+ */\n+uint16_t\n+rte_bbdev_count(void);\n+\n+/**\n+ * Check if a device is valid.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ *\n+ * @return\n+ *   true if device ID is valid and device is attached, false otherwise.\n+ */\n+bool\n+rte_bbdev_is_valid(uint16_t dev_id);\n+\n+/**\n+ * Get the next enabled device.\n+ *\n+ * @param dev_id\n+ *   The current device\n+ *\n+ * @return\n+ *   - The next device, or\n+ *   - RTE_BBDEV_MAX_DEVS if none found\n+ */\n+uint16_t\n+rte_bbdev_find_next(uint16_t dev_id);\n+\n+/** Iterate through all enabled devices */\n+#define RTE_BBDEV_FOREACH(i) for (i = rte_bbdev_find_next(-1); \\\n+\t\ti < RTE_BBDEV_MAX_DEVS; \\\n+\t\ti = rte_bbdev_find_next(i))\n+\n+/**\n+ * Setup up device queues.\n+ * This function must be called on a device before setting up the queues and\n+ * starting the device. It can also be called when a device is in the stopped\n+ * state. If any device queues have been configured their configuration will be\n+ * cleared by a call to this function.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param num_queues\n+ *   Number of queues to configure on device.\n+ * @param socket_id\n+ *   ID of a socket which will be used to allocate memory.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - -ENODEV if dev_id is invalid or the device is corrupted\n+ *   - -EINVAL if num_queues is invalid, 0 or greater than maximum\n+ *   - -EBUSY if the identified device has already started\n+ *   - -ENOMEM if unable to allocate memory\n+ */\n+int\n+rte_bbdev_setup_queues(uint16_t dev_id, uint16_t num_queues, int socket_id);\n+\n+/**\n+ * Enable interrupts.\n+ * This function may be called before starting the device to enable the\n+ * interrupts if they are available.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - -ENODEV if dev_id is invalid or the device is corrupted\n+ *   - -EBUSY if the identified device has already started\n+ *   - -ENOTSUP if the interrupts are not supported by the device\n+ */\n+int\n+rte_bbdev_intr_enable(uint16_t dev_id);\n+\n+/** Device queue configuration structure */\n+struct rte_bbdev_queue_conf {\n+\tint socket;  /**< NUMA socket used for memory allocation */\n+\tuint32_t queue_size;  /**< Size of queue */\n+\tuint8_t priority;  /**< Queue priority */\n+\tbool deferred_start; /**< Do not start queue when device is started. */\n+\tenum rte_bbdev_op_type op_type; /**< Operation type */\n+};\n+\n+/**\n+ * Configure a queue on a device.\n+ * This function can be called after device configuration, and before starting.\n+ * It can also be called when the device or the queue is in the stopped state.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param queue_id\n+ *   The index of the queue.\n+ * @param conf\n+ *   The queue configuration. If NULL, a default configuration will be used.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - EINVAL if the identified queue size or priority are invalid\n+ *   - EBUSY if the identified queue or its device have already started\n+ */\n+int\n+rte_bbdev_queue_configure(uint16_t dev_id, uint16_t queue_id,\n+\t\tconst struct rte_bbdev_queue_conf *conf);\n+\n+/**\n+ * Start a device.\n+ * This is the last step needed before enqueueing operations is possible.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - negative value on failure - as returned from PMD driver\n+ */\n+int\n+rte_bbdev_start(uint16_t dev_id);\n+\n+/**\n+ * Stop a device.\n+ * The device can be reconfigured, and restarted after being stopped.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ *\n+ * @return\n+ *   - 0 on success\n+ */\n+int\n+rte_bbdev_stop(uint16_t dev_id);\n+\n+/**\n+ * Close a device.\n+ * The device cannot be restarted without reconfiguration!\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ *\n+ * @return\n+ *   - 0 on success\n+ */\n+int\n+rte_bbdev_close(uint16_t dev_id);\n+\n+/**\n+ * Start a specified queue on a device.\n+ * This is only needed if the queue has been stopped, or if the deferred_start\n+ * flag has been set when configuring the queue.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param queue_id\n+ *   The index of the queue.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - negative value on failure - as returned from PMD driver\n+ */\n+int\n+rte_bbdev_queue_start(uint16_t dev_id, uint16_t queue_id);\n+\n+/**\n+ * Stop a specified queue on a device, to allow re configuration.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param queue_id\n+ *   The index of the queue.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - negative value on failure - as returned from PMD driver\n+ */\n+int\n+rte_bbdev_queue_stop(uint16_t dev_id, uint16_t queue_id);\n+\n+/** Device statistics. */\n+struct rte_bbdev_stats {\n+\tuint64_t enqueued_count;  /**< Count of all operations enqueued */\n+\tuint64_t dequeued_count;  /**< Count of all operations dequeued */\n+\t/** Total error count on operations enqueued */\n+\tuint64_t enqueue_err_count;\n+\t/** Total error count on operations dequeued */\n+\tuint64_t dequeue_err_count;\n+};\n+\n+/**\n+ * Retrieve the general I/O statistics of a device.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param stats\n+ *   Pointer to structure to where statistics will be copied. On error, this\n+ *   location may or may not have been modified.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - EINVAL if invalid parameter pointer is provided\n+ */\n+int\n+rte_bbdev_stats_get(uint16_t dev_id, struct rte_bbdev_stats *stats);\n+\n+/**\n+ * Reset the statistics of a device.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @return\n+ *   - 0 on success\n+ */\n+int\n+rte_bbdev_stats_reset(uint16_t dev_id);\n+\n+/** Device information supplied by the device's driver */\n+struct rte_bbdev_driver_info {\n+\t/** Driver name */\n+\tconst char *driver_name;\n+\n+\t/** Maximum number of queues supported by the device */\n+\tunsigned int max_num_queues;\n+\t/** Queue size limit (queue size must also be power of 2) */\n+\tuint32_t queue_size_lim;\n+\t/** Set if device off-loads operation to hardware  */\n+\tbool hardware_accelerated;\n+\t/** Max value supported by queue priority */\n+\tuint8_t max_queue_priority;\n+\t/** Set if device supports per-queue interrupts */\n+\tbool queue_intr_supported;\n+\t/** Minimum alignment of buffers, in bytes */\n+\tuint16_t min_alignment;\n+\t/** Default queue configuration used if none is supplied  */\n+\tstruct rte_bbdev_queue_conf default_queue_conf;\n+\t/** Device operation capabilities */\n+\tconst struct rte_bbdev_op_cap *capabilities;\n+\t/** Device cpu_flag requirements */\n+\tconst enum rte_cpu_flag_t *cpu_flag_reqs;\n+};\n+\n+/** Macro used at end of bbdev PMD list */\n+#define RTE_BBDEV_END_OF_CAPABILITIES_LIST() \\\n+\t{ RTE_BBDEV_OP_NONE }\n+\n+/** Device information structure used by an application to discover a devices\n+ * capabilities and current configuration\n+ */\n+struct rte_bbdev_info {\n+\tint socket_id;  /**< NUMA socket that device is on */\n+\tconst char *dev_name;  /**< Unique device name */\n+\tconst struct rte_bus *bus;  /**< Bus information */\n+\tuint16_t num_queues;  /**< Number of queues currently configured */\n+\tbool started;  /**< Set if device is currently started */\n+\tstruct rte_bbdev_driver_info drv;  /**< Info from device driver */\n+};\n+\n+/**\n+ * Retrieve information about a device.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param dev_info\n+ *   Pointer to structure to where information will be copied. On error, this\n+ *   location may or may not have been modified.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - EINVAL if invalid parameter pointer is provided\n+ */\n+int\n+rte_bbdev_info_get(uint16_t dev_id, struct rte_bbdev_info *dev_info);\n+\n+/** Queue information */\n+struct rte_bbdev_queue_info {\n+\t/** Current device configuration */\n+\tstruct rte_bbdev_queue_conf conf;\n+\t/** Set if queue is currently started */\n+\tbool started;\n+};\n+\n+/**\n+ * Retrieve information about a specific queue on a device.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param queue_id\n+ *   The index of the queue.\n+ * @param dev_info\n+ *   Pointer to structure to where information will be copied. On error, this\n+ *   location may or may not have been modified.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - EINVAL if invalid parameter pointer is provided\n+ */\n+int\n+rte_bbdev_queue_info_get(uint16_t dev_id, uint16_t queue_id,\n+\t\tstruct rte_bbdev_queue_info *dev_info);\n+\n+/** @internal The data structure associated with each queue of a device. */\n+struct rte_bbdev_queue_data {\n+\tvoid *queue_private;  /**< Driver-specific per-queue data */\n+\tstruct rte_bbdev_queue_conf conf;  /**< Current configuration */\n+\tstruct rte_bbdev_stats queue_stats;  /**< Queue statistics */\n+\tbool started;  /**< Queue state */\n+};\n+\n+/** @internal Enqueue encode operations for processing on queue of a device. */\n+typedef uint16_t (*rte_bbdev_enqueue_enc_ops_t)(\n+\t\tstruct rte_bbdev_queue_data *q_data,\n+\t\tstruct rte_bbdev_enc_op **ops,\n+\t\tuint16_t num);\n+\n+/** @internal Enqueue decode operations for processing on queue of a device. */\n+typedef uint16_t (*rte_bbdev_enqueue_dec_ops_t)(\n+\t\tstruct rte_bbdev_queue_data *q_data,\n+\t\tstruct rte_bbdev_dec_op **ops,\n+\t\tuint16_t num);\n+\n+/** @internal Dequeue encode operations from a queue of a device. */\n+typedef uint16_t (*rte_bbdev_dequeue_enc_ops_t)(\n+\t\tstruct rte_bbdev_queue_data *q_data,\n+\t\tstruct rte_bbdev_enc_op **ops, uint16_t num);\n+\n+/** @internal Dequeue decode operations from a queue of a device. */\n+typedef uint16_t (*rte_bbdev_dequeue_dec_ops_t)(\n+\t\tstruct rte_bbdev_queue_data *q_data,\n+\t\tstruct rte_bbdev_dec_op **ops, uint16_t num);\n+\n+#ifndef RTE_BBDEV_NAME_MAX_LEN\n+#define RTE_BBDEV_NAME_MAX_LEN  64  /**< Max length of device name */\n+#endif\n+\n+/**\n+ * @internal The data associated with a device, with no function pointers.\n+ * This structure is safe to place in shared memory to be common among\n+ * different processes in a multi-process configuration. Drivers can access\n+ * these fields, but should never write to them!\n+ */\n+struct rte_bbdev_data {\n+\tchar name[RTE_BBDEV_NAME_MAX_LEN]; /**< Unique identifier name */\n+\tvoid *dev_private;  /**< Driver-specific private data */\n+\tuint16_t num_queues;  /**< Number of currently configured queues */\n+\tstruct rte_bbdev_queue_data *queues;  /**< Queue structures */\n+\tuint16_t dev_id;  /**< Device ID */\n+\tint socket_id;  /**< NUMA socket that device is on */\n+\tbool started;  /**< Device run-time state */\n+};\n+\n+/* Forward declarations */\n+struct rte_bbdev_ops;\n+struct rte_bbdev_callback;\n+struct rte_intr_handle;\n+\n+/** Structure to keep track of registered callbacks */\n+TAILQ_HEAD(rte_bbdev_cb_list, rte_bbdev_callback);\n+\n+/**\n+ * @internal The data structure associated with a device. Drivers can access\n+ * these fields, but should only write to the *_ops fields.\n+ */\n+struct __rte_cache_aligned rte_bbdev {\n+\t/**< Enqueue encode function */\n+\trte_bbdev_enqueue_enc_ops_t enqueue_enc_ops;\n+\t/**< Enqueue decode function */\n+\trte_bbdev_enqueue_dec_ops_t enqueue_dec_ops;\n+\t/**< Dequeue encode function */\n+\trte_bbdev_dequeue_enc_ops_t dequeue_enc_ops;\n+\t/**< Dequeue decode function */\n+\trte_bbdev_dequeue_dec_ops_t dequeue_dec_ops;\n+\tconst struct rte_bbdev_ops *dev_ops;  /**< Functions exported by PMD */\n+\tstruct rte_bbdev_data *data;  /**< Pointer to device data */\n+\tenum rte_bbdev_state state;  /**< If device is currently used or not */\n+\tstruct rte_device *device; /**< Backing device */\n+\t/** User application callback for interrupts if present */\n+\tstruct rte_bbdev_cb_list list_cbs;\n+\tstruct rte_intr_handle *intr_handle; /**< Device interrupt handle */\n+};\n+\n+/** @internal array of all devices */\n+extern struct rte_bbdev rte_bbdev_devices[];\n+\n+/**\n+ * Enqueue a burst of processed encode operations to a queue of the device.\n+ * This functions only enqueues as many operations as currently possible and\n+ * does not block until @p num_ops entries in the queue are available.\n+ * This function does not provide any error notification to avoid the\n+ * corresponding overhead.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param queue_id\n+ *   The index of the queue.\n+ * @param ops\n+ *   Pointer array containing operations to be enqueued Must have at least\n+ *   @p num_ops entries\n+ * @param num_ops\n+ *   The maximum number of operations to enqueue.\n+ *\n+ * @return\n+ *   The number of operations actually enqueued (this is the number of processed\n+ *   entries in the @p ops array).\n+ */\n+static inline uint16_t\n+rte_bbdev_enqueue_enc_ops(uint16_t dev_id, uint16_t queue_id,\n+\t\tstruct rte_bbdev_enc_op **ops, uint16_t num_ops)\n+{\n+\tstruct rte_bbdev *dev = &rte_bbdev_devices[dev_id];\n+\tstruct rte_bbdev_queue_data *q_data = &dev->data->queues[queue_id];\n+\tuint16_t n = dev->enqueue_enc_ops(q_data, ops, num_ops);\n+\n+\trte_bbdev_log_verbose(\"%u encode ops enqueued to dev%u,q%u.\\n\",\n+\t\t\tnum_ops, dev_id, queue_id);\n+\n+\treturn n;\n+}\n+\n+/**\n+ * Enqueue a burst of processed decode operations to a queue of the device.\n+ * This functions only enqueues as many operations as currently possible and\n+ * does not block until @p num_ops entries in the queue are available.\n+ * This function does not provide any error notification to avoid the\n+ * corresponding overhead.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param queue_id\n+ *   The index of the queue.\n+ * @param ops\n+ *   Pointer array containing operations to be enqueued Must have at least\n+ *   @p num_ops entries\n+ * @param num_ops\n+ *   The maximum number of operations to enqueue.\n+ *\n+ * @return\n+ *   The number of operations actually enqueued (this is the number of processed\n+ *   entries in the @p ops array).\n+ */\n+static inline uint16_t\n+rte_bbdev_enqueue_dec_ops(uint16_t dev_id, uint16_t queue_id,\n+\t\tstruct rte_bbdev_dec_op **ops, uint16_t num_ops)\n+{\n+\tstruct rte_bbdev *dev = &rte_bbdev_devices[dev_id];\n+\tstruct rte_bbdev_queue_data *q_data = &dev->data->queues[queue_id];\n+\tuint16_t n = dev->enqueue_dec_ops(q_data, ops, num_ops);\n+\n+\trte_bbdev_log_verbose(\"%u decode ops enqueued to dev%u,q%u.\\n\",\n+\t\t\tnum_ops, dev_id, queue_id);\n+\n+\treturn n;\n+}\n+\n+/**\n+ * Dequeue a burst of processed encode operations from a queue of the device.\n+ * This functions returns only the current contents of the queue, and does not\n+ * block until @ num_ops is available.\n+ * This function does not provide any error notification to avoid the\n+ * corresponding overhead.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param queue_id\n+ *   The index of the queue.\n+ * @param ops\n+ *   Pointer array where operations will be dequeued to. Must have at least\n+ *   @p num_ops entries\n+ * @param num_ops\n+ *   The maximum number of operations to dequeue.\n+ *\n+ * @return\n+ *   The number of operations actually dequeued (this is the number of entries\n+ *   copied into the @p ops array).\n+ */\n+static inline uint16_t\n+rte_bbdev_dequeue_enc_ops(uint16_t dev_id, uint16_t queue_id,\n+\t\tstruct rte_bbdev_enc_op **ops, uint16_t num_ops)\n+{\n+\tstruct rte_bbdev *dev = &rte_bbdev_devices[dev_id];\n+\tstruct rte_bbdev_queue_data *q_data = &dev->data->queues[queue_id];\n+\tuint16_t n = dev->dequeue_enc_ops(q_data, ops, num_ops);\n+\n+\trte_bbdev_log_verbose(\"%u encode ops dequeued to dev%u,q%u\\n\",\n+\t\t\tn, dev_id, queue_id);\n+\n+\treturn n;\n+}\n+\n+/**\n+ * Dequeue a burst of processed decode operations from a queue of the device.\n+ * This functions returns only the current contents of the queue, and does not\n+ * block until @ num_ops is available.\n+ * This function does not provide any error notification to avoid the\n+ * corresponding overhead.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param queue_id\n+ *   The index of the queue.\n+ * @param ops\n+ *   Pointer array where operations will be dequeued to. Must have at least\n+ *   @p num_ops entries\n+ * @param num_ops\n+ *   The maximum number of operations to dequeue.\n+ *\n+ * @return\n+ *   The number of operations actually dequeued (this is the number of entries\n+ *   copied into the @p ops array).\n+ */\n+\n+static inline uint16_t\n+rte_bbdev_dequeue_dec_ops(uint16_t dev_id, uint16_t queue_id,\n+\t\tstruct rte_bbdev_dec_op **ops, uint16_t num_ops)\n+{\n+\tstruct rte_bbdev *dev = &rte_bbdev_devices[dev_id];\n+\tstruct rte_bbdev_queue_data *q_data = &dev->data->queues[queue_id];\n+\tuint16_t n = dev->dequeue_dec_ops(q_data, ops, num_ops);\n+\n+\trte_bbdev_log_verbose(\"%u decode ops dequeued to dev%u,q%u\\n\",\n+\t\t\tn, dev_id, queue_id);\n+\n+\treturn n;\n+}\n+\n+/** Definitions of device event types */\n+enum rte_bbdev_event_type {\n+\tRTE_BBDEV_EVENT_UNKNOWN,  /**< unknown event type */\n+\tRTE_BBDEV_EVENT_ERROR,  /**< error interrupt event */\n+\tRTE_BBDEV_EVENT_DEQUEUE,  /**< dequeue event */\n+\tRTE_BBDEV_EVENT_MAX  /**< max value of this enum */\n+};\n+\n+/**\n+ * Typedef for application callback function registered by application\n+ * software for notification of device events\n+ *\n+ * @param dev_id\n+ *   Device identifier\n+ * @param event\n+ *   Device event to register for notification of.\n+ * @param cb_arg\n+ *   User specified parameter to be passed to user's callback function.\n+ * @param ret_param\n+ *   To pass data back to user application.\n+ */\n+typedef void (*rte_bbdev_cb_fn)(uint16_t dev_id,\n+\t\tenum rte_bbdev_event_type event, void *cb_arg,\n+\t\tvoid *ret_param);\n+\n+/**\n+ * Register a callback function for specific device id. Multiple callbacks can\n+ * be added and will be called in the order they are added when an event is\n+ * triggered. Callbacks are called in a separate thread created by the DPDK EAL.\n+ *\n+ * @param dev_id\n+ *   Device id.\n+ * @param event\n+ *   The event that the callback will be registered for.\n+ * @param cb_fn\n+ *   User supplied callback function to be called.\n+ * @param cb_arg\n+ *   Pointer to parameter that will be passed to the callback.\n+ *\n+ * @return\n+ *   Zero on success, negative value on failure.\n+ */\n+int\n+rte_bbdev_callback_register(uint16_t dev_id, enum rte_bbdev_event_type event,\n+\t\trte_bbdev_cb_fn cb_fn, void *cb_arg);\n+\n+/**\n+ * Unregister a callback function for specific device id.\n+ *\n+ * @param dev_id\n+ *   The device identifier.\n+ * @param event\n+ *   The event that the callback will be unregistered for.\n+ * @param cb_fn\n+ *   User supplied callback function to be unregistered.\n+ * @param cb_arg\n+ *   Pointer to the parameter supplied when registering the callback.\n+ *   (void *)-1 means to remove all registered callbacks with the specified\n+ *   function address.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - EINVAL if invalid parameter pointer is provided\n+ *   - EAGAIN if the provided callback pointer does not exist\n+ */\n+int\n+rte_bbdev_callback_unregister(uint16_t dev_id, enum rte_bbdev_event_type event,\n+\t\trte_bbdev_cb_fn cb_fn, void *cb_arg);\n+\n+/**\n+ * Enable a one-shot interrupt on the next operation enqueued to a particular\n+ * queue. The interrupt will be triggered when the operation is ready to be\n+ * dequeued. To handle the interrupt, an epoll file descriptor must be\n+ * registered using rte_bbdev_queue_intr_ctl(), and then an application\n+ * thread/lcore can wait for the interrupt using rte_epoll_wait().\n+ *\n+ * @param dev_id\n+ *   The device identifier.\n+ * @param queue_id\n+ *   The index of the queue.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - negative value on failure - as returned from PMD driver\n+ */\n+int\n+rte_bbdev_queue_intr_enable(uint16_t dev_id, uint16_t queue_id);\n+\n+/**\n+ * Disable a one-shot interrupt on the next operation enqueued to a particular\n+ * queue (if it has been enabled).\n+ *\n+ * @param dev_id\n+ *   The device identifier.\n+ * @param queue_id\n+ *   The index of the queue.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - negative value on failure - as returned from PMD driver\n+ */\n+int\n+rte_bbdev_queue_intr_disable(uint16_t dev_id, uint16_t queue_id);\n+\n+/**\n+ * Control interface for per-queue interrupts.\n+ *\n+ * @param dev_id\n+ *   The device identifier.\n+ * @param queue_id\n+ *   The index of the queue.\n+ * @param epfd\n+ *   Epoll file descriptor that will be associated with the interrupt source.\n+ *   If the special value RTE_EPOLL_PER_THREAD is provided, a per thread epoll\n+ *   file descriptor created by the EAL is used (RTE_EPOLL_PER_THREAD can also\n+ *   be used when calling rte_epoll_wait()).\n+ * @param op\n+ *   The operation be performed for the vector.RTE_INTR_EVENT_ADD or\n+ *   RTE_INTR_EVENT_DEL.\n+ * @param data\n+ *   User context, that will be returned in the epdata.data field of the\n+ *   rte_epoll_event structure filled in by rte_epoll_wait().\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - ENOTSUP if interrupts are not supported by the identified device\n+ *   - negative value on failure - as returned from PMD driver\n+ */\n+int\n+rte_bbdev_queue_intr_ctl(uint16_t dev_id, uint16_t queue_id, int epfd, int op,\n+\t\tvoid *data);\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* _RTE_BBDEV_H_ */\ndiff --git a/lib/librte_bbdev/rte_bbdev_op.h b/lib/librte_bbdev/rte_bbdev_op.h\nnew file mode 100644\nindex 0000000..56adfb8\n--- /dev/null\n+++ b/lib/librte_bbdev/rte_bbdev_op.h\n@@ -0,0 +1,532 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _RTE_BBDEV_OP_H_\n+#define _RTE_BBDEV_OP_H_\n+\n+/**\n+ * @file rte_bbdev_op.h\n+ *\n+ * Defines wireless base band layer 1 operations and capabilities\n+ *\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ */\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#include <stdint.h>\n+\n+#include <rte_common.h>\n+#include <rte_mbuf.h>\n+#include <rte_memory.h>\n+#include <rte_mempool.h>\n+\n+#define RTE_BBDEV_MAX_CODE_BLOCKS 64\n+\n+extern int bbdev_logtype;\n+\n+/**\n+ * Helper macro for logging\n+ *\n+ * @param level\n+ *   Log level: EMERG, ALERT, CRIT, ERR, WARNING, NOTICE, INFO, or DEBUG\n+ * @param fmt\n+ *   The format string, as in printf(3).\n+ * @param ...\n+ *   The variable arguments required by the format string.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - Negative on error\n+ */\n+#define rte_bbdev_log(level, fmt, ...) \\\n+\trte_log(RTE_LOG_ ## level, bbdev_logtype, fmt \"\\n\", ##__VA_ARGS__)\n+\n+/**\n+ * Helper macro for debug logging with extra source info\n+ *\n+ * @param fmt\n+ *   The format string, as in printf(3).\n+ * @param ...\n+ *   The variable arguments required by the format string.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - Negative on error\n+ */\n+#define rte_bbdev_log_debug(fmt, ...) \\\n+\trte_bbdev_log(DEBUG, RTE_STR(__LINE__) \":%s() \" fmt, __func__, \\\n+\t\t##__VA_ARGS__)\n+\n+/**\n+ * Helper macro for extra conditional logging from datapath\n+ *\n+ * @param fmt\n+ *   The format string, as in printf(3).\n+ * @param ...\n+ *   The variable arguments required by the format string.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - Negative on error\n+ */\n+#define rte_bbdev_log_verbose(fmt, ...) \\\n+\t(void)((RTE_LOG_DEBUG <= RTE_LOG_DP_LEVEL) ? \\\n+\trte_log(RTE_LOG_DEBUG, \\\n+\t\tbbdev_logtype, \": \" fmt \"\\n\", ##__VA_ARGS__) : 0)\n+\n+/** Flags for turbo decoder operation and capability structure */\n+enum rte_bbdev_op_td_flag_bitmasks {\n+\t/** If sub block de-interleaving is to be performed. */\n+\tRTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE = (1ULL << 0),\n+\t/** To use CRC Type 24B (otherwise use CRC Type 24A). */\n+\tRTE_BBDEV_TURBO_CRC_TYPE_24B = (1ULL << 1),\n+\t/** If turbo equalization is to be performed. */\n+\tRTE_BBDEV_TURBO_EQUALIZER = (1ULL << 2),\n+\t/** If set, saturate soft output to +/-127 */\n+\tRTE_BBDEV_TURBO_SOFT_OUT_SATURATE = (1ULL << 3),\n+\t/**\n+\t * Set to 1 to start iteration from even, else odd; one iteration =\n+\t * max_iteration + 0.5\n+\t */\n+\tRTE_BBDEV_TURBO_HALF_ITERATION_EVEN = (1ULL << 4),\n+\t/**\n+\t * If 0, TD stops after CRC matches; else if 1, runs to end of next\n+\t * odd iteration after CRC matches\n+\t */\n+\tRTE_BBDEV_TURBO_CONTINUE_CRC_MATCH = (1ULL << 5),\n+\t/** Set if soft output is required to be output  */\n+\tRTE_BBDEV_TURBO_SOFT_OUTPUT = (1ULL << 6),\n+\t/** Set to enable early termination mode */\n+\tRTE_BBDEV_TURBO_EARLY_TERMINATION = (1ULL << 7),\n+\t/** Set if a device supports decoder dequeue interrupts */\n+\tRTE_BBDEV_TURBO_DEC_INTERRUPTS = (1ULL << 9),\n+\t/**\n+\t * Set if operation's input '1' bits are represented by a positive LLR\n+\t * and '0' bits are represented by a negative LLR. Mutual exclusive with\n+\t * RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN.\n+\t */\n+\tRTE_BBDEV_TURBO_POS_LLR_1_BIT_IN = (1ULL << 10),\n+\t/**\n+\t * Set if operation's input '1' bits are represented by a negative LLR\n+\t * and '0' bits are represented by a negative LLR. Mutual exclusive with\n+\t * RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN.\n+\t */\n+\tRTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN = (1ULL << 11),\n+\t/**\n+\t * Set if operation's soft output '1' bits are represented by a positive\n+\t * LLR and '0' bits are represented by a negative LLR. Mutual exclusive\n+\t * with RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT.\n+\t */\n+\tRTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT = (1ULL << 12),\n+\t/**\n+\t * Set if operation's soft output '1' bits are represented by a negative\n+\t * LLR and '0' bits are represented by a negative LLR. Mutual exclusive\n+\t * with RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT.\n+\t */\n+\tRTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT = (1ULL << 13),\n+\t/**\n+\t * Set if driver supports MAP decoder. If not set num_maps (number\n+\t * of Maps) argument is not usable.\n+\t */\n+\tRTE_BBDEV_TURBO_MAP_DEC = (1ULL << 14),\n+};\n+\n+/** Flags for turbo encoder operation and capability structure */\n+enum rte_bbdev_op_te_flag_bitmasks {\n+\t/** Ignore rv_index and set K0 = 0 */\n+\tRTE_BBDEV_TURBO_RV_INDEX_BYPASS = (1ULL << 0),\n+\t/** If rate matching is to be performed */\n+\tRTE_BBDEV_TURBO_RATE_MATCH = (1ULL << 1),\n+\t/** This bit must be set to enable CRC-24B generation */\n+\tRTE_BBDEV_TURBO_CRC_24B_ATTACH = (1ULL << 2),\n+\t/** This bit must be set to enable CRC-24A generation */\n+\tRTE_BBDEV_TURBO_CRC_24A_ATTACH = (1ULL << 3),\n+\t/** Set if a device supports encoder dequeue interrupts */\n+\tRTE_BBDEV_TURBO_ENC_INTERRUPTS = (1ULL << 4),\n+\t/** Set if a device supports scatter-gather functionality */\n+\tRTE_BBDEV_TURBO_ENC_SCATTER_GATHER = (1ULL << 5)\n+};\n+\n+/** Data input and output buffer for BBDEV operations */\n+struct rte_bbdev_op_data {\n+\tstruct rte_mbuf *data;\n+\t/**< First mbuf segment with input/output data. Each segment represents\n+\t * one Code Block. For the input operation a mbuf needs to contain\n+\t * all Code Blocks. For the output operation the mbuf should consist of\n+\t * only one segment and the driver will take care of allocating and\n+\t * chaining another segments for the consecutive Code Blocks if needed.\n+\t */\n+\tuint32_t offset;\n+\t/**< The starting point for the Turbo input/output, in bytes, from the\n+\t * start of the first segment's data buffer. It must be smaller than the\n+\t * first segment's data_len!\n+\t */\n+\tuint32_t length;\n+\t/**< Length of Transport Block - number of bytes for Turbo Encode/Decode\n+\t * operation for input; length of the output for output operation.\n+\t */\n+};\n+\n+struct rte_bbdev_op_dec_cb_params {\n+\tuint16_t k; /**< size of the input code block in bits (40 - 6144) */\n+\tuint32_t e; /**< length in bits of the rate match output (17 bits) */\n+};\n+\n+struct rte_bbdev_op_dec_tb_params {\n+\t/**< size of the input code block in bits (40 - 6144). Used when\n+\t * code block index r < c_neg\n+\t */\n+\tuint16_t k_neg;\n+\t/**< size of the input code block in bits (40 - 6144). Used when\n+\t * code block index r >= c_neg\n+\t */\n+\tuint16_t k_pos;\n+\tuint8_t c_neg; /**< number of code block using k_neg (0 - 63) */\n+\tuint8_t c; /**< total number of code blocks (1 - 64) */\n+\tuint8_t cab; /**< number of code blocks using ea before switch to eb */\n+\t/**< length in bits of the rate match output (17 bits). Used when\n+\t * code block index r < cab\n+\t */\n+\tuint32_t ea;\n+\t/**< length in bits of the rate match output (17 bits). Used when\n+\t * code block index r >= cab\n+\t */\n+\tuint32_t eb;\n+};\n+\n+/** Operation structure for the Turbo Decoder */\n+struct rte_bbdev_op_turbo_dec {\n+\tstruct rte_bbdev_op_data input; /**< input src data */\n+\tstruct rte_bbdev_op_data hard_output; /**< hard output buffer */\n+\tstruct rte_bbdev_op_data soft_output; /**< soft output buffer */\n+\n+\tuint32_t op_flags;  /**< Flags from rte_bbdev_op_td_flag_bitmasks */\n+\tuint8_t rv_index;  /**< Rv index for rate matching (0 - 3) */\n+\tuint8_t iter_min:4;  /**< min number of iterations */\n+\tuint8_t iter_max:4;  /**< max number of iterations */\n+\tuint8_t iter_count;  /**< Actual num. of iterations performed */\n+\t/** 5 bit extrinsic scale (scale factor on extrinsic info) */\n+\tuint8_t ext_scale;\n+\t/** Number of MAP engines, must be power of 2 (or 0 to auto-select) */\n+\tuint8_t num_maps;\n+\tuint8_t code_block_mode; /**< 0 - transpot block, 1 - code block */\n+\tunion {\n+\t\t/** Struct which stores Code Block specific parameters */\n+\t\tstruct rte_bbdev_op_dec_cb_params cb_params;\n+\t\t/** Struct which stores Transport Block specific parameters */\n+\t\tstruct rte_bbdev_op_dec_tb_params tb_params;\n+\t};\n+};\n+\n+struct rte_bbdev_op_enc_cb_params {\n+\tuint16_t k; /**< size of the input code block in bits (40 - 6144) */\n+\tuint32_t e; /**< length in bits of the rate match output (17 bits) */\n+\tuint16_t ncb; /**< Ncb parameter for rate matching, range [k:3(k+4)] */\n+};\n+\n+struct rte_bbdev_op_enc_tb_params {\n+\t/**< size of the input code block in bits (40 - 6144). Used when\n+\t * code block index r < c_neg\n+\t */\n+\tuint16_t k_neg;\n+\t/**< size of the input code block in bits (40 - 6144). Used when\n+\t * code block index r >= c_neg\n+\t */\n+\tuint16_t k_pos;\n+\tuint8_t c_neg; /**< number of code block using k_neg (0 - 63) */\n+\tuint8_t c; /**< total number of code blocks (1 - 64) */\n+\tuint8_t cab; /**< number of code blocks using ea before switch to eb */\n+\t/**< length in bits of the rate match output (17 bits). Used when\n+\t * code block index r < cab\n+\t */\n+\tuint32_t ea;\n+\t/**< length in bits of the rate match output (17 bits). Used when\n+\t * code block index r >= cab\n+\t */\n+\tuint32_t eb;\n+\t/**< Ncb parameter for rate matching, range [k : 3(k+4)]. Used when\n+\t * code block index r < c_neg\n+\t */\n+\tuint16_t ncb_neg;\n+\t/**< Ncb parameter for rate matching, range [k : 3(k+4)]. Used when\n+\t * code block index r >= c_neg\n+\t */\n+\tuint16_t ncb_pos;\n+\t/**< r of the first CB in case of partial TB, default value is 0 */\n+\tuint8_t r;\n+};\n+\n+/** Operation structure for the Turbo Encoder */\n+struct rte_bbdev_op_turbo_enc {\n+\tstruct rte_bbdev_op_data input; /**< input src data */\n+\tstruct rte_bbdev_op_data output; /**< output buffer */\n+\n+\tuint32_t op_flags;  /**< Flags from rte_bbdev_op_te_flag_bitmasks */\n+\tuint8_t rv_index;  /**< Rv index for rate matching (0 - 3) */\n+\tuint8_t code_block_mode; /**< 0 - transpot block, 1 - code block */\n+\tunion {\n+\t\t/** Struct which stores Code Block specific parameters */\n+\t\tstruct rte_bbdev_op_enc_cb_params cb_params;\n+\t\t/** Struct which stores Transport Block specific parameters */\n+\t\tstruct rte_bbdev_op_enc_tb_params tb_params;\n+\t};\n+};\n+\n+/** List of the capabilities for the Turbo Decoder */\n+struct rte_bbdev_op_cap_turbo_dec {\n+\t/** Flags from rte_bbdev_op_td_flag_bitmasks */\n+\tuint32_t capability_flags;\n+\tuint8_t num_buffers_src;  /**< Num input code block buffers */\n+\t/** Num hard output code block buffers */\n+\tuint8_t num_buffers_hard_out;\n+\t/** Num soft output code block buffers if supported by the driver */\n+\tuint8_t num_buffers_soft_out;\n+};\n+\n+/** List of the capabilities for the Turbo Encoder */\n+struct rte_bbdev_op_cap_turbo_enc {\n+\t/** Flags from rte_bbdev_op_te_flag_bitmasks */\n+\tuint32_t capability_flags;\n+\tuint8_t num_buffers_src;  /**< Num input code block buffers */\n+\tuint8_t num_buffers_dst;  /**< Num output code block buffers */\n+};\n+\n+/** Different operation types supported by the device */\n+enum rte_bbdev_op_type {\n+\tRTE_BBDEV_OP_NONE,  /**< Dummy operation that does nothing */\n+\tRTE_BBDEV_OP_TURBO_DEC,  /**< Turbo decode */\n+\tRTE_BBDEV_OP_TURBO_ENC,  /**< Turbo encode */\n+\tRTE_BBDEV_OP_TYPE_COUNT,  /**< Count of different op types */\n+};\n+\n+/** Bit indexes of possible errors reported through status field */\n+enum {\n+\tRTE_BBDEV_DRV_ERROR,\n+\tRTE_BBDEV_DATA_ERROR,\n+\tRTE_BBDEV_CRC_ERROR,\n+};\n+\n+/** Structure specifying a single encode operation */\n+struct rte_bbdev_enc_op {\n+\tint status;  /**< Status of operation that was performed */\n+\tstruct rte_mempool *mempool;  /**< Mempool which op instance is in */\n+\tvoid *opaque_data;  /**< Opaque pointer for user data */\n+\t/** Contains encoder specific parameters */\n+\tstruct rte_bbdev_op_turbo_enc turbo_enc;\n+};\n+\n+/** Structure specifying a single decode operation */\n+struct rte_bbdev_dec_op {\n+\tint status;  /**< Status of operation that was performed */\n+\tstruct rte_mempool *mempool;  /**< Mempool which op instance is in */\n+\tvoid *opaque_data;  /**< Opaque pointer for user data */\n+\t/** Contains decoder specific parameters */\n+\tstruct rte_bbdev_op_turbo_dec turbo_dec;\n+};\n+\n+/** Operation capabilities supported by a device */\n+struct rte_bbdev_op_cap {\n+\tenum rte_bbdev_op_type type;  /**< Type of operation */\n+\tunion {\n+\t\tstruct rte_bbdev_op_cap_turbo_dec turbo_dec;\n+\t\tstruct rte_bbdev_op_cap_turbo_enc turbo_enc;\n+\t} cap;  /**< Operation-type specific capabilities */\n+};\n+\n+/** @internal Private data structure stored with operation pool. */\n+struct rte_bbdev_op_pool_private {\n+\tenum rte_bbdev_op_type type;  /**< Type of operations in a pool */\n+};\n+\n+/**\n+ * Converts queue operation type from enum to string\n+ *\n+ * @param op_type\n+ *   Operation type as enum\n+ *\n+ * @returns\n+ *   Operation type as string\n+ *\n+ */\n+const char*\n+rte_bbdev_op_type_str(enum rte_bbdev_op_type op_type);\n+\n+/**\n+ * Creates a bbdev operation mempool\n+ *\n+ * @param name\n+ *   Pool name.\n+ * @param type\n+ *   Operation type, use RTE_BBDEV_OP_NONE for a pool which supports all\n+ *   operation types.\n+ * @param num_elements\n+ *   Number of elements in the pool.\n+ * @param cache_size\n+ *   Number of elements to cache on an lcore, see rte_mempool_create() for\n+ *   further details about cache size.\n+ * @param socket_id\n+ *   Socket to allocate memory on.\n+ *\n+ * @return\n+ *   - Pointer to a mempool on success,\n+ *   - NULL pointer on failure.\n+ */\n+struct rte_mempool *\n+rte_bbdev_op_pool_create(const char *name, enum rte_bbdev_op_type type,\n+\t\tunsigned int num_elements, unsigned int cache_size,\n+\t\tint socket_id);\n+\n+/**\n+ * Bulk allocate encode operations from a mempool with parameter defaults reset.\n+ *\n+ * @param mempool\n+ *   Operation mempool, created by rte_bbdev_op_pool_create().\n+ * @param ops\n+ *   Output array to place allocated operations\n+ * @param num_ops\n+ *   Number of operations to allocate\n+ *\n+ * @returns\n+ *   - 0 on success\n+ *   - EINVAL if invalid mempool is provided\n+ */\n+static inline int\n+rte_bbdev_enc_op_alloc_bulk(struct rte_mempool *mempool,\n+\t\tstruct rte_bbdev_enc_op **ops, uint16_t num_ops)\n+{\n+\tstruct rte_bbdev_op_pool_private *priv;\n+\tint ret;\n+\n+\t/* Check type */\n+\tpriv = (struct rte_bbdev_op_pool_private *)\n+\t\t\trte_mempool_get_priv(mempool);\n+\tif (unlikely(priv->type != RTE_BBDEV_OP_TURBO_ENC))\n+\t\treturn -EINVAL;\n+\n+\t/* Get elements */\n+\tret = rte_mempool_get_bulk(mempool, (void **)ops, num_ops);\n+\tif (unlikely(ret < 0))\n+\t\treturn ret;\n+\n+\trte_bbdev_log_verbose(\"%u encode ops allocated from %s\\n\",\n+\t\t\tnum_ops, mempool->name);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Bulk allocate decode operations from a mempool with parameter defaults reset.\n+ *\n+ * @param mempool\n+ *   Operation mempool, created by rte_bbdev_op_pool_create().\n+ * @param ops\n+ *   Output array to place allocated operations\n+ * @param num_ops\n+ *   Number of operations to allocate\n+ *\n+ * @returns\n+ *   - 0 on success\n+ *   - EINVAL if invalid mempool is provided\n+ */\n+static inline int\n+rte_bbdev_dec_op_alloc_bulk(struct rte_mempool *mempool,\n+\t\tstruct rte_bbdev_dec_op **ops, uint16_t num_ops)\n+{\n+\tstruct rte_bbdev_op_pool_private *priv;\n+\tint ret;\n+\n+\t/* Check type */\n+\tpriv = (struct rte_bbdev_op_pool_private *)\n+\t\t\trte_mempool_get_priv(mempool);\n+\tif (unlikely(priv->type != RTE_BBDEV_OP_TURBO_DEC))\n+\t\treturn -EINVAL;\n+\n+\t/* Get elements */\n+\tret = rte_mempool_get_bulk(mempool, (void **)ops, num_ops);\n+\tif (unlikely(ret < 0))\n+\t\treturn ret;\n+\n+\trte_bbdev_log_verbose(\"%u encode ops allocated from %s\\n\",\n+\t\t\tnum_ops, mempool->name);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Free decode operation structures that were allocated by\n+ * rte_bbdev_dec_op_alloc_bulk().\n+ * All structures must belong to the same mempool.\n+ *\n+ * @param ops\n+ *   Operation structures\n+ * @param num_ops\n+ *   Number of structures\n+ */\n+static inline void\n+rte_bbdev_dec_op_free_bulk(struct rte_bbdev_dec_op **ops, unsigned int num_ops)\n+{\n+\tif (num_ops > 0) {\n+\t\trte_mempool_put_bulk(ops[0]->mempool, (void **)ops, num_ops);\n+\t\trte_bbdev_log_verbose(\"%u decode ops freed to %s\\n\", num_ops,\n+\t\t\t\tops[0]->mempool->name);\n+\t}\n+}\n+\n+/**\n+ * Free encode operation structures that were allocated by\n+ * rte_bbdev_enc_op_alloc_bulk().\n+ * All structures must belong to the same mempool.\n+ *\n+ * @param ops\n+ *   Operation structures\n+ * @param num_ops\n+ *   Number of structures\n+ */\n+static inline void\n+rte_bbdev_enc_op_free_bulk(struct rte_bbdev_enc_op **ops, unsigned int num_ops)\n+{\n+\tif (num_ops > 0) {\n+\t\trte_mempool_put_bulk(ops[0]->mempool, (void **)ops, num_ops);\n+\t\trte_bbdev_log_verbose(\"%u encode ops freed to %s\\n\", num_ops,\n+\t\t\t\tops[0]->mempool->name);\n+\t}\n+}\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* _RTE_BBDEV_OP_H_ */\ndiff --git a/lib/librte_bbdev/rte_bbdev_op_ldpc.h b/lib/librte_bbdev/rte_bbdev_op_ldpc.h\nnew file mode 100644\nindex 0000000..c4e728d\n--- /dev/null\n+++ b/lib/librte_bbdev/rte_bbdev_op_ldpc.h\n@@ -0,0 +1,545 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _RTE_BBDEV_OP_H_\n+#define _RTE_BBDEV_OP_H_\n+\n+/**\n+ * @file rte_bbdev_op.h\n+ *\n+ * Defines wireless base band layer 1 operations and capabilities\n+ *\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ */\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#include <stdint.h>\n+\n+#include <rte_common.h>\n+#include <rte_mbuf.h>\n+#include <rte_memory.h>\n+#include <rte_mempool.h>\n+\n+#define RTE_BBDEV_MAX_CODE_BLOCKS 64\n+\n+extern int bbdev_logtype;\n+\n+/**\n+ * Helper macro for logging\n+ *\n+ * @param level\n+ *   Log level: EMERG, ALERT, CRIT, ERR, WARNING, NOTICE, INFO, or DEBUG\n+ * @param fmt\n+ *   The format string, as in printf(3).\n+ * @param ...\n+ *   The variable arguments required by the format string.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - Negative on error\n+ */\n+#define rte_bbdev_log(level, fmt, ...) \\\n+\trte_log(RTE_LOG_ ## level, bbdev_logtype, fmt \"\\n\", ##__VA_ARGS__)\n+\n+/**\n+ * Helper macro for debug logging with extra source info\n+ *\n+ * @param fmt\n+ *   The format string, as in printf(3).\n+ * @param ...\n+ *   The variable arguments required by the format string.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - Negative on error\n+ */\n+#define rte_bbdev_log_debug(fmt, ...) \\\n+\trte_bbdev_log(DEBUG, RTE_STR(__LINE__) \":%s() \" fmt, __func__, \\\n+\t\t##__VA_ARGS__)\n+\n+/**\n+ * Helper macro for extra conditional logging from datapath\n+ *\n+ * @param fmt\n+ *   The format string, as in printf(3).\n+ * @param ...\n+ *   The variable arguments required by the format string.\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - Negative on error\n+ */\n+#define rte_bbdev_log_verbose(fmt, ...) \\\n+\t(void)((RTE_LOG_DEBUG <= RTE_LOG_DP_LEVEL) ? \\\n+\trte_log(RTE_LOG_DEBUG, \\\n+\t\tbbdev_logtype, \": \" fmt \"\\n\", ##__VA_ARGS__) : 0)\n+\n+/** Flags for turbo decoder operation and capability structure */\n+enum rte_bbdev_op_td_flag_bitmasks {\n+\t/** If sub block de-interleaving is to be performed. */\n+\tRTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE = (1ULL << 0),\n+\t/** To use CRC Type 24B (otherwise use CRC Type 24A). */\n+\tRTE_BBDEV_TURBO_CRC_TYPE_24B = (1ULL << 1),\n+\t/** If turbo equalization is to be performed. */\n+\tRTE_BBDEV_TURBO_EQUALIZER = (1ULL << 2),\n+\t/** If set, saturate soft output to +/-127 */\n+\tRTE_BBDEV_TURBO_SOFT_OUT_SATURATE = (1ULL << 3),\n+\t/**\n+\t * Set to 1 to start iteration from even, else odd; one iteration =\n+\t * max_iteration + 0.5\n+\t */\n+\tRTE_BBDEV_TURBO_HALF_ITERATION_EVEN = (1ULL << 4),\n+\t/**\n+\t * If 0, TD stops after CRC matches; else if 1, runs to end of next\n+\t * odd iteration after CRC matches\n+\t */\n+\tRTE_BBDEV_TURBO_CONTINUE_CRC_MATCH = (1ULL << 5),\n+\t/** Set if soft output is required to be output  */\n+\tRTE_BBDEV_TURBO_SOFT_OUTPUT = (1ULL << 6),\n+\t/** Set to enable early termination mode */\n+\tRTE_BBDEV_TURBO_EARLY_TERMINATION = (1ULL << 7),\n+\t/** Set if a device supports decoder dequeue interrupts */\n+\tRTE_BBDEV_TURBO_DEC_INTERRUPTS = (1ULL << 9),\n+\t/**\n+\t * Set if operation's input '1' bits are represented by a positive LLR\n+\t * and '0' bits are represented by a negative LLR. Mutual exclusive with\n+\t * RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN.\n+\t */\n+\tRTE_BBDEV_TURBO_POS_LLR_1_BIT_IN = (1ULL << 10),\n+\t/**\n+\t * Set if operation's input '1' bits are represented by a negative LLR\n+\t * and '0' bits are represented by a negative LLR. Mutual exclusive with\n+\t * RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN.\n+\t */\n+\tRTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN = (1ULL << 11),\n+\t/**\n+\t * Set if operation's soft output '1' bits are represented by a positive\n+\t * LLR and '0' bits are represented by a negative LLR. Mutual exclusive\n+\t * with RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT.\n+\t */\n+\tRTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT = (1ULL << 12),\n+\t/**\n+\t * Set if operation's soft output '1' bits are represented by a negative\n+\t * LLR and '0' bits are represented by a negative LLR. Mutual exclusive\n+\t * with RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT.\n+\t */\n+\tRTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT = (1ULL << 13),\n+};\n+\n+enum rte_bbdev_op_ldpc_dec_flag_bitmasks {\n+\n+};\n+\n+enum rte_bbdev_op_ldpc_enc_flag_bitmasks {\n+\n+};\n+\n+/** Flags for turbo encoder operation and capability structure */\n+enum rte_bbdev_op_te_flag_bitmasks {\n+\t/** Ignore rv_index and set K0 = 0 */\n+\tRTE_BBDEV_TURBO_RV_INDEX_BYPASS = (1ULL << 0),\n+\t/** If rate matching is to be performed */\n+\tRTE_BBDEV_TURBO_RATE_MATCH = (1ULL << 1),\n+\t/** This bit must be set to enable CRC-24B generation */\n+\tRTE_BBDEV_TURBO_CRC_24B_ATTACH = (1ULL << 2),\n+\t/** This bit must be set to enable CRC-24A generation */\n+\tRTE_BBDEV_TURBO_CRC_24A_ATTACH = (1ULL << 3),\n+\t/** Set if a device supports encoder dequeue interrupts */\n+\tRTE_BBDEV_TURBO_ENC_INTERRUPTS = (1ULL << 4)\n+};\n+\n+/** Data input and output buffer for BBDEV operations */\n+struct rte_bbdev_op_data {\n+\tstruct rte_mbuf *data;\n+\t/**< First mbuf segment with input/output data. Each segment represents\n+\t * one Code Block. For the input operation a mbuf needs to contain\n+\t * all Code Blocks. For the output operation the mbuf should consist of\n+\t * only one segment and the driver will take care of allocating and\n+\t * chaining another segments for the consecutive Code Blocks if needed.\n+\t */\n+\tuint32_t offset;\n+\t/**< The starting point for the Turbo input/output, in bytes, from the\n+\t * start of the first segment's data buffer. It must be smaller than the\n+\t * first segment's data_len!\n+\t */\n+\tuint32_t length;\n+\t/**< Length of Transport Block - number of bytes for Turbo Encode/Decode\n+\t * operation for input; length of the output for output operation.\n+\t */\n+};\n+\n+struct rte_bbdev_op_dec_cb_params {\n+\tuint16_t k; /**< size of the input code block in bits (40 - 6144) */\n+\tuint32_t e; /**< length in bits of the rate match output (17 bits) */\n+};\n+\n+struct rte_bbdev_op_dec_tb_params {\n+\t/**< size of the input code block in bits (40 - 6144). Used when\n+\t * code block index r < c_neg\n+\t */\n+\tuint16_t k_neg;\n+\t/**< size of the input code block in bits (40 - 6144). Used when\n+\t * code block index r >= c_neg\n+\t */\n+\tuint16_t k_pos;\n+\tuint8_t c_neg; /**< number of code block using k_neg (0 - 63) */\n+\tuint8_t c; /**< total number of code blocks (1 - 64) */\n+\tuint8_t cab; /**< number of code blocks using ea before switch to eb */\n+\t/**< length in bits of the rate match output (17 bits). Used when\n+\t * code block index r < cab\n+\t */\n+\tuint32_t ea;\n+\t/**< length in bits of the rate match output (17 bits). Used when\n+\t * code block index r >= cab\n+\t */\n+\tuint32_t eb;\n+\tuint8_t cb_idx; /**< Code block index */\n+};\n+\n+/** Operation structure for the Turbo Decoder */\n+struct rte_bbdev_op_turbo_dec {\n+\tstruct rte_bbdev_op_data input; /**< input src data */\n+\tstruct rte_bbdev_op_data hard_output; /**< hard output buffer */\n+\tstruct rte_bbdev_op_data soft_output; /**< soft output buffer */\n+\n+\tuint32_t op_flags;  /**< Flags from rte_bbdev_op_td_flag_bitmasks */\n+\tuint8_t rv_index;  /**< Rv index for rate matching (0 - 3) */\n+\tuint8_t iter_min:4;  /**< min number of iterations */\n+\tuint8_t iter_max:4;  /**< max number of iterations */\n+\tuint8_t iter_count;  /**< Actual num. of iterations performed */\n+\t/** 5 bit extrinsic scale (scale factor on extrinsic info) */\n+\tuint8_t ext_scale;\n+\t/** Number of MAP engines, must be power of 2 (or 0 to auto-select) */\n+\tuint8_t num_maps;\n+\tuint8_t code_block_mode; /**< 0 - transpot block, 1 - code block */\n+\tunion {\n+\t\t/** Struct which stores Code Block specific parameters */\n+\t\tstruct rte_bbdev_op_dec_cb_params cb_params;\n+\t\t/** Struct which stores Transport Block specific parameters */\n+\t\tstruct rte_bbdev_op_dec_tb_params tb_params;\n+\t};\n+};\n+\n+struct rte_bbdev_op_enc_cb_params {\n+\tuint16_t k; /**< size of the input code block in bits (40 - 6144) */\n+\tuint32_t e; /**< length in bits of the rate match output (17 bits) */\n+\tuint16_t ncb; /**< Ncb parameter for rate matching, range [k:3(k+4)] */\n+};\n+\n+struct rte_bbdev_op_enc_tb_params {\n+\t/**< size of the input code block in bits (40 - 6144). Used when\n+\t * code block index r < c_neg\n+\t */\n+\tuint16_t k_neg;\n+\t/**< size of the input code block in bits (40 - 6144). Used when\n+\t * code block index r >= c_neg\n+\t */\n+\tuint16_t k_pos;\n+\tuint8_t c_neg; /**< number of code block using k_neg (0 - 63) */\n+\tuint8_t c; /**< total number of code blocks (1 - 64) */\n+\tuint8_t cab; /**< number of code blocks using ea before switch to eb */\n+\t/**< length in bits of the rate match output (17 bits). Used when\n+\t * code block index r < cab\n+\t */\n+\tuint32_t ea;\n+\t/**< length in bits of the rate match output (17 bits). Used when\n+\t * code block index r >= cab\n+\t */\n+\tuint32_t eb;\n+\t/**< Ncb parameter for rate matching, range [k : 3(k+4)]. Used when\n+\t * code block index r < c_neg\n+\t */\n+\tuint16_t ncb_neg;\n+\t/**< Ncb parameter for rate matching, range [k : 3(k+4)]. Used when\n+\t * code block index r >= c_neg\n+\t */\n+\tuint16_t ncb_pos;\n+\tuint8_t cb_idx; /**< Code block index */\n+};\n+\n+/** Operation structure for the Turbo Encoder */\n+struct rte_bbdev_op_turbo_enc {\n+\tstruct rte_bbdev_op_data input; /**< input src data */\n+\tstruct rte_bbdev_op_data output; /**< output buffer */\n+\n+\tuint32_t op_flags;  /**< Flags from rte_bbdev_op_te_flag_bitmasks */\n+\tuint8_t rv_index;  /**< Rv index for rate matching (0 - 3) */\n+\tuint8_t code_block_mode; /**< 0 - transpot block, 1 - code block */\n+\tunion {\n+\t\t/** Struct which stores Code Block specific parameters */\n+\t\tstruct rte_bbdev_op_enc_cb_params cb_params;\n+\t\t/** Struct which stores Transport Block specific parameters */\n+\t\tstruct rte_bbdev_op_enc_tb_params tb_params;\n+\t};\n+};\n+\n+/** List of the capabilities for the Turbo Decoder */\n+struct rte_bbdev_op_cap_turbo_dec {\n+\t/** Flags from rte_bbdev_op_td_flag_bitmasks */\n+\tuint32_t capability_flags;\n+\tuint8_t num_buffers_src;  /**< Num input code block buffers */\n+\t/** Num hard output code block buffers */\n+\tuint8_t num_buffers_hard_out;\n+\t/** Num soft output code block buffers if supported by the driver */\n+\tuint8_t num_buffers_soft_out;\n+};\n+\n+/** List of the capabilities for the Turbo Encoder */\n+struct rte_bbdev_op_cap_turbo_enc {\n+\t/** Flags from rte_bbdev_op_te_flag_bitmasks */\n+\tuint32_t capability_flags;\n+\tuint8_t num_buffers_src;  /**< Num input code block buffers */\n+\tuint8_t num_buffers_dst;  /**< Num output code block buffers */\n+};\n+\n+/** Different operation types supported by the device */\n+enum rte_bbdev_op_type {\n+\tRTE_BBDEV_OP_NONE,  /**< Dummy operation that does nothing */\n+\tRTE_BBDEV_OP_TURBO_DEC,  /**< Turbo decode */\n+\tRTE_BBDEV_OP_TURBO_ENC,  /**< Turbo encode */\n+\tRTE_BBDEV_OP_LDPC_DEC,  /**< LDPC decode */\n+\tRTE_BBDEV_OP_LDPC_ENC,  /**< LDPC encode */\n+\tRTE_BBDEV_OP_TYPE_COUNT,  /**< Count of different op types */\n+};\n+\n+/** Bit indexes of possible errors reported through status field */\n+enum {\n+\tRTE_BBDEV_DRV_ERROR,\n+\tRTE_BBDEV_DATA_ERROR,\n+\tRTE_BBDEV_CRC_ERROR,\n+};\n+\n+/** Structure specifying a single encode operation */\n+struct rte_bbdev_enc_op {\n+\tint status;  /**< Status of operation that was performed */\n+\tstruct rte_mempool *mempool;  /**< Mempool which op instance is in */\n+\tvoid *opaque_data;  /**< Opaque pointer for user data */\n+\tunion {\n+\t\t/** Contains Turbo encoder specific parameters */\n+\t\tstruct rte_bbdev_op_turbo_enc turbo_enc;\n+\t\t/** Contains LDPC encoder specific parameters */\n+\t\tstruct rte_bbdev_op_ldpc_enc ldpc_enc;\n+\t};\n+};\n+\n+/** Structure specifying a single decode operation */\n+struct rte_bbdev_dec_op {\n+\tint status;  /**< Status of operation that was performed */\n+\tstruct rte_mempool *mempool;  /**< Mempool which op instance is in */\n+\tvoid *opaque_data;  /**< Opaque pointer for user data */\n+\tunion {\n+\t\t/** Contains Turbo decoder specific parameters */\n+\t\tstruct rte_bbdev_op_turbo_dec turbo_dec;\n+\t\t/** Contains LDPC decoder specific parameters */\n+\t\tstruct rte_bbdev_op_ldpc_dec ldpc_dec;\n+\t};\n+};\n+\n+/** Operation capabilities supported by a device */\n+struct rte_bbdev_op_cap {\n+\tenum rte_bbdev_op_type type;  /**< Type of operation */\n+\tunion {\n+\t\tstruct rte_bbdev_op_cap_turbo_dec turbo_dec;\n+\t\tstruct rte_bbdev_op_cap_turbo_enc turbo_enc;\n+\t\tstruct rte_bbdev_op_cap_ldpc_dec ldpc_dec;\n+\t\tstruct rte_bbdev_op_cap_ldpc_enc ldpc_enc;\n+\t} cap;  /**< Operation-type specific capabilities */\n+};\n+\n+/** @internal Private data structure stored with operation pool. */\n+struct rte_bbdev_op_pool_private {\n+\tenum rte_bbdev_op_type type;  /**< Type of operations in a pool */\n+};\n+\n+/**\n+ * Converts queue operation type from enum to string\n+ *\n+ * @param op_type\n+ *   Operation type as enum\n+ *\n+ * @returns\n+ *   Operation type as string\n+ *\n+ */\n+const char*\n+rte_bbdev_op_type_str(enum rte_bbdev_op_type op_type);\n+\n+/**\n+ * Creates a bbdev operation mempool\n+ *\n+ * @param name\n+ *   Pool name.\n+ * @param type\n+ *   Operation type, use RTE_BBDEV_OP_NONE for a pool which supports all\n+ *   operation types.\n+ * @param num_elements\n+ *   Number of elements in the pool.\n+ * @param cache_size\n+ *   Number of elements to cache on an lcore, see rte_mempool_create() for\n+ *   further details about cache size.\n+ * @param socket_id\n+ *   Socket to allocate memory on.\n+ *\n+ * @return\n+ *   - Pointer to a mempool on success,\n+ *   - NULL pointer on failure.\n+ */\n+struct rte_mempool *\n+rte_bbdev_op_pool_create(const char *name, enum rte_bbdev_op_type type,\n+\t\tunsigned int num_elements, unsigned int cache_size,\n+\t\tint socket_id);\n+\n+/**\n+ * Bulk allocate encode operations from a mempool with parameter defaults reset.\n+ *\n+ * @param mempool\n+ *   Operation mempool, created by rte_bbdev_op_pool_create().\n+ * @param ops\n+ *   Output array to place allocated operations\n+ * @param num_ops\n+ *   Number of operations to allocate\n+ *\n+ * @returns\n+ *   - 0 on success\n+ *   - EINVAL if invalid mempool is provided\n+ */\n+static inline int\n+rte_bbdev_enc_op_alloc_bulk(struct rte_mempool *mempool,\n+\t\tstruct rte_bbdev_enc_op **ops, uint16_t num_ops)\n+{\n+\tstruct rte_bbdev_op_pool_private *priv;\n+\tint ret;\n+\n+\t/* Check type */\n+\tpriv = (struct rte_bbdev_op_pool_private *)\n+\t\t\trte_mempool_get_priv(mempool);\n+\tif (unlikely(priv->type != RTE_BBDEV_OP_TURBO_ENC))\n+\t\treturn -EINVAL;\n+\n+\t/* Get elements */\n+\tret = rte_mempool_get_bulk(mempool, (void **)ops, num_ops);\n+\tif (unlikely(ret < 0))\n+\t\treturn ret;\n+\n+\trte_bbdev_log_verbose(\"%u encode ops allocated from %s\\n\",\n+\t\t\tnum_ops, mempool->name);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Bulk allocate decode operations from a mempool with parameter defaults reset.\n+ *\n+ * @param mempool\n+ *   Operation mempool, created by rte_bbdev_op_pool_create().\n+ * @param ops\n+ *   Output array to place allocated operations\n+ * @param num_ops\n+ *   Number of operations to allocate\n+ *\n+ * @returns\n+ *   - 0 on success\n+ *   - EINVAL if invalid mempool is provided\n+ */\n+static inline int\n+rte_bbdev_dec_op_alloc_bulk(struct rte_mempool *mempool,\n+\t\tstruct rte_bbdev_dec_op **ops, uint16_t num_ops)\n+{\n+\tstruct rte_bbdev_op_pool_private *priv;\n+\tint ret;\n+\n+\t/* Check type */\n+\tpriv = (struct rte_bbdev_op_pool_private *)\n+\t\t\trte_mempool_get_priv(mempool);\n+\tif (unlikely(priv->type != RTE_BBDEV_OP_TURBO_DEC))\n+\t\treturn -EINVAL;\n+\n+\t/* Get elements */\n+\tret = rte_mempool_get_bulk(mempool, (void **)ops, num_ops);\n+\tif (unlikely(ret < 0))\n+\t\treturn ret;\n+\n+\trte_bbdev_log_verbose(\"%u encode ops allocated from %s\\n\",\n+\t\t\tnum_ops, mempool->name);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Free decode operation structures that were allocated by\n+ * rte_bbdev_dec_op_alloc_bulk().\n+ * All structures must belong to the same mempool.\n+ *\n+ * @param ops\n+ *   Operation structures\n+ * @param num_ops\n+ *   Number of structures\n+ */\n+static inline void\n+rte_bbdev_dec_op_free_bulk(struct rte_bbdev_dec_op **ops, unsigned int num_ops)\n+{\n+\tif (num_ops > 0) {\n+\t\trte_mempool_put_bulk(ops[0]->mempool, (void **)ops, num_ops);\n+\t\trte_bbdev_log_verbose(\"%u decode ops freed to %s\\n\", num_ops,\n+\t\t\t\tops[0]->mempool->name);\n+\t}\n+}\n+\n+/**\n+ * Free encode operation structures that were allocated by\n+ * rte_bbdev_enc_op_alloc_bulk().\n+ * All structures must belong to the same mempool.\n+ *\n+ * @param ops\n+ *   Operation structures\n+ * @param num_ops\n+ *   Number of structures\n+ */\n+static inline void\n+rte_bbdev_enc_op_free_bulk(struct rte_bbdev_enc_op **ops, unsigned int num_ops)\n+{\n+\tif (num_ops > 0) {\n+\t\trte_mempool_put_bulk(ops[0]->mempool, (void **)ops, num_ops);\n+\t\trte_bbdev_log_verbose(\"%u encode ops freed to %s\\n\", num_ops,\n+\t\t\t\tops[0]->mempool->name);\n+\t}\n+}\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* _RTE_BBDEV_OP_H_ */\ndiff --git a/lib/librte_bbdev/rte_bbdev_pmd.h b/lib/librte_bbdev/rte_bbdev_pmd.h\nnew file mode 100644\nindex 0000000..cf65de0\n--- /dev/null\n+++ b/lib/librte_bbdev/rte_bbdev_pmd.h\n@@ -0,0 +1,223 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _RTE_BBDEV_PMD_H_\n+#define _RTE_BBDEV_PMD_H_\n+\n+/**\n+ * @file rte_bbdev_pmd.h\n+ *\n+ * Wireless base band driver-facing APIs.\n+ *\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ *\n+ * This API provides the mechanism for device drivers to register with the\n+ * bbdev interface. User applications should not use this API.\n+ */\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#include <stdint.h>\n+#include <rte_log.h>\n+\n+#include \"rte_bbdev.h\"\n+\n+/** Suggested value for SW based devices */\n+#define RTE_BBDEV_DEFAULT_MAX_NB_QUEUES RTE_MAX_LCORE\n+\n+/** Suggested value for SW based devices */\n+#define RTE_BBDEV_QUEUE_SIZE_LIMIT 16384\n+\n+/**\n+ * @internal\n+ * Allocates a new slot for a bbdev and returns the pointer to that slot\n+ * for the driver to use.\n+ *\n+ * @param name\n+ *   Unique identifier name for each bbdev device\n+ *\n+ * @return\n+ *   - Slot in the rte_bbdev array for a new device;\n+ */\n+struct rte_bbdev *\n+rte_bbdev_allocate(const char *name);\n+\n+/**\n+ * @internal\n+ * Release the specified bbdev.\n+ *\n+ * @param bbdev\n+ *   The *bbdev* pointer is the address of the *rte_bbdev* structure.\n+ * @return\n+ *   - 0 on success, negative on error\n+ */\n+int\n+rte_bbdev_release(struct rte_bbdev *bbdev);\n+\n+/**\n+ * Get the device structure for a named device.\n+ *\n+ * @param name\n+ *   Name of the device\n+ *\n+ * @return\n+ *   - The device structure pointer, or\n+ *   - NULL otherwise\n+ *\n+ */\n+struct rte_bbdev *\n+rte_bbdev_get_named_dev(const char *name);\n+\n+/**\n+ * Definitions of all functions exported by a driver through the the generic\n+ * structure of type *rte_bbdev_ops* supplied in the *rte_bbdev* structure\n+ * associated with a device.\n+ */\n+\n+/** @internal Function used to configure device memory. */\n+typedef int (*rte_bbdev_setup_queues_t)(struct rte_bbdev *dev,\n+\t\tuint16_t num_queues, int socket_id);\n+\n+/** @internal Function used to configure interrupts for a device. */\n+typedef int (*rte_bbdev_intr_enable_t)(struct rte_bbdev *dev);\n+\n+/** @internal Function to allocate and configure a device queue. */\n+typedef int (*rte_bbdev_queue_setup_t)(struct rte_bbdev *dev,\n+\t\tuint16_t queue_id, const struct rte_bbdev_queue_conf *conf);\n+\n+/* @internal\n+ * Function to release memory resources allocated for a device queue.\n+ */\n+typedef int (*rte_bbdev_queue_release_t)(struct rte_bbdev *dev,\n+\t\tuint16_t queue_id);\n+\n+/** @internal Function to start a configured device. */\n+typedef int (*rte_bbdev_start_t)(struct rte_bbdev *dev);\n+\n+/** @internal Function to stop a device. */\n+typedef void (*rte_bbdev_stop_t)(struct rte_bbdev *dev);\n+\n+/** @internal Function to close a device. */\n+typedef int (*rte_bbdev_close_t)(struct rte_bbdev *dev);\n+\n+/** @internal Function to start a device queue. */\n+typedef int (*rte_bbdev_queue_start_t)(struct rte_bbdev *dev,\n+\t\tuint16_t queue_id);\n+\n+/** @internal Function to stop a device queue. */\n+typedef int (*rte_bbdev_queue_stop_t)(struct rte_bbdev *dev, uint16_t queue_id);\n+\n+/** @internal Function to read stats from a device. */\n+typedef void (*rte_bbdev_stats_get_t)(struct rte_bbdev *dev,\n+\t\tstruct rte_bbdev_stats *stats);\n+\n+/** @internal Function to reset stats on a device. */\n+typedef void (*rte_bbdev_stats_reset_t)(struct rte_bbdev *dev);\n+\n+/** @internal Function to retrieve specific information of a device. */\n+typedef void (*rte_bbdev_info_get_t)(struct rte_bbdev *dev,\n+\t\tstruct rte_bbdev_driver_info *dev_info);\n+\n+/* @internal\n+ * Function to enable interrupt for next op on a queue of a device.\n+ */\n+typedef int (*rte_bbdev_queue_intr_enable_t)(struct rte_bbdev *dev,\n+\t\t\t\t    uint16_t queue_id);\n+\n+/* @internal\n+ * Function to disable interrupt for next op on a queue of a device.\n+ */\n+typedef int (*rte_bbdev_queue_intr_disable_t)(struct rte_bbdev *dev,\n+\t\t\t\t    uint16_t queue_id);\n+\n+/**\n+ * Operations implemented by drivers. Fields marked as \"Required\" must be\n+ * provided by a driver for a device to have basic functionality. \"Optional\"\n+ * fields are for non-vital operations\n+ */\n+struct rte_bbdev_ops {\n+\t/**< Allocate and configure device memory. Optional. */\n+\trte_bbdev_setup_queues_t setup_queues;\n+\t/**< Configure interrupts. Optional. */\n+\trte_bbdev_intr_enable_t intr_enable;\n+\t/**< Start device. Optional. */\n+\trte_bbdev_start_t start;\n+\t/**< Stop device. Optional. */\n+\trte_bbdev_stop_t stop;\n+\t/**< Close device. Optional. */\n+\trte_bbdev_close_t close;\n+\n+\t/**< Get device info. Required. */\n+\trte_bbdev_info_get_t info_get;\n+\t/** Get device statistics. Optional. */\n+\trte_bbdev_stats_get_t stats_get;\n+\t/** Reset device statistics. Optional. */\n+\trte_bbdev_stats_reset_t stats_reset;\n+\n+\t/** Set up a device queue. Required. */\n+\trte_bbdev_queue_setup_t queue_setup;\n+\t/** Release a queue. Required. */\n+\trte_bbdev_queue_release_t queue_release;\n+\t/** Start a queue. Optional. */\n+\trte_bbdev_queue_start_t queue_start;\n+\t/**< Stop a queue pair. Optional. */\n+\trte_bbdev_queue_stop_t queue_stop;\n+\n+\t/** Enable queue interrupt. Optional */\n+\trte_bbdev_queue_intr_enable_t queue_intr_enable;\n+\t/** Disable queue interrupt. Optional */\n+\trte_bbdev_queue_intr_disable_t queue_intr_disable;\n+};\n+\n+/**\n+ * Executes all the user application registered callbacks for the specific\n+ * device and event type.\n+ *\n+ * @param dev\n+ *   Pointer to the device structure.\n+ * @param event\n+ *   Event type.\n+ * @param ret_param\n+ *   To pass data back to user application.\n+ */\n+void\n+rte_bbdev_pmd_callback_process(struct rte_bbdev *dev,\n+\tenum rte_bbdev_event_type event, void *ret_param);\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* _RTE_BBDEV_PMD_H_ */\ndiff --git a/lib/librte_bbdev/rte_bbdev_version.map b/lib/librte_bbdev/rte_bbdev_version.map\nnew file mode 100644\nindex 0000000..316a275\n--- /dev/null\n+++ b/lib/librte_bbdev/rte_bbdev_version.map\n@@ -0,0 +1,37 @@\n+EXPERIMENTAL {\n+\tglobal:\n+\n+\trte_bbdev_allocate;\n+\trte_bbdev_callback_register;\n+\trte_bbdev_callback_unregister;\n+\trte_bbdev_close;\n+\trte_bbdev_setup_queues;\n+\trte_bbdev_intr_enable;\n+\trte_bbdev_count;\n+\trte_bbdev_dequeue_dec_ops;\n+\trte_bbdev_dequeue_enc_ops;\n+\trte_bbdev_devices;\n+\trte_bbdev_enqueue_dec_ops;\n+\trte_bbdev_enqueue_enc_ops;\n+\trte_bbdev_find_next;\n+\trte_bbdev_get_named_dev;\n+\trte_bbdev_info_get;\n+\trte_bbdev_is_valid;\n+\trte_bbdev_op_pool_create;\n+\trte_bbdev_op_type_str;\n+\trte_bbdev_pmd_callback_process;\n+\trte_bbdev_queue_configure;\n+\trte_bbdev_queue_info_get;\n+\trte_bbdev_queue_intr_ctl;\n+\trte_bbdev_queue_intr_disable;\n+\trte_bbdev_queue_intr_enable;\n+\trte_bbdev_queue_start;\n+\trte_bbdev_queue_stop;\n+\trte_bbdev_release;\n+\trte_bbdev_start;\n+\trte_bbdev_stats_get;\n+\trte_bbdev_stats_reset;\n+\trte_bbdev_stop;\n+\n+\tlocal: *;\n+};\n\\ No newline at end of file\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex 6a6a745..521612c 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -96,6 +96,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER)          += -lrte_ethdev\n _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV)      += -lrte_cryptodev\n _LDLIBS-$(CONFIG_RTE_LIBRTE_SECURITY)       += -lrte_security\n _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_BBDEV)          += -lrte_bbdev\n _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool\n _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring\n _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring\n@@ -162,6 +163,18 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VHOST)      += -lrte_pmd_vhost\n endif # $(CONFIG_RTE_LIBRTE_VHOST)\n _LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD)    += -lrte_pmd_vmxnet3_uio\n \n+ifeq ($(CONFIG_RTE_LIBRTE_BBDEV),y)\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_NULL)     += -lrte_pmd_bbdev_null\n+\n+# TURBO SOFTWARE PMD is dependent on the FLEXRAN library\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -lrte_pmd_bbdev_turbo_sw\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_common -lcommon\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_crc -lcrc\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_turbo -lturbo\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_rate_matching -lrate_matching\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -lirc -limf -lstdc++ -lipps\n+endif # CONFIG_RTE_LIBRTE_BBDEV\n+\n ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)    += -lrte_pmd_aesni_mb\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)    += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB\n",
    "prefixes": [
        "dpdk-dev",
        "v3",
        "1/5"
    ]
}