diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 19e0d4f..6541187 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -47,6 +47,7 @@ The public API headers are grouped by topics:
   [bitrate]            (@ref rte_bitrate.h),
   [latency]            (@ref rte_latencystats.h),
   [devargs]            (@ref rte_devargs.h),
+  [bbdev]              (@ref rte_bbdev.h),
   [PCI]                (@ref rte_pci.h)
 
 - **device specific**:
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index 823554f..ffdbebe 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -37,6 +37,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           lib/librte_eal/common/include \
                           lib/librte_eal/common/include/generic \
                           lib/librte_acl \
+                          lib/librte_bbdev \
                           lib/librte_bitratestats \
                           lib/librte_cfgfile \
                           lib/librte_cmdline \
diff --git a/doc/guides/bbdevs/index.rst b/doc/guides/bbdevs/index.rst
new file mode 100644
index 0000000..c9aa1b0
--- /dev/null
+++ b/doc/guides/bbdevs/index.rst
@@ -0,0 +1,40 @@
+..
+   BSD LICENSE
+
+   Copyright(c) 2017 Intel Corporation. All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+     * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in
+       the documentation and/or other materials provided with the
+       distribution.
+     * Neither the name of Intel Corporation nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Baseband Device Drivers
+=======================
+
+.. toctree::
+    :maxdepth: 2
+    :numbered:
+
+    null
+    turbo_sw
diff --git a/doc/guides/bbdevs/null.rst b/doc/guides/bbdevs/null.rst
new file mode 100644
index 0000000..0f40232
--- /dev/null
+++ b/doc/guides/bbdevs/null.rst
@@ -0,0 +1,77 @@
+..
+   BSD LICENSE
+
+   Copyright(c) 2017 Intel Corporation. All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+     * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in
+       the documentation and/or other materials provided with the
+       distribution.
+     * Neither the name of Intel Corporation nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+BBDEV null Poll Mode Driver
+============================
+
+The (**bbdev_null**) is a bbdev poll mode driver which provides a minimal
+implementation of a software bbdev device. As a null device it does not modify
+the data in the mbuf on which the bbdev operation is to operate and it only
+works for operation type ``RTE_BBDEV_OP_NONE``.
+
+When a burst of mbufs is submitted to a *bbdev null PMD* for processing then
+each mbuf in the burst will be enqueued in an internal buffer ring to be
+collected on a dequeue call.
+
+
+Limitations
+-----------
+
+* In-place operations for Turbo encode and decode are not supported
+
+Installation
+------------
+
+The *bbdev null PMD* is enabled and built by default in both the Linux and
+FreeBSD builds.
+
+Initialization
+--------------
+
+To use the PMD in an application, user must:
+
+- Call ``rte_vdev_init("bbdev_null")`` within the application.
+
+- Use ``--vdev="bbdev_null"`` in the EAL options, which will call ``rte_vdev_init()`` internally.
+
+The following parameters (all optional) can be provided in the previous two calls:
+
+* ``socket_id``: Specify the socket where the memory for the device is going to be allocated
+  (by default, *socket_id* will be the socket where the core that is creating the PMD is running on).
+
+* ``max_nb_queues``: Specify the maximum number of queues in the device (default is ``RTE_MAX_LCORE``).
+
+Example:
+~~~~~~~~
+
+.. code-block:: console
+
+    ./test-bbdev.py -e="--vdev=bbdev_null,socket_id=0,max_nb_queues=8"
diff --git a/doc/guides/bbdevs/turbo_sw.rst b/doc/guides/bbdevs/turbo_sw.rst
new file mode 100644
index 0000000..a8af487
--- /dev/null
+++ b/doc/guides/bbdevs/turbo_sw.rst
@@ -0,0 +1,101 @@
+..
+   BSD LICENSE
+
+   Copyright(c) 2017 Intel Corporation. All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+     * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in
+       the documentation and/or other materials provided with the
+       distribution.
+     * Neither the name of Intel Corporation nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SW Turbo Poll Mode Driver
+=========================
+
+The SW Turbo PMD (**turbo_sw**) provides a poll mode bbdev driver that utilizes
+Intel optimized libraries for LTE Layer 1 workloads acceleration. This PMD
+supports the functions: Turbo FEC, Rate Matching and CRC functions.
+
+Features
+--------
+
+SW Turbo PMD has support for the following capabilities:
+
+For the encode operation:
+
+* ``RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE``
+* ``RTE_BBDEV_TURBO_RAW_INPUT_DATA``
+
+For the decode operation:
+
+* ``RTE_BBDEV_TURBO_CRC_24B_ATTACH``
+* ``RTE_BBDEV_TURBO_RATE_MATCH``
+* ``RTE_BBDEV_TURBO_RV_INDEX_BYPASS``
+
+
+Limitations
+-----------
+
+* In-place operations for Turbo encode and decode are not supported
+
+Installation
+------------
+
+To build DPDK with the *turbo_sw* the user is required to download
+the export controlled **turbo sw** libs, by requesting it from
+`<https://networkbuilders.intel.com/network-technologies/dpdk>`_.
+
+After downloading the library, the user needs to unpack and compile it
+on their system before building DPDK.
+
+Initialization
+--------------
+
+In order to enable this virtual bbdev PMD, user must:
+
+* Build the **turbo sw** library (explained in Installation section).
+
+* Export the environmental variable ``BBLIB_PATH`` with the path where the library was built.
+
+* Set ``CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW=y`` in DPDK common configuration file ``config/common_base``.
+
+To use the PMD in an application, user must:
+
+- Call ``rte_vdev_init("turbo_sw")`` within the application.
+
+- Use ``--vdev="turbo_sw"`` in the EAL options, which will call ``rte_vdev_init()`` internally.
+
+The following parameters (all optional) can be provided in the previous two calls:
+
+* ``socket_id``: Specify the socket where the memory for the device is going to be allocated
+  (by default, *socket_id* will be the socket where the core that is creating the PMD is running on).
+
+* ``max_nb_queues``: Specify the maximum number of queues in the device (default is ``RTE_MAX_LCORE``).
+
+Example:
+~~~~~~~~
+
+.. code-block:: console
+
+    ./test-bbdev.py -e="--vdev=turbo_sw,socket_id=0,max_nb_queues=8" \
+    -c validation -v ./test_vectors/bbdev_vector_t?_default.data
diff --git a/doc/guides/index.rst b/doc/guides/index.rst
index 63716b0..53f29e7 100644
--- a/doc/guides/index.rst
+++ b/doc/guides/index.rst
@@ -44,6 +44,7 @@ DPDK documentation
    nics/index
    cryptodevs/index
    eventdevs/index
+   bbdevs/index
    xen/index
    contributing/index
    rel_notes/index
