szedata2: add new poll mode driver
authorMatej Vido <matejvido@gmail.com>
Tue, 10 Nov 2015 14:18:13 +0000 (15:18 +0100)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Fri, 20 Nov 2015 16:17:04 +0000 (17:17 +0100)
Add virtual PMD which communicates with COMBO cards through sze2
layer using libsze2 library.

Since link_speed is uint16_t, there can not be used number for 100G
speed, therefore link_speed is set to ETH_LINK_SPEED_10G until the
type of link_speed is solved.

Signed-off-by: Matej Vido <matejvido@gmail.com>
13 files changed:
MAINTAINERS
config/common_bsdapp
config/common_linuxapp
doc/guides/nics/index.rst
doc/guides/nics/szedata2.rst [new file with mode: 0644]
doc/guides/prog_guide/source_org.rst
doc/guides/rel_notes/release_2_2.rst
drivers/net/Makefile
drivers/net/szedata2/Makefile [new file with mode: 0644]
drivers/net/szedata2/rte_eth_szedata2.c [new file with mode: 0644]
drivers/net/szedata2/rte_eth_szedata2.h [new file with mode: 0644]
drivers/net/szedata2/rte_pmd_szedata2_version.map [new file with mode: 0644]
mk/rte.app.mk

index 8ae688d..840faeb 100644 (file)
@@ -246,6 +246,11 @@ M: John Daley <johndale@cisco.com>
 M: Sujith Sankar <ssujith@cisco.com>
 F: drivers/net/enic/
 
 M: Sujith Sankar <ssujith@cisco.com>
 F: drivers/net/enic/
 
+Combo szedata2
+M: Matej Vido <matejvido@gmail.com>
+F: drivers/net/szedata2/
+F: doc/guides/nics/szedata2.rst
+
 Intel e1000
 M: Wenzhuo Lu <wenzhuo.lu@intel.com>
 F: drivers/net/e1000/
 Intel e1000
 M: Wenzhuo Lu <wenzhuo.lu@intel.com>
 F: drivers/net/e1000/
index 7df0763..ae7374a 100644 (file)
@@ -254,6 +254,11 @@ CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
 CONFIG_RTE_LIBRTE_ENIC_PMD=y
 CONFIG_RTE_LIBRTE_ENIC_DEBUG=n
 
 CONFIG_RTE_LIBRTE_ENIC_PMD=y
 CONFIG_RTE_LIBRTE_ENIC_DEBUG=n
 
+#
+# Compile software PMD backed by SZEDATA2 device
+#
+CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
+
 #
 # Compile burst-oriented VIRTIO PMD driver
 #
 #
 # Compile burst-oriented VIRTIO PMD driver
 #
index 52173d5..0954eef 100644 (file)
@@ -252,6 +252,11 @@ CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
 CONFIG_RTE_LIBRTE_ENIC_PMD=y
 CONFIG_RTE_LIBRTE_ENIC_DEBUG=n
 
 CONFIG_RTE_LIBRTE_ENIC_PMD=y
 CONFIG_RTE_LIBRTE_ENIC_DEBUG=n
 
+#
+# Compile software PMD backed by SZEDATA2 device
+#
+CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
+
 #
 # Compile burst-oriented VIRTIO PMD driver
 #
 #
 # Compile burst-oriented VIRTIO PMD driver
 #
index 2d4936d..0a0b724 100644 (file)
@@ -46,6 +46,7 @@ Network Interface Controller Drivers
     intel_vf
     mlx4
     mlx5
     intel_vf
     mlx4
     mlx5
+    szedata2
     virtio
     vmxnet3
     pcap_ring
     virtio
     vmxnet3
     pcap_ring
