aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/Makefile.inc8
-rw-r--r--platform/linux-dpdk/Makefile.am7
l---------platform/linux-dpdk/include-abi/odp/api/abi/errno.h1
l---------platform/linux-dpdk/include-abi/odp/api/abi/hash.h1
-rw-r--r--platform/linux-dpdk/include/odp/api/plat/time_inlines.h56
-rw-r--r--platform/linux-dpdk/include/odp_packet_io_internal.h1
-rw-r--r--platform/linux-dpdk/libodp-linux.pc.in4
-rw-r--r--platform/linux-dpdk/m4/configure.m41
-rw-r--r--platform/linux-dpdk/m4/odp_libconfig.m49
-rw-r--r--platform/linux-dpdk/odp_packet_dpdk.c60
-rw-r--r--platform/linux-dpdk/odp_time.c37
-rw-r--r--platform/linux-dpdk/odp_timer.c32
-rw-r--r--platform/linux-generic/Makefile.am7
-rw-r--r--platform/linux-generic/include-abi/odp/api/abi/errno.h18
-rw-r--r--platform/linux-generic/include-abi/odp/api/abi/hash.h18
-rw-r--r--platform/linux-generic/include/odp/api/plat/time_inlines.h55
-rw-r--r--platform/linux-generic/include/odp_packet_io_internal.h1
-rw-r--r--platform/linux-generic/include/odp_socket_common.h7
-rw-r--r--platform/linux-generic/libodp-linux.pc.in4
-rw-r--r--platform/linux-generic/m4/configure.m41
-rw-r--r--platform/linux-generic/m4/odp_libconfig.m49
-rw-r--r--platform/linux-generic/odp_crypto_openssl.c3
-rw-r--r--platform/linux-generic/odp_packet_io.c27
-rw-r--r--platform/linux-generic/odp_pool.c4
-rw-r--r--platform/linux-generic/odp_time.c37
-rw-r--r--platform/linux-generic/odp_timer.c35
-rw-r--r--platform/linux-generic/odp_traffic_mngr.c42
-rw-r--r--platform/linux-generic/pktio/dpdk.c60
-rw-r--r--platform/linux-generic/pktio/ipc.c31
-rw-r--r--platform/linux-generic/pktio/loop.c20
-rw-r--r--platform/linux-generic/pktio/netmap.c26
-rw-r--r--platform/linux-generic/pktio/null.c22
-rw-r--r--platform/linux-generic/pktio/pcap.c22
-rw-r--r--platform/linux-generic/pktio/socket.c6
-rw-r--r--platform/linux-generic/pktio/socket_common.c139
-rw-r--r--platform/linux-generic/pktio/socket_mmap.c6
-rw-r--r--platform/linux-generic/pktio/tap.c6
-rw-r--r--platform/linux-generic/test/pktio_ipc/ipc_common.c1
-rw-r--r--platform/linux-generic/test/pktio_ipc/pktio_ipc2.c1
39 files changed, 701 insertions, 124 deletions
diff --git a/platform/Makefile.inc b/platform/Makefile.inc
index f99d39ffc..475d38c37 100644
--- a/platform/Makefile.inc
+++ b/platform/Makefile.inc
@@ -1,18 +1,18 @@
include $(top_srcdir)/Makefile.inc
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libodp-linux.pc
+pkgconfig_DATA = lib$(ODP_LIB_NAME).pc
EXTRA_DIST = doc/platform_specific.dox
configdir = $(sysconfdir)/odp
if ODP_USE_CONFIG
-config_DATA = $(top_srcdir)/config/odp-$(with_platform).conf
-EXTRA_DIST += $(top_srcdir)/config/odp-$(with_platform).conf
+config_DATA = $(top_builddir)/$(rel_default_config_path)
+EXTRA_DIST += $(top_builddir)/$(rel_default_config_path)
endif
VPATH = $(srcdir) $(builddir)
-lib_LTLIBRARIES = $(LIB)/libodp-linux.la
+lib_LTLIBRARIES =
AM_LDFLAGS = -version-number '$(ODP_LIBSO_VERSION)'
diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am
index 30e9f1dbd..045051b79 100644
--- a/platform/linux-dpdk/Makefile.am
+++ b/platform/linux-dpdk/Makefile.am
@@ -1,5 +1,6 @@
include $(top_srcdir)/platform/Makefile.inc
include $(top_srcdir)/platform/@with_platform@/Makefile.inc
+lib_LTLIBRARIES += $(LIB)/libodp-linux.la
AM_CPPFLAGS = $(ODP_INCLUDES)
AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/include
@@ -15,7 +16,7 @@ AM_CFLAGS += $(DPDK_CFLAGS)
AM_CFLAGS += $(LIBCONFIG_CFLAGS)
DISTCLEANFILES = include/odp_libconfig_config.h
-include/odp_libconfig_config.h: $(top_srcdir)/config/odp-$(with_platform).conf $(top_builddir)/config.status
+include/odp_libconfig_config.h: $(top_builddir)/$(rel_default_config_path) $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
odpapiabiarchincludedir = $(archincludedir)/odp/api/abi
@@ -55,7 +56,9 @@ odpapiabiarchinclude_HEADERS += \
include-abi/odp/api/abi/cpumask.h \
include-abi/odp/api/abi/crypto.h \
include-abi/odp/api/abi/debug.h \
+ include-abi/odp/api/abi/errno.h \
include-abi/odp/api/abi/event.h \
+ include-abi/odp/api/abi/hash.h \
include-abi/odp/api/abi/init.h \
include-abi/odp/api/abi/ipsec.h \
include-abi/odp/api/abi/packet.h \
@@ -138,7 +141,7 @@ noinst_HEADERS = \
include/protocols/udp.h \
Makefile.inc
-nodist_noinst_HEADERS = \
+BUILT_SOURCES = \
include/odp_libconfig_config.h
__LIB__libodp_linux_la_SOURCES = \
diff --git a/platform/linux-dpdk/include-abi/odp/api/abi/errno.h b/platform/linux-dpdk/include-abi/odp/api/abi/errno.h
new file mode 120000
index 000000000..0bc8b623d
--- /dev/null
+++ b/platform/linux-dpdk/include-abi/odp/api/abi/errno.h
@@ -0,0 +1 @@
+../../../../../linux-generic/include-abi/odp/api/abi/errno.h \ No newline at end of file
diff --git a/platform/linux-dpdk/include-abi/odp/api/abi/hash.h b/platform/linux-dpdk/include-abi/odp/api/abi/hash.h
new file mode 120000
index 000000000..cdcd8260a
--- /dev/null
+++ b/platform/linux-dpdk/include-abi/odp/api/abi/hash.h
@@ -0,0 +1 @@
+../../../../../linux-generic/include-abi/odp/api/abi/hash.h \ No newline at end of file
diff --git a/platform/linux-dpdk/include/odp/api/plat/time_inlines.h b/platform/linux-dpdk/include/odp/api/plat/time_inlines.h
index 0b49c09d6..a1b91682a 100644
--- a/platform/linux-dpdk/include/odp/api/plat/time_inlines.h
+++ b/platform/linux-dpdk/include/odp/api/plat/time_inlines.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2018, Linaro Limited
+ * Copyright (c) 2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -17,6 +18,7 @@
/** @cond _ODP_HIDE_FROM_DOXYGEN_ */
#define _ODP_TIMESPEC_SIZE 16
+#define _ODP_TIME_GIGA_HZ 1000000000ULL
typedef odp_time_t (*time_cur_fn)(void);
typedef uint64_t (*time_res_fn)(void);
@@ -61,14 +63,43 @@ static inline odp_time_t _odp_time_cur(void)
return _odp_time_glob.handler.time_cur();
}
+static inline uint64_t _odp_time_hw_to_ns(odp_time_t time)
+{
+ uint64_t nsec;
+ uint64_t freq_hz = _odp_time_glob.hw_freq_hz;
+ uint64_t count = time.count;
+ uint64_t sec = 0;
+
+ if (count >= freq_hz) {
+ sec = count / freq_hz;
+ count = count - sec * freq_hz;
+ }
+
+ nsec = (_ODP_TIME_GIGA_HZ * count) / freq_hz;
+
+ return (sec * _ODP_TIME_GIGA_HZ) + nsec;
+}
+
+static inline uint64_t _odp_time_convert_to_ns(odp_time_t time)
+{
+ if (_odp_time_glob.use_hw)
+ return _odp_time_hw_to_ns(time);
+
+ return time.nsec;
+}
+
#ifndef _ODP_NO_INLINE
/* Inline functions by default */
#define _ODP_INLINE static inline
- #define odp_time_local __odp_time_local
- #define odp_time_global __odp_time_global
- #define odp_time_cmp __odp_time_cmp
- #define odp_time_diff __odp_time_diff
- #define odp_time_sum __odp_time_sum
+ #define odp_time_local __odp_time_local
+ #define odp_time_global __odp_time_global
+ #define odp_time_to_ns __odp_time_to_ns
+ #define odp_time_local_ns __odp_time_local_ns
+ #define odp_time_global_ns __odp_time_global_ns
+ #define odp_time_cmp __odp_time_cmp
+ #define odp_time_diff __odp_time_diff
+ #define odp_time_sum __odp_time_sum
+
#else
#define _ODP_INLINE
#endif
@@ -83,6 +114,21 @@ _ODP_INLINE odp_time_t odp_time_global(void)
return _odp_time_cur();
}
+_ODP_INLINE uint64_t odp_time_to_ns(odp_time_t time)
+{
+ return _odp_time_convert_to_ns(time);
+}
+
+_ODP_INLINE uint64_t odp_time_local_ns(void)
+{
+ return _odp_time_convert_to_ns(_odp_time_cur());
+}
+
+_ODP_INLINE uint64_t odp_time_global_ns(void)
+{
+ return _odp_time_convert_to_ns(_odp_time_cur());
+}
+
_ODP_INLINE int odp_time_cmp(odp_time_t t2, odp_time_t t1)
{
if (odp_likely(t2.u64 > t1.u64))
diff --git a/platform/linux-dpdk/include/odp_packet_io_internal.h b/platform/linux-dpdk/include/odp_packet_io_internal.h
index 5bc3a3590..44c8774f6 100644
--- a/platform/linux-dpdk/include/odp_packet_io_internal.h
+++ b/platform/linux-dpdk/include/odp_packet_io_internal.h
@@ -159,6 +159,7 @@ typedef struct pktio_if_ops {
int (*mac_get)(pktio_entry_t *pktio_entry, void *mac_addr);
int (*mac_set)(pktio_entry_t *pktio_entry, const void *mac_addr);
int (*link_status)(pktio_entry_t *pktio_entry);
+ int (*link_info)(pktio_entry_t *pktio_entry, odp_pktio_link_info_t *info);
int (*capability)(pktio_entry_t *pktio_entry,
odp_pktio_capability_t *capa);
int (*config)(pktio_entry_t *pktio_entry,
diff --git a/platform/linux-dpdk/libodp-linux.pc.in b/platform/linux-dpdk/libodp-linux.pc.in
index 5b9421226..39729ea58 100644
--- a/platform/linux-dpdk/libodp-linux.pc.in
+++ b/platform/linux-dpdk/libodp-linux.pc.in
@@ -3,10 +3,10 @@ exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-Name: libodp-linux
+Name: lib@ODP_LIB_NAME@
Description: The ODP packet processing engine
Version: @PKGCONFIG_VERSION@
Requires.private: libconfig@DPDK_PKG@
-Libs: -L${libdir} -lodp-linux @DPDK_LIBS_NON_ABI_COMPAT@
+Libs: -L${libdir} -l@ODP_LIB_NAME@ @DPDK_LIBS_NON_ABI_COMPAT@
Libs.private: @DPDK_LIBS_ABI_COMPAT@ @OPENSSL_STATIC_LIBS@ @PTHREAD_LIBS@ @TIMER_LIBS@ -lpthread @ATOMIC_LIBS@
Cflags: -I${includedir} @DPDK_CFLAGS@
diff --git a/platform/linux-dpdk/m4/configure.m4 b/platform/linux-dpdk/m4/configure.m4
index 5172d9edd..9c5f02a35 100644
--- a/platform/linux-dpdk/m4/configure.m4
+++ b/platform/linux-dpdk/m4/configure.m4
@@ -1,4 +1,5 @@
ODP_IMPLEMENTATION_NAME="odp-dpdk"
+ODP_LIB_NAME="odp-linux"
ODP_VISIBILITY
ODP_ATOMIC
diff --git a/platform/linux-dpdk/m4/odp_libconfig.m4 b/platform/linux-dpdk/m4/odp_libconfig.m4
index 2ab6aa047..40d882d30 100644
--- a/platform/linux-dpdk/m4/odp_libconfig.m4
+++ b/platform/linux-dpdk/m4/odp_libconfig.m4
@@ -20,9 +20,16 @@ AC_SUBST(_ODP_CONFIG_VERSION_MINOR)
##########################################################################
default_config_path="${srcdir}/config/odp-linux-dpdk.conf"
+AC_CHECK_PROGS([REALPATH], [realpath])
+AS_IF([test -z "$REALPATH"], [AC_MSG_ERROR([Could not find 'realpath'])])
+
AC_ARG_WITH([config-file],
AS_HELP_STRING([--with-config-file=FILE path to the default configuration file],
[(this file must include all configuration options).]),
[default_config_path=$withval], [])
-ODP_LIBCONFIG([linux-dpdk], [$default_config_path])
+rel_default_config_path=`realpath --relative-to=$(pwd) ${default_config_path}`
+AC_SUBST(default_config_path)
+AC_SUBST(rel_default_config_path)
+
+ODP_LIBCONFIG([linux-dpdk], [$rel_default_config_path])
diff --git a/platform/linux-dpdk/odp_packet_dpdk.c b/platform/linux-dpdk/odp_packet_dpdk.c
index ba3f47b8f..af7fce4af 100644
--- a/platform/linux-dpdk/odp_packet_dpdk.c
+++ b/platform/linux-dpdk/odp_packet_dpdk.c
@@ -1453,7 +1453,64 @@ static int link_status_pkt_dpdk(pktio_entry_t *pktio_entry)
struct rte_eth_link link;
rte_eth_link_get(pkt_priv(pktio_entry)->port_id, &link);
- return link.link_status;
+
+ if (link.link_status)
+ return ODP_PKTIO_LINK_STATUS_UP;
+ return ODP_PKTIO_LINK_STATUS_DOWN;
+}
+
+static int dpdk_link_info(pktio_entry_t *pktio_entry, odp_pktio_link_info_t *info)
+{
+ struct rte_eth_link link;
+ struct rte_eth_fc_conf fc_conf;
+ uint16_t port_id = pkt_priv(pktio_entry)->port_id;
+ int ret;
+
+ memset(&fc_conf, 0, sizeof(struct rte_eth_fc_conf));
+ memset(&link, 0, sizeof(struct rte_eth_link));
+
+ ret = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);
+ if (ret && ret != -ENOTSUP) {
+ ODP_ERR("rte_eth_dev_flow_ctrl_get() failed\n");
+ return -1;
+ }
+
+ memset(info, 0, sizeof(odp_pktio_link_info_t));
+ info->pause_rx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->pause_tx = ODP_PKTIO_LINK_PAUSE_OFF;
+ if (fc_conf.mode == RTE_FC_RX_PAUSE) {
+ info->pause_rx = ODP_PKTIO_LINK_PAUSE_ON;
+ } else if (fc_conf.mode == RTE_FC_TX_PAUSE) {
+ info->pause_tx = ODP_PKTIO_LINK_PAUSE_ON;
+ } else if (fc_conf.mode == RTE_FC_FULL) {
+ info->pause_rx = ODP_PKTIO_LINK_PAUSE_ON;
+ info->pause_tx = ODP_PKTIO_LINK_PAUSE_ON;
+ }
+
+ rte_eth_link_get_nowait(port_id, &link);
+ if (link.link_autoneg == ETH_LINK_AUTONEG)
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_ON;
+ else
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_OFF;
+
+ if (link.link_duplex == ETH_LINK_FULL_DUPLEX)
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_FULL;
+ else
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_HALF;
+
+ if (link.link_speed == ETH_SPEED_NUM_NONE)
+ info->speed = ODP_PKTIO_LINK_SPEED_UNKNOWN;
+ else
+ info->speed = link.link_speed;
+
+ if (link.link_status == ETH_LINK_UP)
+ info->status = ODP_PKTIO_LINK_STATUS_UP;
+ else
+ info->status = ODP_PKTIO_LINK_STATUS_DOWN;
+
+ info->media = "unknown";
+
+ return 0;
}
static void stats_convert(struct rte_eth_stats *rte_stats,
@@ -1514,6 +1571,7 @@ const pktio_if_ops_t dpdk_pktio_ops = {
.mac_get = mac_get_pkt_dpdk,
.mac_set = mac_set_pkt_dpdk,
.link_status = link_status_pkt_dpdk,
+ .link_info = dpdk_link_info,
.capability = capability_pkt_dpdk,
.config = NULL,
.input_queues_config = dpdk_input_queues_config,
diff --git a/platform/linux-dpdk/odp_time.c b/platform/linux-dpdk/odp_time.c
index 4cabc9b3b..f1489cf3c 100644
--- a/platform/linux-dpdk/odp_time.c
+++ b/platform/linux-dpdk/odp_time.c
@@ -81,11 +81,6 @@ static inline uint64_t time_spec_res(void)
return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec;
}
-static inline uint64_t time_spec_to_ns(odp_time_t time)
-{
- return time.nsec;
-}
-
static inline odp_time_t time_spec_from_ns(uint64_t ns)
{
odp_time_t time;
@@ -104,23 +99,6 @@ static inline uint64_t time_hw_res(void)
return _odp_time_glob.hw_freq_hz;
}
-static inline uint64_t time_hw_to_ns(odp_time_t time)
-{
- uint64_t nsec;
- uint64_t freq_hz = _odp_time_glob.hw_freq_hz;
- uint64_t count = time.count;
- uint64_t sec = 0;
-
- if (count >= freq_hz) {
- sec = count / freq_hz;
- count = count - sec * freq_hz;
- }
-
- nsec = (ODP_TIME_SEC_IN_NS * count) / freq_hz;
-
- return (sec * ODP_TIME_SEC_IN_NS) + nsec;
-}
-
static inline odp_time_t time_hw_from_ns(uint64_t ns)
{
odp_time_t time;
@@ -153,14 +131,6 @@ static inline uint64_t time_res(void)
return time_spec_res();
}
-static inline uint64_t time_to_ns(odp_time_t time)
-{
- if (_odp_time_glob.use_hw)
- return time_hw_to_ns(time);
-
- return time_spec_to_ns(time);
-}
-
static inline odp_time_t time_from_ns(uint64_t ns)
{
if (_odp_time_glob.use_hw)
@@ -198,12 +168,7 @@ uint64_t odp_time_diff_ns(odp_time_t t2, odp_time_t t1)
time.u64 = t2.u64 - t1.u64;
- return time_to_ns(time);
-}
-
-uint64_t odp_time_to_ns(odp_time_t time)
-{
- return time_to_ns(time);
+ return odp_time_to_ns(time);
}
odp_time_t odp_time_local_from_ns(uint64_t ns)
diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c
index 460830239..3205c7d98 100644
--- a/platform/linux-dpdk/odp_timer.c
+++ b/platform/linux-dpdk/odp_timer.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2018, Linaro Limited
- * Copyright (c) 2019, Nokia
+ * Copyright (c) 2019-2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -25,6 +25,9 @@
#include <inttypes.h>
#include <string.h>
+/* One divided by one nanosecond in Hz */
+#define GIGA_HZ 1000000000
+
/* Timer states */
#define NOT_TICKING 0
#define EXPIRED 1
@@ -52,6 +55,7 @@ ODP_STATIC_ASSERT(MAX_TIMERS < MAX_TIMER_RING_SIZE,
/* Actual resolution depends on application polling frequency. Promise
* 10 usec resolution. */
#define MAX_RES_NS 10000
+#define MAX_RES_HZ (GIGA_HZ / MAX_RES_NS)
/* Limit minimum supported timeout in timer (CPU) cycles. Timer setup, polling,
* timer management, timeout enqueue, etc takes about this many CPU cycles.
@@ -267,9 +271,11 @@ int odp_timer_capability(odp_timer_clk_src_t clk_src,
capa->max_timers = MAX_TIMERS;
capa->highest_res_ns = MAX_RES_NS;
capa->max_res.res_ns = MAX_RES_NS;
+ capa->max_res.res_hz = MAX_RES_HZ;
capa->max_res.min_tmo = min_tmo;
capa->max_res.max_tmo = MAX_TMO_NS;
capa->max_tmo.res_ns = MAX_RES_NS;
+ capa->max_tmo.res_hz = MAX_RES_HZ;
capa->max_tmo.min_tmo = min_tmo;
capa->max_tmo.max_tmo = MAX_TMO_NS;
@@ -291,12 +297,13 @@ int odp_timer_res_capability(odp_timer_clk_src_t clk_src,
return -1;
}
- if (res_capa->res_ns) {
+ if (res_capa->res_ns || res_capa->res_hz) {
res_capa->min_tmo = min_tmo;
res_capa->max_tmo = MAX_TMO_NS;
} else { /* max_tmo */
res_capa->min_tmo = min_tmo;
res_capa->res_ns = MAX_RES_NS;
+ res_capa->res_hz = MAX_RES_HZ;
}
return 0;
@@ -315,7 +322,18 @@ odp_timer_pool_t odp_timer_pool_create(const char *name,
return ODP_TIMER_POOL_INVALID;
}
- if (param->res_ns < MAX_RES_NS) {
+ if ((param->res_ns && param->res_hz) ||
+ (param->res_ns == 0 && param->res_hz == 0)) {
+ ODP_ERR("Invalid timeout resolution\n");
+ return ODP_TIMER_POOL_INVALID;
+ }
+
+ if (param->res_hz == 0 && param->res_ns < MAX_RES_NS) {
+ ODP_ERR("Too high resolution\n");
+ return ODP_TIMER_POOL_INVALID;
+ }
+
+ if (param->res_ns == 0 && param->res_hz > MAX_RES_HZ) {
ODP_ERR("Too high resolution\n");
return ODP_TIMER_POOL_INVALID;
}
@@ -326,7 +344,12 @@ odp_timer_pool_t odp_timer_pool_create(const char *name,
}
num_timers = param->num_timers;
- res_ns = param->res_ns;
+
+ if (param->res_ns)
+ res_ns = param->res_ns;
+ else
+ res_ns = GIGA_HZ / param->res_hz;
+
/* Scan timer pool twice during resolution interval */
if (res_ns > ODP_TIME_USEC_IN_NS)
@@ -376,6 +399,7 @@ odp_timer_pool_t odp_timer_pool_create(const char *name,
}
timer_pool->param = *param;
+ timer_pool->param.res_ns = res_ns;
ring_u32_init(&timer_pool->free_timer.ring_hdr);
timer_pool->free_timer.ring_mask = num_timers - 1;
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 2986e08e8..267d02a7d 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -2,6 +2,7 @@
#export CUSTOM_STR=https://github.com/OpenDataPlane/odp.git
include $(top_srcdir)/platform/Makefile.inc
+lib_LTLIBRARIES += $(LIB)/libodp-linux.la
AM_CPPFLAGS = $(ODP_INCLUDES)
AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/include
@@ -17,7 +18,7 @@ AM_CFLAGS += $(DPDK_CFLAGS)
AM_CFLAGS += $(LIBCONFIG_CFLAGS)
DISTCLEANFILES = include/odp_libconfig_config.h
-include/odp_libconfig_config.h: $(top_srcdir)/config/odp-$(with_platform).conf $(top_builddir)/config.status
+include/odp_libconfig_config.h: $(top_builddir)/$(rel_default_config_path) $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
odpapiabiarchincludedir = $(archincludedir)/odp/api/abi
@@ -57,7 +58,9 @@ odpapiabiarchinclude_HEADERS += \
include-abi/odp/api/abi/cpumask.h \
include-abi/odp/api/abi/crypto.h \
include-abi/odp/api/abi/debug.h \
+ include-abi/odp/api/abi/errno.h \
include-abi/odp/api/abi/event.h \
+ include-abi/odp/api/abi/hash.h \
include-abi/odp/api/abi/init.h \
include-abi/odp/api/abi/ipsec.h \
include-abi/odp/api/abi/packet.h \
@@ -148,7 +151,7 @@ noinst_HEADERS = \
include/protocols/tcp.h \
include/protocols/thash.h \
include/protocols/udp.h
-nodist_noinst_HEADERS = \
+BUILT_SOURCES = \
include/odp_libconfig_config.h
__LIB__libodp_linux_la_SOURCES = \
diff --git a/platform/linux-generic/include-abi/odp/api/abi/errno.h b/platform/linux-generic/include-abi/odp/api/abi/errno.h
new file mode 100644
index 000000000..6215a0676
--- /dev/null
+++ b/platform/linux-generic/include-abi/odp/api/abi/errno.h
@@ -0,0 +1,18 @@
+/* Copyright (c) 2020, Marvell
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP errno
+ */
+
+#ifndef ODP_API_ABI_ERRNO_H_
+#define ODP_API_ABI_ERRNO_H_
+
+#include <odp/api/abi-default/errno.h>
+
+#endif
diff --git a/platform/linux-generic/include-abi/odp/api/abi/hash.h b/platform/linux-generic/include-abi/odp/api/abi/hash.h
new file mode 100644
index 000000000..fc81dcc91
--- /dev/null
+++ b/platform/linux-generic/include-abi/odp/api/abi/hash.h
@@ -0,0 +1,18 @@
+/* Copyright (c) 2020, Marvell
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP hash
+ */
+
+#ifndef ODP_API_ABI_HASH_H_
+#define ODP_API_ABI_HASH_H_
+
+#include <odp/api/abi-default/hash.h>
+
+#endif
diff --git a/platform/linux-generic/include/odp/api/plat/time_inlines.h b/platform/linux-generic/include/odp/api/plat/time_inlines.h
index 527490e3d..0b05aa4f7 100644
--- a/platform/linux-generic/include/odp/api/plat/time_inlines.h
+++ b/platform/linux-generic/include/odp/api/plat/time_inlines.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2018, Linaro Limited
+ * Copyright (c) 2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -16,6 +17,7 @@
/** @cond _ODP_HIDE_FROM_DOXYGEN_ */
#define _ODP_TIMESPEC_SIZE 16
+#define _ODP_TIME_GIGA_HZ 1000000000ULL
typedef struct _odp_time_global_t {
/* Storage space for struct timespec. Posix headers are not included
@@ -44,14 +46,42 @@ static inline odp_time_t _odp_time_cur(void)
return _odp_timespec_cur();
}
+static inline uint64_t _odp_time_hw_to_ns(odp_time_t time)
+{
+ uint64_t nsec;
+ uint64_t freq_hz = _odp_time_glob.hw_freq_hz;
+ uint64_t count = time.count;
+ uint64_t sec = 0;
+
+ if (count >= freq_hz) {
+ sec = count / freq_hz;
+ count = count - sec * freq_hz;
+ }
+
+ nsec = (_ODP_TIME_GIGA_HZ * count) / freq_hz;
+
+ return (sec * _ODP_TIME_GIGA_HZ) + nsec;
+}
+
+static inline uint64_t _odp_time_convert_to_ns(odp_time_t time)
+{
+ if (_odp_time_glob.use_hw)
+ return _odp_time_hw_to_ns(time);
+
+ return time.nsec;
+}
+
#ifndef _ODP_NO_INLINE
/* Inline functions by default */
#define _ODP_INLINE static inline
- #define odp_time_local __odp_time_local
- #define odp_time_global __odp_time_global
- #define odp_time_cmp __odp_time_cmp
- #define odp_time_diff __odp_time_diff
- #define odp_time_sum __odp_time_sum
+ #define odp_time_local __odp_time_local
+ #define odp_time_global __odp_time_global
+ #define odp_time_to_ns __odp_time_to_ns
+ #define odp_time_local_ns __odp_time_local_ns
+ #define odp_time_global_ns __odp_time_global_ns
+ #define odp_time_cmp __odp_time_cmp
+ #define odp_time_diff __odp_time_diff
+ #define odp_time_sum __odp_time_sum
#else
#define _ODP_INLINE
@@ -67,6 +97,21 @@ _ODP_INLINE odp_time_t odp_time_global(void)
return _odp_time_cur();
}
+_ODP_INLINE uint64_t odp_time_to_ns(odp_time_t time)
+{
+ return _odp_time_convert_to_ns(time);
+}
+
+_ODP_INLINE uint64_t odp_time_local_ns(void)
+{
+ return _odp_time_convert_to_ns(_odp_time_cur());
+}
+
+_ODP_INLINE uint64_t odp_time_global_ns(void)
+{
+ return _odp_time_convert_to_ns(_odp_time_cur());
+}
+
_ODP_INLINE int odp_time_cmp(odp_time_t t2, odp_time_t t1)
{
if (odp_likely(t2.u64 > t1.u64))
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h
index 0e6a8a335..4219ff114 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -180,6 +180,7 @@ typedef struct pktio_if_ops {
int (*mac_get)(pktio_entry_t *pktio_entry, void *mac_addr);
int (*mac_set)(pktio_entry_t *pktio_entry, const void *mac_addr);
int (*link_status)(pktio_entry_t *pktio_entry);
+ int (*link_info)(pktio_entry_t *pktio_entry, odp_pktio_link_info_t *info);
int (*capability)(pktio_entry_t *pktio_entry,
odp_pktio_capability_t *capa);
int (*config)(pktio_entry_t *pktio_entry,
diff --git a/platform/linux-generic/include/odp_socket_common.h b/platform/linux-generic/include/odp_socket_common.h
index afce0f55d..0a9704076 100644
--- a/platform/linux-generic/include/odp_socket_common.h
+++ b/platform/linux-generic/include/odp_socket_common.h
@@ -12,6 +12,8 @@
extern "C" {
#endif
+#include <odp/api/packet_io.h>
+
#include <string.h>
#include <linux/if_ether.h>
@@ -57,6 +59,11 @@ int promisc_mode_get_fd(int fd, const char *name);
*/
int link_status_fd(int fd, const char *name);
+/**
+ * Read link information from a packet socket
+ */
+int link_info_fd(int fd, const char *name, odp_pktio_link_info_t *info);
+
#ifdef __cplusplus
}
#endif
diff --git a/platform/linux-generic/libodp-linux.pc.in b/platform/linux-generic/libodp-linux.pc.in
index 5fe806435..df92e9345 100644
--- a/platform/linux-generic/libodp-linux.pc.in
+++ b/platform/linux-generic/libodp-linux.pc.in
@@ -3,10 +3,10 @@ exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-Name: libodp-linux
+Name: lib@ODP_LIB_NAME@
Description: The ODP packet processing engine
Version: @PKGCONFIG_VERSION@
Requires.private: libconfig@DPDK_PKG@
-Libs: -L${libdir} -lodp-linux
+Libs: -L${libdir} -l@ODP_LIB_NAME@
Libs.private: @OPENSSL_STATIC_LIBS@ @DPDK_LIBS@ @PCAP_LIBS@ @PTHREAD_LIBS@ @TIMER_LIBS@ -lpthread @ATOMIC_LIBS@
Cflags: -I${includedir}
diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4
index bcd55b7c5..06bff0669 100644
--- a/platform/linux-generic/m4/configure.m4
+++ b/platform/linux-generic/m4/configure.m4
@@ -1,4 +1,5 @@
ODP_IMPLEMENTATION_NAME="odp-linux"
+ODP_LIB_NAME="odp-linux"
ODP_VISIBILITY
ODP_ATOMIC
diff --git a/platform/linux-generic/m4/odp_libconfig.m4 b/platform/linux-generic/m4/odp_libconfig.m4
index f042d65d7..d13fcf274 100644
--- a/platform/linux-generic/m4/odp_libconfig.m4
+++ b/platform/linux-generic/m4/odp_libconfig.m4
@@ -20,9 +20,16 @@ AC_SUBST(_ODP_CONFIG_VERSION_MINOR)
##########################################################################
default_config_path="${srcdir}/config/odp-$with_platform.conf"
+AC_CHECK_PROGS([REALPATH], [realpath])
+AS_IF([test -z "$REALPATH"], [AC_MSG_ERROR([Could not find 'realpath'])])
+
AC_ARG_WITH([config-file],
AS_HELP_STRING([--with-config-file=FILE path to the default configuration file],
[(this file must include all configuration options).]),
[default_config_path=$withval], [])
-ODP_LIBCONFIG([$with_platform], [$default_config_path])
+rel_default_config_path=`realpath --relative-to=$(pwd) ${default_config_path}`
+AC_SUBST(default_config_path)
+AC_SUBST(rel_default_config_path)
+
+ODP_LIBCONFIG([$with_platform], [$rel_default_config_path])
diff --git a/platform/linux-generic/odp_crypto_openssl.c b/platform/linux-generic/odp_crypto_openssl.c
index 98a13ce4a..2a8d4fb9b 100644
--- a/platform/linux-generic/odp_crypto_openssl.c
+++ b/platform/linux-generic/odp_crypto_openssl.c
@@ -285,6 +285,9 @@ odp_crypto_generic_session_t *alloc_session(void)
}
odp_spinlock_unlock(&global->lock);
+ if (!session)
+ return NULL;
+
session->idx = session - global->sessions;
for (i = 0; i < ODP_THREAD_COUNT_MAX; i++)
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index 1cd5745aa..d57c21a9e 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2013-2018, Linaro Limited
- * Copyright (c) 2019, Nokia
+ * Copyright (c) 2019-2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -1168,15 +1168,15 @@ int odp_pktio_mac_addr_set(odp_pktio_t hdl, const void *mac_addr, int addr_size)
return ret;
}
-int odp_pktio_link_status(odp_pktio_t hdl)
+odp_pktio_link_status_t odp_pktio_link_status(odp_pktio_t hdl)
{
pktio_entry_t *entry;
- int ret = -1;
+ int ret = ODP_PKTIO_LINK_STATUS_UNKNOWN;
entry = get_pktio_entry(hdl);
if (entry == NULL) {
ODP_DBG("pktio entry %d does not exist\n", hdl);
- return -1;
+ return ODP_PKTIO_LINK_STATUS_UNKNOWN;
}
lock_entry(entry);
@@ -1184,7 +1184,7 @@ int odp_pktio_link_status(odp_pktio_t hdl)
if (odp_unlikely(is_free(entry))) {
unlock_entry(entry);
ODP_DBG("already freed pktio\n");
- return -1;
+ return ODP_PKTIO_LINK_STATUS_UNKNOWN;
}
if (entry->s.ops->link_status)
@@ -1244,6 +1244,23 @@ int odp_pktio_info(odp_pktio_t hdl, odp_pktio_info_t *info)
return 0;
}
+int odp_pktio_link_info(odp_pktio_t hdl, odp_pktio_link_info_t *info)
+{
+ pktio_entry_t *entry;
+
+ entry = get_pktio_entry(hdl);
+
+ if (entry == NULL) {
+ ODP_DBG("pktio entry %d does not exist\n", hdl);
+ return -1;
+ }
+
+ if (entry->s.ops->link_info)
+ return entry->s.ops->link_info(entry, info);
+
+ return -1;
+}
+
uint64_t odp_pktin_ts_res(odp_pktio_t hdl)
{
pktio_entry_t *entry;
diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c
index d31f210e7..913e71f5a 100644
--- a/platform/linux-generic/odp_pool.c
+++ b/platform/linux-generic/odp_pool.c
@@ -666,9 +666,9 @@ static odp_pool_t pool_create(const char *name, const odp_pool_param_t *params,
/* Allocate extra memory for skipping packet buffers which cross huge
* page boundaries. */
if (params->type == ODP_POOL_PACKET) {
- num_extra = (((uint64_t)(num * block_size) +
+ num_extra = ((((uint64_t)num * block_size) +
FIRST_HP_SIZE - 1) / FIRST_HP_SIZE);
- num_extra += (((uint64_t)(num_extra * block_size) +
+ num_extra += ((((uint64_t)num_extra * block_size) +
FIRST_HP_SIZE - 1) / FIRST_HP_SIZE);
}
diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c
index b033a733c..aea823eb6 100644
--- a/platform/linux-generic/odp_time.c
+++ b/platform/linux-generic/odp_time.c
@@ -78,11 +78,6 @@ static inline uint64_t time_spec_res(void)
return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec;
}
-static inline uint64_t time_spec_to_ns(odp_time_t time)
-{
- return time.nsec;
-}
-
static inline odp_time_t time_spec_from_ns(uint64_t ns)
{
odp_time_t time;
@@ -101,23 +96,6 @@ static inline uint64_t time_hw_res(void)
return _odp_time_glob.hw_freq_hz;
}
-static inline uint64_t time_hw_to_ns(odp_time_t time)
-{
- uint64_t nsec;
- uint64_t freq_hz = _odp_time_glob.hw_freq_hz;
- uint64_t count = time.count;
- uint64_t sec = 0;
-
- if (count >= freq_hz) {
- sec = count / freq_hz;
- count = count - sec * freq_hz;
- }
-
- nsec = (ODP_TIME_SEC_IN_NS * count) / freq_hz;
-
- return (sec * ODP_TIME_SEC_IN_NS) + nsec;
-}
-
static inline odp_time_t time_hw_from_ns(uint64_t ns)
{
odp_time_t time;
@@ -150,14 +128,6 @@ static inline uint64_t time_res(void)
return time_spec_res();
}
-static inline uint64_t time_to_ns(odp_time_t time)
-{
- if (_odp_time_glob.use_hw)
- return time_hw_to_ns(time);
-
- return time_spec_to_ns(time);
-}
-
static inline odp_time_t time_from_ns(uint64_t ns)
{
if (_odp_time_glob.use_hw)
@@ -181,12 +151,7 @@ uint64_t odp_time_diff_ns(odp_time_t t2, odp_time_t t1)
time.u64 = t2.u64 - t1.u64;
- return time_to_ns(time);
-}
-
-uint64_t odp_time_to_ns(odp_time_t time)
-{
- return time_to_ns(time);
+ return odp_time_to_ns(time);
}
odp_time_t odp_time_local_from_ns(uint64_t ns)
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c
index 5fa020118..e7c0d4e51 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2013-2018, Linaro Limited
- * Copyright (c) 2019, Nokia
+ * Copyright (c) 2019-2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -54,6 +54,9 @@
/* Inlined API functions */
#include <odp/api/plat/event_inlines.h>
+/* One divided by one nanosecond in Hz */
+#define GIGA_HZ 1000000000
+
#define TMO_UNUSED ((uint64_t)0xFFFFFFFFFFFFFFFF)
/* TMO_INACTIVE is or-ed with the expiration tick to indicate an expired timer.
* The original expiration tick (63 bits) is still available so it can be used
@@ -148,6 +151,7 @@ typedef struct timer_global_t {
odp_shm_t shm;
/* Max timer resolution in nanoseconds */
uint64_t highest_res_ns;
+ uint64_t highest_res_hz;
uint64_t poll_interval_nsec;
int num_timer_pools;
uint8_t timer_pool_used[MAX_TIMER_POOLS];
@@ -324,7 +328,10 @@ static odp_timer_pool_t timer_pool_new(const char *name,
memset(tp, 0, tp_size);
- res_ns = param->res_ns;
+ if (param->res_ns)
+ res_ns = param->res_ns;
+ else
+ res_ns = GIGA_HZ / param->res_hz;
/* Scan timer pool twice during resolution interval */
if (res_ns > ODP_TIME_USEC_IN_NS)
@@ -344,6 +351,7 @@ static odp_timer_pool_t timer_pool_new(const char *name,
}
tp->shm = shm;
tp->param = *param;
+ tp->param.res_ns = res_ns;
tp->min_rel_tck = odp_timer_ns_to_tick(timer_pool_to_hdl(tp),
param->min_tmo);
tp->max_rel_tck = odp_timer_ns_to_tick(timer_pool_to_hdl(tp),
@@ -1239,9 +1247,11 @@ int odp_timer_capability(odp_timer_clk_src_t clk_src,
capa->max_timers = 0;
capa->highest_res_ns = timer_global->highest_res_ns;
capa->max_res.res_ns = timer_global->highest_res_ns;
+ capa->max_res.res_hz = timer_global->highest_res_hz;
capa->max_res.min_tmo = 0;
capa->max_res.max_tmo = MAX_TMO_NSEC;
capa->max_tmo.res_ns = timer_global->highest_res_ns;
+ capa->max_tmo.res_hz = timer_global->highest_res_hz;
capa->max_tmo.min_tmo = 0;
capa->max_tmo.max_tmo = MAX_TMO_NSEC;
@@ -1261,12 +1271,13 @@ int odp_timer_res_capability(odp_timer_clk_src_t clk_src,
return -1;
}
- if (res_capa->res_ns) {
+ if (res_capa->res_ns || res_capa->res_hz) {
res_capa->min_tmo = 0;
res_capa->max_tmo = MAX_TMO_NSEC;
} else { /* max_tmo */
res_capa->min_tmo = 0;
res_capa->res_ns = timer_global->highest_res_ns;
+ res_capa->res_hz = timer_global->highest_res_hz;
}
return 0;
@@ -1280,7 +1291,20 @@ odp_timer_pool_t odp_timer_pool_create(const char *name,
return ODP_TIMER_POOL_INVALID;
}
- if (param->res_ns < timer_global->highest_res_ns) {
+ if ((param->res_ns && param->res_hz) ||
+ (param->res_ns == 0 && param->res_hz == 0)) {
+ __odp_errno = EINVAL;
+ return ODP_TIMER_POOL_INVALID;
+ }
+
+ if (param->res_hz == 0 &&
+ param->res_ns < timer_global->highest_res_ns) {
+ __odp_errno = EINVAL;
+ return ODP_TIMER_POOL_INVALID;
+ }
+
+ if (param->res_ns == 0 &&
+ param->res_hz > timer_global->highest_res_hz) {
__odp_errno = EINVAL;
return ODP_TIMER_POOL_INVALID;
}
@@ -1561,6 +1585,9 @@ int _odp_timer_init_global(const odp_init_t *params)
block_sigalarm();
}
+ /* timer_res_init() may update highest_res_ns */
+ timer_global->highest_res_hz = GIGA_HZ / timer_global->highest_res_ns;
+
return 0;
error:
diff --git a/platform/linux-generic/odp_traffic_mngr.c b/platform/linux-generic/odp_traffic_mngr.c
index de9cbfb73..1b6ca2ec2 100644
--- a/platform/linux-generic/odp_traffic_mngr.c
+++ b/platform/linux-generic/odp_traffic_mngr.c
@@ -4575,7 +4575,8 @@ static int tm_query_info_copy(tm_queue_info_t *queue_info,
uint32_t query_flags,
odp_tm_query_info_t *info)
{
- tm_queue_thresholds_t *threshold_params;
+ if ((query_flags & ODP_TM_QUERY_THRESHOLDS) && !queue_info->threshold_params)
+ return -1;
memset(info, 0, sizeof(odp_tm_query_info_t));
info->total_pkt_cnt =
@@ -4587,9 +4588,7 @@ static int tm_query_info_copy(tm_queue_info_t *queue_info,
info->approx_byte_cnt = 0;
if (query_flags & ODP_TM_QUERY_THRESHOLDS) {
- threshold_params = queue_info->threshold_params;
- if (!threshold_params)
- return -1;
+ tm_queue_thresholds_t *threshold_params = queue_info->threshold_params;
info->max_pkt_cnt = threshold_params->max_pkts;
info->max_byte_cnt = threshold_params->max_bytes;
@@ -4722,6 +4721,41 @@ void odp_tm_stats_print(odp_tm_t odp_tm)
}
}
+uint64_t odp_tm_to_u64(odp_tm_t hdl)
+{
+ return _odp_pri(hdl);
+}
+
+uint64_t odp_tm_queue_to_u64(odp_tm_queue_t hdl)
+{
+ return _odp_pri(hdl);
+}
+
+uint64_t odp_tm_node_to_u64(odp_tm_node_t hdl)
+{
+ return _odp_pri(hdl);
+}
+
+uint64_t odp_tm_shaper_to_u64(odp_tm_shaper_t hdl)
+{
+ return _odp_pri(hdl);
+}
+
+uint64_t odp_tm_sched_to_u64(odp_tm_sched_t hdl)
+{
+ return _odp_pri(hdl);
+}
+
+uint64_t odp_tm_threshold_to_u64(odp_tm_threshold_t hdl)
+{
+ return _odp_pri(hdl);
+}
+
+uint64_t odp_tm_wred_to_u64(odp_tm_wred_t hdl)
+{
+ return _odp_pri(hdl);
+}
+
int _odp_tm_init_global(void)
{
odp_shm_t shm;
diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c
index 18f583a65..7aee73dc1 100644
--- a/platform/linux-generic/pktio/dpdk.c
+++ b/platform/linux-generic/pktio/dpdk.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2016-2018, Linaro Limited
- * Copyright (c) 2019, Nokia
+ * Copyright (c) 2019-2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -2056,8 +2056,63 @@ static int dpdk_link_status(pktio_entry_t *pktio_entry)
memset(&link, 0, sizeof(struct rte_eth_link));
rte_eth_link_get_nowait(pkt_priv(pktio_entry)->port_id, &link);
+ if (link.link_status)
+ return ODP_PKTIO_LINK_STATUS_UP;
+ return ODP_PKTIO_LINK_STATUS_DOWN;
+}
+
+static int dpdk_link_info(pktio_entry_t *pktio_entry, odp_pktio_link_info_t *info)
+{
+ struct rte_eth_link link;
+ struct rte_eth_fc_conf fc_conf;
+ uint16_t port_id = pkt_priv(pktio_entry)->port_id;
+ int ret;
- return link.link_status;
+ memset(&fc_conf, 0, sizeof(struct rte_eth_fc_conf));
+ memset(&link, 0, sizeof(struct rte_eth_link));
+
+ ret = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);
+ if (ret && ret != -ENOTSUP) {
+ ODP_ERR("rte_eth_dev_flow_ctrl_get() failed\n");
+ return -1;
+ }
+
+ memset(info, 0, sizeof(odp_pktio_link_info_t));
+ info->pause_rx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->pause_tx = ODP_PKTIO_LINK_PAUSE_OFF;
+ if (fc_conf.mode == RTE_FC_RX_PAUSE) {
+ info->pause_rx = ODP_PKTIO_LINK_PAUSE_ON;
+ } else if (fc_conf.mode == RTE_FC_TX_PAUSE) {
+ info->pause_tx = ODP_PKTIO_LINK_PAUSE_ON;
+ } else if (fc_conf.mode == RTE_FC_FULL) {
+ info->pause_rx = ODP_PKTIO_LINK_PAUSE_ON;
+ info->pause_tx = ODP_PKTIO_LINK_PAUSE_ON;
+ }
+
+ rte_eth_link_get_nowait(port_id, &link);
+ if (link.link_autoneg == ETH_LINK_AUTONEG)
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_ON;
+ else
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_OFF;
+
+ if (link.link_duplex == ETH_LINK_FULL_DUPLEX)
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_FULL;
+ else
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_HALF;
+
+ if (link.link_speed == ETH_SPEED_NUM_NONE)
+ info->speed = ODP_PKTIO_LINK_SPEED_UNKNOWN;
+ else
+ info->speed = link.link_speed;
+
+ if (link.link_status == ETH_LINK_UP)
+ info->status = ODP_PKTIO_LINK_STATUS_UP;
+ else
+ info->status = ODP_PKTIO_LINK_STATUS_DOWN;
+
+ info->media = "unknown";
+
+ return 0;
}
static void stats_convert(const struct rte_eth_stats *rte_stats,
@@ -2106,6 +2161,7 @@ const pktio_if_ops_t dpdk_pktio_ops = {
.recv = dpdk_recv,
.send = dpdk_send,
.link_status = dpdk_link_status,
+ .link_info = dpdk_link_info,
.mtu_get = dpdk_frame_maxlen,
.promisc_mode_set = dpdk_promisc_mode_set,
.promisc_mode_get = dpdk_promisc_mode_get,
diff --git a/platform/linux-generic/pktio/ipc.c b/platform/linux-generic/pktio/ipc.c
index d63a77b74..34b32ae2c 100644
--- a/platform/linux-generic/pktio/ipc.c
+++ b/platform/linux-generic/pktio/ipc.c
@@ -900,6 +900,35 @@ static int ipc_stop(pktio_entry_t *pktio_entry)
return 0;
}
+static int ipc_link_status(pktio_entry_t *pktio_entry)
+{
+ pkt_ipc_t *pktio_ipc = pkt_priv(pktio_entry);
+
+ if (odp_atomic_load_u32(&pktio_ipc->ready))
+ return ODP_PKTIO_LINK_STATUS_UP;
+ return ODP_PKTIO_LINK_STATUS_DOWN;
+}
+
+static int ipc_link_info(pktio_entry_t *pktio_entry, odp_pktio_link_info_t *info)
+{
+ pkt_ipc_t *pktio_ipc = pkt_priv(pktio_entry);
+
+ memset(info, 0, sizeof(odp_pktio_link_info_t));
+
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_OFF;
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_FULL;
+ info->media = "virtual";
+ info->pause_rx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->pause_tx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->speed = ODP_PKTIO_LINK_SPEED_UNKNOWN;
+ if (odp_atomic_load_u32(&pktio_ipc->ready))
+ info->status = ODP_PKTIO_LINK_STATUS_UP;
+ else
+ info->status = ODP_PKTIO_LINK_STATUS_DOWN;
+
+ return 0;
+}
+
static int ipc_close(pktio_entry_t *pktio_entry)
{
pkt_ipc_t *pktio_ipc = pkt_priv(pktio_entry);
@@ -947,6 +976,8 @@ const pktio_if_ops_t ipc_pktio_ops = {
.send = ipc_pktio_send,
.start = ipc_start,
.stop = ipc_stop,
+ .link_status = ipc_link_status,
+ .link_info = ipc_link_info,
.mtu_get = ipc_mtu_get,
.promisc_mode_set = NULL,
.promisc_mode_get = NULL,
diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c
index e6d004d43..3de096139 100644
--- a/platform/linux-generic/pktio/loop.c
+++ b/platform/linux-generic/pktio/loop.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2013-2018, Linaro Limited
- * Copyright (c) 2013, Nokia Solutions and Networks
+ * Copyright (c) 2013-2020, Nokia Solutions and Networks
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -367,7 +367,22 @@ static int loopback_mac_addr_get(pktio_entry_t *pktio_entry ODP_UNUSED,
static int loopback_link_status(pktio_entry_t *pktio_entry ODP_UNUSED)
{
/* loopback interfaces are always up */
- return 1;
+ return ODP_PKTIO_LINK_STATUS_UP;
+}
+
+static int loopback_link_info(pktio_entry_t *pktio_entry ODP_UNUSED, odp_pktio_link_info_t *info)
+{
+ memset(info, 0, sizeof(odp_pktio_link_info_t));
+
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_OFF;
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_FULL;
+ info->media = "virtual";
+ info->pause_rx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->pause_tx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->speed = ODP_PKTIO_LINK_SPEED_UNKNOWN;
+ info->status = ODP_PKTIO_LINK_STATUS_UP;
+
+ return 0;
}
static int loopback_init_capability(pktio_entry_t *pktio_entry)
@@ -467,6 +482,7 @@ const pktio_if_ops_t loopback_pktio_ops = {
.mac_get = loopback_mac_addr_get,
.mac_set = NULL,
.link_status = loopback_link_status,
+ .link_info = loopback_link_info,
.capability = loopback_capability,
.pktin_ts_res = NULL,
.pktin_ts_from_ns = NULL,
diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c
index e1a5da773..0f608c6f6 100644
--- a/platform/linux-generic/pktio/netmap.c
+++ b/platform/linux-generic/pktio/netmap.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2015-2018, Linaro Limited
- * Copyright (c) 2019, Nokia
+ * Copyright (c) 2019-2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -355,12 +355,33 @@ static int netmap_close(pktio_entry_t *pktio_entry)
static int netmap_link_status(pktio_entry_t *pktio_entry)
{
if (pkt_priv(pktio_entry)->is_virtual)
- return 1;
+ return ODP_PKTIO_LINK_STATUS_UP;
return link_status_fd(pkt_priv(pktio_entry)->sockfd,
pkt_priv(pktio_entry)->if_name);
}
+static int netmap_link_info(pktio_entry_t *pktio_entry, odp_pktio_link_info_t *info)
+{
+ pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
+
+ if (pkt_nm->is_virtual) {
+ memset(info, 0, sizeof(odp_pktio_link_info_t));
+
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_OFF;
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_FULL;
+ info->media = "virtual";
+ info->pause_rx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->pause_tx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->speed = ODP_PKTIO_LINK_SPEED_UNKNOWN;
+ info->status = ODP_PKTIO_LINK_STATUS_UP;
+
+ return 0;
+ }
+
+ return link_info_fd(pkt_nm->sockfd, pkt_nm->if_name, info);
+}
+
/**
* Wait for netmap link to come up
*
@@ -1225,6 +1246,7 @@ const pktio_if_ops_t netmap_pktio_ops = {
.start = netmap_start,
.stop = netmap_stop,
.link_status = netmap_link_status,
+ .link_info = netmap_link_info,
.stats = netmap_stats,
.stats_reset = netmap_stats_reset,
.mtu_get = netmap_mtu_get,
diff --git a/platform/linux-generic/pktio/null.c b/platform/linux-generic/pktio/null.c
index bb7f85c9b..d739ccafe 100644
--- a/platform/linux-generic/pktio/null.c
+++ b/platform/linux-generic/pktio/null.c
@@ -154,6 +154,26 @@ static int null_init_global(void)
return 0;
}
+static int null_link_status(pktio_entry_t *pktio_entry ODP_UNUSED)
+{
+ return ODP_PKTIO_LINK_STATUS_UP;
+}
+
+static int null_link_info(pktio_entry_t *pktio_entry ODP_UNUSED, odp_pktio_link_info_t *info)
+{
+ memset(info, 0, sizeof(odp_pktio_link_info_t));
+
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_OFF;
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_FULL;
+ info->media = "virtual";
+ info->pause_rx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->pause_tx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->speed = ODP_PKTIO_LINK_SPEED_UNKNOWN;
+ info->status = ODP_PKTIO_LINK_STATUS_UP;
+
+ return 0;
+}
+
const pktio_if_ops_t null_pktio_ops = {
.name = "null",
.print = NULL,
@@ -179,4 +199,6 @@ const pktio_if_ops_t null_pktio_ops = {
.config = NULL,
.input_queues_config = null_inqueues_config,
.output_queues_config = null_outqueues_config,
+ .link_status = null_link_status,
+ .link_info = null_link_info
};
diff --git a/platform/linux-generic/pktio/pcap.c b/platform/linux-generic/pktio/pcap.c
index 6ef998717..262528abc 100644
--- a/platform/linux-generic/pktio/pcap.c
+++ b/platform/linux-generic/pktio/pcap.c
@@ -444,6 +444,26 @@ static int pcapif_init_global(void)
return 0;
}
+static int pcapif_link_status(pktio_entry_t *pktio_entry ODP_UNUSED)
+{
+ return ODP_PKTIO_LINK_STATUS_UP;
+}
+
+static int pcapif_link_info(pktio_entry_t *pktio_entry ODP_UNUSED, odp_pktio_link_info_t *info)
+{
+ memset(info, 0, sizeof(odp_pktio_link_info_t));
+
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_OFF;
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_FULL;
+ info->media = "virtual";
+ info->pause_rx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->pause_tx = ODP_PKTIO_LINK_PAUSE_OFF;
+ info->speed = ODP_PKTIO_LINK_SPEED_UNKNOWN;
+ info->status = ODP_PKTIO_LINK_STATUS_UP;
+
+ return 0;
+}
+
const pktio_if_ops_t pcap_pktio_ops = {
.name = "pcap",
.print = NULL,
@@ -466,4 +486,6 @@ const pktio_if_ops_t pcap_pktio_ops = {
.config = NULL,
.input_queues_config = NULL,
.output_queues_config = NULL,
+ .link_status = pcapif_link_status,
+ .link_info = pcapif_link_info
};
diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c
index d148edf03..4776b83f9 100644
--- a/platform/linux-generic/pktio/socket.c
+++ b/platform/linux-generic/pktio/socket.c
@@ -493,6 +493,11 @@ static int sock_link_status(pktio_entry_t *pktio_entry)
pktio_entry->s.name);
}
+static int sock_link_info(pktio_entry_t *pktio_entry, odp_pktio_link_info_t *info)
+{
+ return link_info_fd(pkt_priv(pktio_entry)->sockfd, pktio_entry->s.name, info);
+}
+
static int sock_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
odp_pktio_capability_t *capa)
{
@@ -566,6 +571,7 @@ const pktio_if_ops_t sock_mmsg_pktio_ops = {
.mac_get = sock_mac_addr_get,
.mac_set = NULL,
.link_status = sock_link_status,
+ .link_info = sock_link_info,
.capability = sock_capability,
.pktin_ts_res = NULL,
.pktin_ts_from_ns = NULL,
diff --git a/platform/linux-generic/pktio/socket_common.c b/platform/linux-generic/pktio/socket_common.c
index 4fbf2f041..2eb3b4001 100644
--- a/platform/linux-generic/pktio/socket_common.c
+++ b/platform/linux-generic/pktio/socket_common.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2018, Linaro Limited
- * Copyright (c) 2019, Nokia
+ * Copyright (c) 2019-2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -14,7 +14,9 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <net/if.h>
+#include <linux/ethtool.h>
#include <linux/if_packet.h>
+#include <linux/sockios.h>
#include <errno.h>
#include <odp_debug_internal.h>
#include <odp_errno_define.h>
@@ -155,8 +157,141 @@ int link_status_fd(int fd, const char *name)
__odp_errno = errno;
ODP_DBG("ioctl(SIOCGIFFLAGS): %s: \"%s\".\n", strerror(errno),
ifr.ifr_name);
+ return ODP_PKTIO_LINK_STATUS_UNKNOWN;
+ }
+
+ if (ifr.ifr_flags & IFF_RUNNING)
+ return ODP_PKTIO_LINK_STATUS_UP;
+ return ODP_PKTIO_LINK_STATUS_DOWN;
+}
+
+int link_info_fd(int fd, const char *name, odp_pktio_link_info_t *info)
+{
+ struct ethtool_link_settings hcmd = {.cmd = ETHTOOL_GLINKSETTINGS};
+ struct ethtool_link_settings *ecmd;
+ struct ethtool_pauseparam pcmd = {.cmd = ETHTOOL_GPAUSEPARAM};
+ struct ifreq ifr;
+ int status;
+
+ status = link_status_fd(fd, name);
+ if (status < 0)
+ return -1;
+
+ snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", name);
+
+ /* Link pause status */
+ ifr.ifr_data = (void *)&pcmd;
+ if (ioctl(fd, SIOCETHTOOL, &ifr) && errno != EOPNOTSUPP) {
+ __odp_errno = errno;
+ ODP_ERR("ioctl(SIOCETHTOOL): %s: \"%s\".\n", strerror(errno),
+ ifr.ifr_name);
+ return -1;
+ }
+
+ /* Try to perform handshake and fall back to old API if failed */
+ ifr.ifr_data = (void *)&hcmd;
+ if (ioctl(fd, SIOCETHTOOL, &ifr) < 0) {
+ struct ethtool_cmd ecmd_old = {.cmd = ETHTOOL_GSET};
+
+ ifr.ifr_data = (void *)&ecmd_old;
+ if (ioctl(fd, SIOCETHTOOL, &ifr) < 0) {
+ __odp_errno = errno;
+ ODP_ERR("ioctl(SIOCETHTOOL): %s: \"%s\".\n", strerror(errno), ifr.ifr_name);
+ return -1;
+ }
+
+ memset(info, 0, sizeof(odp_pktio_link_info_t));
+ info->speed = ethtool_cmd_speed(&ecmd_old);
+ if (info->speed == (uint32_t)SPEED_UNKNOWN)
+ info->speed = ODP_PKTIO_LINK_SPEED_UNKNOWN;
+
+ if (ecmd_old.autoneg == AUTONEG_ENABLE)
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_ON;
+ else if (ecmd_old.autoneg == AUTONEG_DISABLE)
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_OFF;
+ else
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_UNKNOWN;
+
+ if (ecmd_old.duplex == DUPLEX_HALF)
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_HALF;
+ else if (ecmd_old.duplex == DUPLEX_FULL)
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_FULL;
+ else
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_UNKNOWN;
+
+ info->pause_rx = pcmd.rx_pause ? ODP_PKTIO_LINK_PAUSE_ON : ODP_PKTIO_LINK_PAUSE_OFF;
+ info->pause_tx = pcmd.tx_pause ? ODP_PKTIO_LINK_PAUSE_ON : ODP_PKTIO_LINK_PAUSE_OFF;
+
+ if (ecmd_old.port == PORT_TP)
+ info->media = "copper";
+ else if (ecmd_old.port == PORT_FIBRE)
+ info->media = "fiber";
+ else if (ecmd_old.port == PORT_OTHER)
+ info->media = "other";
+ else
+ info->media = "unknown";
+
+ info->status = status;
+
+ return 0;
+ }
+
+ if (hcmd.link_mode_masks_nwords >= 0 || hcmd.cmd != ETHTOOL_GLINKSETTINGS) {
+ ODP_ERR("ETHTOOL_GLINKSETTINGS handshake failed\n");
+ return -1;
+ }
+ /* Absolute value indicates kernel recommended 'link_mode_masks_nwords' value. */
+ hcmd.link_mode_masks_nwords = -hcmd.link_mode_masks_nwords;
+
+ /* Reserve space for the three bitmasks (map_supported, map_advertising, map_lp_advertising)
+ * at the end of struct ethtool_link_settings. 'link_mode_masks_nwords' defines the bitmask
+ * length in 32-bit words. */
+ uint8_t ODP_ALIGNED_CACHE data[offsetof(struct ethtool_link_settings, link_mode_masks) +
+ (3 * sizeof(uint32_t) * hcmd.link_mode_masks_nwords)];
+
+ ecmd = (void *)data;
+ *ecmd = hcmd;
+ ifr.ifr_data = (void *)ecmd;
+ if (ioctl(fd, SIOCETHTOOL, &ifr) < 0) {
+ __odp_errno = errno;
+ ODP_ERR("ioctl(SIOCETHTOOL): %s: \"%s\".\n", strerror(errno),
+ ifr.ifr_name);
return -1;
}
- return !!(ifr.ifr_flags & IFF_RUNNING);
+ memset(info, 0, sizeof(odp_pktio_link_info_t));
+ if (ecmd->speed == (uint32_t)SPEED_UNKNOWN)
+ info->speed = ODP_PKTIO_LINK_SPEED_UNKNOWN;
+ else
+ info->speed = ecmd->speed;
+
+ if (ecmd->autoneg == AUTONEG_ENABLE)
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_ON;
+ else if (ecmd->autoneg == AUTONEG_DISABLE)
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_OFF;
+ else
+ info->autoneg = ODP_PKTIO_LINK_AUTONEG_UNKNOWN;
+
+ if (ecmd->duplex == DUPLEX_HALF)
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_HALF;
+ else if (ecmd->duplex == DUPLEX_FULL)
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_FULL;
+ else
+ info->duplex = ODP_PKTIO_LINK_DUPLEX_UNKNOWN;
+
+ info->pause_rx = pcmd.rx_pause ? ODP_PKTIO_LINK_PAUSE_ON : ODP_PKTIO_LINK_PAUSE_OFF;
+ info->pause_tx = pcmd.tx_pause ? ODP_PKTIO_LINK_PAUSE_ON : ODP_PKTIO_LINK_PAUSE_OFF;
+
+ if (ecmd->port == PORT_TP)
+ info->media = "copper";
+ else if (ecmd->port == PORT_FIBRE)
+ info->media = "fiber";
+ else if (ecmd->port == PORT_OTHER)
+ info->media = "other";
+ else
+ info->media = "unknown";
+
+ info->status = status;
+
+ return 0;
}
diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c
index bf1cbad81..d0d37636d 100644
--- a/platform/linux-generic/pktio/socket_mmap.c
+++ b/platform/linux-generic/pktio/socket_mmap.c
@@ -784,6 +784,11 @@ static int sock_mmap_link_status(pktio_entry_t *pktio_entry)
pktio_entry->s.name);
}
+static int sock_mmap_link_info(pktio_entry_t *pktio_entry, odp_pktio_link_info_t *info)
+{
+ return link_info_fd(pkt_priv(pktio_entry)->sockfd, pktio_entry->s.name, info);
+}
+
static int sock_mmap_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
odp_pktio_capability_t *capa)
{
@@ -860,6 +865,7 @@ const pktio_if_ops_t sock_mmap_pktio_ops = {
.mac_get = sock_mmap_mac_addr_get,
.mac_set = NULL,
.link_status = sock_mmap_link_status,
+ .link_info = sock_mmap_link_info,
.capability = sock_mmap_capability,
.pktin_ts_res = NULL,
.pktin_ts_from_ns = NULL,
diff --git a/platform/linux-generic/pktio/tap.c b/platform/linux-generic/pktio/tap.c
index db5c701b2..13a9feaf8 100644
--- a/platform/linux-generic/pktio/tap.c
+++ b/platform/linux-generic/pktio/tap.c
@@ -467,6 +467,11 @@ static int tap_link_status(pktio_entry_t *pktio_entry)
pktio_entry->s.name + 4);
}
+static int tap_link_info(pktio_entry_t *pktio_entry, odp_pktio_link_info_t *info)
+{
+ return link_info_fd(pkt_priv(pktio_entry)->skfd, pktio_entry->s.name + 4, info);
+}
+
static int tap_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
odp_pktio_capability_t *capa)
{
@@ -501,6 +506,7 @@ const pktio_if_ops_t tap_pktio_ops = {
.mac_get = tap_mac_addr_get,
.mac_set = tap_mac_addr_set,
.link_status = tap_link_status,
+ .link_info = tap_link_info,
.capability = tap_capability,
.pktin_ts_res = NULL,
.pktin_ts_from_ns = NULL,
diff --git a/platform/linux-generic/test/pktio_ipc/ipc_common.c b/platform/linux-generic/test/pktio_ipc/ipc_common.c
index b064177bc..655cd80d5 100644
--- a/platform/linux-generic/test/pktio_ipc/ipc_common.c
+++ b/platform/linux-generic/test/pktio_ipc/ipc_common.c
@@ -22,6 +22,7 @@ int ipc_odp_packet_send_or_free(odp_pktio_t pktio,
odp_pktout_queue_t pktout;
int i;
+ memset(&pktout, 0, sizeof(pktout));
start_time = odp_time_local();
wait = odp_time_local_from_ns(ODP_TIME_SEC_IN_NS);
end_time = odp_time_sum(start_time, wait);
diff --git a/platform/linux-generic/test/pktio_ipc/pktio_ipc2.c b/platform/linux-generic/test/pktio_ipc/pktio_ipc2.c
index 0d64e94ba..9d4f91341 100644
--- a/platform/linux-generic/test/pktio_ipc/pktio_ipc2.c
+++ b/platform/linux-generic/test/pktio_ipc/pktio_ipc2.c
@@ -73,6 +73,7 @@ static int ipc_second_process(int master_pid)
return -1;
}
+ memset(&pktin, 0, sizeof(pktin)); /* not needed but makes GCC happy */
if (odp_pktin_queue(ipc_pktio, &pktin, 1) != 1) {
odp_pool_destroy(pool);
ODPH_ERR("no input queue\n");