This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "".
The branch, 2.0 has been updated via 76f82972ecb51aa64215c97cb3d7f94e5de980f9 (commit) via 60a1a4f1cc531d7f0117cd79daf1cbe4206e12ef (commit) via 2fb72324f0a247ffb800b54f112eb75716b42c22 (commit) via 90c3fdd7124ad1ed887fa6b09b7665a39021e895 (commit) via 9d65b4659d98c0c5c2b45c2733d7cc2ef3d13123 (commit) via 39126ab23611e57d4015b376f1e7222489ca2c63 (commit) via beff45d25a614e7b4c84fc734fc588f1c26bb8c4 (commit) via d340de6d0a6002d7f145d278ccf18d4c9c9b233d (commit) via e943f8213505508125e39bf228ba80dab1cb8378 (commit) via a197b3ca3ae732cb8b9aa8237e3ffd5249ecb361 (commit) via bf803098eb1518dfb9e719071256fe22700b8c72 (commit) via 3cb452014694b6a20ab2896370a90b4fbded7512 (commit) via 73bc46197ec0617878034ac793dcc96ed41eb9a1 (commit) via a2e288f35da1f3838f0650157932a93091e6c3f4 (commit) via 7ea3096a0b64b605fd14d654a6b1f644ea72ba3d (commit) via 458683cb05ecdf60c38d2827e8f6241ab4afa8e4 (commit) via 9695d43dc1afa2baf968c97f1afff11e381408aa (commit) via a63f25ff2994b2df78c24f1f8b63d0e06628eb68 (commit) via 34884aa91524c4329e4ea1a9b312538d8f7dd187 (commit) via d74515dcb08a8f15ffee5fca621bd8dc1742a9f5 (commit) via 24bf1003e1fbf6ca4003c31a79dfe5ddc40e38d9 (commit) via 506bf9dcf0e071cd8b168806b1d279124551af86 (commit) via 41472f5887d172234aaa89af0775b9e32f2209e9 (commit) via 8f63377237e1f783f77c2baf94922f07bcb24a55 (commit) via 52cfe7ba6d2541cf5ee464e46e91b2da5efe1497 (commit) via 75cfc6f70d5b21d6f04082e1d03a7e677a895280 (commit) via 052d2687930e5a99568e9349ca9704ae507e8dc5 (commit) via 0ff7861b8a958b5e23adc5b13783aeeff0629e03 (commit) via 50cb30d14d432257f0a80da45b71bce2ddacad8d (commit) via b4d17b1f6807cd980a1b2dd30573f17677ea371b (commit) via f025da7131d921a4207b31bd5af4490da9b0ef24 (commit) via e04e5f90df69e3031622b77fb5273b85d47eb966 (commit) via fdc44dd4322f624c2a5d8c0be5306f7c45364520 (commit) via a9f4c8dd372b1846390ceae6f3f7c8e7578ad743 (commit) via 614399faccde551f7ee473e3763254bce96e3444 (commit) via 13f091e6e0e5fff0552abd1d54b3559b4fc6158f (commit) via f710dd9c76b8a7683f07574afdfc5896f8e4db7a (commit) via 3794fb4eddebf95579fa176d27ef1b82ad16dfdd (commit) via 886e54149d3ee64e56c422a0d3dd7c536e2b4b7d (commit) via ec7353be201b526ade8819d9668dec111a9211d7 (commit) via c2ed3f71a8d61449c5e35ce201f020a74a8ea244 (commit) from 3d3c8f71f39ff139695d6f4b8e5ea17502c5f7cf (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 76f82972ecb51aa64215c97cb3d7f94e5de980f9 Merge: 3d3c8f71 60a1a4f1 Author: Honnappa Nagarahalli honnappa.nagarahalli@arm.com Date: Wed Oct 11 19:22:04 2017 -0500
Merge branch 'api-next' into 2.0
Signed-off-by: Honnappa Nagarahalli honnappa.nagarahalli@arm.com Reviewed-by: Yi He yi.he@arm.com Reviewed-by: Ola Liljedahl ola.liljedahl@arm.com
diff --cc .travis.yml index 55871703,539f4cc9..29909a3a --- a/.travis.yml +++ b/.travis.yml @@@ -161,7 -161,8 +161,9 @@@ install make config T=${TARGET} O=${TARGET} pushd ${TARGET} sed -ri 's,(CONFIG_RTE_LIBRTE_PMD_PCAP=).*,\1y,' .config + sed -ri 's,(CONFIG_RTE_LIBRTE_PMD_OPENSSL=).*,\1y,' .config + cat .config |grep RTE_MACHINE + sed -ri 's,(CONFIG_RTE_MACHINE=).*,\1"snb",' .config popd make install T=${TARGET} EXTRA_CFLAGS="-fPIC" rm -r ./doc ./${TARGET}/app ./${TARGET}/build diff --cc configure.ac index e56adcde,1c106d3c..9e45d0fe --- a/configure.ac +++ b/configure.ac @@@ -224,8 -219,10 +224,9 @@@ AM_CONDITIONAL([user_guide], [test "x${ AM_CONDITIONAL([HAVE_MSCGEN], [test "x${MSCGEN}" = "xmscgen"]) AM_CONDITIONAL([helper_linux], [test x$helper_linux = xyes ]) AM_CONDITIONAL([ARCH_IS_ARM], [test "x${ARCH_DIR}" = "xarm"]) + AM_CONDITIONAL([ARCH_IS_AARCH64], [test "x${ARCH_DIR}" = "xaarch64"]) AM_CONDITIONAL([ARCH_IS_MIPS64], [test "x${ARCH_DIR}" = "xmips64"]) AM_CONDITIONAL([ARCH_IS_POWERPC], [test "x${ARCH_DIR}" = "xpowerpc"]) -AM_CONDITIONAL([ARCH_IS_X86], [test "x${ARCH_DIR}" = "xx86"])
########################################################################## # Setup doxygen documentation diff --cc platform/linux-dpdk/Makefile.am index ad3afec0,00000000..c99cfaa1 mode 100644,000000..100644 --- a/platform/linux-dpdk/Makefile.am +++ b/platform/linux-dpdk/Makefile.am @@@ -1,356 -1,0 +1,372 @@@ +include $(top_srcdir)/platform/Makefile.inc +include $(top_srcdir)/platform/@with_platform@/Makefile.inc + +lib_LTLIBRARIES = $(LIB)/libodp-dpdk.la + +PLAT_CFLAGS = +if ARCH_IS_X86 +PLAT_CFLAGS += -msse4.2 +endif + +if SDK_INSTALL_PATH_ +PLAT_CFLAGS += -include $(SDK_INSTALL_PATH)/include/rte_config.h +else +PLAT_CFLAGS += -include /usr/include/dpdk/rte_config.h +endif + +AM_CPPFLAGS = $(PLAT_CFLAGS) +AM_CPPFLAGS += -I$(top_srcdir)/platform/linux-dpdk/include +AM_CPPFLAGS += -I$(top_srcdir)/platform/linux-generic/include +AM_CPPFLAGS += -I$(srcdir)/include +AM_CPPFLAGS += -I$(top_srcdir)/include +AM_CPPFLAGS += -I$(top_srcdir)/frameworks/modular +AM_CPPFLAGS += -I$(top_srcdir)/include/odp/arch/@ARCH_ABI@ +AM_CPPFLAGS += -I$(top_builddir)/include +AM_CPPFLAGS += -Iinclude +AM_CPPFLAGS += -I$(srcdir) +AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch/$(ARCH_DIR) ++AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch/default +AM_CPPFLAGS += -DSYSCONFDIR="@sysconfdir@" + +AM_CPPFLAGS += $(DPDK_CPPFLAGS) +AM_CPPFLAGS += $(OPENSSL_CPPFLAGS) +AM_CPPFLAGS += $(LIBCONFIG_CFLAGS) + +include_HEADERS = \ + $(top_srcdir)/include/odp.h \ + $(top_srcdir)/include/odp_api.h \ + $(top_srcdir)/include/odp_drv.h + +odpincludedir= $(includedir)/odp +odpinclude_HEADERS = \ + $(srcdir)/include/odp/visibility_begin.h \ + $(srcdir)/include/odp/visibility_end.h + +odpapiincludedir= $(includedir)/odp/api +odpapiinclude_HEADERS = \ + $(srcdir)/include/odp/api/align.h \ + $(srcdir)/include/odp/api/atomic.h \ + $(srcdir)/include/odp/api/barrier.h \ + $(srcdir)/include/odp/api/buffer.h \ + $(srcdir)/include/odp/api/byteorder.h \ + $(srcdir)/include/odp/api/classification.h \ + $(srcdir)/include/odp/api/compiler.h \ + $(srcdir)/include/odp/api/cpu.h \ + $(srcdir)/include/odp/api/cpumask.h \ + $(srcdir)/include/odp/api/crypto.h \ + $(srcdir)/include/odp/api/debug.h \ + $(srcdir)/include/odp/api/deprecated.h \ + $(srcdir)/include/odp/api/errno.h \ + $(srcdir)/include/odp/api/event.h \ + $(srcdir)/include/odp/api/feature.h \ + $(srcdir)/include/odp/api/hash.h \ + $(srcdir)/include/odp/api/hints.h \ + $(srcdir)/include/odp/api/init.h \ + $(srcdir)/include/odp/api/ipsec.h \ + $(srcdir)/include/odp/api/packet_flags.h \ + $(srcdir)/include/odp/api/packet.h \ + $(srcdir)/include/odp/api/packet_io.h \ + $(srcdir)/include/odp/api/packet_io_stats.h \ + $(srcdir)/include/odp/api/pool.h \ + $(srcdir)/include/odp/api/queue.h \ + $(srcdir)/include/odp/api/random.h \ + $(srcdir)/include/odp/api/rwlock.h \ + $(srcdir)/include/odp/api/rwlock_recursive.h \ + $(srcdir)/include/odp/api/schedule.h \ + $(srcdir)/include/odp/api/schedule_types.h \ + $(srcdir)/include/odp/api/shared_memory.h \ + $(srcdir)/include/odp/api/spinlock.h \ + $(srcdir)/include/odp/api/spinlock_recursive.h \ + $(srcdir)/include/odp/api/std_clib.h \ + $(srcdir)/include/odp/api/std_types.h \ + $(srcdir)/include/odp/api/support.h \ + $(srcdir)/include/odp/api/sync.h \ + $(srcdir)/include/odp/api/system_info.h \ + $(srcdir)/include/odp/api/thread.h \ + $(srcdir)/include/odp/api/thrmask.h \ + $(srcdir)/include/odp/api/ticketlock.h \ + $(srcdir)/include/odp/api/time.h \ + $(srcdir)/include/odp/api/timer.h \ + $(srcdir)/include/odp/api/traffic_mngr.h \ + $(srcdir)/include/odp/api/version.h + +if ARCH_IS_ARM +odpapiinclude_HEADERS += $(srcdir)/arch/arm/odp/api/cpu_arch.h +endif +if ARCH_IS_MIPS64 +odpapiinclude_HEADERS += $(srcdir)/arch/mips64/odp/api/cpu_arch.h +endif +if ARCH_IS_POWERPC +odpapiinclude_HEADERS += $(srcdir)/arch/powerpc/odp/api/cpu_arch.h +endif +if ARCH_IS_X86 +odpapiinclude_HEADERS += $(srcdir)/arch/x86/odp/api/cpu_arch.h +endif + +odpapiplatincludedir= $(includedir)/odp/api/plat +odpapiplatinclude_HEADERS = \ + $(builddir)/include/odp/api/plat/static_inline.h \ + $(srcdir)/include/odp/api/plat/atomic_inlines.h \ + $(srcdir)/include/odp/api/plat/atomic_types.h \ + $(srcdir)/include/odp/api/plat/barrier_types.h \ + $(srcdir)/include/odp/api/plat/buffer_types.h \ + $(srcdir)/include/odp/api/plat/byteorder_inlines.h \ + $(srcdir)/include/odp/api/plat/byteorder_types.h \ + $(srcdir)/include/odp/api/plat/classification_types.h \ + $(srcdir)/include/odp/api/plat/cpumask_types.h \ + $(srcdir)/include/odp/api/plat/crypto_types.h \ + $(srcdir)/include/odp/api/plat/event_types.h \ + $(srcdir)/include/odp/api/plat/init_types.h \ + $(srcdir)/include/odp/api/plat/ipsec_types.h \ + $(srcdir)/include/odp/api/plat/packet_flag_inlines.h \ + $(srcdir)/include/odp/api/plat/packet_flag_inlines_api.h \ + $(srcdir)/include/odp/api/plat/packet_inlines.h \ + $(srcdir)/include/odp/api/plat/packet_inlines_api.h \ + $(srcdir)/include/odp/api/plat/packet_io_types.h \ + $(srcdir)/include/odp/api/plat/packet_types.h \ + $(srcdir)/include/odp/api/plat/pool_types.h \ + $(srcdir)/include/odp/api/plat/queue_types.h \ + $(srcdir)/include/odp/api/plat/rwlock_types.h \ + $(srcdir)/include/odp/api/plat/rwlock_recursive_types.h \ + $(srcdir)/include/odp/api/plat/schedule_types.h \ + $(srcdir)/include/odp/api/plat/shared_memory_types.h \ + $(srcdir)/include/odp/api/plat/spinlock_types.h \ + $(srcdir)/include/odp/api/plat/spinlock_recursive_types.h \ + $(srcdir)/include/odp/api/plat/std_clib_inlines.h \ + $(srcdir)/include/odp/api/plat/strong_types.h \ + $(srcdir)/include/odp/api/plat/sync_inlines.h \ + $(srcdir)/include/odp/api/plat/thread_types.h \ + $(srcdir)/include/odp/api/plat/thrmask_types.h \ + $(srcdir)/include/odp/api/plat/ticketlock_inlines.h \ + $(srcdir)/include/odp/api/plat/ticketlock_inlines_api.h \ + $(srcdir)/include/odp/api/plat/ticketlock_types.h \ + $(srcdir)/include/odp/api/plat/time_types.h \ + $(srcdir)/include/odp/api/plat/timer_types.h \ + $(srcdir)/include/odp/api/plat/traffic_mngr_types.h \ + $(srcdir)/include/odp/api/plat/version_types.h + +odpdrvincludedir = $(includedir)/odp/drv +odpdrvinclude_HEADERS = \ + $(srcdir)/include/odp/drv/align.h \ + $(srcdir)/include/odp/drv/atomic.h \ + $(srcdir)/include/odp/drv/barrier.h \ + $(srcdir)/include/odp/drv/byteorder.h \ + $(srcdir)/include/odp/drv/compiler.h \ + $(srcdir)/include/odp/drv/driver.h \ + $(srcdir)/include/odp/drv/hints.h \ + $(srcdir)/include/odp/drv/shm.h \ + $(srcdir)/include/odp/drv/spinlock.h \ + $(srcdir)/include/odp/drv/std_types.h \ + $(srcdir)/include/odp/drv/sync.h + +odpdrvplatincludedir = $(includedir)/odp/drv/plat +odpdrvplatinclude_HEADERS = \ + $(srcdir)/include/odp/drv/plat/atomic_types.h \ + $(srcdir)/include/odp/drv/plat/barrier_types.h \ + $(srcdir)/include/odp/drv/plat/byteorder_types.h \ + $(srcdir)/include/odp/drv/compiler.h \ + $(srcdir)/include/odp/drv/plat/driver_types.h \ + $(srcdir)/include/odp/drv/plat/shm_types.h \ + $(srcdir)/include/odp/drv/plat/spinlock_types.h \ + $(srcdir)/include/odp/drv/plat/strong_types.h + + +noinst_HEADERS = \ + ${top_srcdir}/platform/linux-generic/include/odp_buffer_subsystem.h \ + ${top_srcdir}/platform/linux-generic/include/_fdserver_internal.h \ + ${top_srcdir}/platform/linux-generic/include/_ishm_internal.h \ + ${top_srcdir}/platform/linux-generic/include/_ishmphy_internal.h \ + ${top_srcdir}/platform/linux-generic/include/_ishmpool_internal.h \ + ${top_srcdir}/platform/linux-generic/include/drv_driver_internal.h\ + ${top_srcdir}/platform/linux-generic/include/odp_align_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_atomic_internal.h \ + ${srcdir}/include/odp_buffer_inlines.h \ + ${srcdir}/include/odp_buffer_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_bitmap_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_classification_internal.h \ + ${srcdir}/include/odp_config_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_debug_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_classification_datamodel.h \ + ${top_srcdir}/platform/linux-generic/include/odp_classification_inlines.h \ + ${top_srcdir}/platform/linux-generic/include/odp_classification_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_crypto_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_forward_typedefs_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_internal.h \ + ${srcdir}/pktio/dpdk.h \ + ${srcdir}/include/odp_packet_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_pktio_ops_ipc.h \ + ${top_srcdir}/platform/linux-generic/include/odp_pktio_ops_subsystem.h \ + ${top_srcdir}/platform/linux-generic/include/odp_pktio_ops_socket.h \ + ${top_srcdir}/platform/linux-generic/include/odp_pktio_ops_loopback.h \ + ${top_srcdir}/platform/linux-generic/include/odp_name_table_internal.h \ + ${srcdir}/include/odp_packet_io_internal.h \ + ${srcdir}/include/odp_errno_define.h \ + ${top_srcdir}/platform/linux-generic/include/odp_packet_io_ring_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_pkt_queue_internal.h \ + ${srcdir}/include/odp_pool_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_pool_subsystem.h \ + ${srcdir}/include/odp_posix_extensions.h \ + ${top_srcdir}/platform/linux-generic/include/odp_queue_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_queue_if.h \ + ${top_srcdir}/platform/linux-generic/include/odp_queue_subsystem.h \ + ${top_srcdir}/platform/linux-generic/include/odp_ring_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_schedule_if.h \ + ${top_srcdir}/platform/linux-generic/include/odp_schedule_subsystem.h \ + ${top_srcdir}/platform/linux-generic/include/odp_sorted_list_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_shm_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_time_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_timer_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_timer_wheel_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_traffic_mngr_internal.h \ + ${srcdir}/include/protocols/eth.h \ + ${srcdir}/include/protocols/ip.h \ + ${srcdir}/include/protocols/ipsec.h \ + ${srcdir}/include/protocols/tcp.h \ + ${srcdir}/include/protocols/udp.h \ + ${srcdir}/Makefile.inc + +__LIB__libodp_dpdk_la_SOURCES = \ + ../linux-generic/_fdserver.c \ + ../linux-generic/_ishm.c \ + ../linux-generic/_ishmphy.c \ + ../linux-generic/_ishmpool.c \ + ../linux-generic/_modules.c \ + ../linux-generic/odp_atomic.c \ + ../linux-generic/odp_barrier.c \ + ../linux-generic/odp_bitmap.c \ + buffer/dpdk.c \ + ../linux-generic/odp_byteorder.c \ ++ ../linux-generic/odp_chksum.c \ + ../linux-generic/odp_classification.c \ + ../linux-generic/odp_cpu.c \ + ../linux-generic/odp_cpumask.c \ + ../linux-generic/odp_cpumask_task.c \ + odp_crypto.c \ + odp_errno.c \ + ../linux-generic/odp_event.c \ + ../linux-generic/odp_hash.c \ + odp_init.c \ + ../linux-generic/odp_impl.c \ + ../linux-generic/odp_ipsec.c \ + ../linux-generic/odp_name_table.c \ + odp_packet.c \ + pktio/dpdk.c \ + pktio/subsystem.c \ + odp_packet_flags.c \ + ../linux-generic/odp_packet_io.c \ + ../linux-generic/pktio/loopback.c \ + ../linux-generic/odp_pkt_queue.c \ + pool/dpdk.c \ + ../linux-generic/odp_queue_if.c \ + ../linux-generic/queue/subsystem.c \ + ../linux-generic/queue/generic.c \ + ../linux-generic/queue/scalable.c \ + ../linux-generic/odp_rwlock.c \ + ../linux-generic/odp_rwlock_recursive.c \ + ../linux-generic/pool/subsystem.c \ + ../linux-generic/buffer/subsystem.c \ + ../linux-generic/odp_schedule_if.c \ + ../linux-generic/schedule/generic.c \ + ../linux-generic/schedule/iquery.c \ + ../linux-generic/schedule/scalable.c \ + ../linux-generic/schedule/scalable_ordered.c \ + ../linux-generic/schedule/sp.c \ + ../linux-generic/schedule/subsystem.c \ + ../linux-generic/odp_shared_memory.c \ + ../linux-generic/odp_sorted_list.c \ + ../linux-generic/odp_spinlock.c \ + ../linux-generic/odp_spinlock_recursive.c \ + odp_std_clib.c \ + ../linux-generic/odp_sync.c \ + ../linux-generic/odp_system_info.c \ + odp_thread.c \ + ../linux-generic/odp_thrmask.c \ + ../linux-generic/odp_ticketlock.c \ + odp_time.c \ + ../linux-generic/odp_timer.c \ + ../linux-generic/odp_timer_wheel.c \ + ../linux-generic/odp_traffic_mngr.c \ + ../linux-generic/odp_version.c \ + ../linux-generic/odp_weak.c \ + ../linux-generic/drv_atomic.c \ + ../linux-generic/drv_barrier.c \ + ../linux-generic/drv_driver.c \ + ../linux-generic/drv_shm.c \ + ../linux-generic/drv_spinlock.c + +if ARCH_IS_ARM +__LIB__libodp_dpdk_la_SOURCES += arch/arm/odp_cpu_arch.c \ - arch/arm/odp_sysinfo_parse.c ++ arch/arm/odp_cpu_cycles.c \ ++ arch/arm/odp_global_time.c \ ++ arch/arm/odp_sysinfo_parse.c ++endif ++if ARCH_IS_AARCH64 ++__LIB__libodp_dpdk_la_SOURCES += arch/default/odp_cpu_arch.c \ ++ arch/default/odp_cpu_cycles.c \ ++ arch/aarch64/odp_global_time.c \ ++ arch/default/odp_sysinfo_parse.c +endif +if ARCH_IS_MIPS64 +__LIB__libodp_dpdk_la_SOURCES += arch/mips64/odp_cpu_arch.c \ - arch/mips64/odp_sysinfo_parse.c ++ arch/default/odp_cpu_cycles.c \ ++ arch/default/odp_global_time.c \ ++ arch/mips64/odp_sysinfo_parse.c +endif +if ARCH_IS_POWERPC +__LIB__libodp_dpdk_la_SOURCES += arch/powerpc/odp_cpu_arch.c \ - arch/powerpc/odp_sysinfo_parse.c ++ arch/default/odp_cpu_cycles.c \ ++ arch/default/odp_global_time.c \ ++ arch/powerpc/odp_sysinfo_parse.c +endif +if ARCH_IS_X86 +__LIB__libodp_dpdk_la_SOURCES += arch/x86/cpu_flags.c \ - arch/x86/odp_cpu_arch.c \ - arch/x86/odp_sysinfo_parse.c ++ arch/x86/odp_cpu_arch.c \ ++ arch/default/odp_cpu_cycles.c \ ++ arch/x86/odp_global_time.c \ ++ arch/x86/odp_sysinfo_parse.c +endif + +pool/dpdk.lo: AM_CFLAGS += -DIM_ACTIVE_MODULE +buffer/dpdk.lo: AM_CFLAGS += -DIM_ACTIVE_MODULE +if ODP_SCHEDULE_SCALABLE +../linux-generic/schedule/scalable.lo: AM_CFLAGS += -DIM_ACTIVE_MODULE +else +if ODP_SCHEDULE_SP +../linux-generic/schedule/sp.lo: AM_CFLAGS += -DIM_ACTIVE_MODULE +else +if ODP_SCHEDULE_IQUERY +../linux-generic/schedule/iquery.lo: AM_CFLAGS += -DIM_ACTIVE_MODULE +else +../linux-generic/schedule/generic.lo: AM_CFLAGS += -DIM_ACTIVE_MODULE +endif +endif +endif +if ODP_SCHEDULE_SCALABLE +../linux-generic/queue/scalable.lo: AM_CFLAGS += -DIM_ACTIVE_MODULE +else +../linux-generic/queue/generic.lo: AM_CFLAGS += -DIM_ACTIVE_MODULE +endif + +# Build modular framework into odp-linux library +modularframeworkdir = $(top_srcdir)/frameworks/modular +noinst_HEADERS += $(modularframeworkdir)/list.h \ + $(modularframeworkdir)/odp_module.h + +__LIB__libodp_dpdk_la_SOURCES += ../../frameworks/modular/odp_module.c + +__LIB__libodp_dpdk_la_LIBADD = $(ATOMIC_LIBS) +__LIB__libodp_dpdk_la_LIBADD += $(DPDK_LIBS) +__LIB__libodp_dpdk_la_LIBADD += $(OPENSSL_LIBS) +__LIB__libodp_dpdk_la_LIBADD += $(PTHREAD_LIBS) +__LIB__libodp_dpdk_la_LIBADD += $(TIMER_LIBS) +__LIB__libodp_dpdk_la_LIBADD += $(LIBCONFIG_LIBS) + +# Create symlink for ABI header files. Application does not need to use the arch +# specific include path for installed files. +install-data-hook: + if [ -h $(DESTDIR)$(prefix)/include/odp/api/abi ]; then \ + : ; \ + else \ + $(LN_S) -rf $(DESTDIR)$(prefix)/include/odp/arch/@ARCH_ABI@/odp/api/abi \ + $(DESTDIR)$(prefix)/include/odp/api/abi; \ + fi diff --cc platform/linux-dpdk/include/odp/api/chksum.h index 00000000,00000000..a7f33328 new file mode 120000 --- /dev/null +++ b/platform/linux-dpdk/include/odp/api/chksum.h @@@ -1,0 -1,0 +1,1 @@@ ++../../../../linux-generic/include/odp/api/chksum.h diff --cc platform/linux-dpdk/odp_packet.c index cdfe2815,00000000..523c2229 mode 100644,000000..100644 --- a/platform/linux-dpdk/odp_packet.c +++ b/platform/linux-dpdk/odp_packet.c @@@ -1,1510 -1,0 +1,1505 @@@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <config.h> + +#include <odp/api/plat/packet_inlines.h> +#include <odp/api/packet.h> +#include <odp_packet_internal.h> +#include <odp_debug_internal.h> +#include <odp/api/hints.h> +#include <odp/api/byteorder.h> + +#include <protocols/eth.h> +#include <protocols/ip.h> +#include <protocols/tcp.h> +#include <protocols/udp.h> + +#include <string.h> +#include <stdio.h> +#include <stddef.h> +#include <inttypes.h> + +#include <odp/visibility_begin.h> + +/* Fill in packet header field offsets for inline functions */ + +const _odp_packet_inline_offset_t _odp_packet_inline ODP_ALIGNED_CACHE = { + .mb = offsetof(odp_packet_hdr_t, buf_hdr.mb), + .pool = offsetof(odp_packet_hdr_t, buf_hdr.pool_hdl), + .input = offsetof(odp_packet_hdr_t, input), + .user_ptr = offsetof(odp_packet_hdr_t, buf_hdr.buf_ctx), + .timestamp = offsetof(odp_packet_hdr_t, timestamp), + .input_flags = offsetof(odp_packet_hdr_t, p.input_flags), + .buf_addr = offsetof(odp_packet_hdr_t, buf_hdr.mb) + + offsetof(const struct rte_mbuf, buf_addr), + .data = offsetof(odp_packet_hdr_t, buf_hdr.mb) + + offsetof(struct rte_mbuf, data_off), + .pkt_len = offsetof(odp_packet_hdr_t, buf_hdr.mb) + + (size_t)&rte_pktmbuf_pkt_len((struct rte_mbuf *)0), + .seg_len = offsetof(odp_packet_hdr_t, buf_hdr.mb) + + (size_t)&rte_pktmbuf_data_len((struct rte_mbuf *)0), + .nb_segs = offsetof(odp_packet_hdr_t, buf_hdr.mb) + + offsetof(struct rte_mbuf, nb_segs), + .udata_len = offsetof(odp_packet_hdr_t, uarea_size), + .udata = sizeof(odp_packet_hdr_t), + .rss = offsetof(odp_packet_hdr_t, buf_hdr.mb) + + offsetof(struct rte_mbuf, hash.rss), + .ol_flags = offsetof(odp_packet_hdr_t, buf_hdr.mb) + + offsetof(struct rte_mbuf, ol_flags), + .rss_flag = PKT_RX_RSS_HASH +}; + +#include <odp/visibility_end.h> + +struct rte_mbuf dummy; +ODP_STATIC_ASSERT(sizeof(dummy.data_off) == sizeof(uint16_t), + "data_off should be uint16_t"); +ODP_STATIC_ASSERT(sizeof(dummy.pkt_len) == sizeof(uint32_t), + "pkt_len should be uint32_t"); +ODP_STATIC_ASSERT(sizeof(dummy.data_len) == sizeof(uint16_t), + "data_len should be uint16_t"); +ODP_STATIC_ASSERT(sizeof(dummy.hash.rss) == sizeof(uint32_t), + "hash.rss should be uint32_t"); +ODP_STATIC_ASSERT(sizeof(dummy.ol_flags) == sizeof(uint64_t), + "ol_flags should be uint64_t"); +/* + * + * Alloc and free + * ******************************************************** + * + */ + +static inline odp_buffer_t buffer_handle(odp_packet_hdr_t *pkt_hdr) +{ + return pkt_hdr->buf_hdr.handle.handle; +} + +static inline odp_packet_hdr_t *buf_to_packet_hdr(odp_buffer_t buf) +{ + return (odp_packet_hdr_t *)buf_hdl_to_hdr(buf); +} + +static odp_packet_t packet_alloc(odp_pool_t pool_hdl, uint32_t len) +{ + pool_entry_dp_t *pool_dp; + odp_packet_t pkt; + uintmax_t totsize = RTE_PKTMBUF_HEADROOM + len; + odp_packet_hdr_t *pkt_hdr; + struct rte_mbuf *mbuf; + + ODP_ASSERT(odp_pool_to_entry_cp(pool_hdl)->params.type + == ODP_POOL_PACKET); + + pool_dp = odp_pool_to_entry_dp(pool_hdl); + + mbuf = rte_pktmbuf_alloc(pool_dp->rte_mempool); + if (mbuf == NULL) { + rte_errno = ENOMEM; + return ODP_PACKET_INVALID; + } + pkt_hdr = (odp_packet_hdr_t *)mbuf; + pkt_hdr->buf_hdr.totsize = mbuf->buf_len; + + if (mbuf->buf_len < totsize) { + intmax_t needed = totsize - mbuf->buf_len; + struct rte_mbuf *curseg = mbuf; + + do { + struct rte_mbuf *nextseg = + rte_pktmbuf_alloc(pool_dp->rte_mempool); + + if (nextseg == NULL) { + rte_pktmbuf_free(mbuf); + return ODP_PACKET_INVALID; + } + + curseg->next = nextseg; + curseg = nextseg; + curseg->data_off = 0; + pkt_hdr->buf_hdr.totsize += curseg->buf_len; + needed -= curseg->buf_len; + } while (needed > 0); + } + + pkt = (odp_packet_t)mbuf; + + if (odp_packet_reset(pkt, len) != 0) + return ODP_PACKET_INVALID; + + return pkt; +} + +odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, uint32_t len) +{ + return packet_alloc(pool_hdl, len); +} + +int odp_packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len, + odp_packet_t pkt[], int num) +{ + int i; + + for (i = 0; i < num; i++) { + pkt[i] = packet_alloc(pool_hdl, len); + if (pkt[i] == ODP_PACKET_INVALID) + return rte_errno == ENOMEM ? i : -EINVAL; + } + return i; +} + +void odp_packet_free(odp_packet_t pkt) +{ + struct rte_mbuf *mbuf = (struct rte_mbuf *)pkt; + rte_pktmbuf_free(mbuf); +} + +void odp_packet_free_multi(const odp_packet_t pkt[], int num) +{ + int i; + + for (i = 0; i < num; i++) { + struct rte_mbuf *mbuf = (struct rte_mbuf *)pkt[i]; + + rte_pktmbuf_free(mbuf); + } +} + +int odp_packet_reset(odp_packet_t pkt, uint32_t len) +{ + odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); + struct rte_mbuf *ms, *mb = &pkt_hdr->buf_hdr.mb; + uint8_t nb_segs = 0; + int32_t lenleft = len; + + if (RTE_PKTMBUF_HEADROOM + len > odp_packet_buf_len(pkt)) { + ODP_DBG("Not enought head room for that packet %d/%d\n", + RTE_PKTMBUF_HEADROOM + len, + odp_packet_buf_len(pkt)); + return -1; + } + + pkt_hdr->p.input_flags.all = 0; + pkt_hdr->p.output_flags.all = 0; + pkt_hdr->p.error_flags.all = 0; + + pkt_hdr->p.l2_offset = 0; + pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID; + pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID; + + pkt_hdr->buf_hdr.next = NULL; + + pkt_hdr->input = ODP_PKTIO_INVALID; + pkt_hdr->buf_hdr.event_subtype = ODP_EVENT_PACKET_BASIC; + + mb->port = 0xff; + mb->pkt_len = len; + mb->data_off = RTE_PKTMBUF_HEADROOM; + mb->vlan_tci = 0; + nb_segs = 1; + + if (RTE_PKTMBUF_HEADROOM + lenleft <= mb->buf_len) { + mb->data_len = lenleft; + } else { + mb->data_len = mb->buf_len - RTE_PKTMBUF_HEADROOM; + lenleft -= mb->data_len; + ms = mb->next; + while (lenleft > 0) { + nb_segs++; + ms->data_len = lenleft <= ms->buf_len ? + lenleft : ms->buf_len; + lenleft -= ms->buf_len; + ms = ms->next; + } + } + + mb->nb_segs = nb_segs; + return 0; +} + +odp_packet_t _odp_packet_from_buf_hdr(odp_buffer_hdr_t *buf_hdr) +{ + return (odp_packet_t)buf_hdr; +} + +odp_packet_t odp_packet_from_event(odp_event_t ev) +{ + if (odp_unlikely(ev == ODP_EVENT_INVALID)) + return ODP_PACKET_INVALID; + + return (odp_packet_t)buf_to_packet_hdr((odp_buffer_t)ev); +} + +odp_event_t odp_packet_to_event(odp_packet_t pkt) +{ + if (odp_unlikely(pkt == ODP_PACKET_INVALID)) + return ODP_EVENT_INVALID; + + return (odp_event_t)buffer_handle(odp_packet_hdr(pkt)); +} + +uint32_t odp_packet_buf_len(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->buf_hdr.totsize; +} + +void *odp_packet_tail(odp_packet_t pkt) +{ + struct rte_mbuf *mb = &(odp_packet_hdr(pkt)->buf_hdr.mb); + mb = rte_pktmbuf_lastseg(mb); + return (void *)(rte_pktmbuf_mtod(mb, char *) + mb->data_len); +} + +void *odp_packet_push_head(odp_packet_t pkt, uint32_t len) +{ + struct rte_mbuf *mb = &(odp_packet_hdr(pkt)->buf_hdr.mb); + return (void *)rte_pktmbuf_prepend(mb, len); +} + +static void _copy_head_metadata(struct rte_mbuf *newhead, + struct rte_mbuf *oldhead) +{ + odp_packet_t pkt = (odp_packet_t)newhead; + uint32_t saved_index = odp_packet_hdr(pkt)->buf_hdr.index; + + rte_mbuf_refcnt_set(newhead, rte_mbuf_refcnt_read(oldhead)); + newhead->port = oldhead->port; + newhead->ol_flags = oldhead->ol_flags; + newhead->packet_type = oldhead->packet_type; + newhead->vlan_tci = oldhead->vlan_tci; + newhead->hash.rss = 0; + newhead->seqn = oldhead->seqn; + newhead->vlan_tci_outer = oldhead->vlan_tci_outer; + newhead->udata64 = oldhead->udata64; + memcpy(&newhead->tx_offload, &oldhead->tx_offload, + sizeof(odp_packet_hdr_t) - + offsetof(struct rte_mbuf, tx_offload)); + odp_packet_hdr(pkt)->buf_hdr.handle.handle = + (odp_buffer_t)newhead; + odp_packet_hdr(pkt)->buf_hdr.index = saved_index; +} + +int odp_packet_extend_head(odp_packet_t *pkt, uint32_t len, void **data_ptr, + uint32_t *seg_len) +{ + struct rte_mbuf *mb = &(odp_packet_hdr(*pkt)->buf_hdr.mb); + int addheadsize = len - rte_pktmbuf_headroom(mb); + + if (addheadsize > 0) { + struct rte_mbuf *newhead, *t; + uint32_t totsize_change; + int i; + + newhead = rte_pktmbuf_alloc(mb->pool); + if (newhead == NULL) + return -1; + + newhead->data_len = addheadsize % newhead->buf_len; + newhead->pkt_len = addheadsize; + newhead->data_off = newhead->buf_len - newhead->data_len; + newhead->nb_segs = addheadsize / newhead->buf_len + 1; + t = newhead; + + for (i = 0; i < newhead->nb_segs - 1; --i) { + t->next = rte_pktmbuf_alloc(mb->pool); + + if (t->next == NULL) { + rte_pktmbuf_free(newhead); + return -1; + } + /* The intermediate segments are fully used */ + t->data_len = t->buf_len; + t->data_off = 0; + } + totsize_change = newhead->nb_segs * newhead->buf_len; + if (rte_pktmbuf_chain(newhead, mb)) { + rte_pktmbuf_free(newhead); + return -1; + } + /* Expand the original head segment*/ + newhead->pkt_len += rte_pktmbuf_headroom(mb); + mb->data_off = 0; + mb->data_len = mb->buf_len; + _copy_head_metadata(newhead, mb); + mb = newhead; + *pkt = (odp_packet_t)newhead; + odp_packet_hdr(*pkt)->buf_hdr.totsize += totsize_change; + } else { + rte_pktmbuf_prepend(mb, len); + } + + if (data_ptr) + *data_ptr = odp_packet_data(*pkt); + if (seg_len) + *seg_len = mb->data_len; + + return 0; +} + +void *odp_packet_pull_head(odp_packet_t pkt, uint32_t len) +{ + struct rte_mbuf *mb = &(odp_packet_hdr(pkt)->buf_hdr.mb); + return (void *)rte_pktmbuf_adj(mb, len); +} + +int odp_packet_trunc_head(odp_packet_t *pkt, uint32_t len, void **data_ptr, + uint32_t *seg_len) +{ + struct rte_mbuf *mb = &(odp_packet_hdr(*pkt)->buf_hdr.mb); + + if (odp_packet_len(*pkt) < len) + return -1; + + if (len > mb->data_len) { + struct rte_mbuf *newhead = mb, *prev = NULL; + uint32_t left = len; + uint32_t totsize_change = 0; + + while (newhead->next != NULL) { + if (newhead->data_len > left) + break; + left -= newhead->data_len; + totsize_change += newhead->buf_len; + prev = newhead; + newhead = newhead->next; + --mb->nb_segs; + } + newhead->data_off += left; + newhead->nb_segs = mb->nb_segs; + newhead->pkt_len = mb->pkt_len - len; + newhead->data_len -= left; + _copy_head_metadata(newhead, mb); + prev->next = NULL; + rte_pktmbuf_free(mb); + *pkt = (odp_packet_t)newhead; + odp_packet_hdr(*pkt)->buf_hdr.totsize -= totsize_change; + } else { + rte_pktmbuf_adj(mb, len); + } + + if (data_ptr) + *data_ptr = odp_packet_data(*pkt); + if (seg_len) + *seg_len = mb->data_len; + + return 0; +} + +void *odp_packet_push_tail(odp_packet_t pkt, uint32_t len) +{ + struct rte_mbuf *mb = &(odp_packet_hdr(pkt)->buf_hdr.mb); + + return (void *)rte_pktmbuf_append(mb, len); +} + +int odp_packet_extend_tail(odp_packet_t *pkt, uint32_t len, void **data_ptr, + uint32_t *seg_len) +{ + struct rte_mbuf *mb = &(odp_packet_hdr(*pkt)->buf_hdr.mb); + int newtailsize = len - odp_packet_tailroom(*pkt); + uint32_t old_pkt_len = odp_packet_len(*pkt); + + if (data_ptr) + *data_ptr = odp_packet_tail(*pkt); + + if (newtailsize > 0) { + struct rte_mbuf *newtail = rte_pktmbuf_alloc(mb->pool); + struct rte_mbuf *t; + struct rte_mbuf *m_last = rte_pktmbuf_lastseg(mb); + int i; + + if (newtail == NULL) + return -1; + newtail->data_off = 0; + newtail->pkt_len = newtailsize; + if (newtailsize > newtail->buf_len) + newtail->data_len = newtail->buf_len; + else + newtail->data_len = newtailsize; + newtail->nb_segs = newtailsize / newtail->buf_len + 1; + t = newtail; + + for (i = 0; i < newtail->nb_segs - 1; ++i) { + t->next = rte_pktmbuf_alloc(mb->pool); + + if (t->next == NULL) { + rte_pktmbuf_free(newtail); + return -1; + } + t = t->next; + t->data_off = 0; + /* The last segment's size is not trivial*/ + t->data_len = i == newtail->nb_segs - 2 ? + newtailsize % newtail->buf_len : + t->buf_len; + } + if (rte_pktmbuf_chain(mb, newtail)) { + rte_pktmbuf_free(newtail); + return -1; + } + /* Expand the original tail */ + m_last->data_len = m_last->buf_len - m_last->data_off; + mb->pkt_len += len - newtailsize; + odp_packet_hdr(*pkt)->buf_hdr.totsize += + newtail->nb_segs * newtail->buf_len; + } else { + rte_pktmbuf_append(mb, len); + } + + if (seg_len) + odp_packet_offset(*pkt, old_pkt_len, seg_len, NULL); + + return 0; +} + +void *odp_packet_pull_tail(odp_packet_t pkt, uint32_t len) +{ + struct rte_mbuf *mb = &(odp_packet_hdr(pkt)->buf_hdr.mb); + + if (rte_pktmbuf_trim(mb, len)) + return NULL; + else + return odp_packet_tail(pkt); +} + +int odp_packet_trunc_tail(odp_packet_t *pkt, uint32_t len, void **tail_ptr, + uint32_t *tailroom) +{ + struct rte_mbuf *mb = &(odp_packet_hdr(*pkt)->buf_hdr.mb); + + if (odp_packet_len(*pkt) < len) + return -1; + + if (rte_pktmbuf_trim(mb, len)) { + struct rte_mbuf *reverse[mb->nb_segs]; + struct rte_mbuf *t = mb; + int i; + + for (i = 0; i < mb->nb_segs; ++i) { + reverse[i] = t; + t = t->next; + } + for (i = mb->nb_segs - 1; i >= 0 && len > 0; --i) { + t = reverse[i]; + if (len >= t->data_len) { + len -= t->data_len; + mb->pkt_len -= t->data_len; + t->data_len = 0; + if (i > 0) { + rte_pktmbuf_free_seg(t); + --mb->nb_segs; + reverse[i - 1]->next = NULL; + } + } else { + t->data_len -= len; + mb->pkt_len -= len; + len = 0; + } + } + } + + if (tail_ptr) + *tail_ptr = odp_packet_tail(*pkt); + if (tailroom) + *tailroom = odp_packet_tailroom(*pkt); + + return 0; +} + +void *odp_packet_offset(odp_packet_t pkt, uint32_t offset, uint32_t *len, + odp_packet_seg_t *seg) +{ + struct rte_mbuf *mb = &(odp_packet_hdr(pkt)->buf_hdr.mb); + + do { + if (mb->data_len > offset) { + break; + } else { + offset -= mb->data_len; + mb = mb->next; + } + } while (mb); + + if (mb) { + if (len) + *len = mb->data_len - offset; + if (seg) + *seg = (odp_packet_seg_t)(uintptr_t)mb; + return (void *)(rte_pktmbuf_mtod(mb, char *) + offset); + } else { + return NULL; + } +} + +/* + * + * Meta-data + * ******************************************************** + * + */ + +int odp_packet_input_index(odp_packet_t pkt) +{ + return odp_pktio_index(odp_packet_hdr(pkt)->input); +} + +void odp_packet_user_ptr_set(odp_packet_t pkt, const void *ctx) +{ + odp_packet_hdr(pkt)->buf_hdr.buf_cctx = ctx; +} + +static inline void *packet_offset_to_ptr(odp_packet_t pkt, uint32_t *len, + const size_t offset) +{ + if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID)) + return NULL; + + if (len) + return odp_packet_offset(pkt, offset, len, NULL); + else + return odp_packet_offset(pkt, offset, NULL, NULL); +} + +void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + if (!packet_hdr_has_l2(pkt_hdr)) + return NULL; + return packet_offset_to_ptr(pkt, len, pkt_hdr->p.l2_offset); +} + +uint32_t odp_packet_l2_offset(odp_packet_t pkt) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + if (!packet_hdr_has_l2(pkt_hdr)) + return ODP_PACKET_OFFSET_INVALID; + return pkt_hdr->p.l2_offset; +} + +int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + if (odp_unlikely(offset >= (odp_packet_len(pkt) - 1))) + return -1; + + packet_hdr_has_l2_set(pkt_hdr, 1); + pkt_hdr->p.l2_offset = offset; + return 0; +} + +void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + return packet_offset_to_ptr(pkt, len, pkt_hdr->p.l3_offset); +} + +uint32_t odp_packet_l3_offset(odp_packet_t pkt) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + return pkt_hdr->p.l3_offset; +} + +int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + if (odp_unlikely(offset >= (odp_packet_len(pkt) - 1))) + return -1; + + pkt_hdr->p.l3_offset = offset; + return 0; +} + +void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + return packet_offset_to_ptr(pkt, len, pkt_hdr->p.l4_offset); +} + +uint32_t odp_packet_l4_offset(odp_packet_t pkt) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + return pkt_hdr->p.l4_offset; +} + +int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + if (odp_unlikely(offset >= (odp_packet_len(pkt) - 1))) + return -1; + + pkt_hdr->p.l4_offset = offset; + return 0; +} + +void odp_packet_ts_set(odp_packet_t pkt, odp_time_t timestamp) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + pkt_hdr->timestamp = timestamp; + pkt_hdr->p.input_flags.timestamp = 1; +} + +/* + * + * Segment level + * ******************************************************** + * + */ + +void *odp_packet_seg_data(odp_packet_t pkt ODP_UNUSED, odp_packet_seg_t seg) +{ + return odp_packet_data((odp_packet_t)(uintptr_t)seg); +} + +uint32_t odp_packet_seg_data_len(odp_packet_t pkt ODP_UNUSED, + odp_packet_seg_t seg) +{ + return odp_packet_seg_len((odp_packet_t)(uintptr_t)seg); +} + +/* + * + * Manipulation + * ******************************************************** + * + */ + +int odp_packet_add_data(odp_packet_t *pkt_ptr, uint32_t offset, uint32_t len) +{ + odp_packet_t pkt = *pkt_ptr; + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + uint32_t pktlen = odp_packet_len(pkt); + odp_packet_t newpkt; + + if (offset > pktlen) + return -1; + + newpkt = odp_packet_alloc(pkt_hdr->buf_hdr.pool_hdl, pktlen + len); + + if (newpkt == ODP_PACKET_INVALID) + return -1; + + if (odp_packet_copy_from_pkt(newpkt, 0, pkt, 0, offset) != 0 || + odp_packet_copy_from_pkt(newpkt, offset + len, pkt, offset, + pktlen - offset) != 0) { + odp_packet_free(newpkt); + return -1; + } + + _odp_packet_copy_md_to_packet(pkt, newpkt); + odp_packet_free(pkt); + *pkt_ptr = newpkt; + + return 1; +} + +int odp_packet_rem_data(odp_packet_t *pkt_ptr, uint32_t offset, uint32_t len) +{ + odp_packet_t pkt = *pkt_ptr; + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + uint32_t pktlen = odp_packet_len(pkt); + odp_packet_t newpkt; + + if (offset > pktlen || offset + len > pktlen) + return -1; + + newpkt = odp_packet_alloc(pkt_hdr->buf_hdr.pool_hdl, pktlen - len); + + if (newpkt == ODP_PACKET_INVALID) + return -1; + + if (odp_packet_copy_from_pkt(newpkt, 0, pkt, 0, offset) != 0 || + odp_packet_copy_from_pkt(newpkt, offset, pkt, offset + len, + pktlen - offset - len) != 0) { + odp_packet_free(newpkt); + return -1; + } + + _odp_packet_copy_md_to_packet(pkt, newpkt); + odp_packet_free(pkt); + *pkt_ptr = newpkt; + + return 1; +} + +int odp_packet_align(odp_packet_t *pkt, uint32_t offset, uint32_t len, + uint32_t align) +{ + int rc; + uint32_t shift; + uint32_t seglen = 0; /* GCC */ + void *addr = odp_packet_offset(*pkt, offset, &seglen, NULL); + uint64_t uaddr = (uint64_t)(uintptr_t)addr; + uint64_t misalign; + + if (align > ODP_CACHE_LINE_SIZE) + return -1; + + if (seglen >= len) { + misalign = align <= 1 ? 0 : + ROUNDUP_ALIGN(uaddr, align) - uaddr; + if (misalign == 0) + return 0; + shift = align - misalign; + } else { + if (len > odp_packet_seg_len(*pkt)) + return -1; + shift = len - seglen; + uaddr -= shift; + misalign = align <= 1 ? 0 : + ROUNDUP_ALIGN(uaddr, align) - uaddr; + if (misalign) + shift += align - misalign; + } + + rc = odp_packet_extend_head(pkt, shift, NULL, NULL); + if (rc < 0) + return rc; + + (void)odp_packet_move_data(*pkt, 0, shift, + odp_packet_len(*pkt) - shift); + + (void)odp_packet_trunc_tail(pkt, shift, NULL, NULL); + return 1; +} + +int odp_packet_concat(odp_packet_t *dst, odp_packet_t src) +{ + odp_packet_hdr_t *dst_hdr = odp_packet_hdr(*dst); + odp_packet_hdr_t *src_hdr = odp_packet_hdr(src); + struct rte_mbuf *mb_dst = pkt_to_mbuf(dst_hdr); + struct rte_mbuf *mb_src = pkt_to_mbuf(src_hdr); + odp_packet_t new_dst; + odp_pool_t pool; + uint32_t dst_len; + uint32_t src_len; + + if (odp_likely(!rte_pktmbuf_chain(mb_dst, mb_src))) { + dst_hdr->buf_hdr.totsize += src_hdr->buf_hdr.totsize; + return 0; + } + + /* Fall back to using standard copy operations after maximum number of + * segments has been reached. */ + dst_len = odp_packet_len(*dst); + src_len = odp_packet_len(src); + pool = odp_packet_pool(*dst); + + new_dst = odp_packet_copy(*dst, pool); + if (odp_unlikely(new_dst == ODP_PACKET_INVALID)) + return -1; + + if (odp_packet_extend_tail(&new_dst, src_len, NULL, NULL) >= 0) { + (void)odp_packet_copy_from_pkt(new_dst, dst_len, + src, 0, src_len); + odp_packet_free(*dst); + odp_packet_free(src); + *dst = new_dst; + return 1; + } + + odp_packet_free(new_dst); + return -1; +} + +int odp_packet_split(odp_packet_t *pkt, uint32_t len, odp_packet_t *tail) +{ + uint32_t pktlen = odp_packet_len(*pkt); + + if (len >= pktlen || tail == NULL) + return -1; + + *tail = odp_packet_copy_part(*pkt, len, pktlen - len, + odp_packet_pool(*pkt)); + + if (*tail == ODP_PACKET_INVALID) + return -1; + + return odp_packet_trunc_tail(pkt, pktlen - len, NULL, NULL); +} + +/* + * + * Copy + * ******************************************************** + * + */ + +odp_packet_t odp_packet_copy(odp_packet_t pkt, odp_pool_t pool) +{ + uint32_t pktlen = odp_packet_len(pkt); + odp_packet_t newpkt = odp_packet_alloc(pool, pktlen); + + if (newpkt != ODP_PACKET_INVALID) { + if (_odp_packet_copy_md_to_packet(pkt, newpkt) || + odp_packet_copy_from_pkt(newpkt, 0, pkt, 0, pktlen)) { + odp_packet_free(newpkt); + newpkt = ODP_PACKET_INVALID; + } + } + + return newpkt; +} + +odp_packet_t odp_packet_copy_part(odp_packet_t pkt, uint32_t offset, + uint32_t len, odp_pool_t pool) +{ + uint32_t pktlen = odp_packet_len(pkt); + odp_packet_t newpkt; + + if (offset >= pktlen || offset + len > pktlen) + return ODP_PACKET_INVALID; + + newpkt = odp_packet_alloc(pool, len); + if (newpkt != ODP_PACKET_INVALID) + odp_packet_copy_from_pkt(newpkt, 0, pkt, offset, len); + + return newpkt; +} + +int odp_packet_copy_to_mem(odp_packet_t pkt, uint32_t offset, + uint32_t len, void *dst) +{ + void *mapaddr; + uint32_t seglen = 0; /* GCC */ + uint32_t cpylen; + uint8_t *dstaddr = (uint8_t *)dst; + + if (offset + len > odp_packet_len(pkt)) + return -1; + + while (len > 0) { + mapaddr = odp_packet_offset(pkt, offset, &seglen, NULL); + cpylen = len > seglen ? seglen : len; + memcpy(dstaddr, mapaddr, cpylen); + offset += cpylen; + dstaddr += cpylen; + len -= cpylen; + } + + return 0; +} + +int odp_packet_copy_from_mem(odp_packet_t pkt, uint32_t offset, + uint32_t len, const void *src) +{ + void *mapaddr; + uint32_t seglen = 0; /* GCC */ + uint32_t cpylen; + const uint8_t *srcaddr = (const uint8_t *)src; + + if (offset + len > odp_packet_len(pkt)) + return -1; + + while (len > 0) { + mapaddr = odp_packet_offset(pkt, offset, &seglen, NULL); + cpylen = len > seglen ? seglen : len; + memcpy(mapaddr, srcaddr, cpylen); + offset += cpylen; + srcaddr += cpylen; + len -= cpylen; + } + + return 0; +} + +int odp_packet_copy_from_pkt(odp_packet_t dst, uint32_t dst_offset, + odp_packet_t src, uint32_t src_offset, + uint32_t len) +{ + odp_packet_hdr_t *dst_hdr = odp_packet_hdr(dst); + odp_packet_hdr_t *src_hdr = odp_packet_hdr(src); + void *dst_map; + void *src_map; + uint32_t cpylen, minseg; + uint32_t dst_seglen = 0; /* GCC */ + uint32_t src_seglen = 0; /* GCC */ + int overlap; + + if (dst_offset + len > odp_packet_len(dst) || + src_offset + len > odp_packet_len(src)) + return -1; + + overlap = (dst_hdr == src_hdr && + ((dst_offset <= src_offset && + dst_offset + len >= src_offset) || + (src_offset <= dst_offset && + src_offset + len >= dst_offset))); + + if (overlap && src_offset < dst_offset) { + odp_packet_t temp = + odp_packet_copy_part(src, src_offset, len, + odp_packet_pool(src)); + if (temp == ODP_PACKET_INVALID) + return -1; + odp_packet_copy_from_pkt(dst, dst_offset, temp, 0, len); + odp_packet_free(temp); + return 0; + } + + while (len > 0) { + dst_map = odp_packet_offset(dst, dst_offset, &dst_seglen, NULL); + src_map = odp_packet_offset(src, src_offset, &src_seglen, NULL); + + minseg = dst_seglen > src_seglen ? src_seglen : dst_seglen; + cpylen = len > minseg ? minseg : len; + + if (overlap) + memmove(dst_map, src_map, cpylen); + else + memcpy(dst_map, src_map, cpylen); + + dst_offset += cpylen; + src_offset += cpylen; + len -= cpylen; + } + + return 0; +} + +int odp_packet_copy_data(odp_packet_t pkt, uint32_t dst_offset, + uint32_t src_offset, uint32_t len) +{ + return odp_packet_copy_from_pkt(pkt, dst_offset, + pkt, src_offset, len); +} + +int odp_packet_move_data(odp_packet_t pkt, uint32_t dst_offset, + uint32_t src_offset, uint32_t len) +{ + return odp_packet_copy_from_pkt(pkt, dst_offset, + pkt, src_offset, len); +} + +/* + * + * Debugging + * ******************************************************** + * + */ + +void odp_packet_print(odp_packet_t pkt) +{ + odp_packet_seg_t seg; + int max_len = 512; + char str[max_len]; + uint8_t *p; + int len = 0; + int n = max_len - 1; + odp_packet_hdr_t *hdr = odp_packet_hdr(pkt); + odp_buffer_t buf = packet_to_buffer(pkt); + + len += snprintf(&str[len], n - len, "Packet "); + len += odp_buffer_snprint(&str[len], n - len, buf); + len += snprintf(&str[len], n - len, " input_flags 0x%" PRIx64 "\n", + hdr->p.input_flags.all); + len += snprintf(&str[len], n - len, " error_flags 0x%" PRIx32 "\n", + hdr->p.error_flags.all); + len += snprintf(&str[len], n - len, " output_flags 0x%" PRIx32 "\n", + hdr->p.output_flags.all); + len += snprintf(&str[len], n - len, + " l2_offset %" PRIu32 "\n", hdr->p.l2_offset); + len += snprintf(&str[len], n - len, + " l3_offset %" PRIu32 "\n", hdr->p.l3_offset); + len += snprintf(&str[len], n - len, + " l4_offset %" PRIu32 "\n", hdr->p.l4_offset); + len += snprintf(&str[len], n - len, + " frame_len %" PRIu32 "\n", + hdr->buf_hdr.mb.pkt_len); + len += snprintf(&str[len], n - len, + " input %" PRIu64 "\n", + odp_pktio_to_u64(hdr->input)); + len += snprintf(&str[len], n - len, + " headroom %" PRIu32 "\n", + odp_packet_headroom(pkt)); + len += snprintf(&str[len], n - len, + " tailroom %" PRIu32 "\n", + odp_packet_tailroom(pkt)); + len += snprintf(&str[len], n - len, + " num_segs %i\n", odp_packet_num_segs(pkt)); + + seg = odp_packet_first_seg(pkt); + + while (seg != ODP_PACKET_SEG_INVALID) { + len += snprintf(&str[len], n - len, + " seg_len %" PRIu32 "\n", + odp_packet_seg_data_len(pkt, seg)); + + seg = odp_packet_next_seg(pkt, seg); + } + + str[len] = '\0'; + + ODP_PRINT("\n%s\n", str); + rte_pktmbuf_dump(stdout, &hdr->buf_hdr.mb, 32); + + p = odp_packet_data(pkt); + ODP_ERR("00000000: %02X %02X %02X %02X %02X %02X %02X %02X\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + ODP_ERR("00000008: %02X %02X %02X %02X %02X %02X %02X %02X\n", + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); +} + +int odp_packet_is_valid(odp_packet_t pkt) +{ + odp_buffer_t buf = packet_to_buffer(pkt); + + return odp_buffer_is_valid(buf); +} + +/* + * + * Internal Use Routines + * ******************************************************** + * + */ + +int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt) +{ + odp_packet_hdr_t *srchdr = odp_packet_hdr(srcpkt); + odp_packet_hdr_t *dsthdr = odp_packet_hdr(dstpkt); + uint32_t src_size = odp_packet_user_area_size(srcpkt); + uint32_t dst_size = odp_packet_user_area_size(dstpkt); + + dsthdr->input = srchdr->input; + dsthdr->dst_queue = srchdr->dst_queue; + dsthdr->buf_hdr.buf_u64 = srchdr->buf_hdr.buf_u64; + + dsthdr->buf_hdr.mb.port = srchdr->buf_hdr.mb.port; + dsthdr->buf_hdr.mb.ol_flags = srchdr->buf_hdr.mb.ol_flags; + dsthdr->buf_hdr.mb.packet_type = srchdr->buf_hdr.mb.packet_type; + dsthdr->buf_hdr.mb.vlan_tci = srchdr->buf_hdr.mb.vlan_tci; + dsthdr->buf_hdr.mb.hash = srchdr->buf_hdr.mb.hash; + dsthdr->buf_hdr.mb.vlan_tci_outer = srchdr->buf_hdr.mb.vlan_tci_outer; + dsthdr->buf_hdr.mb.tx_offload = srchdr->buf_hdr.mb.tx_offload; + + if (dst_size != 0) + memcpy(odp_packet_user_area(dstpkt), + odp_packet_user_area(srcpkt), + dst_size <= src_size ? dst_size : src_size); + + copy_packet_parser_metadata(srchdr, dsthdr); + + /* Metadata copied, but return indication of whether the packet + * user area was truncated in the process. Note this can only + * happen when copying between different pools. + */ + return dst_size < src_size; +} + +/** + * Parser helper function for IPv4 + */ +static inline uint8_t parse_ipv4(packet_parser_t *prs, const uint8_t **parseptr, + uint32_t *offset, uint32_t frame_len) +{ + const _odp_ipv4hdr_t *ipv4 = (const _odp_ipv4hdr_t *)*parseptr; + uint8_t ver = _ODP_IPV4HDR_VER(ipv4->ver_ihl); + uint8_t ihl = _ODP_IPV4HDR_IHL(ipv4->ver_ihl); + uint16_t frag_offset; + uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr); + uint32_t l3_len = odp_be_to_cpu_16(ipv4->tot_len); + + if (odp_unlikely(ihl < _ODP_IPV4HDR_IHL_MIN) || + odp_unlikely(ver != 4) || + (l3_len > frame_len - *offset)) { + prs->error_flags.ip_err = 1; + return 0; + } + + *offset += ihl * 4; + *parseptr += ihl * 4; + + if (odp_unlikely(ihl > _ODP_IPV4HDR_IHL_MIN)) + prs->input_flags.ipopt = 1; + + /* 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))) + prs->input_flags.ipfrag = 1; + + /* Handle IPv4 broadcast / multicast */ + prs->input_flags.ip_bcast = (dstaddr == 0xffffffff); + prs->input_flags.ip_mcast = (dstaddr >> 28) == 0xd; + + return ipv4->proto; +} + +/** + * Parser helper function for IPv6 + */ +static inline uint8_t parse_ipv6(packet_parser_t *prs, const uint8_t **parseptr, + uint32_t *offset, uint32_t frame_len, + uint32_t seg_len) +{ + const _odp_ipv6hdr_t *ipv6 = (const _odp_ipv6hdr_t *)*parseptr; + const _odp_ipv6hdr_ext_t *ipv6ext; + uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr.u8[0]); + uint32_t l3_len = odp_be_to_cpu_16(ipv6->payload_len) + + _ODP_IPV6HDR_LEN; + + /* Basic sanity checks on IPv6 header */ + if ((odp_be_to_cpu_32(ipv6->ver_tc_flow) >> 28) != 6 || + l3_len > frame_len - *offset) { + prs->error_flags.ip_err = 1; + return 0; + } + + /* IPv6 broadcast / multicast flags */ + prs->input_flags.ip_mcast = (dstaddr0 & 0xff000000) == 0xff000000; + prs->input_flags.ip_bcast = 0; + + /* Skip past IPv6 header */ + *offset += sizeof(_odp_ipv6hdr_t); + *parseptr += sizeof(_odp_ipv6hdr_t); + + /* Skip past any IPv6 extension headers */ + if (ipv6->next_hdr == _ODP_IPPROTO_HOPOPTS || + ipv6->next_hdr == _ODP_IPPROTO_ROUTE) { + prs->input_flags.ipopt = 1; + + do { + ipv6ext = (const _odp_ipv6hdr_ext_t *)*parseptr; + uint16_t extlen = 8 + ipv6ext->ext_len * 8; + + *offset += extlen; + *parseptr += extlen; + } while ((ipv6ext->next_hdr == _ODP_IPPROTO_HOPOPTS || + ipv6ext->next_hdr == _ODP_IPPROTO_ROUTE) && + *offset < seg_len); + + if (*offset >= prs->l3_offset + + odp_be_to_cpu_16(ipv6->payload_len)) { + prs->error_flags.ip_err = 1; + return 0; + } + + if (ipv6ext->next_hdr == _ODP_IPPROTO_FRAG) + prs->input_flags.ipfrag = 1; + + return ipv6ext->next_hdr; + } + + if (odp_unlikely(ipv6->next_hdr == _ODP_IPPROTO_FRAG)) { + prs->input_flags.ipopt = 1; + prs->input_flags.ipfrag = 1; + } + + return ipv6->next_hdr; +} + +/** + * Parser helper function for TCP + */ +static inline void parse_tcp(packet_parser_t *prs, + const uint8_t **parseptr, uint32_t *offset) +{ + const _odp_tcphdr_t *tcp = (const _odp_tcphdr_t *)*parseptr; + + if (tcp->hl < sizeof(_odp_tcphdr_t) / sizeof(uint32_t)) + prs->error_flags.tcp_err = 1; + else if ((uint32_t)tcp->hl * 4 > sizeof(_odp_tcphdr_t)) + prs->input_flags.tcpopt = 1; + + if (offset) + *offset += (uint32_t)tcp->hl * 4; + *parseptr += (uint32_t)tcp->hl * 4; +} + +/** + * Parser helper function for UDP + */ +static inline void parse_udp(packet_parser_t *prs, + const uint8_t **parseptr, uint32_t *offset) +{ + const _odp_udphdr_t *udp = (const _odp_udphdr_t *)*parseptr; + uint32_t udplen = odp_be_to_cpu_16(udp->length); + + if (odp_unlikely(udplen < sizeof(_odp_udphdr_t))) + prs->error_flags.udp_err = 1; + + if (offset) + *offset += sizeof(_odp_udphdr_t); + *parseptr += sizeof(_odp_udphdr_t); +} + +/** + * Parse common packet headers up to given layer + * + * The function expects at least PACKET_PARSE_SEG_LEN bytes of data to be + * available from the ptr. + */ +int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, + uint32_t frame_len, uint32_t seg_len, + odp_pktio_parser_layer_t layer) +{ + uint32_t offset; + uint16_t ethtype; + const uint8_t *parseptr; + uint8_t ip_proto; + const _odp_ethhdr_t *eth; + uint16_t macaddr0, macaddr2, macaddr4; + const _odp_vlanhdr_t *vlan; + + if (layer == ODP_PKTIO_PARSER_LAYER_NONE) + return 0; + + /* We only support Ethernet for now */ + prs->input_flags.eth = 1; + /* Assume valid L2 header, no CRC/FCS check in SW */ + prs->input_flags.l2 = 1; + /* Detect jumbo frames */ + if (frame_len > _ODP_ETH_LEN_MAX) + prs->input_flags.jumbo = 1; + + offset = sizeof(_odp_ethhdr_t); + eth = (const _odp_ethhdr_t *)ptr; + + /* Handle Ethernet broadcast/multicast addresses */ + macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth)); + prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; + + if (macaddr0 == 0xffff) { + macaddr2 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 1)); + macaddr4 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 2)); + prs->input_flags.eth_bcast = + (macaddr2 == 0xffff) && (macaddr4 == 0xffff); + } else { + prs->input_flags.eth_bcast = 0; + } + + /* Get Ethertype */ + ethtype = odp_be_to_cpu_16(eth->type); + parseptr = (const uint8_t *)(eth + 1); + + /* Check for SNAP vs. DIX */ + if (ethtype < _ODP_ETH_LEN_MAX) { + prs->input_flags.snap = 1; + if (ethtype > frame_len - offset) { + prs->error_flags.snap_len = 1; + goto parse_exit; + } + ethtype = odp_be_to_cpu_16(*((const uint16_t *)(uintptr_t) + (parseptr + 6))); + offset += 8; + parseptr += 8; + } + + /* Parse the VLAN header(s), if present */ + if (ethtype == _ODP_ETHTYPE_VLAN_OUTER) { + prs->input_flags.vlan_qinq = 1; + prs->input_flags.vlan = 1; + + vlan = (const _odp_vlanhdr_t *)parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); + } + + if (ethtype == _ODP_ETHTYPE_VLAN) { + prs->input_flags.vlan = 1; + vlan = (const _odp_vlanhdr_t *)parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); + } + + if (layer == ODP_PKTIO_PARSER_LAYER_L2) + return prs->error_flags.all != 0; + + /* Set l3_offset+flag only for known ethtypes */ + prs->l3_offset = offset; + prs->input_flags.l3 = 1; + + /* Parse Layer 3 headers */ + switch (ethtype) { + case _ODP_ETHTYPE_IPV4: + prs->input_flags.ipv4 = 1; + ip_proto = parse_ipv4(prs, &parseptr, &offset, frame_len); + break; + + case _ODP_ETHTYPE_IPV6: + prs->input_flags.ipv6 = 1; + ip_proto = parse_ipv6(prs, &parseptr, &offset, frame_len, + seg_len); + break; + + case _ODP_ETHTYPE_ARP: + prs->input_flags.arp = 1; + ip_proto = 255; /* Reserved invalid by IANA */ + break; + + default: + prs->input_flags.l3 = 0; + prs->l3_offset = ODP_PACKET_OFFSET_INVALID; + ip_proto = 255; /* Reserved invalid by IANA */ + } + + if (layer == ODP_PKTIO_PARSER_LAYER_L3) + return prs->error_flags.all != 0; + + /* Set l4_offset+flag only for known ip_proto */ + prs->l4_offset = offset; + prs->input_flags.l4 = 1; + + /* Parse Layer 4 headers */ + switch (ip_proto) { + case _ODP_IPPROTO_ICMPv4: + /* Fall through */ + + case _ODP_IPPROTO_ICMPv6: + prs->input_flags.icmp = 1; + break; + + case _ODP_IPPROTO_TCP: + if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) + return -1; + prs->input_flags.tcp = 1; + parse_tcp(prs, &parseptr, NULL); + break; + + case _ODP_IPPROTO_UDP: + if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) + return -1; + prs->input_flags.udp = 1; + parse_udp(prs, &parseptr, NULL); + break; + + case _ODP_IPPROTO_AH: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_ah = 1; + break; + + case _ODP_IPPROTO_ESP: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_esp = 1; + break; + + case _ODP_IPPROTO_SCTP: + prs->input_flags.sctp = 1; + break; + + default: + prs->input_flags.l4 = 0; + prs->l4_offset = ODP_PACKET_OFFSET_INVALID; + break; + } +parse_exit: + return prs->error_flags.all != 0; +} +/** + * Simple packet parser + */ +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, + odp_pktio_parser_layer_t layer) +{ + uint32_t seg_len = odp_packet_seg_len((odp_packet_t)pkt_hdr); + uint32_t len = packet_len(pkt_hdr); + void *base = odp_packet_data((odp_packet_t)pkt_hdr); + + return packet_parse_common(&pkt_hdr->p, base, len, seg_len, layer); +} + +uint64_t odp_packet_to_u64(odp_packet_t hdl) +{ + return _odp_pri(hdl); +} + +uint64_t odp_packet_seg_to_u64(odp_packet_seg_t hdl) +{ + return _odp_pri(hdl); +} + +odp_packet_t odp_packet_ref_static(odp_packet_t pkt) +{ + return odp_packet_copy(pkt, odp_packet_pool(pkt)); +} + +odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset) +{ + odp_packet_t new; + int ret; + + new = odp_packet_copy(pkt, odp_packet_pool(pkt)); + + if (new == ODP_PACKET_INVALID) { + ODP_ERR("copy failed\n"); + return ODP_PACKET_INVALID; + } + + ret = odp_packet_trunc_head(&new, offset, NULL, NULL); + + if (ret < 0) { + ODP_ERR("trunk_head failed\n"); + odp_packet_free(new); + return ODP_PACKET_INVALID; + } + + return new; +} + +odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset, + odp_packet_t hdr) +{ + odp_packet_t new; + int ret; + + new = odp_packet_copy(pkt, odp_packet_pool(pkt)); + + if (new == ODP_PACKET_INVALID) { + ODP_ERR("copy failed\n"); + return ODP_PACKET_INVALID; + } + + if (offset) { + ret = odp_packet_trunc_head(&new, offset, NULL, NULL); + + if (ret < 0) { + ODP_ERR("trunk_head failed\n"); + odp_packet_free(new); + return ODP_PACKET_INVALID; + } + } + + ret = odp_packet_concat(&hdr, new); + + if (ret < 0) { + ODP_ERR("concat failed\n"); + odp_packet_free(new); + return ODP_PACKET_INVALID; + } + + return hdr; +} + +int odp_packet_has_ref(odp_packet_t pkt) +{ + (void)pkt; + + return 0; +} + - uint32_t odp_packet_unshared_len(odp_packet_t pkt) - { - return odp_packet_len(pkt); - } - +/* Include non-inlined versions of API functions */ +#if ODP_ABI_COMPAT == 1 +#include <odp/api/plat/packet_inlines_api.h> +#endif diff --cc platform/linux-dpdk/pktio/dpdk.c index d7a90197,00000000..e64f02d5 mode 100644,000000..100644 --- a/platform/linux-dpdk/pktio/dpdk.c +++ b/platform/linux-dpdk/pktio/dpdk.c @@@ -1,770 -1,0 +1,771 @@@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp_posix_extensions.h> +#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/api/cpu.h> +#include <odp/api/hints.h> +#include <odp/api/thread.h> + +#include <odp/api/system_info.h> +#include <odp_debug_internal.h> +#include <odp_classification_internal.h> +#include <odp_packet_io_internal.h> +#include <pktio/dpdk.h> +#include <net/if.h> +#include <math.h> + +pktio_table_t *pktio_tbl; + +/* Forward declaration */ +static pktio_ops_module_t dpdk_pktio_ops; + +static uint32_t mtu_get_pkt_dpdk(pktio_entry_t *pktio_entry); + +static inline pktio_ops_dpdk_data_t * + __retrieve_op_data(pktio_entry_t *pktio) +{ + return (pktio_ops_dpdk_data_t *)(pktio->ops_data(dpdk)); +} + +static inline void __release_op_data(pktio_entry_t *pktio) +{ + free(pktio->ops_data(dpdk)); + pktio->ops_data(dpdk) = NULL; +} + +/* Test if s has only digits or not. Dpdk pktio uses only digits.*/ +static int _dpdk_netdev_is_valid(const char *s) +{ + while (*s) { + if (!isdigit(*s)) + return 0; + s++; + } + + return 1; +} + +static void rss_conf_to_hash_proto(struct rte_eth_rss_conf *rss_conf, + const odp_pktin_hash_proto_t *hash_proto) +{ + memset(rss_conf, 0, sizeof(struct rte_eth_rss_conf)); + + if (hash_proto->proto.ipv4_udp) + rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP; + if (hash_proto->proto.ipv4_tcp) + rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; + if (hash_proto->proto.ipv4) + rss_conf->rss_hf |= ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | + ETH_RSS_NONFRAG_IPV4_OTHER; + if (hash_proto->proto.ipv6_udp) + rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP | + ETH_RSS_IPV6_UDP_EX; + if (hash_proto->proto.ipv6_tcp) + rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP | + ETH_RSS_IPV6_TCP_EX; + if (hash_proto->proto.ipv6) + rss_conf->rss_hf |= ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | + ETH_RSS_NONFRAG_IPV6_OTHER | + ETH_RSS_IPV6_EX; + rss_conf->rss_key = NULL; +} + +static void _dpdk_print_port_mac(uint8_t portid) +{ + struct ether_addr eth_addr; + + memset(ð_addr, 0, sizeof(eth_addr)); + rte_eth_macaddr_get(portid, ð_addr); + ODP_DBG("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n", + (unsigned)portid, + eth_addr.addr_bytes[0], + eth_addr.addr_bytes[1], + eth_addr.addr_bytes[2], + eth_addr.addr_bytes[3], + eth_addr.addr_bytes[4], + eth_addr.addr_bytes[5]); +} + +static int input_queues_config_pkt_dpdk(pktio_entry_t *pktio_entry, + const odp_pktin_queue_param_t *p) +{ + pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + odp_pktin_mode_t mode = pktio_entry->s.param.in_mode; + + /** + * Scheduler synchronizes input queue polls. Only single thread + * at a time polls a queue */ + if (mode == ODP_PKTIN_MODE_SCHED || + p->op_mode == ODP_PKTIO_OP_MT_UNSAFE) + pkt_dpdk->lockless_rx = 1; + else + pkt_dpdk->lockless_rx = 0; + + if (p->hash_enable && p->num_queues > 1) { + pkt_dpdk->hash = p->hash_proto; + } else { + pkt_dpdk->hash.proto.ipv4_udp = 1; + pkt_dpdk->hash.proto.ipv4_tcp = 1; + pkt_dpdk->hash.proto.ipv4 = 1; + pkt_dpdk->hash.proto.ipv6_udp = 1; + pkt_dpdk->hash.proto.ipv6_tcp = 1; + pkt_dpdk->hash.proto.ipv6 = 1; + } + + return 0; +} + +static int output_queues_config_pkt_dpdk(pktio_entry_t *pktio_entry, + const odp_pktout_queue_param_t *p) +{ + pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + + if (p->op_mode == ODP_PKTIO_OP_MT_UNSAFE) + pkt_dpdk->lockless_tx = 1; + else + pkt_dpdk->lockless_tx = 0; + + return 0; +} + +static int setup_pkt_dpdk(odp_pktio_t pktio ODP_UNUSED, + pktio_entry_t *pktio_entry, + const char *netdev, + odp_pool_t pool ODP_UNUSED) +{ + uint8_t portid = 0; + struct rte_eth_dev_info dev_info; + pktio_ops_dpdk_data_t *pkt_dpdk = NULL; + int i; + + if (!_dpdk_netdev_is_valid(netdev)) { + ODP_DBG("Interface name should only contain numbers!: %s\n", + netdev); + return -1; + } + + pktio_entry->ops_data(dpdk) = malloc(sizeof(pktio_ops_dpdk_data_t)); + pkt_dpdk = __retrieve_op_data(pktio_entry); + + if (odp_unlikely(pkt_dpdk == NULL)) { + ODP_ERR("Failed to allocate pktio_ops_dpdk_data_t struct"); + return -1; + } + + portid = atoi(netdev); + pkt_dpdk->portid = portid; + memset(&dev_info, 0, sizeof(struct rte_eth_dev_info)); + rte_eth_dev_info_get(portid, &dev_info); + if (dev_info.driver_name == NULL) { + ODP_DBG("No driver found for interface: %s\n", netdev); + return -1; + } + if (!strcmp(dev_info.driver_name, "rte_ixgbe_pmd")) + pkt_dpdk->min_rx_burst = 4; + else + pkt_dpdk->min_rx_burst = 0; + + _dpdk_print_port_mac(portid); + + pkt_dpdk->capa.max_input_queues = RTE_MIN(dev_info.max_rx_queues, + PKTIO_MAX_QUEUES); + pkt_dpdk->capa.max_output_queues = RTE_MIN(dev_info.max_tx_queues, + PKTIO_MAX_QUEUES); + + for (i = 0; i < PKTIO_MAX_QUEUES; i++) { + odp_ticketlock_init(&pkt_dpdk->rx_lock[i]); + odp_ticketlock_init(&pkt_dpdk->tx_lock[i]); + } + return 0; +} + +static int close_pkt_dpdk(pktio_entry_t *pktio_entry) +{ + const pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + + if (pktio_entry->s.state == PKTIO_STATE_STOPPED) + rte_eth_dev_close(pkt_dpdk->portid); + + __release_op_data(pktio_entry); + return 0; +} + +static int start_pkt_dpdk(pktio_entry_t *pktio_entry) +{ + int ret, i; + pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + uint8_t portid = pkt_dpdk->portid; + int sid = rte_eth_dev_socket_id(pkt_dpdk->portid); + int socket_id = sid < 0 ? 0 : sid; + uint16_t nbrxq, nbtxq; + pool_entry_cp_t *pool_entry_cp = + odp_pool_to_entry_cp(pktio_entry->s.pool); + pool_entry_dp_t *pool_entry_dp = + odp_pool_to_entry_dp(pktio_entry->s.pool); + uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; + uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; + struct rte_eth_rss_conf rss_conf; + + /* DPDK doesn't support nb_rx_q/nb_tx_q being 0 */ + if (!pktio_entry->s.num_in_queue) + pktio_entry->s.num_in_queue = 1; + if (!pktio_entry->s.num_out_queue) + pktio_entry->s.num_out_queue = 1; + + rss_conf_to_hash_proto(&rss_conf, &pkt_dpdk->hash); + + struct rte_eth_conf port_conf = { + .rxmode = { + .mq_mode = ETH_MQ_RX_RSS, + .split_hdr_size = 0, + .header_split = 0, /**< Header Split */ + .hw_ip_checksum = 0, /**< IP checksum offload */ + .hw_vlan_filter = 0, /**< VLAN filtering */ + .jumbo_frame = 1, /**< Jumbo Frame Support */ + .hw_strip_crc = 0, /**< CRC stripp by hardware */ + }, + .rx_adv_conf = { + .rss_conf = rss_conf, + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, + }; + + /* rx packet len same size as pool segment minus headroom and double + * VLAN tag + */ + port_conf.rxmode.max_rx_pkt_len = + rte_pktmbuf_data_room_size(pool_entry_dp->rte_mempool) - + 2 * 4 - RTE_PKTMBUF_HEADROOM; + + nbtxq = pktio_entry->s.num_out_queue; + nbrxq = pktio_entry->s.num_in_queue; + + ret = rte_eth_dev_configure(portid, nbrxq, nbtxq, &port_conf); + if (ret < 0) { + ODP_ERR("Cannot configure device: err=%d, port=%u\n", + ret, (unsigned)portid); + return -1; + } + + if (nb_rxd + nb_txd > pool_entry_cp->params.pkt.num / 4) { + double downrate = (double)(pool_entry_cp->params.pkt.num / 4) / + (double)(nb_rxd + nb_txd); + nb_rxd >>= (int)ceil(downrate); + nb_txd >>= (int)ceil(downrate); + ODP_DBG("downrate %f\n", downrate); + ODP_DBG("Descriptors scaled down. RX: %u TX: %u pool: %u\n", + nb_rxd, nb_txd, pool_entry_cp->params.pkt.num); + } + /* init one RX queue on each port */ + for (i = 0; i < nbrxq; i++) { + ret = rte_eth_rx_queue_setup(portid, i, nb_rxd, socket_id, + NULL, + pool_entry_dp->rte_mempool); + if (ret < 0) { + ODP_ERR("rxq:err=%d, port=%u\n", ret, (unsigned)portid); + return -1; + } + } + + /* init one TX queue on each port */ + for (i = 0; i < nbtxq; i++) { + ret = rte_eth_tx_queue_setup(portid, i, nb_txd, socket_id, + NULL); + if (ret < 0) { + ODP_ERR("txq:err=%d, port=%u\n", ret, (unsigned)portid); + return -1; + } + } + + rte_eth_promiscuous_enable(portid); + /* Some DPDK PMD vdev like pcap do not support promisc mode change. Use + * system call for them. */ + if (!rte_eth_promiscuous_get(portid)) + pkt_dpdk->vdev_sysc_promisc = 1; + else + pkt_dpdk->vdev_sysc_promisc = 0; + + rte_eth_allmulticast_enable(portid); + + ret = rte_eth_dev_start(portid); + if (ret < 0) { + ODP_ERR("rte_eth_dev_start:err=%d, port=%u\n", + ret, portid); + return ret; + } + + return 0; +} + +static int stop_pkt_dpdk(pktio_entry_t *pktio_entry) +{ + pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + rte_eth_dev_stop(pkt_dpdk->portid); + return 0; +} + +/* Forward declaration */ +static int send_pkt_dpdk(pktio_entry_t *pktio_entry, int index, + const odp_packet_t pkt_table[], int len); + +/* This function can't be called if pkt_dpdk->lockless_tx is true */ +static void _odp_pktio_send_completion(pktio_entry_t *pktio_entry) +{ + int i; + unsigned j; + odp_packet_t dummy; + pool_entry_dp_t *pool_entry_dp = + odp_pool_to_entry_dp(pktio_entry->s.pool); + struct rte_mempool *rte_mempool = pool_entry_dp->rte_mempool; + + for (j = 0; j < pktio_entry->s.num_out_queue; j++) + send_pkt_dpdk(pktio_entry, j, &dummy, 0); + + for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { + pktio_entry_t *entry = &pktio_tbl->entries[i]; + + if (rte_mempool_avail_count(rte_mempool) != 0) + return; + + if (entry == pktio_entry) + continue; + + if (odp_ticketlock_trylock(&entry->s.txl)) { + if (entry->s.state != PKTIO_STATE_FREE && + entry->s.ops == &dpdk_pktio_ops) { + for (j = 0; j < pktio_entry->s.num_out_queue; + j++) + send_pkt_dpdk(pktio_entry, j, + &dummy, 0); + } + odp_ticketlock_unlock(&entry->s.txl); + } + } +} + +static int recv_pkt_dpdk(pktio_entry_t *pktio_entry, int index, + odp_packet_t pkt_table[], int len) +{ + uint16_t nb_rx, i; + pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + odp_packet_t *saved_pkt_table; + uint8_t min = pkt_dpdk->min_rx_burst; + odp_time_t ts_val; + odp_time_t *ts = NULL; + + if (odp_unlikely(min > len)) { + ODP_DBG("PMD requires >%d buffers burst. " + "Current %d, dropped %d\n", min, len, min - len); + saved_pkt_table = pkt_table; + pkt_table = malloc(min * sizeof(odp_packet_t)); + } + + if (!pkt_dpdk->lockless_rx) + odp_ticketlock_lock(&pkt_dpdk->rx_lock[index]); + + nb_rx = rte_eth_rx_burst((uint8_t)pkt_dpdk->portid, + (uint16_t)index, + (struct rte_mbuf **)pkt_table, + (uint16_t)RTE_MAX(len, min)); + + if (pktio_entry->s.config.pktin.bit.ts_all || + pktio_entry->s.config.pktin.bit.ts_ptp) { + ts_val = odp_time_global(); + ts = &ts_val; + } + + if (nb_rx == 0 && !pkt_dpdk->lockless_tx) { + pool_entry_dp_t *pool_entry_dp = + odp_pool_to_entry_dp(pktio_entry->s.pool); + struct rte_mempool *rte_mempool = + pool_entry_dp->rte_mempool; + if (rte_mempool_avail_count(rte_mempool) == 0) + _odp_pktio_send_completion(pktio_entry); + } + + if (!pkt_dpdk->lockless_rx) + odp_ticketlock_unlock(&pkt_dpdk->rx_lock[index]); + + for (i = 0; i < nb_rx; ++i) { + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt_table[i]); + + packet_parse_reset(pkt_hdr); + pkt_hdr->input = pktio_entry->s.handle; + + if (!pktio_cls_enabled(pktio_entry) && + pktio_entry->s.config.parser.layer) + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer); + packet_set_ts(pkt_hdr, ts); + } + + if (odp_unlikely(min > len)) { + memcpy(saved_pkt_table, pkt_table, + len * sizeof(odp_packet_t)); + for (i = len; i < nb_rx; i++) + odp_packet_free(pkt_table[i]); + nb_rx = RTE_MIN(len, nb_rx); + free(pkt_table); + pktio_entry->s.stats.in_discards += min - len; + pkt_table = saved_pkt_table; + } + + if (pktio_cls_enabled(pktio_entry)) { + int failed = 0, success = 0; + + for (i = 0; i < nb_rx; i++) { + odp_packet_t new_pkt; + odp_pool_t new_pool; + uint8_t *pkt_addr; + odp_packet_hdr_t parsed_hdr; + int ret; + odp_packet_hdr_t *pkt_hdr = + odp_packet_hdr(pkt_table[i]); + + pkt_addr = odp_packet_data(pkt_table[i]); + ret = cls_classify_packet(pktio_entry, pkt_addr, + odp_packet_len(pkt_table[i]), + odp_packet_len(pkt_table[i]), + &new_pool, &parsed_hdr); + if (ret) { + failed++; + odp_packet_free(pkt_table[i]); + continue; + } + if (new_pool != odp_packet_pool(pkt_table[i])) { + new_pkt = odp_packet_copy(pkt_table[i], + new_pool); + + odp_packet_free(pkt_table[i]); + if (new_pkt == ODP_PACKET_INVALID) { + failed++; + continue; + } + pkt_table[i] = new_pkt; + } + packet_set_ts(pkt_hdr, ts); + pktio_entry->s.stats.in_octets += + odp_packet_len(pkt_table[i]); + copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); + if (success != i) + pkt_table[success] = pkt_table[i]; + ++success; + } + pktio_entry->s.stats.in_errors += failed; + pktio_entry->s.stats.in_ucast_pkts += nb_rx - failed; + nb_rx = success; + } + + return nb_rx; +} + +static int send_pkt_dpdk(pktio_entry_t *pktio_entry, int index, + const odp_packet_t pkt_table[], int len) +{ + int pkts; + pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + + if (!pkt_dpdk->lockless_tx) + odp_ticketlock_lock(&pkt_dpdk->tx_lock[index]); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" + pkts = rte_eth_tx_burst(pkt_dpdk->portid, index, + (struct rte_mbuf **)pkt_table, len); +#pragma GCC diagnostic pop + + if (!pkt_dpdk->lockless_tx) + odp_ticketlock_unlock(&pkt_dpdk->tx_lock[index]); + + if (pkts == 0) { + uint32_t mtu; + + if (odp_unlikely(rte_errno != 0)) + return -1; + + mtu = mtu_get_pkt_dpdk(pktio_entry); + if (odp_unlikely(odp_packet_len(pkt_table[0]) > mtu)) { + __odp_errno = EMSGSIZE; + return -1; + } + } + rte_errno = 0; + return pkts; +} + +static uint32_t _dpdk_vdev_mtu(uint8_t port_id) +{ + struct rte_eth_dev_info dev_info = {0}; + struct ifreq ifr; + int ret; + int sockfd; + + rte_eth_dev_info_get(port_id, &dev_info); + if_indextoname(dev_info.if_index, ifr.ifr_name); + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + ret = ioctl(sockfd, SIOCGIFMTU, &ifr); + close(sockfd); + if (ret < 0) { + ODP_DBG("ioctl SIOCGIFMTU error\n"); + return 0; + } + + return ifr.ifr_mtu; +} + +static uint32_t mtu_get_pkt_dpdk(pktio_entry_t *pktio_entry) +{ + pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + uint16_t mtu = 0; + int ret; + + ret = rte_eth_dev_get_mtu(pkt_dpdk->portid, &mtu); + if (ret < 0) + return 0; + + /* some dpdk PMD vdev does not support getting mtu size, + * try to use system call if dpdk cannot get mtu value. + */ + if (mtu == 0) + mtu = _dpdk_vdev_mtu(pkt_dpdk->portid); + return mtu; +} + +static int _dpdk_vdev_promisc_mode_set(uint8_t port_id, int enable) +{ + struct rte_eth_dev_info dev_info = {0}; + struct ifreq ifr; + int ret; + int sockfd; + + rte_eth_dev_info_get(port_id, &dev_info); + if_indextoname(dev_info.if_index, ifr.ifr_name); + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + + ret = ioctl(sockfd, SIOCGIFFLAGS, &ifr); + if (ret < 0) { + close(sockfd); + ODP_DBG("ioctl SIOCGIFFLAGS error\n"); + return -1; + } + + if (enable) + ifr.ifr_flags |= IFF_PROMISC; + else + ifr.ifr_flags &= ~(IFF_PROMISC); + + ret = ioctl(sockfd, SIOCSIFFLAGS, &ifr); + if (ret < 0) { + close(sockfd); + ODP_DBG("ioctl SIOCSIFFLAGS error\n"); + return -1; + } + + ret = ioctl(sockfd, SIOCGIFMTU, &ifr); + if (ret < 0) { + close(sockfd); + ODP_DBG("ioctl SIOCGIFMTU error\n"); + return -1; + } + + ODP_DBG("vdev promisc set to %d\n", enable); + close(sockfd); + return 0; +} + +static int promisc_mode_set_pkt_dpdk(pktio_entry_t *pktio_entry, int enable) +{ + const pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + uint8_t portid = pkt_dpdk->portid; + + if (enable) + rte_eth_promiscuous_enable(portid); + else + rte_eth_promiscuous_disable(portid); + + if (pkt_dpdk->vdev_sysc_promisc) { + int ret = _dpdk_vdev_promisc_mode_set(portid, enable); + if (ret < 0) + ODP_DBG("vdev promisc mode fail\n"); + } + + return 0; +} + +static int _dpdk_vdev_promisc_mode(uint8_t port_id) +{ + struct rte_eth_dev_info dev_info = {0}; + struct ifreq ifr; + int ret; + int sockfd; + + rte_eth_dev_info_get(port_id, &dev_info); + if_indextoname(dev_info.if_index, ifr.ifr_name); + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + ret = ioctl(sockfd, SIOCGIFFLAGS, &ifr); + close(sockfd); + if (ret < 0) { + ODP_DBG("ioctl SIOCGIFFLAGS error\n"); + return -1; + } + + if (ifr.ifr_flags & IFF_PROMISC) { + ODP_DBG("promisc is 1\n"); + return 1; + } + return 0; +} + +static int promisc_mode_get_pkt_dpdk(pktio_entry_t *pktio_entry) +{ + const pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + uint8_t portid = pkt_dpdk->portid; + + if (pkt_dpdk->vdev_sysc_promisc) + return _dpdk_vdev_promisc_mode(portid); + else + return rte_eth_promiscuous_get(portid); +} + +static int mac_get_pkt_dpdk(pktio_entry_t *pktio_entry, void *mac_addr) +{ + const pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + rte_eth_macaddr_get(pkt_dpdk->portid, + (struct ether_addr *)mac_addr); + return ETH_ALEN; +} + + +static int capability_pkt_dpdk(pktio_entry_t *pktio_entry, + odp_pktio_capability_t *capa) +{ + const pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + *capa = pkt_dpdk->capa; + return 0; +} +static int link_status_pkt_dpdk(pktio_entry_t *pktio_entry) +{ + const pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + struct rte_eth_link link; + + rte_eth_link_get(pkt_dpdk->portid, &link); + return link.link_status; +} + +static void stats_convert(struct rte_eth_stats *rte_stats, + odp_pktio_stats_t *stats) +{ + stats->in_octets = rte_stats->ibytes; + stats->in_ucast_pkts = 0; + stats->in_discards = rte_stats->imissed; + stats->in_errors = rte_stats->ierrors; + stats->in_unknown_protos = 0; + stats->out_octets = rte_stats->obytes; + stats->out_ucast_pkts = 0; + stats->out_discards = 0; + stats->out_errors = rte_stats->oerrors; +} + +static int stats_pkt_dpdk(pktio_entry_t *pktio_entry, odp_pktio_stats_t *stats) +{ + const pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + int ret; + struct rte_eth_stats rte_stats; + + ret = rte_eth_stats_get(pkt_dpdk->portid, &rte_stats); + + if (ret == 0) { + stats_convert(&rte_stats, stats); + return 0; + } + + if (ret > 0) + return -ret; + return ret; +} + +static int stats_reset_pkt_dpdk(pktio_entry_t *pktio_entry) +{ + const pktio_ops_dpdk_data_t *pkt_dpdk = + __retrieve_op_data(pktio_entry); + rte_eth_stats_reset(pkt_dpdk->portid); + return 0; +} + +static pktio_ops_module_t dpdk_pktio_ops = { + .base = { + .name = "odp-dpdk", + .init_local = NULL, + .init_global = NULL, + .term_local = NULL, + .term_global = NULL, + }, + .print = NULL, + .open = setup_pkt_dpdk, + .close = close_pkt_dpdk, + .start = start_pkt_dpdk, + .stop = stop_pkt_dpdk, + .stats = stats_pkt_dpdk, + .stats_reset = stats_reset_pkt_dpdk, + .pktin_ts_res = NULL, + .pktin_ts_from_ns = NULL, + .mtu_get = mtu_get_pkt_dpdk, + .promisc_mode_set = promisc_mode_set_pkt_dpdk, + .promisc_mode_get = promisc_mode_get_pkt_dpdk, + .mac_get = mac_get_pkt_dpdk, ++ .mac_set = NULL, + .link_status = link_status_pkt_dpdk, + .capability = capability_pkt_dpdk, + .config = NULL, + .input_queues_config = input_queues_config_pkt_dpdk, + .output_queues_config = output_queues_config_pkt_dpdk, + .recv = recv_pkt_dpdk, + .send = send_pkt_dpdk +}; + +ODP_MODULE_CONSTRUCTOR(dpdk_pktio_ops) +{ + odp_module_constructor(&dpdk_pktio_ops); + + odp_subsystem_register_module(pktio_ops, &dpdk_pktio_ops); +} + +/* Temporary variable to enable link this module, + * will remove in Makefile scheme changes. + */ +int enable_link_dpdk_pktio_ops = 0; + diff --cc platform/linux-generic/Makefile.am index 539342df,eb49f455..d5ddb4db --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@@ -12,7 -9,7 +12,8 @@@ AM_CPPFLAGS += -I$(top_srcdir)/include AM_CPPFLAGS += -I$(top_builddir)/include AM_CPPFLAGS += -Iinclude AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch/$(ARCH_DIR) +AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform) + AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch/default AM_CPPFLAGS += -Iinclude AM_CPPFLAGS += -DSYSCONFDIR="@sysconfdir@"
@@@ -246,9 -206,9 +219,10 @@@ __LIB__libodp_linux_la_SOURCES = odp_atomic.c \ odp_barrier.c \ odp_bitmap.c \ - odp_buffer.c \ + buffer/generic.c \ + buffer/subsystem.c \ odp_byteorder.c \ + odp_chksum.c \ odp_classification.c \ odp_cpu.c \ odp_cpumask.c \ diff --cc platform/linux-generic/include/odp_pktio_ops_subsystem.h index 7a915b82,00000000..3843ac70 mode 100644,000000..100644 --- a/platform/linux-generic/include/odp_pktio_ops_subsystem.h +++ b/platform/linux-generic/include/odp_pktio_ops_subsystem.h @@@ -1,106 -1,0 +1,108 @@@ +/* Copyright (c) 2017, ARM Limited. All rights reserved. + * + * Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_PKTIO_OPS_SUBSYSTEM_H_ +#define ODP_PKTIO_OPS_SUBSYSTEM_H_ + +#include <odp_module.h> +#include <odp/api/packet_io.h> + +/* ODP packet IO operations subsystem declaration */ +ODP_SUBSYSTEM_DECLARE(pktio_ops); + +/* Subsystem APIs declarations */ +ODP_SUBSYSTEM_API(pktio_ops, int, open, odp_pktio_t, + pktio_entry_t *, const char *, odp_pool_t); +ODP_SUBSYSTEM_API(pktio_ops, int, close, pktio_entry_t *); +ODP_SUBSYSTEM_API(pktio_ops, int, start, pktio_entry_t *); +ODP_SUBSYSTEM_API(pktio_ops, int, stop, pktio_entry_t *); +ODP_SUBSYSTEM_API(pktio_ops, int, stats, pktio_entry_t *, + odp_pktio_stats_t *stats); +ODP_SUBSYSTEM_API(pktio_ops, int, stats_reset, pktio_entry_t *); +ODP_SUBSYSTEM_API(pktio_ops, uint64_t, pktin_ts_res, pktio_entry_t *); +ODP_SUBSYSTEM_API(pktio_ops, odp_time_t, pktin_ts_from_ns, + pktio_entry_t *, uint64_t ns); +ODP_SUBSYSTEM_API(pktio_ops, int, recv, pktio_entry_t *, + int index, odp_packet_t packets[], int count); +ODP_SUBSYSTEM_API(pktio_ops, int, send, pktio_entry_t *, + int index, const odp_packet_t packets[], int count); +ODP_SUBSYSTEM_API(pktio_ops, uint32_t, mtu_get, pktio_entry_t *); +ODP_SUBSYSTEM_API(pktio_ops, int, promisc_mode_set, + pktio_entry_t *, int enable); +ODP_SUBSYSTEM_API(pktio_ops, int, promisc_mode_get, pktio_entry_t *); +ODP_SUBSYSTEM_API(pktio_ops, int, mac_get, pktio_entry_t *, void *); ++ODP_SUBSYSTEM_API(pktio_ops, int, mac_set, pktio_entry_t *, const void *); +ODP_SUBSYSTEM_API(pktio_ops, int, link_status, pktio_entry_t *); +ODP_SUBSYSTEM_API(pktio_ops, int, capability, pktio_entry_t *, + odp_pktio_capability_t *); +ODP_SUBSYSTEM_API(pktio_ops, int, config, pktio_entry_t *, + const odp_pktio_config_t *); +ODP_SUBSYSTEM_API(pktio_ops, int, input_queues_config, + pktio_entry_t *, const odp_pktin_queue_param_t *); +ODP_SUBSYSTEM_API(pktio_ops, int, output_queues_config, + pktio_entry_t *, const odp_pktout_queue_param_t *); +ODP_SUBSYSTEM_API(pktio_ops, void, print, pktio_entry_t *); + +/* Declare subsystem init and term routines */ +ODP_SUBSYSTEM_API(pktio_ops, int, init_global, bool); +ODP_SUBSYSTEM_API(pktio_ops, int, init_local, bool); +ODP_SUBSYSTEM_API(pktio_ops, int, term_global, bool); +ODP_SUBSYSTEM_API(pktio_ops, int, term_local, bool); + +typedef ODP_MODULE_CLASS(pktio_ops) { + odp_module_base_t base; + + odp_api_proto(pktio_ops, open) open; + odp_api_proto(pktio_ops, close) close; + odp_api_proto(pktio_ops, start) start; + odp_api_proto(pktio_ops, stop) stop; + odp_api_proto(pktio_ops, stats) stats; + odp_api_proto(pktio_ops, stats_reset) stats_reset; + odp_api_proto(pktio_ops, pktin_ts_res) pktin_ts_res; + odp_api_proto(pktio_ops, pktin_ts_from_ns) pktin_ts_from_ns; + odp_api_proto(pktio_ops, recv) recv; + odp_api_proto(pktio_ops, send) send; + odp_api_proto(pktio_ops, mtu_get) mtu_get; + odp_api_proto(pktio_ops, promisc_mode_set) promisc_mode_set; + odp_api_proto(pktio_ops, promisc_mode_get) promisc_mode_get; + odp_api_proto(pktio_ops, mac_get) mac_get; ++ odp_api_proto(pktio_ops, mac_set) mac_set; + odp_api_proto(pktio_ops, link_status) link_status; + odp_api_proto(pktio_ops, capability) capability; + odp_api_proto(pktio_ops, config) config; + odp_api_proto(pktio_ops, input_queues_config) input_queues_config; + odp_api_proto(pktio_ops, output_queues_config) output_queues_config; + odp_api_proto(pktio_ops, print) print; +} pktio_ops_module_t; + +/* All implementations of this subsystem */ +#include <odp_pktio_ops_ipc.h> +#include <odp_pktio_ops_loopback.h> +#include <odp_pktio_ops_netmap.h> +#include <odp_pktio_ops_pcap.h> +#include <odp_pktio_ops_socket.h> +#include <odp_pktio_ops_tap.h> + +/* Per implementation private data + * TODO: refactory each implementation to hide it internally + */ +typedef union { + void *dpdk; + pktio_ops_ipc_data_t ipc; + pktio_ops_loopback_data_t loopback; + pktio_ops_netmap_data_t netmap; + pktio_ops_pcap_data_t pcap; + pktio_ops_socket_data_t socket; + pktio_ops_socket_mmap_data_t mmap; + pktio_ops_tap_data_t tap; +} pktio_ops_data_t; + +/* Extract pktio ops data from pktio entry structure */ +#define ops_data(mod) s.ops_data.mod + +#endif diff --cc platform/linux-generic/pktio/dpdk.c index bbe8ddda,45153af8..c3261522 --- a/platform/linux-generic/pktio/dpdk.c +++ b/platform/linux-generic/pktio/dpdk.c @@@ -1582,24 -1542,13 +1582,25 @@@ static pktio_ops_module_t dpdk_pktio_op .promisc_mode_set = dpdk_promisc_mode_set, .promisc_mode_get = dpdk_promisc_mode_get, .mac_get = dpdk_mac_addr_get, + .mac_set = NULL, + .link_status = dpdk_link_status, .capability = dpdk_capability, - .pktin_ts_res = NULL, - .pktin_ts_from_ns = NULL, .config = NULL, .input_queues_config = dpdk_input_queues_config, - .output_queues_config = dpdk_output_queues_config + .output_queues_config = dpdk_output_queues_config, + .print = NULL, };
+ODP_MODULE_CONSTRUCTOR(dpdk_pktio_ops) +{ + odp_module_constructor(&dpdk_pktio_ops); + + odp_subsystem_register_module(pktio_ops, &dpdk_pktio_ops); +} + +/* Temporary variable to enable link this module, + * will remove in Makefile scheme changes. + */ +int enable_link_dpdk_pktio_ops = 0; + #endif /* ODP_PKTIO_DPDK */ diff --cc platform/linux-generic/pktio/ipc.c index 5211d1e5,c8880ae9..6e3fdfdb --- a/platform/linux-generic/pktio/ipc.c +++ b/platform/linux-generic/pktio/ipc.c @@@ -801,22 -790,8 +801,23 @@@ static pktio_ops_module_t ipc_pktio_op .promisc_mode_set = NULL, .promisc_mode_get = NULL, .mac_get = ipc_mac_addr_get, + .mac_set = NULL, - .pktin_ts_res = NULL, - .pktin_ts_from_ns = NULL, - .config = NULL + .link_status = NULL, + .capability = NULL, + .config = NULL, + .input_queues_config = NULL, + .output_queues_config = NULL, + .print = NULL, }; + +ODP_MODULE_CONSTRUCTOR(ipc_pktio_ops) +{ + odp_module_constructor(&ipc_pktio_ops); + + odp_subsystem_register_module(pktio_ops, &ipc_pktio_ops); +} + +/* Temporary variable to enable link this module, + * will remove in Makefile scheme changes. + */ +int enable_link_ipc_pktio_ops = 0; diff --cc platform/linux-generic/pktio/loopback.c index a3edc9d2,eba6d3b0..b17868a3 --- a/platform/linux-generic/pktio/loopback.c +++ b/platform/linux-generic/pktio/loopback.c @@@ -269,8 -265,11 +269,9 @@@ static pktio_ops_module_t loopback_pkti .promisc_mode_set = loopback_promisc_mode_set, .promisc_mode_get = loopback_promisc_mode_get, .mac_get = loopback_mac_addr_get, + .mac_set = NULL, .link_status = loopback_link_status, .capability = loopback_capability, - .pktin_ts_res = NULL, - .pktin_ts_from_ns = NULL, .config = NULL, .input_queues_config = NULL, .output_queues_config = NULL, diff --cc platform/linux-generic/pktio/netmap.c index e2d4baa5,9ee412f0..d4b5636b --- a/platform/linux-generic/pktio/netmap.c +++ b/platform/linux-generic/pktio/netmap.c @@@ -977,8 -962,10 +977,9 @@@ static pktio_ops_module_t netmap_pktio_ .promisc_mode_set = netmap_promisc_mode_set, .promisc_mode_get = netmap_promisc_mode_get, .mac_get = netmap_mac_addr_get, + .mac_set = NULL, + .link_status = netmap_link_status, .capability = netmap_capability, - .pktin_ts_res = NULL, - .pktin_ts_from_ns = NULL, .config = NULL, .input_queues_config = netmap_input_queues_config, .output_queues_config = netmap_output_queues_config, diff --cc platform/linux-generic/pktio/pcap.c index 7808242f,596bf6f2..252a9048 --- a/platform/linux-generic/pktio/pcap.c +++ b/platform/linux-generic/pktio/pcap.c @@@ -452,8 -440,10 +452,9 @@@ static pktio_ops_module_t pcap_pktio_op .promisc_mode_set = pcapif_promisc_mode_set, .promisc_mode_get = pcapif_promisc_mode_get, .mac_get = pcapif_mac_addr_get, + .mac_set = NULL, + .link_status = NULL, .capability = pcapif_capability, - .pktin_ts_res = NULL, - .pktin_ts_from_ns = NULL, .config = NULL, .input_queues_config = NULL, .output_queues_config = NULL, diff --cc platform/linux-generic/pktio/socket.c index 55d2e27c,0a80035f..df277e67 --- a/platform/linux-generic/pktio/socket.c +++ b/platform/linux-generic/pktio/socket.c @@@ -881,8 -873,11 +881,9 @@@ static pktio_ops_module_t socket_pktio_ .promisc_mode_set = sock_promisc_mode_set, .promisc_mode_get = sock_promisc_mode_get, .mac_get = sock_mac_addr_get, + .mac_set = NULL, .link_status = sock_link_status, .capability = sock_capability, - .pktin_ts_res = NULL, - .pktin_ts_from_ns = NULL, .config = NULL, .input_queues_config = NULL, .output_queues_config = NULL, diff --cc platform/linux-generic/pktio/socket_mmap.c index 09ad8137,67c5b206..3930ade2 --- a/platform/linux-generic/pktio/socket_mmap.c +++ b/platform/linux-generic/pktio/socket_mmap.c @@@ -737,8 -730,11 +737,9 @@@ static pktio_ops_module_t socket_mmap_p .promisc_mode_set = sock_mmap_promisc_mode_set, .promisc_mode_get = sock_mmap_promisc_mode_get, .mac_get = sock_mmap_mac_addr_get, + .mac_set = NULL, .link_status = sock_mmap_link_status, .capability = sock_mmap_capability, - .pktin_ts_res = NULL, - .pktin_ts_from_ns = NULL, .config = NULL, .input_queues_config = NULL, .output_queues_config = NULL, diff --cc platform/linux-generic/pktio/tap.c index 80a13d23,ed447944..bb7efe05 --- a/platform/linux-generic/pktio/tap.c +++ b/platform/linux-generic/pktio/tap.c @@@ -396,22 -391,9 +396,23 @@@ static pktio_ops_module_t tap_pktio_op .promisc_mode_set = tap_promisc_mode_set, .promisc_mode_get = tap_promisc_mode_get, .mac_get = tap_mac_addr_get, + .mac_set = NULL, + .link_status = NULL, .capability = tap_capability, - .pktin_ts_res = NULL, - .pktin_ts_from_ns = NULL, - .config = NULL + .config = NULL, + .input_queues_config = NULL, + .output_queues_config = NULL, + .print = NULL, }; + +ODP_MODULE_CONSTRUCTOR(tap_pktio_ops) +{ + odp_module_constructor(&tap_pktio_ops); + + odp_subsystem_register_module(pktio_ops, &tap_pktio_ops); +} + +/* Temporary variable to enable link this module, + * will remove in Makefile scheme changes. + */ +int enable_link_tap_pktio_ops = 0; diff --cc platform/linux-generic/schedule/scalable.c index 2786573f,642e7ee7..d8f53820 --- a/platform/linux-generic/schedule/scalable.c +++ b/platform/linux-generic/schedule/scalable.c @@@ -602,9 -601,8 +602,8 @@@ void sched_queue_rem(odp_schedule_group
sgi = grp; sg = sg_vec[sgi]; - x = __atomic_sub_fetch(&sg->xcount[prio], 1, __ATOMIC_RELAXED); + - x = __atomic_sub_fetch(&sg->xcount[prio], 1, __ATOMIC_RELAXED); if (x == 0) { /* Last ODP queue for this priority * Notify all threads in sg->thr_wanted that they
-----------------------------------------------------------------------
Summary of changes: .travis.yml | 32 +- configure.ac | 3 +- doc/images/reflen.svg | 45 --- doc/users-guide/users-guide-packet.adoc | 26 +- include/odp/api/spec/chksum.h | 53 ++++ include/odp/api/spec/ipsec.h | 4 +- include/odp/api/spec/packet.h | 23 +- include/odp/api/spec/packet_io.h | 18 ++ include/odp/api/spec/traffic_mngr.h | 6 +- include/odp_api.h | 1 + platform/Makefile.inc | 20 +- platform/linux-dpdk/Makefile.am | 26 +- platform/linux-dpdk/include/odp/api/chksum.h | 1 + platform/linux-dpdk/odp_packet.c | 5 - platform/linux-dpdk/pktio/dpdk.c | 1 + platform/linux-generic/Makefile.am | 78 +++-- platform/linux-generic/_fdserver.c | 24 +- .../arch/{arm => aarch64}/odp/api/cpu_arch.h | 0 .../arch/{arm => aarch64}/odp_atomic.h | 4 - .../linux-generic/arch/{arm => aarch64}/odp_cpu.h | 15 +- .../arch/{arm => aarch64}/odp_cpu_idling.h | 20 +- .../odp_cpu_arch.c => aarch64/odp_global_time.c} | 45 --- .../linux-generic/arch/{arm => aarch64}/odp_llsc.h | 88 ------ platform/linux-generic/arch/arm/odp_atomic.h | 181 ----------- platform/linux-generic/arch/arm/odp_cpu.h | 22 +- platform/linux-generic/arch/arm/odp_cpu_idling.h | 20 +- platform/linux-generic/arch/arm/odp_llsc.h | 157 ---------- .../linux-generic/arch/arm/odp_sysinfo_parse.c | 28 -- platform/linux-generic/arch/default/odp_cpu.h | 24 +- platform/linux-generic/arch/default/odp_cpu_arch.c | 28 -- .../default/odp_cpu_cycles.c} | 11 +- .../{x86/odp_cpu.h => default/odp_cpu_idling.h} | 11 +- .../odp_cpu_arch.c => default/odp_global_time.c} | 28 +- platform/linux-generic/arch/mips64/odp_cpu.h | 43 --- platform/linux-generic/arch/mips64/odp_cpu_arch.c | 25 -- platform/linux-generic/arch/powerpc/odp_cpu.h | 43 --- platform/linux-generic/arch/powerpc/odp_cpu_arch.c | 25 -- .../linux-generic/arch/powerpc/odp_global_time.c | 15 + platform/linux-generic/arch/x86/odp_cpu_arch.c | 72 ----- .../arch/x86/{odp_cpu_arch.c => odp_global_time.c} | 34 +- platform/linux-generic/doc/platform_specific.dox | 2 +- .../include/odp/api/{feature.h => chksum.h} | 10 +- .../include/odp/api/plat/traffic_mngr_types.h | 2 +- .../linux-generic/include/odp_packet_internal.h | 5 - .../include/odp_pktio_ops_subsystem.h | 2 + platform/linux-generic/odp_barrier.c | 4 +- platform/linux-generic/odp_chksum.c | 36 +++ platform/linux-generic/odp_packet.c | 51 --- platform/linux-generic/odp_packet_io.c | 36 +++ platform/linux-generic/pktio/dpdk.c | 1 + platform/linux-generic/pktio/ipc.c | 1 + platform/linux-generic/pktio/loopback.c | 1 + platform/linux-generic/pktio/netmap.c | 1 + platform/linux-generic/pktio/pcap.c | 1 + platform/linux-generic/pktio/socket.c | 1 + platform/linux-generic/pktio/socket_mmap.c | 1 + platform/linux-generic/pktio/tap.c | 1 + platform/linux-generic/schedule/scalable.c | 1 - test/common_plat/m4/configure.m4 | 1 + test/common_plat/m4/validation.m4 | 3 +- test/common_plat/performance/odp_bench_packet.c | 13 - test/common_plat/validation/api/Makefile.am | 1 + test/common_plat/validation/api/chksum/.gitignore | 1 + test/common_plat/validation/api/chksum/Makefile.am | 5 + test/common_plat/validation/api/chksum/chksum.c | 343 +++++++++++++++++++++ test/common_plat/validation/api/chksum/chksum.h | 26 ++ .../{ipsec/ipsec_main.c => chksum/chksum_main.c} | 4 +- test/common_plat/validation/api/packet/packet.c | 148 +-------- test/common_plat/validation/api/pktio/pktio.c | 23 ++ test/linux-generic/Makefile.am | 1 + 70 files changed, 739 insertions(+), 1292 deletions(-) delete mode 100644 doc/images/reflen.svg create mode 100644 include/odp/api/spec/chksum.h create mode 120000 platform/linux-dpdk/include/odp/api/chksum.h copy platform/linux-generic/arch/{arm => aarch64}/odp/api/cpu_arch.h (100%) copy platform/linux-generic/arch/{arm => aarch64}/odp_atomic.h (99%) copy platform/linux-generic/arch/{arm => aarch64}/odp_cpu.h (85%) copy platform/linux-generic/arch/{arm => aarch64}/odp_cpu_idling.h (74%) rename platform/linux-generic/arch/{arm/odp_cpu_arch.c => aarch64/odp_global_time.c} (65%) copy platform/linux-generic/arch/{arm => aarch64}/odp_llsc.h (68%) delete mode 100644 platform/linux-generic/arch/arm/odp_sysinfo_parse.c copy platform/linux-generic/{odp_version.c => arch/default/odp_cpu_cycles.c} (50%) rename platform/linux-generic/arch/{x86/odp_cpu.h => default/odp_cpu_idling.h} (70%) copy platform/linux-generic/arch/{mips64/odp_cpu_arch.c => default/odp_global_time.c} (53%) delete mode 100644 platform/linux-generic/arch/mips64/odp_cpu.h delete mode 100644 platform/linux-generic/arch/powerpc/odp_cpu.h create mode 100644 platform/linux-generic/arch/powerpc/odp_global_time.c copy platform/linux-generic/arch/x86/{odp_cpu_arch.c => odp_global_time.c} (79%) copy platform/linux-generic/include/odp/api/{feature.h => chksum.h} (63%) create mode 100644 platform/linux-generic/odp_chksum.c create mode 100644 test/common_plat/validation/api/chksum/.gitignore create mode 100644 test/common_plat/validation/api/chksum/Makefile.am create mode 100644 test/common_plat/validation/api/chksum/chksum.c create mode 100644 test/common_plat/validation/api/chksum/chksum.h copy test/common_plat/validation/api/{ipsec/ipsec_main.c => chksum/chksum_main.c} (74%)
hooks/post-receive