diff --git a/doc/guides/nics/szedata2.rst b/doc/guides/nics/szedata2.rst
new file mode 100644 (file)
index 0000000..b952b46
--- /dev/null
@@ -0,0 +1,127 @@
+..  BSD LICENSE
+    Copyright 2015 CESNET
+    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 CESNET 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.
+
+SZEDATA2 poll mode driver library
+=================================
+
+The SZEDATA2 poll mode driver library implements support for cards from COMBO
+family (**COMBO-80G**, **COMBO-100G**).
+The SZEDATA2 PMD is virtual PMD which uses interface provided by libsze2
+library to communicate with COMBO cards over sze2 layer.
+
+More information about family of
+`COMBO cards <https://www.liberouter.org/technologies/cards/>`_
+and used technology
+(`NetCOPE platform <https://www.liberouter.org/technologies/netcope/>`_) can be
+found on the `Liberouter website <https://www.liberouter.org/>`_.
+
+.. note::
+
+   This driver has external dependencies.
+   Therefore it is disabled in default configuration files.
+   It can be enabled by setting ``CONFIG_RTE_LIBRTE_PMD_SZEDATA2=y``
+   and recompiling.
+
+Prerequisities
+--------------
+
+This PMD requires kernel modules which are responsible for initialization and
+allocation of resources needed for sze2 layer function.
+Communication between PMD and kernel modules is mediated by libsze2 library.
+These kernel modules and library are not part of DPDK and must be installed
+separately:
+
+*  **libsze2 library**
+
+   The library provides API for initialization of sze2 transfers, receiving and
+   transmitting data segments.
+
+*  **Kernel modules**
+
+   * combov3
+   * szedata2_cv3
+
+   Kernel modules manage initialization of hardware, allocation and
+   sharing of resources for user space applications:
+
+Information about getting the dependencies can be found `here
+<https://www.liberouter.org/technologies/netcope/access-to-libsze2-library/>`_.
+
+
+Using the SZEDATA2 PMD
+----------------------
+
+SZEDATA2 PMD can be created by passing ``--vdev=`` option to EAL in the
+following format:
+
+.. code-block:: console
+
+   --vdev 'DEVICE,dev_path=PATH,rx_ifaces=RX_MASK,tx_ifaces=TX_MASK'
+
+``DEVICE`` and options ``dev_path``, ``rx_ifaces``, ``tx_ifaces`` are mandatory
+and must be separated by commas.
+
+*  ``DEVICE``: contains prefix ``eth_szedata2`` followed by numbers or letters,
+   must be unique for each virtual device
+
+*  ``dev_path``: Defines path to szedata2 device.
+   Value is valid path to szedata2 device. Example:
+
+   .. code-block:: console
+
+      dev_path=/dev/szedataII0
+
+*  ``rx_ifaces``: Defines which receive channels will be used.
+   For each channel is created one queue. Value is mask for selecting which
+   receive channels are required. Example:
+
+   .. code-block:: console
+
+      rx_ifaces=0x3
+
+*  ``tx_ifaces``: Defines which transmit channels will be used.
+   For each channel is created one queue. Value is mask for selecting which
+   transmit channels are required. Example:
+
+   .. code-block:: console
+
+      tx_ifaces=0x3
+
+Example of usage
+----------------
+
+Read packets from 0. and 1. receive channel and write them to 0. and 1.
+transmit channel:
+
+.. code-block:: console
+
+   $RTE_TARGET/app/testpmd -c 0xf -n 2 \
+   --vdev 'eth_szedata20,dev_path=/dev/szedataII0,rx_ifaces=0x3,tx_ifaces=0x3' \
+   -- --port-topology=chained --rxq=2 --txq=2 --nb-cores=2
index ae11b3b..0c06d47 100644 (file)
@@ -106,6 +106,7 @@ The drivers directory has a *net* subdirectory which contains::
     +-- null               # NULL poll mode driver for testing
     +-- pcap               # PCAP poll mode driver
     +-- ring               # Ring poll mode driver
     +-- null               # NULL poll mode driver for testing
     +-- pcap               # PCAP poll mode driver
     +-- ring               # Ring poll mode driver
+    +-- szedata2           # SZEDATA2 poll mode driver
     +-- virtio             # Virtio poll mode driver
     +-- vmxnet3            # VMXNET3 poll mode driver
     +-- xenvirt            # Xen virtio poll mode driver
     +-- virtio             # Virtio poll mode driver
     +-- vmxnet3            # VMXNET3 poll mode driver
     +-- xenvirt            # Xen virtio poll mode driver
index 2d91bdc..4fea433 100644 (file)
@@ -98,6 +98,11 @@ New Features
   Like mlx4, this PMD is only available for Linux and is disabled by default
   due to external dependencies (libibverbs and libmlx5).
 
   Like mlx4, this PMD is only available for Linux and is disabled by default
   due to external dependencies (libibverbs and libmlx5).
 
+* **Added virtual szedata2 driver for COMBO cards.**
+
+  Added virtual PMD for COMBO-100G and COMBO-80G cards.
+  PMD is disabled in default configuration.
+
 * **Enhanced support for virtio driver.**
 
   * Virtio ring layout optimization (fixed avail ring)
 * **Enhanced support for virtio driver.**
 
   * Virtio ring layout optimization (fixed avail ring)
