@@ -51,6 +51,7 @@ AC_ARG_WITH([platform],
AM_CONDITIONAL([ODP_PLATFORM_GENERIC], [test "x$with_platform" = xlinux-generic])
AM_CONDITIONAL([ODP_PLATFORM_KEYSTONE2], [test "x$with_platform" = xlinux-keystone2])
+AM_CONDITIONAL([ODP_PLATFORM_DPDK], [test "x$with_platform" = xlinux-dpdk])
AC_SUBST([with_platform])
@@ -111,6 +112,7 @@ AC_CONFIG_FILES([Makefile
platform/Makefile
platform/linux-generic/Makefile
platform/linux-keystone2/Makefile
+ platform/linux-dpdk/Makefile
test/Makefile
test/api_test/Makefile
test/example/Makefile
deleted file mode 100644
@@ -1,158 +0,0 @@
-## Copyright (c) 2013, Linaro Limited
-## 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 Linaro Limited 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 HOLDER 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.
-
-.DEFAULT_GOAL := libs
-
-ODP_ROOT = ../..
-LIB_DIR = ./lib
-DOC_DIR = ./doc
-
-LINUX_GENERIC_DIR = ../linux-generic
-
-RTE_SDK ?= $(abspath $(ODP_ROOT)/../dpdk)
-RTE_OUTPUT ?= $(abspath $(RTE_SDK)/build)
-RTE_LIB ?= $(abspath $(RTE_OUTPUT)/lib/libintel_dpdk.a)
-
-PLAT_CFLAGS = -include $(RTE_OUTPUT)/include/rte_config.h
-PLAT_CFLAGS += -I$(RTE_OUTPUT)/include
-PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/arch
-PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/exec-env
-PLAT_CFLAGS += -msse4.2
-
-EXTRA_CFLAGS += $(PLAT_CFLAGS)
-EXTRA_CFLAGS += -I./include
-EXTRA_CFLAGS += -I./include/api
-EXTRA_CFLAGS += -I$(LINUX_GENERIC_DIR)/include
-EXTRA_CFLAGS += -I$(LINUX_GENERIC_DIR)/include/api
-EXTRA_CFLAGS += -I$(ODP_ROOT)/include
-
-include $(ODP_ROOT)/Makefile.inc
-STATIC_LIB = ./lib/libodp.a
-
-#
-# Object files
-#
-OBJS =
-OBJS += $(OBJ_DIR)/odp_barrier.o
-OBJS += $(OBJ_DIR)/odp_buffer.o
-OBJS += $(OBJ_DIR)/odp_buffer_pool.o
-OBJS += $(OBJ_DIR)/odp_coremask.o
-OBJS += $(OBJ_DIR)/odp_init.o
-OBJS += $(OBJ_DIR)/odp_linux.o
-OBJS += $(OBJ_DIR)/odp_packet.o
-OBJS += $(OBJ_DIR)/odp_packet_flags.o
-OBJS += $(OBJ_DIR)/odp_packet_io.o
-OBJS += $(OBJ_DIR)/odp_packet_socket.o
-OBJS += $(OBJ_DIR)/odp_queue.o
-OBJS += $(OBJ_DIR)/odp_schedule.o
-OBJS += $(OBJ_DIR)/odp_shared_memory.o
-OBJS += $(OBJ_DIR)/odp_spinlock.o
-OBJS += $(OBJ_DIR)/odp_system_info.o
-OBJS += $(OBJ_DIR)/odp_thread.o
-OBJS += $(OBJ_DIR)/odp_ticketlock.o
-OBJS += $(OBJ_DIR)/odp_time.o
-OBJS += $(OBJ_DIR)/odp_timer.o
-OBJS += $(OBJ_DIR)/odp_ring.o
-OBJS += $(OBJ_DIR)/odp_rwlock.o
-OBJS += $(OBJ_DIR)/odp_packet_dpdk.o
-
-DEPS = $(OBJS:.o=.d)
-
-.PHONY: all
-all: libs docs
-
--include $(DEPS)
-
-#$(OBJ_DIR):
-# $(MKDIR) $(OBJ_DIR)
-
-$(LIB_DIR):
- $(MKDIR) $(LIB_DIR)
-
-$(DOC_DIR):
- $(MKDIR) $(DOC_DIR)/html
- $(MKDIR) $(DOC_DIR)/latex
-
-#
-# Compile rules
-#
-vpath %.c source:$(LINUX_GENERIC_DIR)/source
-
-$(OBJ_DIR)/%.o: %.c
- $(ECHO) " CC $<"
- $(CC) -c -MD $(EXTRA_CFLAGS) $(CFLAGS) -o $@ $<
-
-#
-# Lib rule
-#
-$(OBJ_DIR)/libodp.o: $(OBJS)
- $(ECHO) " LD $@"
- $(LD) -r -o $@ $(OBJS) $(RTE_LIB)
-
-$(STATIC_LIB): $(OBJ_DIR)/libodp.o
- $(ECHO) " AR $@"
- $(AR) -cr $@ $(OBJ_DIR)/libodp.o
-
-
-clean:
- $(RMDIR) $(OBJ_DIR)
- $(RMDIR) $(LIB_DIR)
- $(RMDIR) $(DOC_DIR)
- $(RM) Doxyfile
-
-Doxyfile: Doxyfile.in
- doxygen -u - < $< > $@
-
-.PHONY: docs
-docs: $(DOC_DIR) Doxyfile ./include/odp*.h
- doxygen
-
-.PHONY: docs_install
-docs_install: docs
- $(COPY) doc $(DESTDIR)
-
-.PHONY: pdf
-pdf: docs
- make --directory doc/latex refman.pdf 1> /dev/null
-
-.PHONY: libs
-libs: $(OBJ_DIR) $(LIB_DIR) $(STATIC_LIB)
-
-.PHONY: lib_install
-lib_install: libs
- install -d $(DESTDIR)/lib
- install -m 0644 ${STATIC_LIB} $(DESTDIR)/lib/
-
-.PHONY: headers_install
-headers_install: libs
- $(ECHO) Installing headers to $(DESTDIR)/include
- $(COPY) $(ODP_ROOT)/include $(DESTDIR)
- $(COPY) $(LINUX_GENERIC_DIR)/include/api/* $(DESTDIR)/include/
- $(COPY) include/api/* $(DESTDIR)/include/
-
-install: lib_install headers_install
new file mode 100644
@@ -0,0 +1,100 @@
+include $(top_srcdir)/Makefile.inc
+LIB = $(top_builddir)/lib
+
+dist_pkgdata_DATA = $(LIB)/libodp.la
+
+pkgconfigdir = pkgconfig
+nodist_pkgconfig_DATA = $(top_builddir)/pkgconfig/libodp.pc
+
+.PHONY: pkgconfig/libodp.pc
+
+RTE_SDK ?= $(top_srcdir)/../dpdk
+RTE_OUTPUT ?= $(RTE_SDK)/build
+RTE_LIB ?= $(RTE_OUTPUT)/lib
+
+PLAT_CFLAGS = -include $(RTE_OUTPUT)/include/rte_config.h
+PLAT_CFLAGS += -I$(RTE_OUTPUT)/include
+PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/arch
+PLAT_CFLAGS += -I$(RTE_OUTPUT)/include/exec-env
+PLAT_CFLAGS += -msse4.2
+
+AM_CFLAGS += $(PLAT_CFLAGS)
+AM_CFLAGS += -I$(srcdir)/include
+AM_CFLAGS += -I$(srcdir)/include/api
+AM_CFLAGS += -I$(top_srcdir)/platform/linux-generic/include
+AM_CFLAGS += -I$(top_srcdir)/platform/linux-generic/include/api
+AM_CFLAGS += -I$(top_srcdir)/include
+
+AM_LDFLAGS += -L$(RTE_LIB)
+VPATH = $(srcdir) $(builddir)
+if ODP_PLATFORM_DPDK
+lib_LTLIBRARIES = $(LIB)/libodp.la
+DPDK_LIBS="-lintel_dpdk -ldl"
+LIBS += $(DPDK_LIBS)
+
+include_HEADERS = \
+ $(top_srcdir)/platform/linux-dpdk/include/api/odp_buffer.h \
+ $(top_srcdir)/include/odp.h \
+ $(top_srcdir)/include/odp_align.h \
+ $(top_srcdir)/include/odp_atomic.h \
+ $(top_srcdir)/include/odp_barrier.h \
+ $(top_srcdir)/include/odp_buffer_pool.h \
+ $(top_srcdir)/include/odp_byteorder.h \
+ $(top_srcdir)/include/odp_compiler.h \
+ $(top_srcdir)/include/odp_config.h \
+ $(top_srcdir)/include/odp_coremask.h \
+ $(top_srcdir)/include/odp_debug.h \
+ $(top_srcdir)/include/odp_hints.h \
+ $(top_srcdir)/include/odp_init.h \
+ $(top_srcdir)/include/odp_packet_flags.h \
+ $(top_srcdir)/include/odp_packet.h \
+ $(top_srcdir)/include/odp_packet_io.h \
+ $(top_srcdir)/include/odp_queue.h \
+ $(top_srcdir)/include/odp_rwlock.h \
+ $(top_srcdir)/include/odp_schedule.h \
+ $(top_srcdir)/include/odp_shared_memory.h \
+ $(top_srcdir)/include/odp_spinlock.h \
+ $(top_srcdir)/include/odp_std_types.h \
+ $(top_srcdir)/include/odp_sync.h \
+ $(top_srcdir)/include/odp_system_info.h \
+ $(top_srcdir)/include/odp_thread.h \
+ $(top_srcdir)/include/odp_ticketlock.h \
+ $(top_srcdir)/include/odp_time.h \
+ $(top_srcdir)/include/odp_timer.h \
+ $(top_srcdir)/include/odp_version.h
+
+subdirheadersdir = $(includedir)/helper
+subdirheaders_HEADERS = \
+ $(top_srcdir)/include/helper/odp_chksum.h \
+ $(top_srcdir)/include/helper/odp_eth.h \
+ $(top_srcdir)/include/helper/odp_ip.h \
+ $(top_srcdir)/include/helper/odp_linux.h \
+ $(top_srcdir)/include/helper/odp_packet_helper.h \
+ $(top_srcdir)/include/helper/odp_ring.h \
+ $(top_srcdir)/include/helper/odp_udp.h
+
+__LIB__libodp_la_SOURCES = \
+ ../linux-generic/odp_barrier.c \
+ odp_buffer.c \
+ odp_buffer_pool.c \
+ ../linux-generic/odp_coremask.c \
+ odp_init.c \
+ odp_linux.c \
+ odp_packet.c \
+ odp_packet_dpdk.c \
+ ../linux-generic/odp_packet_flags.c \
+ odp_packet_io.c \
+ ../linux-generic/odp_packet_socket.c \
+ odp_queue.c \
+ ../linux-generic/odp_ring.c \
+ ../linux-generic/odp_rwlock.c \
+ ../linux-generic/odp_schedule.c \
+ ../linux-generic/odp_shared_memory.c \
+ ../linux-generic/odp_spinlock.c \
+ ../linux-generic/odp_system_info.c \
+ ../linux-generic/odp_thread.c \
+ ../linux-generic/odp_ticketlock.c \
+ ../linux-generic/odp_time.c \
+ ../linux-generic/odp_timer.c
+
+endif
deleted file mode 100644
@@ -1,6 +0,0 @@
-# Copyright (c) 2013, Linaro Limited
-# All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-
-STD_LIBS += -ldl
new file mode 100644
@@ -0,0 +1,70 @@
+ODP-DPDK:
+---------
+ This effort is to port ODP on top of DPDK and use dpdk as the
+accelerator for all intel NIC's. Pre-requisite is DPDK should be cloned and
+compiled.
+
+# To Clone DPDK
+$ git clone http://92.243.14.124/git/dpdk ./dpdk
+# Ensure that dpdk is present at the same directory level as odp, that is, ./odp and ./dpdk
+# we support only 1.6.0r2 of dpdk for now
+$ git tag -l -- will list all the tags available
+$ git checkout tags/v1.6.0r2
+
+$ cd ./dpdk
+# Only for the first time
+$ make config T=x86_64-default-linuxapp-gcc O=my_sdk_build_dir
+set CONFIG_RTE_BUILD_COMBINE_LIBS=y in my_sdk_build_dir/.config
+
+Note: If not-intel SFP's are used in NIC, then go to my_sdk_build_dir/.config and set CONFIG_RTE_LIBRTE_IXGBE_ALLOW_UNSUPPORTED_SFP=y
+
+$ cd my_sdk_build_dir/
+$ make clean; make
+
+# To reserve huge pages which is needed for dpdk execute following command
+$ echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
+# If you are running on a multi-node machine then, hugepages should be reserved on each node
+$ echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
+
+$ sudo mkdir /mnt/huge
+$ sudo mount -t hugetlbfs nodev /mnt/huge
+# To load uio driver
+$ sudo /sbin/modprobe uio
+$ ulimit -Sn 2048
+
+# sudo insmod igb_uio.ko
+$ cd ./dpdk
+$ insmod ./build/build/lib/librte_eal/linuxapp/igb_uio/igb_uio.ko
+
+$ rmmod ixgbe
+$ modprobe ixgbe
+# If the SFP's used are non-intel, then
+$ modprobe ixgbe allow_unsupported_sfp=1
+
+$ cd ./dpdk
+$ ./tools/igb_uio_bind.py --status
+
+Now you should look for pci id listed and give it in the following command in
+place of 42:00.0
+
+# To give the interfaces to dpdk, use following command
+$ sudo ./tools/igb_uio_bind.py --bind=igb_uio 42:00.0
+$ sudo ./tools/igb_uio_bind.py --bind=igb_uio 42:00.1
+# To restore it back to kernel, use following command
+$ sudo ./tools/igb_uio_bind.py --bind=ixgbe 42:00.0
+$ sudo ./tools/igb_uio_bind.py --bind=ixgbe 42:00.1
+
+# To compile ODP with linux-dpdk
+$ ./bootstrap
+$ ./configure --with-platform=linux-dpdk
+$ make clean
+$ make
+
+# Commands to test
+l2fwding app - ./test/l2fwd/odp_l2fwd -i 0,1 -t 5 -m 0 -c 2
+loopback app - ./test/packet/odp_pktio -i 0,1 -t 5 -m 0 -c 2
+
+ -i 0,1 - interface number
+ -t 5 - dpdk type
+ -m 0 - burst mode
+ -c 2 - number of cpus
@@ -63,18 +63,11 @@ size_t odp_buffer_size(odp_buffer_t buf);
int odp_buffer_type(odp_buffer_t buf);
#define ODP_BUFFER_TYPE_INVALID (-1) /**< Buffer type invalid */
-#define ODP_BUFFER_TYPE_RAW 0 /**< Raw buffer */
-#define ODP_BUFFER_TYPE_PACKET 1 /**< Packet buffer */
-#define ODP_BUFFER_TYPE_TIMER 2 /**< Timer buffer */
-
-/**
- * Tests if buffer is part of a scatter/gather list
- *
- * @param buf Buffer handle
- *
- * @return 1 if belongs to a scatter list, otherwise 0
- */
-int odp_buffer_is_scatter(odp_buffer_t buf);
+#define ODP_BUFFER_TYPE_ANY 0 /**< Buffer that can hold any other
+ buffer type */
+#define ODP_BUFFER_TYPE_RAW 1 /**< Raw buffer, no additional metadata */
+#define ODP_BUFFER_TYPE_PACKET 2 /**< Packet buffer */
+#define ODP_BUFFER_TYPE_TIMEOUT 3 /**< Timeout buffer */
/**
* Tests if buffer is valid
new file mode 100644
@@ -0,0 +1,90 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp_buffer.h>
+#include <odp_buffer_internal.h>
+#include <odp_buffer_pool_internal.h>
+
+#include <string.h>
+#include <stdio.h>
+
+
+void *odp_buffer_addr(odp_buffer_t buf)
+{
+ odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf);
+
+ return hdr->buf_addr;
+}
+
+
+size_t odp_buffer_size(odp_buffer_t buf)
+{
+ odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf);
+
+ return hdr->buf_len;
+}
+
+
+int odp_buffer_type(odp_buffer_t buf)
+{
+ odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf);
+
+ return hdr->type;
+}
+
+
+int odp_buffer_is_valid(odp_buffer_t buf)
+{
+ odp_buffer_bits_t handle;
+
+ handle.u32 = buf;
+
+ return (handle.index != ODP_BUFFER_INVALID_INDEX);
+}
+
+
+int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf)
+{
+ odp_buffer_hdr_t *hdr;
+ int len = 0;
+
+ if (!odp_buffer_is_valid(buf)) {
+ printf("Buffer is not valid.\n");
+ return len;
+ }
+
+ hdr = odp_buf_to_hdr(buf);
+
+ len += snprintf(&str[len], n-len,
+ "Buffer\n");
+ len += snprintf(&str[len], n-len,
+ " pool %"PRIu64"\n", (int64_t) hdr->pool);
+ len += snprintf(&str[len], n-len,
+ " phy_addr %"PRIu64"\n", hdr->buf_physaddr);
+ len += snprintf(&str[len], n-len,
+ " addr %p\n", hdr->buf_addr);
+ len += snprintf(&str[len], n-len,
+ " size %u\n", hdr->buf_len);
+ len += snprintf(&str[len], n-len,
+ " ref_count %i\n", hdr->refcnt);
+ len += snprintf(&str[len], n-len,
+ " type %i\n", hdr->type);
+
+ return len;
+}
+
+
+void odp_buffer_print(odp_buffer_t buf)
+{
+ int max_len = 512;
+ char str[max_len];
+ int len;
+
+ len = odp_buffer_snprint(str, max_len-1, buf);
+ str[len] = 0;
+
+ printf("\n%s\n", str);
+}
new file mode 100644
@@ -0,0 +1,156 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp_std_types.h>
+#include <odp_buffer_pool.h>
+#include <odp_buffer_pool_internal.h>
+#include <odp_buffer_internal.h>
+#include <odp_packet_internal.h>
+#include <odp_shared_memory.h>
+#include <odp_align.h>
+#include <odp_internal.h>
+#include <odp_config.h>
+#include <odp_hints.h>
+#include <odp_debug.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+/* for DPDK */
+#include <odp_packet_dpdk.h>
+
+#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define NB_MBUF 8192
+
+#ifdef POOL_USE_TICKETLOCK
+#include <odp_ticketlock.h>
+#define LOCK(a) odp_ticketlock_lock(a)
+#define UNLOCK(a) odp_ticketlock_unlock(a)
+#define LOCK_INIT(a) odp_ticketlock_init(a)
+#else
+#include <odp_spinlock.h>
+#define LOCK(a) odp_spinlock_lock(a)
+#define UNLOCK(a) odp_spinlock_unlock(a)
+#define LOCK_INIT(a) odp_spinlock_init(a)
+#endif
+
+
+#if ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS
+#error ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS
+#endif
+
+#define NULL_INDEX ((uint32_t)-1)
+
+
+typedef union pool_entry_u {
+ struct pool_entry_s s;
+
+ uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct pool_entry_s))];
+
+} pool_entry_t;
+
+
+typedef struct pool_table_t {
+ pool_entry_t pool[ODP_CONFIG_BUFFER_POOLS];
+
+} pool_table_t;
+
+
+/* The pool table */
+static pool_table_t *pool_tbl;
+
+/* Pool entry pointers (for inlining) */
+void *pool_entry_ptr[ODP_CONFIG_BUFFER_POOLS];
+
+
+int odp_buffer_pool_init_global(void)
+{
+ odp_buffer_pool_t i;
+
+ pool_tbl = odp_shm_reserve("odp_buffer_pools",
+ sizeof(pool_table_t),
+ sizeof(pool_entry_t));
+
+ if (pool_tbl == NULL)
+ return -1;
+
+ memset(pool_tbl, 0, sizeof(pool_table_t));
+
+
+ for (i = 0; i < ODP_CONFIG_BUFFER_POOLS; i++) {
+ /* init locks */
+ pool_entry_t *pool = &pool_tbl->pool[i];
+ LOCK_INIT(&pool->s.lock);
+ pool->s.pool = i;
+
+ pool_entry_ptr[i] = pool;
+ }
+
+ ODP_DBG("\nBuffer pool init global\n");
+ ODP_DBG(" pool_entry_s size %zu\n", sizeof(struct pool_entry_s));
+ ODP_DBG(" pool_entry_t size %zu\n", sizeof(pool_entry_t));
+ ODP_DBG(" odp_buffer_hdr_t size %zu\n", sizeof(odp_buffer_hdr_t));
+ ODP_DBG("\n");
+
+ return 0;
+}
+
+
+odp_buffer_pool_t odp_buffer_pool_create(const char *name,
+ void *base_addr, uint64_t size,
+ size_t buf_size, size_t buf_align,
+ int buf_type)
+{
+ struct rte_mempool *pktmbuf_pool = NULL;
+ ODP_DBG("odp_buffer_pool_create: %s, %lx, %u, %u, %u, %d\n", name,
+ (uint64_t) base_addr, (unsigned) size,
+ (unsigned) buf_size, (unsigned) buf_align,
+ buf_type);
+
+ pktmbuf_pool =
+ rte_mempool_create(name, NB_MBUF,
+ MBUF_SIZE, 32,
+ sizeof(struct rte_pktmbuf_pool_private),
+ rte_pktmbuf_pool_init, NULL,
+ rte_pktmbuf_init, NULL,
+ rte_socket_id(), 0);
+ if (pktmbuf_pool == NULL) {
+ ODP_ERR("Cannot init DPDK mbuf pool\n");
+ return -1;
+ }
+
+ return (odp_buffer_pool_t) pktmbuf_pool;
+}
+
+
+odp_buffer_pool_t odp_buffer_pool_lookup(const char *name)
+{
+ struct rte_mempool *mp = NULL;
+
+ mp = rte_mempool_lookup(name);
+ if (mp == NULL)
+ return ODP_BUFFER_POOL_INVALID;
+
+ return (odp_buffer_pool_t)mp;
+}
+
+
+odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool_id)
+{
+ return (odp_buffer_t)rte_pktmbuf_alloc((struct rte_mempool *)pool_id);
+}
+
+
+void odp_buffer_free(odp_buffer_t buf)
+{
+ rte_pktmbuf_free((struct rte_mbuf *)buf);
+}
+
+
+void odp_buffer_pool_print(odp_buffer_pool_t pool_id)
+{
+ rte_mempool_dump((const struct rte_mempool *)pool_id);
+}
new file mode 100644
@@ -0,0 +1,113 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp_init.h>
+#include <odp_internal.h>
+#include <odp_debug.h>
+#include <odp_packet_dpdk.h>
+
+int odp_init_dpdk(void)
+{
+ int test_argc = 5;
+ char *test_argv[6];
+ int core_count, i, num_cores = 0;
+ char core_mask[8];
+
+ core_count = odp_sys_core_count();
+ for (i = 0; i < core_count; i++)
+ num_cores += (0x1 << i);
+ sprintf(core_mask, "%x", num_cores);
+
+ test_argv[0] = malloc(sizeof("odp_dpdk"));
+ strcpy(test_argv[0], "odp_dpdk");
+ test_argv[1] = malloc(sizeof("-c"));
+ strcpy(test_argv[1], "-c");
+ test_argv[2] = malloc(sizeof(core_mask));
+ strcpy(test_argv[2], core_mask);
+ test_argv[3] = malloc(sizeof("-n"));
+ strcpy(test_argv[3], "-n");
+ test_argv[4] = malloc(sizeof("3"));
+ strcpy(test_argv[4], "3");
+
+ if (rte_eal_init(test_argc, (char **)test_argv) < 0) {
+ ODP_ERR("Cannot init the Intel DPDK EAL!");
+ return -1;
+ }
+
+ if (rte_pmd_init_all() < 0) {
+ ODP_ERR("Cannot init pmd\n");
+ return -1;
+ }
+
+ if (rte_eal_pci_probe() < 0) {
+ ODP_ERR("Cannot probe PCI\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int odp_init_global(void)
+{
+ odp_thread_init_global();
+
+ odp_system_info_init();
+
+ if (odp_init_dpdk()) {
+ ODP_ERR("ODP dpdk init failed.\n");
+ return -1;
+ }
+
+ if (odp_shm_init_global()) {
+ ODP_ERR("ODP shm init failed.\n");
+ return -1;
+ }
+
+ if (odp_buffer_pool_init_global()) {
+ ODP_ERR("ODP buffer pool init failed.\n");
+ return -1;
+ }
+
+ if (odp_queue_init_global()) {
+ ODP_ERR("ODP queue init failed.\n");
+ return -1;
+ }
+
+ if (odp_schedule_init_global()) {
+ ODP_ERR("ODP schedule init failed.\n");
+ return -1;
+ }
+
+ if (odp_pktio_init_global()) {
+ ODP_ERR("ODP packet io init failed.\n");
+ return -1;
+ }
+
+ if (odp_timer_init_global()) {
+ ODP_ERR("ODP timer init failed.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int odp_init_local(int thr_id)
+{
+ odp_thread_init_local(thr_id);
+
+ if (odp_pktio_init_local()) {
+ ODP_ERR("ODP packet io local init failed.\n");
+ return -1;
+ }
+
+ if (odp_schedule_init_local()) {
+ ODP_ERR("ODP schedule local init failed.\n");
+ return -1;
+ }
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,96 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <sched.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include <helper/odp_linux.h>
+#include <odp_internal.h>
+#include <odp_thread.h>
+#include <odp_init.h>
+#include <odp_system_info.h>
+
+#include <rte_lcore.h>
+
+typedef struct {
+ int thr_id;
+ void *(*start_routine) (void *);
+ void *arg;
+
+} odp_start_args_t;
+
+
+static void *odp_run_start_routine(void *arg)
+{
+ odp_start_args_t *start_args = arg;
+
+ /* ODP thread local init */
+ odp_init_local(start_args->thr_id);
+
+ return start_args->start_routine(start_args->arg);
+}
+
+
+void odp_linux_pthread_create(odp_linux_pthread_t *thread_tbl, int num,
+ int first_core, void *(*start_routine) (void *), void *arg)
+{
+ int i;
+ cpu_set_t cpu_set;
+ odp_start_args_t *start_args;
+ int core_count;
+ int cpu;
+
+ (void) cpu_set;
+ (void) thread_tbl;
+
+ core_count = odp_sys_core_count();
+
+ assert((first_core >= 0) && (first_core < core_count));
+ assert((num >= 0) && (num <= core_count));
+
+ for (i = 0; i < num; i++) {
+ cpu = (first_core + i) % core_count;
+
+ start_args = malloc(sizeof(odp_start_args_t));
+ memset(start_args, 0, sizeof(odp_start_args_t));
+ start_args->start_routine = start_routine;
+ start_args->arg = arg;
+
+ odp_thread_create(cpu);
+ start_args->thr_id = cpu;
+ /* If not master core */
+ if (cpu != 0) {
+ rte_eal_remote_launch(
+ (int(*)(void *))odp_run_start_routine,
+ start_args, cpu);
+ } else {
+ lcore_config[cpu].ret = (int)(uint64_t)
+ odp_run_start_routine(start_args);
+ lcore_config[cpu].state = FINISHED;
+ }
+ }
+}
+
+
+void odp_linux_pthread_join(odp_linux_pthread_t *thread_tbl, int num)
+{
+ uint32_t lcore_id;
+
+ (void) thread_tbl;
+ (void) num;
+
+ RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+ if (rte_eal_wait_lcore(lcore_id) < 0)
+ return;
+ }
+}
new file mode 100644
@@ -0,0 +1,374 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp_packet.h>
+#include <odp_packet_internal.h>
+#include <odp_hints.h>
+#include <odp_byteorder.h>
+
+#include <helper/odp_eth.h>
+#include <helper/odp_ip.h>
+
+#include <string.h>
+#include <stdio.h>
+
+static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4,
+ size_t *offset_out);
+static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6,
+ size_t *offset_out);
+
+void odp_packet_init(odp_packet_t pkt)
+{
+ odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt);
+ const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr);
+ uint8_t *start;
+ size_t len;
+
+ start = (uint8_t *)pkt_hdr + start_offset;
+ len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset;
+ memset(start, 0, len);
+
+ pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
+ pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
+ pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
+}
+
+odp_packet_t odp_packet_from_buffer(odp_buffer_t buf)
+{
+ return (odp_packet_t)buf;
+}
+
+odp_buffer_t odp_buffer_from_packet(odp_packet_t pkt)
+{
+ return (odp_buffer_t)pkt;
+}
+
+void odp_packet_set_len(odp_packet_t pkt, size_t len)
+{
+ /* for rte_pktmbuf */
+ odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(odp_buffer_from_packet(pkt));
+ buf_hdr->pkt.data_len = len;
+
+ odp_packet_hdr(pkt)->frame_len = len;
+}
+
+size_t odp_packet_get_len(odp_packet_t pkt)
+{
+ return odp_packet_hdr(pkt)->frame_len;
+}
+
+uint8_t *odp_packet_buf_addr(odp_packet_t pkt)
+{
+ return odp_buffer_addr(odp_buffer_from_packet(pkt));
+}
+
+uint8_t *odp_packet_start(odp_packet_t pkt)
+{
+ return odp_packet_buf_addr(pkt) + odp_packet_hdr(pkt)->frame_offset;
+}
+
+
+uint8_t *odp_packet_l2(odp_packet_t pkt)
+{
+ const size_t offset = odp_packet_l2_offset(pkt);
+
+ if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
+ return NULL;
+
+ return odp_packet_buf_addr(pkt) + offset;
+}
+
+size_t odp_packet_l2_offset(odp_packet_t pkt)
+{
+ return odp_packet_hdr(pkt)->l2_offset;
+}
+
+void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset)
+{
+ odp_packet_hdr(pkt)->l2_offset = offset;
+}
+
+uint8_t *odp_packet_l3(odp_packet_t pkt)
+{
+ const size_t offset = odp_packet_l3_offset(pkt);
+
+ if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
+ return NULL;
+
+ return odp_packet_buf_addr(pkt) + offset;
+}
+
+size_t odp_packet_l3_offset(odp_packet_t pkt)
+{
+ return odp_packet_hdr(pkt)->l3_offset;
+}
+
+void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset)
+{
+ odp_packet_hdr(pkt)->l3_offset = offset;
+}
+
+uint8_t *odp_packet_l4(odp_packet_t pkt)
+{
+ const size_t offset = odp_packet_l4_offset(pkt);
+
+ if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
+ return NULL;
+
+ return odp_packet_buf_addr(pkt) + offset;
+}
+
+size_t odp_packet_l4_offset(odp_packet_t pkt)
+{
+ return odp_packet_hdr(pkt)->l4_offset;
+}
+
+void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset)
+{
+ odp_packet_hdr(pkt)->l4_offset = offset;
+}
+
+/**
+ * Simple packet parser: eth, VLAN, IP, TCP/UDP/ICMP
+ *
+ * Internal function: caller is resposible for passing only valid packet handles
+ * , lengths and offsets (usually done&called in packet input).
+ *
+ * @param pkt Packet handle
+ * @param len Packet length in bytes
+ * @param frame_offset Byte offset to L2 header
+ */
+void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset)
+{
+ odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt);
+ odp_ethhdr_t *eth;
+ odp_vlanhdr_t *vlan;
+ odp_ipv4hdr_t *ipv4;
+ odp_ipv6hdr_t *ipv6;
+ uint16_t ethtype;
+ size_t offset = 0;
+ uint8_t ip_proto = 0;
+
+ pkt_hdr->input_flags.eth = 1;
+ pkt_hdr->frame_offset = frame_offset;
+ pkt_hdr->frame_len = len;
+
+ if (odp_unlikely(len < ODP_ETH_LEN_MIN)) {
+ pkt_hdr->error_flags.frame_len = 1;
+ return;
+ } else if (len > ODP_ETH_LEN_MAX) {
+ pkt_hdr->input_flags.jumbo = 1;
+ }
+
+ /* Assume valid L2 header, no CRC/FCS check in SW */
+ pkt_hdr->input_flags.l2 = 1;
+ pkt_hdr->l2_offset = frame_offset;
+
+ eth = (odp_ethhdr_t *)odp_packet_start(pkt);
+ ethtype = odp_be_to_cpu_16(eth->type);
+ vlan = (odp_vlanhdr_t *)ð->type;
+
+ if (ethtype == ODP_ETHTYPE_VLAN_OUTER) {
+ pkt_hdr->input_flags.vlan_qinq = 1;
+ ethtype = odp_be_to_cpu_16(vlan->tpid);
+ offset += sizeof(odp_vlanhdr_t);
+ vlan = &vlan[1];
+ }
+
+ if (ethtype == ODP_ETHTYPE_VLAN) {
+ pkt_hdr->input_flags.vlan = 1;
+ ethtype = odp_be_to_cpu_16(vlan->tpid);
+ offset += sizeof(odp_vlanhdr_t);
+ }
+
+ /* Set l3_offset+flag only for known ethtypes */
+ switch (ethtype) {
+ case ODP_ETHTYPE_IPV4:
+ pkt_hdr->input_flags.ipv4 = 1;
+ pkt_hdr->input_flags.l3 = 1;
+ pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset;
+ ipv4 = (odp_ipv4hdr_t *)odp_packet_l3(pkt);
+ ip_proto = parse_ipv4(pkt_hdr, ipv4, &offset);
+ break;
+ case ODP_ETHTYPE_IPV6:
+ pkt_hdr->input_flags.ipv6 = 1;
+ pkt_hdr->input_flags.l3 = 1;
+ pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset;
+ ipv6 = (odp_ipv6hdr_t *)odp_packet_l3(pkt);
+ ip_proto = parse_ipv6(pkt_hdr, ipv6, &offset);
+ break;
+ case ODP_ETHTYPE_ARP:
+ pkt_hdr->input_flags.arp = 1;
+ /* fall through */
+ default:
+ ip_proto = 0;
+ break;
+ }
+
+ switch (ip_proto) {
+ case ODP_IPPROTO_UDP:
+ pkt_hdr->input_flags.udp = 1;
+ pkt_hdr->input_flags.l4 = 1;
+ pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset;
+ break;
+ case ODP_IPPROTO_TCP:
+ pkt_hdr->input_flags.tcp = 1;
+ pkt_hdr->input_flags.l4 = 1;
+ pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset;
+ break;
+ case ODP_IPPROTO_SCTP:
+ pkt_hdr->input_flags.sctp = 1;
+ pkt_hdr->input_flags.l4 = 1;
+ pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset;
+ break;
+ case ODP_IPPROTO_ICMP:
+ pkt_hdr->input_flags.icmp = 1;
+ pkt_hdr->input_flags.l4 = 1;
+ pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset;
+ break;
+ default:
+ /* 0 or unhandled IP protocols, don't set L4 flag+offset */
+ if (pkt_hdr->input_flags.ipv6) {
+ /* IPv6 next_hdr is not L4, mark as IP-option instead */
+ pkt_hdr->input_flags.ipopt = 1;
+ }
+ break;
+ }
+}
+
+static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4,
+ size_t *offset_out)
+{
+ uint8_t ihl;
+ uint16_t frag_offset;
+
+ ihl = ODP_IPV4HDR_IHL(ipv4->ver_ihl);
+ if (odp_unlikely(ihl < ODP_IPV4HDR_IHL_MIN)) {
+ pkt_hdr->error_flags.ip_err = 1;
+ return 0;
+ }
+
+ if (odp_unlikely(ihl > ODP_IPV4HDR_IHL_MIN)) {
+ pkt_hdr->input_flags.ipopt = 1;
+ return 0;
+ }
+
+ /* A packet is a fragment if:
+ * "more fragments" flag is set (all fragments except the last)
+ * OR
+ * "fragment offset" field is nonzero (all fragments except the first)
+ */
+ frag_offset = odp_be_to_cpu_16(ipv4->frag_offset);
+ if (odp_unlikely(ODP_IPV4HDR_IS_FRAGMENT(frag_offset))) {
+ pkt_hdr->input_flags.ipfrag = 1;
+ return 0;
+ }
+
+ if (ipv4->proto == ODP_IPPROTO_ESP ||
+ ipv4->proto == ODP_IPPROTO_AH) {
+ pkt_hdr->input_flags.ipsec = 1;
+ return 0;
+ }
+
+ /* Set pkt_hdr->input_flags.ipopt when checking L4 hdrs after return */
+
+ *offset_out = sizeof(uint32_t) * ihl;
+ return ipv4->proto;
+}
+
+static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6,
+ size_t *offset_out)
+{
+ if (ipv6->next_hdr == ODP_IPPROTO_ESP ||
+ ipv6->next_hdr == ODP_IPPROTO_AH) {
+ pkt_hdr->input_flags.ipopt = 1;
+ pkt_hdr->input_flags.ipsec = 1;
+ return 0;
+ }
+
+ if (odp_unlikely(ipv6->next_hdr == ODP_IPPROTO_FRAG)) {
+ pkt_hdr->input_flags.ipopt = 1;
+ pkt_hdr->input_flags.ipfrag = 1;
+ return 0;
+ }
+
+ /* Don't step through more extensions */
+ *offset_out = ODP_IPV6HDR_LEN;
+ return ipv6->next_hdr;
+}
+
+void odp_packet_print(odp_packet_t pkt)
+{
+ int max_len = 512;
+ char str[max_len];
+ int len = 0;
+ int n = max_len-1;
+ odp_packet_hdr_t *hdr = odp_packet_hdr(pkt);
+
+ len += snprintf(&str[len], n-len, "Packet ");
+ len += odp_buffer_snprint(&str[len], n-len, (odp_buffer_t) pkt);
+ len += snprintf(&str[len], n-len,
+ " input_flags 0x%x\n", hdr->input_flags.all);
+ len += snprintf(&str[len], n-len,
+ " error_flags 0x%x\n", hdr->error_flags.all);
+ len += snprintf(&str[len], n-len,
+ " output_flags 0x%x\n", hdr->output_flags.all);
+ len += snprintf(&str[len], n-len,
+ " frame_offset %u\n", hdr->frame_offset);
+ len += snprintf(&str[len], n-len,
+ " l2_offset %u\n", hdr->l2_offset);
+ len += snprintf(&str[len], n-len,
+ " l3_offset %u\n", hdr->l3_offset);
+ len += snprintf(&str[len], n-len,
+ " l4_offset %u\n", hdr->l4_offset);
+ len += snprintf(&str[len], n-len,
+ " frame_len %u\n", hdr->frame_len);
+ len += snprintf(&str[len], n-len,
+ " input %u\n", hdr->input);
+ str[len] = '\0';
+
+ printf("\n%s\n", str);
+}
+
+int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src)
+{
+ odp_packet_hdr_t *const pkt_hdr_dst = odp_packet_hdr(pkt_dst);
+ odp_packet_hdr_t *const pkt_hdr_src = odp_packet_hdr(pkt_src);
+ const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr);
+ uint8_t *start_src;
+ uint8_t *start_dst;
+ size_t len;
+
+ if (pkt_dst == ODP_PACKET_INVALID || pkt_src == ODP_PACKET_INVALID)
+ return -1;
+
+ /* if (pkt_hdr_dst->buf_hdr.size < */
+ /* pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) */
+ if (pkt_hdr_dst->buf_hdr.buf_len <
+ pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset)
+ return -1;
+
+ /* Copy packet header */
+ start_dst = (uint8_t *)pkt_hdr_dst + start_offset;
+ start_src = (uint8_t *)pkt_hdr_src + start_offset;
+ len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset;
+ memcpy(start_dst, start_src, len);
+
+ /* Copy frame payload */
+ start_dst = (uint8_t *)odp_packet_start(pkt_dst);
+ start_src = (uint8_t *)odp_packet_start(pkt_src);
+ len = pkt_hdr_src->frame_len;
+ memcpy(start_dst, start_src, len);
+
+ /* Copy useful things from the buffer header */
+ /* pkt_hdr_dst->buf_hdr.cur_offset = pkt_hdr_src->buf_hdr.cur_offset; */
+
+ /* Create a copy of the scatter list */
+ /* odp_buffer_copy_scatter(odp_buffer_from_packet(pkt_dst), */
+ /* odp_buffer_from_packet(pkt_src)); */
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,189 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <poll.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <linux/ethtool.h>
+#include <linux/sockios.h>
+
+#include <odp_hints.h>
+#include <odp_thread.h>
+
+#include <odp_packet_dpdk.h>
+#include <net/if.h>
+
+/*
+ * RX and TX Prefetch, Host, and Write-back threshold values should be
+ * carefully set for optimal performance. Consult the network
+ * controller's datasheet and supporting DPDK documentation for guidance
+ * on how these parameters should be set.
+ */
+#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */
+#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */
+#define RX_WTHRESH 4 /**< Default values of RX write-back threshold reg. */
+
+/*
+ * These default values are optimized for use with the Intel(R) 82599 10 GbE
+ * Controller and the DPDK ixgbe PMD. Consider using other values for other
+ * network controllers and/or network drivers.
+ */
+#define TX_PTHRESH 36 /**< Default values of TX prefetch threshold reg. */
+#define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */
+#define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */
+
+#define MAX_PKT_BURST 16
+#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
+#define RTE_TEST_RX_DESC_DEFAULT 128
+#define RTE_TEST_TX_DESC_DEFAULT 512
+static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
+static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
+
+static const struct rte_eth_conf port_conf = {
+ .rxmode = {
+ .split_hdr_size = 0,
+ .header_split = 0, /**< Header Split disabled */
+ .hw_ip_checksum = 0, /**< IP checksum offload disabled */
+ .hw_vlan_filter = 0, /**< VLAN filtering disabled */
+ .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
+ .hw_strip_crc = 0, /**< CRC stripped by hardware */
+ },
+ .txmode = {
+ .mq_mode = ETH_MQ_TX_NONE,
+ },
+};
+
+static const struct rte_eth_rxconf rx_conf = {
+ .rx_thresh = {
+ .pthresh = RX_PTHRESH,
+ .hthresh = RX_HTHRESH,
+ .wthresh = RX_WTHRESH,
+ },
+};
+
+static const struct rte_eth_txconf tx_conf = {
+ .tx_thresh = {
+ .pthresh = TX_PTHRESH,
+ .hthresh = TX_HTHRESH,
+ .wthresh = TX_WTHRESH,
+ },
+ .tx_free_thresh = 0, /* Use PMD default values */
+ .tx_rs_thresh = 0, /* Use PMD default values */
+ /*
+ * As the example won't handle mult-segments and offload cases,
+ * set the flag by default.
+ */
+ .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOOFFLOADS,
+};
+
+int setup_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, const char *netdev,
+ odp_buffer_pool_t pool)
+{
+ ODP_DBG("setup_pkt_dpdk\n");
+
+ static struct ether_addr eth_addr[RTE_MAX_ETHPORTS];
+ uint8_t portid = 0;
+ uint16_t queueid = 0;
+ int ret;
+ printf("dpdk netdev: %s\n", netdev);
+ printf("dpdk pool: %lx\n", pool);
+
+ portid = atoi(netdev);
+ pkt_dpdk->portid = portid;
+ pkt_dpdk->queueid = queueid;
+ pkt_dpdk->pool = pool;
+ printf("dpdk portid: %u\n", portid);
+
+ fflush(stdout);
+ ret = rte_eth_dev_configure(portid, 1, 1, &port_conf);
+ if (ret < 0)
+ ODP_ERR("Cannot configure device: err=%d, port=%u\n",
+ ret, (unsigned) portid);
+
+ rte_eth_macaddr_get(portid, ð_addr[portid]);
+ ODP_DBG("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n",
+ (unsigned) portid,
+ eth_addr[portid].addr_bytes[0],
+ eth_addr[portid].addr_bytes[1],
+ eth_addr[portid].addr_bytes[2],
+ eth_addr[portid].addr_bytes[3],
+ eth_addr[portid].addr_bytes[4],
+ eth_addr[portid].addr_bytes[5]);
+
+ /* init one RX queue on each port */
+ fflush(stdout);
+ ret = rte_eth_rx_queue_setup(portid, queueid, nb_rxd,
+ rte_eth_dev_socket_id(portid), &rx_conf,
+ (struct rte_mempool *)pool);
+ if (ret < 0)
+ ODP_ERR("rte_eth_rx_queue_setup:err=%d, port=%u\n",
+ ret, (unsigned) portid);
+ ODP_DBG("dpdk rx queue setup done\n");
+
+ /* init one TX queue on each port */
+ fflush(stdout);
+ ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
+ rte_eth_dev_socket_id(portid), &tx_conf);
+ if (ret < 0)
+ ODP_ERR("rte_eth_tx_queue_setup:err=%d, port=%u\n",
+ ret, (unsigned) portid);
+ ODP_DBG("dpdk tx queue setup done\n");
+
+ /* Start device */
+ ret = rte_eth_dev_start(portid);
+ if (ret < 0)
+ ODP_ERR("rte_eth_dev_start:err=%d, port=%u\n",
+ ret, (unsigned) portid);
+ ODP_DBG("dpdk setup done\n\n");
+
+
+ return 0;
+}
+
+int close_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk)
+{
+ ODP_DBG("close pkt_dpdk, %u\n", pkt_dpdk->portid);
+
+ return 0;
+}
+
+int recv_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[],
+ unsigned len)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ uint16_t nb_rx, i = 0;
+
+ memset(pkts_burst, 0 , sizeof(pkts_burst));
+ nb_rx = rte_eth_rx_burst((uint8_t)pkt_dpdk->portid,
+ (uint16_t)pkt_dpdk->queueid,
+ (struct rte_mbuf **)pkts_burst, (uint16_t)len);
+ for (i = 0; i < nb_rx; i++)
+ pkt_table[i] = (odp_packet_t)pkts_burst[i];
+ return nb_rx;
+}
+
+int send_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[],
+ unsigned len)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ uint16_t i;
+
+ for (i = 0; i < len; i++)
+ pkts_burst[i] = (struct rte_mbuf *)pkt_table[i];
+ return rte_eth_tx_burst((uint8_t)pkt_dpdk->portid,
+ (uint16_t)pkt_dpdk->queueid,
+ (struct rte_mbuf **)pkts_burst, (uint16_t)len);
+}
new file mode 100644
@@ -0,0 +1,561 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp_packet_io.h>
+#include <odp_packet_io_internal.h>
+#include <odp_packet_io_queue.h>
+#include <odp_packet.h>
+#include <odp_packet_internal.h>
+#include <odp_internal.h>
+#include <odp_spinlock.h>
+#include <odp_shared_memory.h>
+#include <odp_packet_socket.h>
+#ifdef ODP_HAVE_NETMAP
+#include <odp_packet_netmap.h>
+#endif
+#include <odp_hints.h>
+#include <odp_config.h>
+#include <odp_queue_internal.h>
+#include <odp_schedule_internal.h>
+#include <odp_debug.h>
+
+#include <odp_pktio_socket.h>
+#ifdef ODP_HAVE_NETMAP
+#include <odp_pktio_netmap.h>
+#endif
+
+#include <string.h>
+
+typedef struct {
+ pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES];
+} pktio_table_t;
+
+static pktio_table_t *pktio_tbl;
+
+
+static pktio_entry_t *get_entry(odp_pktio_t id)
+{
+ if (odp_unlikely(id == ODP_PKTIO_INVALID ||
+ id > ODP_CONFIG_PKTIO_ENTRIES))
+ return NULL;
+
+ return &pktio_tbl->entries[id - 1];
+}
+
+int odp_pktio_init_global(void)
+{
+ char name[ODP_QUEUE_NAME_LEN];
+ pktio_entry_t *pktio_entry;
+ queue_entry_t *queue_entry;
+ odp_queue_t qid;
+ int id;
+
+ pktio_tbl = odp_shm_reserve("odp_pktio_entries",
+ sizeof(pktio_table_t),
+ sizeof(pktio_entry_t));
+ if (pktio_tbl == NULL)
+ return -1;
+
+ memset(pktio_tbl, 0, sizeof(pktio_table_t));
+
+ for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) {
+ pktio_entry = get_entry(id);
+
+ odp_spinlock_init(&pktio_entry->s.lock);
+
+ /* Create a default output queue for each pktio resource */
+ snprintf(name, sizeof(name), "%i-pktio_outq_default", (int)id);
+ name[ODP_QUEUE_NAME_LEN-1] = '\0';
+
+ qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL);
+ if (qid == ODP_QUEUE_INVALID)
+ return -1;
+ pktio_entry->s.outq_default = qid;
+
+ queue_entry = queue_to_qentry(qid);
+ queue_entry->s.pktout = id;
+ }
+
+ return 0;
+}
+
+int odp_pktio_init_local(void)
+{
+ return 0;
+}
+
+static int is_free(pktio_entry_t *entry)
+{
+ return (entry->s.taken == 0);
+}
+
+static void set_free(pktio_entry_t *entry)
+{
+ entry->s.taken = 0;
+}
+
+static void set_taken(pktio_entry_t *entry)
+{
+ entry->s.taken = 1;
+}
+
+static void lock_entry(pktio_entry_t *entry)
+{
+ odp_spinlock_lock(&entry->s.lock);
+}
+
+static void unlock_entry(pktio_entry_t *entry)
+{
+ odp_spinlock_unlock(&entry->s.lock);
+}
+
+static void init_pktio_entry(pktio_entry_t *entry, odp_pktio_params_t *params)
+{
+ set_taken(entry);
+ entry->s.inq_default = ODP_QUEUE_INVALID;
+ switch (params->type) {
+ case ODP_PKTIO_TYPE_SOCKET_BASIC:
+ case ODP_PKTIO_TYPE_SOCKET_MMSG:
+ case ODP_PKTIO_TYPE_SOCKET_MMAP:
+ memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock));
+ memset(&entry->s.pkt_sock_mmap, 0,
+ sizeof(entry->s.pkt_sock_mmap));
+ break;
+#ifdef ODP_HAVE_NETMAP
+ case ODP_PKTIO_TYPE_NETMAP:
+ memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm));
+ break;
+#endif
+ case ODP_PKTIO_TYPE_DPDK:
+ memset(&entry->s.pkt_dpdk, 0, sizeof(entry->s.pkt_dpdk));
+ break;
+ default:
+ ODP_ERR("Packet I/O type not supported. Please recompile\n");
+ break;
+ }
+ /* Save pktio parameters, type is the most useful */
+ memcpy(&entry->s.params, params, sizeof(*params));
+}
+
+static odp_pktio_t alloc_lock_pktio_entry(odp_pktio_params_t *params)
+{
+ odp_pktio_t id;
+ pktio_entry_t *entry;
+ int i;
+
+ for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) {
+ entry = &pktio_tbl->entries[i];
+ if (is_free(entry)) {
+ lock_entry(entry);
+ if (is_free(entry)) {
+ init_pktio_entry(entry, params);
+ id = i + 1;
+ return id; /* return with entry locked! */
+ }
+ unlock_entry(entry);
+ }
+ }
+
+ return ODP_PKTIO_INVALID;
+}
+
+static int free_pktio_entry(odp_pktio_t id)
+{
+ pktio_entry_t *entry = get_entry(id);
+
+ if (entry == NULL)
+ return -1;
+
+ set_free(entry);
+
+ return 0;
+}
+
+odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool,
+ odp_pktio_params_t *params)
+{
+ odp_pktio_t id;
+ pktio_entry_t *pktio_entry;
+ int res;
+
+ if (params == NULL) {
+ ODP_ERR("Invalid pktio params\n");
+ return ODP_PKTIO_INVALID;
+ }
+
+ switch (params->type) {
+ case ODP_PKTIO_TYPE_SOCKET_BASIC:
+ case ODP_PKTIO_TYPE_SOCKET_MMSG:
+ case ODP_PKTIO_TYPE_SOCKET_MMAP:
+ ODP_DBG("Allocating socket pktio\n");
+ break;
+#ifdef ODP_HAVE_NETMAP
+ case ODP_PKTIO_TYPE_NETMAP:
+ ODP_DBG("Allocating netmap pktio\n");
+ break;
+#endif
+ case ODP_PKTIO_TYPE_DPDK:
+ ODP_DBG("Allocating dpdk pktio\n");
+ break;
+ default:
+ ODP_ERR("Invalid pktio type: %02x\n", params->type);
+ return ODP_PKTIO_INVALID;
+ }
+
+ id = alloc_lock_pktio_entry(params);
+ if (id == ODP_PKTIO_INVALID) {
+ ODP_ERR("No resources available.\n");
+ return ODP_PKTIO_INVALID;
+ }
+ /* if successful, alloc_pktio_entry() returns with the entry locked */
+
+ pktio_entry = get_entry(id);
+
+ switch (params->type) {
+ case ODP_PKTIO_TYPE_SOCKET_BASIC:
+ case ODP_PKTIO_TYPE_SOCKET_MMSG:
+ res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool);
+ if (res == -1) {
+ close_pkt_sock(&pktio_entry->s.pkt_sock);
+ free_pktio_entry(id);
+ id = ODP_PKTIO_INVALID;
+ }
+ break;
+ case ODP_PKTIO_TYPE_SOCKET_MMAP:
+ res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, dev,
+ pool, params->sock_params.fanout);
+ if (res == -1) {
+ close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap);
+ free_pktio_entry(id);
+ id = ODP_PKTIO_INVALID;
+ }
+ break;
+#ifdef ODP_HAVE_NETMAP
+ case ODP_PKTIO_TYPE_NETMAP:
+
+ res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev,
+ pool, ¶ms->nm_params);
+ if (res == -1) {
+ close_pkt_netmap(&pktio_entry->s.pkt_nm);
+ free_pktio_entry(id);
+ id = ODP_PKTIO_INVALID;
+ }
+ break;
+#endif
+ case ODP_PKTIO_TYPE_DPDK:
+ res = setup_pkt_dpdk(&pktio_entry->s.pkt_dpdk, dev, pool);
+ if (res == -1) {
+ close_pkt_dpdk(&pktio_entry->s.pkt_dpdk);
+ free_pktio_entry(id);
+ id = ODP_PKTIO_INVALID;
+ }
+ break;
+ default:
+ free_pktio_entry(id);
+ id = ODP_PKTIO_INVALID;
+ ODP_ERR("Invalid pktio type. Please recompile.\n");
+ break;
+ }
+
+ unlock_entry(pktio_entry);
+ return id;
+}
+
+int odp_pktio_close(odp_pktio_t id)
+{
+ pktio_entry_t *entry;
+ int res = -1;
+
+ entry = get_entry(id);
+ if (entry == NULL)
+ return -1;
+
+ lock_entry(entry);
+ if (!is_free(entry)) {
+ switch (entry->s.params.type) {
+ case ODP_PKTIO_TYPE_SOCKET_BASIC:
+ case ODP_PKTIO_TYPE_SOCKET_MMSG:
+ res = close_pkt_sock(&entry->s.pkt_sock);
+ break;
+ case ODP_PKTIO_TYPE_SOCKET_MMAP:
+ res = close_pkt_sock_mmap(&entry->s.pkt_sock_mmap);
+ break;
+#ifdef ODP_HAVE_NETMAP
+ case ODP_PKTIO_TYPE_NETMAP:
+ res = close_pkt_netmap(&entry->s.pkt_nm);
+ break;
+#endif
+ case ODP_PKTIO_TYPE_DPDK:
+ res = close_pkt_dpdk(&entry->s.pkt_dpdk);
+ break;
+ default:
+ break;
+ res |= free_pktio_entry(id);
+ }
+ }
+ unlock_entry(entry);
+
+ if (res != 0)
+ return -1;
+
+ return 0;
+}
+
+void odp_pktio_set_input(odp_packet_t pkt, odp_pktio_t pktio)
+{
+ odp_packet_hdr(pkt)->input = pktio;
+}
+
+odp_pktio_t odp_pktio_get_input(odp_packet_t pkt)
+{
+ return odp_packet_hdr(pkt)->input;
+}
+
+int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len)
+{
+ pktio_entry_t *pktio_entry = get_entry(id);
+ int pkts;
+ int i;
+
+ if (pktio_entry == NULL)
+ return -1;
+
+ lock_entry(pktio_entry);
+ switch (pktio_entry->s.params.type) {
+ case ODP_PKTIO_TYPE_SOCKET_BASIC:
+ pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock,
+ pkt_table, len);
+ break;
+ case ODP_PKTIO_TYPE_SOCKET_MMSG:
+ pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock,
+ pkt_table, len);
+ break;
+ case ODP_PKTIO_TYPE_SOCKET_MMAP:
+ pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap,
+ pkt_table, len);
+ break;
+#ifdef ODP_HAVE_NETMAP
+ case ODP_PKTIO_TYPE_NETMAP:
+ pkts = recv_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, len);
+ break;
+#endif
+ case ODP_PKTIO_TYPE_DPDK:
+ pkts = recv_pkt_dpdk(&pktio_entry->s.pkt_dpdk, pkt_table, len);
+ break;
+ default:
+ pkts = -1;
+ break;
+ }
+
+ unlock_entry(pktio_entry);
+ if (pkts < 0)
+ return pkts;
+
+ for (i = 0; i < pkts; ++i)
+ odp_pktio_set_input(pkt_table[i], id);
+
+ return pkts;
+}
+
+int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len)
+{
+ pktio_entry_t *pktio_entry = get_entry(id);
+ int pkts;
+
+ if (pktio_entry == NULL)
+ return -1;
+
+ lock_entry(pktio_entry);
+ switch (pktio_entry->s.params.type) {
+ case ODP_PKTIO_TYPE_SOCKET_BASIC:
+ pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock,
+ pkt_table, len);
+ break;
+ case ODP_PKTIO_TYPE_SOCKET_MMSG:
+ pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock,
+ pkt_table, len);
+ break;
+ case ODP_PKTIO_TYPE_SOCKET_MMAP:
+ pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap,
+ pkt_table, len);
+ break;
+#ifdef ODP_HAVE_NETMAP
+ case ODP_PKTIO_TYPE_NETMAP:
+ pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm,
+ pkt_table, len);
+ break;
+#endif
+ case ODP_PKTIO_TYPE_DPDK:
+ pkts = send_pkt_dpdk(&pktio_entry->s.pkt_dpdk,
+ pkt_table, len);
+ break;
+ default:
+ pkts = -1;
+ }
+ unlock_entry(pktio_entry);
+
+ return pkts;
+}
+
+int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue)
+{
+ pktio_entry_t *pktio_entry = get_entry(id);
+ queue_entry_t *qentry = queue_to_qentry(queue);
+
+ if (pktio_entry == NULL || qentry == NULL)
+ return -1;
+
+ if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN)
+ return -1;
+
+ lock_entry(pktio_entry);
+ pktio_entry->s.inq_default = queue;
+ unlock_entry(pktio_entry);
+
+ queue_lock(qentry);
+ qentry->s.pktin = id;
+ qentry->s.status = QUEUE_STATUS_SCHED;
+ queue_unlock(qentry);
+
+ odp_schedule_queue(queue, qentry->s.param.sched.prio);
+
+ return 0;
+}
+
+int odp_pktio_inq_remdef(odp_pktio_t id)
+{
+ return odp_pktio_inq_setdef(id, ODP_QUEUE_INVALID);
+}
+
+odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id)
+{
+ pktio_entry_t *pktio_entry = get_entry(id);
+
+ if (pktio_entry == NULL)
+ return ODP_QUEUE_INVALID;
+
+ return pktio_entry->s.inq_default;
+}
+
+odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id)
+{
+ pktio_entry_t *pktio_entry = get_entry(id);
+
+ if (pktio_entry == NULL)
+ return ODP_QUEUE_INVALID;
+
+ return pktio_entry->s.outq_default;
+}
+
+int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr)
+{
+ odp_packet_t pkt = odp_packet_from_buffer((odp_buffer_t) buf_hdr);
+ int len = 1;
+ int nbr;
+
+ nbr = odp_pktio_send(qentry->s.pktout, &pkt, len);
+ return (nbr == len ? 0 : -1);
+}
+
+odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry)
+{
+ (void)qentry;
+ return NULL;
+}
+
+int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[],
+ int num)
+{
+ odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
+ int nbr;
+ int i;
+
+ for (i = 0; i < num; ++i)
+ pkt_tbl[i] = odp_packet_from_buffer((odp_buffer_t) buf_hdr[i]);
+
+ nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num);
+ return (nbr == num ? 0 : -1);
+}
+
+int pktout_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[],
+ int num)
+{
+ (void)qentry;
+ (void)buf_hdr;
+ (void)num;
+
+ return 0;
+}
+
+int pktin_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr)
+{
+ /* Use default action */
+ return queue_enq(qentry, buf_hdr);
+}
+
+odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry)
+{
+ odp_buffer_hdr_t *buf_hdr;
+
+ buf_hdr = queue_deq(qentry);
+
+ if (buf_hdr == NULL) {
+ odp_packet_t pkt;
+ odp_buffer_t buf;
+ odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
+ odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX];
+ int pkts, i, j;
+
+ pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl,
+ QUEUE_MULTI_MAX);
+
+ if (pkts > 0) {
+ pkt = pkt_tbl[0];
+ buf = odp_buffer_from_packet(pkt);
+ buf_hdr = odp_buf_to_hdr(buf);
+
+ for (i = 1, j = 0; i < pkts; ++i) {
+ buf = odp_buffer_from_packet(pkt_tbl[i]);
+ tmp_hdr_tbl[j++] = odp_buf_to_hdr(buf);
+ }
+ queue_enq_multi(qentry, tmp_hdr_tbl, j);
+ }
+ }
+
+ return buf_hdr;
+}
+
+int pktin_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num)
+{
+ /* Use default action */
+ return queue_enq_multi(qentry, buf_hdr, num);
+}
+
+int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num)
+{
+ int nbr;
+
+ nbr = queue_deq_multi(qentry, buf_hdr, num);
+
+ if (nbr < num) {
+ odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
+ odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX];
+ odp_buffer_t buf;
+ int pkts, i;
+
+ pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl,
+ QUEUE_MULTI_MAX);
+ if (pkts > 0) {
+ for (i = 0; i < pkts; ++i) {
+ buf = odp_buffer_from_packet(pkt_tbl[i]);
+ tmp_hdr_tbl[i] = odp_buf_to_hdr(buf);
+ }
+ queue_enq_multi(qentry, tmp_hdr_tbl, pkts);
+ }
+ }
+
+ return nbr;
+}
new file mode 100644
@@ -0,0 +1,435 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp_queue.h>
+#include <odp_queue_internal.h>
+#include <odp_std_types.h>
+#include <odp_align.h>
+#include <odp_buffer.h>
+#include <odp_buffer_internal.h>
+#include <odp_buffer_pool_internal.h>
+#include <odp_internal.h>
+#include <odp_shared_memory.h>
+#include <odp_schedule_internal.h>
+#include <odp_config.h>
+#include <odp_packet_io_internal.h>
+#include <odp_packet_io_queue.h>
+#include <odp_debug.h>
+#include <odp_hints.h>
+
+#ifdef USE_TICKETLOCK
+#include <odp_ticketlock.h>
+#define LOCK(a) odp_ticketlock_lock(a)
+#define UNLOCK(a) odp_ticketlock_unlock(a)
+#define LOCK_INIT(a) odp_ticketlock_init(a)
+#else
+#include <odp_spinlock.h>
+#define LOCK(a) odp_spinlock_lock(a)
+#define UNLOCK(a) odp_spinlock_unlock(a)
+#define LOCK_INIT(a) odp_spinlock_init(a)
+#endif
+
+#include <string.h>
+
+
+typedef struct queue_table_t {
+ queue_entry_t queue[ODP_CONFIG_QUEUES];
+} queue_table_t;
+
+static queue_table_t *queue_tbl;
+
+
+queue_entry_t *get_qentry(uint32_t queue_id)
+{
+ return &queue_tbl->queue[queue_id];
+}
+
+static void queue_init(queue_entry_t *queue, const char *name,
+ odp_queue_type_t type, odp_queue_param_t *param)
+{
+ strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1);
+ queue->s.type = type;
+
+ if (param) {
+ memcpy(&queue->s.param, param, sizeof(odp_queue_param_t));
+ } else {
+ /* Defaults */
+ memset(&queue->s.param, 0, sizeof(odp_queue_param_t));
+ queue->s.param.sched.prio = ODP_SCHED_PRIO_DEFAULT;
+ queue->s.param.sched.sync = ODP_SCHED_SYNC_DEFAULT;
+ queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT;
+ }
+
+ switch (type) {
+ case ODP_QUEUE_TYPE_PKTIN:
+ queue->s.enqueue = pktin_enqueue;
+ queue->s.dequeue = pktin_dequeue;
+ queue->s.enqueue_multi = pktin_enq_multi;
+ queue->s.dequeue_multi = pktin_deq_multi;
+ break;
+ case ODP_QUEUE_TYPE_PKTOUT:
+ queue->s.enqueue = pktout_enqueue;
+ queue->s.dequeue = pktout_dequeue;
+ queue->s.enqueue_multi = pktout_enq_multi;
+ queue->s.dequeue_multi = pktout_deq_multi;
+ break;
+ default:
+ queue->s.enqueue = queue_enq;
+ queue->s.dequeue = queue_deq;
+ queue->s.enqueue_multi = queue_enq_multi;
+ queue->s.dequeue_multi = queue_deq_multi;
+ break;
+ }
+
+ queue->s.head = NULL;
+ queue->s.tail = NULL;
+ queue->s.sched_buf = ODP_BUFFER_INVALID;
+}
+
+
+int odp_queue_init_global(void)
+{
+ uint32_t i;
+
+ ODP_DBG("Queue init ... ");
+
+ queue_tbl = odp_shm_reserve("odp_queues",
+ sizeof(queue_table_t),
+ sizeof(queue_entry_t));
+
+ if (queue_tbl == NULL)
+ return -1;
+
+ memset(queue_tbl, 0, sizeof(queue_table_t));
+
+ for (i = 0; i < ODP_CONFIG_QUEUES; i++) {
+ /* init locks */
+ queue_entry_t *queue = get_qentry(i);
+ LOCK_INIT(&queue->s.lock);
+ queue->s.handle = queue_from_id(i);
+ }
+
+ ODP_DBG("done\n");
+ ODP_DBG("Queue init global\n");
+ ODP_DBG(" struct queue_entry_s size %zu\n",
+ sizeof(struct queue_entry_s));
+ ODP_DBG(" queue_entry_t size %zu\n",
+ sizeof(queue_entry_t));
+ ODP_DBG("\n");
+
+ return 0;
+}
+
+odp_queue_type_t odp_queue_type(odp_queue_t handle)
+{
+ queue_entry_t *queue;
+
+ queue = queue_to_qentry(handle);
+
+ return queue->s.type;
+}
+
+odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle)
+{
+ queue_entry_t *queue;
+
+ queue = queue_to_qentry(handle);
+
+ return queue->s.param.sched.sync;
+}
+
+odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type,
+ odp_queue_param_t *param)
+{
+ uint32_t i;
+ queue_entry_t *queue;
+ odp_queue_t handle = ODP_QUEUE_INVALID;
+
+ for (i = 0; i < ODP_CONFIG_QUEUES; i++) {
+ queue = &queue_tbl->queue[i];
+
+ if (queue->s.status != QUEUE_STATUS_FREE)
+ continue;
+
+ LOCK(&queue->s.lock);
+ if (queue->s.status == QUEUE_STATUS_FREE) {
+ queue_init(queue, name, type, param);
+
+ if (type == ODP_QUEUE_TYPE_SCHED ||
+ type == ODP_QUEUE_TYPE_PKTIN)
+ queue->s.status = QUEUE_STATUS_NOTSCHED;
+ else
+ queue->s.status = QUEUE_STATUS_READY;
+
+ handle = queue->s.handle;
+ UNLOCK(&queue->s.lock);
+ break;
+ }
+ UNLOCK(&queue->s.lock);
+ }
+
+ if (handle != ODP_QUEUE_INVALID &&
+ (type == ODP_QUEUE_TYPE_SCHED || type == ODP_QUEUE_TYPE_PKTIN)) {
+ odp_buffer_t buf;
+
+ buf = odp_schedule_buffer_alloc(handle);
+ if (buf == ODP_BUFFER_INVALID) {
+ ODP_ERR("queue_init: sched buf alloc failed\n");
+ return ODP_QUEUE_INVALID;
+ }
+
+ queue->s.sched_buf = buf;
+ odp_schedule_mask_set(handle, queue->s.param.sched.prio);
+ }
+
+ return handle;
+}
+
+
+odp_buffer_t queue_sched_buf(odp_queue_t handle)
+{
+ queue_entry_t *queue;
+ queue = queue_to_qentry(handle);
+
+ return queue->s.sched_buf;
+}
+
+
+int queue_sched_atomic(odp_queue_t handle)
+{
+ queue_entry_t *queue;
+ queue = queue_to_qentry(handle);
+
+ return queue->s.param.sched.sync == ODP_SCHED_SYNC_ATOMIC;
+}
+
+
+odp_queue_t odp_queue_lookup(const char *name)
+{
+ uint32_t i;
+
+ for (i = 0; i < ODP_CONFIG_QUEUES; i++) {
+ queue_entry_t *queue = &queue_tbl->queue[i];
+
+ if (queue->s.status == QUEUE_STATUS_FREE)
+ continue;
+
+ LOCK(&queue->s.lock);
+ if (strcmp(name, queue->s.name) == 0) {
+ /* found it */
+ UNLOCK(&queue->s.lock);
+ return queue->s.handle;
+ }
+ UNLOCK(&queue->s.lock);
+ }
+
+ return ODP_QUEUE_INVALID;
+}
+
+
+int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)
+{
+ int sched = 0;
+
+ LOCK(&queue->s.lock);
+ if (queue->s.head == NULL) {
+ /* Empty queue */
+ queue->s.head = buf_hdr;
+ queue->s.tail = buf_hdr;
+ buf_hdr->pkt.next = NULL;
+ } else {
+ queue->s.tail->pkt.next = buf_hdr;
+ queue->s.tail = buf_hdr;
+ buf_hdr->pkt.next = NULL;
+ }
+
+ if (queue->s.status == QUEUE_STATUS_NOTSCHED) {
+ queue->s.status = QUEUE_STATUS_SCHED;
+ sched = 1; /* retval: schedule queue */
+ }
+ UNLOCK(&queue->s.lock);
+
+ /* Add queue to scheduling */
+ if (sched == 1)
+ odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio);
+
+ return 0;
+}
+
+
+int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
+{
+ int sched = 0;
+ int i;
+ odp_buffer_hdr_t *tail;
+
+ for (i = 0; i < num - 1; i++)
+ buf_hdr[i]->pkt.next = buf_hdr[i+1];
+
+ tail = buf_hdr[num-1];
+ buf_hdr[num-1]->pkt.next = NULL;
+
+ LOCK(&queue->s.lock);
+ /* Empty queue */
+ if (queue->s.head == NULL)
+ queue->s.head = buf_hdr[0];
+ else
+ queue->s.tail->pkt.next = buf_hdr[0];
+
+ queue->s.tail = tail;
+
+ if (queue->s.status == QUEUE_STATUS_NOTSCHED) {
+ queue->s.status = QUEUE_STATUS_SCHED;
+ sched = 1; /* retval: schedule queue */
+ }
+ UNLOCK(&queue->s.lock);
+
+ /* Add queue to scheduling */
+ if (sched == 1)
+ odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio);
+
+ return 0;
+}
+
+
+int odp_queue_enq_multi(odp_queue_t handle, odp_buffer_t buf[], int num)
+{
+ odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];
+ queue_entry_t *queue;
+ int i;
+
+ if (num > QUEUE_MULTI_MAX)
+ num = QUEUE_MULTI_MAX;
+
+ queue = queue_to_qentry(handle);
+
+ for (i = 0; i < num; i++)
+ buf_hdr[i] = odp_buf_to_hdr(buf[i]);
+
+ return queue->s.enqueue_multi(queue, buf_hdr, num);
+}
+
+
+int odp_queue_enq(odp_queue_t handle, odp_buffer_t buf)
+{
+ odp_buffer_hdr_t *buf_hdr;
+ queue_entry_t *queue;
+
+ queue = queue_to_qentry(handle);
+ buf_hdr = odp_buf_to_hdr(buf);
+
+ return queue->s.enqueue(queue, buf_hdr);
+}
+
+
+odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)
+{
+ odp_buffer_hdr_t *buf_hdr = NULL;
+
+ LOCK(&queue->s.lock);
+
+ if (queue->s.head == NULL) {
+ /* Already empty queue */
+ if (queue->s.status == QUEUE_STATUS_SCHED &&
+ queue->s.type != ODP_QUEUE_TYPE_PKTIN)
+ queue->s.status = QUEUE_STATUS_NOTSCHED;
+ } else {
+ buf_hdr = queue->s.head;
+ queue->s.head = buf_hdr->pkt.next;
+ buf_hdr->pkt.next = NULL;
+
+ if (queue->s.head == NULL) {
+ /* Queue is now empty */
+ queue->s.tail = NULL;
+ }
+ }
+
+ UNLOCK(&queue->s.lock);
+
+ return buf_hdr;
+}
+
+
+int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
+{
+ int i = 0;
+
+ LOCK(&queue->s.lock);
+
+ if (queue->s.head == NULL) {
+ /* Already empty queue */
+ if (queue->s.status == QUEUE_STATUS_SCHED &&
+ queue->s.type != ODP_QUEUE_TYPE_PKTIN)
+ queue->s.status = QUEUE_STATUS_NOTSCHED;
+ } else {
+ odp_buffer_hdr_t *hdr = queue->s.head;
+
+ for (; i < num && hdr; i++) {
+ buf_hdr[i] = hdr;
+ /* odp_prefetch(hdr->addr); */
+ hdr = hdr->pkt.next;
+ buf_hdr[i]->pkt.next = NULL;
+ }
+
+ queue->s.head = hdr;
+
+ if (hdr == NULL) {
+ /* Queue is now empty */
+ queue->s.tail = NULL;
+ }
+ }
+
+ UNLOCK(&queue->s.lock);
+
+ return i;
+}
+
+
+int odp_queue_deq_multi(odp_queue_t handle, odp_buffer_t buf[], int num)
+{
+ queue_entry_t *queue;
+ odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];
+ int i, ret;
+
+ if (num > QUEUE_MULTI_MAX)
+ num = QUEUE_MULTI_MAX;
+
+ queue = queue_to_qentry(handle);
+
+ ret = queue->s.dequeue_multi(queue, buf_hdr, num);
+
+ for (i = 0; i < ret; i++)
+ buf[i] = (odp_buffer_t) buf_hdr[i];
+
+ return ret;
+}
+
+
+odp_buffer_t odp_queue_deq(odp_queue_t handle)
+{
+ queue_entry_t *queue;
+ odp_buffer_hdr_t *buf_hdr;
+
+ queue = queue_to_qentry(handle);
+ buf_hdr = queue->s.dequeue(queue);
+
+ if (buf_hdr)
+ return (odp_buffer_t) buf_hdr;
+
+ return ODP_BUFFER_INVALID;
+}
+
+
+void queue_lock(queue_entry_t *queue)
+{
+ LOCK(&queue->s.lock);
+}
+
+
+void queue_unlock(queue_entry_t *queue)
+{
+ UNLOCK(&queue->s.lock);
+}
deleted file mode 100644
@@ -1,101 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <odp_buffer.h>
-#include <odp_buffer_internal.h>
-#include <odp_buffer_pool_internal.h>
-
-#include <string.h>
-#include <stdio.h>
-
-
-void *odp_buffer_addr(odp_buffer_t buf)
-{
- odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf);
-
- return hdr->buf_addr;
-}
-
-
-size_t odp_buffer_size(odp_buffer_t buf)
-{
- odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf);
-
- return hdr->buf_len;
-}
-
-
-int odp_buffer_type(odp_buffer_t buf)
-{
- odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf);
-
- return hdr->type;
-}
-
-
-int odp_buffer_is_scatter(odp_buffer_t buf)
-{
- odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf);
-
- if (hdr->refcnt == 0)
- return 0;
- else
- return 1;
-}
-
-
-int odp_buffer_is_valid(odp_buffer_t buf)
-{
- odp_buffer_bits_t handle;
-
- handle.u32 = buf;
-
- return (handle.index != ODP_BUFFER_INVALID_INDEX);
-}
-
-
-int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf)
-{
- odp_buffer_hdr_t *hdr;
- int len = 0;
-
- if (!odp_buffer_is_valid(buf)) {
- printf("Buffer is not valid.\n");
- return len;
- }
-
- hdr = odp_buf_to_hdr(buf);
-
- len += snprintf(&str[len], n-len,
- "Buffer\n");
- len += snprintf(&str[len], n-len,
- " pool %"PRIu64"\n", (int64_t) hdr->pool);
- len += snprintf(&str[len], n-len,
- " phy_addr %"PRIu64"\n", hdr->buf_physaddr);
- len += snprintf(&str[len], n-len,
- " addr %p\n", hdr->buf_addr);
- len += snprintf(&str[len], n-len,
- " size %u\n", hdr->buf_len);
- len += snprintf(&str[len], n-len,
- " ref_count %i\n", hdr->refcnt);
- len += snprintf(&str[len], n-len,
- " type %i\n", hdr->type);
-
- return len;
-}
-
-
-void odp_buffer_print(odp_buffer_t buf)
-{
- int max_len = 512;
- char str[max_len];
- int len;
-
- len = odp_buffer_snprint(str, max_len-1, buf);
- str[len] = 0;
-
- printf("\n%s\n", str);
-}
deleted file mode 100644
@@ -1,156 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <odp_std_types.h>
-#include <odp_buffer_pool.h>
-#include <odp_buffer_pool_internal.h>
-#include <odp_buffer_internal.h>
-#include <odp_packet_internal.h>
-#include <odp_shared_memory.h>
-#include <odp_align.h>
-#include <odp_internal.h>
-#include <odp_config.h>
-#include <odp_hints.h>
-#include <odp_debug.h>
-
-#include <string.h>
-#include <stdlib.h>
-
-/* for DPDK */
-#include <odp_packet_dpdk.h>
-
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
-#define NB_MBUF 8192
-
-#ifdef POOL_USE_TICKETLOCK
-#include <odp_ticketlock.h>
-#define LOCK(a) odp_ticketlock_lock(a)
-#define UNLOCK(a) odp_ticketlock_unlock(a)
-#define LOCK_INIT(a) odp_ticketlock_init(a)
-#else
-#include <odp_spinlock.h>
-#define LOCK(a) odp_spinlock_lock(a)
-#define UNLOCK(a) odp_spinlock_unlock(a)
-#define LOCK_INIT(a) odp_spinlock_init(a)
-#endif
-
-
-#if ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS
-#error ODP_CONFIG_BUFFER_POOLS > ODP_BUFFER_MAX_POOLS
-#endif
-
-#define NULL_INDEX ((uint32_t)-1)
-
-
-typedef union pool_entry_u {
- struct pool_entry_s s;
-
- uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct pool_entry_s))];
-
-} pool_entry_t;
-
-
-typedef struct pool_table_t {
- pool_entry_t pool[ODP_CONFIG_BUFFER_POOLS];
-
-} pool_table_t;
-
-
-/* The pool table */
-static pool_table_t *pool_tbl;
-
-/* Pool entry pointers (for inlining) */
-void *pool_entry_ptr[ODP_CONFIG_BUFFER_POOLS];
-
-
-int odp_buffer_pool_init_global(void)
-{
- odp_buffer_pool_t i;
-
- pool_tbl = odp_shm_reserve("odp_buffer_pools",
- sizeof(pool_table_t),
- sizeof(pool_entry_t));
-
- if (pool_tbl == NULL)
- return -1;
-
- memset(pool_tbl, 0, sizeof(pool_table_t));
-
-
- for (i = 0; i < ODP_CONFIG_BUFFER_POOLS; i++) {
- /* init locks */
- pool_entry_t *pool = &pool_tbl->pool[i];
- LOCK_INIT(&pool->s.lock);
- pool->s.pool = i;
-
- pool_entry_ptr[i] = pool;
- }
-
- ODP_DBG("\nBuffer pool init global\n");
- ODP_DBG(" pool_entry_s size %zu\n", sizeof(struct pool_entry_s));
- ODP_DBG(" pool_entry_t size %zu\n", sizeof(pool_entry_t));
- ODP_DBG(" odp_buffer_hdr_t size %zu\n", sizeof(odp_buffer_hdr_t));
- ODP_DBG("\n");
-
- return 0;
-}
-
-
-odp_buffer_pool_t odp_buffer_pool_create(const char *name,
- void *base_addr, uint64_t size,
- size_t buf_size, size_t buf_align,
- int buf_type)
-{
- struct rte_mempool *pktmbuf_pool = NULL;
- ODP_DBG("odp_buffer_pool_create: %s, %lx, %u, %u, %u, %d\n", name,
- (uint64_t) base_addr, (unsigned) size,
- (unsigned) buf_size, (unsigned) buf_align,
- buf_type);
-
- pktmbuf_pool =
- rte_mempool_create(name, NB_MBUF,
- MBUF_SIZE, 32,
- sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL,
- rte_pktmbuf_init, NULL,
- rte_socket_id(), 0);
- if (pktmbuf_pool == NULL) {
- ODP_ERR("Cannot init DPDK mbuf pool\n");
- return -1;
- }
-
- return (odp_buffer_pool_t) pktmbuf_pool;
-}
-
-
-odp_buffer_pool_t odp_buffer_pool_lookup(const char *name)
-{
- struct rte_mempool *mp = NULL;
-
- mp = rte_mempool_lookup(name);
- if (mp == NULL)
- return ODP_BUFFER_POOL_INVALID;
-
- return (odp_buffer_pool_t)mp;
-}
-
-
-odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool_id)
-{
- return (odp_buffer_t)rte_pktmbuf_alloc((struct rte_mempool *)pool_id);
-}
-
-
-void odp_buffer_free(odp_buffer_t buf)
-{
- rte_pktmbuf_free((struct rte_mbuf *)buf);
-}
-
-
-void odp_buffer_pool_print(odp_buffer_pool_t pool_id)
-{
- rte_mempool_dump((const struct rte_mempool *)pool_id);
-}
deleted file mode 100644
@@ -1,113 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <odp_init.h>
-#include <odp_internal.h>
-#include <odp_debug.h>
-#include <odp_packet_dpdk.h>
-
-int odp_init_dpdk(void)
-{
- int test_argc = 5;
- char *test_argv[6];
- int core_count, i, num_cores = 0;
- char core_mask[8];
-
- core_count = odp_sys_core_count();
- for (i = 0; i < core_count; i++)
- num_cores += (0x1 << i);
- sprintf(core_mask, "%x", num_cores);
-
- test_argv[0] = malloc(sizeof("odp_dpdk"));
- strcpy(test_argv[0], "odp_dpdk");
- test_argv[1] = malloc(sizeof("-c"));
- strcpy(test_argv[1], "-c");
- test_argv[2] = malloc(sizeof(core_mask));
- strcpy(test_argv[2], core_mask);
- test_argv[3] = malloc(sizeof("-n"));
- strcpy(test_argv[3], "-n");
- test_argv[4] = malloc(sizeof("3"));
- strcpy(test_argv[4], "3");
-
- if (rte_eal_init(test_argc, (char **)test_argv) < 0) {
- ODP_ERR("Cannot init the Intel DPDK EAL!");
- return -1;
- }
-
- if (rte_pmd_init_all() < 0) {
- ODP_ERR("Cannot init pmd\n");
- return -1;
- }
-
- if (rte_eal_pci_probe() < 0) {
- ODP_ERR("Cannot probe PCI\n");
- return -1;
- }
-
- return 0;
-}
-
-int odp_init_global(void)
-{
- odp_thread_init_global();
-
- odp_system_info_init();
-
- if (odp_init_dpdk()) {
- ODP_ERR("ODP dpdk init failed.\n");
- return -1;
- }
-
- if (odp_shm_init_global()) {
- ODP_ERR("ODP shm init failed.\n");
- return -1;
- }
-
- if (odp_buffer_pool_init_global()) {
- ODP_ERR("ODP buffer pool init failed.\n");
- return -1;
- }
-
- if (odp_queue_init_global()) {
- ODP_ERR("ODP queue init failed.\n");
- return -1;
- }
-
- if (odp_schedule_init_global()) {
- ODP_ERR("ODP schedule init failed.\n");
- return -1;
- }
-
- if (odp_pktio_init_global()) {
- ODP_ERR("ODP packet io init failed.\n");
- return -1;
- }
-
- if (odp_timer_init_global()) {
- ODP_ERR("ODP timer init failed.\n");
- return -1;
- }
-
- return 0;
-}
-
-
-int odp_init_local(int thr_id)
-{
- odp_thread_init_local(thr_id);
-
- if (odp_pktio_init_local()) {
- ODP_ERR("ODP packet io local init failed.\n");
- return -1;
- }
-
- if (odp_schedule_init_local()) {
- ODP_ERR("ODP schedule local init failed.\n");
- return -1;
- }
-
- return 0;
-}
deleted file mode 100644
@@ -1,374 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <odp_packet.h>
-#include <odp_packet_internal.h>
-#include <odp_hints.h>
-#include <odp_byteorder.h>
-
-#include <helper/odp_eth.h>
-#include <helper/odp_ip.h>
-
-#include <string.h>
-#include <stdio.h>
-
-static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4,
- size_t *offset_out);
-static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6,
- size_t *offset_out);
-
-void odp_packet_init(odp_packet_t pkt)
-{
- odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt);
- const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr);
- uint8_t *start;
- size_t len;
-
- start = (uint8_t *)pkt_hdr + start_offset;
- len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset;
- memset(start, 0, len);
-
- pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
- pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
- pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
-}
-
-odp_packet_t odp_packet_from_buffer(odp_buffer_t buf)
-{
- return (odp_packet_t)buf;
-}
-
-odp_buffer_t odp_buffer_from_packet(odp_packet_t pkt)
-{
- return (odp_buffer_t)pkt;
-}
-
-void odp_packet_set_len(odp_packet_t pkt, size_t len)
-{
- /* for rte_pktmbuf */
- odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(odp_buffer_from_packet(pkt));
- buf_hdr->pkt.data_len = len;
-
- odp_packet_hdr(pkt)->frame_len = len;
-}
-
-size_t odp_packet_get_len(odp_packet_t pkt)
-{
- return odp_packet_hdr(pkt)->frame_len;
-}
-
-uint8_t *odp_packet_buf_addr(odp_packet_t pkt)
-{
- return odp_buffer_addr(odp_buffer_from_packet(pkt));
-}
-
-uint8_t *odp_packet_start(odp_packet_t pkt)
-{
- return odp_packet_buf_addr(pkt) + odp_packet_hdr(pkt)->frame_offset;
-}
-
-
-uint8_t *odp_packet_l2(odp_packet_t pkt)
-{
- const size_t offset = odp_packet_l2_offset(pkt);
-
- if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
- return NULL;
-
- return odp_packet_buf_addr(pkt) + offset;
-}
-
-size_t odp_packet_l2_offset(odp_packet_t pkt)
-{
- return odp_packet_hdr(pkt)->l2_offset;
-}
-
-void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset)
-{
- odp_packet_hdr(pkt)->l2_offset = offset;
-}
-
-uint8_t *odp_packet_l3(odp_packet_t pkt)
-{
- const size_t offset = odp_packet_l3_offset(pkt);
-
- if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
- return NULL;
-
- return odp_packet_buf_addr(pkt) + offset;
-}
-
-size_t odp_packet_l3_offset(odp_packet_t pkt)
-{
- return odp_packet_hdr(pkt)->l3_offset;
-}
-
-void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset)
-{
- odp_packet_hdr(pkt)->l3_offset = offset;
-}
-
-uint8_t *odp_packet_l4(odp_packet_t pkt)
-{
- const size_t offset = odp_packet_l4_offset(pkt);
-
- if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
- return NULL;
-
- return odp_packet_buf_addr(pkt) + offset;
-}
-
-size_t odp_packet_l4_offset(odp_packet_t pkt)
-{
- return odp_packet_hdr(pkt)->l4_offset;
-}
-
-void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset)
-{
- odp_packet_hdr(pkt)->l4_offset = offset;
-}
-
-/**
- * Simple packet parser: eth, VLAN, IP, TCP/UDP/ICMP
- *
- * Internal function: caller is resposible for passing only valid packet handles
- * , lengths and offsets (usually done&called in packet input).
- *
- * @param pkt Packet handle
- * @param len Packet length in bytes
- * @param frame_offset Byte offset to L2 header
- */
-void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset)
-{
- odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt);
- odp_ethhdr_t *eth;
- odp_vlanhdr_t *vlan;
- odp_ipv4hdr_t *ipv4;
- odp_ipv6hdr_t *ipv6;
- uint16_t ethtype;
- size_t offset = 0;
- uint8_t ip_proto = 0;
-
- pkt_hdr->input_flags.eth = 1;
- pkt_hdr->frame_offset = frame_offset;
- pkt_hdr->frame_len = len;
-
- if (odp_unlikely(len < ODP_ETH_LEN_MIN)) {
- pkt_hdr->error_flags.frame_len = 1;
- return;
- } else if (len > ODP_ETH_LEN_MAX) {
- pkt_hdr->input_flags.jumbo = 1;
- }
-
- /* Assume valid L2 header, no CRC/FCS check in SW */
- pkt_hdr->input_flags.l2 = 1;
- pkt_hdr->l2_offset = frame_offset;
-
- eth = (odp_ethhdr_t *)odp_packet_start(pkt);
- ethtype = odp_be_to_cpu_16(eth->type);
- vlan = (odp_vlanhdr_t *)ð->type;
-
- if (ethtype == ODP_ETHTYPE_VLAN_OUTER) {
- pkt_hdr->input_flags.vlan_qinq = 1;
- ethtype = odp_be_to_cpu_16(vlan->tpid);
- offset += sizeof(odp_vlanhdr_t);
- vlan = &vlan[1];
- }
-
- if (ethtype == ODP_ETHTYPE_VLAN) {
- pkt_hdr->input_flags.vlan = 1;
- ethtype = odp_be_to_cpu_16(vlan->tpid);
- offset += sizeof(odp_vlanhdr_t);
- }
-
- /* Set l3_offset+flag only for known ethtypes */
- switch (ethtype) {
- case ODP_ETHTYPE_IPV4:
- pkt_hdr->input_flags.ipv4 = 1;
- pkt_hdr->input_flags.l3 = 1;
- pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset;
- ipv4 = (odp_ipv4hdr_t *)odp_packet_l3(pkt);
- ip_proto = parse_ipv4(pkt_hdr, ipv4, &offset);
- break;
- case ODP_ETHTYPE_IPV6:
- pkt_hdr->input_flags.ipv6 = 1;
- pkt_hdr->input_flags.l3 = 1;
- pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset;
- ipv6 = (odp_ipv6hdr_t *)odp_packet_l3(pkt);
- ip_proto = parse_ipv6(pkt_hdr, ipv6, &offset);
- break;
- case ODP_ETHTYPE_ARP:
- pkt_hdr->input_flags.arp = 1;
- /* fall through */
- default:
- ip_proto = 0;
- break;
- }
-
- switch (ip_proto) {
- case ODP_IPPROTO_UDP:
- pkt_hdr->input_flags.udp = 1;
- pkt_hdr->input_flags.l4 = 1;
- pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset;
- break;
- case ODP_IPPROTO_TCP:
- pkt_hdr->input_flags.tcp = 1;
- pkt_hdr->input_flags.l4 = 1;
- pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset;
- break;
- case ODP_IPPROTO_SCTP:
- pkt_hdr->input_flags.sctp = 1;
- pkt_hdr->input_flags.l4 = 1;
- pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset;
- break;
- case ODP_IPPROTO_ICMP:
- pkt_hdr->input_flags.icmp = 1;
- pkt_hdr->input_flags.l4 = 1;
- pkt_hdr->l4_offset = pkt_hdr->l3_offset + offset;
- break;
- default:
- /* 0 or unhandled IP protocols, don't set L4 flag+offset */
- if (pkt_hdr->input_flags.ipv6) {
- /* IPv6 next_hdr is not L4, mark as IP-option instead */
- pkt_hdr->input_flags.ipopt = 1;
- }
- break;
- }
-}
-
-static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4,
- size_t *offset_out)
-{
- uint8_t ihl;
- uint16_t frag_offset;
-
- ihl = ODP_IPV4HDR_IHL(ipv4->ver_ihl);
- if (odp_unlikely(ihl < ODP_IPV4HDR_IHL_MIN)) {
- pkt_hdr->error_flags.ip_err = 1;
- return 0;
- }
-
- if (odp_unlikely(ihl > ODP_IPV4HDR_IHL_MIN)) {
- pkt_hdr->input_flags.ipopt = 1;
- return 0;
- }
-
- /* A packet is a fragment if:
- * "more fragments" flag is set (all fragments except the last)
- * OR
- * "fragment offset" field is nonzero (all fragments except the first)
- */
- frag_offset = odp_be_to_cpu_16(ipv4->frag_offset);
- if (odp_unlikely(ODP_IPV4HDR_IS_FRAGMENT(frag_offset))) {
- pkt_hdr->input_flags.ipfrag = 1;
- return 0;
- }
-
- if (ipv4->proto == ODP_IPPROTO_ESP ||
- ipv4->proto == ODP_IPPROTO_AH) {
- pkt_hdr->input_flags.ipsec = 1;
- return 0;
- }
-
- /* Set pkt_hdr->input_flags.ipopt when checking L4 hdrs after return */
-
- *offset_out = sizeof(uint32_t) * ihl;
- return ipv4->proto;
-}
-
-static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6,
- size_t *offset_out)
-{
- if (ipv6->next_hdr == ODP_IPPROTO_ESP ||
- ipv6->next_hdr == ODP_IPPROTO_AH) {
- pkt_hdr->input_flags.ipopt = 1;
- pkt_hdr->input_flags.ipsec = 1;
- return 0;
- }
-
- if (odp_unlikely(ipv6->next_hdr == ODP_IPPROTO_FRAG)) {
- pkt_hdr->input_flags.ipopt = 1;
- pkt_hdr->input_flags.ipfrag = 1;
- return 0;
- }
-
- /* Don't step through more extensions */
- *offset_out = ODP_IPV6HDR_LEN;
- return ipv6->next_hdr;
-}
-
-void odp_packet_print(odp_packet_t pkt)
-{
- int max_len = 512;
- char str[max_len];
- int len = 0;
- int n = max_len-1;
- odp_packet_hdr_t *hdr = odp_packet_hdr(pkt);
-
- len += snprintf(&str[len], n-len, "Packet ");
- len += odp_buffer_snprint(&str[len], n-len, (odp_buffer_t) pkt);
- len += snprintf(&str[len], n-len,
- " input_flags 0x%x\n", hdr->input_flags.all);
- len += snprintf(&str[len], n-len,
- " error_flags 0x%x\n", hdr->error_flags.all);
- len += snprintf(&str[len], n-len,
- " output_flags 0x%x\n", hdr->output_flags.all);
- len += snprintf(&str[len], n-len,
- " frame_offset %u\n", hdr->frame_offset);
- len += snprintf(&str[len], n-len,
- " l2_offset %u\n", hdr->l2_offset);
- len += snprintf(&str[len], n-len,
- " l3_offset %u\n", hdr->l3_offset);
- len += snprintf(&str[len], n-len,
- " l4_offset %u\n", hdr->l4_offset);
- len += snprintf(&str[len], n-len,
- " frame_len %u\n", hdr->frame_len);
- len += snprintf(&str[len], n-len,
- " input %u\n", hdr->input);
- str[len] = '\0';
-
- printf("\n%s\n", str);
-}
-
-int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src)
-{
- odp_packet_hdr_t *const pkt_hdr_dst = odp_packet_hdr(pkt_dst);
- odp_packet_hdr_t *const pkt_hdr_src = odp_packet_hdr(pkt_src);
- const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr);
- uint8_t *start_src;
- uint8_t *start_dst;
- size_t len;
-
- if (pkt_dst == ODP_PACKET_INVALID || pkt_src == ODP_PACKET_INVALID)
- return -1;
-
- /* if (pkt_hdr_dst->buf_hdr.size < */
- /* pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset) */
- if (pkt_hdr_dst->buf_hdr.buf_len <
- pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset)
- return -1;
-
- /* Copy packet header */
- start_dst = (uint8_t *)pkt_hdr_dst + start_offset;
- start_src = (uint8_t *)pkt_hdr_src + start_offset;
- len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset;
- memcpy(start_dst, start_src, len);
-
- /* Copy frame payload */
- start_dst = (uint8_t *)odp_packet_start(pkt_dst);
- start_src = (uint8_t *)odp_packet_start(pkt_src);
- len = pkt_hdr_src->frame_len;
- memcpy(start_dst, start_src, len);
-
- /* Copy useful things from the buffer header */
- /* pkt_hdr_dst->buf_hdr.cur_offset = pkt_hdr_src->buf_hdr.cur_offset; */
-
- /* Create a copy of the scatter list */
- /* odp_buffer_copy_scatter(odp_buffer_from_packet(pkt_dst), */
- /* odp_buffer_from_packet(pkt_src)); */
-
- return 0;
-}
deleted file mode 100644
@@ -1,177 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <poll.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <linux/ethtool.h>
-#include <linux/sockios.h>
-
-#include <odp_hints.h>
-#include <odp_thread.h>
-
-#include <odp_packet_dpdk.h>
-#include <net/if.h>
-
-/*
- * RX and TX Prefetch, Host, and Write-back threshold values should be
- * carefully set for optimal performance. Consult the network
- * controller's datasheet and supporting DPDK documentation for guidance
- * on how these parameters should be set.
- */
-#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */
-#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */
-#define RX_WTHRESH 4 /**< Default values of RX write-back threshold reg. */
-
-/*
- * These default values are optimized for use with the Intel(R) 82599 10 GbE
- * Controller and the DPDK ixgbe PMD. Consider using other values for other
- * network controllers and/or network drivers.
- */
-#define TX_PTHRESH 36 /**< Default values of TX prefetch threshold reg. */
-#define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */
-#define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */
-
-#define MAX_PKT_BURST 32
-#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
-#define RTE_TEST_RX_DESC_DEFAULT 128
-#define RTE_TEST_TX_DESC_DEFAULT 512
-static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
-static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
-
-static const struct rte_eth_conf port_conf = {
- .rxmode = {
- .split_hdr_size = 0,
- .header_split = 0, /**< Header Split disabled */
- .hw_ip_checksum = 0, /**< IP checksum offload disabled */
- .hw_vlan_filter = 0, /**< VLAN filtering disabled */
- .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
- .hw_strip_crc = 0, /**< CRC stripped by hardware */
- },
- .txmode = {
- .mq_mode = ETH_MQ_TX_NONE,
- },
-};
-
-static const struct rte_eth_rxconf rx_conf = {
- .rx_thresh = {
- .pthresh = RX_PTHRESH,
- .hthresh = RX_HTHRESH,
- .wthresh = RX_WTHRESH,
- },
-};
-
-static const struct rte_eth_txconf tx_conf = {
- .tx_thresh = {
- .pthresh = TX_PTHRESH,
- .hthresh = TX_HTHRESH,
- .wthresh = TX_WTHRESH,
- },
- .tx_free_thresh = 0, /* Use PMD default values */
- .tx_rs_thresh = 0, /* Use PMD default values */
- /*
- * As the example won't handle mult-segments and offload cases,
- * set the flag by default.
- */
- .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOOFFLOADS,
-};
-
-int setup_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, const char *netdev,
- odp_buffer_pool_t pool)
-{
- ODP_DBG("setup_pkt_dpdk\n");
-
- static struct ether_addr eth_addr[RTE_MAX_ETHPORTS];
- uint8_t portid = 0;
- uint16_t queueid = 0;
- int ret;
- printf("vincent netdev: %s\n", netdev);
- printf("vincent pool: %lx\n", pool);
-
- portid = atoi(netdev);
- pkt_dpdk->portid = portid;
- pkt_dpdk->queueid = queueid;
- pkt_dpdk->pool = pool;
- printf("vincent portid: %u\n", portid);
-
- fflush(stdout);
- ret = rte_eth_dev_configure(portid, 1, 1, &port_conf);
- if (ret < 0)
- ODP_ERR("Cannot configure device: err=%d, port=%u\n",
- ret, (unsigned) portid);
-
- rte_eth_macaddr_get(portid, ð_addr[portid]);
- ODP_DBG("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n",
- (unsigned) portid,
- eth_addr[portid].addr_bytes[0],
- eth_addr[portid].addr_bytes[1],
- eth_addr[portid].addr_bytes[2],
- eth_addr[portid].addr_bytes[3],
- eth_addr[portid].addr_bytes[4],
- eth_addr[portid].addr_bytes[5]);
-
- /* init one RX queue on each port */
- fflush(stdout);
- ret = rte_eth_rx_queue_setup(portid, queueid, nb_rxd,
- rte_eth_dev_socket_id(portid), &rx_conf,
- (struct rte_mempool *)pool);
- if (ret < 0)
- ODP_ERR("rte_eth_rx_queue_setup:err=%d, port=%u\n",
- ret, (unsigned) portid);
- ODP_DBG("dpdk rx queue setup done\n");
-
- /* init one TX queue on each port */
- fflush(stdout);
- ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
- rte_eth_dev_socket_id(portid), &tx_conf);
- if (ret < 0)
- ODP_ERR("rte_eth_tx_queue_setup:err=%d, port=%u\n",
- ret, (unsigned) portid);
- ODP_DBG("dpdk tx queue setup done\n");
-
- /* Start device */
- ret = rte_eth_dev_start(portid);
- if (ret < 0)
- ODP_ERR("rte_eth_dev_start:err=%d, port=%u\n",
- ret, (unsigned) portid);
- ODP_DBG("dpdk setup done\n\n");
-
-
- return 0;
-}
-
-int close_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk)
-{
- ODP_DBG("close pkt_dpdk, %u\n", pkt_dpdk->portid);
-
- return 0;
-}
-
-int recv_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[],
- unsigned len)
-{
- return rte_eth_rx_burst((uint8_t)pkt_dpdk->portid,
- (uint16_t)pkt_dpdk->queueid,
- (struct rte_mbuf **)pkt_table, (uint16_t)len);
-}
-
-int send_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, odp_packet_t pkt_table[],
- unsigned len)
-{
- return rte_eth_tx_burst((uint8_t)pkt_dpdk->portid,
- (uint16_t)pkt_dpdk->queueid,
- (struct rte_mbuf **)pkt_table, (uint16_t)len);
-}
deleted file mode 100644
@@ -1,561 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <odp_packet_io.h>
-#include <odp_packet_io_internal.h>
-#include <odp_packet_io_queue.h>
-#include <odp_packet.h>
-#include <odp_packet_internal.h>
-#include <odp_internal.h>
-#include <odp_spinlock.h>
-#include <odp_shared_memory.h>
-#include <odp_packet_socket.h>
-#ifdef ODP_HAVE_NETMAP
-#include <odp_packet_netmap.h>
-#endif
-#include <odp_hints.h>
-#include <odp_config.h>
-#include <odp_queue_internal.h>
-#include <odp_schedule_internal.h>
-#include <odp_debug.h>
-
-#include <odp_pktio_socket.h>
-#ifdef ODP_HAVE_NETMAP
-#include <odp_pktio_netmap.h>
-#endif
-
-#include <string.h>
-
-typedef struct {
- pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES];
-} pktio_table_t;
-
-static pktio_table_t *pktio_tbl;
-
-
-static pktio_entry_t *get_entry(odp_pktio_t id)
-{
- if (odp_unlikely(id == ODP_PKTIO_INVALID ||
- id > ODP_CONFIG_PKTIO_ENTRIES))
- return NULL;
-
- return &pktio_tbl->entries[id - 1];
-}
-
-int odp_pktio_init_global(void)
-{
- char name[ODP_QUEUE_NAME_LEN];
- pktio_entry_t *pktio_entry;
- queue_entry_t *queue_entry;
- odp_queue_t qid;
- int id;
-
- pktio_tbl = odp_shm_reserve("odp_pktio_entries",
- sizeof(pktio_table_t),
- sizeof(pktio_entry_t));
- if (pktio_tbl == NULL)
- return -1;
-
- memset(pktio_tbl, 0, sizeof(pktio_table_t));
-
- for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) {
- pktio_entry = get_entry(id);
-
- odp_spinlock_init(&pktio_entry->s.lock);
-
- /* Create a default output queue for each pktio resource */
- snprintf(name, sizeof(name), "%i-pktio_outq_default", (int)id);
- name[ODP_QUEUE_NAME_LEN-1] = '\0';
-
- qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL);
- if (qid == ODP_QUEUE_INVALID)
- return -1;
- pktio_entry->s.outq_default = qid;
-
- queue_entry = queue_to_qentry(qid);
- queue_entry->s.pktout = id;
- }
-
- return 0;
-}
-
-int odp_pktio_init_local(void)
-{
- return 0;
-}
-
-static int is_free(pktio_entry_t *entry)
-{
- return (entry->s.taken == 0);
-}
-
-static void set_free(pktio_entry_t *entry)
-{
- entry->s.taken = 0;
-}
-
-static void set_taken(pktio_entry_t *entry)
-{
- entry->s.taken = 1;
-}
-
-static void lock_entry(pktio_entry_t *entry)
-{
- odp_spinlock_lock(&entry->s.lock);
-}
-
-static void unlock_entry(pktio_entry_t *entry)
-{
- odp_spinlock_unlock(&entry->s.lock);
-}
-
-static void init_pktio_entry(pktio_entry_t *entry, odp_pktio_params_t *params)
-{
- set_taken(entry);
- entry->s.inq_default = ODP_QUEUE_INVALID;
- switch (params->type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock));
- memset(&entry->s.pkt_sock_mmap, 0,
- sizeof(entry->s.pkt_sock_mmap));
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
- memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm));
- break;
-#endif
- case ODP_PKTIO_TYPE_DPDK:
- memset(&entry->s.pkt_dpdk, 0, sizeof(entry->s.pkt_dpdk));
- break;
- default:
- ODP_ERR("Packet I/O type not supported. Please recompile\n");
- break;
- }
- /* Save pktio parameters, type is the most useful */
- memcpy(&entry->s.params, params, sizeof(*params));
-}
-
-static odp_pktio_t alloc_lock_pktio_entry(odp_pktio_params_t *params)
-{
- odp_pktio_t id;
- pktio_entry_t *entry;
- int i;
-
- for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) {
- entry = &pktio_tbl->entries[i];
- if (is_free(entry)) {
- lock_entry(entry);
- if (is_free(entry)) {
- init_pktio_entry(entry, params);
- id = i + 1;
- return id; /* return with entry locked! */
- }
- unlock_entry(entry);
- }
- }
-
- return ODP_PKTIO_INVALID;
-}
-
-static int free_pktio_entry(odp_pktio_t id)
-{
- pktio_entry_t *entry = get_entry(id);
-
- if (entry == NULL)
- return -1;
-
- set_free(entry);
-
- return 0;
-}
-
-odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool,
- odp_pktio_params_t *params)
-{
- odp_pktio_t id;
- pktio_entry_t *pktio_entry;
- int res;
-
- if (params == NULL) {
- ODP_ERR("Invalid pktio params\n");
- return ODP_PKTIO_INVALID;
- }
-
- switch (params->type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- ODP_DBG("Allocating socket pktio\n");
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
- ODP_DBG("Allocating netmap pktio\n");
- break;
-#endif
- case ODP_PKTIO_TYPE_DPDK:
- ODP_DBG("Allocating dpdk pktio\n");
- break;
- default:
- ODP_ERR("Invalid pktio type: %02x\n", params->type);
- return ODP_PKTIO_INVALID;
- }
-
- id = alloc_lock_pktio_entry(params);
- if (id == ODP_PKTIO_INVALID) {
- ODP_ERR("No resources available.\n");
- return ODP_PKTIO_INVALID;
- }
- /* if successful, alloc_pktio_entry() returns with the entry locked */
-
- pktio_entry = get_entry(id);
-
- switch (params->type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool);
- if (res == -1) {
- close_pkt_sock(&pktio_entry->s.pkt_sock);
- free_pktio_entry(id);
- id = ODP_PKTIO_INVALID;
- }
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, dev,
- pool, params->sock_params.fanout);
- if (res == -1) {
- close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap);
- free_pktio_entry(id);
- id = ODP_PKTIO_INVALID;
- }
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
-
- res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev,
- pool, ¶ms->nm_params);
- if (res == -1) {
- close_pkt_netmap(&pktio_entry->s.pkt_nm);
- free_pktio_entry(id);
- id = ODP_PKTIO_INVALID;
- }
- break;
-#endif
- case ODP_PKTIO_TYPE_DPDK:
- res = setup_pkt_dpdk(&pktio_entry->s.pkt_dpdk, dev, pool);
- if (res == -1) {
- close_pkt_dpdk(&pktio_entry->s.pkt_dpdk);
- free_pktio_entry(id);
- id = ODP_PKTIO_INVALID;
- }
- break;
- default:
- free_pktio_entry(id);
- id = ODP_PKTIO_INVALID;
- ODP_ERR("Invalid pktio type. Please recompile.\n");
- break;
- }
-
- unlock_entry(pktio_entry);
- return id;
-}
-
-int odp_pktio_close(odp_pktio_t id)
-{
- pktio_entry_t *entry;
- int res = -1;
-
- entry = get_entry(id);
- if (entry == NULL)
- return -1;
-
- lock_entry(entry);
- if (!is_free(entry)) {
- switch (entry->s.params.type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- res = close_pkt_sock(&entry->s.pkt_sock);
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- res = close_pkt_sock_mmap(&entry->s.pkt_sock_mmap);
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
- res = close_pkt_netmap(&entry->s.pkt_nm);
- break;
-#endif
- case ODP_PKTIO_TYPE_DPDK:
- res = close_pkt_dpdk(&entry->s.pkt_dpdk);
- break;
- default:
- break;
- res |= free_pktio_entry(id);
- }
- }
- unlock_entry(entry);
-
- if (res != 0)
- return -1;
-
- return 0;
-}
-
-void odp_pktio_set_input(odp_packet_t pkt, odp_pktio_t pktio)
-{
- odp_packet_hdr(pkt)->input = pktio;
-}
-
-odp_pktio_t odp_pktio_get_input(odp_packet_t pkt)
-{
- return odp_packet_hdr(pkt)->input;
-}
-
-int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len)
-{
- pktio_entry_t *pktio_entry = get_entry(id);
- int pkts;
- int i;
-
- if (pktio_entry == NULL)
- return -1;
-
- lock_entry(pktio_entry);
- switch (pktio_entry->s.params.type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock,
- pkt_table, len);
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock,
- pkt_table, len);
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap,
- pkt_table, len);
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
- pkts = recv_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, len);
- break;
-#endif
- case ODP_PKTIO_TYPE_DPDK:
- pkts = recv_pkt_dpdk(&pktio_entry->s.pkt_dpdk, pkt_table, len);
- break;
- default:
- pkts = -1;
- break;
- }
-
- unlock_entry(pktio_entry);
- if (pkts < 0)
- return pkts;
-
- for (i = 0; i < pkts; ++i)
- odp_pktio_set_input(pkt_table[i], id);
-
- return pkts;
-}
-
-int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len)
-{
- pktio_entry_t *pktio_entry = get_entry(id);
- int pkts;
-
- if (pktio_entry == NULL)
- return -1;
-
- lock_entry(pktio_entry);
- switch (pktio_entry->s.params.type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock,
- pkt_table, len);
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock,
- pkt_table, len);
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap,
- pkt_table, len);
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
- pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm,
- pkt_table, len);
- break;
-#endif
- case ODP_PKTIO_TYPE_DPDK:
- pkts = send_pkt_dpdk(&pktio_entry->s.pkt_dpdk,
- pkt_table, len);
- break;
- default:
- pkts = -1;
- }
- unlock_entry(pktio_entry);
-
- return pkts;
-}
-
-int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue)
-{
- pktio_entry_t *pktio_entry = get_entry(id);
- queue_entry_t *qentry = queue_to_qentry(queue);
-
- if (pktio_entry == NULL || qentry == NULL)
- return -1;
-
- if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN)
- return -1;
-
- lock_entry(pktio_entry);
- pktio_entry->s.inq_default = queue;
- unlock_entry(pktio_entry);
-
- queue_lock(qentry);
- qentry->s.pktin = id;
- qentry->s.status = QUEUE_STATUS_SCHED;
- queue_unlock(qentry);
-
- odp_schedule_queue(queue, qentry->s.param.sched.prio);
-
- return 0;
-}
-
-int odp_pktio_inq_remdef(odp_pktio_t id)
-{
- return odp_pktio_inq_setdef(id, ODP_QUEUE_INVALID);
-}
-
-odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id)
-{
- pktio_entry_t *pktio_entry = get_entry(id);
-
- if (pktio_entry == NULL)
- return ODP_QUEUE_INVALID;
-
- return pktio_entry->s.inq_default;
-}
-
-odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id)
-{
- pktio_entry_t *pktio_entry = get_entry(id);
-
- if (pktio_entry == NULL)
- return ODP_QUEUE_INVALID;
-
- return pktio_entry->s.outq_default;
-}
-
-int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr)
-{
- odp_packet_t pkt = odp_packet_from_buffer((odp_buffer_t) buf_hdr);
- int len = 1;
- int nbr;
-
- nbr = odp_pktio_send(qentry->s.pktout, &pkt, len);
- return (nbr == len ? 0 : -1);
-}
-
-odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry)
-{
- (void)qentry;
- return NULL;
-}
-
-int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[],
- int num)
-{
- odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
- int nbr;
- int i;
-
- for (i = 0; i < num; ++i)
- pkt_tbl[i] = odp_packet_from_buffer((odp_buffer_t) buf_hdr[i]);
-
- nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num);
- return (nbr == num ? 0 : -1);
-}
-
-int pktout_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[],
- int num)
-{
- (void)qentry;
- (void)buf_hdr;
- (void)num;
-
- return 0;
-}
-
-int pktin_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr)
-{
- /* Use default action */
- return queue_enq(qentry, buf_hdr);
-}
-
-odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry)
-{
- odp_buffer_hdr_t *buf_hdr;
-
- buf_hdr = queue_deq(qentry);
-
- if (buf_hdr == NULL) {
- odp_packet_t pkt;
- odp_buffer_t buf;
- odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
- odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX];
- int pkts, i, j;
-
- pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl,
- QUEUE_MULTI_MAX);
-
- if (pkts > 0) {
- pkt = pkt_tbl[0];
- buf = odp_buffer_from_packet(pkt);
- buf_hdr = odp_buf_to_hdr(buf);
-
- for (i = 1, j = 0; i < pkts; ++i) {
- buf = odp_buffer_from_packet(pkt_tbl[i]);
- tmp_hdr_tbl[j++] = odp_buf_to_hdr(buf);
- }
- queue_enq_multi(qentry, tmp_hdr_tbl, j);
- }
- }
-
- return buf_hdr;
-}
-
-int pktin_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num)
-{
- /* Use default action */
- return queue_enq_multi(qentry, buf_hdr, num);
-}
-
-int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num)
-{
- int nbr;
-
- nbr = queue_deq_multi(qentry, buf_hdr, num);
-
- if (nbr < num) {
- odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
- odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX];
- odp_buffer_t buf;
- int pkts, i;
-
- pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl,
- QUEUE_MULTI_MAX);
- if (pkts > 0) {
- for (i = 0; i < pkts; ++i) {
- buf = odp_buffer_from_packet(pkt_tbl[i]);
- tmp_hdr_tbl[i] = odp_buf_to_hdr(buf);
- }
- queue_enq_multi(qentry, tmp_hdr_tbl, pkts);
- }
- }
-
- return nbr;
-}
deleted file mode 100644
@@ -1,435 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <odp_queue.h>
-#include <odp_queue_internal.h>
-#include <odp_std_types.h>
-#include <odp_align.h>
-#include <odp_buffer.h>
-#include <odp_buffer_internal.h>
-#include <odp_buffer_pool_internal.h>
-#include <odp_internal.h>
-#include <odp_shared_memory.h>
-#include <odp_schedule_internal.h>
-#include <odp_config.h>
-#include <odp_packet_io_internal.h>
-#include <odp_packet_io_queue.h>
-#include <odp_debug.h>
-#include <odp_hints.h>
-
-#ifdef USE_TICKETLOCK
-#include <odp_ticketlock.h>
-#define LOCK(a) odp_ticketlock_lock(a)
-#define UNLOCK(a) odp_ticketlock_unlock(a)
-#define LOCK_INIT(a) odp_ticketlock_init(a)
-#else
-#include <odp_spinlock.h>
-#define LOCK(a) odp_spinlock_lock(a)
-#define UNLOCK(a) odp_spinlock_unlock(a)
-#define LOCK_INIT(a) odp_spinlock_init(a)
-#endif
-
-#include <string.h>
-
-
-typedef struct queue_table_t {
- queue_entry_t queue[ODP_CONFIG_QUEUES];
-} queue_table_t;
-
-static queue_table_t *queue_tbl;
-
-
-queue_entry_t *get_qentry(uint32_t queue_id)
-{
- return &queue_tbl->queue[queue_id];
-}
-
-static void queue_init(queue_entry_t *queue, const char *name,
- odp_queue_type_t type, odp_queue_param_t *param)
-{
- strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1);
- queue->s.type = type;
-
- if (param) {
- memcpy(&queue->s.param, param, sizeof(odp_queue_param_t));
- } else {
- /* Defaults */
- memset(&queue->s.param, 0, sizeof(odp_queue_param_t));
- queue->s.param.sched.prio = ODP_SCHED_PRIO_DEFAULT;
- queue->s.param.sched.sync = ODP_SCHED_SYNC_DEFAULT;
- queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT;
- }
-
- switch (type) {
- case ODP_QUEUE_TYPE_PKTIN:
- queue->s.enqueue = pktin_enqueue;
- queue->s.dequeue = pktin_dequeue;
- queue->s.enqueue_multi = pktin_enq_multi;
- queue->s.dequeue_multi = pktin_deq_multi;
- break;
- case ODP_QUEUE_TYPE_PKTOUT:
- queue->s.enqueue = pktout_enqueue;
- queue->s.dequeue = pktout_dequeue;
- queue->s.enqueue_multi = pktout_enq_multi;
- queue->s.dequeue_multi = pktout_deq_multi;
- break;
- default:
- queue->s.enqueue = queue_enq;
- queue->s.dequeue = queue_deq;
- queue->s.enqueue_multi = queue_enq_multi;
- queue->s.dequeue_multi = queue_deq_multi;
- break;
- }
-
- queue->s.head = NULL;
- queue->s.tail = NULL;
- queue->s.sched_buf = ODP_BUFFER_INVALID;
-}
-
-
-int odp_queue_init_global(void)
-{
- uint32_t i;
-
- ODP_DBG("Queue init ... ");
-
- queue_tbl = odp_shm_reserve("odp_queues",
- sizeof(queue_table_t),
- sizeof(queue_entry_t));
-
- if (queue_tbl == NULL)
- return -1;
-
- memset(queue_tbl, 0, sizeof(queue_table_t));
-
- for (i = 0; i < ODP_CONFIG_QUEUES; i++) {
- /* init locks */
- queue_entry_t *queue = get_qentry(i);
- LOCK_INIT(&queue->s.lock);
- queue->s.handle = queue_from_id(i);
- }
-
- ODP_DBG("done\n");
- ODP_DBG("Queue init global\n");
- ODP_DBG(" struct queue_entry_s size %zu\n",
- sizeof(struct queue_entry_s));
- ODP_DBG(" queue_entry_t size %zu\n",
- sizeof(queue_entry_t));
- ODP_DBG("\n");
-
- return 0;
-}
-
-odp_queue_type_t odp_queue_type(odp_queue_t handle)
-{
- queue_entry_t *queue;
-
- queue = queue_to_qentry(handle);
-
- return queue->s.type;
-}
-
-odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle)
-{
- queue_entry_t *queue;
-
- queue = queue_to_qentry(handle);
-
- return queue->s.param.sched.sync;
-}
-
-odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type,
- odp_queue_param_t *param)
-{
- uint32_t i;
- queue_entry_t *queue;
- odp_queue_t handle = ODP_QUEUE_INVALID;
-
- for (i = 0; i < ODP_CONFIG_QUEUES; i++) {
- queue = &queue_tbl->queue[i];
-
- if (queue->s.status != QUEUE_STATUS_FREE)
- continue;
-
- LOCK(&queue->s.lock);
- if (queue->s.status == QUEUE_STATUS_FREE) {
- queue_init(queue, name, type, param);
-
- if (type == ODP_QUEUE_TYPE_SCHED ||
- type == ODP_QUEUE_TYPE_PKTIN)
- queue->s.status = QUEUE_STATUS_NOTSCHED;
- else
- queue->s.status = QUEUE_STATUS_READY;
-
- handle = queue->s.handle;
- UNLOCK(&queue->s.lock);
- break;
- }
- UNLOCK(&queue->s.lock);
- }
-
- if (handle != ODP_QUEUE_INVALID &&
- (type == ODP_QUEUE_TYPE_SCHED || type == ODP_QUEUE_TYPE_PKTIN)) {
- odp_buffer_t buf;
-
- buf = odp_schedule_buffer_alloc(handle);
- if (buf == ODP_BUFFER_INVALID) {
- ODP_ERR("queue_init: sched buf alloc failed\n");
- return ODP_QUEUE_INVALID;
- }
-
- queue->s.sched_buf = buf;
- odp_schedule_mask_set(handle, queue->s.param.sched.prio);
- }
-
- return handle;
-}
-
-
-odp_buffer_t queue_sched_buf(odp_queue_t handle)
-{
- queue_entry_t *queue;
- queue = queue_to_qentry(handle);
-
- return queue->s.sched_buf;
-}
-
-
-int queue_sched_atomic(odp_queue_t handle)
-{
- queue_entry_t *queue;
- queue = queue_to_qentry(handle);
-
- return queue->s.param.sched.sync == ODP_SCHED_SYNC_ATOMIC;
-}
-
-
-odp_queue_t odp_queue_lookup(const char *name)
-{
- uint32_t i;
-
- for (i = 0; i < ODP_CONFIG_QUEUES; i++) {
- queue_entry_t *queue = &queue_tbl->queue[i];
-
- if (queue->s.status == QUEUE_STATUS_FREE)
- continue;
-
- LOCK(&queue->s.lock);
- if (strcmp(name, queue->s.name) == 0) {
- /* found it */
- UNLOCK(&queue->s.lock);
- return queue->s.handle;
- }
- UNLOCK(&queue->s.lock);
- }
-
- return ODP_QUEUE_INVALID;
-}
-
-
-int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)
-{
- int sched = 0;
-
- LOCK(&queue->s.lock);
- if (queue->s.head == NULL) {
- /* Empty queue */
- queue->s.head = buf_hdr;
- queue->s.tail = buf_hdr;
- buf_hdr->pkt.next = NULL;
- } else {
- queue->s.tail->pkt.next = buf_hdr;
- queue->s.tail = buf_hdr;
- buf_hdr->pkt.next = NULL;
- }
-
- if (queue->s.status == QUEUE_STATUS_NOTSCHED) {
- queue->s.status = QUEUE_STATUS_SCHED;
- sched = 1; /* retval: schedule queue */
- }
- UNLOCK(&queue->s.lock);
-
- /* Add queue to scheduling */
- if (sched == 1)
- odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio);
-
- return 0;
-}
-
-
-int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
-{
- int sched = 0;
- int i;
- odp_buffer_hdr_t *tail;
-
- for (i = 0; i < num - 1; i++)
- buf_hdr[i]->pkt.next = buf_hdr[i+1];
-
- tail = buf_hdr[num-1];
- buf_hdr[num-1]->pkt.next = NULL;
-
- LOCK(&queue->s.lock);
- /* Empty queue */
- if (queue->s.head == NULL)
- queue->s.head = buf_hdr[0];
- else
- queue->s.tail->pkt.next = buf_hdr[0];
-
- queue->s.tail = tail;
-
- if (queue->s.status == QUEUE_STATUS_NOTSCHED) {
- queue->s.status = QUEUE_STATUS_SCHED;
- sched = 1; /* retval: schedule queue */
- }
- UNLOCK(&queue->s.lock);
-
- /* Add queue to scheduling */
- if (sched == 1)
- odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio);
-
- return 0;
-}
-
-
-int odp_queue_enq_multi(odp_queue_t handle, odp_buffer_t buf[], int num)
-{
- odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];
- queue_entry_t *queue;
- int i;
-
- if (num > QUEUE_MULTI_MAX)
- num = QUEUE_MULTI_MAX;
-
- queue = queue_to_qentry(handle);
-
- for (i = 0; i < num; i++)
- buf_hdr[i] = odp_buf_to_hdr(buf[i]);
-
- return queue->s.enqueue_multi(queue, buf_hdr, num);
-}
-
-
-int odp_queue_enq(odp_queue_t handle, odp_buffer_t buf)
-{
- odp_buffer_hdr_t *buf_hdr;
- queue_entry_t *queue;
-
- queue = queue_to_qentry(handle);
- buf_hdr = odp_buf_to_hdr(buf);
-
- return queue->s.enqueue(queue, buf_hdr);
-}
-
-
-odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)
-{
- odp_buffer_hdr_t *buf_hdr = NULL;
-
- LOCK(&queue->s.lock);
-
- if (queue->s.head == NULL) {
- /* Already empty queue */
- if (queue->s.status == QUEUE_STATUS_SCHED &&
- queue->s.type != ODP_QUEUE_TYPE_PKTIN)
- queue->s.status = QUEUE_STATUS_NOTSCHED;
- } else {
- buf_hdr = queue->s.head;
- queue->s.head = buf_hdr->pkt.next;
- buf_hdr->pkt.next = NULL;
-
- if (queue->s.head == NULL) {
- /* Queue is now empty */
- queue->s.tail = NULL;
- }
- }
-
- UNLOCK(&queue->s.lock);
-
- return buf_hdr;
-}
-
-
-int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
-{
- int i = 0;
-
- LOCK(&queue->s.lock);
-
- if (queue->s.head == NULL) {
- /* Already empty queue */
- if (queue->s.status == QUEUE_STATUS_SCHED &&
- queue->s.type != ODP_QUEUE_TYPE_PKTIN)
- queue->s.status = QUEUE_STATUS_NOTSCHED;
- } else {
- odp_buffer_hdr_t *hdr = queue->s.head;
-
- for (; i < num && hdr; i++) {
- buf_hdr[i] = hdr;
- /* odp_prefetch(hdr->addr); */
- hdr = hdr->pkt.next;
- buf_hdr[i]->pkt.next = NULL;
- }
-
- queue->s.head = hdr;
-
- if (hdr == NULL) {
- /* Queue is now empty */
- queue->s.tail = NULL;
- }
- }
-
- UNLOCK(&queue->s.lock);
-
- return i;
-}
-
-
-int odp_queue_deq_multi(odp_queue_t handle, odp_buffer_t buf[], int num)
-{
- queue_entry_t *queue;
- odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];
- int i, ret;
-
- if (num > QUEUE_MULTI_MAX)
- num = QUEUE_MULTI_MAX;
-
- queue = queue_to_qentry(handle);
-
- ret = queue->s.dequeue_multi(queue, buf_hdr, num);
-
- for (i = 0; i < ret; i++)
- buf[i] = (odp_buffer_t) buf_hdr[i];
-
- return ret;
-}
-
-
-odp_buffer_t odp_queue_deq(odp_queue_t handle)
-{
- queue_entry_t *queue;
- odp_buffer_hdr_t *buf_hdr;
-
- queue = queue_to_qentry(handle);
- buf_hdr = queue->s.dequeue(queue);
-
- if (buf_hdr)
- return (odp_buffer_t) buf_hdr;
-
- return ODP_BUFFER_INVALID;
-}
-
-
-void queue_lock(queue_entry_t *queue)
-{
- LOCK(&queue->s.lock);
-}
-
-
-void queue_unlock(queue_entry_t *queue)
-{
- UNLOCK(&queue->s.lock);
-}