diff --git a/doc/guides/prog_guide/bbdev.rst b/doc/guides/prog_guide/bbdev.rst
new file mode 100644
index 0000000..f2fdab0
--- /dev/null
+++ b/doc/guides/prog_guide/bbdev.rst
@@ -0,0 +1,609 @@
+..
+   BSD LICENSE
+
+   Copyright(c) 2017 Intel Corporation. All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+     * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in
+       the documentation and/or other materials provided with the
+       distribution.
+     * Neither the name of Intel Corporation nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Wireless Baseband Device Library
+================================
+
+The Wireless Baseband library provides a common programming framework that
+abstracts HW accelerators based on FPGA and/or Fixed Function Accelerators that
+assist with LTE Physical Layer processing. Furthermore, it decouples the
+application from the compute-intensive wireless functions by abstracting their
+optimized libraries to appear as virtual bbdev devices.
+
+The framework currently only supports Turbo Code FEC function.
+
+
+Design Principles
+-----------------
+
+The Wireless Baseband library follows the same ideology of DPDK's Ethernet
+Device and Crypto Device frameworks. Wireless Baseband provides a generic
+acceleration abstraction framework which supports both physical (hardware) and
+virtual (software) wireless acceleration functions.
+
+.. figure:: img/bbdev_workflow.*
+
+Device Management
+-----------------
+
+Device Creation
+~~~~~~~~~~~~~~~
+
+Physical bbdev devices are discovered during the PCI probe/enumeration of the
+EAL function which is executed at DPDK initialization, based on
+their PCI device identifier, each unique PCI BDF (bus/bridge, device,
+function).
+
+Virtual devices can be created by two mechanisms, either using the EAL command
+line options or from within the application using an EAL API directly.
+
+From the command line using the --vdev EAL option
+
+.. code-block:: console
+
+   --vdev 'turbo_sw,max_nb_queues=8,socket_id=0'
+
+Our using the rte_vdev_init API within the application code.
+
+.. code-block:: c
+
+    rte_vdev_init("turbo_sw", "max_nb_queues=2,socket_id=0")
+
+All virtual bbdev devices support the following initialization parameters:
+
+- ``max_nb_queues`` - maximum number of queues supported by the device.
+
+- ``socket_id`` - socket on which to allocate the device resources on.
+
+
+Device Identification
+~~~~~~~~~~~~~~~~~~~~~
+
+Each device, whether virtual or physical is uniquely designated by two
+identifiers:
+
+- A unique device index used to designate the bbdev device in all functions
+  exported by the bbdev API.
+
+- A device name used to designate the bbdev device in console messages, for
+  administration or debugging purposes. For ease of use, the port name includes
+  the port index.
+
+
+Device Configuration
+~~~~~~~~~~~~~~~~~~~~
+
+From the application point of view, each instance of a bbdev device consists of
+one or more queues identified by queue IDs. While different devices may have
+different capabilities (e.g. support different operation types), all queues on
+a device support identical configuration possibilities. A queue is configured
+for only one type of operation and is configured at initializations time.
+When an operation is enqueued to a specific queue ID, the result is dequeued
+from the same queue ID.
+
+Configuration of a device has two different levels: configuration that applies
+to the whole device, and configuration that applies to a single queue.
+
+Device configuration is applied with ``rte_bbdev_configure(dev_id,num_queues,conf)``
+and queue configuration is applied with
+``rte_bbdev_queue_configure(dev_id,queue_id,conf)``. Note that, although all
+queues on a device support same capabilities, they can be configured differently
+and will then behave differently.
+
+The configuration of each bbdev device includes the following operations:
+
+- Allocation of resources, including hardware resources if a physical device.
+- Resetting the device into a well-known default state.
+- Initialization of statistics counters.
+
+The rte_bbdev_configure API is used to configure a bbdev device.
+
+.. code-block:: c
+
+   int rte_bbdev_configure(uint16_t dev_id, uint16_t num_queues,
+                           const struct rte_bbdev_conf *conf);
+
+- ``num_queues`` argument identifies the total number of queues to setup for
+  this device.
+
+- ``rte_bbdev_conf`` structure is used to pass the configuration parameters for
+  device configuration.
+
+
+Queues Configuration
+~~~~~~~~~~~~~~~~~~~~
+
+Each bbdev devices queue is individually configured through the
+``rte_bbdev_queue_configure()`` API.
+Each queue resources may be allocated on a specified socket.
+
+.. code-block:: c
+
+    struct rte_bbdev_queue_conf {
+        int socket;  /**< NUMA socket used for memory allocation */
+        uint32_t queue_size;  /**< Size of queue */
+        uint8_t priority;  /**< Queue priority */
+        bool deferred_start; /**< Do not start queue when device is started. */
+        enum rte_bbdev_op_type op_type; /**< Operation type */
+    };
+
+Device & Queues Management
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After initialization, devices are in a stopped state, so must be started by the
+application. If an application is finished using a device it can close the
+device. Once closed, it cannot be restarted.
+
+.. code-block:: c
+
+    int rte_bbdev_start(uint16_t dev_id)
+    int rte_bbdev_stop(uint16_t dev_id)
+    int rte_bbdev_close(uint16_t dev_id)
+    int rte_bbdev_queue_start(uint16_t dev_id, uint16_t queue_id)
+    int rte_bbdev_queue_stop(uint16_t dev_id, uint16_t queue_id)
+
+
+By default, all queues are started when the device is started, but they can be
+stopped individually.
+
+.. code-block:: c
+
+    int rte_bbdev_queue_start(uint16_t dev_id, uint16_t queue_id)
+    int rte_bbdev_queue_stop(uint16_t dev_id, uint16_t queue_id)
+
+
+Logical Cores, Memory and Queues Relationships
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The bbdev device Library as the Poll Mode Driver library support NUMA for when
+a processor’s logical cores and interfaces utilize its local memory. Therefore
+baseband operations, the mbuf being operated on should be allocated from memory
+pools created in the local memory. The buffers should, if possible, remain on
+the local processor to obtain the best performance results and buffer
+descriptors should be populated with mbufs allocated from a mempool allocated
+from local memory.
+
+The run-to-completion model also performs better, especially in the case of
+virtual bbdev devices, if the baseband operation and data buffers are in local
+memory instead of a remote processor's memory. This is also true for the
+pipe-line model provided all logical cores used are located on the same processor.
+
+Multiple logical cores should never share the same queue for enqueuing
+operations or dequeuing operations on the same bbdev device since this would
+require global locks and hinder performance. It is however possible to use a
+different logical core to dequeue an operation on a queue pair from the logical
+core which it was enqueued on. This means that a baseband burst enqueue/dequeue
+APIs are a logical place to transition from one logical core to another in a
+packet processing pipeline.
+
+
+Device Operation Capabilities
+-----------------------------
+
+Capabilities (in terms of operations supported, max number of queues, etc.)
+identify what a bbdev is capable of performing that differs from one device to
+another. For the full scope of the bbdev capability see the definition of the
+structure in the *DPDK API Reference*.
+
+.. code-block:: c
+
+   struct rte_bbdev_op_cap;
+
+A device reports its capabilities when registering itself in the bbdev framework.
+With the aid of this capabilities mechanism, an application can query devices to
+discover which operations within the LTE physical layer they are capable of
+performing. Below is an example of the capabilities for a PMD it supports in
+relation to Turbo Encoding and Decoding operations.
+
+.. code-block:: c
+
+    static const struct rte_bbdev_op_cap bbdev_capabilities[] = {
+        {
+            .type = RTE_BBDEV_OP_TURBO_DEC,
+            .cap.turbo_dec = {
+                .capability_flags =
+                    RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE |
+                    RTE_BBDEV_TURBO_RAW_INPUT_DATA,
+                .num_buffers_src = 1,
+                .num_buffers_hard_out = 1,
+                .num_buffers_soft_out = 0,
+            }
+        },
+        {
+            .type   = RTE_BBDEV_OP_TURBO_ENC,
+            .cap.turbo_enc = {
+                .capability_flags =
+                        RTE_BBDEV_TURBO_CRC_24B_ATTACH |
+                        RTE_BBDEV_TURBO_RATE_MATCH |
+                        RTE_BBDEV_TURBO_RV_INDEX_BYPASS,
+                .num_buffers_src = 1,
+                .num_buffers_dst = 1,
+            }
+        }
+    };
+
+Capabilities Discovery
+~~~~~~~~~~~~~~~~~~~~~~
+
+Discovering the features and capabilities of a bbdev device poll mode driver
+is achieved through the ``rte_bbdev_info_get()`` function.
+
+.. code-block:: c
+
+   int rte_bbdev_info_get(uint16_t dev_id, struct rte_bbdev_info *dev_info)
+
+This allows the user to query a specific bbdev PMD and get all the device
+capabilities. The ``rte_bbdev_info`` structure provides two levels of
+information:
+
+- Device relevant information, like: name and related rte_bus.
+
+- Driver specific information, as defined by the ``struct rte_bbdev_driver_info``
+  structure, this is where capabilities reside along with other specifics like:
+  maximum queue sizes and priority level.
+
+.. code-block:: c
+
+    struct rte_bbdev_info {
+        int socket_id;  /**< NUMA socket that device is on */
+        const char *dev_name;  /**< Unique device name */
+        const struct rte_bus *bus;  /**< Bus information */
+        uint16_t num_queues;  /**< Number of queues currently configured */
+        struct rte_bbdev_conf conf;  /**< Current device configuration */
+        bool started;  /**< Set if device is currently started */
+        struct rte_bbdev_driver_info drv;  /**< Info from device driver */
+    };
+
+Operation Processing
+--------------------
+
+Scheduling of baseband operations on DPDK's application data path is
+performed using a burst oriented asynchronous API set. A queue on a bbdev
+device accepts a burst of baseband operations using enqueue burst API. On physical
+bbdev devices the enqueue burst API will place the operations to be processed
+on the device's hardware input queue, for virtual devices the processing of the
+baseband operations is usually completed during the enqueue call to the bbdev
+device. The dequeue burst API will retrieve any processed operations available
+from the queue on the bbdev device, from physical devices this is usually
+directly from the device's processed queue, and for virtual device's from a
+``rte_ring`` where processed operations are place after being processed on the
+enqueue call.
+
+
+Enqueue / Dequeue Burst APIs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The burst enqueue API uses a bbdev device identifier and a queue
+identifier to specify the bbdev device queue to schedule the processing on.
+The ``num_ops`` parameter is the number of operations to process which are
+supplied in the ``ops`` array of ``rte_bbdev_op`` structures.
+The enqueue function returns the number of operations it actually enqueued for
+processing, a return value equal to ``num_ops`` means that all packets have been
+enqueued.
+
+.. code-block:: c
+
+   uint16_t rte_bbdev_enqueue_ops(uint16_t dev_id, uint16_t queue_id,
+                                  struct rte_bbdev_op **ops, uint16_t num_ops)
+
+The dequeue API uses the same format as the enqueue API of processed but
+the ``num_ops`` and ``ops`` parameters are now used to specify the max processed
+operations the user wishes to retrieve and the location in which to store them.
+The API call returns the actual number of processed operations returned, this
+can never be larger than ``num_ops``.
+
+.. code-block:: c
+
+   uint16_t rte_bbdev_dequeue_ops(uint16_t dev_id, uint16_t queue_id,
+                                  struct rte_bbdev_op **ops, uint16_t num_ops)
+
+
+Operation Representation
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+A bbdev operation is represented by a ``rte_bbdev_op`` structure, which is a
+generic metadata container for all necessary information required for the
+bbdev operation to be processed on a particular bbdev device poll mode driver.
+
+.. code-block:: c
+
+    struct rte_bbdev_op {
+        enum rte_bbdev_op_type type;  /**< Type of this operation */
+        int status;  /**< Status of operation that was performed */
+        struct rte_mempool *mempool;  /**< Mempool which op instance is in */
+        void *opaque_data;  /**< Opaque pointer for user data */
+        ...
+        union {
+            void *generic;
+            struct rte_bbdev_op_turbo_dec *turbo_dec;
+            struct rte_bbdev_op_turbo_enc *turbo_enc;
+        };
+    };
+
+The operation structure includes the operation type and the operation status,
+a reference to the operation specific data, which can vary in size and content
+depending on the operation being provisioned. It also contains the source
+mempool for the operation, if it allocated from a mempool.
+
+If bbdev operations are allocated from a bbdev operation mempool, see next
+section, there is also the ability to allocate private memory with the
+operation for applications purposes.
+
+Application software is responsible for specifying all the operation specific
+fields in the ``rte_bbdev_op`` structure which are then used by the bbdev PMD
+to process the requested operation.
+
+
+Operation Management and Allocation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The bbdev library provides an API set for managing bbdev operations which
+utilize the Mempool Library to allocate operation buffers. Therefore, it ensures
+that the bbdev operation is interleaved optimally across the channels and
+ranks for optimal processing.
+
+.. code-block:: c
+
+    struct rte_mempool *
+    rte_bbdev_op_pool_create(const char *name, enum rte_bbdev_op_type type,
+                             unsigned int num_elements, unsigned int cache_size,
+                             int socket_id)
+
+``rte_bbdev_op_alloc_bulk()`` and ``rte_bbdev_op_free_bulk()`` are used to
+allocate bbdev operations of a specific type from a given bbdev operation mempool.
+
+.. code-block:: c
+
+    int rte_bbdev_op_alloc_bulk(struct rte_mempool *mempool,
+                                enum rte_bbdev_op_type type,
+                                struct rte_bbdev_op **ops,
+                                uint16_t num_ops)
+
+``rte_bbdev_op_free_bulk()`` is called by the application to return an operation
+to its allocating pool.
+
+.. code-block:: c
+
+   void rte_bbdev_op_free_bulk(struct rte_bbdev_op **ops, unsigned int num_ops)
+
+
+BBDEV Operations
+~~~~~~~~~~~~~~~~
+
+The bbdev operation structure contains all the mutable data relating to
+performing Turbo code processing on a referenced mbuf data buffer. It is used
+for either encode or decode operations.
+
+Turbo Encode operation accepts one input and one output.
+
+Turbo Decode operation accepts one input and two outputs, called *hard-decision*
+and *soft-decision* outputs. *Soft-decision* output is optional.
+
+It is expected that the application provides input and output ``mbuf`` pointers
+allocated and ready to use. The baseband framework supports turbo coding on
+Code Blocks (CB) and Transport Blocks (TB).
+
+For the output buffer(s), the application needs only to provide an allocated and
+free mbuf (containing only one mbuf segment), so that bbdev can write the
+operation outcome.
+
+**Turbo Encode Op structure**
+
+.. code-block:: c
+
+    struct rte_bbdev_op_turbo_enc {
+        struct rte_bbdev_op_data input; /**< input src data */
+        struct rte_bbdev_op_data output; /**< output buffer */
+
+        uint32_t op_flags;
+        int32_t n_soft;
+        int32_t k_mimo;
+        int32_t mdl_harq;
+
+        int32_t g;
+        int32_t nl;
+        int32_t qm;
+        uint8_t rv_index;
+
+        uint8_t code_block_mode; /**< 0 - transpot block, 1 - code block */
+        union {
+            struct rte_bbdev_op_enc_cb_params cb_params;
+            struct rte_bbdev_op_enc_tb_params tb_params;
+        };
+    };
+
+
+**Turbo Decode Op structure**
+
+.. code-block:: c
+
+    struct rte_bbdev_op_turbo_dec {
+        struct rte_bbdev_op_data input; /**< input src data */
+        struct rte_bbdev_op_data hard_output; /**< hard output buffer */
+        struct rte_bbdev_op_data soft_output; /**< soft output buffer */
+
+        uint32_t op_flags;
+        uint8_t rv_index;
+        uint8_t iter_min:4;
+        uint8_t iter_max:4;
+        uint8_t iter_count;
+        uint8_t ext_scale;
+        uint8_t num_maps;
+
+        uint8_t code_block_mode; /**< 0 - transpot block, 1 - code block */
+        union {
+            struct rte_bbdev_op_dec_cb_params cb_params;
+            struct rte_bbdev_op_dec_tb_params tb_params;
+        };
+    };
+
+Input and output data buffers are identified by ``rte_bbdev_op_data`` structure.
+This strucutre has three elements:
+
+- ``data`` - This is the mbuf reference
+
+- ``offset`` - The starting point for the Turbo input/output, in bytes, from the
+  start of the data in the data buffer. It must be smaller than data_len of the
+  mbuf's first segment
+
+- ``length`` - The length, in bytes, of the buffer on which the Turbo operation
+  will or has been computed. For the input, the length is set by the application.
+  For the output(s), the length is computed by the bbdev PMD driver.
+
+Sample code
+-----------
+
+The baseband device sample application gives an introduction on how to use the
+bbdev framework, by giving a sample code performing a loop-back operation with a
+baseband processor capable of transceiving data packets.
+
+The following sample pseudo-code shows the basic steps to encode several buffers
+using (**sw_trubo**) bbdev PMD.
+
+.. code-block:: c
+
+    /* EAL Init */
+    ret = rte_eal_init(argc, argv);
+    if (ret < 0)
+        rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
+
+    /* Get number of available bbdev devices */
+    nb_bbdevs = rte_bbdev_count();
+    if (nb_bbdevs == 0)
+        rte_exit(EXIT_FAILURE, "No bbdevs detected!\n");
+
+    /* Create bbdev op pools */
+    bbdev_op_pool[RTE_BBDEV_OP_TURBO_ENC] =
+            rte_bbdev_op_pool_create("bbdev_op_pool_enc",
+            RTE_BBDEV_OP_TURBO_ENC, NB_MBUF, 128, rte_socket_id());
+
+    /* Configure BBDEV device */
+    ret = rte_bbdev_configure(dev_id, qs_nb, NULL);
+    if (ret < 0)
+        rte_exit(EXIT_FAILURE,
+                "ERROR(%d): BBDEV %u not configured properly\n",
+                ret, dev_id);
+
+    /* Get information for this device */
+    rte_bbdev_info_get(dev_id, &info);
+
+    /* setup device queues */
+    qconf.socket = info.socket_id;
+    qconf.queue_size = info.drv.queue_size_lim;
+    qconf.op_type = RTE_BBDEV_OP_TURBO_ENC;
+
+    for (q_id = 0; q_id < qs_nb; q_id++) {
+        /* Configure all queues belonging to this bbdev device */
+        ret = rte_bbdev_queue_configure(dev_id, q_id, &qconf);
+        if (ret < 0)
+            rte_exit(EXIT_FAILURE,
+                    "ERROR(%d): BBDEV %u queue %u not configured properly\n",
+                    ret, dev_id, q_id);
+    }
+
+    /* Start bbdev device */
+    ret = rte_bbdev_start(dev_id);
+
+    /* Create the mbuf mempool for pkts */
+    mbuf_pool = rte_pktmbuf_pool_create("bbdev_mbuf_pool",
+            NB_MBUF, MEMPOOL_CACHE_SIZE, 0,
+            RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
+    if (mbuf_pool == NULL)
+        rte_exit(EXIT_FAILURE,
+                "Unable to create '%s' pool\n", pool_name);
+
+    while (!global_exit_flag) {
+
+        /* Allocate burst of op structures in preparation for enqueue */
+        if (rte_bbdev_op_alloc_bulk(bbdev_op_pool[RTE_BBDEV_OP_TURBO_ENC],
+            op_type, ops_burst, op_num) != 0)
+            continue;
+
+        /* Allocate input mbuf pkts */
+        ret = rte_pktmbuf_alloc_bulk(mbuf_pool, input_pkts_burst, MAX_PKT_BURST);
+        if (ret < 0)
+            continue;
+
+        /* Allocate output mbuf pkts */
+        ret = rte_pktmbuf_alloc_bulk(mbuf_pool, output_pkts_burst, MAX_PKT_BURST);
+        if (ret < 0)
+            continue;
+
+        switch (op_type) {
+        case RTE_BBDEV_OP_TURBO_ENC:
+            for (j = 0; j < op_num; j++) {
+                /* Append the size of the ethernet header */
+                rte_pktmbuf_append(input_pkts_burst[j],
+                        sizeof(struct ether_hdr));
+
+                /* set op */
+                ops_burst[j]->type = RTE_BBDEV_OP_TURBO_ENC;
+
+                ops_burst[j]->turbo_enc->input.offset =
+                    sizeof(struct ether_hdr);
+
+                ops_burst[j]->turbo_enc->input.length =
+                    rte_pktmbuf_pkt_len(bbdev_pkts[j]);
+
+                ops_burst[j]->turbo_enc->input.data =
+                    input_pkts_burst[j];
+
+                ops_burst[j]->turbo_enc->output.offset =
+                    sizeof(struct ether_hdr);
+
+                ops_burst[j]->turbo_enc->output.data =
+                        output_pkts_burst[j];
+            }
+            break;
+
+        case RTE_BBDEV_OP_TURBO_DEC:
+            break;
+
+        default:
+            break;
+        }
+
+        /* Enqueue packets on BBDEV device */
+        op_num = rte_bbdev_enqueue_ops(qconf->bbdev_id,
+                qconf->bbdev_qs[q], ops_burst,
+                MAX_PKT_BURST);
+
+        /* Dequeue packets from BBDEV device*/
+        op_num = rte_bbdev_dequeue_ops(qconf->bbdev_id,
+                qconf->bbdev_qs[q], ops_burst,
+                MAX_PKT_BURST);
+    }
+
+
+BBDEV Device API
+~~~~~~~~~~~~~~~~
+
+The bbdev Library API is described in the *DPDK API Reference* document.
diff --git a/doc/guides/prog_guide/img/bbdev_workflow.svg b/doc/guides/prog_guide/img/bbdev_workflow.svg
new file mode 100644
index 0000000..44a1fa6
--- /dev/null
+++ b/doc/guides/prog_guide/img/bbdev_workflow.svg
@@ -0,0 +1,440 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by Microsoft Visio, SVG Export bbdev_workflow.svg Page-1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+		xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="8.23078in" height="6.07112in"
+		viewBox="0 0 592.616 437.121" xml:space="preserve" color-interpolation-filters="sRGB" class="st18">
+	<v:documentProperties v:langID="1033" v:metric="true" v:viewMarkup="false"/>
+
+	<style type="text/css">
+	<![CDATA[
+		.st1 {marker-end:url(#mrkr4-6);stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}
+		.st2 {fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:0.44247787610619}
+		.st3 {visibility:visible}
+		.st4 {fill:#5b9bd5;fill-opacity:0.22;filter:url(#filter_2);stroke:#5b9bd5;stroke-opacity:0.22}
+		.st5 {fill:#9bc2e6;stroke:#c8c8c8;stroke-width:0.25}
+		.st6 {fill:#5b9bd5;stroke:#c8c8c8;stroke-width:0.25}
+		.st7 {fill:#2d71ae;stroke:#c8c8c8;stroke-width:0.25}
+		.st8 {fill:#feffff;font-family:Calibri;font-size:1.16666em}
+		.st9 {fill:#5b9bd5;fill-opacity:0.22;filter:url(#filter_2);stroke:none}
+		.st10 {fill:#ffffff;stroke:none;stroke-width:0.25}
+		.st11 {fill:#000000;font-family:Calibri;font-size:1.00001em}
+		.st12 {fill:#feffff;font-family:Calibri;font-size:1.00001em}
+		.st13 {marker-end:url(#mrkr4-90);stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}
+		.st14 {fill:none;stroke:none;stroke-width:0.25}
+		.st15 {fill:#000000;font-family:Consolas;font-size:0.75em}
+		.st16 {font-size:1em}
+		.st17 {fill:#feffff;font-family:Consolas;font-size:0.75em;font-weight:bold}
+		.st18 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+	]]>
+	</style>
+
+	<defs id="Markers">
+		<g id="lend4">
+			<path d="M 2 1 L 0 0 L 2 -1 L 2 1 " style="stroke:none"/>
+		</g>
+		<marker id="mrkr4-6" class="st2" v:arrowType="4" v:arrowSize="2" v:setback="4.34" refX="-4.34" orient="auto"
+				markerUnits="strokeWidth" overflow="visible">
+			<use xlink:href="#lend4" transform="scale(-2.26,-2.26) "/>
+		</marker>
+		<marker id="mrkr4-90" class="st2" v:arrowType="4" v:arrowSize="2" v:setback="4.52" refX="-4.52" orient="auto"
+				markerUnits="strokeWidth" overflow="visible">
+			<use xlink:href="#lend4" transform="scale(-2.26,-2.26) "/>
+		</marker>
+	</defs>
+	<defs id="Filters">
+		<filter id="filter_2">
+			<feGaussianBlur stdDeviation="2"/>
+		</filter>
+	</defs>
+	<g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+		<title>Page-1</title>
+		<v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394"
+				v:shadowOffsetY="-8.50394"/>
+		<v:layer v:name="Connector" v:index="0"/>
+		<v:layer v:name="Flowchart" v:index="1"/>
+		<g id="shape20-1" v:mID="20" v:groupContext="shape" v:layerMember="0"
+				transform="translate(-15.561,-361.299) rotate(-26.5651) scale(-1,1)">
+			<title>Line-curve connector</title>
+			<v:userDefs>
+				<v:ud v:nameU="Scale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<path d="M0 437.12 L15.98 442.17 L31.98 445 L48.02 445.59 L64.09 443.95 L80.2 440.08 L80.54 439.96" class="st1"/>
+		</g>
+		<g id="group1-7" transform="translate(151.579,-379.1)" v:mID="1" v:groupContext="group" v:layerMember="1">
+			<v:custProps>
+				<v:cp v:nameU="Cost" v:lbl="Cost" v:type="7" v:format="@" v:langID="1033"/>
+				<v:cp v:nameU="Duration" v:lbl="Duration" v:type="2" v:langID="1033"/>
+				<v:cp v:nameU="Resources" v:lbl="Resources" v:langID="1033"/>
+			</v:custProps>
+			<v:userDefs>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<title>Start state</title>
+			<g id="shape2-8" v:mID="2" v:groupContext="shape" v:layerMember="1">
+				<title>Sheet.2</title>
+				<g id="shadow2-9" v:groupContext="shadow" v:shadowOffsetX="0.345598" v:shadowOffsetY="-1.97279" v:shadowType="1"
+						transform="matrix(1,0,0,1,0.345598,1.97279)" class="st3">
+					<path d="M0 408.77 A28.3465 28.3465 0 0 1 56.69 408.77 A28.3465 28.3465 0 1 1 0 408.77 Z" class="st4"/>
+				</g>
+				<path d="M0 408.77 A28.3465 28.3465 0 0 1 56.69 408.77 A28.3465 28.3465 0 1 1 0 408.77 Z" class="st5"/>
+			</g>
+			<g id="shape3-13" v:mID="3" v:groupContext="shape" v:layerMember="1" transform="translate(5.66929,-5.66929)">
+				<title>Sheet.3</title>
+				<path d="M0 414.44 A22.6772 22.6772 0 0 1 45.35 414.44 A22.6772 22.6772 0 1 1 0 414.44 Z" class="st6"/>
+			</g>
+		</g>
+		<g id="group4-15" transform="translate(401.701,-329.149)" v:mID="4" v:groupContext="group" v:layerMember="1">
+			<v:custProps>
+				<v:cp v:nameU="Cost" v:lbl="Cost" v:type="7" v:format="@" v:langID="1033"/>
+				<v:cp v:nameU="Duration" v:lbl="Duration" v:type="2" v:langID="1033"/>
+				<v:cp v:nameU="Resources" v:lbl="Resources" v:langID="1033"/>
+			</v:custProps>
+			<v:userDefs>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<title>Stop state</title>
+			<g id="shape5-16" v:mID="5" v:groupContext="shape" v:layerMember="1">
+				<title>Sheet.5</title>
+				<g id="shadow5-17" v:groupContext="shadow" v:shadowOffsetX="0.345598" v:shadowOffsetY="-1.97279" v:shadowType="1"
+						transform="matrix(1,0,0,1,0.345598,1.97279)" class="st3">
+					<path d="M0 408.77 A28.3465 28.3465 0 0 1 56.69 408.77 A28.3465 28.3465 0 1 1 0 408.77 Z" class="st4"/>
+				</g>
+				<path d="M0 408.77 A28.3465 28.3465 0 0 1 56.69 408.77 A28.3465 28.3465 0 1 1 0 408.77 Z" class="st7"/>
+			</g>
+			<g id="shape6-21" v:mID="6" v:groupContext="shape" v:layerMember="1" transform="translate(5.66929,-5.66929)">
+				<title>Sheet.6</title>
+				<path d="M0 414.44 A22.6772 22.6772 0 0 1 45.35 414.44 A22.6772 22.6772 0 1 1 0 414.44 Z" class="st6"/>
+			</g>
+		</g>
+		<g id="group7-23" transform="translate(15.8562,-86.9787)" v:mID="7" v:groupContext="group" v:layerMember="1">
+			<v:custProps>
+				<v:cp v:nameU="Cost" v:lbl="Cost" v:type="7" v:format="@" v:langID="1033"/>
+				<v:cp v:nameU="Duration" v:lbl="Duration" v:type="2" v:langID="1033"/>
+				<v:cp v:nameU="Resources" v:lbl="Resources" v:langID="1033"/>
+			</v:custProps>
+			<v:userDefs>
+				<v:ud v:nameU="ControlY" v:val="VT0(0.53740157480315):24"/>
+				<v:ud v:nameU="ScaleFactor" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+				<v:ud v:nameU="ControlY" v:prompt="" v:val="VT0(2.5984251981273):1"/>
+			</v:userDefs>
+			<title>Entity 2</title>
+			<g id="shape8-24" v:mID="8" v:groupContext="shape" v:layerMember="1" transform="translate(0,-187.087)">
+				<title>Sheet.8</title>
+				<desc>Device Configuration</desc>
+				<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+				<v:textRect cx="150.285" cy="416.665" width="300.57" height="40.9108"/>
+				<g id="shadow8-25" v:groupContext="shadow" v:shadowOffsetX="0.345598" v:shadowOffsetY="-1.97279" v:shadowType="1"
+						transform="matrix(1,0,0,1,0.345598,1.97279)" class="st3">
+					<rect x="0" y="396.21" width="300.569" height="40.9108" class="st4"/>
+				</g>
+				<rect x="0" y="396.21" width="300.569" height="40.9108" class="st6"/>
+				<text x="90.77" y="420.87" class="st8" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>Device Configuration</text>			</g>
+			<g id="shape9-30" v:mID="9" v:groupContext="shape" v:layerMember="1">
+				<title>Sheet.9</title>
+				<g id="shadow9-31" v:groupContext="shadow" v:shadowOffsetX="0.345598" v:shadowOffsetY="-1.97279" v:shadowType="1"
+						transform="matrix(1,0,0,1,0.345598,1.97279)" class="st3">
+					<rect x="0" y="250.034" width="300.569" height="187.087" class="st4"/>
+				</g>
+				<rect x="0" y="250.034" width="300.569" height="187.087" class="st6"/>
+			</g>
+		</g>
+		<g id="shape10-35" v:mID="10" v:groupContext="shape" v:layerMember="1" transform="translate(37.0945,-201.59)">
+			<title>Entity 1</title>
+			<desc>Device identified</desc>
+			<v:custProps>
+				<v:cp v:nameU="Cost" v:lbl="Cost" v:type="7" v:format="@" v:langID="1033"/>
+				<v:cp v:nameU="Duration" v:lbl="Duration" v:type="2" v:langID="1033"/>
+				<v:cp v:nameU="Resources" v:lbl="Resources" v:langID="1033"/>
+			</v:custProps>
+			<v:userDefs>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<v:textBlock v:margins="rect(5.66929,5.66929,5.66929,5.66929)" v:tabSpace="42.5197"/>
+			<v:textRect cx="47.5394" cy="408.774" width="95.08" height="56.6929"/>
+			<g id="shadow10-36" v:groupContext="shadow" v:shadowOffsetX="0.345598" v:shadowOffsetY="-1.97279" v:shadowType="1"
+					transform="matrix(1,0,0,1,0.345598,1.97279)" class="st3">
+				<rect x="0" y="380.428" width="95.0787" height="56.6929" class="st9"/>
+			</g>
+			<rect x="0" y="380.428" width="95.0787" height="56.6929" class="st10"/>
+			<text x="6.5" y="412.37" class="st11" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>Device identified</text>		</g>
+		<g id="shape11-41" v:mID="11" v:groupContext="shape" v:layerMember="1" transform="translate(179.925,-157.762)">
+			<title>Entity 1.11</title>
+			<desc>Device configured</desc>
+			<v:custProps>
+				<v:cp v:nameU="Cost" v:lbl="Cost" v:type="7" v:format="@" v:langID="1033"/>
+				<v:cp v:nameU="Duration" v:lbl="Duration" v:type="2" v:langID="1033"/>
+				<v:cp v:nameU="Resources" v:lbl="Resources" v:langID="1033"/>
+			</v:custProps>
+			<v:userDefs>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<v:textBlock v:margins="rect(5.66929,5.66929,5.66929,5.66929)" v:tabSpace="42.5197"/>
+			<v:textRect cx="51.0236" cy="408.774" width="102.05" height="56.6929"/>
+			<g id="shadow11-42" v:groupContext="shadow" v:shadowOffsetX="0.345598" v:shadowOffsetY="-1.97279" v:shadowType="1"
+					transform="matrix(1,0,0,1,0.345598,1.97279)" class="st3">
+				<rect x="0" y="380.428" width="102.047" height="56.6929" class="st9"/>
+			</g>
+			<rect x="0" y="380.428" width="102.047" height="56.6929" class="st10"/>
+			<text x="7.11" y="412.37" class="st11" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>Device configured</text>		</g>
+		<g id="shape12-47" v:mID="12" v:groupContext="shape" v:layerMember="1" transform="translate(41.6772,-103.431)">
+			<title>Entity 1.12</title>
+			<desc>Queues configured</desc>
+			<v:custProps>
+				<v:cp v:nameU="Cost" v:lbl="Cost" v:type="7" v:format="@" v:langID="1033"/>
+				<v:cp v:nameU="Duration" v:lbl="Duration" v:type="2" v:langID="1033"/>
+				<v:cp v:nameU="Resources" v:lbl="Resources" v:langID="1033"/>
+			</v:custProps>
+			<v:userDefs>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<v:textBlock v:margins="rect(5.66929,5.66929,5.66929,5.66929)" v:tabSpace="42.5197"/>
+			<v:textRect cx="54.9508" cy="408.774" width="109.91" height="56.6929"/>
+			<g id="shadow12-48" v:groupContext="shadow" v:shadowOffsetX="0.345598" v:shadowOffsetY="-1.97279" v:shadowType="1"
+					transform="matrix(1,0,0,1,0.345598,1.97279)" class="st3">
+				<rect x="0" y="380.428" width="109.902" height="56.6929" class="st9"/>
+			</g>
+			<rect x="0" y="380.428" width="109.902" height="56.6929" class="st10"/>
+			<text x="8.67" y="412.37" class="st11" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>Queues configured</text>		</g>
+		<g id="shape14-53" v:mID="14" v:groupContext="shape" v:layerMember="1" transform="translate(382.508,-187.417)">
+			<title>Entity 1.14</title>
+			<desc>Device stopped</desc>
+			<v:custProps>
+				<v:cp v:nameU="Cost" v:lbl="Cost" v:type="7" v:format="@" v:langID="1033"/>
+				<v:cp v:nameU="Duration" v:lbl="Duration" v:type="2" v:langID="1033"/>
+				<v:cp v:nameU="Resources" v:lbl="Resources" v:langID="1033"/>
+			</v:custProps>
+			<v:userDefs>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<v:textBlock v:margins="rect(5.66929,5.66929,5.66929,5.66929)" v:tabSpace="42.5197"/>
+			<v:textRect cx="47.5394" cy="408.774" width="95.08" height="56.6929"/>
+			<g id="shadow14-54" v:groupContext="shadow" v:shadowOffsetX="0.345598" v:shadowOffsetY="-1.97279" v:shadowType="1"
+					transform="matrix(1,0,0,1,0.345598,1.97279)" class="st3">
+				<rect x="0" y="380.428" width="95.0787" height="56.6929" class="st4"/>
+			</g>
+			<rect x="0" y="380.428" width="95.0787" height="56.6929" class="st6"/>
+			<text x="9.93" y="412.37" class="st12" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>Device stopped</text>		</g>
+		<g id="shape15-59" v:mID="15" v:groupContext="shape" v:layerMember="1" transform="translate(382.508,-45.6848)">
+			<title>Entity 1.15</title>
+			<desc>Device running</desc>
+			<v:custProps>
+				<v:cp v:nameU="Cost" v:lbl="Cost" v:type="7" v:format="@" v:langID="1033"/>
+				<v:cp v:nameU="Duration" v:lbl="Duration" v:type="2" v:langID="1033"/>
+				<v:cp v:nameU="Resources" v:lbl="Resources" v:langID="1033"/>
+			</v:custProps>
+			<v:userDefs>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<v:textBlock v:margins="rect(5.66929,5.66929,5.66929,5.66929)" v:tabSpace="42.5197"/>
+			<v:textRect cx="47.5394" cy="408.774" width="95.08" height="56.6929"/>
+			<g id="shadow15-60" v:groupContext="shadow" v:shadowOffsetX="0.345598" v:shadowOffsetY="-1.97279" v:shadowType="1"
+					transform="matrix(1,0,0,1,0.345598,1.97279)" class="st3">
+				<rect x="0" y="380.428" width="95.0787" height="56.6929" class="st4"/>
+			</g>
+			<rect x="0" y="380.428" width="95.0787" height="56.6929" class="st6"/>
+			<text x="10.99" y="412.37" class="st12" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>Device running</text>		</g>
+		<g id="shape34-65" v:mID="34" v:groupContext="shape" v:layerMember="0"
+				transform="translate(199.861,-224.664) rotate(8.90802)">
+			<title>Line-curve connector.34</title>
+			<v:userDefs>
+				<v:ud v:nameU="Scale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<path d="M0 437.12 L17.46 430.61 L34.07 426.41 L49.84 424.52 L64.76 424.95 L78.84 427.69 L92.07 432.74 L92.39 432.92"
+					class="st1"/>
+		</g>
+		<g id="shape35-70" v:mID="35" v:groupContext="shape" v:layerMember="0"
+				transform="translate(94.9467,-136.066) rotate(-18.1275) scale(-1,1)">
+			<title>Line-curve connector.35</title>
+			<v:userDefs>
+				<v:ud v:nameU="Scale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<path d="M0 437.12 L11.56 444.96 L23.54 449.98 L35.96 452.17 L48.8 451.54 L62.07 448.08 L75.78 441.79 L76.09 441.61"
+					class="st1"/>
+		</g>
+		<g id="shape36-75" v:mID="36" v:groupContext="shape" v:layerMember="0"
+				transform="translate(141.346,-101.138) rotate(5.87165)">
+			<title>Line-curve connector.36</title>
+			<v:userDefs>
+				<v:ud v:nameU="Scale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<path d="M0 437.12 L21.68 451.72 L45.69 462.76 L72.02 470.24 L100.69 474.16 L131.68 474.53 L165.01 471.32 L200.66 464.56
+						 L238.64 454.24 L278.95 440.36 L279.28 440.23" class="st1"/>
+		</g>
+		<g id="shape37-80" v:mID="37" v:groupContext="shape" v:layerMember="0"
+				transform="translate(-54.6126,221.357) rotate(-90) scale(-1,1)">
+			<title>Line-curve connector.37</title>
+			<v:userDefs>
+				<v:ud v:nameU="Scale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<path d="M0 437.12 L19.19 424.76 L38.39 416.27 L57.58 411.65 L76.77 410.91 L95.96 414.03 L115.16 421.03 L134.35 431.91
+						 L134.64 432.11" class="st1"/>
+		</g>
+		<g id="shape38-85" v:mID="38" v:groupContext="shape" v:layerMember="0" transform="translate(-7.07327,334.743) rotate(-90)">
+			<title>Directed line 1</title>
+			<v:userDefs>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<path d="M0 437.12 L76 437.12" class="st13"/>
+		</g>
+		<g id="shape41-91" v:mID="41" v:groupContext="shape" v:layerMember="0" transform="translate(758.012,56.3606) rotate(45)">
+			<title>Loop on center</title>
+			<v:userDefs>
+				<v:ud v:nameU="ScaleFactor" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<path d="M22.5 419.89 A22.9262 22.9262 0 1 1 30.34 458.86 L30.03 458.68" class="st1"/>
+		</g>
+		<g id="shape42-96" v:mID="42" v:groupContext="shape" v:layerMember="0"
+				transform="translate(91.9936,116.697) rotate(-55.69)">
+			<title>Loop on center.42</title>
+			<v:userDefs>
+				<v:ud v:nameU="ScaleFactor" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<path d="M23.68 421.54 A23.5418 23.5418 0 1 1 30.85 458.2 L30.57 457.98" class="st1"/>
+		</g>
+		<g id="shape43-101" v:mID="43" v:groupContext="shape" v:layerMember="0"
+				transform="translate(378.733,-215.747) rotate(-0.494766) scale(-1,1)">
+			<title>Line-curve connector.43</title>
+			<v:userDefs>
+				<v:ud v:nameU="Scale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<path d="M0 437.12 L25.31 429.84 L50.04 425.26 L74.18 423.39 L97.73 424.22 L120.7 427.75 L143.08 433.99 L143.42 434.12"
+					class="st1"/>
+		</g>
+		<g id="shape44-106" v:mID="44" v:groupContext="shape" v:layerMember="0" transform="translate(-7.07327,193.011) rotate(-90)">
+			<title>Directed line 1.44</title>
+			<v:userDefs>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<path d="M0 437.12 L76 437.12" class="st13"/>
+		</g>
+		<g id="shape45-111" v:mID="45" v:groupContext="shape" transform="translate(98.3701,-345.449)">
+			<title>Sheet.45</title>
+			<desc>rte_eal_init() rte_bbdev_count()</desc>
+			<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+			<v:textRect cx="54.9508" cy="425.073" width="109.91" height="24.0945"/>
+			<rect x="0" y="413.026" width="109.902" height="24.0945" class="st14"/>
+			<text x="20.31" y="422.37" class="st15" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>rte_eal_init()<v:newlineChar/><tspan
+						x="12.89" dy="1.2em" class="st16">rte</tspan>_bbdev_count()</text>		</g>
+		<g id="shape48-115" v:mID="48" v:groupContext="shape" transform="translate(135.988,-243.26)">
+			<title>Sheet.48</title>
+			<desc>rte_bbdev_configure()</desc>
+			<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+			<v:textRect cx="59.2028" cy="429.609" width="118.41" height="15.0236"/>
+			<rect x="0" y="422.097" width="118.406" height="15.0236" class="st14"/>
+			<text x="7.25" y="432.31" class="st17" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>rte_bbdev_configure()</text>		</g>
+		<g id="shape49-118" v:mID="49" v:groupContext="shape" transform="translate(165.752,-113.636)">
+			<title>Sheet.49</title>
+			<desc>rte_bbdev_queue_configure()</desc>
+			<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+			<v:textRect cx="70.5118" cy="429.609" width="141.03" height="15.0236"/>
+			<rect x="0" y="422.097" width="141.024" height="15.0236" class="st14"/>
+			<text x="3.71" y="432.31" class="st17" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>rte_bbdev_queue_configure()</text>		</g>
+		<g id="shape50-121" v:mID="50" v:groupContext="shape" transform="translate(316.638,-121.148)">
+			<title>Sheet.50</title>
+			<desc>rte_bbdev_start()</desc>
+			<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+			<v:textRect cx="47.5394" cy="429.609" width="95.08" height="15.0236"/>
+			<rect x="0" y="422.097" width="95.0787" height="15.0236" class="st10"/>
+			<text x="5.48" y="432.31" class="st15" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>rte_bbdev_start()</text>		</g>
+		<g id="shape51-124" v:mID="51" v:groupContext="shape" transform="translate(382.508,-145.656)">
+			<title>Sheet.51</title>
+			<desc>rte_bbdev_stop()</desc>
+			<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+			<v:textRect cx="47.5394" cy="429.609" width="95.08" height="15.0236"/>
+			<rect x="0" y="422.097" width="95.0787" height="15.0236" class="st10"/>
+			<text x="7.95" y="432.31" class="st15" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>rte_bbdev_stop()</text>		</g>
+		<g id="shape52-127" v:mID="52" v:groupContext="shape" transform="translate(463.39,-106.124)">
+			<title>Sheet.52</title>
+			<desc>rte_bbdev_enqueue_ops()</desc>
+			<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+			<v:textRect cx="64.4882" cy="429.609" width="128.98" height="15.0236"/>
+			<rect x="0" y="422.097" width="128.976" height="15.0236" class="st10"/>
+			<text x="7.58" y="432.31" class="st15" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>rte_bbdev_enqueue_ops()</text>		</g>
+		<g id="shape54-130" v:mID="54" v:groupContext="shape" transform="translate(414.965,-0.25)">
+			<title>Sheet.54</title>
+			<desc>rte_bbdev_dequeue_ops()</desc>
+			<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+			<v:textRect cx="64.4882" cy="429.609" width="128.98" height="15.0236"/>
+			<rect x="0" y="422.097" width="128.976" height="15.0236" class="st10"/>
+			<text x="7.58" y="432.31" class="st15" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>rte_bbdev_dequeue_ops()</text>		</g>
+		<g id="shape55-133" v:mID="55" v:groupContext="shape" transform="translate(365.559,-277.053)">
+			<title>Sheet.55</title>
+			<desc>rte_bbdev_close()</desc>
+			<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+			<v:textRect cx="64.4882" cy="429.609" width="128.98" height="15.0236"/>
+			<rect x="0" y="422.097" width="128.976" height="15.0236" class="st10"/>
+			<text x="22.43" y="432.31" class="st15" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>rte_bbdev_close()</text>		</g>
+		<g id="shape56-136" v:mID="56" v:groupContext="shape" transform="translate(259.945,-233.683)">
+			<title>Sheet.56</title>
+			<desc>rte_bbdev_configure()</desc>
+			<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+			<v:textRect cx="59.2028" cy="429.609" width="118.41" height="15.0236"/>
+			<rect x="0" y="422.097" width="118.406" height="15.0236" class="st14"/>
+			<text x="7.25" y="432.31" class="st15" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>rte_bbdev_configure()</text>		</g>
+		<g id="shape57-139" v:mID="57" v:groupContext="shape" transform="translate(203.252,-35.2579)">
+			<title>Sheet.57</title>
+			<desc>rte_bbdev_start()</desc>
+			<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+			<v:textRect cx="47.5394" cy="429.609" width="95.08" height="15.0236"/>
+			<rect x="0" y="422.097" width="95.0787" height="15.0236" class="st10"/>
+			<text x="5.48" y="432.31" class="st15" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>rte_bbdev_start()</text>		</g>
+		<g id="shape59-142" v:mID="59" v:groupContext="shape" v:layerMember="1" transform="translate(5.47638,-339.415)">
+			<title>Entity 1.59</title>
+			<desc>Device stopped</desc>
+			<v:custProps>
+				<v:cp v:nameU="Cost" v:lbl="Cost" v:type="7" v:format="@" v:langID="1033"/>
+				<v:cp v:nameU="Duration" v:lbl="Duration" v:type="2" v:langID="1033"/>
+				<v:cp v:nameU="Resources" v:lbl="Resources" v:langID="1033"/>
+			</v:custProps>
+			<v:userDefs>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<v:textBlock v:margins="rect(5.66929,5.66929,5.66929,5.66929)" v:tabSpace="42.5197"/>
+			<v:textRect cx="47.5394" cy="408.774" width="95.08" height="56.6929"/>
+			<g id="shadow59-143" v:groupContext="shadow" v:shadowOffsetX="0.345598" v:shadowOffsetY="-1.97279" v:shadowType="1"
+					transform="matrix(1,0,0,1,0.345598,1.97279)" class="st3">
+				<rect x="0" y="380.428" width="95.0787" height="56.6929" class="st4"/>
+			</g>
+			<rect x="0" y="380.428" width="95.0787" height="56.6929" class="st6"/>
+			<text x="9.93" y="412.37" class="st12" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>Device stopped</text>		</g>
+		<g id="shape60-148" v:mID="60" v:groupContext="shape" v:layerMember="0"
+				transform="translate(460.301,-61.0184) rotate(68.7086)">
+			<title>Line-curve connector.60</title>
+			<v:userDefs>
+				<v:ud v:nameU="Scale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="AntiScale" v:val="VT0(1):26"/>
+				<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
+			</v:userDefs>
+			<path d="M0 437.12 L16.55 442.51 L32.69 445.54 L48.43 446.22 L63.76 444.54 L78.69 440.5 L79.03 440.37" class="st1"/>
+		</g>
+		<g id="shape47-153" v:mID="47" v:groupContext="shape" transform="translate(0.25,-314.896)">
+			<title>Sheet.47</title>
+			<desc>rte_bbdev_info_get()</desc>
+			<v:textBlock v:margins="rect(1,1,1,1)" v:tabSpace="42.5197"/>
+			<v:textRect cx="54.9508" cy="429.609" width="109.91" height="15.0236"/>
+			<rect x="0" y="422.097" width="109.902" height="15.0236" class="st10"/>
+			<text x="5.47" y="432.31" class="st15" v:langID="6153"><v:paragraph v:horizAlign="1"/><v:tabList/>rte_bbdev_info_get()</text>		</g>
+	</g>
+</svg>
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 40f04a1..a0f8618 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -61,6 +61,7 @@ Programmer's Guide
     kernel_nic_interface
     thread_safety_dpdk_functions
     eventdev
+    bbdev
     qos_framework
     power_man
     packet_classif_access_ctrl
diff --git a/doc/guides/sample_app_ug/bbdev_app.rst b/doc/guides/sample_app_ug/bbdev_app.rst
new file mode 100644
index 0000000..71a3853
--- /dev/null
+++ b/doc/guides/sample_app_ug/bbdev_app.rst
@@ -0,0 +1,187 @@
+..  BSD LICENSE
+    Copyright(c) 2017 Intel Corporation. All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+    * Neither the name of Intel Corporation nor the names of its
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+.. bbdev_app:
+
+Loop-back Sample Application using Baseband Device (bbdev)
+==========================================================
+
+The baseband sample application is a simple example of packet processing using
+the Data Plane Development Kit (DPDK) for baseband workloads using the BBdev library.
+
+Overview
+--------
+
+The Baseband device sample application performs a loop-back operation using a baseband device
+capable of transceiving data packets.
+A packet is received on a DOWNLINK_RX_PORT or UPLINK_RX_PORTS -> enqueued for
+baseband operation -> dequeued from the baseband device then looped back to
+DOWNLINK_TX_PORTS or UPLINK_TX_PORTS, respectively.
+
+*   The source MAC address is replaced by the TX_PORT MAC address
+
+*   The destination MAC address is replaced by  02:00:00:00:00:TX_PORT_ID
+
+Compiling the Application
+-------------------------
+
+#.  Go to the example directory:
+
+    .. code-block:: console
+
+        export RTE_SDK=/path/to/rte_sdk
+        cd ${RTE_SDK}/examples/bbdev_app
+
+#.  Set the target (a default target is used if not specified). For example:
+
+    .. code-block:: console
+
+        export RTE_TARGET=x86_64-native-linuxapp-gcc
+
+    See the *DPDK Getting Started Guide* for possible RTE_TARGET values.
+
+#.  Build the application:
+
+    .. code-block:: console
+
+        make
+
+Running the Application
+-----------------------
+
+The application requires a number of command line options:
+
+.. code-block:: console
+
+    $ ./build/bbdev [EAL options] -- [-r DOWNLINK_RX_PORTS] [-R UPLINK_RX_PORTS] /
+	[-t DOWNLINK_TX_PORTS ] [-T UPLINK_TX_PORTS] /
+	[-c DOWNLINK_CORES] [-C UPLINK_CORES]
+
+where:
+
+* ``r DOWNLINK_RX_PORTS``: decimal amount of downlink receiver ports
+* ``R UPLINK_RX_PORTS``: decimal amount of uplink receiver ports
+* ``t DOWNLINK_TX_PORTS``: decimal amount of downlink transceiver ports
+* ``T UPLINK_TX_PORTS``: decimal amount of uplink transceiver ports
+* ``c DOWNLINK_CORES``: hexmask for downlink cores amount
+* ``C UPLINK_CORES``: hexmask for uplink cores amount
+
+The application requires that baseband devices capable of performing
+the specified baseband operation are available on application initialization.
+This means that HW baseband device/s must be bound to a DPDK driver or
+a SW baseband device/s (virtual BBdev) must be created (using --vdev).
+
+To run the application in linuxapp environment with one baseband device per download and upload,
+handled by 1 port and 2 logical cores, issue the command:
+
+.. code-block:: console
+
+    $ ./build/bbdev --vdev='turbo_sw0' --vdev='turbo_sw1' \
+	-w <NIC0PCIADDR> -w <NIC1PCIADDR> -c 0xf8 --socket-mem=2,2 \
+	--file-prefix=bbdev -- -r 1 -R 2 -t 1 -T 2 -c 0x30 -C 0xc0
+
+where, NIC0PCIADDR and NIC1PCIADDR are PCI addresses
+
+This command creates two virtual bbdev devices (turbo_sw0 and turbo_sw1) where
+each device is linked to a corresponding ethernet port as whitelisted by the
+argument -w. 5 cores are allocated to the application, and assigned as:
+
+ - core 3 is the master and used to print the stats live on screen,
+
+ - cores 4 & 5 are the downlink cores, Tx & Rx
+
+ - cores 6 & 7 are the uplink cores, Tx & Rx
+
+Refer to the *DPDK Getting Started Guide* for general information on running applications
+and the Environment Abstraction Layer (EAL) options.
+
+Explanation
+-----------
+
+The Baseband device sample application demonstrates the performance of a baseband operation
+on a data packet being sent and received.
+Devices are discovered by the DPDK EAL during its initialization phase, and once it is present
+in the application context, device type and its capabilities can be queried by calling rte_bbdev_info_get(dev_id, &info) function.
+There are two levels to baseband device configuration - one that applies to the whole device, and one that applies to a single queue.
+To apply device configuration rte_bbdev_configure()
+must be called (for example configuring how many queues on a device will be used)
+Where to configure queues on device rte_bbdev_queue_configure() applies.
+From the application point of view, each instance of a baseband device consists of one or more queues,
+identified by queue IDs.
+Even though different devices might possess different capabilities,
+all queues on given device support identical configuration possibilities.
+A queue can be configured for only one type of operation which is done at initializations time.
+After the initialization, devices are left in a stopped state, until started by the application.
+By default, all queues are started with the device, however they might be stopped individually.
+When application ceases to use a device it can be closed by calling rte_bbdev_close(dev_id), however it cannot be restarted.
+
+
+Baseband operation specification
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Operations are enqueued to and later dequeued from the device. To maintain their order two functions are used:
+
+- ``rte_bbdev_enqueue_ops(dev_id, queue_id, ops, num_ops)``
+- ``rte_bbdev_dequeue_ops(dev_id, queue_id, ops, num_ops)``
+
+Note that queues are not thread-safe and multiple queues or application-level locking
+is a requirement for multi-threaded applications aiming to share a device.
+It is however possible to use one thread to enqueue to a queue ID and another thread to dequeue from the same queue ID.
+To determine number of queues supported by the device a function can be called:
+
+- ``rte_bbdev_info_get()``
+
+However it is possible to specify number of supported queues when creating a software device.
+
+Using Packet Generator with baseband device sample application
+--------------------------------------------------------------
+
+To allow the bbdev sample app to do the loopback, an influx of traffic is required.
+This can be done by using DPDK Pktgen to burst traffic on two ethernet ports, and
+it will print the transmitted along with the looped-back traffic on Rx ports.
+Executing the command below will generate traffic on the two whitelisted ethernet
+ports.
+
+.. code-block:: console
+
+    $ ./pktgen-3.4.0/app/x86_64-native-linuxapp-gcc/pktgen -c 0x7 \
+	--socket-mem=1,1 --file-prefix=pg -w <NIC2PCIADDR> -w <NIC3PCIADDR> -- \
+	-m "1.0, 2.1" -P
+
+where:
+
+* ``-c COREMASK``: A hexadecimal bitmask of cores to run on
+* ``--socket-mem``: Memory to allocate on specific sockets (use comma separated values)
+* ``--file-prefix``: Prefix for hugepage filenames
+* ``-w PCI WHITELIST``: Add a PCI device in white list. The argument format is <[domain:]bus:devid.func>.
+* ``-m <string>``: Matrix for mapping ports to logical cores.
+* ``-P``: PROMISCUOUS mode
+
+
+Refer to *The Pktgen Application* documents for general information on running Pktgen with DPDK applications.
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 069d4f1..cc568a9 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -77,6 +77,7 @@ Sample Applications User Guides
     ptpclient
     performance_thread
     ipsec_secgw
+    bbdev_app
 
 **Figures**
 
diff --git a/doc/guides/tools/index.rst b/doc/guides/tools/index.rst
index c9133ec..a390fe7 100644
--- a/doc/guides/tools/index.rst
+++ b/doc/guides/tools/index.rst
@@ -41,3 +41,4 @@ DPDK Tools User Guides
     devbind
     cryptoperf
     testeventdev
+    testbbdev
diff --git a/doc/guides/tools/testbbdev.rst b/doc/guides/tools/testbbdev.rst
new file mode 100644
index 0000000..682176d
--- /dev/null
+++ b/doc/guides/tools/testbbdev.rst
@@ -0,0 +1,546 @@
+..
+   BSD LICENSE
+
+   Copyright(c) 2017 Intel Corporation. All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+     * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in
+       the documentation and/or other materials provided with the
+       distribution.
+     * Neither the name of Intel Corporation nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+dpdk-test-bbdev Application
+==============================
+
+The ``dpdk-test-bbdev`` tool is a Data Plane Development Kit (DPDK) utility that
+allows measuring performance parameters of PMDs available in the bbdev framework.
+Available tests available for execution are: latency, throughput, validation and
+sanity tests. Execution of tests can be customized using various parameters
+passed to a python running script.
+
+Compiling the Application
+-------------------------
+
+**Step 1: PMD setting**
+
+The ``dpdk-test-bbdev`` tool depends on crypto device drivers PMD which
+are disabled by default in the build configuration file ``common_base``.
+The bbdevice drivers PMD which should be tested can be enabled by setting
+
+   ``CONFIG_RTE_LIBRTE_PMD_<name>=y``
+
+Setting example for (*turbo_sw*) PMD
+
+   ``CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW=y``
+
+**Step 2: Build the application**
+
+Execute the ``dpdk-setup.sh`` script to build the DPDK library together with the
+``dpdk-test-bbdev`` application.
+
+Initially, the user must select a DPDK target to choose the correct target type
+and compiler options to use when building the libraries.
+The user must have all libraries, modules, updates and compilers installed
+in the system prior to this, as described in the earlier chapters in this
+Getting Started Guide.
+
+Running the Application
+-----------------------
+
+The tool application has a number of command line options:
+
+.. code-block:: console
+
+  python test-bbdev.py [-h] [-p TESTAPP_PATH] [-e EAL_PARAMS] [-t TIMEOUT]
+                       [-c TEST_CASE [TEST_CASE ...]]
+                       [-v TEST_VECTOR [TEST_VECTOR...]] [-n NUM_OPS]
+                       [-b BURST_SIZE [BURST_SIZE ...]]
+
+command-line Options
+~~~~~~~~~~~~~~~~~~~~
+
+The following are the command-line options:
+
+``-h, --help``
+ Shows help message and exit.
+
+``-p TESTAPP_PATH, --testapp_path TESTAPP_PATH``
+ Indicates the path to the bbdev test app. If not specified path is set based
+ on *$RTE_SDK* environment variable concatenated with "*/build/app/testbbdev*".
+
+``-e EAL_PARAMS, --eal_params EAL_PARAMS``
+ Specifies EAL arguments which are passed to the test app. For more details,
+ refer to DPDK documentation at http://dpdk.org/doc.
+
+``-t TIMEOUT, --timeout TIMEOUT``
+ Specifies timeout in seconds. If not specified timeout is set to 300 seconds.
+
+``-c TEST_CASE [TEST_CASE ...], --test_cases TEST_CASE [TEST_CASE ...]``
+ Defines test cases to run. If not specified all available tests are run.
+
+ The following tests can be run:
+  * unittest
+     Small unit tests witch check basic functionality of bbdev library.
+  * latency
+     Test calculates three latency metrics:
+      * offload_latency_tc
+         measures the cost of offloading enqueue and dequeue operations.
+      * offload_latency_empty_q_tc
+         measures the cost of offloading a dequeue operation from an empty queue.
+         checks how long last dequeueing if there is no operations to dequeue
+      * operation_latency_tc
+         measures the time difference from the first attempt to enqueue till the
+         first successful dequeue.
+  * validation
+     Test do enqueue on given vector and compare output after dequeueing.
+  * throughput
+     Test measures the achieved throughput on the available lcores.
+     Results are printed in million operations per second and million bits per second.
+  * interrupt
+     The same test as 'throughput' but uses interrupts instead of PMD to perform
+     the dequeue.
+
+ **Example usage:**
+
+ ``./test-bbdev.py -c validation``
+  Runs validation test suite
+
+ ``./test-bbdev.py -c latency throughput``
+  Runs latency and throughput test suites
+
+``-v TEST_VECTOR [TEST_VECTOR ...], --test_vector TEST_VECTOR [TEST_VECTOR ...]``
+ Specifies paths to the test vector files. If not specified path is set based
+ on *$RTE_SDK* environment variable concatenated with
+ "*/app/test-bbdev/test_vectors/bbdev_vector_null.data*" and indicates default
+ data file.
+
+ **Example usage:**
+
+ ``./test-bbdev.py -v app/test-bbdev/test_vectors/bbdev_vector_td_test1.data``
+  Fills vector based on bbdev_vector_td_test1.data file and runs all tests
+
+ ``./test-bbdev.py -v bbdev_vector_td_test1.data bbdev_vector_te_test2.data``
+  The bbdev test app is executed twice. First time vector is filled based on
+  *bbdev_vector_td_test1.data* file and second time based on
+  *bbdev_vector_te_test2.data* file. For both executions all tests are run.
+
+``-n NUM_OPS, --num_ops NUM_OPS``
+ Specifies number of operations to process on device. If not specified num_ops
+ is set to 32 operations.
+
+``-v BURST_SIZE [BURST_SIZE ...], --burst-size BURST_SIZE [BURST_SIZE ...]``
+ Specifies operations enqueue/dequeue burst size. If not specified burst_size is
+ set to 32.
+
+
+Parameter globbing
+~~~~~~~~~~~~~~~~~~
+
+Thanks to the globbing functionality in python test-bbdev.py script allows to
+run tests with different set of vector files without giving all of them explicitly.
+
+**Example usage:**
+
+.. code-block:: console
+
+  ./test-bbdev.py -v app/test-bbdev/test_vectors/bbdev_vector_*.data
+
+It runs all tests with following vectors:
+
+- ``bbdev_vector_null.data``
+
+- ``bbdev_vector_te_default.data``
+
+- ``bbdev_vector_td_default.data``
+
+
+.. code-block:: console
+
+  ./test-bbdev.py -v app/test-bbdev/test_vectors/bbdev_vector_t?_default.data
+
+It runs all tests with "default" vectors:
+
+- ``bbdev_vector_te_default.data``
+
+- ``bbdev_vector_td_default.data``
+
+
+Running Tests
+-------------
+
+Shortened tree of isg_cid-wireless_dpdk_ae with dpdk compiled for
+x86_64-native-linuxapp-icc target:
+
+::
+
+ |-- app
+     |-- test-bbdev
+         |-- test_vectors
+             |-- bbdev_vector_null.data
+             |-- bbdev_vector_te_default.data
+             |-- bbdev_vector_td_default.data
+
+ |-- x86_64-native-linuxapp-icc
+     |-- app
+         |-- testbbdev
+
+All bbdev devices
+~~~~~~~~~~~~~~~~~
+
+.. code-block:: console
+
+  ./test-bbdev.py -p ../../x86_64-native-linuxapp-icc/app/testbbdev
+  -v ./test_vectors/bbdev_vector_td_default.data
+
+It runs all available tests using the test vector filled based on
+*bbdev_vector_td_default.data* file.
+By default number of operations to process on device is set to 32, timeout is
+set to 300s and operations enqueue/dequeue burst size is set to 32.
+Moreover a bbdev (*bbdev_null*) device will be created.
+
+bbdev turbo_sw device
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: console
+
+  ./test-bbdev.py -p ../../x86_64-native-linuxapp-icc/app/testbbdev
+  -e="--vdev=turbo_sw" -t 120 -c validation
+  -v ./test_vectors/bdev_vector_te_bypass*.data -n 64 -b 8 32
+
+It runs **validation** test for each vector file that matches the given pattern.
+Number of operations to process on device is set to 64 and operations timeout is
+set to 120s and enqueue/dequeue burst size is set to 8 and to 32.
+Moreover a bbdev (*turbo_sw*) device will be created.
+
+
+bbdev null device
+~~~~~~~~~~~~~~~~~
+
+Executing bbdev null device with *bbdev_vector_null.data* helps in measuring the
+overhead introduced by the bbdev framework.
+
+.. code-block:: console
+
+  ./test-bbdev.py -e="--vdev=bbdev_null0"
+  -v ./test_vectors/bbdev_vector_null.data
+
+**Note:**
+
+bbdev_null device does not have to be defined explicitly as it is created by default.
+
+
+
+Test Vector files
+=================
+
+Test Vector files contain the data which is used to set turbo decoder/encoder
+parameters and buffers for validation purpose. New test vector files should be
+stored in ``app/test-bbdev/test_vectors/`` directory. Detailed description of
+the systax of the test vector files is in the following section.
+
+
+Basic principles for test vector files
+--------------------------------------
+Line started with ``#`` is treated as a comment and is ignored.
+
+If variable is a chain of values, values should be separated by a comma. If
+assignment is split into several lines, each line (except the last one) has to
+be ended with a comma.
+There is no comma after last value in last line. Correct assignment should
+look like the following:
+
+.. parsed-literal::
+
+ variable =
+ value, value, value, value,
+ value, value
+
+In case where variable is a single value correct assignment looks like the
+following:
+
+.. parsed-literal::
+
+ variable =
+ value
+
+Length of chain variable is calculated by parser. Can not be defined
+explicitly.
+
+Variable op_type has to be defined as a first variable in file. It specifies
+what type of operations will be executed. For decoder op_type has to be set to
+``RTE_BBDEV_OP_TURBO_DEC`` and for encoder to ``RTE_BBDEV_OP_TURBO_ENC``.
+
+Full details of the meaning and valid values for the below fields are
+documented in *rte_bbdev_op.h*
+
+
+Turbo decoder test vectors template
+-----------------------------------
+
+For turbo decoder it has to be always set to ``RTE_BBDEV_OP_TURBO_DEC``
+
+.. parsed-literal::
+
+    op_type =
+    RTE_BBDEV_OP_TURBO_DEC
+
+Chain of uint32_t values. Note that it is possible to define more than one
+input/output entries which will result in chaining two or more data structures
+for *segmented Transport Blocks*
+
+.. parsed-literal::
+
+    input0 =
+    0x00000000, 0x7f817f00, 0x7f7f8100, 0x817f8100, 0x81008100, 0x7f818100, 0x81817f00, 0x7f818100,
+    0x81007f00, 0x7f818100, 0x817f8100, 0x81817f00, 0x81008100, 0x817f7f00, 0x7f7f8100, 0x81817f00
+
+Chain of uint32_t values
+
+.. parsed-literal::
+
+    input1 =
+    0x7f7f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
+
+Chain of uint32_t values
+
+.. parsed-literal::
+
+    input2 =
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
+
+Chain of uint32_t values
+
+.. parsed-literal::
+
+    hard_output0 =
+    0xa7d6732e
+
+Chain of uint32_t values
+
+.. parsed-literal::
+
+    hard_output1 =
+    0xa61
+
+Chain of uint32_t values
+
+.. parsed-literal::
+
+    soft_output0 =
+    0x817f817f, 0x7f817f7f, 0x81818181, 0x817f7f81, 0x7f818181, 0x8181817f, 0x817f817f, 0x8181817f
+
+Chain of uint32_t values
+
+.. parsed-literal::
+
+    soft_output1 =
+    0x817f7f81, 0x7f7f7f81, 0x7f7f8181
+
+uint32_t value
+
+.. parsed-literal::
+
+    e =
+    44
+
+uint16_t value
+
+.. parsed-literal::
+
+    k =
+    40
+
+uint8_t value
+
+.. parsed-literal::
+
+    rv_index =
+    0
+
+uint8_t value
+
+.. parsed-literal::
+
+    iter_max =
+    8
+
+uint8_t value
+
+.. parsed-literal::
+
+    iter_min =
+    4
+
+uint8_t value
+
+.. parsed-literal::
+
+    expected_iter_count =
+    8
+
+uint8_t value
+
+.. parsed-literal::
+
+    ext_scale =
+    15
+
+uint8_t value
+
+.. parsed-literal::
+
+    num_maps =
+    0
+
+Chain of flags for turbo decoder operation. Following flags can be used:
+
+- ``RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE``
+
+- ``RTE_BBDEV_TURBO_CRC_TYPE_24B``
+
+- ``RTE_BBDEV_TURBO_EQUALIZER``
+
+- ``RTE_BBDEV_TURBO_SOFT_OUT_SATURATE``
+
+- ``RTE_BBDEV_TURBO_HALF_ITERATION_EVEN``
+
+- ``RTE_BBDEV_TURBO_CONTINUE_CRC_MATCH``
+
+- ``RTE_BBDEV_TURBO_SOFT_OUTPUT``
+
+- ``RTE_BBDEV_TURBO_EARLY_TERMINATION``
+
+If ``RTE_BBDEV_TURBO_CRC_TYPE_24B`` is set input has to be increased by three
+bytes for CRC24B purposes
+
+.. parsed-literal::
+
+    op_flags =
+    RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE, RTE_BBDEV_TURBO_EQUALIZER,
+    RTE_BBDEV_TURBO_SOFT_OUTPUT
+
+Chain of operation statuses that are expected after operation is performed.
+Following statuses can be used:
+
+- ``DMA``
+
+- ``FCW``
+
+- ``CRC``
+
+- ``OK``
+
+``OK`` means no errors are expected. Cannot be used with other values.
+
+.. parsed-literal::
+
+    expected_status =
+    FCW, CRC
+
+
+Turbo encoder test vectors template
+-----------------------------------
+
+For turbo encoder it has to be always set to ``RTE_BBDEV_OP_TURBO_ENC``
+
+.. parsed-literal::
+
+    op_type =
+    RTE_BBDEV_OP_TURBO_ENC
+
+Chain of uint32_t values
+
+.. parsed-literal::
+
+    input0 =
+    0x11d2bcac, 0x4d
+
+Chain of uint32_t values
+
+.. parsed-literal::
+
+    output0 =
+    0xd2399179, 0x640eb999, 0x2cbaf577, 0xaf224ae2, 0x9d139927, 0xe6909b29,
+    0xa25b7f47, 0x2aa224ce, 0x79f2
+
+uint32_t value
+
+.. parsed-literal::
+
+    e =
+    272
+
+uint16_t value
+
+.. parsed-literal::
+
+    k =
+    40
+
+uint16_t value
+
+.. parsed-literal::
+
+    ncb =
+    192
+
+uint8_t value
+
+.. parsed-literal::
+
+    rv_index =
+    0
+
+Chain of flags for turbo encoder operation. Following flags can be used:
+
+- ``RTE_BBDEV_TURBO_RV_INDEX_BYPASS``
+
+- ``RTE_BBDEV_TURBO_RATE_MATCH``
+
+- ``RTE_BBDEV_TURBO_CRC_24B_ATTACH``
+
+- ``RTE_BBDEV_TURBO_CRC_24A_ATTACH``
+
+
+.. parsed-literal::
+
+    op_flags =
+    RTE_BBDEV_TURBO_RATE_MATCH
+
+Chain of operation statuses that are expected after operation is performed.
+Following statuses can be used:
+
+- ``DMA``
+
+- ``FCW``
+
+- ``OK``
+
+``OK`` means no errors are expected. Cannot be used with other values.
+
+.. parsed-literal::
+
+    expected_status =
+    OK