index 6da1ce2..cddcd57 100644 (file)
@@ -46,6 +46,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += mpipe
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += null
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += pcap
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += ring
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += null
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += pcap
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += ring
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += szedata2
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
diff --git a/drivers/net/szedata2/Makefile b/drivers/net/szedata2/Makefile
new file mode 100644 (file)
index 0000000..c3c42e5
--- /dev/null
@@ -0,0 +1,62 @@
+#   BSD LICENSE
+#
+#   Copyright (c) 2015 CESNET
+#   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 CESNET 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.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_szedata2.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_pmd_szedata2_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += rte_eth_szedata2.c
+
+#
+# Export include files
+#
+SYMLINK-y-include +=
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_malloc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_kvargs
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
new file mode 100644 (file)
index 0000000..5f3a19c
--- /dev/null
@@ -0,0 +1,827 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright (c) 2015 CESNET
+ *   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 CESNET 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.
+ */
+
+#include <stdint.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <err.h>
+
+#include <libsze2.h>
+
+#include <rte_mbuf.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_kvargs.h>
+#include <rte_dev.h>
+
+#include "rte_eth_szedata2.h"
+
+#define RTE_ETH_SZEDATA2_DEV_PATH_ARG "dev_path"
+#define RTE_ETH_SZEDATA2_RX_IFACES_ARG "rx_ifaces"
+#define RTE_ETH_SZEDATA2_TX_IFACES_ARG "tx_ifaces"
+
+#define RTE_ETH_SZEDATA2_MAX_RX_QUEUES 32
+#define RTE_ETH_SZEDATA2_MAX_TX_QUEUES 32
+#define RTE_ETH_SZEDATA2_TX_LOCK_SIZE (32 * 1024 * 1024)
+
+/**
+ * size of szedata2_packet header with alignment
+ */
+#define RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED 8
+
+struct szedata2_rx_queue {
+       struct szedata *sze;
+       uint8_t rx_channel;
+       uint8_t in_port;
+       struct rte_mempool *mb_pool;
+       volatile uint64_t rx_pkts;
+       volatile uint64_t rx_bytes;
+       volatile uint64_t err_pkts;
+};
+
+struct szedata2_tx_queue {
+       struct szedata *sze;
+       uint8_t tx_channel;
+       volatile uint64_t tx_pkts;
+       volatile uint64_t err_pkts;
+       volatile uint64_t tx_bytes;
+};
+
+struct rxtx_szedata2 {
+       uint32_t num_of_rx;
+       uint32_t num_of_tx;
+       uint32_t sze_rx_mask_req;
+       uint32_t sze_tx_mask_req;
+       char *sze_dev;
+};
+
+struct pmd_internals {
+       struct szedata2_rx_queue rx_queue[RTE_ETH_SZEDATA2_MAX_RX_QUEUES];
+       struct szedata2_tx_queue tx_queue[RTE_ETH_SZEDATA2_MAX_TX_QUEUES];
+       unsigned nb_rx_queues;
+       unsigned nb_tx_queues;
+       uint32_t num_of_rx;
+       uint32_t num_of_tx;
+       uint32_t sze_rx_req;
+       uint32_t sze_tx_req;
+       int if_index;
+       char *sze_dev;
+};
+
+static const char *valid_arguments[] = {
+       RTE_ETH_SZEDATA2_DEV_PATH_ARG,
+       RTE_ETH_SZEDATA2_RX_IFACES_ARG,
+       RTE_ETH_SZEDATA2_TX_IFACES_ARG,
+       NULL
+};
+
+static struct ether_addr eth_addr = {
+       .addr_bytes = { 0x00, 0x11, 0x17, 0x00, 0x00, 0x00 }
+};
+static const char *drivername = "SZEdata2 PMD";
+static struct rte_eth_link pmd_link = {
+               .link_speed = ETH_LINK_SPEED_10G,
+               .link_duplex = ETH_LINK_FULL_DUPLEX,
+               .link_status = 0
+};
+
+
+static uint32_t
+count_ones(uint32_t num)
+{
+       num = num - ((num >> 1) & 0x55555555); /* reuse input as temporary */
+       num = (num & 0x33333333) + ((num >> 2) & 0x33333333);        /* temp */
+       return (((num + (num >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; /* count */
+}
+
+static int
+init_rx_channels(struct rte_eth_dev *dev, int v)
+{
+       struct pmd_internals *internals = dev->data->dev_private;
+       int ret;
+       uint32_t i;
+       uint32_t count = internals->num_of_rx;
+       uint32_t num_sub = 0;
+       uint32_t x;
+       uint32_t rx;
+       uint32_t tx;
+
+       rx = internals->sze_rx_req;
+       tx = 0;
+
+       for (i = 0; i < count; i++) {
+               /*
+                * Open, subscribe rx,tx channels and start device
+                */
+               if (v)
+                       RTE_LOG(INFO, PMD, "Opening SZE device %u. time\n", i);
+
+               internals->rx_queue[num_sub].sze =
+                       szedata_open(internals->sze_dev);
+               if (internals->rx_queue[num_sub].sze == NULL)
+                       return -1;
+
+               /* separate least significant non-zero bit */
+               x = rx & ((~rx) + 1);
+
+               if (v)
+                       RTE_LOG(INFO, PMD, "Subscribing rx channel: 0x%x "
+                               "tx channel: 0x%x\n", x, tx);
+
+               ret = szedata_subscribe3(internals->rx_queue[num_sub].sze,
+                               &x, &tx);
+               if (ret) {
+                       szedata_close(internals->rx_queue[num_sub].sze);
+                       internals->rx_queue[num_sub].sze = NULL;
+                       return -1;
+               }
+
+               if (v)
+                       RTE_LOG(INFO, PMD, "Subscribed rx channel: 0x%x "
+                               "tx channel: 0x%x\n", x, tx);
+
+               if (x) {
+                       if (v)
+                               RTE_LOG(INFO, PMD, "Starting SZE device for "
+                                       "rx queue: %u\n", num_sub);
+
+                       ret = szedata_start(internals->rx_queue[num_sub].sze);
+                       if (ret) {
+                               szedata_close(internals->rx_queue[num_sub].sze);
+                               internals->rx_queue[num_sub].sze = NULL;
+                               return -1;
+                       }
+
+                       /*
+                        * set to 1 all bits lower than bit set to 1
+                        * and that bit to 0
+                        */
+                       x -= 1;
+                       internals->rx_queue[num_sub].rx_channel =
+                               count_ones(x);
+
+                       if (v)
+                               RTE_LOG(INFO, PMD, "Subscribed rx channel "
+                                       "no: %u\n",
+                                       internals->rx_queue[num_sub].rx_channel
+                                       );
+
+                       num_sub++;
+                       internals->nb_rx_queues = num_sub;
+               } else {
+                       if (v)
+                               RTE_LOG(INFO, PMD,
+                                       "Could not subscribe any rx channel. "
+                                       "Closing SZE device\n");
+
+                       szedata_close(internals->rx_queue[num_sub].sze);
+                       internals->rx_queue[num_sub].sze = NULL;
+               }
+
+               /* set least significant non-zero bit to zero */
+               rx = rx & (rx - 1);
+       }
+
+       dev->data->nb_rx_queues = (uint16_t)num_sub;
+
+       if (v)
+               RTE_LOG(INFO, PMD, "Successfully opened rx channels: %u\n",
+                       num_sub);
+
+       return 0;
+}
+
+static int
+init_tx_channels(struct rte_eth_dev *dev, int v)
+{
+       struct pmd_internals *internals = dev->data->dev_private;
+       int ret;
+       uint32_t i;
+       uint32_t count = internals->num_of_tx;
+       uint32_t num_sub = 0;
+       uint32_t x;
+       uint32_t rx;
+       uint32_t tx;
+
+       rx = 0;
+       tx = internals->sze_tx_req;
+
+       for (i = 0; i < count; i++) {
+               /*
+                * Open, subscribe rx,tx channels and start device
+                */
+               if (v)
+                       RTE_LOG(INFO, PMD, "Opening SZE device %u. time\n",
+                               i + internals->num_of_rx);
+
+               internals->tx_queue[num_sub].sze =
+                       szedata_open(internals->sze_dev);
+               if (internals->tx_queue[num_sub].sze == NULL)
+                       return -1;
+
+               /* separate least significant non-zero bit */
+               x = tx & ((~tx) + 1);
+
+               if (v)
+                       RTE_LOG(INFO, PMD, "Subscribing rx channel: 0x%x "
+                               "tx channel: 0x%x\n", rx, x);
+
+               ret = szedata_subscribe3(internals->tx_queue[num_sub].sze,
+                               &rx, &x);
+               if (ret) {
+                       szedata_close(internals->tx_queue[num_sub].sze);
+                       internals->tx_queue[num_sub].sze = NULL;
+                       return -1;
+               }
+
+               if (v)
+                       RTE_LOG(INFO, PMD, "Subscribed rx channel: 0x%x "
+                               "tx channel: 0x%x\n", rx, x);
+
+               if (x) {
+                       if (v)
+                               RTE_LOG(INFO, PMD, "Starting SZE device for "
+                                       "tx queue: %u\n", num_sub);
+
+                       ret = szedata_start(internals->tx_queue[num_sub].sze);
+                       if (ret) {
+                               szedata_close(internals->tx_queue[num_sub].sze);
+                               internals->tx_queue[num_sub].sze = NULL;
+                               return -1;
+                       }
+
+                       /*
+                        * set to 1 all bits lower than bit set to 1
+                        * and that bit to 0
+                        */
+                       x -= 1;
+                       internals->tx_queue[num_sub].tx_channel =
+                               count_ones(x);
+
+                       if (v)
+                               RTE_LOG(INFO, PMD, "Subscribed tx channel "
+                                       "no: %u\n",
+                                       internals->tx_queue[num_sub].tx_channel
+                                       );
+
+                       num_sub++;
+                       internals->nb_tx_queues = num_sub;
+               } else {
+                       if (v)
+                               RTE_LOG(INFO, PMD,
+                                       "Could not subscribe any tx channel. "
+                                       "Closing SZE device\n");
+
+                       szedata_close(internals->tx_queue[num_sub].sze);
+                       internals->tx_queue[num_sub].sze = NULL;
+               }
+
+               /* set least significant non-zero bit to zero */
+               tx = tx & (tx - 1);
+       }
+
+       dev->data->nb_tx_queues = (uint16_t)num_sub;
+
+       if (v)
+               RTE_LOG(INFO, PMD, "Successfully opened tx channels: %u\n",
+                       num_sub);
+
+       return 0;
+}
+
+static void
+close_rx_channels(struct rte_eth_dev *dev)
+{
+       struct pmd_internals *internals = dev->data->dev_private;
+       uint32_t i;
+       uint32_t num_sub = internals->nb_rx_queues;
+
+       for (i = 0; i < num_sub; i++) {
+               if (internals->rx_queue[i].sze != NULL) {
+                       szedata_close(internals->rx_queue[i].sze);
+                       internals->rx_queue[i].sze = NULL;
+               }
+       }
+       /* set number of rx queues to zero */
+       internals->nb_rx_queues = 0;
+       dev->data->nb_rx_queues = (uint16_t)0;
+}
+
+static void
+close_tx_channels(struct rte_eth_dev *dev)
+{
+       struct pmd_internals *internals = dev->data->dev_private;
+       uint32_t i;
+       uint32_t num_sub = internals->nb_tx_queues;
+
+       for (i = 0; i < num_sub; i++) {
+               if (internals->tx_queue[i].sze != NULL) {
+                       szedata_close(internals->tx_queue[i].sze);
+                       internals->tx_queue[i].sze = NULL;
+               }
+       }
+       /* set number of rx queues to zero */
+       internals->nb_tx_queues = 0;
+       dev->data->nb_tx_queues = (uint16_t)0;
+}
+
+static int
+eth_dev_start(struct rte_eth_dev *dev)
+{
+       struct pmd_internals *internals = dev->data->dev_private;
+       int ret;
+
+       if (internals->nb_rx_queues == 0) {
+               ret = init_rx_channels(dev, 0);
+               if (ret != 0) {
+                       close_rx_channels(dev);
+                       return -1;
+               }
+       }
+
+       if (internals->nb_tx_queues == 0) {
+               ret = init_tx_channels(dev, 0);
+               if (ret != 0) {
+                       close_tx_channels(dev);
+                       close_rx_channels(dev);
+                       return -1;
+               }
+       }
+
+       dev->data->dev_link.link_status = 1;
+       return 0;
+}
+
+static void
+eth_dev_stop(struct rte_eth_dev *dev)
+{
+       unsigned i;
+       struct pmd_internals *internals = dev->data->dev_private;
+
+       for (i = 0; i < internals->nb_rx_queues; i++) {
+               if (internals->rx_queue[i].sze != NULL) {
+                       szedata_close(internals->rx_queue[i].sze);
+                       internals->rx_queue[i].sze = NULL;
+               }
+       }
+
+       for (i = 0; i < internals->nb_tx_queues; i++) {
+               if (internals->tx_queue[i].sze != NULL) {
+                       szedata_close(internals->tx_queue[i].sze);
+                       internals->tx_queue[i].sze = NULL;
+               }
+       }
+
+       internals->nb_rx_queues = 0;
+       internals->nb_tx_queues = 0;
+
+       dev->data->nb_rx_queues = (uint16_t)0;
+       dev->data->nb_tx_queues = (uint16_t)0;
+
+       dev->data->dev_link.link_status = 0;
+}
+
+static int
+eth_dev_configure(struct rte_eth_dev *dev __rte_unused)
+{
+       return 0;
+}
+
+static void
+eth_dev_info(struct rte_eth_dev *dev,
+               struct rte_eth_dev_info *dev_info)
+{
+       struct pmd_internals *internals = dev->data->dev_private;
+       dev_info->driver_name = drivername;
+       dev_info->if_index = internals->if_index;
+       dev_info->max_mac_addrs = 1;
+       dev_info->max_rx_pktlen = (uint32_t)-1;
+       dev_info->max_rx_queues = (uint16_t)internals->nb_rx_queues;
+       dev_info->max_tx_queues = (uint16_t)internals->nb_tx_queues;
+       dev_info->min_rx_bufsize = 0;
+       dev_info->pci_dev = NULL;
+}
+
+static void
+eth_stats_get(struct rte_eth_dev *dev,
+               struct rte_eth_stats *stats)
+{
+       unsigned i;
+       uint64_t rx_total = 0;
+       uint64_t tx_total = 0;
+       uint64_t tx_err_total = 0;
+       uint64_t rx_total_bytes = 0;
+       uint64_t tx_total_bytes = 0;
+       const struct pmd_internals *internal = dev->data->dev_private;
+
+       for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&
+                       i < internal->nb_rx_queues; i++) {
+               stats->q_ipackets[i] = internal->rx_queue[i].rx_pkts;
+               stats->q_ibytes[i] = internal->rx_queue[i].rx_bytes;
+               rx_total += stats->q_ipackets[i];
+               rx_total_bytes += stats->q_ibytes[i];
+       }
+
+       for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&
+                       i < internal->nb_tx_queues; i++) {
+               stats->q_opackets[i] = internal->tx_queue[i].tx_pkts;
+               stats->q_errors[i] = internal->tx_queue[i].err_pkts;
+               stats->q_obytes[i] = internal->tx_queue[i].tx_bytes;
+               tx_total += stats->q_opackets[i];
+               tx_err_total += stats->q_errors[i];
+               tx_total_bytes += stats->q_obytes[i];
+       }
+
+       stats->ipackets = rx_total;
+       stats->opackets = tx_total;
+       stats->ibytes = rx_total_bytes;
+       stats->obytes = tx_total_bytes;
+       stats->oerrors = tx_err_total;
+}
+
+static void
+eth_stats_reset(struct rte_eth_dev *dev)
+{
+       unsigned i;
+       struct pmd_internals *internal = dev->data->dev_private;
+       for (i = 0; i < internal->nb_rx_queues; i++) {
+               internal->rx_queue[i].rx_pkts = 0;
+               internal->rx_queue[i].rx_bytes = 0;
+       }
+       for (i = 0; i < internal->nb_tx_queues; i++) {
+               internal->tx_queue[i].tx_pkts = 0;
+               internal->tx_queue[i].err_pkts = 0;
+               internal->tx_queue[i].tx_bytes = 0;
+       }
+}
+
+static void
+eth_dev_close(struct rte_eth_dev *dev)
+{
+       unsigned i;
+       struct pmd_internals *internals = dev->data->dev_private;
+
+       for (i = 0; i < internals->nb_rx_queues; i++) {
+               if (internals->rx_queue[i].sze != NULL) {
+                       szedata_close(internals->rx_queue[i].sze);
+                       internals->rx_queue[i].sze = NULL;
+               }
+       }
+
+       for (i = 0; i < internals->nb_tx_queues; i++) {
+               if (internals->tx_queue[i].sze != NULL) {
+                       szedata_close(internals->tx_queue[i].sze);
+                       internals->tx_queue[i].sze = NULL;
+               }
+       }
+
+       internals->nb_rx_queues = 0;
+       internals->nb_tx_queues = 0;
+
+       dev->data->nb_rx_queues = (uint16_t)0;
+       dev->data->nb_tx_queues = (uint16_t)0;
+}
+
+static void
+eth_queue_release(void *q __rte_unused)
+{
+}
+
+static int
+eth_link_update(struct rte_eth_dev *dev __rte_unused,
+               int wait_to_complete __rte_unused)
+{
+       return 0;
+}
+
+static int
+eth_rx_queue_setup(struct rte_eth_dev *dev,
+               uint16_t rx_queue_id,
+               uint16_t nb_rx_desc __rte_unused,
+               unsigned int socket_id __rte_unused,
+               const struct rte_eth_rxconf *rx_conf __rte_unused,
+               struct rte_mempool *mb_pool)
+{
+       struct pmd_internals *internals = dev->data->dev_private;
+       struct szedata2_rx_queue *szedata2_q =
+               &internals->rx_queue[rx_queue_id];
+       szedata2_q->mb_pool = mb_pool;
+       dev->data->rx_queues[rx_queue_id] = szedata2_q;
+       szedata2_q->in_port = dev->data->port_id;
+       return 0;
+}
+
+static int
+eth_tx_queue_setup(struct rte_eth_dev *dev,
+               uint16_t tx_queue_id,
+               uint16_t nb_tx_desc __rte_unused,
+               unsigned int socket_id __rte_unused,
+               const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+       struct pmd_internals *internals = dev->data->dev_private;
+       dev->data->tx_queues[tx_queue_id] = &internals->tx_queue[tx_queue_id];
+       return 0;
+}
+
+static void
+eth_mac_addr_set(struct rte_eth_dev *dev __rte_unused,
+               struct ether_addr *mac_addr __rte_unused)
+{
+}
+
+static struct eth_dev_ops ops = {
+               .dev_start          = eth_dev_start,
+               .dev_stop           = eth_dev_stop,
+               .dev_close          = eth_dev_close,
+               .dev_configure      = eth_dev_configure,
+               .dev_infos_get      = eth_dev_info,
+               .rx_queue_setup     = eth_rx_queue_setup,
+               .tx_queue_setup     = eth_tx_queue_setup,
+               .rx_queue_release   = eth_queue_release,
+               .tx_queue_release   = eth_queue_release,
+               .link_update        = eth_link_update,
+               .stats_get          = eth_stats_get,
+               .stats_reset        = eth_stats_reset,
+               .mac_addr_set       = eth_mac_addr_set,
+};
+
+static int
+parse_mask(const char *mask_str, uint32_t *mask_num)
+{
+       char *endptr;
+       long int value;
+
+       value = strtol(mask_str, &endptr, 0);
+       if (*endptr != '\0' || value > UINT32_MAX || value < 0)
+               return -1;
+
+       *mask_num = (uint32_t)value;
+       return 0;
+}
+
+static int
+add_rx_mask(const char *key __rte_unused, const char *value, void *extra_args)
+{
+       struct rxtx_szedata2 *szedata2 = extra_args;
+       uint32_t mask;
+
+       if (parse_mask(value, &mask) != 0)
+               return -1;
+
+       szedata2->sze_rx_mask_req |= mask;
+       return 0;
+}
+
+static int
+add_tx_mask(const char *key __rte_unused, const char *value, void *extra_args)
+{
+       struct rxtx_szedata2 *szedata2 = extra_args;
+       uint32_t mask;
+
+       if (parse_mask(value, &mask) != 0)
+               return -1;
+
+       szedata2->sze_tx_mask_req |= mask;
+       return 0;
+}
+
+static int
+rte_pmd_init_internals(const char *name, const unsigned nb_rx_queues,
+               const unsigned nb_tx_queues,
+               const unsigned numa_node,
+               struct pmd_internals **internals,
+               struct rte_eth_dev **eth_dev)
+{
+       struct rte_eth_dev_data *data = NULL;
+
+       RTE_LOG(INFO, PMD,
+                       "Creating szedata2-backed ethdev on numa socket %u\n",
+                       numa_node);
+
+       /*
+        * now do all data allocation - for eth_dev structure
+        * and internal (private) data
+        */
+       data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
+       if (data == NULL)
+               goto error;
+
+       *internals = rte_zmalloc_socket(name, sizeof(**internals), 0,
+                       numa_node);
+       if (*internals == NULL)
+               goto error;
+
+       /* reserve an ethdev entry */
+       *eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL);
+       if (*eth_dev == NULL)
+               goto error;
+
+       /*
+        * now put it all together
+        * - store queue data in internals,
+        * - store numa_node info in pci_driver
+        * - point eth_dev_data to internals
+        * - and point eth_dev structure to new eth_dev_data structure
+        *
+        * NOTE: we'll replace the data element, of originally allocated eth_dev
+        * so the rings are local per-process
+        */
+
+       (*internals)->nb_rx_queues = nb_rx_queues;
+       (*internals)->nb_tx_queues = nb_tx_queues;
+
+       (*internals)->if_index = 0;
+
+       data->dev_private = *internals;
+       data->port_id = (*eth_dev)->data->port_id;
+       snprintf(data->name, sizeof(data->name), "%s", (*eth_dev)->data->name);
+       data->nb_rx_queues = (uint16_t)nb_rx_queues;
+       data->nb_tx_queues = (uint16_t)nb_tx_queues;
+       data->dev_link = pmd_link;
+       data->mac_addrs = &eth_addr;
+
+       (*eth_dev)->data = data;
+       (*eth_dev)->dev_ops = &ops;
+       (*eth_dev)->data->dev_flags = RTE_ETH_DEV_DETACHABLE;
+       (*eth_dev)->driver = NULL;
+       (*eth_dev)->data->kdrv = RTE_KDRV_NONE;
+       (*eth_dev)->data->drv_name = drivername;
+       (*eth_dev)->data->numa_node = numa_node;
+
+       return 0;
+
+error:
+       rte_free(data);
+       rte_free(*internals);
+       return -1;
+}
+
+static int
+rte_eth_from_szedata2(const char *name,
+               struct rxtx_szedata2 *szedata2,
+               const unsigned numa_node)
+{
+       struct pmd_internals *internals = NULL;
+       struct rte_eth_dev *eth_dev = NULL;
+       int ret;
+
+       if (rte_pmd_init_internals(name, 0, 0, numa_node,
+                       &internals, &eth_dev) < 0)
+               return -1;
+
+       internals->sze_dev = szedata2->sze_dev;
+       internals->sze_rx_req = szedata2->sze_rx_mask_req;
+       internals->sze_tx_req = szedata2->sze_tx_mask_req;
+       internals->num_of_rx = szedata2->num_of_rx;
+       internals->num_of_tx = szedata2->num_of_tx;
+
+       RTE_LOG(INFO, PMD, "Number of rx channels to open: %u mask: 0x%x\n",
+                       internals->num_of_rx, internals->sze_rx_req);
+       RTE_LOG(INFO, PMD, "Number of tx channels to open: %u mask: 0x%x\n",
+                       internals->num_of_tx, internals->sze_tx_req);
+
+       ret = init_rx_channels(eth_dev, 1);
+       if (ret != 0) {
+               close_rx_channels(eth_dev);
+               return -1;
+       }
+
+       ret = init_tx_channels(eth_dev, 1);
+       if (ret != 0) {
+               close_tx_channels(eth_dev);
+               close_rx_channels(eth_dev);
+               return -1;
+       }
+
+       eth_dev->rx_pkt_burst = NULL;
+       eth_dev->tx_pkt_burst = NULL;
+
+       return 0;
+}
+
+
+static int
+rte_pmd_szedata2_devinit(const char *name, const char *params)
+{
+       unsigned numa_node;
+       int ret;
+       struct rte_kvargs *kvlist;
+       unsigned k_idx;
+       struct rte_kvargs_pair *pair = NULL;
+       struct rxtx_szedata2 szedata2 = { 0, 0, 0, 0, NULL };
+       bool dev_path_missing = true;
+
+       RTE_LOG(INFO, PMD, "Initializing pmd_szedata2 for %s\n", name);
+
+       numa_node = rte_socket_id();
+
+       kvlist = rte_kvargs_parse(params, valid_arguments);
+       if (kvlist == NULL)
+               return -1;
+
+       /*
+        * Get szedata2 device path and rx,tx channels from passed arguments.
+        */
+
+       if (rte_kvargs_count(kvlist, RTE_ETH_SZEDATA2_DEV_PATH_ARG) != 1)
+               goto err;
+
+       if (rte_kvargs_count(kvlist, RTE_ETH_SZEDATA2_RX_IFACES_ARG) < 1)
+               goto err;
+
+       if (rte_kvargs_count(kvlist, RTE_ETH_SZEDATA2_TX_IFACES_ARG) < 1)
+               goto err;
+
+       for (k_idx = 0; k_idx < kvlist->count; k_idx++) {
+               pair = &kvlist->pairs[k_idx];
+               if (strstr(pair->key, RTE_ETH_SZEDATA2_DEV_PATH_ARG) != NULL) {
+                       szedata2.sze_dev = pair->value;
+                       dev_path_missing = false;
+                       break;
+               }
+       }
+
+       if (dev_path_missing)
+               goto err;
+
+       ret = rte_kvargs_process(kvlist, RTE_ETH_SZEDATA2_RX_IFACES_ARG,
+                       &add_rx_mask, &szedata2);
+       if (ret < 0)
+               goto err;
+
+       ret = rte_kvargs_process(kvlist, RTE_ETH_SZEDATA2_TX_IFACES_ARG,
+                       &add_tx_mask, &szedata2);
+       if (ret < 0)
+               goto err;
+
+       szedata2.num_of_rx = count_ones(szedata2.sze_rx_mask_req);
+       szedata2.num_of_tx = count_ones(szedata2.sze_tx_mask_req);
+
+       RTE_LOG(INFO, PMD, "SZE device found at path %s\n", szedata2.sze_dev);
+
+       return rte_eth_from_szedata2(name, &szedata2, numa_node);
+err:
+       rte_kvargs_free(kvlist);
+       return -1;
+}
+
+static int
+rte_pmd_szedata2_devuninit(const char *name)
+{
+       struct rte_eth_dev *dev = NULL;
+
+       RTE_LOG(INFO, PMD, "Uninitializing pmd_szedata2 for %s "
+                       "on numa socket %u\n", name, rte_socket_id());
+
+       if (name == NULL)
+               return -1;
+
+       dev = rte_eth_dev_allocated(name);
+       if (dev == NULL)
+               return -1;
+
+       rte_free(dev->data->dev_private);
+       rte_free(dev->data);
+       rte_eth_dev_release_port(dev);
+       return 0;
+}
+
+static struct rte_driver pmd_szedata2_drv = {
+       .name = "eth_szedata2",
+       .type = PMD_VDEV,
+       .init = rte_pmd_szedata2_devinit,
+       .uninit = rte_pmd_szedata2_devuninit,
+};
+
+PMD_REGISTER_DRIVER(pmd_szedata2_drv);
diff --git a/drivers/net/szedata2/rte_eth_szedata2.h b/drivers/net/szedata2/rte_eth_szedata2.h
new file mode 100644 (file)
index 0000000..4d09a98
--- /dev/null
@@ -0,0 +1,102 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright (c) 2015 CESNET
+ *   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 CESNET 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.
+ */
+
+#ifndef RTE_PMD_SZEDATA2_H_
+#define RTE_PMD_SZEDATA2_H_
+
+/* szedata2_packet header length == 4 bytes == 2B segment size + 2B hw size */
+#define RTE_SZE2_PACKET_HEADER_SIZE 4
+
+#define RTE_SZE2_MMIO_MAX 10
+
+/*!
+ * Round 'what' to the nearest larger (or equal) multiple of '8'
+ * (szedata2 packet is aligned to 8 bytes)
+ */
+#define RTE_SZE2_ALIGN8(what) (((what) + ((8) - 1)) & (~((8) - 1)))
+
+/*! main handle structure */
+struct szedata {
+       int fd;
+       struct sze2_instance_info *info;
+       uint32_t *write_size;
+       void *space[RTE_SZE2_MMIO_MAX];
+       struct szedata_lock lock[2][2];
+
+       __u32 *rx_asize, *tx_asize;
+
+       /* szedata_read_next variables - to keep context (ct) */
+
+       /*
+        * rx
+        */
+       /** initial sze lock ptr */
+       const struct szedata_lock   *ct_rx_lck_orig;
+       /** current sze lock ptr (initial or next) */
+       const struct szedata_lock   *ct_rx_lck;
+       /** remaining bytes (not read) within current lock */
+       unsigned int                ct_rx_rem_bytes;
+       /** current pointer to locked memory */
+       unsigned char               *ct_rx_cur_ptr;
+       /**
+        * allocated buffer to store RX packet if it was split
+        * into 2 buffers
+        */
+       unsigned char               *ct_rx_buffer;
+       /** registered function to provide filtering based on hwdata */
+       int (*ct_rx_filter)(u_int16_t hwdata_len, u_char *hwdata);
+
+       /*
+        * tx
+        */
+       /**
+        * buffer for tx - packet is prepared here
+        * (in future for burst write)
+        */
+       unsigned char               *ct_tx_buffer;
+       /** initial sze TX lock ptrs - number according to TX interfaces */
+       const struct szedata_lock   **ct_tx_lck_orig;
+       /** current sze TX lock ptrs - number according to TX interfaces */
+       const struct szedata_lock   **ct_tx_lck;
+       /** already written bytes in both locks */
+       unsigned int                *ct_tx_written_bytes;
+       /** remaining bytes (not written) within current lock */
+       unsigned int                *ct_tx_rem_bytes;
+       /** current pointers to locked memory */
+       unsigned char               **ct_tx_cur_ptr;
+       /** NUMA node closest to PCIe device, or -1 */
+       int                         numa_node;
+};
+
+
+#endif
diff --git a/drivers/net/szedata2/rte_pmd_szedata2_version.map b/drivers/net/szedata2/rte_pmd_szedata2_version.map
new file mode 100644 (file)
index 0000000..ad607bb
--- /dev/null
@@ -0,0 +1,3 @@
+DPDK_2.2 {
+       local: *;
+};
index 724efa7..148653e 100644 (file)
@@ -92,6 +92,8 @@ endif # ! CONFIG_RTE_BUILD_COMBINE_LIBS
 
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP)       += -lpcap
 
 
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP)       += -lpcap
 
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2)   += -lsze2
+
 ifeq ($(CONFIG_RTE_LIBRTE_VHOST_NUMA),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST)          += -lnuma
 endif
 ifeq ($(CONFIG_RTE_LIBRTE_VHOST_NUMA),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST)          += -lnuma
 endif
@@ -142,6 +144,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)      += -lrte_pmd_ixgbe
 _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -lrte_pmd_mlx4
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5
 _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -lrte_pmd_mlx4
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2)   += -lrte_pmd_szedata2
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD)      += -lrte_pmd_mpipe -lgxio
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING)       += -lrte_pmd_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP)       += -lrte_pmd_pcap
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD)      += -lrte_pmd_mpipe -lgxio
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING)       += -lrte_pmd_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP)       += -lrte_pmd_pcap