diff options
Diffstat (limited to 'include/odp/api')
195 files changed, 22675 insertions, 3434 deletions
diff --git a/include/odp/api/abi-default/align.h b/include/odp/api/abi-default/align.h new file mode 100644 index 000000000..fa95d728b --- /dev/null +++ b/include/odp/api/abi-default/align.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP alignments + */ + +#ifndef ODP_ABI_ALIGN_H_ +#define ODP_ABI_ALIGN_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/cpu.h> + +/** @addtogroup odp_compiler_optim + * @{ + */ + +#ifdef __GNUC__ + +#define ODP_ALIGNED(x) __attribute__((__aligned__(x))) + +#define ODP_PACKED __attribute__((__packed__)) + +#define ODP_OFFSETOF(type, member) __builtin_offsetof(type, member) + +#define ODP_FIELD_SIZEOF(type, member) sizeof(((type *)0)->member) + +#else +#error Non-gcc compatible compiler +#endif + +/* ODP_CACHE_LINE_SIZE is defined in odp/api/abi/cpu.h */ + +#define ODP_PAGE_SIZE 4096 + +#define ODP_ALIGNED_CACHE ODP_ALIGNED(ODP_CACHE_LINE_SIZE) + +#define ODP_ALIGNED_PAGE ODP_ALIGNED(ODP_PAGE_SIZE) + +#define ODP_CACHE_LINE_ROUNDUP(x) \ +((ODP_CACHE_LINE_SIZE) * (((x) + (ODP_CACHE_LINE_SIZE) - 1) / (ODP_CACHE_LINE_SIZE))) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/atomic.h b/include/odp/api/abi-default/atomic.h new file mode 100644 index 000000000..9999360fc --- /dev/null +++ b/include/odp/api/abi-default/atomic.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2021 ARM Limited + */ + +/** + * @file + * + * ODP atomic operations + */ + +#ifndef ODP_ABI_ATOMIC_H_ +#define ODP_ABI_ATOMIC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> +#include <odp/api/align.h> + +/** + * @internal + * Atomic 32-bit unsigned integer + */ +typedef struct ODP_ALIGNED(sizeof(uint32_t)) odp_atomic_u32_s { + uint32_t v; /**< Actual storage for the atomic variable */ +} odp_atomic_u32_t; + +#if __GCC_ATOMIC_LLONG_LOCK_FREE >= 2 + +/** + * @internal + * Atomic 64-bit unsigned integer + */ +typedef struct ODP_ALIGNED(sizeof(uint64_t)) odp_atomic_u64_s { + uint64_t v; /**< Actual storage for the atomic variable */ +} odp_atomic_u64_t; + +#else + +/** + * @internal + * Use embedded lock for atomic 64-bit variable implementation + */ +#define ODP_ATOMIC_U64_LOCK 1 + +/** + * @internal + * Atomic 64-bit unsigned integer + */ +typedef struct ODP_ALIGNED(sizeof(uint64_t)) odp_atomic_u64_s { + uint64_t v; /**< Actual storage for the atomic variable */ + /* Some architectures do not support lock-free operations on 64-bit + * data types. We use a spin lock to ensure atomicity. */ + char lock; /**< Spin lock (if needed) used to ensure atomic access */ +} odp_atomic_u64_t; + +#endif + +#if defined(__SIZEOF_INT128__) || defined(_ODP_LOCK_FREE_128BIT_ATOMICS) + +/** + * @internal + * Atomic 128-bit unsigned integer + */ +typedef struct ODP_ALIGNED(sizeof(odp_u128_t)) odp_atomic_u128_s { + odp_u128_t v; /**< Actual storage for the atomic variable */ +} odp_atomic_u128_t; + +#else + +/** + * @internal + * Atomic 128-bit unsigned integer + */ +typedef struct ODP_ALIGNED(sizeof(odp_u128_t)) odp_atomic_u128_s { + odp_u128_t v; /**< Actual storage for the atomic variable */ + /* Some architectures do not support lock-free operations on 128-bit + * data types. We use a spin lock to ensure atomicity. */ + char lock; /**< Spin lock (if needed) used to ensure atomic access */ +} odp_atomic_u128_t; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/barrier.h b/include/odp/api/abi-default/barrier.h new file mode 100644 index 000000000..ee0329a97 --- /dev/null +++ b/include/odp/api/abi-default/barrier.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP barrier + */ + +#ifndef ODP_ABI_BARRIER_H_ +#define ODP_ABI_BARRIER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> +#include <odp/api/atomic.h> + +/** + * @internal + * ODP thread synchronization barrier + */ +struct odp_barrier_s { + uint32_t count; /**< Thread count */ + odp_atomic_u32_t bar; /**< Barrier counter */ +}; + +typedef struct odp_barrier_s odp_barrier_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/buffer.h b/include/odp/api/abi-default/buffer.h new file mode 100644 index 000000000..dce3fcac3 --- /dev/null +++ b/include/odp/api/abi-default/buffer.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + */ + +#ifndef ODP_ABI_BUFFER_H_ +#define ODP_ABI_BUFFER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/buffer_types.h b/include/odp/api/abi-default/buffer_types.h new file mode 100644 index 000000000..9179ae321 --- /dev/null +++ b/include/odp/api/abi-default/buffer_types.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + * Copyright (c) 2023 Nokia + */ + +#ifndef ODP_ABI_BUFFER_TYPES_H_ +#define ODP_ABI_BUFFER_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_buffer_t; + +/** @addtogroup odp_buffer + * @{ + */ + +typedef _odp_abi_buffer_t *odp_buffer_t; + +#define ODP_BUFFER_INVALID ((odp_buffer_t)0) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/byteorder.h b/include/odp/api/abi-default/byteorder.h new file mode 100644 index 000000000..a3a512598 --- /dev/null +++ b/include/odp/api/abi-default/byteorder.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP byteorder + */ + +#ifndef ODP_ABI_BYTEORDER_H_ +#define ODP_ABI_BYTEORDER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +#ifndef __BYTE_ORDER__ +#error __BYTE_ORDER__ not defined! +#endif + +#ifndef __ORDER_BIG_ENDIAN__ +#error __ORDER_BIG_ENDIAN__ not defined! +#endif + +#ifndef __ORDER_LITTLE_ENDIAN__ +#error __ORDER_LITTLE_ENDIAN__ not defined! +#endif + +/** @addtogroup odp_compiler_optim + * @{ + */ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #define ODP_LITTLE_ENDIAN 1 + #define ODP_BIG_ENDIAN 0 + #define ODP_BYTE_ORDER ODP_LITTLE_ENDIAN + #define ODP_LITTLE_ENDIAN_BITFIELD 1 + #define ODP_BIG_ENDIAN_BITFIELD 0 + #define ODP_BITFIELD_ORDER ODP_LITTLE_ENDIAN_BITFIELD +#else + #define ODP_LITTLE_ENDIAN 0 + #define ODP_BIG_ENDIAN 1 + #define ODP_BYTE_ORDER ODP_BIG_ENDIAN + #define ODP_LITTLE_ENDIAN_BITFIELD 0 + #define ODP_BIG_ENDIAN_BITFIELD 1 + #define ODP_BITFIELD_ORDER ODP_BIG_ENDIAN_BITFIELD +#endif + +typedef uint16_t odp_u16le_t; +typedef uint16_t odp_u16be_t; + +typedef uint32_t odp_u32le_t; +typedef uint32_t odp_u32be_t; + +typedef uint64_t odp_u64le_t; +typedef uint64_t odp_u64be_t; + +typedef uint16_t odp_u16sum_t; +typedef uint32_t odp_u32sum_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/classification.h b/include/odp/api/abi-default/classification.h new file mode 100644 index 000000000..fdc98f252 --- /dev/null +++ b/include/odp/api/abi-default/classification.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + */ + +#ifndef ODP_ABI_CLASSIFICATION_H_ +#define ODP_ABI_CLASSIFICATION_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_cos_t; + +/** Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_pmr_t; + +/** @addtogroup odp_classification + * @{ + */ + +typedef _odp_abi_cos_t *odp_cos_t; +typedef _odp_abi_pmr_t *odp_pmr_t; + +#define ODP_COS_INVALID ((odp_cos_t)0) +#define ODP_PMR_INVALID ((odp_pmr_t)0) + +#define ODP_COS_NAME_LEN 32 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/comp.h b/include/odp/api/abi-default/comp.h new file mode 100644 index 000000000..3f936aa20 --- /dev/null +++ b/include/odp/api/abi-default/comp.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2018 Linaro Limited + */ + +#ifndef ODP_ABI_COMP_H_ +#define ODP_ABI_COMP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_comp_session_t; + +/** @addtogroup odp_compression + * @{ + */ + +typedef _odp_abi_comp_session_t *odp_comp_session_t; + +#define ODP_COMP_SESSION_INVALID ((odp_comp_session_t)0) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/cpu.h b/include/odp/api/abi-default/cpu.h new file mode 100644 index 000000000..7bc444236 --- /dev/null +++ b/include/odp/api/abi-default/cpu.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2016-2018 Linaro Limited + */ + +#ifndef ODP_ABI_CPU_H_ +#define ODP_ABI_CPU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ODP_CACHE_LINE_SIZE +#define ODP_CACHE_LINE_SIZE 64 +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/cpumask.h b/include/odp/api/abi-default/cpumask.h new file mode 100644 index 000000000..bb7638f0c --- /dev/null +++ b/include/odp/api/abi-default/cpumask.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP CPU masks and enumeration + */ + +#ifndef ODP_ABI_CPUMASK_H_ +#define ODP_ABI_CPUMASK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup odp_cpumask + * @{ + */ + +#include <odp/api/std_types.h> +#include <odp/api/align.h> +#include <sched.h> + +#define ODP_CPUMASK_SIZE (sizeof(cpu_set_t) * 8) + +#define ODP_CPUMASK_STR_SIZE ((ODP_CPUMASK_SIZE + 3) / 4 + 3) + +/** + * CPU mask + * + * Don't access directly, use access functions. + */ +typedef struct ODP_ALIGNED(8) odp_cpumask_t { + /** @private CPU mask storage + * + * This is private to the implementation. + * Don't access directly, use access functions. + */ + uint8_t _u8[ODP_CPUMASK_SIZE / 8]; +} odp_cpumask_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/crypto.h b/include/odp/api/abi-default/crypto.h new file mode 100644 index 000000000..aa80587c4 --- /dev/null +++ b/include/odp/api/abi-default/crypto.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + * Copyright (c) 2022 Nokia + */ + +#ifndef ODP_ABI_CRYPTO_H_ +#define ODP_ABI_CRYPTO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/crypto_types.h b/include/odp/api/abi-default/crypto_types.h new file mode 100644 index 000000000..8d860b6ef --- /dev/null +++ b/include/odp/api/abi-default/crypto_types.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + * Copyright (c) 2022 Nokia + */ + +#ifndef ODP_ABI_CRYPTO_TYPES_H_ +#define ODP_ABI_CRYPTO_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +/** @addtogroup odp_crypto + * @{ + */ + +#define ODP_CRYPTO_SESSION_INVALID (0xffffffffffffffffULL) + +typedef uint64_t odp_crypto_session_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/debug.h b/include/odp/api/abi-default/debug.h new file mode 100644 index 000000000..5b196d589 --- /dev/null +++ b/include/odp/api/abi-default/debug.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP debug + */ + +#ifndef ODP_ABI_DEBUG_H_ +#define ODP_ABI_DEBUG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @internal Compile time assertion macro. Fails compilation and outputs 'msg' + * if condition 'cond' is false. Macro definition is empty when compiler is not + * supported or the compiler does not support static assertion. + */ +#ifndef __cplusplus +#define ODP_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg) +#else +#define ODP_STATIC_ASSERT(cond, msg) static_assert(cond, msg) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/dma.h b/include/odp/api/abi-default/dma.h new file mode 100644 index 000000000..dcc67bc71 --- /dev/null +++ b/include/odp/api/abi-default/dma.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +#ifndef ODP_ABI_DMA_H_ +#define ODP_ABI_DMA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/dma_types.h b/include/odp/api/abi-default/dma_types.h new file mode 100644 index 000000000..005ba3d16 --- /dev/null +++ b/include/odp/api/abi-default/dma_types.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Nokia + */ + +#ifndef ODP_ABI_DMA_TYPES_H_ +#define ODP_ABI_DMA_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_dma_t; + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_dma_compl_t; + +/** @addtogroup odp_dma + * @{ + */ + +typedef _odp_abi_dma_t *odp_dma_t; + +#define ODP_DMA_INVALID ((odp_dma_t)0) + +typedef _odp_abi_dma_t *odp_dma_compl_t; + +#define ODP_DMA_COMPL_INVALID ((odp_dma_compl_t)0) + +typedef uint64_t odp_dma_transfer_id_t; + +#define ODP_DMA_TRANSFER_ID_INVALID ((odp_dma_transfer_id_t)0) + +#define ODP_DMA_NAME_LEN 32 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/errno.h b/include/odp/api/abi-default/errno.h new file mode 100644 index 000000000..d8eee49fb --- /dev/null +++ b/include/odp/api/abi-default/errno.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2020 Marvell + */ + +/** + * @file + * + * ODP errno + */ + +#ifndef ODP_ABI_ERRNO_H_ +#define ODP_ABI_ERRNO_H_ + +/* Empty header to allow platforms to override inlining + * of errno functions. + */ + +#endif diff --git a/include/odp/api/abi-default/event.h b/include/odp/api/abi-default/event.h new file mode 100644 index 000000000..295f8608d --- /dev/null +++ b/include/odp/api/abi-default/event.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +#ifndef ODP_ABI_EVENT_H_ +#define ODP_ABI_EVENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/event_types.h b/include/odp/api/abi-default/event_types.h new file mode 100644 index 000000000..e5b50d9c0 --- /dev/null +++ b/include/odp/api/abi-default/event_types.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + * Copyright (c) 2022-2023 Nokia + */ + +#ifndef ODP_ABI_EVENT_TYPES_H_ +#define ODP_ABI_EVENT_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_event_t; + +/** @addtogroup odp_event + * @{ + */ + +typedef _odp_abi_event_t *odp_event_t; + +#define ODP_EVENT_INVALID ((odp_event_t)0) + +typedef enum { + ODP_EVENT_BUFFER = 1, + ODP_EVENT_PACKET = 2, + ODP_EVENT_TIMEOUT = 3, + ODP_EVENT_IPSEC_STATUS = 5, + ODP_EVENT_PACKET_VECTOR = 6, + ODP_EVENT_PACKET_TX_COMPL = 7, + ODP_EVENT_DMA_COMPL = 8, + ODP_EVENT_ML_COMPL = 9 +} odp_event_type_t; + +typedef enum { + ODP_EVENT_NO_SUBTYPE = 0, + ODP_EVENT_PACKET_BASIC = 1, + ODP_EVENT_PACKET_CRYPTO = 2, + ODP_EVENT_PACKET_IPSEC = 3, + ODP_EVENT_PACKET_COMP = 4, + ODP_EVENT_ML_COMPL_LOAD = 5, + ODP_EVENT_ML_COMPL_RUN = 6 +} odp_event_subtype_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/hash.h b/include/odp/api/abi-default/hash.h new file mode 100644 index 000000000..9cd0fb03d --- /dev/null +++ b/include/odp/api/abi-default/hash.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2020 Marvell + */ + +/** + * @file + * + * ODP hash + */ + +#ifndef ODP_ABI_HASH_H_ +#define ODP_ABI_HASH_H_ + +/* Empty header to allow platforms to override inlining + * of hash functions. + */ + +#endif diff --git a/include/odp/api/abi-default/init.h b/include/odp/api/abi-default/init.h new file mode 100644 index 000000000..221567e24 --- /dev/null +++ b/include/odp/api/abi-default/init.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP initialization. + */ + +#ifndef ODP_ABI_INIT_H_ +#define ODP_ABI_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +typedef uint64_t odp_instance_t; + +/** + * @internal platform specific data + */ +typedef struct odp_platform_init_t { + char dummy; /**< @internal Dummy */ +} odp_platform_init_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/ipsec.h b/include/odp/api/abi-default/ipsec.h new file mode 100644 index 000000000..ab3d5b643 --- /dev/null +++ b/include/odp/api/abi-default/ipsec.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2016-2018 Linaro Limited + * Copyright (c) 2022 Nokia + */ + +#ifndef ODP_ABI_IPSEC_H_ +#define ODP_ABI_IPSEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the packet inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/ipsec_types.h b/include/odp/api/abi-default/ipsec_types.h new file mode 100644 index 000000000..9d099b80d --- /dev/null +++ b/include/odp/api/abi-default/ipsec_types.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2016-2018 Linaro Limited + * Copyright (c) 2022 Nokia + */ + +#ifndef ODP_ABI_IPSEC_TYPES_H_ +#define ODP_ABI_IPSEC_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_ipsec_sa_t; + +/** @addtogroup odp_ipsec + * @{ + */ + +typedef _odp_abi_ipsec_sa_t *odp_ipsec_sa_t; + +#define ODP_IPSEC_SA_INVALID ((odp_ipsec_sa_t)0) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/ml_types.h b/include/odp/api/abi-default/ml_types.h new file mode 100644 index 000000000..723beb1bc --- /dev/null +++ b/include/odp/api/abi-default/ml_types.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021-2023 Nokia + */ + +#ifndef ODP_ABI_ML_TYPES_H_ +#define ODP_ABI_ML_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_ml_model_t; + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_ml_compl_t; + +/** @internal Implementation specific ML parameters */ +struct _odp_ml_model_extra_param_t { + /** @internal Dummy field to avoid empty struct */ + char dummy; +}; + +/** @addtogroup odp_ml + * @{ + */ + +typedef _odp_abi_ml_model_t *odp_ml_model_t; +typedef _odp_abi_ml_compl_t *odp_ml_compl_t; +typedef struct _odp_ml_model_extra_param_t odp_ml_model_extra_param_t; + +#define ODP_ML_MODEL_INVALID ((odp_ml_model_t)0) +#define ODP_ML_COMPL_INVALID ((odp_ml_compl_t)0) + +#define ODP_ML_MODEL_NAME_LEN 64 +#define ODP_ML_MODEL_IO_NAME_LEN 64 +#define ODP_ML_SHAPE_NAME_LEN 16 +#define ODP_ML_EXTRA_STAT_NAME_LEN 64 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/packet.h b/include/odp/api/abi-default/packet.h new file mode 100644 index 000000000..033f50cea --- /dev/null +++ b/include/odp/api/abi-default/packet.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + */ + +#ifndef ODP_ABI_PACKET_H_ +#define ODP_ABI_PACKET_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the packet inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/packet_flags.h b/include/odp/api/abi-default/packet_flags.h new file mode 100644 index 000000000..ee1e6ae11 --- /dev/null +++ b/include/odp/api/abi-default/packet_flags.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP packet descriptor + */ + +#ifndef ODP_ABI_PACKET_FLAGS_H_ +#define ODP_ABI_PACKET_FLAGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/packet_io.h b/include/odp/api/abi-default/packet_io.h new file mode 100644 index 000000000..f9b089778 --- /dev/null +++ b/include/odp/api/abi-default/packet_io.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +#ifndef ODP_ABI_PACKET_IO_H_ +#define ODP_ABI_PACKET_IO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the packet inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/packet_io_types.h b/include/odp/api/abi-default/packet_io_types.h new file mode 100644 index 000000000..1aa1cf816 --- /dev/null +++ b/include/odp/api/abi-default/packet_io_types.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2020-2023 Nokia + */ + +/** + * @file + * + * ODP Packet IO + */ + +#ifndef ODP_ABI_PACKET_IO_TYPES_H_ +#define ODP_ABI_PACKET_IO_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_pktio_t; + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_lso_profile_t; + +/** @addtogroup odp_packet_io + * @{ + */ + +typedef _odp_abi_pktio_t *odp_pktio_t; +typedef _odp_abi_lso_profile_t *odp_lso_profile_t; + +/** @internal */ +typedef struct odp_pktin_queue_t { + odp_pktio_t pktio; /**< @internal pktio handle */ + int index; /**< @internal pktio queue index */ +} odp_pktin_queue_t; + +/** @internal */ +typedef struct odp_pktout_queue_t { + odp_pktio_t pktio; /**< @internal pktio handle */ + int index; /**< @internal pktio queue index */ +} odp_pktout_queue_t; + +#define ODP_PKTIO_INVALID ((odp_pktio_t)0) +#define ODP_LSO_PROFILE_INVALID ((odp_lso_profile_t)0) + +#define ODP_PKTIO_MAX_INDEX 63 + +#define ODP_PKTIO_MACADDR_MAXSIZE 16 + +#define ODP_PKTIN_NO_WAIT 0 + +#define ODP_PKTIN_MAX_QUEUES 64 + +#define ODP_PKTOUT_MAX_QUEUES 64 + +#define ODP_PKTIO_STATS_EXTRA_NAME_LEN 64 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/packet_types.h b/include/odp/api/abi-default/packet_types.h new file mode 100644 index 000000000..e8b2c8484 --- /dev/null +++ b/include/odp/api/abi-default/packet_types.h @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + * Copyright (c) 2021 Nokia + */ + +#ifndef ODP_ABI_PACKET_TYPES_H_ +#define ODP_ABI_PACKET_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_packet_t; + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< *internal Dummy */ } _odp_abi_packet_seg_t; + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< *internal Dummy */ } _odp_abi_packet_buf_t; + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< *internal Dummy */ } _odp_abi_packet_vector_t; + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< *internal Dummy */ } _odp_abi_packet_tx_compl_t; + +/** @addtogroup odp_packet + * @{ + */ + +typedef _odp_abi_packet_t *odp_packet_t; +typedef _odp_abi_packet_seg_t *odp_packet_seg_t; +typedef _odp_abi_packet_buf_t *odp_packet_buf_t; +typedef _odp_abi_packet_vector_t *odp_packet_vector_t; +typedef _odp_abi_packet_tx_compl_t *odp_packet_tx_compl_t; + +#define ODP_PACKET_INVALID ((odp_packet_t)0) +#define ODP_PACKET_SEG_INVALID ((odp_packet_seg_t)0) +#define ODP_PACKET_BUF_INVALID ((odp_packet_buf_t)0) +#define ODP_PACKET_OFFSET_INVALID 0xffff +#define ODP_PACKET_VECTOR_INVALID ((odp_packet_vector_t)0) +#define ODP_PACKET_TX_COMPL_INVALID ((odp_packet_tx_compl_t)0) + +/** Packet Color */ +typedef enum { + ODP_PACKET_GREEN = 0, + ODP_PACKET_YELLOW = 1, + ODP_PACKET_RED = 2, + ODP_PACKET_ALL_COLORS = 3, +} odp_packet_color_t; + +/** Packet Checksum Status */ +typedef enum { + ODP_PACKET_CHKSUM_UNKNOWN = 0, + ODP_PACKET_CHKSUM_BAD, + ODP_PACKET_CHKSUM_OK +} odp_packet_chksum_status_t; + +/** Parse result flags */ +typedef struct odp_packet_parse_result_flag_t { + /** Flags union */ + union { + /** All flags as a 64 bit word */ + uint64_t all; + + /** Flags as a bitfield struct */ + struct { + /** See odp_packet_has_error() */ + uint64_t has_error : 1; + /** See odp_packet_has_l2_error() */ + uint64_t has_l2_error : 1; + /** See odp_packet_has_l3_error() */ + uint64_t has_l3_error : 1; + /** See odp_packet_has_l4_error() */ + uint64_t has_l4_error : 1; + /** See odp_packet_has_l2() */ + uint64_t has_l2 : 1; + /** See odp_packet_has_l3() */ + uint64_t has_l3 : 1; + /** See odp_packet_has_l4() */ + uint64_t has_l4 : 1; + /** See odp_packet_has_eth() */ + uint64_t has_eth : 1; + /** See odp_packet_has_eth_bcast() */ + uint64_t has_eth_bcast : 1; + /** See odp_packet_has_eth_mcast() */ + uint64_t has_eth_mcast : 1; + /** See odp_packet_has_jumbo() */ + uint64_t has_jumbo : 1; + /** See odp_packet_has_vlan() */ + uint64_t has_vlan : 1; + /** See odp_packet_has_vlan_qinq() */ + uint64_t has_vlan_qinq : 1; + /** See odp_packet_has_arp() */ + uint64_t has_arp : 1; + /** See odp_packet_has_ipv4() */ + uint64_t has_ipv4 : 1; + /** See odp_packet_has_ipv6() */ + uint64_t has_ipv6 : 1; + /** See odp_packet_has_ip_bcast() */ + uint64_t has_ip_bcast : 1; + /** See odp_packet_has_ip_mcast() */ + uint64_t has_ip_mcast : 1; + /** See odp_packet_has_ipfrag() */ + uint64_t has_ipfrag : 1; + /** See odp_packet_has_ipopt() */ + uint64_t has_ipopt : 1; + /** See odp_packet_has_ipsec() */ + uint64_t has_ipsec : 1; + /** See odp_packet_has_udp() */ + uint64_t has_udp : 1; + /** See odp_packet_has_tcp() */ + uint64_t has_tcp : 1; + /** See odp_packet_has_sctp() */ + uint64_t has_sctp : 1; + /** See odp_packet_has_icmp() */ + uint64_t has_icmp : 1; + }; + }; + +} odp_packet_parse_result_flag_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/pool.h b/include/odp/api/abi-default/pool.h new file mode 100644 index 000000000..dd2f66ac5 --- /dev/null +++ b/include/odp/api/abi-default/pool.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +#ifndef ODP_ABI_POOL_H_ +#define ODP_ABI_POOL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the packet inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/pool_types.h b/include/odp/api/abi-default/pool_types.h new file mode 100644 index 000000000..ce1042c12 --- /dev/null +++ b/include/odp/api/abi-default/pool_types.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + * Copyright (c) 2022 Nokia + */ + +#ifndef ODP_ABI_POOL_TYPES_H_ +#define ODP_ABI_POOL_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_pool_t; + +/** @addtogroup odp_pool + * @{ + */ + +typedef _odp_abi_pool_t *odp_pool_t; + +#define ODP_POOL_INVALID ((odp_pool_t)0) + +#define ODP_POOL_NAME_LEN 32 + +#define ODP_POOL_MAX_THREAD_STATS 128 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/proto_stats.h b/include/odp/api/abi-default/proto_stats.h new file mode 100644 index 000000000..9b3147762 --- /dev/null +++ b/include/odp/api/abi-default/proto_stats.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Marvell + */ + +#ifndef ODP_ABI_PROTO_STATS_H_ +#define ODP_ABI_PROTO_STATS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required to enable API function inlining */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/proto_stats_types.h b/include/odp/api/abi-default/proto_stats_types.h new file mode 100644 index 000000000..e17adf886 --- /dev/null +++ b/include/odp/api/abi-default/proto_stats_types.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Marvell + * Copyright (c) 2021 Nokia + */ + +#ifndef ODP_ABI_PROTO_STATS_TYPES_H_ +#define ODP_ABI_PROTO_STATS_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_proto_stats_t; + +/** @addtogroup odp_proto_stats + * @{ + */ + +typedef _odp_abi_proto_stats_t *odp_proto_stats_t; + +#define ODP_PROTO_STATS_INVALID ((odp_proto_stats_t)0) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/queue.h b/include/odp/api/abi-default/queue.h new file mode 100644 index 000000000..5ad307801 --- /dev/null +++ b/include/odp/api/abi-default/queue.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + */ + +#ifndef ODP_ABI_QUEUE_H_ +#define ODP_ABI_QUEUE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the queue inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/queue_types.h b/include/odp/api/abi-default/queue_types.h new file mode 100644 index 000000000..677348c18 --- /dev/null +++ b/include/odp/api/abi-default/queue_types.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + * Copyright (c) 2021 Nokia + */ + +#ifndef ODP_ABI_QUEUE_TYPES_H_ +#define ODP_ABI_QUEUE_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_queue_t; + +/** @addtogroup odp_queue + * @{ + */ + +typedef _odp_abi_queue_t *odp_queue_t; + +#define ODP_QUEUE_INVALID ((odp_queue_t)0) + +#define ODP_QUEUE_NAME_LEN 32 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/random.h b/include/odp/api/abi-default/random.h new file mode 100644 index 000000000..b99419155 --- /dev/null +++ b/include/odp/api/abi-default/random.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +#ifndef ODP_ABI_RANDOM_H_ +#define ODP_ABI_RANDOM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the packet inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/rwlock.h b/include/odp/api/abi-default/rwlock.h new file mode 100644 index 000000000..300108e67 --- /dev/null +++ b/include/odp/api/abi-default/rwlock.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP rwlock + */ + +#ifndef ODP_ABI_RWLOCK_H_ +#define ODP_ABI_RWLOCK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/atomic.h> + +/** @internal */ +typedef struct odp_rwlock_s { + odp_atomic_u32_t cnt; /**< lock count + 0 lock not taken + -1 write lock taken + >0 read lock(s) taken */ +} odp_rwlock_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/rwlock_recursive.h b/include/odp/api/abi-default/rwlock_recursive.h new file mode 100644 index 000000000..eb5c000c0 --- /dev/null +++ b/include/odp/api/abi-default/rwlock_recursive.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP recursive read/write lock + */ + +#ifndef ODP_ABI_RWLOCK_RECURSIVE_H_ +#define ODP_ABI_RWLOCK_RECURSIVE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/rwlock.h> +#include <odp/api/std_types.h> +#include <odp/api/thread.h> + +/** @internal */ +typedef struct odp_rwlock_recursive_s { + odp_rwlock_t lock; /**< the lock */ + int wr_owner; /**< write owner thread */ + uint32_t wr_cnt; /**< write recursion count */ + uint8_t rd_cnt[ODP_THREAD_COUNT_MAX]; /**< read recursion count */ +} odp_rwlock_recursive_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/schedule.h b/include/odp/api/abi-default/schedule.h new file mode 100644 index 000000000..73c51a7c6 --- /dev/null +++ b/include/odp/api/abi-default/schedule.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +#ifndef ODP_ABI_SCHEDULE_H_ +#define ODP_ABI_SCHEDULE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the schedule inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/schedule_types.h b/include/odp/api/abi-default/schedule_types.h new file mode 100644 index 000000000..eeb18771e --- /dev/null +++ b/include/odp/api/abi-default/schedule_types.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP schedule + */ + +#ifndef ODP_ABI_SCHEDULE_TYPES_H_ +#define ODP_ABI_SCHEDULE_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +/** @addtogroup odp_scheduler + * @{ + */ + +#define ODP_SCHED_WAIT UINT64_MAX +#define ODP_SCHED_NO_WAIT 0 + +#define ODP_SCHED_GROUP_NAME_LEN 32 + +typedef int odp_schedule_sync_t; + +#define ODP_SCHED_SYNC_PARALLEL 0 +#define ODP_SCHED_SYNC_ATOMIC 1 +#define ODP_SCHED_SYNC_ORDERED 2 + +typedef int odp_schedule_group_t; + +/* These must be kept in sync with thread_globals_t in odp_thread.c */ +#define ODP_SCHED_GROUP_INVALID ((odp_schedule_group_t)-1) +#define ODP_SCHED_GROUP_ALL 0 +#define ODP_SCHED_GROUP_WORKER 1 +#define ODP_SCHED_GROUP_CONTROL 2 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/shared_memory.h b/include/odp/api/abi-default/shared_memory.h new file mode 100644 index 000000000..70d6e906f --- /dev/null +++ b/include/odp/api/abi-default/shared_memory.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + */ + +#ifndef ODP_ABI_SHM_H_ +#define ODP_ABI_SHM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_shm_t; + +/** @addtogroup odp_shared_memory + * @{ + */ + +typedef _odp_abi_shm_t *odp_shm_t; + +#define ODP_SHM_INVALID ((odp_shm_t)0) +#define ODP_SHM_NAME_LEN 32 + +#define ODP_SHM_IOVA_INVALID ((uint64_t)-1) +#define ODP_SHM_PA_INVALID ODP_SHM_IOVA_INVALID + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/spinlock.h b/include/odp/api/abi-default/spinlock.h new file mode 100644 index 000000000..68f8aa8aa --- /dev/null +++ b/include/odp/api/abi-default/spinlock.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP spinlock + */ + +#ifndef ODP_ABI_SPINLOCK_H_ +#define ODP_ABI_SPINLOCK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @internal */ +typedef struct odp_spinlock_s { + char lock; /**< lock flag, should match odp_atomic_flag_t */ +} odp_spinlock_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/spinlock_recursive.h b/include/odp/api/abi-default/spinlock_recursive.h new file mode 100644 index 000000000..6f8068033 --- /dev/null +++ b/include/odp/api/abi-default/spinlock_recursive.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP recursive spinlock + */ + +#ifndef ODP_ABI_SPINLOCK_RECURSIVE_H_ +#define ODP_ABI_SPINLOCK_RECURSIVE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spinlock.h> +#include <odp/api/std_types.h> + +/** @internal */ +typedef struct odp_spinlock_recursive_s { + odp_spinlock_t lock; /**< the lock */ + int owner; /**< thread owning the lock */ + uint32_t cnt; /**< recursion count */ +} odp_spinlock_recursive_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/stash.h b/include/odp/api/abi-default/stash.h new file mode 100644 index 000000000..ec9316e68 --- /dev/null +++ b/include/odp/api/abi-default/stash.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2020 Nokia + */ + +#ifndef ODP_ABI_STASH_H_ +#define ODP_ABI_STASH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/stash_types.h b/include/odp/api/abi-default/stash_types.h new file mode 100644 index 000000000..6779f3af6 --- /dev/null +++ b/include/odp/api/abi-default/stash_types.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +#ifndef ODP_ABI_STASH_TYPES_H_ +#define ODP_ABI_STASH_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_stash_t; + +/** @addtogroup odp_stash + * @{ + */ + +typedef _odp_abi_stash_t *odp_stash_t; + +#define ODP_STASH_INVALID ((odp_stash_t)0) + +#define ODP_STASH_NAME_LEN 32 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/std.h b/include/odp/api/abi-default/std.h new file mode 100644 index 000000000..7de653653 --- /dev/null +++ b/include/odp/api/abi-default/std.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +#ifndef ODP_ABI_STD_H_ +#define ODP_ABI_STD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/std_types.h b/include/odp/api/abi-default/std_types.h new file mode 100644 index 000000000..cb8c4230f --- /dev/null +++ b/include/odp/api/abi-default/std_types.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +#ifndef ODP_ABI_STD_TYPES_H_ +#define ODP_ABI_STD_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* uint64_t, uint32_t, etc */ +#include <stdint.h> + +/* size_t */ +#include <stddef.h> + +/* true and false for odp_bool_t */ +#include <stdbool.h> + +/** @addtogroup odp_std + * @{ + */ + +typedef int odp_bool_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/sync.h b/include/odp/api/abi-default/sync.h new file mode 100644 index 000000000..862081a50 --- /dev/null +++ b/include/odp/api/abi-default/sync.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP barrier + */ + +#ifndef ODP_ABI_SYNC_H_ +#define ODP_ABI_SYNC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/thread.h b/include/odp/api/abi-default/thread.h new file mode 100644 index 000000000..3b7ce41dc --- /dev/null +++ b/include/odp/api/abi-default/thread.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +#ifndef ODP_ABI_THREAD_H_ +#define ODP_ABI_THREAD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/thread_types.h b/include/odp/api/abi-default/thread_types.h new file mode 100644 index 000000000..d8c27fb98 --- /dev/null +++ b/include/odp/api/abi-default/thread_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +#ifndef ODP_ABI_THREAD_TYPES_H_ +#define ODP_ABI_THREAD_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup odp_thread + * @{ + */ + +#define ODP_THREAD_COUNT_MAX 256 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/thrmask.h b/include/odp/api/abi-default/thrmask.h new file mode 100644 index 000000000..a5aff670b --- /dev/null +++ b/include/odp/api/abi-default/thrmask.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP thread masks + */ + +#ifndef ODP_ABI_THRMASK_H_ +#define ODP_ABI_THRMASK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup odp_thread + * @{ + */ + +#include <odp/api/cpumask.h> + +/** + * Minimum size of output buffer for odp_thrmask_to_str() + */ +#define ODP_THRMASK_STR_SIZE ODP_CPUMASK_STR_SIZE + +/** + * Thread mask + * + * Don't access directly, use access functions. + */ +typedef struct odp_thrmask_t { + odp_cpumask_t m; /**< @private Mask*/ +} odp_thrmask_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/ticketlock.h b/include/odp/api/abi-default/ticketlock.h new file mode 100644 index 000000000..d8489ad9d --- /dev/null +++ b/include/odp/api/abi-default/ticketlock.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP ticketlock + */ + +#ifndef ODP_ABI_TICKETLOCK_H_ +#define ODP_ABI_TICKETLOCK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/atomic.h> + +/** @internal */ +typedef struct odp_ticketlock_s { + odp_atomic_u32_t next_ticket; /**< Next ticket */ + odp_atomic_u32_t cur_ticket; /**< Current ticket */ +} odp_ticketlock_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/time.h b/include/odp/api/abi-default/time.h new file mode 100644 index 000000000..e8af62c0f --- /dev/null +++ b/include/odp/api/abi-default/time.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +#ifndef ODP_ABI_TIME_H_ +#define ODP_ABI_TIME_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/time_types.h b/include/odp/api/abi-default/time_types.h new file mode 100644 index 000000000..afbe6d188 --- /dev/null +++ b/include/odp/api/abi-default/time_types.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +#ifndef ODP_ABI_TIME_TYPES_H_ +#define ODP_ABI_TIME_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +/** @addtogroup odp_time + * @{ + **/ + +/** + * @internal Time structure used for both POSIX timespec and HW counter + * implementations. + */ +typedef struct odp_time_t { + /** @internal Variant mappings for time type */ + union { + /** @internal Used with generic 64 bit operations */ + uint64_t u64; + + /** @internal Nanoseconds */ + uint64_t nsec; + + /** @internal HW timer counter value */ + uint64_t count; + + }; +} odp_time_t; + +#define ODP_TIME_NULL ((odp_time_t){.u64 = 0}) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/timer.h b/include/odp/api/abi-default/timer.h new file mode 100644 index 000000000..39b71c6a3 --- /dev/null +++ b/include/odp/api/abi-default/timer.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +#ifndef ODP_ABI_TIMER_H_ +#define ODP_ABI_TIMER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Empty header required due to the timer inline functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/timer_types.h b/include/odp/api/abi-default/timer_types.h new file mode 100644 index 000000000..89b237fdb --- /dev/null +++ b/include/odp/api/abi-default/timer_types.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP timer service + */ + +#ifndef ODP_ABI_TIMER_TYPES_H_ +#define ODP_ABI_TIMER_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_timer_t; + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_timeout_t; + +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_timer_pool_t; + +/** @addtogroup odp_timer + * @{ + **/ + +typedef _odp_abi_timer_pool_t *odp_timer_pool_t; + +#define ODP_TIMER_POOL_INVALID ((odp_timer_pool_t)0) + +#define ODP_TIMER_POOL_NAME_LEN 32 + +typedef _odp_abi_timer_t *odp_timer_t; + +#define ODP_TIMER_INVALID ((odp_timer_t)0) + +typedef _odp_abi_timeout_t *odp_timeout_t; + +#define ODP_TIMEOUT_INVALID ((odp_timeout_t)0) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/traffic_mngr.h b/include/odp/api/abi-default/traffic_mngr.h new file mode 100644 index 000000000..32a0ab473 --- /dev/null +++ b/include/odp/api/abi-default/traffic_mngr.h @@ -0,0 +1,158 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2022 Marvell + */ + +/** + * @file + * + * ODP traffic mngr + */ + +#ifndef ODP_ABI_TRAFFIC_MNGR_H_ +#define ODP_ABI_TRAFFIC_MNGR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +/** @addtogroup odp_traffic_mngr + * Macros and operations on a TM system. + * @{ + */ + +/** The ODP_TM_MAX_NUM_SYSTEMS constant specifies the maximum number of TM + * systems that may be created. On some platforms this might be much more + * limited to as little as one hardware TM system. + */ +#define ODP_TM_MAX_NUM_SYSTEMS 8 + +/** The ODP_TM_MAX_PRIORITIES constant specifies the largest range of + * priorities that any TM system can support. All strict priority values MUST + * in the range 0..ODP_TM_MAX_PRIORITIES-1. + */ +#define ODP_TM_MAX_PRIORITIES 16 + +/** The ODP_TM MAX_LEVELS constant specifies the largest range of + * tm_node levels that any TM system can support. Hence all tm_node level + * values MUST be in the range 0..ODP_TM_MAX_LEVELS-1. Smaller tm_node + * levels are associated with tm_nodes closer to the TM system egress. + */ +#define ODP_TM_MAX_LEVELS 8 + +/** + * The smallest SCHED weight is 1 (i.e. 0 is not a legal WFQ/WRR value). + */ +#define ODP_TM_MIN_SCHED_WEIGHT 1U + +/** The ODP_TM_MAX_SCHED_WEIGHT constant is the largest weight any TM system + * can support (at least from a configuration standpoint). A given TM system + * could have a smaller value. + */ +#define ODP_TM_MAX_SCHED_WEIGHT 255U + +/** The ODP_TM_MAX_TM_QUEUES constant is the largest number of tm_queues + * that can be handled by any one TM system. + */ +#define ODP_TM_MAX_TM_QUEUES (4 * 1024) + +/** The ODP_TM_MAX_NUM_OUTPUTS constant is the largest number of outputs that + * can be configured for any one TM system. + */ +#define ODP_TM_MAX_NUM_OUTPUTS 256 + +/** The ODP_TM_MAX_NUM_TM_NODES constant is the largest number of tm_nodes that + * can be in existence for any one TM system. + */ +#define ODP_TM_MAX_NUM_TM_NODES (4 * 1024) + +/** The ODP_TM_MAX_TM_NODE_FANIN constant is the largest number of fan-in + * "inputs" that can be simultaneously connected to a single tm_node. + * *TBD* Does this need to be as large as ODP_TM_MAX_TM_QUEUES? *TBD* + */ +#define ODP_TM_MAX_TM_NODE_FANIN (4 * 1024) + +/** The INVALID_PRIORITY constant is used when one needs to indicate an + * invalid priority value. + */ +#define ODP_TM_INVALID_PRIORITY 255 + +/** The odp_tm_percent_t type is used when specifying fields that are + * percentages. It is a fixed point integer whose units are 1/100 of a + * percent. Hence 100% is represented as the integer value 10000. Note + * that because it is often used as a ratio of the current queue value and + * maximum queue threshold, it can be > 100%, but in any event will never + * be larger than 500% (i.e. it MUST be capped at 50000). + */ +typedef uint16_t odp_tm_percent_t; + +/** The odp_tm_handle_t type is a generic type that can stand for any of the + * other ODP_TM handle types. + */ +typedef uint64_t odp_tm_handle_t; + +/** Each odp_tm_t value represents a specific TM system. Almost all + * functions in this API require a odp_tm_t value - either directly + * as a function parameter or indirectly by having another ODP TM handle value + * as a function parameter. + */ +typedef odp_tm_handle_t odp_tm_t; + +/** Each odp_tm_queue_t value is an opaque ODP handle representing a specific + * tm_queue within a specific TM system. + */ +typedef odp_tm_handle_t odp_tm_queue_t; + +/** Each odp_tm_node_t value is an opaque ODP handle representing a specific + * tm_node within a specific TM system. + */ +typedef odp_tm_handle_t odp_tm_node_t; + +/** Each odp_tm_shaper_t value is an opaque ODP handle representing a specific + * shaper profile usable across all TM systems described by this API. A given + * shaper profile can then be attached to any tm_queue or tm_node. + */ +typedef odp_tm_handle_t odp_tm_shaper_t; + +/** Each odp_tm_sched_t value is an opaque ODP handle representing a specific + * tm_node scheduler profile usable across all TM systems described by this + * API. A given tm_node scheduler profile can then be attached to any tm_node. + */ +typedef odp_tm_handle_t odp_tm_sched_t; + +/** Each odp_tm_threshold_t value is an opaque ODP handle representing a + * specific queue threshold profile usable across all TM systems described by + * this API. A given queue threshold profile can then be attached to any + * tm_queue or tm_node. + */ +typedef odp_tm_handle_t odp_tm_threshold_t; + +/** Each odp_tm_wred_t value is an opaque ODP handle representing a specific + * WRED profile usable across all TM systems described by this API. A given + * WRED profile can then be attached to any tm_queue or tm_node. + */ +typedef odp_tm_handle_t odp_tm_wred_t; + +/** The ODP_TM_INVALID constant can be used with any ODP TM handle type and + * indicates that this value does NOT represent a valid TM object. + */ +#define ODP_TM_INVALID 0 + +/** + * @def ODP_TM_ROOT + * Constant that is used to refer to the egress/root node of the TM subsystem's + * tree/hierarchy of nodes. + */ +#define ODP_TM_ROOT ((odp_tm_handle_t)-1) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/abi-default/version.h b/include/odp/api/abi-default/version.h new file mode 100644 index 000000000..f15058623 --- /dev/null +++ b/include/odp/api/abi-default/version.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +#ifndef ODP_ABI_VERSION_H_ +#define ODP_ABI_VERSION_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @internal Version string expand */ +#define ODP_VERSION_STR_EXPAND(x) #x + +/** @internal Version to string */ +#define ODP_VERSION_TO_STR(x) ODP_VERSION_STR_EXPAND(x) + +/** @internal API version string */ +#define ODP_VERSION_API_STR \ +ODP_VERSION_TO_STR(ODP_VERSION_API_GENERATION) "." \ +ODP_VERSION_TO_STR(ODP_VERSION_API_MAJOR) "." \ +ODP_VERSION_TO_STR(ODP_VERSION_API_MINOR) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/align.h b/include/odp/api/align.h new file mode 100644 index 000000000..c003b714d --- /dev/null +++ b/include/odp/api/align.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP alignments + */ + +#ifndef ODP_API_ALIGN_H_ +#define ODP_API_ALIGN_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/align.h> + +#include <odp/api/spec/align.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h new file mode 100644 index 000000000..7f79256e8 --- /dev/null +++ b/include/odp/api/atomic.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP atomic operations + */ + +#ifndef ODP_API_ATOMIC_H_ +#define ODP_API_ATOMIC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/atomic.h> + +#include <odp/api/spec/atomic.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/barrier.h b/include/odp/api/barrier.h new file mode 100644 index 000000000..768b66c0d --- /dev/null +++ b/include/odp/api/barrier.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP execution barriers + */ + +#ifndef ODP_API_BARRIER_H_ +#define ODP_API_BARRIER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> +#include <odp/api/atomic.h> +#include <odp/api/abi/shared_memory.h> +#include <odp/api/abi/barrier.h> + +#include <odp/api/spec/barrier.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/buffer.h b/include/odp/api/buffer.h new file mode 100644 index 000000000..13a31d169 --- /dev/null +++ b/include/odp/api/buffer.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP buffer descriptor + */ + +#ifndef ODP_API_BUFFER_H_ +#define ODP_API_BUFFER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/buffer.h> + +#include <odp/api/spec/buffer.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/buffer_types.h b/include/odp/api/buffer_types.h new file mode 100644 index 000000000..73d2294be --- /dev/null +++ b/include/odp/api/buffer_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +/** + * @file + * + * ODP buffer types + */ + +#ifndef ODP_API_BUFFER_TYPES_H_ +#define ODP_API_BUFFER_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/buffer_types.h> + +#include <odp/api/spec/buffer_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/byteorder.h b/include/odp/api/byteorder.h new file mode 100644 index 000000000..39857381f --- /dev/null +++ b/include/odp/api/byteorder.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited + */ + +/** + * @file + * + * ODP byteorder + */ + +#ifndef ODP_API_BYTEORDER_H_ +#define ODP_API_BYTEORDER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/byteorder.h> + +#include <odp/api/spec/byteorder.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/chksum.h b/include/odp/api/chksum.h new file mode 100644 index 000000000..39cb08f7c --- /dev/null +++ b/include/odp/api/chksum.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + */ + +/** + * @file + * + * ODP checksum functions + */ + +#ifndef ODP_API_CHKSUM_H_ +#define ODP_API_CHKSUM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spec/chksum.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/classification.h b/include/odp/api/classification.h new file mode 100644 index 000000000..5a14a9e79 --- /dev/null +++ b/include/odp/api/classification.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited + */ + +/** + * @file + * + * ODP classification descriptor + */ + +#ifndef ODP_API_CLASSIFICATION_H_ +#define ODP_API_CLASSIFICATION_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> +#include <odp/api/abi/classification.h> +#include <odp/api/abi/packet_types.h> +#include <odp/api/abi/queue_types.h> + +#include <odp/api/spec/classification.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/comp.h b/include/odp/api/comp.h new file mode 100644 index 000000000..fa14d4631 --- /dev/null +++ b/include/odp/api/comp.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2018 Linaro Limited + */ + +/** + * @file + * + * ODP crypto + */ + +#ifndef ODP_API_COMP_H_ +#define ODP_API_COMP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/comp.h> + +#include <odp/api/spec/comp.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/cpu.h b/include/odp/api/cpu.h new file mode 100644 index 000000000..43729b5ab --- /dev/null +++ b/include/odp/api/cpu.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP CPU + */ + +#ifndef ODP_API_CPU_H_ +#define ODP_API_CPU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/cpu.h> + +/* Thread inline file implements cpu API function */ +#include <odp/api/thread.h> +#include <odp/api/spec/cpu.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/cpumask.h b/include/odp/api/cpumask.h new file mode 100644 index 000000000..662888288 --- /dev/null +++ b/include/odp/api/cpumask.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP CPU masks and enumeration + */ + +#ifndef ODP_API_CPUMASK_H_ +#define ODP_API_CPUMASK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/cpumask.h> + +#include <odp/api/spec/cpumask.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/crypto.h b/include/odp/api/crypto.h new file mode 100644 index 000000000..ce9d0f26a --- /dev/null +++ b/include/odp/api/crypto.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited + */ + +/** + * @file + * + * ODP crypto + */ + +#ifndef ODP_API_CRYPTO_H_ +#define ODP_API_CRYPTO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/crypto.h> + +#include <odp/api/spec/crypto.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/crypto_types.h b/include/odp/api/crypto_types.h new file mode 100644 index 000000000..922410c11 --- /dev/null +++ b/include/odp/api/crypto_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +/** + * @file + * + * ODP crypto + */ + +#ifndef ODP_API_CRYPTO_TYPES_H_ +#define ODP_API_CRYPTO_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/crypto_types.h> + +#include <odp/api/spec/crypto_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/debug.h b/include/odp/api/debug.h new file mode 100644 index 000000000..a9eccbc43 --- /dev/null +++ b/include/odp/api/debug.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP debug + */ + +#ifndef ODP_API_DEBUG_H_ +#define ODP_API_DEBUG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/debug.h> + +#include <odp/api/spec/debug.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/deprecated.h b/include/odp/api/deprecated.h new file mode 100644 index 000000000..afa2dd4e7 --- /dev/null +++ b/include/odp/api/deprecated.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + */ + +/** + * @file + * + * Control deprecated API definitions + */ + +#ifndef ODP_API_DEPRECATED_H_ +#define ODP_API_DEPRECATED_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spec/deprecated.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/dma.h b/include/odp/api/dma.h new file mode 100644 index 000000000..20f079859 --- /dev/null +++ b/include/odp/api/dma.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Nokia + */ + +/** + * @file + * + * ODP DMA + */ + +#ifndef ODP_API_DMA_H_ +#define ODP_API_DMA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/dma.h> + +#include <odp/api/spec/dma.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/dma_types.h b/include/odp/api/dma_types.h new file mode 100644 index 000000000..c6aedcd49 --- /dev/null +++ b/include/odp/api/dma_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021-2022 Nokia + */ + +/** + * @file + * + * ODP DMA + */ + +#ifndef ODP_API_DMA_TYPES_H_ +#define ODP_API_DMA_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/dma_types.h> + +#include <odp/api/spec/dma_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/errno.h b/include/odp/api/errno.h new file mode 100644 index 000000000..4b37dbf60 --- /dev/null +++ b/include/odp/api/errno.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP errno API + */ + +#ifndef ODP_API_ERRNO_H_ +#define ODP_API_ERRNO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/errno.h> + +#include <odp/api/spec/errno.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/event.h b/include/odp/api/event.h new file mode 100644 index 000000000..26fb9b97d --- /dev/null +++ b/include/odp/api/event.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP event + */ + +#ifndef ODP_API_EVENT_H_ +#define ODP_API_EVENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/event.h> + +#include <odp/api/spec/event.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/event_types.h b/include/odp/api/event_types.h new file mode 100644 index 000000000..8254583d7 --- /dev/null +++ b/include/odp/api/event_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +/** + * @file + * + * ODP event API type definitions + */ + +#ifndef ODP_API_EVENT_TYPES_H_ +#define ODP_API_EVENT_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/event_types.h> + +#include <odp/api/spec/event_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/hash.h b/include/odp/api/hash.h new file mode 100644 index 000000000..135fd2aef --- /dev/null +++ b/include/odp/api/hash.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP Hash function + */ + +#ifndef ODP_API_HASH_H_ +#define ODP_API_HASH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/hash.h> + +#include <odp/api/spec/hash.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/hints.h b/include/odp/api/hints.h new file mode 100644 index 000000000..bcd2780d1 --- /dev/null +++ b/include/odp/api/hints.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP compiler hints + */ + +#ifndef ODP_API_HINTS_H_ +#define ODP_API_HINTS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spec/hints.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/init.h b/include/odp/api/init.h new file mode 100644 index 000000000..259c6f765 --- /dev/null +++ b/include/odp/api/init.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP initialization. + */ + +#ifndef ODP_API_INIT_H_ +#define ODP_API_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/init.h> + +#include <odp/api/spec/init.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/ipsec.h b/include/odp/api/ipsec.h new file mode 100644 index 000000000..b61edaa6a --- /dev/null +++ b/include/odp/api/ipsec.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2016-2018 Linaro Limited + */ + +/** + * @file + * + * ODP IPSEC API - platform specific header + */ + +#ifndef ODP_API_IPSEC_H_ +#define ODP_API_IPSEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/ipsec.h> + +#include <odp/api/spec/ipsec.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/ipsec_types.h b/include/odp/api/ipsec_types.h new file mode 100644 index 000000000..ddbf04ed1 --- /dev/null +++ b/include/odp/api/ipsec_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +/** + * @file + * + * ODP IPsec + */ + +#ifndef ODP_API_IPSEC_TYPES_H_ +#define ODP_API_IPSEC_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/ipsec_types.h> + +#include <odp/api/spec/ipsec_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/ml.h b/include/odp/api/ml.h new file mode 100644 index 000000000..55213dd52 --- /dev/null +++ b/include/odp/api/ml.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Nokia + */ + +/** + * @file + * + * ODP Machine Learning (ML) offload + */ + +#ifndef ODP_API_ML_H_ +#define ODP_API_ML_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spec/ml.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/ml_quantize.h b/include/odp/api/ml_quantize.h new file mode 100644 index 000000000..cab2a3f22 --- /dev/null +++ b/include/odp/api/ml_quantize.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +/** + * @file + * + * ODP Machine Learning (ML) offload + */ + +#ifndef ODP_API_ML_QUANTIZE_H_ +#define ODP_API_ML_QUANTIZE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spec/ml_quantize.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/ml_types.h b/include/odp/api/ml_types.h new file mode 100644 index 000000000..3c3f8a416 --- /dev/null +++ b/include/odp/api/ml_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Nokia + */ + +/** + * @file + * + * ODP Machine Learning (ML) types + */ + +#ifndef ODP_API_ML_TYPES_H_ +#define ODP_API_ML_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/ml_types.h> + +#include <odp/api/spec/ml_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/packet.h b/include/odp/api/packet.h new file mode 100644 index 000000000..e5733595f --- /dev/null +++ b/include/odp/api/packet.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2022 Nokia + */ + +/** + * @file + * + * ODP packet descriptor + */ + +#ifndef ODP_API_PACKET_H_ +#define ODP_API_PACKET_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/packet.h> + +#include <odp/api/spec/packet.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/packet_flags.h b/include/odp/api/packet_flags.h new file mode 100644 index 000000000..15e085270 --- /dev/null +++ b/include/odp/api/packet_flags.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited + */ + +/** + * @file + * + * ODP packet flags + */ + +#ifndef ODP_API_PACKET_FLAGS_H_ +#define ODP_API_PACKET_FLAGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/packet_flags.h> + +#include <odp/api/spec/packet_flags.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h new file mode 100644 index 000000000..5f3e9d3e3 --- /dev/null +++ b/include/odp/api/packet_io.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP Packet IO + */ + +#ifndef ODP_API_PACKET_IO_H_ +#define ODP_API_PACKET_IO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/packet_io.h> + +#include <odp/api/spec/packet_io.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/packet_io_stats.h b/include/odp/api/packet_io_stats.h new file mode 100644 index 000000000..fa16ae290 --- /dev/null +++ b/include/odp/api/packet_io_stats.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2016-2018 Linaro Limited + */ + +/** + * @file + * + * ODP packet IO stats + */ + +#ifndef ODP_API_PACKET_IO_STATS_H_ +#define ODP_API_PACKET_IO_STATS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/packet_io_types.h> + +#include <odp/api/spec/packet_io_stats.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/packet_io_types.h b/include/odp/api/packet_io_types.h new file mode 100644 index 000000000..c5fd72e96 --- /dev/null +++ b/include/odp/api/packet_io_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +/** + * @file + * + * ODP Packet IO + */ + +#ifndef ODP_API_PACKET_IO_TYPES_H_ +#define ODP_API_PACKET_IO_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/packet_io_types.h> + +#include <odp/api/spec/packet_io_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/packet_types.h b/include/odp/api/packet_types.h new file mode 100644 index 000000000..647810259 --- /dev/null +++ b/include/odp/api/packet_types.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021-2022 Nokia + */ + +/** + * @file + * + * ODP packet + */ + +#ifndef ODP_API_PACKET_TYPES_H_ +#define ODP_API_PACKET_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/packet_io_types.h> +#include <odp/api/abi/packet_types.h> + +#include <odp/api/spec/packet_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/pool.h b/include/odp/api/pool.h new file mode 100644 index 000000000..0f4dfab27 --- /dev/null +++ b/include/odp/api/pool.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP pool + */ + +#ifndef ODP_API_POOL_H_ +#define ODP_API_POOL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/pool.h> + +#include <odp/api/spec/pool.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/pool_types.h b/include/odp/api/pool_types.h new file mode 100644 index 000000000..d2b88c332 --- /dev/null +++ b/include/odp/api/pool_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +/** + * @file + * + * ODP pool + */ + +#ifndef ODP_API_POOL_TYPES_H_ +#define ODP_API_POOL_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/pool_types.h> + +#include <odp/api/spec/pool_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/proto_stats.h b/include/odp/api/proto_stats.h new file mode 100644 index 000000000..2f16dfbf0 --- /dev/null +++ b/include/odp/api/proto_stats.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Marvell + */ + +/** + * @file + * + * ODP proto stats + */ + +#ifndef ODP_API_PROTO_STATS_H_ +#define ODP_API_PROTO_STATS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> +#include <odp/api/abi/queue.h> +#include <odp/api/abi/proto_stats_types.h> +#include <odp/api/abi/proto_stats.h> + +#include <odp/api/spec/proto_stats.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/proto_stats_types.h b/include/odp/api/proto_stats_types.h new file mode 100644 index 000000000..c6bae0842 --- /dev/null +++ b/include/odp/api/proto_stats_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Nokia + */ + +/** + * @file + * + * ODP proto stats types + */ + +#ifndef ODP_API_PROTO_STATS_TYPES_H_ +#define ODP_API_PROTO_STATS_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/proto_stats_types.h> + +#include <odp/api/spec/proto_stats_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/protocols.h b/include/odp/api/protocols.h new file mode 100644 index 000000000..232e96904 --- /dev/null +++ b/include/odp/api/protocols.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2020 Marvell + */ + +/** + * @file + * + * ODP protocols + */ + +#ifndef ODP_API_PROTOCOLS_H_ +#define ODP_API_PROTOCOLS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spec/protocols.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/queue.h b/include/odp/api/queue.h new file mode 100644 index 000000000..b3728f1ab --- /dev/null +++ b/include/odp/api/queue.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2022 Nokia + */ + +/** + * @file + * + * ODP queue + */ + +#ifndef ODP_API_QUEUE_H_ +#define ODP_API_QUEUE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/queue.h> + +#include <odp/api/spec/queue.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/queue_types.h b/include/odp/api/queue_types.h new file mode 100644 index 000000000..3aefdb3d0 --- /dev/null +++ b/include/odp/api/queue_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Nokia + */ + +/** + * @file + * + * ODP queue + */ + +#ifndef ODP_API_QUEUE_TYPES_H_ +#define ODP_API_QUEUE_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/queue_types.h> + +#include <odp/api/spec/queue_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/random.h b/include/odp/api/random.h new file mode 100644 index 000000000..27cd593b0 --- /dev/null +++ b/include/odp/api/random.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP random number API + */ + +#ifndef ODP_API_RANDOM_H_ +#define ODP_API_RANDOM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/random.h> + +#include <odp/api/spec/random.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/random_types.h b/include/odp/api/random_types.h new file mode 100644 index 000000000..2b90f61ee --- /dev/null +++ b/include/odp/api/random_types.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +/** + * @file + * + * ODP random number API + */ + +#ifndef ODP_API_RANDOM_TYPES_H_ +#define ODP_API_RANDOM_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spec/random_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/reassembly.h b/include/odp/api/reassembly.h new file mode 100644 index 000000000..2d52f6e15 --- /dev/null +++ b/include/odp/api/reassembly.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Marvell + */ + +/** + * @file + * + * ODP REASSEMBLY API - platform specific header + */ + +#ifndef ODP_API_REASSEMBLY_H_ +#define ODP_API_REASSEMBLY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spec/reassembly.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/rwlock.h b/include/odp/api/rwlock.h new file mode 100644 index 000000000..ca852a5be --- /dev/null +++ b/include/odp/api/rwlock.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited + */ + +/** + * @file + * + * ODP RW Locks + */ + +#ifndef ODP_API_RWLOCK_H_ +#define ODP_API_RWLOCK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/rwlock.h> + +#include <odp/api/spec/rwlock.h> + +#ifdef __cplusplus +} +#endif + +#endif /* ODP_RWLOCK_H_ */ diff --git a/include/odp/api/rwlock_recursive.h b/include/odp/api/rwlock_recursive.h new file mode 100644 index 000000000..288975476 --- /dev/null +++ b/include/odp/api/rwlock_recursive.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP recursive read/write lock + */ + +#ifndef ODP_API_RWLOCK_RECURSIVE_H_ +#define ODP_API_RWLOCK_RECURSIVE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/rwlock_recursive.h> + +#include <odp/api/spec/rwlock_recursive.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/schedule.h b/include/odp/api/schedule.h new file mode 100644 index 000000000..1a0e31276 --- /dev/null +++ b/include/odp/api/schedule.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP schedule + */ + +#ifndef ODP_API_SCHEDULE_H_ +#define ODP_API_SCHEDULE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/schedule.h> + +#include <odp/api/spec/schedule.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/schedule_types.h b/include/odp/api/schedule_types.h new file mode 100644 index 000000000..1b415b578 --- /dev/null +++ b/include/odp/api/schedule_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP schedule + */ + +#ifndef ODP_API_SCHEDULE_TYPES_H_ +#define ODP_API_SCHEDULE_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/schedule_types.h> + +#include <odp/api/spec/schedule_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/shared_memory.h b/include/odp/api/shared_memory.h new file mode 100644 index 000000000..a08f84cc4 --- /dev/null +++ b/include/odp/api/shared_memory.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP shared memory + */ + +#ifndef ODP_API_SHARED_MEMORY_H_ +#define ODP_API_SHARED_MEMORY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/shared_memory.h> + +#include <odp/api/spec/shared_memory.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/spec/.gitignore b/include/odp/api/spec/.gitignore index 67020331b..df9c87d90 100644 --- a/include/odp/api/spec/.gitignore +++ b/include/odp/api/spec/.gitignore @@ -1 +1,2 @@ +deprecated.h version.h diff --git a/include/odp/api/spec/align.h b/include/odp/api/spec/align.h index fdf8c29e1..d5e5910aa 100644 --- a/include/odp/api/spec/align.h +++ b/include/odp/api/spec/align.h @@ -1,18 +1,15 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited */ - /** * @file * * ODP alignments */ -#ifndef ODP_API_ALIGN_H_ -#define ODP_API_ALIGN_H_ +#ifndef ODP_API_SPEC_ALIGN_H_ +#define ODP_API_SPEC_ALIGN_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -49,12 +46,12 @@ extern "C" { /** * @def ODP_CACHE_LINE_SIZE - * Cache line size + * Cache line size in bytes */ /** * @def ODP_PAGE_SIZE - * Page size + * Page size in bytes */ /** @@ -68,6 +65,15 @@ extern "C" { */ /** + * @def ODP_CACHE_LINE_ROUNDUP + * Round up to cache line size + * + * Rounds up the passed value to the next multiple of cache line size + * (ODP_CACHE_LINE_SIZE). Returns the original value if it is already + * a multiple of cache line size or zero. + */ + +/** * @} */ diff --git a/include/odp/api/spec/atomic.h b/include/odp/api/spec/atomic.h index 408829df2..3a098ead1 100644 --- a/include/odp/api/spec/atomic.h +++ b/include/odp/api/spec/atomic.h @@ -1,7 +1,6 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2021 ARM Limited */ /** @@ -10,8 +9,8 @@ * ODP atomic operations */ -#ifndef ODP_API_ATOMIC_H_ -#define ODP_API_ATOMIC_H_ +#ifndef ODP_API_SPEC_ATOMIC_H_ +#define ODP_API_SPEC_ATOMIC_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -20,16 +19,18 @@ extern "C" { /** * @defgroup odp_atomic ODP ATOMIC + * Atomic variables. + * * @details * <b> Atomic integers using relaxed memory ordering </b> * - * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be used to - * implement e.g. shared counters. If not otherwise documented, operations in - * this API are implemented using <b> RELAXED memory ordering </b> (see memory - * order descriptions in the C11 specification). Relaxed operations do not - * provide synchronization or ordering for other memory accesses (initiated - * before or after the operation), only atomicity of the operation itself is - * guaranteed. + * Atomic integer types (odp_atomic_u32_t, odp_atomic_u64_t and + * odp_atomic_u128_t) can be used to implement e.g. shared counters. If not + * otherwise documented, operations in this API are implemented using + * <b> RELAXED memory ordering </b> (see memory order descriptions in + * the C11 specification). Relaxed operations do not provide synchronization or + * ordering for other memory accesses (initiated before or after the operation), + * only atomicity of the operation itself is guaranteed. * * <b> Operations with non-relaxed memory ordering </b> * @@ -52,6 +53,9 @@ extern "C" { */ /** + * @typedef odp_atomic_u128_t + * Atomic 128-bit unsigned integer + * * @typedef odp_atomic_u64_t * Atomic 64-bit unsigned integer * @@ -187,9 +191,10 @@ void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min); * Compare and swap atomic uint32 variable * * Compares value of atomic variable to the value pointed by 'old_val'. - * If values are equal, the operation writes 'new_val' into the atomic variable - * and returns success. If they are not equal, the operation writes current - * value of atomic variable into 'old_val' and returns failure. + * If the values are equal, the operation writes 'new_val' into the atomic variable + * and returns success. The operation returns failure only when the values are + * not equal (strong CAS operation). The current value of atomic variable is written + * into 'old_val' on failure. * * @param atom Pointer to atomic variable * @param[in,out] old_val Pointer to the old value of the atomic variable. @@ -197,10 +202,8 @@ void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min); * @param new_val New value to be written into the atomic variable * * @return 0 on failure, !0 on success - * */ -int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val, - uint32_t new_val); +int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val, uint32_t new_val); /** * Exchange value of atomic uint32 variable @@ -343,9 +346,10 @@ void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min); * Compare and swap atomic uint64 variable * * Compares value of atomic variable to the value pointed by 'old_val'. - * If values are equal, the operation writes 'new_val' into the atomic variable - * and returns success. If they are not equal, the operation writes current - * value of atomic variable into 'old_val' and returns failure. + * If the values are equal, the operation writes 'new_val' into the atomic variable + * and returns success. The operation returns failure only when the values are + * not equal (strong CAS operation). The current value of atomic variable is written + * into 'old_val' on failure. * * @param atom Pointer to atomic variable * @param[in,out] old_val Pointer to the old value of the atomic variable. @@ -354,8 +358,7 @@ void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min); * * @return 0 on failure, !0 on success */ -int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val, - uint64_t new_val); +int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val, uint64_t new_val); /** * Exchange value of atomic uint64 variable @@ -371,6 +374,58 @@ int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val, uint64_t odp_atomic_xchg_u64(odp_atomic_u64_t *atom, uint64_t new_val); /* + * 128-bit operations in RELAXED memory ordering + * -------------------------------------------- + */ + +/** + * Initialize atomic odp_u128_t variable + * + * Initializes the atomic variable with 'val'. This operation is not atomic. + * Application must ensure that there's no race condition while initializing + * the variable. + * + * @param atom Pointer to atomic variable + * @param val Value to initialize the variable with + */ +void odp_atomic_init_u128(odp_atomic_u128_t *atom, odp_u128_t val); + +/** + * Load value of atomic odp_u128_t variable + * + * @param atom Pointer to atomic variable + * + * @return Value of the variable + */ +odp_u128_t odp_atomic_load_u128(odp_atomic_u128_t *atom); + +/** + * Store value to atomic odp_u128_t variable + * + * @param atom Pointer to atomic variable + * @param val Value to store in the variable + */ +void odp_atomic_store_u128(odp_atomic_u128_t *atom, odp_u128_t val); + +/** + * Compare and swap atomic odp_u128_t variable + * + * Compares value of atomic variable to the value pointed by 'old_val'. + * If the values are equal, the operation writes 'new_val' into the atomic variable + * and returns success. The operation returns failure only when the values are + * not equal (strong CAS operation). The current value of atomic variable is written + * into 'old_val' on failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + */ +int odp_atomic_cas_u128(odp_atomic_u128_t *atom, odp_u128_t *old_val, odp_u128_t new_val); + +/* * 32-bit operations in non-RELAXED memory ordering * ------------------------------------------------ */ @@ -620,6 +675,80 @@ typedef union odp_atomic_op_t { */ int odp_atomic_lock_free_u64(odp_atomic_op_t *atomic_op); +/* + * 128-bit operations in non-RELAXED memory ordering + * ------------------------------------------------ + */ + +/** + * Compare and swap atomic odp_u128_t variable using ACQUIRE memory ordering + * + * Otherwise identical to odp_atomic_cas_u128() but ensures ACQUIRE memory + * ordering on success. Memory ordering is RELAXED on failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + */ +int odp_atomic_cas_acq_u128(odp_atomic_u128_t *atom, odp_u128_t *old_val, + odp_u128_t new_val); + +/** + * Compare and swap atomic odp_u128_t variable using RELEASE memory ordering + * + * Otherwise identical to odp_atomic_cas_u128() but ensures RELEASE memory + * ordering on success. Memory ordering is RELAXED on failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + */ +int odp_atomic_cas_rel_u128(odp_atomic_u128_t *atom, odp_u128_t *old_val, + odp_u128_t new_val); + +/** + * Compare and swap atomic odp_u128_t variable using ACQUIRE-and-RELEASE memory + * ordering + * + * Otherwise identical to odp_atomic_cas_u128() but ensures ACQUIRE-and-RELEASE + * memory ordering on success. Memory ordering is RELAXED on failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + */ +int odp_atomic_cas_acq_rel_u128(odp_atomic_u128_t *atom, odp_u128_t *old_val, + odp_u128_t new_val); + +/** + * Query which atomic odp_atomic_u128_t operations are lock-free + * + * Lock-free implementations have higher performance and scale better than + * implementations using locks. + * + * Init operations (e.g. odp_atomic_init_u128()) are not atomic. This function + * clears the op.init bit but will never set it to one. + * + * Note: 128-bit atomic API includes only init, load, store and CAS operations. + * + * @param atomic_op Pointer to atomic operation structure for storing + * operation flags. All bits are initialized to zero during + * the operation. The parameter is ignored when NULL. + * @retval 0 None of the 128-bit atomic operations are lock-free + * @retval 1 Some of the 128-bit atomic operations are lock-free + * @retval 2 All 128-bit atomic operations are lock-free + */ +int odp_atomic_lock_free_u128(odp_atomic_op_t *atomic_op); + /** * @} */ diff --git a/include/odp/api/spec/barrier.h b/include/odp/api/spec/barrier.h index 6de683c73..e83d46c35 100644 --- a/include/odp/api/spec/barrier.h +++ b/include/odp/api/spec/barrier.h @@ -1,7 +1,5 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited */ /** @@ -10,8 +8,8 @@ * ODP execution barriers */ -#ifndef ODP_API_BARRIER_H_ -#define ODP_API_BARRIER_H_ +#ifndef ODP_API_SPEC_BARRIER_H_ +#define ODP_API_SPEC_BARRIER_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus diff --git a/include/odp/api/spec/buffer.h b/include/odp/api/spec/buffer.h index 94829b324..5ce2355b8 100644 --- a/include/odp/api/spec/buffer.h +++ b/include/odp/api/spec/buffer.h @@ -1,37 +1,30 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2022-2023 Nokia */ - /** * @file * - * ODP buffer descriptor + * ODP buffer */ -#ifndef ODP_API_BUFFER_H_ -#define ODP_API_BUFFER_H_ +#ifndef ODP_API_SPEC_BUFFER_H_ +#define ODP_API_SPEC_BUFFER_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif -/** @defgroup odp_buffer ODP BUFFER - * Operations on a buffer. - * @{ - */ +#include <odp/api/buffer_types.h> +#include <odp/api/event_types.h> +#include <odp/api/pool_types.h> +#include <odp/api/std_types.h> -/** - * @typedef odp_buffer_t - * ODP buffer - */ - -/** - * @def ODP_BUFFER_INVALID - * Invalid buffer +/** @addtogroup odp_buffer + * Buffer event metadata and operations. + * @{ */ /** @@ -48,6 +41,17 @@ extern "C" { odp_buffer_t odp_buffer_from_event(odp_event_t ev); /** + * Convert multiple buffer events to buffer handles + * + * All events must be of type ODP_EVENT_BUFFER. + * + * @param[out] buf Buffer handle array for output + * @param ev Array of event handles to convert + * @param num Number of buffers and events + */ +void odp_buffer_from_event_multi(odp_buffer_t buf[], const odp_event_t ev[], int num); + +/** * Convert buffer handle to event * * @param buf Buffer handle @@ -57,6 +61,15 @@ odp_buffer_t odp_buffer_from_event(odp_event_t ev); odp_event_t odp_buffer_to_event(odp_buffer_t buf); /** + * Convert multiple buffer handles to events + * + * @param buf Array of buffer handles to convert + * @param[out] ev Event handle array for output + * @param num Number of buffers and events + */ +void odp_buffer_to_event_multi(const odp_buffer_t buf[], odp_event_t ev[], int num); + +/** * Buffer start address * * @param buf Buffer handle @@ -75,7 +88,24 @@ void *odp_buffer_addr(odp_buffer_t buf); uint32_t odp_buffer_size(odp_buffer_t buf); /** - * Tests if buffer is valid + * Buffer user area + * + * Returns pointer to the user area associated with the buffer. Size of the area is fixed + * and defined in buffer pool parameters. + * + * @param buf Buffer handle + * + * @return Pointer to the user area of the buffer + * @retval NULL The buffer does not have user area + */ +void *odp_buffer_user_area(odp_buffer_t buf); + +/** + * Check that buffer is valid + * + * This function can be used for debugging purposes to check if a buffer handle represents + * a valid buffer. The level of error checks depends on the implementation. The call should not + * crash if the buffer handle is corrupted. * * @param buf Buffer handle * @@ -96,8 +126,8 @@ odp_pool_t odp_buffer_pool(odp_buffer_t buf); /** * Buffer alloc * - * The validity of a buffer can be checked at any time with - * odp_buffer_is_valid(). + * Allocates a buffer from the pool. Returns ODP_BUFFER_INVALID when a buffer + * can not be allocated. * * @param pool Pool handle * @@ -108,8 +138,8 @@ odp_buffer_t odp_buffer_alloc(odp_pool_t pool); /** * Allocate multiple buffers - - * Otherwise like odp_buffer_alloc(), but allocates multiple buffers from a pool + * + * Otherwise like odp_buffer_alloc(), but allocates multiple buffers from a pool. * * @param pool Pool handle * @param[out] buf Array of buffer handles for output diff --git a/include/odp/api/spec/buffer_types.h b/include/odp/api/spec/buffer_types.h new file mode 100644 index 000000000..7307e72f7 --- /dev/null +++ b/include/odp/api/spec/buffer_types.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2023 Nokia + */ + +/** + * @file + * + * ODP buffer types + */ + +#ifndef ODP_API_SPEC_BUFFER_TYPES_H_ +#define ODP_API_SPEC_BUFFER_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup odp_buffer ODP BUFFER + * @{ + */ + +/** + * @typedef odp_buffer_t + * ODP buffer + */ + +/** + * @def ODP_BUFFER_INVALID + * Invalid buffer + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/byteorder.h b/include/odp/api/spec/byteorder.h index 38c0bdbf7..65d2e722a 100644 --- a/include/odp/api/spec/byteorder.h +++ b/include/odp/api/spec/byteorder.h @@ -1,7 +1,5 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited */ /** @@ -10,8 +8,8 @@ * ODP byteorder */ -#ifndef ODP_API_BYTEORDER_H_ -#define ODP_API_BYTEORDER_H_ +#ifndef ODP_API_SPEC_BYTEORDER_H_ +#define ODP_API_SPEC_BYTEORDER_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus diff --git a/include/odp/api/spec/chksum.h b/include/odp/api/spec/chksum.h new file mode 100644 index 000000000..800aab2c2 --- /dev/null +++ b/include/odp/api/spec/chksum.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + */ + +/** + * @file + * + * ODP checksum functions. + */ + +#ifndef ODP_API_SPEC_CHKSUM_H_ +#define ODP_API_SPEC_CHKSUM_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +/** @defgroup odp_chksum ODP CHECKSUM + * Checksum functions. + * @{ + */ + +/** + * Ones' complement sum of 16-bit words + * + * Calculates 16-bit ones' complement sum over the data. In case of odd number + * of bytes, calculation uses a zero byte as padding at the end. This algorithm + * may be used as part of e.g. IPv4/UDP/TCP checksum generation and checking. + * + * @param data Pointer to data. Data address must be 16-bit aligned + * in minimum. + * @param data_len Data length in bytes. In case of an odd number, calculation + * includes one byte of padding. + * + * @return Ones' complement sum + */ +uint16_t odp_chksum_ones_comp16(const void *data, uint32_t data_len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/classification.h b/include/odp/api/spec/classification.h index 0e1addd6e..518b2bd3c 100644 --- a/include/odp/api/spec/classification.h +++ b/include/odp/api/spec/classification.h @@ -1,58 +1,198 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited + * Copyright (c) 2021-2023 Nokia */ - /** * @file * * ODP classification descriptor */ -#ifndef ODP_API_CLASSIFY_H_ -#define ODP_API_CLASSIFY_H_ +#ifndef ODP_API_SPEC_CLASSIFICATION_H_ +#define ODP_API_SPEC_CLASSIFICATION_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif +#include <odp/api/packet_io_types.h> +#include <odp/api/pool_types.h> +#include <odp/api/std_types.h> +#include <odp/api/threshold.h> + /** @defgroup odp_classification ODP CLASSIFICATION - * Classification operations. + * Packet input classification. * @{ */ +/** + * @typedef odp_pmr_t + * Packet matching rule handle + */ /** - * @typedef odp_cos_t - * ODP Class of service handle + * @def ODP_PMR_INVALID + * Invalid packet matching rule handle */ /** - * @typedef odp_flowsig_t - * flow signature type, only used for packet metadata field. + * @typedef odp_cos_t + * Class of service handle */ /** * @def ODP_COS_INVALID - * This value is returned from odp_cls_cos_create() on failure, - * May also be used as a sink class of service that - * results in packets being discarded. + * Invalid class of service handle */ /** * @def ODP_COS_NAME_LEN - * Maximum ClassOfService name length in chars including null char + * Maximum class of service name length in chars including null char */ /** - * @def ODP_PMR_INVAL - * Invalid odp_pmr_t value. - * This value is returned from odp_cls_pmr_create() - * function on failure. + * Packet Matching Rule terms + * + * This enumeration selects the protocol field that is matched against PMR + * value/mask or value range. Protocol field values and masks are passed in big + * endian (network endian) format. However, ODP_PMR_LEN value and range are + * passed in CPU native endian (uint32_t words), as the term does not represent + * a protocol field. + * + * PMR value/mask data size is term specific. This size must be set into val_sz + * field of odp_pmr_param_t. There is no alignment requirement for PMR + * value/mask data. */ +typedef enum { + /** Total length of received packet. Exceptionally, value and mask are + * uint32_t (val_sz = 4) in CPU endian. */ + ODP_PMR_LEN, + + /** Initial (outer) Ethertype only (val_sz = 2) + * + * PMR matches Ethertype field when packet does not have VLAN headers. When there are + * VLAN headers, it matches Tag protocol identifier (TPID) field of the first VLAN header. + * I.e. it matches a field in the same offset from the start of the packet in both cases. + */ + ODP_PMR_ETHTYPE_0, + + /** Ethertype of most inner VLAN tag (val_sz = 2) */ + ODP_PMR_ETHTYPE_X, + + /** First (outer) VLAN ID (val_sz = 2) + * + * VLAN ID value and mask are stored into 12 least significant bits of a 16-bit word. + * The word is passed in big endian format. + */ + ODP_PMR_VLAN_ID_0, + + /** Last (most inner) VLAN ID (val_sz = 2) + * + * VLAN ID value and mask are stored into 12 least significant bits of a 16-bit word. + * The word is passed in big endian format. + */ + ODP_PMR_VLAN_ID_X, + + /** PCP bits in the first (outer) VLAN header (val_sz = 1) + * + * Priority Code Point (PCP) value is stored into three least significant bits of + * the octet pointed by odp_pmr_param_t::value. The same applies for odp_pmr_param_t::mask. + */ + ODP_PMR_VLAN_PCP_0, + + /** Destination MAC address (val_sz = 6) */ + ODP_PMR_DMAC, + + /** IPv4 Protocol or IPv6 Next Header (val_sz = 1) */ + ODP_PMR_IPPROTO, + + /** Differentiated Services Code Point (DSCP) bits in IPv4 or IPv6 header (val_sz = 1) + * + * DSCP value is stored into six least significant bits of the octet pointed by + * odp_pmr_param_t::value. The same applies for odp_pmr_param_t::mask. + */ + ODP_PMR_IP_DSCP, + + /** Destination UDP port (val_sz = 2) */ + ODP_PMR_UDP_DPORT, + + /** Destination TCP port (val_sz = 2) */ + ODP_PMR_TCP_DPORT, + + /** Source UDP port (val_sz = 2) */ + ODP_PMR_UDP_SPORT, + + /** Source TCP port (val_sz = 2) */ + ODP_PMR_TCP_SPORT, + + /** Source IPv4 address (val_sz = 4) */ + ODP_PMR_SIP_ADDR, + + /** Destination IPv4 address (val_sz = 4) */ + ODP_PMR_DIP_ADDR, + + /** Source IPv6 address (val_sz = 16) */ + ODP_PMR_SIP6_ADDR, + + /** Destination IPv6 address (val_sz = 16) */ + ODP_PMR_DIP6_ADDR, + + /** IPsec session identifier (val_sz = 4)*/ + ODP_PMR_IPSEC_SPI, + + /** NVGRE/VXLAN network identifier (val_sz = 4) */ + ODP_PMR_LD_VNI, + + /** + * Custom frame match rule + * + * PMR offset is counted from the start of the packet. The match is + * defined by the offset, the expected value, and its size. Custom frame + * rules must be applied before any other PMR. + */ + ODP_PMR_CUSTOM_FRAME, + + /** + * Custom layer 3 match rule + * + * PMR offset is counted from the start of layer 3 in the packet. + * The match is defined by the offset, the expected value, and its size. + * Custom L3 rules may be combined with other PMRs. + */ + ODP_PMR_CUSTOM_L3, + + /** IGMP Group address (val_sz = 4), implies IPPROTO=2 */ + ODP_PMR_IGMP_GRP_ADDR, + + /** ICMP identifier (val_sz = 2), implies IPPROTO=1 and ICMP_TYPE=0 or ICMP_TYPE=8 */ + ODP_PMR_ICMP_ID, + + /** ICMP type (val_sz = 1), implies IPPROTO=1 */ + ODP_PMR_ICMP_TYPE, + + /** ICMP code (val_sz = 1), implies IPPROTO=1 */ + ODP_PMR_ICMP_CODE, + + /** Source SCTP port (val_sz = 2), implies IPPROTO=132 */ + ODP_PMR_SCTP_SPORT, + + /** Destination SCTP port (val_sz = 2), implies IPPROTO=132 */ + ODP_PMR_SCTP_DPORT, + + /** GTPv1 tunnel endpoint identifier (val_sz = 4) + * + * Matches if and only if IP protocol is UDP, UDP destination port + * is 2152 and the UDP payload interpreted as GTP header has GTP + * version 1 and TEID as specified. + */ + ODP_PMR_GTPV1_TEID, + + /** Inner header may repeat above values with this offset */ + ODP_PMR_INNER_HDR_OFF = 32 + +} odp_cls_pmr_term_t; /** * Supported PMR term values @@ -72,10 +212,14 @@ typedef union odp_cls_pmr_terms_t { uint64_t vlan_id_0:1; /** Last VLAN ID (inner) */ uint64_t vlan_id_x:1; + /** PCP in the first VLAN header (#ODP_PMR_VLAN_PCP_0) */ + uint64_t vlan_pcp_0:1; /** destination MAC address */ uint64_t dmac:1; /** IP Protocol or IPv6 Next Header */ uint64_t ip_proto:1; + /** DSCP in IP header (#ODP_PMR_IP_DSCP) */ + uint64_t ip_dscp:1; /** Destination UDP port, implies IPPROTO=17 */ uint64_t udp_dport:1; /** Destination TCP port implies IPPROTO=6 */ @@ -96,77 +240,451 @@ typedef union odp_cls_pmr_terms_t { uint64_t ipsec_spi:1; /** NVGRE/VXLAN network identifier */ uint64_t ld_vni:1; - /** Custom match rule, offset from start of - * frame. The match is defined by the offset, the - * expected value, and its size. - */ - uint64_t custom_frame:1; - + /** Custom frame match rule. PMR offset is counted from + * the start of the packet. */ + uint64_t custom_frame:1; + /** Custom layer 3 match rule. PMR offset is counted from + * the start of layer 3 in the packet. */ + uint64_t custom_l3:1; + /** IGMP Group address, implies IPPROTO=2 */ + uint64_t igmp_grp_addr:1; + /** ICMP identifier, implies IPPROTO=1 and ICMP_TYPE=0 or ICMP_TYPE=8 */ + uint64_t icmp_id:1; + /** ICMP type, implies IPPROTO=1 */ + uint64_t icmp_type:1; + /** ICMP code, implies IPPROTO=1 */ + uint64_t icmp_code:1; + /** Source SCTP port, implies IPPROTO=132 */ + uint64_t sctp_sport:1; + /** Destination SCTP port, implies IPPROTO=132 */ + uint64_t sctp_dport:1; + /** GTPv1 tunnel endpoint identifier */ + uint64_t gtpv1_teid:1; } bit; + /** All bits of the bit field structure */ uint64_t all_bits; + } odp_cls_pmr_terms_t; /** + * Packet Matching Rule parameter structure + * + * Match value/mask size and endianness are defined in PMR term documentation + * (see odp_cls_pmr_term_t). Most values and masks are passed in big + * endian format without data alignment requirement. ODP_PMR_LEN is + * an exception to this (uint32_t in CPU endian). + */ +typedef struct odp_pmr_param_t { + /** Packet Matching Rule term */ + odp_cls_pmr_term_t term; + + /** True if the value is range and false if match. Default is false. */ + odp_bool_t range_term; + + /** Variant mappings for types of matches */ + union { + /** Parameters for single-valued matches */ + struct { + /** Points to the value to be matched. Value size and + * endianness are defined by the term used. Values of + * protocol fields are defined in big endian format. + */ + const void *value; + + /** Mask of the bits to be matched. The same size and + * endianness is used than with the value. */ + const void *mask; + } match; + + /** Parameter for range value matches */ + struct { + /** Start value of the range */ + const void *val_start; + + /** End value of the range */ + const void *val_end; + } range; + }; + + /** Size of the value to be matched */ + uint32_t val_sz; + + /** Offset to the value + * + * Byte offset to the value to be matched in a packet. PMR term defines + * starting point for the offset. Used only with custom PMR terms, + * ignored with other terms. + */ + uint32_t offset; + +} odp_pmr_param_t; + +/** + * Packet Matching Rule creation options + */ +typedef struct odp_pmr_create_opt_t { + /** PMR terms + * + * Array of odp_pmr_param_t entries, one entry per term desired. + * Use odp_cls_pmr_param_init() to initialize parameters into their default values. + */ + odp_pmr_param_t *terms; + + /** Number of terms in the match rule. */ + int num_terms; + + /** Classification mark value + * + * Value to be set in the CLS mark of a packet when the packet matches this + * Packet Matching Rule. The default value is zero. The maximum value is indicated in + * odp_cls_capability_t::max_mark capability. + */ + uint64_t mark; + +} odp_pmr_create_opt_t; + +/** Random Early Detection (RED) + * Random Early Detection is enabled to initiate a drop probability for the + * incoming packet when the packets in the queue/pool cross the specified + * threshold values. RED is enabled when 'red_enable' boolean is true and + * the resource usage is equal to or greater than the minimum threshold value. + * Resource usage could be defined either as the percentage of pool being full + * or the number of packets/bytes occupied in the queue depending on the + * platform capabilities. + * + * When RED is enabled for a particular flow then further incoming packets are + * assigned a drop probability based on the size of the pool/queue. + * + * Drop probability is configured as follows + * * Drop probability is 100%, when resource usage >= threshold.max + * * Drop probability is 0%, when resource usage <= threshold.min + * * Drop probability is between 0...100 % when resource usage is between + * threshold.min and threshold.max + * + * RED is logically configured in the CoS and could be implemented in either + * pool or queue linked to the CoS depending on platform capabilities. + * Application should make sure not to link multiple CoS with different RED or + * BP configuration to the same queue or pool. + */ +typedef struct odp_red_param_t { + /** A boolean to enable RED + * When true, RED is enabled and configured with RED parameters. + * Otherwise, RED parameters are ignored. Default value is false. + */ + odp_bool_t enable; + + /** Threshold parameters for RED + * RED is enabled when the resource usage is equal to or greater than + * the minimum threshold value and is disabled otherwise + */ + odp_threshold_t threshold; + +} odp_red_param_t; + +/** Back pressure (BP) + * When back pressure is enabled for a particular flow, the HW can send + * back pressure information to the remote peer indicating a network congestion. + */ +typedef struct odp_bp_param_t { + /** A boolean to enable Back pressure + * When true, back pressure is enabled and configured with the BP + * parameters. Otherwise BP parameters are ignored. Default value + * is false. + */ + odp_bool_t enable; + + /** Threshold value for back pressure. + * BP is enabled when the resource usage is equal to or greater than the + * max backpressure threshold. Min threshold parameters are ignored for + * BP configuration. + * @see odp_red_param_t for 'resource usage' documentation. + */ + odp_threshold_t threshold; + + /** + * PFC priority level + * + * When enabled (#ODP_PKTIO_LINK_PFC_ON), PFC frames are generated when the above + * threshold is exceeded. The generated frames request the receiver to temporary halt + * transmission of traffic on this priority level (0 .. 7). + */ + uint8_t pfc_level; + +} odp_bp_param_t; + +/** + * Classifier CoS specific statistics counters + * + * Counters are incremented per packet classified to the CoS. In a CoS chain, + * counters are incremented in every CoS for which counters are enabled. + */ +typedef struct odp_cls_cos_stats_t { + /** Number of octets in classified packets. In case of Ethernet, packet + * size includes MAC header. */ + uint64_t octets; + + /** Number of classified packets, including packets dropped due to drop + * action. */ + uint64_t packets; + + /** Number of discarded packets due to other reasons than packet + * errors or drop action. */ + uint64_t discards; + + /** Number of packets with errors. */ + uint64_t errors; + +} odp_cls_cos_stats_t; + +/** + * Classifier queue specific statistics counters + * + * Counters are incremented per packet destined to the queue per originating + * CoS. Note that a single queue can be a destination for multiple CoS's. + */ +typedef struct odp_cls_queue_stats_t { + /** Number of octets in successfully delivered packets. In case of + * Ethernet, packet size includes MAC header. */ + uint64_t octets; + + /** Number of successfully delivered packets. */ + uint64_t packets; + + /** Number of discarded packets due to other reasons (e.g. RED) than + * errors. */ + uint64_t discards; + + /** Number of packets with errors. Depending on packet input + * configuration, packets with errors may be dropped or not. */ + uint64_t errors; + +} odp_cls_queue_stats_t; + +/** + * Classifier statistics capabilities + */ +typedef struct odp_cls_stats_capability_t { + /** CoS level capabilities */ + struct { + /** Supported counters */ + union { + /** Statistics counters in a bit field structure */ + struct { + /** See odp_cls_cos_stats_t::octets */ + uint64_t octets : 1; + + /** See odp_cls_cos_stats_t::packets */ + uint64_t packets : 1; + + /** See odp_cls_cos_stats_t::discards */ + uint64_t discards : 1; + + /** See odp_cls_cos_stats_t::errors */ + uint64_t errors : 1; + + } counter; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or + * for bitwise operations over the entire structure. */ + uint64_t all_counters; + }; + } cos; + + /** Queue level capabilities */ + struct { + /** Supported counters */ + union { + /** Statistics counters in a bit field structure */ + struct { + /** See odp_cls_queue_stats_t::octets */ + uint64_t octets : 1; + + /** See odp_cls_queue_stats_t::packets */ + uint64_t packets : 1; + + /** See odp_cls_queue_stats_t::discards */ + uint64_t discards : 1; + + /** See odp_cls_queue_stats_t::errors */ + uint64_t errors : 1; + + } counter; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or + * for bitwise operations over the entire structure. */ + uint64_t all_counters; + }; + } queue; + +} odp_cls_stats_capability_t; + +/** * Classification capabilities * This capability structure defines system level classification capability */ typedef struct odp_cls_capability_t { /** PMR terms supported by the classifier - * A bit mask of one bit for each of odp_pmr_term_t - */ + * + * A bit mask of one bit for each of odp_pmr_term_t. */ odp_cls_pmr_terms_t supported_terms; - /** Maximum number of PMR terms */ - unsigned max_pmr_terms; + /** Maximum number of single-term PMRs + * + * Depending on the implementation, using several/composite terms for a + * single PMR may end up incurring more than one PMR element from this + * total capacity. */ + uint32_t max_pmr; + + /** Maximum number of PMRs per CoS */ + uint32_t max_pmr_per_cos; - /** Number of PMR terms available for use now */ - unsigned available_pmr_terms; + /** Maximum number of terms per composite PMR */ + uint32_t max_terms_per_pmr; /** Maximum number of CoS supported */ - unsigned max_cos; + uint32_t max_cos; + + /** Maximum number of concurrent CoS stats + * + * Maximum number of CoSes that can have statistics enabled at the same + * time. If this value is zero, then CoS level statistics are not + * supported. */ + uint32_t max_cos_stats; + + /** Maximum number of queues supported per CoS + * + * If the value is 1, then hashing is not supported. */ + uint32_t max_hash_queues; + + /** Protocol header combination supported for Hashing */ + odp_pktin_hash_proto_t hash_protocols; /** A Boolean to denote support of PMR range */ odp_bool_t pmr_range_supported; + + /** Support for Random Early Detection */ + odp_support_t random_early_detection; + + /** Supported threshold type for RED */ + odp_threshold_types_t threshold_red; + + /** Support for Back Pressure to the remote peer */ + odp_support_t back_pressure; + + /** Supported threshold type for BP */ + odp_threshold_types_t threshold_bp; + + /** Maximum value of odp_pmr_create_opt_t::mark */ + uint64_t max_mark; + + /** Statistics counters capabilities */ + odp_cls_stats_capability_t stats; + } odp_cls_capability_t; /** - * class of service packet drop policies + * Enumeration of actions for CoS. */ typedef enum { - ODP_COS_DROP_POOL, /**< Follow buffer pool drop policy */ - ODP_COS_DROP_NEVER, /**< Never drop, ignoring buffer pool policy */ -} odp_cls_drop_t; + /** + * Enqueue packet + * + * Packets that arrive in the CoS are enqueued to a destination queue. + */ + ODP_COS_ACTION_ENQUEUE, -/** - * Packet header field enumeration - * for fields that may be used to calculate - * the flow signature, if present in a packet. - */ -typedef enum { - ODP_COS_FHDR_IN_PKTIO, /**< Ingress port number */ - ODP_COS_FHDR_L2_SAP, /**< Ethernet Source MAC address */ - ODP_COS_FHDR_L2_DAP, /**< Ethernet Destination MAC address */ - ODP_COS_FHDR_L2_VID, /**< Ethernet VLAN ID */ - ODP_COS_FHDR_L3_FLOW, /**< IPv6 flow_id */ - ODP_COS_FHDR_L3_SAP, /**< IP source address */ - ODP_COS_FHDR_L3_DAP, /**< IP destination address */ - ODP_COS_FHDR_L4_PROTO, /**< IP protocol (e.g. TCP/UDP/ICMP) */ - ODP_COS_FHDR_L4_SAP, /**< Transport source port */ - ODP_COS_FHDR_L4_DAP, /**< Transport destination port */ - ODP_COS_FHDR_IPSEC_SPI, /**< IPsec session identifier */ - ODP_COS_FHDR_LD_VNI, /**< NVGRE/VXLAN network identifier */ - ODP_COS_FHDR_USER /**< Application-specific header field(s) */ -} odp_cos_hdr_flow_fields_t; + /** + * Drop packet + * + * Packets that arrive in the CoS are dropped. Packets are freed into + * their originating pool. + */ + ODP_COS_ACTION_DROP, + +} odp_cos_action_t; /** * Class of service parameters * Used to communicate class of service creation options */ typedef struct odp_cls_cos_param { - odp_queue_t queue; /**< Queue associated with CoS */ - odp_pool_t pool; /**< Pool associated with CoS */ - odp_cls_drop_t drop_policy; /**< Drop policy associated with CoS */ + /** Action to take. When action is ODP_COS_ACTION_DROP, all the other + * parameters are ignored. If action is ODP_COS_ACTION_ENQUEUE, then + * queue must be set, or num_queue must be greater than one. + * + * The final match in the CoS chain defines the action for a packet. + * I.e. packet is dropped only when the CoS of the last matching rule + * has drop action. Actions in the previous CoSes in the chain are + * ignored. + * + * Default is ODP_COS_ACTION_ENQUEUE. + */ + odp_cos_action_t action; + + /** Enable statistics. If true, counters are incremented when packets + * are classified to the CoS. Default is false. + * + * @see odp_cls_cos_stats() + */ + odp_bool_t stats_enable; + + /** Number of queues to be linked to this CoS. + * If the number is greater than 1 then hashing is enabled. + * If number is equal to 1 then hashing is disabled. + * When hashing is enabled the queues are created by the implementation + * and application need not configure any queue to the class of service. + * When hashing is disabled application has to configure the queue to + * the class of service. + * Depending on the implementation this number might be rounded-off to + * nearest supported value (e.g power of 2) + * + * Default value is 1. + */ + uint32_t num_queue; + + /** Variant mapping for queue hash configuration */ + union { + /** Mapping used when num_queue = 1, hashing is disabled in + * this case and application has to configure this queue and + * packets are delivered to this queue */ + odp_queue_t queue; + + /** Mapping used when num_queue > 1, hashing is enabled in + * this case and queues are created by the implementation */ + struct { + /** Queue parameters */ + odp_queue_param_t queue_param; + + /** Protocol header fields which are included in + * packet input hash calculation */ + odp_pktin_hash_proto_t hash_proto; + }; + }; + /** Pool associated with CoS + * + * May be set to ODP_POOL_INVALID, in which case the default pool of + * the originating packet input is used (see odp_pktio_open()). If + * there is no originating packet input (e.g. with lookaside IPsec), + * then this parameter must be set to a valid pool. + * + * Default is ODP_POOL_INVALID. + */ + odp_pool_t pool; + + /** Random Early Detection configuration */ + odp_red_param_t red; + + /** Back Pressure configuration */ + odp_bp_param_t bp; + + /** Packet input vector configuration */ + odp_pktin_vector_config_t vector; + } odp_cls_cos_param_t; /** @@ -174,7 +692,7 @@ typedef struct odp_cls_cos_param { * * Initialize an odp_cls_cos_param_t to its default value for all fields * - * @param param Address of the odp_cls_cos_param_t to be initialized + * @param param Address of the odp_cls_cos_param_t to be initialized */ void odp_cls_cos_param_init(odp_cls_cos_param_t *param); @@ -183,315 +701,376 @@ void odp_cls_cos_param_init(odp_cls_cos_param_t *param); * * Outputs classification capabilities on success. * - * @param[out] capability Pointer to classification capability structure. + * @param[out] capability Pointer to classification capability structure. * - * @retval 0 on success - * @retval <0 on failure + * @retval 0 on success + * @retval <0 on failure */ int odp_cls_capability(odp_cls_capability_t *capability); /** * Create a class-of-service * + * Depending on the action parameter, packets to the CoS are either enqueued to + * a destination queue, or dropped. + * * The use of class-of-service name is optional. Unique names are not required. + * Use odp_cls_cos_param_init() to initialize parameters into their default + * values. + * + * @param name Name of the class-of-service or NULL. Maximum string + * length is ODP_COS_NAME_LEN. + * @param param Class-of-service parameters * - * @param name Name of the class-of-service or NULL. Maximum string - * length is ODP_COS_NAME_LEN. - * @param param Class-of-service parameters + * @retval Class-of-service handle + * @retval ODP_COS_INVALID on failure. + */ +odp_cos_t odp_cls_cos_create(const char *name, + const odp_cls_cos_param_t *param); + +/** + * Create multiple class-of-services * - * @retval Class-of-service handle - * @retval ODP_COS_INVALID on failure. + * Otherwise like odp_cls_cos_create(), but creates multiple CoSes with a + * single call. The output CoS handles are written in the same order as input + * parameters. A single odp_cls_cos_create_multi() call is equivalent to calling + * odp_cls_cos_create() 'num' times in row. * - * @note ODP_QUEUE_INVALID and ODP_POOL_INVALID are valid values for queue - * and pool associated with a class of service and when any one of these values - * are configured as INVALID then the packets assigned to the CoS gets dropped. + * Each parameter array must contain 'num' elements with the exception that + * 'name' array may also be NULL. + * + * @param name Array of CoS name pointers or NULL. NULL is also valid + * CoS name pointer value. + * @param param Array of CoS parameters + * @param[out] cos Array of CoS handles for output + * @param num Number of CoSes to create + * + * @return Number of CoSes actually created (0 ... num) + * @retval <0 on failure */ -odp_cos_t odp_cls_cos_create(const char *name, odp_cls_cos_param_t *param); +int odp_cls_cos_create_multi(const char *name[], + const odp_cls_cos_param_t param[], + odp_cos_t cos[], int num); /** - * Discard a class-of-service along with all its associated resources + * Queue hash result + * Returns the queue within a CoS in which a particular packet will be enqueued + * based on the packet parameters and hash protocol field configured with the + * class of service. * - * @param[in] cos_id class-of-service instance. + * @param cos CoS handle + * @param packet Packet handle * - * @retval 0 on success - * @retval <0 on failure + * @retval Returns the queue handle on which this packet will be enqueued. + * @retval ODP_QUEUE_INVALID for error case + * + * @note The packet has to be updated with valid header pointers L2, L3 and L4. */ -int odp_cos_destroy(odp_cos_t cos_id); +odp_queue_t odp_cls_hash_result(odp_cos_t cos, odp_packet_t packet); /** - * Assign a queue for a class-of-service + * Discard a class-of-service along with all its associated resources * - * @param[in] cos_id class-of-service instance. + * Before destroying a CoS, all the PMRs referring to the CoS (as a source or + * destination CoS) must be destroyed first. Also, the CoS must not be in use + * as the default CoS in any pktio (see odp_pktio_default_cos_set()) or as the + * destination CoS of any IPsec SA. * - * @param[in] queue_id Identifier of a queue where all packets - * of this specific class of service - * will be enqueued. + * @param cos CoS handle * - * @retval 0 on success - * @retval <0 on failure + * @retval 0 on success + * @retval <0 on failure */ -int odp_cos_queue_set(odp_cos_t cos_id, odp_queue_t queue_id); +int odp_cos_destroy(odp_cos_t cos); /** -* Get the queue associated with the specific class-of-service -* -* @param[in] cos_id class-of-service instance. -* -* @retval queue_handle Queue handle associated with the -* given class-of-service -* -* @retval ODP_QUEUE_INVALID on failure -*/ -odp_queue_t odp_cos_queue(odp_cos_t cos_id); + * Destroy multiple class-of-services + * + * Otherwise like odp_cos_destroy(), but destroys multiple CoSes with a single + * call. + * + * @param cos Array of CoS handles + * @param num Number of CoSes to destroy + * + * @retval Number of CoSes actually destroyed (1 ... num) + * @retval <0 on failure + */ +int odp_cos_destroy_multi(odp_cos_t cos[], int num); /** - * Assign packet drop policy for specific class-of-service + * Assign a queue for a class-of-service * - * @param[in] cos_id class-of-service instance. - * @param[in] drop_policy Desired packet drop policy for this class. + * Action of the given CoS may not be ODP_COS_ACTION_DROP. * - * @retval 0 on success - * @retval <0 on failure + * @param cos CoS handle + * @param queue Handle of the queue where all packets of this specific + * class of service will be enqueued. Must not be + * ODP_QUEUE_INVALID. * - * @note Optional. + * @retval 0 on success + * @retval <0 on failure */ -int odp_cos_drop_set(odp_cos_t cos_id, odp_cls_drop_t drop_policy); +int odp_cos_queue_set(odp_cos_t cos, odp_queue_t queue); /** -* Get the drop policy configured for a specific class-of-service instance. +* Get the queue associated with the specific class-of-service * -* @param[in] cos_id class-of-service instance. +* @param cos CoS handle * -* @retval Drop policy configured with the given -* class-of-service +* @retval Queue handle associated with the given class-of-service +* @retval ODP_QUEUE_INVALID on failure, or if there are multiple queues, or if +* the CoS action is ODP_COS_ACTION_DROP. */ -odp_cls_drop_t odp_cos_drop(odp_cos_t cos_id); +odp_queue_t odp_cos_queue(odp_cos_t cos); /** - * Request to override per-port class of service - * based on Layer-2 priority field if present. + * Get the number of queues linked with the specific class-of-service + * + * @param cos CoS handle * - * @param[in] pktio_in Ingress port identifier. - * @param[in] num_qos Number of QoS levels, typically 8. - * @param[in] qos_table Values of the Layer-2 QoS header field. - * @param[in] cos_table Class-of-service assigned to each of the - * allowed Layer-2 QOS levels. - * @retval 0 on success - * @retval <0 on failure + * @return Number of queues linked with the class-of-service. */ -int odp_cos_with_l2_priority(odp_pktio_t pktio_in, - uint8_t num_qos, - uint8_t qos_table[], - odp_cos_t cos_table[]); +uint32_t odp_cls_cos_num_queue(odp_cos_t cos); /** - * Request to override per-port class of service - * based on Layer-3 priority field if present. + * Get the list of queue associated with the specific class-of-service * - * @param[in] pktio_in Ingress port identifier. - * @param[in] num_qos Number of allowed Layer-3 QoS levels. - * @param[in] qos_table Values of the Layer-3 QoS header field. - * @param[in] cos_table Class-of-service assigned to each of the - * allowed Layer-3 QOS levels. - * @param[in] l3_preference when true, Layer-3 QoS overrides - * L2 QoS when present. + * @param cos CoS handle + * @param[out] queue Array of queue handles associated with + * the class-of-service. + * @param num Maximum number of queue handles to output. * - * @retval 0 on success - * @retval <0 on failure - * - * @note Optional. + * @return Number of queues linked with CoS + * @retval 0 on failure */ -int odp_cos_with_l3_qos(odp_pktio_t pktio_in, - uint32_t num_qos, - uint8_t qos_table[], - odp_cos_t cos_table[], - odp_bool_t l3_preference); - +uint32_t odp_cls_cos_queues(odp_cos_t cos, odp_queue_t queue[], uint32_t num); /** - * @typedef odp_cos_flow_set_t - * Set of header fields that take part in flow signature hash calculation: - * bit positions per odp_cos_hdr_flow_fields_t enumeration. + * Get statistics for a CoS + * + * The statistics counters are incremented for packets classified to the + * given CoS. + * + * Counters that are not supported are set to zero. + * + * It's implementation defined if odp_pktio_stats_reset() call affects these + * counters. + * + * @param cos CoS handle + * @param[out] stats Statistics structure for output + * + * @retval 0 on success + * @retval <0 on failure */ +int odp_cls_cos_stats(odp_cos_t cos, odp_cls_cos_stats_t *stats); /** - * @typedef odp_pmr_t - * PMR - Packet Matching Rule - * Up to 32 bit of ternary matching of one of the available header fields + * Get statistics for a queue assigned to a CoS + * + * The statistics counters are incremented only for packets originating from the + * given CoS. Queue handles can be requested with odp_cos_queue() and + * odp_cls_cos_queues(). + * + * Counters not supported by the queue are set to zero. + * + * It's implementation defined if odp_pktio_stats_reset() call affects these + * counters. + * + * @param cos CoS handle + * @param queue Queue handle + * @param[out] stats Statistics structure for output + * + * @retval 0 on success + * @retval <0 on failure */ +int odp_cls_queue_stats(odp_cos_t cos, odp_queue_t queue, + odp_cls_queue_stats_t *stats); /** - * Packet Matching Rule field enumeration - * for fields that may be used to calculate - * the PMR, if present in a packet. + * Initialize packet matching rule parameters + * + * Initialize an odp_pmr_param_t to its default values for all fields + * + * @param param Address of the odp_pmr_param_t to be initialized */ -typedef enum { - ODP_PMR_LEN, /**< Total length of received packet*/ - ODP_PMR_ETHTYPE_0, /**< Initial (outer) - Ethertype only (*val=uint16_t)*/ - ODP_PMR_ETHTYPE_X, /**< Ethertype of most inner VLAN tag - (*val=uint16_t)*/ - ODP_PMR_VLAN_ID_0, /**< First VLAN ID (outer) (*val=uint16_t) */ - ODP_PMR_VLAN_ID_X, /**< Last VLAN ID (inner) (*val=uint16_t) */ - ODP_PMR_DMAC, /**< destination MAC address (*val=uint64_t)*/ - ODP_PMR_IPPROTO, /**< IP Protocol or IPv6 Next Header - (*val=uint8_t) */ - ODP_PMR_UDP_DPORT, /**< Destination UDP port, implies IPPROTO=17*/ - ODP_PMR_TCP_DPORT, /**< Destination TCP port implies IPPROTO=6*/ - ODP_PMR_UDP_SPORT, /**< Source UDP Port (*val=uint16_t)*/ - ODP_PMR_TCP_SPORT, /**< Source TCP port (*val=uint16_t)*/ - ODP_PMR_SIP_ADDR, /**< Source IP address (uint32_t)*/ - ODP_PMR_DIP_ADDR, /**< Destination IP address (uint32_t)*/ - ODP_PMR_SIP6_ADDR, /**< Source IP address (uint8_t[16])*/ - ODP_PMR_DIP6_ADDR, /**< Destination IP address (uint8_t[16])*/ - ODP_PMR_IPSEC_SPI, /**< IPsec session identifier(*val=uint32_t)*/ - ODP_PMR_LD_VNI, /**< NVGRE/VXLAN network identifier - (*val=uint32_t)*/ - ODP_PMR_CUSTOM_FRAME, /**< Custom match rule, offset from start of - frame. The match is defined by the offset, the - expected value, and its size. They must be - applied before any other PMR. - (*val=uint8_t[val_sz])*/ - - /** Inner header may repeat above values with this offset */ - ODP_PMR_INNER_HDR_OFF = 32 -} odp_cls_pmr_term_t; +void odp_cls_pmr_param_init(odp_pmr_param_t *param); /** - * Packet Matching Rule parameter structure + * Initialize packet matching rule creation option + * + * Initialize an odp_pmr_create_opt_t to its default values for all fields + * + * @param opt Address of the odp_pmr_create_opt_t to be initialized */ -typedef struct odp_pmr_param_t { - odp_cls_pmr_term_t term; /**< Packet Matching Rule term */ +void odp_cls_pmr_create_opt_init(odp_pmr_create_opt_t *opt); - /** True if the value is range and false if match */ - odp_bool_t range_term; - - union { - struct { - /** Value to be matched */ - const void *value; - - /** Masked set of bits to be matched */ - const void *mask; - } match; - struct { - /** Start and End values are included in the range */ - /** start value of range */ - const void *val_start; - - /** End value of range */ - const void *val_end; - } range; - }; - uint32_t val_sz; /**< Size of the term value */ - - uint32_t offset; /**< User-defined offset in packet - Used if term == ODP_PMR_CUSTOM_FRAME only, - ignored otherwise */ -} odp_pmr_param_t; +/** + * Create Packet Matching Rule (PMR) + * + * Creates a PMR between source and destination Class of Service (CoS). A packet arriving to + * a CoS is matched against all the PMRs that define it as their source CoS. A PMR match moves + * the packet from the source to the destination CoS. If multiple PMRs of a CoS match with + * the packet, it is implementation specific which PMR is selected. + * + * A composite PMR is created when PMR parameters define more than one term. A composite PMR is + * considered to match only if a packet matches with all its terms. It is implementation specific + * which term combinations are supported as composite PMRs. When creating a composite PMR, + * application should check the return value and perform appropriate fallback actions if the create + * call returns failure. See odp_cls_capability_t::max_pmr and + * odp_cls_capability_t::max_terms_per_pmr for related capabilities. + * + * Use odp_cls_pmr_param_init() to initialize parameters into their default values. + * + * PMRs created with this function are equivant to PMRs created through odp_cls_pmr_create_opt() + * with the same PMR terms and with all additional options set to their default values (e.g. + * CLS mark is set to zero in all matching packets). + * + * @param terms Array of odp_pmr_param_t entries, one entry per term + * @param num_terms Number of terms in the PMR. + * @param src_cos source CoS handle + * @param dst_cos destination CoS handle + * + * @return PMR handle on success + * @retval ODP_PMR_INVALID on failure + */ +odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms, + odp_cos_t src_cos, odp_cos_t dst_cos); /** - * Initialize packet matching rule parameters + * Create a packet matching rule with options * - * Initialize an odp_pmr_param_t to its default values for all fields + * Similar to odp_cls_pmr_create() function with additional PMR creation + * options specified through odp_pmr_create_opt_t. + * + * Use odp_cls_pmr_create_opt_init() to initialize options into their default + * values. + * + * @param opt points to PMR create options + * @param src_cos source CoS handle + * @param dst_cos destination CoS handle + * + * @return Handle to the Packet Match Rule. + * @retval ODP_PMR_INVALID on failure * - * @param param Address of the odp_pmr_param_t to be initialized */ -void odp_cls_pmr_param_init(odp_pmr_param_t *param); +odp_pmr_t odp_cls_pmr_create_opt(const odp_pmr_create_opt_t *opt, + odp_cos_t src_cos, odp_cos_t dst_cos); /** - * Create a packet match rule between source and destination class of service. - * This packet matching rule is applied on all packets arriving at the source - * class of service and packets satisfying this PMR are sent to the destination - * class of service. - * A composite PMR rule is created when the number of terms in the match rule - * is more than one. The composite rule is considered as matching only if - * the packet satisfies all the terms in Packet Match Rule. - * The underlying platform may not support all or any specific combination - * of value match rules, and the application should take care - * of inspecting the return value when installing such rules, and perform - * appropriate fallback action. - * - * @param[in] terms Array of odp_pmr_param_t entries, one entry per - * term desired. - * @param[in] num_terms Number of terms in the match rule. - * @param[in] src_cos source CoS handle - * @param[in] dst_cos destination CoS handle - * - * @return Handle to the Packet Match Rule. - * @retval ODP_PMR_INVAL on failure + * Create multiple packet matching rules + * + * Otherwise like odp_cls_pmr_create_opt(), but creates multiple rules with a + * single call. The output PMR handles are written in the same order as input + * parameters. A single odp_cls_pmr_create_multi() call is equivalent to calling + * odp_cls_pmr_create_opt() 'num' times in row. + * + * Each parameter array must contain 'num' elements. + * + * @param opt Array of PMR create options + * @param src_cos Array of source CoS handles + * @param dst_cos Array of destination CoS handles + * @param[out] pmr Array of PMR handles for output + * @param num Number of packet matching rules to create + * + * @return Number of PMRs actually created (0 ... num) + * @retval <0 on failure */ -odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms, - odp_cos_t src_cos, odp_cos_t dst_cos); +int odp_cls_pmr_create_multi(const odp_pmr_create_opt_t opt[], + odp_cos_t src_cos[], odp_cos_t dst_cos[], + odp_pmr_t pmr[], int num); /** * Function to destroy a packet match rule + * * Destroying a PMR removes the link between the source and destination * class of service and this PMR will no longer be applied for packets arriving - * at the source class of service. All the resource associated with the PMR - * be release but the class of service will remain intact. + * at the source class of service. All the resources associated with the PMR + * will be released but the class of service will remain intact. + * * Depending on the implementation details, destroying a composite rule * may not guarantee the availability of hardware resources to create the * same or essentially similar rule. * - * @param[in] pmr_id Identifier of the PMR to be destroyed + * @param pmr Handle of the PMR to be destroyed + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_cls_pmr_destroy(odp_pmr_t pmr); + +/** + * Destroy multiple packet matching rules + * + * Otherwise like odp_cls_pmr_destroy(), but destroys multiple PMRs with a + * single call. * - * @retval 0 on success - * @retval <0 on failure + * @param pmr Array of PMR handles + * @param num Number of PMRs to destroy + * + * @retval Number of PMRs actually destroyed (1 ... num) + * @retval <0 on failure */ -int odp_cls_pmr_destroy(odp_pmr_t pmr_id); +int odp_cls_pmr_destroy_multi(odp_pmr_t pmr[], int num); /** -* Assigns a packet pool for a specific class of service. +* Assigns a packet pool for a specific class of service +* * All the packets belonging to the given class of service will * be allocated from the assigned packet pool. * The packet pool associated with class of service will supersede the * packet pool associated with the pktio interface. * -* @param cos_id class of service handle -* @param pool_id packet pool handle +* @param cos CoS handle +* @param pool_id Packet pool handle * -* @retval 0 on success -* @retval <0 on failure +* @retval 0 on success +* @retval <0 on failure */ -int odp_cls_cos_pool_set(odp_cos_t cos_id, odp_pool_t pool_id); +int odp_cls_cos_pool_set(odp_cos_t cos, odp_pool_t pool_id); /** * Get the pool associated with the given class of service * -* @param cos_id class of service handle +* @param cos CoS handle * -* @retval pool handle of the associated pool -* @retval ODP_POOL_INVALID if no associated pool found or -* in case of an error +* @retval pool handle of the associated pool +* @retval ODP_POOL_INVALID on failure, or if the pool has not been set */ -odp_pool_t odp_cls_cos_pool(odp_cos_t cos_id); +odp_pool_t odp_cls_cos_pool(odp_cos_t cos); /** * Get printable value for an odp_cos_t * - * @param hdl odp_cos_t handle to be printed - * @return uint64_t value that can be used to print/display this - * handle + * @param cos CoS handle to be printed + * + * @return uint64_t value that can be used to print/display this handle * * @note This routine is intended to be used for diagnostic purposes * to enable applications to generate a printable value that represents * an odp_cos_t handle. */ -uint64_t odp_cos_to_u64(odp_cos_t hdl); +uint64_t odp_cos_to_u64(odp_cos_t cos); /** * Get printable value for an odp_pmr_t * - * @param hdl odp_pmr_t handle to be printed - * @return uint64_t value that can be used to print/display this - * handle + * @param pmr odp_pmr_t handle to be printed + * + * @return uint64_t value that can be used to print/display this handle * * @note This routine is intended to be used for diagnostic purposes * to enable applications to generate a printable value that represents * an odp_pmr_t handle. */ -uint64_t odp_pmr_to_u64(odp_pmr_t hdl); +uint64_t odp_pmr_to_u64(odp_pmr_t pmr); + +/** + * Print classifier info + * + * Print implementation defined information about classifier. The information is + * intended to be used for debugging. + */ +void odp_cls_print_all(void); /** * @} diff --git a/include/odp/api/spec/comp.h b/include/odp/api/spec/comp.h new file mode 100644 index 000000000..49ccf4509 --- /dev/null +++ b/include/odp/api/spec/comp.h @@ -0,0 +1,613 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2018 Linaro Limited + */ + +/** + * @file + * + * ODP Compression + */ + +#ifndef ODP_API_SPEC_COMP_H_ +#define ODP_API_SPEC_COMP_H_ + +#include <odp/visibility_begin.h> + +#include <odp/api/event_types.h> +#include <odp/api/packet_types.h> +#include <odp/api/queue_types.h> +#include <odp/api/std_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup odp_compression ODP COMP + * Data compression and decompression. + * + * Hash calculation may be combined with de-/compression operations. + * @{ + */ + +/** + * @def ODP_COMP_SESSION_INVALID + * Invalid session handle + */ + +/** + * @typedef odp_comp_session_t + * Compression/Decompression session handle + */ + +/** + * Compression operation mode + */ +typedef enum { + /** Synchronous Compression operation + * + * Application uses synchronous operation, + * which outputs all results on function return. + * */ + ODP_COMP_OP_MODE_SYNC, + + /** Asynchronous Compression operation + * + * Application uses asynchronous operation, + * which return results via events. + * */ + ODP_COMP_OP_MODE_ASYNC +} odp_comp_op_mode_t; + +/** + * Compression operation type. + */ +typedef enum { + /** Operation type - Compress */ + ODP_COMP_OP_COMPRESS, + + /** Operation type - Decompress */ + ODP_COMP_OP_DECOMPRESS +} odp_comp_op_t; + +/** + * Compression hash algorithms + */ +typedef enum { + /** No hash algorithm selected. */ + ODP_COMP_HASH_ALG_NONE, + + /** SHA-1 hash algorithm. */ + ODP_COMP_HASH_ALG_SHA1, + + /** SHA-2 hash algorithm 256-bit digest length. */ + ODP_COMP_HASH_ALG_SHA256 +} odp_comp_hash_alg_t; + +/** + * Compression algorithms + * + */ +typedef enum { + /** No algorithm specified. Added for testing purpose. */ + ODP_COMP_ALG_NULL, + + /** DEFLATE - RFC1951 */ + ODP_COMP_ALG_DEFLATE, + + /** ZLIB - RFC1950 */ + ODP_COMP_ALG_ZLIB, + + /** LZS */ + ODP_COMP_ALG_LZS +} odp_comp_alg_t; + +/** + * Compression operation status codes + */ +typedef enum { + /** Operation completed successfully*/ + ODP_COMP_STATUS_SUCCESS, + + /** Operation terminated due to insufficient output buffer */ + ODP_COMP_STATUS_OUT_OF_SPACE_TERM, + + /** Operation failure */ + ODP_COMP_STATUS_FAILURE, +} odp_comp_status_t; + +/** + * Hash algorithms in a bit field structure + */ +typedef union odp_comp_hash_algos_t { + /** hash algorithms */ + struct { + /** ODP_COMP_HASH_ALG_NONE */ + uint32_t none : 1; + + /** ODP_COMP_HASH_ALG_SHA1 */ + uint32_t sha1 : 1; + + /** ODP_COMP_HASH_ALG_SHA256 */ + uint32_t sha256 : 1; + + } bit; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or bitwise + * operations over the entire structure. + */ + uint32_t all_bits; +} odp_comp_hash_algos_t; + +/** + * Compression algorithms in a bit field structure + */ +typedef union odp_comp_algos_t { + /** Compression algorithms */ + struct { + /** ODP_COMP_ALG_NULL */ + uint32_t null : 1; + + /** ODP_COMP_ALG_DEFLATE */ + uint32_t deflate : 1; + + /** ODP_COMP_ALG_ZLIB */ + uint32_t zlib : 1; + + /** ODP_COMP_ALG_LZS */ + uint32_t lzs : 1; + } bit; + + /** All bits of the bit field structure + * This field can be used to set/clear all flags, or bitwise + * operations over the entire structure. + */ + uint32_t all_bits; +} odp_comp_algos_t; + +/** + * Compression Interface Capabilities + */ +typedef struct odp_comp_capability_t { + /** Maximum number of sessions */ + uint32_t max_sessions; + + /** Supported compression algorithms */ + odp_comp_algos_t comp_algos; + + /** Supported hash algorithms */ + odp_comp_hash_algos_t hash_algos; + + /** Synchronous compression mode support (ODP_COMP_OP_MODE_SYNC) */ + odp_support_t sync; + + /** Asynchronous compression mode support (ODP_COMP_OP_MODE_ASYNC) */ + odp_support_t async; +} odp_comp_capability_t; + +/** + * Hash algorithm capabilities + */ +typedef struct odp_comp_hash_alg_capability_t { + /** Digest length in bytes */ + uint32_t digest_len; +} odp_comp_hash_alg_capability_t; + +/** + * Compression algorithm capabilities + */ +typedef struct odp_comp_alg_capability_t { + /** Maximum compression level supported by implementation of this + * algorithm. Indicates number of compression levels supported by + * implementation. Valid range from (1 ... max_level) + */ + uint32_t max_level; + + /** Supported hash algorithms */ + odp_comp_hash_algos_t hash_algo; + + /** Compression ratio + * Optimal compression operation ratio for this algorithm. + * This is an estimate of maximum compression operation output for this + * algorithm. It is expressed as a percentage of maximum expected + * output data size with respect to input data size. + * i.e a value of 200% denotes the output data is 2x times the input + * data size. This is an optimal/most case estimate and it is possible + * that the percentage of output data produced might be greater + * than this value. + * + * @see odp_percent_t + */ + odp_percent_t compression_ratio; +} odp_comp_alg_capability_t; + +/** + * Compression Huffman type. Used by DEFLATE algorithm + */ +typedef enum odp_comp_huffman_code { + /** Fixed Huffman code */ + ODP_COMP_HUFFMAN_FIXED, + + /** Dynamic Huffman code */ + ODP_COMP_HUFFMAN_DYNAMIC, + + /** Default huffman code selected by implementation */ + ODP_COMP_HUFFMAN_DEFAULT, +} odp_comp_huffman_code_t; + +/** + * Compression DEFLATEe algorithm parameters. + * Also initialized by other deflate based algorithms , ex. ZLIB + */ +typedef struct odp_comp_deflate_param { + /** + * Compression level + * + * Valid range is integer between (0 ... max_level) + * level supported by the implementation. + * + * where, + * 0 - implementation default + * + * 1 - fastest compression i.e. output produced at + * best possible speed at the expense of compression quality + * + * max_level - High quality compression + * + * @see odp_comp_alg_capability_t::max_level + */ + uint32_t comp_level; + + /** huffman code to use */ + odp_comp_huffman_code_t huffman_code; +} odp_comp_deflate_param_t; + +/** + * Compression algorithm specific parameters + */ +typedef union odp_comp_alg_param_t { + /** deflate parameter */ + odp_comp_deflate_param_t deflate; + + /** Struct for defining zlib algorithm parameters */ + struct { + /** deflate algo params */ + odp_comp_deflate_param_t deflate; + } zlib; +} odp_comp_alg_param_t; + + /** + * Compression session creation parameters + */ +typedef struct odp_comp_session_param_t { + /** Compression operation type Compress vs Decompress */ + odp_comp_op_t op; + + /** Compression operation mode + * + * Operation mode Synchronous vs Asynchronous + * + * @see odp_comp_op(), odp_comp_op_enq() + */ + odp_comp_op_mode_t mode; + + /** Compression algorithm + * + * @see odp_comp_capability() + */ + odp_comp_alg_t comp_algo; + + /** Hash algorithm + * + * @see odp_comp_alg_capability() + */ + odp_comp_hash_alg_t hash_algo; + + /** parameters specific to compression */ + odp_comp_alg_param_t alg_param; + + /** Session packet enqueue ordering + * Boolean to indicate if packet enqueue ordering is required per + * session. Valid only for Asynchronous operation mode + * (ODP_COMP_OP_MODE_ASYNC). Packet order is always maintained for + * synchronous operation mode (ODP_COMP_OP_MODE_SYNC) + * + * true: packet session enqueue order maintained + * + * false: packet session enqueue order is not maintained + * + * @note: By disabling packet order requirement, performance oriented + * application can leverage HW offered parallelism to increase operation + * performance. + */ + odp_bool_t packet_order; + + /** Destination queue for compression operations result. + * Results are enqueued as ODP_EVENT_PACKET with subtype + * ODP_EVENT_PACKET_COMP + */ + odp_queue_t compl_queue; +} odp_comp_session_param_t; + +/** + * Compression packet operation result + */ +typedef struct odp_comp_packet_result_t { + /** Operation status code */ + odp_comp_status_t status; + + /** Input packet handle */ + odp_packet_t pkt_in; + + /** Output packet data range + * Specifies offset and length of data resulting from compression + * operation. When hashing is configured output_data_range.len equals + * length of output data + length of digest. + */ + odp_packet_data_range_t output_data_range; +} odp_comp_packet_result_t; + +/** + * Compression per packet operation parameters + */ +typedef struct odp_comp_packet_op_param_t { + /** Session handle */ + odp_comp_session_t session; + + /** Input data range to process. where, + * + * offset - starting offset + * length - length of data for compression operation + * */ + odp_packet_data_range_t in_data_range; + + /** Output packet data range. + * Indicates where processed packet will be written. where, + * + * offset - starting offset + * length - length of buffer available for output + * + * Output packet data is not modified outside of this provided data + * range. If output data length is not sufficient for compression + * operation ODP_COMP_STATUS_OUT_OF_SPACE_TERM error will occur + */ + odp_packet_data_range_t out_data_range; +} odp_comp_packet_op_param_t; + +/** + * Query compression capabilities + * + * Output compression capabilities on success. + * + * @param[out] capa Pointer to capability structure for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_comp_capability(odp_comp_capability_t *capa); + +/** + * Query supported compression algorithm capabilities + * + * Output algorithm capabilities. + * + * @param comp Compression algorithm + * @param[out] capa Compression algorithm capability + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_comp_alg_capability(odp_comp_alg_t comp, + odp_comp_alg_capability_t *capa); + +/** + * Query supported hash algorithm capabilities + * + * Outputs all supported configuration options for the algorithm. + * + * @param hash Hash algorithm + * @param capa Hash algorithm capability + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_comp_hash_alg_capability(odp_comp_hash_alg_t hash, + odp_comp_hash_alg_capability_t *capa); + +/** + * Initialize compression session parameters + * + * Initialize an odp_comp_session_param_t to its default values for + * all fields. + * + * @param param Pointer to odp_comp_session_param_t to be initialized + */ +void odp_comp_session_param_init(odp_comp_session_param_t *param); + +/** + * Compression session creation + * + * Create a comp session according to the session parameters. Use + * odp_comp_session_param_init() to initialize parameters into their + * default values. + * + * @param param Session parameters + * + * @retval Comp session handle + * @retval ODP_COMP_SESSION_INVALID on failure + */ +odp_comp_session_t +odp_comp_session_create(const odp_comp_session_param_t *param); + +/** + * Compression session destroy + * + * Destroy an unused session. Result is undefined if session is being used + * (i.e. asynchronous operation is in progress). + * + * @param session Session handle + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_comp_session_destroy(odp_comp_session_t session); + +/** + * Synchronous packet compression operation + * + * This operation does packet compression in synchronous mode. A successful + * operation returns the number of successfully processed input packets and + * updates the results in the corresponding output packets. Outputted packets + * contain compression results metadata (odp_comp_packet_result_t), which + * should be checked for operation status. Length of outputted data can be got + * from output_data_range.len. + * + * When hashing is configured along with compression operation the + * result is appended at the end of the output data, output_data_range.len + * equals length of output data + 'digest_len'. Processed data length + * can be computed by subtracting 'digest_len' from output_data_range.len where + * 'digest_len' can be queried from odp_comp_hash_alg_capability(). + * Hash is always performed on plain text. Hash validation in decompression is + * performed by the application. + * For every input packet entry in 'pkt_in' array, application should pass + * corresponding valid output packet handle. If any error occurs during + * processing of packets, the API returns with number of entries successfully + * processed. + * Output packet metadatas like length or data pointer will not be updated. + * + * @param pkt_in Packets to be processed + * @param pkt_out Packet handle array for resulting packets + * @param num_pkt Number of packets to be processed + * @param param Operation parameters + * + * @return Number of input packets consumed (0 ... num_pkt) + * @retval <0 on failure + * + * @note The 'pkt_in','pkt_out'and 'param' arrays should be of same length, + * Results are undefined if otherwise. + + * @note Same packet handle cannot be used as input and output parameter. + * In-place compression operation is not supported + */ +int odp_comp_op(const odp_packet_t pkt_in[], odp_packet_t pkt_out[], + int num_pkt, const odp_comp_packet_op_param_t param[]); + +/** + * Asynchronous packet compression operation + * + * This operation does packet compression in asynchronous mode. It processes + * packets otherwise identical to odp_comp_op(), but the resulting packets are + * enqueued to 'compl_queue' configured during session (odp_comp_session_t) + * creation. For every input packet entry in in_pkt array, user should pass + * corresponding valid output packet handle. On return, API returns with + * number of entries successfully submitted for operation. + * + * When hashing is configured along with compression operation the + * result is appended at the end of the output data, output_data_range.len + * equals length of output data + 'digest_len'. Processed data length + * can be computed by subtracting 'digest_len' from output_data_range.len where + * 'digest_len' can be queried from odp_comp_hash_alg_capability(). + * Hash is always performed on plain text. Hash validation in decompression is + * performed by the application. + * + * In case of partially accepted array i.e. + * when number of packets returned < num_pkt, application may attempt to + * resubmit subsequent entries via calling any of the operation API. + * + * All the packets successfully enqueued will be submitted to 'compl_queue' + * after compression operation, Application should check 'status' of the + * operation in odp_comp_packet_result_t. + * Output packet metadatas like length or data pointer will not be updated. + * + * Please note it is always recommended that application using async mode, + * provide sufficiently large buffer size to avoid + * ODP_COMP_STATUS_OUT_OF_SPACE_TERM. + * + * @param pkt_in Packets to be processed + * @param pkt_out Packet handle array for resulting packets + * @param num_pkt Number of packets to be processed + * @param param Operation parameters + * + * @return Number of input packets enqueued (0 ... num_pkt) + * @retval <0 on failure + * + * @note The 'pkt_in','pkt_out'and 'param' arrays should be of same length, + * Results are undefined if otherwise. + + * @note Same packet handle cannot be used as input and output parameter. + * In-place compression operation is not supported + + * @see odp_comp_op(), odp_comp_packet_result() + */ +int odp_comp_op_enq(const odp_packet_t pkt_in[], odp_packet_t pkt_out[], + int num_pkt, const odp_comp_packet_op_param_t param[]); + +/** + * Get compression operation results from processed packet. + * + * Successful compression operations of all modes (ODP_COMP_OP_MODE_SYNC and + * ODP_COMP_OP_MODE_ASYNC) produce packets which contain compression result + * metadata. This function copies operation results from compression processed + * packet. Event subtype of this packet is ODP_EVENT_PACKET_COMP. Results are + * undefined if non-compression processed packet is passed as input. + * + * @param[out] result pointer to operation result for output + * @param packet compression processed packet (ODP_EVENT_PACKET_COMP) + * + * @retval 0 On success + * @retval <0 On failure + */ +int odp_comp_result(odp_comp_packet_result_t *result, odp_packet_t packet); + + /** + * Convert compression processed packet event to packet handle + * + * Get packet handle corresponding to processed packet event. Event subtype + * must be ODP_EVENT_PACKET_COMP. Compression operation results can be + * examined with odp_comp_result(). + * + * @param event Event handle + * + * @return Valid Packet handle on success, + * @retval ODP_PACKET_INVALID on failure + * + * @see odp_event_subtype(), odp_comp_result() + * + */ +odp_packet_t odp_comp_packet_from_event(odp_event_t event); + + /** + * Convert processed packet handle to event + * + * The packet handle must be an output of a compression operation + * + * @param pkt Packet handle from compression operation + * @return Event handle + */ +odp_event_t odp_comp_packet_to_event(odp_packet_t pkt); + +/** + * Get printable value for an odp_comp_session_t + * + * @param hdl odp_comp_session_t handle to be printed + * @return uint64_t value that can be used to print/display this + * handle + * + * @note This routine is intended to be used for diagnostic purposes + * to enable applications to generate a printable value that represents + * an odp_comp_session_t handle. + */ +uint64_t odp_comp_session_to_u64(odp_comp_session_t hdl); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif + diff --git a/include/odp/api/spec/compiler.h b/include/odp/api/spec/compiler.h deleted file mode 100644 index c88350e2c..000000000 --- a/include/odp/api/spec/compiler.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - - -/** - * @file - * - * Compiler related - */ - -#ifndef ODP_API_COMPILER_H_ -#define ODP_API_COMPILER_H_ -#include <odp/visibility_begin.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup odp_compiler_optim - * Macro for old compilers - * @{ - */ - -/** @internal GNU compiler version */ -#define GCC_VERSION (__GNUC__ * 10000 \ - + __GNUC_MINOR__ * 100 \ - + __GNUC_PATCHLEVEL__) - -/** - * @internal - * Compiler __builtin_bswap16() is not available on all platforms - * until GCC 4.8.0 - work around this by offering __odp_builtin_bswap16() - * Don't use this function directly, instead see odp_byteorder.h - */ -#if GCC_VERSION < 40800 -#define __odp_builtin_bswap16(u16) ((((u16)&0x00ff) << 8)|(((u16)&0xff00) >> 8)) -#else -#define __odp_builtin_bswap16(u16) __builtin_bswap16(u16) -#endif - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#include <odp/visibility_end.h> -#endif diff --git a/include/odp/api/spec/cpu.h b/include/odp/api/spec/cpu.h index 0f47e4798..9550354fa 100644 --- a/include/odp/api/spec/cpu.h +++ b/include/odp/api/spec/cpu.h @@ -1,18 +1,15 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited */ - /** * @file * * ODP CPU API */ -#ifndef ODP_CPU_H_ -#define ODP_CPU_H_ +#ifndef ODP_API_SPEC_CPU_H_ +#define ODP_API_SPEC_CPU_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -22,10 +19,10 @@ extern "C" { #include <odp/api/std_types.h> /** @defgroup odp_cpu ODP CPU + * CPU cycle count, frequency, etc. information. * @{ */ - /** * CPU identifier * @@ -69,44 +66,48 @@ const char *odp_cpu_model_str_id(int id); /** * Current CPU frequency in Hz * - * Returns current frequency of this CPU + * Returns current frequency of this CPU. Returns zero if the frequency + * request is not supported. * * @return CPU frequency in Hz - * @retval 0 on failure + * @retval 0 Not supported or a failure */ uint64_t odp_cpu_hz(void); /** * Current CPU frequency of a CPU (in Hz) * - * Returns current frequency of specified CPU + * Returns current frequency of the specified CPU. Returns zero if the frequency + * request is not supported. * * @param id CPU ID * * @return CPU frequency in Hz - * @retval 0 on failure + * @retval 0 Not supported or a failure */ uint64_t odp_cpu_hz_id(int id); /** * Maximum CPU frequency in Hz * - * Returns maximum frequency of this CPU + * Returns the maximum frequency of this CPU. Returns zero if the frequency + * request is not supported. * * @return CPU frequency in Hz - * @retval 0 on failure + * @retval 0 Not supported or a failure */ uint64_t odp_cpu_hz_max(void); /** * Maximum CPU frequency of a CPU (in Hz) * - * Returns maximum frequency of specified CPU + * Returns the maximum frequency of the specified CPU. Returns zero if the + * frequency request is not supported. * * @param id CPU ID * * @return CPU frequency in Hz - * @retval 0 on failure + * @retval 0 Not supported or a failure */ uint64_t odp_cpu_hz_max_id(int id); @@ -116,14 +117,15 @@ uint64_t odp_cpu_hz_max_id(int id); * Return current CPU cycle count. Cycle count may not be reset at ODP init * and thus may wrap back to zero between two calls. Use odp_cpu_cycles_max() * to read the maximum count value after which it wraps. Cycle count frequency - * follows the CPU frequency and thus may change at any time. The count may - * advance in steps larger than one. Use odp_cpu_cycles_resolution() to read - * the step size. + * follows the CPU frequency and thus may change at any time. Cycle count should + * not be used for time measurements due to the possibility of frequency + * variation. The count may advance in steps larger than one. Use + * odp_cpu_cycles_resolution() to read the step size. * - * @note Do not use CPU count for time measurements since the frequency may - * vary. + * Returns zero if CPU cycle counter is not supported. * * @return Current CPU cycle count + * @retval 0 Not supported */ uint64_t odp_cpu_cycles(void); @@ -144,9 +146,11 @@ uint64_t odp_cpu_cycles_diff(uint64_t c2, uint64_t c1); /** * Maximum CPU cycle count * - * Maximum CPU cycle count value before it wraps back to zero. + * Maximum CPU cycle count value before it wraps back to zero. Returns zero + * if CPU cycle counter is not supported. * * @return Maximum CPU cycle count value + * @retval 0 Not supported */ uint64_t odp_cpu_cycles_max(void); @@ -154,9 +158,11 @@ uint64_t odp_cpu_cycles_max(void); * Resolution of CPU cycle count * * CPU cycle count may advance in steps larger than one. This function returns - * resolution of odp_cpu_cycles() in CPU cycles. + * resolution of odp_cpu_cycles() in CPU cycles. Returns zero if CPU cycle + * counter is not supported. * * @return CPU cycle count resolution in CPU cycles + * @retval 0 Not supported */ uint64_t odp_cpu_cycles_resolution(void); diff --git a/include/odp/api/spec/cpumask.h b/include/odp/api/spec/cpumask.h index 22d8e8f24..a6c08e6c0 100644 --- a/include/odp/api/spec/cpumask.h +++ b/include/odp/api/spec/cpumask.h @@ -1,18 +1,16 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2022 Nokia */ - /** * @file * * ODP CPU masks and enumeration */ -#ifndef ODP_API_CPUMASK_H_ -#define ODP_API_CPUMASK_H_ +#ifndef ODP_API_SPEC_CPUMASK_H_ +#define ODP_API_SPEC_CPUMASK_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -209,26 +207,36 @@ int odp_cpumask_last(const odp_cpumask_t *mask); int odp_cpumask_next(const odp_cpumask_t *mask, int cpu); /** - * Default cpumask for worker threads + * Default CPU mask for worker threads + * + * Initializes CPU mask with the default set of CPUs available for worker threads. It's system + * specific if other CPUs may be used for worker threads as well. Parameter 'num' defines + * the maximum number of CPUs to be returned. Use zero for all available CPUs. The mask pointer + * may be set to NULL when CPU mask is not required. * - * Initializes cpumask with CPUs available for worker threads. Sets up to 'num' - * CPUs and returns the count actually set. Use zero for all available CPUs. + * Returns the number of CPUs selected and written into the CPU mask (when not NULL). * * @param[out] mask CPU mask to initialize - * @param num Number of worker threads, zero for all available CPUs - * @return Actual number of CPUs used to create the mask + * @param num Maximum number of CPUs to return. Use zero for all available CPUs. + * + * @return Number of selected CPUs */ int odp_cpumask_default_worker(odp_cpumask_t *mask, int num); /** - * Default cpumask for control threads + * Default CPU mask for control threads + * + * Initializes CPU mask with the default set of CPUs available for control threads. It's system + * specific if other CPUs may be used for control threads as well. Parameter 'num' defines + * the maximum number of CPUs to be returned. Use zero for all available CPUs. The mask pointer + * may be set to NULL when CPU mask is not required. * - * Initializes cpumask with CPUs available for control threads. Sets up to 'num' - * CPUs and returns the count actually set. Use zero for all available CPUs. + * Returns the number of CPUs selected and written into the CPU mask (when not NULL). * * @param[out] mask CPU mask to initialize - * @param num Number of control threads, zero for all available CPUs - * @return Actual number of CPUs used to create the mask + * @param num Maximum number of CPUs to return. Use zero for all available CPUs. + * + * @return Number of selected CPUs */ int odp_cpumask_default_control(odp_cpumask_t *mask, int num); diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index 9855bf989..8b7d1df54 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -1,496 +1,32 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited + * Copyright (c) 2021-2023 Nokia */ - /** * @file * * ODP crypto */ -#ifndef ODP_API_CRYPTO_H_ -#define ODP_API_CRYPTO_H_ +#ifndef ODP_API_SPEC_CRYPTO_H_ +#define ODP_API_SPEC_CRYPTO_H_ #include <odp/visibility_begin.h> +#include <odp/api/crypto_types.h> +#include <odp/api/packet_types.h> +#include <odp/api/std_types.h> + #ifdef __cplusplus extern "C" { #endif -/** @defgroup odp_crypto ODP CRYPTO - * Macros, enums, types and operations to utilise crypto. +/** @addtogroup odp_crypto + * Data ciphering and authentication. * @{ */ /** - * @def ODP_CRYPTO_SESSION_INVALID - * Invalid session handle - */ - -/** - * @typedef odp_crypto_session_t - * Crypto API opaque session handle - */ - -/** - * @typedef odp_crypto_compl_t -* Crypto API completion event (platform dependent). -*/ - -/** - * Crypto API operation mode - */ -typedef enum { - /** Synchronous, return results immediately */ - ODP_CRYPTO_SYNC, - /** Asynchronous, return results via posted event */ - ODP_CRYPTO_ASYNC, -} odp_crypto_op_mode_t; - -/** - * Crypto API operation type - */ -typedef enum { - /** Encrypt and/or compute authentication ICV */ - ODP_CRYPTO_OP_ENCODE, - /** Decrypt and/or verify authentication ICV */ - ODP_CRYPTO_OP_DECODE, -} odp_crypto_op_t; - -/** - * Crypto API cipher algorithm - */ -typedef enum { - /** No cipher algorithm specified */ - ODP_CIPHER_ALG_NULL, - - /** DES */ - ODP_CIPHER_ALG_DES, - - /** Triple DES with cipher block chaining */ - ODP_CIPHER_ALG_3DES_CBC, - - /** AES with cipher block chaining */ - ODP_CIPHER_ALG_AES_CBC, - - /** AES in Galois/Counter Mode - * - * @note Must be paired with cipher ODP_AUTH_ALG_AES_GCM - */ - ODP_CIPHER_ALG_AES_GCM, - - /** @deprecated Use ODP_CIPHER_ALG_AES_CBC instead */ - ODP_CIPHER_ALG_AES128_CBC, - - /** @deprecated Use ODP_CIPHER_ALG_AES_GCM instead */ - ODP_CIPHER_ALG_AES128_GCM - -} odp_cipher_alg_t; - -/** - * Crypto API authentication algorithm - */ -typedef enum { - /** No authentication algorithm specified */ - ODP_AUTH_ALG_NULL, - - /** HMAC-MD5 - * - * MD5 algorithm in HMAC mode - */ - ODP_AUTH_ALG_MD5_HMAC, - - /** HMAC-SHA-256 - * - * SHA-256 algorithm in HMAC mode - */ - ODP_AUTH_ALG_SHA256_HMAC, - - /** AES in Galois/Counter Mode - * - * @note Must be paired with cipher ODP_CIPHER_ALG_AES_GCM - */ - ODP_AUTH_ALG_AES_GCM, - - /** @deprecated Use ODP_AUTH_ALG_MD5_HMAC instead */ - ODP_AUTH_ALG_MD5_96, - - /** @deprecated Use ODP_AUTH_ALG_SHA256_HMAC instead */ - ODP_AUTH_ALG_SHA256_128, - - /** @deprecated Use ODP_AUTH_ALG_AES_GCM instead */ - ODP_AUTH_ALG_AES128_GCM -} odp_auth_alg_t; - -/** - * Cipher algorithms in a bit field structure - */ -typedef union odp_crypto_cipher_algos_t { - /** Cipher algorithms */ - struct { - /** ODP_CIPHER_ALG_NULL */ - uint32_t null : 1; - - /** ODP_CIPHER_ALG_DES */ - uint32_t des : 1; - - /** ODP_CIPHER_ALG_3DES_CBC */ - uint32_t trides_cbc : 1; - - /** ODP_CIPHER_ALG_AES_CBC */ - uint32_t aes_cbc : 1; - - /** ODP_CIPHER_ALG_AES_GCM */ - uint32_t aes_gcm : 1; - - /** @deprecated Use aes_cbc instead */ - uint32_t aes128_cbc : 1; - - /** @deprecated Use aes_gcm instead */ - uint32_t aes128_gcm : 1; - } bit; - - /** All bits of the bit field structure - * - * This field can be used to set/clear all flags, or bitwise - * operations over the entire structure. */ - uint32_t all_bits; -} odp_crypto_cipher_algos_t; - -/** - * Authentication algorithms in a bit field structure - */ -typedef union odp_crypto_auth_algos_t { - /** Authentication algorithms */ - struct { - /** ODP_AUTH_ALG_NULL */ - uint32_t null : 1; - - /** ODP_AUTH_ALG_MD5_HMAC */ - uint32_t md5_hmac : 1; - - /** ODP_AUTH_ALG_SHA256_HMAC */ - uint32_t sha256_hmac : 1; - - /** ODP_AUTH_ALG_AES_GCM */ - uint32_t aes_gcm : 1; - - /** @deprecated Use md5_hmac instead */ - uint32_t md5_96 : 1; - - /** @deprecated Use sha256_hmac instead */ - uint32_t sha256_128 : 1; - - /** @deprecated Use aes_gcm instead */ - uint32_t aes128_gcm : 1; - } bit; - - /** All bits of the bit field structure - * - * This field can be used to set/clear all flags, or bitwise - * operations over the entire structure. */ - uint32_t all_bits; -} odp_crypto_auth_algos_t; - -/** - * Crypto API key structure - */ -typedef struct odp_crypto_key { - /** Key data */ - uint8_t *data; - - /** Key length in bytes */ - uint32_t length; - -} odp_crypto_key_t; - -/** - * Crypto API IV structure - */ -typedef struct odp_crypto_iv { - /** IV data */ - uint8_t *data; - - /** IV length in bytes */ - uint32_t length; - -} odp_crypto_iv_t; - -/** - * Crypto API data range specifier - */ -typedef struct odp_crypto_data_range { - /** Offset from beginning of packet */ - uint32_t offset; - - /** Length of data to operate on */ - uint32_t length; - -} odp_crypto_data_range_t; - -/** - * Crypto API session creation parameters - */ -typedef struct odp_crypto_session_param_t { - /** Encode vs. decode operation */ - odp_crypto_op_t op; - - /** Authenticate cipher vs. plain text - * - * Controls ordering of authentication and cipher operations, - * and is relative to the operation (encode vs decode). When encoding, - * TRUE indicates the authentication operation should be performed - * after the cipher operation else before. When decoding, TRUE - * indicates the reverse order of operation. - * - * true: Authenticate cipher text - * false: Authenticate plain text - */ - odp_bool_t auth_cipher_text; - - /** Preferred sync vs. async */ - odp_crypto_op_mode_t pref_mode; - - /** Cipher algorithm - * - * Use odp_crypto_capability() for supported algorithms. - */ - odp_cipher_alg_t cipher_alg; - - /** Cipher key - * - * Use odp_crypto_cipher_capa() for supported key and IV lengths. - */ - odp_crypto_key_t cipher_key; - - /** Cipher Initialization Vector (IV) */ - odp_crypto_iv_t iv; - - /** Authentication algorithm - * - * Use odp_crypto_capability() for supported algorithms. - */ - odp_auth_alg_t auth_alg; - - /** Authentication key - * - * Use odp_crypto_auth_capa() for supported digest and key lengths. - */ - odp_crypto_key_t auth_key; - - /** Async mode completion event queue - * - * When odp_crypto_operation() is asynchronous, the completion queue is - * used to return the completion status of the operation to the - * application. - */ - odp_queue_t compl_queue; - - /** Output pool - * - * When the output packet is not specified during the call to - * odp_crypto_operation(), the output packet will be allocated - * from this pool. - */ - odp_pool_t output_pool; - -} odp_crypto_session_param_t; - -/** @deprecated Use odp_crypto_session_param_t instead */ -typedef odp_crypto_session_param_t odp_crypto_session_params_t; - -/** - * Crypto API per packet operation parameters - */ -typedef struct odp_crypto_op_param_t { - /** Session handle from creation */ - odp_crypto_session_t session; - - /** User context */ - void *ctx; - - /** Input packet - * - * Specifies the input packet for the crypto operation. When the - * 'out_pkt' variable is set to ODP_PACKET_INVALID (indicating a new - * packet should be allocated for the resulting packet). - */ - odp_packet_t pkt; - - /** Output packet - * - * Both "in place" (the original packet 'pkt' is modified) and - * "copy" (the packet is replicated to a new packet which contains - * the modified data) modes are supported. The "in place" mode of - * operation is indicated by setting 'out_pkt' equal to 'pkt'. - * For the copy mode of operation, setting 'out_pkt' to a valid packet - * value indicates the caller wishes to specify the destination packet. - * Setting 'out_pkt' to ODP_PACKET_INVALID indicates the caller wishes - * the destination packet be allocated from the output pool specified - * during session creation. - */ - odp_packet_t out_pkt; - - /** Override session IV pointer */ - uint8_t *override_iv_ptr; - - /** Offset from start of packet for hash result - * - * Specifies the offset where the hash result is to be stored. In case - * of decode sessions, input hash values will be read from this offset, - * and overwritten with hash results. If this offset lies within - * specified 'auth_range', implementation will mute this field before - * calculating the hash result. - */ - uint32_t hash_result_offset; - - /** Data range to apply cipher */ - odp_crypto_data_range_t cipher_range; - - /** Data range to authenticate */ - odp_crypto_data_range_t auth_range; - -} odp_crypto_op_param_t; - -/** @deprecated Use odp_crypto_op_param_t instead */ -typedef odp_crypto_op_param_t odp_crypto_op_params_t; - -/** - * Crypto API session creation return code - */ -typedef enum { - /** Session created */ - ODP_CRYPTO_SES_CREATE_ERR_NONE, - /** Creation failed, no resources */ - ODP_CRYPTO_SES_CREATE_ERR_ENOMEM, - /** Creation failed, bad cipher params */ - ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER, - /** Creation failed, bad auth params */ - ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH, -} odp_crypto_ses_create_err_t; - -/** - * Crypto API algorithm return code - */ -typedef enum { - /** Algorithm successful */ - ODP_CRYPTO_ALG_ERR_NONE, - /** Invalid data block size */ - ODP_CRYPTO_ALG_ERR_DATA_SIZE, - /** Key size invalid for algorithm */ - ODP_CRYPTO_ALG_ERR_KEY_SIZE, - /** Computed ICV value mismatch */ - ODP_CRYPTO_ALG_ERR_ICV_CHECK, - /** IV value not specified */ - ODP_CRYPTO_ALG_ERR_IV_INVALID, -} odp_crypto_alg_err_t; - -/** - * Crypto API hardware centric return code - */ -typedef enum { - /** Operation completed successfully */ - ODP_CRYPTO_HW_ERR_NONE, - /** Error detected during DMA of data */ - ODP_CRYPTO_HW_ERR_DMA, - /** Operation failed due to pool depletion */ - ODP_CRYPTO_HW_ERR_BP_DEPLETED, -} odp_crypto_hw_err_t; - -/** - * Cryto API per packet operation completion status - */ -typedef struct odp_crypto_compl_status { - /** Algorithm specific return code */ - odp_crypto_alg_err_t alg_err; - - /** Hardware specific return code */ - odp_crypto_hw_err_t hw_err; - -} odp_crypto_compl_status_t; - -/** - * Crypto API operation result - */ -typedef struct odp_crypto_op_result { - /** Request completed successfully */ - odp_bool_t ok; - - /** User context from request */ - void *ctx; - - /** Output packet */ - odp_packet_t pkt; - - /** Cipher status */ - odp_crypto_compl_status_t cipher_status; - - /** Authentication status */ - odp_crypto_compl_status_t auth_status; - -} odp_crypto_op_result_t; - -/** - * Crypto capabilities - */ -typedef struct odp_crypto_capability_t { - /** Maximum number of crypto sessions */ - uint32_t max_sessions; - - /** Supported cipher algorithms */ - odp_crypto_cipher_algos_t ciphers; - - /** Cipher algorithms implemented with HW offload */ - odp_crypto_cipher_algos_t hw_ciphers; - - /** Supported authentication algorithms */ - odp_crypto_auth_algos_t auths; - - /** Authentication algorithms implemented with HW offload */ - odp_crypto_auth_algos_t hw_auths; - -} odp_crypto_capability_t; - -/** - * Cipher algorithm capabilities - */ -typedef struct odp_crypto_cipher_capability_t { - /** Key length in bytes */ - uint32_t key_len; - - /** IV length in bytes */ - uint32_t iv_len; - -} odp_crypto_cipher_capability_t; - -/** - * Authentication algorithm capabilities - */ -typedef struct odp_crypto_auth_capability_t { - /** Digest length in bytes */ - uint32_t digest_len; - - /** Key length in bytes */ - uint32_t key_len; - - /** Additional Authenticated Data (AAD) lengths */ - struct { - /** Minimum AAD length in bytes */ - uint32_t min; - - /** Maximum AAD length in bytes */ - uint32_t max; - - /** Increment of supported lengths between min and max - * (in bytes) */ - uint32_t inc; - } aad_len; - -} odp_crypto_auth_capability_t; - -/** * Query crypto capabilities * * Outputs crypto capabilities on success. @@ -546,16 +82,20 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth, * * Create a crypto session according to the session parameters. Use * odp_crypto_session_param_init() to initialize parameters into their - * default values. + * default values. If call ends up with an error no new session will be + * created. + * + * The parameter structure as well as the key and IV data pointed to by it + * can be freed after the call. * - * @param param Session parameters - * @param session Created session else ODP_CRYPTO_SESSION_INVALID - * @param status Failure code if unsuccessful + * @param param Session parameters + * @param[out] session Created session else ODP_CRYPTO_SESSION_INVALID + * @param[out] status Failure code if unsuccessful * * @retval 0 on success * @retval <0 on failure */ -int odp_crypto_session_create(odp_crypto_session_param_t *param, +int odp_crypto_session_create(const odp_crypto_session_param_t *param, odp_crypto_session_t *session, odp_crypto_ses_create_err_t *status); @@ -573,97 +113,217 @@ int odp_crypto_session_create(odp_crypto_session_param_t *param, int odp_crypto_session_destroy(odp_crypto_session_t session); /** - * Return crypto completion handle that is associated with event - * - * Note: any invalid parameters will cause undefined behavior and may cause - * the application to abort or crash. + * Get printable value for an odp_crypto_session_t * - * @param ev An event of type ODP_EVENT_CRYPTO_COMPL + * @param hdl odp_crypto_session_t handle to be printed + * @return uint64_t value that can be used to print/display this + * handle * - * @return crypto completion handle + * @note This routine is intended to be used for diagnostic purposes + * to enable applications to generate a printable value that represents + * an odp_crypto_session_t handle. */ -odp_crypto_compl_t odp_crypto_compl_from_event(odp_event_t ev); +uint64_t odp_crypto_session_to_u64(odp_crypto_session_t hdl); /** - * Convert crypto completion handle to event handle + * Initialize crypto session parameters * - * @param completion_event Completion event to convert to generic event + * Initialize an odp_crypto_session_param_t to its default values for + * all fields. * - * @return Event handle + * @param param Pointer to odp_crypto_session_param_t to be initialized */ -odp_event_t odp_crypto_compl_to_event(odp_crypto_compl_t completion_event); +void odp_crypto_session_param_init(odp_crypto_session_param_t *param); /** - * Release crypto completion event + * Return crypto processed packet that is associated with event * - * @param completion_event Completion event we are done accessing - */ -void odp_crypto_compl_free(odp_crypto_compl_t completion_event); - -/** - * Crypto per packet operation + * Get packet handle to an crypto processed packet event. Event subtype must be + * ODP_EVENT_PACKET_CRYPTO. Crypto operation results can be examined with + * odp_crypto_result(). * - * Performs the cryptographic operations specified during session creation - * on the packet. If the operation is performed synchronously, "posted" - * will return FALSE and the result of the operation is immediately available. - * If "posted" returns TRUE the result will be delivered via the completion - * queue specified when the session was created. + * Note: any invalid parameters will cause undefined behavior and may cause + * the application to abort or crash. * - * @param param Operation parameters - * @param posted Pointer to return posted, TRUE for async operation - * @param result Results of operation (when posted returns FALSE) + * @param ev Event handle * - * @retval 0 on success - * @retval <0 on failure + * @return Packet handle */ -int odp_crypto_operation(odp_crypto_op_param_t *param, - odp_bool_t *posted, - odp_crypto_op_result_t *result); +odp_packet_t odp_crypto_packet_from_event(odp_event_t ev); /** - * Crypto per packet operation query result from completion event + * Convert crypto packet handle to event * - * @param completion_event Event containing operation results - * @param result Pointer to result structure + * The packet handle must be an output of an crypto operation. + * + * @param pkt Packet handle from crypto operation + * + * @return Event handle */ -void odp_crypto_compl_result(odp_crypto_compl_t completion_event, - odp_crypto_op_result_t *result); +odp_event_t odp_crypto_packet_to_event(odp_packet_t pkt); /** - * Get printable value for an odp_crypto_session_t + * Get crypto operation results from a crypto processed packet * - * @param hdl odp_crypto_session_t handle to be printed - * @return uint64_t value that can be used to print/display this - * handle + * Crypto operations of all types (SYNC and ASYNC) produce packets which + * contain crypto result metadata. This function returns success status + * of the crypto operation that was applied to a packet and optionally + * writes additional information in a result structure. * - * @note This routine is intended to be used for diagnostic purposes - * to enable applications to generate a printable value that represents - * an odp_crypto_session_t handle. + * If the crypto operation succeeded, zero is returned and the values + * written in the cipher_status and auth_status fields of the result + * structure have undefined values. + * + * If the crypto operation failed, -1 is returned and the cipher_status + * and auth_status fields of the result structure indicate the reason for + * the failure. + * + * The subtype of the passed packet must be ODP_EVENT_PACKET_CRYPTO, + * otherwise the result of the call is undefined. + * + * @param packet A crypto processed packet (ODP_EVENT_PACKET_CRYPTO) + * @param[out] result Pointer to operation result for output or NULL + * + * @retval 0 Crypto operation succeeded + * @retval -1 Crypto operation failed + * @retval <-1 Failed to get crypto operation status of the packet */ -uint64_t odp_crypto_session_to_u64(odp_crypto_session_t hdl); +int odp_crypto_result(odp_crypto_packet_result_t *result, + odp_packet_t packet); /** - * Get printable value for an odp_crypto_compl_t + * Crypto packet operation * - * @param hdl odp_crypto_compl_t handle to be printed - * @return uint64_t value that can be used to print/display this - * handle + * Performs the SYNC cryptographic operations specified during session creation + * on the packets. All arrays should be of num_pkt size. * - * @note This routine is intended to be used for diagnostic purposes - * to enable applications to generate a printable value that represents - * an odp_crypto_compl_t handle. + * Result of the crypto operation can be checked using odp_crypto_result(). + * Parse flags in packet metadata are not affected by the crypto operation. + * In particular, odp_packet_has_error() can not be used for checking if the + * crypto operation succeeded. + * + * Use of the pkt_out parameter depends on the configured crypto operation + * type as described below. + * + * ODP_CRYPTO_OP_TYPE_LEGACY: + * + * Caller should initialize each element of pkt_out either with the desired + * output packet handle or with ODP_PACKET_INVALID to make ODP allocate a new + * packet from provided pool. + * + * All packet data and metadata are copied from the input packet to the output + * packet before the requested crypto operation is performed to the output + * packet. If an output packet is given to the operation, it must be at least + * as long as the input packet and, in encode operations, long enough for the + * hash result to be fully inside the packet data. Memory layout of the output + * packet may change during the crypto operation. If the output packet is + * longer than needed, it is not truncated and the extra data bytes retain + * their content. + * + * It is ok to pass the same packet handle as both the input packet and the + * output packet for the same crypto operation. In that case the input packet + * is consumed but returned as the output packet (with possibly different + * memory layout). + * + * ODP_CRYPTO_OP_TYPE_BASIC: + * + * ODP allocates the output packet from the pool from which the input + * packet was allocated. The processed input packet is consumed. All + * packet data and metadata are copied from the input packet to the output + * packet before the requested crypto operation is applied to the output + * packet. Memory layout (including packet data pointers, head and tail room, + * segmentation) of the output packet may differ from that of the input + * packet. + * + * The value of pkt_out[n] is ignored as pkt_out[n] is used purely as an + * output parameter that returns the handle of the newly allocated packet. + * + * ODP_CRYPTO_OP_TYPE_OOP: + * + * Writes the output bytes of the crypto operation in a caller provided + * output packet passed through pkt_out[n]. Input packets are not consumed + * nor modified. Memory layout (including packet data pointers, head and + * tail room, segmentation) of the output packet may change during the + * operation. + * + * Crypto output is the processed crypto_range, auth_range and + * MAC/digest (in encode sessions) of the input packet. The operation + * behaves as if crypto range and auth range were first copied from the + * input packet to the output packet and then the crypto operation + * was applied to the output packet. + * + * Auth range of (AEAD) algorithms that ignore auth range is not copied. + * + * The offset of the crypto range and auth range in the output packet is + * the same as in the input packet, adjusted by dst_offset_shift operation + * parameter. + * + * pkt_out[n] must be a valid handle to a packet that is long enough to + * contain the shifted crypto range, auth range and, in encode sessions, + * the MAC/digest result. pkt_out[n] must not be the same as any input + * packet or any other output packet. + * + * OOP_CRYPTO_OP_TYPE_BASIC_AND_OOP: + * + * Behaves as the ODP_CRYPTO_OP_TYPE_BASIC operation type if pkt_out[n] is + * ODP_PACKET_INVALID. Otherwise behaves as the ODP_CRYPTO_OP_TYPE_OOP + * operation type. + * + * @param pkt_in Packets to be processed + * @param[in,out] pkt_out Packet handle array for resulting packets + * @param param Operation parameters array + * @param num_pkt Number of packets to be processed + * + * @return Number of input packets processed (0 ... num_pkt) + * @retval <0 on failure */ -uint64_t odp_crypto_compl_to_u64(odp_crypto_compl_t hdl); +int odp_crypto_op(const odp_packet_t pkt_in[], + odp_packet_t pkt_out[], + const odp_crypto_packet_op_param_t param[], + int num_pkt); /** - * Initialize crypto session parameters + * Crypto packet operation * - * Initialize an odp_crypto_session_param_t to its default values for - * all fields. + * Performs the ASYNC cryptographic operations specified during session + * creation on the packets. Behaves otherwise like odp_crypto_op() but + * returns output packets through events. * - * @param param Pointer to odp_crypto_session_param_t to be initialized + * With operation types other than ODP_CRYPTO_OP_TYPE_LEGACY, packet + * data of processed packets may not be valid before odp_crypto_result() + * has been called. + * + * With ODP_CRYPTO_OP_TYPE_OOP, an enqueued input packet is consumed but + * returned back unmodified after the crypto operation is complete. The + * caller may not access the input packet until getting the handle back + * through odp_crypto_result(). + * + * All arrays should be of num_pkt size, except that pkt_out parameter + * is ignored when the crypto operation type is ODP_CRYPTO_OP_TYPE_BASIC. + * + * From packet ordering perspective this function behaves as if each input + * packet was enqueued to a crypto session specific ODP queue in the order + * the packets appear in the parameter array. The conceptual session input + * queue has the same order type (ODP_QUEUE_ORDER_KEEP or + * ODP_QUEUE_ORDER_IGNORE) as the completion queue of the session. + * The order of output events of a crypto session in a completion queue is + * the same as the order of the corresponding input packets in the conceptual + * session input queue. The order of output events of different crypto + * sessions is not defined even when they go through the same crypto + * completion queue. + * + * @param pkt_in Packets to be processed + * @param pkt_out Packet handle array for resulting packets + * @param param Operation parameters array + * @param num_pkt Number of packets to be processed + * + * @return Number of input packets consumed (0 ... num_pkt) + * @retval <0 on failure */ -void odp_crypto_session_param_init(odp_crypto_session_param_t *param); +int odp_crypto_op_enq(const odp_packet_t pkt_in[], + const odp_packet_t pkt_out[], + const odp_crypto_packet_op_param_t param[], + int num_pkt); /** * @} diff --git a/include/odp/api/spec/crypto_types.h b/include/odp/api/spec/crypto_types.h new file mode 100644 index 000000000..579022762 --- /dev/null +++ b/include/odp/api/spec/crypto_types.h @@ -0,0 +1,1059 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited + * Copyright (c) 2021-2023 Nokia + */ + +/** + * @file + * + * ODP crypto types */ + +#ifndef ODP_API_SPEC_CRYPTO_TYPES_H_ +#define ODP_API_SPEC_CRYPTO_TYPES_H_ +#include <odp/visibility_begin.h> + +#include <odp/api/packet_types.h> +#include <odp/api/pool_types.h> +#include <odp/api/std_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup odp_crypto ODP CRYPTO + * @{ + */ + +/** + * @def ODP_CRYPTO_SESSION_INVALID + * Invalid session handle + */ + +/** + * @typedef odp_crypto_session_t + * Crypto API opaque session handle + */ + +/** + * Crypto API operation mode + */ +typedef enum { + /** Synchronous, return results immediately */ + ODP_CRYPTO_SYNC, + /** Asynchronous, return results via posted event */ + ODP_CRYPTO_ASYNC, +} odp_crypto_op_mode_t; + +/** + * Crypto API operation + */ +typedef enum { + /** Encrypt and/or compute authentication ICV */ + ODP_CRYPTO_OP_ENCODE, + /** Decrypt and/or verify authentication ICV */ + ODP_CRYPTO_OP_DECODE, +} odp_crypto_op_t; + +/** + * Crypto API cipher algorithm + */ +typedef enum { + /** No cipher algorithm specified */ + ODP_CIPHER_ALG_NULL, + + /** DES */ + ODP_CIPHER_ALG_DES, + + /** Triple DES with cipher block chaining */ + ODP_CIPHER_ALG_3DES_CBC, + + /** Triple DES with Electronic Codebook */ + ODP_CIPHER_ALG_3DES_ECB, + + /** AES with cipher block chaining */ + ODP_CIPHER_ALG_AES_CBC, + + /** AES with counter mode */ + ODP_CIPHER_ALG_AES_CTR, + + /** AES with electronic codebook */ + ODP_CIPHER_ALG_AES_ECB, + + /** AES with 128-bit cipher feedback */ + ODP_CIPHER_ALG_AES_CFB128, + + /** AES with XEX-based tweaked-codebook mode with ciphertext stealing + * (XTS) */ + ODP_CIPHER_ALG_AES_XTS, + + /** AES-GCM + * + * AES in Galois/Counter Mode (GCM) algorithm. GCM provides both + * authentication and ciphering of data (authenticated encryption) + * in the same operation. Hence this algorithm must be paired always + * with ODP_AUTH_ALG_AES_GCM authentication. + */ + ODP_CIPHER_ALG_AES_GCM, + + /** AES-CCM + * + * AES in Counter with CBC-MAC (CCM) mode algorithm. CCM provides both + * authentication and ciphering of data (authenticated encryption) + * in the same operation. Hence this algorithm must be paired always + * with ODP_AUTH_ALG_AES_CCM authentication. + */ + ODP_CIPHER_ALG_AES_CCM, + + /** ChaCha20-Poly1305 + * + * ChaCha20 with Poly1305 provide both authentication and ciphering of + * data (authenticated encryption) in the same operation. Hence this + * algorithm must be paired always with ODP_AUTH_ALG_CHACHA20_POLY1305 + * authentication. + */ + ODP_CIPHER_ALG_CHACHA20_POLY1305, + + /** Confidentiality F8 algorithm (UEA1) + * + * KASUMI-based F8 algorithm (also known as UEA1). + * + * IV should be formatted according to the 3GPP TS 35.201: + * COUNT || BEARER || DIRECTION || 0...0 + */ + ODP_CIPHER_ALG_KASUMI_F8, + + /** Confidentiality UEA2 algorithm (128-EEA1) + * + * SNOW 3G-based UEA2 algorithm (also known as 128-EEA1). + * + * IV (128 bits) should be formatted according to the ETSI/SAGE + * UEA2 & UIA2 specification: + * COUNT || BEARER || DIRECTION || 0...0 || + * COUNT || BEARER || DIRECTION || 0...0 || + */ + ODP_CIPHER_ALG_SNOW3G_UEA2, + + /** Confidentiality 128-EEA2 algorithm + * + * AES-CTR-based 128-EEA2 algorithm. + * + * IV (128 bits) should be formatted according to the ETSI/SAGE + * 128-EAA2 & 128-EIA2 specification: + * COUNT || BEARER || DIRECTION || 0....0 + */ + ODP_CIPHER_ALG_AES_EEA2, + + /** ZUC based confidentiality algorithm + * + * 128-EEA3/128-NEA3 algorithm when key length is 128 bits. + * + * IV (128 bits) should be formatted according to the ETSI/SAGE + * 128-EEA3 & 128-EIA3 specification: + * COUNT || BEARER || DIRECTION || 0...0 || + * COUNT || BEARER || DIRECTION || 0...0 || + * + * 256-bit key length support is experimental and subject to + * change. The following variants may be supported: + * + * - ZUC-256 with 25 byte IV (of which 184 bits are variable) + * as specified in "The ZUC-256 Stream Cipher". + * - ZUC-256 with 16 byte IV as specified in + * "An Addendum to the ZUC-256 Stream Cipher", + * https://eprint.iacr.org/2021/1439 + */ + ODP_CIPHER_ALG_ZUC_EEA3, + +} odp_cipher_alg_t; + +/** + * Crypto API authentication algorithm + */ +typedef enum { + /** No authentication algorithm specified */ + ODP_AUTH_ALG_NULL, + + /** HMAC-MD5 + * + * MD5 algorithm in HMAC mode + */ + ODP_AUTH_ALG_MD5_HMAC, + + /** HMAC-SHA-1 + * + * SHA-1 algorithm in HMAC mode + */ + ODP_AUTH_ALG_SHA1_HMAC, + + /** HMAC-SHA-224 + * + * SHA-224 algorithm in HMAC mode + */ + ODP_AUTH_ALG_SHA224_HMAC, + + /** HMAC-SHA-256 + * + * SHA-256 algorithm in HMAC mode + */ + ODP_AUTH_ALG_SHA256_HMAC, + + /** HMAC-SHA-384 + * + * SHA-384 algorithm in HMAC mode + */ + ODP_AUTH_ALG_SHA384_HMAC, + + /** HMAC-SHA-512 + * + * SHA-512 algorithm in HMAC mode + */ + ODP_AUTH_ALG_SHA512_HMAC, + + /** AES-GCM + * + * AES in Galois/Counter Mode (GCM) algorithm. GCM provides both + * authentication and ciphering of data (authenticated encryption) + * in the same operation. Hence this algorithm must be paired always + * with ODP_CIPHER_ALG_AES_GCM cipher. + */ + ODP_AUTH_ALG_AES_GCM, + + /** AES-GMAC + * + * AES Galois Message Authentication Code (GMAC) algorithm. AES-GMAC + * is based on AES-GCM operation, but provides authentication only. + * Hence this algorithm can be paired only with ODP_CIPHER_ALG_NULL + * cipher. + * + * NIST and RFC specifications of GMAC refer to all data to be + * authenticated as AAD. In ODP the data to be authenticated, i.e. + * AAD, is ODP packet data and specified using the auth_range + * parameter. The aad_length and aad_ptr parameters, which would + * require the data to be contiguous in memory, are ignored with + * AES-GMAC. + * + * GMAC needs an initialization vector, which must be passed via + * operation parameters (auth_iv_ptr). + */ + ODP_AUTH_ALG_AES_GMAC, + + /** AES-CCM + * + * AES in Counter with CBC-MAC (CCM) mode algorithm. CCM provides both + * authentication and ciphering of data (authenticated encryption) + * in the same operation. Hence this algorithm must be paired always + * with ODP_CIPHER_ALG_AES_CCM cipher. + */ + ODP_AUTH_ALG_AES_CCM, + + /** AES-CMAC + * + * AES Cipher-based Message Authentication Code (CMAC) algorithm. CMAC + * is a keyed hash function that is based on a symmetric key block + * cipher, such as the AES. + */ + ODP_AUTH_ALG_AES_CMAC, + + /** AES-XCBC-MAC + * + * AES CBC MAC for arbitrary-length messages (XCBC-MAC). + * + */ + ODP_AUTH_ALG_AES_XCBC_MAC, + + /** ChaCha20-Poly1305 AEAD + * + * ChaCha20 with Poly1305 provide both authentication and ciphering of + * data (authenticated encryption) in the same operation. Hence this + * algorithm must be paired always with + * ODP_CIPHER_ALG_CHACHA20_POLY1305 cipher. + */ + ODP_AUTH_ALG_CHACHA20_POLY1305, + + /** Integrity F9 algorithm (UIA1) + * + * KASUMI-based F9 algorithm (also known as UIA1). + * + * IV (9 bytes) is a concatenation of COUNT (32b), FRESH (32b) and + * DIRECTION (LSB-aligned, 1b). + * IV (8 bytes) is a concatenation of COUNT (32b) and FRESH (32b) + * DIRECTION (1b) and padding should come at the end of message. + */ + ODP_AUTH_ALG_KASUMI_F9, + + /** Integrity UIA2 algorithm (128-EIA1) + * + * SNOW 3G-based UIA2 algorithm (also known as 128-EIA1). + * IV (128 bits) should be formatted according to the ETSI/SAGE + * UEA2 & UIA2 specification: + * COUNT || FRESH || + * DIRECTION XOR COUNT0 || COUNT1 .. COUNT31 || + * FRESH0 .. FRESH15 || FRESH16 XOR DIRECTION || FRESH17 .. FRESH31 + */ + ODP_AUTH_ALG_SNOW3G_UIA2, + + /** Integrity 128-EIA2 algorithm + * + * AES_CMAC-based 128-EIA2 algorithm. + * + * IV (64 bits) should be formatted according to the ETSI/SAGE + * 128-EEA2 & 128-EIA2 specification: + * COUNT || BEARER || DIRECTION || 0....0 + */ + ODP_AUTH_ALG_AES_EIA2, + + /** ZUC-based integrity algorithm. + * + * 128-EIA3/128-NIA3 algorithm when key length is 128 bits. + * + * IV (128 bits) should be formatted according to the ETSI/SAGE + * 128-EEA3 & 128-EIA2 specification: + * COUNT || BEARER || + * DIRECTION XOR COUNT0 || COUNT1 .. COUNT31 || + * BEARER || 0...0 || DIRECTION || 0...0 + * + * 256-bit key length support is experimental and subject to + * change. The following variants may be supported: + * + * - ZUC-256 with 25 byte IV (of which 184 bits are variable) and + * 32/64/128 bit MAC as specified in "The ZUC-256 Stream Cipher". + * - ZUC-256 with 16 byte IV and 32/64/128 bit MAC as specified in + * "An Addendum to the ZUC-256 Stream Cipher", + * https://eprint.iacr.org/2021/1439 + */ + ODP_AUTH_ALG_ZUC_EIA3, + + /** MD5 algorithm */ + ODP_AUTH_ALG_MD5, + + /** SHA1 algorithm */ + ODP_AUTH_ALG_SHA1, + + /** 224 bit SHA2 algorithm */ + ODP_AUTH_ALG_SHA224, + + /** 256 bit SHA2 algorithm */ + ODP_AUTH_ALG_SHA256, + + /** 384 bit SHA2 algorithm */ + ODP_AUTH_ALG_SHA384, + + /** 512 bit SHA2 algorithm */ + ODP_AUTH_ALG_SHA512, + +} odp_auth_alg_t; + +/** + * Cipher algorithms in a bit field structure + */ +typedef union odp_crypto_cipher_algos_t { + /** Cipher algorithms */ + struct { + /** ODP_CIPHER_ALG_NULL */ + uint32_t null : 1; + + /** ODP_CIPHER_ALG_DES */ + uint32_t des : 1; + + /** ODP_CIPHER_ALG_3DES_CBC */ + uint32_t trides_cbc : 1; + + /** ODP_CIPHER_ALG_3DES_ECB */ + uint32_t trides_ecb : 1; + + /** ODP_CIPHER_ALG_AES_CBC */ + uint32_t aes_cbc : 1; + + /** ODP_CIPHER_ALG_AES_CTR */ + uint32_t aes_ctr : 1; + + /** ODP_CIPHER_ALG_AES_ECB */ + uint32_t aes_ecb : 1; + + /** ODP_CIPHER_ALG_AES_CFB128 */ + uint32_t aes_cfb128 : 1; + + /** ODP_CIPHER_ALG_AES_XTS */ + uint32_t aes_xts : 1; + + /** ODP_CIPHER_ALG_AES_GCM */ + uint32_t aes_gcm : 1; + + /** ODP_CIPHER_ALG_AES_CCM */ + uint32_t aes_ccm : 1; + + /** ODP_CIPHER_ALG_CHACHA20_POLY1305 */ + uint32_t chacha20_poly1305 : 1; + + /** ODP_CIPHER_ALG_KASUMI_F8 */ + uint32_t kasumi_f8 : 1; + + /** ODP_CIPHER_ALG_SNOW3G_UEA2 */ + uint32_t snow3g_uea2 : 1; + + /** ODP_CIPHER_ALG_AES_EEA2 */ + uint32_t aes_eea2 : 1; + + /** ODP_CIPHER_ALG_ZUC_EEA3 */ + uint32_t zuc_eea3 : 1; + + } bit; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or bitwise + * operations over the entire structure. */ + uint32_t all_bits; +} odp_crypto_cipher_algos_t; + +/** + * Authentication algorithms in a bit field structure + */ +typedef union odp_crypto_auth_algos_t { + /** Authentication algorithms */ + struct { + /** ODP_AUTH_ALG_NULL */ + uint32_t null : 1; + + /** ODP_AUTH_ALG_MD5_HMAC */ + uint32_t md5_hmac : 1; + + /** ODP_AUTH_ALG_SHA1_HMAC */ + uint32_t sha1_hmac : 1; + + /** ODP_AUTH_ALG_SHA224_HMAC */ + uint32_t sha224_hmac : 1; + + /** ODP_AUTH_ALG_SHA256_HMAC */ + uint32_t sha256_hmac : 1; + + /** ODP_AUTH_ALG_SHA384_HMAC */ + uint32_t sha384_hmac : 1; + + /** ODP_AUTH_ALG_SHA512_HMAC */ + uint32_t sha512_hmac : 1; + + /** ODP_AUTH_ALG_AES_GCM */ + uint32_t aes_gcm : 1; + + /** ODP_AUTH_ALG_AES_GMAC*/ + uint32_t aes_gmac : 1; + + /** ODP_AUTH_ALG_AES_CCM */ + uint32_t aes_ccm : 1; + + /** ODP_AUTH_ALG_AES_CMAC*/ + uint32_t aes_cmac : 1; + + /** ODP_AUTH_ALG_AES_XCBC_MAC*/ + uint32_t aes_xcbc_mac : 1; + + /** ODP_AUTH_ALG_CHACHA20_POLY1305 */ + uint32_t chacha20_poly1305 : 1; + + /** ODP_AUTH_ALG_KASUMI_F9 */ + uint32_t kasumi_f9 : 1; + + /** ODP_AUTH_ALG_SNOW3G_UIA2 */ + uint32_t snow3g_uia2 : 1; + + /** ODP_AUTH_ALG_AES_EIA2 */ + uint32_t aes_eia2 : 1; + + /** ODP_AUTH_ALG_ZUC_EIA3 */ + uint32_t zuc_eia3 : 1; + + /** ODP_AUTH_ALG_MD5 */ + uint32_t md5 : 1; + + /** ODP_AUTH_ALG_SHA1 */ + uint32_t sha1 : 1; + + /** ODP_AUTH_ALG_SHA224 */ + uint32_t sha224 : 1; + + /** ODP_AUTH_ALG_SHA256 */ + uint32_t sha256 : 1; + + /** ODP_AUTH_ALG_SHA384 */ + uint32_t sha384 : 1; + + /** ODP_AUTH_ALG_SHA512 */ + uint32_t sha512 : 1; + + } bit; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or bitwise + * operations over the entire structure. */ + uint32_t all_bits; +} odp_crypto_auth_algos_t; + +/** + * Crypto API key structure + */ +typedef struct odp_crypto_key { + /** Key data */ + uint8_t *data; + + /** Key length in bytes */ + uint32_t length; + +} odp_crypto_key_t; + +/** + * Type of odp_crypto_op()/odp_crypto_op_enq() calls. + */ +typedef enum odp_crypto_op_type_t { + /** + * Input packet data and metadata are copied to the output packet + * and then processed. Output packet is allocated by the caller + * or by ODP. + * + * This is the default value but will be deprecated in the future. + */ + ODP_CRYPTO_OP_TYPE_LEGACY, + + /** + * Input packet data and metadata are copied to the output packet + * and then processed. Output packet is allocated by ODP. + */ + ODP_CRYPTO_OP_TYPE_BASIC, + + /** + * Out-of-place crypto operation. Output packet is provided by + * the caller and the input packet is not consumed nor modified. + * + * Output of the crypto operation is written in the caller provided + * output packet without affecting other data and metadata of the + * output packet. Memory layout of the output packet may change + * during the operation. + * + * Crypto output is the processed crypto_range, auth_range and + * MAC/digest (in encode sessions) of the input packet. + */ + ODP_CRYPTO_OP_TYPE_OOP, + + /** + * Basic or out-of-place crypto operation depending on op params. + * + * If the output packet specified in a crypto operation (i.e. + * pkt_out[i] is ODP_PACKET_INVALID) then the packet is processed + * the same way as in the ODP_CRYPTO_OP_TYPE_BASIC operation type. + * Otherwise the packet is processed as in the ODP_CRYPTO_OP_TYPE_OOP + * operation type. + * + * Sessions of this operation type may have lower performance than + * the more specific operation types. + */ + ODP_CRYPTO_OP_TYPE_BASIC_AND_OOP, + +} odp_crypto_op_type_t; + +/** + * Crypto API session creation parameters + */ +typedef struct odp_crypto_session_param_t { + /** Encode vs. decode operation + * + * The default value is ODP_CRYPTO_OP_ENCODE. + */ + odp_crypto_op_t op; + + /** Crypto operation type + * + * This field defines how the crypto operation functions are + * to be called and what they return. In particular, this field + * specifies the interpretation of the output packet parameter, + * how output packets are allocated and what data and metadata + * they contain. + * + * The default value is ODP_CRYPTO_OP_TYPE_LEGACY. + */ + odp_crypto_op_type_t op_type; + + /** Cipher range unit + * + * When this flag is true, cipher range offset and length are in bits. + * Otherwise the offset and length are in bytes. + * + * If cipher capabilities do not include bit_mode, setting this to + * true causes a session creation failure. + * + * The default value is false. + */ + odp_bool_t cipher_range_in_bits; + + /** Auth range unit + * + * When this flag is true, auth range offset and length are in bits. + * Otherwise the offset and length are in bytes. + * + * If auth capabilities do not include bit_mode, setting this to + * true causes a session creation failure. + * + * The default value is false. + */ + odp_bool_t auth_range_in_bits; + + /** Authenticate cipher vs. plain text + * + * Controls ordering of authentication and cipher operations, + * and is relative to the operation (encode vs decode). When encoding, + * TRUE indicates the authentication operation should be performed + * after the cipher operation else before. When decoding, TRUE + * indicates the reverse order of operation. + * + * The value is ignored with authenticated encryption algorithms + * such as AES-GCM. The value is also ignored when one of the + * algorithms is null. + * + * true: Authenticate cipher text + * false: Authenticate plain text + * + * The default value is false. + */ + odp_bool_t auth_cipher_text; + + /** Hash result location may overlap authentication range + * + * This flag indicates that the hash result location may (but is + * not required to) overlap authentication range. Setting this + * flag may reduce performance. + * + * Default value is false. + */ + odp_bool_t hash_result_in_auth_range; + + /** Enable skipping crypto on per-packet basis + * + * When this flag is true, the null_crypto flag of crypto operation + * parameters can be set to request skipping of ciphering and + * authentication of a packet regardless of session configuration. + * This may be useful for preserving packet order between packets + * that require crypto processing and packets that do not. + * + * This flag must be set false when op_mode is ODP_CRYPTO_SYNC. + * + * The default value is false. + */ + odp_bool_t null_crypto_enable; + + /** Operation mode when using packet interface: sync or async + * + * The default value is ODP_CRYPTO_SYNC. + */ + odp_crypto_op_mode_t op_mode; + + /** Cipher algorithm + * + * Select cipher algorithm to be used. ODP_CIPHER_ALG_NULL indicates + * that ciphering is disabled. Use odp_crypto_capability() for + * supported algorithms. Note that some algorithms restrict choice of + * the pairing authentication algorithm. When ciphering is enabled + * cipher key and IV need to be set. The default value is + * ODP_CIPHER_ALG_NULL. + * + * When ciphering is disabled, i.e. cipher_alg is ODP_CIPHER_ALG_NULL, + * cipher_key and cipher_iv_len parameters are ignored. + */ + odp_cipher_alg_t cipher_alg; + + /** Cipher key + * + * Use odp_crypto_cipher_capa() for supported key and IV lengths. + */ + odp_crypto_key_t cipher_key; + + /** Cipher IV length. The default value is zero. */ + uint32_t cipher_iv_len; + + /** Authentication algorithm + * + * Select authentication algorithm to be used. ODP_AUTH_ALG_NULL + * indicates that authentication is disabled. Use + * odp_crypto_capability() for supported algorithms. Note that some + * algorithms restrict choice of the pairing cipher algorithm. When + * single algorithm provides both ciphering and authentication + * (i.e. Authenticated Encryption), authentication side key + * (auth_key) and IV (auth_iv) are ignored, and cipher side values are + * used instead. These algorithms ignore authentication side key + * and IV: ODP_AUTH_ALG_AES_GCM, ODP_AUTH_ALG_AES_CCM and + * ODP_AUTH_ALG_CHACHA20_POLY1305. Otherwise, all authentication side + * parameters must be set when authentication is enabled. The default + * value is ODP_AUTH_ALG_NULL. + * + * When authentication is disabled, i.e. auth_alg is + * ODP_AUTH_ALG_NULL, auth_key, auth_iv_len, auth_digest_len, + * auth_aad_len and hash_result_in_auth_range parameters are ignored. + */ + odp_auth_alg_t auth_alg; + + /** Authentication key + * + * Use odp_crypto_auth_capability() for supported key lengths. + */ + odp_crypto_key_t auth_key; + + /** Authentication IV length. The default value is zero. */ + uint32_t auth_iv_len; + + /** Authentication digest length in bytes + * + * Use odp_crypto_auth_capability() for supported digest lengths. + */ + uint32_t auth_digest_len; + + /** Additional Authenticated Data (AAD) length in bytes + * + * AAD length is constant for all operations (packets) of the session. + * Set to zero when AAD is not used. Use odp_crypto_auth_capability() + * for supported AAD lengths. The default value is zero. + */ + uint32_t auth_aad_len; + + /** Async mode completion event queue + * + * The completion queue is used to return completions from + * odp_crypto_op_enq() to the application. + */ + odp_queue_t compl_queue; + + /** Output pool + * + * When the output packet is not specified during the call to + * crypto operation in the legacy operation type, the output + * packet will be allocated from this pool. + * + * In ODP_CRYPTO_OP_TYPE_BASIC and ODP_CRYPTO_OP_TYPE_OOP + * operation types this must be set to ODP_POOL_INVALID. + */ + odp_pool_t output_pool; + +} odp_crypto_session_param_t; + +/** + * Crypto packet API per packet operation parameters + */ +typedef struct odp_crypto_packet_op_param_t { + /** Session handle from creation */ + odp_crypto_session_t session; + + /** IV pointer for cipher */ + const uint8_t *cipher_iv_ptr; + + /** IV pointer for authentication */ + const uint8_t *auth_iv_ptr; + + /** Offset from start of packet for hash result + * + * In case of decode sessions, the expected hash will be read from + * this offset from the input packet and compared with the calculated + * hash. After the operation the hash bytes will have undefined + * values except with out-of-place sessions (ODP_CRYPTO_OP_TYPE_OOP + * operation type). + * + * With out-of-place decode sessions the input packet is not modified + * but if the hash location overlaps the cipher range or the auth + * range, then the corresponding location in the output packet will + * have undefined content. + * + * In case of encode sessions the calculated hash will be stored in + * this offset in the output packet. + * + * If the hash_result_in_auth_range session parameter is true, + * the hash result location may overlap auth_range. In that case the + * result location will be treated as containing zero bytes for the + * purpose of hash calculation in decode sessions. + */ + uint32_t hash_result_offset; + + /** Pointer to AAD. AAD length is defined by 'auth_aad_len' + * session parameter. + */ + const uint8_t *aad_ptr; + + /** Data range to be ciphered. + * + * The range is given in bits or bytes as configured at session + * creation. + * + * Ignored by the null cipher with operation types other than + * ODP_CRYPTO_OP_TYPE_OOP. + * + * With the OOP operation type the cipher range is copied to the + * output packet even with the null cipher. Non-zero-length ranges + * are not necessarily supported with the null cipher and the OOP + * operation type. If the requested range is not supported, the + * crypto operation will fail. The failure is indicated through + * odp_crypto_result() or through a negative return value of + * odp_crypto_op()/odp_crypto_op_enq(). + **/ + odp_packet_data_range_t cipher_range; + + /** Data range to be authenticated + * + * The range is given in bits or bytes as configured at session + * creation. + * + * The value is ignored with authenticated encryption algorithms, + * such as AES-GCM, which authenticate data in the cipher range + * and the AAD. + * + * Ignored by the null auth algorithm with operation types other than + * ODP_CRYPTO_OP_TYPE_OOP. + * + * With the OOP operation type the auth range is copied to the + * output packet even with the null auth algorithm. Non-zero-length + * ranges are not necessarily supported with the null algorithm and + * the OOP operation type. If the requested range is not supported, + * the crypto operation will fail. The failure is indicated through + * odp_crypto_result() or through a negative return value of + * odp_crypto_op()/odp_crypto_op_enq(). + * + * As a special case AES-GMAC uses this field instead of aad_ptr + * for the data bytes to be authenticated. + */ + odp_packet_data_range_t auth_range; + + /** Shift of the output offsets with ODP_CRYPTO_OP_TYPE_OOP + * + * The processed crypto range and auth range of the input packet + * will be written in the output packet at the offset specified + * in the ranges (i.e. the same as in the input packet), shifted + * by this many bytes. This allows directing the output to + * a different packet offset than the offset of the input data. + * + * This is ignored if the crypto operation type is not + * ODP_CRYPTO_OP_TYPE_OOP. + */ + int32_t dst_offset_shift; + + /** Use null crypto algorithms + * + * Process packet using the null cipher and null auth algorithm + * instead of the algoithms configured in the session. This flag is + * ignored if the null_crypto_enable session parameter is not set. + */ + uint8_t null_crypto :1; + +} odp_crypto_packet_op_param_t; + +/** + * Crypto API session creation return code + */ +typedef enum { + /** Session created */ + ODP_CRYPTO_SES_ERR_NONE, + /** Creation failed, no resources */ + ODP_CRYPTO_SES_ERR_ENOMEM, + /** Creation failed, bad cipher params */ + ODP_CRYPTO_SES_ERR_CIPHER, + /** Creation failed, bad auth params */ + ODP_CRYPTO_SES_ERR_AUTH, + + /** Unsupported combination of algorithms + * + * The combination of cipher and auth algorithms with their + * specific parameters is not supported even if the algorithms + * appear in capabilities and are supported in combination with + * other algorithms or other algorithm specific parameters. + */ + ODP_CRYPTO_SES_ERR_ALG_COMBO, + + /** Unsupported order of cipher and auth + * + * The requested mutual order of ciphering and authentication + * is not supported with the chosen individual cipher and + * authentication algorithms. + */ + ODP_CRYPTO_SES_ERR_ALG_ORDER, + + /** Unsupported combination of session creation parameters + * + * The combination of provided session creation parameters is not + * supported. This error can occur when there are limitations that + * are not expressible through crypto capabilities or other error + * status values. + */ + ODP_CRYPTO_SES_ERR_PARAMS, +} odp_crypto_ses_create_err_t; + +/** + * Crypto API algorithm return code + */ +typedef enum { + /** Algorithm successful */ + ODP_CRYPTO_ALG_ERR_NONE, + /** Invalid range or packet size */ + ODP_CRYPTO_ALG_ERR_DATA_SIZE, + /** Computed ICV value mismatch */ + ODP_CRYPTO_ALG_ERR_ICV_CHECK, + /** Other error */ + ODP_CRYPTO_ALG_ERR_OTHER, +} odp_crypto_alg_err_t; + +/** + * Crypto API per packet operation completion status + */ +typedef struct odp_crypto_op_status { + /** Algorithm specific return code */ + odp_crypto_alg_err_t alg_err; +} odp_crypto_op_status_t; + +/** + * Crypto packet API operation result + */ +typedef struct odp_crypto_packet_result_t { + /** Input packet passed to odp_crypo_op_enq() when the operation + * type of the session is ODP_CRYPTO_OP_TYPE_OOP. In other cases + * this field does not have a valid value. + */ + odp_packet_t pkt_in; + + /** Cipher status */ + odp_crypto_op_status_t cipher_status; + + /** Authentication status */ + odp_crypto_op_status_t auth_status; + +} odp_crypto_packet_result_t; + +/** + * Crypto capabilities + */ +typedef struct odp_crypto_capability_t { + /** Maximum number of crypto sessions */ + uint32_t max_sessions; + + /** Supported packet operation in SYNC mode */ + odp_support_t sync_mode; + + /** Supported packet operation in ASYNC mode */ + odp_support_t async_mode; + + /** Supported cipher algorithms */ + odp_crypto_cipher_algos_t ciphers; + + /** Cipher algorithms implemented with HW offload */ + odp_crypto_cipher_algos_t hw_ciphers; + + /** Supported authentication algorithms */ + odp_crypto_auth_algos_t auths; + + /** Authentication algorithms implemented with HW offload */ + odp_crypto_auth_algos_t hw_auths; + + /** + * Scheduled crypto completion queue support + * + * This defines whether scheduled queues are supported as crypto + * compl_queue. + * 0: Scheduled queues are not supported as crypto completion queues + * 1: Scheduled queues are supported as crypto completion queues + * @see odp_crypto_session_param_t + */ + odp_bool_t queue_type_sched; + + /** + * Plain crypto completion queue support + * + * This defines whether plain queues are supported as crypto + * compl_queue. + * 0: Plain queues are not supported as crypto completion queues + * 1: Plain queues are supported as crypto completion queues + * @see odp_crypto_session_param_t + */ + odp_bool_t queue_type_plain; +} odp_crypto_capability_t; + +/** + * Cipher algorithm capabilities + */ +typedef struct odp_crypto_cipher_capability_t { + /** Key length in bytes */ + uint32_t key_len; + + /** IV length in bytes */ + uint32_t iv_len; + + /** Cipher supports bit mode + * + * This cipher can work on a range of bits in addition to a range of + * bytes. When this capability is not present, only byte ranges are + * supported. The unit of cipher range is selected at session creation + * through the cipher_range_in_bits session parameter. + * + * Note: In bit mode the cipher range must start on a byte boundary. + * Using an offset which is not divisible by 8 will result in + * undefined behaviour. + * + * Note2: If the range length in bit mode is not a multiple of 8, + * the remaining bits of the data in the last byte of the input/output + * will be the most significant bits, i.e. the most significant bit is + * considered to be the first bit of a byte for the purpose of input + * and output data range. The output bits that fall out of the output + * range are undefined. + */ + odp_bool_t bit_mode; + +} odp_crypto_cipher_capability_t; + +/** + * Authentication algorithm capabilities + */ +typedef struct odp_crypto_auth_capability_t { + /** Digest length in bytes */ + uint32_t digest_len; + + /** Key length in bytes */ + uint32_t key_len; + + /** IV length in bytes */ + uint32_t iv_len; + + /** Additional Authenticated Data (AAD) lengths */ + struct { + /** Minimum AAD length in bytes */ + uint32_t min; + + /** Maximum AAD length in bytes */ + uint32_t max; + + /** Increment of supported lengths between min and max + * (in bytes) */ + uint32_t inc; + } aad_len; + + /** Auth algorithm supports bit mode + * + * This auth algorithm can work on a range of bits in addition to + * a range of bytes. When this capability is not present, only byte + * ranges are supported. The unit of auth range is selected at session + * creation through the auth_range_in_bits session parameter. + * + * Note: In bit mode the auth range must start on a byte boundary. + * Using an offset which is not divisible by 8 will result in + * undefined behaviour. + * + * Note2: If the range length in bit mode is not a multiple of 8, + * the remaining bits of the data in the last byte of the input/output + * will be the most significant bits, i.e. the most significant bit is + * considered to be the first bit of a byte for the purpose of input + * and output data range. The output bits that fall out of the output + * range are undefined. + */ + odp_bool_t bit_mode; + +} odp_crypto_auth_capability_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/debug.h b/include/odp/api/spec/debug.h index b3b170f3e..4a3365a3e 100644 --- a/include/odp/api/spec/debug.h +++ b/include/odp/api/spec/debug.h @@ -1,7 +1,5 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited */ /** * @file @@ -9,14 +7,18 @@ * ODP debug */ -#ifndef ODP_API_DEBUG_H_ -#define ODP_API_DEBUG_H_ +#ifndef ODP_API_SPEC_DEBUG_H_ +#define ODP_API_SPEC_DEBUG_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif +/** @addtogroup odp_initialization + * @{ + */ + /** * @def ODP_STATIC_ASSERT * Compile time assertion macro. Fails compilation and outputs message 'msg' @@ -28,6 +30,10 @@ extern "C" { * @param msg Compile time error message to be displayed if cond is false */ +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/include/odp/api/spec/deprecated.h.in b/include/odp/api/spec/deprecated.h.in new file mode 100644 index 000000000..d062842c1 --- /dev/null +++ b/include/odp/api/spec/deprecated.h.in @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + */ + +/** + * @file + * + * Macro for deprecated API definitions + */ + +#ifndef ODP_API_SPEC_DEPRECATED_H_ +#define ODP_API_SPEC_DEPRECATED_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Deprecated API definitions + * + * Some API definitions may be deprecated by this or a previous API version. + * This macro controls if those are enabled (and visible to the application) + * or disabled. + * + * * 0: Deprecated API definitions are disabled (default) + * * 1: Deprecated API definitions are enabled + */ +#define ODP_DEPRECATED_API @ODP_DEPRECATED_API@ + +/** + * @def ODP_DEPRECATE + * + * Macro to deprecate API definitions + */ + +#if ODP_DEPRECATED_API +#define ODP_DEPRECATE(x) x +#else +#define ODP_DEPRECATE(x) _deprecated_ ## x +#endif + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/dma.h b/include/odp/api/spec/dma.h new file mode 100644 index 000000000..5303dc03f --- /dev/null +++ b/include/odp/api/spec/dma.h @@ -0,0 +1,370 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021-2023 Nokia + */ + +/** + * @file + * + * ODP DMA + */ + +#ifndef ODP_API_SPEC_DMA_H_ +#define ODP_API_SPEC_DMA_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/dma_types.h> +#include <odp/api/pool_types.h> + +/** @addtogroup odp_dma + * @{ + */ + +/** + * Query DMA capabilities + * + * Outputs DMA capabilities on success. + * + * @param[out] capa Pointer to a capability structure for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_dma_capability(odp_dma_capability_t *capa); + +/** + * Initialize DMA session parameters + * + * Initialize an odp_dma_param_t to its default values. + * + * @param[out] param Parameter structure to be initialized + */ +void odp_dma_param_init(odp_dma_param_t *param); + +/** + * Create DMA session + * + * Create a DMA session according to the parameters. The use of session name is optional. Unique + * names are not required. However, odp_dma_lookup() returns only a single matching named session. + * Use odp_dma_param_init() to initialize parameters into their default values. + * + * @param name DMA session name or NULL. Maximum string length is ODP_DMA_NAME_LEN. + * @param param DMA session parameters + * + * @return DMA session handle on success + * @retval ODP_DMA_INVALID on failure + */ +odp_dma_t odp_dma_create(const char *name, const odp_dma_param_t *param); + +/** + * Destroy DMA session + * + * A DMA session may be destroyed only when there are no active transfers in the session (all + * previously started transfers have completed). + * + * @param dma DMA session to be destroyed + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_dma_destroy(odp_dma_t dma); + +/** + * Find DMA session by name + * + * @param name DMA session name + * + * @return Handle of the first matching DMA session + * @retval ODP_DMA_INVALID DMA session could not be found + */ +odp_dma_t odp_dma_lookup(const char *name); + +/** + * Initialize DMA transfer parameters + * + * Initialize an odp_dma_transfer_param_t to its default values. + * + * @param[out] trs_param Parameter structure to be initialized + */ +void odp_dma_transfer_param_init(odp_dma_transfer_param_t *trs_param); + +/** + * Initialize DMA transfer completion parameters + * + * Initialize an odp_dma_compl_param_t to its default values. + * + * @param[out] compl_param Parameter structure to be initialized + */ +void odp_dma_compl_param_init(odp_dma_compl_param_t *compl_param); + +/** + * Perform DMA transfer + * + * Performs DMA transfer according to the session and transfer parameters. Returns 1 when + * the transfer was completed successfully. Returns 0 when the transfer was not performed + * due to resources being temporarily busy. In this case, the same transfer is likely to succeed + * after enough resources are available. Returns <0 on failure. + * + * The call outputs optionally transfer results on a non-zero return value. Use NULL as 'result' + * pointer if results are not required. + * + * @param dma DMA session + * @param trs_param Transfer parameters + * @param[out] result Pointer to transfer result structure for output, or NULL when not used + * + * @retval 1 when transfer completed successfully + * @retval 0 when resources are busy and transfer was not performed + * @retval <0 on failure + */ +int odp_dma_transfer(odp_dma_t dma, const odp_dma_transfer_param_t *trs_param, + odp_dma_result_t *result); + +/** + * Perform multiple DMA transfers + * + * Like odp_dma_transfer(), but performs 'num' transfers. + * + * @param dma DMA session + * @param trs_param Array of transfer parameter pointers + * @param[out] result Array of transfer result pointers for output, or NULL when not used + * @param num Number of transfers to perform. Both arrays have this many elements. + * + * @return Number of transfers completed successfully (1 ... num) + * @retval 0 when resources are busy and no transfers were performed + * @retval <0 on failure + */ +int odp_dma_transfer_multi(odp_dma_t dma, const odp_dma_transfer_param_t *trs_param[], + odp_dma_result_t *result[], int num); + +/** + * Start DMA transfer + * + * Starts asynchronous DMA transfer according to the session and transfer parameters. + * Completion parameters specify how transfer completion is reported. Returns 1 when the transfer + * was started successfully. Returns 0 when the transfer was not started due to resources being + * temporarily busy. In this case, the same transfer is likely to start successfully after enough + * resources are available. Returns <0 on failure. + * + * @param dma DMA session + * @param trs_param Transfer parameters + * @param compl_param Transfer completion parameters + * + * @retval 1 when transfer started successfully + * @retval 0 when resources are busy and transfer was not started + * @retval <0 on failure + * + * @see odp_dma_transfer_id_alloc(), odp_dma_transfer_done(), odp_dma_compl_result() + */ +int odp_dma_transfer_start(odp_dma_t dma, const odp_dma_transfer_param_t *trs_param, + const odp_dma_compl_param_t *compl_param); + +/** + * Start multiple DMA transfers + * + * Like odp_dma_transfer_start(), but starts 'num' transfers. + * + * @param dma DMA session + * @param trs_param Array of transfer parameter pointers + * @param compl_param Array of transfer completion parameter pointers + * @param num Number of transfers to start. Both parameter arrays have this many elements. + * + * @return Number of transfers started successfully (1 ... num) + * @retval 0 when resources are busy and no transfers were started + * @retval <0 on failure + */ +int odp_dma_transfer_start_multi(odp_dma_t dma, const odp_dma_transfer_param_t *trs_param[], + const odp_dma_compl_param_t *compl_param[], int num); + +/** + * Check if DMA transfer has completed + * + * Application must call this function for every transfer that was started in ODP_DMA_COMPL_POLL + * mode until a non-zero value is returned. The transfer identifier from completion parameters of + * the transfer start call is used. When a non-zero value is returned, the transfer is complete + * and the identifier may be freed or reused for another transfer. + * + * The call outputs optionally transfer results on a non-zero return value. Use NULL as 'result' + * pointer if results are not required. + * + * @param dma DMA session + * @param transfer_id Transfer identifier + * @param[out] result Pointer to transfer result structure for output, or NULL when not used. + * + * @retval 0 transfer has not finished + * @retval >0 transfer has finished successfully + * @retval <0 on failure + */ +int odp_dma_transfer_done(odp_dma_t dma, odp_dma_transfer_id_t transfer_id, + odp_dma_result_t *result); + +/** + * Allocate DMA transfer identifier + * + * Transfer identifiers are used in #ODP_DMA_COMPL_POLL mode. It identifies a previously started + * transfer for an odp_dma_transfer_done() call. The maximum number of transfer identifiers is + * implementation specific, but there are at least odp_dma_capability_t::max_transfers identifiers + * per session. + * + * @param dma DMA session + * + * @return Transfer identifier + * @retval ODP_DMA_TRANSFER_ID_INVALID Transfer identifier could not be allocated + */ +odp_dma_transfer_id_t odp_dma_transfer_id_alloc(odp_dma_t dma); + +/** + * Free DMA transfer identifier + * + * @param dma DMA session + * @param transfer_id DMA transfer identifier to be freed + */ +void odp_dma_transfer_id_free(odp_dma_t dma, odp_dma_transfer_id_t transfer_id); + +/** + * Get printable value for DMA session handle + * + * @param dma Handle to be converted for debugging + * + * @return uint64_t value that can be used to print/display this handle + */ +uint64_t odp_dma_to_u64(odp_dma_t dma); + +/** + * Print debug info about DMA session + * + * Print implementation defined information about DMA session to the ODP log. + * The information is intended to be used for debugging. + * + * @param dma DMA session handle + */ +void odp_dma_print(odp_dma_t dma); + +/** + * Check DMA completion event + * + * Reads DMA completion event (ODP_EVENT_DMA_COMPL), and returns if the transfer succeeded or + * failed. The call outputs optionally transfer results. Use NULL as 'result' pointer if results + * are not required. + * + * @param dma_compl DMA completion event + * @param[out] result Pointer to transfer result structure for output, or NULL when not used. + * + * @retval 0 Transfer was successful + * @retval <0 Transfer failed + */ +int odp_dma_compl_result(odp_dma_compl_t dma_compl, odp_dma_result_t *result); + +/** + * Convert event to DMA completion event + * + * Converts an ODP_EVENT_DMA_COMPL type event to a DMA completion event. + * + * @param ev Event handle + * + * @return DMA completion event handle + */ +odp_dma_compl_t odp_dma_compl_from_event(odp_event_t ev); + +/** + * Convert DMA completion event to event + * + * @param dma_compl DMA completion event handle + * + * @return Event handle + */ +odp_event_t odp_dma_compl_to_event(odp_dma_compl_t dma_compl); + +/** + * Get printable value for DMA completion event handle + * + * @param dma_compl Handle to be converted for debugging + * + * @return uint64_t value that can be used to print/display this handle + */ +uint64_t odp_dma_compl_to_u64(odp_dma_compl_t dma_compl); + +/** + * DMA completion event user area + * + * Returns pointer to the user area associated with the completion event. Size of the area is fixed + * and defined in completion event pool parameters. + * + * @param dma_compl DMA completion event handle + * + * @return Pointer to the user area of the completion event + * @retval NULL The completion event does not have user area + */ +void *odp_dma_compl_user_area(odp_dma_compl_t dma_compl); + +/** + * Allocate DMA completion event + * + * Allocates a DMA completion event from a pool. The pool must have been created with + * odp_dma_pool_create() call. All completion event metadata are set to their default values. + * + * @param pool Pool handle + * + * @return DMA completion event handle + * @retval ODP_DMA_COMPL_INVALID Completion event could not be allocated + */ +odp_dma_compl_t odp_dma_compl_alloc(odp_pool_t pool); + +/** + * Free DMA completion event + * + * Frees a DMA completion event into the pool it was allocated from. + * + * @param dma_compl DMA completion event handle + */ +void odp_dma_compl_free(odp_dma_compl_t dma_compl); + +/** + * Print DMA completion event debug information + * + * Prints implementation specific debug information about + * the completion event to the ODP log. + * + * @param dma_compl DMA completion event handle + */ +void odp_dma_compl_print(odp_dma_compl_t dma_compl); + +/** + * Initialize DMA completion event pool parameters + * + * Initialize an odp_dma_pool_param_t to its default values. + * + * @param[out] pool_param Parameter structure to be initialized + */ +void odp_dma_pool_param_init(odp_dma_pool_param_t *pool_param); + +/** + * Create DMA completion event pool + * + * Creates a pool of DMA completion events (ODP_EVENT_DMA_COMPL). Pool type is ODP_POOL_DMA_COMPL. + * The use of pool name is optional. Unique names are not required. However, odp_pool_lookup() + * returns only a single matching pool. Use odp_dma_pool_param_init() to initialize pool parameters + * into their default values. Parameters values must not exceed pool capabilities + * (odp_dma_pool_capability_t). + * + * @param name Name of the pool or NULL. Maximum string length is ODP_POOL_NAME_LEN. + * @param pool_param Pool parameters + * + * @return Handle of the created pool + * @retval ODP_POOL_INVALID Pool could not be created + */ +odp_pool_t odp_dma_pool_create(const char *name, const odp_dma_pool_param_t *pool_param); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif + diff --git a/include/odp/api/spec/dma_types.h b/include/odp/api/spec/dma_types.h new file mode 100644 index 000000000..0a0e267df --- /dev/null +++ b/include/odp/api/spec/dma_types.h @@ -0,0 +1,576 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021-2023 Nokia + */ + +/** + * @file + * + * ODP DMA + */ + +#ifndef ODP_API_SPEC_DMA_TYPES_H_ +#define ODP_API_SPEC_DMA_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/event_types.h> +#include <odp/api/packet_types.h> +#include <odp/api/queue_types.h> +#include <odp/api/std_types.h> + +/** @defgroup odp_dma ODP DMA + * DMA offload + * @{ + */ + +/** + * @typedef odp_dma_t + * DMA session + */ + +/** + * @typedef odp_dma_transfer_id_t + * DMA transfer identifier + */ + +/** + * @typedef odp_dma_compl_t + * DMA completion event + */ + +/** + * @def ODP_DMA_INVALID + * Invalid DMA session + */ + +/** + * @def ODP_DMA_TRANSFER_ID_INVALID + * Invalid DMA transfer identifier + */ + +/** + * @def ODP_DMA_COMPL_INVALID + * Invalid DMA completion event + */ + +/** + * @def ODP_DMA_NAME_LEN + * Maximum DMA name length in chars including null char + */ + +/** + * DMA completion event pool capabilities + * + * Pool statistics are not supported with DMA completion event pools. + */ +typedef struct odp_dma_pool_capability_t { + /** Maximum number of DMA completion event pools + * + * See odp_pool_capability_t::max_pools for total capability. */ + uint32_t max_pools; + + /** Maximum number of DMA completion events in a pool */ + uint32_t max_num; + + /** Maximum user area size in bytes */ + uint32_t max_uarea_size; + + /** Pool user area persistence + * + * See buf.uarea_persistence of odp_pool_capability_t for details + * (odp_pool_capability_t::uarea_persistence). */ + odp_bool_t uarea_persistence; + + /** Minimum size of thread local cache */ + uint32_t min_cache_size; + + /** Maximum size of thread local cache */ + uint32_t max_cache_size; + +} odp_dma_pool_capability_t; + +/** + * DMA completion event pool parameters + */ +typedef struct odp_dma_pool_param_t { + /** Number of DMA completion events in the pool + * + * Maximum value is defined by 'max_num' pool capability */ + uint32_t num; + + /** User area size in bytes + * + * Maximum value is defined by 'max_uarea_size' pool capability. Specify as 0 if no user + * area is needed. The default value is 0. + */ + uint32_t uarea_size; + + /** Parameters for user area initialization */ + struct { + /** See uarea_init.init_fn of odp_pool_param_t for details + * (odp_pool_param_t::init_fn). Function is called during + * odp_dma_pool_create(). */ + void (*init_fn)(void *uarea, uint32_t size, void *args, uint32_t index); + + /** See uarea_init.args of odp_pool_param_t for details + * (odp_pool_param_t::args). */ + void *args; + + } uarea_init; + + /** Maximum number of events cached locally per thread + * + * See odp_pool_param_t::cache_size documentation for details. Valid values range from + * 'min_cache_size' to 'max_cache_size' capability. The default value is implementation + * specific and set by odp_dma_pool_param_init(). + */ + uint32_t cache_size; + +} odp_dma_pool_param_t; + +/* Includes pool_types.h, which depends on odp_dma_pool_param_t. */ +#include <odp/api/queue_types.h> + +/** + * DMA transfer direction + * + * Transfer direction defines source and destination memory type of DMA transfers. API specification + * defines only one option (#ODP_DMA_MAIN_TO_MAIN) for the transfer direction. It is used for + * transfers within the main memory. Some implementations may extend this enumeration with + * implementation specific directions and memory types (e.g. from main memory to a device, etc.). + */ +typedef uint32_t odp_dma_direction_t; + +/** DMA transfer within the main memory */ +#define ODP_DMA_MAIN_TO_MAIN 0x1u + +/** + * DMA transfer type + * + * Transfer type defines how DMA transfers operate data. Currently, only one transfer type is + * defined (#ODP_DMA_TYPE_COPY). + * + */ +typedef uint32_t odp_dma_transfer_type_t; + +/** Copy data + * + * Copy all data from source segment(s) to destination segment(s). There may be different + * number of source and destination segments in a transfer, but total length of all source + * segments must be equal to total length of all destination segments. Segments must not + * point to overlapping memory addresses. There are no alignment requirements for + * segment addresses or lengths. Data transfer from source to destination may happen + * in any segment and byte order. + */ +#define ODP_DMA_TYPE_COPY 0x1u + +/** + * DMA transfer completion mode + * + * Transfer completion mode defines how transfer completion is reported to the application. + * Completion modes are: #ODP_DMA_COMPL_NONE, #ODP_DMA_COMPL_SYNC, #ODP_DMA_COMPL_EVENT, and + * #ODP_DMA_COMPL_POLL + * + * If not otherwise specified, a DMA transfer is complete when memory reads and writes are complete + * for all its segments, and writes are visible to all memory observers (threads and + * HW accelerators). + */ +typedef uint32_t odp_dma_compl_mode_t; + +/** No completion indication + * + * Application uses odp_dma_transfer_start() call to start a DMA transfer, but does + * not request a completion notification for it. This can be useful for example when application + * starts a burst of transfers, but requests a completion event only on the last one + * (none on others). + */ +#define ODP_DMA_COMPL_NONE 0x1u + +/** Synchronous transfer + * + * Application uses odp_dma_transfer() call for DMA transfers. Each call performs + * the requested transfer and returns when the transfer is complete. + */ +#define ODP_DMA_COMPL_SYNC 0x2u + +/** Asynchronous transfer with completion event + * + * Application uses odp_dma_transfer_start() call to start a DMA transfer. The + * transfer is complete when application receives the completion event. + */ +#define ODP_DMA_COMPL_EVENT 0x4u + +/** Asynchronous transfer with completion polling + * + * Application uses odp_dma_transfer_start() call to start a DMA transfer and uses + * odp_dma_transfer_done() call to check if the transfer has completed. + */ +#define ODP_DMA_COMPL_POLL 0x8u + +/** + * DMA transfer data format + */ +typedef enum { + /** Data format is raw memory address */ + ODP_DMA_FORMAT_ADDR = 0, + + /** Data format is odp_packet_t */ + ODP_DMA_FORMAT_PACKET + +} odp_dma_data_format_t; + +/** + * DMA transfer ordering + * + * These options specify ordering of consecutive DMA transfers within a session. Transfer order + * is defined by the order of consecutive transfer (start) calls and the order of transfers + * within each multi-transfer call. Note that ordering option matters also when using + * odp_dma_transfer_multi() call, as ODP_DMA_ORDER_NONE allows implementation to perform transfers + * in parallel. + * + * These options do not apply to data (segment or byte) processing order within a transfer. + * If two transfers read/write overlapping memory areas, an appropriate transfer ordering option + * (e.g. ODP_DMA_ORDER_ALL) needs to be used for correct operation. + */ +typedef enum { + /** No specific ordering between transfers + * + * This may result the best performance (maximum implementation parallelism) as + * transfers may start and complete in any order. */ + ODP_DMA_ORDER_NONE = 0, + + /** Report transfer completions in order + * + * Transfers may be performed in any order, but transfer completions must be reported + * in the same order they were started within a session. This allows application to + * start multiple transfers and wait only completion of the last one. */ + ODP_DMA_ORDER_COMPL, + + /** Perform all transfers in order + * + * Perform transfers and report their completions in the same order they were started + * within a session. This enables for example a subsequent transfer to read data + * written by a previous transfer. */ + ODP_DMA_ORDER_ALL + +} odp_dma_transfer_order_t; + +/** + * DMA transfer multi-thread safeness + */ +typedef enum { + /** Multi-thread safe operation + * + * Multiple threads may perform DMA transfers concurrently on the same DMA session. + */ + ODP_DMA_MT_SAFE = 0, + + /** Application serializes operations + * + * Multiple threads may perform DMA transfers on the same DMA session, but application + * serializes all transfer related calls (odp_dma_transfer(), odp_dma_transfer_start(), + * _start_multi(), _done() and _result()). Threads do not call any of these operations + * concurrently. + */ + ODP_DMA_MT_SERIAL + +} odp_dma_mt_mode_t; + +/** + * DMA capabilities + */ +typedef struct odp_dma_capability_t { + /** Maximum number of DMA sessions + * + * The value of zero means that DMA offload is not available. + */ + uint32_t max_sessions; + + /** Maximum number of transfers per DMA session + * + * Maximum number of transfers that can be in-flight (started but not yet completed) + * per session. When this limit is reached, new transfer requests may not be accepted + * until some previously started transfers are complete. */ + uint32_t max_transfers; + + /** Maximum number of source segments in a single transfer */ + uint32_t max_src_segs; + + /** Maximum number of destination segments in a single transfer */ + uint32_t max_dst_segs; + + /** Maximum number of destination and source segments combined in a single transfer */ + uint32_t max_segs; + + /** Maximum segment length in bytes + * + * This is the maximum length of any source or destination segment. */ + uint32_t max_seg_len; + + /** Supported completion modes + * + * Each supported completion mode has a corresponding flag set in the mask. + * Synchronous transfer (ODP_DMA_COMPL_SYNC) is always supported. + */ + odp_dma_compl_mode_t compl_mode_mask; + + /** + * Scheduled queue support + * + * 0: Scheduled queues are not supported as DMA completion queues + * 1: Scheduled queues are supported as DMA completion queues + */ + odp_bool_t queue_type_sched; + + /** + * Plain queue support + * + * 0: Plain queues are not supported as DMA completion queues + * 1: Plain queues are supported as DMA completion queues + */ + odp_bool_t queue_type_plain; + + /** DMA completion event pool capabilities */ + odp_dma_pool_capability_t pool; + +} odp_dma_capability_t; + +/** + * DMA session parameters + */ +typedef struct odp_dma_param_t { + /** Transfer direction + * + * The default value is ODP_DMA_MAIN_TO_MAIN. + */ + odp_dma_direction_t direction; + + /** Transfer type + * + * The default value is ODP_DMA_TYPE_COPY. + */ + odp_dma_transfer_type_t type; + + /** Transfer completion modes + * + * Specify the completion modes application will use within the session. + * + * Multiple modes may be selected, but it is implementation specific which combinations + * are supported. If an unsupported combination is requested odp_dma_create() returns + * a failure. See odp_dma_capability_t::compl_mode_mask for the supported modes. + */ + odp_dma_compl_mode_t compl_mode_mask; + + /** Transfer operation multi-thread safeness + * + * The default value is ODP_DMA_MT_SAFE. + */ + odp_dma_mt_mode_t mt_mode; + + /** Transfer ordering + * + * The default value is ODP_DMA_ORDER_NONE. + */ + odp_dma_transfer_order_t order; + +} odp_dma_param_t; + +/** + * DMA segment + */ +typedef struct odp_dma_seg_t { + /** Segment start address or packet handle */ + union { + /** Segment start address in memory + * + * Defines segment start when data format is #ODP_DMA_FORMAT_ADDR. Ignored with + * other data formats. + */ + void *addr; + + /** Packet handle + * + * Defines the packet when data format is #ODP_DMA_FORMAT_PACKET. Ignored + * with other data formats. */ + odp_packet_t packet; + + }; + + /** Segment length in bytes + * + * Defines segment length with all data formats. The maximum value is defined by + * max_seg_len capability. When data format is #ODP_DMA_FORMAT_PACKET, the value must not + * exceed odp_packet_len() - 'offset'. + */ + uint32_t len; + + /** Segment start offset into the packet + * + * Defines segment start within the packet data. The offset is calculated from + * odp_packet_data() position, and the value must not exceed odp_packet_len(). + * Ignored when data format is other than #ODP_DMA_FORMAT_PACKET. + */ + uint32_t offset; + + /** Segment hints + * + * Depending on the implementation, setting these hints may improve performance. + * Initialize all unused bits to zero. + */ + union { + /** Segment hints bit field */ + struct { + /** Allow full cache line access + * + * When set to 1, data on the same cache line with the destination segment + * is allowed to be overwritten. This hint is ignored on source segments. + */ + uint16_t full_lines : 1; + }; + + /** All bits of the bit field structure + * + * This can be used to set/clear all bits, or to perform bitwise operations + * on those. + */ + uint16_t all_hints; + }; + +} odp_dma_seg_t; + +/** + * DMA transfer parameters + * + * These parameters define data sources and destinations for a DMA transfer. Capabilities specify + * the maximum number of segments and the maximum segment length that are supported. + * + * The selected data format specifies how segment structure fields are used. When data format is + * ODP_DMA_FORMAT_ADDR, set segment start address (odp_dma_seg_t::addr) and + * length (odp_dma_seg_t::len). When data format is ODP_DMA_FORMAT_PACKET, set packet + * handle (odp_dma_seg_t::packet), segment start offset (odp_dma_seg_t::offset) and length. + * If a DMA segment spans over multiple packet segments, it is considered as equally many + * DMA segments. So, take packet segmentation into account when making sure that the maximum + * number of DMA segments capabilities are not exceeded. + */ +typedef struct odp_dma_transfer_param_t { + /** Source data format + * + * The default value is ODP_DMA_FORMAT_ADDR. + */ + odp_dma_data_format_t src_format; + + /** Destination data format + * + * The default value is ODP_DMA_FORMAT_ADDR. + */ + odp_dma_data_format_t dst_format; + + /** Number of source segments + * + * The default value is 1. + */ + uint32_t num_src; + + /** Number of destination segments + * + * The default value is 1. + */ + uint32_t num_dst; + + /** Table of source segments + * + * The table has 'num_src' entries. Data format is defined by 'src_format'. + */ + odp_dma_seg_t *src_seg; + + /** Table of destination segments + * + * The table has 'num_dst' entries. Data format is defined by 'dst_format'. + */ + odp_dma_seg_t *dst_seg; + +} odp_dma_transfer_param_t; + +/** + * DMA transfer completion parameters + */ +typedef struct odp_dma_compl_param_t { + /** Completion mode + * + * Select a completion mode: #ODP_DMA_COMPL_EVENT, #ODP_DMA_COMPL_POLL or + * #ODP_DMA_COMPL_NONE. The mode must match one of the modes selected in session creation + * parameters (odp_dma_param_t::compl_mode_mask). + * + * ODP_DMA_COMPL_NONE can be used to specify that completion indication is not requested. + * Application may for example start a series of transfers and request completion + * indication only on the last one. + */ + odp_dma_compl_mode_t compl_mode; + + /** Transfer identifier + * + * Transfer identifier is used in ODP_DMA_COMPL_POLL mode. Application passes the same + * identifier here and to a later odp_dma_transfer_done() call to check transfer + * completion status. Identifiers are allocated with odp_dma_transfer_id_alloc(). + * The identifier of a completed transfer may be reused for another transfer. + */ + odp_dma_transfer_id_t transfer_id; + + /** Completion event + * + * When a transfer is started in ODP_DMA_COMPL_EVENT mode, this event is sent to + * the completion queue when the transfer is complete. The event type must be + * ODP_EVENT_DMA_COMPL. Use odp_dma_compl_result() to retrieve transfer results from + * the event. + */ + odp_event_t event; + + /** Completion queue + * + * The completion event is sent into this queue in ODP_DMA_COMPL_EVENT mode. + */ + odp_queue_t queue; + + /** User context pointer + * + * User defined context pointer which is copied to transfer results (odp_dma_result_t). The + * value does not need to represent a valid address (any intptr_t value is allowed). + * + * The default value is NULL. + */ + void *user_ptr; + +} odp_dma_compl_param_t; + +/** DMA transfer results */ +typedef struct odp_dma_result_t { + /** DMA transfer success + * + * true: DMA transfer was successful + * false: DMA transfer failed + */ + odp_bool_t success; + + /** User context pointer + * + * User defined context pointer value from transfer completion parameters + * (odp_dma_compl_param_t). The default value is NULL. + */ + void *user_ptr; + +} odp_dma_result_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif + diff --git a/include/odp/api/spec/errno.h b/include/odp/api/spec/errno.h index 9b60a98ba..85c002e2b 100644 --- a/include/odp/api/spec/errno.h +++ b/include/odp/api/spec/errno.h @@ -1,7 +1,5 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited */ /** @@ -10,8 +8,8 @@ * ODP errno API */ -#ifndef ODP_ERRNO_H_ -#define ODP_ERRNO_H_ +#ifndef ODP_API_SPEC_ERRNO_H_ +#define ODP_API_SPEC_ERRNO_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -20,6 +18,8 @@ extern "C" { /** * @defgroup odp_errno ODP ERRNO + * Error number. + * * @details * <b> ODP errno </b> * @@ -29,8 +29,7 @@ extern "C" { * may initialize errno to zero at anytime by calling odp_errno_zero(). Other * ODP functions never set errno to zero. Valid errno values are non-zero * and implementation specific. It's also implementation specific which - * functions set errno in addition to those explicitly specified by - * the API spec. ODP errno is initially zero. + * functions set errno. ODP errno is initially zero. * * @{ */ diff --git a/include/odp/api/spec/event.h b/include/odp/api/spec/event.h index fdfa52d1c..69464125b 100644 --- a/include/odp/api/spec/event.h +++ b/include/odp/api/spec/event.h @@ -1,55 +1,168 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2022-2023 Nokia */ - /** * @file * * ODP event */ -#ifndef ODP_API_EVENT_H_ -#define ODP_API_EVENT_H_ +#ifndef ODP_API_SPEC_EVENT_H_ +#define ODP_API_SPEC_EVENT_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif -/** @defgroup odp_event ODP EVENT - * Operations on an event. +#include <odp/api/event_types.h> +#include <odp/api/packet_types.h> +#include <odp/api/pool_types.h> + +/** @addtogroup odp_event + * Generic event metadata and operations. * @{ */ +/** + * Event type of an event + * + * Event type specifies purpose and general format of an event. + * + * @param event Event handle + * + * @return Event type + */ +odp_event_type_t odp_event_type(odp_event_t event); /** - * @typedef odp_event_t - * ODP event + * Event subtype of an event + * + * Event subtype expands event type specification by providing more detailed + * purpose and format of an event. + * + * @param event Event handle + * + * @return Event subtype */ +odp_event_subtype_t odp_event_subtype(odp_event_t event); /** - * @def ODP_EVENT_INVALID - * Invalid event + * Event type and subtype of an event + * + * Returns event type and outputs event subtype. + * + * @param event Event handle + * @param[out] subtype Pointer to event subtype for output + * + * @return Event type */ +odp_event_type_t odp_event_types(odp_event_t event, + odp_event_subtype_t *subtype); /** - * @typedef odp_event_type_t - * ODP event types: - * ODP_EVENT_BUFFER, ODP_EVENT_PACKET, ODP_EVENT_TIMEOUT, - * ODP_EVENT_CRYPTO_COMPL + * Event types and subtypes of multiple events + * + * Outputs the event types and subtypes (optional) of all given events into the + * output arrays. Application can pass NULL as 'subtype' parameter if subtype + * values are not required. The types are written in the same order as input + * events. + * + * @param event Array of event handles + * @param[out] type Event type array for output + * @param[out] subtype Event subtype array for output, or NULL + * @param num Number of events, event types, and optionally subtypes */ +void odp_event_types_multi(const odp_event_t event[], odp_event_type_t type[], + odp_event_subtype_t subtype[], int num); /** - * Get event type + * Event type of multiple events * - * @param event Event handle + * Returns the number of first events in the array which have the same event + * type. Outputs the event type of those events. * - * @return Event type + * @param event Array of event handles + * @param num Number of events (> 0) + * @param[out] type Event type pointer for output + * + * @return Number of first events (1 ... num) with the same event type + * (includes event[0]) */ -odp_event_type_t odp_event_type(odp_event_t event); +int odp_event_type_multi(const odp_event_t event[], int num, + odp_event_type_t *type); + +/** + * Event pool + * + * Returns handle to the pool where the event was allocated from. If the + * underlying event type does not have an API for returning pool handle + * (e.g. ODP_EVENT_IPSEC_STATUS), ODP_POOL_INVALID is returned. + * + * @param event Event handle + * + * @return Pool handle or ODP_POOL_INVALID depending on event type + */ +odp_pool_t odp_event_pool(odp_event_t event); + +/** + * Event user area + * + * Returns pointer to the user area associated with the event. This maps to the + * user area of underlying event type (e.g. odp_packet_user_area() for packets). + * If the event does not have user area, NULL is returned. + * + * @param event Event handle + * + * @return Pointer to the user area of the event + * @retval NULL The event does not have user area + */ +void *odp_event_user_area(odp_event_t event); + +/** + * Event user area and flag + * + * Returns pointer to the user area and outputs value of user flag associated + * with the event. The user area maps to the user area of underlying event type + * (e.g. odp_packet_user_area() for packets). If the event does not have user + * area, NULL is returned. + * + * The user flag maps to the user flag value of underlying event type (e.g. + * odp_packet_user_flag() for packets). If the event does not have user flag, a + * negative value is outputted. + * + * @param event Event handle + * @param[out] flag User flag value pointer for output. >0 if user flag is + * set, 0 if flags is not set, or <0 if event does not have + * user flag. + * + * @return Pointer to the user area of the event + * @retval NULL The event does not have user area + */ +void *odp_event_user_area_and_flag(odp_event_t event, int *flag); + +/** + * Filter and convert packet events + * + * Checks event type of all input events, converts all packet events and outputs + * packet handles. Returns the number packet handles outputted. Outputs the + * remaining, non-packet event handles to 'remain' array. Handles are outputted + * to both arrays in the same order those are stored in 'event' array. Both + * output arrays must fit 'num' elements. + * + * @param event Array of event handles + * @param[out] packet Packet handle array for output + * @param[out] remain Event handle array for output of remaining, non-packet + * events + * @param num Number of events (> 0) + * + * @return Number of packets outputted (0 ... num) + */ +int odp_event_filter_packet(const odp_event_t event[], + odp_packet_t packet[], + odp_event_t remain[], int num); /** * Get printable value for an odp_event_t @@ -65,6 +178,20 @@ odp_event_type_t odp_event_type(odp_event_t event); uint64_t odp_event_to_u64(odp_event_t hdl); /** + * Check that event is valid + * + * This function can be used for debugging purposes to check if an event handle represents + * a valid event. The level of error checks depends on the implementation. The call should not + * crash if the event handle is corrupted. + * + * @param event Event handle + * + * @retval 1 Event handle represents a valid event. + * @retval 0 Event handle does not represent a valid event. + */ +int odp_event_is_valid(odp_event_t event); + +/** * Free event * * Frees the event based on its type. Results are undefined if event @@ -76,6 +203,66 @@ uint64_t odp_event_to_u64(odp_event_t hdl); void odp_event_free(odp_event_t event); /** + * Free multiple events + * + * Otherwise like odp_event_free(), but frees multiple events to their + * originating pools. + * + * @param event Array of event handles + * @param num Number of events to free + */ +void odp_event_free_multi(const odp_event_t event[], int num); + +/** + * Free multiple events to the same pool + * + * Otherwise like odp_event_free_multi(), but all events must be from the + * same originating pool. + * + * @param event Array of event handles + * @param num Number of events to free + */ +void odp_event_free_sp(const odp_event_t event[], int num); + +/** + * Event flow id value + * + * Returns the flow id value set in the event. + * Usage of flow id enables scheduler to maintain multiple synchronization + * contexts per single queue. For example, when multiple flows are assigned to + * an atomic queue, events of a single flow (events from the same queue with + * the same flow id value) are guaranteed to be processed by only single thread + * at a time. For packets received through packet input initial + * event flow id will be same as flow hash generated for packets. The hash + * algorithm and therefore the resulting flow id value is implementation + * specific. Use pktio API configuration options to select the fields used for + * initial flow id calculation. For all other events initial flow id is zero + * An application can change event flow id using odp_event_flow_id_set(). + * + * @param event Event handle + * + * @return Flow id of the event + * + */ +uint32_t odp_event_flow_id(odp_event_t event); + +/** + * Set event flow id value + * + * Store the event flow id for the event and sets the flow id flag. + * When scheduler is configured as flow aware, scheduled queue synchronization + * will be based on this id within each queue. + * When scheduler is configured as flow unaware, event flow id is ignored by + * the implementation. + * The value of flow id must be less than the number of flows configured in the + * scheduler. + * + * @param event Event handle + * @param flow_id Flow event id to be set. + */ +void odp_event_flow_id_set(odp_event_t event, uint32_t flow_id); + +/** * @} */ diff --git a/include/odp/api/spec/event_types.h b/include/odp/api/spec/event_types.h new file mode 100644 index 000000000..b967e2871 --- /dev/null +++ b/include/odp/api/spec/event_types.h @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2022-2023 Nokia + */ + +/** + * @file + * + * ODP event API type definitions + */ + +#ifndef ODP_API_SPEC_EVENT_TYPES_H_ +#define ODP_API_SPEC_EVENT_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup odp_event ODP EVENT + * @{ + */ + +/** + * @typedef odp_event_t + * ODP event + */ + +/** + * @def ODP_EVENT_INVALID + * Invalid event + */ + +/** + * @typedef odp_event_type_t + * Event type + * + * Event type specifies purpose and general format of an event. It can be + * checked with odp_event_type() or odp_event_types(). Each event type has + * functions (e.g. odp_buffer_from_event()) to convert between the generic event + * handle (odp_event_t) and the type specific handle (e.g. odp_buffer_t). + * Results are undefined, if conversion function of a wrong event type is used. + * Application cannot change event type by chaining conversion functions. + * + * List of event types: + * - ODP_EVENT_BUFFER + * - Buffer event (odp_buffer_t) for simple data storage and message passing + * - ODP_EVENT_PACKET + * - Packet event (odp_packet_t) containing packet data and plenty of + * packet processing related metadata + * - ODP_EVENT_TIMEOUT + * - Timeout event (odp_timeout_t) from a timer + * - ODP_EVENT_IPSEC_STATUS + * - IPSEC status update event (odp_ipsec_status_t) + * - ODP_EVENT_PACKET_VECTOR + * - Vector of packet events (odp_packet_t) as odp_packet_vector_t + * - ODP_EVENT_PACKET_TX_COMPL + * - Packet Tx completion event (odp_packet_tx_compl_t) generated as a result of a Packet Tx + * completion. + * - ODP_EVENT_DMA_COMPL + * - DMA completion event (odp_dma_compl_t) indicates that a DMA transfer has finished + * - ODP_EVENT_ML_COMPL + * - ML completion event (odp_ml_compl_t) indicates that an ML operation has finished + */ + +/** + * @typedef odp_event_subtype_t + * Event subtype + * + * Event subtype expands event type specification by providing more detailed + * purpose and format of an event. It can be checked with odp_event_subtype() or + * odp_event_types(). Each event subtype may define specific functions + * (e.g. odp_ipsec_packet_from_event()) to convert between the generic event + * handle (odp_event_t) and event type specific handle (e.g. odp_packet_t). When + * subtype is known, these subtype specific functions should be preferred over + * the event type general function (e.g. odp_packet_from_event()). Results are + * undefined, if conversion function of a wrong event subtype is used. + * Application cannot change event subtype by chaining conversion functions. + * + * List of event subtypes: + * - ODP_EVENT_PACKET_BASIC + * - Packet event (odp_packet_t) with basic packet metadata + * - ODP_EVENT_PACKET_COMP + * - Packet event (odp_packet_t) generated as a result of a compression/ + * decompression operation. It contains compression specific metadata in + * addition to the basic packet metadata. + * - ODP_EVENT_PACKET_CRYPTO + * - Packet event (odp_packet_t) generated as a result of a Crypto + * operation. It contains crypto specific metadata in addition to the + * basic packet metadata. + * - ODP_EVENT_PACKET_IPSEC + * - Packet event (odp_packet_t) generated as a result of an IPsec + * operation. It contains IPSEC specific metadata in addition to the basic + * packet metadata. + * - ODP_EVENT_NO_SUBTYPE + * - An event type does not have any subtypes defined + * - ODP_EVENT_ML_COMPL_LOAD + * - ML completion event (odp_ml_compl_t) that contains results from a completed model load or + * unload operation. + * - ODP_EVENT_ML_COMPL_RUN + * - ML completion event (odp_ml_compl_t) that contains results from a completed model run + * operation. + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/hash.h b/include/odp/api/spec/hash.h index 66b740e2c..cb4f3241a 100644 --- a/include/odp/api/spec/hash.h +++ b/include/odp/api/spec/hash.h @@ -1,7 +1,5 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited */ /** @@ -10,8 +8,8 @@ * ODP Hash functions */ -#ifndef ODP_API_HASH_H_ -#define ODP_API_HASH_H_ +#ifndef ODP_API_SPEC_HASH_H_ +#define ODP_API_SPEC_HASH_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -20,8 +18,8 @@ extern "C" { #include <odp/api/std_types.h> -/** @defgroup odp_hash ODP HASH FUNCTIONS - * ODP Hash functions +/** @defgroup odp_hash ODP HASH + * Hash functions. * @{ */ diff --git a/include/odp/api/spec/hints.h b/include/odp/api/spec/hints.h index 82400f073..fa5b1b9bb 100644 --- a/include/odp/api/spec/hints.h +++ b/include/odp/api/spec/hints.h @@ -1,18 +1,15 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited */ - /** * @file * * ODP compiler hints */ -#ifndef ODP_API_HINTS_H_ -#define ODP_API_HINTS_H_ +#ifndef ODP_API_SPEC_HINTS_H_ +#define ODP_API_SPEC_HINTS_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -52,11 +49,6 @@ extern "C" { #define ODP_PRINTF_FORMAT(x, y) __attribute__((format(printf, (x), (y)))) /** - * Indicate deprecated variables, functions or types - */ -#define ODP_DEPRECATED __attribute__((__deprecated__)) - -/** * Intentionally unused variables of functions */ #define ODP_UNUSED __attribute__((__unused__)) @@ -64,19 +56,18 @@ extern "C" { /** * Branch likely taken */ -#define odp_likely(x) __builtin_expect((x), 1) +#define odp_likely(x) __builtin_expect(!!(x), 1) /** * Branch unlikely taken */ -#define odp_unlikely(x) __builtin_expect((x), 0) - +#define odp_unlikely(x) __builtin_expect(!!(x), 0) /* * __builtin_prefetch (const void *addr, rw, locality) * * rw 0..1 (0: read, 1: write) - * locality 0..3 (0: dont leave to cache, 3: leave on all cache levels) + * locality 0..3 (0: don't leave to cache, 3: leave on all cache levels) */ /** @@ -89,14 +80,11 @@ extern "C" { */ #define odp_prefetch_store(x) __builtin_prefetch((x), 1, 3) - - #else #define ODP_WEAK_SYMBOL #define ODP_HOT_CODE #define ODP_COLD_CODE -#define ODP_DEPRECATED #define ODP_UNUSED #define odp_likely(x) #define odp_unlikely(x) @@ -105,7 +93,6 @@ extern "C" { #endif - /** * @} */ diff --git a/include/odp/api/spec/init.h b/include/odp/api/spec/init.h index 154cdf8f3..ee787665f 100644 --- a/include/odp/api/spec/init.h +++ b/include/odp/api/spec/init.h @@ -1,26 +1,14 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2019-2023 Nokia */ - /** * @file - * - * ODP initialization. - * ODP requires a global level init for the process and a local init per - * thread before the other ODP APIs may be called. - * - odp_init_global() - * - odp_init_local() - * - * For a graceful termination the matching termination APIs exit - * - odp_term_global() - * - odp_term_local() */ -#ifndef ODP_API_INIT_H_ -#define ODP_API_INIT_H_ +#ifndef ODP_API_SPEC_INIT_H_ +#define ODP_API_SPEC_INIT_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -29,11 +17,11 @@ extern "C" { #include <odp/api/std_types.h> #include <odp/api/hints.h> -#include <odp/api/thread.h> +#include <odp/api/thread_types.h> #include <odp/api/cpumask.h> /** @defgroup odp_initialization ODP INITIALIZATION - * Initialisation operations. + * ODP instance initialization and termination. * @{ */ @@ -43,14 +31,39 @@ extern "C" { */ /** + * Called from signal handler + */ +#define ODP_TERM_FROM_SIGH ((uint64_t)0x1) + +/** + * Last standard flag for abnormal terminate + * + * An implementation may use this for adding its own flags after the standard flags. + */ +#define ODP_TERM_LAST_FLAG ODP_TERM_FROM_SIGH + +/** * ODP log level. */ typedef enum { + /** Debug */ ODP_LOG_DBG, + + /** Warning */ + ODP_LOG_WARN, + + /** Error */ ODP_LOG_ERR, + + /** Unimplemented */ ODP_LOG_UNIMPLEMENTED, + + /** Abort */ ODP_LOG_ABORT, + + /** Print */ ODP_LOG_PRINT + } odp_log_level_t; /** @@ -91,11 +104,12 @@ int odp_override_log(odp_log_level_t level, const char *fmt, ...); * - By overriding the ODP implementation default abort function * odp_override_abort(). * - * @warning The latter option is less portable and GNU linker dependent - * (utilizes function attribute "weak"). If both are defined, the odp_init_t - * function pointer has priority over the override function. + * The latter option is less portable and GNU linker dependent (utilizes function + * attribute "weak"). If both are defined, the odp_init_t function pointer has + * priority over the override function. * - * @warning this function shall not return + * Note that no ODP calls should be called in the abort function and the function + * should not return. */ void odp_override_abort(void) ODP_NORETURN; @@ -106,23 +120,55 @@ typedef int (*odp_log_func_t)(odp_log_level_t level, const char *fmt, ...); typedef void (*odp_abort_func_t)(void) ODP_NORETURN; /** - * ODP initialization data + * Application memory model + */ +typedef enum { + /** Thread memory model: by default all memory is shareable between + * threads. + * + * Within a single ODP instance all ODP handles and pointers to ODP + * allocated data may be shared amongst threads independent of data + * allocation time (e.g. before or after thread creation). */ + ODP_MEM_MODEL_THREAD = 0, + + /** Process memory model: by default all memory is not shareable between + * processes. + * + * Within a single ODP instance all ODP handles and pointers to ODP + * allocated data (excluding non-single VA SHM blocks) may be shared + * amongst processes independent of data allocation time (e.g. before + * or after fork). + * + * @see ODP_SHM_SINGLE_VA + */ + ODP_MEM_MODEL_PROCESS + +} odp_mem_model_t; + +/** + * Global initialization parameters * - * Data that is required to initialize the ODP API with the - * application specific data such as specifying a logging callback, the log - * level etc. + * These parameters may be used at global initialization time to configure and + * optimize ODP implementation to match the intended usage. Application + * specifies maximum resource usage. Implementation may round up resource + * reservations as needed. Initialization function returns a failure if resource + * requirements are too high. Init parameters may be used also to override + * logging and abort functions. * - * @note It is expected that all unassigned members are zero + * Use odp_init_param_init() to initialize the parameters into their default + * values. Unused parameters are left to default values. */ typedef struct odp_init_t { /** Maximum number of worker threads the user will run concurrently. Valid range is from 0 to platform specific maximum. Set both num_worker and num_control to zero for default number of threads. */ int num_worker; + /** Maximum number of control threads the user will run concurrently. Valid range is from 0 to platform specific maximum. Set both num_worker and num_control to zero for default number of threads. */ int num_control; + /** Pointer to bit mask mapping CPUs available to this ODP instance for running worker threads. Initialize to a NULL pointer to use default CPU mapping. @@ -138,6 +184,7 @@ typedef struct odp_init_t { worker masks */ const odp_cpumask_t *worker_cpus; + /** Pointer to bit mask mapping CPUs available to this ODP instance for running control threads. Initialize to a NULL pointer to use default CPU mapping. @@ -149,13 +196,46 @@ typedef struct odp_init_t { worker and control masks do not overlap. */ const odp_cpumask_t *control_cpus; + /** Replacement for the default log fn */ odp_log_func_t log_fn; + /** Replacement for the default abort fn */ odp_abort_func_t abort_fn; + + /** Unused features. These are hints to the ODP implementation that + * the application will not use any APIs associated with these + * features. Implementations may use this information to provide + * optimized behavior. Results are undefined if applications assert + * that a feature will not be used and it is used anyway. + */ + odp_feature_t not_used; + + /** Application memory model. The main application thread has to call + * odp_init_global() and odp_init_local() before creating threads that + * share ODP data. The default value is ODP_MEM_MODEL_THREAD. + */ + odp_mem_model_t mem_model; + + /** Shared memory parameters */ + struct { + /** Maximum memory usage in bytes. This is the maximum + * amount of shared memory that application will reserve + * concurrently. Use 0 when not set. Default value is 0. + */ + uint64_t max_memory; + } shm; + } odp_init_t; /** + * Initialize the odp_init_t to default values for all fields + * + * @param[out] param Address of the odp_init_t to be initialized + */ +void odp_init_param_init(odp_init_t *param); + +/** * @typedef odp_platform_init_t * ODP platform initialization data * @@ -165,16 +245,28 @@ typedef struct odp_init_t { * passing any required platform specific data. */ - /** * Global ODP initialization * - * This function must be called once (per instance) before calling any other - * ODP API functions. A successful call creates a new ODP instance into the - * system and outputs a handle for it. The handle is used in other calls - * (e.g. odp_init_local()) as a reference to the instance. When user provides - * configuration parameters, the platform may configure and optimize the - * instance to match user requirements. + * An ODP instance is created with an odp_init_global() call. By default, each + * thread of the instance must call odp_init_local() before calling any other + * ODP API functions. Exceptions to this are functions that are needed for + * setting up parameters for odp_init_global() and odp_init_local() calls: + * - odp_init_param_init() + * - odp_cpumask_zero(), odp_cpumask_set(), etc functions to format + * odp_cpumask_t. However, these cpumask functions are excluded as their + * behaviour depend on global initialization parameters: + * odp_cpumask_default_worker(), odp_cpumask_default_control() and + * odp_cpumask_all_available() + * + * A successful odp_init_global() call outputs a handle for the new instance. + * The handle is used in other initialization and termination calls. + * For a graceful termination, odp_term_local() must be called first on each + * thread and then odp_term_global() only once. + * + * When user provides configuration parameters, the platform may configure and + * optimize the instance to match user requirements. A failure is returned if + * requirements cannot be met. * * Configuration parameters are divided into standard and platform specific * parts. Standard parameters are supported by any ODP platform, where as @@ -194,80 +286,135 @@ typedef struct odp_init_t { * @retval 0 on success * @retval <0 on failure * - * @see odp_term_global() - * @see odp_init_local() which is required per thread before use. + * @see odp_init_local(), odp_term_global(), odp_init_param_init() */ int odp_init_global(odp_instance_t *instance, const odp_init_t *params, const odp_platform_init_t *platform_params); /** - * Global ODP termination + * Thread local ODP initialization * - * This function is the final ODP call made when terminating - * an ODP application in a controlled way. It cannot handle exceptional - * circumstances. In general it calls the API modules terminate functions in - * the reverse order to that which the module init functions were called - * during odp_init_global(). + * All threads must call this function before calling any other ODP API + * functions. See odp_init_global() documentation for exceptions to this rule. + * Global initialization (odp_init_global()) must have completed prior calling + * this function. * - * This function must be called only after all threads of the instance have - * executed odp_term_local(). To simplify synchronization between threads - * odp_term_local() identifies which one is the last thread of an instance. + * The instance parameter specifies which ODP instance the thread joins. + * A thread may only join a single ODP instance at a time. The thread + * type parameter indicates if the thread does most part of application + * processing (ODP_THREAD_WORKER), or if it performs mostly background + * tasks (ODP_THREAD_CONTROL). * * @param instance Instance handle + * @param thr_type Thread type * * @retval 0 on success * @retval <0 on failure * - * @warning The unwinding of HW resources to allow them to be reused without - * reseting the device is a complex task that the application is expected to - * coordinate. This api may have platform dependent implications. + * @see odp_init_global(), odp_term_local() + */ +int odp_init_local(odp_instance_t instance, odp_thread_type_t thr_type); + +/** + * Thread local ODP termination + * + * This function is the second to final ODP call made when terminating + * an ODP application in a controlled way. It cannot handle exceptional + * circumstances. It is recommended that all ODP resources are freed before + * the last thread (of the instance) calls this function. This helps ODP + * to avoid memory and other resource leaks. + * + * odp_term_global() may be called only after all threads of the instance have + * executed odp_term_local(). To simplify synchronization between threads + * a return value identifies which one is the last thread of an instance. + * + * @retval 1 on success and more ODP threads exist + * @retval 0 on success and this is the last ODP thread + * @retval <0 on failure * - * @see odp_init_global() - * @see odp_term_local() which must have been called prior to this. + * @see odp_init_local(), odp_term_global() */ -int odp_term_global(odp_instance_t instance); +int odp_term_local(void); /** - * Thread local ODP initialization + * Global ODP termination * - * All threads must call this function before calling any other ODP API - * functions. The instance parameter specifies which ODP instance the thread - * joins. A thread may be simultaneously part of single ODP instance only. + * This function is the final ODP call made when terminating an ODP application + * in a controlled way. It cannot handle exceptional circumstances. + * + * This function must be called only after all threads of the instance have + * executed odp_term_local(). * * @param instance Instance handle - * @param thr_type Thread type * * @retval 0 on success * @retval <0 on failure * - * @see odp_term_local() - * @see odp_init_global() which must have been called prior to this. + * @see odp_init_global(), odp_term_local() */ -int odp_init_local(odp_instance_t instance, odp_thread_type_t thr_type); +int odp_term_global(odp_instance_t instance); /** - * Thread local ODP termination + * Abnormal ODP termination after a non-recoverable error + * + * Application may call this function to terminate an ODP instance after facing + * a non-recoverable error. Depending on the implementation, this function may + * attempt to dump stack and other memory areas, clean up and stop HW + * operations and/or perform other actions helpful in postmortem analysis. + * Depending on the nature of the error resulting in the abnormal termination, + * these actions may partially or completely fail. Flags (ODP_TERM_*) parameter + * can be used to control and data parameter can be used to pass additional + * flag-specific information to the termination process. Implementation + * specific flags with implementation specific data may also exist, see from + * implementation documentation how those should be utilized. + * + * Some coordination across threads is required when abnormally terminating, if + * other threads continue calling ODP functions during or after termination, + * their operation is most likely affected. + * + * When the function returns, the ODP instance has been destroyed either + * completely or partially. Application must not attempt to call any ODP + * functions during its remaining lifetime, but terminate as soon as feasible. * - * This function is the second to final ODP call made when terminating - * an ODP application in a controlled way. It cannot handle exceptional - * circumstances. In general it calls the API modules per thread terminate - * functions in the reverse order to that which the module init functions were - * called during odp_init_local(). + * @param instance Instance handle + * @param flags A bit mask of control flags (ODP_TERM_*), set to 0 + * when no flags + * @param data Additional data, set to NULL when no additional data * - * @retval 1 on success and more ODP threads exist - * @retval 0 on success and this is the last ODP thread - * @retval <0 on failure + * @retval 0 on all actions successfully performed + * @retval <0 on failure to perform all actions, implementation specific status + * code for debugging + */ +int odp_term_abnormal(odp_instance_t instance, uint64_t flags, void *data); + +/** + * Set thread specific log function * - * @warning The unwinding of HW resources to allow them to be reused without - * reseting the device is a complex task that the application is expected - * to coordinate. + * By default, all ODP log writes use the global log function, which may be set + * as part of odp_init_t. Using this operation, an alternative ODP log function + * may be set for the calling thread. When set, ODP uses the thread specific log + * function for all log writes originating from ODP API calls made by the + * calling thread. Setting the log function to NULL causes the calling thread to + * use the global log function. * - * @see odp_init_local() - * @see odp_term_global() should be called by the last ODP thread before exit - * of an application. + * @param func Log function */ -int odp_term_local(void); +void odp_log_thread_fn_set(odp_log_func_t func); + +/** + * Get instance handle + * + * A successful call outputs the calling thread's ODP instance handle. + * + * @param[out] instance Instance handle pointer for output + * + * @retval 0 on success + * @retval <0 on failure + * + * @see odp_init_global(), odp_init_local() + */ +int odp_instance(odp_instance_t *instance); /** * @} diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h new file mode 100644 index 000000000..cdb18116b --- /dev/null +++ b/include/odp/api/spec/ipsec.h @@ -0,0 +1,644 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2016-2018 Linaro Limited + * Copyright (c) 2021-2022 Nokia + */ + +/** + * @file + * + * ODP IPsec API + */ + +#ifndef ODP_API_SPEC_IPSEC_H_ +#define ODP_API_SPEC_IPSEC_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/crypto_types.h> +#include <odp/api/event_types.h> +#include <odp/api/ipsec_types.h> +#include <odp/api/packet_types.h> +#include <odp/api/std_types.h> + +/** @addtogroup odp_ipsec + * IPSEC protocol offload. + * @{ + */ + +/** + * Query IPSEC capabilities + * + * Outputs IPSEC capabilities on success. + * + * @param[out] capa Pointer to capability structure for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_ipsec_capability(odp_ipsec_capability_t *capa); + +/** + * Query supported IPSEC cipher algorithm capabilities + * + * Outputs all supported configuration options for the algorithm. Output is + * sorted (from the smallest to the largest) first by key length, then by IV + * length. Use this information to select key lengths, etc cipher algorithm + * options for SA creation (odp_ipsec_crypto_param_t). + * + * @param cipher Cipher algorithm + * @param[out] capa Array of capability structures for output + * @param num Maximum number of capability structures to output + * + * @return Number of capability structures for the algorithm. If this is larger + * than 'num', only 'num' first structures were output and application + * may call the function again with a larger value of 'num'. + * @retval <0 on failure + */ +int odp_ipsec_cipher_capability(odp_cipher_alg_t cipher, + odp_ipsec_cipher_capability_t capa[], int num); + +/** + * Query supported IPSEC authentication algorithm capabilities + * + * Outputs all supported configuration options for the algorithm. Output is + * sorted (from the smallest to the largest) first by ICV length, then by key + * length. Use this information to select key lengths, etc authentication + * algorithm options for SA creation (odp_ipsec_crypto_param_t). + * + * @param auth Authentication algorithm + * @param[out] capa Array of capability structures for output + * @param num Maximum number of capability structures to output + * + * @return Number of capability structures for the algorithm. If this is larger + * than 'num', only 'num' first structures were output and application + * may call the function again with a larger value of 'num'. + * @retval <0 on failure + */ +int odp_ipsec_auth_capability(odp_auth_alg_t auth, + odp_ipsec_auth_capability_t capa[], int num); + +/** + * Initialize IPSEC configuration options + * + * Initialize an odp_ipsec_config_t to its default values. + * + * @param[out] config Pointer to IPSEC configuration structure + */ +void odp_ipsec_config_init(odp_ipsec_config_t *config); + +/** + * Global IPSEC configuration + * + * Initialize and configure IPSEC offload with global configuration options. + * This must be called before any SAs are created. Use odp_ipsec_capability() + * to examine which features and modes are supported. This function must be + * called before creating the first SA with odp_ipsec_sa_create(). Calling this + * function multiple times results in undefined behaviour. + * + * @param config Pointer to IPSEC configuration structure + * + * @retval 0 on success + * @retval <0 on failure + * + * @see odp_ipsec_capability(), odp_ipsec_config_init() + */ +int odp_ipsec_config(const odp_ipsec_config_t *config); + +/** + * Initialize IPSEC SA parameters + * + * Initialize an odp_ipsec_sa_param_t to its default values for all fields. + * + * @param param Pointer to the parameter structure + */ +void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param); + +/** + * Create IPSEC SA + * + * Create a new IPSEC SA according to the parameters. + * + * The parameter structure as well as all key, address and other memory + * buffers pointed to by it can be freed after the call. + * + * @param param IPSEC SA parameters + * + * @return IPSEC SA handle + * @retval ODP_IPSEC_SA_INVALID on failure + * + * @see odp_ipsec_sa_param_init() + */ +odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param); + +/** + * Disable IPSEC SA + * + * Application must use this call to disable a SA before destroying it. The call + * marks the SA disabled, so that IPSEC implementation stops using it. For + * example, inbound SPI lookups will not match any more. Application must + * stop providing the SA as parameter to new IPSEC input/output operations + * before calling disable. Packets in progress during the call may still match + * the SA and be processed successfully. + * + * When in synchronous operation mode, the call will return when it's possible + * to destroy the SA. In asynchronous mode, the same is indicated by an + * ODP_EVENT_IPSEC_STATUS event sent to the queue specified for the SA. The + * status event is guaranteed to be the last event for the SA, i.e. all + * in-progress operations have completed and resulting events (including status + * events) have been enqueued before it. + * + * @param sa IPSEC SA to be disabled + * + * @retval 0 On success + * @retval <0 On failure + * + * @see odp_ipsec_sa_destroy() + */ +int odp_ipsec_sa_disable(odp_ipsec_sa_t sa); + +/** + * Destroy IPSEC SA + * + * Destroy an unused IPSEC SA. Result is undefined if the SA is being used + * (i.e. asynchronous operation is in progress). + * + * @param sa IPSEC SA to be destroyed + * + * @retval 0 On success + * @retval <0 On failure + * + * @see odp_ipsec_sa_create() + */ +int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa); + +/** + * Printable format of odp_ipsec_sa_t + * + * @param sa IPSEC SA handle + * + * @return uint64_t value that can be used to print/display this handle + */ +uint64_t odp_ipsec_sa_to_u64(odp_ipsec_sa_t sa); + +/** + * Inbound synchronous IPSEC operation + * + * This operation does inbound IPSEC processing in synchronous mode + * (ODP_IPSEC_OP_MODE_SYNC). A successful operation returns the number of + * packets consumed and outputs a new packet handle for each outputted packet. + * Outputted packets contain IPSEC result metadata (odp_ipsec_packet_result_t), + * which should be checked for transformation errors, etc. Outputted packets + * with error status have undefined content, except that in case of sa_lookup + * error the original input packet data is returned. The operation does not + * modify packets that it does not consume. It cannot consume all input + * packets if 'num_out' is smaller than 'num_in'. + * + * Packet context pointer and user area content are copied from input to output + * packets. Output packets are allocated from the same pool(s) as input packets. + * + * When 'param.num_sa' is zero, this operation performs SA look up for each + * packet. Otherwise, application must provide the SA(s) as part of operation + * input parameters (odp_ipsec_in_param_t). The operation outputs used SA(s) as + * part of per packet results (odp_ipsec_packet_result_t), or an error + * status if a SA was not found. + * + * Each input packet must have a valid value for these metadata (other metadata + * is ignored): + * - L3 offset: Offset to the first byte of the (outmost) IP header + * - L4 offset: When udp_encap is enabled, offset to the first byte of the + * encapsulating UDP header + * + * Additionally, implementation checks input IP packet length (odp_packet_len() + * minus odp_packet_l3_offset()) against protocol headers and reports an error + * (status.error.proto) if packet data length is less than protocol headers + * indicate. + * + * Packets are processed in the input order. Packet order is maintained from + * input 'pkt' array to output 'pkt' array. Packet order is not guaranteed + * between calling threads. + * + * Input packets must not be IP fragments. + * + * The operation does packet transformation according to IPSEC standards (see + * e.g. RFC 4302 and 4303). Resulting packets are well formed, reconstructed + * original IP packets, with IPSEC headers removed and valid header field values + * restored. The amount and content of packet data before the IP header is + * undefined. Some amount of TFC padding may follow the IP packet payload, + * in which case packet length is larger than protocol headers indicate. + * TFC dummy packets have l3_type set to ODP_PROTO_L3_TYPE_NONE in tunnel mode + * or l4_type set to ODP_PROTO_L4_TYPE_NO_NEXT in transport mode. Dummy + * packets contain implementation specific amount of (dummy) data. Furthermore, + * inline IPSEC processing may drop dummy packets. + * + * Each successfully transformed packet has a valid value for these metadata + * regardless of the inner packet parse configuration + * (odp_ipsec_inbound_config_t): + * - l3_offset: Offset to the first byte of the original IP packet. The value + * is implementation specific for tunnel mode TFC dummy packets. + * - l3_type: Specifies if the original packet is IPv4 or IPv6. For tunnel + * mode TFC dummy packets set to ODP_PROTO_L3_TYPE_NONE. + * - l4_type: Always set to ODP_PROTO_L4_TYPE_NO_NEXT for transport mode dummy + * packets. Otherwise, depends on parse configuration. Default + * value is ODP_PROTO_L4_TYPE_NONE. + * - pktio: For inline IPSEC processed packets, original packet input + * interface + * + * Other metadata for parse results and error checks depend on configuration + * (selected parse and error check levels). + * + * @param pkt_in Packets to be processed + * @param num_in Number of packets to be processed + * @param[out] pkt_out Packet handle array for resulting packets + * @param[in, out] num_out Number of resulting packets. Application sets this + * to 'pkt_out' array size. A successful operation sets + * this to the number of outputted packets + * (1 ... num_out). + * @param param Inbound operation parameters + * + * @return Number of input packets consumed (0 ... num_in) + * @retval <0 On failure + * + * @see odp_packet_user_ptr(), odp_packet_user_area(), odp_packet_l3_offset(), + * odp_packet_l4_offset() + */ +int odp_ipsec_in(const odp_packet_t pkt_in[], int num_in, + odp_packet_t pkt_out[], int *num_out, + const odp_ipsec_in_param_t *param); + +/** + * Outbound synchronous IPSEC operation + * + * This operation does outbound IPSEC processing in synchronous mode + * (ODP_IPSEC_OP_MODE_SYNC). A successful operation returns the number of + * packets consumed and outputs a new packet handle for each outputted packet. + * Outputted packets contain IPSEC result metadata (odp_ipsec_packet_result_t), + * which should be checked for transformation errors, etc. Outputted packets + * with error status have undefined content, except that in case of MTU error + * the original input packet data is returned. The operation does not modify + * packets that it does not consume. It cannot consume all input packets if + * 'num_out' is smaller than 'num_in'. + * + * Packet context pointer and user area content are copied from input to output + * packets. Output packets are allocated from the same pool(s) as input packets. + * + * When outbound IP fragmentation offload is enabled, the number of outputted + * packets may be greater than the number of input packets. + * + * Each input packet must have a valid value for these metadata (other metadata + * is ignored): + * - L3 offset: Offset to the first byte of the (outmost) IP header + * - L4 offset: Offset to the L4 header if L4 checksum offload is requested + * + * Additionally, input IP packet length (odp_packet_len() minus + * odp_packet_l3_offset()) must match values in protocol headers. Otherwise + * results are undefined. + * + * Packets are processed in the input order. Packet order is maintained from + * input 'pkt' array to output 'pkt' array. Packet order is not guaranteed + * between calling threads. + * + * The operation does packet transformation according to IPSEC standards (see + * e.g. RFC 4302 and 4303). Resulting packets are well formed IP packets + * with IPSEC, etc headers constructed according to the standards. The amount + * and content of packet data before the IP header is undefined. Use outbound + * operation parameters to specify the amount of TFC padding appended to + * the packet during IPSEC transformation. Options can be used also to create + * TFC dummy packets. Packet data content is ignored in tunnel mode TFC dummy + * packet creation as tfc_pad_len option defines solely the packet length. + * In all other cases, payload length for the IPSEC transformation is specified + * by odp_packet_len() minus odp_packet_l3_offset() plus tfc_pad_len option. + * + * Each successfully transformed packet has a valid value for these metadata: + * - L3 offset: Offset to the first byte of the (outmost) IP header + * + * @param pkt_in Packets to be processed + * @param num_in Number of packets to be processed + * @param[out] pkt_out Packet handle array for resulting packets + * @param[in, out] num_out Number of resulting packets. Application sets this + * to 'pkt_out' array size. A successful operation sets + * this to the number of outputted packets + * (1 ... num_out). + * @param param Outbound operation parameters + * + * @return Number of input packets consumed (0 ... num_in) + * @retval <0 On failure + * + * @see odp_packet_user_ptr(), odp_packet_user_area(), odp_packet_l3_offset() + */ +int odp_ipsec_out(const odp_packet_t pkt_in[], int num_in, + odp_packet_t pkt_out[], int *num_out, + const odp_ipsec_out_param_t *param); + +/** + * Inbound asynchronous IPSEC operation + * + * This operation does inbound IPSEC processing in asynchronous mode. It + * processes packets otherwise identically to odp_ipsec_in(), but outputs + * resulting packets as ODP_EVENT_PACKET events (with ODP_EVENT_PACKET_IPSEC + * subtype). The following ordering considerations apply to the events. + * + * Asynchronous mode maintains packet order per SA when application calls the + * operation within an ordered or atomic scheduler context of the same queue. + * Resulting events for the same SA are enqueued in order. Packet order per SA + * at a destination queue is the same as if application would have enqueued + * packets there with odp_queue_enq_multi(). + * + * Packet order is also maintained when application otherwise guarantees + * (e.g. using locks) that the operation is not called simultaneously from + * multiple threads for the same SA(s). + * + * Logically, packet processing (e.g. sequence number check) happens in the + * output order as defined above. + * + * The function may be used also in inline processing mode, e.g. for IPSEC + * packets for which inline processing is not possible. Packets for the same SA + * may be processed simultaneously in both modes (initiated by this function + * and inline operation). + * + * Post-processing may be required after the reception of an IPsec packet + * event to complete IPsec processing for the packet. The post-processing + * happens in the odp_ipsec_result() function that must be called at least + * once before packet data or metadata (other than packet type and subtype) + * may be accessed. + * + * If reassembly is attempted but fails, the result packet delivered to the + * application will have reassembly status as ODP_PACKET_REASS_INCOMPLETE and + * will not have ODP_EVENT_PACKET_IPSEC subtype. In that case, the application + * can call odp_packet_reass_partial_state() to get fragments of the packet. The + * fragments will have subtype as ODP_EVENT_PACKET_IPSEC and the application + * must call odp_ipsec_result() for such a fragment before accessing its packet + * data. + * + * @param pkt Packets to be processed + * @param num Number of packets to be processed + * @param param Inbound operation parameters + * + * @return Number of input packets consumed (0 ... num) + * @retval <0 On failure + * + * @see odp_ipsec_in(), odp_ipsec_result() + */ +int odp_ipsec_in_enq(const odp_packet_t pkt[], int num, + const odp_ipsec_in_param_t *param); + +/** + * Outbound asynchronous IPSEC operation + * + * This operation does outbound IPSEC processing in asynchronous mode. It + * processes packets otherwise identically to odp_ipsec_out(), but outputs + * resulting packets as ODP_EVENT_PACKET events (with ODP_EVENT_PACKET_IPSEC + * subtype). The following ordering considerations apply to the events. + * + * Asynchronous mode maintains packet order per SA when application calls the + * operation within an ordered or atomic scheduler context of the same queue. + * Resulting events for the same SA are enqueued in order. Packet order per SA + * at a destination queue is the same as if application would have enqueued + * packets there with odp_queue_enq_multi(). + * + * Packet order is also maintained when application otherwise guarantees + * (e.g. using locks) that the operation is not called simultaneously from + * multiple threads for the same SA(s). + * + * Logically, packet processing (e.g. sequence number assignment) happens in the + * output order as defined above. + * + * The function may be used also in inline processing mode, e.g. for IPSEC + * packets for which inline processing is not possible. + * + * Post-processing may be required after the reception of an IPsec packet + * event to complete IPsec processing for the packet. The post-processing + * happens in the odp_ipsec_result() function that must be called at least + * once before packet data or metadata (other than packet type and subtype) + * may be accessed. + * + * @param pkt Packets to be processed + * @param num Number of packets to be processed + * @param param Outbound operation parameters + * + * @return Number of input packets consumed (0 ... num) + * @retval <0 On failure + * + * @see odp_ipsec_out(), odp_ipsec_result() + */ +int odp_ipsec_out_enq(const odp_packet_t pkt[], int num, + const odp_ipsec_out_param_t *param); + +/** + * Outbound inline IPSEC operation + * + * This operation does outbound inline IPSEC processing for the packets. It's + * otherwise identical to odp_ipsec_out_enq(), but outputs all successfully + * transformed packets to the specified output interface (or tm_queue), instead of + * generating events for those. + * + * Inline operation parameters are defined per packet. The array of parameters + * must have 'num' elements and is pointed to by 'inline_param'. + * + * @param pkt Packets to be processed + * @param num Number of packets to be processed + * @param param Outbound operation parameters + * @param inline_param Outbound inline operation specific parameters + * + * @return Number of packets consumed (0 ... num) + * @retval <0 On failure + * + * @see odp_ipsec_out_enq() + */ +int odp_ipsec_out_inline(const odp_packet_t pkt[], int num, + const odp_ipsec_out_param_t *param, + const odp_ipsec_out_inline_param_t *inline_param); + +/** + * Convert IPSEC processed packet event to packet handle + * + * Get packet handle to an IPSEC processed packet event. Event subtype must be + * ODP_EVENT_IPSEC_PACKET. IPSEC operation results can be examined with + * odp_ipsec_result(). + * + * @param ev Event handle + * + * @return Packet handle + * + * @see odp_event_subtype(), odp_ipsec_result() + */ +odp_packet_t odp_ipsec_packet_from_event(odp_event_t ev); + +/** + * Convert IPSEC processed packet handle to event + * + * The packet handle must be an output of an IPSEC operation. + * + * @param pkt Packet handle from IPSEC operation + * + * @return Event handle + */ +odp_event_t odp_ipsec_packet_to_event(odp_packet_t pkt); + +/** + * Get IPSEC operation results from an IPSEC processed packet + * + * Successful IPSEC operations of all types (SYNC, ASYNC and INLINE) produce + * packets which contain IPSEC result metadata. This function copies the + * operation results from an IPSEC processed packet. Event subtype of this kind + * of packet is ODP_EVENT_PACKET_IPSEC. Results are undefined if a non-IPSEC + * processed packet is passed as input. + * + * Some packet API operations output a new packet handle + * (e.g. odp_packet_concat()). IPSEC metadata remain valid as long as the packet + * handle is not changed from the original (output of e.g. odp_ipsec_in() or + * odp_ipsec_packet_from_event() call) IPSEC processed packet handle. + * + * @param[out] result Pointer to operation result for output + * @param packet An IPSEC processed packet (ODP_EVENT_PACKET_IPSEC) + * + * @retval 0 On success + * @retval <0 On failure + * + * @see odp_ipsec_in(), odp_ipsec_in_enq(), odp_ipsec_out(), + * odp_ipsec_out_enq(), odp_ipsec_packet_from_event() + */ +int odp_ipsec_result(odp_ipsec_packet_result_t *result, odp_packet_t packet); + +/** + * Get IPSEC status information from an ODP_EVENT_IPSEC_STATUS event + * + * Copies IPSEC status information from an event. The event must be of + * type ODP_EVENT_IPSEC_STATUS. + * + * @param[out] status Pointer to status information structure for output. + * @param event An ODP_EVENT_IPSEC_STATUS event + * + * @retval 0 On success + * @retval <0 On failure + * + * @see odp_ipsec_sa_disable() + */ +int odp_ipsec_status(odp_ipsec_status_t *status, odp_event_t event); + +/** + * IPSEC test API for modifying internal state of an SA. + * + * This function is not meant to be used by normal applications but by special + * test applications that test or debug the operation of the underlying ODP + * implementation. Calling this function may degrade the performance of the + * calling thread, other threads or the IPSEC implementation in general. + * + * Calling this function for an SA at the same time when the SA is used for + * processing traffic or when the SA is being modified through other parts + * of IPSEC API may result in undefined behaviour. + * + * SA state update through this function may not be supported by all ODP + * implementations, ODP instances or SA instances or at every moment. This + * function may return failure for unspecified reasons even when the capability + * call indicated support for updating a particular parameter and previous + * similar calls succeeded. + * + * @param sa IPSEC SA to be updated + * @param op Specifies operation to be performed + * @param param Pointer to IPSEC TEST SA param structure to be + * used for the operation + * + * @return 0 On success + * @retval <0 On failure + */ +int odp_ipsec_test_sa_update(odp_ipsec_sa_t sa, + odp_ipsec_test_sa_operation_t op, + const odp_ipsec_test_sa_param_t *param); + +/** + * Update MTU for outbound IP fragmentation + * + * When IP fragmentation offload is enabled, the SA is created with an MTU. + * This call may be used to update MTU at any time. MTU updates are not + * expected to happen very frequently. + * + * @param sa IPSEC SA to be updated + * @param mtu The new MTU value + * + * @retval 0 On success + * @retval <0 On failure + */ +int odp_ipsec_sa_mtu_update(odp_ipsec_sa_t sa, uint32_t mtu); + +/** + * Get user defined SA context pointer + * + * @param sa IPSEC SA handle + * + * @return User defined SA context pointer value + * @retval NULL On failure + */ +void *odp_ipsec_sa_context(odp_ipsec_sa_t sa); + +/** + * Print global IPSEC configuration info + * + * Print implementation-defined information about the global IPSEC + * configuration. + */ +void odp_ipsec_print(void); + +/** + * Print IPSEC SA info + * + * @param sa SA handle + * + * Print implementation-defined IPSEC SA debug information to the ODP log. + */ +void odp_ipsec_sa_print(odp_ipsec_sa_t sa); + +/** + * Get IPSEC stats for the IPSEC SA handle + * + * @param sa IPSEC SA handle + * @param[out] stats Stats output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_ipsec_stats(odp_ipsec_sa_t sa, odp_ipsec_stats_t *stats); + +/** + * Get IPSEC stats for multiple IPSEC SA handles + * + * @param sa Array of IPSEC SA handles + * @param[out] stats Stats array for output + * @param num Number of SA handles + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_ipsec_stats_multi(odp_ipsec_sa_t sa[], odp_ipsec_stats_t stats[], int num); + +/** + * Retrieve information about an IPSEC SA + * + * The cipher and auth key data(including key extra) will not be exposed and + * the corresponding pointers will be set to NULL. The IP address pointers + * will point to the corresponding buffers available in the SA info structure. + * + * The user defined SA context pointer is an opaque field and hence the value + * provided during the SA creation will be returned. + * + * @param sa The IPSEC SA for which to retrieve information + * @param[out] sa_info Pointer to caller allocated SA info structure to be + * filled in + * + * @retval 0 On success + * @retval <0 On failure + **/ +int odp_ipsec_sa_info(odp_ipsec_sa_t sa, odp_ipsec_sa_info_t *sa_info); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/ipsec_types.h b/include/odp/api/spec/ipsec_types.h new file mode 100644 index 000000000..71b53a770 --- /dev/null +++ b/include/odp/api/spec/ipsec_types.h @@ -0,0 +1,1495 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2016-2018 Linaro Limited + * Copyright (c) 2022 Nokia + */ + +/** + * @file + * + * ODP IPsec API type definitions + */ + +#ifndef ODP_API_SPEC_IPSEC_TYPES_H_ +#define ODP_API_SPEC_IPSEC_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/classification.h> +#include <odp/api/crypto_types.h> +#include <odp/api/packet_io_types.h> +#include <odp/api/protocols.h> +#include <odp/api/std_types.h> +#include <odp/api/traffic_mngr.h> + +/** @defgroup odp_ipsec ODP IPSEC + * @{ + */ + +/** + * @typedef odp_ipsec_sa_t + * IPSEC Security Association (SA) + */ + + /** + * @def ODP_IPSEC_SA_INVALID + * Invalid IPSEC SA + */ + +/** + * IPSEC operation mode + */ +typedef enum odp_ipsec_op_mode_t { + /** Synchronous IPSEC operation + * + * Application uses synchronous IPSEC operations, + * which output all results on function return. + */ + ODP_IPSEC_OP_MODE_SYNC = 0, + + /** Asynchronous IPSEC operation + * + * Application uses asynchronous IPSEC operations, + * which return results via events. + */ + ODP_IPSEC_OP_MODE_ASYNC, + + /** Inline IPSEC operation + * + * Packet input/output is connected directly to IPSEC inbound/outbound + * processing. Application uses asynchronous or inline IPSEC + * operations. + * + * Inline processed inbound packets are delivered to the application + * in the same way as packets processed by odp_ipsec_in_enq(). + */ + ODP_IPSEC_OP_MODE_INLINE, + + /** IPSEC is disabled in inbound / outbound direction */ + ODP_IPSEC_OP_MODE_DISABLED + +} odp_ipsec_op_mode_t; + +/** + * IPSEC TEST SA operation + */ +typedef enum odp_ipsec_test_sa_operation_t { + /** Update next sequence number + * + * The seq_num parameter is an outbound SA specific parameter. + * Invoking the odp_ipsec_test_sa_update() API to update this + * field on an inbound SA will cause the API to return failure. + */ + ODP_IPSEC_TEST_SA_UPDATE_SEQ_NUM = 0, + + /** Update highest authenticated sequence number + * + * The antireplay_window_top parameter is inbound SA specific. + * Invoking the odp_ipsec_test_sa_update() API to update this + * field on an outbound SA will cause the API to return failure. + */ + ODP_IPSEC_TEST_SA_UPDATE_ANTIREPLAY_WINDOW_TOP + +} odp_ipsec_test_sa_operation_t; + +/** + * IPSEC TEST SA parameter + */ +typedef union odp_ipsec_test_sa_param_t { + /** Next sequence number + * + * @see ODP_IPSEC_TEST_SA_UPDATE_SEQ_NUM + */ + uint64_t seq_num; + + /** Highest authenticated sequence number + * + * @see ODP_IPSEC_TEST_SA_UPDATE_ANTIREPLAY_WINDOW_TOP + */ + uint64_t antireplay_window_top; + +} odp_ipsec_test_sa_param_t; + +/** + * Configuration options for IPSEC inbound processing + */ +typedef struct odp_ipsec_inbound_config_t { + /** Default destination queue for IPSEC events + * + * When inbound SA lookup fails in the asynchronous mode, + * resulting IPSEC events are enqueued into this queue. + */ + odp_queue_t default_queue; + + /** Constraints for SPI values used with inbound SA lookup. Minimal + * SPI range and unique values may improve performance. */ + struct { + /** Minimum SPI value for SA lookup. Default value is 0. */ + uint32_t min_spi; + + /** Maximum SPI value for SA lookup. Default value is + * UINT32_MAX. */ + uint32_t max_spi; + + /** Select if SPI values for SA lookup are unique or may contain + * the same SPI value multiple times. The default value is 0. + * + * 0: All SAs in SA lookup have unique SPI value + * 1: The same SPI value may be used for multiple SAs + */ + odp_bool_t spi_overlap; + + } lookup; + + /** Retain outer headers + * + * Select up to which protocol layer (at least) outer headers are + * retained in inbound inline processing. Default value is + * ODP_PROTO_LAYER_NONE. + * + * ODP_PROTO_LAYER_NONE: Application does not require any outer + * headers to be retained. + * + * ODP_PROTO_LAYER_L2: Retain headers up to layer 2. + * + * ODP_PROTO_LAYER_L3: Retain headers up to layer 3, otherwise the + * same as ODP_PROTO_LAYER_ALL. + * + * ODP_PROTO_LAYER_L4: Retain headers up to layer 4, otherwise the + * same as ODP_PROTO_LAYER_ALL. + * + * ODP_PROTO_LAYER_ALL: In tunnel mode, all headers before IPSEC are + * retained. In transport mode, all headers + * before IP (carrying IPSEC) are retained. + * + */ + odp_proto_layer_t retain_outer; + + /** Parse packet headers after IPSEC transformation + * + * Select header parsing level after inbound processing. Headers of the + * resulting packet must be checked (at least) up to this level. + * Parsing starts from IP (layer 3). Packet metadata from IP to this + * layer is set. In addition, offset (and pointer) to the next layer + * is set. Other layer/protocol specific metadata have undefined + * values. + * + * Each successfully transformed packet has a valid value for L3 offset + * regardless of the parse configuration. Default value is + * ODP_PROTO_LAYER_NONE. ODP_PROTO_LAYER_L2 is not a valid value. + */ + odp_proto_layer_t parse_level; + + /** Flags to control IPSEC payload data checks up to the selected parse + * level. Checksum checking status can be queried for each packet with + * odp_packet_l3_chksum_status() and odp_packet_l4_chksum_status(). + * Default value for all bits is 0 (skip all checksum checks). + */ + odp_proto_chksums_t chksums; + + /** Post-IPsec reassembly configuration + * + * This field provides global IPsec configuration parameters for + * fragment reassembly. The enable flag does not turn on reassembly + * but tells if reassembly may be enabled in SA parameters. + * + * The enable flag may be set only if retain_outer is + * ODP_PROTO_LAYER_NONE. + */ + odp_reass_config_t reassembly; + + /** Attempt reassembly after inbound IPsec processing in + * odp_ipsec_in_enq(). Default value is false. + */ + odp_bool_t reass_async; + + /** Attempt reassembly after inline inbound IPsec processing. + * Default value is false. + **/ + odp_bool_t reass_inline; + +} odp_ipsec_inbound_config_t; + +/** + * Configuration options for IPSEC outbound processing + */ +typedef struct odp_ipsec_outbound_config_t { + /** Flags to control L3/L4 checksum insertion as part of outbound + * packet processing. These flags control checksum insertion (for the + * payload packet) in the same way as the checksum flags in + * odp_pktout_config_opt_t control checksum insertion when sending + * packets out through a pktio interface. Also packet checksum override + * functions (e.g. odp_packet_l4_chksum_insert()) can be used in + * the same way. + */ + union { + /** Mapping for individual bits */ + struct { + /** Insert IPv4 header checksum on the payload packet + * before IPSEC transformation. Default value is 0. */ + uint32_t inner_ipv4 : 1; + + /** Insert UDP header checksum on the payload packet + * before IPSEC transformation. Default value is 0. */ + uint32_t inner_udp : 1; + + /** Insert TCP header checksum on the payload packet + * before IPSEC transformation. Default value is 0. */ + uint32_t inner_tcp : 1; + + /** Insert SCTP header checksum on the payload packet + * before IPSEC transformation. Default value is 0. */ + uint32_t inner_sctp : 1; + + } chksum; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or bitwise + * operations over the entire structure. */ + uint32_t all_chksum; + }; + +} odp_ipsec_outbound_config_t; + +/** + * IPSEC TEST capability + */ +typedef struct odp_ipsec_test_capability_t { + /** Parameters supported for sa_update */ + struct { + /** Next sequence number value + * + * @see ODP_IPSEC_TEST_SA_UPDATE_SEQ_NUM + */ + odp_bool_t seq_num; + + /** Highest authenticated sequence number + * + * @see ODP_IPSEC_TEST_SA_UPDATE_ANTIREPLAY_WINDOW_TOP + */ + odp_bool_t antireplay_window_top; + + } sa_operations; + +} odp_ipsec_test_capability_t; + +/** + * IPSEC capability + */ +typedef struct odp_ipsec_capability_t { + /** Maximum number of IPSEC SAs */ + uint32_t max_num_sa; + + /** Synchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_SYNC) support */ + odp_support_t op_mode_sync; + + /** + * Asynchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_ASYNC) support + */ + odp_support_t op_mode_async; + + /** + * Inline inbound IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) + * support + */ + odp_support_t op_mode_inline_in; + + /** + * Inline outgoing IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) + * support + */ + odp_support_t op_mode_inline_out; + + /** IP Authenticated Header (ODP_IPSEC_AH) support */ + odp_support_t proto_ah; + + /** Fragment after IPsec support */ + odp_support_t frag_after; + + /** Fragment before IPsec support */ + odp_support_t frag_before; + + /** + * Support of pipelined classification (ODP_IPSEC_PIPELINE_CLS) of + * resulting inbound packets + */ + odp_support_t pipeline_cls; + + /** + * Support of retaining outer headers (retain_outer) in inbound inline + * processed packets + */ + odp_support_t retain_header; + + /** + * Inner packet checksum check offload support in inbound direction. + */ + odp_proto_chksums_t chksums_in; + + /** Maximum number of different destination CoSes in classification + * pipelining. The same CoS may be used for many SAs. This is equal or + * less than 'max_cos' capability in classifier API. + */ + uint32_t max_cls_cos; + + /** + * Scheduled queue support + * + * 0: Scheduled queues are not supported either as IPsec SA destination + * queues or as IPsec default queue + * 1: Scheduled queues are supported as both IPsec SA destination queues + * and IPsec default queue + * @see odp_ipsec_sa_param_t + */ + odp_bool_t queue_type_sched; + + /** + * Plain queue support + * + * 0: Plain queues are not supported either as IPsec SA destination + * queues or as IPsec default queue + * 1: Plain queues are supported as both IPsec SA destination queues and + * IPsec default queue + * @see odp_ipsec_sa_param_t + */ + odp_bool_t queue_type_plain; + + /** Maximum number of different destination queues. The same queue may + * be used for many SAs. */ + uint32_t max_queues; + + /** Support for returning completion packets as vectors */ + odp_pktin_vector_capability_t vector; + + /** Maximum anti-replay window size. */ + uint32_t max_antireplay_ws; + + /** Supported cipher algorithms */ + odp_crypto_cipher_algos_t ciphers; + + /** Supported authentication algorithms */ + odp_crypto_auth_algos_t auths; + + /** Support of traffic manager (TM) after inline outbound IPSEC + * processing. On unsupported platforms, application is not allowed + * to use a TM enabled pktio (ODP_PKTOUT_MODE_TM) with outbound + * inline IPSEC. + * + * @see odp_pktio_open(), odp_pktio_param_t + */ + odp_support_t inline_ipsec_tm; + + /** IPSEC TEST capabilities + * + * @see odp_ipsec_test_sa_update() + */ + odp_ipsec_test_capability_t test; + + /** Post-IPsec reassembly capability */ + odp_reass_capability_t reassembly; + + /** Support of reassembly after inbound processing in odp_ipsec_in_enq() */ + odp_bool_t reass_async; + + /** Support of reassembly after inline inbound IPsec processing */ + odp_bool_t reass_inline; + +} odp_ipsec_capability_t; + +/** + * Cipher algorithm capabilities + */ +typedef struct odp_ipsec_cipher_capability_t { + /** Key length in bytes */ + uint32_t key_len; + +} odp_ipsec_cipher_capability_t; + +/** + * Authentication algorithm capabilities + */ +typedef struct odp_ipsec_auth_capability_t { + /** Key length in bytes */ + uint32_t key_len; + + /** ICV length in bytes */ + uint32_t icv_len; +} odp_ipsec_auth_capability_t; + +/** + * IPSEC configuration options + */ +typedef struct odp_ipsec_config_t { + /** Inbound IPSEC operation mode. Application selects which mode + * will be used for inbound IPSEC operations. + * + * @see odp_ipsec_in(), odp_ipsec_in_enq() + */ + odp_ipsec_op_mode_t inbound_mode; + + /** Outbound IPSEC operation mode. Application selects which mode + * will be used for outbound IPSEC operations. + * + * @see odp_ipsec_out(), odp_ipsec_out_enq(), odp_ipsec_out_inline() + */ + odp_ipsec_op_mode_t outbound_mode; + + /** Maximum number of IPSEC SAs that application will use + * simultaneously */ + uint32_t max_num_sa; + + /** IPSEC inbound processing configuration */ + odp_ipsec_inbound_config_t inbound; + + /** IPSEC outbound processing configuration */ + odp_ipsec_outbound_config_t outbound; + + /** Enable stats collection + * + * Default value is false (stats collection disabled). + * + * @see odp_ipsec_stats(), odp_ipsec_stats_multi() + */ + odp_bool_t stats_en; + + /** + * Packet vector configuration for async and inline operations + * + * This packet vector configuration affects packets delivered to + * the application through the default queue and the SA destination + * queues. It does not affect packets delivered through pktio + * input queues. + */ + odp_pktin_vector_config_t vector; + +} odp_ipsec_config_t; + +/** + * IPSEC SA direction + */ +typedef enum odp_ipsec_dir_t { + /** Inbound IPSEC SA */ + ODP_IPSEC_DIR_INBOUND = 0, + + /** Outbound IPSEC SA */ + ODP_IPSEC_DIR_OUTBOUND + +} odp_ipsec_dir_t; + +/** + * IPSEC protocol mode + */ +typedef enum odp_ipsec_mode_t { + /** IPSEC tunnel mode */ + ODP_IPSEC_MODE_TUNNEL = 0, + + /** IPSEC transport mode */ + ODP_IPSEC_MODE_TRANSPORT + +} odp_ipsec_mode_t; + +/** + * IPSEC protocol + */ +typedef enum odp_ipsec_protocol_t { + /** ESP protocol */ + ODP_IPSEC_ESP = 0, + + /** AH protocol */ + ODP_IPSEC_AH + +} odp_ipsec_protocol_t; + +/** + * IPSEC tunnel type + */ +typedef enum odp_ipsec_tunnel_type_t { + /** Outer header is IPv4 */ + ODP_IPSEC_TUNNEL_IPV4 = 0, + + /** Outer header is IPv6 */ + ODP_IPSEC_TUNNEL_IPV6 + +} odp_ipsec_tunnel_type_t; + +/** + * IPSEC crypto parameters + */ +typedef struct odp_ipsec_crypto_param_t { + /** Cipher algorithm + * + * Select cipher algorithm to be used. ODP_CIPHER_ALG_NULL indicates + * that ciphering is disabled. See 'ciphers' field of + * odp_ipsec_capability_t for supported cipher algorithms. Algorithm + * descriptions can be found from odp_cipher_alg_t documentation. Note + * that some algorithms restrict choice of the pairing authentication + * algorithm. When ciphering is enabled, cipher key and potential extra + * key material (cipher_key_extra) need to be set. The default value + * is ODP_CIPHER_ALG_NULL. + */ + odp_cipher_alg_t cipher_alg; + + /** Cipher key */ + odp_crypto_key_t cipher_key; + + /** Extra keying material for cipher algorithm + * + * Additional data used as salt or nonce if the algorithm requires it, + * other algorithms ignore this field. These algorithms require this + * field to be set: + * - ODP_CIPHER_ALG_AES_CTR: 4 bytes of nonce + * - ODP_CIPHER_ALG_AES_GCM: 4 bytes of salt + * - ODP_CIPHER_ALG_AES_CCM: 3 bytes of salt + * - ODP_CIPHER_ALG_CHACHA20_POLY1305: 4 bytes of salt + */ + odp_crypto_key_t cipher_key_extra; + + /** Authentication algorithm + * + * Select authentication algorithm to be used. ODP_AUTH_ALG_NULL + * indicates that authentication is disabled. See 'auths' field of + * odp_ipsec_capability_t for supported authentication algorithms. + * Algorithm descriptions can be found from odp_auth_alg_t + * documentation. Note that some algorithms restrict choice of the + * pairing cipher algorithm. When single algorithm provides both + * ciphering and authentication (i.e. Authenticated Encryption), + * authentication side key information ('auth_key' and + * 'auth_key_extra') is ignored, and cipher side values are + * used instead. These algorithms ignore authentication side key + * information: ODP_AUTH_ALG_AES_GCM, ODP_AUTH_ALG_AES_CCM and + * ODP_AUTH_ALG_CHACHA20_POLY1305. Otherwise, authentication side + * parameters must be set when authentication is enabled. The default + * value is ODP_AUTH_ALG_NULL. + */ + odp_auth_alg_t auth_alg; + + /** Authentication key */ + odp_crypto_key_t auth_key; + + /** Extra keying material for authentication algorithm + * + * Additional data used as salt or nonce if the algorithm requires it, + * other algorithms ignore this field. These algorithms require this + * field to be set: + * - ODP_AUTH_ALG_AES_GMAC: 4 bytes of salt + */ + odp_crypto_key_t auth_key_extra; + + /** + * Length of integrity check value (ICV) in bytes. + * + * Some algorithms support multiple ICV lengths when used with IPsec. + * This field can be used to select a non-default ICV length. + * + * Zero value indicates that the default ICV length shall be used. + * The default length depends on the selected algorithm as follows: + * + * Algorithm Default length Other lengths + * ---------------------------------------------------------------- + * ODP_AUTH_ALG_NULL 0 + * ODP_AUTH_ALG_MD5_HMAC 12 + * ODP_AUTH_ALG_SHA1_HMAC 12 + * ODP_AUTH_ALG_SHA256_HMAC 16 + * ODP_AUTH_ALG_SHA384_HMAC 24 + * ODP_AUTH_ALG_SHA512_HMAC 32 + * ODP_AUTH_ALG_AES_GCM 16 8, 12 + * ODP_AUTH_ALG_AES_GMAC 16 + * ODP_AUTH_ALG_AES_CCM 16 8, 12 + * ODP_AUTH_ALG_AES_CMAC 12 + * ODP_AUTH_ALG_AES_XCBC_MAC 12 + * ODP_AUTH_ALG_CHACHA20_POLY1305 16 + * + * The requested ICV length must be supported for the selected + * algorithm as indicated by odp_ipsec_auth_capability(). + * + * The default value is 0. + */ + uint32_t icv_len; + +} odp_ipsec_crypto_param_t; + +/** IPv4 header parameters */ +typedef struct odp_ipsec_ipv4_param_t { + /** IPv4 source address (NETWORK ENDIAN) */ + void *src_addr; + + /** IPv4 destination address (NETWORK ENDIAN) */ + void *dst_addr; + + /** IPv4 Differentiated Services Code Point. The default value is 0. */ + uint8_t dscp; + + /** IPv4 Don't Fragment bit. The default value is 0. */ + uint8_t df; + + /** IPv4 Time To Live. The default value is 255. */ + uint8_t ttl; + +} odp_ipsec_ipv4_param_t; + +/** IPv6 header parameters */ +typedef struct odp_ipsec_ipv6_param_t { + /** IPv6 source address (NETWORK ENDIAN) */ + void *src_addr; + + /** IPv6 destination address (NETWORK ENDIAN) */ + void *dst_addr; + + /** IPv6 flow label. The default value is 0. */ + uint32_t flabel; + + /** IPv6 Differentiated Services Code Point. The default value is 0. */ + uint8_t dscp; + + /** IPv6 hop limit. The default value is 255. */ + uint8_t hlimit; + +} odp_ipsec_ipv6_param_t; + +/** + * IPSEC tunnel parameters + * + * These parameters are used to build outbound tunnel headers. All values are + * passed in CPU native byte / bit order if not specified otherwise. + * IP addresses must be in NETWORK byte order as those are passed in with + * pointers and copied byte-by-byte from memory to the packet. + */ +typedef struct odp_ipsec_tunnel_param_t { + /** Tunnel type: IPv4 or IPv6. The default is IPv4. */ + odp_ipsec_tunnel_type_t type; + + /** Tunnel type specific parameters */ + struct { + /** IPv4 header parameters */ + odp_ipsec_ipv4_param_t ipv4; + + /** IPv6 header parameters */ + odp_ipsec_ipv6_param_t ipv6; + }; +} odp_ipsec_tunnel_param_t; + +/** + * IPSEC SA option flags + */ +typedef struct odp_ipsec_sa_opt_t { + /** Extended Sequence Numbers (ESN) + * + * * 1: Use extended (64 bit) sequence numbers + * * 0: Use normal sequence numbers (the default value) + */ + uint32_t esn : 1; + + /** UDP encapsulation + * + * * 1: Do UDP encapsulation/decapsulation so that IPSEC packets can + * traverse through NAT boxes. + * * 0: No UDP encapsulation (the default value) + */ + uint32_t udp_encap : 1; + + /** Copy DSCP bits + * + * * 1: Copy IPv4 or IPv6 DSCP bits from inner IP header to + * the outer IP header in encapsulation, and vice versa in + * decapsulation. + * * 0: Use values from odp_ipsec_tunnel_param_t in encapsulation and + * do not change DSCP field in decapsulation (the default value). + */ + uint32_t copy_dscp : 1; + + /** Copy IPv6 Flow Label + * + * * 1: Copy IPv6 flow label from inner IPv6 header to the + * outer IPv6 header. + * * 0: Use value from odp_ipsec_tunnel_param_t (the default value) + */ + uint32_t copy_flabel : 1; + + /** Copy IPv4 Don't Fragment bit + * + * * 1: Copy the DF bit from the inner IPv4 header to the outer + * IPv4 header. + * * 0: Use value from odp_ipsec_tunnel_param_t (the default value) + */ + uint32_t copy_df : 1; + + /** Decrement inner packet Time To Live (TTL) field + * + * * 1: In tunnel mode, decrement inner packet IPv4 TTL or + * IPv6 Hop Limit after tunnel decapsulation, or before tunnel + * encapsulation. + * * 0: Inner packet is not modified (the default value) + */ + uint32_t dec_ttl : 1; + +} odp_ipsec_sa_opt_t; + +/** + * IPSEC SA lifetime limits + * + * These limits are used for setting up SA lifetime. IPSEC operations check + * against the limits and output a status code (e.g. soft_exp_bytes) when + * a limit is crossed. It's implementation defined how many times soft + * lifetime expiration is reported: only once, first N or all packets following + * the limit crossing. Any number of limits may be used simultaneously. + * Use zero when there is no limit. + * + * The default value is zero (i.e. no limit) for all the limits. + */ +typedef struct odp_ipsec_lifetime_t { + /** Soft expiry limits for the session */ + struct { + /** Limit in bytes */ + uint64_t bytes; + + /** Limit in packet */ + uint64_t packets; + } soft_limit; + + /** Hard expiry limits for the session */ + struct { + /** Limit in bytes */ + uint64_t bytes; + + /** Limit in packet */ + uint64_t packets; + } hard_limit; +} odp_ipsec_lifetime_t; + +/** + * Fragmentation mode + * + * These options control outbound IP packet fragmentation offload. When offload + * is enabled, IPSEC operation will determine if fragmentation is needed and + * does it according to the mode. + */ +typedef enum odp_ipsec_frag_mode_t { + /** Do not fragment IP packets */ + ODP_IPSEC_FRAG_DISABLED = 0, + + /** Fragment IP packet before IPSEC operation */ + ODP_IPSEC_FRAG_BEFORE, + + /** Fragment IP packet after IPSEC operation */ + ODP_IPSEC_FRAG_AFTER, + + /** Only check if IP fragmentation is needed, + * do not fragment packets. */ + ODP_IPSEC_FRAG_CHECK +} odp_ipsec_frag_mode_t; + +/** + * Packet lookup mode + * + * Lookup mode controls how an SA participates in SA lookup offload. + * Inbound operations perform SA lookup if application does not provide a SA as + * a parameter. In inline mode, a lookup miss directs the packet back to normal + * packet input interface processing. SA lookup failure status + * (status.error.sa_lookup) is reported through odp_ipsec_packet_result_t. + */ +typedef enum odp_ipsec_lookup_mode_t { + /** Inbound SA lookup is disabled for the SA. */ + ODP_IPSEC_LOOKUP_DISABLED = 0, + + /** Inbound SA lookup is enabled. Lookup matches only SPI value. */ + ODP_IPSEC_LOOKUP_SPI, + + /** Inbound SA lookup is enabled. Lookup matches both SPI value and + * destination IP address. Functionality is otherwise identical to + * ODP_IPSEC_LOOKUP_SPI. */ + ODP_IPSEC_LOOKUP_DSTADDR_SPI + +} odp_ipsec_lookup_mode_t; + +/** + * IPSEC pipeline configuration + */ +typedef enum odp_ipsec_pipeline_t { + /** Do not pipeline. Send all resulting events to the application. */ + ODP_IPSEC_PIPELINE_NONE = 0, + + /** Send resulting packets to the classifier + * + * IPSEC capability 'pipeline_cls' determines if pipelined + * classification is supported. */ + ODP_IPSEC_PIPELINE_CLS + +} odp_ipsec_pipeline_t; + +/** + * IPSEC header type + */ +typedef enum odp_ipsec_ip_version_t { + /** Header is IPv4 */ + ODP_IPSEC_IPV4 = 4, + + /** Header is IPv6 */ + ODP_IPSEC_IPV6 = 6 + +} odp_ipsec_ip_version_t; + +/** + * IPSEC Security Association (SA) parameters + */ +typedef struct odp_ipsec_sa_param_t { + /** IPSEC SA direction: inbound or outbound */ + odp_ipsec_dir_t dir; + + /** IPSEC protocol: ESP or AH. The default value is ODP_IPSEC_ESP. */ + odp_ipsec_protocol_t proto; + + /** IPSEC protocol mode: transport or tunnel */ + odp_ipsec_mode_t mode; + + /** Parameters for crypto and authentication algorithms */ + odp_ipsec_crypto_param_t crypto; + + /** Various SA option flags */ + odp_ipsec_sa_opt_t opt; + + /** SA lifetime parameters */ + odp_ipsec_lifetime_t lifetime; + + /** SPI value */ + uint32_t spi; + + /** Destination queue for IPSEC events + * + * Operations in asynchronous or inline mode enqueue resulting events + * into this queue. The default queue ('default_queue') is used when + * SA is not known. + */ + odp_queue_t dest_queue; + + /** User defined SA context pointer + * + * User defined context pointer associated with the SA. + * The implementation may prefetch the context data. Default value + * of the pointer is NULL. + */ + void *context; + + /** Context data length + * + * User defined context data length in bytes for prefetching. + * The implementation may use this value as a hint for the number of + * context data bytes to prefetch. Default value is zero (no hint). + */ + uint32_t context_len; + + /** IPSEC SA direction dependent parameters */ + struct { + /** Inbound specific parameters */ + struct { + /** SA lookup mode + * The default value is ODP_IPSEC_LOOKUP_DISABLED. + */ + odp_ipsec_lookup_mode_t lookup_mode; + + /** Additional SA lookup parameters. Values are + * considered only in ODP_IPSEC_LOOKUP_DSTADDR_SPI + * lookup mode. */ + struct { + /** Select IP version */ + odp_ipsec_ip_version_t ip_version; + + /** IP destination address (NETWORK ENDIAN) to + * be matched in addition to SPI value. */ + void *dst_addr; + + } lookup_param; + + /** Minimum anti-replay window size. Use 0 to disable + * anti-replay service. The default value is 0. + */ + uint32_t antireplay_ws; + + /** Select pipelined destination for resulting events + * + * Asynchronous and inline modes generate events. + * Select where those events are sent. Inbound SAs may + * choose to use pipelined classification. The default + * value is ODP_IPSEC_PIPELINE_NONE. + */ + odp_ipsec_pipeline_t pipeline; + + /** Classifier destination CoS for resulting packets + * + * Successfully decapsulated packets are sent to + * classification through this CoS. Other resulting + * events are sent to 'dest_queue'. This field is + * considered only when 'pipeline' is + * ODP_IPSEC_PIPELINE_CLS. The CoS must not be shared + * between any pktio interface default CoS. The maximum + * number of different CoS supported is defined by + * IPSEC capability max_cls_cos. + */ + odp_cos_t dest_cos; + + /** Enable reassembly of IPsec tunneled fragments + * + * Attempt reassembly of fragments after IPsec tunnel + * decapsulation. + * + * Reassembly is attempted for inline or asynchronously + * processed packets, not for packets processed using + * the synchronous API function. + * + * Fragments received through different SAs will not be + * reassembled into the same packet. + * + * IPsec statistics reflect IPsec processing before + * reassembly and thus count all individual fragments. + * + * Reassembly may be enabled for an SA only if + * reassembly was enabled in the global IPsec + * configuration. + * + * Default value is false. + * + * @see odp_ipsec_config() + * + */ + odp_bool_t reassembly_en; + + } inbound; + + /** Outbound specific parameters */ + struct { + /** Parameters for tunnel mode */ + odp_ipsec_tunnel_param_t tunnel; + + /** Fragmentation mode + * The default value is ODP_IPSEC_FRAG_DISABLED. + */ + odp_ipsec_frag_mode_t frag_mode; + + /** MTU for outbound IP fragmentation offload + * + * This is the maximum length of IP packets that + * outbound IPSEC operations may produce. The value may + * be updated later with odp_ipsec_sa_mtu_update(). + */ + uint32_t mtu; + + } outbound; + }; + +} odp_ipsec_sa_param_t; + +/** + * IPSEC stats content + */ +typedef struct odp_ipsec_stats_t { + /** Number of packets processed successfully */ + uint64_t success; + + /** Number of packets with protocol errors */ + uint64_t proto_err; + + /** Number of packets with authentication errors */ + uint64_t auth_err; + + /** Number of packets with antireplay check failures */ + uint64_t antireplay_err; + + /** Number of packets with algorithm errors */ + uint64_t alg_err; + + /** Number of packets with MTU errors */ + uint64_t mtu_err; + + /** Number of packets with hard lifetime(bytes) expired */ + uint64_t hard_exp_bytes_err; + + /** Number of packets with hard lifetime(packets) expired */ + uint64_t hard_exp_pkts_err; + + /** Total bytes of packet data processed by IPsec SA in success cases + * + * The range of packet bytes included in the success_bytes count is + * implementation defined but includes at least the bytes input for + * encryption or bytes output after decryption in ESP or the bytes + * authenticated in AH. + */ + uint64_t success_bytes; +} odp_ipsec_stats_t; + +/** + * IPSEC SA information + */ +typedef struct odp_ipsec_sa_info_t { + /** IPsec SA parameters + * + * This is not necessarily an exact copy of the actual parameter + * structure used in SA creation. The fields that were relevant + * for the SA in the creation phase will have the same values, + * but other fields, such as tunnel parameters for a transport + * mode SA, will have undefined values. + */ + odp_ipsec_sa_param_t param; + + /** IPSEC SA direction dependent parameters */ + union { + /** Inbound specific parameters */ + struct { + /** Additional SA lookup parameters. */ + struct { + /** IP destination address (NETWORK ENDIAN) to + * be matched in addition to SPI value. */ + uint8_t dst_addr[ODP_IPV6_ADDR_SIZE]; + } lookup_param; + + /** Antireplay window size + * + * Antireplay window size configured for the SA. + * This value can be different from what application + * had requested. + */ + uint32_t antireplay_ws; + + /** Antireplay window top + * + * Sequence number representing a recent top of the + * anti-replay window. There may be a delay before the + * SA state is reflected in the value. The value will be + * zero if no packets have been processed or if the + * anti-replay service is not enabled. + */ + uint64_t antireplay_window_top; + } inbound; + + /** Outbound specific parameters */ + struct { + /** Sequence number + * + * Sequence number used for a recently processed packet. + * There may be a delay before the SA state is reflected + * in the value. When no packets have been processed, + * the value will be zero. + */ + uint64_t seq_num; + + /** Tunnel IP address */ + union { + /** IPv4 */ + struct { + /** IPv4 source address */ + uint8_t src_addr[ODP_IPV4_ADDR_SIZE]; + /** IPv4 destination address */ + uint8_t dst_addr[ODP_IPV4_ADDR_SIZE]; + } ipv4; + + /** IPv6 */ + struct { + /** IPv6 source address */ + uint8_t src_addr[ODP_IPV6_ADDR_SIZE]; + /** IPv6 destination address */ + uint8_t dst_addr[ODP_IPV6_ADDR_SIZE]; + } ipv6; + } tunnel; + } outbound; + }; +} odp_ipsec_sa_info_t; + +/** IPSEC operation status has no errors */ +#define ODP_IPSEC_OK 0 + +/** IPSEC errors */ +typedef struct odp_ipsec_error_t { + /** IPSEC errors */ + union { + /** Error bits */ + struct { + /** Protocol error. Not a valid ESP or AH packet, + * packet data length error, etc. */ + uint32_t proto : 1; + + /** SA lookup failed */ + uint32_t sa_lookup : 1; + + /** Authentication failed */ + uint32_t auth : 1; + + /** Anti-replay check failed */ + uint32_t antireplay : 1; + + /** Other algorithm error */ + uint32_t alg : 1; + + /** Packet does not fit into the given MTU size */ + uint32_t mtu : 1; + + /** Hard lifetime expired: bytes */ + uint32_t hard_exp_bytes : 1; + + /** Hard lifetime expired: packets */ + uint32_t hard_exp_packets : 1; + }; + + /** All error bits + * + * This field can be used to set, clear or compare + * multiple bits. For example, 'status.error.all != 0' + * checks if there are any errors. + */ + uint32_t all; + }; + +} odp_ipsec_error_t; + +/** IPSEC warnings */ +typedef struct odp_ipsec_warn_t { + /** IPSEC warnings */ + union { + /** Warning bits */ + struct { + /** Soft lifetime expired: bytes */ + uint32_t soft_exp_bytes : 1; + + /** Soft lifetime expired: packets */ + uint32_t soft_exp_packets : 1; + }; + + /** All warning bits + * + * This field can be used to set/clear all bits, or to perform + * bitwise operations over those. */ + uint32_t all; + }; + +} odp_ipsec_warn_t; + +/** IPSEC operation status */ +typedef struct odp_ipsec_op_status_t { + /** IPSEC status bits */ + union { + /** IPSEC errors and warnings */ + struct { + /** IPSEC errors */ + odp_ipsec_error_t error; + + /** IPSEC warnings */ + odp_ipsec_warn_t warn; + }; + + /** All status bits. Combines all error and warning bits. + * For example, 'status.all != ODP_IPSEC_OK' checks if there + * are any errors or warnings. */ + uint64_t all; + + }; + +} odp_ipsec_op_status_t; + +/** IPSEC operation flags */ +typedef struct odp_ipsec_op_flag_t { + /** IPSEC operations flags */ + union { + /** Operation flags */ + struct { + /** Packet was processed in inline mode */ + uint32_t inline_mode : 1; + + }; + + /** All flag bits + * + * This field can be used to set/clear all flags, or to perform + * bitwise operations over those. */ + uint32_t all; + }; + +} odp_ipsec_op_flag_t; + +/** + * IPSEC outbound operation options + * + * These may be used to override some SA level options + */ +typedef struct odp_ipsec_out_opt_t { + /** Union of all flag bits */ + union { + /** Option flags. Set flag for those options that are + * used, all other options are ignored. */ + struct { + /** Use fragmentation mode option */ + uint32_t frag_mode: 1; + + /** Use TFC padding length option */ + uint32_t tfc_pad: 1; + + /** Tunnel mode TFC dummy packet. This can be used only + * in tunnel mode. When the flag is set, packet length + * and content is ignored and instead a TFC dummy + * packet is created during IPSEC operation. The dummy + * packet length is defined by 'tfc_pad_len' option. + * If the SA is configured to copy IP header fields + * from inner IP packet, those fields must be passed + * with IP parameters option. */ + uint32_t tfc_dummy: 1; + + /** Use IP parameters option */ + uint32_t ip_param: 1; + + } flag; + + /** All flag bits + * + * This field can be used to set/clear all flags, or to perform + * bitwise operations over those. */ + uint32_t all_flags; + }; + + /** Fragmentation mode */ + odp_ipsec_frag_mode_t frag_mode; + + /** TFC padding length + * + * Number of TFC padding bytes added to the packet during IPSEC + * processing. Resulting packet should not exceed the maximum packet + * length of the pool, otherwise IPSEC operation may fail. + * Implementation guarantees that the padding does not contain any + * confidential information. */ + uint32_t tfc_pad_len; + + /** Union of IP parameters */ + union { + /** Override IPv4 parameters in outer header creation. + * IP addresses are ignored. */ + odp_ipsec_ipv4_param_t ipv4; + + /** Override IPv6 parameters in outer header creation. + * IP addresses are ignored. */ + odp_ipsec_ipv6_param_t ipv6; + }; + +} odp_ipsec_out_opt_t; + +/** + * IPSEC outbound operation parameters + */ +typedef struct odp_ipsec_out_param_t { + /** Number of SAs + * + * Outbound IPSEC operation needs SA from application. Use either + * single SA for all packets, or a SA per packet. + * + * Valid values are: + * - 1: Single SA for all packets + * - N: A SA per packet. N must match the number of packets. + */ + int num_sa; + + /** Number of outbound operation options + * + * Valid values are: + * - 0: No options + * - 1: Single option for all packets + * - N: An option per packet. N must match the number of packets. + */ + int num_opt; + + /** Pointer to an array of IPSEC SAs */ + const odp_ipsec_sa_t *sa; + + /** Pointer to an array of outbound operation options + * + * May be NULL when num_opt is zero. + */ + const odp_ipsec_out_opt_t *opt; + +} odp_ipsec_out_param_t; + +/** + * IPSEC inbound operation parameters + */ +typedef struct odp_ipsec_in_param_t { + /** Number of SAs + * + * Inbound IPSEC operation processes a packet using the SA provided by + * the application. If the application does not provide an SA, the + * operation searches for the SA by matching the input packet with all + * inbound SAs according to the lookup mode (odp_ipsec_lookup_mode_t) + * configured in each SA. When passing SAs, use either single SA for + * all packets, or a SA per packet. + * + * Valid values are: + * - 0: No SAs. SA lookup is done for all packets. + * - 1: Single SA for all packets + * - N: A SA per packet. N must match the number of packets. + */ + int num_sa; + + /** Pointer to an array of IPSEC SAs + * + * May be NULL when num_sa is zero. + */ + const odp_ipsec_sa_t *sa; + +} odp_ipsec_in_param_t; + +/** + * Outbound inline IPSEC operation parameters + */ +typedef struct odp_ipsec_out_inline_param_t { + /** Packet output interface for inline outbound operation without TM + * + * Outbound inline IPSEC operation uses this packet IO interface to + * output the packet after a successful IPSEC transformation. The pktio + * must have been configured to operate in inline IPSEC mode. + * + * The pktio must not have been configured with ODP_PKTOUT_MODE_TM. + * For IPSEC inline output to TM enabled interfaces set this field + * to ODP_PKTIO_INVALID and specify the TM queue to be used through + * the tm_queue parameter. Inline IPSEC output through TM can be + * done only if the platform has inline_ipsec_tm capability. + */ + odp_pktio_t pktio; + + /** TM queue for inline outbound operation + * + * TM queue to be used for inline IPSEC output when pktio field + * is ODP_PKTIO_INVALID, indicating use of TM. Otherwise ignored. + * + * @see odp_ipsec_capability() + */ + odp_tm_queue_t tm_queue; + + /** Outer headers for inline output operation + * + * Outbound inline IPSEC operation uses this information to prepend + * outer headers to the IPSEC packet before sending it out. + */ + struct { + /** Points to first byte of outer headers to be copied in + * front of the outgoing IPSEC packet. Implementation copies + * the headers during odp_ipsec_out_inline() call. + * + * Null value indicates that the outer headers are in the + * packet data, starting at L2 offset and ending at the byte + * before L3 offset. In this case, value of 'len' field must + * be greater than zero and set to L3 offset minus L2 offset. + */ + const uint8_t *ptr; + + /** Outer header length in bytes */ + uint32_t len; + } outer_hdr; + +} odp_ipsec_out_inline_param_t; + +/** + * IPSEC operation result for a packet + */ +typedef struct odp_ipsec_packet_result_t { + /** IPSEC operation status. Use this to check if IPSEC operation + * reported any errors or warnings (e.g. status.all != ODP_IPSEC_OK). + */ + odp_ipsec_op_status_t status; + + /** IPSEC operation flags */ + odp_ipsec_op_flag_t flag; + + /** IPSEC SA that was used to create the packet + * + * Operation updates this SA handle value, when SA look up is performed + * as part of the operation and the look up is successful. Operation + * status code indicates if the look up failed. Otherwise, the SA + * provided by the application is copied here. + */ + odp_ipsec_sa_t sa; + + /** Packet outer header status before inbound inline processing. + * This is valid only when outer headers are retained + * (see odp_ipsec_inbound_config_t) and flag.inline_mode is set. + */ + struct { + /** Points to the first byte of retained outer headers. These + * headers are stored in a contiquous, per packet, + * implementation specific memory space. Since the memory space + * may overlap with e.g. packet head/tailroom, the content + * becomes invalid if packet data storage is modified in + * any way. The memory space may not be shareable to other + * threads. */ + uint8_t *ptr; + + /** Outer header length in bytes */ + uint32_t len; + } outer_hdr; + + /** Total IP length of the original ESP or AH packet before IPsec + * decapsulation. This is valid only for inbound inline and async + * processed packets. Zero value means that the length information + * is not available. + * + * If the result packet was reassembled from multiple IPsec + * protected packets, this is the sum of the lengths of all the + * involved IPsec packets. + */ + uint32_t orig_ip_len; + +} odp_ipsec_packet_result_t; + +/** + * IPSEC status ID + */ +typedef enum odp_ipsec_status_id_t { + /** Response to SA disable command + * + * Following status event (odp_ipsec_status_t) fields have valid + * content, other fields must be ignored: + * - sa: The SA that was requested to be disabled + * - result: Operation result + */ + ODP_IPSEC_STATUS_SA_DISABLE = 0, + + /** Warning from inline IPSEC processing + * + * Following status event (odp_ipsec_status_t) fields have valid + * content, other fields must be ignored: + * - sa: The SA that caused the warning + * - warn: The warning(s) reported by this event + * + * This status event is generated only for outbound SAs in + * ODP_IPSEC_OP_MODE_INLINE mode. + */ + ODP_IPSEC_STATUS_WARN + +} odp_ipsec_status_id_t; + +/** + * IPSEC status content + */ +typedef struct odp_ipsec_status_t { + /** IPSEC status ID */ + odp_ipsec_status_id_t id; + + /** IPSEC SA that was target of the operation */ + odp_ipsec_sa_t sa; + + /** Result of the operation + * + * 0: Success + * <0: Failure + */ + int result; + + /** Warnings of an ODP_IPSEC_STATUS_WARN status event */ + odp_ipsec_warn_t warn; + +} odp_ipsec_status_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/ml.h b/include/odp/api/spec/ml.h new file mode 100644 index 000000000..1a7710ab3 --- /dev/null +++ b/include/odp/api/spec/ml.h @@ -0,0 +1,699 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021-2023 Nokia + * Copyright (c) 2021 Marvell + */ + +/** + * @file + * + * ODP Machine Learning (ML) offload + */ + +#ifndef ODP_API_SPEC_ML_H_ +#define ODP_API_SPEC_ML_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/event_types.h> +#include <odp/api/ml_types.h> +#include <odp/api/pool_types.h> +#include <odp/api/std_types.h> + +/** + * @addtogroup odp_ml + * Machine Learning (ML) offload + * @{ + * + * <b> ML API call sequence </b> + * + * Before ML offload can be used, it must be configured with an odp_ml_config() call. An application + * fills in configuration parameters to describe its intended ML offload usage. The parameter + * values may help ODP implementation to optimize memory and other HW resource usage. The + * application may use odp_ml_capability() to check ML capabilities both before and after the + * configuration step. + * + * After configuration, an ML model binary is passed with other parameters to odp_ml_model_create() + * call which checks and prepares the model for usage. The application may use odp_ml_model_info(), + * odp_ml_model_input_info() and odp_ml_model_output_info() calls to check model input and output + * data formats. Before the application can use the model for inference, it loads the model with + * an odp_ml_model_load() or odp_ml_model_load_start() call. After a successful load, the + * application may use e.g. odp_ml_run() or odp_ml_run_start() to perform inferences. + * + * When all previously started inference operations are complete, application uses + * odp_ml_model_unload() or odp_ml_model_unload_start() to unload the model. After a successful + * unload, the model may be destroyed with an odp_ml_model_destroy() call, or loaded again. + * + * <b> Completion identifiers </b> + * + * Completion identifiers are used with ML operations in asynchronous poll mode + * (#ODP_ML_COMPL_MODE_POLL). Application declares the maximum identifier value it will + * use per model with odp_ml_model_param_t.max_compl_id parameter. It cannot exceed + * the implementation capability of odp_ml_capability_t.max_compl_id. Completion identifier + * values are model specific. The same value can be used simultaneously with two different + * models, but cannot be used simultaneously in two ML operations on the same model. A value may be + * reused for the next ML operation (on the same model) only after the previous operation is + * complete. Within those limitations, application may use/reuse completion identifier + * values from 0 to max_compl_id range freely. + */ + +/** + * Query ML capabilities + * + * Outputs ML capabilities on success. Use this capability call to check ML offload implementation + * limits and its support of various ML API features. When ML offload is not available, + * odp_ml_capability_t.max_models is zero. + * + * @param[out] capa Pointer to a capability structure for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_ml_capability(odp_ml_capability_t *capa); + +/** + * Initialize ML configuration parameters + * + * Initialize an odp_ml_config_t to its default values. + * + * @param[out] config Configuration structure to be initialized + */ +void odp_ml_config_init(odp_ml_config_t *config); + +/** + * Configure ML offload + * + * Initializes and configures ML offload according to the configuration parameters. This function + * must be called only once and before any ML resources are created. Use odp_ml_capability() to + * query configuration capabilities and odp_ml_config_init() to initialize configuration + * parameters into their default values. + * + * @param config ML configuration parameters + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_ml_config(const odp_ml_config_t *config); + +/** + * Initialize ML model parameters + * + * Initialize an odp_ml_model_param_t to its default values. + * + * @param[out] param Parameters structure to be initialized + */ +void odp_ml_model_param_init(odp_ml_model_param_t *param); + +/** + * Create an ML model + * + * Creates an ML model according to the parameters. Use odp_ml_model_param_init() to initialize + * parameters into their default values. The use of model name is optional. Unique names are not + * required. However, odp_ml_model_lookup() returns only a single matching model. Maximum name + * string length is #ODP_ML_MODEL_NAME_LEN. + * + * The call copies the model binary and prepares it for loading. Application may free memory + * buffers pointed by the parameters when the call returns. Use odp_ml_model_load() + * or odp_ml_model_load_start() to load the model. A model is ready for inference runs + * (see e.g. odp_ml_run()) after it has been loaded successfully. + * + * When model metadata misses some details of model input / output data format, user can + * pass those with odp_ml_model_param_t.extra_info. Some ODP implementations may define + * implementation specific extra parameters (e.g. hints about HW resource usage), user can pass + * those with odp_ml_model_param_t.extra_param when applicable. + * + * @param name Name of the model, or NULL + * @param param ML model parameters + * + * @return ML model handle on success + * @retval ODP_ML_MODEL_INVALID on failure + */ +odp_ml_model_t odp_ml_model_create(const char *name, const odp_ml_model_param_t *param); + +/** + * Destroy an ML model + * + * Destroys a model and releases the resources reserved for it. If the model has been loaded, it + * must be unloaded (see odp_ml_model_unload() or odp_ml_model_unload_start()) prior to calling + * this function. + * + * @param model ML model to be destroyed + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_ml_model_destroy(odp_ml_model_t model); + +/** + * Find a model by name + * + * @param name Name of the model + * + * @return Handle of the first matching ML model + * @retval ODP_ML_MODEL_INVALID Model could not be found + */ +odp_ml_model_t odp_ml_model_lookup(const char *name); + +/** + * Load ML model + * + * Loads ML model in synchronous mode. When the call returns, load is complete and the model is + * ready for inference requests. A loaded model must be unloaded before it can be destroyed. + * The same model can be loaded and unloaded multiple times before being destroyed. + * + * The call optionally outputs results. Use NULL as 'result' pointer if results are not required. + * + * Application should not try to keep loaded more than configured number of models + * (odp_ml_config_t.max_models_loaded). Check ML capabilities for maximum number of loaded + * models (odp_ml_capability_t.max_models_loaded) and support of load completion modes + * (odp_ml_capability_t.load). + * + * @param model ML model to be loaded + * @param[out] result Pointer to load result structure for output, or NULL + * + * @retval 0 Model load was successful + * @retval <0 on failure + */ +int odp_ml_model_load(odp_ml_model_t model, odp_ml_load_result_t *result); + +/** + * Start asynchronous model load + * + * Otherwise like odp_ml_model_load(), but loads the model asynchronously. A successful call + * requests the model to be loaded, but does not wait for load completion. Completion parameters + * are used to select if load completion is reported in poll (#ODP_ML_COMPL_MODE_POLL) or event + * (#ODP_ML_COMPL_MODE_EVENT) mode. For poll mode, odp_ml_model_load_status() is called to check + * for completion. For event mode, ML offload sends the completion event into the completion + * queue when the load is complete. Use odp_ml_compl_param_init() to initialize completion + * parameters into their default values. + * + * @param model ML model to be loaded + * @param compl_param Completion parameters for load + * + * @retval 0 Model load started successfully + * @retval <0 on failure + */ +int odp_ml_model_load_start(odp_ml_model_t model, const odp_ml_compl_param_t *compl_param); + +/** + * Check model load completion + * + * Checks if a previously started model load (in #ODP_ML_COMPL_MODE_POLL mode) has completed. + * The completion identifier value from load operation completion parameters + * (odp_ml_compl_param_t.compl_id) is passed as a parameter. It specifies the load operation to be + * checked. Initially 0 is returned for all configured (but unused) completion identifier values. + * An odp_ml_model_load_start() call clears the previous completion status of an identifier, and + * this function returns 0 while the load is in progress. When the load is successfully + * complete, >0 is returned. If the load completed with a failure, -1 is returned. The same + * value is returned until the next start operation that reuses the identifier (with the same + * model). The completion identifier may be reused only after >0 or -1 is returned. + * + * Optionally, outputs more detailed operation results into odp_ml_load_result_t structure. + * Use NULL as 'result' pointer if these results are not required. + * + * @param model ML model being loaded + * @param compl_id Completion identifier that was used in load start + * @param[out] result Pointer to load result structure for output, or NULL + * + * @retval >0 Model load was successful + * @retval 0 Model load has not finished + * @retval -1 Model load failed + * @retval <-1 Failed to read completion status (e.g. bad handle) + */ +int odp_ml_model_load_status(odp_ml_model_t model, uint32_t compl_id, odp_ml_load_result_t *result); + +/** + * Unload ML model + * + * Unloads ML model in synchronous mode. All previously started inference operations must have been + * completed before model unload is attempted. When the call returns, unload is complete and the + * model is ready to be destroyed or loaded again. + * + * The call optionally outputs results. Use NULL as 'result' pointer if results are not required. + * + * @param model ML model to be unloaded + * @param[out] result Pointer to load result structure for output, or NULL + * + * @retval 0 Model unload was successful + * @retval <0 on failure + */ +int odp_ml_model_unload(odp_ml_model_t model, odp_ml_load_result_t *result); + +/** + * Start asynchronous model unload + * + * Otherwise like odp_ml_model_unload(), but unloads the model asynchronously. A successful call + * requests the model to be unloaded, but does not wait for unload completion. Completion + * parameters are used to select if unload completion is reported in poll (#ODP_ML_COMPL_MODE_POLL) + * or event (#ODP_ML_COMPL_MODE_EVENT) mode. For poll mode, odp_ml_model_unload_status() is called + * to check for completion. For event mode, ML offload sends the completion event into the + * completion queue when the unload is complete. Use odp_ml_compl_param_init() to initialize + * completion parameters into their default values. + * + * @param model ML model to be unloaded + * @param compl_param Completion parameters for unload + * + * @retval 0 Model unload started successfully + * @retval <0 on failure + */ +int odp_ml_model_unload_start(odp_ml_model_t model, const odp_ml_compl_param_t *compl_param); + +/** + * Check model unload completion + * + * Checks if a previously started model unload (in #ODP_ML_COMPL_MODE_POLL mode) has completed. + * The completion identifier value from unload operation completion parameters + * (odp_ml_compl_param_t.compl_id) is passed as a parameter. It specifies the unload operation to be + * checked. Initially 0 is returned for all configured (but unused) completion identifier values. + * An odp_ml_model_unload_start() call clears the previous completion status of an identifier, and + * this function returns 0 while the unload is in progress. When the unload is successfully + * complete, >0 is returned. If the unload completed with a failure, -1 is returned. The same + * value is returned until the next start operation that reuses the identifier (with the same + * model). The completion identifier may be reused only after >0 or -1 is returned. + * + * Optionally, outputs more detailed operation results into odp_ml_load_result_t structure. + * Use NULL as 'result' pointer if these results are not required. + * + * @param model ML model being unloaded + * @param compl_id Completion identifier that was used in unload start + * @param[out] result Pointer to load result structure for output, or NULL + * + * @retval >0 Model unload was successful + * @retval 0 Model unload has not finished + * @retval -1 Model unload failed + * @retval <-1 Failed to read completion status (e.g. bad handle) + */ +int odp_ml_model_unload_status(odp_ml_model_t model, uint32_t compl_id, + odp_ml_load_result_t *result); + +/** + * Initialize model run parameters + * + * Initialize an odp_ml_run_param_t to its default values. + * + * @param[out] param Model run parameters structure to be initialized + */ +void odp_ml_run_param_init(odp_ml_run_param_t *param); + +/** + * Run the model in synchronous mode + * + * Performs an ML inference operation using the model and input data pointed by the data descriptor. + * A successful operation writes inference output data into memory buffers pointed by the data + * descriptor. Input/output data buffers are described as an array of segment descriptors. Each + * segment descriptor specifies a memory buffer used with only one model input/output. Multiple + * subsequent descriptors may be used to specify segmented data for the same input/output. + * When the model has multiple inputs/outputs, descriptor order in the array follows the model + * input/output order reported by odp_ml_model_input_info() and odp_ml_model_output_info() calls. + * All memory buffers for the first input/output are specified before any buffers for the second + * input/output, and so on. + * + * When some model inputs/outputs have #ODP_ML_SHAPE_BATCH shape type, the batch size is specified + * in run parameters (odp_ml_run_param_t.batch_size). The same batch size is used for all such + * inputs/outputs. Application may request additional operation results by setting 'result' pointer + * in run parameters. Use odp_ml_run_param_init() to initialize run parameters into their default + * values. Default run parameter values are used when 'param' is NULL. + * + * Returns 1 when model run completed successfully. Returns 0 when the operation was not performed + * due to ML offload resources being temporarily busy. Returns <0 on failure. + * + * @param model ML model to be run + * @param data Model input/output data descriptor + * @param param Model run parameters, or NULL + * + * @retval 1 Model run completed successfully + * @retval 0 Resources are busy and model was not run + * @retval <0 on failure + */ +int odp_ml_run(odp_ml_model_t model, const odp_ml_data_t *data, const odp_ml_run_param_t *param); + +/** + * Run the model multiple times in synchronous mode + * + * Otherwise like odp_ml_run(), but runs the model 'num' times with different input/output + * data buffers. Output data buffers of one ML inference operation must not overlap with + * input/output data buffers of another one. + * + * Returns number of model runs successfully completed. When return value is less than 'num', + * the remaining runs were not performed due to ML offload resources being temporarily busy. + * Returns <0 on failure. + * + * @param model ML model to be run + * @param data Array of model input/output data descriptors. The array has 'num' elements. + * @param param Array of model run parameters, or NULL. The array has 'num' elements + * when used. + * @param num Number of model runs to perform + * + * @return Number of model runs completed successfully (1 ... num) + * @retval 0 Resources are busy and model was not run + * @retval <0 on failure + */ +int odp_ml_run_multi(odp_ml_model_t model, const odp_ml_data_t data[], + const odp_ml_run_param_t param[], int num); + +/** + * Start model run in asynchronous mode + * + * Otherwise like odp_ml_run(), but runs the model asynchronously. A successful call + * requests the model to be run, but does not wait for run completion. Completion parameters + * select if run completion is reported in poll (#ODP_ML_COMPL_MODE_POLL) or event + * (#ODP_ML_COMPL_MODE_EVENT) mode. For poll mode, odp_ml_run_status() is called to check + * for completion. For event mode, ML offload sends the completion event into the completion queue + * when the run is complete. Use odp_ml_compl_param_init() to initialize completion parameters + * into their default values. + * + * Additional operation results (odp_ml_run_result_t) are available through the status call + * (odp_ml_run_status()) or completion event (odp_ml_compl_run_result()). Results are + * not output through the run parameters structure (i.e. odp_ml_run_param_t.result is ignored). + * + * Returns 1 when model run was started successfully. Returns 0 when model run was not started + * due to ML offload resources being temporarily busy. Returns <0 on failure. + * + * @param model ML model to be run + * @param data Model input/output data descriptor + * @param compl_param Completion parameters + * @param run_param Model run parameters, or NULL + * + * @retval 1 Model run started successfully + * @retval 0 Resources are busy and model run was not started + * @retval <0 on failure + */ +int odp_ml_run_start(odp_ml_model_t model, const odp_ml_data_t *data, + const odp_ml_compl_param_t *compl_param, const odp_ml_run_param_t *run_param); + +/** + * Start multiple model runs in asynchronous mode + * + * Otherwise like odp_ml_run_start(), but starts 'num' model runs with different input/output + * data buffers. Output data buffers of one ML inference operation must not overlap with + * input/output data buffers of another one. + * + * Returns number of model runs started successfully. When return value is less than 'num', + * the remaining runs were not started due to ML offload resources being temporarily busy. + * Returns <0 on failure. + * + * @param model ML model to be run + * @param data Array of model input/output data descriptors. The array has 'num' elements. + * @param compl_param Array of completion parameters. The array has 'num' elements. + * @param run_param Array of model run parameters, or NULL. The array has 'num' elements + * when used. + * @param num Number of model runs to start + * + * @return Number of model runs started successfully (1 ... num) + * @retval 0 Resources are busy and model runs were not started + * @retval <0 on failure + */ +int odp_ml_run_start_multi(odp_ml_model_t model, const odp_ml_data_t data[], + const odp_ml_compl_param_t compl_param[], + const odp_ml_run_param_t run_param[], int num); + +/** + * Check model run completion + * + * Checks if a previously started model run (in #ODP_ML_COMPL_MODE_POLL mode) has completed. + * The completion identifier value from run operation completion parameters + * (odp_ml_compl_param_t.compl_id) is passed as a parameter. It specifies the run operation to be + * checked. Initially 0 is returned for all configured (but unused) completion identifier values. + * An odp_ml_run_start() call clears the previous completion status of an identifier, and + * this function returns 0 while the run is in progress. When the run is successfully + * complete, >0 is returned. If the run completed with a failure, -1 is returned. The same + * value is returned until the next start operation that reuses the identifier (with the same + * model). The completion identifier may be reused only after >0 or -1 is returned. + * + * Optionally, outputs more detailed operation results into odp_ml_run_result_t structure. + * Use NULL as 'result' pointer if these results are not required. + * + * @param model ML model running + * @param compl_id Completion identifier that was used in run start + * @param[out] result Pointer to run result structure for output, or NULL + * + * @retval >0 Model run was successful + * @retval 0 Model run has not finished + * @retval -1 Model run failed + * @retval <-1 Failed to read completion status (e.g. bad handle) + */ +int odp_ml_run_status(odp_ml_model_t model, uint32_t compl_id, odp_ml_run_result_t *result); + +/** + * Initialize ML completion event pool parameters + * + * Initialize an odp_ml_compl_pool_param_t to its default values. + * + * @param[out] param Parameter structure to be initialized + */ +void odp_ml_compl_pool_param_init(odp_ml_compl_pool_param_t *param); + +/** + * Create ML completion event pool + * + * Creates a pool of ML completion events (ODP_EVENT_ML_COMPL). Pool type is ODP_POOL_ML_COMPL. + * The use of pool name is optional. Unique names are not required. However, odp_pool_lookup() + * returns only a single matching pool. Use odp_ml_compl_pool_param_init() to initialize pool + * parameters into their default values. Parameters values must not exceed pool capabilities + * (see odp_ml_compl_pool_capability_t). + * + * @param name Name of the pool or NULL. Maximum string length is #ODP_POOL_NAME_LEN. + * @param param Pool parameters + * + * @return Pool handle on success + * @retval ODP_POOL_INVALID on failure + */ +odp_pool_t odp_ml_compl_pool_create(const char *name, const odp_ml_compl_pool_param_t *param); + +/** + * Allocate ML completion event + * + * Allocates an ML completion event from a pool. The pool must have been created with + * odp_ml_compl_pool_create() call. All completion event metadata are set to their default values. + * + * @param pool ML completion event pool + * + * @return ML completion event handle + * @retval ODP_ML_COMPL_INVALID Completion event could not be allocated + */ +odp_ml_compl_t odp_ml_compl_alloc(odp_pool_t pool); + +/** + * Free ML completion event + * + * Frees an ML completion event into the pool it was allocated from. + * + * @param ml_compl ML completion event handle + */ +void odp_ml_compl_free(odp_ml_compl_t ml_compl); + +/** + * Check ML model run results from completion event + * + * Reads model run results from an ML completion event (ODP_EVENT_ML_COMPL). The event indicates + * completion of a previously started inference operation. Subtype of the completion event must be + * ODP_EVENT_ML_COMPL_RUN. Function return value indicates if the model run succeeded or failed. + * Additionally, outputs more detailed results into the provided odp_ml_run_result_t + * structure. Use NULL as 'result' pointer if those results are not required. + * + * @param ml_compl ML completion event (subtype ODP_EVENT_ML_COMPL_RUN) + * @param[out] result Pointer to ML run result structure for output, or NULL. + * + * @retval 0 Model run was successful + * @retval -1 Model run failed + * @retval <-1 Failed to read results from the event (e.g. bad handle) + */ +int odp_ml_compl_run_result(odp_ml_compl_t ml_compl, odp_ml_run_result_t *result); + +/** + * Check ML model load / unload results from completion event + * + * Reads model load / unload results from an ML completion event (ODP_EVENT_ML_COMPL). The event + * indicates completion of a previously started model load / unload operation. Subtype of the + * completion event must be ODP_EVENT_ML_COMPL_LOAD. Function return value indicates if the model + * load / unload succeeded or failed. Additionally, outputs more detailed results into the provided + * odp_ml_load_result_t structure. Use NULL as 'result' pointer if those results are not required. + * + * @param ml_compl ML completion event (subtype ODP_EVENT_ML_COMPL_LOAD) + * @param[out] result Pointer to model load / unload result structure for output, or NULL. + * + * @retval 0 Model load / unload was successful + * @retval -1 Model load / unload failed + * @retval <-1 Failed to read results from the event (e.g. bad handle) + */ +int odp_ml_compl_load_result(odp_ml_compl_t ml_compl, odp_ml_load_result_t *result); + +/** + * ML completion event user area + * + * Returns pointer to the user area associated with the completion event. Size of the area is + * fixed and defined in pool parameters. + * + * @param ml_compl ML completion event + * + * @return Pointer to the user area of the completion event + * @retval NULL The completion event does not have user area + */ +void *odp_ml_compl_user_area(odp_ml_compl_t ml_compl); + +/** + * Convert event to ML completion event + * + * Converts an ODP_EVENT_ML_COMPL type event to an ML completion event. + * + * @param event Event handle + * + * @return ML completion event handle + */ +odp_ml_compl_t odp_ml_compl_from_event(odp_event_t event); + +/** + * Convert ML completion event to event + * + * @param ml_compl ML completion event handle + * + * @return Event handle + */ +odp_event_t odp_ml_compl_to_event(odp_ml_compl_t ml_compl); + +/** + * Convert ML completion event handle to a uint64_t value for debugging + * + * @param ml_compl ML completion event handle to be converted + * + * @return uint64_t value that can be used for debugging (e.g. printed) + */ +uint64_t odp_ml_compl_to_u64(odp_ml_compl_t ml_compl); + +/** + * Initialize ML completion parameters + * + * Initialize an odp_ml_compl_param_t to its default values. + * + * @param[out] param Address of parameters structure to be initialized + */ +void odp_ml_compl_param_init(odp_ml_compl_param_t *param); + +/** + * Retrieve model information + * + * Retrieve information about the model. Model information includes e.g. version numbers and + * number of model inputs/outputs. Information about each input and output can be retrieved with + * odp_ml_model_input_info() and odp_ml_model_output_info() calls. + * + * @param model ML model handle + * @param[out] info Pointer to model information structure for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_ml_model_info(odp_ml_model_t model, odp_ml_model_info_t *info); + +/** + * Retrieve model input information + * + * Writes information about each model input into the array. If there are more inputs than array + * elements, writes only 'num' elements. Returns the number of model inputs on success, and zero on + * failure. When 'num' is zero, ignores value of 'info' and returns normally. + * + * @param model ML model handle + * @param[out] info Pointer to model input information array for output + * @param num Number of elements in the array + * + * @return Number of model inputs + * @retval 0 on failure + */ +uint32_t odp_ml_model_input_info(odp_ml_model_t model, odp_ml_input_info_t info[], uint32_t num); + +/** + * Retrieve model output information + * + * Writes information about each model output into the array. If there are more outputs than array + * elements, writes only 'num' elements. Returns the number of model outputs on success, and zero on + * failure. When 'num' is zero, ignores value of 'info' and returns normally. + * + * @param model ML model handle + * @param[out] info Pointer to model output information array for output + * @param num Number of elements in the array + * + * @return Number of model outputs + * @retval 0 on failure + */ +uint32_t odp_ml_model_output_info(odp_ml_model_t model, odp_ml_output_info_t info[], uint32_t num); + +/** + * Convert ML model handle to a uint64_t value for debugging + * + * @param model ML model handle + * + * @return uint64_t value that can be used for debugging (e.g. printed) + */ +uint64_t odp_ml_model_to_u64(odp_ml_model_t model); + +/** + * Print debug information about the model. + * + * Print implementation defined information about ML model to the ODP log. The information is + * intended to be used for debugging. + + * @param model ML model handle + */ +void odp_ml_model_print(odp_ml_model_t model); + +/** + * Print ML debug information + * + * Print implementation defined information about ML offload to the ODP log. The information is + * intended to be used for debugging. + */ +void odp_ml_print(void); + +/** + * Extra statistics counter information + * + * Returns the number of extra statistics counters supported by the ML offload, and outputs + * information (e.g. name) about those. Counters are implementation specific and maintained + * per model. Statistics counting is enabled through model create parameters. + * + * When 'info' pointer is not NULL, fills in up to 'num' counter info structures. If the return + * value is larger than 'num', there are more counters than the function was allowed to output. + * If the return value N is less than 'num' (on success), only first N structures have been written. + * + * Info array elements are filled in the same order than odp_ml_model_extra_stats() outputs + * counter values. + * + * @param model ML model + * @param[out] info Pointer to extra statistics counter information array for output. + * NULL may be used to query only the number of counters. + * @param num Number of elements in the array + * + * @return Number of extra statistics counters + * @retval <0 on failure + */ +int odp_ml_model_extra_stat_info(odp_ml_model_t model, odp_ml_extra_stat_info_t info[], int num); + +/** + * Read extra statistics counter values + * + * Reads extra statistics counter values and returns the number of supported counters. Outputs + * up to 'num' counter values into 'stats' array. If the return value is larger than 'num', + * there are more counters than the function was allowed to output. If the return value N is less + * than 'num' (on success), only first N counters have been written. The order of counters in + * the array matches the counter information array order on odp_ml_model_extra_stat_info() output. + * + * @param model ML model + * @param[out] stats Pointer to extra statistics counter array for output + * @param num Number of elements in the array + * + * @return Number of extra statistics counters + * @retval <0 on failure + */ +int odp_ml_model_extra_stats(odp_ml_model_t model, uint64_t stats[], int num); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/ml_quantize.h b/include/odp/api/spec/ml_quantize.h new file mode 100644 index 000000000..25565ef27 --- /dev/null +++ b/include/odp/api/spec/ml_quantize.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +/** + * @file + * + * ODP Machine Learning (ML) quantization functions + */ + +#ifndef ODP_API_SPEC_ML_QUANTIZE_H_ +#define ODP_API_SPEC_ML_QUANTIZE_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +/** @addtogroup odp_ml + * @{ + */ + +/** + * Quantize 32-bit float to uint8_t + * + * Quantizes 'num' 32-bit floating point values to uint8_t values using the provided scale and + * zero point. + * + * dst_u8 = (src_fp32 / scale) + zerop + * + * @param[out] dst_u8 Destination address for quantized values + * @param src_fp32 Source address of values to be quantized + * @param num Number of values + * @param scale Scale for quantization + * @param zerop Zero point for quantization + */ +void odp_ml_fp32_to_uint8(uint8_t *dst_u8, const float *src_fp32, uint32_t num, + float scale, uint8_t zerop); + +/** + * De-quantize 32-bit float from uint8_t + * + * De-quantizes 'num' 32-bit floating point values from uint8_t values using the provided scale and + * zero point. + * + * dst_fp32 = (src_u8 - zerop) * scale + * + * @param[out] dst_fp32 Destination address for de-quantized values + * @param src_u8 Source address of values to be de-quantized + * @param num Number of values + * @param scale Scale for de-quantization + * @param zerop Zero point for de-quantization + */ +void odp_ml_fp32_from_uint8(float *dst_fp32, const uint8_t *src_u8, uint32_t num, + float scale, uint8_t zerop); + +/** + * Quantize 32-bit float to int8_t + * + * Quantizes 'num' 32-bit floating point values to int8_t values using the provided scale and + * zero point. + * + * dst_i8 = (src_fp32 / scale) + zerop + * + * @param[out] dst_i8 Destination address for quantized values + * @param src_fp32 Source address of values to be quantized + * @param num Number of values + * @param scale Scale for quantization + * @param zerop Zero point for quantization + */ +void odp_ml_fp32_to_int8(int8_t *dst_i8, const float *src_fp32, uint32_t num, float scale, + int8_t zerop); + +/** + * De-quantize 32-bit float from int8_t + * + * De-quantizes 'num' 32-bit floating point values from int8_t values using the provided scale and + * zero point. + * + * dst_fp32 = (src_i8 - zerop) * scale + * + * @param[out] dst_fp32 Destination address for de-quantized values + * @param src_i8 Source address of values to be de-quantized + * @param num Number of values + * @param scale Scale for de-quantization + * @param zerop Zero point for de-quantization + */ +void odp_ml_fp32_from_int8(float *dst_fp32, const int8_t *src_i8, uint32_t num, float scale, + int8_t zerop); + +/** + * Quantize 32-bit float to 16-bit float + * + * Quantizes 'num' 32-bit floating point values to 16-bit floating point values. + * + * @param[out] dst_fp16 Destination address for quantized values + * @param src_fp32 Source address of values to be quantized + * @param num Number of values + */ +void odp_ml_fp32_to_fp16(uint16_t *dst_fp16, const float *src_fp32, uint32_t num); + +/** + * De-quantize 32-bit float from 16-bit float + * + * De-quantizes 'num' 32-bit floating point values from 16-bit floating point values. + * + * @param[out] dst_fp32 Destination address for de-quantized values + * @param src_fp16 Source address of values to be de-quantized + * @param num Number of values + */ +void odp_ml_fp32_from_fp16(float *dst_fp32, const uint16_t *src_fp16, uint32_t num); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/ml_types.h b/include/odp/api/spec/ml_types.h new file mode 100644 index 000000000..2b8f9d6c8 --- /dev/null +++ b/include/odp/api/spec/ml_types.h @@ -0,0 +1,873 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021-2023 Nokia + * Copyright (c) 2021 Marvell + */ + +/** + * @file + * + * ODP Machine Learning (ML) types + */ + +#ifndef ODP_API_SPEC_ML_TYPES_H_ +#define ODP_API_SPEC_ML_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/event_types.h> +#include <odp/api/queue_types.h> +#include <odp/api/std_types.h> + +/** @defgroup odp_ml ODP ML + * @{ + */ + +/** + * @typedef odp_ml_model_t + * ODP ML model handle + */ + +/** + * @def ODP_ML_MODEL_INVALID + * Invalid ML model + */ + +/** + * @typedef odp_ml_compl_t + * ML completion event + */ + +/** + * @def ODP_ML_COMPL_INVALID + * Invalid ML completion event + */ + +/** + * @def ODP_ML_MODEL_NAME_LEN + * Maximum length of model name in chars (including null char) + */ + +/** + * @def ODP_ML_MODEL_IO_NAME_LEN + * Maximum length of model input/output name in chars (including null char) + */ + +/** + * @def ODP_ML_SHAPE_NAME_LEN + * Maximum length of data dimension name in chars (including null char) + */ + +/** + * @def ODP_ML_EXTRA_STAT_NAME_LEN + * Maximum length of extra statistics counter name in chars (including null char) + */ + +/** + * @typedef odp_ml_model_extra_param_t + * ODP implementation specific extra parameters for model creation + */ + +/** Maximum number of dimensions in input / output data shape */ +#define ODP_ML_MAX_DIMS 8 + +/** Dimension size is dynamic */ +#define ODP_ML_DIM_DYNAMIC 0 + +/** Synchronous operation */ +#define ODP_ML_COMPL_MODE_SYNC 0x1u + +/** + * Asynchronous poll mode operation + * + * A function call starts an operation and a status function call indicates when + * the operation has finished. + */ +#define ODP_ML_COMPL_MODE_POLL 0x2u + +/** + * Asynchronous event mode operation + * + * A function call starts an operation and a completion event indicates when + * the operation has finished. + */ +#define ODP_ML_COMPL_MODE_EVENT 0x4u + +/** ML completion mode */ +typedef uint32_t odp_ml_compl_mode_t; + +/** + * ML completion event pool capabilities + * + * Pool statistics are not supported with ML completion event pools. + */ +typedef struct odp_ml_compl_pool_capability_t { + /** + * Maximum number of ML completion event pools + * + * See odp_pool_capability_t.max_pools for maximum number of pools of any type. It + * includes also ML completion event pools. + */ + uint32_t max_pools; + + /** Maximum number of ML completion events in a pool */ + uint32_t max_num; + + /** Maximum user area size in bytes */ + uint32_t max_uarea_size; + + /** User area persistence + * + * See buf.uarea_persistence of odp_pool_capability_t for details + * (odp_pool_capability_t.uarea_persistence). + */ + odp_bool_t uarea_persistence; + + /** Maximum size of local thread cache */ + uint32_t max_cache_size; + + /** Minimum size of local thread cache */ + uint32_t min_cache_size; + +} odp_ml_compl_pool_capability_t; + +/** + * ML completion event pool parameters + * + * Use odp_ml_compl_pool_param_init() to initialize the structure to its default values. + */ +typedef struct odp_ml_compl_pool_param_t { + /** + * Number of ML completion events in the pool + * + * The maximum supported value is defined by ML pool capability 'max_num' + * (odp_ml_compl_pool_capability_t.max_num). + */ + uint32_t num; + + /** + * User area size in bytes + * + * The maximum supported value is defined by ML pool capability 'max_uarea_size'. + * Specify as zero if no user area is needed. The default value is 0. + */ + uint32_t uarea_size; + + /** Parameters for user area initialization */ + struct { + /** See uarea_init.init_fn of odp_pool_param_t for details + * (odp_pool_param_t.init_fn). Function is called during + * odp_ml_compl_pool_create(). The default value is NULL. */ + void (*init_fn)(void *uarea, uint32_t size, void *args, uint32_t index); + + /** See uarea_init.args of odp_pool_param_t for details + * (odp_pool_param_t.args). The default value is NULL. */ + void *args; + + } uarea_init; + + /** + * Maximum number of events cached locally per thread + * + * See odp_pool_param_t.cache_size documentation for details. Valid values range from + * 'min_cache_size' to 'max_cache_size' ML pool capability. The default value is + * implementation specific and set by odp_ml_compl_pool_param_init(). + */ + uint32_t cache_size; + +} odp_ml_compl_pool_param_t; + +/** Machine learning capabilities */ +typedef struct odp_ml_capability_t { + /** Maximum number of models + * + * Maximum number of models that can be created simultaneously. The value is zero when + * ML offload is not available. */ + uint32_t max_models; + + /** Maximum number of models that can be loaded simultaneously */ + uint32_t max_models_loaded; + + /** Maximum model size in bytes */ + uint64_t max_model_size; + + /** Maximum completion identifier value */ + uint32_t max_compl_id; + + /** Maximum number of model inputs */ + uint32_t max_inputs; + + /** Maximum number of model outputs */ + uint32_t max_outputs; + + /** + * Maximum number of data segments per model input + * + * Segmented input data is not supported when 1. + */ + uint32_t max_segs_per_input; + + /** + * Maximum number of data segments per model output + * + * Segmented output data is not supported when 1. + */ + uint32_t max_segs_per_output; + + /** + * Minimum input data alignment in bytes + * + * For each model input, the first data segment must start at this or a higher power of two + * memory alignment in bytes. The value is 1 when there is no alignment requirement. + */ + uint32_t min_input_align; + + /** + * Minimum output data alignment in bytes + * + * For each model output, the first data segment must start at this or a higher power of two + * memory alignment in bytes. The value is 1 when there is no alignment requirement. + */ + uint32_t min_output_align; + + /** + * Input data packing + * + * 0: Data packing is not required. + * 1: Data for all model inputs must be continuous in memory. The memory block starts with + * data for the first input and continues through all inputs in-order and without gaps + * between inputs. The minimum alignment requirement (min_input_align) applies only for + * the first input. + */ + odp_bool_t packed_input_data; + + /** + * Output data packing + * + * 0: Data packing is not required. + * 1: Data buffer space for all model outputs must be continuous in memory. The memory + * block starts with buffer space for the first output and continues through all outputs + * in-order and without gaps between outputs. The minimum alignment requirement + * (min_output_align) applies only for the first output. + */ + odp_bool_t packed_output_data; + + /** Model load / unload capabilities */ + struct { + /** + * Supported completion modes for model load / unload operations + * + * Mask of supported completion modes. Each supported mode has the corresponding + * flag (e.g. #ODP_ML_COMPL_MODE_SYNC) set in the mask. + */ + odp_ml_compl_mode_t compl_mode_mask; + + /** + * Support of model load / unload completion into plain queues + * + * Specifies if plain queues are supported as destination queues for + * load / unload completion events (#ODP_ML_COMPL_MODE_EVENT). + * + * 0: Plain queues are not supported as completion queues + * 1: Plain queues are supported as completion queues + */ + odp_bool_t compl_queue_plain; + + /** + * Support of model load / unload completion into scheduled queues + * + * Specifies if scheduled queues are supported as destination queues for + * load / unload completion events (#ODP_ML_COMPL_MODE_EVENT). + * + * 0: Scheduled queues are not supported as completion queues + * 1: Scheduled queues are supported as completion queues + */ + odp_bool_t compl_queue_sched; + + } load; + + /** Model run capabilities */ + struct { + /** + * Supported completion modes for model run operations + * + * Mask of supported completion modes. Each supported mode has the corresponding + * flag (e.g. #ODP_ML_COMPL_MODE_SYNC) set in the mask. + */ + odp_ml_compl_mode_t compl_mode_mask; + + /** + * Support of model run completion into plain queues + * + * Specifies if plain queues are supported as destination queues for + * run completion events (#ODP_ML_COMPL_MODE_EVENT). + * + * 0: Plain queues are not supported as completion queues + * 1: Plain queues are supported as completion queues + */ + odp_bool_t compl_queue_plain; + + /** + * Support of model run completion into scheduled queues + * + * Specifies if scheduled queues are supported as destination queues for + * run completion events (#ODP_ML_COMPL_MODE_EVENT). + * + * 0: Scheduled queues are not supported as completion queues + * 1: Scheduled queues are supported as completion queues + */ + odp_bool_t compl_queue_sched; + + } run; + + /** ML completion event pool capabilities */ + odp_ml_compl_pool_capability_t pool; + +} odp_ml_capability_t; + +/** Machine learning configuration parameters */ +typedef struct odp_ml_config_t { + /** + * Maximum number of models + * + * Application may create and use this many models simultaneously. The default value is 1. + */ + uint32_t max_models_created; + + /** + * Maximum number of models loaded + * + * Maximum number of models that the application will keep loaded simultaneously. + * The default value is 1. + */ + uint32_t max_models_loaded; + + /** + * Maximum model binary size in bytes + * + * All model binaries application will pass to odp_ml_model_create() are this size or + * smaller. + */ + uint64_t max_model_size; + + /** + * Load / unload completion modes + * + * Mask of completion modes that application will use with model load/unload operations. + * Multiple modes may be selected, but it is implementation specific if some combinations + * are not supported. In case of an unsupported combination odp_ml_config() returns + * failure. Check odp_ml_capability_t.load for supported modes. The default value is 0. + */ + odp_ml_compl_mode_t load_mode_mask; + + /** + * Run completion modes + * + * Mask of completion modes that application will use with model run operations. + * Multiple modes may be selected, but it is implementation specific if some combinations + * are not supported. In case of an unsupported combination odp_ml_config() returns + * failure. Check odp_ml_capability_t.run for supported modes. The default value is 0. + */ + odp_ml_compl_mode_t run_mode_mask; + +} odp_ml_config_t; + +/** Model input / output data type enumeration */ +typedef enum { + /** Data type is not defined */ + ODP_ML_DATA_TYPE_NONE = 0, + + /** 8-bit integer */ + ODP_ML_DATA_TYPE_INT8, + + /** 8-bit unsigned integer */ + ODP_ML_DATA_TYPE_UINT8, + + /** 16-bit integer */ + ODP_ML_DATA_TYPE_INT16, + + /** 16-bit unsigned integer */ + ODP_ML_DATA_TYPE_UINT16, + + /** 24-bit integer */ + ODP_ML_DATA_TYPE_INT24, + + /** 24-bit unsigned integer */ + ODP_ML_DATA_TYPE_UINT24, + + /** 32-bit integer */ + ODP_ML_DATA_TYPE_INT32, + + /** 32-bit unsigned integer */ + ODP_ML_DATA_TYPE_UINT32, + + /** 64-bit integer */ + ODP_ML_DATA_TYPE_INT64, + + /** 64-bit unsigned integer */ + ODP_ML_DATA_TYPE_UINT64, + + /** 16-bit floating point number */ + ODP_ML_DATA_TYPE_FP16, + + /** 16-bit brain floating point (bfloat16) number */ + ODP_ML_DATA_TYPE_BFP16, + + /** 32-bit floating point number */ + ODP_ML_DATA_TYPE_FP32, + + /** 64-bit floating point number */ + ODP_ML_DATA_TYPE_FP64, + +} odp_ml_data_type_t; + +/** Model input / output data shape type */ +typedef enum { + /** Type of shape is not defined */ + ODP_ML_SHAPE_NONE = 0, + + /** Static shape of data + * + * Shape is static when all dimensions have fixed sizes. + */ + ODP_ML_SHAPE_STATIC, + + /** Dynamic batch size + * + * Shape that has only one dynamic dimension, and the dimension is used as batch size of + * input / output data. The same batch size is applied for all inputs and outputs of + * the model. + */ + ODP_ML_SHAPE_BATCH, + +} odp_ml_shape_type_t; + +/** Model input / output data shape information */ +typedef struct odp_ml_shape_info_t { + /** Shape type */ + odp_ml_shape_type_t type; + + /** Number of dimensions + * + * Number of input / output data dimensions. When zero, the model does not have + * dimension information available. ODP API supports in maximum #ODP_ML_MAX_DIMS + * dimensions. + */ + uint32_t num_dim; + + /** Dimension sizes + * + * Number of data values in each ('num_dim') dimension. Type of the data is defined by + * odp_ml_data_type_t enumeration. Depending on the shape type, some dimensions may have + * dynamic size which is denoted with #ODP_ML_DIM_DYNAMIC value. When shape type is + * #ODP_ML_SHAPE_BATCH, the shape has one dynamic dimension which is used as the batch + * size. + * + * For example, a static (#ODP_ML_SHAPE_STATIC) NCHW tensor could be presented as: + * + * num_dim = 4; + * dim[0] = 1; // no batching, N = 1 + * dim[1] = 3; // 3 color channels + * dim[2] = 720; // height 720 pixels + * dim[3] = 1280; // width 1280 pixels + * + * ... and with dynamic batch size (#ODP_ML_SHAPE_BATCH): + * + * num_dim = 4; + * dim[0] = ODP_ML_DIM_DYNAMIC; // dynamic in range: dim_min[0] ... dim_max[0] + * dim[1] = 3; + * dim[2] = 720; + * dim[3] = 1280; + */ + uint32_t dim[ODP_ML_MAX_DIMS]; + + /** Minimum dimension sizes + * + * Defines the minimum value for each dynamic size (#ODP_ML_DIM_DYNAMIC) in dim[] array. + * Zero is used when the minimum value is unknown. When dimension size is static, the + * value is equal to dim[] array value. + */ + uint32_t dim_min[ODP_ML_MAX_DIMS]; + + /** Maximum dimension sizes + * + * Defines the maximum value for each dynamic size (#ODP_ML_DIM_DYNAMIC) in dim[] array. + * Zero is used when the maximum value is unknown. When dimension size is static, the + * value is equal to dim[] array value. + */ + uint32_t dim_max[ODP_ML_MAX_DIMS]; + + /** Dimension name + * + * Name of each ('num_dim') dimension as a null terminated string. Null string is used if + * a dimension does not have a name. Maximum string length is #ODP_ML_SHAPE_NAME_LEN + * including the null character. + * + * For example, an NCHW tensor could have dimensions named as: + * dim_name = {"N", "C", "H", "W"} + */ + char dim_name[ODP_ML_MAX_DIMS][ODP_ML_SHAPE_NAME_LEN]; + +} odp_ml_shape_info_t; + +/** Model input information */ +typedef struct odp_ml_input_info_t { + /** Model input name */ + char name[ODP_ML_MODEL_IO_NAME_LEN]; + + /** Model input data type */ + odp_ml_data_type_t data_type; + + /** Size of model input data type in bytes */ + uint32_t data_type_size; + + /** Model input data shape */ + odp_ml_shape_info_t shape; + +} odp_ml_input_info_t; + +/** Model output information */ +typedef struct odp_ml_output_info_t { + /** Model output name */ + char name[ODP_ML_MODEL_IO_NAME_LEN]; + + /** Model output data type */ + odp_ml_data_type_t data_type; + + /** Size of model output data type in bytes */ + uint32_t data_type_size; + + /** Model output data shape */ + odp_ml_shape_info_t shape; + +} odp_ml_output_info_t; + +/** Model information */ +typedef struct odp_ml_model_info_t { + /** Model name */ + char name[ODP_ML_MODEL_NAME_LEN]; + + /** + * Model version number + * + * Version number of the model binary. The number changes when the model is modified + * in any way. + */ + uint64_t model_version; + + /** + * Model interface version number + * + * The model interface version number changes only when model input or output data + * format is modified. Data formats are the same for two model versions that have + * the same interface version number. + */ + uint64_t interface_version; + + /** Model index assigned by the implementation */ + uint32_t index; + + /** Number of model inputs */ + uint32_t num_inputs; + + /** Number of model outputs */ + uint32_t num_outputs; + +} odp_ml_model_info_t; + +/** + * Model input / output data format + */ +typedef struct odp_ml_data_format_t { + /** Model input / output data type */ + odp_ml_data_type_t data_type; + + /** Size of data type in bytes */ + uint32_t data_type_size; + + /** Model input / output data shape */ + odp_ml_shape_info_t shape; + +} odp_ml_data_format_t; + +/** + * Machine learning model parameters + * + * Use odp_ml_model_param_init() to initialize the structure to its default values. + */ +typedef struct odp_ml_model_param_t { + /** + * Model binary + * + * Points to model binary stored into a memory buffer. Model format is + * implementation specific. */ + void *model; + + /** Size of the model binary in bytes */ + uint64_t size; + + /** + * Maximum completion identifier value + * + * When application uses asynchronous poll mode (#ODP_ML_COMPL_MODE_POLL) operations with + * the model, it will choose completion identifier values between 0 and this value. Valid + * values range from 0 to max_compl_id capability. The default value is zero. + */ + uint32_t max_compl_id; + + /** + * Enable / disable extra statistics counters + * + * Extra statistics may be read with odp_ml_model_extra_stats() when enabled. Statistics + * are disabled by default. + */ + odp_bool_t extra_stat_enable; + + /** + * Extra model information + * + * When model metadata misses some details of model input / output data format, user can + * pass those with this structure. When 'num_inputs' / 'num_outputs' is non-zero, data + * format of all model inputs / outputs are overridden by the provided values. Values are + * ignored when 'num_inputs' / 'num_outputs' is zero. + */ + struct { + /** + * Number of model inputs + * + * Number of model inputs and elements in 'input_format' array. When non-zero, + * the value must match the number of inputs defined in model metadata. The default + * value is 0. + */ + uint32_t num_inputs; + + /** + * Number of model outputs + * + * Number of model outputs and elements in 'output_format' array. When non-zero, + * the value must match the number of outputs defined in model metadata. The default + * value is 0. + */ + uint32_t num_outputs; + + /** + * Model input data format array + * + * Points to an array of data formats. The array has 'num_inputs' elements. Inputs + * are defined in the same order they are listed in model metadata. + * An odp_ml_model_create() call copies these values. The default value is NULL. + */ + const odp_ml_data_format_t *input_format; + + /** + * Model output data format array + * + * Points to an array of data formats. The array has 'num_outputs' elements. Outputs + * are defined in the same order they are listed in model metadata. + * An odp_ml_model_create() call copies these values. The default value is NULL. + */ + const odp_ml_data_format_t *output_format; + + } extra_info; + + /** + * ODP implementation specific extra parameters + * + * See ODP implementation documentation for details about extra parameter usage. For + * example, extra parameters may give hints about HW resource usage with the model to be + * created. An odp_ml_model_create() call copies these parameter values. When NULL, all + * extra parameters are set to their default values. The default value is NULL. + */ + const odp_ml_model_extra_param_t *extra_param; + +} odp_ml_model_param_t; + +/** Results of model run operation */ +typedef struct odp_ml_run_result_t { + /** Model run error code + * + * Zero when model run completed successfully. Otherwise, error code contains + * an implementation specific value. + */ + uint64_t error_code; + + /** User context pointer value from odp_ml_compl_param_t */ + void *user_ptr; + +} odp_ml_run_result_t; + +/** Result of model load / unload operation */ +typedef struct odp_ml_load_result_t { + /** Model load / unload error code + * + * Zero when model load / unload completed successfully. Otherwise, error code contains + * an implementation specific value. + */ + uint64_t error_code; + + /** User context pointer value from odp_ml_compl_param_t */ + void *user_ptr; + +} odp_ml_load_result_t; + +/** + * ML completion parameters + * + * Use odp_ml_compl_param_init() to initialize the structure to its default values. + */ +typedef struct odp_ml_compl_param_t { + /** + * Completion mode + * + * The selected completion mode defines which other parameters are used. When + * #ODP_ML_COMPL_MODE_EVENT mode is selected, 'event' and 'queue' must have valid values + * but value of 'compl_id' is ignored, or vice versa when #ODP_ML_COMPL_MODE_POLL mode is + * selected. + */ + odp_ml_compl_mode_t mode; + + /** + * Completion event + * + * Event to be enqueued by ML offload to the completion queue when ML operation + * is complete. Event type must be ODP_EVENT_ML_COMPL. ML offload sets the subtype of + * the event to ODP_EVENT_ML_COMPL_LOAD or ODP_EVENT_ML_COMPL_RUN based on the completed + * operation. + */ + odp_event_t event; + + /** + * Completion queue + * + * Destination queue for the completion event. + */ + odp_queue_t queue; + + /** + * Completion identifier + * + * When completion mode is #ODP_ML_COMPL_MODE_POLL, ML operation completion status is + * reported through this completion identifier. The value passed here is used in + * a following status call to check model load, unload, or inference completion + * (see e.g. odp_ml_model_load_status()). + * + * Application selects a value between 0 and max_compl_id defined in model creation + * parameters (see odp_ml_model_param_t). Only single ML operation (per model) may be + * started with the same identifier value at a time. A value may be reused for the next + * ML operation only after the previous operation is complete. + */ + uint32_t compl_id; + + /** + * User defined context pointer + * + * ODP implementation does not refer to the pointer, but just copies it to the result. + * For example, application may use this pointer to link a received completion event + * to the originating model run request and its input / output data. The default value + * is NULL. + */ + void *user_ptr; + +} odp_ml_compl_param_t; + +/** Model input / output data segment */ +typedef struct odp_ml_data_seg_t { + /** Segment start address */ + void *addr; + + /** Segment size in bytes */ + uint64_t size; + +} odp_ml_data_seg_t; + +/** Model input / output data for a model inference run */ +typedef struct odp_ml_data_t { + /** + * Number of input data segments + * + * Number of elements in 'input_seg' array (at least one per input). + */ + uint32_t num_input_seg; + + /** + * Number of output data segments + * + * Number of elements in 'output_seg' array (at least one per output). + */ + uint32_t num_output_seg; + + /** + * Model input data segments + * + * Points to an array of data segment descriptors for model input data. Each segment + * (odp_ml_data_seg_t) specifies data for one input only. Multiple consecutive segments may + * be used to specify data for the same input. Sum of those segment sizes must match data + * size of the input. Inputs are defined in the same order which odp_ml_model_input_info() + * reports those. + * + * Input data segments may overlap in memory. + */ + odp_ml_data_seg_t *input_seg; + + /** + * Model output data segments + * + * Points to an array of data segment descriptors for model output data. Each segment + * (odp_ml_data_seg_t) specifies data buffer space for one output only. Multiple + * consecutive segments may be used to specify buffer space for the same output. + * Sum of those segment sizes must match data size of the output. Outputs are defined + * in the same order which odp_ml_model_output_info() reports those. + * + * An output data segment must not overlap with any other (input or output) segment + * in memory. + */ + odp_ml_data_seg_t *output_seg; + +} odp_ml_data_t; + +/** + * Parameters for model run + * + * Use odp_ml_run_param_init() to initialize the structure to its default values. + */ +typedef struct odp_ml_run_param_t { + /** + * Batch size + * + * Batch size for all model inputs and outputs that have #ODP_ML_SHAPE_BATCH shape type. + * The default value is 0. + */ + uint32_t batch_size; + + /** + * Model run results + * + * Points to a result structure for model run result output. Results are output only + * in synchronous mode (#ODP_ML_COMPL_MODE_SYNC). The pointer value is ignored in + * asynchronous modes. Use NULL when results are not required. The default value is NULL. + */ + odp_ml_run_result_t *result; + +} odp_ml_run_param_t; + +/** + * ML extra statistics counter information + */ +typedef struct odp_ml_extra_stat_info_t { + /** Name of the statistics counter */ + char name[ODP_ML_EXTRA_STAT_NAME_LEN]; + +} odp_ml_extra_stat_info_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h index 92c35ae6d..7f6c732ee 100644 --- a/include/odp/api/spec/packet.h +++ b/include/odp/api/spec/packet.h @@ -1,75 +1,47 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2021-2023 Nokia */ - /** * @file * * ODP packet descriptor */ -#ifndef ODP_API_PACKET_H_ -#define ODP_API_PACKET_H_ +#ifndef ODP_API_SPEC_PACKET_H_ +#define ODP_API_SPEC_PACKET_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif -#include <odp/api/time.h> +#include <odp/api/event_types.h> +#include <odp/api/packet_types.h> +#include <odp/api/packet_io_types.h> +#include <odp/api/pool_types.h> +#include <odp/api/proto_stats_types.h> +#include <odp/api/std_types.h> +#include <odp/api/time_types.h> -/** @defgroup odp_packet ODP PACKET - * Operations on a packet. +/** @addtogroup odp_packet + * Packet event metadata and operations. * @{ */ /** - * @typedef odp_packet_t - * ODP packet - */ - -/** - * @def ODP_PACKET_INVALID - * Invalid packet - */ - -/** - * @def ODP_PACKET_OFFSET_INVALID - * Invalid packet offset - */ - -/** - * @typedef odp_packet_seg_t - * ODP packet segment - */ - -/** - * @def ODP_PACKET_SEG_INVALID - * Invalid packet segment + * Event subtype of a packet + * + * Returns the subtype of a packet event. Subtype tells if the packet contains + * only basic metadata (ODP_EVENT_PACKET_BASIC) or in addition to that some + * specific metadata (e.g. ODP_EVENT_PACKET_CRYPTO or ODP_EVENT_PACKET_IPSEC). + * + * @param packet Packet handle + * + * @return Packet subtype */ - - /** - * @typedef odp_packet_color_t - * Color of packet for shaper/drop processing - */ - - /** - * @def ODP_PACKET_GREEN - * Packet is green - */ - - /** - * @def ODP_PACKET_YELLOW - * Packet is yellow - */ - - /** - * @def ODP_PACKET_RED - * Packet is red - */ +odp_event_subtype_t odp_packet_subtype(odp_packet_t packet); /* * @@ -138,15 +110,25 @@ void odp_packet_free(odp_packet_t pkt); void odp_packet_free_multi(const odp_packet_t pkt[], int num); /** + * Free multiple packets to the same pool + * + * Otherwise like odp_packet_free_multi(), but all packets must be from the + * same originating pool. + * + * @param pkt Array of packet handles + * @param num Number of packets to free + */ +void odp_packet_free_sp(const odp_packet_t pkt[], int num); + +/** * Reset packet * * Resets all packet metadata to their default values. Packet length is used * to initialize pointers and lengths. It must be less than the total buffer - * length of the packet minus the default headroom length. Packet is not - * modified on failure. + * length of the packet. Packet is not modified on failure. * * @param pkt Packet handle - * @param len Packet data length + * @param len Packet data length (1 ... odp_packet_buf_len()) * * @retval 0 on success * @retval <0 on failure @@ -169,6 +151,18 @@ int odp_packet_reset(odp_packet_t pkt, uint32_t len); odp_packet_t odp_packet_from_event(odp_event_t ev); /** + * Convert multiple packet events to packet handles + * + * All events must be of type ODP_EVENT_PACKET. + * + * @param[out] pkt Packet handle array for output + * @param ev Array of event handles to convert + * @param num Number of packets and events + */ +void odp_packet_from_event_multi(odp_packet_t pkt[], const odp_event_t ev[], + int num); + +/** * Convert packet handle to event * * @param pkt Packet handle @@ -177,6 +171,53 @@ odp_packet_t odp_packet_from_event(odp_event_t ev); */ odp_event_t odp_packet_to_event(odp_packet_t pkt); +/** + * Convert multiple packet handles to events + * + * @param pkt Array of packet handles to convert + * @param[out] ev Event handle array for output + * @param num Number of packets and events + */ +void odp_packet_to_event_multi(const odp_packet_t pkt[], odp_event_t ev[], + int num); + +/** + * Get information about successful reassembly offload that has happened + * + * This function may be called only if the reassembly status of a packet + * is ODP_PACKET_REASS_COMPLETE. + * + * @param pkt Completely reassembled packet. + * @param[out] info Pointer to the info structure to be filled + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_packet_reass_info(odp_packet_t pkt, odp_packet_reass_info_t *info); + +/** + * Get partial reassembly state from a packet + * + * In case of incomplete reassembly, a packet carries information on + * the time already used for the reassembly attempt and one or more + * fragments. The fragments are not necessarily the original received + * fragments but may be partially reassembled parts of the packet. + * + * This function may be called only if the reassembly status of a packet + * is ODP_PACKET_REASS_INCOMPLETE. + * + * @param pkt Incompletely reassembled packet. The packet will + * be consumed if the function succeeds. + * @param[out] frags Packet handle array for output. The size of this array must + * be at least `odp_reass_config_t::max_num_frags`. + * @param[out] res Pointer to result structure + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_packet_reass_partial_state(odp_packet_t pkt, odp_packet_t frags[], + odp_packet_reass_partial_state_t *res); + /* * * Pointers and lengths @@ -215,43 +256,71 @@ uint32_t odp_packet_buf_len(odp_packet_t pkt); /** * Packet data pointer * - * Returns the current packet data pointer. When a packet is received - * from packet input, this points to the first byte of the received - * packet. Packet level offsets are calculated relative to this position. + * Returns pointer to the first byte of packet data. When packet is segmented, + * only a portion of packet data follows the pointer. When unsure, use e.g. + * odp_packet_seg_len() to check the data length following the pointer. Packet + * level offsets are calculated relative to this position. * - * User can adjust the data pointer with head_push/head_pull (does not modify - * segmentation) and add_data/rem_data calls (may modify segmentation). + * When a packet is received from packet input, this points to the first byte + * of the received packet. Pool configuration parameters may be used to ensure + * that the first packet segment contains all/most of the data relevant to the + * application. + * + * User can adjust the data pointer with e.g. push_head/pull_head (does not + * modify segmentation) and extend_head/trunc_head (may modify segmentation) + * calls. * * @param pkt Packet handle * * @return Pointer to the packet data * - * @see odp_packet_l2_ptr(), odp_packet_seg_len() + * @see odp_packet_seg_len(), odp_packet_push_head(), odp_packet_extend_head() */ void *odp_packet_data(odp_packet_t pkt); /** - * Packet segment data length + * Packet data length following the data pointer * - * Returns number of data bytes following the current data pointer - * (odp_packet_data()) location in the segment. + * Returns number of data bytes (in the segment) following the current data + * pointer position. When unsure, use this function to check how many bytes + * can be accessed linearly after data pointer (odp_packet_data()). This + * equals to odp_packet_len() for single segment packets. * * @param pkt Packet handle * - * @return Segment data length in bytes (pointed by odp_packet_data()) + * @return Segment data length in bytes following odp_packet_data() * * @see odp_packet_data() */ uint32_t odp_packet_seg_len(odp_packet_t pkt); /** + * Packet data pointer with segment length + * + * Returns both data pointer and number of data bytes (in the segment) + * following it. This is equivalent to calling odp_packet_data() and + * odp_packet_seg_len(). + * + * @param pkt Packet handle + * @param[out] seg_len Pointer to output segment length + * + * @return Pointer to the packet data + * + * @see odp_packet_data(), odp_packet_seg_len() + */ +void *odp_packet_data_seg_len(odp_packet_t pkt, uint32_t *seg_len); + +/** * Packet data length * - * Returns sum of data lengths over all packet segments. + * Returns total data length over all packet segments. This equals the sum of + * segment level data lengths (odp_packet_seg_data_len()). * * @param pkt Packet handle * * @return Packet data length + * + * @see odp_packet_seg_len(), odp_packet_data(), odp_packet_seg_data_len() */ uint32_t odp_packet_len(odp_packet_t pkt); @@ -498,7 +567,8 @@ int odp_packet_extend_head(odp_packet_t *pkt, uint32_t len, void **data_ptr, * * @param[in, out] pkt Pointer to packet handle. A successful operation outputs * the new packet handle. - * @param len Number of bytes to truncate the head (0 ... packet_len) + * @param len Number of bytes to truncate the head + * (0 ... packet_len - 1) * @param[out] data_ptr Pointer to output the new data pointer. * Ignored when NULL. * @param[out] seg_len Pointer to output segment length at 'data_ptr' above. @@ -571,7 +641,8 @@ int odp_packet_extend_tail(odp_packet_t *pkt, uint32_t len, void **data_ptr, * * @param[in, out] pkt Pointer to packet handle. A successful operation outputs * the new packet handle. - * @param len Number of bytes to truncate the tail (0 ... packet_len) + * @param len Number of bytes to truncate the tail + * (0 ... packet_len - 1) * @param[out] tail_ptr Pointer to output the new tail pointer. * Ignored when NULL. * @param[out] tailroom Pointer to output the new tailroom. Ignored when NULL. @@ -635,7 +706,9 @@ int odp_packet_add_data(odp_packet_t *pkt, uint32_t offset, uint32_t len); * @param[in, out] pkt Pointer to packet handle. A successful operation outputs * the new packet handle. * @param offset Byte offset into the packet - * @param len Number of bytes to remove from the offset + * @param len Number of bytes to remove from the offset. When offset + * is zero: 0 ... packet_len - 1 bytes, otherwise + * 0 ... packet_len - offset bytes. * * @retval 0 Operation successful, old pointers remain valid * @retval >0 Operation successful, old pointers need to be updated @@ -838,6 +911,7 @@ int odp_packet_concat(odp_packet_t *dst, odp_packet_t src); * @param[in, out] pkt Pointer to packet handle. A successful operation * outputs a new packet handle for the head packet. * @param len Data length remaining in the head packet + * (1 ... packet_len - 1) * @param tail Pointer to output the tail packet handle * * @retval 0 Operation successful, old pointers remain valid @@ -846,6 +920,135 @@ int odp_packet_concat(odp_packet_t *dst, odp_packet_t src); */ int odp_packet_split(odp_packet_t *pkt, uint32_t len, odp_packet_t *tail); +/** + * Packet buffer head pointer + * + * Packet buffer start address. Buffer level headroom starts from here. For the first + * packet buffer of a packet this is equivalent to odp_packet_head(). + * + * @param pkt_buf Packet buffer + * + * @return Packet buffer head pointer + */ +void *odp_packet_buf_head(odp_packet_buf_t pkt_buf); + +/** + * Packet buffer size in bytes + * + * Packet buffer size is calculated from the buffer head pointer (see odp_packet_buf_head()). + * It contains all buffer level headroom, data, and tailroom. For a single segmented packet this is + * equivalent to odp_packet_buf_len(). + * + * @param pkt_buf Packet buffer + * + * @return Packet buffer size + */ +uint32_t odp_packet_buf_size(odp_packet_buf_t pkt_buf); + +/** + * Packet buffer data offset + * + * Offset from the buffer head pointer to the first byte of packet data in the packet buffer. + * Valid values range from 0 to buf_size - 1. For the first packet buffer of a packet + * this is equivalent to odp_packet_headroom(). + * + * @param pkt_buf Packet buffer + * + * @return Packet buffer data offset + */ +uint32_t odp_packet_buf_data_offset(odp_packet_buf_t pkt_buf); + +/** + * Packet buffer data length in bytes + * + * Packet buffer contains this many bytes of packet data. Valid values range from 1 to + * buf_size - data_offset. For the first packet buffer of a packet this is equivalent to + * odp_packet_seg_len(). + * + * @param pkt_buf Packet buffer + * + * @return Packet buffer data length + */ +uint32_t odp_packet_buf_data_len(odp_packet_buf_t pkt_buf); + +/** + * Packet buffer data set + * + * Update packet data start offset and length in the packet buffer. Valid offset values range + * from 0 to buf_size - 1. Valid length values range from 1 to buf_size - data_offset. + * + * @param pkt_buf Packet buffer + * @param data_offset Packet buffer data offset in bytes (from the buffer head pointer) + * @param data_len Packet buffer data length in bytes + */ +void odp_packet_buf_data_set(odp_packet_buf_t pkt_buf, uint32_t data_offset, uint32_t data_len); + +/** + * Convert packet buffer head pointer to handle + * + * Converts a packet buffer head pointer (from a previous odp_packet_buf_head() call) to a packet + * buffer handle. This allows an application to save memory as it can store only buffer pointers + * (instead of pointers and handles) and convert those to handles when needed. This conversion + * may be done only for packet buffers that are not part of any packet (i.e. buffers between + * odp_packet_disassemble() and odp_packet_reassemble() calls). + * + * This call can be used only for packets of an external memory pool (see odp_pool_ext_create()). + * + * @param pool Pool from which the packet buffer (disassembled packet) originate from + * @param head Head pointer + * + * @return Packet buffer handle on success + * @retval ODP_PACKET_BUF_INVALID on failure + */ +odp_packet_buf_t odp_packet_buf_from_head(odp_pool_t pool, void *head); + +/** + * Disassemble packet into packet buffers + * + * Breaks up a packet into a list of packet buffers. Outputs a packet buffer handle for each + * segment of the packet (see odp_packet_num_segs()). After a successful operation the packet + * handle must not be referenced anymore. Packet buffers are reassembled into a new packet (or + * several new packets) with a later odp_packet_reassemble() call(s). All packet buffers must be + * reassembled into a packet and freed into the originating pool before the pool is destroyed. + * + * This call can be used only for packets of an external memory pool (see odp_pool_ext_create()). + * + * @param pkt Packet to be disassembled + * @param[out] pkt_buf Packet buffer handle array for output + * @param num Number of elements in packet buffer handle array. Must be equal to or + * larger than number of segments in the packet. + * + * @return Number of handles written (equals the number of segments in the packet) + * @retval 0 on failure + */ +uint32_t odp_packet_disassemble(odp_packet_t pkt, odp_packet_buf_t pkt_buf[], uint32_t num); + +/** + * Reassemble packet from packet buffers + * + * Forms a new packet from packet buffers of a previous odp_packet_disassemble() call(s). Packet + * buffers from different disassembled packets may be used, but all buffers must be from packets of + * the same pool. Packet pool capability 'max_segs_per_pkt' defines the maximum number of + * packet buffers that can be reassembled to form a new packet. + * + * Application may use odp_packet_buf_data_set() to adjust data_offset and data_len values + * in each packet buffer to match the current packet data placement. The operation + * maintains packet data content and position. Each buffer becomes a segment in the new packet. + * Packet metadata related to data length and position are set according data layout + * in the buffers. All other packet metadata are set to their default values. After a successful + * operation packet buffer handles must not be referenced anymore. + * + * This call can be used only for packets of an external memory pool (see odp_pool_ext_create()). + * + * @param pool Pool from which all packet buffers (disassembled packets) originate from + * @param pkt_buf Packet buffers to form a new packet + * @param num Number of packet buffers. Must not exceed max_segs_per_pkt pool capability. + * + * @return Handle of the newly formed packet + * @retval ODP_PACKET_INVALID on failure + */ +odp_packet_t odp_packet_reassemble(odp_pool_t pool, odp_packet_buf_t pkt_buf[], uint32_t num); + /* * * References @@ -892,7 +1095,7 @@ odp_packet_t odp_packet_ref_static(odp_packet_t pkt); * dynamic references must not be mixed. Results are undefined if these * restrictions are not observed. * - * The packet handle 'pkt' may itself by a (dynamic) reference to a packet. + * The packet handle 'pkt' may itself be a (dynamic) reference to a packet. * * If the caller does not intend to modify either the packet or the new * reference to it, odp_packet_ref_static() may be used to create @@ -919,7 +1122,7 @@ odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset); * packet consists metadata and data of the 'hdr' packet, followed by the * shared part of packet 'pkt'. * - * The packet handle ('pkt') may itself by a (dynamic) reference to a packet, + * The packet handle ('pkt') may itself be a (dynamic) reference to a packet, * but the header packet handle ('hdr') must be unique. Both packets must be * have been allocated from the same pool and the handles must not refer to * the same packet. Results are undefined if these restrictions are not @@ -944,25 +1147,6 @@ odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset, odp_packet_t hdr); /** - * Packet unshared data length - * - * When a packet has multiple references, packet data is divided into two - * parts: unshared and shared. The unshared part always precedes the shared - * part. This call returns number of bytes in the unshared part. When a - * packet has only a single reference (see odp_packet_has_ref()), all packet - * data is unshared and unshared length equals the packet length - * (odp_packet_len()). - * - * Application may modify only the unshared part, the rest of the packet data - * must be treated as read only. - * - * @param pkt Packet handle - * - * @return Packet unshared data length - */ -uint32_t odp_packet_unshared_len(odp_packet_t pkt); - -/** * Test if packet has multiple references * * A packet that has multiple references share data with other packets. In case @@ -1131,6 +1315,77 @@ int odp_packet_move_data(odp_packet_t pkt, uint32_t dst_offset, */ /** + * Parse packet + * + * Parse protocol headers in packet data and update layer/protocol specific + * metadata (e.g. offsets, errors, protocols, checksum statuses, etc). Parsing + * starts at 'offset', which is the first header byte of protocol 'param.proto'. + * Parameter 'param.last_layer' defines the last layer application requests + * to check. Use ODP_PROTO_LAYER_ALL for all layers. A successful operation + * sets (or resets) packet metadata for all layers from the layer of + * 'param.proto' to the application defined last layer. In addition, offset + * (and pointer) to the next layer is set. Other layer/protocol specific + * metadata have undefined values. When operation fails, all layer/protocol + * specific metadata have undefined values. + * + * @param pkt Packet handle + * @param offset Byte offset into the packet + * @param param Parse parameters. Proto and last_layer fields must be set. + * Clear all check bits that are not used. + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_packet_parse(odp_packet_t pkt, uint32_t offset, + const odp_packet_parse_param_t *param); + +/** + * Parse multiple packets + * + * Otherwise like odp_packet_parse(), but parses multiple packets. Packets may + * have unique offsets, but must start with the same protocol. The same + * parse parameters are applied to all packets. + * + * @param pkt Packet handle array + * @param offset Byte offsets into the packets + * @param num Number of packets and offsets + * @param param Parse parameters. Proto and last_layer fields must be set. + * Clear all check bits that are not used. + * + * @return Number of packets parsed successfully (0 ... num) + * @retval <0 on failure + */ +int odp_packet_parse_multi(const odp_packet_t pkt[], const uint32_t offset[], + int num, const odp_packet_parse_param_t *param); + +/** + * Read parse results + * + * Read out the most commonly used packet parse results. The same information is + * available through individual function calls, but this call may be more + * efficient when reading multiple results from a packet. + * + * @param pkt Packet handle + * @param[out] result Pointer for parse result output + */ +void odp_packet_parse_result(odp_packet_t pkt, + odp_packet_parse_result_t *result); + +/** + * Read parse results from multiple packets + * + * Otherwise same functionality as odp_packet_parse_result() but handles + * multiple packets. + * + * @param pkt Packet handle array + * @param[out] result Parse result array for output + * @param num Number of packets and results + */ +void odp_packet_parse_result_multi(const odp_packet_t pkt[], + odp_packet_parse_result_t *result[], + int num); + +/** * Packet pool * * Returns handle to the packet pool where the packet was allocated from. @@ -1155,6 +1410,22 @@ odp_pool_t odp_packet_pool(odp_packet_t pkt); odp_pktio_t odp_packet_input(odp_packet_t pkt); /** + * Set packet input interface + * + * Set packet input interface to a valid packet IO handle or ODP_PKTIO_INVALID. + * An application may use this for testing or other purposes, when perception + * of the packet input interface need to be changed. The call updates both + * input interface handle (odp_packet_input()) and index + * (odp_packet_input_index()). + * + * @param pkt Packet handle + * @param pktio Handle to a valid packet input interface or ODP_PKTIO_INVALID. + * ODP_PKTIO_INVALID indicates that the packet was not received by + * any packet IO interface. + */ +void odp_packet_input_set(odp_packet_t pkt, odp_pktio_t pktio); + +/** * Packet input interface index * * Returns the index of the packet I/O interface that received the packet, or @@ -1170,7 +1441,10 @@ int odp_packet_input_index(odp_packet_t pkt); /** * User context pointer * - * Return previously stored user context pointer. + * Return previously stored user context pointer. If not otherwise documented, + * the pointer value is maintained over packet manipulating operations. + * Implementation initializes the pointer value to NULL during new packet + * creation (e.g. alloc and packet input) and reset. * * @param pkt Packet handle * @@ -1186,10 +1460,10 @@ void *odp_packet_user_ptr(odp_packet_t pkt); * value of type intptr_t. ODP may use the pointer for data prefetching, but * must ignore any invalid addresses. * - * @param pkt Packet handle - * @param ctx User context pointer + * @param pkt Packet handle + * @param user_ptr User context pointer */ -void odp_packet_user_ptr_set(odp_packet_t pkt, const void *ctx); +void odp_packet_user_ptr_set(odp_packet_t pkt, const void *user_ptr); /** * User area address @@ -1216,17 +1490,43 @@ void *odp_packet_user_area(odp_packet_t pkt); uint32_t odp_packet_user_area_size(odp_packet_t pkt); /** + * Check user flag + * + * Implementation clears user flag during new packet creation (e.g. alloc and packet input) + * and reset. User may set the flag with odp_packet_user_flag_set(). Implementation never + * sets the flag, only clears it. The flag may be useful e.g. to mark when the user area + * content is valid. + * + * @param pkt Packet handle + * + * @retval 0 User flag is clear + * @retval >0 User flag is set + */ +int odp_packet_user_flag(odp_packet_t pkt); + +/** + * Set user flag + * + * Set (or clear) the user flag. + * + * @param pkt Packet handle + * @param val New value for the flag. Zero clears the flag, other values set the flag. + */ +void odp_packet_user_flag_set(odp_packet_t pkt, int val); + +/** * Layer 2 start pointer * - * Returns pointer to the start of the layer 2 header. Optionally, outputs - * number of data bytes in the segment following the pointer. + * Returns pointer to the start of layer 2. Optionally, outputs number of data + * bytes in the segment following the pointer. The pointer value is generated + * from the current layer 2 offset. * * @param pkt Packet handle * @param[out] len Number of data bytes remaining in the segment (output). * Ignored when NULL. * - * @return Layer 2 start pointer - * @retval NULL packet does not contain a valid L2 header + * @return Layer 2 start pointer + * @retval NULL Layer 2 offset has not been set * * @see odp_packet_l2_offset(), odp_packet_l2_offset_set(), odp_packet_has_l2() */ @@ -1235,16 +1535,16 @@ void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len); /** * Layer 2 start offset * - * Returns offset to the start of the layer 2 header. The offset is calculated - * from the current odp_packet_data() position in bytes. - * - * User is responsible to update the offset when modifying the packet data - * pointer position. + * Returns offset to the start of layer 2. The offset is calculated from the + * current odp_packet_data() position in bytes. Packet parsing sets the offset + * according to parse configuration and layers recognized in the packet. Data + * start position updating functions (e.g. odp_packet_push_head()) do not modify + * the offset, but user sets a new value when needed. * * @param pkt Packet handle * - * @return Layer 2 start offset - * @retval ODP_PACKET_OFFSET_INVALID packet does not contain a valid L2 header + * @return Layer 2 start offset + * @retval ODP_PACKET_OFFSET_INVALID Layer 2 offset has not been set * * @see odp_packet_l2_offset_set(), odp_packet_has_l2() */ @@ -1253,9 +1553,9 @@ uint32_t odp_packet_l2_offset(odp_packet_t pkt); /** * Set layer 2 start offset * - * Set offset to the start of the layer 2 header. The offset is calculated from - * the current odp_packet_data() position in bytes. Offset must not exceed - * packet data length. Packet is not modified on an error. + * Set offset to the start of layer 2. The offset is calculated from the current + * odp_packet_data() position in bytes. Offset must not exceed packet data + * length. Offset is not modified on an error. * * @param pkt Packet handle * @param offset Layer 2 start offset (0 ... odp_packet_len()-1) @@ -1268,15 +1568,16 @@ int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset); /** * Layer 3 start pointer * - * Returns pointer to the start of the layer 3 header. Optionally, outputs - * number of data bytes in the segment following the pointer. + * Returns pointer to the start of layer 3. Optionally, outputs number of data + * bytes in the segment following the pointer. The pointer value is generated + * from the current layer 3 offset. * * @param pkt Packet handle * @param[out] len Number of data bytes remaining in the segment (output). * Ignored when NULL. * - * @return Layer 3 start pointer - * @retval NULL packet does not contain a valid L3 header + * @return Layer 3 start pointer + * @retval NULL Layer 3 offset has not been set * * @see odp_packet_l3_offset(), odp_packet_l3_offset_set(), odp_packet_has_l3() */ @@ -1285,16 +1586,16 @@ void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len); /** * Layer 3 start offset * - * Returns offset to the start of the layer 3 header. The offset is calculated - * from the current odp_packet_data() position in bytes. - * - * User is responsible to update the offset when modifying the packet data - * pointer position. + * Returns offset to the start of layer 3. The offset is calculated from the + * current odp_packet_data() position in bytes. Packet parsing sets the offset + * according to parse configuration and layers recognized in the packet. Data + * start position updating functions (e.g. odp_packet_push_head()) do not modify + * the offset, but user sets a new value when needed. * * @param pkt Packet handle * - * @return Layer 3 start offset, or ODP_PACKET_OFFSET_INVALID when packet does - * not contain a valid L3 header. + * @return Layer 3 start offset + * @retval ODP_PACKET_OFFSET_INVALID Layer 3 offset has not been set * * @see odp_packet_l3_offset_set(), odp_packet_has_l3() */ @@ -1303,9 +1604,9 @@ uint32_t odp_packet_l3_offset(odp_packet_t pkt); /** * Set layer 3 start offset * - * Set offset to the start of the layer 3 header. The offset is calculated from - * the current odp_packet_data() position in bytes. Offset must not exceed - * packet data length. Packet is not modified on an error. + * Set offset to the start of layer 3. The offset is calculated from the current + * odp_packet_data() position in bytes. Offset must not exceed packet data + * length. Offset is not modified on an error. * * @param pkt Packet handle * @param offset Layer 3 start offset (0 ... odp_packet_len()-1) @@ -1318,15 +1619,16 @@ int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset); /** * Layer 4 start pointer * - * Returns pointer to the start of the layer 4 header. Optionally, outputs - * number of data bytes in the segment following the pointer. + * Returns pointer to the start of layer 4. Optionally, outputs number of data + * bytes in the segment following the pointer. The pointer value is generated + * from the current layer 4 offset. * * @param pkt Packet handle * @param[out] len Number of data bytes remaining in the segment (output). * Ignored when NULL. * - * @return Layer 4 start pointer - * @retval NULL packet does not contain a valid L4 header + * @return Layer 4 start pointer + * @retval NULL Layer 4 offset has not been set * * @see odp_packet_l4_offset(), odp_packet_l4_offset_set(), odp_packet_has_l4() */ @@ -1335,16 +1637,16 @@ void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len); /** * Layer 4 start offset * - * Returns offset to the start of the layer 4 header. The offset is calculated - * from the current odp_packet_data() position in bytes. - * - * User is responsible to update the offset when modifying the packet data - * pointer position. + * Returns offset to the start of layer 4. The offset is calculated from the + * current odp_packet_data() position in bytes. Packet parsing sets the offset + * according to parse configuration and layers recognized in the packet. Data + * start position updating functions (e.g. odp_packet_push_head()) do not modify + * the offset, but user sets a new value when needed. * * @param pkt Packet handle * - * @return Layer 4 start offset - * @retval ODP_PACKET_OFFSET_INVALID packet does not contain a valid L4 header + * @return Layer 4 start offset + * @retval ODP_PACKET_OFFSET_INVALID Layer 4 offset has not been set * * @see odp_packet_l4_offset_set(), odp_packet_has_l4() */ @@ -1353,9 +1655,9 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt); /** * Set layer 4 start offset * - * Set offset to the start of the layer 4 header. The offset is calculated from - * the current odp_packet_data() position in bytes. Offset must not exceed - * packet data length. Packet is not modified on an error. + * Set offset to the start of layer 4. The offset is calculated from the current + * odp_packet_data() position in bytes. Offset must not exceed packet data + * length. Offset is not modified on an error. * * @param pkt Packet handle * @param offset Layer 4 start offset (0 ... odp_packet_len()-1) @@ -1366,6 +1668,146 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt); int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset); /** + * Layer 2 protocol type + * + * Returns layer 2 protocol type. Initial type value is ODP_PROTO_L2_TYPE_NONE. + * + * @param pkt Packet handle + * + * @return Layer 2 protocol type + */ +odp_proto_l2_type_t odp_packet_l2_type(odp_packet_t pkt); + +/** + * Layer 3 protocol type + * + * Returns layer 3 protocol type. Initial type value is ODP_PROTO_L3_TYPE_NONE. + * + * In addition to protocol types specified in ODP_PROTO_L3_TYPE_* defines, + * the function may also return other L3 protocol types (e.g. from IEEE + * EtherTypes list) recognized by the parser. If protocol type is not + * recognized, ODP_PROTO_L3_TYPE_NONE is returned. + * + * @param pkt Packet handle + * + * @return Layer 3 protocol type + */ +odp_proto_l3_type_t odp_packet_l3_type(odp_packet_t pkt); + +/** + * Layer 4 protocol type + * + * Returns layer 4 protocol type. Initial type value is ODP_PROTO_L4_TYPE_NONE. + * + * In addition to protocol types specified in ODP_PROTO_L4_TYPE_* defines, + * the function may also return other L4 protocol types (e.g. from IANA protocol + * number list) recognized by the parser. If protocol type is not recognized, + * ODP_PROTO_L4_TYPE_NONE is returned. + * + * @param pkt Packet handle + * + * @return Layer 4 protocol type + */ +odp_proto_l4_type_t odp_packet_l4_type(odp_packet_t pkt); + +/** + * Layer 3 checksum check status + * + * Returns the result of the latest layer 3 checksum check done for the packet. + * The status tells if checksum check was attempted and the result of the + * attempt. It depends on packet input (or IPSEC) configuration, packet content + * and implementation capabilities if checksum check is attempted for a packet. + * + * @param pkt Packet handle + * + * @return L3 checksum check status + */ +odp_packet_chksum_status_t odp_packet_l3_chksum_status(odp_packet_t pkt); + +/** + * Layer 4 checksum check status + * + * Returns the result of the latest layer 4 checksum check done for the packet. + * The status tells if checksum check was attempted and the result of the + * attempt. It depends on packet input (or IPSEC) configuration, packet content + * and implementation capabilities if checksum check is attempted for a packet. + * + * When a UDP packet does not have a checksum (e.g. checksum field of a UDP/IPv4 + * packet is zero), checksum check result is ODP_PACKET_CHKSUM_OK. + * + * @param pkt Packet handle + * + * @return L4 checksum check status + */ +odp_packet_chksum_status_t odp_packet_l4_chksum_status(odp_packet_t pkt); + +/** + * Layer 3 checksum insertion override + * + * Override checksum insertion configuration per packet. This per packet setting + * overrides a higher level configuration for checksum insertion into a L3 + * header during packet output processing. + * + * Calling this function is always allowed but the checksum will not be + * inserted if the packet is output through a pktio that does not have + * the relevant checksum insertion enabled. + * + * L3 type and L3 offset in packet metadata should provide valid protocol + * and header offset for checksum insertion purposes. + * + * @param pkt Packet handle + * @param insert 0: do not insert L3 checksum + * 1: insert L3 checksum + * + * @see odp_packet_l3_offset(), odp_packet_has_ipv4(), odp_packet_has_ipv6() + */ +void odp_packet_l3_chksum_insert(odp_packet_t pkt, int insert); + +/** + * Layer 4 checksum insertion override + * + * Override checksum insertion configuration per packet. This per packet setting + * overrides a higher level configuration for checksum insertion into a L4 + * header during packet output processing. + * + * Calling this function is always allowed but the checksum will not be + * inserted if the packet is output through a pktio that does not have + * the relevant checksum insertion enabled. + * + * L3 type, L4 type, L3 offset and L4 offset in packet metadata should provide + * valid protocols and header offsets for checksum insertion purposes. + * + * @param pkt Packet handle + * @param insert 0: do not insert L4 checksum + * 1: insert L4 checksum + * + * @see odp_packet_l3_offset(), odp_packet_has_ipv4(), odp_packet_has_ipv6() + * @see odp_packet_l4_offset(), odp_packet_has_tcp(), odp_packet_has_udp() + * @see odp_packet_has_sctp() + */ +void odp_packet_l4_chksum_insert(odp_packet_t pkt, int insert); + +/** + * Ones' complement sum of packet data + * + * Returns 16-bit ones' complement sum that was calculated over a portion of + * packet data during a packet processing operation (e.g. packet input or + * IPSEC offload). The data range is output with 'range' parameter, and usually + * includes IP payload (L4 headers and payload). When 'range.length' is zero, + * the sum has not been calculated. In case of odd number of bytes, + * calculation uses a zero byte as padding at the end. The sum may be used as + * part of e.g. UDP/TCP checksum checking, especially with IP fragments. + * + * @param pkt Packet handle + * @param[out] range Data range of the sum (output). The calculation started + * from range.offset and included range.length bytes. When + * range.length is zero, the sum has not been calculated. + * + * @return Ones' complement sum over the data range + */ +uint16_t odp_packet_ones_comp(odp_packet_t pkt, odp_packet_data_range_t *range); + +/** * Packet flow hash value * * Returns the hash generated from the packet header. Use @@ -1405,17 +1847,18 @@ void odp_packet_flow_hash_set(odp_packet_t pkt, uint32_t flow_hash); /** * Packet timestamp * - * Returns packet timestamp value as odp_time_t type. Use time API for - * additional operations on packet timestamp values or conversion into - * nanoseconds. Use odp_packet_has_ts() to check if packet has a valid - * timestamp. Packet input interface timestamp resolution can be checked with - * odp_pktin_ts_res(). + * Returns timestamp value recorded into the packet. Use odp_packet_has_ts() to check if the packet + * has a valid timestamp. Packet input uses packet IO interface specific time source and thus + * timestamp (or nanosecond) values from one interface cannot be mixed with values from another + * interface (or time source in general). Packet IO interface timestamp resolution can be checked + * with odp_pktio_ts_res() and current time with odp_pktio_time(). + * + * Time API operations (e.g. odp_time_diff()) can be used with packet timestamp values or + * when converting those into nanoseconds (odp_time_to_ns()). * * @param pkt Packet handle * * @return Timestamp value - * - * @see odp_pktin_ts_res(), odp_packet_has_ts(), odp_time_to_ns() */ odp_time_t odp_packet_ts(odp_packet_t pkt); @@ -1427,12 +1870,27 @@ odp_time_t odp_packet_ts(odp_packet_t pkt); * @param pkt Packet handle * @param timestamp Timestamp value * - * @see odp_packet_ts(), odp_packet_has_ts(), - * odp_pktin_ts_from_ns() + * @see odp_packet_ts(), odp_packet_has_ts(), odp_pktio_ts_from_ns() */ void odp_packet_ts_set(odp_packet_t pkt, odp_time_t timestamp); /** + * Request Tx timestamp capture + * + * Control whether timestamp needs to be captured when this packet is + * transmitted. By default, Tx timestamping is disabled. This API is allowed to + * be called always, but the Tx timestamp is not captured if the output packet + * IO device is not configured to enable timestamping. + * + * @param pkt Packet handle + * @param enable 0: do not capture timestamp on Tx + * 1: capture timestamp on Tx + * + * @see odp_pktout_ts_read() + */ +void odp_packet_ts_request(odp_packet_t pkt, int enable); + +/** * Get packet color * * @param pkt Packet handle @@ -1482,6 +1940,521 @@ int8_t odp_packet_shaper_len_adjust(odp_packet_t pkt); */ void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj); +/** + * Classification mark value + * + * Get the value of the CLS mark of the packet. The mark value is zero by default, but may be + * changed by the classification subsystem. + * + * @param pkt Packet handle + * + * @return mark value + * + * @see odp_cls_capability_t::max_mark, odp_pmr_create_opt_t::mark, odp_cls_pmr_create_opt() + */ +uint64_t odp_packet_cls_mark(odp_packet_t pkt); + +/** + * Request Large Send Offload (LSO) for a packet + * + * Setup packet metadata which requests LSO segmentation to be performed during packet output. + * The selected LSO profile specifies details of the segmentation operation to be done. Depending on + * LSO profile options, additional metadata (e.g. L3/L4 protocol header offsets) may need to be + * set on the packet. + * + * @param pkt Packet handle + * @param lso_opt LSO options + * + * @retval 0 On success + * @retval <0 On failure + */ +int odp_packet_lso_request(odp_packet_t pkt, const odp_packet_lso_opt_t *lso_opt); + +/** + * Clear LSO request from a packet + * + * Clears packet metadata not to request LSO segmentation. + * + * @param pkt Packet handle + */ +void odp_packet_lso_request_clr(odp_packet_t pkt); + +/** + * Check if LSO is requested for the packet + * + * @param pkt Packet handle + * + * @retval non-zero LSO is requested + * @retval 0 LSO is not requested + */ +int odp_packet_has_lso_request(odp_packet_t pkt); + +/** + * Payload data offset + * + * Returns offset to the start of payload data. Packet data before this offset is considered as + * protocol headers. The offset is calculated from the current odp_packet_data() position in bytes. + * Data start position updating functions (e.g. odp_packet_push_head()) do not modify the offset, + * but user sets a new value when needed. + * + * Packet parsing does not set this offset. Initial offset value is undefined. Application may + * utilize the offset for internal purposes or when requesting LSO segmentation for the packet. + * + * @param pkt Packet handle + * + * @return Payload data offset + * @retval ODP_PACKET_OFFSET_INVALID Payload data offset has not been set + */ +uint32_t odp_packet_payload_offset(odp_packet_t pkt); + +/** + * Set payload data start offset + * + * Set offset to the start of payload data. The offset is calculated from the current + * odp_packet_data() position in bytes. Offset must not exceed packet data length. Offset is not + * modified on an error. + * + * @param pkt Packet handle + * @param offset Payload data start offset (0 ... odp_packet_len()-1) or ODP_PACKET_OFFSET_INVALID + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_packet_payload_offset_set(odp_packet_t pkt, uint32_t offset); + +/** + * Enable or disable Tx packet aging + * + * Enable or disable Tx packet drop based on packet age. When enabled, packet will be dropped + * if it is in Tx pktout queue or traffic shapers/schedulers for longer than timeout set. + * + * When tmo_ns is + * !0: Aging is enabled + * 0: Aging is disabled + * + * Aging is disabled by default. Maximum tmo value is defined by max_tx_aging_tmo_ns capa. + * + * @param pkt Packet handle + * @param tmo_ns Packet aging drop timeout in nsec. When 0, aging drop is disabled (default). + * + * @see odp_pktio_capability_t::max_tx_aging_tmo_ns + */ +void odp_packet_aging_tmo_set(odp_packet_t pkt, uint64_t tmo_ns); + +/** + * Check if packet has Tx aging drop enabled + * + * @param pkt Packet handle + * + * @return Aging drop timeout if enabled. + * @retval >0 Aging drop timeout in nano seconds and implies aging drop is enabled. + * @retval 0 If Aging drop is disabled. + */ +uint64_t odp_packet_aging_tmo(odp_packet_t pkt); + +/** + * Request packet transmit completion + * + * Enables or disables packet transmit completion request for the packet. Completion may be + * requested either in event (#ODP_PACKET_TX_COMPL_EVENT) or poll (#ODP_PACKET_TX_COMPL_POLL) mode. + * When event mode is enabled, an event of type ODP_EVENT_PACKET_TX_COMPL will be sent to the + * destination queue to signal transmit completion. When poll mode is enabled, + * odp_packet_tx_compl_done() is used with the provided completion identifier to check the + * completion. In both cases, transmit completion is reported only after pktio interface has + * finished processing the packet. + * + * A previously enabled request can be disabled by setting the mode to ODP_PACKET_TX_COMPL_DISABLED. + * Transmit completion request is disabled by default. + * + * @param pkt Packet handle + * @param opt Packet transmit completion request options + * + * @retval 0 On success + * @retval <0 On failure + */ +int odp_packet_tx_compl_request(odp_packet_t pkt, const odp_packet_tx_compl_opt_t *opt); + +/** + * Check if packet transmit completion is requested + * + * @param pkt Packet handle + * + * @retval non-zero Transmit completion is requested + * @retval 0 Transmit completion is not requested + */ +int odp_packet_has_tx_compl_request(odp_packet_t pkt); + +/** + * Set packet free control option + * + * This option enables application to control if a packet is freed/not freed back into a pool + * after an ODP offload feature has finished processing it. The option does not have an effect on + * odp_packet_free() or other direct free calls. It affects only packets that are sent directly + * through a packet output interface queue (odp_pktout_queue_t or odp_queue_t), also when packets + * are LSO offloaded. Packets transmitted through inline IPsec or TM are not affected. + * + * Packet output interface frees transmitted packets by default. When the option is set to + * #ODP_PACKET_FREE_CTRL_DONT_FREE, packet output will not free the packet after transmit and + * application may reuse or free the packet as soon as its transmission is complete + * (see e.g. odp_packet_tx_compl_done()). Check packet IO interface capability free_ctrl.dont_free + * (odp_pktio_capability_t.free_ctrl) for the option support. When an interface does not support + * the option, it ignores the value. + * + * The option must not be enabled on packets that have multiple references. The default value is + * #ODP_PACKET_FREE_CTRL_DISABLED. + * + * @param pkt Packet handle + * @param ctrl Packet free control option value + */ +void odp_packet_free_ctrl_set(odp_packet_t pkt, odp_packet_free_ctrl_t ctrl); + +/** + * Returns packet free control option value + * + * @param pkt Packet handle + * + * @return The current value of the packet free control option + */ +odp_packet_free_ctrl_t odp_packet_free_ctrl(odp_packet_t pkt); + +/** + * Request packet proto stats. + * + * The statistics enabled in the proto stats object are updated for the packet in + * packet output when the packet is transmitted or dropped. The statistics update + * is done as the last step of output processing after possible packet + * transformations (e.g. fragmentation, IPsec) that may occur. If a packet is + * fragmented or segmented to multiple packets as part of output processing, all + * the resulting packets inherit the proto stats object association from the + * original packet. + * + * The relevant octet counts will be updated with the actual packet length at + * the time of transmission or drop plus the respective adjustment value passed + * in the 'opt' parameter. The octet counts thus include possible additional + * headers added by ODP during packet output (e.g. ESP header added by inline + * outbound IPsec processing). Ethernet padding and FCS are not included in the + * octet counts. The adjustment value is added only if the respective capability + * field is true and otherwise ignored. + * + * @param pkt Packet handle + * @param opt Proto stats options. If NULL, then proto stats update is + * disabled for this packet. + * + * @see odp_proto_stats_capability_t::tx + */ +void odp_packet_proto_stats_request(odp_packet_t pkt, odp_packet_proto_stats_opt_t *opt); + +/** + * Get proto stats object. + * + * Get the proto stats object associated with the given packet. + * + * @param pkt Packet handle + * + * @return Proto stats object handle or ODP_PROTO_STATS_INVALID if not set. + */ +odp_proto_stats_t odp_packet_proto_stats(odp_packet_t pkt); + +/* + * + * Packet vector handling routines + * ******************************************************** + * + */ + +/** + * Get packet vector handle from event + * + * Converts an ODP_EVENT_PACKET_VECTOR type event to a packet vector handle + * + * @param ev Event handle + * @return Packet vector handle + * + * @see odp_event_type() + */ +odp_packet_vector_t odp_packet_vector_from_event(odp_event_t ev); + +/** + * Convert packet vector handle to event + * + * @param pktv Packet vector handle + * + * @return Event handle + */ +odp_event_t odp_packet_vector_to_event(odp_packet_vector_t pktv); + +/** + * Allocate a packet vector from a packet vector pool + * + * Allocates a packet vector from the specified packet vector pool. + * The pool must have been created with the ODP_POOL_VECTOR type. + * + * @param pool Packet vector pool handle + * + * @return Handle of allocated packet vector + * @retval ODP_PACKET_VECTOR_INVALID Packet vector could not be allocated + * + * @note A newly allocated vector shall not contain any packets, instead, alloc + * operation shall reserve the space for odp_pool_param_t::vector::max_size packets. + */ +odp_packet_vector_t odp_packet_vector_alloc(odp_pool_t pool); + +/** + * Free packet vector + * + * Frees the packet vector into the packet vector pool it was allocated from. + * + * @param pktv Packet vector handle + * + * @note This API just frees the vector, not any packets inside the vector. + * Application can use odp_event_free() to free the vector and packets inside + * the vector. + */ +void odp_packet_vector_free(odp_packet_vector_t pktv); + +/** + * Get packet vector table + * + * Packet vector table is an array of packets (odp_packet_t) stored in + * contiguous memory location. Upon completion of this API, the implementation + * returns the packet table pointer in pkt_tbl. + * + * @param pktv Packet vector handle + * @param[out] pkt_tbl Points to packet vector table + * + * @return Number of packets available in the vector. + * + * @note When pktin subsystem is producing the packet vectors, + * odp_pktin_vector_config_t::pool shall be used to configure the pool to form + * the vector table. + * + * @note The maximum number of packets this vector can hold is defined by + * odp_pool_param_t::vector::max_size. The return value of this function will not + * be greater than odp_pool_param_t::vector::max_size + * + * @note The pkt_tbl points to the packet vector table. Application can edit the + * packet handles in the table directly (up to odp_pool_param_t::vector::max_size). + * Application must update the size of the table using odp_packet_vector_size_set() + * when there is a change in the size of the vector. + * + * @note Invalid packet handles (ODP_PACKET_INVALID) are not allowed to be + * stored in the table to allow consumers of odp_packet_vector_t handle to have + * optimized implementation. So consumption of packets in the middle of the + * vector would call for moving the remaining packets up to form a contiguous + * array of packets and update the size of the new vector using + * odp_packet_vector_size_set(). + * + * @note The table memory is backed by a vector pool buffer. The ownership of + * the table memory is linked to the ownership of the event. I.e. after sending + * the event to a queue, the sender loses ownership to the table also. + */ +uint32_t odp_packet_vector_tbl(odp_packet_vector_t pktv, odp_packet_t **pkt_tbl); + +/** + * Number of packets in a vector + * + * @param pktv Packet vector handle + * + * @return The number of packets available in the vector + */ +uint32_t odp_packet_vector_size(odp_packet_vector_t pktv); + +/** + * Set the number of packets stored in a vector + * + * Update the number of packets stored in a vector. When the application is + * producing a packet vector, this function shall be used by the application + * to set the number of packets available in this vector. + * + * @param pktv Packet vector handle + * @param size Number of packets in this vector + * + * @note The maximum number of packets this vector can hold is defined by + * odp_pool_param_t::vector::max_size. The size value must not be greater than + * odp_pool_param_t::vector::max_size + * + * @note All handles in the vector table (0 .. size - 1) need to be valid packet + * handles. + * + * @see odp_packet_vector_tbl() + * + */ +void odp_packet_vector_size_set(odp_packet_vector_t pktv, uint32_t size); + +/** + * Packet vector user area + * + * Returns pointer to the user area associated with the packet vector. Size of the area is fixed + * and defined in vector pool parameters. + * + * @param pktv Packet vector handle + * + * @return Pointer to the user area of the packet vector + * @retval NULL The packet vector does not have user area + */ +void *odp_packet_vector_user_area(odp_packet_vector_t pktv); + +/** + * Check user flag + * + * Implementation clears user flag during new packet vector creation (e.g. alloc and packet input) + * and reset. User may set the flag with odp_packet_vector_user_flag_set(). Implementation never + * sets the flag, only clears it. The flag may be useful e.g. to mark when the user area + * content is valid. + * + * @param pktv Packet vector handle + * + * @retval 0 User flag is clear + * @retval >0 User flag is set + */ +int odp_packet_vector_user_flag(odp_packet_vector_t pktv); + +/** + * Set user flag + * + * Set (or clear) the user flag. + * + * @param pktv Packet vector handle + * @param val New value for the flag. Zero clears the flag, other values set the flag. + */ +void odp_packet_vector_user_flag_set(odp_packet_vector_t pktv, int val); + +/** + * Check that packet vector is valid + * + * This function can be used for debugging purposes to check if a packet vector handle represents + * a valid packet vector. The level of error checks depends on the implementation. Considerable + * number of cpu cycles may be consumed depending on the level. The call should not crash if + * the packet vector handle is corrupted. + * + * @param pktv Packet vector handle + * + * @retval 0 Packet vector is not valid + * @retval 1 Packet vector is valid + */ +int odp_packet_vector_valid(odp_packet_vector_t pktv); + +/** + * Packet vector pool + * + * Returns handle to the packet vector pool where the packet vector was + * allocated from. + * + * @param pktv Packet vector handle + * + * @return Packet vector pool handle + */ +odp_pool_t odp_packet_vector_pool(odp_packet_vector_t pktv); + +/** + * Print packet vector debug information + * + * Print all packet vector debug information to ODP log. + * + * @param pktv Packet vector handle + */ +void odp_packet_vector_print(odp_packet_vector_t pktv); + +/** + * Get printable value for an odp_packet_vector_t + * + * @param hdl odp_packet_vector_t handle to be printed + * + * @return uint64_t value that can be used to print/display this handle + * + * @note This routine is intended to be used for diagnostic purposes to enable + * applications to generate a printable value that represents an + * odp_packet_vector_t handle. + */ +uint64_t odp_packet_vector_to_u64(odp_packet_vector_t hdl); + +/** + * Check reassembly status of the packet + * + * @param pkt Packet handle + * @return Reassembly status + * + */ +odp_packet_reass_status_t odp_packet_reass_status(odp_packet_t pkt); + +/* + * + * Packet Tx completion event handling routines + * ******************************************************** + */ + +/** + * Get packet Tx completion handle from event + * + * Converts an ODP_EVENT_PACKET_TX_COMPL type event to packet Tx completion + * handle. + * + * @param ev Event handle + * + * @return Packet Tx completion handle + * + * @see odp_event_type() + */ +odp_packet_tx_compl_t odp_packet_tx_compl_from_event(odp_event_t ev); + +/** Convert packet Tx completion to event + * + * @param tx_compl Packet Tx completion + * + * @return Event handle + */ +odp_event_t odp_packet_tx_compl_to_event(odp_packet_tx_compl_t tx_compl); + +/** + * Free packet Tx completion + * + * Frees the packet Tx completion back to platform. It frees packet Tx + * completion that gets allocated as part of packet Tx completion request + * for a given packet. + * + * @param tx_compl Packet Tx completion handle + * + * @see odp_packet_tx_completion_request() + */ +void odp_packet_tx_compl_free(odp_packet_tx_compl_t tx_compl); + +/** + * User context pointer + * + * Return user context pointer from packet Tx completion event. + * This is the same value set to packet using odp_packet_user_ptr_set(). + * + * @param tx_compl Packet Tx completion handle + * + * @return User context pointer + * + * @see odp_packet_user_ptr_set() + */ +void *odp_packet_tx_compl_user_ptr(odp_packet_tx_compl_t tx_compl); + +/** + * Check packet transmit completion + * + * Checks if a previously sent packet with a ODP_PACKET_TX_COMPL_POLL type transmit completion + * request (see odp_packet_tx_compl_opt_t) has been transmitted. The packet send function call + * clears completion identifier status, and 0 is returned while the transmit is in progress. + * When >0 is returned, transmit of the packet is complete and the completion identifier may be + * reused for another transmit. + * + * When transmit of a packet is complete, it indicates that transmit of other packets sent + * before the packet through the same queue have also completed. + * + * Returns initially 0 for all configured completion identifiers. + * + * @param pktio Packet IO interface that was used to send the packet + * @param compl_id Completion identifier that was used in the transmit completion request + * + * @retval >0 Packet transmit is complete + * @retval 0 Packet transmit is not complete + * @retval <0 Failed to read packet transmit status + */ +int odp_packet_tx_compl_done(odp_pktio_t pktio, uint32_t compl_id); + /* * * Debugging @@ -1490,19 +2463,34 @@ void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj); */ /** - * Print packet to the console + * Print packet debug information * - * Print all packet debug information to the console. + * Print all packet debug information to the ODP log. * * @param pkt Packet handle */ void odp_packet_print(odp_packet_t pkt); /** - * Perform full packet validity check + * Print packet data + * + * Print packet debug information with packet data to the ODP log. Operation + * prints 'len' bytes of packet data starting from 'offset' byte. Offset plus + * length must not exceed packet length (odp_packet_len()). + * + * @param pkt Packet handle + * @param offset Byte offset into the packet + * @param len Number of bytes to print + */ +void odp_packet_print_data(odp_packet_t pkt, uint32_t offset, uint32_t len); + +/** + * Check that packet is valid * - * The operation may consume considerable number of cpu cycles depending on - * the check level. + * This function can be used for debugging purposes to check if a packet handle represents + * a valid packet. The level of error checks depends on the implementation. Considerable number of + * cpu cycles may be consumed depending on the level. The call should not crash if the packet + * handle is corrupted. * * @param pkt Packet handle * diff --git a/include/odp/api/spec/packet_flags.h b/include/odp/api/spec/packet_flags.h index 377b75ba0..3bbd8f331 100644 --- a/include/odp/api/spec/packet_flags.h +++ b/include/odp/api/spec/packet_flags.h @@ -1,18 +1,16 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited + * Copyright (c) 2023 Nokia */ - /** * @file * * ODP packet flags */ -#ifndef ODP_API_PACKET_FLAGS_H_ -#define ODP_API_PACKET_FLAGS_H_ +#ifndef ODP_API_SPEC_PACKET_FLAGS_H_ +#define ODP_API_SPEC_PACKET_FLAGS_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -20,90 +18,124 @@ extern "C" { #endif #include <odp/api/std_types.h> -#include <odp/api/packet.h> +#include <odp/api/packet_types.h> /** @addtogroup odp_packet - * Boolean operations on a packet. + * @par Operations on packet metadata flags + * + * If user sets multiple conflicting packet metadata flags + * using odp_packet_has_XX_set() functions, only the last set flag value is + * guaranteed to hold. The values of other conflicting flags are implementation + * specific. The conflicting flag combinations are defined in function + * documentations. * @{ */ /** - * Check for packet errors + * Check for all parse errors in packet * - * Checks all error flags at once. + * Check if packet parsing has found any errors in the packet. The level of + * error checking depends on the parse configuration (e.g. included layers and + * checksums). Protocol layer functions (e.g. odp_packet_has_l3()) indicate + * which layers have been checked, and layer error functions + * (e.g. odp_packet_has_l3_error()) which layers have errors. * - * @param pkt Packet handle - * @retval non-zero packet has errors - * @retval 0 packet has no errors + * If packet subtype is ODP_EVENT_PACKET_IPSEC, odp_packet_has_error() would + * indicate parsing errors after IPSEC processing. IPSEC errors/warnings need + * to be checked using odp_ipsec_result(). + * + * @param pkt Packet handle + * + * @retval non-zero Packet has errors + * @retval 0 No errors were found */ int odp_packet_has_error(odp_packet_t pkt); /** - * Check for packet L2 errors + * Check for errors in layer 2 * - * check for all L2 errors + * When layer 2 is included in the parse configuration, check if any errors were + * found in layer 2 of the packet. * - * @param pkt Packet handle - * @retval non-zero packet has L2 errors - * @retval 0 packet has no L2 error + * @param pkt Packet handle + * + * @retval non-zero Packet has errors in layer 2 + * @retval 0 No errors were found in layer 2 */ int odp_packet_has_l2_error(odp_packet_t pkt); /** - * Check for L2 header, e.g. ethernet + * Check for errors in layer 3 * - * @param pkt Packet handle - * @retval non-zero if packet contains a valid & known L2 header - * @retval 0 if packet does not contain a valid & known L2 header + * When layer 3 is included in the parse configuration, check if any errors were + * found in layer 3 of the packet. + * + * @param pkt Packet handle + * + * @retval non-zero Packet has errors in layer 3 + * @retval 0 No errors found in layer 3 */ -int odp_packet_has_l2(odp_packet_t pkt); +int odp_packet_has_l3_error(odp_packet_t pkt); /** - * Check for packet L3 errors + * Check for errors in layer 4 * - * check for all L3 errors + * When layer 4 is included in the parse configuration, check if any errors were + * found in layer 4 of the packet. * - * @param pkt Packet handle - * @retval non-zero packet has L3 errors - * @retval 0 packet has no L3 error + * @param pkt Packet handle + * + * @retval non-zero Packet has errors in layer 4 + * @retval 0 No errors were found in layer 4 */ -int odp_packet_has_l3_error(odp_packet_t pkt); +int odp_packet_has_l4_error(odp_packet_t pkt); /** - * Check for L3 header, e.g. IPv4, IPv6 + * Check for layer 2 protocols * - * @param pkt Packet handle - * @retval non-zero if packet contains a valid & known L3 header - * @retval 0 if packet does not contain a valid & known L3 header + * When layer 2 is included in the parse configuration, check if packet parsing + * has found and checked a layer 2 protocol (e.g. Ethernet) in the packet. + * + * @param pkt Packet handle + * + * @retval non-zero A layer 2 protocol header was found and checked + * @retval 0 No layer 2 protocol was found */ -int odp_packet_has_l3(odp_packet_t pkt); +int odp_packet_has_l2(odp_packet_t pkt); /** - * Check for packet L4 errors + * Check for layer 3 protocols * - * check for all L4 errors + * When layer 3 is included in the parse configuration, check if packet parsing + * has found and checked a layer 3 protocol (e.g. IPv4, IPv6) in the packet. * - * @param pkt Packet handle - * @retval non-zero packet has L4 errors - * @retval 0 packet has no L4 error + * @param pkt Packet handle + * + * @retval non-zero A layer 3 protocol header was found and checked + * @retval 0 No layer 3 protocol was found */ -int odp_packet_has_l4_error(odp_packet_t pkt); +int odp_packet_has_l3(odp_packet_t pkt); /** - * Check for L4 header, e.g. UDP, TCP, SCTP (also ICMP) + * Check for layer 4 protocols * - * @param pkt Packet handle - * @retval non-zero if packet contains a valid & known L4 header - * @retval 0 if packet does not contain a valid & known L4 header + * When layer 4 is included in the parse configuration, check if packet parsing + * has found and checked a layer 4 protocol (e.g. UDP, TCP, SCTP) in the packet. + * + * @param pkt Packet handle + * + * @retval non-zero A layer 4 protocol header was found and checked + * @retval 0 No layer 4 protocol was found */ int odp_packet_has_l4(odp_packet_t pkt); /** * Check for Ethernet header * - * @param pkt Packet handle - * @retval non-zero if packet contains a valid eth header - * @retval 0 if packet does not contain a valid eth header + * @param pkt Packet handle + * + * @retval non-zero Packet contains an Ethernet header + * @retval 0 Packet does not contain an Ethernet header */ int odp_packet_has_eth(odp_packet_t pkt); @@ -113,9 +145,10 @@ int odp_packet_has_eth(odp_packet_t pkt); * ODP recognizes the destination MAC address FF:FF:FF:FF:FF:FF as * a broadcast address. All others are considered non-broadcast. * - * @param pkt Packet handle - * @retval non-zero if Ethernet destination address is the broadcast address - * @retval 0 if Ethernet destination address is not the broadcast address + * @param pkt Packet handle + * + * @retval non-zero Ethernet destination address is the broadcast address + * @retval 0 Ethernet destination address is not the broadcast address */ int odp_packet_has_eth_bcast(odp_packet_t pkt); @@ -124,63 +157,74 @@ int odp_packet_has_eth_bcast(odp_packet_t pkt); * * ODP recognizes the destination MAC address as multicast if bit 7 is 1. * - * @param pkt Packet handle - * @retval non-zero if Ethernet destination address is a multicast address - * @retval 0 if Ethernet destination address is not a multicast address + * @param pkt Packet handle + * + * @retval non-zero Ethernet destination address is a multicast address + * @retval 0 Ethernet destination address is not a multicast address */ int odp_packet_has_eth_mcast(odp_packet_t pkt); /** * Check for jumbo frame * - * @param pkt Packet handle - * @retval non-zero if packet contains a jumbo frame - * @retval 0 if packet does not contain a jumbo frame + * @param pkt Packet handle + * + * @retval non-zero Packet is a jumbo frame + * @retval 0 Packet is not a jumbo frame */ int odp_packet_has_jumbo(odp_packet_t pkt); /** * Check for VLAN * - * @param pkt Packet handle - * @retval non-zero if packet contains a VLAN header - * @retval 0 if packet does not contain a VLAN header + * Check if packet contains normal or QinQ VLAN header. + * + * @param pkt Packet handle + * + * @retval non-zero Packet contains a VLAN header + * @retval 0 Packet does not contain a VLAN header */ int odp_packet_has_vlan(odp_packet_t pkt); /** * Check for VLAN QinQ (stacked VLAN) * - * @param pkt Packet handle - * @retval non-zero if packet contains a VLAN QinQ header - * @retval 0 if packet does not contain a VLAN QinQ header + * Check if packet contains QinQ VLAN header. + * + * @param pkt Packet handle + * + * @retval non-zero Packet contains a VLAN QinQ header + * @retval 0 Packet does not contain a VLAN QinQ header */ int odp_packet_has_vlan_qinq(odp_packet_t pkt); /** * Check for ARP * - * @param pkt Packet handle - * @retval non-zero if packet contains an ARP message - * @retval 0 if packet does not contain an ARP message + * @param pkt Packet handle + * + * @retval non-zero Packet contains an ARP message + * @retval 0 Packet does not contain an ARP message */ int odp_packet_has_arp(odp_packet_t pkt); /** * Check for IPv4 * - * @param pkt Packet handle - * @retval non-zero if packet contains an IPv4 header - * @retval 0 if packet does not contain an IPv4 header + * @param pkt Packet handle + * + * @retval non-zero Packet contains an IPv4 header + * @retval 0 Packet does not contain an IPv4 header */ int odp_packet_has_ipv4(odp_packet_t pkt); /** * Check for IPv6 * - * @param pkt Packet handle - * @retval non-zero if packet contains an IPv6 header - * @retval 0 if packet does not contain an IPv6 header + * @param pkt Packet handle + * + * @retval non-zero Packet contains an IPv6 header + * @retval 0 Packet does not contain an IPv6 header */ int odp_packet_has_ipv6(odp_packet_t pkt); @@ -192,9 +236,10 @@ int odp_packet_has_ipv6(odp_packet_t pkt); * * For IPv6, no destination addresses are recognized as broadcast addresses. * - * @param pkt Packet handle - * @retval non-zero if IP destination address is a broadcast address - * @retval 0 if IP destination address is not a broadcast address + * @param pkt Packet handle + * + * @retval non-zero IP destination address is a broadcast address + * @retval 0 IP destination address is not a broadcast address */ int odp_packet_has_ip_bcast(odp_packet_t pkt); @@ -207,91 +252,100 @@ int odp_packet_has_ip_bcast(odp_packet_t pkt); * For IPv6 ODP recognizes destination IP addresses with prefixes FF00:: * through FFFF:: as multicast addresses. * - * @param pkt Packet handle - * @retval non-zero if IP destination address is a multicast address - * @retval 0 if IP destination address is not a multicast address + * @param pkt Packet handle + * + * @retval non-zero IP destination address is a multicast address + * @retval 0 IP destination address is not a multicast address */ int odp_packet_has_ip_mcast(odp_packet_t pkt); /** * Check for IP fragment * - * @param pkt Packet handle - * @retval non-zero if packet is an IP fragment - * @retval 0 if packet is not an IP fragment + * @param pkt Packet handle + * + * @retval non-zero Packet is an IP fragment + * @retval 0 Packet is not an IP fragment */ int odp_packet_has_ipfrag(odp_packet_t pkt); /** * Check for IP options * - * @param pkt Packet handle - * @retval non-zero if packet contains IP options - * @retval 0 if packet does not contain IP options + * @param pkt Packet handle + * + * @retval non-zero Packet contains IP options + * @retval 0 Packet does not contain IP options */ int odp_packet_has_ipopt(odp_packet_t pkt); /** * Check for IPSec * - * @param pkt Packet handle - * @retval non-zero if packet requires IPSec processing - * @retval 0 if packet does not require IPSec processing + * @param pkt Packet handle + * + * @retval non-zero Packet requires IPSec processing + * @retval 0 Packet does not require IPSec processing */ int odp_packet_has_ipsec(odp_packet_t pkt); /** * Check for UDP * - * @param pkt Packet handle - * @retval non-zero if packet contains a UDP header - * @retval 0 if packet does not contain a UDP header + * @param pkt Packet handle + * + * @retval non-zero Packet contains a UDP header + * @retval 0 Packet does not contain a UDP header */ int odp_packet_has_udp(odp_packet_t pkt); /** * Check for TCP * - * @param pkt Packet handle - * @retval non-zero if packet contains a TCP header - * @retval 0 if packet does not contain a TCP header + * @param pkt Packet handle + * + * @retval non-zero Packet contains a TCP header + * @retval 0 Packet does not contain a TCP header */ int odp_packet_has_tcp(odp_packet_t pkt); /** * Check for SCTP * - * @param pkt Packet handle - * @retval non-zero if packet contains a SCTP header - * @retval 0 if packet does not contain a SCTP header + * @param pkt Packet handle + * + * @retval non-zero Packet contains a SCTP header + * @retval 0 Packet does not contain a SCTP header */ int odp_packet_has_sctp(odp_packet_t pkt); /** * Check for ICMP * - * @param pkt Packet handle - * @retval non-zero if packet contains an ICMP header - * @retval 0 if packet does not contain an ICMP header + * @param pkt Packet handle + * + * @retval non-zero Packet contains an ICMP header + * @retval 0 Packet does not contain an ICMP header */ int odp_packet_has_icmp(odp_packet_t pkt); /** * Check for packet flow hash * - * @param pkt Packet handle - * @retval non-zero if packet contains a hash value - * @retval 0 if packet does not contain a hash value + * @param pkt Packet handle + * + * @retval non-zero Packet contains a hash value + * @retval 0 Packet does not contain a hash value */ int odp_packet_has_flow_hash(odp_packet_t pkt); /** * Check for packet timestamp * - * @param pkt Packet handle + * @param pkt Packet handle * - * @retval non-zero if packet contains a timestamp value - * @retval 0 if packet does not contain a timestamp value + * @retval non-zero Packet contains a timestamp value + * @retval 0 Packet does not contain a timestamp value * * @see odp_packet_has_ts_clr() */ @@ -356,6 +410,9 @@ void odp_packet_has_jumbo_set(odp_packet_t pkt, int val); /** * Set flag for VLAN * + * Set when packet contains normal VLAN header. Only one VLAN flag + * (VLAN/VLAN QinQ) can be set simultaneously. + * * @param pkt Packet handle * @param val Value */ @@ -364,6 +421,9 @@ void odp_packet_has_vlan_set(odp_packet_t pkt, int val); /** * Set flag for VLAN QinQ (stacked VLAN) * + * Set when packet contains QinQ VLAN header. Only one VLAN flag + * (VLAN/VLAN QinQ) can be set simultaneously. + * * @param pkt Packet handle * @param val Value */ @@ -372,6 +432,8 @@ void odp_packet_has_vlan_qinq_set(odp_packet_t pkt, int val); /** * Set flag for ARP * + * Only one of ARP/IPv4/IPv6 flags can be set simultaneously. + * * @param pkt Packet handle * @param val Value */ @@ -380,6 +442,8 @@ void odp_packet_has_arp_set(odp_packet_t pkt, int val); /** * Set flag for IPv4 * + * Only one of ARP/IPv4/IPv6 flags can be set simultaneously. + * * @param pkt Packet handle * @param val Value */ @@ -388,6 +452,8 @@ void odp_packet_has_ipv4_set(odp_packet_t pkt, int val); /** * Set flag for IPv6 * + * Only one of ARP/IPv4/IPv6 flags can be set simultaneously. + * * @param pkt Packet handle * @param val Value */ @@ -396,6 +462,8 @@ void odp_packet_has_ipv6_set(odp_packet_t pkt, int val); /** * Set flag for IP broadcast address * + * Only one of IP broadcast/multicast flags can be set simultaneously. + * * @param pkt Packet handle * @param val Value */ @@ -404,6 +472,8 @@ void odp_packet_has_ip_bcast_set(odp_packet_t pkt, int val); /** * Set flag for IP multicast address * + * Only one of IP broadcast/multicast flags can be set simultaneously. + * * @param pkt Packet handle * @param val Value */ @@ -436,6 +506,8 @@ void odp_packet_has_ipsec_set(odp_packet_t pkt, int val); /** * Set flag for UDP * + * Only one of TCP/UDP/SCTP/ICMP flags can be set simultaneously. + * * @param pkt Packet handle * @param val Value */ @@ -444,6 +516,8 @@ void odp_packet_has_udp_set(odp_packet_t pkt, int val); /** * Set flag for TCP * + * Only one of TCP/UDP/SCTP/ICMP flags can be set simultaneously. + * * @param pkt Packet handle * @param val Value */ @@ -452,6 +526,8 @@ void odp_packet_has_tcp_set(odp_packet_t pkt, int val); /** * Set flag for SCTP * + * Only one of TCP/UDP/SCTP/ICMP flags can be set simultaneously. + * * @param pkt Packet handle * @param val Value */ @@ -460,6 +536,8 @@ void odp_packet_has_sctp_set(odp_packet_t pkt, int val); /** * Set flag for ICMP * + * Only one of TCP/UDP/SCTP/ICMP flags can be set simultaneously. + * * @param pkt Packet handle * @param val Value */ diff --git a/include/odp/api/spec/packet_io.h b/include/odp/api/spec/packet_io.h index 85cd6d184..a83617f7c 100644 --- a/include/odp/api/spec/packet_io.h +++ b/include/odp/api/spec/packet_io.h @@ -1,34 +1,36 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2020-2023 Nokia */ - /** * @file * * ODP Packet IO */ -#ifndef ODP_API_PACKET_IO_H_ -#define ODP_API_PACKET_IO_H_ +#ifndef ODP_API_SPEC_PACKET_IO_H_ +#define ODP_API_SPEC_PACKET_IO_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif +#include <odp/api/classification.h> +#include <odp/api/packet_types.h> #include <odp/api/packet_io_stats.h> -#include <odp/api/queue.h> -#include <odp/api/time.h> +#include <odp/api/packet_io_types.h> +#include <odp/api/queue_types.h> +#include <odp/api/reassembly.h> +#include <odp/api/time_types.h> -/** @defgroup odp_packet_io ODP PACKET IO - * Operations on a packet Input/Output interface. +/** @addtogroup odp_packet_io + * Packet IO interfaces. * * Packet IO is the Ingress and Egress interface to ODP processing. It * allows manipulation of the interface for setting such attributes as - * the mtu, mac etc. + * number of queues, MAC address etc. * Pktio is usually followed by the classifier and a default class COS * can be set so that the scheduler may distribute flows. The interface * may be used directly in polled mode with odp_pktin_recv() and @@ -40,389 +42,12 @@ extern "C" { */ /** - * @typedef odp_pktio_t - * Packet IO handle - */ - -/** - * @typedef odp_pktin_queue_t - * Direct packet input queue handle - */ - -/** - * @typedef odp_pktout_queue_t - * Direct packet output queue handle - */ - -/** - * @def ODP_PKTIO_INVALID - * Invalid packet IO handle - */ - -/** - * @def ODP_PKTIO_MACADDR_MAXSIZE - * Minimum size of output buffer for odp_pktio_mac_addr() - * Actual MAC address sizes may be different. - */ - -/** - * @def ODP_PKTIN_NO_WAIT - * Do not wait on packet input - */ - -/** - * @def ODP_PKTIN_WAIT - * Wait infinitely on packet input - */ - -/** - * Packet input mode - */ -typedef enum odp_pktin_mode_t { - /** Direct packet input from the interface */ - ODP_PKTIN_MODE_DIRECT = 0, - /** Packet input through scheduler and scheduled event queues */ - ODP_PKTIN_MODE_SCHED, - /** Packet input through plain event queues */ - ODP_PKTIN_MODE_QUEUE, - /** Application will never receive from this interface */ - ODP_PKTIN_MODE_DISABLED -} odp_pktin_mode_t; - -/** - * Packet output mode - */ -typedef enum odp_pktout_mode_t { - /** Direct packet output on the interface */ - ODP_PKTOUT_MODE_DIRECT = 0, - /** Packet output through event queues */ - ODP_PKTOUT_MODE_QUEUE, - /** Packet output through traffic manager API */ - ODP_PKTOUT_MODE_TM, - /** Application will never send to this interface */ - ODP_PKTOUT_MODE_DISABLED -} odp_pktout_mode_t; - -/** - * Packet input hash protocols - * - * The list of protocol header field combinations, which are included into - * packet input hash calculation. - */ -typedef union odp_pktin_hash_proto_t { - /** Protocol header fields for hashing */ - struct { - /** IPv4 addresses and UDP port numbers */ - uint32_t ipv4_udp : 1; - /** IPv4 addresses and TCP port numbers */ - uint32_t ipv4_tcp : 1; - /** IPv4 addresses */ - uint32_t ipv4 : 1; - /** IPv6 addresses and UDP port numbers */ - uint32_t ipv6_udp : 1; - /** IPv6 addresses and TCP port numbers */ - uint32_t ipv6_tcp : 1; - /** IPv6 addresses */ - uint32_t ipv6 : 1; - } proto; - - /** All bits of the bit field structure */ - uint32_t all_bits; -} odp_pktin_hash_proto_t; - -/** - * Packet IO operation mode - */ -typedef enum odp_pktio_op_mode_t { - /** Multithread safe operation - * - * Direct packet IO operation (recv or send) is multithread safe. Any - * number of application threads may perform the operation - * concurrently. */ - ODP_PKTIO_OP_MT = 0, - - /** Not multithread safe operation - * - * Direct packet IO operation (recv or send) may not be multithread - * safe. Application ensures synchronization between threads so that - * simultaneously only single thread attempts the operation on - * the same (pktin or pktout) queue. */ - ODP_PKTIO_OP_MT_UNSAFE - -} odp_pktio_op_mode_t; - -/** - * Packet input queue parameters - */ -typedef struct odp_pktin_queue_param_t { - /** Operation mode - * - * The default value is ODP_PKTIO_OP_MT. Application may enable - * performance optimization by defining ODP_PKTIO_OP_MT_UNSAFE when - * applicable. */ - odp_pktio_op_mode_t op_mode; - - /** Enable classifier - * - * * 0: Classifier is disabled (default) - * * 1: Classifier is enabled. Use classifier to direct incoming - * packets into pktin event queues. Classifier can be enabled - * only in ODP_PKTIN_MODE_SCHED and ODP_PKTIN_MODE_QUEUE modes. - * Both classifier and hashing cannot be enabled simultaneously - * ('hash_enable' must be 0). */ - odp_bool_t classifier_enable; - - /** Enable flow hashing - * - * * 0: Do not hash flows (default) - * * 1: Enable flow hashing. Use flow hashing to spread incoming - * packets into input queues. Hashing can be enabled in all - * modes. Both classifier and hashing cannot be enabled - * simultaneously ('classifier_enable' must be 0). */ - odp_bool_t hash_enable; - - /** Protocol field selection for hashing - * - * Multiple protocols can be selected. Ignored when 'hash_enable' is - * zero. The default value is all bits zero. */ - odp_pktin_hash_proto_t hash_proto; - - /** Number of input queues to be created - * - * When classifier is enabled in odp_pktin_queue_config() this - * value is ignored, otherwise at least one queue is required. - * More than one input queues require flow hashing configured. - * The maximum value is defined by pktio capability 'max_input_queues'. - * Queue type is defined by the input mode. The default value is 1. */ - unsigned num_queues; - - /** Queue parameters - * - * These are used for input queue creation in ODP_PKTIN_MODE_QUEUE - * or ODP_PKTIN_MODE_SCHED modes. Scheduler parameters are considered - * only in ODP_PKTIN_MODE_SCHED mode. Default values are defined in - * odp_queue_param_t documentation. - * When classifier is enabled in odp_pktin_queue_config() this - * value is ignored. */ - odp_queue_param_t queue_param; - -} odp_pktin_queue_param_t; - -/** - * Packet output queue parameters - * - * These parameters are used in ODP_PKTOUT_MODE_DIRECT and - * ODP_PKTOUT_MODE_QUEUE modes. - */ -typedef struct odp_pktout_queue_param_t { - /** Operation mode - * - * The default value is ODP_PKTIO_OP_MT. Application may enable - * performance optimization by defining ODP_PKTIO_OP_MT_UNSAFE when - * applicable. */ - odp_pktio_op_mode_t op_mode; - - /** Number of output queues to be created. The value must be between - * 1 and interface capability. The default value is 1. */ - unsigned num_queues; - -} odp_pktout_queue_param_t; - -/** - * Packet IO parameters - * - * Packet IO interface level parameters. Use odp_pktio_param_init() to - * initialize the structure with default values. - */ -typedef struct odp_pktio_param_t { - /** Packet input mode - * - * The default value is ODP_PKTIN_MODE_DIRECT. */ - odp_pktin_mode_t in_mode; - - /** Packet output mode - * - * The default value is ODP_PKTOUT_MODE_DIRECT. */ - odp_pktout_mode_t out_mode; - -} odp_pktio_param_t; - -/** - * Packet input configuration options bit field - * - * Packet input configuration options listed in a bit field structure. Packet - * input timestamping may be enabled for all packets or at least for those that - * belong to time synchronization protocol (PTP). - * - * Packet input checksum checking may be enabled or disabled. When it is - * enabled, implementation will verify checksum correctness on incoming packets - * and depending on drop configuration either deliver erroneous packets with - * appropriate flags set (e.g. odp_packet_has_l3_error()) or drop those. - * When packet dropping is enabled, application will never receive a packet - * with the specified error and may avoid to check the error flag. - */ -typedef union odp_pktin_config_opt_t { - /** Option flags */ - struct { - /** Timestamp all packets on packet input */ - uint64_t ts_all : 1; - - /** Timestamp (at least) IEEE1588 / PTP packets - * on packet input */ - uint64_t ts_ptp : 1; - - /** Check IPv4 header checksum on packet input */ - uint64_t ipv4_chksum : 1; - - /** Check UDP checksum on packet input */ - uint64_t udp_chksum : 1; - - /** Check TCP checksum on packet input */ - uint64_t tcp_chksum : 1; - - /** Check SCTP checksum on packet input */ - uint64_t sctp_chksum : 1; - - /** Drop packets with an IPv4 error on packet input */ - uint64_t drop_ipv4_err : 1; - - /** Drop packets with an IPv6 error on packet input */ - uint64_t drop_ipv6_err : 1; - - /** Drop packets with a UDP error on packet input */ - uint64_t drop_udp_err : 1; - - /** Drop packets with a TCP error on packet input */ - uint64_t drop_tcp_err : 1; - - /** Drop packets with a SCTP error on packet input */ - uint64_t drop_sctp_err : 1; - - } bit; - - /** All bits of the bit field structure - * - * This field can be used to set/clear all flags, or bitwise - * operations over the entire structure. */ - uint64_t all_bits; -} odp_pktin_config_opt_t; - -/** - * Packet output configuration options bit field - * - * Packet output configuration options listed in a bit field structure. Packet - * output checksum insertion may be enabled or disabled. When it is enabled, - * implementation will calculate and insert checksum into every outgoing packet - * by default. Application may use a packet metadata flag to disable checksum - * insertion per packet bases. For correct operation, packet metadata must - * provide valid offsets for the appropriate protocols. For example, UDP - * checksum calculation needs both L3 and L4 offsets (to access IP and UDP - * headers). When application (e.g. a switch) does not modify L3/L4 data and - * thus checksum does not need to be updated, output checksum insertion should - * be disabled for optimal performance. - */ -typedef union odp_pktout_config_opt_t { - /** Option flags */ - struct { - /** Insert IPv4 header checksum on packet output */ - uint64_t ipv4_chksum : 1; - - /** Insert UDP checksum on packet output */ - uint64_t udp_chksum : 1; - - /** Insert TCP checksum on packet output */ - uint64_t tcp_chksum : 1; - - /** Insert SCTP checksum on packet output */ - uint64_t sctp_chksum : 1; - - } bit; - - /** All bits of the bit field structure - * - * This field can be used to set/clear all flags, or bitwise - * operations over the entire structure. */ - uint64_t all_bits; -} odp_pktout_config_opt_t; - -/** - * Packet IO configuration options - * - * Packet IO interface level configuration options. Use odp_pktio_capability() - * to see which options are supported by the implementation. - * Use odp_pktio_config_init() to initialize the structure with default values. - */ -typedef struct odp_pktio_config_t { - /** Packet input configuration options bit field - * - * Default value for all bits is zero. */ - odp_pktin_config_opt_t pktin; - - /** Packet output configuration options bit field - * - * Default value for all bits is zero. */ - odp_pktout_config_opt_t pktout; - - /** Interface loopback mode - * - * In this mode the packets sent out through the interface is - * looped back to input of the same interface. Supporting loopback mode - * is an optional feature per interface and should be queried in the - * interface capability before enabling the same. */ - odp_bool_t enable_loop; - -} odp_pktio_config_t; - -/** - * Packet IO set operations - * - * Supported packet IO interface set operations listed in a bit field structure. - */ -typedef union odp_pktio_set_op_t { - /** Operation flags */ - struct { - /** Promiscuous mode */ - uint32_t promisc_mode : 1; - } op; - /** All bits of the bit field structure. - * This field can be used to set/clear all flags, or bitwise - * operations over the entire structure. */ - uint32_t all_bits; -} odp_pktio_set_op_t; - -/** - * Packet IO capabilities - */ -typedef struct odp_pktio_capability_t { - /** Maximum number of input queues */ - unsigned max_input_queues; - - /** Maximum number of output queues */ - unsigned max_output_queues; - - /** Supported pktio configuration options */ - odp_pktio_config_t config; - - /** Supported set operations - * - * A bit set to one indicates a supported operation. All other bits are - * set to zero. */ - odp_pktio_set_op_t set_op; - - /** Support of Loopback mode - * - * A boolean to denote whether loop back mode is supported on this - * specific interface. */ - odp_bool_t loop_supported; -} odp_pktio_capability_t; - -/** * Open a packet IO interface * * An ODP program can open a single packet IO interface per device, attempts - * to open an already open device will fail, returning ODP_PKTIO_INVALID with - * errno set. Use odp_pktio_lookup() to obtain a handle to an already open - * device. Packet IO parameters provide interface level configuration options. + * to open an already open device will fail, returning ODP_PKTIO_INVALID. Use + * odp_pktio_lookup() to obtain a handle to an already open device. Packet IO + * parameters provide interface level configuration options. * * Use odp_pktio_param_init() to initialize packet IO parameters into their * default values. Default values are also used when 'param' pointer is NULL. @@ -437,6 +62,12 @@ typedef struct odp_pktio_capability_t { * output mode is ODP_PKTOUT_MODE_DISABLED or ODP_PKTOUT_MODE_TM, * odp_pktout_queue_config() call is optional and will ignore all parameters. * + * Advanced packet IO interface offload features and options can be setup with + * odp_pktio_config() before the interface is started. These features include e.g. + * checksum, segmentation (LSO), reassembly and inline IPSEC offloads. When + * odp_pktio_config() is not used, the interface is started with the default + * values of odp_pktio_config_t. + * * Packet receive and transmit on the interface is enabled with a call to * odp_pktio_start(). If not specified otherwise, any interface level * configuration must not be changed when the interface is active (between start @@ -446,6 +77,7 @@ typedef struct odp_pktio_capability_t { * * odp_pktio_open() * * odp_pktin_queue_config() * * odp_pktout_queue_config() + * * [optionally] odp_pktio_config() * * odp_pktio_start() * * ... and tear down sequence is: @@ -469,7 +101,7 @@ typedef struct odp_pktio_capability_t { * the odp_pktio_default_cos_set() routine, or because a matching PMR * assigned the packet to a specific CoS. The default pool specified * here is applicable only for those packets that are not assigned to a - * more specific CoS. + * more specific CoS that specifies another pool. * * @see odp_pktio_start(), odp_pktio_stop(), odp_pktio_close() */ @@ -494,10 +126,11 @@ int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa); * * Return the maximum packet IO interface index. Interface indexes * (e.g. returned by odp_pktio_index()) range from zero to this maximum value. + * The return value does not exceed #ODP_PKTIO_MAX_INDEX. * * @return Maximum packet IO interface index */ -unsigned odp_pktio_max_index(void); +unsigned int odp_pktio_max_index(void); /** * Configure packet IO interface options @@ -580,8 +213,10 @@ int odp_pktout_queue_config(odp_pktio_t pktio, * output. If return value (N) is less than 'num', only queues[0 ... N-1] have * been written. * - * Packets (and other events) from these queues are received with - * odp_queue_deq(), odp_schedule(), etc calls. + * In addition to packet input, application and other parts of ODP (e.g. timer) + * may enqueue events into these queues. Depending on the queue mode, application + * uses either odp_queue_deq() or odp_schedule() (or variants of those) to receive + * packets and other events from these queues. * * @param pktio Packet IO handle * @param[out] queues Points to an array of queue handles for output @@ -623,7 +258,7 @@ int odp_pktin_queue(odp_pktio_t pktio, odp_pktin_queue_t queues[], int num); * * Packets are enqueued to these queues with odp_queue_enq() or * odp_queue_enq_multi(). Behaviour is undefined if other events than packets - * are enqueued. + * are enqueued. Application cannot dequeue from these queues. * * @param pktio Packet IO handle * @param[out] queues Points to an array of queue handles for output @@ -748,7 +383,6 @@ int odp_pktin_recv(odp_pktin_queue_t queue, odp_packet_t packets[], int num); * @param num Maximum number of packets to receive * @param wait Wait time specified as as follows: * * ODP_PKTIN_NO_WAIT: Do not wait - * * ODP_PKTIN_WAIT: Wait infinitely * * Other values specify the minimum time to wait. * Use odp_pktin_wait_time() to convert nanoseconds * to a valid parameter value. Wait time may be @@ -787,7 +421,6 @@ int odp_pktin_recv_tmo(odp_pktin_queue_t queue, odp_packet_t packets[], * @param num Maximum number of packets to receive * @param wait Wait time specified as as follows: * * ODP_PKTIN_NO_WAIT: Do not wait - * * ODP_PKTIN_WAIT: Wait infinitely * * Other values specify the minimum time to wait. * Use odp_pktin_wait_time() to convert nanoseconds * to a valid parameter value. Wait time may be @@ -796,9 +429,8 @@ int odp_pktin_recv_tmo(odp_pktin_queue_t queue, odp_packet_t packets[], * @return Number of packets received * @retval <0 on failure */ -int odp_pktin_recv_mq_tmo(const odp_pktin_queue_t queues[], unsigned num_q, - unsigned *from, odp_packet_t packets[], int num, - uint64_t wait); +int odp_pktin_recv_mq_tmo(const odp_pktin_queue_t queues[], uint32_t num_q, uint32_t *from, + odp_packet_t packets[], int num, uint64_t wait); /** * Packet input wait time @@ -819,35 +451,115 @@ uint64_t odp_pktin_wait_time(uint64_t nsec); * the operation is optimized for single thread operation per queue and the same * queue must not be accessed simultaneously from multiple threads. * - * A successful call returns the actual number of packets sent. If return value - * is less than 'num', the remaining packets at the end of packets[] array - * are not consumed, and the caller has to take care of them. + * A successful call returns the actual number of packets accepted for transmit. If return value + * is less than 'num', the remaining packets at the end of packets[] array are not consumed, + * and the caller has to take care of them. Transmitted packets are freed back into their + * originating pools by default. If interface supports #ODP_PACKET_FREE_CTRL_DONT_FREE + * option and it is set (odp_packet_free_ctrl_set()) in a packet, the packet is not freed + * but application owns it again after its transmit is complete. Application may use + * odp_packet_tx_compl_request() to request an indication when transmit of a packet is complete. + * + * Entire packet data is sent out (odp_packet_len() bytes of data, starting from + * odp_packet_data()). All other packet metadata is ignored unless otherwise + * specified e.g. for protocol offload purposes. Link protocol specific frame + * checksum and padding are added to frames before transmission. * * @param queue Packet output queue handle for sending packets * @param packets[] Array of packets to send * @param num Number of packets to send * - * @return Number of packets sent + * @return Number of packets accepted for transmit * @retval <0 on failure */ int odp_pktout_send(odp_pktout_queue_t queue, const odp_packet_t packets[], int num); /** - * Return the currently configured MTU value of a packet IO interface. + * Initialize LSO profile parameters * - * @param[in] pktio Packet IO handle. + * Initialize an odp_lso_profile_param_t to its default values for all fields. * - * @return MTU value on success - * @retval 0 on failure + * @param param Address of the odp_lso_profile_param_t to be initialized */ -uint32_t odp_pktio_mtu(odp_pktio_t pktio); +void odp_lso_profile_param_init(odp_lso_profile_param_t *param); /** - * Enable/Disable promiscuous mode on a packet IO interface. + * Create LSO profile + * + * LSO profile defines the set of segmentation operations to be performed to a packet. LSO profiles + * are created before the packet IO interface is started (after odp_pktio_config() and before + * odp_pktio_start()). + * + * See odp_lso_capability_t for maximum number of profiles supported and other LSO capabilities. + * + * @param pktio Packet IO interface which is used with this LSO profile + * @param param LSO profile parameters * - * @param[in] pktio Packet IO handle. - * @param[in] enable 1 to enable, 0 to disable. + * @return LSO profile handle + * @retval ODP_LSO_PROFILE_INVALID on failure + */ +odp_lso_profile_t odp_lso_profile_create(odp_pktio_t pktio, const odp_lso_profile_param_t *param); + +/** + * Destroy LSO profile + * + * LSO profiles can be destroyed only when the packet IO interface is not active (i.e. after it + * has been stopped). + * + * @param lso_profile LSO profile to be destroyed + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_lso_profile_destroy(odp_lso_profile_t lso_profile); + +/** + * Send packets with segmentation offload + * + * Like odp_pktout_send(), but splits a packet payload into 'max_payload_len' or smaller segments + * during output. Packet headers (before 'payload_offset') are copied into each segment and + * automatically modified before transmission. Header updates are based on segmentation protocol + * selection (odp_lso_profile_param_t::lso_proto) in LSO profile. Header checksums are updated + * after modifications. L3/L4 header modifications (see e.g. ODP_LSO_PROTO_TCP_IPV4) require that + * L3/L4 layer offsets in the packet are valid (see e.g. odp_packet_l3_offset()). + * + * In addition, custom field updates may be used to cover unsupported or proprietary protocols. + * Custom fields must not overlap with each other and can be used only when ODP_LSO_PROTO_CUSTOM + * is selected. + * + * Packets are processed and transmitted in the array order. Segments of each packet are transmitted + * in ascending order. + * + * When all packets share the same LSO options, usage of 'lso_opt' parameter may improve + * performance as a number of packet metadata writes/reads are avoided. Results are undefined if + * 'lso_opt' is NULL and a packet misses LSO options. + * + * Packets with less than (or equal to) 'max_payload_len' payload bytes can be sent also, however + * odp_pktout_send() should be more optimal for those than this function. + * + * Check LSO support level from packet IO capabilities (odp_pktio_capability_t). + * + * @param queue Packet output queue handle + * @param packet[] Array of packets to be LSO processed and sent + * @param num Number of packets + * @param lso_opt When set, LSO options to be used for all packets. When NULL, LSO options are + * read from each packet (see odp_packet_lso_request()). + * + * @return Number of packets successfully segmented (0 ... num) + * @retval <0 on failure + */ +int odp_pktout_send_lso(odp_pktout_queue_t queue, const odp_packet_t packet[], int num, + const odp_packet_lso_opt_t *lso_opt); + +/** + * Set promiscuous mode + * + * Enable or disable promiscuous mode on a packet IO interface. Use packet IO capability + * odp_pktio_set_op_t::promisc_mode to check if an interface supports this operation. + * When the operation is supported, promiscuous mode is disabled by default. + * + * @param pktio Packet IO handle. + * @param enable 1 to enable, 0 to disable. * * @retval 0 on success * @retval <0 on failure @@ -857,7 +569,7 @@ int odp_pktio_promisc_mode_set(odp_pktio_t pktio, odp_bool_t enable); /** * Determine if promiscuous mode is enabled for a packet IO interface. * - * @param[in] pktio Packet IO handle. + * @param pktio Packet IO handle. * * @retval 1 if promiscuous mode is enabled. * @retval 0 if promiscuous mode is disabled. @@ -866,6 +578,62 @@ int odp_pktio_promisc_mode_set(odp_pktio_t pktio, odp_bool_t enable); int odp_pktio_promisc_mode(odp_pktio_t pktio); /** + * Maximum frame length at packet input + * + * Maximum frame length in bytes that the packet IO interface can receive. + * For Ethernet, the frame length bytes start with MAC addresses and continue + * to the end of the payload. So, Ethernet checksum, interpacket gap + * and preamble bytes are excluded from the length. + * + * @param pktio Packet IO handle. + * + * @return Maximum frame length at packet input + * @retval 0 on failure + */ +uint32_t odp_pktin_maxlen(odp_pktio_t pktio); + +/** + * Maximum frame length at packet output + * + * Maximum frame length in bytes that the packet IO interface can transmit. + * For Ethernet, the frame length bytes start with MAC addresses and continue + * to the end of the payload. So, Ethernet checksum, interpacket gap + * and preamble bytes are excluded from the length. + * + * @param pktio Packet IO handle. + * + * @return Maximum frame length at packet output + * @retval 0 on failure + */ +uint32_t odp_pktout_maxlen(odp_pktio_t pktio); + +/** + * Set maximum frame lengths + * + * Set the maximum frame lengths in bytes that the packet IO interface can + * receive and transmit. For Ethernet, the frame length bytes start with MAC + * addresses and continue to the end of the payload. So, Ethernet checksum, + * interpacket gap, and preamble bytes are excluded from the lengths. + * + * Use odp_pktio_capability() to query interface capabilities. If setting + * maximum frame length is only supported in input or output direction, the + * parameter for the unsupported direction has to be set to zero. When + * 'equal' flag in odp_pktio_capability_t::maxlen is set, the same maximum + * frame length value has to be used for both input and output directions. + * + * @param pktio Packet IO handle + * @param maxlen_input Maximum frame length at packet input + * @param maxlen_output Maximum frame length at packet output + * + * @retval 0 on success + * @retval <0 on failure + * + * @see odp_pktin_maxlen(), odp_pktout_maxlen() + */ +int odp_pktio_maxlen_set(odp_pktio_t pktio, uint32_t maxlen_input, + uint32_t maxlen_output); + +/** * Get the default MAC address of a packet IO interface. * * @param pktio Packet IO handle @@ -878,16 +646,31 @@ int odp_pktio_promisc_mode(odp_pktio_t pktio); int odp_pktio_mac_addr(odp_pktio_t pktio, void *mac_addr, int size); /** + * Set the default MAC address of a packet IO interface. + * + * Support of this operation on a packet IO interface is reported + * through ‘mac_addr’ set operation capability. + * + * @param pktio Packet IO handle + * @param mac_addr MAC address to be set as default address + * @param size Size of the MAC address + * + * @return 0 on success + * @retval <0 on failure + */ +int odp_pktio_mac_addr_set(odp_pktio_t pktio, const void *mac_addr, + int size); + +/** * Setup per-port default class-of-service. * - * @param[in] pktio Ingress port pktio handle. - * @param[in] default_cos Class-of-service set to all packets arriving - * at this ingress port, - * unless overridden by subsequent - * header-based filters. + * @param pktio Ingress port pktio handle. + * @param default_cos Class-of-service set to all packets arriving at this + * ingress port. Use ODP_COS_INVALID to remove the default + * CoS. * - * @retval 0 on success - * @retval <0 on failure + * @retval 0 on success + * @retval <0 on failure * * @note The default_cos has to be unique per odp_pktio_t instance. */ @@ -896,12 +679,12 @@ int odp_pktio_default_cos_set(odp_pktio_t pktio, odp_cos_t default_cos); /** * Setup per-port error class-of-service * - * @param[in] pktio Ingress port pktio handle. - * @param[in] error_cos class-of-service set to all packets arriving - * at this ingress port that contain an error. + * @param pktio Ingress port pktio handle. + * @param error_cos class-of-service set to all packets arriving at this + * ingress port that contain an error. * - * @retval 0 on success - * @retval <0 on failure + * @retval 0 on success + * @retval <0 on failure * * @note Optional. */ @@ -910,24 +693,28 @@ int odp_pktio_error_cos_set(odp_pktio_t pktio, odp_cos_t error_cos); /** * Setup per-port header offset * - * @param[in] pktio Ingress port pktio handle. - * @param[in] offset Number of bytes the classifier must skip. + * @param pktio Ingress port pktio handle. + * @param offset Number of bytes the classifier must skip. * - * @retval 0 on success - * @retval <0 on failure - * @note Optional. + * This option is input to packet input parser/classifier indicating + * how many bytes of data should be skipped from start of packet, + * before parsing starts. So this option effects all packet input + * protocol identification and other offloads. * + * @retval 0 on success + * @retval <0 on failure + * + * @note Optional. */ int odp_pktio_skip_set(odp_pktio_t pktio, uint32_t offset); /** * Specify per-port buffer headroom * - * @param[in] pktio Ingress port pktio handle. - * @param[in] headroom Number of bytes of space preceding - * packet data to reserve for use as headroom. - * Must not exceed the implementation - * defined ODP_PACKET_MAX_HEADROOM. + * @param pktio Ingress port pktio handle. + * @param headroom Number of bytes of space preceding packet data to reserve + * for use as headroom. Must not exceed the implementation + * defined ODP_PACKET_MAX_HEADROOM. * * @retval 0 on success * @retval <0 on failure @@ -1009,21 +796,10 @@ void odp_pktio_print(odp_pktio_t pktio); * * @param pktio Packet IO handle. * - * @retval 1 link is up - * @retval 0 link is down - * @retval <0 on failure + * @retval ODP_PKTIO_LINK_STATUS_UP or ODP_PKTIO_LINK_STATUS_DOWN on success + * @retval ODP_PKTIO_LINK_STATUS_UNKNOWN on failure */ -int odp_pktio_link_status(odp_pktio_t pktio); - -/** - * Packet IO information - */ -typedef struct odp_pktio_info_t { - const char *name; /**< Packet IO device name */ - const char *drv_name; /**< Packet IO driver name (implementation specific) */ - odp_pool_t pool; /**< Packet pool */ - odp_pktio_param_t param; /**< Packet IO parameters */ -} odp_pktio_info_t; +odp_pktio_link_status_t odp_pktio_link_status(odp_pktio_t pktio); /** * Retrieve information about a pktio @@ -1044,30 +820,80 @@ typedef struct odp_pktio_info_t { int odp_pktio_info(odp_pktio_t pktio, odp_pktio_info_t *info); /** - * Packet input timestamp resolution in hertz + * Retrieve information about packet IO link status * - * This is the resolution of packet input timestamps. Returns zero on a failure - * or when timestamping is disabled. + * Fills in link information structure with the current link status values. + * May be called any time with a valid pktio handle. The call is not intended + * for fast path use. The info structure is written only on success. * * @param pktio Packet IO handle + * @param[out] info Pointer to packet IO link info struct for output * - * @return Packet input timestamp resolution in hertz + * @retval 0 on success + * @retval <0 on failure + */ +int odp_pktio_link_info(odp_pktio_t pktio, odp_pktio_link_info_t *info); + +/** + * Packet IO timestamp resolution in hertz + * + * This is the resolution of packet input and output timestamps using a packet + * IO time source. + * + * @param pktio Packet IO handle + * + * @return Packet IO timestamp resolution in hertz * @retval 0 on failure */ -uint64_t odp_pktin_ts_res(odp_pktio_t pktio); +uint64_t odp_pktio_ts_res(odp_pktio_t pktio); /** - * Convert nanoseconds to packet input time + * Convert nanoseconds to packet IO time * - * Packet input time source is used for timestamping incoming packets. - * This function is used convert nanosecond time to packet input timestamp time. + * Packet IO time source is used for timestamping incoming and outgoing packets. + * This function is used to convert nanosecond time to packet input or output + * timestamp time. * * @param pktio Packet IO handle * @param ns Time in nanoseconds * - * @return Packet input timestamp + * @return Packet IO timestamp + * @retval ODP_TIME_NULL on failure + */ +odp_time_t odp_pktio_ts_from_ns(odp_pktio_t pktio, uint64_t ns); + +/** + * Current packet IO time and global time + * + * Returns current packet IO time and optionally global time. The returned + * global time is that of global time source, where as the packet IO time is of + * packet IO time source that is used to timestamp incoming and outgoing + * packets. + * + * @param pktio Packet IO handle + * @param[out] ts_global Pointer to odp_time_t for output or NULL. + * On success, global timestamp will be taken at the + * same point of time as packet IO time. + * + * @return Current packet IO time + * @retval ODP_TIME_NULL on failure + */ +odp_time_t odp_pktio_time(odp_pktio_t pktio, odp_time_t *ts_global); + +/** + * Read last captured Tx timestamp of a packet if available and clear it for + * next timestamp. + * + * @param pktio Packet IO handle + * @param[out] ts Pointer to odp_time_t for output + * + * @retval 0 on success + * @retval >0 Timestamp not available either because none has been requested or + * the requested timestamp is not yet available. In case it is the + * latter, then retry again later for retrieving the timestamp. + * @retval <0 on failure */ -odp_time_t odp_pktin_ts_from_ns(odp_pktio_t pktio, uint64_t ns); +int odp_pktout_ts_read(odp_pktio_t pktio, odp_time_t *ts); /** * @} diff --git a/include/odp/api/spec/packet_io_stats.h b/include/odp/api/spec/packet_io_stats.h index 299ecd0e1..d711d75f7 100644 --- a/include/odp/api/spec/packet_io_stats.h +++ b/include/odp/api/spec/packet_io_stats.h @@ -1,137 +1,429 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2021-2022 Nokia */ /** * @file * - * ODP Packet IO + * ODP Packet IO statistics */ -#ifndef ODP_API_PACKET_IO_STATS_H_ -#define ODP_API_PACKET_IO_STATS_H_ +#ifndef ODP_API_SPEC_PACKET_IO_STATS_H_ +#define ODP_API_SPEC_PACKET_IO_STATS_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif +#include <odp/api/queue_types.h> + /** @addtogroup odp_packet_io * @{ */ /** - * Packet IO statistics + * @def ODP_PKTIO_STATS_EXTRA_NAME_LEN + * Maximum packet IO extra statistics counter name length in chars including + * null char + */ + +/** + * Packet IO statistics counters * - * Packet IO statistics counters follow RFCs for Management Information Base - * (MIB)for use with network management protocols in the Internet community: - * https://tools.ietf.org/html/rfc3635 - * https://tools.ietf.org/html/rfc2863 - * https://tools.ietf.org/html/rfc2819 + * In the counter definitions the term successfully refers to packets which were + * not discarded or detected to contain errors by the packet IO interface. In + * case of Ethernet, it's implementation specific whether valid pause frames are + * included in the counters or not. */ typedef struct odp_pktio_stats_t { - /** - * The number of octets in valid MAC frames received on this interface, - * including the MAC header and FCS. See ifHCInOctets counter - * description in RFC 3635 for details. - */ + /** Number of octets in successfully received packets. In case of + * Ethernet, packet size includes MAC header. */ uint64_t in_octets; - /** - * The number of packets, delivered by this sub-layer to a higher - * (sub-)layer, which were not addressed to a multicast or broadcast - * address at this sub-layer. See ifHCInUcastPkts in RFC 2863, RFC 3635. - */ + /** Number of successfully received packets. */ + uint64_t in_packets; + + /** Number of successfully received Ethernet packets with a unicast + * destination MAC address. */ uint64_t in_ucast_pkts; - /** - * The number of inbound packets which were chosen to be discarded - * even though no errors had been detected to prevent their being - * deliverable to a higher-layer protocol. One possible reason for - * discarding such a packet could be to free up buffer space. - * See ifInDiscards in RFC 2863. - */ + /** Number of successfully received Ethernet packets with a multicast + * destination MAC address. */ + uint64_t in_mcast_pkts; + + /** Number of successfully received Ethernet packets with a broadcast + * destination MAC address. */ + uint64_t in_bcast_pkts; + + /** Number of inbound packets which were discarded due to a lack of free + * resources (e.g. buffers) or other reasons than packet errors. */ uint64_t in_discards; - /** - * The sum for this interface of AlignmentErrors, FCSErrors, FrameTooLongs, - * InternalMacReceiveErrors. See ifInErrors in RFC 3635. - */ + /** Number of inbound packets with errors. Depending on packet input + * configuration, packets with errors may be dropped or not. */ uint64_t in_errors; - /** - * For packet-oriented interfaces, the number of packets received via - * the interface which were discarded because of an unknown or - * unsupported protocol. For character-oriented or fixed-length - * interfaces that support protocol multiplexing the number of - * transmission units received via the interface which were discarded - * because of an unknown or unsupported protocol. For any interface - * that does not support protocol multiplexing, this counter will always - * be 0. See ifInUnknownProtos in RFC 2863, RFC 3635. - */ - uint64_t in_unknown_protos; - - /** - * The number of octets transmitted in valid MAC frames on this - * interface, including the MAC header and FCS. This does include - * the number of octets in valid MAC Control frames transmitted on - * this interface. See ifHCOutOctets in RFC 3635. - */ + /** Number of octets in successfully transmitted packets. In case of + * Ethernet, packet size includes MAC header. */ uint64_t out_octets; - /** - * The total number of packets that higher-level protocols requested - * be transmitted, and which were not addressed to a multicast or - * broadcast address at this sub-layer, including those that were - * discarded or not sent. does not include MAC Control frames. - * See ifHCOutUcastPkts RFC 2863, 3635. - */ + /** Number of successfully transmitted packets. */ + uint64_t out_packets; + + /** Number of successfully transmitted Ethernet packets with a unicast + * destination MAC address. */ uint64_t out_ucast_pkts; - /** - * The number of outbound packets which were chosen to be discarded - * even though no errors had been detected to prevent their being - * transmitted. One possible reason for discarding such a packet could - * be to free up buffer space. See OutDiscards in RFC 2863. - */ + /** Number of successfully transmitted Ethernet packets with a multicast + * destination MAC address. */ + uint64_t out_mcast_pkts; + + /** Number of successfully transmitted Ethernet packets with a broadcast + * destination MAC address. */ + uint64_t out_bcast_pkts; + + /** Number of outbound packets which were discarded due to a lack of + * free resources (e.g. buffers) or other reasons than errors. */ uint64_t out_discards; - /** - * The sum for this interface of SQETestErrors, LateCollisions, - * ExcessiveCollisions, InternalMacTransmitErrors and - * CarrierSenseErrors. See ifOutErrors in RFC 3635. - */ + /** Number of packets with transmission errors. */ uint64_t out_errors; } odp_pktio_stats_t; /** + * Packet IO input queue specific statistics counters + * + * Statistics counters for an individual packet input queue. Refer to packet IO + * level statistics odp_pktio_stats_t for counter definitions. + */ +typedef struct odp_pktin_queue_stats_t { + /** See odp_pktio_stats_t::in_octets */ + uint64_t octets; + + /** See odp_pktio_stats_t::in_packets */ + uint64_t packets; + + /** See odp_pktio_stats_t::in_discards */ + uint64_t discards; + + /** See odp_pktio_stats_t::in_errors */ + uint64_t errors; + +} odp_pktin_queue_stats_t; + +/** + * Packet IO output queue specific statistics counters + * + * Statistics counters for an individual packet output queue. Refer to packet IO + * level statistics odp_pktio_stats_t for counter definitions. + */ +typedef struct odp_pktout_queue_stats_t { + /** See odp_pktio_stats_t::out_octets */ + uint64_t octets; + + /** See odp_pktio_stats_t::out_packets */ + uint64_t packets; + + /** See odp_pktio_stats_t::out_discards */ + uint64_t discards; + + /** See odp_pktio_stats_t::out_errors */ + uint64_t errors; + +} odp_pktout_queue_stats_t; + +/** + * Packet IO statistics capabilities + */ +typedef struct odp_pktio_stats_capability_t { + /** Interface level capabilities */ + struct { + /** Supported counters */ + union { + /** Statistics counters in a bit field structure */ + struct { + /** See odp_pktio_stats_t::in_octets */ + uint64_t in_octets : 1; + + /** See odp_pktio_stats_t::in_packets */ + uint64_t in_packets : 1; + + /** See odp_pktio_stats_t::in_ucast_pkts */ + uint64_t in_ucast_pkts : 1; + + /** See odp_pktio_stats_t::in_mcast_pkts */ + uint64_t in_mcast_pkts : 1; + + /** See odp_pktio_stats_t::in_bcast_pkts */ + uint64_t in_bcast_pkts : 1; + + /** See odp_pktio_stats_t::in_discards */ + uint64_t in_discards : 1; + + /** See odp_pktio_stats_t::in_errors */ + uint64_t in_errors : 1; + + /** See odp_pktio_stats_t::out_octets */ + uint64_t out_octets : 1; + + /** See odp_pktio_stats_t::out_packets */ + uint64_t out_packets : 1; + + /** See odp_pktio_stats_t::out_ucast_pkts */ + uint64_t out_ucast_pkts : 1; + + /** See odp_pktio_stats_t::out_mcast_pkts */ + uint64_t out_mcast_pkts : 1; + + /** See odp_pktio_stats_t::out_bcast_pkts */ + uint64_t out_bcast_pkts : 1; + + /** See odp_pktio_stats_t::out_discards */ + uint64_t out_discards : 1; + + /** See odp_pktio_stats_t::out_errors */ + uint64_t out_errors : 1; + } counter; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or + * for bitwise operations over the entire structure. */ + uint64_t all_counters; + }; + } pktio; + + /** Input queue level capabilities */ + struct { + /** Supported counters */ + union { + /** Statistics counters in a bit field structure */ + struct { + /** See odp_pktin_queue_stats_t::octets */ + uint64_t octets : 1; + + /** See odp_pktin_queue_stats_t::packets */ + uint64_t packets : 1; + + /** See odp_pktin_queue_stats_t::discards */ + uint64_t discards : 1; + + /** See odp_pktin_queue_stats_t::errors */ + uint64_t errors : 1; + } counter; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or + * for bitwise operations over the entire structure. */ + uint64_t all_counters; + }; + } pktin_queue; + + /** Output queue level capabilities */ + struct { + /** Supported counters */ + union { + /** Statistics counters in a bit field structure */ + struct { + /** See odp_pktout_queue_stats_t::octets */ + uint64_t octets : 1; + + /** See odp_pktout_queue_stats_t::packets */ + uint64_t packets : 1; + + /** See odp_pktout_queue_stats_t::discards */ + uint64_t discards : 1; + + /** See odp_pktout_queue_stats_t::errors */ + uint64_t errors : 1; + } counter; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or + * for bitwise operations over the entire structure. */ + uint64_t all_counters; + }; + } pktout_queue; + +} odp_pktio_stats_capability_t; + +/** + * Packet IO extra statistics counter information + */ +typedef struct odp_pktio_extra_stat_info_t { + /** Name of the counter */ + char name[ODP_PKTIO_STATS_EXTRA_NAME_LEN]; + +} odp_pktio_extra_stat_info_t; + +/** * Get statistics for pktio handle * - * @param pktio Packet IO handle - * @param[out] stats Output buffer for counters + * Counters not supported by the interface are set to zero. + * + * @param pktio Packet IO handle + * @param[out] stats Output buffer for counters + * * @retval 0 on success * @retval <0 on failure + */ +int odp_pktio_stats(odp_pktio_t pktio, odp_pktio_stats_t *stats); + +/** + * Get statistics for direct packet input queue + * + * Packet input queue handles can be requested with odp_pktin_queue(). Counters + * not supported by the interface are set to zero. * - * @note: If counter is not supported by platform it has - * to be set to 0. + * @param queue Packet input queue handle + * @param[out] stats Output buffer for counters + * + * @retval 0 on success + * @retval <0 on failure */ -int odp_pktio_stats(odp_pktio_t pktio, - odp_pktio_stats_t *stats); +int odp_pktin_queue_stats(odp_pktin_queue_t queue, + odp_pktin_queue_stats_t *stats); /** - * Reset statistics for pktio handle + * Get statistics for packet input event queue + * + * The queue must be a packet input event queue. Event queue handles can be + * requested with odp_pktin_event_queue(). Counters not supported by the + * interface are set to zero. + * + * @param pktio Packet IO handle + * @param queue Packet input event queue handle + * @param[out] stats Output buffer for counters * - * Reset all pktio counters to 0. - * @param pktio Packet IO handle * @retval 0 on success * @retval <0 on failure + */ +int odp_pktin_event_queue_stats(odp_pktio_t pktio, odp_queue_t queue, + odp_pktin_queue_stats_t *stats); + +/** + * Get statistics for direct packet output queue + * + * Packet output queue handles can be requested with odp_pktout_queue(). + * Counters not supported by the interface are set to zero. * + * @param queue Packet output queue handle + * @param[out] stats Output buffer for counters + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_pktout_queue_stats(odp_pktout_queue_t queue, + odp_pktout_queue_stats_t *stats); + +/** + * Get statistics for packet output event queue + * + * The queue must be a packet output event queue. Event queue handles can be + * requested with odp_pktout_event_queue(). Counters not supported by the + * interface are set to zero. + * + * @param pktio Packet IO handle + * @param queue Packet output event queue handle + * @param[out] stats Output buffer for counters + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_pktout_event_queue_stats(odp_pktio_t pktio, odp_queue_t queue, + odp_pktout_queue_stats_t *stats); + +/** + * Reset statistics for pktio handle + * + * Reset all interface level statistics counters (odp_pktio_stats_t) to zero. + * It's implementation defined if other packet IO related statistics are + * affected. + * + * @param pktio Packet IO handle + * + * @retval 0 on success + * @retval <0 on failure */ int odp_pktio_stats_reset(odp_pktio_t pktio); /** + * Get extra statistics counter information for a packet IO interface + * + * Returns the number of implementation specific packet IO extra statistics + * counters supported by the interface. Outputs up to 'num' extra statistics + * counter info structures when the 'info' array pointer is not NULL. If the + * return value is larger than 'num', there are more extra counters than the + * function was allowed to output. If the return value (N) is less than 'num', + * only info[0 ... N-1] have been written. + * + * The index of a counter in the 'info' array can be used to read the value of + * the individual counter with odp_pktio_extra_stat_counter(). The order of + * counters in the output array matches with odp_pktio_extra_stats(). + * + * @param pktio Packet IO handle + * @param[out] info Array of extra statistics info structs for output + * @param num Maximum number of info structs to output + * + * @return Number of extra statistics + * @retval <0 on failure + */ +int odp_pktio_extra_stat_info(odp_pktio_t pktio, + odp_pktio_extra_stat_info_t info[], int num); + +/** + * Get extra statistics for a packet IO interface + * + * Returns the number of implementation specific packet IO extra statistics + * counters supported by the interface. Outputs up to 'num' counters when the + * 'stats' array pointer is not NULL. If the return value is larger than 'num', + * there are more counters than the function was allowed to output. If the + * return value (N) is less than 'num', only stats[0 ... N-1] have been written. + * + * The index of a counter in the 'stats' array can be used to read the value of + * the individual counter with odp_pktio_extra_stat_counter(). The order of + * counters in the output array matches with odp_pktio_extra_stat_info(). + * + * @param pktio Packet IO handle + * @param[out] stats Array of extra statistics for output + * @param num Maximum number of extra statistics to output + * + * @return Number of extra statistics + * @retval <0 on failure + */ +int odp_pktio_extra_stats(odp_pktio_t pktio, uint64_t stats[], int num); + +/** + * Get extra statistic counter value + * + * 'id' is the index of the particular counter in the output array of + * odp_pktio_extra_stat_info() or odp_pktio_extra_stats(). + * + * + * @param pktio Packet IO handle + * @param id ID of the extra statistics counter + * @param[out] stat Pointer for statistic counter output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_pktio_extra_stat_counter(odp_pktio_t pktio, uint32_t id, + uint64_t *stat); + +/** + * Print extra statistics for a packet IO interface + * + * Print all packet IO device extra statistics to ODP log. + * + * @param pktio Packet IO handle + */ +void odp_pktio_extra_stats_print(odp_pktio_t pktio); + +/** * @} */ diff --git a/include/odp/api/spec/packet_io_types.h b/include/odp/api/spec/packet_io_types.h new file mode 100644 index 000000000..9e56e087a --- /dev/null +++ b/include/odp/api/spec/packet_io_types.h @@ -0,0 +1,1253 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2020-2023 Nokia + */ + +/** + * @file + * + * ODP Packet IO types + */ + +#ifndef ODP_API_SPEC_PACKET_IO_TYPES_H_ +#define ODP_API_SPEC_PACKET_IO_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/packet_types.h> +#include <odp/api/packet_io_stats.h> +#include <odp/api/pool_types.h> +#include <odp/api/queue_types.h> +#include <odp/api/reassembly.h> +#include <odp/api/std_types.h> + +/** @defgroup odp_packet_io ODP PACKET IO + * @{ + */ + +/** + * @typedef odp_pktio_t + * Packet IO handle + */ + +/** + * @typedef odp_pktin_queue_t + * Direct packet input queue handle + */ + +/** + * @typedef odp_pktout_queue_t + * Direct packet output queue handle + */ + +/** + * @typedef odp_lso_profile_t + * LSO profile handle + */ + +/** + * @def ODP_PKTIO_INVALID + * Invalid packet IO handle + */ + +/** + * @def ODP_LSO_PROFILE_INVALID + * Invalid LSO profile handle + */ + +/** + * @def ODP_PKTIO_MAX_INDEX + * Maximum packet IO interface index. Use odp_pktio_max_index() to check the + * runtime maximum value, which may be smaller than this value. + */ + +/** + * @def ODP_PKTIO_MACADDR_MAXSIZE + * Minimum size of output buffer for odp_pktio_mac_addr() + * Actual MAC address sizes may be different. + */ + +/** + * @def ODP_PKTIN_NO_WAIT + * Do not wait on packet input + */ + +/** + * @def ODP_PKTIN_MAX_QUEUES + * Maximum number of packet input queues supported by the API. Use + * odp_pktio_capability() to check the maximum number of queues per interface. + */ + +/** + * @def ODP_PKTOUT_MAX_QUEUES + * Maximum number of packet output queues supported by the API. Use + * odp_pktio_capability() to check the maximum number of queues per interface. + */ + +/** + * Packet input mode + */ +typedef enum odp_pktin_mode_t { + /** Direct packet input from the interface */ + ODP_PKTIN_MODE_DIRECT = 0, + /** Packet input through scheduler and scheduled event queues */ + ODP_PKTIN_MODE_SCHED, + /** Packet input through plain event queues */ + ODP_PKTIN_MODE_QUEUE, + /** Application will never receive from this interface */ + ODP_PKTIN_MODE_DISABLED +} odp_pktin_mode_t; + +/** + * Packet output mode + */ +typedef enum odp_pktout_mode_t { + /** Direct packet output on the interface */ + ODP_PKTOUT_MODE_DIRECT = 0, + /** Packet output through event queues */ + ODP_PKTOUT_MODE_QUEUE, + /** Packet output through traffic manager API */ + ODP_PKTOUT_MODE_TM, + /** Application will never send to this interface */ + ODP_PKTOUT_MODE_DISABLED +} odp_pktout_mode_t; + +/** + * Packet input hash protocols + * + * The list of protocol header field combinations, which are included into + * packet input hash calculation. + */ +typedef union odp_pktin_hash_proto_t { + /** Protocol header fields for hashing */ + struct { + /** IPv4 addresses and UDP port numbers */ + uint32_t ipv4_udp : 1; + /** IPv4 addresses and TCP port numbers */ + uint32_t ipv4_tcp : 1; + /** IPv4 addresses */ + uint32_t ipv4 : 1; + /** IPv6 addresses and UDP port numbers */ + uint32_t ipv6_udp : 1; + /** IPv6 addresses and TCP port numbers */ + uint32_t ipv6_tcp : 1; + /** IPv6 addresses */ + uint32_t ipv6 : 1; + } proto; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all bits, or to perform bitwise + * operations over those. */ + uint32_t all_bits; +} odp_pktin_hash_proto_t; + +/** + * Packet IO operation mode + */ +typedef enum odp_pktio_op_mode_t { + /** Multithread safe operation + * + * Direct packet IO operation (recv or send) is multithread safe. Any + * number of application threads may perform the operation + * concurrently. */ + ODP_PKTIO_OP_MT = 0, + + /** Not multithread safe operation + * + * Direct packet IO operation (recv or send) may not be multithread + * safe. Application ensures synchronization between threads so that + * simultaneously only single thread attempts the operation on + * the same (pktin or pktout) queue. */ + ODP_PKTIO_OP_MT_UNSAFE + +} odp_pktio_op_mode_t; + +/** + * Packet input queue parameters override + */ +typedef struct odp_pktin_queue_param_ovr_t { + /** Override for schedule group in odp_schedule_param_t + * + * This parameter is considered only when queue type is + * ODP_QUEUE_TYPE_SCHED. */ + odp_schedule_group_t group; +} odp_pktin_queue_param_ovr_t; + +/** + * Packet input vector configuration + */ +typedef struct odp_pktin_vector_config_t { + /** Enable packet input vector + * + * When true, packet input vector is enabled and configured with vector + * config parameters. Otherwise, packet input vector configuration + * parameters are ignored. When vectors are enabled, packets may + * be delivered both as packet vector events and packet events. + * The default value is false. + */ + odp_bool_t enable; + + /** Vector pool + * + * Vector pool to allocate the vectors to hold packets. + * The pool must have been created with the ODP_POOL_VECTOR type. + */ + odp_pool_t pool; + + /** Maximum time to wait for packets + * + * Maximum timeout in nanoseconds to wait for the producer to form the + * vector of packet events (odp_packet_vector_t). This value should be + * in the range of odp_pktin_vector_capability_t::min_tmo_ns to + * odp_pktin_vector_capability_t::max_tmo_ns. + */ + uint64_t max_tmo_ns; + + /** Maximum number of packets in a vector + * + * The packet input subsystem forms packet vector events when either + * it reaches odp_pktin_vector_config_t::max_tmo_ns or producer reaches + * max_size packets. This value should be in the range of + * odp_pktin_vector_capability_t::min_size to + * odp_pktin_vector_capability_t::max_size. + * + * @note The maximum number of packets this vector can hold is defined + * by odp_pool_param_t::vector::max_size with odp_pktin_vector_config_t::pool. + * The max_size should not be greater than odp_pool_param_t::vector::max_size. + */ + uint32_t max_size; + +} odp_pktin_vector_config_t; + +/** + * Packet input queue parameters + */ +typedef struct odp_pktin_queue_param_t { + /** Operation mode + * + * The default value is ODP_PKTIO_OP_MT. Application may enable + * performance optimization by defining ODP_PKTIO_OP_MT_UNSAFE when + * applicable. */ + odp_pktio_op_mode_t op_mode; + + /** Enable classifier + * + * * 0: Classifier is disabled (default) + * * 1: Classifier is enabled. Use classifier to direct incoming + * packets into pktin event queues. Classifier can be enabled + * only in ODP_PKTIN_MODE_SCHED and ODP_PKTIN_MODE_QUEUE modes. + * Both classifier and hashing cannot be enabled simultaneously + * ('hash_enable' must be 0). */ + odp_bool_t classifier_enable; + + /** Enable flow hashing + * + * * 0: Do not hash flows (default) + * * 1: Enable flow hashing. Use flow hashing to spread incoming + * packets into input queues. Hashing can be enabled in all + * modes. Both classifier and hashing cannot be enabled + * simultaneously ('classifier_enable' must be 0). */ + odp_bool_t hash_enable; + + /** Protocol field selection for hashing + * + * Multiple protocols can be selected. Ignored when 'hash_enable' is + * zero. The default value is all bits zero. */ + odp_pktin_hash_proto_t hash_proto; + + /** Number of input queues to be created + * + * When classifier is enabled in odp_pktin_queue_config() this + * value is ignored, otherwise at least one queue is required. + * More than one input queues require flow hashing configured. + * The maximum value is defined by pktio capability 'max_input_queues'. + * Queue type is defined by the input mode. The default value is 1. */ + uint32_t num_queues; + + /** Input queue size array + * + * An array containing queue sizes for each 'num_queues' input queues + * in ODP_PKTIN_MODE_DIRECT mode. The value of zero means + * implementation specific default size. Nonzero values must be between + * 'min_input_queue_size' and 'max_input_queue_size' capabilities. The + * implementation may round-up given values. The default value is zero. + */ + uint32_t queue_size[ODP_PKTIN_MAX_QUEUES]; + + /** Queue parameters + * + * These are used for input queue creation in ODP_PKTIN_MODE_QUEUE + * or ODP_PKTIN_MODE_SCHED modes. Scheduler parameters are considered + * only in ODP_PKTIN_MODE_SCHED mode. Default values are defined in + * odp_queue_param_t documentation. The type field is ignored + * and the queue type is deduced from the pktio input mode. + * When classifier is enabled in odp_pktin_queue_config() this + * value is ignored. */ + odp_queue_param_t queue_param; + + /** Queue parameters override + * + * When the override array is defined, the same parameter value + * in 'queue_param' is ignored and these per queue parameter + * values are used instead. Array elements are used in order + * (i.e. the first queue gets parameters from the first array + * element, etc). + * Must point to an array of num_queues elements or NULL to + * disable queue parameters override. The default value is + * NULL. + */ + odp_pktin_queue_param_ovr_t *queue_param_ovr; + + /** Packet input vector configuration */ + odp_pktin_vector_config_t vector; + +} odp_pktin_queue_param_t; + +/** + * Packet output queue parameters + * + * These parameters are used in ODP_PKTOUT_MODE_DIRECT and + * ODP_PKTOUT_MODE_QUEUE modes. + */ +typedef struct odp_pktout_queue_param_t { + /** Operation mode + * + * The default value is ODP_PKTIO_OP_MT. Application may enable + * performance optimization by defining ODP_PKTIO_OP_MT_UNSAFE when + * applicable. */ + odp_pktio_op_mode_t op_mode; + + /** Number of output queues to be created. The value must be between + * 1 and interface capability. The default value is 1. */ + uint32_t num_queues; + + /** Output queue size array + * + * An array containing queue sizes for each 'num_queues' output queues. + * The value of zero means implementation specific default size. + * Nonzero values must be between 'min_output_queue_size' and + * 'max_output_queue_size' capabilities. The implementation may + * round-up given values. The default value is zero. + */ + uint32_t queue_size[ODP_PKTOUT_MAX_QUEUES]; + +} odp_pktout_queue_param_t; + +/** + * Packet IO parameters + * + * Packet IO interface level parameters. Use odp_pktio_param_init() to + * initialize the structure with default values. + */ +typedef struct odp_pktio_param_t { + /** Packet input mode + * + * The default value is ODP_PKTIN_MODE_DIRECT. */ + odp_pktin_mode_t in_mode; + + /** Packet output mode + * + * The default value is ODP_PKTOUT_MODE_DIRECT. */ + odp_pktout_mode_t out_mode; + +} odp_pktio_param_t; + +/** + * Packet input configuration options bit field + * + * Packet input configuration options listed in a bit field structure. Packet + * input timestamping may be enabled for all packets or at least for those that + * belong to time synchronization protocol (PTP). + * + * Packet input checksum checking may be enabled or disabled. When it is + * enabled, implementation will attempt to verify checksum correctness on + * incoming packets and depending on drop configuration either deliver erroneous + * packets with appropriate flags set (e.g. odp_packet_has_l3_error(), + * odp_packet_l3_chksum_status()) or drop those. When packet dropping is + * enabled, application will never receive a packet with the specified error + * and may avoid to check the error flag. + * + * If checksum checking is enabled, IPv4 header checksum checking is always + * done for packets that do not have IP options and L4 checksum checking + * is done for unfragmented packets that do not have IPv4 options or IPv6 + * extension headers. In other cases checksum checking may or may not + * be done. For example, L4 checksum of fragmented packets is typically + * not checked. + * + * IPv4 checksum checking may be enabled only when parsing level is + * ODP_PROTO_LAYER_L3 or higher. Similarly, L4 level checksum checking + * may be enabled only with parsing level ODP_PROTO_LAYER_L4 or higher. + * + * Whether checksum checking was done and whether a checksum was correct + * can be queried for each received packet with odp_packet_l3_chksum_status() + * and odp_packet_l4_chksum_status(). + */ +typedef union odp_pktin_config_opt_t { + /** Option flags */ + struct { + /** Timestamp all packets on packet input */ + uint64_t ts_all : 1; + + /** Timestamp (at least) IEEE1588 / PTP packets + * on packet input */ + uint64_t ts_ptp : 1; + + /** Check IPv4 header checksum on packet input */ + uint64_t ipv4_chksum : 1; + + /** Check UDP checksum on packet input */ + uint64_t udp_chksum : 1; + + /** Check TCP checksum on packet input */ + uint64_t tcp_chksum : 1; + + /** Check SCTP checksum on packet input */ + uint64_t sctp_chksum : 1; + + /** Drop packets with an IPv4 error on packet input */ + uint64_t drop_ipv4_err : 1; + + /** Drop packets with an IPv6 error on packet input */ + uint64_t drop_ipv6_err : 1; + + /** Drop packets with a UDP error on packet input */ + uint64_t drop_udp_err : 1; + + /** Drop packets with a TCP error on packet input */ + uint64_t drop_tcp_err : 1; + + /** Drop packets with a SCTP error on packet input */ + uint64_t drop_sctp_err : 1; + + } bit; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or bitwise + * operations over the entire structure. */ + uint64_t all_bits; +} odp_pktin_config_opt_t; + +/** + * Packet output configuration options bit field + * + * Packet output configuration options listed in a bit field structure. Packet + * output checksum insertion may be enabled or disabled (e.g. ipv4_chksum_ena): + * + * 0: Disable checksum insertion. Application will not request checksum + * insertion for any packet. This is the default value for xxx_chksum_ena + * bits. + * 1: Enable checksum insertion. Application will request checksum insertion + * for some packets. + * + * When checksum insertion is enabled, application may use configuration options + * to set the default behaviour on packet output (e.g. ipv4_chksum): + * + * 0: Do not insert checksum by default. This is the default value for + * xxx_chksum bits. + * 1: Calculate and insert checksum by default. + * + * These defaults may be overridden on per packet basis using e.g. + * odp_packet_l4_chksum_insert(). + * + * For correct operation, packet metadata must provide valid offsets and type + * flags for the appropriate layer 3 and layer 4 protocols. L3 and L4 offsets + * can be updated with odp_packet_l3_offset_set() and odp_packet_l4_offset_set() + * calls. L3 and L4 type flags can be updated using odp_packet_has_*_set() calls + * For example, UDP checksum calculation needs both L3 and L4 types (IP and UDP) and + * L3 and L4 offsets (to access IP and UDP headers), while IP checksum + * calculation only needs L3 type (IP) and L3 offset (to access IP header). + * When application (e.g. a switch) does not modify L3/L4 data and thus checksum + * does not need to be updated, checksum insertion should be disabled for optimal + * performance. + * + * UDP, TCP and SCTP checksum insertion must not be requested for IP fragments. + * Use checksum override function (odp_packet_l4_chksum_insert()) to disable + * checksumming when sending a fragment through a packet IO interface that has + * the relevant L4 checksum insertion enabled. + * + * Result of checksum insertion at packet output is undefined if the protocol + * headers required for checksum calculation are not well formed. Packet must + * contain at least as many data bytes after L3/L4 offsets as the headers + * indicate. Other data bytes of the packet are ignored for the checksum + * insertion. + */ +typedef union odp_pktout_config_opt_t { + /** Option flags for packet output */ + struct { + /** Enable Tx timestamp capture */ + uint64_t ts_ena : 1; + + /** Enable IPv4 header checksum insertion */ + uint64_t ipv4_chksum_ena : 1; + + /** Enable UDP checksum insertion */ + uint64_t udp_chksum_ena : 1; + + /** Enable TCP checksum insertion */ + uint64_t tcp_chksum_ena : 1; + + /** Enable SCTP checksum insertion */ + uint64_t sctp_chksum_ena : 1; + + /** Insert IPv4 header checksum by default */ + uint64_t ipv4_chksum : 1; + + /** Insert UDP checksum on packet by default */ + uint64_t udp_chksum : 1; + + /** Insert TCP checksum on packet by default */ + uint64_t tcp_chksum : 1; + + /** Insert SCTP checksum on packet by default */ + uint64_t sctp_chksum : 1; + + /** Packet references not used on packet output + * + * When set, application indicates that it will not transmit + * packet references on this packet IO interface. + * Since every ODP implementation supports it, it is always + * ok to set this flag. + * + * 0: Packet references may be transmitted on the + * interface (the default value). + * 1: Packet references will not be transmitted on the + * interface. + */ + uint64_t no_packet_refs : 1; + + /** Enable packet aging and drop + * + * 0: application will not request packet aging (default) + * 1: application may request packet aging + */ + uint64_t aging_ena : 1; + + /** + * For backwards compatibility, setting this flag is the same as setting + * tx_compl.mode_event in odp_pktio_config_t. The default value is zero. + * + * @deprecated Use odp_pktio_config_t::mode_event instead. + */ + uint64_t tx_compl_ena : 1; + + /** Enable packet protocol stats update */ + uint64_t proto_stats_ena : 1; + + } bit; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or bitwise + * operations over the entire structure. */ + uint64_t all_bits; +} odp_pktout_config_opt_t; + +/** + * Parser configuration + */ +typedef struct odp_pktio_parser_config_t { + /** Protocol parsing level in packet input + * + * Application requires that protocol headers in a packet are checked + * up to this layer during packet input. Use ODP_PROTO_LAYER_ALL for + * all layers. Packet metadata for this and all preceding layers are + * set. In addition, offset (and pointer) to the next layer is set. + * Other layer/protocol specific metadata have undefined values. + * + * The default value is ODP_PROTO_LAYER_ALL. */ + odp_proto_layer_t layer; + +} odp_pktio_parser_config_t; + +/** Ethernet flow control modes */ +typedef enum odp_pktio_link_pause_t { + /** Flow control mode is unknown */ + ODP_PKTIO_LINK_PAUSE_UNKNOWN = -1, + /** No flow control */ + ODP_PKTIO_LINK_PAUSE_OFF = 0, + /** Pause frame flow control enabled */ + ODP_PKTIO_LINK_PAUSE_ON = 1, + /** Priority-based Flow Control (PFC) enabled */ + ODP_PKTIO_LINK_PFC_ON = 2 + +} odp_pktio_link_pause_t; + +/** + * Packet IO configuration options + * + * Packet IO interface level configuration options. Use odp_pktio_capability() + * to see which options are supported by the implementation. + * Use odp_pktio_config_init() to initialize the structure with default values. + */ +typedef struct odp_pktio_config_t { + /** Packet input configuration options bit field + * + * Default value for all bits is zero. */ + odp_pktin_config_opt_t pktin; + + /** Packet output configuration options bit field + * + * Default value for all bits is zero. */ + odp_pktout_config_opt_t pktout; + + /** Packet input parser configuration */ + odp_pktio_parser_config_t parser; + + /** Interface loopback mode + * + * In this mode the packets sent out through the interface is + * looped back to input of the same interface. Supporting loopback mode + * is an optional feature per interface and should be queried in the + * interface capability before enabling the same. + * + * Default value is false. + */ + odp_bool_t enable_loop; + + /** Inbound IPSEC inlined with packet input + * + * Enable/disable inline inbound IPSEC operation. When enabled packet + * input directs all IPSEC packets automatically to IPSEC inbound + * processing. IPSEC configuration (through IPSEC API) must be done + * before enabling this feature in pktio. + * Packets that are not (recognized as) IPSEC are processed + * according to the packet input configuration. + * + * 0: Disable inbound IPSEC inline operation (default) + * 1: Enable inbound IPSEC inline operation + * + * @see odp_ipsec_config(), odp_ipsec_sa_create() + */ + odp_bool_t inbound_ipsec; + + /** Outbound IPSEC inlined with packet output + * + * Enable/disable inline outbound IPSEC operation. When enabled IPSEC + * outbound processing can send outgoing IPSEC packets directly + * to the pktio interface for output. IPSEC configuration is done + * through the IPSEC API. + * + * Support of outbound IPSEC inline operation with traffic manager + * (ODP_PKTOUT_MODE_TM) can be queried with odp_ipsec_capability(). + * + * * 0: Disable outbound IPSEC inline operation (default) + * * 1: Enable outbound IPSEC inline operation + * + * @see odp_ipsec_config(), odp_ipsec_sa_create(), odp_ipsec_out_inline() + */ + odp_bool_t outbound_ipsec; + + /** Enable Large Send Offload (LSO) + * + * Enables LSO on the interface. Use LSO capabilities (odp_lso_capability_t) to check if + * the interface supports LSO (in the selected packet output mode). LSO cannot be enabled + * in ODP_PKTOUT_MODE_QUEUE mode. Also, LSO operation cannot be combined with IPSEC on + * packet output. + * + * Application requests LSO for outgoing packets with odp_pktout_send_lso() or + * odp_tm_enq_multi_lso(). Other packet output calls ignore LSO metadata in packets. + * + * 0: Application will not use LSO (default) + * 1: Application will use LSO + */ + odp_bool_t enable_lso; + + /** Packet input reassembly configuration */ + odp_reass_config_t reassembly; + + /** Link flow control configuration */ + struct { + /** Reception of flow control frames + * + * Configures interface operation when an Ethernet flow control frame is received: + * * ODP_PKTIO_LINK_PAUSE_OFF: Flow control is disabled + * * ODP_PKTIO_LINK_PAUSE_ON: Enable traditional Ethernet pause frame handling. + * When a pause frame is received, all packet output + * is halted temporarily. + * * ODP_PKTIO_LINK_PFC_ON: Enable Priority-based Flow Control (PFC) + * handling. When a PFC frame is received, packet + * output of certain (VLAN) class of service levels + * are halted temporarily. + * + * The default value is ODP_PKTIO_LINK_PAUSE_OFF. + */ + odp_pktio_link_pause_t pause_rx; + + /** Transmission of flow control frames + * + * Configures Ethernet flow control frame generation on the interface: + * * ODP_PKTIO_LINK_PAUSE_OFF: Flow control is disabled + * * ODP_PKTIO_LINK_PAUSE_ON: Enable traditional Ethernet pause frame + * generation. Pause frames are generated to request + * the remote end of the link to halt all + * transmissions temporarily. + * * ODP_PKTIO_LINK_PFC_ON: Enable Priority-based Flow Control (PFC) frame + * generation. PFC frames are generated to request + * the remote end of the link to halt transmission + * of certain (VLAN) class of service levels + * temporarily. + * + * When PFC is enabled, classifier API is used to configure CoS nodes with back + * pressure threshold and PFC priority level parameters (odp_bp_param_t). + * + * The default value is ODP_PKTIO_LINK_PAUSE_OFF. + */ + odp_pktio_link_pause_t pause_tx; + + } flow_control; + + /** + * Packet transmit completion configuration + */ + struct { + /** + * Enable packet transmit completion events + * + * Use pktio capability tx_compl to check if packet transmit completion mode + * #ODP_PACKET_TX_COMPL_EVENT is supported. + * + * 0: Application will not request ODP_PACKET_TX_COMPL_EVENT mode + * completion (default) + * 1: Application may request ODP_PACKET_TX_COMPL_EVENT mode completion + */ + uint32_t mode_event : 1; + + /** + * Enable packet transmit completion check through polling + * + * Use pktio capability tx_compl to check if packet transmit completion mode + * #ODP_PACKET_TX_COMPL_POLL is supported. + * + * 0: Application will not request ODP_PACKET_TX_COMPL_POLL mode + * completion (default) + * 1: Application may request ODP_PACKET_TX_COMPL_POLL mode completion + */ + uint32_t mode_poll : 1; + + /** + * Maximum completion index + * + * When ODP_PACKET_TX_COMPL_POLL mode is enabled, the maximum completion index + * value that application will use. The value must be between 0 and + * tx_compl.max_compl_id capability. The default value is zero. + */ + uint32_t max_compl_id; + + } tx_compl; + +} odp_pktio_config_t; + +/** + * Packet IO set operations + * + * Supported packet IO interface set operations listed in a bit field structure. + */ +typedef union odp_pktio_set_op_t { + /** Operation flags */ + struct { + /** Promiscuous mode */ + uint32_t promisc_mode : 1; + /** MAC address */ + uint32_t mac_addr : 1; + /** Per port header offset(skip)set */ + uint32_t skip_offset : 1; + /** Maximum frame length */ + uint32_t maxlen : 1; + } op; + /** All bits of the bit field structure. + * This field can be used to set/clear all flags, or bitwise + * operations over the entire structure. */ + uint32_t all_bits; +} odp_pktio_set_op_t; + +/** Maximum number of custom LSO fields supported by ODP API */ +#define ODP_LSO_MAX_CUSTOM 8 + +/** LSO custom modification options */ +typedef enum odp_lso_modify_t { + /** Add current segment number. Numbering starts from zero. */ + ODP_LSO_ADD_SEGMENT_NUM = 0x1, + + /** Add number of payload bytes in the segment */ + ODP_LSO_ADD_PAYLOAD_LEN = 0x2, + + /** Add number of payload bytes in all previous segments */ + ODP_LSO_ADD_PAYLOAD_OFFSET = 0x4 + +} odp_lso_modify_t; + +/** LSO protocol options + * + * An LSO operation may perform segmentation on these protocols. + */ +typedef enum odp_lso_protocol_t { + /** Protocol not selected. */ + ODP_LSO_PROTO_NONE = 0, + + /** Custom protocol. LSO performs only custom field updates to the packet headers. */ + ODP_LSO_PROTO_CUSTOM, + + /** LSO performs IPv4 fragmentation. + * + * IP header length and checksum fields are updated. IP fragmentation related fields are + * filled and IPv4 Identification field value is copied from the original packet. */ + ODP_LSO_PROTO_IPV4, + + /** LSO performs IPv6 fragmentation. */ + ODP_LSO_PROTO_IPV6, + + /** LSO performs TCP segmentation on top of IPv4. + * + * IP header length and checksum fields are updated. IP fragmentation is not performed + * and IPv4 Don't Fragment bit is not set. Unique IPv4 Identification field values + * are generated. Those are usually increments of the IPv4 ID field value in the packet. + */ + ODP_LSO_PROTO_TCP_IPV4, + + /** LSO performs TCP segmentation on top of IPv6. */ + ODP_LSO_PROTO_TCP_IPV6, + + /** LSO performs SCTP segmentation on top of IPv4. */ + ODP_LSO_PROTO_SCTP_IPV4, + + /** LSO performs SCTP segmentation on top of IPv6. */ + ODP_LSO_PROTO_SCTP_IPV6 + +} odp_lso_protocol_t; + +/** Large Send Offload (LSO) capabilities */ +typedef struct odp_lso_capability_t { + /** Maximum number of LSO profiles. When zero, LSO is not supported. */ + uint32_t max_profiles; + + /** Maximum number of LSO profiles per packet IO interface. When zero, LSO is not + * supported by the interface. */ + uint32_t max_profiles_per_pktio; + + /** Maximum number of segments in an input packet. When one, LSO operation accepts only + * non-segmented packets as input. */ + uint32_t max_packet_segments; + + /** Maximum number of segments an LSO operation may create. This implies that + * the maximum supported input packet payload size for an LSO operation is + * max_segments * max_payload_len bytes. */ + uint32_t max_segments; + + /** Maximum payload length per an LSO generated packet (in bytes). This is the maximum value + * for max_payload_len in odp_packet_lso_opt_t. */ + uint32_t max_payload_len; + + /** Maximum supported offset to the packet payload (in bytes). This is the maximum value + * for payload_offset in odp_packet_lso_opt_t. */ + uint32_t max_payload_offset; + + /** Supported LSO custom modification options */ + struct { + /** ODP_LSO_ADD_SEGMENT_NUM support */ + uint16_t add_segment_num:1; + + /** ODP_LSO_ADD_PAYLOAD_LEN support */ + uint16_t add_payload_len:1; + + /** ODP_LSO_ADD_PAYLOAD_OFFSET support */ + uint16_t add_payload_offset:1; + + } mod_op; + + /** Maximum number of custom fields supported per LSO profile. When zero, custom + * fields are not supported. */ + uint8_t max_num_custom; + + /** Supported LSO protocol options */ + struct { + /** ODP_LSO_PROTO_CUSTOM support */ + uint32_t custom:1; + + /** ODP_LSO_PROTO_IPV4 support */ + uint32_t ipv4:1; + + /** ODP_LSO_PROTO_IPV6 support */ + uint32_t ipv6:1; + + /** ODP_LSO_PROTO_TCP_IPV4 support */ + uint32_t tcp_ipv4:1; + + /** ODP_LSO_PROTO_TCP_IPV6 support */ + uint32_t tcp_ipv6:1; + + /** ODP_LSO_PROTO_SCTP_IPV4 support */ + uint32_t sctp_ipv4:1; + + /** ODP_LSO_PROTO_SCTP_IPV6 support */ + uint32_t sctp_ipv6:1; + + } proto; + +} odp_lso_capability_t; + +/** + * Packet input vector capabilities + */ +typedef struct odp_pktin_vector_capability_t { + /** Packet input vector availability */ + odp_support_t supported; + + /** Maximum number of packets that can be accumulated into a packet + * vector by a producer + * + * odp_pktin_vector_config_t::max_size should not be greater than this + * value. */ + uint32_t max_size; + + /** Minimum value allowed to be configured to + * odp_pktin_vector_config_t::max_size */ + uint32_t min_size; + + /** Maximum timeout in nanoseconds for the producer to wait for the + * vector of packets + * + * odp_pktin_vector_config_t::max_tmo_ns should not be greater than this + * value. */ + uint64_t max_tmo_ns; + + /** Minimum value allowed to be configured to + * odp_pktin_vector_config_t::max_tmo_ns */ + uint64_t min_tmo_ns; + +} odp_pktin_vector_capability_t; + +/** + * Packet IO capabilities + * + * Note that interface capabilities may differ between packet output modes. For example, + * LSO may not be supported in ODP_PKTOUT_MODE_TM mode, while it is supported in + * ODP_PKTOUT_MODE_DIRECT mode. + */ +typedef struct odp_pktio_capability_t { + /** Maximum number of input queues + * + * Value does not exceed ODP_PKTIN_MAX_QUEUES. */ + uint32_t max_input_queues; + + /** Minimum input queue size + * + * Zero if configuring queue size is not supported. */ + uint32_t min_input_queue_size; + + /** Maximum input queue size + * + * Zero if configuring queue size is not supported. */ + uint32_t max_input_queue_size; + + /** Maximum number of output queues + * + * Value does not exceed ODP_PKTOUT_MAX_QUEUES. */ + uint32_t max_output_queues; + + /** Minimum output queue size + * + * Zero if configuring queue size is not supported. */ + uint32_t min_output_queue_size; + + /** Maximum output queue size + * + * Zero if configuring queue size is not supported. */ + uint32_t max_output_queue_size; + + /** Supported pktio configuration options */ + odp_pktio_config_t config; + + /** Supported set operations + * + * A bit set to one indicates a supported operation. All other bits are + * set to zero. */ + odp_pktio_set_op_t set_op; + + /** Packet input vector capability */ + odp_pktin_vector_capability_t vector; + + /** LSO capabilities */ + odp_lso_capability_t lso; + + /** Supported frame lengths for odp_pktio_maxlen_set() + * + * A frame length value of zero indicates an unsupported operation. */ + struct { + /** Equal maximum frame length for both packet input and output + * + * When set, the same maximum frame length value has to be used + * for both input and output directions. */ + odp_bool_t equal; + /** Minimum valid value for 'maxlen_input' */ + uint32_t min_input; + /** Maximum valid value for 'maxlen_input' */ + uint32_t max_input; + /** Minimum valid value for 'maxlen_output' */ + uint32_t min_output; + /** Maximum valid value for 'maxlen_output' */ + uint32_t max_output; + } maxlen; + + /** + * Max Tx aging timeout in nano seconds supported when packet aging + * feature is supported. + * + * 0: aging is not supported + * >0: maximum aging timeout supported in nanoseconds + */ + uint64_t max_tx_aging_tmo_ns; + + /** Supported packet Tx completion options */ + struct { + /** + * Scheduled queue support + * + * This defines whether schedule queues are supported for receiving Tx + * completion events. + * + * 0: Scheduled queues are not supported for receiving Tx completion events. + * 1: Scheduled queues are supported for receiving Tx completion events. + * @see odp_packet_tx_compl_request() + */ + odp_bool_t queue_type_sched; + + /** + * Plain queue support + * + * This defines whether plain queues are supported for receiving Tx + * completion events. + * + * 0: Plain queues are not supported for receiving Tx completion events. + * 1: Plain queues are supported for receiving Tx completion events. + * @see odp_packet_tx_compl_request() + */ + odp_bool_t queue_type_plain; + + /** + * For backwards compatibility, mode_all is synonym of mode_event. + * + * @deprecated Use mode_event instead. + */ + uint32_t mode_all : 1; + + /** Packet transmit completion mode ODP_PACKET_TX_COMPL_EVENT support */ + uint32_t mode_event : 1; + + /** Packet transmit completion mode ODP_PACKET_TX_COMPL_POLL support */ + uint32_t mode_poll : 1; + + /** Maximum supported completion ID value */ + uint32_t max_compl_id; + + } tx_compl; + + /** Supported packet free control options */ + struct { + /** + * Packet free control option #ODP_PACKET_FREE_CTRL_DONT_FREE support + * with odp_packet_free_ctrl_set(). + */ + uint32_t dont_free : 1; + + } free_ctrl; + + /** Packet input reassembly capability */ + odp_reass_capability_t reassembly; + + /** Statistics counters capabilities */ + odp_pktio_stats_capability_t stats; + + /** Supported flow control modes */ + struct { + /** Reception of traditional Ethernet pause frames */ + uint32_t pause_rx: 1; + + /** Reception of PFC frames */ + uint32_t pfc_rx: 1; + + /** Generation of traditional Ethernet pause frames */ + uint32_t pause_tx: 1; + + /** Generation of PFC frames */ + uint32_t pfc_tx: 1; + + } flow_control; + +} odp_pktio_capability_t; + +/** + * LSO profile parameters + */ +typedef struct odp_lso_profile_param_t { + /** + * Segmentation protocol + * + * Selects on which protocol LSO operation performs segmentation (e.g. IP fragmentation vs. + * TCP segmentation). When ODP_LSO_PROTO_CUSTOM is selected, only custom field + * modifications are performed. The default value is ODP_LSO_PROTO_NONE. Check LSO + * capability for supported protocols. + */ + odp_lso_protocol_t lso_proto; + + /** + * Custom fields + * + * Set lso_proto to ODP_LSO_PROTO_CUSTOM when using custom fields. Fields are defined + * in the same order they appear in the packet. + */ + struct { + /** Custom field to be modified by LSO */ + struct { + /** Field modify operation. Selects how value of the field is modified + * from its original value during segmentation. Field value is assumed + * to be in network (big endian) byte order. */ + odp_lso_modify_t mod_op; + + /** Field offset in bytes from packet start */ + uint32_t offset; + + /** Field size in bytes. Valid values are 1, 2, 4, and 8 bytes. */ + uint8_t size; + + } field[ODP_LSO_MAX_CUSTOM]; + + /** Number of custom fields specified. The default value is 0. */ + uint8_t num_custom; + + } custom; + +} odp_lso_profile_param_t; + +/** Link status */ +typedef enum odp_pktio_link_status_t { + /** Link status is unknown */ + ODP_PKTIO_LINK_STATUS_UNKNOWN = -1, + /** Link status is down */ + ODP_PKTIO_LINK_STATUS_DOWN = 0, + /** Link status is up */ + ODP_PKTIO_LINK_STATUS_UP = 1 + +} odp_pktio_link_status_t; + +/** + * Packet IO information + */ +typedef struct odp_pktio_info_t { + /** Packet IO device name */ + const char *name; + + /** Packet IO driver name (implementation specific) */ + const char *drv_name; + + /** Packet pool */ + odp_pool_t pool; + + /** Packet IO parameters */ + odp_pktio_param_t param; + +} odp_pktio_info_t; + +/** @name Link speed + * Packet IO link speeds in Mbps + * @anchor link_speed + * @{ + */ + +/** Link speed unknown */ +#define ODP_PKTIO_LINK_SPEED_UNKNOWN 0 +/** Link speed 10 Mbit/s */ +#define ODP_PKTIO_LINK_SPEED_10M 10 +/** Link speed 100 Mbit/s */ +#define ODP_PKTIO_LINK_SPEED_100M 100 +/** Link speed 1 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_1G 1000 +/** Link speed 2.5 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_2_5G 2500 +/** Link speed 5 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_5G 5000 +/** Link speed 10 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_10G 10000 +/** Link speed 20 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_20G 20000 +/** Link speed 25 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_25G 25000 +/** Link speed 40 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_40G 40000 +/** Link speed 50 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_50G 50000 +/** Link speed 56 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_56G 56000 +/** Link speed 100 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_100G 100000 +/** Link speed 200 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_200G 200000 +/** Link speed 400 Gbit/s */ +#define ODP_PKTIO_LINK_SPEED_400G 400000 + +/** @} */ + +/** Autonegotiation mode */ +typedef enum odp_pktio_link_autoneg_t { + /** Autonegotiation state unknown */ + ODP_PKTIO_LINK_AUTONEG_UNKNOWN = -1, + /** Autonegotiation disabled */ + ODP_PKTIO_LINK_AUTONEG_OFF = 0, + /** Autonegotiation enabled */ + ODP_PKTIO_LINK_AUTONEG_ON = 1 + +} odp_pktio_link_autoneg_t; + +/** Duplex mode */ +typedef enum odp_pktio_link_duplex_t { + /** Link duplex mode is unknown */ + ODP_PKTIO_LINK_DUPLEX_UNKNOWN = -1, + /** Half duplex mode */ + ODP_PKTIO_LINK_DUPLEX_HALF = 0, + /** Full duplex mode */ + ODP_PKTIO_LINK_DUPLEX_FULL = 1 + +} odp_pktio_link_duplex_t; + +/** + * Packet IO link information + */ +typedef struct odp_pktio_link_info_t { + /** Link autonegotiation */ + odp_pktio_link_autoneg_t autoneg; + /** Duplex mode */ + odp_pktio_link_duplex_t duplex; + /** Link media type + * + * The implementation owned string describes link media type. Values are + * implementation specific short names like copper, fiber, or virtual. + * The value of "unknown" is used when media type cannot be determined. */ + const char *media; + /** Reception of pause frames */ + odp_pktio_link_pause_t pause_rx; + /** Transmission of pause frames */ + odp_pktio_link_pause_t pause_tx; + /** Link speed in Mbps + * + * The value of zero means that the link speed is unknown. + * ODP_PKTIO_LINK_SPEED_* (@ref link_speed) defines can be used to + * compare the value to standard link speeds. */ + uint32_t speed; + /** Link status */ + odp_pktio_link_status_t status; +} odp_pktio_link_info_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/packet_types.h b/include/odp/api/spec/packet_types.h new file mode 100644 index 000000000..b9d55abde --- /dev/null +++ b/include/odp/api/spec/packet_types.h @@ -0,0 +1,525 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2021-2023 Nokia + */ + +/** + * @file + * + * ODP packet types + */ + +#ifndef ODP_API_SPEC_PACKET_TYPES_H_ +#define ODP_API_SPEC_PACKET_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/proto_stats_types.h> +#include <odp/api/queue_types.h> + +/** @defgroup odp_packet ODP PACKET + * @{ + */ + +/** + * @typedef odp_packet_t + * ODP packet + */ + +/** + * @def ODP_PACKET_INVALID + * Invalid packet + */ + +/** + * @def ODP_PACKET_OFFSET_INVALID + * Invalid packet offset + */ + +/** + * @typedef odp_packet_seg_t + * ODP packet segment + * + * A packet segment refers to a contiguous part of packet data (in memory). Segments of a packet + * can be examined with odp_packet_seg_data(), odp_packet_seg_data_len() and other calls. + */ + +/** + * @def ODP_PACKET_SEG_INVALID + * Invalid packet segment + */ + +/** + * @typedef odp_packet_buf_t + * ODP packet buffer + * + * Packet buffers are not part of any packet, but they result from a previous + * odp_packet_disassemble() call. A new packet is formed from packet buffers with + * a odp_packet_reassemble() call. + */ + +/** + * @def ODP_PACKET_BUF_INVALID + * Invalid packet buffer + */ + +/** + * @typedef odp_packet_color_t + * Color of packet for shaper/drop processing + * + * @var ODP_PACKET_GREEN + * Packet is green + * + * @var ODP_PACKET_YELLOW + * Packet is yellow + * + * @var ODP_PACKET_RED + * Packet is red + */ + +/** + * Maximum number of packet colors which accommodates ODP_PACKET_GREEN, ODP_PACKET_YELLOW and + * ODP_PACKET_RED. + */ +#define ODP_NUM_PACKET_COLORS 3 + +/** + * Layer 2 protocol type + */ +typedef uint8_t odp_proto_l2_type_t; + +/** Layer 2 protocol type not defined */ +#define ODP_PROTO_L2_TYPE_NONE 0 + + /** Layer 2 protocol is Ethernet */ +#define ODP_PROTO_L2_TYPE_ETH 1 + +/** + * Layer 3 protocol type + */ +typedef uint16_t odp_proto_l3_type_t; + +/** Layer 3 protocol type not defined */ +#define ODP_PROTO_L3_TYPE_NONE 0xFFFF + +/* Types from IEEE EtherType assignments list */ + +/** Layer 3 protocol is ARP */ +#define ODP_PROTO_L3_TYPE_ARP 0x0806 + +/** Layer 3 protocol is RARP */ +#define ODP_PROTO_L3_TYPE_RARP 0x8035 + +/** Layer 3 protocol is MPLS */ +#define ODP_PROTO_L3_TYPE_MPLS 0x8847 + +/** Layer 3 protocol type is IPv4 */ +#define ODP_PROTO_L3_TYPE_IPV4 0x0800 + +/** Layer 3 protocol type is IPv6 */ +#define ODP_PROTO_L3_TYPE_IPV6 0x86DD + +/** + * Layer 4 protocol type + */ +typedef uint8_t odp_proto_l4_type_t; + +/** Layer 4 protocol type not defined */ + #define ODP_PROTO_L4_TYPE_NONE 255 + +/* Types from IANA assigned Internet protocol numbers list */ + +/** Layer 4 protocol type is ICMPv4 */ + #define ODP_PROTO_L4_TYPE_ICMPV4 1 + +/** Layer 4 protocol type is IGMP */ +#define ODP_PROTO_L4_TYPE_IGMP 2 + +/** Layer 4 protocol type is IPv4 */ +#define ODP_PROTO_L4_TYPE_IPV4 4 + +/** Layer 4 protocol type is TCP */ + #define ODP_PROTO_L4_TYPE_TCP 6 + +/** Layer 4 protocol type is UDP */ +#define ODP_PROTO_L4_TYPE_UDP 17 + +/** Layer 4 protocol type is IPv6 */ +#define ODP_PROTO_L4_TYPE_IPV6 41 + +/** Layer 4 protocol type is GRE */ +#define ODP_PROTO_L4_TYPE_GRE 47 + +/** Layer 4 protocol type is IPSEC ESP */ +#define ODP_PROTO_L4_TYPE_ESP 50 + +/** Layer 4 protocol type is IPSEC AH */ +#define ODP_PROTO_L4_TYPE_AH 51 + +/** Layer 4 protocol type is ICMPv6 */ +#define ODP_PROTO_L4_TYPE_ICMPV6 58 + +/** Layer 4 protocol type is No Next Header for IPv6 */ +#define ODP_PROTO_L4_TYPE_NO_NEXT 59 + +/** Layer 4 protocol type is IP Payload Compression Protocol */ +#define ODP_PROTO_L4_TYPE_IPCOMP 108 + +/** Layer 4 protocol type is SCTP */ +#define ODP_PROTO_L4_TYPE_SCTP 132 + +/** Layer 4 protocol type is ROHC */ +#define ODP_PROTO_L4_TYPE_ROHC 142 + +/** + * @typedef odp_packet_chksum_status_t + * Checksum check status in packet + * + * @var ODP_PACKET_CHKSUM_UNKNOWN + * Checksum was not checked. Checksum check was not + * attempted or the attempt failed. + * + * @var ODP_PACKET_CHKSUM_BAD + * Checksum was checked and it was not correct. + * + * @var ODP_PACKET_CHKSUM_OK + * Checksum was checked and it was correct. + */ + +/** + * @typedef odp_packet_vector_t + * ODP packet vector + */ + +/** + * @def ODP_PACKET_VECTOR_INVALID + * Invalid packet vector + */ + +/** + * @typedef odp_packet_tx_compl_t + * ODP Packet Tx completion + */ + +/** + * @def ODP_PACKET_TX_COMPL_INVALID + * Invalid packet Tx completion + */ + +/** + * Protocol + */ +typedef enum odp_proto_t { + /** No protocol defined */ + ODP_PROTO_NONE = 0, + + /** Ethernet (including VLAN) */ + ODP_PROTO_ETH, + + /** IP version 4 */ + ODP_PROTO_IPV4, + + /** IP version 6 */ + ODP_PROTO_IPV6 + +} odp_proto_t; + +/** + * Protocol layer + */ +typedef enum odp_proto_layer_t { + /** No layers */ + ODP_PROTO_LAYER_NONE = 0, + + /** Layer L2 protocols (Ethernet, VLAN, etc) */ + ODP_PROTO_LAYER_L2, + + /** Layer L3 protocols (IPv4, IPv6, ICMP, IPSEC, etc) */ + ODP_PROTO_LAYER_L3, + + /** Layer L4 protocols (UDP, TCP, SCTP) */ + ODP_PROTO_LAYER_L4, + + /** All layers */ + ODP_PROTO_LAYER_ALL + +} odp_proto_layer_t; + +/** + * Packet API data range specifier + */ +typedef struct odp_packet_data_range { + /** Offset from beginning of packet */ + uint32_t offset; + + /** Length of data to operate on */ + uint32_t length; + +} odp_packet_data_range_t; + +/** + * Reassembly status of a packet + */ +typedef enum odp_packet_reass_status_t { + /** Reassembly was not attempted */ + ODP_PACKET_REASS_NONE = 0, + + /** Reassembly was attempted but is incomplete. Partial reassembly + * result can be accessed using ``odp_packet_reass_partial_state()``. + * + * The packet does not contain valid packet data and cannot be used + * in normal packet operations. + */ + ODP_PACKET_REASS_INCOMPLETE, + + /** Reassembly was successfully done. The packet has been + * reassembled from multiple received fragments. */ + ODP_PACKET_REASS_COMPLETE, +} odp_packet_reass_status_t; + +/** + * Information about a completed reassembly + */ +typedef struct odp_packet_reass_info_t { + /** Number of fragments reassembled */ + uint16_t num_frags; +} odp_packet_reass_info_t; + +/** + * Result from odp_packet_reass_partial_state() + */ +typedef struct odp_packet_reass_partial_state_t { + /** Number of fragments returned */ + uint16_t num_frags; + + /** Time, in ns, since the reception of the first received fragment */ + uint64_t elapsed_time; +} odp_packet_reass_partial_state_t; + +/** + * Flags to control packet data checksum checking + */ +typedef union odp_proto_chksums_t { + /** Individual checksum bits. */ + struct { + /** IPv4 header checksum */ + uint32_t ipv4 : 1; + + /** UDP checksum */ + uint32_t udp : 1; + + /** TCP checksum */ + uint32_t tcp : 1; + + /** SCTP checksum */ + uint32_t sctp : 1; + + } chksum; + + /** All checksum bits + * + * This field can be used to set/clear all flags, or to perform bitwise + * operations over those. */ + uint32_t all_chksum; + +} odp_proto_chksums_t; + +/** + * Packet parse parameters + */ +typedef struct odp_packet_parse_param_t { + /** Protocol header at parse starting point. Valid values for this + * field are: ODP_PROTO_ETH, ODP_PROTO_IPV4, ODP_PROTO_IPV6. */ + odp_proto_t proto; + + /** Continue parsing until this layer. Must be the same or higher + * layer than the layer of 'proto'. */ + odp_proto_layer_t last_layer; + + /** Flags to control payload data checksums checks up to the selected + * parse layer. Checksum checking status can be queried for each packet + * with odp_packet_l3_chksum_status() and + * odp_packet_l4_chksum_status(). + */ + odp_proto_chksums_t chksums; + +} odp_packet_parse_param_t; + +/** + * Packet parse results + */ +typedef struct odp_packet_parse_result_t { + /** Parse result flags */ + odp_packet_parse_result_flag_t flag; + + /** See odp_packet_len() */ + uint32_t packet_len; + + /** See odp_packet_l2_offset() */ + uint32_t l2_offset; + /** See odp_packet_l3_offset() */ + uint32_t l3_offset; + /** See odp_packet_l4_offset() */ + uint32_t l4_offset; + + /** See odp_packet_l3_chksum_status() */ + odp_packet_chksum_status_t l3_chksum_status; + /** See odp_packet_l4_chksum_status() */ + odp_packet_chksum_status_t l4_chksum_status; + + /** See odp_packet_l2_type() */ + odp_proto_l2_type_t l2_type; + /** See odp_packet_l3_type() */ + odp_proto_l3_type_t l3_type; + /** See odp_packet_l4_type() */ + odp_proto_l4_type_t l4_type; + +} odp_packet_parse_result_t; + +/** + * LSO options + */ +typedef struct odp_packet_lso_opt_t { + /** LSO profile handle + * + * The selected LSO profile specifies details of the segmentation operation to be done. + * Depending on LSO profile options, additional metadata (e.g. L3/L4 protocol header + * offsets) may need to be set on the packet. See LSO documentation + * (e.g. odp_pktout_send_lso() and odp_lso_protocol_t) for additional metadata + * requirements. + */ + odp_lso_profile_t lso_profile; + + /** LSO payload offset + * + * LSO operation considers packet data before 'payload_offset' as + * protocol headers and copies those in front of every created segment. It will modify + * protocol headers according to the LSO profile before segment transmission. + * + * When stored into a packet, this offset can be read with odp_packet_payload_offset() and + * modified with odp_packet_payload_offset_set(). + */ + uint32_t payload_offset; + + /** Maximum payload length in an LSO segment + * + * Max_payload_len parameter defines the maximum number of payload bytes in each + * created segment. Depending on the implementation, segments with less payload may be + * created. However, this value is used typically to divide packet payload evenly over + * all segments except the last one, which contains the remaining payload bytes. + */ + uint32_t max_payload_len; + +} odp_packet_lso_opt_t; + +/** + * Packet transmit completion mode + */ +typedef enum odp_packet_tx_compl_mode_t { + /** Disable packet transmit completion */ + ODP_PACKET_TX_COMPL_DISABLED = 0, + + /** + * Enable packet transmit completion event + * + * A packet transmit completion event is sent for both transmitted and dropped packets. + */ + ODP_PACKET_TX_COMPL_EVENT, + + /** + * Enable packet transmit completion check through polling + * + * Packet transmit completion status is updated for both transmitted and dropped packets. + */ + ODP_PACKET_TX_COMPL_POLL, + +} odp_packet_tx_compl_mode_t; + +/** + * For backwards compatibility, ODP_PACKET_TX_COMPL_ALL is synonym of ODP_PACKET_TX_COMPL_EVENT. + * + * @deprecated Use #ODP_PACKET_TX_COMPL_EVENT instead. + */ +#define ODP_PACKET_TX_COMPL_ALL ODP_PACKET_TX_COMPL_EVENT + +/** + * Packet transmit completion request options + */ +typedef struct odp_packet_tx_compl_opt_t { + /** + * Packet transmit completion mode + * + * When completion mode is #ODP_PACKET_TX_COMPL_DISABLED, all other fields of this struct + * are ignored. + */ + odp_packet_tx_compl_mode_t mode; + + /** Union of packet transmit completion destinations */ + union { + /** + * Destination queue + * + * When completion mode is #ODP_PACKET_TX_COMPL_EVENT, a packet transmit completion + * event will be sent to this queue. + */ + odp_queue_t queue; + + /** + * Completion identifier + * + * When completion mode is #ODP_PACKET_TX_COMPL_POLL, a packet transmit completion + * status will be reported through this completion identifier. Application selects + * a value between 0 and tx_compl.max_compl_id in packet IO configuration options + * (see odp_pktio_config_t). Only single packet may be transmitted with the same + * identifier value at a time (through the same packet IO interface). A value may + * be reused for the next transmit only after transmit of the previous packet is + * complete. Multiple packets may have the same identifier value set as long as + * those packets are not transmitted simultaneously. + */ + uint32_t compl_id; + }; + +} odp_packet_tx_compl_opt_t; + +/** + * Packet free control option + */ +typedef enum odp_packet_free_ctrl_t { + /** Packet free control disabled */ + ODP_PACKET_FREE_CTRL_DISABLED = 0, + + /** Don't free packet after processing it */ + ODP_PACKET_FREE_CTRL_DONT_FREE, + +} odp_packet_free_ctrl_t; + +/** + * Packet proto stats options + */ +typedef struct odp_packet_proto_stats_opt_t { + /** Packet proto stats object handle + * + * Stats in the packet proto stats object will be updated. + */ + odp_proto_stats_t stat; + + /** Octet counter 0 adjust */ + int32_t oct_count0_adj; + + /** Octet counter 1 adjust */ + int32_t oct_count1_adj; +} odp_packet_proto_stats_opt_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/pool.h b/include/odp/api/spec/pool.h index c0de195a7..1b71a5a09 100644 --- a/include/odp/api/spec/pool.h +++ b/include/odp/api/spec/pool.h @@ -1,18 +1,16 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2020-2023 Nokia */ - /** * @file * * ODP pool */ -#ifndef ODP_API_POOL_H_ -#define ODP_API_POOL_H_ +#ifndef ODP_API_SPEC_POOL_H_ +#define ODP_API_SPEC_POOL_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -20,130 +18,14 @@ extern "C" { #endif #include <odp/api/std_types.h> +#include <odp/api/pool_types.h> -/** @defgroup odp_pool ODP POOL - * Operations on a pool. +/** @addtogroup odp_pool + * Packet and buffer (event) pools. * @{ */ /** - * @typedef odp_pool_t - * ODP pool - */ - -/** - * @def ODP_POOL_INVALID - * Invalid pool - */ - -/** - * @def ODP_POOL_NAME_LEN - * Maximum pool name length in chars including null char - */ - -/** - * Pool capabilities - */ -typedef struct odp_pool_capability_t { - /** Maximum number of pools of any type */ - unsigned max_pools; - - /** Buffer pool capabilities */ - struct { - /** Maximum number of buffer pools */ - unsigned max_pools; - - /** Maximum buffer data alignment in bytes */ - uint32_t max_align; - - /** Maximum buffer data size in bytes - * - * The value of zero means that size is limited only by the - * available memory size for the pool. */ - uint32_t max_size; - - /** Maximum number of buffers of any size - * - * The value of zero means that limited only by the available - * memory size for the pool. */ - uint32_t max_num; - } buf; - - /** Packet pool capabilities */ - struct { - /** Maximum number of packet pools */ - unsigned max_pools; - - /** Maximum packet data length in bytes - * - * This defines the maximum packet data length that can be - * stored into a packet. Attempts to allocate or extend packets - * to sizes larger than this limit will fail. - * - * The value of zero means that limited only by the available - * memory size for the pool. */ - uint32_t max_len; - - /** Maximum number of packets of any length - * - * The value of zero means that limited only by the available - * memory size for the pool. */ - uint32_t max_num; - - /** Minimum packet level headroom length in bytes - * - * The minimum number of headroom bytes that newly created - * packets have by default. The default apply to both ODP - * packet input and user allocated packets.*/ - uint32_t min_headroom; - - /** Minimum packet level tailroom length in bytes - * - * The minimum number of tailroom bytes that newly created - * packets have by default. The default apply to both ODP - * packet input and user allocated packets.*/ - uint32_t min_tailroom; - - /** Maximum number of segments per packet */ - uint32_t max_segs_per_pkt; - - /** Minimum packet segment data length in bytes - * - * The user defined segment length (seg_len in - * odp_pool_param_t) will be rounded up into this value. */ - uint32_t min_seg_len; - - /** Maximum packet segment data length in bytes - * - * The user defined segment length (seg_len in odp_pool_param_t) - * must not be larger than this. - * - * The value of zero means that limited only by the available - * memory size for the pool. */ - uint32_t max_seg_len; - - /** Maximum user area size in bytes - * - * The value of zero means that limited only by the available - * memory size for the pool. */ - uint32_t max_uarea_size; - } pkt; - - /** Timeout pool capabilities */ - struct { - /** Maximum number of timeout pools */ - unsigned max_pools; - - /** Maximum number of timeout events in a pool - * - * The value of zero means that limited only by the available - * memory size for the pool. */ - uint32_t max_num; - } tmo; - -} odp_pool_capability_t; - -/** * Query pool capabilities * * Outputs pool capabilities on success. @@ -156,104 +38,35 @@ typedef struct odp_pool_capability_t { int odp_pool_capability(odp_pool_capability_t *capa); /** - * Pool parameters - * Used to communicate pool creation options. - * @note A single thread may not be able to allocate all 'num' elements - * from the pool at any particular time, as other threads or hardware - * blocks are allowed to keep some for caching purposes. - */ -typedef struct odp_pool_param_t { - /** Pool type */ - int type; - - union { - struct { - /** Number of buffers in the pool */ - uint32_t num; - - /** Buffer size in bytes. The maximum number of bytes - application will store in each buffer. */ - uint32_t size; - - /** Minimum buffer alignment in bytes. Valid values are - powers of two. Use 0 for default alignment. - Default will always be a multiple of 8. */ - uint32_t align; - } buf; - struct { - /** The number of packets that the pool must provide - that are packet length 'len' bytes or smaller. - The maximum value is defined by pool capability - pkt.max_num. */ - uint32_t num; - - /** Minimum packet length that the pool must provide - 'num' packets. The number of packets may be less - than 'num' when packets are larger than 'len'. - The maximum value is defined by pool capability - pkt.max_len. Use 0 for default. */ - uint32_t len; - - /** Maximum packet length that will be allocated from - the pool. The maximum value is defined by pool - capability pkt.max_len. Use 0 for default (the - pool maximum). */ - uint32_t max_len; - - /** Minimum number of packet data bytes that are stored - in the first segment of a packet. The maximum value - is defined by pool capability pkt.max_seg_len. - Use 0 for default. */ - uint32_t seg_len; - - /** User area size in bytes. The maximum value is - defined by pool capability pkt.max_uarea_size. - Specify as 0 if no user area is needed. */ - uint32_t uarea_size; - } pkt; - struct { - /** Number of timeouts in the pool */ - uint32_t num; - } tmo; - }; -} odp_pool_param_t; - -/** Packet pool*/ -#define ODP_POOL_PACKET ODP_EVENT_PACKET -/** Buffer pool */ -#define ODP_POOL_BUFFER ODP_EVENT_BUFFER -/** Timeout pool */ -#define ODP_POOL_TIMEOUT ODP_EVENT_TIMEOUT - -/** * Create a pool * * This routine is used to create a pool. The use of pool name is optional. * Unique names are not required. However, odp_pool_lookup() returns only a - * single matching pool. + * single matching pool. Use odp_pool_param_init() to initialize parameters + * into their default values. * * @param name Name of the pool or NULL. Maximum string length is * ODP_POOL_NAME_LEN. - * @param params Pool parameters. + * @param param Pool parameters. * * @return Handle of the created pool * @retval ODP_POOL_INVALID Pool could not be created */ - -odp_pool_t odp_pool_create(const char *name, odp_pool_param_t *params); +odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *param); /** * Destroy a pool previously created by odp_pool_create() * + * This routine destroys a previously created pool, and will destroy any + * internal shared memory objects associated with the pool. The pool must not + * be in use (in pktio, classifier, timer, etc.) when calling this function. + * Results are undefined if an attempt is made to destroy a pool that contains + * allocated or otherwise active buffers. + * * @param pool Handle of the pool to be destroyed * * @retval 0 Success * @retval -1 Failure - * - * @note This routine destroys a previously created pool, and will destroy any - * internal shared memory objects associated with the pool. Results are - * undefined if an attempt is made to destroy a pool that contains allocated - * or otherwise active buffers. */ int odp_pool_destroy(odp_pool_t pool); @@ -268,15 +81,6 @@ int odp_pool_destroy(odp_pool_t pool); odp_pool_t odp_pool_lookup(const char *name); /** - * Pool information struct - * Used to get information about a pool. - */ -typedef struct odp_pool_info_t { - const char *name; /**< pool name */ - odp_pool_param_t params; /**< pool parameters */ -} odp_pool_info_t; - -/** * Retrieve information about a pool * * @param pool Pool handle @@ -287,7 +91,6 @@ typedef struct odp_pool_info_t { * @retval 0 Success * @retval -1 Failure. Info could not be retrieved. */ - int odp_pool_info(odp_pool_t pool, odp_pool_info_t *info); /** @@ -301,6 +104,14 @@ int odp_pool_info(odp_pool_t pool, odp_pool_info_t *info); void odp_pool_print(odp_pool_t pool); /** + * Print debug info about all pools + * + * Print implementation defined information about all created pools to the ODP + * log. The information is intended to be used for debugging. + */ +void odp_pool_print_all(void); + +/** * Get printable value for an odp_pool_t * * @param hdl odp_pool_t handle to be printed @@ -323,6 +134,188 @@ uint64_t odp_pool_to_u64(odp_pool_t hdl); void odp_pool_param_init(odp_pool_param_t *param); /** + * Maximum pool index + * + * Return the maximum pool index. Pool indexes (e.g. returned by odp_pool_index()) + * range from zero to this maximum value. + * + * @return Maximum pool index + */ +unsigned int odp_pool_max_index(void); + +/** + * Get pool index + * + * @param pool Pool handle + * + * @return Pool index (0..odp_pool_max_index()) + * @retval <0 on failure + */ +int odp_pool_index(odp_pool_t pool); + +/** + * Read pool statistics + * + * Read statistics counters that were enabled in pool creation parameters (odp_pool_param_t.stats). + * The function writes all disabled counters to zero, except per thread counters + * (thread.cache_available[]) which have undefined values. + * + * When per thread counters are enabled, application sets 'stats.thread.first' and + * 'stats.thread.last' to select the threads ('first' <= 'last'). A single call may read statistics + * from one to #ODP_POOL_MAX_THREAD_STATS threads. Valid thread ID values range from 0 to + * odp_thread_count_max() - 1. A successful call fills the output array starting always from the + * first element 'stats.thread.cache_available[0]' (='stats.thread.first'). Unused array elements + * have undefined values. + * + * Depending on the implementation, there may be some delay until performed pool operations are + * visible in the statistics. + * + * @param pool Pool handle + * @param[in,out] stats Output buffer for counters + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_pool_stats(odp_pool_t pool, odp_pool_stats_t *stats); + +/** + * Get selected pool statistics + * + * Read the selected counters given in odp_pool_stats_opt_t bit field structure. Only counters + * included in odp_pool_stats_selected_t can be read and the selected counters must have been + * enabled during pool creation. Values of the unselected counters are undefined. Depending on the + * implementation, there may be some delay until performed pool operations are visible in the + * statistics. + * + * Depending on the implementation, this function may have higher performance compared to + * odp_pool_stats(), as only the selected set of counters is read. + * + * @param pool Pool handle + * @param[out] stats Output buffer for counters + * @param opt Bit field for selecting the counters to be read + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_pool_stats_selected(odp_pool_t pool, odp_pool_stats_selected_t *stats, + const odp_pool_stats_opt_t *opt); + +/** + * Reset statistics for pool + * + * Reset all statistics counters to zero except: odp_pool_stats_t::available, + * odp_pool_stats_t::cache_available, odp_pool_stats_t::thread::cache_available + * + * @param pool Pool handle + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_pool_stats_reset(odp_pool_t pool); + +/** + * Query capabilities of an external memory pool type + * + * Outputs pool capabilities on success. Returns failure if a bad pool type is used. When + * the requested pool type is valid but not supported, sets the value of 'max_pools' to zero. + * + * @param type Pool type + * @param[out] capa Pointer to capability structure for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_pool_ext_capability(odp_pool_type_t type, odp_pool_ext_capability_t *capa); + +/** + * Initialize pool params + * + * Initialize an odp_pool_ext_param_t to its default values for all fields + * based on the selected pool type. + * + * @param type Pool type + * @param param odp_pool_ext_param_t to be initialized + */ +void odp_pool_ext_param_init(odp_pool_type_t type, odp_pool_ext_param_t *param); + +/** + * Create an external memory pool + * + * This routine is used to create a pool. The use of pool name is optional. + * Unique names are not required. However, odp_pool_lookup() returns only a + * single matching pool. Use odp_pool_ext_param_init() to initialize parameters + * into their default values. + * + * @param name Name of the pool or NULL. Maximum string length is ODP_POOL_NAME_LEN. + * @param param Pool parameters + * + * @return Pool handle on success + * @retval ODP_POOL_INVALID on failure + */ +odp_pool_t odp_pool_ext_create(const char *name, const odp_pool_ext_param_t *param); + +/** + * Populate external memory pool with buffer memory + * + * Populate can be called multiple times to add memory buffers into the pool. Application must + * populate the pool with the exact number of buffers specified in pool parameters. The pool is + * ready to be used for allocations only after all populate calls have returned successfully. + * Application marks the last populate call with ODP_POOL_POPULATE_DONE flag. + * + * Depending on pool usage (and ODP implementation), the memory may need to be accessible by + * HW accelerators. Application may use e.g. odp_shm_reserve() with ODP_SHM_HW_ACCESS flag to + * ensure HW access. The memory area used for one pool, starting from (or before) the lowest + * addressed buffer and extending to the end (or after) of the highest addressed buffer, must not + * overlap with the memory area used for any other pool. Pool capabilities + * (odp_pool_ext_capability_t) specify the minimum alignment of the memory area. + * + * Pool type defines memory buffer layout and where the buffer pointer (buf[N]) points + * in the layout. Pool capabilities specify requirements for buffer size, layout and + * pointer alignment. + * + * For packet pools, packet buffer layout is shown below. The packet headroom (odp_packet_head()) + * starts immediately after the application header. For a segmented packet, each segment has this + * same layout. Buffer size includes all headers, headroom, data, tailroom and trailer. + * + * @code{.unparsed} + * + * +-------------------------------+ -- -- + * buf[N] ---> | | | | + * | ODP header (optional) | > odp_header_size | + * | | | | + * +-------------------------------+ -- | + * | | | | + * | Application header (optional) | > app_header_size | + * | | | > buf_size + * +-------------------------------+ -- | + * odp_packet_head()--> | | | + * | Packet data | | + * | (headroom, data, tailroom) | | + * | | | + * | | | + * +-------------------------------+ -- | + * | | | | + * | ODP trailer (optional) | > odp_trailer_size | + * | | | | + * +-------------------------------+ -- -- + * + * @endcode + * + * @param pool External memory pool + * @param buf Buffer pointers to be populated into the pool + * @param buf_size Buffer size + * @param num Number of buffer pointers + * @param flags 0: No flags + * ODP_POOL_POPULATE_DONE: Marks the last populate call and completes the pool + * population phase + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_pool_ext_populate(odp_pool_t pool, void *buf[], uint32_t buf_size, uint32_t num, + uint32_t flags); + +/** * @} */ diff --git a/include/odp/api/spec/pool_types.h b/include/odp/api/spec/pool_types.h new file mode 100644 index 000000000..cb3db4737 --- /dev/null +++ b/include/odp/api/spec/pool_types.h @@ -0,0 +1,944 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021-2023 Nokia + */ + +/** + * @file + * + * Type definitions for pools + */ + +#ifndef ODP_API_SPEC_POOL_TYPES_H_ +#define ODP_API_SPEC_POOL_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> +#include <odp/api/dma_types.h> +#include <odp/api/ml_types.h> + +/** @defgroup odp_pool ODP POOL + * @{ + */ + +/** + * @typedef odp_pool_t + * ODP pool + */ + +/** + * @def ODP_POOL_INVALID + * Invalid pool + */ + +/** + * @def ODP_POOL_NAME_LEN + * Maximum pool name length in chars including null char + */ + +/** + * @def ODP_POOL_MAX_THREAD_STATS + * Maximum number of per thread statistics a single odp_pool_stats() call can read + */ + +/** Maximum number of packet pool subparameters */ +#define ODP_POOL_MAX_SUBPARAMS 7 + +/** + * Pool statistics counters options + * + * Pool statistics counters listed in a bit field structure. + */ +typedef union odp_pool_stats_opt_t { + /** Option flags */ + struct { + /** See odp_pool_stats_t::available */ + uint64_t available : 1; + + /** See odp_pool_stats_t::alloc_ops */ + uint64_t alloc_ops : 1; + + /** See odp_pool_stats_t::alloc_fails */ + uint64_t alloc_fails : 1; + + /** See odp_pool_stats_t::free_ops */ + uint64_t free_ops : 1; + + /** See odp_pool_stats_t::total_ops */ + uint64_t total_ops : 1; + + /** See odp_pool_stats_t::cache_available */ + uint64_t cache_available : 1; + + /** See odp_pool_stats_t::cache_alloc_ops */ + uint64_t cache_alloc_ops : 1; + + /** See odp_pool_stats_t::cache_free_ops */ + uint64_t cache_free_ops : 1; + + /** See odp_pool_stats_t::thread::cache_available */ + uint64_t thread_cache_available : 1; + } bit; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or for bitwise + * operations over the entire structure. */ + uint64_t all; + +} odp_pool_stats_opt_t; + +/** + * Pool statistics counters + * + * In addition to API alloc and free calls, statistics counters may be updated + * by alloc/free operations from implementation internal software or hardware + * components. + */ +typedef struct odp_pool_stats_t { + /** The number of available events in the pool */ + uint64_t available; + + /** The number of alloc operations from the pool. Includes both + * successful and failed operations (pool empty). */ + uint64_t alloc_ops; + + /** The number of failed alloc operations (pool empty) */ + uint64_t alloc_fails; + + /** The number of free operations to the pool */ + uint64_t free_ops; + + /** The total number of alloc and free operations. Includes both + * successful and failed operations (pool empty). */ + uint64_t total_ops; + + /** The number of available events in the local caches of all threads */ + uint64_t cache_available; + + /** The number of successful alloc operations from pool caches (returned + * at least one event). */ + uint64_t cache_alloc_ops; + + /** The number of free operations, which stored events to pool caches. */ + uint64_t cache_free_ops; + + /** Per thread counters */ + struct { + /** First thread identifier to read counters from. Ignored when + * 'thread.cache_available' is not enabled. */ + uint16_t first; + + /** Last thread identifier to read counters from. Ignored when + * 'thread.cache_available' is not enabled. */ + uint16_t last; + + /** The number of available events in each thread local cache + * + * If 'first' and 'last' include all threads of the instance, + * the sum of 'thread.cache_available' matches + * 'cache_available'. */ + uint64_t cache_available[ODP_POOL_MAX_THREAD_STATS]; + } thread; + +} odp_pool_stats_t; + +/** + * Pool statistics counters + * + * Same as odp_pool_stats_t excluding per thread counters. + */ +typedef struct odp_pool_stats_selected_t { + /** See odp_pool_stats_t::available */ + uint64_t available; + + /** See odp_pool_stats_t::alloc_ops */ + uint64_t alloc_ops; + + /** See odp_pool_stats_t::alloc_fails */ + uint64_t alloc_fails; + + /** See odp_pool_stats_t::free_ops */ + uint64_t free_ops; + + /** See odp_pool_stats_t::total_ops */ + uint64_t total_ops; + + /** See odp_pool_stats_t::cache_available */ + uint64_t cache_available; + + /** See odp_pool_stats_t::cache_alloc_ops */ + uint64_t cache_alloc_ops; + + /** See odp_pool_stats_t::cache_free_ops */ + uint64_t cache_free_ops; + +} odp_pool_stats_selected_t; + +/** + * Pool capabilities + */ +typedef struct odp_pool_capability_t { + /** Maximum number of pools of any type (odp_pool_type_t) */ + uint32_t max_pools; + + /** Buffer pool capabilities */ + struct { + /** Maximum number of buffer pools */ + uint32_t max_pools; + + /** Maximum buffer data alignment in bytes */ + uint32_t max_align; + + /** Maximum buffer data size in bytes + * + * The value of zero means that size is limited only by the + * available memory size for the pool. */ + uint32_t max_size; + + /** Maximum number of buffers of any size + * + * The value of zero means that limited only by the available + * memory size for the pool. */ + uint32_t max_num; + + /** Maximum user area size in bytes */ + uint32_t max_uarea_size; + + /** Pool user area persistence + * + * When supported, implementation does not overwrite buffer user area + * content at any point of buffer lifetime nor after freeing a buffer + * back into pool. + * + * 0: User area content is maintained throughout regular buffer usage + * after allocation, but may be modified after free (default) + * 1: User area content is maintained throughout regular buffer usage + * and additionally also after buffer is freed into the pool (between + * buffer free and allocation) */ + odp_bool_t uarea_persistence; + + /** Minimum size of thread local cache */ + uint32_t min_cache_size; + + /** Maximum size of thread local cache */ + uint32_t max_cache_size; + + /** Supported statistics counters */ + odp_pool_stats_opt_t stats; + } buf; + + /** Packet pool capabilities */ + struct { + /** Maximum number of packet pools */ + uint32_t max_pools; + + /** Maximum packet data length in bytes + * + * This defines the maximum packet data length that can be + * stored into a packet. Attempts to allocate or extend packets + * to sizes larger than this limit will fail. + * + * The value of zero means that limited only by the available + * memory size for the pool. */ + uint32_t max_len; + + /** Maximum number of packets of any length + * + * The value of zero means that limited only by the available + * memory size for the pool. */ + uint32_t max_num; + + /** Maximum packet data alignment in bytes + * + * This is the maximum value of packet pool alignment + * (pkt.align) parameter. */ + uint32_t max_align; + + /** Minimum packet level headroom length in bytes + * + * The minimum number of headroom bytes that newly created + * packets have by default. The default apply to both ODP + * packet input and user allocated packets.*/ + uint32_t min_headroom; + + /** Maximum packet level headroom length in bytes + * + * The maximum value of packet pool headroom parameter + * that can be configured. This value applies to both ODP + * packet input and user allocated packets.*/ + uint32_t max_headroom; + + /** Minimum packet level tailroom length in bytes + * + * The minimum number of tailroom bytes that newly created + * packets have by default. The default apply to both ODP + * packet input and user allocated packets.*/ + uint32_t min_tailroom; + + /** Maximum number of segments per packet */ + uint32_t max_segs_per_pkt; + + /** Minimum packet segment data length in bytes + * + * The user defined segment length (seg_len in + * odp_pool_param_t) will be rounded up into this value. */ + uint32_t min_seg_len; + + /** Maximum packet segment data length in bytes + * + * The user defined segment length (seg_len in odp_pool_param_t) + * must not be larger than this. + * + * The value of zero means that limited only by the available + * memory size for the pool. */ + uint32_t max_seg_len; + + /** Maximum user area size in bytes */ + uint32_t max_uarea_size; + + /** Pool user area persistence + * + * See buf.uarea_persistence for details. */ + odp_bool_t uarea_persistence; + + /** Maximum number of subparameters + * + * Maximum number of packet pool subparameters. Valid range is + * 0 ... ODP_POOL_MAX_SUBPARAMS. */ + uint8_t max_num_subparam; + + /** Minimum size of thread local cache */ + uint32_t min_cache_size; + + /** Maximum size of thread local cache */ + uint32_t max_cache_size; + + /** Supported statistics counters */ + odp_pool_stats_opt_t stats; + } pkt; + + /** Timeout pool capabilities */ + struct { + /** Maximum number of timeout pools */ + uint32_t max_pools; + + /** Maximum number of timeout events in a pool + * + * The value of zero means that limited only by the available + * memory size for the pool. */ + uint32_t max_num; + + /** Maximum user area size in bytes */ + uint32_t max_uarea_size; + + /** Pool user area persistence + * + * See buf.uarea_persistence for details. */ + odp_bool_t uarea_persistence; + + /** Minimum size of thread local cache */ + uint32_t min_cache_size; + + /** Maximum size of thread local cache */ + uint32_t max_cache_size; + + /** Supported statistics counters */ + odp_pool_stats_opt_t stats; + } tmo; + + /** Vector pool capabilities */ + struct { + /** Maximum number of vector pools */ + uint32_t max_pools; + + /** Maximum number of vector events in a pool + * + * The value of zero means that limited only by the available + * memory size for the pool. */ + uint32_t max_num; + + /** Maximum number of handles (such as odp_packet_t) in a vector. */ + uint32_t max_size; + + /** Maximum user area size in bytes */ + uint32_t max_uarea_size; + + /** Pool user area persistence + * + * See buf.uarea_persistence for details. */ + odp_bool_t uarea_persistence; + + /** Minimum size of thread local cache */ + uint32_t min_cache_size; + + /** Maximum size of thread local cache */ + uint32_t max_cache_size; + + /** Supported statistics counters */ + odp_pool_stats_opt_t stats; + } vector; + +} odp_pool_capability_t; + +/** + * Packet pool subparameters + */ +typedef struct odp_pool_pkt_subparam_t { + /** Number of 'len' byte packets. */ + uint32_t num; + + /** Packet length in bytes */ + uint32_t len; + +} odp_pool_pkt_subparam_t; + +/** + * Pool types + */ +typedef enum odp_pool_type_t { + /** Packet pool*/ + ODP_POOL_PACKET = ODP_EVENT_PACKET, + + /** Buffer pool */ + ODP_POOL_BUFFER = ODP_EVENT_BUFFER, + + /** Timeout pool */ + ODP_POOL_TIMEOUT = ODP_EVENT_TIMEOUT, + + /** Vector event pool + * + * Each vector event holds an array of handles. All handles of a vector + * are the same type (such as odp_packet_t). + * @see ODP_EVENT_PACKET_VECTOR + */ + ODP_POOL_VECTOR, + + /** DMA completion event pool */ + ODP_POOL_DMA_COMPL, + + /** ML completion event pool */ + ODP_POOL_ML_COMPL + +} odp_pool_type_t; + +/** + * Pool parameters + */ +typedef struct odp_pool_param_t { + /** Pool type */ + odp_pool_type_t type; + + /** Parameters for buffer pools */ + struct { + /** Number of buffers in the pool */ + uint32_t num; + + /** Buffer size in bytes. The maximum number of bytes + * application will store in each buffer. + */ + uint32_t size; + + /** Minimum buffer alignment in bytes. Valid values are + * powers of two. Use 0 for default alignment. + * Default will always be a multiple of 8. + */ + uint32_t align; + + /** Minimum user area size in bytes. The maximum value is defined by + * pool capability buf.max_uarea_size. Specify as 0 if no user + * area is needed. The default value is 0. + */ + uint32_t uarea_size; + + /** Maximum number of buffers cached locally per thread + * + * A non-zero value allows implementation to cache buffers + * locally per each thread. Thread local caching may improve + * performance, but requires application to take account that + * some buffers may be stored locally per thread and thus are + * not available for allocation from other threads. + * + * This is the maximum number of buffers to be cached per + * thread. The actual cache size is implementation specific. + * The value must not be less than 'min_cache_size' or exceed + * 'max_cache_size' capability. The default value is + * implementation specific and set by odp_pool_param_init(). + */ + uint32_t cache_size; + } buf; + + /** Parameters for packet pools */ + struct { + /** Minimum number of 'len' byte packets. + * + * The pool must contain at least this many packets that are + * 'len' bytes or smaller. An implementation may round up the + * value, as long as the 'max_num' parameter below is not + * violated. The maximum value for this field is defined by + * pool capability pkt.max_num. + */ + uint32_t num; + + /** Maximum number of packets. + * + * This is the maximum number of packets of any length that can + * be allocated from the pool. The maximum value is defined by + * pool capability pkt.max_num. Use 0 when there's no + * requirement for the maximum number of packets. The default + * value is 0. + */ + uint32_t max_num; + + /** Minimum length of 'num' packets. + * + * The pool must contain at least 'num' packets up to this + * packet length (1 ... 'len' bytes). The maximum value for + * this field is defined by pool capability pkt.max_len. + * Use 0 for default. + */ + uint32_t len; + + /** Maximum packet length that will be allocated from + * the pool. The maximum value is defined by pool capability + * pkt.max_len. Use 0 for default. + */ + uint32_t max_len; + + /** Minimum packet data alignment in bytes. + * + * Valid values are powers of two. User allocated packets have + * start of data (see odp_packet_data()) aligned to this or + * a higher alignment (power of two value). This parameter + * does not apply to packets that ODP allocates internally + * (e.g. packets from packet input). + * + * The maximum value is defined by pool capability + * pkt.max_align. Use 0 for default alignment. + */ + uint32_t align; + + /** Minimum number of packet data bytes that can be stored in + * the first segment of a newly allocated packet (starting from + * odp_packet_data()). The maximum value is defined by + * pool capability pkt.max_seg_len. Use 0 for default. + */ + uint32_t seg_len; + + /** Minimum user area size in bytes. The maximum value is defined by + * pool capability pkt.max_uarea_size. Specify as 0 if no user + * area is needed. The default value is 0. + */ + uint32_t uarea_size; + + /** Minimum headroom size in bytes. Each newly allocated + * packet from the pool must have at least this much headroom. + * The maximum value is defined by pool capability + * pkt.max_headroom. Use zero if headroom is not needed. + */ + uint32_t headroom; + + /** Number of subparameters + * + * The number of subparameter table entries used. The maximum + * value is defined by pool capability pkt.max_num_subparam. + * The default value is 0. + */ + uint8_t num_subparam; + + /** Subparameter table + * + * Subparameters continue pool configuration with additional + * packet length requirements. The first table entry follows + * the num/len specification above. So that, sub[0].len > 'len' + * and sub[0].num refers to packet lengths between 'len' + 1 + * and sub[0].len. Similarly, sub[1] follows sub[0] + * specification, and so on. + * + * Each requirement is supported separately and may be rounded + * up, as long as the 'max_num' parameter is not violated. It's + * implementation specific if some requirements are supported + * simultaneously (e.g. due to subpool design). + */ + odp_pool_pkt_subparam_t sub[ODP_POOL_MAX_SUBPARAMS]; + + /** Maximum number of packets cached locally per thread + * + * See buf.cache_size documentation for details. + */ + uint32_t cache_size; + } pkt; + + /** Parameters for timeout pools */ + struct { + /** Number of timeouts in the pool */ + uint32_t num; + + /** Minimum user area size in bytes. The maximum value is defined by + * pool capability tmo.max_uarea_size. Specify as 0 if no user + * area is needed. The default value is 0. + */ + uint32_t uarea_size; + + /** Maximum number of timeouts cached locally per thread + * + * See buf.cache_size documentation for details. + */ + uint32_t cache_size; + } tmo; + + /** Parameters for vector pools */ + struct { + /** Number of vectors in the pool */ + uint32_t num; + + /** Maximum number of handles (such as odp_packet_t) in a vector. */ + uint32_t max_size; + + /** Minimum user area size in bytes. The maximum value is defined by + * pool capability vector.max_uarea_size. Specify as 0 if no user + * area is needed. The default value is 0. + */ + uint32_t uarea_size; + + /** Maximum number of vectors cached locally per thread + * + * See buf.cache_size documentation for details. + */ + uint32_t cache_size; + } vector; + + /** Parameters for user area initialization */ + struct { + /** User area initialization function + * + * Application defined user area initialization function to be + * called for each event of the pool during odp_pool_create(). Ignored + * if user area persistence is not supported + * (odp_pool_capability_t::uarea_persistence) or pool will not have any + * user area. The default value is NULL. + * + * @param uarea Pointer to the user area of an event + * @param size User area size + * @param args Pointer to application defined arguments + * @param index Index of the event (0..num events in pool - 1), not + * necessarily in order + */ + void (*init_fn)(void *uarea, uint32_t size, void *args, uint32_t index); + + /** Pointer to application defined arguments to be passed to every call + * of init_fn. The default value is NULL. + */ + void *args; + } uarea_init; + + /** + * Configure statistics counters + * + * An application can read the enabled statistics counters using + * odp_pool_stats(). For optimal performance an application should + * enable only the required counters. + */ + odp_pool_stats_opt_t stats; + +} odp_pool_param_t; + +/** + * External memory pool population done + * + * Application uses this flag to mark the last odp_pool_ext_populate() call, which completes + * external memory pool population phase. + */ +#define ODP_POOL_POPULATE_DONE 0x1 + +/** + * External memory pool capabilities + * + * Generic fields (not specific to a pool type) contain capabilities + * of the requested pool type. + */ +typedef struct odp_pool_ext_capability_t { + /** Requested pool type + * + * Pool type from the odp_pool_ext_capability() call is recorded here for reference. */ + odp_pool_type_t type; + + /** Maximum number of pools + * + * Maximum number of external memory pools of the requested type. */ + uint32_t max_pools; + + /** Minimum size of thread local cache */ + uint32_t min_cache_size; + + /** Maximum size of thread local cache */ + uint32_t max_cache_size; + + /** Supported statistics counters */ + odp_pool_stats_opt_t stats; + + /** Packet pool capabilities */ + struct { + /** Maximum number of packet buffers */ + uint32_t max_num_buf; + + /** Maximum packet buffer size in bytes */ + uint32_t max_buf_size; + + /** ODP header size in bytes + * + * Application must reserve this many bytes from the start of a packet buffer + * for ODP implementation usage. When the value is zero, ODP implementation does + * not need header space to be reserved for it. Application will not modify this + * memory area (after buffer populate call). + */ + uint32_t odp_header_size; + + /** ODP trailer size in bytes + * + * Application must reserve this many bytes from the end of a packet buffer + * for ODP implementation usage. When the value is zero, ODP implementation does + * not need trailer space to be reserved for it. Application will not modify this + * memory area (after buffer populate call). + */ + uint32_t odp_trailer_size; + + /** Minimum packet pool memory area alignment in bytes + * + * The memory area used for a packet pool, starting from (or before) the lowest + * addressed buffer and extending to the end (or after) of the highest addressed + * buffer, must have at least this (power of two) alignment. The value is 1 when + * there is no alignment requirement. + */ + uint32_t min_mem_align; + + /** Minimum packet buffer pointer alignment in bytes + * + * Packet buffer pointers populated into a pool must be evenly divisible with + * this value. The value is 1 when there is no alignment requirement. + */ + uint32_t min_buf_align; + + /** Minimum packet headroom alignment in bytes + * + * Packet buffers populated into a pool must have their headroom start address + * evenly divisible with this value. The value is 1 when there is no alignment + * requirement. + */ + uint32_t min_head_align; + + /** Packet buffer alignment flags + * + * These flags specify additional alignment requirements for packet buffers. + * If not stated otherwise, min_buf_align and min_head_align alignment + * requirements apply also. + */ + struct { + /** Packet buffers are size aligned + * + * When set, packet buffer pointers must be aligned to the buffer size. + * For example, if the buffer size would be 2304 bytes (0x900), + * each buffer start address must be a multiple of 0x900 + * (e.g. 0x12000900, 0x12001200, 0x12004800, etc). */ + uint16_t buf_size_aligned : 1; + + }; + + /** Maximum headroom parameter value + * + * The packet pool headroom parameter may not exceed this value. + */ + uint32_t max_headroom; + + /** Maximum headroom size in bytes + * + * Any newly allocated packet will have at most this much headroom. Application + * may use this to ensure that packet buffer size is large enough to fit both + * buffer headers, headroom and data. + */ + uint32_t max_headroom_size; + + /** Maximum number of segments per packet */ + uint32_t max_segs_per_pkt; + + /** Maximum user area size in bytes */ + uint32_t max_uarea_size; + + /** Pool user area persistence + * + * See buf.uarea_persistence of odp_pool_capability_t for details + * (odp_pool_capability_t::uarea_persistence). */ + odp_bool_t uarea_persistence; + + } pkt; + +} odp_pool_ext_capability_t; + +/** + * External memory pool parameters + */ +typedef struct odp_pool_ext_param_t { + /** Pool type */ + odp_pool_type_t type; + + /** Parameters for user area initialization */ + struct { + /** See uarea_init.init_fn of odp_pool_param_t for details + * (odp_pool_param_t::init_fn). However, note that with external memory + * pools, this function is called during memory population and not during + * pool creation (odp_pool_ext_populate()). Depending on the implementation, + * the function may be called each time pool is being populated with + * odp_pool_ext_populate() or during the last population call + * (odp_pool_ext_populate() with #ODP_POOL_POPULATE_DONE). */ + void (*init_fn)(void *uarea, uint32_t size, void *args, uint32_t index); + + /** See uarea_init.args of odp_pool_param_t for details + * (odp_pool_param_t::args). */ + void *args; + + } uarea_init; + + /** Maximum thread local cache size for the pool + * + * Valid value range is from min_cache_size to max_cache_size capability. + * The default value is implementation specific. See odp_pool_param_t (buf.cache_size) + * for more detailed documentation. + */ + uint32_t cache_size; + + /** + * Pool statistics configuration + * + * All pool statistics are disabled by default. For optimal performance, enable only those + * counters that are actually used. Counters may be read with odp_pool_stats(). + */ + odp_pool_stats_opt_t stats; + + /** Parameters for packet pools */ + struct { + /** Number of packet buffers + * + * The number of packet buffers application will populate into the pool. + * The maximum value is defined by pool capability pkt.max_num_buf. + */ + uint32_t num_buf; + + /** Packet buffer size + * + * Total buffer size in bytes including all headers, trailer, head-/tailroom + * and data. This is calculated from buffer start pointer to the end of buffer + * data area (including tailroom) or ODP trailer (see odp_trailer_size capability). + * All packet buffers application populates into the pool are of this size. + */ + uint32_t buf_size; + + /** Application header size + * + * Application reserves this many bytes for its own buffer header usage. + * The application header follows immediately the ODP buffer header + * (see odp_header_size capability). ODP implementation will not modify this + * memory area. The default value is 0. + */ + uint32_t app_header_size; + + /** User area size + * + * Per packet user area size in bytes. As with normal pools, user area location + * is ODP implementation specific. Use zero if no user area is needed. + * The maximum value is defined by pool capability pkt.max_uarea_size. + * The default value is 0. + */ + uint32_t uarea_size; + + /** Minimum headroom size + * + * Each newly allocated packet from the pool must have at least this much + * headroom in bytes. The configuration applies to both ODP packet input and + * application allocated packets. Use zero if headroom is not needed. The maximum + * value is defined by pool capability pkt.max_headroom. Implementation may + * round up the initial headroom size up to pool capability pkt.max_headroom_size. + */ + uint32_t headroom; + + } pkt; + +} odp_pool_ext_param_t; + +/** + * Pool information struct + * Used to get information about a pool. + */ +typedef struct odp_pool_info_t { + /** Pool type */ + odp_pool_type_t type; + + /** Pool name */ + const char *name; + + /** External memory pool + * + * 0: Pool is a normal pool + * 1: Pool is an external memory pool + */ + odp_bool_t pool_ext; + + /** Pool parameters union */ + union { + /** Copy of pool parameters. This is set when pool_ext is 0. */ + odp_pool_param_t params; + + /** Copy of external memory pool parameters. This is set when pool_ext is 1. */ + odp_pool_ext_param_t pool_ext_param; + + /** Copy of pool parameters when pool type is ODP_POOL_DMA_COMPL. */ + odp_dma_pool_param_t dma_pool_param; + + /** Copy of pool parameters when pool type is ODP_POOL_ML_COMPL. */ + odp_ml_compl_pool_param_t ml_pool_param; + }; + + /** Additional info for packet pools */ + struct { + /** Maximum number of packets of any length + * + * This is the maximum number of packets that can be allocated + * from the pool at anytime. Application can use this e.g. + * to prepare enough per packet contexts. + */ + uint32_t max_num; + + } pkt; + + /** Minimum data address. + * + * This is the minimum address that application accessible + * data of any object (event) allocated from the pool may + * locate. When there's no application accessible data + * (e.g. ODP_POOL_TIMEOUT pools), the value may be zero. + */ + uintptr_t min_data_addr; + + /** Maximum data address. + * + * This is the maximum address that application accessible + * data of any object (event) allocated from the pool may + * locate. When there's no application accessible data + * (e.g. ODP_POOL_TIMEOUT pools), the value may be zero. + */ + uintptr_t max_data_addr; + +} odp_pool_info_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/proto_stats.h b/include/odp/api/spec/proto_stats.h new file mode 100644 index 000000000..7dd57ac0f --- /dev/null +++ b/include/odp/api/spec/proto_stats.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Marvell + */ + +/** + * @file + * + * ODP Proto Stats + */ + +#ifndef ODP_API_SPEC_PROTO_STATS_H_ +#define ODP_API_SPEC_PROTO_STATS_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/proto_stats_types.h> + +/** @addtogroup odp_proto_stats + * Flow specific packet statistics. + * @{ + */ + +/** + * Initialize proto stats parameters + * + * Initialize an odp_proto_stats_param_t to its default values. + * By default all the statistics are disabled. + * + * @param param Proto stats parameter pointer. + */ +void odp_proto_stats_param_init(odp_proto_stats_param_t *param); + +/** + * Get proto stats capability + * + * Get supported protocol statistics and metadata for a PKTIO. + * + * @param pktio Packet IO handle + * @param[out] capa Pointer where capabilities are updated + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_proto_stats_capability(odp_pktio_t pktio, odp_proto_stats_capability_t *capa); + +/** + * Create a proto stats object + * + * Create a proto stats object with given name and parameters. + * A proto stats object can be created with any set of statistics but only the + * statistics that are supported by a PKTIO are updated in a proto stats object + * for that PKTIO associated packets. Same proto stats object can be used with + * any PKTIO. + * + * @param name Object name + * @param param Proto stats parameters + * + * @return Proto stats object handle + * @retval ODP_PROTO_STATS_INVALID on failure + */ +odp_proto_stats_t odp_proto_stats_create(const char *name, const odp_proto_stats_param_t *param); + +/** + * Lookup a proto stats object by name + * + * Lookup an already created proto stats object by name. + * + * @param name Proto stats object name + * + * @return Proto stats object handle + * @retval ODP_PROTO_STATS_INVALID on failure + */ +odp_proto_stats_t odp_proto_stats_lookup(const char *name); + +/** + * Destroy a proto stats object + * + * Destroy a proto stats object already created. + * + * Before destroying proto stats object having tx statistics enabled, + * for all PKTIO devices to which packets were Tx'ed earlier with + * this proto stats object, odp_pktio_stop() must be called. Additionally, + * existing packets that refer to the proto stats object being destroyed + * must not be sent at the same time as or after the proto stats object + * destruction. + * + * @param stat Proto stats handle + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_proto_stats_destroy(odp_proto_stats_t stat); + +/** + * Get all proto stats counters + * + * Get current values of all counters of the proto stats object. + * The values of counters that are not enabled in the proto stats object are undefined. + * + * @param stat Proto stats object handle + * @param[out] data Pointer to a caller allocated structure where the statistics will + * be written to. + * + * @retval =0 on success + * @retval <0 on failure + */ +int odp_proto_stats(odp_proto_stats_t stat, odp_proto_stats_data_t *data); + +/** + * Print proto stats object info to ODP log. + * + * Print implementation-defined proto stats debug information to ODP log. + * + * @param stat Proto stats object handle + */ +void odp_proto_stats_print(odp_proto_stats_t stat); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/proto_stats_types.h b/include/odp/api/spec/proto_stats_types.h new file mode 100644 index 000000000..4c08e60ab --- /dev/null +++ b/include/odp/api/spec/proto_stats_types.h @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Marvell + * Copyright (c) 2021 Nokia + */ + +/** + * @file + * + * ODP proto stats types + */ + +#ifndef ODP_API_SPEC_PROTO_STATS_TYPES_H_ +#define ODP_API_SPEC_PROTO_STATS_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +/** @defgroup odp_proto_stats ODP PROTO STATS + * @{ + */ + +/** + * @typedef odp_proto_stats_t + * ODP proto stats handle + */ + +/** + * @def ODP_PROTO_STATS_INVALID + * Invalid proto stats handle + */ + +/** ODP proto stats counters + * + * Statistics that can be enabled in proto stats object. For Tx stats counters, + * Pktout config `odp_pktout_config_opt_t::bit::proto_stats_ena` needs to be + * enabled. + * + * Tx packet and octet sent/drop statistics might include packets sent/dropped via + * Traffic Manager or Tx packet Aging or due to any other Tx errors. It is + * implementation specific as to what all Tx sent/drop events are accounted for. + */ +typedef union odp_proto_stats_counters_t { + /** Option flags */ + struct { + /** Tx packet sent count */ + uint64_t tx_pkts : 1; + + /** Tx packet drop count */ + uint64_t tx_pkt_drops : 1; + + /** Tx packet sent Octet counter 0 */ + uint64_t tx_oct_count0 : 1; + + /** Tx packet drop Octet counter 0 */ + uint64_t tx_oct_count0_drops : 1; + + /** Tx packet sent octet counter 1 */ + uint64_t tx_oct_count1 : 1; + + /** Tx packet drop octet counter 1 */ + uint64_t tx_oct_count1_drops : 1; + } bit; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or bitwise + * operations over the entire structure. + */ + uint64_t all_bits; +} odp_proto_stats_counters_t; + +/** ODP proto stats params */ +typedef struct odp_proto_stats_param_t { + /** Stats counters to enable */ + odp_proto_stats_counters_t counters; +} odp_proto_stats_param_t; + +/** + * Proto stats capabilities + */ +typedef struct odp_proto_stats_capability_t { + /** Tx capabilities */ + struct { + /** Stats counters supported */ + odp_proto_stats_counters_t counters; + + /** Packet adjust support for Octet counter 0 */ + odp_bool_t oct_count0_adj; + + /** Packet adjust support for Octet counter 1 */ + odp_bool_t oct_count1_adj; + } tx; +} odp_proto_stats_capability_t; + +/** ODP proto stats counters */ +typedef struct odp_proto_stats_data_t { + /** Packet sent count */ + uint64_t tx_pkts; + + /** Packet drop count */ + uint64_t tx_pkt_drops; + + /** Packet sent Octet counter 0 */ + uint64_t tx_oct_count0; + + /** Packet drop Octet counter 0 */ + uint64_t tx_oct_count0_drops; + + /** Packet sent octet counter 1 */ + uint64_t tx_oct_count1; + + /** Packet drop octet counter 1 */ + uint64_t tx_oct_count1_drops; +} odp_proto_stats_data_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/protocols.h b/include/odp/api/spec/protocols.h new file mode 100644 index 000000000..104002937 --- /dev/null +++ b/include/odp/api/spec/protocols.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2020 Marvell + */ + +/** + * @file + * + * ODP protocols + */ + +#ifndef ODP_API_SPEC_PROTOCOLS_H_ +#define ODP_API_SPEC_PROTOCOLS_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup odp_protocols ODP PROTOCOLS + * Network protocols + * @{ + */ + +/** IPv4 address size */ +#define ODP_IPV4_ADDR_SIZE 4 + +/** IPv6 address size */ +#define ODP_IPV6_ADDR_SIZE 16 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/queue.h b/include/odp/api/spec/queue.h index 7972feacb..9ce2ac73f 100644 --- a/include/odp/api/spec/queue.h +++ b/include/odp/api/spec/queue.h @@ -1,181 +1,39 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2023 Nokia */ - /** * @file * * ODP queue */ -#ifndef ODP_API_QUEUE_H_ -#define ODP_API_QUEUE_H_ +#ifndef ODP_API_SPEC_QUEUE_H_ +#define ODP_API_SPEC_QUEUE_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif -#include <odp/api/schedule_types.h> -#include <odp/api/event.h> +#include <odp/api/event_types.h> +#include <odp/api/queue_types.h> +#include <odp/api/std_types.h> -/** @defgroup odp_queue ODP QUEUE - * Macros and operation on a queue. +/** @addtogroup odp_queue + * Queues for event passing and scheduling. * @{ */ /** - * @typedef odp_queue_t - * ODP queue - */ - -/** - * @typedef odp_queue_group_t - * Queue group instance type - */ - -/** - * @def ODP_QUEUE_INVALID - * Invalid queue - */ - -/** - * @def ODP_QUEUE_NAME_LEN - * Maximum queue name length in chars including null char - */ - -/** - * Queue type - */ -typedef enum odp_queue_type_t { - /** Plain queue - * - * Plain queues offer simple FIFO storage of events. Application may - * dequeue directly from these queues. */ - ODP_QUEUE_TYPE_PLAIN = 0, - - /** Scheduled queue - * - * Scheduled queues are connected to the scheduler. Application must - * not dequeue events directly from these queues but use the scheduler - * instead. */ - ODP_QUEUE_TYPE_SCHED -} odp_queue_type_t; - -/** - * Queue operation mode - */ -typedef enum odp_queue_op_mode_t { - /** Multithread safe operation - * - * Queue operation (enqueue or dequeue) is multithread safe. Any - * number of application threads may perform the operation - * concurrently. */ - ODP_QUEUE_OP_MT = 0, - - /** Not multithread safe operation - * - * Queue operation (enqueue or dequeue) may not be multithread safe. - * Application ensures synchronization between threads so that - * simultaneously only single thread attempts the operation on - * the same queue. */ - ODP_QUEUE_OP_MT_UNSAFE, - - /** Disabled - * - * Direct enqueue or dequeue operation from application is disabled. - * An attempt to enqueue/dequeue directly will result undefined - * behaviour. Various ODP functions (e.g. packet input, timer, - * crypto, scheduler, etc) are able to perform enqueue or - * dequeue operations normally on the queue. - * */ - ODP_QUEUE_OP_DISABLED - -} odp_queue_op_mode_t; - -/** - * Queue capabilities - */ -typedef struct odp_queue_capability_t { - /** Maximum number of event queues */ - uint32_t max_queues; - - /** Maximum number of ordered locks per queue */ - unsigned max_ordered_locks; - - /** Maximum number of scheduling groups */ - unsigned max_sched_groups; - - /** Number of scheduling priorities */ - unsigned sched_prios; - -} odp_queue_capability_t; - -/** - * ODP Queue parameters - */ -typedef struct odp_queue_param_t { - /** Queue type - * - * Valid values for other parameters in this structure depend on - * the queue type. */ - odp_queue_type_t type; - - /** Enqueue mode - * - * Default value for both queue types is ODP_QUEUE_OP_MT. Application - * may enable performance optimizations by defining MT_UNSAFE or - * DISABLED modes when applicable. */ - odp_queue_op_mode_t enq_mode; - - /** Dequeue mode - * - * For PLAIN queues, the default value is ODP_QUEUE_OP_MT. Application - * may enable performance optimizations by defining MT_UNSAFE or - * DISABLED modes when applicable. However, when a plain queue is input - * to the implementation (e.g. a queue for packet output), the - * parameter is ignored in queue creation and the value is - * ODP_QUEUE_OP_DISABLED. - * - * For SCHED queues, the parameter is ignored in queue creation and - * the value is ODP_QUEUE_OP_DISABLED. */ - odp_queue_op_mode_t deq_mode; - - /** Scheduler parameters - * - * These parameters are considered only when queue type is - * ODP_QUEUE_TYPE_SCHED. */ - odp_schedule_param_t sched; - - /** Queue context pointer - * - * User defined context pointer associated with the queue. The same - * pointer can be accessed with odp_queue_context() and - * odp_queue_context_set() calls. The implementation may read the - * pointer for prefetching the context data. Default value of the - * pointer is NULL. */ - void *context; - - /** Queue context data length - * - * User defined context data length in bytes for prefetching. - * The implementation may use this value as a hint for the number of - * context data bytes to prefetch. Default value is zero (no hint). */ - uint32_t context_len; -} odp_queue_param_t; - -/** * Queue create * - * Create a queue according to the queue parameters. Queue type is specified by - * queue parameter 'type'. Use odp_queue_param_init() to initialize parameters - * into their default values. Default values are also used when 'param' pointer - * is NULL. The default queue type is ODP_QUEUE_TYPE_PLAIN. The use of queue - * name is optional. Unique names are not required. However, odp_queue_lookup() - * returns only a single matching queue. + * Create a queue according to the queue parameters. The use of queue name is + * optional. Unique names are not required. However, odp_queue_lookup() returns + * only a single matching queue. Use odp_queue_param_init() to initialize + * parameters into their default values. Default values are also used when + * 'param' pointer is NULL. * * @param name Name of the queue or NULL. Maximum string length is * ODP_QUEUE_NAME_LEN. @@ -187,12 +45,40 @@ typedef struct odp_queue_param_t { odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t *param); /** + * Create multiple queues + * + * Otherwise like odp_queue_create(), but creates multiple queues with a single + * call. The output queue handles are written in the same order as input + * parameters. A single odp_queue_create_multi() call is equivalent to calling + * odp_queue_create() 'num' times in row. + * + * If 'share_param' value is false, 'param' array must contain 'num' elements. + * If the value is true, only a single element is required and it's used as + * queue parameters for all created queues. If 'name' array is not NULL, the + * array must contain 'num' elements. + * + * @param name Array of queue name pointers or NULL. NULL is also + * valid queue name pointer value. + * @param param Array of queue parameters + * @param share_param If true, use same parameters ('param[0]') for all + * queues. + * @param[out] queue Array of queue handles for output + * @param num Number of queues to create + * + * @return Number of queues actually created (0 ... num) + * @retval <0 on failure + */ +int odp_queue_create_multi(const char *name[], const odp_queue_param_t param[], + odp_bool_t share_param, odp_queue_t queue[], + int num); + +/** * Destroy ODP queue * * Destroys ODP queue. The queue must be empty and detached from other - * ODP API (crypto, pktio, etc). Application must ensure that no other - * operations on this queue are invoked in parallel. Otherwise behavior - * is undefined. + * ODP API (crypto, pktio, classifier, timer, etc). Application must ensure + * that no other operations on this queue are invoked in parallel. Otherwise + * behavior is undefined. * * @param queue Queue handle * @@ -202,6 +88,20 @@ odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t *param); int odp_queue_destroy(odp_queue_t queue); /** + * Destroy multiple queues + * + * Otherwise like odp_queue_destroy(), but destroys multiple queues with a + * single call. + * + * @param queue Array of queue handles + * @param num Number of queues to destroy + * + * @retval Number of queues actually destroyed (1 ... num) + * @retval <0 on failure + */ +int odp_queue_destroy_multi(odp_queue_t queue[], int num); + +/** * Find a queue by name * * @param name Queue name @@ -242,18 +142,30 @@ int odp_queue_context_set(odp_queue_t queue, void *context, uint32_t len); /** * Get queue context * + * Returns previously stored queue context pointer. The context pointer may + * be set with odp_queue_context_set() or during queue creation + * (see odp_queue_param_t). The pointer value is set to NULL by default. + * * @param queue Queue handle * * @return pointer to the queue context * @retval NULL on failure + * + * @see odp_queue_context_set(), odp_queue_create() */ void *odp_queue_context(odp_queue_t queue); /** - * Queue enqueue + * Enqueue an event to a queue + * + * Enqueues the event into the queue. The caller loses ownership of the event on + * a successful call. The event is not enqueued on failure, and the caller + * maintains ownership of it. * - * Enqueue the 'ev' on 'queue'. On failure the event is not consumed, the caller - * has to take care of it. + * When successful, this function acts as a release memory barrier between + * the sender (the calling thread) and the receiver of the event. The receiver + * sees correctly the memory stores done by the sender before it enqueued + * the event. * * @param queue Queue handle * @param ev Event handle @@ -266,14 +178,15 @@ int odp_queue_enq(odp_queue_t queue, odp_event_t ev); /** * Enqueue multiple events to a queue * - * Enqueue the events from 'events[]' on 'queue'. A successful call returns the - * actual number of events enqueued. If return value is less than 'num', the - * remaining events at the end of events[] are not consumed, and the caller - * has to take care of them. + * Like odp_queue_enq(), but enqueues multiple events into the queue. Events are + * stored into the queue in the order they are in the array. A successful + * call returns the actual number of events enqueued. If return value is less + * than 'num', the remaining events at the end of events[] are not enqueued, + * and the caller maintains ownership of those. * * @param queue Queue handle - * @param[in] events Array of event handles - * @param num Number of event handles to enqueue + * @param events Array of event handles + * @param num Number of events to enqueue * * @return Number of events actually enqueued (0 ... num) * @retval <0 on failure @@ -281,27 +194,34 @@ int odp_queue_enq(odp_queue_t queue, odp_event_t ev); int odp_queue_enq_multi(odp_queue_t queue, const odp_event_t events[], int num); /** - * Queue dequeue + * Dequeue an event from a queue + * + * Returns the next event from head of the queue, or ODP_EVENT_INVALID when the + * queue is empty. Cannot be used for ODP_QUEUE_TYPE_SCHED type queues + * (use odp_schedule() instead). * - * Dequeues next event from head of the queue. Cannot be used for - * ODP_QUEUE_TYPE_SCHED type queues (use odp_schedule() instead). + * When successful, this function acts as an acquire memory barrier between + * the sender and the receiver (the calling thread) of the event. The receiver + * sees correctly the memory stores done by the sender before it enqueued + * the event. * * @param queue Queue handle * * @return Event handle - * @retval ODP_EVENT_INVALID on failure (e.g. queue empty) + * @retval ODP_EVENT_INVALID on failure, or when the queue is empty */ odp_event_t odp_queue_deq(odp_queue_t queue); /** * Dequeue multiple events from a queue * - * Dequeues multiple events from head of the queue. Cannot be used for - * ODP_QUEUE_TYPE_SCHED type queues (use odp_schedule() instead). + * Like odp_queue_deq(), but dequeues multiple events from head of the queue. + * Cannot be used for ODP_QUEUE_TYPE_SCHED type queues (use odp_schedule_multi() + * instead). A successful call returns the actual number of events dequeued. * - * @param queue Queue handle + * @param queue Queue handle * @param[out] events Array of event handles for output - * @param num Maximum number of events to dequeue + * @param num Maximum number of events to dequeue * @return Number of events actually dequeued (0 ... num) * @retval <0 on failure @@ -356,10 +276,11 @@ odp_schedule_group_t odp_queue_sched_group(odp_queue_t queue); * * @param queue Queue handle * - * @return Number of ordered locks associated with this ordered queue - * @retval <0 Specified queue is not ordered + * @return Number of ordered locks associated with this ordered queue + * @retval 0 Specified queue is not ordered or no ordered lock associated + * with the ordered queue. */ -int odp_queue_lock_count(odp_queue_t queue); +uint32_t odp_queue_lock_count(odp_queue_t queue); /** * Get printable value for an odp_queue_t @@ -386,15 +307,6 @@ uint64_t odp_queue_to_u64(odp_queue_t hdl); void odp_queue_param_init(odp_queue_param_t *param); /** - * Queue information - * Retrieve information about a queue with odp_queue_info() - */ -typedef struct odp_queue_info_t { - const char *name; /**< queue name */ - odp_queue_param_t param; /**< queue parameters */ -} odp_queue_info_t; - -/** * Retrieve information about a queue * * Invalid queue handles or handles to free/destroyed queues leads to @@ -409,6 +321,24 @@ typedef struct odp_queue_info_t { int odp_queue_info(odp_queue_t queue, odp_queue_info_t *info); /** + * Print queue info + * + * Print implementation defined information about the specified queue to the ODP + * log. The information is intended to be used for debugging. + * + * @param queue Queue handle + */ +void odp_queue_print(odp_queue_t queue); + +/** + * Print debug info about all queues + * + * Print implementation defined information about all created queues to the ODP + * log. The information is intended to be used for debugging. + */ +void odp_queue_print_all(void); + +/** * @} */ diff --git a/include/odp/api/spec/queue_types.h b/include/odp/api/spec/queue_types.h new file mode 100644 index 000000000..9edf7271d --- /dev/null +++ b/include/odp/api/spec/queue_types.h @@ -0,0 +1,314 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2018 Linaro Limited + */ + +/** + * @file + * + * ODP queue types + */ + +#ifndef ODP_API_SPEC_QUEUE_TYPES_H_ +#define ODP_API_SPEC_QUEUE_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/schedule_types.h> + +/** @defgroup odp_queue ODP QUEUE + * @{ + */ + +/** + * @typedef odp_queue_t + * ODP queue + */ + +/** + * @def ODP_QUEUE_INVALID + * Invalid queue + */ + +/** + * @def ODP_QUEUE_NAME_LEN + * Maximum queue name length in chars including null char + */ + +/** + * Queue type + */ +typedef enum odp_queue_type_t { + /** Plain queue + * + * Plain queues offer simple FIFO storage of events. Application may + * dequeue directly from these queues. */ + ODP_QUEUE_TYPE_PLAIN = 0, + + /** Scheduled queue + * + * Scheduled queues are connected to the scheduler. Application must + * not dequeue events directly from these queues but use the scheduler + * instead. */ + ODP_QUEUE_TYPE_SCHED +} odp_queue_type_t; + +/** + * Queue operation mode + */ +typedef enum odp_queue_op_mode_t { + /** Multithread safe operation + * + * Queue operation (enqueue or dequeue) is multithread safe. Any + * number of application threads may perform the operation + * concurrently. */ + ODP_QUEUE_OP_MT = 0, + + /** Not multithread safe operation + * + * Queue operation (enqueue or dequeue) may not be multithread safe. + * Application ensures synchronization between threads so that + * simultaneously only single thread attempts the operation on + * the same queue. */ + ODP_QUEUE_OP_MT_UNSAFE, + + /** Disabled + * + * Direct enqueue or dequeue operation from application is disabled. + * An attempt to enqueue/dequeue directly will result undefined + * behaviour. Various ODP functions (e.g. packet input, timer, + * crypto, scheduler, etc) are able to perform enqueue or + * dequeue operations normally on the queue. + * */ + ODP_QUEUE_OP_DISABLED + +} odp_queue_op_mode_t; + +/** + * Non-blocking level + * + * A non-blocking level defines implementation guarantees for application + * progress when multiple threads operate on the same resource (e.g. a queue) + * simultaneously. The first level (ODP_BLOCKING) does not have any block + * freedom guarantees, but a suspending thread may block the other threads for + * the entire time it remains suspended (infinitely if crashed). + * On the contrary, actual non-blocking levels provide guarantees of progress: + * + * ODP_NONBLOCKING_LF: A non-blocking and lock-free implementation guarantees + * that at least one of the threads successfully completes + * its operations, regardless of what other threads do. + * Application progress is guaranteed, but individual + * threads may starve while trying to execute their + * operations on the shared resource. + * + * ODP_NONBLOCKING_WF: A non-blocking and wait-free implementation guarantees + * application progress with starvation freedom. All + * threads are guaranteed to complete their operations in + * a bounded number of steps, regardless of what other + * threads do. + * + * Non-blocking levels are listed from the weakest to the strongest guarantee of + * block freedom. Performance of a non-blocking implementation may be lower than + * the blocking one. Non-blocking guarantees are important e.g. for real-time + * applications when real-time and non real-time threads share a resource. + */ +typedef enum odp_nonblocking_t { + /** Blocking implementation. A suspeding thread may block all other + * threads, i.e. no block freedom guarantees. This is the lowest level. + */ + ODP_BLOCKING = 0, + + /** Non-blocking and lock-free implementation. Other threads can make + * progress while a thread is suspended. Starvation freedom is not + * guaranteed. + */ + ODP_NONBLOCKING_LF, + + /** Non-blocking and wait-free implementation. Other threads can make + * progress while a thread is suspended. Starvation freedom is + * guaranteed. + */ + ODP_NONBLOCKING_WF + +} odp_nonblocking_t; + +/** + * Original event order maintenance options + * + * Options to keep or ignore the original event order of a source queue. This + * option is relevant for (plain or parallel scheduled) queues that are + * destinations for events enqueued while holding an ordered queue + * synchronization context. By default, an ordered context maintains original + * event order regardless of the destination queue type. Event re-ordering may + * cause extra synchronization effort for implementation and a long delay before + * application can receive a re-ordered event from the destination queue. This + * is wasteful and in some cases the extra delay is not acceptable for those + * destination queues that do not need to maintain the original event order. + * Application can use ODP_QUEUE_ORDER_IGNORE option to prevent implementation + * from performing unnecessary event re-ordering and negative side-effects of + * that. + */ +typedef enum odp_queue_order_t { + /** Keep original event order. Events enqueued into this queue while + * holding an ordered queue synchronization context maintain the + * original event order of the source queue. + */ + ODP_QUEUE_ORDER_KEEP = 0, + + /** Ignore original event order. Events enqueued into this queue do not + * need to maintain the original event order of the source queue. + * Implementation must avoid significant event re-ordering delays. + */ + ODP_QUEUE_ORDER_IGNORE + +} odp_queue_order_t; + +/** + * Queue capabilities + */ +typedef struct odp_queue_capability_t { + /** Maximum number of event queues of any type (default size). Use + * this in addition to queue type specific 'max_num', if both queue + * types are used simultaneously. */ + uint32_t max_queues; + + /** Plain queue capabilities */ + struct { + /** Maximum number of plain (ODP_BLOCKING) queues of the + * default size. */ + uint32_t max_num; + + /** Maximum number of events a plain (ODP_BLOCKING) queue can + * store simultaneously. The value of zero means that plain + * queues do not have a size limit, but a single queue can + * store all available events. */ + uint32_t max_size; + + /** Lock-free (ODP_NONBLOCKING_LF) implementation capabilities. + * The specification is the same as for the blocking + * implementation. */ + struct { + /** Maximum number of queues. Lock-free queues are not + * supported when zero. */ + uint32_t max_num; + + /** Maximum queue size. The value of zero means that + * there is no size limit. */ + uint32_t max_size; + + } lockfree; + + /** Wait-free (ODP_NONBLOCKING_WF) implementation capabilities. + * The specification is the same as for the blocking + * implementation. */ + struct { + /** Maximum number of queues. Wait-free queues are not + * supported when zero. */ + uint32_t max_num; + + /** Maximum queue size. The value of zero means that + * there is no size limit. */ + uint32_t max_size; + + } waitfree; + + } plain; + +} odp_queue_capability_t; + +/** + * ODP Queue parameters + */ +typedef struct odp_queue_param_t { + /** Queue type + * + * Valid values for other parameters in this structure depend on + * the queue type. The default value is ODP_QUEUE_TYPE_PLAIN. */ + odp_queue_type_t type; + + /** Enqueue mode + * + * Default value for both queue types is ODP_QUEUE_OP_MT. Application + * may enable performance optimizations by defining MT_UNSAFE or + * DISABLED modes when applicable. */ + odp_queue_op_mode_t enq_mode; + + /** Dequeue mode + * + * For PLAIN queues, the default value is ODP_QUEUE_OP_MT. Application + * may enable performance optimizations by defining MT_UNSAFE or + * DISABLED modes when applicable. However, when a plain queue is input + * to the implementation (e.g. a queue for packet output), the + * parameter is ignored in queue creation and the value is + * ODP_QUEUE_OP_DISABLED. + * + * For SCHED queues, the parameter is ignored in queue creation and + * the value is ODP_QUEUE_OP_DISABLED. */ + odp_queue_op_mode_t deq_mode; + + /** Scheduler parameters + * + * These parameters are considered only when queue type is + * ODP_QUEUE_TYPE_SCHED. */ + odp_schedule_param_t sched; + + /** Original event order maintenance + * + * Keep or ignore the original event order of a source queue. + * The default value is ODP_QUEUE_ORDER_KEEP. */ + odp_queue_order_t order; + + /** Non-blocking level + * + * Queue implementation must guarantee at least this level of block + * freedom for queue enqueue and dequeue/schedule operations. + * The default value is ODP_BLOCKING. */ + odp_nonblocking_t nonblocking; + + /** Queue context pointer + * + * User defined context pointer associated with the queue. The same + * pointer can be accessed with odp_queue_context() and + * odp_queue_context_set() calls. The implementation may read the + * pointer for prefetching the context data. Default value of the + * pointer is NULL. */ + void *context; + + /** Queue context data length + * + * User defined context data length in bytes for prefetching. + * The implementation may use this value as a hint for the number of + * context data bytes to prefetch. Default value is zero (no hint). */ + uint32_t context_len; + + /** Queue size + * + * The queue must be able to store at minimum this many events + * simultaneously. The value must not exceed 'max_size' queue + * capability. The value of zero means implementation specific + * default size. The default value is 0. */ + uint32_t size; + +} odp_queue_param_t; + +/** + * Queue information + * Retrieve information about a queue with odp_queue_info() + */ +typedef struct odp_queue_info_t { + const char *name; /**< queue name */ + odp_queue_param_t param; /**< queue parameters */ +} odp_queue_info_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/random.h b/include/odp/api/spec/random.h index 4765475c2..10f1026b3 100644 --- a/include/odp/api/spec/random.h +++ b/include/odp/api/spec/random.h @@ -1,49 +1,28 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited */ - /** * @file * * ODP random number API */ -#ifndef ODP_API_RANDOM_H_ -#define ODP_API_RANDOM_H_ +#ifndef ODP_API_SPEC_RANDOM_H_ +#define ODP_API_SPEC_RANDOM_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif -/** @defgroup odp_random ODP RANDOM - * @{ - */ +#include <odp/api/random_types.h> +#include <odp/api/std_types.h> -/** - * Random kind selector - * - * The kind of random denotes the statistical quality of the random data - * returned. Basic random simply appears uniformly distributed, Cryptographic - * random is statistically random and suitable for use by cryptographic - * functions. True random is generated from a hardware entropy source rather - * than an algorithm and is thus completely unpredictable. These form a - * hierarchy where higher quality data is presumably more costly to generate - * than lower quality data. +/** @addtogroup odp_random + * Random number generation. + * @{ */ -typedef enum { - /** Basic random, presumably pseudo-random generated by SW. This - * is the lowest kind of random */ - ODP_RANDOM_BASIC, - /** Cryptographic quality random */ - ODP_RANDOM_CRYPTO, - /** True random, generated from a HW entropy source. This is the - * highest kind of random */ - ODP_RANDOM_TRUE, -} odp_random_kind_t; /** * Query random max kind @@ -72,7 +51,7 @@ odp_random_kind_t odp_random_max_kind(void); * is expected to fail if the implementation is unable to * provide the requested type. * - * @return Number of bytes written + * @return Number of bytes written (0...len). * @retval <0 on failure */ int32_t odp_random_data(uint8_t *buf, uint32_t len, odp_random_kind_t kind); @@ -83,7 +62,7 @@ int32_t odp_random_data(uint8_t *buf, uint32_t len, odp_random_kind_t kind); * For testing purposes it is often useful to generate "random" sequences that * are repeatable. This is accomplished by supplying a seed value that is used * for pseudo-random data generation. The caller-provided seed value is - * updated for each call to continue the sequence. Restarting a series of + * updated for each call to continue the sequence. Restarting the same series of * calls with the same initial seed value will generate the same sequence of * random test data. * @@ -96,7 +75,7 @@ int32_t odp_random_data(uint8_t *buf, uint32_t len, odp_random_kind_t kind); * variable. Results are undefined if multiple threads * call this routine with the same seed variable. * - * @return Number of bytes written + * @return Number of bytes written (always len) * @retval <0 on failure */ int32_t odp_random_test_data(uint8_t *buf, uint32_t len, uint64_t *seed); diff --git a/include/odp/api/spec/random_types.h b/include/odp/api/spec/random_types.h new file mode 100644 index 000000000..5d5ee9450 --- /dev/null +++ b/include/odp/api/spec/random_types.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2022 Nokia + */ + +/** + * @file + * + * ODP random number API + */ + +#ifndef ODP_API_SPEC_RANDOM_TYPES_H_ +#define ODP_API_SPEC_RANDOM_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +/** @defgroup odp_random ODP RANDOM + * @{ + */ + +/** + * Random kind selector + * + * The kind of random denotes the statistical quality of the random data + * returned. Basic random simply appears uniformly distributed, Cryptographic + * random is statistically random and suitable for use by cryptographic + * functions. True random is generated from a hardware entropy source rather + * than an algorithm and is thus completely unpredictable. These form a + * hierarchy where higher quality data is presumably more costly to generate + * than lower quality data. + */ +typedef enum { + /** Basic random, presumably pseudo-random generated by SW. This + * is the lowest kind of random */ + ODP_RANDOM_BASIC, + /** Cryptographic quality random */ + ODP_RANDOM_CRYPTO, + /** True random, generated from a HW entropy source. This is the + * highest kind of random */ + ODP_RANDOM_TRUE, +} odp_random_kind_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/reassembly.h b/include/odp/api/spec/reassembly.h new file mode 100644 index 000000000..6f1b22390 --- /dev/null +++ b/include/odp/api/spec/reassembly.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Marvell + */ + +/** + * @file + * + * ODP REASSEMBLY API + */ + +#ifndef ODP_API_SPEC_REASSEMBLY_H_ +#define ODP_API_SPEC_REASSEMBLY_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +/** @defgroup odp_reassembly ODP REASSEMBLY + * Reassembly + * @{ + */ + +/** + * Reassembly capabilities + * + */ +typedef struct odp_reass_capability_t { + /** Reassembly offload for both IPv4 and IPv6 packets. This capability + * does not allow enabling reassembly for only IPv4 or only IPv6. + */ + odp_bool_t ip; + + /** Reassembly offload for IPv4 packets */ + odp_bool_t ipv4; + + /** Reassembly offload for IPv6 packets */ + odp_bool_t ipv6; + + /** Maximum time in ns that a fragment can wait in the reassembly + * offload for the arrival of further fragments. + */ + uint64_t max_wait_time; + + /** Maximum number of fragments that can be reassembled */ + uint16_t max_num_frags; + +} odp_reass_capability_t; + +/** + * Fragment reassembly configuration + * + * Configure inline fragment reassembly offload support. Fragment + * reassembly offload can be enabled in IPSEC and PKTIN operations. + * + * When the offload is enabled, fragments will be delayed for a specified time + * period to allow reassembly. + * + * Reassembly result will be delivered to the application through an ODP packet + * with reassembly metadata. odp_packet_reass_status() can be used to query if + * reassembly has been attempted and if reassembly was successfully completed. + * + * In case of successful reassembly, the reassembled packet is delivered + * to the receiver as a regular ODP packet as if the reassembled packet + * was received as such. When reassembly is enabled in pktio, it will be + * attempted before other offloads such as packet parsing, inline IPsec and + * classification. + * + * In case of failed reassembly, the result is delivered to the application + * as a special packet that does not contain valid packet data. Such a + * packet can be used to get information of the incomplete reassembly + * so that the application can try to retry or continue the reassembly. + * See odp_packet_reass_partial_state(). + * + * Reassembly may not complete if not all fragments were received in time but + * also for packet parsing difficulty, fragment overlap, resource shortage or + * other reasons. In such cases, application may receive packets with reassembly + * status as either ``ODP_PACKET_REASS_NONE`` or ``ODP_PACKET_REASS_INCOMPLETE``. + * + * This structure is used only for configuration, not for capability + * query even though it is indirectly contained in odp_pktio_capability_t. + * The content of odp_pktio_capability_t.config.reassembly written by + * odp_pktio_capability() is undefined. Reassembly capabilities of a pktio + * can be checked through odp_pktio_capability_t.reassembly. + * + * @see odp_packet_reass_status(), odp_packet_reass_partial_state() + */ +typedef struct odp_reass_config_t { + /** Attempt inline reassembly of IPv4 packets. Disabled by default. + * This may be set if the relevant odp_reass_capability_t::ipv4 + * capability is present or if odp_reass_capability_t::ip capability + * is present and en_ipv6 is also set. + */ + odp_bool_t en_ipv4; + + /** Attempt inline reassembly of IPv6 packets. Disabled by default. + * This may be set if the relevant odp_reass_capability_t::ipv6 + * capability is present or if odp_reass_capability_t::ip capability + * is present and en_ipv4 is also set. + */ + odp_bool_t en_ipv6; + + /** Maximum time in ns that a fragment may wait in the reassembly + * offload for the arrival of further fragments. The value may + * not exceed the max_wait_time capability. Zero value means + * implementation defined maximum wait time. + * + * Default value is 0. + */ + uint64_t max_wait_time; + + /** Maximum number of fragments that can be reassembled + * + * Minimum allowed value is 2. Default value is 2. + */ + uint16_t max_num_frags; +} odp_reass_config_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/rwlock.h b/include/odp/api/spec/rwlock.h index ff8a3f278..de749add8 100644 --- a/include/odp/api/spec/rwlock.h +++ b/include/odp/api/spec/rwlock.h @@ -1,11 +1,9 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited */ -#ifndef ODP_API_RWLOCK_H_ -#define ODP_API_RWLOCK_H_ +#ifndef ODP_API_SPEC_RWLOCK_H_ +#define ODP_API_SPEC_RWLOCK_H_ #include <odp/visibility_begin.h> /** @@ -20,6 +18,8 @@ extern "C" { /** * @defgroup odp_locks ODP LOCKS + * Various types of locks for thread synchronization. + * * @details * <b> Reader / writer lock (odp_rwlock_t) </b> * @@ -36,7 +36,6 @@ extern "C" { * ODP reader/writer lock */ - /** * Initialize a reader/writer lock. * diff --git a/include/odp/api/spec/rwlock_recursive.h b/include/odp/api/spec/rwlock_recursive.h index 1c19c7217..6b4afcbbe 100644 --- a/include/odp/api/spec/rwlock_recursive.h +++ b/include/odp/api/spec/rwlock_recursive.h @@ -1,7 +1,5 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited */ /** @@ -10,8 +8,8 @@ * ODP recursive read/write lock */ -#ifndef ODP_API_RWLOCK_RECURSIVE_H_ -#define ODP_API_RWLOCK_RECURSIVE_H_ +#ifndef ODP_API_SPEC_RWLOCK_RECURSIVE_H_ +#define ODP_API_SPEC_RWLOCK_RECURSIVE_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus diff --git a/include/odp/api/spec/schedule.h b/include/odp/api/spec/schedule.h index 8244746d7..7226c198b 100644 --- a/include/odp/api/spec/schedule.h +++ b/include/odp/api/spec/schedule.h @@ -1,18 +1,15 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited */ - /** * @file * * ODP schedule */ -#ifndef ODP_API_SCHEDULE_H_ -#define ODP_API_SCHEDULE_H_ +#ifndef ODP_API_SPEC_SCHEDULE_H_ +#define ODP_API_SPEC_SCHEDULE_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -20,52 +17,17 @@ extern "C" { #endif #include <odp/api/std_types.h> -#include <odp/api/event.h> -#include <odp/api/queue.h> +#include <odp/api/event_types.h> +#include <odp/api/queue_types.h> #include <odp/api/schedule_types.h> #include <odp/api/thrmask.h> -/** @defgroup odp_scheduler ODP SCHEDULER - * Operations on the scheduler. +/** @addtogroup odp_scheduler + * Event scheduler for work load balancing and prioritization. * @{ */ /** - * @def ODP_SCHED_WAIT - * Wait infinitely - */ - -/** - * @def ODP_SCHED_NO_WAIT - * Do not wait - */ - -/** - * @def ODP_SCHED_GROUP_NAME_LEN - * Maximum schedule group name length in chars including null char - */ - -/** - * @def ODP_SCHED_GROUP_INVALID - * Invalid scheduler group - */ - -/** - * @def ODP_SCHED_GROUP_ALL - * Predefined scheduler group of all threads - */ - -/** - * @def ODP_SCHED_GROUP_WORKER - * Predefined scheduler group of all worker threads - */ - -/** - * @def ODP_SCHED_GROUP_CONTROL - * Predefined scheduler group of all control threads - */ - -/** * Schedule wait time * * Converts nanoseconds to wait values for other schedule functions. @@ -77,20 +39,34 @@ extern "C" { uint64_t odp_schedule_wait_time(uint64_t ns); /** - * Schedule + * Schedule an event * - * Schedules all queues created with ODP_QUEUE_TYPE_SCHED type. Returns - * next highest priority event which is available for the calling thread. - * Outputs the source queue of the event. If there's no event available, waits + * Run event scheduler to find the next highest priority event which is + * available for the calling thread. Only queues that have been created with + * ODP_QUEUE_TYPE_SCHED type are connected to the scheduler. Optionally, + * outputs the source queue of the event. If there's no event available, waits * for an event according to the wait parameter setting. Returns * ODP_EVENT_INVALID if reaches end of the wait period. * * When returns an event, the thread holds the queue synchronization context - * (atomic or ordered) until the next odp_schedule() or odp_schedule_multi() - * call. The next call implicitly releases the current context and potentially - * returns with a new context. User can allow early context release (e.g., see - * odp_schedule_release_atomic() and odp_schedule_release_ordered()) for - * performance optimization. + * (atomic or ordered) until the next schedule call (e.g. odp_schedule() or + * odp_schedule_multi()). The next call implicitly releases the current context + * and potentially returns with a new context. User can allow early context + * release (e.g., see odp_schedule_release_atomic() and + * odp_schedule_release_ordered()) for performance optimization. + * + * When successful, this function acts as an acquire memory barrier between + * the sender and the receiver (the calling thread) of the event. The receiver + * sees correctly the memory stores done by the sender before it enqueued + * the event. + * + * When the event was scheduled from an atomic queue, this function acts as + * an acquire memory barrier between the previous holder of the same atomic + * synchronization context and the calling thread. When the context is released, + * a release memory barrier is performed towards the next holder of the context. + * This ensures that memory stores done when holding an atomic context are + * correctly visible to other threads that will subsequently hold the same + * atomic context. * * @param from Output parameter for the source queue (where the event was * dequeued from). Ignored if NULL. @@ -133,15 +109,58 @@ int odp_schedule_multi(odp_queue_t *from, uint64_t wait, odp_event_t events[], int num); /** + * Schedule, wait for events + * + * Like odp_schedule_multi(), but waits infinitely for events. + * + * @param[out] from Output parameter for the source queue (where the event + * was dequeued from). Ignored if NULL. + * @param[out] events Event array for output + * @param num Maximum number of events to output + * + * @return Number of events outputted (1 ... num) + */ +int odp_schedule_multi_wait(odp_queue_t *from, odp_event_t events[], int num); + +/** + * Schedule, do not wait for events + * + * Like odp_schedule_multi(), but does not wait for events. + * + * @param[out] from Output parameter for the source queue (where the event + * was dequeued from). Ignored if NULL. + * @param[out] events Event array for output + * @param num Maximum number of events to output + * + * @return Number of events outputted (0 ... num) + */ +int odp_schedule_multi_no_wait(odp_queue_t *from, odp_event_t events[], + int num); + +/** * Pause scheduling * - * Pause global scheduling for this thread. After this call, all schedule calls - * will return only locally pre-scheduled events (if any). User can exit the - * schedule loop only after the schedule function indicates that there's no more - * (pre-scheduled) events. + * Pause global scheduling for this thread. After this call, only + * ODP_SCHED_NO_WAIT schedule calls are allowed and these calls will return only + * locally pre-scheduled events (if any). User can exit the schedule loop only + * after the schedule function indicates that there's no more (pre-scheduled) + * events. + * + * Example call pattern: + * + * while (!stop) { + * odp_event_t ev = odp_schedule(NULL, ODP_SCHED_WAIT); + * // Process event + * } + * + * odp_schedule_pause(); * - * Must be used with odp_schedule() and odp_schedule_multi() before exiting (or - * stalling) the schedule loop. + * while (1) { + * odp_event_t ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT); + * if (ev == ODP_EVENT_INVALID) + * break; + * odp_event_free(ev); + * } */ void odp_schedule_pause(void); @@ -201,22 +220,113 @@ void odp_schedule_release_ordered(void); void odp_schedule_prefetch(int num); /** + * Maximum scheduling priority level + * + * This is the maximum value that can be set to 'prio' field in + * odp_schedule_param_t (e.g. odp_queue_create()). Queues with a higher + * priority value are served with higher priority than queues with a lower + * priority value. + * + * @return Maximum scheduling priority level + */ +int odp_schedule_max_prio(void); + +/** + * Minimum scheduling priority level + * + * This is the minimum value that can be set to 'prio' field in + * odp_schedule_param_t (e.g. odp_queue_create()). Queues with a higher + * priority value are served with higher priority than queues with a lower + * priority value. + * + * @return Minimum scheduling priority level + */ +int odp_schedule_min_prio(void); + +/** + * Default scheduling priority level + * + * This is the default value of 'prio' field in odp_schedule_param_t + * (e.g. odp_queue_param_init()). The default value should be suitable for + * an application that uses single priority level for all its queues (uses + * scheduler only for load balancing and synchronization). Typically, + * the default value is between minimum and maximum values, but with a few + * priority levels it may be close or equal to those. + * + * @return Default scheduling priority level + */ +int odp_schedule_default_prio(void); + +/** * Number of scheduling priorities * + * The number of priority levels support by the scheduler. It equals to + * odp_schedule_max_prio() - odp_schedule_min_prio() + 1. + * * @return Number of scheduling priorities */ int odp_schedule_num_prio(void); /** + * Initialize schedule configuration options + * + * Initialize an odp_schedule_config_t to its default values. + * + * @param[out] config Pointer to schedule configuration structure + */ +void odp_schedule_config_init(odp_schedule_config_t *config); + +/** + * Global schedule configuration + * + * Initialize and configure scheduler with global configuration options + * to schedule events across different scheduled queues. + * This function must be called only once and before scheduler is used + * (any other scheduler function is called except odp_schedule_capability() and + * odp_schedule_config_init()) or any queues are created (by application itself + * or by other ODP modules). + * An application can pass NULL value to use default configuration. It will + * have the same result as filling the structure with + * odp_schedule_config_init() and then passing it to odp_schedule_config(). + * + * The initialization sequeunce should be, + * odp_schedule_capability() + * odp_schedule_config_init() + * odp_schedule_config() + * odp_schedule() + * + * @param config Pointer to scheduler configuration structure or NULL for the + * default configuration + * + * @retval 0 on success + * @retval <0 on failure + * + * @see odp_schedule_capability(), odp_schedule_config_init() + */ +int odp_schedule_config(const odp_schedule_config_t *config); + +/** + * Query scheduler capabilities + * + * Outputs schedule capabilities on success. + * + * @param[out] capa Pointer to capability structure for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_schedule_capability(odp_schedule_capability_t *capa); + +/** * Schedule group create * * Creates a schedule group with the thread mask. Only threads in the * mask will receive events from a queue that belongs to the schedule group. * Thread masks of various schedule groups may overlap. There are predefined - * groups such as ODP_SCHED_GROUP_ALL and ODP_SCHED_GROUP_WORKER, which are - * always present and automatically updated. The use of group name is optional. - * Unique names are not required. However, odp_schedule_group_lookup() returns - * only a single matching group. + * groups, such as ODP_SCHED_GROUP_ALL and ODP_SCHED_GROUP_WORKER, which are + * present by default and are automatically updated. The use of group name is + * optional. Unique names are not required. However, odp_schedule_group_lookup() + * returns only a single matching group. * * @param name Name of the schedule group or NULL. Maximum string length is * ODP_SCHED_GROUP_NAME_LEN. @@ -300,14 +410,6 @@ int odp_schedule_group_thrmask(odp_schedule_group_t group, odp_thrmask_t *thrmask); /** - * Schedule group information - */ -typedef struct odp_schedule_group_info_t { - const char *name; /**< Schedule group name */ - odp_thrmask_t thrmask; /**< Thread mask of the schedule group */ -} odp_schedule_group_info_t; - -/** * Retrieve information about a schedule group * * Fills in schedule group information structure with current values. @@ -347,12 +449,15 @@ int odp_schedule_group_info(odp_schedule_group_t group, * be protected by its own ordered lock. This promotes maximum parallelism by * allowing order to maintained on a more granular basis. If an ordered lock * is used multiple times in the same ordered context results are undefined. + * Only one ordered lock can be active in an ordered context at any given time. + * Results are undefined when multiple ordered locks are acquired in nested + * fashion within the same ordered context. * * @param lock_index Index of the ordered lock in the current context to be * acquired. Must be in the range 0..odp_queue_lock_count() * - 1 */ -void odp_schedule_order_lock(unsigned lock_index); +void odp_schedule_order_lock(uint32_t lock_index); /** * Release ordered context lock @@ -365,7 +470,80 @@ void odp_schedule_order_lock(unsigned lock_index); * hold this lock. Must be in the range * 0..odp_queue_lock_count() - 1 */ -void odp_schedule_order_unlock(unsigned lock_index); +void odp_schedule_order_unlock(uint32_t lock_index); + +/** + * Release existing ordered context lock and acquire a new lock + * + * This call is valid only when holding an ordered synchronization context. + * Release a previously locked ordered context lock and acquire a new ordered + * context lock. The operation is equivalent to application calling first + * odp_schedule_order_unlock(unlock_index) and then + * odp_schedule_order_lock(lock_index). The same constraints apply with this + * call as with those two. + * + * @param unlock_index Index of the acquired ordered lock in the current + * context to be released. + * @param lock_index Index of the ordered lock in the current context to be + * acquired. Must be in the range + * 0...odp_queue_lock_count() - 1. + * + * @see odp_schedule_order_lock(), odp_schedule_order_unlock() + * + */ +void odp_schedule_order_unlock_lock(uint32_t unlock_index, uint32_t lock_index); + +/** Asynchronous ordered context lock + * Request an ordered context lock to be acquired. Starts an ordered context + * lock acquire operation, but does not wait until the lock has been acquired. + * Application can use this call to potentially interleave some processing + * within waiting for this lock. Each start lock call must be paired with a wait + * call that blocks until the lock has been acquired. Locks cannot be acquired + * in nested fashion i.e each start call must follow a paring wait and unlock + * calls, before using another lock. + * The same constraints apply as with odp_schedule_order_lock() + * + * @param lock_index Index of the ordered lock in the current context to + * start acquire operation. + * Must be in the range 0..odp_queue_lock_count() - 1. + * + */ +void odp_schedule_order_lock_start(uint32_t lock_index); + +/** Asynchronous ordered context lock wait + * Wait for a previously started lock acquire operation to finish. + * Lock index must match with the previous start call. Ordered lock acquisition + * will be completed during this call. + * + * @param lock_index Index of the ordered lock in the current context to + * complete acquire operation. + * Must be in the range 0..odp_queue_lock_count() - 1. + */ +void odp_schedule_order_lock_wait(uint32_t lock_index); + +/** + * Wait until the currently held scheduling context is the first in order + * + * Wait until there are no other scheduling contexts that precede the + * scheduling context of the calling thread in the source queue order. + * The context remains the first in order until the thread releases it. + * + * This function must not be called if the current thread is not holding + * an ordered scheduling context or if an ordered lock is being held. + * + * This functions does nothing if ordered wait is not supported. + * + * @see odp_schedule_capability() + */ +void odp_schedule_order_wait(void); + +/** + * Print debug info about scheduler + * + * Print implementation defined information about scheduler to the ODP log. + * The information is intended to be used for debugging. + */ +void odp_schedule_print(void); /** * @} diff --git a/include/odp/api/spec/schedule_types.h b/include/odp/api/spec/schedule_types.h index 8a4e42c64..30cb939dc 100644 --- a/include/odp/api/spec/schedule_types.h +++ b/include/odp/api/spec/schedule_types.h @@ -1,7 +1,6 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2023 Nokia */ /** @@ -10,43 +9,34 @@ * ODP schedule types */ -#ifndef ODP_API_SCHEDULE_TYPES_H_ -#define ODP_API_SCHEDULE_TYPES_H_ +#ifndef ODP_API_SPEC_SCHEDULE_TYPES_H_ +#define ODP_API_SPEC_SCHEDULE_TYPES_H_ #include <odp/visibility_begin.h> +#include <odp/api/std_types.h> +#include <odp/api/thrmask.h> + #ifdef __cplusplus extern "C" { #endif -/** @addtogroup odp_scheduler +/** @defgroup odp_scheduler ODP SCHEDULER * @{ */ /** - * @typedef odp_schedule_prio_t - * Scheduler priority level - */ - -/** - * @def ODP_SCHED_PRIO_HIGHEST - * Highest scheduling priority - */ - -/** - * @def ODP_SCHED_PRIO_NORMAL - * Normal scheduling priority + * @def ODP_SCHED_WAIT + * Wait infinitely */ /** - * @def ODP_SCHED_PRIO_LOWEST - * Lowest scheduling priority + * @def ODP_SCHED_NO_WAIT + * Do not wait */ /** - * @def ODP_SCHED_PRIO_DEFAULT - * Default scheduling priority. User does not care about the selected priority - * level - throughput, load balancing and synchronization features are more - * important than priority scheduling. + * @def ODP_SCHED_GROUP_NAME_LEN + * Maximum schedule group name length in chars including null char */ /** @@ -78,7 +68,13 @@ extern "C" { * The atomic queue synchronization context is dedicated to the thread until it * requests another event from the scheduler, which implicitly releases the * context. User may allow the scheduler to release the context earlier than - * that by calling odp_schedule_release_atomic(). + * that by calling odp_schedule_release_atomic(). However, this call is just + * a hint to the implementation and the context may be held until the next + * schedule call. + * + * When scheduler is enabled as flow-aware, the event flow id value affects + * scheduling of the event and synchronization is maintained per flow within + * each queue. */ /** @@ -90,21 +86,53 @@ extern "C" { * enables the user to achieve high single flow throughput by avoiding * SW synchronization for ordering between threads. * - * The source queue (dequeue) ordering is maintained when - * events are enqueued to their destination queue(s) within the same ordered - * queue synchronization context. A thread holds the context until it - * requests another event from the scheduler, which implicitly releases the - * context. User may allow the scheduler to release the context earlier than - * that by calling odp_schedule_release_ordered(). + * When odp_schedule() returns an event, the calling thread is associated + * with an ordered scheduling synchronization context. The contexts arising + * from the same ordered queue have the same mutual ordering as the + * corresponding events had in the queue. + * + * When odp_schedule_multi() returns more than one event from an ordered + * queue, the events returned were consecutive in the queue and the calling + * thread is associated with single ordered scheduling synchronization + * context that is ordered with respect to other contexts as if just the + * first event was returned. + * + * When threads holding ordered scheduling synchronization contexts, which + * arise from the same ordered queue, enqueue events to destination queues, + * the order of events in each destination queue will be as follows: + * + * - Events enqueued by one thread have the order in which the enqueue + * calls were made. * - * Events from the same (source) queue appear in their original order - * when dequeued from a destination queue. The destination queue can have any - * queue type and synchronization method. Event ordering is based on the - * received event(s), but also other (newly allocated or stored) events are - * ordered when enqueued within the same ordered context. Events not enqueued - * (e.g. freed or stored) within the context are considered missing from - * reordering and are skipped at this time (but can be ordered again within - * another context). + * - Two events enqueued by different threads have the same mutual order + * as the scheduling synchronization contexts of the enqueuing threads. + * + * The ordering rules above apply to all events, not just those that were + * scheduled from the ordered queue. For instance, newly allocated events + * and previously stored events are ordered in the destination queue based + * on the scheduling synchronization context. The ordering rules apply + * regarless of the type (scheduled or plain) or schedule type (atomic, + * ordered, or parallel) of the destination queue. If the order type of + * the destination queue is ODP_QUEUE_ORDER_IGNORE, then the order between + * events enqueued by different threads is not guaranteed. + * + * An ordered scheduling synchronization context is implicitly released when + * the thread holding the context requests a new event from the scheduler. + * User may allow the scheduler to release the context earlier than that by + * calling odp_schedule_release_ordered(). However, this call is just a hint + * to the implementation and the context may be held until the next schedule + * call. + * + * Enqueue calls by different threads may return in a different order than + * the final order of the enqueued events in the destination queue. + * + * Unnecessary event re-ordering may be avoided for those destination queues + * that do not need to maintain the specified event order by setting 'order' + * queue parameter to ODP_QUEUE_ORDER_IGNORE. + * + * When scheduler is enabled as flow-aware, the event flow id value affects + * scheduling of the event and synchronization is maintained and order is + * defined per flow within each queue. */ /** @@ -113,6 +141,11 @@ extern "C" { */ /** + * @def ODP_SCHED_GROUP_INVALID + * Invalid scheduler group + */ + +/** * @def ODP_SCHED_GROUP_ALL * Group of all threads. All active worker and control threads belong to this * group. The group is automatically updated when new threads enter or old @@ -126,11 +159,25 @@ extern "C" { * old threads exit ODP. */ +/** + * @def ODP_SCHED_GROUP_CONTROL + * Predefined scheduler group of all control threads + */ + +/** + * Scheduling priority level + * + * Priority level is an integer value between odp_schedule_min_prio() and + * odp_schedule_max_prio(). Queues with a higher priority value are served with + * higher priority than queues with a lower priority value. + */ +typedef int odp_schedule_prio_t; + /** Scheduler parameters */ typedef struct odp_schedule_param_t { /** Priority level * - * Default value is ODP_SCHED_PRIO_DEFAULT. */ + * Default value is returned by odp_schedule_default_prio(). */ odp_schedule_prio_t prio; /** Synchronization method @@ -146,10 +193,129 @@ typedef struct odp_schedule_param_t { /** Ordered lock count for this queue * * Default value is 0. */ - unsigned lock_count; + uint32_t lock_count; } odp_schedule_param_t; /** + * Scheduler capabilities + */ +typedef struct odp_schedule_capability_t { + /** Maximum number of ordered locks per queue */ + uint32_t max_ordered_locks; + + /** Maximum number of scheduling groups. The value includes the enabled + * predefined scheduling groups (ODP_SCHED_GROUP_ALL, + * ODP_SCHED_GROUP_WORKER, and ODP_SCHED_GROUP_CONTROL). By default, an + * application can create 'max_groups' - 3 groups. */ + uint32_t max_groups; + + /** Number of scheduling priorities */ + uint32_t max_prios; + + /** Maximum number of scheduled (ODP_BLOCKING) queues of the default + * size. */ + uint32_t max_queues; + + /** Maximum number of events a scheduled (ODP_BLOCKING) queue can store + * simultaneously. The value of zero means that scheduled queues do not + * have a size limit, but a single queue can store all available + * events. */ + uint32_t max_queue_size; + + /** Maximum flow ID per queue + * + * Valid flow ID range in flow aware mode of scheduling is from 0 to + * this maximum value. So, maximum number of flows per queue is this + * value plus one. A value of 0 indicates that flow aware mode is not + * supported. */ + uint32_t max_flow_id; + + /** Lock-free (ODP_NONBLOCKING_LF) queues support. + * The specification is the same as for the blocking implementation. */ + odp_support_t lockfree_queues; + + /** Wait-free (ODP_NONBLOCKING_WF) queues support. + * The specification is the same as for the blocking implementation. */ + odp_support_t waitfree_queues; + + /** Order wait support. If not supported, odp_schedule_order_wait() + * does nothing. */ + odp_support_t order_wait; + +} odp_schedule_capability_t; + +/** + * Schedule configuration + */ +typedef struct odp_schedule_config_t { + /** Maximum number of scheduled queues to be supported. + * + * @see odp_schedule_capability_t + */ + uint32_t num_queues; + + /** Maximum number of events required to be stored simultaneously in + * scheduled queue. This number must not exceed 'max_queue_size' + * capability. A value of 0 configures default queue size supported by + * the implementation. + */ + uint32_t queue_size; + + /** Maximum flow ID per queue + * + * This value must not exceed 'max_flow_id' capability. Flow aware + * mode of scheduling is enabled when the value is greater than 0. + * The default value is 0. + * + * Application can assign events to specific flows by calling + * odp_event_flow_id_set() before enqueuing events into a scheduled + * queue. When in flow aware mode, the event flow id value affects + * scheduling of the event and synchronization is maintained per flow + * within each queue. + * + * Depending on the implementation, there may be much more flows + * supported than queues, as flows are lightweight entities. + * + * @see odp_schedule_capability_t, odp_event_flow_id() + */ + uint32_t max_flow_id; + + /** Enable/disable predefined scheduling groups */ + struct { + /** ODP_SCHED_GROUP_ALL + * + * 0: Disable group + * 1: Enable group (default) + */ + odp_bool_t all; + + /** ODP_SCHED_GROUP_CONTROL + * + * 0: Disable group + * 1: Enable group (default) + */ + odp_bool_t control; + + /** ODP_SCHED_GROUP_WORKER + * + * 0: Disable group + * 1: Enable group (default) + */ + odp_bool_t worker; + + } sched_group; + +} odp_schedule_config_t; + +/** + * Schedule group information + */ +typedef struct odp_schedule_group_info_t { + const char *name; /**< Schedule group name */ + odp_thrmask_t thrmask; /**< Thread mask of the schedule group */ +} odp_schedule_group_info_t; + +/** * @} */ diff --git a/include/odp/api/spec/shared_memory.h b/include/odp/api/spec/shared_memory.h index 1a9c1299e..3845f6e4d 100644 --- a/include/odp/api/spec/shared_memory.h +++ b/include/odp/api/spec/shared_memory.h @@ -1,18 +1,16 @@ -/* Copyright (c) 2013-2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2019-2021 Nokia */ - /** * @file * * ODP shared memory */ -#ifndef ODP_API_SHARED_MEMORY_H_ -#define ODP_API_SHARED_MEMORY_H_ +#ifndef ODP_API_SPEC_SHARED_MEMORY_H_ +#define ODP_API_SPEC_SHARED_MEMORY_H_ #include <odp/visibility_begin.h> #include <odp/api/init.h> @@ -21,7 +19,7 @@ extern "C" { #endif /** @defgroup odp_shared_memory ODP SHARED MEMORY - * Operations on shared memory. + * Shared memory blocks. * @{ */ @@ -36,20 +34,25 @@ extern "C" { */ /** - * @def ODP_SHM_NULL - * Synonym for buffer pool use + * @def ODP_SHM_NAME_LEN + * Maximum shared memory block name length in chars including null char */ /** - * @def ODP_SHM_NAME_LEN - * Maximum shared memory block name length in chars including null char + * @def ODP_SHM_IOVA_INVALID + * Invalid IOVA address */ -/* - * Shared memory flags: +/** + * @def ODP_SHM_PA_INVALID + * Invalid physical address */ -#define ODP_SHM_SW_ONLY 0x1 /**< Application SW only, no HW access */ -#define ODP_SHM_PROC 0x2 /**< Share with external processes */ + +/** + * Share with external processes + */ +#define ODP_SHM_PROC 0x2 + /** * Single virtual address * @@ -58,6 +61,7 @@ extern "C" { * of ODP thread type (e.g. pthread vs. process (or fork process time)). */ #define ODP_SHM_SINGLE_VA 0x4 + /** * Export memory * @@ -67,17 +71,88 @@ extern "C" { #define ODP_SHM_EXPORT 0x08 /** + * Use huge pages + * + * When set, this flag guarantees that the memory reserved by odp_shm_reserve() + * is allocated from huge pages. The reserve call will return failure if enough + * huge page memory is not available. + */ +#define ODP_SHM_HP 0x10 + +/** + * Share memory with HW accelerators + * + * When set, this flag guarantees that the reserved memory is accessible + * by both CPUs and HW accelerators of the device. This may require e.g. that + * the odp_shm_reserve() call configures the memory to be accessible through + * an Input-Output Memory Management Unit (IOMMU). + */ +#define ODP_SHM_HW_ACCESS 0x20 + +/** + * Don't use huge pages + * + * When set, this flag guarantees that the memory reserved by odp_shm_reserve() + * is not allocated from huge pages. This flag must not be combined with + * ODP_SHM_HP. + */ +#define ODP_SHM_NO_HP 0x40 + +/** * Shared memory block info */ typedef struct odp_shm_info_t { - const char *name; /**< Block name */ - void *addr; /**< Block address */ - uint64_t size; /**< Block size in bytes */ - uint64_t page_size; /**< Memory page size */ - uint32_t flags; /**< ODP_SHM_* flags */ + /** Block name */ + const char *name; + + /** Block address */ + void *addr; + + /** Block size in bytes */ + uint64_t size; + + /** Memory page size */ + uint64_t page_size; + + /** ODP_SHM_* flags */ + uint32_t flags; + + /** + * Number of memory segments + * + * Number of segments in physical (or IOVA) address space that map memory to + * the SHM block. More information about each segment can be retrieved with + * odp_shm_segment_info(). Number of segments is always at least one, also when + * physical (or IOVA) segmentation information is not available. */ + uint32_t num_seg; + } odp_shm_info_t; /** + * SHM memory segment info + */ +typedef struct odp_shm_segment_info_t { + /** Segment start address (virtual) */ + uintptr_t addr; + + /** Segment start address in IO virtual address (IOVA) space + * + * Value is ODP_SHM_IOVA_INVALID when IOVA address is not available. + */ + uint64_t iova; + + /** Segment start address in physical address space + * + * Value is ODP_SHM_PA_INVALID when physical address is not available. + */ + uint64_t pa; + + /** Segment length in bytes */ + uint64_t len; + +} odp_shm_segment_info_t; + +/** * Shared memory capabilities */ typedef struct odp_shm_capability_t { @@ -85,7 +160,7 @@ typedef struct odp_shm_capability_t { * * This number of separate shared memory blocks can be * reserved concurrently. */ - unsigned max_blocks; + uint32_t max_blocks; /** Maximum memory block size in bytes * @@ -99,6 +174,14 @@ typedef struct odp_shm_capability_t { * available memory size. */ uint64_t max_align; + /** Supported shared memory flags + * + * A bit mask of supported ODP_SHM_* flags. Depending on the + * implementation some flag combinations may not be supported. In this + * case odp_shm_reserve() will fail. + */ + uint32_t flags; + } odp_shm_capability_t; /** @@ -116,25 +199,34 @@ int odp_shm_capability(odp_shm_capability_t *capa); /** * Reserve a contiguous block of shared memory * - * @param[in] name Name of the block (maximum ODP_SHM_NAME_LEN - 1 chars) - * @param[in] size Block size in bytes - * @param[in] align Block alignment in bytes - * @param[in] flags Shared memory parameter flags (ODP_SHM_*). - * Default value is 0. + * Reserve a contiguous block of shared memory that fulfills size, alignment + * and shareability (ODP_SHM_* flags) requirements. By default (without flags), the memory + * block can be shared between all threads of the ODP instance. Memory address (odp_shm_addr()) + * shareability depends on application memory model and #ODP_SHM_SINGLE_VA flag usage. + * + * Name is optional and does not need to be unique. However, if the block will be + * searched with odp_shm_lookup() or odp_shm_import(), a unique name is needed + * for correct match. + * + * @param name Name of the block or NULL. Maximum string length is ODP_SHM_NAME_LEN. + * @param size Block size in bytes + * @param align Block alignment in bytes + * @param flags Shared memory parameter flags (ODP_SHM_*). Default value is 0. * * @return Handle of the reserved block * @retval ODP_SHM_INVALID on failure + * + * @see odp_mem_model_t */ -odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, - uint32_t flags); +odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags); /** * Free a contiguous block of shared memory * - * Frees a previously reserved block of shared memory. - * @note Freeing memory that is in use will result in UNDEFINED behavior + * Frees a previously reserved block of shared memory. Freeing memory that is + * in use will result in UNDEFINED behavior * - * @param[in] shm Block handle + * @param shm Block handle * * @retval 0 on success * @retval <0 on failure @@ -144,7 +236,7 @@ int odp_shm_free(odp_shm_t shm); /** * Lookup for a block of shared memory * - * @param[in] name Name of the block + * @param name Name of the block * * @return A handle to the block if it is found by name * @retval ODP_SHM_INVALID on failure @@ -177,20 +269,19 @@ odp_shm_t odp_shm_import(const char *remote_name, /** * Shared memory block address * - * @param[in] shm Block handle + * @param shm Block handle * * @return Memory block address * @retval NULL on failure */ void *odp_shm_addr(odp_shm_t shm); - /** * Shared memory block info - * @note This is the only shared memory API function which accepts invalid - * shm handles (any bit value) without causing undefined behavior. * - * @param[in] shm Block handle + * Get information about the specified shared memory block. + * + * @param shm Block handle * @param[out] info Block info pointer for output * * @retval 0 on success @@ -198,6 +289,26 @@ void *odp_shm_addr(odp_shm_t shm); */ int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info); +/** + * SHM block segmentation information + * + * Retrieve information about each memory segment of an SHM block. SHM info call outputs the number + * of memory segments (odp_shm_info_t::num_seg). A single segment info call may be used + * to request information for all the segments, or for a subset of those. Use 'index' and 'num' + * parameters to specify the segments. Segment indexing starts from zero and continues to + * odp_shm_info_t.num_seg - 1. Segment infos are written in virtual memory address order and + * without address overlaps. Segment info array must have at least 'num' elements. + * + * @param shm SHM block handle + * @param index Index of the first segment to retrieve information + * @param num Number of segments to retrieve information + * @param[out] info Segment info array for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_shm_segment_info(odp_shm_t shm, uint32_t index, uint32_t num, + odp_shm_segment_info_t info[]); /** * Print all shared memory blocks @@ -205,17 +316,27 @@ int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info); void odp_shm_print_all(void); /** + * Print shared memory block info + * + * Print implementation defined information about the specified shared memory + * block to the ODP log. The information is intended to be used for debugging. + * + * @param shm Block handle + */ +void odp_shm_print(odp_shm_t shm); + +/** * Get printable value for an odp_shm_t * - * @param hdl odp_shm_t handle to be printed - * @return uint64_t value that can be used to print/display this - * handle + * This routine is intended to be used for diagnostic purposes to enable + * applications to generate a printable value that represents an odp_shm_t + * handle. + * + * @param shm Block handle * - * @note This routine is intended to be used for diagnostic purposes - * to enable applications to generate a printable value that represents - * an odp_shm_t handle. + * @return uint64_t value that can be used to print this handle */ -uint64_t odp_shm_to_u64(odp_shm_t hdl); +uint64_t odp_shm_to_u64(odp_shm_t shm); /** * @} diff --git a/include/odp/api/spec/spinlock.h b/include/odp/api/spec/spinlock.h index 11b7339b1..a71c83c52 100644 --- a/include/odp/api/spec/spinlock.h +++ b/include/odp/api/spec/spinlock.h @@ -1,7 +1,5 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited */ /** @@ -10,8 +8,8 @@ * ODP spinlock */ -#ifndef ODP_API_SPINLOCK_H_ -#define ODP_API_SPINLOCK_H_ +#ifndef ODP_API_SPEC_SPINLOCK_H_ +#define ODP_API_SPEC_SPINLOCK_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus diff --git a/include/odp/api/spec/spinlock_recursive.h b/include/odp/api/spec/spinlock_recursive.h index c9c7ddb02..bc42f1ce1 100644 --- a/include/odp/api/spec/spinlock_recursive.h +++ b/include/odp/api/spec/spinlock_recursive.h @@ -1,7 +1,5 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited */ /** @@ -10,8 +8,8 @@ * ODP recursive spinlock */ -#ifndef ODP_API_SPINLOCK_RECURSIVE_H_ -#define ODP_API_SPINLOCK_RECURSIVE_H_ +#ifndef ODP_API_SPEC_SPINLOCK_RECURSIVE_H_ +#define ODP_API_SPEC_SPINLOCK_RECURSIVE_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus diff --git a/include/odp/api/spec/stash.h b/include/odp/api/spec/stash.h new file mode 100644 index 000000000..61ae58eba --- /dev/null +++ b/include/odp/api/spec/stash.h @@ -0,0 +1,439 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2020-2023 Nokia + */ + +/** + * @file + * + * ODP stash + */ + +#ifndef ODP_API_SPEC_STASH_H_ +#define ODP_API_SPEC_STASH_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/stash_types.h> + +/** @addtogroup odp_stash + * Stash for storing object handles + * @{ + */ + +/** + * Query stash capabilities + * + * Outputs capabilities of the given stash type on success. The stash type + * is not supported if 'max_stashes' capability is zero. The default stash + * type (ODP_STASH_TYPE_DEFAULT) is always supported. The function returns + * failure if the given stash type is unknown to the implementation. + * + * @param[out] capa Pointer to capability structure for output + * @param type Stash type + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_stash_capability(odp_stash_capability_t *capa, odp_stash_type_t type); + +/** + * Initialize stash params + * + * Initialize an odp_stash_param_t to its default values for all fields. + * + * @param param Parameter structure to be initialized + */ +void odp_stash_param_init(odp_stash_param_t *param); + +/** + * Create a stash + * + * This routine is used to create a stash for object handles. Object handle + * values are opaque data to ODP implementation. Application may use a stash + * to store e.g. pointers, offsets or indexes to arbitrary objects which are + * allocated and freed frequently (e.g. per packet) during application + * processing. Object handle size is specified in stash parameters. + * + * It is optional to give a name. Names do not have to be unique. However, + * odp_stash_lookup() returns only a single matching stash. + * + * @param name Name of the stash or NULL. Maximum string length is + * ODP_STASH_NAME_LEN. + * @param param Stash creation parameters + * + * @return Handle of the created stash + * @retval ODP_STASH_INVALID Stash could not be created + */ +odp_stash_t odp_stash_create(const char *name, const odp_stash_param_t *param); + +/** + * Destroy a stash + * + * Destroy a previously created stash. Stash must be empty before it is + * destroyed. Results are undefined if an attempt is made to destroy a stash + * that contains object handles. + * + * @param stash The stash to be destroyed + * + * @retval 0 Success + * @retval <0 Failure + */ +int odp_stash_destroy(odp_stash_t stash); + +/** + * Find a stash by name + * + * @param name Name of the stash + * + * @return Handle of the first matching stash + * @retval ODP_STASH_INVALID Stash could not be found + */ +odp_stash_t odp_stash_lookup(const char *name); + +/** + * Get printable value for a stash handle + * + * @param stash Handle to be converted for debugging + * @return uint64_t value that can be used for debugging (e.g. printed) + */ +uint64_t odp_stash_to_u64(odp_stash_t stash); + +/** + * Put object handles into a stash + * + * Store object handles into the stash. Handle values are opaque data to + * ODP implementation and may be e.g. pointers or indexes to arbitrary objects. + * Application specifies object handle size and maximum number of handles to be + * stored in stash creation parameters. + * + * A successful operation returns the actual number of object handles stored. + * If the return value is less than 'num', the remaining handles at the end of + * 'obj' array are not stored. + * + * In case of ODP_STASH_TYPE_FIFO, object handles are stored into the stash in + * the order they are in the array. + * + * @param stash Stash handle + * @param obj Points to an array of object handles to be stored. + * Object handle size is specified by 'obj_size' in stash + * creation parameters. The array must be 'obj_size' aligned + * in memory. + * @param num Number of object handles to store + * + * @return Number of object handles actually stored (0 ... num) + * @retval <0 on failure + */ +int32_t odp_stash_put(odp_stash_t stash, const void *obj, int32_t num); + +/** + * Put batch of object handles into a stash + * + * Otherwise like odp_stash_put(), except that this function stores either all + * 'num' object handles or none. odp_stash_capability_t.max_put_batch defines + * the maximum supported batch size. + * + * @param stash Stash handle + * @param obj Points to an array of object handles to be stored. + * Object handle size is specified by 'obj_size' in stash + * creation parameters. The array must be 'obj_size' aligned + * in memory. + * @param num Number of object handles to store + * + * @return Number of object handles actually stored (0 or num) + * @retval <0 on failure + */ +int32_t odp_stash_put_batch(odp_stash_t stash, const void *obj, int32_t num); + +/** + * Put 32-bit integers into a stash + * + * Otherwise like odp_stash_put(), except that this function operates on 32-bit + * integers. The stash must have been created with 'obj_size' of 4. + * + * @param stash Stash handle + * @param val Points to an array of 32-bit integers to be stored. The array + * must be 32-bit aligned in memory. + * @param num Number of integers to store + * + * @return Number of integers actually stored (0 ... num) + * @retval <0 on failure + */ +int32_t odp_stash_put_u32(odp_stash_t stash, const uint32_t val[], int32_t num); + +/** + * Put batch of 32-bit integers into a stash + * + * Otherwise like odp_stash_put_u32(), except that this function stores either + * all 'num' object handles or none. odp_stash_capability_t.max_put_batch + * defines the maximum supported batch size. + * + * @param stash Stash handle + * @param val Points to an array of 32-bit integers to be stored. The array + * must be 32-bit aligned in memory. + * @param num Number of integers to store + * + * @return Number of integers actually stored (0 or num) + * @retval <0 on failure + */ +int32_t odp_stash_put_u32_batch(odp_stash_t stash, const uint32_t val[], int32_t num); + +/** + * Put 64-bit integers into a stash + * + * Otherwise like odp_stash_put(), except that this function operates on 64-bit + * integers. The stash must have been created with 'obj_size' of 8. + * + * @param stash Stash handle + * @param val Points to an array of 64-bit integers to be stored. The array + * must be 64-bit aligned in memory. + * @param num Number of integers to store + * + * @return Number of integers actually stored (0 ... num) + * @retval <0 on failure + */ +int32_t odp_stash_put_u64(odp_stash_t stash, const uint64_t val[], int32_t num); + +/** + * Put batch of 64-bit integers into a stash + * + * Otherwise like odp_stash_put_u64(), except that this function stores either + * all 'num' object handles or none. odp_stash_capability_t.max_put_batch + * defines the maximum supported batch size. + * + * @param stash Stash handle + * @param val Points to an array of 64-bit integers to be stored. The array + * must be 64-bit aligned in memory. + * @param num Number of integers to store + * + * @return Number of integers actually stored (0 or num) + * @retval <0 on failure + */ +int32_t odp_stash_put_u64_batch(odp_stash_t stash, const uint64_t val[], int32_t num); + +/** + * Put pointers into a stash + * + * Otherwise like odp_stash_put(), except that this function operates on + * pointers. The stash must have been created with 'obj_size' matching to the + * size of uintptr_t. + * + * @param stash Stash handle + * @param ptr Points to an array of pointers to be stored. The array must be + * pointer size aligned in memory. + * @param num Number of pointers to store + * + * @return Number of pointers actually stored (0 ... num) + * @retval <0 on failure + */ +int32_t odp_stash_put_ptr(odp_stash_t stash, const uintptr_t ptr[], int32_t num); + +/** + * Put batch of pointers into a stash + * + * Otherwise like odp_stash_put_ptr(), except that this function stores either + * all 'num' object handles or none. odp_stash_capability_t.max_put_batch + * defines the maximum supported batch size. + * + * @param stash Stash handle + * @param ptr Points to an array of pointers to be stored. The array must be + * pointer size aligned in memory. + * @param num Number of pointers to store + * + * @return Number of pointers actually stored (0 or num) + * @retval <0 on failure + */ +int32_t odp_stash_put_ptr_batch(odp_stash_t stash, const uintptr_t ptr[], int32_t num); + +/** + * Get object handles from a stash + * + * Get previously stored object handles from the stash. Application specifies + * object handle size in stash creation parameters. + * + * @param stash Stash handle + * @param[out] obj Points to an array of object handles for output. + * Object handle size is specified by 'obj_size' in stash + * creation parameters. The array must be 'obj_size' aligned + * in memory. + * @param num Maximum number of object handles to get from the stash + * + * @return Number of object handles actually output (0 ... num) to 'obj' array + * @retval <0 on failure + */ +int32_t odp_stash_get(odp_stash_t stash, void *obj, int32_t num); + +/** + * Get batch of object handles from a stash + * + * Otherwise like odp_stash_get(), except that this function outputs either + * all 'num' object handles or none. odp_stash_capability_t.max_get_batch + * defines the maximum supported batch size. + * + * @param stash Stash handle + * @param[out] obj Points to an array of object handles for output. + * Object handle size is specified by 'obj_size' in stash + * creation parameters. The array must be 'obj_size' aligned + * in memory. + * @param num Number of object handles to get from the stash + * + * @return Number of object handles actually output (0 or num) to 'obj' array + * @retval <0 on failure + */ +int32_t odp_stash_get_batch(odp_stash_t stash, void *obj, int32_t num); + +/** + * Get 32-bit integers from a stash + * + * Otherwise like odp_stash_get(), except that this function operates on 32-bit + * integers. The stash must have been created with 'obj_size' of 4. + * + * @param stash Stash handle + * @param[out] val Points to an array of 32-bit integers for output. The + * array must be 32-bit aligned in memory. + * @param num Maximum number of integers to get from the stash + * + * @return Number of integers actually output (0 ... num) to 'val' array + * @retval <0 on failure + */ +int32_t odp_stash_get_u32(odp_stash_t stash, uint32_t val[], int32_t num); + +/** + * Get batch of 32-bit integers from a stash + * + * Otherwise like odp_stash_get_u32(), except that this function outputs either + * all 'num' object handles or none. odp_stash_capability_t.max_get_batch + * defines the maximum supported batch size. + * + * @param stash Stash handle + * @param[out] val Points to an array of 32-bit integers for output. The + * array must be 32-bit aligned in memory. + * @param num Number of integers to get from the stash + * + * @return Number of integers actually output (0 or num) to 'val' array + * @retval <0 on failure + */ +int32_t odp_stash_get_u32_batch(odp_stash_t stash, uint32_t val[], int32_t num); + +/** + * Get 64-bit integers from a stash + * + * Otherwise like odp_stash_get(), except that this function operates on 64-bit + * integers. The stash must have been created with 'obj_size' of 8. + * + * @param stash Stash handle + * @param[out] val Points to an array of 64-bit integers for output. The + * array must be 64-bit aligned in memory. + * @param num Maximum number of integers to get from the stash + * + * @return Number of integers actually output (0 ... num) to 'val' array + * @retval <0 on failure + */ +int32_t odp_stash_get_u64(odp_stash_t stash, uint64_t val[], int32_t num); + +/** + * Get batch of 64-bit integers from a stash + * + * Otherwise like odp_stash_get_u64(), except that this function outputs either + * all 'num' object handles or none. odp_stash_capability_t.max_get_batch + * defines the maximum supported batch size. + * + * @param stash Stash handle + * @param[out] val Points to an array of 64-bit integers for output. The + * array must be 64-bit aligned in memory. + * @param num Number of integers to get from the stash + * + * @return Number of integers actually output (0 or num) to 'val' array + * @retval <0 on failure + */ +int32_t odp_stash_get_u64_batch(odp_stash_t stash, uint64_t val[], int32_t num); + +/** + * Get pointers from a stash + * + * Otherwise like odp_stash_get(), except that this function operates on + * pointers. The stash must have been created with 'obj_size' matching to the + * size of uintptr_t. + * + * @param stash Stash handle + * @param[out] ptr Points to an array of pointers for output. The array must + * be pointer size aligned in memory. + * @param num Maximum number of pointers to get from the stash + * + * @return Number of pointers actually output (0 ... num) to 'ptr' array + * @retval <0 on failure + */ +int32_t odp_stash_get_ptr(odp_stash_t stash, uintptr_t ptr[], int32_t num); + +/** + * Get batch of pointers from a stash + * + * Otherwise like odp_stash_get_ptr(), except that this function outputs either + * all 'num' object handles or none. odp_stash_capability_t.max_get_batch + * defines the maximum supported batch size. + * + * @param stash Stash handle + * @param[out] ptr Points to an array of pointers for output. The array must + * be pointer size aligned in memory. + * @param num Number of pointers to get from the stash + * + * @return Number of pointers actually output (0 or num) to 'ptr' array + * @retval <0 on failure + */ +int32_t odp_stash_get_ptr_batch(odp_stash_t stash, uintptr_t ptr[], int32_t num); + +/** + * Flush object handles from the thread local cache + * + * Flushes all object handles from the thread local cache into the stash, so + * that those are available to odp_stash_get() calls from other threads. This + * call may be used to ensure that thread local cache is empty e.g. before + * the calling thread stops using the stash. + * + * Flush and put operations share 'put_mode' setting in stash creation + * parameters. So, application must ensure that flush and put operations are not + * used concurrently, when ODP_STASH_OP_ST is selected. + * + * @param stash Stash handle + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_stash_flush_cache(odp_stash_t stash); + +/** + * Print debug information about the stash + * + * Print implementation defined information about the stash to the ODP log. The information + * is intended to be used for debugging. + * + * @param stash Stash handle + */ +void odp_stash_print(odp_stash_t stash); + +/** + * Read statistics counters of a stash + * + * Read the statistics counters enabled using odp_stash_stats_opt_t during stash creation. + * Inactive counters are set to zero by the implementation. + * + * @param stash Stash handle + * @param[out] stats Points to statistics counters structure for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_stash_stats(odp_stash_t stash, odp_stash_stats_t *stats); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/stash_types.h b/include/odp/api/spec/stash_types.h new file mode 100644 index 000000000..48c4b9be8 --- /dev/null +++ b/include/odp/api/spec/stash_types.h @@ -0,0 +1,312 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2020-2023 Nokia + */ + +/** + * @file + * + * ODP stash types + */ + +#ifndef ODP_API_SPEC_STASH_TYPES_H_ +#define ODP_API_SPEC_STASH_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +/** @defgroup odp_stash ODP STASH + * @{ + */ + +/** + * @typedef odp_stash_t + * Stash handle + */ + +/** + * @def ODP_STASH_INVALID + * Invalid stash handle + */ + +/** + * @def ODP_STASH_NAME_LEN + * Maximum stash name length in chars including null char + */ + +/** + * Stash types + */ +typedef enum odp_stash_type_t { + /** The default stash type + * + * It is implementation specific in which order odp_stash_get() calls + * return object handles from the stash. The order may be FIFO, LIFO + * or something else. Use this for the best performance when any + * particular ordering is not required. + */ + ODP_STASH_TYPE_DEFAULT = 0, + + /** Stash type FIFO + * + * Stash is implemented as a FIFO. A stash maintains object handle + * order of consecutive odp_stash_put() calls. Object handles stored + * first in the stash are received first by following odp_stash_get() + * calls. To maintain (strict) FIFO ordering of object handles, + * application needs to ensure that odp_stash_put() + * (or odp_stash_get()) operations are not performed concurrently from + * multiple threads. When multiple threads put (or get) object handles + * concurrently in the stash, object handles from different threads + * may be interleaved on output. + */ + ODP_STASH_TYPE_FIFO + +} odp_stash_type_t; + +/** + * Stash operation mode + */ +typedef enum odp_stash_op_mode_t { + /** Multi-thread safe operation + * + * Multiple threads operate on the stash. A stash operation + * (odp_stash_put() or odp_stash_get()) may be performed concurrently + * from multiple threads. + */ + ODP_STASH_OP_MT = 0, + + /** Single thread operation + * + * Multiple threads operate on the stash, but application ensures that + * a stash operation (odp_stash_put() or odp_stash_get()) is not + * performed concurrently from multiple threads. + */ + ODP_STASH_OP_ST, + + /** Thread local operation + * + * Only a single thread operates on the stash. Both stash operations + * (odp_stash_put() and odp_stash_get()) are always performed from the + * same thread. + */ + ODP_STASH_OP_LOCAL + +} odp_stash_op_mode_t; + +/** + * Stash statistics counters options + * + * Statistics counters listed in a bit field structure. + */ +typedef union odp_stash_stats_opt_t { + /** Option flags */ + struct { + /** See odp_stash_stats_t::count */ + uint64_t count : 1; + + /** See odp_stash_stats_t::cache_count */ + uint64_t cache_count : 1; + + } bit; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or for bitwise + * operations over the entire structure. */ + uint64_t all; + +} odp_stash_stats_opt_t; + +/** + * Stash statistics counters + */ +typedef struct odp_stash_stats_t { + /** Object count in the stash + * + * Number of objects currently stored in the stash. The count does not include objects + * stored in thread local caches. When caching is enabled, the total object count + * is the sum of 'count' and 'cache_count'. + */ + uint64_t count; + + /** Object count in thread local caches of the stash + * + * Number of objects stored in all thread local caches of the stash. + */ + uint64_t cache_count; + +} odp_stash_stats_t; + +/** + * Stash capabilities (per stash type) + */ +typedef struct odp_stash_capability_t { + /** Maximum number of stashes of any type */ + uint32_t max_stashes_any_type; + + /** Maximum number of stashes of this type + * + * The value of zero means that the requested stash type is not + * supported. + */ + uint32_t max_stashes; + + /** Maximum common number of object handles per stash for any object size + * + * An application is able to store at least this many objects when using any of the + * supported object sizes. Some of the per object size values listed in 'max_num' may be + * larger than this common value. + */ + uint64_t max_num_obj; + + /** Maximum number of object handles per stash for each object size + * + * Values for unsupported object handle sizes are set to zero. + */ + struct { + /** Maximum number of 1 byte object handles */ + uint64_t u8; + + /** Maximum number of 2 byte object handles */ + uint64_t u16; + + /** Maximum number of 4 byte object handles */ + uint64_t u32; + + /** Maximum number of 8 byte object handles */ + uint64_t u64; + + /** Maximum number of 16 byte object handles */ + uint64_t u128; + + /** Maximum number of 'max_obj_size' object handles */ + uint64_t max_obj_size; + } max_num; + + /** Maximum object handle size in bytes + * + * At least 4 byte object handle size is always supported. + */ + uint32_t max_obj_size; + + /** Maximum size of thread local cache */ + uint32_t max_cache_size; + + /** Maximum number of object handles in batch get operations + * + * At least 1 object batch size is always supported. + */ + uint32_t max_get_batch; + + /** Maximum number of object handles in batch put operations + * + * At least 1 object batch size is always supported. + */ + uint32_t max_put_batch; + + /** Supported statistics counters */ + odp_stash_stats_opt_t stats; + +} odp_stash_capability_t; + +/** + * Stash parameters + */ +typedef struct odp_stash_param_t { + /** Stash type + * + * Select type of the stash to be created. The default value is + * ODP_STASH_TYPE_DEFAULT. Use stash capability to check if additional + * types are supported. + */ + odp_stash_type_t type; + + /** Put operation mode + * + * The default value is ODP_STASH_OP_MT. Usage of ODP_STASH_OP_ST or + * ODP_STASH_OP_LOCAL mode may improve performance when applicable. + * If ODP_STASH_OP_LOCAL is used, it must be set to both put_mode and + * get_mode. + */ + odp_stash_op_mode_t put_mode; + + /** Get operation mode + * + * The default value is ODP_STASH_OP_MT. Usage of ODP_STASH_OP_ST or + * ODP_STASH_OP_LOCAL mode may improve performance when applicable. + * If ODP_STASH_OP_LOCAL is used, it must be set to both put_mode and + * get_mode. + */ + odp_stash_op_mode_t get_mode; + + /** Number of object handles + * + * Application must be able to store at least this many object handles + * into the stash. An implementation may round up the value. The given + * value must not exceed 'max_num' capability. + */ + uint64_t num_obj; + + /** Object handle size in bytes + * + * Application uses object handles of this size in put and get + * operations. Valid values are powers of two (1, 2, 4, 8, ... bytes) + * and must not exceed 'max_obj_size' capability. + */ + uint32_t obj_size; + + /** Maximum number of object handles cached locally per thread + * + * A non-zero value allows implementation to cache object handles + * locally per each thread. Thread local caching may improve + * performance, but requires application to take into account that + * some object handles may be stored locally per thread and thus are + * not available to odp_stash_get() calls from other threads. + * + * Strict FIFO ordering of object handles cannot be maintained with + * thread local caching. If application does not require strict + * ordering, it may allow caching also with ODP_STASH_TYPE_FIFO type + * stashes. + * + * This is the maximum number of handles to be cached per thread. The + * actual cache size and how it is divided between put and get + * operations is implementation specific. The value must not exceed + * 'max_cache_size' capability. The default value is 0. + * + * Thread local cache may be emptied with odp_stash_flush_cache(). + */ + uint32_t cache_size; + + /** + * Configure statistics counters + * + * See stash capabilities for supported statistics counters. Use odp_stash_stats() to read + * the enabled counters. For optimal performance, enable only those counters that are + * actually used. All counters are disabled by default. + */ + odp_stash_stats_opt_t stats; + + /** + * Strict size + * + * If true, application never attempts to store more handles into the stash than specified + * in the 'num_obj' parameter. Implementation may use this value as a hint for performance + * optimizations. The default value is false. + */ + odp_bool_t strict_size; + +} odp_stash_param_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/std_clib.h b/include/odp/api/spec/std.h index 33e9db536..7be543338 100644 --- a/include/odp/api/spec/std_clib.h +++ b/include/odp/api/spec/std.h @@ -1,28 +1,28 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2021 Nokia */ /** * @file * - * ODP version of often used C library calls + * ODP standard types and optimized C library functions */ -#ifndef ODP_API_STD_CLIB_H_ -#define ODP_API_STD_CLIB_H_ +#ifndef ODP_API_SPEC_STD_H_ +#define ODP_API_SPEC_STD_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif -/** - * @defgroup odp_std_clib ODP STD CLIB - * @details - * ODP version of often used C library calls - * @{ +#include <odp/api/std_types.h> + +/** @addtogroup odp_std + * Standard types and performance optimized versions of selected C library + * functions. + * @{ */ /** @@ -73,6 +73,18 @@ void *odp_memset(void *ptr, int value, size_t num); int odp_memcmp(const void *ptr1, const void *ptr2, size_t num); /** + * Convert fractional number (u64) to double + * + * Converts value of the unsigned 64 bit fractional number to a double-precision + * floating-point value. + * + * @param fract Pointer to a fractional number + * + * @return Value of the fractional number as double + */ +double odp_fract_u64_to_dbl(const odp_fract_u64_t *fract); + +/** * @} */ diff --git a/include/odp/api/spec/std_types.h b/include/odp/api/spec/std_types.h index ec6a6df6d..5428631b6 100644 --- a/include/odp/api/spec/std_types.h +++ b/include/odp/api/spec/std_types.h @@ -1,26 +1,28 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2021 ARM Limited + * Copyright (c) 2021 Nokia */ - /** * @file * - * Standard C language types and definitions for ODP. + * Common types and definitions for ODP API files. * */ -#ifndef ODP_API_STD_TYPES_H_ -#define ODP_API_STD_TYPES_H_ +#ifndef ODP_API_SPEC_STD_TYPES_H_ +#define ODP_API_SPEC_STD_TYPES_H_ #include <odp/visibility_begin.h> +/* uint64_t, uint32_t, etc */ +#include <stdint.h> +#include <odp/api/align.h> #ifdef __cplusplus extern "C" { #endif -/** @addtogroup odp_system ODP SYSTEM +/** @defgroup odp_std ODP STD * @{ */ @@ -32,6 +34,132 @@ extern "C" { */ /** + * Percentage type + * Use odp_percent_t for specifying fields that are percentages. It is a fixed + * point integer whose units are expressed as one-hundredth of a percent. + * Hence 100% is represented as integer value 10000. + */ +typedef uint32_t odp_percent_t; + +/** Unaligned uint16_t type */ +typedef uint16_t odp_una_u16_t ODP_ALIGNED(1); + +/** Unaligned uint32_t type */ +typedef uint32_t odp_una_u32_t ODP_ALIGNED(1); + +/** Unaligned uint64_t type */ +typedef uint64_t odp_una_u64_t ODP_ALIGNED(1); + +/** + * @typedef odp_u128_t + * 128-bit unsigned integer structure + */ + +/** + * 128-bit unsigned integer structure + */ +typedef struct ODP_ALIGNED(16) odp_u128_s { + /** 128 bits in various sizes */ + union { + /** 128 bits as uint64_t words */ + uint64_t u64[2]; + /** 128 bits as uint32_t words */ + uint32_t u32[4]; + /** 128 bits as uint16_t words */ + uint16_t u16[8]; + /** 128 bits as bytes */ + uint8_t u8[16]; + }; +} odp_u128_t; + +/** + * Unsigned 64 bit fractional number + * + * The number is composed of integer and fraction parts. The fraction part is composed of + * two terms: numerator and denominator. Value of the number is sum of the integer and fraction + * parts: value = integer + numer/denom. When the fraction part is zero, the numerator is zero and + * the denominator may be zero. + */ +typedef struct odp_fract_u64_t { + /** Integer part */ + uint64_t integer; + + /** Numerator of the fraction part */ + uint64_t numer; + + /** Denominator of the fraction part. This may be zero when the numerator + * is zero. */ + uint64_t denom; + +} odp_fract_u64_t; + +/** + * ODP support + * + * Support levels are specified in the relative order, where ODP_SUPPORT_NO is + * the lowest level. E.g. if the examined support level is greater than + * ODP_SUPPORT_NO, the feature is supported in some form. + */ +typedef enum odp_support_t { + /** + * Feature is not supported + */ + ODP_SUPPORT_NO = 0, + /** + * Feature is supported + */ + ODP_SUPPORT_YES, + /** + * Feature is supported and preferred + */ + ODP_SUPPORT_PREFERRED + +} odp_support_t; + +/** Definition of ODP features */ +typedef union odp_feature_t { + /** All features */ + uint32_t all_feat; + + /** Individual feature bits */ + struct { + /** Classifier APIs, e.g., odp_cls_xxx(), odp_cos_xxx() */ + uint32_t cls:1; + + /** Compression APIs, e.g., odp_comp_xxx() */ + uint32_t compress:1; + + /** Crypto APIs, e.g., odp_crypto_xxx() */ + uint32_t crypto:1; + + /** DMA APIs, e.g., odp_dma_xxx() */ + uint32_t dma:1; + + /** IPsec APIs, e.g., odp_ipsec_xxx() */ + uint32_t ipsec:1; + + /** Machine Learning APIs, e.g., odp_ml_xxx() */ + uint32_t ml:1; + + /** Scheduler APIs, e.g., odp_schedule_xxx() */ + uint32_t schedule:1; + + /** Stash APIs, e.g., odp_stash_xxx() */ + uint32_t stash:1; + + /** Time APIs, e.g., odp_time_xxx() */ + uint32_t time:1; + + /** Timer APIs, e.g., odp_timer_xxx(), odp_timeout_xxx() */ + uint32_t timer:1; + + /** Traffic Manager APIs, e.g., odp_tm_xxx() */ + uint32_t tm:1; + } feat; + +} odp_feature_t; + +/** * @} */ diff --git a/include/odp/api/spec/sync.h b/include/odp/api/spec/sync.h index 6f87db559..18272af88 100644 --- a/include/odp/api/spec/sync.h +++ b/include/odp/api/spec/sync.h @@ -1,7 +1,6 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2023 Nokia */ /** @@ -10,8 +9,8 @@ * ODP memory barriers */ -#ifndef ODP_API_SYNC_H_ -#define ODP_API_SYNC_H_ +#ifndef ODP_API_SPEC_SYNC_H_ +#define ODP_API_SPEC_SYNC_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -23,15 +22,24 @@ extern "C" { * @details * <b> Memory barriers </b> * - * Memory barriers enforce ordering of memory load and store operations - * specified before and after the barrier. These barriers may affect both - * compiler optimizations and CPU out-of-order execution. All ODP - * synchronization mechanisms (e.g. execution barriers, locks, queues, etc ) - * include all necessary memory barriers, so these calls are not needed when - * using those. Also ODP atomic operations have memory ordered versions. These - * explicit barriers may be needed when thread synchronization is based on - * a non-ODP defined mechanism. Depending on the HW platform, heavy usage of - * memory barriers may cause significant performance degradation. + * A memory barrier enforces the order between memory accesses (loads and/or stores) + * specified (in program order) before the barrier with those specified after the barrier. + * A barrier may affect both compiler optimizations and CPU out-of-order execution. Depending + * on the used HW platform and barrier types, heavy usage of barriers may cause significant + * performance degradation. + * + * An application may use these memory barrier functions e.g. to build a synchronization + * mechanism between its threads in shared memory, or when it accesses memory mapped registers + * of a device. + * + * An application does not need to use these memory barriers when using other ODP APIs for thread + * synchronization (execution barriers, spinlocks, etc.), or when exchanging data through ODP API + * mechanisms (queues, stashes, etc.). Those ODP calls include necessary (acquire and release) + * memory barriers to maintain coherency between data producers and consumers. + * + * Some ODP atomic operations include a memory barrier - see for example odp_atomic_load_acq_u32() + * or odp_atomic_store_rel_u32(). Application may use also those (non-relaxed) atomic operations + * to enforce memory ordering while using atomic variables. * * @{ */ @@ -80,6 +88,39 @@ void odp_mb_acquire(void); void odp_mb_full(void); /** + * Memory barrier for load and store synchronization + * + * This memory barrier ensures that all memory accesses (loads and stores) specified before the + * barrier (in program order) are complete prior to any memory access specified after the barrier + * begins execution. + * + * This is a stronger barrier than odp_mb_full(), as in addition to visibility order also memory + * access completion is ensured. The barrier may be useful e.g. when synchronizing loads and stores + * into memory mapped registers of a device. + */ +void odp_mb_sync(void); + +/** + * Memory barrier for load synchronization + * + * This memory barrier ensures that all memory loads specified before the barrier (in program + * order) are complete prior to any memory load specified after the barrier begins execution. + * + * The barrier may be useful e.g. when synchronizing loads from memory mapped registers of a device. + */ +void odp_mb_sync_load(void); + +/** + * Memory synchronization barrier for stores + * + * This memory barrier ensures that all memory stores specified before the barrier (in program + * order) are complete prior to any memory store specified after the barrier begins execution. + * + * The barrier may be useful e.g. when synchronizing stores to memory mapped registers of a device. + */ +void odp_mb_sync_store(void); + +/** * @} */ diff --git a/include/odp/api/spec/system_info.h b/include/odp/api/spec/system_info.h index 0bb4f1f12..98efe06f7 100644 --- a/include/odp/api/spec/system_info.h +++ b/include/odp/api/spec/system_info.h @@ -1,18 +1,16 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2020-2021 Nokia */ - /** * @file * * ODP system information */ -#ifndef ODP_API_SYSTEM_INFO_H_ -#define ODP_API_SYSTEM_INFO_H_ +#ifndef ODP_API_SPEC_SYSTEM_INFO_H_ +#define ODP_API_SPEC_SYSTEM_INFO_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -20,17 +18,314 @@ extern "C" { #endif /** @defgroup odp_system ODP SYSTEM + * System information. * @{ */ +/** Maximum memory block name length in chars (including null char) */ +#define ODP_SYSTEM_MEMBLOCK_NAME_LEN 64 + +/** + * CPU instruction set architecture (ISA) families + */ +typedef enum odp_cpu_arch_t { + /** Unknown CPU architecture */ + ODP_CPU_ARCH_UNKNOWN = 0, + + /** ARM */ + ODP_CPU_ARCH_ARM, + + /** MIPS */ + ODP_CPU_ARCH_MIPS, + + /** PowerPC */ + ODP_CPU_ARCH_PPC, + + /** RISC-V */ + ODP_CPU_ARCH_RISCV, + + /** x86 */ + ODP_CPU_ARCH_X86 + +} odp_cpu_arch_t; + +/** + * ARM ISA versions + * + * ISA versions are defined in ascending order. + */ +typedef enum odp_cpu_arch_arm_t { + /** Unknown ARM ISA version */ + ODP_CPU_ARCH_ARM_UNKNOWN = 0, + + /** ARMv6 ISA */ + ODP_CPU_ARCH_ARMV6, + + /** ARMv7-A ISA */ + ODP_CPU_ARCH_ARMV7, + + /** ARMv8.0-A ISA */ + ODP_CPU_ARCH_ARMV8_0, + + /** ARMv8.1-A ISA */ + ODP_CPU_ARCH_ARMV8_1, + + /** ARMv8.2-A ISA */ + ODP_CPU_ARCH_ARMV8_2, + + /** ARMv8.3-A ISA */ + ODP_CPU_ARCH_ARMV8_3, + + /** ARMv8.4-A ISA */ + ODP_CPU_ARCH_ARMV8_4, + + /** ARMv8.5-A ISA */ + ODP_CPU_ARCH_ARMV8_5, + + /** ARMv8.6-A ISA */ + ODP_CPU_ARCH_ARMV8_6, + + /** ARMv8.7-A ISA */ + ODP_CPU_ARCH_ARMV8_7, + + /** ARMv8.8-A ISA */ + ODP_CPU_ARCH_ARMV8_8, + + /** ARMv8.9-A ISA */ + ODP_CPU_ARCH_ARMV8_9, + + /** ARMv9.0-A ISA */ + ODP_CPU_ARCH_ARMV9_0, + + /** ARMv9.1-A ISA */ + ODP_CPU_ARCH_ARMV9_1, + + /** ARMv9.2-A ISA */ + ODP_CPU_ARCH_ARMV9_2, + + /** ARMv9.3-A ISA */ + ODP_CPU_ARCH_ARMV9_3, + +} odp_cpu_arch_arm_t; + +/** + * MIPS ISA versions + */ +typedef enum odp_cpu_arch_mips_t { + /** Unknown MIPS ISA version */ + ODP_CPU_ARCH_MIPS_UNKNOWN = 0 + +} odp_cpu_arch_mips_t; + +/** + * PowerPC ISA versions + */ +typedef enum odp_cpu_arch_ppc_t { + /** Unknown PPC ISA version */ + ODP_CPU_ARCH_PPC_UNKNOWN = 0 + +} odp_cpu_arch_ppc_t; + +/** + * RISC-V ISA versions + */ +typedef enum odp_cpu_arch_riscv_t { + /** Unknown RISC-V ISA version */ + ODP_CPU_ARCH_RISCV_UNKNOWN = 0 + +} odp_cpu_arch_riscv_t; + +/** + * x86 ISA versions + */ +typedef enum odp_cpu_arch_x86_t { + /** Unknown x86 ISA version */ + ODP_CPU_ARCH_X86_UNKNOWN = 0, + + /** x86 32bit ISA */ + ODP_CPU_ARCH_X86_I686, + + /** x86 64bit ISA */ + ODP_CPU_ARCH_X86_64 + +} odp_cpu_arch_x86_t; + +/** + * CPU ISA versions + */ +typedef union odp_cpu_arch_isa_t { + /** ARM ISA versions */ + odp_cpu_arch_arm_t arm; + + /** MIPS ISA versions */ + odp_cpu_arch_mips_t mips; + + /** PowerPC ISA versions */ + odp_cpu_arch_ppc_t ppc; + + /** RISC-V ISA versions */ + odp_cpu_arch_riscv_t riscv; + + /** x86 ISA versions */ + odp_cpu_arch_x86_t x86; + +} odp_cpu_arch_isa_t; + +/** + * System info + */ +typedef struct odp_system_info_t { + /** + * CPU architecture + * + * Defines CPU ISA family: ARM, MIPS, PPC, RISC-V, x86 or unknown + */ + odp_cpu_arch_t cpu_arch; + + /** + * ISA version of ODP software + * + * Defines the ISA version that was used to build the ODP library. Depending on compiler + * target architecture setting, the value may be lower than the ISA version supported by + * the CPU hardware. + */ + odp_cpu_arch_isa_t cpu_isa_sw; + + /** + * ISA version of CPU hardware + * + * Defines the ISA version supported by the CPU hardware. The value is set to + * ODP_CPU_ARCH_<arch>_UNKNOWN, when the ISA version cannot be determined. + */ + odp_cpu_arch_isa_t cpu_isa_hw; + +} odp_system_info_t; + +/** + * Memory information + */ +typedef struct odp_system_meminfo_t { + /** + * Total mapped memory + * + * Total amount of memory (in bytes) in all memory pages that are reserved by + * this ODP instance from the system. + */ + uint64_t total_mapped; + + /** + * Total memory usage + * + * Total amount of memory (in bytes) that is currently in use by this ODP instance. + * This is a subset of 'total_mapped' bytes. + */ + uint64_t total_used; + + /** + * Total memory usage overheads + * + * Total amount of memory (in bytes) that is currently consumed by roundings to + * alignment/block/page size limits, etc. overheads. This is a subset of 'total_used' + * bytes. + */ + uint64_t total_overhead; + +} odp_system_meminfo_t; + +/** + * Memory block information + */ +typedef struct odp_system_memblock_t { + /** Memory block name */ + char name[ODP_SYSTEM_MEMBLOCK_NAME_LEN]; + + /** Start address of the block */ + uintptr_t addr; + + /** + * Memory usage + * + * Total amount of memory (in bytes) that is used by this block. + */ + uint64_t used; + + /** + * Memory usage overheads + * + * Total amount of memory (in bytes) that is currently consumed by rounding to + * alignment/block/page size limits, etc. overheads. This is a subset of 'used' bytes. + */ + uint64_t overhead; + + /** Memory page size in bytes + * + * Page size used for this block. + */ + uint64_t page_size; + +} odp_system_memblock_t; + +/** + * Retrieve system information + * + * Fills in system information structure on success. The call is not intended + * for fast path use. + * + * @param[out] info Pointer to system info struct for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_system_info(odp_system_info_t *info); + +/** + * Retrieve ODP memory usage information + * + * Retrieves information about ODP memory usage for debugging and monitoring purposes. A successful + * call fills in system memory info and outputs up to 'num' elements into memory block info array. + * Each array element represents a memory block used due to an API call (SHM reservation, pool + * creation, etc) or an implementation internal memory allocation. + * + * When return value is 'num' or less, it indicates the number of elements written. If return value + * is larger than 'num', all 'num' elements were written and the return value indicates the number + * of elements that would have been written into a large enough array. + * + * @param[out] info Pointer to memory info struct for output + * @param[out] block Pointer memory block info array for output + * @param num Maximum number of array elements to output (0 ... array size) + * + * @return Number of array elements written / would have been written + * @retval <0 on failure + */ +int32_t odp_system_meminfo(odp_system_meminfo_t *info, odp_system_memblock_t block[], int32_t num); + /** * Default system huge page size in bytes * * @return Default huge page size in bytes + * @retval 0 on no huge pages */ uint64_t odp_sys_huge_page_size(void); /** + * System huge page sizes in bytes + * + * Returns the number of huge page sizes supported by the system. Outputs up to + * 'num' sizes when the 'size' array pointer is not NULL. If return value is + * larger than 'num', there are more supported sizes than the function was + * allowed to output. If return value (N) is less than 'num', only sizes + * [0 ... N-1] have been written. Returned values are ordered from smallest to + * largest. + * + * @param[out] size Points to an array of huge page sizes for output + * @param num Maximum number of huge page sizes to output + * + * @return Number of supported huge page sizes + * @retval <0 on failure + */ +int odp_sys_huge_page_size_all(uint64_t size[], int num); + +/** * Page size in bytes * * @return Page size in bytes @@ -45,6 +340,24 @@ uint64_t odp_sys_page_size(void); int odp_sys_cache_line_size(void); /** + * Print system info + * + * Print out implementation defined information about the system. This + * information is intended for debugging purposes and may contain e.g. + * information about CPUs, memory and other HW configuration. + */ +void odp_sys_info_print(void); + +/** + * Print configuration + * + * Print out implementation defined information about selected configuration options. This + * information is intended for debugging purposes and may contain e.g. content of various + * configuration files, environment variables and configuration options of ODP API. + */ +void odp_sys_config_print(void); + +/** * @} */ diff --git a/include/odp/api/spec/thread.h b/include/odp/api/spec/thread.h index 689ba59b5..34d3c2b82 100644 --- a/include/odp/api/spec/thread.h +++ b/include/odp/api/spec/thread.h @@ -1,70 +1,39 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2022-2023 Nokia */ - /** * @file * * ODP thread API */ -#ifndef ODP_API_THREAD_H_ -#define ODP_API_THREAD_H_ +#ifndef ODP_API_SPEC_THREAD_H_ +#define ODP_API_SPEC_THREAD_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif -/** @defgroup odp_thread ODP THREAD - * @{ - */ +#include <odp/api/thread_types.h> -/** - * @def ODP_THREAD_COUNT_MAX - * Maximum number of threads supported in build time. Use - * odp_thread_count_max() for maximum number of threads supported in run time, - * which depend on system configuration and may be lower than this number. - */ - -/** - * Thread type +/** @addtogroup odp_thread + * Thread types, masks and IDs. + * @{ */ -typedef enum odp_thread_type_e { - /** - * Worker thread - * - * Worker threads do most part of ODP application packet processing. - * These threads provide high packet and data rates, with low and - * predictable latency. Typically, worker threads are pinned to isolated - * CPUs and packets are processed in a run-to-completion loop with very - * low interference from the operating system. - */ - ODP_THREAD_WORKER = 0, - - /** - * Control thread - * - * Control threads do not participate the main packet flow through the - * system, but e.g. control or monitor the worker threads, or handle - * exceptions. These threads may perform general purpose processing, - * use system calls, share the CPU with other threads and be interrupt - * driven. - */ - ODP_THREAD_CONTROL -} odp_thread_type_t; - /** * Get thread identifier * - * Returns the thread identifier of the current thread. Thread ids range from 0 - * to odp_thread_count_max() - 1. The ODP thread id is assigned by - * odp_init_local() and freed by odp_term_local(). Thread id is unique within - * the ODP instance. + * Returns the ODP thread identifier of current thread. Thread IDs range from 0 + * to odp_thread_count_max() - 1 and are unique within an ODP instance. + * + * Thread IDs are assigned by odp_init_local() and freed by odp_term_local(). + * IDs are assigned sequentially starting from 0 in the same order threads call + * odp_init_local(). Thread IDs freed by odp_term_local() may be reused by + * following odp_init_local() calls. * * @return Thread identifier of the current thread */ @@ -74,25 +43,70 @@ int odp_thread_id(void); * Thread count * * Returns the current ODP thread count. This is the number of active threads - * running the ODP instance. Each odp_init_local() call increments and each - * odp_term_local() call decrements the count. The count is always between 1 and - * odp_thread_count_max(). + * of any type running in the ODP instance. Each odp_init_local() call + * increments and each odp_term_local() call decrements the count. The count is + * always between 1 and odp_thread_count_max(). * * @return Current thread count */ int odp_thread_count(void); /** + * Control thread count + * + * Otherwise like odp_thread_count(), but returns the number of active threads + * of type #ODP_THREAD_CONTROL. The count is always between 0 and + * odp_thread_control_count_max(). + * + * @return Current control thread count + */ +int odp_thread_control_count(void); + +/** + * Worker thread count + * + * Otherwise like odp_thread_count(), but returns the number of active threads + * of type #ODP_THREAD_WORKER. The count is always between 0 and + * odp_thread_worker_count_max(). + * + * @return Current worker thread count + */ +int odp_thread_worker_count(void); + +/** * Maximum thread count * - * Returns the maximum thread count, which is a constant value and set in - * ODP initialization phase. This may be lower than ODP_THREAD_COUNT_MAX. + * Returns the maximum number of threads of any type. This is a constant value + * and set in ODP initialization phase. The value may be lower than + * #ODP_THREAD_COUNT_MAX. * * @return Maximum thread count */ int odp_thread_count_max(void); /** + * Maximum control thread count + * + * Otherwise like odp_thread_count_max(), but returns the maximum number of + * control threads (#ODP_THREAD_CONTROL). The returned value is always <= + * odp_thread_count_max(). + * + * @return Maximum control thread count + */ +int odp_thread_control_count_max(void); + +/** + * Maximum worker thread count + * + * Otherwise like odp_thread_count_max(), but returns the maximum number of + * worker threads (#ODP_THREAD_WORKER). The returned value is always <= + * odp_thread_count_max(). + * + * @return Maximum worker thread count + */ +int odp_thread_worker_count_max(void); + +/** * Thread type * * Returns the thread type of the current thread. @@ -101,7 +115,6 @@ int odp_thread_count_max(void); */ odp_thread_type_t odp_thread_type(void); - /** * @} */ diff --git a/include/odp/api/spec/thread_types.h b/include/odp/api/spec/thread_types.h new file mode 100644 index 000000000..13846cd8f --- /dev/null +++ b/include/odp/api/spec/thread_types.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2018 Linaro Limited + */ + +/** + * @file + * + * ODP thread API types + */ + +#ifndef ODP_API_SPEC_THREAD_TYPES_H_ +#define ODP_API_SPEC_THREAD_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup odp_thread ODP THREAD + * @{ + */ + +/** + * @def ODP_THREAD_COUNT_MAX + * Maximum number of threads supported in build time. Use odp_thread_count_max() + * for maximum number of threads supported in run time, which depends on system + * configuration and may be lower than this number. + */ + +/** + * Thread type + */ +typedef enum odp_thread_type_e { + /** + * Worker thread + * + * Worker threads do most part of ODP application packet processing. + * These threads provide high packet and data rates, with low and + * predictable latency. Typically, worker threads are pinned to isolated + * CPUs and packets are processed in a run-to-completion loop with very + * low interference from the operating system. + */ + ODP_THREAD_WORKER = 0, + + /** + * Control thread + * + * Control threads do not participate the main packet flow through the + * system, but e.g. control or monitor the worker threads, or handle + * exceptions. These threads may perform general purpose processing, + * use system calls, share the CPU with other threads and be interrupt + * driven. + */ + ODP_THREAD_CONTROL +} odp_thread_type_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/spec/threshold.h b/include/odp/api/spec/threshold.h new file mode 100644 index 000000000..732da7274 --- /dev/null +++ b/include/odp/api/spec/threshold.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + */ + +/** + * @file + * + * ODP threshold descriptor + */ + +#ifndef ODP_API_SPEC_THRESHOLD_H_ +#define ODP_API_SPEC_THRESHOLD_H_ + +#include <odp/visibility_begin.h> +#include <odp/api/std_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Supported threshold types + * + * Supported threshold types in a bit field structure. + */ +typedef union odp_threshold_types_t { + /** bitfields for different threshold types */ + struct { + /** Percentage of the total size of pool or queue */ + uint8_t percent:1; + + /** Total number of all transient packets */ + uint8_t packet:1; + + /** Total size of all transient packets in bytes */ + uint8_t bytes:1; + }; + + /** All bits of the bit field structure */ + uint8_t all_bits; +} odp_threshold_types_t; + +/** + * ODP Threshold types + * + * Different types of threshold measurements + */ +typedef enum odp_threshold_type_t { + /** Percentage of the total size of pool or queue */ + ODP_THRESHOLD_PERCENT, + + /** Total number of all transient packets */ + ODP_THRESHOLD_PACKET, + + /** Total size of all transient packets in bytes */ + ODP_THRESHOLD_BYTE +} odp_threshold_type_t; + +/** + * ODP Threshold + * + * Threshold configuration + */ +typedef struct odp_threshold_t { + /** Type of threshold */ + odp_threshold_type_t type; + + /** Different threshold types */ + union { + /** Percentage */ + struct { + /** Max percentage value */ + odp_percent_t max; + + /** Min percentage value */ + odp_percent_t min; + } percent; + + /** Packet count */ + struct { + /** Max packet count */ + uint64_t max; + + /** Min packet count */ + uint64_t min; + } packet; + + /** Sum of all data bytes of all packets */ + struct { + /** Max byte count */ + uint64_t max; + + /** Min byte count */ + uint64_t min; + } byte; + }; +} odp_threshold_t; + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/thrmask.h b/include/odp/api/spec/thrmask.h index 3986769ac..725690e9e 100644 --- a/include/odp/api/spec/thrmask.h +++ b/include/odp/api/spec/thrmask.h @@ -1,7 +1,5 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited */ /** @@ -10,8 +8,8 @@ * ODP thread masks */ -#ifndef ODP_API_THRMASK_H_ -#define ODP_API_THRMASK_H_ +#ifndef ODP_API_SPEC_THRMASK_H_ +#define ODP_API_SPEC_THRMASK_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus diff --git a/include/odp/api/spec/ticketlock.h b/include/odp/api/spec/ticketlock.h index b23253b55..2a14273ee 100644 --- a/include/odp/api/spec/ticketlock.h +++ b/include/odp/api/spec/ticketlock.h @@ -1,18 +1,15 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited */ - /** * @file * * ODP ticketlock */ -#ifndef ODP_API_TICKETLOCK_H_ -#define ODP_API_TICKETLOCK_H_ +#ifndef ODP_API_SPEC_TICKETLOCK_H_ +#define ODP_API_SPEC_TICKETLOCK_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -44,7 +41,6 @@ extern "C" { */ void odp_ticketlock_init(odp_ticketlock_t *tklock); - /** * Acquire ticket lock. * @@ -69,7 +65,6 @@ int odp_ticketlock_trylock(odp_ticketlock_t *tklock); */ void odp_ticketlock_unlock(odp_ticketlock_t *tklock); - /** * Check if ticket lock is locked. * diff --git a/include/odp/api/spec/time.h b/include/odp/api/spec/time.h index fcc94c98e..f7e20a6f4 100644 --- a/include/odp/api/spec/time.h +++ b/include/odp/api/spec/time.h @@ -1,72 +1,120 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2020-2023 Nokia */ - /** * @file * * ODP time */ -#ifndef ODP_API_TIME_H_ -#define ODP_API_TIME_H_ +#ifndef ODP_API_SPEC_TIME_H_ +#define ODP_API_SPEC_TIME_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif -/** @defgroup odp_time ODP TIME +#include <odp/api/std_types.h> +#include <odp/api/time_types.h> + +/** @addtogroup odp_time + * SoC global and CPU local wall clock time + * * @{ */ -/* Time in nanoseconds */ -#define ODP_TIME_USEC_IN_NS 1000ULL /**< Microsecond in nsec */ -#define ODP_TIME_MSEC_IN_NS 1000000ULL /**< Millisecond in nsec */ -#define ODP_TIME_SEC_IN_NS 1000000000ULL /**< Second in nsec */ +/** + * Current local time + * + * Returns current CPU local time stamp value. The used time source is specific to the calling + * thread and the CPU it is running on during the call. Time stamp values from different + * time sources cannot be compared or otherwise mixed. + * + * Local time stamp value advances with a constant rate defined by odp_time_local_res(). The rate + * remains constant even during dynamic CPU frequency scaling. Local time stamp and related + * nanosecond values may not start from zero, but are guaranteed not to wrap around in at least + * 10 years from the ODP instance startup. + * + * @return CPU local time stamp value + */ +odp_time_t odp_time_local(void); /** - * @typedef odp_time_t - * ODP time stamp. Time stamp can represent a time stamp from local or global - * time source. A local time stamp must not be shared between threads. API calls - * work correctly only when all time stamps for input are from the same time - * source. + * Current local time in nanoseconds + * + * Like odp_time_local(), but the time stamp value is converted into nanoseconds. + * + * @return Local time stamp in nanoseconds */ +uint64_t odp_time_local_ns(void); /** - * @def ODP_TIME_NULL - * Zero time stamp + * Current local time (strict) + * + * Like odp_time_local(), but reads the time stamp value more strictly in the program order. + * The function may decrease CPU performance around the call, as it may include additional + * barrier instructions or otherwise limit out-of-order execution. + * + * @return Local time stamp */ +odp_time_t odp_time_local_strict(void); /** - * Current local time + * Current local time in nanoseconds (strict) * - * Returns current local time stamp value. The local time source provides high - * resolution time, it is initialized to zero during ODP startup and will not - * wrap around in at least 10 years. - * Local time stamps are local to the calling thread and must not be shared - * with other threads. + * Like odp_time_local_strict(), but the time stamp value is converted into nanoseconds. * - * @return Local time stamp. + * @return Local time stamp in nanoseconds */ -odp_time_t odp_time_local(void); +uint64_t odp_time_local_strict_ns(void); /** * Current global time * - * Returns current global time stamp value. The global time source provides high - * resolution time, it is initialized to zero during ODP startup and will not - * wrap around in at least 10 years. - * Global time stamps can be shared between threads. + * Returns current SoC global time stamp value. Global time stamp values read by different threads + * (or CPUs) may be compared or otherwise mixed as those come from the same time source. + * + * Global time stamp value advances with a constant rate defined by odp_time_global_res(). The rate + * remains constant even during dynamic CPU frequency scaling. Global time stamp and related + * nanosecond values may not start from zero, but are guaranteed not to wrap around in at least + * 10 years from the ODP instance startup. * - * @return Global time stamp. + * @return SoC global time stamp value */ odp_time_t odp_time_global(void); /** + * Current global time in nanoseconds + * + * Like odp_time_global(), but the time stamp value is converted into nanoseconds. + * + * @return Global time stamp in nanoseconds + */ +uint64_t odp_time_global_ns(void); + +/** + * Current global time (strict) + * + * Like odp_time_global(), but reads the time stamp value more strictly (see + * odp_time_local_strict() documentation) in the program order. + * + * @return Global time stamp + */ +odp_time_t odp_time_global_strict(void); + +/** + * Current global time in nanoseconds (strict) + * + * Like odp_time_global_strict(), but the time stamp value is converted into nanoseconds. + * + * @return Global time stamp in nanoseconds + */ +uint64_t odp_time_global_strict_ns(void); + +/** * Time difference * * @param t2 Second time stamp @@ -77,8 +125,35 @@ odp_time_t odp_time_global(void); odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1); /** + * Time difference in nanoseconds + * + * @param t2 Second time stamp + * @param t1 First time stamp + * + * @return Difference of time stamps (t2 - t1) in nanoseconds + */ +uint64_t odp_time_diff_ns(odp_time_t t2, odp_time_t t1); + +/** + * Add nanoseconds into time + * + * Adds 'ns' nanoseconds into the time stamp value. The resulting time may wrap around, if + * the sum of 'time' and 'ns' is more than 10 years from the ODP instance startup. + * + * @param time Time stamp + * @param ns Nanoseconds to be added + * + * @return Time stamp incremented by 'ns' nanoseconds + */ +odp_time_t odp_time_add_ns(odp_time_t time, uint64_t ns); + +/** * Time sum * + * Returns the sum of time stamp values. Time stamps must be from the same time source (global or + * local). The resulting time may wrap around, if the sum exceeds 10 years from the ODP instance + * startup. + * * @param t1 Time stamp * @param t2 Time stamp * @@ -158,17 +233,14 @@ void odp_time_wait_until(odp_time_t time); void odp_time_wait_ns(uint64_t ns); /** - * Get printable value for an odp_time_t - * - * @param time time to be printed + * Get ODP instance startup time * - * @return uint64_t value that can be used to print/display this time + * Outputs time stamp values captured at ODP instance startup. Application may use those + * to calculate time stamp values relative to ODP startup time. * - * @note This routine is intended to be used for diagnostic purposes - * to enable applications to generate a printable value that represents - * an odp_time_t time. + * @param[out] startup Startup time structure for output */ -uint64_t odp_time_to_u64(odp_time_t time); +void odp_time_startup(odp_time_startup_t *startup); /** * @} diff --git a/include/odp/api/spec/time_types.h b/include/odp/api/spec/time_types.h new file mode 100644 index 000000000..bd8f324a3 --- /dev/null +++ b/include/odp/api/spec/time_types.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2020-2023 Nokia + */ + +/** + * @file + * + * ODP time + */ + +#ifndef ODP_API_SPEC_TIME_TYPES_H_ +#define ODP_API_SPEC_TIME_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup odp_time ODP TIME + * @{ + */ + +/** A microsecond in nanoseconds */ +#define ODP_TIME_USEC_IN_NS 1000ULL + +/** A millisecond in nanoseconds */ +#define ODP_TIME_MSEC_IN_NS 1000000ULL + +/** A second in nanoseconds */ +#define ODP_TIME_SEC_IN_NS 1000000000ULL + +/** A minute in nanoseconds */ +#define ODP_TIME_MIN_IN_NS 60000000000ULL + +/** An hour in nanoseconds */ +#define ODP_TIME_HOUR_IN_NS 3600000000000ULL + +/** + * @typedef odp_time_t + * ODP time stamp. Time stamp can represent a time stamp from local or global + * time source. A local time stamp must not be shared between threads. API calls + * work correctly only when all time stamps for input are from the same time + * source. + */ + +/** + * @def ODP_TIME_NULL + * Zero time stamp + */ + +/** + * Time stamp values at ODP startup + */ +typedef struct odp_time_startup_t { + /** Global time at ODP startup */ + odp_time_t global; + + /** Global time in nanoseconds at ODP startup */ + uint64_t global_ns; + +} odp_time_startup_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/timer.h b/include/odp/api/spec/timer.h index 75f9db98e..1e7a06ad4 100644 --- a/include/odp/api/spec/timer.h +++ b/include/odp/api/spec/timer.h @@ -1,127 +1,137 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2019-2023 Nokia */ - /** * @file * * ODP timer service */ -#ifndef ODP_API_TIMER_H_ -#define ODP_API_TIMER_H_ +#ifndef ODP_API_SPEC_TIMER_H_ +#define ODP_API_SPEC_TIMER_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif -/** @defgroup odp_timer ODP TIMER - * @{ - */ - -/** - * @typedef odp_timer_pool_t - * ODP timer pool handle - */ - -/** - * @def ODP_TIMER_POOL_INVALID - * Invalid timer pool handle - */ - -/** - * Clock sources for timers in timer pool. - */ -typedef enum { - /** Use CPU clock as clock source for timers */ - ODP_CLOCK_CPU, - /** Use external clock as clock source for timers */ - ODP_CLOCK_EXT - /* Platform dependent which other clock sources exist */ -} odp_timer_clk_src_t; - -/** - * @typedef odp_timer_t - * ODP timer handle - */ - -/** - * @def ODP_TIMER_INVALID - * Invalid timer handle - */ +#include <odp/api/timer_types.h> +#include <odp/api/event_types.h> +#include <odp/api/pool_types.h> +#include <odp/api/queue_types.h> -/** - * @typedef odp_timeout_t - * ODP timeout handle +/** @addtogroup odp_timer + * @{ */ /** - * @def ODP_TIMEOUT_INVALID - * Invalid timeout handle + * Query timer capabilities per clock source + * + * Outputs timer capabilities on success. Returns -1 if the clock source + * is not supported. + * + * @param clk_src Clock source for timers + * @param[out] capa Pointer to capability structure for output + * + * @retval 0 on success + * @retval -1 when the clock source is not supported + * @retval <-1 on other failures */ +int odp_timer_capability(odp_timer_clk_src_t clk_src, odp_timer_capability_t *capa); /** - * Return values of timer set calls. - */ -typedef enum { -/** - * Timer set operation succeeded + * Timer resolution capability + * + * This function fills in capability limits for timer pool resolution and + * min/max timeout values, based on either resolution or maximum timeout. + * Set the required value to a resolution field (res_ns or res_hz) or to the + * maximum timeout field (max_tmo), and set other fields to zero. A successful + * call fills in the other fields. The call returns a failure, if the user + * defined value exceeds capability limits. Outputted values are minimums for + * 'res_ns' and 'min_tmo', and maximums for 'res_hz' and 'max_tmo'. + * + * @param clk_src Clock source for timers + * @param[in,out] res_capa Resolution capability pointer for input/output. + * Set either a resolution or max timeout field, + * a successful call fills in other fields. + * + * @retval 0 on success + * @retval <0 on failure */ - ODP_TIMER_SUCCESS = 0, -/** - * Timer set operation failed, expiration too early. - * Either retry with a later expiration time or process the timeout - * immediately. */ - ODP_TIMER_TOOEARLY = -1, +int odp_timer_res_capability(odp_timer_clk_src_t clk_src, + odp_timer_res_capability_t *res_capa); /** - * Timer set operation failed, expiration too late. - * Truncate the expiration time against the maximum timeout for the - * timer pool. */ - ODP_TIMER_TOOLATE = -2, -/** - * Timer set operation failed because no timeout event specified and no - * timeout event present in the timer (timer inactive/expired). + * Periodic timer capability + * + * Checks periodic timer capability to support the requested base frequency and other parameters. + * Application sets 'capa' with the requested timer pool base frequency, the maximum + * frequency multiplier and the minimum timeout resolution. If there is no requirement for timeout + * resolution, it is set to zero. + * + * When the call returns success, 'capa' fields are overwritten in following ways. On return value + * of 1, timer supports the requested base frequency exactly, and meets or exceeds other requested + * values. The base frequency value is not modified, but other 'capa' fields are updated with + * resulting maximum capabilities. + * + * When the call returns 0, the requested base frequency is not supported exactly, but timer + * capabilities meet or exceed all other requested values. In this case, the call overwrites + * 'base_freq_hz' with the closest supported frequency and updates other 'capa' fields accordingly. + * + * Failure is returned when the requirements are not supported or the call fails otherwise. + * + * @param clk_src Clock source for timer pool + * @param[in,out] capa Pointer to periodic timer capability for input/output. + * + * @retval 1 Success. Capability matches base frequency, and meets or exceeds other requested + * values. + * @retval 0 Success. Capability does not match base frequency exactly, but meets or exceeds + * other requested values. + * @retval <0 Failure */ - ODP_TIMER_NOEVENT = -3 -} odp_timer_set_t; +int odp_timer_periodic_capability(odp_timer_clk_src_t clk_src, + odp_timer_periodic_capability_t *capa); /** - * @def ODP_TIMER_POOL_NAME_LEN - * Maximum timer pool name length in chars including null char - */ - -/** Timer pool parameters - * Timer pool parameters are used when creating and querying timer pools. + * Initialize timer pool parameters + * + * Initialize an odp_timer_pool_param_t to its default values for all fields. + * + * @param[out] param Pointer to the odp_timer_pool_param_t structure to be initialized */ -typedef struct { - uint64_t res_ns; /**< Timeout resolution in nanoseconds */ - uint64_t min_tmo; /**< Minimum relative timeout in nanoseconds */ - uint64_t max_tmo; /**< Maximum relative timeout in nanoseconds */ - uint32_t num_timers; /**< (Minimum) number of supported timers */ - int priv; /**< Shared (false) or private (true) timer pool */ - odp_timer_clk_src_t clk_src; /**< Clock source for timers */ -} odp_timer_pool_param_t; +void odp_timer_pool_param_init(odp_timer_pool_param_t *param); /** * Create a timer pool * - * The use of pool name is optional. Unique names are not required. + * Creates a timer pool according to the parameters. Use 'timer_type' parameter to select if timers + * are single shot or periodic. All timers in the pool are of the same type. The selected timer + * type defines which other parameters are used or ignored. + * + * The use of pool name is optional. Unique names are not required. Use odp_timer_pool_param_init() + * to initialize timer pool parameters into their default values. + * + * After creation a timer pool can be either started (see odp_timer_pool_start_multi()) or + * destroyed. The returned pool handle cannot be used with any other APIs, except + * odp_timer_pool_to_u64(), before the pool is successfully started. + * + * Periodic timer expiration frequency is a multiple of the timer pool base frequency + * (odp_timer_pool_param_t::base_freq_hz). Depending on implementation, the base frequency may need + * to be selected carefully with respect to the timer pool source clock frequency. Use + * odp_timer_periodic_capability() to check which base frequencies and multipliers are supported. + * + * The call returns failure when requested parameter values are not supported. * * @param name Name of the timer pool or NULL. Maximum string length is * ODP_TIMER_POOL_NAME_LEN. * @param params Timer pool parameters. The content will be copied. * * @return Timer pool handle on success - * @retval ODP_TIMER_POOL_INVALID on failure and errno set + * @retval ODP_TIMER_POOL_INVALID on failure */ -odp_timer_pool_t -odp_timer_pool_create(const char *name, - const odp_timer_pool_param_t *params); +odp_timer_pool_t odp_timer_pool_create(const char *name, const odp_timer_pool_param_t *params); /** * Start a timer pool @@ -130,171 +140,308 @@ odp_timer_pool_create(const char *name, * The purpose of this call is to coordinate the creation of multiple timer * pools that may use the same underlying HW resources. * This function may be called multiple times. + * + * @deprecated Use odp_timer_pool_start_multi() instead */ void odp_timer_pool_start(void); /** + * Start timer pools + * + * Start given timer pools. After a pool has been successfully started the pool handle can be used + * with other APIs. Each timer pool can be started only once. + * + * Returns 'num' when all given timer pools have been successfully started. If the return value + * N < 'num', only the first N pools started successfully and at least some of the remaining ones + * failed to start. In case of a negative return value, none of the pools were started. The + * unstarted timer pools cannot be used anymore (can only be destroyed). + * + * @param timer_pool Array of timer pool handles + * @param num Number of pools to start + * + * @retval num on success + * @retval <num on failure + */ +int odp_timer_pool_start_multi(odp_timer_pool_t timer_pool[], int num); + +/** * Destroy a timer pool * * Destroy a timer pool, freeing all resources. * All timers must have been freed. * - * @param tpid Timer pool identifier + * @param timer_pool Timer pool */ -void odp_timer_pool_destroy(odp_timer_pool_t tpid); +void odp_timer_pool_destroy(odp_timer_pool_t timer_pool); /** * Convert timer ticks to nanoseconds * - * @param tpid Timer pool identifier - * @param ticks Timer ticks + * @param timer_pool Timer pool + * @param ticks Timer ticks * * @return Nanoseconds */ -uint64_t odp_timer_tick_to_ns(odp_timer_pool_t tpid, uint64_t ticks); +uint64_t odp_timer_tick_to_ns(odp_timer_pool_t timer_pool, uint64_t ticks); /** * Convert nanoseconds to timer ticks * - * @param tpid Timer pool identifier - * @param ns Nanoseconds + * @param timer_pool Timer pool + * @param ns Nanoseconds * * @return Timer ticks */ -uint64_t odp_timer_ns_to_tick(odp_timer_pool_t tpid, uint64_t ns); +uint64_t odp_timer_ns_to_tick(odp_timer_pool_t timer_pool, uint64_t ns); /** * Current tick value * - * @param tpid Timer pool identifier + * Returns the current tick value of the timer pool. Timer tick is an implementation defined unit + * of time. Ticks and related nanosecond values are timer pool specific. Those may not start from + * zero, but are guaranteed not to wrap around in at least 10 years from the ODP instance startup. + * + * Timer tick value increments with a constant, timer pool specific frequency. Tick frequency may + * be equal or higher than the requested timer pool resolution. The frequency can be checked with + * odp_timer_pool_info(). Tick value increments with implementation specific step sizes. + * + * Use odp_timer_sample_ticks() to determine offset between tick values of two or more timer pools. + * + * @param timer_pool Timer pool * * @return Current time in timer ticks + * + * @see odp_timer_tick_info_t */ -uint64_t odp_timer_current_tick(odp_timer_pool_t tpid); +uint64_t odp_timer_current_tick(odp_timer_pool_t timer_pool); /** - * ODP timer pool information and configuration + * Sample tick values of timer pools + * + * Reads timer pool tick values simultaneously (or closely back-to-back) from all requested timer + * pools, and outputs those on success. Optionally, outputs corresponding source clock (HW) counter + * values, which are implementation specific and may be used for debugging. When a timer pool does + * not support reading of the source clock value, zero is written instead. Values are written into + * the output arrays in the same order which timer pools were defined. Nothing is written on + * failure. + * + * @param timer_pool Timer pools to sample + * @param[out] tick Tick value array for output (one element per timer pool) + * @param[out] clk_count Source clock counter value array for output (one element per + * timer pool), or NULL when counter values are not requested. + * @param num Number of timer pools to sample + * + * @retval 0 All requested timer pools sampled successfully + * @retval -1 Failure */ - -typedef struct { - odp_timer_pool_param_t param; /**< Parameters specified at creation */ - uint32_t cur_timers; /**< Number of currently allocated timers */ - uint32_t hwm_timers; /**< High watermark of allocated timers */ - const char *name; /**< Name of timer pool */ -} odp_timer_pool_info_t; +int odp_timer_sample_ticks(odp_timer_pool_t timer_pool[], uint64_t tick[], uint64_t clk_count[], + int num); /** * Query timer pool configuration and current state * - * @param tpid Timer pool identifier - * @param[out] info Pointer to information buffer + * @param timer_pool Timer pool + * @param[out] info Pointer to information buffer * * @retval 0 on success * @retval <0 on failure. Info could not be retrieved. */ -int odp_timer_pool_info(odp_timer_pool_t tpid, +int odp_timer_pool_info(odp_timer_pool_t timer_pool, odp_timer_pool_info_t *info); /** * Allocate a timer * - * Create a timer (allocating all necessary resources e.g. timeout event) from - * the timer pool. The user_ptr is copied to timeouts and can be retrieved - * using the odp_timeout_user_ptr() call. + * Allocates a timer from the timer pool. Depending on timer type, the allocated timer is started + * with either odp_timer_start() or odp_timer_periodic_start() call. A timer may be reused multiple + * times before freeing it back into the timer pool. + * + * When timer expires, the timeout event defined in timer start parameters (see + * odp_timer_start_t::tmo_ev or odp_timer_periodic_start_t::tmo_ev) is sent into the provided + * destination queue. * - * @param tpid Timer pool identifier - * @param queue Destination queue for timeout notifications - * @param user_ptr User defined pointer or NULL to be copied to timeouts + * The provided user pointer value is copied into timeout events when the event type is + * ODP_EVENT_TIMEOUT. The value can be retrieved from an event with odp_timeout_user_ptr() call. + * + * @param timer_pool Timer pool + * @param queue Destination queue for timeout events + * @param user_ptr User defined pointer value or NULL * * @return Timer handle on success - * @retval ODP_TIMER_INVALID on failure and errno set. + * @retval ODP_TIMER_INVALID on failure */ -odp_timer_t odp_timer_alloc(odp_timer_pool_t tpid, - odp_queue_t queue, - void *user_ptr); +odp_timer_t odp_timer_alloc(odp_timer_pool_t timer_pool, odp_queue_t queue, const void *user_ptr); /** * Free a timer * - * Free (destroy) a timer, reclaiming associated resources. - * The timeout event for an active timer will be returned. - * The timeout event for an expired timer will not be returned. It is the - * responsibility of the application to handle this timeout when it is received. + * Frees a previously allocated timer. The timer must be inactive when calling this function. + * In other words, the application must cancel an active single shot timer (odp_timer_cancel()) + * successfully or wait it to expire before freeing it. Similarly for an active periodic timer, the + * application must cancel it (odp_timer_periodic_cancel()) and receive the last event from + * the timer (odp_timer_periodic_ack()) before freeing it. + * + * The call returns failure only on non-recoverable errors. Application must not use the timer + * handle anymore after the call, regardless of the return value. * - * @param tim Timer handle - * @return Event handle of timeout event - * @retval ODP_EVENT_INVALID on failure + * @param timer Timer + * + * @retval 0 on success + * @retval <0 on failure */ -odp_event_t odp_timer_free(odp_timer_t tim); +int odp_timer_free(odp_timer_t timer); /** - * Set a timer (absolute time) with a user-provided timeout event + * Start a timer * - * Set (arm) the timer to expire at specific time. The timeout - * event will be enqueued when the timer expires. + * Starts a timer with an expiration time and a timeout event. The timer must not be active when + * calling this function. After a successful call, the timer remains active until it expires or + * is cancelled successfully. An active timer can be restarted with odp_timer_restart(). * - * @param tim Timer - * @param abs_tck Expiration time in absolute timer ticks - * @param[in,out] tmo_ev Reference to an event variable that points to - * timeout event or NULL to reuse the existing timeout event. Any existing - * timeout event that is replaced by a successful set operation will be - * returned here. + * The timeout event is sent to the destination queue when the timer expires. The expiration time + * may be passed as absolute timer ticks or ticks relative to the current time. Use 'tick_type' + * parameter to select between the tick types. Current time of the timer pool can be read with + * odp_timer_current_tick(). * - * @retval ODP_TIMER_SUCCESS Operation succeeded - * @retval ODP_TIMER_TOOEARLY Operation failed because expiration tick too - * early - * @retval ODP_TIMER_TOOLATE Operation failed because expiration tick too - * late - * @retval ODP_TIMER_NOEVENT Operation failed because timeout event not - * specified in odp_timer_set call and not present in timer + * The timer is not started when a failure is returned. + * + * @param timer Timer to be started + * @param start_param Timer start parameters + * + * @retval ODP_TIMER_SUCCESS Success + * @retval ODP_TIMER_TOO_NEAR Failure. The expiration time passed already, or is too near to + * the current time. + * @retval ODP_TIMER_TOO_FAR Failure. The expiration time is too far from the current time. + * @retval ODP_TIMER_FAIL Other failure. */ -int odp_timer_set_abs(odp_timer_t tim, - uint64_t abs_tck, - odp_event_t *tmo_ev); +int odp_timer_start(odp_timer_t timer, const odp_timer_start_t *start_param); /** - * Set a timer with a relative expiration time and user-provided event. + * Restart a timer + * + * A successful restart call updates the expiration time of an active timer. The timeout event + * is not changed. + * + * The timer is not modified when a failure is returned. The call returns #ODP_TIMER_FAIL if + * the timer has expired already, or is so close to expire that it cannot be restarted anymore. + * A failure is returned also when the new expiration time is too near to the current time + * (#ODP_TIMER_TOO_NEAR) or too far from the current time (#ODP_TIMER_TOO_FAR). * - * Set (arm) the timer to expire at a relative future time. + * The new expiration time is passed the same way as with odp_timer_start() call. * - * @param tim Timer - * @param rel_tck Expiration time in timer ticks relative to current time of - * the timer pool the timer belongs to - * @param[in,out] tmo_ev Reference to an event variable that points to - * timeout event or NULL to reuse the existing timeout event. Any existing - * timeout event that is replaced by a successful set operation will be - * returned here. + * @param timer Timer to be restarted + * @param start_param Timer start parameters. Value of 'tmo_ev' parameter is ignored. * - * @retval ODP_TIMER_SUCCESS Operation succeeded - * @retval ODP_TIMER_TOOEARLY Operation failed because expiration tick too - * early - * @retval ODP_TIMER_TOOLATE Operation failed because expiration tick too - * late - * @retval ODP_TIMER_NOEVENT Operation failed because timeout event not - * specified in call and not present in timer + * @retval ODP_TIMER_SUCCESS Success + * @retval ODP_TIMER_TOO_NEAR Failure. The new expiration time passed already, or is too near to + * the current time. + * @retval ODP_TIMER_TOO_FAR Failure. The new expiration time is too far from the current time. + * @retval ODP_TIMER_FAIL Failure. The timer expired already, or other failure. */ -int odp_timer_set_rel(odp_timer_t tim, - uint64_t rel_tck, - odp_event_t *tmo_ev); +int odp_timer_restart(odp_timer_t timer, const odp_timer_start_t *start_param); + +/** + * Start a periodic timer + * + * Starts a timer that delivers timeout events periodically to the destination queue starting + * from the first expiration time provided. The timer must have been allocated from a pool of + * periodic timers. The timer must not be active when calling this function. After a successful + * call, the timer remains active until it is cancelled and all its timeout events have been + * acknowledged. + * + * Timer expiration frequency (period) is defined as a multiple of the timer pool base frequency + * (odp_timer_pool_param_t::base_freq_hz). The timeout event type must be ODP_EVENT_TIMEOUT + * (odp_timeout_t). + * + * Periodic timers cannot be restarted. If the period needs to be changed, the timer is first + * cancelled and then started again with new parameters. + * + * Application must acknowledge each timeout event with odp_timer_periodic_ack() call. The call + * should be made as soon as possible after receiving the event. + * + * The timer is not started when a failure is returned. + * + * @param timer Periodic timer to be started + * @param start_param Periodic timer start parameters + * + * @retval ODP_TIMER_SUCCESS Success + * @retval ODP_TIMER_TOO_NEAR Failure. The first expiration time passed already, or is too near to + * the current time. + * @retval ODP_TIMER_TOO_FAR Failure. The first expiration time is too far from the current time. + * @retval ODP_TIMER_FAIL Other failure. + * + * @see odp_timer_periodic_cancel() + */ +int odp_timer_periodic_start(odp_timer_t timer, const odp_timer_periodic_start_t *start_param); + +/** + * Acknowledge timeout from a periodic timer + * + * This call is valid only for periodic timers. Each timeout event from a periodic timer must be + * acknowledged with this call. Acknowledgment should be done as soon as possible after receiving + * the event. A late call may affect accuracy of the following period(s). However, a missing + * acknowledgment may not stop timeout event delivery to the destination queue, and thus the same + * event may appear in the destination queue multiple times (when application falls behind). + * + * Normally, the acknowledgment call returns zero on success and consumes the timeout event. + * Application must not use the event anymore after this. A greater than zero return value + * indicates timeout events from a cancelled timer. These events may not arrive at the + * requested interval, but are used to finalize the timer cancel request. Return value of 2 marks + * the last event from a cancelled timer. After receiving it application may free the timer and + * the timeout event. + * + * @param timer Periodic timer + * @param tmo_ev Timeout event that was received from the periodic timer + * + * @retval 2 Success, the last event from a cancelled timer. The call did not consume + * the event. + * @retval 1 Success, an event from a cancelled timer. The call consumed the event. + * @retval 0 Success, the call consumed the event. + * @retval <0 Failure, the call did not consume the event. + */ +int odp_timer_periodic_ack(odp_timer_t timer, odp_event_t tmo_ev); + +/** + * Cancel a periodic timer + * + * Cancel a previously started periodic timer. A successful operation stops timer expiration. + * The timer delivers remaining timeout event(s) into the destination queue. Note that these events + * may not arrive at the requested interval. Return value of odp_timer_periodic_ack() call + * will indicate the last timeout event from the timer. Application may free the timer and + * the timeout event only after receiving the last event. + * + * @param timer Timer + * + * @retval 0 Periodic timer expiration stopped. The timeout event will be received through + * the destination queue. + * @retval <0 Timer cancel failed. + */ +int odp_timer_periodic_cancel(odp_timer_t timer); /** * Cancel a timer * - * Cancel a timer, preventing future expiration and delivery. Return any - * present timeout event. + * Cancels a previously started single shot timer. A successful operation (#ODP_TIMER_SUCCESS) + * prevents timer expiration and returns the timeout event back to application. Application may + * use or free the event normally. + * + * When the timer is close to expire or has expired already, the call may not be able cancel it + * anymore. In this case, the call returns #ODP_TIMER_TOO_NEAR and the timeout is delivered to + * the destination queue. * - * A timer that has already expired may be impossible to cancel and the timeout - * will instead be delivered to the destination queue. + * @param timer Timer + * @param[out] tmo_ev Pointer to an event handle for output. Event handle is written only + * on success. * - * @param tim Timer - * @param[out] tmo_ev Pointer to an event variable - * @retval 0 Success, active timer cancelled, timeout returned in '*tmo_ev' - * @retval <0 on failure (timer inactive or already expired) + * @retval ODP_TIMER_SUCCESS Timer was cancelled successfully. Timeout event returned in 'tmo_ev'. + * @retval ODP_TIMER_TOO_NEAR Timer cannot be cancelled. Timer has expired already, or cannot be + * cancelled due to close expiration time. + * @retval ODP_TIMER_FAIL Other failure. */ -int odp_timer_cancel(odp_timer_t tim, odp_event_t *tmo_ev); +int odp_timer_cancel(odp_timer_t timer, odp_event_t *tmo_ev); /** - * Return timeout handle that is associated with timeout event + * Get timeout handle from a ODP_EVENT_TIMEOUT type event * * @param ev An event of type ODP_EVENT_TIMEOUT * @@ -303,6 +450,17 @@ int odp_timer_cancel(odp_timer_t tim, odp_event_t *tmo_ev); odp_timeout_t odp_timeout_from_event(odp_event_t ev); /** + * Convert multiple timeout events to timeout handles + * + * All events must be of type ODP_EVENT_TIMEOUT. + * + * @param[out] tmo Timeout handle array for output + * @param ev Array of event handles to convert + * @param num Number of timeouts and events + */ +void odp_timeout_from_event_multi(odp_timeout_t tmo[], const odp_event_t ev[], int num); + +/** * Convert timeout handle to event handle * * @param tmo Timeout handle @@ -313,14 +471,17 @@ odp_event_t odp_timeout_to_event(odp_timeout_t tmo); /** * Check for fresh timeout + * * If the corresponding timer has been reset or cancelled since this timeout * was enqueued, the timeout is stale (not fresh). * * @param tmo Timeout handle * @retval 1 Timeout is fresh * @retval 0 Timeout is stale + * + * @deprecated The function will be removed in a future API version. */ -int odp_timeout_fresh(odp_timeout_t tmo); +int ODP_DEPRECATE(odp_timeout_fresh)(odp_timeout_t tmo); /** * Return timer handle for the timeout @@ -332,7 +493,15 @@ int odp_timeout_fresh(odp_timeout_t tmo); odp_timer_t odp_timeout_timer(odp_timeout_t tmo); /** - * Return expiration tick for the timeout + * Timeout expiration tick + * + * Returns the absolute expiration time (in timer ticks) that was used to set + * (or reset) the timer. For timers set with absolute expiration time this + * equals the provided tick value. + * + * For periodic timers, returns the expiration time of the period, or zero. + * When periodic timer implementation cannot return expiration time, it returns zero + * for all timeouts from the timer pool. * * @param tmo Timeout handle * @@ -342,6 +511,7 @@ uint64_t odp_timeout_tick(odp_timeout_t tmo); /** * Return user pointer for the timeout + * * The user pointer was specified when the timer was allocated. * * @param tmo Timeout handle @@ -351,6 +521,19 @@ uint64_t odp_timeout_tick(odp_timeout_t tmo); void *odp_timeout_user_ptr(odp_timeout_t tmo); /** + * Timeout user area + * + * Returns pointer to the user area associated with the timeout. Size of the area is fixed + * and defined in timeout pool parameters. + * + * @param tmo Timeout handle + * + * @return Pointer to the user area of the timeout + * @retval NULL The timeout does not have user area + */ +void *odp_timeout_user_area(odp_timeout_t tmo); + +/** * Timeout alloc * * Allocates timeout from pool. Pool must be created with ODP_POOL_TIMEOUT type. @@ -363,6 +546,20 @@ void *odp_timeout_user_ptr(odp_timeout_t tmo); odp_timeout_t odp_timeout_alloc(odp_pool_t pool); /** + * Allocate multiple timeouts + * + * Otherwise like odp_timeout_alloc(), but allocates multiple timeouts from a pool. + * + * @param pool Pool handle + * @param[out] tmo Array of timeout handles for output + * @param num Number of timeouts to allocate + * + * @return Number of timeouts actually allocated (0 ... num) + * @retval <0 on failure + */ +int odp_timeout_alloc_multi(odp_pool_t pool, odp_timeout_t tmo[], int num); + +/** * Timeout free * * Frees the timeout back to the pool it was allocated from. @@ -372,43 +569,83 @@ odp_timeout_t odp_timeout_alloc(odp_pool_t pool); void odp_timeout_free(odp_timeout_t tmo); /** + * Free multiple timeouts + * + * Otherwise like odp_timeout_free(), but frees multiple timeouts to their originating pools. + * + * @param tmo Array of timeout handles + * @param num Number of timeouts to free + */ +void odp_timeout_free_multi(odp_timeout_t tmo[], int num); + +/** + * Print timer pool debug information + * + * Prints implementation specific debug information about + * the timer pool to the ODP log. + * + * @param timer_pool Timer pool handle + */ +void odp_timer_pool_print(odp_timer_pool_t timer_pool); + +/** + * Print timer debug information + * + * Prints implementation specific debug information about + * the timer to the ODP log. + * + * @param timer Timer handle + */ +void odp_timer_print(odp_timer_t timer); + +/** + * Print timeout debug information + * + * Prints implementation specific debug information about + * the timeout to the ODP log. + * + * @param tmo Timeout handle + */ +void odp_timeout_print(odp_timeout_t tmo); + +/** * Get printable value for an odp_timer_pool_t * - * @param hdl odp_timer_pool_t handle to be printed - * @return uint64_t value that can be used to print/display this - * handle + * @param timer_pool odp_timer_pool_t handle to be printed + * + * @return uint64_t value that can be used to print/display this handle * * @note This routine is intended to be used for diagnostic purposes * to enable applications to generate a printable value that represents * an odp_timer_pool_t handle. */ -uint64_t odp_timer_pool_to_u64(odp_timer_pool_t hdl); +uint64_t odp_timer_pool_to_u64(odp_timer_pool_t timer_pool); /** * Get printable value for an odp_timer_t * - * @param hdl odp_timer_t handle to be printed - * @return uint64_t value that can be used to print/display this - * handle + * @param timer odp_timer_t handle to be printed + * + * @return uint64_t value that can be used to print/display this handle * * @note This routine is intended to be used for diagnostic purposes * to enable applications to generate a printable value that represents * an odp_timer_t handle. */ -uint64_t odp_timer_to_u64(odp_timer_t hdl); +uint64_t odp_timer_to_u64(odp_timer_t timer); /** * Get printable value for an odp_timeout_t * - * @param hdl odp_timeout_t handle to be printed - * @return uint64_t value that can be used to print/display this - * handle + * @param tmo odp_timeout_t handle to be printed + * + * @return uint64_t value that can be used to print/display this handle * * @note This routine is intended to be used for diagnostic purposes * to enable applications to generate a printable value that represents * an odp_timeout_t handle. */ -uint64_t odp_timeout_to_u64(odp_timeout_t hdl); +uint64_t odp_timeout_to_u64(odp_timeout_t tmo); /** * @} diff --git a/include/odp/api/spec/timer_types.h b/include/odp/api/spec/timer_types.h new file mode 100644 index 000000000..7db57c340 --- /dev/null +++ b/include/odp/api/spec/timer_types.h @@ -0,0 +1,620 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2019-2023 Nokia + */ + +/** + * @file + * + * ODP timer API type definitions + */ + +#ifndef ODP_API_SPEC_TIMER_TYPES_H_ +#define ODP_API_SPEC_TIMER_TYPES_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/deprecated.h> +#include <odp/api/event_types.h> +#include <odp/api/std_types.h> + +/** @defgroup odp_timer ODP TIMER + * Timer generating timeout events. + * @{ + */ + +/** + * @typedef odp_timer_pool_t + * ODP timer pool handle + */ + +/** + * @def ODP_TIMER_POOL_INVALID + * Invalid timer pool handle + */ + +/** + * @typedef odp_timer_t + * ODP timer handle + */ + +/** + * @def ODP_TIMER_INVALID + * Invalid timer handle + */ + +/** + * @typedef odp_timeout_t + * ODP timeout handle + */ + +/** + * @def ODP_TIMEOUT_INVALID + * Invalid timeout handle + */ + +/** + * @def ODP_TIMER_POOL_NAME_LEN + * Maximum timer pool name length in chars including null char + */ + +/** + * Timer type + * + * There are two types of timers. A single shot timer (ODP_TIMER_TYPE_SINGLE) is started with + * an expiration time for each timeout. A periodic timer (ODP_TIMER_TYPE_PERIODIC) keeps expiring + * and sending timeout events with the given period until it is cancelled. + */ +typedef enum { + /** Single shot timer */ + ODP_TIMER_TYPE_SINGLE = 0, + + /** Periodic timer */ + ODP_TIMER_TYPE_PERIODIC + +} odp_timer_type_t; + +/** + * Timer resolution capability + */ +typedef struct { + /** Timeout resolution in nanoseconds */ + uint64_t res_ns; + + /** Timeout resolution in hertz */ + uint64_t res_hz; + + /** Minimum relative timeout in nanoseconds */ + uint64_t min_tmo; + + /** Maximum relative timeout in nanoseconds */ + uint64_t max_tmo; + +} odp_timer_res_capability_t; + +/** + * Periodic timer capability + */ +typedef struct { + /** + * Periodic timer pool base frequency in hertz + * + * Base frequency is represented as a fractional number where the fraction part is always + * less than one. In other words, the integer part specifies whole hertz whereas + * the fraction part specifies parts of a hertz (if any). The fraction part does not + * need to be reduced to its lowest terms - e.g. 100.5 Hz may be represented as 100 1/2 Hz, + * 100 5/10 Hz, or 100 Hz with some other equivalent fraction part. + */ + odp_fract_u64_t base_freq_hz; + + /** Maximum base frequency multiplier */ + uint64_t max_multiplier; + + /** Timeout resolution in nanoseconds */ + uint64_t res_ns; + +} odp_timer_periodic_capability_t; + +/** + * Timer capability + */ +typedef struct { + /** Maximum number of timer pools + * + * The total number of timer pools that can be created combining both types and + * different clock sources. + */ + uint32_t max_pools_combined; + + /** Maximum number of timer pools for single shot timers (per clock source) */ + uint32_t max_pools; + + /** Maximum number of single shot timers in a pool + * + * The value of zero means that limited only by the available + * memory size for the pool. */ + uint32_t max_timers; + + /** Highest timer resolution in nanoseconds. + * + * This defines the highest resolution supported by a timer. + * It's the minimum valid value for 'res_ns' timer pool + * parameter. + * + * This value is equal to 'max_res.res_ns' capability. + */ + uint64_t highest_res_ns; + + /** + * Maximum resolution + * + * This defines the highest resolution supported by a timer, with + * limits to min/max timeout values. The highest resolution for a timer + * pool is defined by 'max_res.res_ns' in nanoseconds and + * 'max_res.res_hz' in hertz. + * When this resolution is used: + * - 'min_tmo' parameter value must be in minimum 'max_res.min_tmo' + * - 'max_tmo' parameter value must be in maximum 'max_res.max_tmo' + */ + odp_timer_res_capability_t max_res; + + /** + * Maximum timeout length + * + * This defines the maximum relative timeout value supported by a timer, + * with limits to min timeout and max resolution values. The maximum + * value for 'max_tmo' timer pool parameter is defined by + * 'max_tmo.max_tmo'. When this max timeout value is used: + * - 'min_tmo' parameter value must be in minimum 'max_tmo.min_tmo' + * - 'res_ns' parameter value must be in minimum 'max_tmo.res_ns' or + * - 'res_hz' parameter value must be in maximum 'max_tmo.res_hz' + */ + odp_timer_res_capability_t max_tmo; + + /** + * Scheduled queue destination support + * + * This defines whether schedule queues are supported as timeout + * destination queues. + * 0: Scheduled queues are not supported as timeout destination queues + * 1: Scheduled queues are supported as timeout destination queues + * @see odp_timer_alloc() + */ + odp_bool_t queue_type_sched; + + /** + * Plain queue destination support + * + * This defines whether plain queues are supported as timeout + * destination queues. + * 0: Plain queues are not supported as timeout destination queues + * 1: Plain queues are supported as timeout destination queues + * @see odp_timer_alloc() + */ + odp_bool_t queue_type_plain; + + /** Periodic timer capabilities */ + struct { + /** Maximum number of timer pools for periodic timers + * + * When zero, periodic timers (#ODP_TIMER_TYPE_PERIODIC) are not supported. + */ + uint32_t max_pools; + + /** Maximum number of periodic timers in a pool */ + uint32_t max_timers; + + /** Minimum supported base frequency value */ + odp_fract_u64_t min_base_freq_hz; + + /** Maximum supported base frequency value */ + odp_fract_u64_t max_base_freq_hz; + + } periodic; + +} odp_timer_capability_t; + +/** + * Clock sources for timer pools + * + * ODP_CLOCK_DEFAULT is the default clock source and it is supported always. It is implementation + * defined which other clock sources are supported. See from implementation documentation how the + * supported clock sources are mapped into these enumerations. + */ +typedef enum { + /** Clock source number 0 */ + ODP_CLOCK_SRC_0, + + /** Clock source number 1 */ + ODP_CLOCK_SRC_1, + + /** Clock source number 2 */ + ODP_CLOCK_SRC_2, + + /** Clock source number 3 */ + ODP_CLOCK_SRC_3, + + /** Clock source number 4 */ + ODP_CLOCK_SRC_4, + + /** Clock source number 5 */ + ODP_CLOCK_SRC_5, + + /** Number of clock source enumerations */ + ODP_CLOCK_NUM_SRC + +} odp_timer_clk_src_t; + +/** The default clock source */ +#define ODP_CLOCK_DEFAULT ODP_CLOCK_SRC_0 + +/** + * Timer expiration mode + * + * Expiration mode selects how timer expiration tick is interpreted. In ODP_TIMER_EXP_RELAXED mode, + * timer implementation may round the requested time up or down within resolution limits, and + * therefore application may receive timeouts slightly before or after the requested time. + * In ODP_TIMER_EXP_AFTER mode, timers are limited to expire exactly on the requested time or + * after it, but never before the time. + */ +typedef enum { + /** + * Expiration after the target time + * + * Timers expire on the specified time or after it, but never before it. */ + ODP_TIMER_EXP_AFTER = 0, + + /** + * Expiration relaxed + * + * Timers may expire before or after the specified time (within resolution limits). + * Depending on implementation, this may improve expiration accuracy compared to + * ODP_TIMER_EXP_AFTER. + */ + ODP_TIMER_EXP_RELAXED + +} odp_timer_exp_mode_t; + +/** + * Timer pool parameters + */ +typedef struct { + /** Timer type + * + * Select whether the pool is created for single shot (#ODP_TIMER_TYPE_SINGLE) or + * periodic (#ODP_TIMER_TYPE_PERIODIC) timers. All timers in a pool are of the same type. + * Timer capabilities specify how many pools of each type are supported. + * + * The default value is ODP_TIMER_TYPE_SINGLE. + */ + odp_timer_type_t timer_type; + + /** Clock source for timers + * + * The default value is ODP_CLOCK_DEFAULT. */ + odp_timer_clk_src_t clk_src; + + /** Timer expiration mode + * + * The default value is ODP_TIMER_EXP_AFTER. */ + odp_timer_exp_mode_t exp_mode; + + /** Timeout resolution in nanoseconds. Timer pool must serve timeouts + * with this or higher resolution. The minimum valid value (highest + * resolution) is defined by timer resolution capability. When this + * parameter is used, set 'res_hz' to zero. The default value is zero. */ + uint64_t res_ns; + + /** Timeout resolution in hertz. This may be used to specify the highest + * required resolution in hertz instead of nanoseconds. When this + * parameter is used, set 'res_ns' to zero. The default value is zero. */ + uint64_t res_hz; + + /** Minimum relative timeout in nanoseconds + * + * All requested timeouts will be at least this many nanoseconds after the current + * time of the timer pool. Timer set functions return an error, if too short timeout + * was requested. The value may be also smaller than the requested resolution. + * + * The default value is zero. Ignored when timer type is periodic. + */ + uint64_t min_tmo; + + /** Maximum relative timeout in nanoseconds + * + * All requested timeouts will be at most this many nanoseconds after the current + * time of the timer pool. Timer set functions return an error, if too long timeout was + * requested. + * + * Ignored when timer type is periodic. + */ + uint64_t max_tmo; + + /** Periodic timer parameters + * + * Additional parameters for periodic timers. Ignored when timer type is single shot. + */ + struct { + /** Timer pool base frequency in hertz + * + * A periodic timer pool has a base frequency. Each timer of the pool has + * an expiration frequency that is an integer multiple of the base frequency. + * Depending on the implementation, base frequency may need to be selected + * carefully to avoid timer periods to drift against the source clock. + * Use odp_timer_periodic_capability() to check base frequency support, + * and resulting max_multiplier and resolution values. + * + * Fraction part of the value is always less than one, see + * odp_timer_periodic_capability_t::base_freq_hz for details. The default value + * is zero. + * + * An example with two timer frequencies: + * base_freq_hz.integer = 33333, .numer = 1, .denom = 3 + * max_multiplier = 30 + * timer A: freq_multiplier = 2 + * timer frequency: 2 * 33333 1/3 Hz = 66.6666..kHz + * timer B: freq_multiplier = 30 + * timer frequency: 30 * 33333 1/3 Hz = 1 MHz + */ + odp_fract_u64_t base_freq_hz; + + /** Maximum base frequency multiplier + * + * This is the maximum base frequency multiplier value + * (odp_timer_periodic_start_t::freq_multiplier) for any timer in the pool. + */ + uint64_t max_multiplier; + + } periodic; + + /** Number of timers in the pool. */ + uint32_t num_timers; + + /** Thread private timer pool. When zero, multiple thread may use the + * timer pool concurrently. When non-zero, only single thread uses the + * timer pool (concurrently). The default value is zero. */ + int priv; + +} odp_timer_pool_param_t; + +/** + * Timer tick type + */ +typedef enum { + /** Relative ticks + * + * Timer tick value is relative to the current time (odp_timer_current_tick()) + * of the timer pool. + */ + ODP_TIMER_TICK_REL = 0, + + /** Absolute ticks + * + * Timer tick value is absolute timer pool ticks. + */ + ODP_TIMER_TICK_ABS + +} odp_timer_tick_type_t; + +/** + * Timer start parameters + */ +typedef struct odp_timer_start_t { + /** Tick type + * + * Defines if expiration time ticks are absolute or relative. + */ + odp_timer_tick_type_t tick_type; + + /** Expiration time in ticks + * + * New expiration time for the timer to be started/restarted. When 'tick_type' is + * ODP_TIMER_TICK_REL, expiration time is odp_timer_current_tick() + 'tick'.*/ + uint64_t tick; + + /** Timeout event + * + * When the timer expires, this event is enqueued to the destination queue of the timer. + * The event type can be ODP_EVENT_BUFFER, ODP_EVENT_PACKET or ODP_EVENT_TIMEOUT. It is + * recommended to use ODP_EVENT_TIMEOUT type events. Those (odp_timeout_t) carry also + * timeout specific metadata. + * + * This field is ignored by odp_timer_restart() calls. + */ + odp_event_t tmo_ev; + +} odp_timer_start_t; + +/** + * Periodic timer start parameters + * + * A periodic timer pool can be thought as a wall clock, where the base frequency + * (odp_timer_pool_param_t::base_freq_hz) defines how many times per second a pointer travels + * around the clock face. When a timer (see "Timer A" in the figure) is started with the base + * frequency multiplier (odp_timer_periodic_start_t::freq_multiplier) of one, a single reference + * to it is placed into the clock face. When a timer (see "Timer B") is started with the multiplier + * value of two, two references to it is placed into opposite sides of the clock face, etc. When the + * pointer reaches a timer reference, the timer expires and a timeout event is sent to the + * destination queue. The maximum base frequency multiplier (odp_timer_pool_param_t::max_multiplier) + * defines the maximum number of references a timer can have on the clock face. The first + * expiration time parameter (odp_timer_periodic_start_t::first_tick) is used to tune timer + * reference placement on the clock face against the current time (the current pointer location). + * + * @code{.unparsed} + * + * Periodic timer pool + * + * o + * o o <--- Timer B + * + * o \ o + * \ + * Timer B ---> o \ o <--- Timer A + * o + * + * + * Timer pool: max_multiplier = 8 + * Timer A: freq_multiplier = 1 + * Timer B: freq_multiplier = 2 + * + * @endcode + * + */ +typedef struct odp_timer_periodic_start_t { + /** First expiration time + * + * The first expiration time in absolute timer ticks. When zero, the first expiration time + * is one period after the current time, or as close to that as the implementation can + * achieve. After the first expiration, timer expiration continues with the defined + * frequency. The tick value must be less than one timer period after the current time. + */ + uint64_t first_tick; + + /** Base frequency multiplier + * + * Periodic timer expiration frequency is defined as a multiple of the timer pool + * base frequency: timer frequency (Hz) = base_freq_hz * freq_multiplier. Valid values + * range from 1 to timer pool parameter 'max_multiplier'. + * + * Depending on the implementation, a multiplier value that is a divisor of + * 'max_multiplier' may improve timer expiration accuracy: + * max_multiplier = k * freq_multiplier, where k is an integer. + */ + uint64_t freq_multiplier; + + /** Timeout event + * + * This event is enqueued to the destination queue when the timer expires. The event type + * must be ODP_EVENT_TIMEOUT. + */ + odp_event_t tmo_ev; + +} odp_timer_periodic_start_t; + +/** + * Return values for timer start, restart and cancel calls + */ +typedef enum { + /** + * Timer operation succeeded + * + * Timer start, restart and cancel operations may return this value. + */ + ODP_TIMER_SUCCESS = 0, + + /** + * Timer operation failed, too near to the current time + * + * The operation failed because the requested time/timer has expired already, or is too + * near to the current time. Timer start, restart and cancel operations may return this + * value. + */ + ODP_TIMER_TOO_NEAR = -1, + + /** + * Timer operation failed, too far from the current time + * + * The operation failed because the requested time is too far from the current time. + * Only timer start and restart operations may return this value. + */ + ODP_TIMER_TOO_FAR = -2, + + /** + * Timer operation failed + * + * The operation failed due to some other reason than timing of the request. Timer start, + * restart and cancel operations may return this value. + */ + ODP_TIMER_FAIL = -3 + +} odp_timer_retval_t; + +/** + * For backwards compatibility, odp_timer_set_t is synonym of odp_timer_retval_t + * + * @deprecated Use odp_timer_retval_t instead. + */ +typedef odp_timer_retval_t ODP_DEPRECATE(odp_timer_set_t); + +/** + * Timer tick information + */ +typedef struct odp_timer_tick_info_t { + /** + * Timer tick frequency in hertz + * + * Timer tick frequency expressed as a fractional number. The integer part contains + * full hertz. The fraction part (numerator / denominator) contains parts of + * a hertz to be added with the integer. + * + * For example, a timer tick frequency of 333 333 and 1/3 Hz could be presented with + * these values: integer = 333 333, numer = 1, denom = 3. Implementation may choose numer + * and denom values freely. + */ + odp_fract_u64_t freq; + + /** + * One timer tick in nanoseconds + * + * Nanoseconds per tick is expressed as a fractional number. The integer part contains + * full nanoseconds. The fraction part (numerator / denominator) contains parts of + * a nanosecond to be added with the integer. + * + * For example, a timer tick period of 3.125 nanoseconds (320MHz) could be presented with + * these values: integer = 3, numer = 125 000 000, denom = 1 000 000 000. Implementation + * may choose numer and denom values freely. + */ + odp_fract_u64_t nsec; + + /** + * One timer tick in source clock cycles + * + * The clock cycle count is expressed as a fractional number. The integer part contains + * full clock cycles. The fraction part (numerator / denominator) contains parts of + * a clock cycle to be added with the integer. + * + * For example, a timer tick period of 42 and 1/3 source clock cycles could be presented + * with these values: integer = 42, numer = 1, denom = 3. Implementation may choose numer + * and denom values freely. + * + * The value is zero, when there is no direct connection between tick and the source + * clock signal. + */ + odp_fract_u64_t clk_cycle; + +} odp_timer_tick_info_t; + +/** + * ODP timer pool information and configuration + */ +typedef struct { + /** Parameters specified at creation */ + odp_timer_pool_param_t param; + + /** Number of currently allocated timers */ + uint32_t cur_timers; + + /** High watermark of allocated timers */ + uint32_t hwm_timers; + + /** Name of timer pool */ + const char *name; + + /** Timer pool tick information */ + odp_timer_tick_info_t tick_info; + +} odp_timer_pool_info_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/traffic_mngr.h b/include/odp/api/spec/traffic_mngr.h index 71198bbdd..117ed22cd 100644 --- a/include/odp/api/spec/traffic_mngr.h +++ b/include/odp/api/spec/traffic_mngr.h @@ -1,19 +1,19 @@ -/** Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2021-2022 Nokia + * Copyright (c) 2022 Marvell */ -#ifndef ODP_TRAFFIC_MNGR_H_ -#define ODP_TRAFFIC_MNGR_H_ +#ifndef ODP_API_SPEC_TRAFFIC_MNGR_H_ +#define ODP_API_SPEC_TRAFFIC_MNGR_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus extern "C" { #endif +#include <odp/api/packet_io_types.h> #include <odp/api/std_types.h> -#include <odp/api/packet_io.h> /** * @file @@ -23,7 +23,7 @@ extern "C" { /** @defgroup odp_traffic_mngr ODP TRAFFIC MNGR * @{ * - * An API for configuring and using Traffic Management systems + * Traffic management on packet output. * * This file forms a simple interface for creating, configuring and using * Traffic Management (TM) subsystems. By TM subsystem it is meant a general @@ -37,7 +37,7 @@ extern "C" { * based systems or one or more hybrid systems - where because of * hardware constraints some of the packet scheduling is done in hardware * and some is done in software. In addition, there may also be additional - * API's beyond those described here for (a) controlling advanced capabilities + * APIs beyond those described here for (a) controlling advanced capabilities * supported by specific hardware, software or hybrid subsystems or (b) * dealing with constraints and limitations of specific implementations. */ @@ -75,7 +75,7 @@ extern "C" { /** * @def ODP_TM_MAX_TM_QUEUES - * The largest number of tm_queues that can handled by any one TM system. + * The largest number of tm_queues that can be handled by any one TM system. */ /** @@ -96,23 +96,6 @@ extern "C" { */ /** - * @def ODP_TM_MIN_SHAPER_BW - * The largest amount of bandwidth that any shaper's peak or commit rate can - * be set to. It is in units of 1000 bytes/second. - */ - -/** - * @def ODP_TM_MAX_SHAPER_BW - * The largest amount of bandwidth that any shaper's peak or commit rate can - * be set to. It is in units of 1000 bytes/second. - */ - -/** - * @def ODP_NUM_SHAPER_COLORS - * The number of enumeration values defined in the odp_tm_shaper_color_t type. - */ - -/** * @def ODP_TM_INVALID_PRIORITY * Used to indicate an invalid priority value. */ @@ -143,7 +126,7 @@ extern "C" { /** * @typedef odp_tm_node_t - * Each odp_tm_queue_t value is an opaque ODP handle representing a specific + * Each odp_tm_node_t value is an opaque ODP handle representing a specific * tm node within a specific TM system. */ @@ -189,6 +172,63 @@ extern "C" { * tree/hierarchy of nodes. */ +/** + * TM queue specific statistics counters + */ +typedef struct odp_tm_queue_stats_t { + /** Number of octets in successfully transmitted packets. In case of + * Ethernet, packet size includes MAC header. */ + uint64_t octets; + + /** Number of successfully transmitted packets. */ + uint64_t packets; + + /** Number of packets discarded due to other reasons (e.g. aging) than + * errors. */ + uint64_t discards; + + /** Number of octets in packets discarded due to other reasons (e.g. + * aging) than errors. */ + uint64_t discard_octets; + + /** Number of packets with transmission errors. */ + uint64_t errors; + +} odp_tm_queue_stats_t; + +/** + * TM queue level statistics capabilities + */ +typedef struct odp_tm_queue_stats_capability_t { + /** Supported counters */ + union { + /** Statistics counters in a bit field structure */ + struct { + /** See odp_tm_queue_stats_t::octets */ + uint64_t octets : 1; + + /** See odp_tm_queue_stats_t::packets */ + uint64_t packets : 1; + + /** See odp_tm_queue_stats_t::discards */ + uint64_t discards : 1; + + /** See odp_tm_queue_stats_t::discard_octets */ + uint64_t discard_octets : 1; + + /** See odp_tm_queue_stats_t::errors */ + uint64_t errors : 1; + + } counter; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or + * for bitwise operations over the entire structure. */ + uint64_t all_counters; + }; +} odp_tm_queue_stats_capability_t; + /** Per Level Capabilities * * The odp_tm_level_capabilities_t record is used to describe the capabilities @@ -213,17 +253,71 @@ typedef struct { /** min_weight only has significance when the weights_supported field * below is true, in which case it specifies the smallest value * of the weights allowed at this level. */ - uint8_t min_weight; + uint32_t min_weight; /** max_weight only has significance when the weights_supported field * below is true, in which case it specifies the largest value * of the weights allowed at this level. */ - uint8_t max_weight; - - /** tm_node_shaper_supported indicates that the tm_nodes at this level - * all support TM shaping, */ + uint32_t max_weight; + + /** Minimum allowed value for odp_tm_shaper_params_t::commit_burst and + * odp_tm_shaper_params_t::peak_burst when + * odp_tm_shaper_params_t::packet_mode is true. + */ + uint32_t min_burst_packets; + + /** Maximum allowed value for odp_tm_shaper_params_t::commit_burst and + * odp_tm_shaper_params_t::peak_burst when + * odp_tm_shaper_params_t::packet_mode is true. + */ + uint32_t max_burst_packets; + + /** Minimum allowed value for odp_tm_shaper_params_t::commit_rate and + * odp_tm_shaper_params_t::peak_rate when + * odp_tm_shaper_params_t::packet_mode is true. + */ + uint64_t min_rate_packets; + + /** Maximum allowed value for odp_tm_shaper_params_t::commit_rate and + * odp_tm_shaper_params_t::peak_rate when + * odp_tm_shaper_params_t::packet_mode is true. + */ + uint64_t max_rate_packets; + + /** Minimum allowed value for odp_tm_shaper_params_t::commit_burst and + * odp_tm_shaper_params_t::peak_burst when + * odp_tm_shaper_params_t::packet_mode is false. + */ + uint32_t min_burst; + + /** Maximum allowed value for odp_tm_shaper_params_t::commit_burst and + * odp_tm_shaper_params_t::peak_burst when + * odp_tm_shaper_params_t::packet_mode is false. + */ + uint32_t max_burst; + + /** Minimum allowed value for odp_tm_shaper_params_t::commit_rate and + * odp_tm_shaper_params_t::peak_rate when + * odp_tm_shaper_params_t::packet_mode is false. + */ + uint64_t min_rate; + + /** Maximum allowed value for odp_tm_shaper_params_t::commit_rate and + * odp_tm_shaper_params_t::peak_rate when + * odp_tm_shaper_params_t::packet_mode is false. + */ + uint64_t max_rate; + + /** Shaper is supported in rate shape mode */ odp_bool_t tm_node_shaper_supported; + /** Shaper is supported in rate limit mode */ + odp_bool_t tm_node_rate_limiter_supported; + + /** tm_node_shaper_packet_mode indicates that tm_nodes at this level + * support shaper in packet mode */ + odp_bool_t tm_node_shaper_packet_mode; + /** tm_node_wred_supported indicates that the tm_nodes at this level * support some form of Random Early Detection. */ odp_bool_t tm_node_wred_supported; @@ -244,8 +338,49 @@ typedef struct { * When true the min_weight and max_weight fields above specify * the legal range of such weights. */ odp_bool_t weights_supported; + + /** TM node threshold profile support */ + struct { + /** Threshold given as bytes */ + uint8_t byte : 1; + + /** Threshold given as packets */ + uint8_t packet : 1; + + /** Threshold given as bytes and packets simultaneously */ + uint8_t byte_and_packet : 1; + + } tm_node_threshold; + } odp_tm_level_capabilities_t; +/** The tm_pkt_prio_mode_t enumeration type is used to indicate different + * modes a tm system supports with respect to assigning priority to a packet + * and propagating it across TM system. All the nodes in a TM system can + * function only on single mode specified at time of odp_tm_create(). + */ +typedef enum odp_tm_pkt_prio_mode { + /** Indicates Packet priority preserve mode. In this mode, a packet gets + * its priority based on a TM queue it gets enqueued to and then it + * carries the same priority along with it as long as it is in the TM + * system. At every TM node in the topology, that specific pkt is + * scheduled as per that priority. + */ + ODP_TM_PKT_PRIO_MODE_PRESERVE, + + /** Indicates Packet priority overwrite mode. In this mode, a packet + * gets a new priority every time it passes through a TM queue or a + * TM node. All the packets fed by a fan-in node will get the same + * priority and that will be valid until overwritten again by another TM + * node. This priority is part of the TM fan-in node parameters and is + * fixed at node creation time. + */ + ODP_TM_PKT_PRIO_MODE_OVERWRITE, + + /** Max enum of Packet priority mode */ + ODP_TM_PKT_PRIO_MODE_MAX, +} odp_tm_pkt_prio_mode_t; + /** TM Capabilities Record. * * The odp_tm_capabilities_t record type is used to describe the feature set @@ -275,16 +410,16 @@ typedef struct { */ odp_bool_t egress_fcn_supported; - /** tm_queue_shaper_supported indicates that the tm_queues support - * proper TM shaping. Note that TM Shaping is NOT the same thing as - * Ingress Metering/Policing as specified by RFC 2697 (A Single Rate - * Three Color Marker) or RFC 2698 (A Two Rate Three Color Marker). - * These RFC's can be used for a Diffserv traffic conditioner, or - * other ingress policing. They make no mention of and have no - * algorithms for delaying packets - which is what TM shapers are - * expected to do. */ + /** Shaper is supported in rate shape mode */ odp_bool_t tm_queue_shaper_supported; + /** Shaper is supported in rate limit mode */ + odp_bool_t tm_queue_rate_limiter_supported; + + /** tm_queue_shaper_packet_mode indicates that tm_queues support + * shaper in packet mode */ + odp_bool_t tm_queue_shaper_packet_mode; + /** tm_queue_wred_supported indicates that the tm_queues support some * form of Random Early Detection. */ odp_bool_t tm_queue_wred_supported; @@ -331,13 +466,105 @@ typedef struct { /** The per_level array specifies the TM system capabilities that * can vary based upon the tm_node level. */ odp_tm_level_capabilities_t per_level[ODP_TM_MAX_LEVELS]; + + /** dynamic_topology_update indicates support for TM system dynamic + * topology update. A dynamic topology update is defined as update to + * a TM system topology while TM system is not in stopped state. + * When TRUE, application can update topology dynamically + * without bringing the TM system to stopped state. When FALSE, + * application has to call odp_tm_stop() before updating the + * topology and odp_tm_start() after completing the update. + */ + odp_bool_t dynamic_topology_update; + + /** dynamic_shaper_update indicates support for TM system's dynamic + * shaper profile changes. When TRUE, application can update shaper + * profile of a TM queue or TM node dynamically. + * When FALSE, it implies that TM system should be brought to + * stopped state before changing the shaper profile or updating + * the parameters of the shaper profile of any TM node or TM queue. + */ + odp_bool_t dynamic_shaper_update; + + /** dynamic_sched_update indicates support for TM system's dynamic + * sched profile changes. When TRUE, application can update sched + * profile of a TM queue or TM node dynamically. + * When FALSE, it implies that TM system should be brought to + * stopped state before changing the sched profile or updating + * the parameters of the sched profile of any TM node or TM queue. + */ + odp_bool_t dynamic_sched_update; + + /** dynamic_wred_update indicates support for TM system's dynamic + * wred profile changes. When TRUE, application can update wred + * profile of a TM queue or TM node dynamically. + * When FALSE, it implies that TM system should be brought to + * stopped state before changing the wred profile or updating + * the parameters of the wred profile of any TM node or TM queue. + */ + odp_bool_t dynamic_wred_update; + + /** dynamic_threshold_update indicates support for TM system's dynamic + * threshold profile changes. When TRUE, application can update + * threshold profile of a TM queue or TM node dynamically. + * When FALSE, it implies that TM system should be brought to + * stopped state before changing the threshold profile or updating + * the parameters of the threshold profile of any TM node or TM queue. + */ + odp_bool_t dynamic_threshold_update; + + /** TM queue statistics counter capabilities */ + odp_tm_queue_stats_capability_t queue_stats; + + /** TM queue threshold profile support */ + struct { + /** Threshold given as bytes */ + uint8_t byte : 1; + + /** Threshold given as packets */ + uint8_t packet : 1; + + /** Threshold given as bytes and packets simultaneously */ + uint8_t byte_and_packet : 1; + + } tm_queue_threshold; + + /** tm_queue_query_flags indicates supported types of TM queue query. + * Types of TM queue query are same as query_flags that are passed to + * odp_tm_queue_query(), odp_tm_priority_query() and + * odp_tm_total_query(). When zero, none of the queue query API's are + * supported. When non-zero, only the only supported types of passed + * query_flags are taken into account and corresponding fields updated. + * + * @see ODP_TM_QUERY_PKT_CNT, ODP_TM_QUERY_BYTE_CNT, + * ODP_TM_QUERY_THRESHOLDS. + */ + uint32_t tm_queue_query_flags; + + /** Indicates the packet priority modes supported by TM systems on a + * platform. A platform can support multiple packet priority modes. The + * actual mode a TM system runs with is defined by + * odp_tm_requirements_t. + */ + odp_bool_t pkt_prio_modes[ODP_TM_PKT_PRIO_MODE_MAX]; + + /** Maximum number of schedulers supported by a TM node at any level. + * A TM node contains a WFQ/WRR scheduler for each packet priority level + * for which the node has more than one possible input. TM topology and + * priority configuration must be made so that the resulting number of + * WFQ/WRR schedulers does not exceed this capability in any TM node. + * + * The value can vary between 0 and ODP_TM_MAX_PRIORITIES. + */ + uint8_t max_schedulers_per_node; } odp_tm_capabilities_t; /** Per Level Requirements * * The odp_tm_level_requirements_t record is used to describe the requirements * that might vary based upon the tm_node level. It is always used as - * part of the odp_tm_requirements record. */ + * part of the odp_tm_requirements record. The default value of all boolean + * fields is false. */ typedef struct { /** max_num_tm_nodes specifies the maximum number of tm_nodes required * at this level. */ @@ -357,12 +584,12 @@ typedef struct { /** min_weight only has significance when the weights_supported field * below is true, in which case it specifies the smallest value * of the weights that will be used at this level. */ - uint8_t min_weight; + uint32_t min_weight; /** max_weight only has significance when the weights_supported field * below is true, in which case it specifies the largest value * of the weights that will be used at this level. */ - uint8_t max_weight; + uint32_t max_weight; /** tm_node_shaper_needed indicates that the tm_nodes at this level * are expected to do TM shaping, */ @@ -383,17 +610,24 @@ typedef struct { * disciplines. */ odp_bool_t fair_queuing_needed; - /** weights_needd indicates that the tm_node schedulers at this + /** weights_needed indicates that the tm_node schedulers at this * level are expected have different weights for their different * fanins. When true the min_weight and max_weight fields above * specify the used range of such weights. */ odp_bool_t weights_needed; + + /** tm_node_threshold_needed indicates that the tm_nodes at this + * level may use threshold profile support */ + odp_bool_t tm_node_threshold_needed; } odp_tm_level_requirements_t; /** TM Requirements Record. * * The odp_tm_requirements_t record type is used to describe the minimum - * set of features and limits to be actually used by the application. */ + * set of features and limits to be actually used by the application. + * + * The default value of all boolean fields is false. + **/ typedef struct { /** max_tm_queues specifies the maximum number of tm_queues that will * be used for this TM System. */ @@ -401,7 +635,8 @@ typedef struct { /** num_levels specifies that number of levels of hierarchical * scheduling that will be used. This is a count of the tm_node - * stages and does not include tm_queues or tm_egress objects. */ + * stages and does not include tm_queues or tm_egress objects. + * The default value is 0. */ uint8_t num_levels; /** tm_queue_shaper_needed indicates that the tm_queues are expected @@ -417,6 +652,10 @@ typedef struct { * ignored if tm_queue_wred_needed above is false. */ odp_bool_t tm_queue_dual_slope_needed; + /** tm_queue_threshold_needed indicates that the tm_queues are + * expected to use threshold profile support */ + odp_bool_t tm_queue_threshold_needed; + /** vlan_marking_needed indicates that the ODP application expects * to use some form of VLAN egress marking using the * odp_tm_vlan_marking() function. See also comments for @@ -440,9 +679,15 @@ typedef struct { * the application will not enable this color for vlan marking, * ecn marking nor drop precedence marking. A value of TRUE means that * the application expects to use this color in conjunction with one or - * more of the marking API's. */ + * more of the marking APIs. */ odp_bool_t marking_colors_needed[ODP_NUM_PACKET_COLORS]; + /** Packet priority mode. + * TM capabilities indicate which modes are supported. + * The default value is ODP_TM_PKT_PRIO_MODE_PRESERVE. + */ + odp_tm_pkt_prio_mode_t pkt_prio_mode; + /** The per_level array specifies the TM system requirements that * can vary based upon the tm_node level. */ odp_tm_level_requirements_t per_level[ODP_TM_MAX_LEVELS]; @@ -471,20 +716,20 @@ typedef enum { typedef struct { odp_tm_egress_kind_t egress_kind; /**< Union discriminator */ + /** Variant parameters for different TM outputs */ union { - odp_pktio_t pktio; - odp_tm_egress_fcn_t egress_fcn; + odp_pktio_t pktio; /**< Output to PktIO */ + odp_tm_egress_fcn_t egress_fcn; /**< Output to user func */ }; } odp_tm_egress_t; -/** Initialize Requirements record. +/** Initialize Requirements record fields to their default values. * * odp_tm_requirements_init() must be called to initialize any * odp_tm_requirements_t record before it is first used or assigned to. - * This is done to allow for vendor specific additions to this record. * - * @param[in] requirements A pointer to an odp_tm_requirements_t record which - * is to be initialized. + * @param requirements A pointer to an odp_tm_requirements_t record which + * is to be initialized. */ void odp_tm_requirements_init(odp_tm_requirements_t *requirements); @@ -492,54 +737,48 @@ void odp_tm_requirements_init(odp_tm_requirements_t *requirements); * * odp_tm_egress_init() must be called to initialize any odp_tm_egress_t * record before it is first used or assigned to. - * This is done to allow for vendor specific additions to this record. * - * @param[in] egress A pointer to an odp_tm_egress_t record which - * is to be initialized. + * @param egress A pointer to an odp_tm_egress_t record which + * is to be initialized. */ void odp_tm_egress_init(odp_tm_egress_t *egress); -/** Query All TM Capabilities - * - * The odp_tm_capabilities() function can be used to obtain the complete set of - * TM limits supported by this implementation. The reason that this returns - * a SET of capabilities and not just one, is because it is expected that - * many HW based implementations may have one set of limits for the HW and - * also support a SW TM implementation with a (presumably larger) different - * set of limits. There are also cases where there could be more than - * SW implementation (one supporting say tens of thousands of tm_queues and - * a variant supporting tens of millions of tm_queues). - * The caller passes in an array of odp_tm_capabilities_t records and the - * number of such records. Then the first N of these records will be filled - * in by the implementation and the number N will be returned. In the event - * that N is larger than the capabilities_size, N will still be returned, - * but only capabilities_size records will be filled in. - * - * @param[out] capabilities An array of odp_tm_capabilities_t records to - * be filled in. - * @param[in] capabilities_size The number of odp_tm_capabilities_t records - * in the capabilities array. - * @return Returns < 0 upon failure. Returns N > 0, - * where N is the maximum number of different - * odp_tm_capabilities_t records that the - * implementations supports. *NOTE* that this - * number can be > capabilities_size! - */ -int odp_tm_capabilities(odp_tm_capabilities_t capabilities[], - uint32_t capabilities_size); +/** Query TM Capabilities specific to an egress + * + * The function returns the set of TM limits supported by this implementation + * for a given egress. Unlike odp_tm_capability() which return's capabilities + * of already created TM system which are limited by its requirements, this + * function returns maximum TM system limits. + * + * Lack of TM support in the given egress does not cause this + * function to return a failure. Lack of TM support is indicated + * by zero max_tm_queues capability. + * + * If the pktio of an egress of the pktio kind has not been opened + * in the ODP_PKTOUT_MODE_TM pktout mode, the capabilities will + * indicate that TM is not supported. + * + * @param[out] capabilities odp_tm_capabilities_t record to be filled in. + * @param egress Only capabilities compatible with this egress + * are returned. + * @retval 0 on success + * @retval <0 on failure + */ +int odp_tm_egress_capabilities(odp_tm_capabilities_t *capabilities, + const odp_tm_egress_t *egress); /** Create/instantiate a TM Packet Scheduling system. * - * @param[in] name The name to be assigned to this TM system. Cannot - * be NULL, and also must be unique amongst all other - * TM system names. - * @param[in] requirements The minimum required feature set and limits needed - * by the ODP application. - * @param[in] egress Describes the single egress "spigot" of this - * TM system. - * @return Returns ODP_TM_INVALID upon failure, otherwise the - * newly created TM system's odp_tm_t handle is - * returned. + * @param name The name to be assigned to this TM system. Cannot + * be NULL, and also must be unique amongst all other + * TM system names. + * @param requirements The minimum required feature set and limits needed + * by the ODP application. + * @param egress Describes the single egress "spigot" of this + * TM system. + * @return Returns ODP_TM_INVALID upon failure, otherwise the + * newly created TM system's odp_tm_t handle is + * returned. */ odp_tm_t odp_tm_create(const char *name, odp_tm_requirements_t *requirements, @@ -557,21 +796,21 @@ odp_tm_t odp_tm_create(const char *name, * the existing (built-in or created by odp_tm_create) TM system that best * matches the requirements is returned. * - * @param[in] name If NULL then only uses the requirements parameter to - * find a closest match, otherwise if the name is - * matched by an existing TM system it is returned. - * @param[in] requirements Used when the name is NULL (in which case the - * closest match is returned) or when the name is - * not-NULL, but doesn't match any existing TM system - * in which case the requirements is used to find the - * FIRST TM system matching exactly these limits. - * @param[in] egress If a TM system is found, then this specifies the - * egress "spigot" to be associated with this TM - * system. - * @return If an existing TM system (built-in or previously - * created via odp_tm_create) is found, its - * odp_tm_t value is returned, otherwise - * ODP_TM_INVALID is returned. + * @param name If NULL then only uses the requirements parameter to + * find a closest match, otherwise if the name is + * matched by an existing TM system it is returned. + * @param requirements Used when the name is NULL (in which case the + * closest match is returned) or when the name is + * not-NULL, but doesn't match any existing TM system + * in which case the requirements is used to find the + * FIRST TM system matching exactly these limits. + * @param egress If a TM system is found, then this specifies the + * egress "spigot" to be associated with this TM + * system. + * @return If an existing TM system (built-in or previously + * created via odp_tm_create) is found, its + * odp_tm_t value is returned, otherwise + * ODP_TM_INVALID is returned. */ odp_tm_t odp_tm_find(const char *name, odp_tm_requirements_t *requirements, @@ -590,8 +829,7 @@ odp_tm_t odp_tm_find(const char *name, * In addition, ODP TM implementations should fail API requests that "exceed" * the limits or features contracted for in the requirements. * - * @param[in] odp_tm The odp_tm_t value of the TM system to be - * queried. + * @param tm TM handle * @param[out] capabilities A pointer to an odp_tm_capabilities_t record * where the actual limits used by the TM system are * copied into. Note that these limits do NOT @@ -599,10 +837,53 @@ odp_tm_t odp_tm_find(const char *name, * a TM system was created by odp_tm_create, * but of course these limits in some cases could * be larger. + * * @return Returns 0 upon success, < 0 upon failure (which * indicates that the odp_tm value did not exist). */ -int odp_tm_capability(odp_tm_t odp_tm, odp_tm_capabilities_t *capabilities); +int odp_tm_capability(odp_tm_t tm, odp_tm_capabilities_t *capabilities); + +/** + * Start a TM system + * + * odp_tm_start() needs to be used to start an already created or found TM + * system. By default, all the TM systems are in stopped state. + * + * @param tm TM handle + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_tm_start(odp_tm_t tm); + +/** + * Stop a TM system + * + * odp_tm_stop() can to used to stop a TM system that is already started for the + * purpose of reconfiguration that cannot be done dynamically. + * + * When TM is in the stopped state, + * - New packets must not be sent to the TM either directly by TM API or indirectly + * via IPsec outbound inline API. New packets can only be enqueued after + * starting the TM system using odp_tm_start(). + * - Packets already inflight inside TM or IPSec for transmit may get silently dropped + * or may get transmitted with unspecified TM treatment. + * + * A following call to odp_tm_start() restarts TM system and its scheduling/shaping + * on existing and new packets. + * + * @param tm TM handle + * + * @retval 0 on success + * @retval <0 on failure + * + * @see odp_tm_capabilities_t::dynamic_topology_update + * @see odp_tm_capabilities_t::dynamic_shaper_update + * @see odp_tm_capabilities_t::dynamic_sched_update + * @see odp_tm_capabilities_t::dynamic_wred_update + * @see odp_tm_capabilities_t::dynamic_threshold_update + */ +int odp_tm_stop(odp_tm_t tm); /** Destroy a TM system. * @@ -618,36 +899,38 @@ int odp_tm_capability(odp_tm_t odp_tm, odp_tm_capabilities_t *capabilities); * TM system, other than EVENTUALLY these packets will be either sent (in ANY * order) or freed. * - * @param[in] odp_tm The odp_tm_t value of the TM system to be destroyed (and - * hence destroyed (and hence freed). - * @return 0 upon success, < 0 upon failure. + * @param tm The handle of the TM system to be destroyed (and hence freed). + * + * @return 0 upon success, < 0 upon failure. */ -int odp_tm_destroy(odp_tm_t odp_tm); +int odp_tm_destroy(odp_tm_t tm); -/** Marking APIs */ +/* Marking APIs + * -------------------------------------------------------- */ /** Vlan Marking. * * The odp_tm_vlan_marking() function allows one to configure the TM egress * so as to have it set the one bit VLAN Drop Eligibility Indicator (DEI) * field (but only for pkts that already carry a VLAN tag) of a pkt based upon - * the final pkt (or shaper?) color assigned to the pkt when it reaches the - * egress node. When drop_eligible_enabled is false, then the given color has - * no effect on the VLAN fields. See IEEE 802.1q for more details. + * the final pkt color assigned to the pkt when it reaches the egress node. When + * drop_eligible_enabled is false, then the given color has no effect on the + * VLAN fields. See IEEE 802.1q for more details. * * Note that ALL ODP implementations are required to SUCCESSFULLY handle all * calls to this function with drop_eligible_enabled == FALSE - i.e. must * always return 0 when disabling this feature. * - * @param[in] odp_tm Odp_tm is used to identify the TM system - * whose egress behavior is being changed. - * @param[in] color The packet color whose egress marking is - * being changed. - * @param[in] drop_eligible_enabled If true then will set the DEI bit for - * egressed VLAN tagged pkts with this color. - * @return 0 upon success, < 0 upon failure. + * @param tm Handle of the TM system whose egress behavior + * is being changed. + * @param color The packet color whose egress marking is + * being changed. + * @param drop_eligible_enabled If true then will set the DEI bit for + * egressed VLAN tagged pkts with this color. + * + * @return 0 upon success, < 0 upon failure. */ -int odp_tm_vlan_marking(odp_tm_t odp_tm, +int odp_tm_vlan_marking(odp_tm_t tm, odp_packet_color_t color, odp_bool_t drop_eligible_enabled); @@ -668,18 +951,19 @@ int odp_tm_vlan_marking(odp_tm_t odp_tm, * calls to this function with ecn_ce_enabled == FALSE - i.e. must always * return 0 when disabling this feature. * - * @param[in] odp_tm Odp_tm is used to identify the TM system whose - * egress behavior is being changed. - * @param[in] color The packet color whose egress marking is - * being changed. - * @param[in] ecn_ce_enabled If true then egressed IPv4/IPv6 pkts whose - * protocol field is TCP AND whose ECN subfield has - * either one of the two values 1 or 2, will set this - * subfield to the value ECN_CE - i.e. Congestion - * Experienced (whose value is 3). - * @return 0 upon success, < 0 upon failure. - */ -int odp_tm_ecn_marking(odp_tm_t odp_tm, + * @param tm Handle of the TM system whose egress behavior is being + * changed. + * @param color The packet color whose egress marking is + * being changed. + * @param ecn_ce_enabled If true then egressed IPv4/IPv6 pkts whose + * protocol field is TCP AND whose ECN subfield has + * either one of the two values 1 or 2, will set this + * subfield to the value ECN_CE - i.e. Congestion + * Experienced (whose value is 3). + * + * @return 0 upon success, < 0 upon failure. + */ +int odp_tm_ecn_marking(odp_tm_t tm, odp_packet_color_t color, odp_bool_t ecn_ce_enabled); @@ -708,58 +992,94 @@ int odp_tm_ecn_marking(odp_tm_t odp_tm, * calls to this function with drop_prec_enabled == FALSE - i.e. must always * return 0 when disabling this feature. * - * @param[in] odp_tm Odp_tm is used to identify the TM system whose - * egress behavior is being changed. - * @param[in] color The packet color whose egress marking is - * being changed. - * @param[in] drop_prec_enabled If true then egressed IPv4/IPv6 pkts with this - * color will have the pkt's Drop Precedence - * sub-subfield of the DSCP subfield set to - * LOW, MEDIUM or HIGH drop precedence. - * @return 0 upon success, < 0 upon failure. - */ -int odp_tm_drop_prec_marking(odp_tm_t odp_tm, + * @param tm Handle of the TM system whose egress behavior is + * being changed. + * @param color The packet color whose egress marking is + * being changed. + * @param drop_prec_enabled If true then egressed IPv4/IPv6 pkts with this + * color will have the pkt's Drop Precedence + * sub-subfield of the DSCP subfield set to + * LOW, MEDIUM or HIGH drop precedence. + * + * @return 0 upon success, < 0 upon failure. + */ +int odp_tm_drop_prec_marking(odp_tm_t tm, odp_packet_color_t color, odp_bool_t drop_prec_enabled); -/** Shaper profile types and functions */ +/* Shaper profile types and functions + * -------------------------------------------------------- */ -/** Possible values of running the shaper algorithm. ODP_TM_SHAPER_GREEN - * means that the traffic is within the commit specification (rate and burst - * size), ODP_TM_SHAPER_YELLOW means that the traffic is within the peak - * specification (rate and burst size) and ODP_TM_SHAPER_RED means that the - * traffic is exceeding both its commit and peak specifications. Note that - * packets can also have an assigned <b> packet color</b> of ODP_PACKET_GREEN, - * ODP_PACKET_YELLOW or ODP_PACKET_RED which has a different meaning and - * purpose than the shaper colors. - */ +/** Mode selection between rate shaping and rate limiting */ typedef enum { - ODP_TM_SHAPER_GREEN, ODP_TM_SHAPER_YELLOW, ODP_TM_SHAPER_RED -} odp_tm_shaper_color_t; + /** Rate shape traffic to the specified burst and rate by delaying + * packets. + * + * The shaper does not drop packets in normal operation, but since + * it delays packets, it can cause queues to fill up and cause queue + * management to drop packets. + */ + ODP_TM_SHAPER_RATE_SHAPE, + + /** Rate limit traffic to the specified burst and rate by dropping + * excess packets. + * + * It is implementation dependent when exactly the limiter state + * update and packet drop happens. For example, they may occur + * immediately when packets are available from the source or when + * the downstream node and scheduler are accepting new packets from + * this node/queue. It is possible that in some cases a delayed + * packet drop causes queues to fill up. + */ + ODP_TM_SHAPER_RATE_LIMIT + +} odp_tm_shaper_mode_t; -/** The odp_tm_shaper_params_t record type is used to supply the parameters - * associated with a shaper profile. Since it is expected that - * implementations might augment this record type with platform specific - * additional fields - it is required that odp_tm_shaper_params_init() be - * called on variables of this type before any of the fields are filled in. +/** + * TM shaper parameters + * + * Use odp_tm_shaper_params_init() to initialize parameters into their default + * values. */ typedef struct { + /** Shaper mode. The default value is ODP_TM_SHAPER_RATE_SHAPE. + * + * A shaper profile must not be used in a TM queue or TM node if + * the queue/node does not support shaper or if it does not support + * the shaper mode set in the profile. + * + * @see odp_tm_capabilities_t::tm_queue_shaper_supported + * @see odp_tm_capabilities_t::tm_queue_rate_limiter_supported + * @see odp_tm_level_capabilities_t::tm_node_shaper_supported + * @see odp_tm_level_capabilities_t::tm_node_rate_limiter_supported + */ + odp_tm_shaper_mode_t mode; + /** The committed information rate for this shaper profile. The units - * for this integer are always in bits per second. */ - uint64_t commit_bps; + * for this integer is in bits per second when packet_mode is + * not TRUE while packets per second when packet mode is TRUE. + */ + uint64_t commit_rate; /** The peak information rate for this shaper profile. The units for - * this integer are always in bits per second. */ - uint64_t peak_bps; + * this integer is in bits per second when packet_mode is + * not TRUE while in packets per second when packet mode is TRUE. + * This field is ignored when dual_rate is FALSE. + */ + uint64_t peak_rate; /** The commit burst tolerance for this shaper profile. The units for - * this field are always bits. This value sets an upper limit for the + * this field is bits when packet_mode is not TRUE and packets when + * packet_mode is TRUE. This value sets an upper limit for the * size of the commitCnt. */ uint32_t commit_burst; /** The peak burst tolerance for this shaper profile. The units for - * this field are always bits. This value sets an upper limit for the - * size of the peakCnt. */ + * this field in bits when packet_mode is not TRUE and packets + * when packet_mode is TRUE. This value sets an upper limit for the + * size of the peakCnt. + * This field is ignored when dual_rate is FALSE. + */ uint32_t peak_burst; /** The shaper_len_adjust is a value between -128 and 127 which is @@ -770,22 +1090,36 @@ typedef struct { * to a value approximating the "time" (in units of bytes) taken by * the Ethernet preamble and Inter Frame Gap. Traditionally this * would be the value 20 (8 + 12), but in same cases can be as low as - * 9 (4 + 5). */ + * 9 (4 + 5). + * This field is ignored when packet_mode is TRUE. + * + * The default value is 0. */ int8_t shaper_len_adjust; /** If dual_rate is TRUE it indicates the desire for the * implementation to use dual rate shaping for packets associated with * this profile. The precise semantics of dual rate shaping are * implementation specific, but in any case require a non-zero set of - * both commit and peak parameters. */ + * both commit and peak parameters. + * + * The default value is false. */ odp_bool_t dual_rate; + + /** If packet_mode is TRUE it indicates that shaper should work + * in packet mode ignoring lengths of packet and hence shaping + * traffic in packet's per second as opposed to bits per second. + * + * The default value is false. */ + odp_bool_t packet_mode; + } odp_tm_shaper_params_t; -/** odp_tm_shaper_params_init() must be called to initialize any - * odp_tm_shaper_params_t record before it is first used or assigned to. +/** + * Initialize TM shaper parameters + * + * Initialize an odp_tm_shaper_params_t to its default values for all fields. * - * @param[in] params A pointer to an odp_tm_shaper_params_t record which - * is to be initialized. + * @param params Address of the odp_tm_shaper_params_t to be initialized */ void odp_tm_shaper_params_init(odp_tm_shaper_params_t *params); @@ -793,17 +1127,17 @@ void odp_tm_shaper_params_init(odp_tm_shaper_params_t *params); * subsequently be attached to any number (including zero) of tm_queues * or tm_nodes. * - * @param[in] name Optional name associated with this shaper profile. Can - * be NULL. If non-NULL must be unique amongst the set of - * all other shaper profiles. - * @param[in] params The profile parameters. See comments associated with - * the odp_tm_shaper_params_t for more details. - * @return Returns ODP_TM_INVALID upon failure, or the newly - * allocated odp_tm_shaper_t value representing this - * profile object. + * @param name Optional name associated with this shaper profile. Can + * be NULL. If non-NULL must be unique amongst the set of + * all other shaper profiles. + * @param params The profile parameters. See comments associated with + * the odp_tm_shaper_params_t for more details. + * @return Returns ODP_TM_INVALID upon failure, or the newly + * allocated odp_tm_shaper_t value representing this + * profile object. */ odp_tm_shaper_t odp_tm_shaper_create(const char *name, - odp_tm_shaper_params_t *params); + const odp_tm_shaper_params_t *params); /** Destroy shaper profile object * @@ -811,9 +1145,9 @@ odp_tm_shaper_t odp_tm_shaper_create(const char *name, * profile object. It is an error if this shaper profile is still being * referenced by an active (connected) tm_node. * - * @param[in] shaper_profile Specifies the shaper profile object which is - * being destroyed. - * @return Returns < 0 upon failure or 0 upon success. + * @param shaper_profile Specifies the shaper profile object which is + * being destroyed. + * @return Returns < 0 upon failure or 0 upon success. */ int odp_tm_shaper_destroy(odp_tm_shaper_t shaper_profile); @@ -821,7 +1155,7 @@ int odp_tm_shaper_destroy(odp_tm_shaper_t shaper_profile); * with the specified shaper profile object, and copies them into the supplied * record. * - * @param[in] shaper_profile Specifies the shaper profile object whose + * @param shaper_profile Specifies the shaper profile object whose * values are to be read. * @param[out] params A pointer to an odp_tm_shaper_params_t record * where the current shaper profile object values @@ -833,30 +1167,31 @@ int odp_tm_shaper_params_read(odp_tm_shaper_t shaper_profile, /** odp_tm_shaper_params_update() "sets" the current set of values associated * with the specified shaper profile object. In addition, this call has the - * effect that all tm_input's and tm_nodes that are associated (attached?) - * with this shaper profile object will be updated with the new values. - * - * @param[in] shaper_profile Specifies the shaper profile object whose - * values are to be set. - * @param[in] params A pointer to an odp_tm_shaper_params_t record - * where the new shaper profile object values - * are taken from. - * @return Returns < 0 upon failure or 0 upon success. + * effect that all tm_input's and tm_nodes that are associated with this shaper + * profile object will be updated with the new values. + * + * @param shaper_profile Specifies the shaper profile object whose + * values are to be set. + * @param params A pointer to an odp_tm_shaper_params_t record + * where the new shaper profile object values + * are taken from. + * @return Returns < 0 upon failure or 0 upon success. */ int odp_tm_shaper_params_update(odp_tm_shaper_t shaper_profile, - odp_tm_shaper_params_t *params); + const odp_tm_shaper_params_t *params); /** odp_tm_shaper_lookup() can be used to find the shaper profile object * created with the specified name. * - * @param[in] name Name of a previously created shaper profile. Cannot be - * NULL. - * @return Returns ODP_TM_INVALID upon failure, or the shaper - * profile handle created with this name. + * @param name Name of a previously created shaper profile. Cannot be NULL. + * + * @return Returns ODP_TM_INVALID upon failure, or the shaper + * profile handle created with this name. */ odp_tm_shaper_t odp_tm_shaper_lookup(const char *name); -/** Scheduler Profiles - types and functions */ +/* Scheduler Profiles - types and functions + * -------------------------------------------------------- */ /** The odp_tm_sched_mode_t type is used to control whether a tm_node * scheduler takes into account packet lengths (by setting the sched_mode to @@ -871,49 +1206,51 @@ typedef enum { ODP_TM_FRAME_BASED_WEIGHTS /**< Ignore the packet length */ } odp_tm_sched_mode_t; -/** The odp_tm_sched_params_t record type is used to supply the parameters - * associated with a scheduler profile. Since it is expected that - * implementations might augment this record type with platform specific - * additional fields - it is required that odp_tm_sched_params_init() be - * called on variables of this type before any of the fields are filled in. +/** + * TM scheduler parameters + * + * Use odp_tm_sched_params_init() to initialize parameters into their default + * values. */ typedef struct { /** sched_modes indicates whether weighted scheduling should be used - * or not - on a priority basis. */ + * or not - on a priority basis. + * The default value is ODP_TM_BYTE_BASED_WEIGHTS for all priorities */ odp_tm_sched_mode_t sched_modes[ODP_TM_MAX_PRIORITIES]; /** In the case that sched_modes for a given strict priority level * indicates the use of weighted scheduling, this field supplies the * weighting factors. The weights - when defined - are used such that - * the (adjusted) frame lengths are divided by these 8-bit weights + * the (adjusted) frame lengths are divided by these weights * (i.e. they are divisors and not multipliers). Consequently a * weight of 0 (when sched_mode is ODP_TM_BYTE_BASED_WEIGHTS) is * illegal. */ - uint8_t sched_weights[ODP_TM_MAX_PRIORITIES]; + uint32_t sched_weights[ODP_TM_MAX_PRIORITIES]; } odp_tm_sched_params_t; -/** odp_tm_sched_params_init() must be called to initialize any - * odp_tm_sched_params_t record before it is first used or assigned to. +/** + * Initialize TM scheduler parameters + * + * Initialize an odp_tm_sched_params_t to its default values for all fields. * - * @param[in] params A pointer to an odp_tm_sched_params_t record which - * is to be initialized. + * @param params Address of the odp_tm_sched_params_t to be initialized */ void odp_tm_sched_params_init(odp_tm_sched_params_t *params); /** odp_tm_sched_create() creates a scheduler profile object, which can * subsequently be attached to any number (including zero) of tm_nodes. * - * @param[in] name Optional name associated with this scheduler profile. - * Can be NULL. If non-NULL must be unique amongst the - * set of all other scheduler profiles. - * @param[in] params The profile parameters. See comments associated with - * the odp_tm_sched_params_t for more details. - * @return Returns ODP_TM_INVALID upon failure, or the newly - * allocated odp_tm_sched_t value representing this profile - * object. + * @param name Optional name associated with this scheduler profile. + * Can be NULL. If non-NULL must be unique amongst the + * set of all other scheduler profiles. + * @param params The profile parameters. See comments associated with + * the odp_tm_sched_params_t for more details. + * @return Returns ODP_TM_INVALID upon failure, or the newly + * allocated odp_tm_sched_t value representing this profile + * object. */ odp_tm_sched_t odp_tm_sched_create(const char *name, - odp_tm_sched_params_t *params); + const odp_tm_sched_params_t *params); /** Destroy scheduler profile object * @@ -921,9 +1258,9 @@ odp_tm_sched_t odp_tm_sched_create(const char *name, * profile object. It is an error if this scheduler profile is still being * referenced by an active (connected) tm_node. * - * @param[in] sched_profile Specifies the shaper profile object which is - * being destroyed. - * @return Returns < 0 upon failure or 0 upon success. + * @param sched_profile Specifies the shaper profile object which is + * being destroyed. + * @return Returns < 0 upon failure or 0 upon success. */ int odp_tm_sched_destroy(odp_tm_sched_t sched_profile); @@ -931,7 +1268,7 @@ int odp_tm_sched_destroy(odp_tm_sched_t sched_profile); * with the specified scheduler profile object, and copies them into the * supplied record. * - * @param[in] sched_profile Specifies the scheduler profile whose values + * @param sched_profile Specifies the scheduler profile whose values * are to be read. * @param[out] params A pointer to an odp_tm_sched_params_t record * where the current scheduler profile object @@ -943,49 +1280,55 @@ int odp_tm_sched_params_read(odp_tm_sched_t sched_profile, /** odp_tm_sched_params_update() "sets" the current set of values associated * with the specified scheduler profile object. In addition, this call has - * the effect that all tm_nodes that are associated (attached?) with this - * Scheduler profile object will be updated with the new values. - * - * @param[in] sched_profile Specifies the Scheduler profile object whose - * values are to be set. - * @param[in] params A pointer to an odp_tm_sched_params_t record - * where the new scheduler profile object values - * are taken from. - * @return Returns < 0 upon failure or 0 upon success. + * the effect that all tm_nodes that are associated with this scheduler profile + * object will be updated with the new values. + * + * @param sched_profile Specifies the Scheduler profile object whose + * values are to be set. + * @param params A pointer to an odp_tm_sched_params_t record + * where the new scheduler profile object values + * are taken from. + * @return Returns < 0 upon failure or 0 upon success. */ int odp_tm_sched_params_update(odp_tm_sched_t sched_profile, - odp_tm_sched_params_t *params); + const odp_tm_sched_params_t *params); /** odp_tm_sched_lookup() can be used to find the scheduler profile object * created with the specified name. * - * @param[in] name Name of a previously created scheduler profile. Cannot be - * NULL. - * @return Returns ODP_TM_INVALID upon failure, or the scheduler - * profile handle created with this name. + * @param name Name of a previously created scheduler profile. Cannot be NULL. + * + * @return Returns ODP_TM_INVALID upon failure, or the scheduler + * profile handle created with this name. */ odp_tm_sched_t odp_tm_sched_lookup(const char *name); -/** Queue Threshold Profiles - types and functions */ +/* Queue Threshold Profiles - types and functions + * -------------------------------------------------------- */ -/** The odp_tm_threshold_params_t record type is used to supply the parameters - * associated with a queue thresholds profile. Since it is expected that - * implementations might augment this record type with platform specific - * additional fields - it is required that odp_tm_threshold_params_init() be - * called on variables of this type before any of the fields are filled in +/** + * TM threshold parameters + * + * Use odp_tm_threshold_params_init() to initialize parameters into their + * default values. */ typedef struct { uint64_t max_pkts; /**< max pkt cnt for this threshold profile */ uint64_t max_bytes; /**< max byte cnt for this threshold profile */ - odp_bool_t enable_max_pkts; /**< TRUE if max_pkts is valid */ - odp_bool_t enable_max_bytes; /**< TRUE if max_bytes is valid */ + + /** TRUE if max_pkts is valid. The default value is false. */ + odp_bool_t enable_max_pkts; + + /** TRUE if max_bytes is valid. The default value is false. */ + odp_bool_t enable_max_bytes; } odp_tm_threshold_params_t; -/** odp_tm_threshold_params_init() must be called to initialize any - * odp_tm_threshold_params_t record before it is first used or assigned to. +/** + * Initialize TM threshold parameters * - * @param[in] params A pointer to an odp_tm_threshold_params_t record which - * is to be initialized. + * Initialize an odp_tm_threshold_params_t to its default values for all fields. + * + * @param params Address of the odp_tm_threshold_params_t to be initialized */ void odp_tm_threshold_params_init(odp_tm_threshold_params_t *params); @@ -993,17 +1336,18 @@ void odp_tm_threshold_params_init(odp_tm_threshold_params_t *params); * can subsequently be attached to any number (including zero) of tm_queues or * tm_nodes. * - * @param[in] name Optional name associated with this queue threshold - * profile. Can be NULL. If non-NULL must be unique - * amongst the set of all other queue threshold profiles. - * @param[in] params The profile parameters. See comments associated with - * the odp_tm_threshold_params_t for more details. - * @return Returns ODP_TM_INVALID upon failure, or the newly - * allocated odp_tm_threshold_t value representing this - * profile object. + * @param name Optional name associated with this queue threshold + * profile. Can be NULL. If non-NULL must be unique + * amongst the set of all other queue threshold profiles. + * @param params The profile parameters. See comments associated with + * the odp_tm_threshold_params_t for more details. + * @return Returns ODP_TM_INVALID upon failure, or the newly + * allocated odp_tm_threshold_t value representing this + * profile object. */ odp_tm_threshold_t odp_tm_threshold_create(const char *name, - odp_tm_threshold_params_t *params); + const odp_tm_threshold_params_t + *params); /** Destroy a queue threshold profile object * @@ -1011,9 +1355,9 @@ odp_tm_threshold_t odp_tm_threshold_create(const char *name, * profile object. It is an error if this threshold profile is still being * referenced by an active (connected) tm_queue or tm_node. * - * @param[in] threshold_profile Specifies the queue thresholds profile - * object which is being destroyed. - * @return Returns < 0 upon failure or 0 upon success. + * @param threshold_profile Specifies the queue thresholds profile + * object which is being destroyed. + * @return Returns < 0 upon failure or 0 upon success. */ int odp_tm_threshold_destroy(odp_tm_threshold_t threshold_profile); @@ -1021,7 +1365,7 @@ int odp_tm_threshold_destroy(odp_tm_threshold_t threshold_profile); * with the specified queue thresholds profile object, and copies them into the * supplied record. * - * @param[in] threshold_profile Specifies the queue thresholds profile + * @param threshold_profile Specifies the queue thresholds profile * object whose values are to be read. * @param[out] params A pointer to an odp_tm_threshold_params_t * record where the current queue thresholds @@ -1034,36 +1378,37 @@ int odp_tm_thresholds_params_read(odp_tm_threshold_t threshold_profile, /** odp_tm_thresholds_params_update() "sets" the current set of values * associated with the specified queue thresholds profile object. In addition, * this call has the effect that all tm_input's and tm_nodes that are - * associated (attached?) with this queue thresholds profile object will be - * updated with the new values. - * - * @param[in] threshold_profile Specifies the queue thresholds profile - * object whose values are to be set. - * @param[in] params A pointer to an odp_tm_threshold_params_t - * record where the current queue thresholds - * profile object values are taken from. - * @return Returns < 0 upon failure or 0 upon success. + * associated with this queue thresholds profile object will be updated with the + * new values. + * + * @param threshold_profile Specifies the queue thresholds profile + * object whose values are to be set. + * @param params A pointer to an odp_tm_threshold_params_t + * record where the current queue thresholds + * profile object values are taken from. + * @return Returns < 0 upon failure or 0 upon success. */ int odp_tm_thresholds_params_update(odp_tm_threshold_t threshold_profile, - odp_tm_threshold_params_t *params); + const odp_tm_threshold_params_t *params); /** odp_tm_thresholds_lookup() can be used to find the queue thresholds * profile object created with the specified name. * - * @param[in] name Name of a previously created queue thresholds profile. - * Cannot be NULL. - * @return Returns ODP_TM_INVALID upon failure, or the queue - * thresholds profile handle created with this name. + * @param name Name of a previously created queue thresholds profile. + * Cannot be NULL. + * @return Returns ODP_TM_INVALID upon failure, or the queue + * thresholds profile handle created with this name. */ odp_tm_threshold_t odp_tm_thresholds_lookup(const char *name); -/** WRED Profiles - types and functions */ +/* WRED Profiles - types and functions + * -------------------------------------------------------- */ -/** The odp_tm_wred_params_t record type is used to supply the parameters - * associated with a Random Early Detection profile. Since it is expected that - * implementations might augment this record type with platform specific - * additional fields - it is required that odp_tm_wred_params_init() be called - * on variables of this type before any of the fields are filled in. +/** + * TM WRED parameters + * + * Use odp_tm_wred_params_init() to initialize parameters into their default + * values. */ typedef struct { /** When min_threshold is set to zero then single-slope WRED is @@ -1105,7 +1450,7 @@ typedef struct { /** When enable_wred is false, all tm_queues and tm_nodes that are * attached to this profile will not take part in a Random Early - * Detection algorithm. */ + * Detection algorithm. The default value is false. */ odp_bool_t enable_wred; /** When use_byte_fullness is true then WRED will use queue memory @@ -1113,15 +1458,16 @@ typedef struct { * is false, WRED will use the queue length (i.e. the number of * packets in the queue) as the fullness criterion. Often will be set * to true for WRED profiles applied to tm_queues and set to false for - * WRED profiles applied to tm_nodes. */ + * WRED profiles applied to tm_nodes. The default value is false. */ odp_bool_t use_byte_fullness; } odp_tm_wred_params_t; -/** odp_tm_wred_params_init() must be called to initialize any - * odp_tm_wred_params_t record before it is first used or assigned to. +/** + * Initialize TM WRED parameters + * + * Initialize an odp_tm_wred_params_t to its default values for all fields. * - * @param[in] params A pointer to an odp_tm_wred_params_t record which - * is to be initialized. + * @param params Address of the odp_tm_wred_params_t to be initialized */ void odp_tm_wred_params_init(odp_tm_wred_params_t *params); @@ -1129,17 +1475,17 @@ void odp_tm_wred_params_init(odp_tm_wred_params_t *params); * profile object, which can subsequently be attached to any number (including * zero) of tm_queues or tm_nodes. * - * @param[in] name Optional name associated with this WRED profile. Can - * be NULL. If non-NULL must be unique amongst the set of - * all other WRED profiles. - * @param[in] params The profile parameters. See comments associated with the - * odp_tm_wred_params_t for more details. - * @return Returns ODP_TM_INVALID upon failure, or the newly - * allocated odp_tm_wred_t value representing this profile - * object. + * @param name Optional name associated with this WRED profile. Can + * be NULL. If non-NULL must be unique amongst the set of + * all other WRED profiles. + * @param params The profile parameters. See comments associated with the + * odp_tm_wred_params_t for more details. + * @return Returns ODP_TM_INVALID upon failure, or the newly + * allocated odp_tm_wred_t value representing this profile + * object. */ odp_tm_wred_t odp_tm_wred_create(const char *name, - odp_tm_wred_params_t *params); + const odp_tm_wred_params_t *params); /** Destroy WRED profile object * @@ -1147,9 +1493,9 @@ odp_tm_wred_t odp_tm_wred_create(const char *name, * profile object. It is an error if this profile object is still being * referenced by an active (connected) tm_node. * - * @param[in] wred_profile Specifies the WRED profile object which is - * being destroyed. - * @return Returns < 0 upon failure or 0 upon success. + * @param wred_profile Specifies the WRED profile object which is + * being destroyed. + * @return Returns < 0 upon failure or 0 upon success. */ int odp_tm_wred_destroy(odp_tm_wred_t wred_profile); @@ -1157,7 +1503,7 @@ int odp_tm_wred_destroy(odp_tm_wred_t wred_profile); * with the specified WRED profile object, and copies them into the supplied * record. * - * @param[in] wred_profile Specifies the WRED profile object whose + * @param wred_profile Specifies the WRED profile object whose * values are to be read. * @param[out] params A pointer to an odp_tm_wred_params_t record * where the current WRED profile object values @@ -1169,35 +1515,34 @@ int odp_tm_wred_params_read(odp_tm_wred_t wred_profile, /** odp_tm_wred_params_update() "sets" the current set of values associated * with the specified WRED profile object. In addition, this call has the - * effect that all tm_input's and tm_nodes that are associated (attached?) - * with this WRED profile object will be updated with the new values. + * effect that all tm_input's and tm_nodes that are associated with this WRED + * profile object will be updated with the new values. * - * @param[in] wred_profile Specifies the WRED profile object whose - * values are to be set. - * @param[in] params A pointer to an odp_tm_wred_params_t record - * where the new WRED profile object values - * are taken from. - * @return Returns < 0 upon failure or 0 upon success. + * @param wred_profile Specifies the WRED profile object whose + * values are to be set. + * @param params A pointer to an odp_tm_wred_params_t record + * where the new WRED profile object values + * are taken from. + * @return Returns < 0 upon failure or 0 upon success. */ int odp_tm_wred_params_update(odp_tm_wred_t wred_profile, - odp_tm_wred_params_t *params); + const odp_tm_wred_params_t *params); /** odp_tm_wred_lookup() can be used to find the WRED profile object created * with the specified name. * - * @param[in] name Name of a previously created WRED profile. Cannot be - * NULL. - * @return Returns ODP_TM_INVALID upon failure, or the WRED - * profile handle created with this name. + * @param name Name of a previously created WRED profile. Cannot be NULL. + * + * @return Returns ODP_TM_INVALID upon failure, or the WRED + * profile handle created with this name. */ odp_tm_wred_t odp_tm_wred_lookup(const char *name); -/** The odp_tm_node_params_t record type is used to hold extra parameters when - * calling the odp_tm_node_create() function. Many of these fields are - * optional EXCEPT for max_fanin and level. Also since it is expected that - * implementations might augment this record type with platform specific - * additional fields - it is required that odp_tm_node_params_init() be called - * on variables of this type before any of the fields are filled in. +/** + * TM node parameters + * + * Many of these fields are optional EXCEPT for max_fanin and level. Use + * odp_tm_node_params_init() to initialize parameters into their default values. */ typedef struct { /** The user_context field is an generic pointer that the user can @@ -1212,17 +1557,19 @@ typedef struct { /** The shaper profile to be associated with this tm_node. Can be * ODP_TM_INVALID and can also be set and changed post-creation via - * odp_tm_node_shaper_config(); */ + * odp_tm_node_shaper_config(); The default value is ODP_TM_INVALID. */ odp_tm_shaper_t shaper_profile; /** The threshold profile to be used in setting the max queue fullness - * for WRED and/or tail drop? Can be ODP_TM_INVALID and can also be - * set and changed post-creation via odp_tm_node_threshold_config(). */ + * for WRED and/or tail drop. Can be ODP_TM_INVALID and can also be set + * and changed post-creation via odp_tm_node_threshold_config(). The + * default value is ODP_TM_INVALID. */ odp_tm_threshold_t threshold_profile; /** The WRED profile(s) to be associated with this tm_node. Any or * all array elements can be ODP_TM_INVALID and can also be set and - * changed post-creation via odp_tm_node_wred_config(). */ + * changed post-creation via odp_tm_node_wred_config(). + * The default value is ODP_TM_INVALID for every color. */ odp_tm_wred_t wred_profile[ODP_NUM_PACKET_COLORS]; /** The level (or tm_node stage) sets the level for this tm_node It @@ -1231,13 +1578,30 @@ typedef struct { * greater levels may be connected to the fan-in of tm_node's with * numerically smaller levels. */ uint8_t level; + + /** New strict priority level assigned to packets going through this + * node when packet priority mode is ODP_TM_PKT_PRIO_MODE_OVERWRITE. + * In other packet priority modes this field is ignored. The new + * priority does not affect packet processing in this node but in + * its destination node. + * + * The value must be in the range 0..ODP_TM_MAX_PRIORITIES-1. + * Additionally, the total number of possible priorities seen by + * the destination node must not exceed the max priority configured + * for the destination node. + * + * @see odp_tm_pkt_prio_mode_t + * @see odp_tm_level_requirements_t::max_priority + */ + uint8_t priority; } odp_tm_node_params_t; -/** odp_tm_node_params_init() must be called to initialize any - * odp_tm_node_params_t record before it is first used or assigned to. +/** + * Initialize TM node parameters + * + * Initialize an odp_tm_node_params_t to its default values for all fields. * - * @param[in] params A pointer to an odp_tm_node_params_t record which - * is to be initialized. + * @param params Address of the odp_tm_node_params_t to be initialized */ void odp_tm_node_params_init(odp_tm_node_params_t *params); @@ -1248,40 +1612,39 @@ void odp_tm_node_params_init(odp_tm_node_params_t *params); * strict priority levels for an tm_node cannot be changed after tm_node * creation. The level parameter MUST be in the range 0..max_level - 1. * - * @param[in] odp_tm Odp_tm is used to identify the TM system into which this - * odp_tm_node object is created. - * @param[in] name Optional name that can be used later later to find this - * same odp_tm_node_t. Can be NULL, otherwise must be - * unique across all odp_tm_node objects. - * @param[in] params A pointer to a record holding (an extensible) set of - * properties/attributes of this tm_node. - * @return Returns ODP_TM_INVALID upon failure, otherwise returns - * a valid odp_tm_node_t handle if successful. + * @param tm Handle of the TM system into which this odp_tm_node object is + * created. + * @param name Optional name that can be used later later to find this + * same odp_tm_node_t. Can be NULL, otherwise must be + * unique across all odp_tm_node objects. + * @param params TM node parameters. + * + * @return Returns ODP_TM_INVALID upon failure, otherwise returns + * a valid odp_tm_node_t handle if successful. */ -odp_tm_node_t odp_tm_node_create(odp_tm_t odp_tm, - const char *name, - odp_tm_node_params_t *params); +odp_tm_node_t odp_tm_node_create(odp_tm_t tm, const char *name, + const odp_tm_node_params_t *params); /** Destroy a tm_node object. * * The odp_tm_node_destroy frees the resources used by a tm_node_t object. * The tm_node to be destroyed MUST not have any parent or child entities. * - * @param[in] tm_node Specifies the tm_node to be destroyed (freed). - * @return Returns -1 upon failure, 0 upon success. + * @param tm_node Specifies the tm_node to be destroyed (freed). + * @return Returns -1 upon failure, 0 upon success. */ int odp_tm_node_destroy(odp_tm_node_t tm_node); /** The odp_tm_node_shaper_config() function is used to dynamically set or * change the shaper profile associated with this tm_node. * - * @param[in] tm_node Specifies the tm_node to be changed. - * @param[in] shaper_profile Specifies the shaper profile that should - * now be used for the shaper entity within the - * given tm_node. Note that it is legal to specify - * ODP_TM_INVALID indicating that this tm_node - * no longer implements a shaper function. - * @return Returns 0 upon success and < 0 upon failure. + * @param tm_node Specifies the tm_node to be changed. + * @param shaper_profile Specifies the shaper profile that should + * now be used for the shaper entity within the + * given tm_node. Note that it is legal to specify + * ODP_TM_INVALID indicating that this tm_node + * no longer implements a shaper function. + * @return Returns 0 upon success and < 0 upon failure. */ int odp_tm_node_shaper_config(odp_tm_node_t tm_node, odp_tm_shaper_t shaper_profile); @@ -1289,15 +1652,15 @@ int odp_tm_node_shaper_config(odp_tm_node_t tm_node, /** The odp_tm_node_sched_config() function is used to dynamically set or * change the scheduler profile associated with a tm_node. * - * @param[in] tm_node Specifies the tm_node to be changed. - * @param[in] tm_fan_in_node Specifies which of the specified tm_node's - * fan-in's weights etc are to be changed. The - * fan-in is identified by the "producer"/parent - * tm_node actually connected to this fan-in. - * @param[in] sched_profile Specifies the scheduler profile that should - * now be used for the WFQ/RR entity within the - * given tm_node. - * @return Returns 0 upon success and < 0 upon failure. + * @param tm_node Specifies the tm_node to be changed. + * @param tm_fan_in_node Specifies which of the specified tm_node's + * fan-in's weights etc are to be changed. The + * fan-in is identified by the "producer"/parent + * tm_node actually connected to this fan-in. + * @param sched_profile Specifies the scheduler profile that should + * now be used for the WFQ/RR entity within the + * given tm_node. + * @return Returns 0 upon success and < 0 upon failure. */ int odp_tm_node_sched_config(odp_tm_node_t tm_node, odp_tm_node_t tm_fan_in_node, @@ -1306,10 +1669,10 @@ int odp_tm_node_sched_config(odp_tm_node_t tm_node, /** The odp_tm_node_threshold_config() function is used to dynamically set or * change the queue threshold profile associated with this tm_node. * - * @param[in] tm_node Specifies the tm_node to be changed. - * @param[in] thresholds_profile Specifies the queue threshold profile that - * should now be used for the given tm_node. - * @return Returns 0 upon success and < 0 upon failure. + * @param tm_node Specifies the tm_node to be changed. + * @param thresholds_profile Specifies the queue threshold profile that + * should now be used for the given tm_node. + * @return Returns 0 upon success and < 0 upon failure. */ int odp_tm_node_threshold_config(odp_tm_node_t tm_node, odp_tm_threshold_t thresholds_profile); @@ -1318,16 +1681,16 @@ int odp_tm_node_threshold_config(odp_tm_node_t tm_node, * change the WRED profile associated with this tm_node or tm_node/pkt_color * combination. * - * @param[in] tm_node Specifies the tm_node to be changed. - * @param[in] pkt_color Specifies the pkt_color that this profile is to be - * used with. Can also be the special value - * ALL_PKT_COLORS. - * @param[in] wred_profile Specifies the WRED profile that should now be used - * by this tm_queue, when processing pkts of this - * pkt_color. It can be the value ODP_TM_INVALID - * indicating that this tm_queue/pkt_color combination - * no longer implements WRED. - * @return Returns 0 upon success and < 0 upon failure. + * @param tm_node Specifies the tm_node to be changed. + * @param pkt_color Specifies the pkt_color that this profile is to be + * used with. Can also be the special value + * ALL_PKT_COLORS. + * @param wred_profile Specifies the WRED profile that should now be used + * by this tm_queue, when processing pkts of this + * pkt_color. It can be the value ODP_TM_INVALID + * indicating that this tm_queue/pkt_color combination + * no longer implements WRED. + * @return Returns 0 upon success and < 0 upon failure. */ int odp_tm_node_wred_config(odp_tm_node_t tm_node, odp_packet_color_t pkt_color, @@ -1336,43 +1699,40 @@ int odp_tm_node_wred_config(odp_tm_node_t tm_node, /** odp_tm_node_lookup() can be used to find the tm_node object created with * the specified name. * - * @param[in] odp_tm Odp_tm is used to identify the TM system into which this - * odp_tm_node object is created. - * @param[in] name Name of a previously created tm_node. Cannot be - * NULL. - * @return Returns ODP_TM_INVALID upon failure, or the tm_node - * handle created with this name. + * @param tm TM handle + * @param name Name of a previously created tm_node. Cannot be NULL. + * + * @return Returns ODP_TM_INVALID upon failure, or the tm_node + * handle created with this name. */ -odp_tm_node_t odp_tm_node_lookup(odp_tm_t odp_tm, const char *name); +odp_tm_node_t odp_tm_node_lookup(odp_tm_t tm, const char *name); /** odp_tm_node_context() can be used to get the user_context value that is * associated with the given tm_node. * - * @param[in] tm_node Specifies the tm_node whose user_context is to be gotten. - * @return Returns the user_context pointer associated with this - * tm_node. Returns NULL if the tm_node is not valid OR - * if the user_context was NLL. - * handle created with this name. + * @param tm_node Specifies the tm_node whose user_context is to be gotten. + * @return Returns the user_context pointer associated with this + * tm_node. Returns NULL if the tm_node is not valid OR + * if the user_context was NULL. */ void *odp_tm_node_context(odp_tm_node_t tm_node); /** odp_tm_node_context_set() can be used to set the user_context value that is * associated with the given tm_node. * - * @param[in] tm_node Specifies the tm_node whose user_context is to be set. - * @param[in] user_context Generic pointer associated with the given tm_node. - * Does not have any effect on the tm_node semantics. - * @return Returns 0 upon success and -1 if the given tm_node - * is not valid. + * @param tm_node Specifies the tm_node whose user_context is to be set. + * @param user_context Generic pointer associated with the given tm_node. + * Does not have any effect on the tm_node semantics. + * @return Returns 0 upon success and -1 if the given tm_node + * is not valid. */ int odp_tm_node_context_set(odp_tm_node_t tm_node, void *user_context); -/** The odp_tm_queue_params_t record type is used to hold extra parameters - * when calling the odp_tm_queue_create() function. Many of these fields are - * optional EXCEPT for priority. Also since it is expected that - * implementations might augment this record type with platform specific - * additional fields - it is required that odp_tm_queue_params_init() be - * called on variables of this type before any of the fields are filled in. +/** + * TM queue parameters + * + * Use odp_tm_queue_params_init() to initialize parameters into their default + * values. */ typedef struct { /** The user_context field is an generic pointer that the user can @@ -1382,94 +1742,104 @@ typedef struct { /** The shaper profile to be associated with this tm_queue. Can be * ODP_TM_INVALID and can also be set and changed post-creation via - * odp_tm_queue_shaper_config(). */ + * odp_tm_queue_shaper_config(). The default value is ODP_TM_INVALID. */ odp_tm_shaper_t shaper_profile; /** The threshold profile to be used in setting the max queue fullness - * for WRED and/or tail drop? Can be ODP_TM_INVALID and can also be - * set and changed post-creation via odp_tm_queue_threshold_config(). */ + * for WRED and/or tail drop. Can be ODP_TM_INVALID and can also be set + * and changed post-creation via odp_tm_queue_threshold_config(). The + * default value is ODP_TM_INVALID. + * + * One can specify the maximum queue limits either as a maximum number + * of packets in the queue or as a maximum number of bytes in the queue, + * or if both are specified, then whichever limit is hit first. */ odp_tm_threshold_t threshold_profile; /** The WRED profile(s) to be associated with this tm_queue. Any or * all array elements can be ODP_TM_INVALID and can also be set and - * changed post-creation via odp_tm_queue_wred_config(). */ + * changed post-creation via odp_tm_queue_wred_config(). + * The default value is ODP_TM_INVALID for every color. */ odp_tm_wred_t wred_profile[ODP_NUM_PACKET_COLORS]; /** The strict priority level assigned to packets in this tm_queue - * in other words all packets associated with a given tm_queue MUST * have the same single strict priority level and this level must be - * in the range 0..max_priority. */ + * in the range 0..max_priority. The default value is 0. */ uint8_t priority; + + /** Maintain original packet order of the source queue when enqueuing + * packets to this queue while holding ordered or atomic queue + * synchronization context. Default value of this flag is true. + */ + odp_bool_t ordered_enqueue; } odp_tm_queue_params_t; -/** odp_tm_queue_params_init() must be called to initialize any - * odp_tm_queue_params_t record before it is first used or assigned to. +/** + * Initialize TM queue parameters + * + * Initialize an odp_tm_queue_params_t to its default values for all fields. * - * @param[in] params A pointer to an odp_tm_queue_params_t record which - * is to be initialized. + * @param params Address of the odp_tm_queue_params_t to be initialized */ void odp_tm_queue_params_init(odp_tm_queue_params_t *params); -/** Create an tm_queue object. One can specify the maximum queue limits - * either as a maximum number of packets in the queue OR as a maximum number - * of bytes in the queue, or if both are specified, then whichever limit is - * hit first. Note that in the case of specifying the maximum queue memory - * size as bytes, the system is free to instead convert this byte value into a - * number of buffers and instead limit the queue memory usage by buffer counts - * versus strictly using byte counts. +/** + * TM queue create + * + * Create a TM queue according to the queue parameters. Use + * odp_tm_queue_params_init() to initialize parameters into their default values. + * + * @param tm Handle of the TM system into which this odp_tm_queue object is + * created. + * @param params TM queue parameters. * - * @param[in] odp_tm Odp_tm is used to identify the TM system into which this - * odp_tm_queue object is created. - * @param[in] params A pointer to a record holding (an extensible) set of - * properties/attributes of this tm_queue. - * @return Returns ODP_TM_INVALID upon failure, otherwise a valid - * odp_tm_queue_t handle. + * @return Returns ODP_TM_INVALID upon failure, otherwise a valid + * odp_tm_queue_t handle. */ -odp_tm_queue_t odp_tm_queue_create(odp_tm_t odp_tm, - odp_tm_queue_params_t *params); +odp_tm_queue_t odp_tm_queue_create(odp_tm_t tm, + const odp_tm_queue_params_t *params); /** Destroy an tm_queue object. The odp_tm_queue_destroy frees the resources * used by a tm_queue_t object. The tm_queue to be destroyed MUST not be * connected in a tm system, and consequently cannot contain any pkts. * - * @param[in] tm_queue Specifies the tm_queue to be destroyed (freed). - * @return Returns -1 upon failure, 0 upon success. + * @param tm_queue Specifies the tm_queue to be destroyed (freed). + * @return Returns -1 upon failure, 0 upon success. */ int odp_tm_queue_destroy(odp_tm_queue_t tm_queue); /** odp_tm_queue_context() can be used to get the user_context value that is * associated with the given tm_queue. * - * @param[in] tm_queue Specifies the tm_queue whose user_context is to be - * returned. - * @return Returns the user_context pointer associated with this - * tm_queue. Returns NULL if the tm_quue is not valid OR - * if the user_context was NULL. + * @param tm_queue Specifies the tm_queue whose user_context is to be + * returned. + * @return Returns the user_context pointer associated with this + * tm_queue. Returns NULL if the tm_queue is not valid OR + * if the user_context was NULL. */ void *odp_tm_queue_context(odp_tm_queue_t tm_queue); /** odp_tm_queue_context_set() can be used to set the user_context value that is * associated with the given tm_queue. * - * @param[in] tm_queue Specifies the tm_queue whose user_context is to be - * set. - * @param[in] user_context Generic pointer associated with the given tm_queue. - * Does not have any effect on the tm_queue semantics. - * @return Returns 0 upon success and -1 if the given tm_queu - * is not valid. + * @param tm_queue Specifies the tm_queue whose user_context is to be set. + * @param user_context Generic pointer associated with the given tm_queue. + * Does not have any effect on the tm_queue semantics. + * @return Returns 0 upon success and -1 if the given tm_queue + * is not valid. */ int odp_tm_queue_context_set(odp_tm_queue_t tm_queue, void *user_context); /** The odp_tm_queue_shaper_config() function is used to dynamically set * or change the shaper profile associated with this tm_queue. * - * @param[in] tm_queue Specifies the tm_queue to be changed. - * @param[in] shaper_profile Specifies the shaper profile that should now be - * used for shaping the tm_queue's packet stream. - * Note that it is legal to specify ODP_TM_INVALID - * indicating that this tm_queue no longer - * implements a shaper function. - * @return Returns 0 upon success and < 0 upon failure. + * @param tm_queue Specifies the tm_queue to be changed. + * @param shaper_profile Specifies the shaper profile that should now be + * used for shaping the tm_queue's packet stream. + * Note that it is legal to specify ODP_TM_INVALID + * indicating that this tm_queue no longer + * implements a shaper function. + * @return Returns 0 upon success and < 0 upon failure. */ int odp_tm_queue_shaper_config(odp_tm_queue_t tm_queue, odp_tm_shaper_t shaper_profile); @@ -1479,15 +1849,15 @@ int odp_tm_queue_shaper_config(odp_tm_queue_t tm_queue, * the name, this function affects a tm_node scheduler - specifically the * scheduler fan-in when such fan-in comes from an tm_queue. * - * @param[in] tm_node Specifies the tm_node to be changed. - * @param[in] tm_fan_in_queue Specifies which of the specified tm_node's - * fan-in's weights etc are to be changed. The - * fan-in is identified by the "producer"/parent - * tm_queue actually connected to this fan-in. - * @param[in] sched_profile Specifies the scheduler profile that should - * now be used for the WFQ/RR entity within the - * given tm_node. - * @return Returns 0 upon success and < 0 upon failure. + * @param tm_node Specifies the tm_node to be changed. + * @param tm_fan_in_queue Specifies which of the specified tm_node's + * fan-in's weights etc are to be changed. The + * fan-in is identified by the "producer"/parent + * tm_queue actually connected to this fan-in. + * @param sched_profile Specifies the scheduler profile that should + * now be used for the WFQ/RR entity within the + * given tm_node. + * @return Returns 0 upon success and < 0 upon failure. */ int odp_tm_queue_sched_config(odp_tm_node_t tm_node, odp_tm_queue_t tm_fan_in_queue, @@ -1496,10 +1866,10 @@ int odp_tm_queue_sched_config(odp_tm_node_t tm_node, /** The odp_tm_queue_threshold_config() function is used to dynamically set or * change the queue threshold profile associated with this tm_queue. * - * @param[in] tm_queue Specifies the tm_queue to be changed. - * @param[in] thresholds_profile Specifies the queue threshold profile that - * should now be used for the given tm_queue. - * @return Returns 0 upon success and < 0 upon failure. + * @param tm_queue Specifies the tm_queue to be changed. + * @param thresholds_profile Specifies the queue threshold profile that + * should now be used for the given tm_queue. + * @return Returns 0 upon success and < 0 upon failure. */ int odp_tm_queue_threshold_config(odp_tm_queue_t tm_queue, odp_tm_threshold_t thresholds_profile); @@ -1508,22 +1878,23 @@ int odp_tm_queue_threshold_config(odp_tm_queue_t tm_queue, * the WRED profile associated with this tm_queue or tm_queue/pkt_color * combination. * - * @param[in] tm_queue Specifies the tm_queue to be changed. - * @param[in] pkt_color Specifies the pkt_color that this profile is to be - * used with. Can also be the special value - * ALL_PKT_COLORS. - * @param[in] wred_profile Specifies the WRED profile that should now be used - * by this tm_queue, when processing pkts of this - * pkt_color. It can be the value ODP_TM_INVALID - * indicating that this tm_queue/pkt_color combination - * no longer implements WRED. - * @return Returns 0 upon success and < 0 upon failure. + * @param tm_queue Specifies the tm_queue to be changed. + * @param pkt_color Specifies the pkt_color that this profile is to be + * used with. Can also be the special value + * ALL_PKT_COLORS. + * @param wred_profile Specifies the WRED profile that should now be used + * by this tm_queue, when processing pkts of this + * pkt_color. It can be the value ODP_TM_INVALID + * indicating that this tm_queue/pkt_color combination + * no longer implements WRED. + * @return Returns 0 upon success and < 0 upon failure. */ int odp_tm_queue_wred_config(odp_tm_queue_t tm_queue, odp_packet_color_t pkt_color, odp_tm_wred_t wred_profile); -/** Topology setting functions */ +/* Topology setting functions + * -------------------------------------------------------- */ /** Connects two tm_nodes * @@ -1531,14 +1902,14 @@ int odp_tm_queue_wred_config(odp_tm_queue_t tm_queue, * dst_tm_node. Note that an ODP_TM_ROOT handle passed in for the * dst_tm_node implies connection to the egress/root object of this TM system. * - * @param[in] src_tm_node odp_tm_node_t handle of the tm_node whose output is - * to be connected to the fan-in of the next tm_node - * as represented by the dst_tm_node. - * @param[in] dst_tm_node odp_tm_node_t handle of the tm_node object that will - * receive all of the pkt_descs from the src tm_node - * output. If ODP_TM_ROOT, then attachment is to - * the root egress object/spigot. - * @return 0 upon success, < 0 on failure. + * @param src_tm_node odp_tm_node_t handle of the tm_node whose output is + * to be connected to the fan-in of the next tm_node + * as represented by the dst_tm_node. + * @param dst_tm_node odp_tm_node_t handle of the tm_node object that will + * receive all of the pkt_descs from the src tm_node + * output. If ODP_TM_ROOT, then attachment is to + * the root egress object/spigot. + * @return 0 upon success, < 0 on failure. */ int odp_tm_node_connect(odp_tm_node_t src_tm_node, odp_tm_node_t dst_tm_node); @@ -1549,11 +1920,10 @@ int odp_tm_node_connect(odp_tm_node_t src_tm_node, odp_tm_node_t dst_tm_node); * tm_queue to be in the fanin tree (directly or indirectly) of this tm_node. * Note that it is legal for this tm_node to no fanout connection. * - * @param[in] src_tm_node odp_tm_node_t handle of the tm_node whose output is - * to be disconnected from the fan-in of the next - * tm_node. + * @param src_tm_node odp_tm_node_t handle of the tm_node whose output is + * to be disconnected from the fan-in of the next tm_node. * - * @return 0 upon success, < 0 on failure. + * @return 0 upon success, < 0 on failure. */ int odp_tm_node_disconnect(odp_tm_node_t src_tm_node); @@ -1561,12 +1931,12 @@ int odp_tm_node_disconnect(odp_tm_node_t src_tm_node); * parent tm_node or to the egress/root node. The tm_queue will then become * one of the dst node's fan-in set. * - * @param[in] tm_queue Specifies the tm_queue. - * @param[in] dst_tm_node odp_tm_node_t handle of the tm_node object that will - * receive all of the pkt_descs from the src tm_node - * output. If ODP_TM_ROOT, then attachment is to - * the root egress object/spigot. - * @return Returns 0 upon success and < 0 upon failure. + * @param tm_queue Specifies the tm_queue. + * @param dst_tm_node odp_tm_node_t handle of the tm_node object that will + * receive all of the pkt_descs from the src tm_node + * output. If ODP_TM_ROOT, then attachment is to + * the root egress object/spigot. + * @return Returns 0 upon success and < 0 upon failure. */ int odp_tm_queue_connect(odp_tm_queue_t tm_queue, odp_tm_node_t dst_tm_node); @@ -1576,45 +1946,82 @@ int odp_tm_queue_connect(odp_tm_queue_t tm_queue, odp_tm_node_t dst_tm_node); * tm_queue from its fanout. Note that it is legal for this tm_queue to * have no fanout connection. * - * @param[in] tm_queue Specifies the tm_queue. - * @return 0 upon success, < 0 on failure. + * @param tm_queue Specifies the tm_queue. + * @return 0 upon success, < 0 on failure. */ int odp_tm_queue_disconnect(odp_tm_queue_t tm_queue); -/** Input API */ +/* Input API + * -------------------------------------------------------- */ -/** The odp_tm_enq() function is used to add packets to a given TM system. - * Note that the System Metadata associated with the pkt needed by the TM - * system is (a) a drop_eligible bit, (b) a two bit "pkt_color", (c) a 16-bit - * pkt_len, and MAYBE? (d) a signed 8-bit shaper_len_adjust. +/** Send packet to TM system + * + * Note that the packet metadata utilized by the TM system is (a) + * drop_eligible, (b) pkt_color, (c) pkt_len, and (d) shaper_len_adjust. * * If there is a non-zero shaper_len_adjust, then it is added to the pkt_len * after any non-zero shaper_len_adjust that is part of the shaper profile. * * The pkt_color bits are a result of some earlier Metering/Marking/Policing - * processing (typically ingress based), and should not be confused with the - * shaper_color produced from the TM shaper entities within the tm_inputs and - * tm_nodes. + * processing. * - * @param[in] tm_queue Specifies the tm_queue (and indirectly the TM system). - * @param[in] pkt Handle to a packet. - * @return Returns 0 upon success, < 0 upon failure. One of the - * more common failure reasons is WRED drop. + * @param tm_queue Specifies the tm_queue (and indirectly the TM system). + * @param pkt Handle to a packet. + * @return Returns 0 upon success, < 0 upon failure. One of the + * more common failure reasons is WRED drop. */ int odp_tm_enq(odp_tm_queue_t tm_queue, odp_packet_t pkt); +/** The odp_tm_enq_multi() function is used to add packets to a given TM system. + * This function enqueues multiple packets but is otherwise similar to + * odp_tm_enq(). Packets dropped by WRED or other queue management action do not + * cause this function to return a failure. Such packets get consumed just like + * the packets that are not dropped. + * + * When the return value is less than 'num', the remaining packets at the end of + * the array are not consumed, and the caller maintains ownership of those. + * + * @param tm_queue Specifies the tm_queue (and indirectly the TM system). + * @param packets Array of packets to enqueue. + * @param num Number of packets to enqueue. + * + * @return Number of packets consumed (0 ... num) + * @retval <0 on failure. + */ +int odp_tm_enq_multi(odp_tm_queue_t tm_queue, const odp_packet_t packets[], int num); + +/** Send packets with segmentation offload to TM system + * + * Like odp_tm_enq_multi(), but segments packets according LSO configuration. See e.g. + * odp_pktout_send_lso() for documentation how packets are split into smaller packets during + * the segmentation offload. Packet segmentation is done first and TM functionality is applied + * to the resulting packets. + * + * @param tm_queue Specifies the tm_queue (and indirectly the TM system) + * @param packets Array of packets to enqueue with segmentation offload + * @param num Number of packets in the array + * @param lso_opt LSO options to be used for all packets. When NULL, LSO options are + * read from each packet (see odp_packet_lso_request()). + * + * @return Number of packets successfully processed and consumed (0 ... num) + * @retval <0 on failure + */ +int odp_tm_enq_multi_lso(odp_tm_queue_t tm_queue, const odp_packet_t packets[], int num, + const odp_packet_lso_opt_t *lso_opt); + /** The odp_tm_enq_with_cnt() function behaves identically to odp_tm_enq(), - * except that it also returns (an approximation to?) the current tm_queue - * packet queue count. + * except that it also returns the current tm_queue packet queue count (may be + * an approximation). * - * @param[in] tm_queue Specifies the tm_queue (and indirectly the TM system). - * @param[in] pkt Handle to a packet. - * @return Returns the number of packets previously enqueued on - * this tm_queue upon success, < 0 upon failure. + * @param tm_queue Specifies the tm_queue (and indirectly the TM system). + * @param pkt Handle to a packet. + * @return Returns the number of packets previously enqueued on + * this tm_queue upon success, < 0 upon failure. */ int odp_tm_enq_with_cnt(odp_tm_queue_t tm_queue, odp_packet_t pkt); -/* Dynamic state query functions */ +/* Dynamic state query functions + * -------------------------------------------------------- */ /** The odp_tm_node_info_t record type is used to return various bits of * information about a given tm_node via the odp_tm_node_info() function. @@ -1653,9 +2060,10 @@ typedef struct { /** Get tm_node Info * * The odp_tm_node_info() function is used to extract various bits of - * configuration associated with a given tm_node. + * configuration associated with a given tm_node. The info structure is written + * only on success. * - * @param[in] tm_node Specifies the tm_node to be queried. + * @param tm_node Specifies the tm_node to be queried. * @param[out] info A pointer to an odp_tm_node_info_t record that is to * be filled in by this call. * @return Returns < 0 upon failure, 0 upon success. @@ -1713,13 +2121,13 @@ typedef struct { * from their fanin list, a reasonable list walk can occur - even while past or * future entries are being removed or while future entries are being added. * Note that all new additions to a fanin list always take place at the end of - * the list. + * the list. The info structure is written only on success. * - * @param[in] tm_node Specifies the tm_node to be queried. - * @param[inout] info A pointer to an odp_tm_node_fanin_info_t record that - * is used to determine which fanin entry is to be - * next filled in by this call. - * @return Returns < 0 upon failure, 0 upon success. + * @param tm_node Specifies the tm_node to be queried. + * @param[in,out] info A pointer to an odp_tm_node_fanin_info_t record that + * is used to determine which fanin entry is to be + * next filled in by this call. + * @return Returns < 0 upon failure, 0 upon success. */ int odp_tm_node_fanin_info(odp_tm_node_t tm_node, odp_tm_node_fanin_info_t *info); @@ -1745,7 +2153,7 @@ typedef struct { odp_tm_wred_t wred_profile[ODP_NUM_PACKET_COLORS]; /** The next_tm_node is the "next" node in the tree - i.e. the fanout - * of this tm_queu. Can be ODP_TM_ROOT if this tm_queue directly + * of this tm_queue. Can be ODP_TM_ROOT if this tm_queue directly * connects to the egress spigot and can be ODP_TM_INVALID if this * tm_queue is disconnected from the TM system tree. */ odp_tm_node_t next_tm_node; @@ -1758,9 +2166,10 @@ typedef struct { /** Get tm_queue Info * * The odp_tm_queue_info() function is used to extract various bits of - * configuration associated with a given tm_queue. + * configuration associated with a given tm_queue. The info structure is + * written only on success. * - * @param[in] tm_queue Specifies the tm_queue to be queried. + * @param tm_queue Specifies the tm_queue to be queried. * @param[out] info A pointer to an odp_tm_queue_info_t record that is to * be filled in by this call. * @return Returns < 0 upon failure, 0 upon success. @@ -1772,7 +2181,7 @@ int odp_tm_queue_info(odp_tm_queue_t tm_queue, odp_tm_queue_info_t *info); */ #define ODP_TM_QUERY_PKT_CNT 0x01 /**< The total_pkt_cnt value */ #define ODP_TM_QUERY_BYTE_CNT 0x02 /**< The total_byte_cnt value */ -#define ODP_TM_QUERY_THRESHOLDS 0x04 /**< The thresholds??? */ +#define ODP_TM_QUERY_THRESHOLDS 0x04 /**< The threshold values */ /** The odp_tm_query_info_t record type is used to return the various counts * as requested by functions like odp_tm_queue_query() and @@ -1838,15 +2247,14 @@ typedef struct { } odp_tm_query_info_t; /** The odp_tm_queue_query() function can be used to check a single tm_queue's - * queue utilization. The query_flags indicate whether or not packet counts, - * byte counts or both are being requested. It is an error to request - * neither. The implementation may still return both sets of counts - * regardless of query_flags if the cost of returning all the counts is - * comparable to the cost of checking the query_flags. + * queue utilization. The query flags indicate which information is being + * requested. + * The implementation may choose to return additional information that was not + * requested. The info structure is written only on success. * - * @param[in] tm_queue Specifies the tm_queue (and indirectly the + * @param tm_queue Specifies the tm_queue (and indirectly the * TM system). - * @param[out] query_flags A set of flag bits indicating which counters are + * @param query_flags A set of flag bits indicating which counters are * being requested to be returned in the info record. * @param[out] info Pointer to an odp_tm_query_info_t record where the * requested queue info is returned. @@ -1857,17 +2265,15 @@ int odp_tm_queue_query(odp_tm_queue_t tm_queue, odp_tm_query_info_t *info); /** The odp_tm_priority_query() function can be used to check the queue - * utilization of all tm_queue's with the given priority. The query_flags - * indicate whether or not packet counts, byte counts or both are being - * requested. It is an error to request neither. The implementation may - * still return both sets of counts regardless of query_flags if the cost of - * returning all the counts is comparable to the cost of checking the - * query_flags. - * - * @param[in] odp_tm Specifies the TM system. - * @param[in] priority Supplies the strict priority level used to specify + * utilization of all tm_queue's with the given priority. The query flags + * indicate which information is being requested. The implementation may + * choose to return additional information that was not requested. + * The info structure is written only on success. + * + * @param odp_tm Specifies the TM system. + * @param priority Supplies the strict priority level used to specify * which tm_queues are included in the info values. - * @param[out] query_flags A set of flag bits indicating which counters are + * @param query_flags A set of flag bits indicating which counters are * being requested to be returned in the info record. * @param[out] info Pointer to an odp_tm_query_info_t record where the * requested queue info is returned. @@ -1880,14 +2286,12 @@ int odp_tm_priority_query(odp_tm_t odp_tm, /** The odp_tm_total_query() function can be used to check the queue * utilization of all tm_queue's in a single TM system. The query_flags - * indicate whether or not packet counts, byte counts or both are being - * requested. It is an error to request neither. The implementation may - * still return both sets of counts regardless of query_flags if the cost of - * returning all the counts is comparable to the cost of checking the - * query_flags. - * - * @param[in] odp_tm Specifies the TM system. - * @param[out] query_flags A set of flag bits indicating which counters are + * indicate which information is being requested. The implementation may + * choose to return additional information that was not requested. + * The info structure is written only on success. + * + * @param odp_tm Specifies the TM system. + * @param query_flags A set of flag bits indicating which counters are * being requested to be returned in the info record. * @param[out] info Pointer to an odp_tm_query_info_t record where the * requested queue info is returned. @@ -1903,14 +2307,14 @@ int odp_tm_total_query(odp_tm_t odp_tm, * semantic effects other than returning these queue threshold values in the * odp_tm_query_info_t record. * - * @param[in] odp_tm Specifies the TM system. - * @param[in] priority Supplies the strict priority level that - * the threshold profile params are associated - * with. - * @param[in] thresholds_profile Specifies the queue threshold profile that - * should now be associated with the supplied - * strict priority level. - * @return Returns 0 upon success and < 0 upon failure. + * @param odp_tm Specifies the TM system. + * @param priority Supplies the strict priority level that + * the threshold profile params are associated with. + * + * @param thresholds_profile Specifies the queue threshold profile that + * should now be associated with the supplied + * strict priority level. + * @return Returns 0 upon success and < 0 upon failure. */ int odp_tm_priority_threshold_config(odp_tm_t odp_tm, uint8_t priority, @@ -1922,13 +2326,14 @@ int odp_tm_priority_threshold_config(odp_tm_t odp_tm, * other than returning these queue threshold values in the * odp_tm_query_info_t record. * - * @param[in] odp_tm Specifies the TM system. - * @param[in] thresholds_profile Specifies the queue threshold profile that - * should now be used for the entire TM - * system. - * @return Returns 0 upon success and < 0 upon failure. + * @param tm TM handle + * @param thresholds_profile Specifies the queue threshold profile that + * should now be used for the entire TM + * system. + * + * @return Returns 0 upon success and < 0 upon failure. */ -int odp_tm_total_threshold_config(odp_tm_t odp_tm, +int odp_tm_total_threshold_config(odp_tm_t tm, odp_tm_threshold_t thresholds_profile); /** The odp_tm_is_idle function is used to determine if the specified ODP @@ -1940,18 +2345,127 @@ int odp_tm_total_threshold_config(odp_tm_t odp_tm, * since for some implementations this call could take a fairly long time * to execute! * - * @param[in] odp_tm Specifies the TM system. - * @return Returns 1 if the TM system is idle and 0 otherwise. + * @param tm TM handle + * + * @return Returns 1 if the TM system is idle and 0 otherwise. */ -odp_bool_t odp_tm_is_idle(odp_tm_t odp_tm); +odp_bool_t odp_tm_is_idle(odp_tm_t tm); /** The odp_tm_stats_print function is used to write implementation-defined * information about the specified TM system to the ODP log. The intended use * is for debugging. * - * @param[in] odp_tm Specifies the TM system. + * @param tm TM handle + */ +void odp_tm_stats_print(odp_tm_t tm); + +/** + * Get statistics for a TM queue + * + * Counters not supported by the queue are set to zero. + * + * It's implementation defined if odp_pktio_stats_reset() call affects these + * counters. + * + * @param tm_queue TM queue handle + * @param[out] stats Statistics structure for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_tm_queue_stats(odp_tm_queue_t tm_queue, odp_tm_queue_stats_t *stats); + +/** + * Get printable value for an odp_tm_t + * + * @param tm TM handle + * + * @return uint64_t value that can be used to print/display this + * handle + * + * @note This routine is intended to be used for diagnostic purposes + * to enable applications to generate a printable value that represents + * an odp_tm_t handle. + */ +uint64_t odp_tm_to_u64(odp_tm_t tm); + +/** + * Get printable value for an odp_tm_queue_t + * + * @param hdl odp_tm_queue_t handle to be printed + * @return uint64_t value that can be used to print/display this + * handle + * + * @note This routine is intended to be used for diagnostic purposes + * to enable applications to generate a printable value that represents + * an odp_tm_queue_t handle. + */ +uint64_t odp_tm_queue_to_u64(odp_tm_queue_t hdl); + +/** + * Get printable value for an odp_tm_node_t + * + * @param hdl odp_tm_node_t handle to be printed + * @return uint64_t value that can be used to print/display this + * handle + * + * @note This routine is intended to be used for diagnostic purposes + * to enable applications to generate a printable value that represents + * an odp_tm_node_t handle. + */ +uint64_t odp_tm_node_to_u64(odp_tm_node_t hdl); + +/** + * Get printable value for an odp_tm_shaper_t + * + * @param hdl odp_tm_shaper_t handle to be printed + * @return uint64_t value that can be used to print/display this + * handle + * + * @note This routine is intended to be used for diagnostic purposes + * to enable applications to generate a printable value that represents + * an odp_tm_shaper_t handle. + */ +uint64_t odp_tm_shaper_to_u64(odp_tm_shaper_t hdl); + +/** + * Get printable value for an odp_tm_sched_t + * + * @param hdl odp_tm_sched_t handle to be printed + * @return uint64_t value that can be used to print/display this + * handle + * + * @note This routine is intended to be used for diagnostic purposes + * to enable applications to generate a printable value that represents + * an odp_tm_sched_t handle. + */ +uint64_t odp_tm_sched_to_u64(odp_tm_sched_t hdl); + +/** + * Get printable value for an odp_tm_threshold_t + * + * @param hdl odp_tm_threshold_t handle to be printed + * @return uint64_t value that can be used to print/display this + * handle + * + * @note This routine is intended to be used for diagnostic purposes + * to enable applications to generate a printable value that represents + * an odp_tm_threshold_t handle. + */ +uint64_t odp_tm_threshold_to_u64(odp_tm_threshold_t hdl); + +/** + * Get printable value for an odp_tm_wred_t + * + * @param hdl odp_tm_wred_t handle to be printed + * @return uint64_t value that can be used to print/display this + * handle + * + * @note This routine is intended to be used for diagnostic purposes + * to enable applications to generate a printable value that represents + * an odp_tm_wred_t handle. */ -void odp_tm_stats_print(odp_tm_t odp_tm); +uint64_t odp_tm_wred_to_u64(odp_tm_wred_t hdl); /** * @} diff --git a/include/odp/api/spec/version.h.in b/include/odp/api/spec/version.h.in index f5e9e9c8b..19c5f2ec1 100644 --- a/include/odp/api/spec/version.h.in +++ b/include/odp/api/spec/version.h.in @@ -1,18 +1,16 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + * Copyright (c) 2020-2021 Nokia */ - /** * @file * * ODP version */ -#ifndef ODP_API_VERSION_H_ -#define ODP_API_VERSION_H_ +#ifndef ODP_API_SPEC_VERSION_H_ +#define ODP_API_SPEC_VERSION_H_ #include <odp/visibility_begin.h> #ifdef __cplusplus @@ -21,8 +19,7 @@ extern "C" { /** * @defgroup odp_version ODP VERSION - * @details - * <b> ODP API and implementation versions </b> + * API and implementation versions * * ODP API version is identified by ODP_VERSION_API_XXX preprocessor macros. * In addition to these macros, API calls can be used to identify implementation @@ -57,6 +54,23 @@ extern "C" { #define ODP_VERSION_API_MINOR @ODP_VERSION_API_MINOR@ /** + * ODP API version number macro + * + * Macro to build a version number for comparisons + */ +#define ODP_VERSION_API_NUM(gen, ma, mi) ((gen) << 24 | (ma) << 16 | (mi) << 8) + +/** + * ODP API version number + * + * API version number for comparisons against ODP_VERSION_API_NUM() + * macro output. + */ +#define ODP_VERSION_API ODP_VERSION_API_NUM(ODP_VERSION_API_GENERATION, \ + ODP_VERSION_API_MAJOR, \ + ODP_VERSION_API_MINOR) + +/** * ODP API version string * * The API version string defines ODP API version in this format: diff --git a/include/odp/api/spinlock.h b/include/odp/api/spinlock.h new file mode 100644 index 000000000..de4a86bf7 --- /dev/null +++ b/include/odp/api/spinlock.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP spinlock + */ + +#ifndef ODP_API_SPINLOCK_H_ +#define ODP_API_SPINLOCK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/spinlock.h> + +#include <odp/api/spec/spinlock.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/spinlock_recursive.h b/include/odp/api/spinlock_recursive.h new file mode 100644 index 000000000..6717a3958 --- /dev/null +++ b/include/odp/api/spinlock_recursive.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP recursive spinlock + */ + +#ifndef ODP_API_SPINLOCK_RECURSIVE_H_ +#define ODP_API_SPINLOCK_RECURSIVE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/spinlock_recursive.h> + +#include <odp/api/spec/spinlock_recursive.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/stash.h b/include/odp/api/stash.h new file mode 100644 index 000000000..e3071ec4e --- /dev/null +++ b/include/odp/api/stash.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2020 Nokia + */ + +/** + * @file + * + * ODP stash + */ + +#ifndef ODP_API_STASH_H_ +#define ODP_API_STASH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/stash.h> + +#include <odp/api/spec/stash.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/stash_types.h b/include/odp/api/stash_types.h new file mode 100644 index 000000000..429a47b27 --- /dev/null +++ b/include/odp/api/stash_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Nokia + */ + +/** + * @file + * + * ODP stash + */ + +#ifndef ODP_API_STASH_TYPES_H_ +#define ODP_API_STASH_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/stash_types.h> + +#include <odp/api/spec/stash_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/std.h b/include/odp/api/std.h new file mode 100644 index 000000000..7a057efc6 --- /dev/null +++ b/include/odp/api/std.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +#ifndef ODP_API_STD_H_ +#define ODP_API_STD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/std_types.h> +#include <odp/api/abi/std.h> + +#include <odp/api/spec/std.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/std_types.h b/include/odp/api/std_types.h new file mode 100644 index 000000000..b94007314 --- /dev/null +++ b/include/odp/api/std_types.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * Standard C language types and definitions for ODP. + */ + +#ifndef ODP_API_STD_TYPES_H_ +#define ODP_API_STD_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include <odp/api/abi/std_types.h> + +#include <odp/api/spec/std_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/sync.h b/include/odp/api/sync.h new file mode 100644 index 000000000..c936a1477 --- /dev/null +++ b/include/odp/api/sync.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP synchronisation + */ + +#ifndef ODP_API_SYNC_H_ +#define ODP_API_SYNC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/sync.h> + +#include <odp/api/spec/sync.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/system_info.h b/include/odp/api/system_info.h new file mode 100644 index 000000000..d830a4f9c --- /dev/null +++ b/include/odp/api/system_info.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP system information + */ + +#ifndef ODP_API_SYSTEM_INFO_H_ +#define ODP_API_SYSTEM_INFO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> + +#include <odp/api/spec/system_info.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/thread.h b/include/odp/api/thread.h new file mode 100644 index 000000000..24199a166 --- /dev/null +++ b/include/odp/api/thread.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP thread API + */ + +#ifndef ODP_API_THREAD_H_ +#define ODP_API_THREAD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/thread.h> + +#include <odp/api/spec/thread.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/thread_types.h b/include/odp/api/thread_types.h new file mode 100644 index 000000000..54ea5b714 --- /dev/null +++ b/include/odp/api/thread_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +/** + * @file + * + * ODP thread + */ + +#ifndef ODP_API_THREAD_TYPES_H_ +#define ODP_API_THREAD_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/thread_types.h> + +#include <odp/api/spec/thread_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/threshold.h b/include/odp/api/threshold.h new file mode 100644 index 000000000..f8e85e206 --- /dev/null +++ b/include/odp/api/threshold.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2017-2018 Linaro Limited + */ + +/** + * @file + * + * ODP threshold API - platform specific header + */ + +#ifndef ODP_API_THRESHOLD_H_ +#define ODP_API_THRESHOLD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spec/threshold.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/thrmask.h b/include/odp/api/thrmask.h new file mode 100644 index 000000000..04cdffb99 --- /dev/null +++ b/include/odp/api/thrmask.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP thread masks + */ + +#ifndef ODP_API_THRMASK_H_ +#define ODP_API_THRMASK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/thrmask.h> + +#include <odp/api/spec/thrmask.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/ticketlock.h b/include/odp/api/ticketlock.h new file mode 100644 index 000000000..6ca983b3b --- /dev/null +++ b/include/odp/api/ticketlock.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP ticketlock + */ + +#ifndef ODP_API_TICKETLOCK_H_ +#define ODP_API_TICKETLOCK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/ticketlock.h> + +#include <odp/api/spec/ticketlock.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/time.h b/include/odp/api/time.h new file mode 100644 index 000000000..24757bbc6 --- /dev/null +++ b/include/odp/api/time.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP time + */ + +#ifndef ODP_API_TIME_H_ +#define ODP_API_TIME_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/time.h> + +#include <odp/api/spec/time.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/time_types.h b/include/odp/api/time_types.h new file mode 100644 index 000000000..6cb14ffc7 --- /dev/null +++ b/include/odp/api/time_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +/** + * @file + * + * ODP time + */ + +#ifndef ODP_API_TIME_TYPES_H_ +#define ODP_API_TIME_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/time_types.h> + +#include <odp/api/spec/time_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/timer.h b/include/odp/api/timer.h new file mode 100644 index 000000000..512c9aec0 --- /dev/null +++ b/include/odp/api/timer.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP timer service + */ + +#ifndef ODP_API_TIMER_H_ +#define ODP_API_TIMER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/timer.h> + +#include <odp/api/spec/timer.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/timer_types.h b/include/odp/api/timer_types.h new file mode 100644 index 000000000..0fb0c7e1e --- /dev/null +++ b/include/odp/api/timer_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Nokia + */ + +/** + * @file + * + * ODP timer service + */ + +#ifndef ODP_API_TIMER_TYPES_H_ +#define ODP_API_TIMER_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/timer_types.h> + +#include <odp/api/spec/timer_types.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/traffic_mngr.h b/include/odp/api/traffic_mngr.h new file mode 100644 index 000000000..96ccff170 --- /dev/null +++ b/include/odp/api/traffic_mngr.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2015-2018 Linaro Limited + */ + +/** + * @file + * + * ODP Traffic manager + */ + +#ifndef ODP_API_TRAFFIC_MNGR_H_ +#define ODP_API_TRAFFIC_MNGR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/traffic_mngr.h> + +#include <odp/api/spec/traffic_mngr.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/version.h b/include/odp/api/version.h new file mode 100644 index 000000000..4461ccc32 --- /dev/null +++ b/include/odp/api/version.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2013-2018 Linaro Limited + */ + +/** + * @file + * + * ODP version + */ + +#ifndef ODP_API_VERSION_H_ +#define ODP_API_VERSION_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/abi/version.h> + +#include <odp/api/spec/version.h> + +#ifdef __cplusplus +} +#endif + +#endif |