aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMatias Elo <matias.elo@nokia.com>2023-04-14 10:46:15 +0300
committerMatias Elo <matias.elo@nokia.com>2023-04-14 10:46:15 +0300
commit7efdbaa4934c0cab3aa274d350d82af2d756d4d2 (patch)
treef533bed82bfa212e92efbadc92a48fcee7939f2a /test
parentf3a95e9658ffda83da051e9b3f9338583389dc42 (diff)
parentd1433e17eda246d24b61cadae88b339f5a0226ba (diff)
Merge tag 'v1.41.0.0' of https://github.com/OpenDataPlane/odp into odp-dpdk
Signed-off-by: Matias Elo <matias.elo@nokia.com>
Diffstat (limited to 'test')
-rw-r--r--test/performance/Makefile.am10
-rw-r--r--test/performance/odp_atomic_perf.c5
-rw-r--r--test/performance/odp_crypto.c76
-rw-r--r--test/performance/odp_ipsecfwd.c535
-rw-r--r--test/performance/odp_ipsecfwd.conf41
-rw-r--r--test/performance/odp_packet_gen.c2
-rw-r--r--test/performance/odp_timer_perf.c2
-rw-r--r--test/validation/api/classification/odp_classification_basic.c10
-rw-r--r--test/validation/api/classification/odp_classification_test_pmr.c24
-rw-r--r--test/validation/api/classification/odp_classification_tests.c20
-rw-r--r--test/validation/api/crypto/odp_crypto_test_inp.c1081
-rw-r--r--test/validation/api/dma/dma.c334
-rw-r--r--test/validation/api/ipsec/ipsec_test_out.c27
-rw-r--r--test/validation/api/pktio/pktio.c11
-rw-r--r--test/validation/api/stash/stash.c258
-rw-r--r--test/validation/api/timer/timer.c160
16 files changed, 1943 insertions, 653 deletions
diff --git a/test/performance/Makefile.am b/test/performance/Makefile.am
index beeb652cc..9dc83fd22 100644
--- a/test/performance/Makefile.am
+++ b/test/performance/Makefile.am
@@ -18,7 +18,6 @@ COMPILE_ONLY = odp_cpu_bench \
odp_crypto \
odp_dma_perf \
odp_ipsec \
- odp_ipsecfwd \
odp_l2fwd \
odp_packet_gen \
odp_pktio_ordered \
@@ -29,6 +28,10 @@ COMPILE_ONLY = odp_cpu_bench \
odp_stress \
odp_timer_perf
+if LIBCONFIG
+COMPILE_ONLY += odp_ipsecfwd
+endif
+
TESTSCRIPTS = odp_cpu_bench_run.sh \
odp_crypto_run.sh \
odp_dma_perf_run.sh \
@@ -62,7 +65,6 @@ odp_crc_SOURCES = odp_crc.c
odp_crypto_SOURCES = odp_crypto.c
odp_dma_perf_SOURCES = odp_dma_perf.c
odp_ipsec_SOURCES = odp_ipsec.c
-odp_ipsecfwd_SOURCES = odp_ipsecfwd.c
odp_lock_perf_SOURCES = odp_lock_perf.c
odp_mem_perf_SOURCES = odp_mem_perf.c
odp_packet_gen_SOURCES = odp_packet_gen.c
@@ -78,6 +80,10 @@ odp_sched_perf_SOURCES = odp_sched_perf.c
odp_stress_SOURCES = odp_stress.c
odp_timer_perf_SOURCES = odp_timer_perf.c
+if LIBCONFIG
+odp_ipsecfwd_SOURCES = odp_ipsecfwd.c
+endif
+
# l2fwd test depends on generator example
EXTRA_odp_l2fwd_DEPENDENCIES = $(top_builddir)/example/generator/odp_generator$(EXEEXT)
$(top_builddir)/example/generator/odp_generator$(EXEEXT):
diff --git a/test/performance/odp_atomic_perf.c b/test/performance/odp_atomic_perf.c
index ee760babf..5eeba8442 100644
--- a/test/performance/odp_atomic_perf.c
+++ b/test/performance/odp_atomic_perf.c
@@ -18,8 +18,9 @@
/* Default number of test rounds */
#define NUM_ROUNDS 1000000u
-/* Initial value for atomic variables */
-#define INIT_VAL 1234567
+/* Initial value for atomic variables. Supports up to 2 billion
+ * rounds of 32-bit min and max tests. */
+#define INIT_VAL 0x80000000
/* Max number of workers if num_cpu=0 */
#define DEFAULT_MAX_WORKERS 10
diff --git a/test/performance/odp_crypto.c b/test/performance/odp_crypto.c
index 2f79ae644..52af6d2fc 100644
--- a/test/performance/odp_crypto.c
+++ b/test/performance/odp_crypto.c
@@ -90,20 +90,20 @@ typedef struct {
*/
typedef struct {
/**
- * If non zero prints content of packets. Enabled by -d or
+ * If non-zero, prints content of packets. Enabled by -d or
* --debug option.
*/
int debug_packets;
/**
- * If non zero Try to run crypto operation in place. Note some
+ * If non-zero, try to run crypto operation in place. Note some
* implementation may not support such mode. Enabled by -n or
* --inplace option.
*/
int in_place;
/**
- * If non zeor output of previous operation taken as input for
+ * If non-zero, output of previous operation taken as input for
* next encrypt operations. Enabled by -r or --reuse option.
*/
int reuse_packet;
@@ -118,7 +118,7 @@ typedef struct {
/**
* Number of iteration to repeat crypto operation to get good
- * average number. Specified through -i or --terations option.
+ * average number. Specified through -i or --iterations option.
* Default is 10000.
*/
int iteration_count;
@@ -136,7 +136,7 @@ typedef struct {
/**
* Pointer to selected algorithm to test. If NULL all available
- * alogorthims are tested. Name of algorithm is passed through
+ * algorithms are tested. Name of algorithm is passed through
* -a or --algorithm option.
*/
crypto_alg_config_t *alg_config;
@@ -451,6 +451,49 @@ static crypto_alg_config_t algs_config[] = {
.auth_digest_len = 4,
},
},
+ {
+ .name = "snow3g-uea2",
+ .session = {
+ .cipher_alg = ODP_CIPHER_ALG_SNOW3G_UEA2,
+ .cipher_key = {
+ .data = test_key16,
+ .length = sizeof(test_key16)
+ },
+ .cipher_iv_len = 16,
+ .auth_alg = ODP_AUTH_ALG_NULL,
+ },
+ },
+ {
+ .name = "snow3g-uia2",
+ .session = {
+ .cipher_alg = ODP_CIPHER_ALG_NULL,
+ .auth_alg = ODP_AUTH_ALG_SNOW3G_UIA2,
+ .auth_key = {
+ .data = test_key16,
+ .length = sizeof(test_key16)
+ },
+ .auth_iv_len = 16,
+ .auth_digest_len = 4,
+ },
+ },
+ {
+ .name = "snow3g-uea2-snow3g-uia2",
+ .session = {
+ .cipher_alg = ODP_CIPHER_ALG_SNOW3G_UEA2,
+ .cipher_key = {
+ .data = test_key16,
+ .length = sizeof(test_key16)
+ },
+ .cipher_iv_len = 16,
+ .auth_alg = ODP_AUTH_ALG_SNOW3G_UIA2,
+ .auth_key = {
+ .data = test_key16,
+ .length = sizeof(test_key16)
+ },
+ .auth_iv_len = 16,
+ .auth_digest_len = 4,
+ },
+ },
};
/**
@@ -810,8 +853,6 @@ run_measure_one(crypto_args_t *cargs,
}
packets_sent += rc;
} else {
- odp_crypto_packet_result_t result;
-
rc = odp_crypto_op(&pkt, &out_pkt,
&params, 1);
if (rc <= 0) {
@@ -822,8 +863,7 @@ run_measure_one(crypto_args_t *cargs,
}
packets_sent += rc;
packets_received++;
- if (odp_unlikely(odp_crypto_result(&result, out_pkt) != 0) ||
- odp_unlikely(!result.ok)) {
+ if (odp_unlikely(odp_crypto_result(NULL, out_pkt) != 0)) {
ODPH_ERR("Crypto operation failed\n");
odp_packet_free(out_pkt);
return -1;
@@ -846,7 +886,6 @@ run_measure_one(crypto_args_t *cargs,
if (cargs->schedule || cargs->poll) {
odp_event_t ev;
- odp_crypto_packet_result_t result;
odp_packet_t out_pkt;
if (cargs->schedule)
@@ -857,8 +896,7 @@ run_measure_one(crypto_args_t *cargs,
while (ev != ODP_EVENT_INVALID) {
out_pkt = odp_crypto_packet_from_event(ev);
- if (odp_unlikely(odp_crypto_result(&result, out_pkt) != 0) ||
- odp_unlikely(!result.ok)) {
+ if (odp_unlikely(odp_crypto_result(NULL, out_pkt) != 0)) {
ODPH_ERR("Crypto operation failed\n");
odp_packet_free(out_pkt);
return -1;
@@ -948,6 +986,11 @@ static int check_cipher_alg(const odp_crypto_capability_t *capa,
case ODP_CIPHER_ALG_ZUC_EEA3:
if (capa->ciphers.bit.zuc_eea3)
return 0;
+ break;
+ case ODP_CIPHER_ALG_SNOW3G_UEA2:
+ if (capa->ciphers.bit.snow3g_uea2)
+ return 0;
+ break;
default:
break;
}
@@ -1002,6 +1045,11 @@ static int check_auth_alg(const odp_crypto_capability_t *capa,
case ODP_AUTH_ALG_ZUC_EIA3:
if (capa->auths.bit.zuc_eia3)
return 0;
+ break;
+ case ODP_AUTH_ALG_SNOW3G_UIA2:
+ if (capa->auths.bit.snow3g_uia2)
+ return 0;
+ break;
default:
break;
}
@@ -1096,7 +1144,7 @@ static int check_auth_params(const odp_crypto_capability_t *crypto_capa,
}
/**
- * Process one algorithm. Note if paload size is specicified it is
+ * Process one algorithm. Note if payload size is specified it is
* only one run. Or iterate over set of predefined payloads.
*/
static int run_measure_one_config(test_run_arg_t *arg)
@@ -1442,7 +1490,7 @@ static void parse_args(int argc, char *argv[], crypto_args_t *cargs)
}
/**
- * Prinf usage information
+ * Print usage information
*/
static void usage(char *progname)
{
diff --git a/test/performance/odp_ipsecfwd.c b/test/performance/odp_ipsecfwd.c
index 6098fd964..a6df747f3 100644
--- a/test/performance/odp_ipsecfwd.c
+++ b/test/performance/odp_ipsecfwd.c
@@ -19,6 +19,7 @@
#include <odp_api.h>
#include <odp/helper/odph_api.h>
+#include <libconfig.h>
#define PROG_NAME "odp_ipsecfwd"
#define SHORT_PROG_NAME "ipsfwd"
@@ -105,6 +106,17 @@ typedef struct ODP_ALIGNED_CACHE {
uint8_t pktio;
} thread_config_t;
+typedef struct {
+ odp_ipsec_sa_param_t sa_param;
+ char cipher_key[65U];
+ char cipher_key_extra[5U];
+ char auth_key[65U];
+ char auth_key_extra[5U];
+ odp_u32be_t lkp_dst_ip;
+ odp_u32be_t src_ip;
+ odp_u32be_t dst_ip;
+} sa_config_t;
+
typedef uint32_t (*rx_fn_t)(thread_config_t *config, odp_event_t evs[], int num);
typedef void (*ipsec_fn_t)(odp_packet_t pkts[], int num, odph_table_t fwd_tbl, stats_t *stats);
typedef void (*drain_fn_t)(prog_config_t *config);
@@ -123,9 +135,9 @@ typedef struct prog_config_s {
fwd_entry_t fwd_entries[MAX_FWDS];
odp_queue_t sa_qs[MAX_SA_QUEUES];
pktio_t pktios[MAX_IFS];
+ sa_config_t default_cfg;
ops_t ops;
- char *sa_conf_file;
- char *fwd_conf_file;
+ char *conf_file;
odp_instance_t odp_instance;
odp_queue_t compl_q;
odp_pool_t pktio_pool;
@@ -203,6 +215,7 @@ static __thread pkt_ifs_t ifs;
static void init_config(prog_config_t *config)
{
memset(config, 0, sizeof(*config));
+ odp_ipsec_sa_param_init(&config->default_cfg.sa_param);
config->compl_q = ODP_QUEUE_INVALID;
config->pktio_pool = ODP_POOL_INVALID;
config->num_input_qs = 1;
@@ -315,14 +328,50 @@ static void print_usage(void)
"Simple IPsec performance tester. Forward and process plain and ipsec packets.\n"
"\n"
"Examples:\n"
- " %s -i ens9f1 -s /etc/odp/sa.conf -f /etc/odp/fwd.conf\n"
+ " %s -i ens9f1 -C /etc/odp/ipsecfwd.conf\n"
"\n"
- " With sa.conf containing, for example:\n"
- " 0 222 192.168.1.10 192.168.1.16 4 jWnZr4t7w!zwC*F- 0 2"
- " n2r5u7x!A%%D*G-KaPdSg 0 12\n"
+ " With ipsecfwd.conf containing, for example:\n"
+ " default: {\n"
+ " dir = 1\n"
+ " proto = 0\n"
+ " mode = 0\n"
+ " crypto: {\n"
+ " cipher_alg = 4\n"
+ " cipher_key = \"jWnZr4t7w!zwC*F-\"\n"
+ " auth_alg = 2\n"
+ " auth_key = \"n2r5u7x!A%%D*\"\n"
+ " icv_len = 12\n"
+ " };\n"
+ " };\n"
"\n"
- " With fwd.conf containing, for example:\n"
- " 192.168.1.0/24 ens9f1 aa:bb:cc:dd:11:22\n"
+ " sa: (\n"
+ " {\n"
+ " spi = 1337\n"
+ " outbound: {\n"
+ " tunnel: {\n"
+ " src_addr = \"192.168.1.10\"\n"
+ " dst_addr = \"192.168.1.16\"\n"
+ " };\n"
+ " };\n"
+ " },\n"
+ " {\n"
+ " spi = 1338\n"
+ " outbound: {\n"
+ " tunnel: {\n"
+ " src_addr = \"192.168.3.110\"\n"
+ " dst_addr = \"192.168.3.116\"\n"
+ " };\n"
+ " };\n"
+ " }\n"
+ " );\n"
+ "\n"
+ " fwd: (\n"
+ " {\n"
+ " prefix: \"192.168.1.0/24\"\n"
+ " if: \"ens9f1\"\n"
+ " dst_mac: \"00:00:05:00:07:00\"\n"
+ " }\n"
+ " );\n"
"\n"
"Usage: %s [options]\n"
"\n"
@@ -336,39 +385,35 @@ static void print_usage(void)
" -m, --mode Queueing mode.\n"
" 0: ordered (default)\n"
" 1: parallel\n"
- " -s, --sa SA configuration file. Individual SA configuration is\n"
- " expected to be within a single line, values whitespace\n"
- " separated:\n"
- "\n"
- " <line in file> Dir SPI TunSrcIPv4 TunDstIPv4"
- " CipherAlgoIdx CipherKey CipherKeyExtra AuthAlgIdx AuthKey AuthKeyExtra ICVLen\n"
+ " -C, --conf Configuration file. 'libconfig' syntax is expected.\n"
+ " SA configuration supports default fallback, i.e.\n"
+ " individual SA configuration blocks may omit some\n"
+ " parameters and instead set these once in default block\n"
+ " which then are used to fill missing parameters. The only\n"
+ " required argument for an SA is the 'spi' parameter.\n"
+ " Individual SA parameter blocks are expected to be in\n"
+ " 'sa'-named list. Parameter naming follows API\n"
+ " specification, see 'odp_ipsec_sa_param_t' for parameter\n"
+ " names and hierarchy. Traffic is mapped to SAs based on UDP\n"
+ " port: the port is used as the SPI. For forwarding entries,\n"
+ " individual parameter blocks are similarly expected to be\n"
+ " in 'fwd'-named list. With forwarding entries, every\n"
+ " parameter is always required and interfaces present in\n"
+ " forwarding entries should be one of the interfaces passed\n"
+ " with '--interfaces' option. See example above for\n"
+ " potential SA and forwarding configuration.\n"
"\n"
- " With combined algorithms, authentication data is ignored.\n"
- " Traffic is mapped to SAs based on UDP port: the port is\n"
- " used as the SPI. Non-zero Dir value declares an outbound\n"
- " SA whereas zero Dir value declares an inbound SA.\n"
- "\n"
- " Supported cipher and authentication algorithms:\n",
+ " Supported cipher and authentication algorithms for SAs:\n",
PROG_NAME, PROG_NAME, MIN(pool_capa.pkt.max_num, PKT_CNT),
MIN(pool_capa.pkt.max_len, PKT_SIZE));
print_supported_algos(&ipsec_capa);
- printf(" -f, --fwd_table Forwarding configuration file. Individual forwarding\n"
- " configuration is expected to be within a single line,\n"
- " values whitespace separated:\n"
- "\n"
- " <line in file> IPv4Prefix/MaskLen NetIf DstMac\n"
- "\n"
- " IPv4Prefix and MaskLen define a matchable prefix and NetIf\n"
- " and DstMac define the outgoing interface and destination\n"
- " MAC address for a match. NetIf should be one of the\n"
- " interfaces passed with \"--interfaces\" option\n"
- " -I, --num_input_qs Input queue count. 1 by default.\n"
+ printf(" -I, --num_input_qs Input queue count. 1 by default.\n"
" -S, --num_sa_qs SA queue count. 1 by default.\n"
" -O, --num_output_qs Output queue count. 1 by default.\n"
" -d, --direct_rx Use direct RX. Interfaces will be polled by workers\n"
- " directly. \"--mode\", \"--num_input_qs\" and\n"
- " \"--num_output_qs\" options are ignored, input and output\n"
- " queue counts will match worker count.\n"
+ " directly. '--mode', '--num_input_qs' and '--num_output_qs'\n"
+ " options are ignored, input and output queue counts will\n"
+ " match worker count.\n"
" -h, --help This help.\n"
"\n");
}
@@ -949,25 +994,206 @@ static odp_bool_t create_sa_dest_queues(odp_ipsec_capability_t *ipsec_capa,
return true;
}
-static void create_sa_entry(uint32_t dir, uint32_t spi, const char *src_ip_str,
- const char *dst_ip_str, int cipher_idx, uint8_t *cipher_key,
- uint8_t *cipher_key_extra, int auth_idx, uint8_t *auth_key,
- uint8_t *auth_key_extra, uint32_t icv_len, uint32_t ar_ws,
- uint32_t max_num_sa, prog_config_t *config)
+static void parse_crypto(config_setting_t *cfg, sa_config_t *config)
{
- uint32_t src_ip, dst_ip;
- odp_ipsec_sa_param_t sa_param;
- odp_ipsec_crypto_param_t crypto_param;
- odp_ipsec_sa_t sa;
+ int val;
+ const char *val_str;
+ config_setting_t *cs = config_setting_lookup(cfg, "crypto");
- if (config->num_sas == max_num_sa) {
- ODPH_ERR("Maximum number of SAs parsed (%u), ignoring rest\n", max_num_sa);
+ if (cs == NULL)
+ return;
+
+ if (config_setting_lookup_int(cs, "cipher_alg", &val) == CONFIG_TRUE)
+ config->sa_param.crypto.cipher_alg = val;
+
+ if (config_setting_lookup_string(cs, "cipher_key", &val_str) == CONFIG_TRUE) {
+ strcpy(config->cipher_key, val_str);
+ config->sa_param.crypto.cipher_key.data = (uint8_t *)config->cipher_key;
+ config->sa_param.crypto.cipher_key.length =
+ strlen((const char *)config->cipher_key);
+ }
+
+ if (config_setting_lookup_string(cs, "cipher_key_extra", &val_str) == CONFIG_TRUE) {
+ strcpy(config->cipher_key_extra, val_str);
+ config->sa_param.crypto.cipher_key_extra.data =
+ (uint8_t *)config->cipher_key_extra;
+ config->sa_param.crypto.cipher_key_extra.length =
+ strlen((const char *)config->cipher_key_extra);
+ }
+
+ if (config_setting_lookup_int(cs, "auth_alg", &val) == CONFIG_TRUE)
+ config->sa_param.crypto.auth_alg = val;
+
+ if (config_setting_lookup_string(cs, "auth_key", &val_str) == CONFIG_TRUE) {
+ strcpy(config->auth_key, val_str);
+ config->sa_param.crypto.auth_key.data = (uint8_t *)config->auth_key;
+ config->sa_param.crypto.auth_key.length = strlen((const char *)config->auth_key);
+ }
+
+ if (config_setting_lookup_string(cs, "auth_key_extra", &val_str) == CONFIG_TRUE) {
+ strcpy(config->auth_key_extra, val_str);
+ config->sa_param.crypto.auth_key_extra.data = (uint8_t *)config->auth_key_extra;
+ config->sa_param.crypto.auth_key_extra.length =
+ strlen((const char *)config->auth_key_extra);
+ }
+
+ if (config_setting_lookup_int(cs, "icv_len", &val) == CONFIG_TRUE)
+ config->sa_param.crypto.icv_len = val;
+}
+
+static void parse_opt(config_setting_t *cfg, sa_config_t *config)
+{
+ int val;
+ config_setting_t *cs = config_setting_lookup(cfg, "opt");
+
+ if (cs == NULL)
+ return;
+
+ if (config_setting_lookup_int(cs, "esn", &val) == CONFIG_TRUE)
+ config->sa_param.opt.esn = val;
+
+ if (config_setting_lookup_int(cs, "udp_encap", &val) == CONFIG_TRUE)
+ config->sa_param.opt.udp_encap = val;
+
+ if (config_setting_lookup_int(cs, "copy_dscp", &val) == CONFIG_TRUE)
+ config->sa_param.opt.copy_dscp = val;
+
+ if (config_setting_lookup_int(cs, "copy_flabel", &val) == CONFIG_TRUE)
+ config->sa_param.opt.copy_flabel = val;
+
+ if (config_setting_lookup_int(cs, "copy_df", &val) == CONFIG_TRUE)
+ config->sa_param.opt.copy_df = val;
+
+ if (config_setting_lookup_int(cs, "dec_ttl", &val) == CONFIG_TRUE)
+ config->sa_param.opt.dec_ttl = val;
+}
+
+static void parse_limits(config_setting_t *cfg, sa_config_t *config)
+{
+ config_setting_t *cs = config_setting_lookup(cfg, "lifetime"), *soft, *hard;
+ long long val;
+
+ if (cs == NULL)
return;
+
+ soft = config_setting_lookup(cs, "soft_limit");
+ hard = config_setting_lookup(cs, "hard_limit");
+
+ if (soft != NULL) {
+ if (config_setting_lookup_int64(soft, "bytes", &val) == CONFIG_TRUE)
+ config->sa_param.lifetime.soft_limit.bytes = val;
+
+ if (config_setting_lookup_int64(soft, "packets", &val) == CONFIG_TRUE)
+ config->sa_param.lifetime.soft_limit.packets = val;
+ }
+
+ if (hard != NULL) {
+ if (config_setting_lookup_int64(hard, "bytes", &val) == CONFIG_TRUE)
+ config->sa_param.lifetime.hard_limit.bytes = val;
+
+ if (config_setting_lookup_int64(hard, "packets", &val) == CONFIG_TRUE)
+ config->sa_param.lifetime.hard_limit.packets = val;
}
+}
- if (odph_ipv4_addr_parse(&src_ip, src_ip_str) < 0 ||
- odph_ipv4_addr_parse(&dst_ip, dst_ip_str) < 0) {
- ODPH_ERR("Error parsing IP addresses for SA %u\n", spi);
+static void parse_inbound(config_setting_t *cfg, sa_config_t *config)
+{
+ config_setting_t *cs = config_setting_lookup(cfg, "inbound");
+ int val;
+ const char *val_str;
+
+ if (cs == NULL)
+ return;
+
+ if (config_setting_lookup_int(cs, "lookup_mode", &val) == CONFIG_TRUE)
+ config->sa_param.inbound.lookup_mode = val;
+
+ if (config_setting_lookup_string(cs, "lookup_dst_addr", &val_str) == CONFIG_TRUE) {
+ odph_ipv4_addr_parse(&config->lkp_dst_ip, val_str);
+ config->lkp_dst_ip = odp_cpu_to_be_32(config->lkp_dst_ip);
+ config->sa_param.inbound.lookup_param.dst_addr = &config->lkp_dst_ip;
+ }
+
+ if (config_setting_lookup_int(cs, "antireplay_ws", &val) == CONFIG_TRUE)
+ config->sa_param.inbound.antireplay_ws = val;
+
+ if (config_setting_lookup_int(cs, "reassembly_en", &val) == CONFIG_TRUE)
+ config->sa_param.inbound.reassembly_en = val;
+}
+
+static void parse_outbound(config_setting_t *cfg, sa_config_t *config)
+{
+ config_setting_t *cs = config_setting_lookup(cfg, "outbound"), *tunnel;
+ const char *val_str;
+ int val;
+
+ if (cs == NULL)
+ return;
+
+ tunnel = config_setting_lookup(cs, "tunnel");
+
+ if (tunnel != NULL) {
+ if (config_setting_lookup_string(tunnel, "src_addr", &val_str) == CONFIG_TRUE) {
+ odph_ipv4_addr_parse(&config->src_ip, val_str);
+ config->src_ip = odp_cpu_to_be_32(config->src_ip);
+ config->sa_param.outbound.tunnel.ipv4.src_addr = &config->src_ip;
+ }
+
+ if (config_setting_lookup_string(tunnel, "dst_addr", &val_str) == CONFIG_TRUE) {
+ odph_ipv4_addr_parse(&config->dst_ip, val_str);
+ config->dst_ip = odp_cpu_to_be_32(config->dst_ip);
+ config->sa_param.outbound.tunnel.ipv4.dst_addr = &config->dst_ip;
+ }
+
+ if (config_setting_lookup_int(tunnel, "dscp", &val) == CONFIG_TRUE)
+ config->sa_param.outbound.tunnel.ipv4.dscp = val;
+
+ if (config_setting_lookup_int(tunnel, "df", &val) == CONFIG_TRUE)
+ config->sa_param.outbound.tunnel.ipv4.df = val;
+
+ if (config_setting_lookup_int(tunnel, "ttl", &val) == CONFIG_TRUE)
+ config->sa_param.outbound.tunnel.ipv4.ttl = val;
+ }
+
+ if (config_setting_lookup_int(cs, "frag_mode", &val) == CONFIG_TRUE)
+ config->sa_param.outbound.frag_mode = val;
+
+ if (config_setting_lookup_int(cs, "mtu", &val) == CONFIG_TRUE)
+ config->sa_param.outbound.mtu = val;
+}
+
+static void parse_sa_entry(config_setting_t *cfg, sa_config_t *config)
+{
+ int val;
+
+ if (config_setting_lookup_int(cfg, "dir", &val) == CONFIG_TRUE)
+ config->sa_param.dir = val;
+
+ if (config_setting_lookup_int(cfg, "proto", &val) == CONFIG_TRUE)
+ config->sa_param.proto = val;
+
+ if (config_setting_lookup_int(cfg, "mode", &val) == CONFIG_TRUE)
+ config->sa_param.mode = val;
+
+ if (config_setting_lookup_int(cfg, "spi", &val) == CONFIG_TRUE)
+ config->sa_param.spi = val;
+
+ parse_crypto(cfg, config);
+ parse_opt(cfg, config);
+ parse_limits(cfg, config);
+ parse_inbound(cfg, config);
+ parse_outbound(cfg, config);
+}
+
+static void create_sa_entry(odp_ipsec_sa_param_t *sa_param, prog_config_t *config,
+ uint32_t max_num_sa)
+{
+ uint32_t dir = sa_param->dir;
+ uint32_t spi = sa_param->spi;
+ odp_ipsec_sa_t sa;
+
+ if (config->num_sas == max_num_sa) {
+ ODPH_ERR("Maximum number of SAs parsed (%u), ignoring rest\n", max_num_sa);
return;
}
@@ -981,37 +1207,8 @@ static void create_sa_entry(uint32_t dir, uint32_t spi, const char *src_ip_str,
return;
}
- src_ip = odp_cpu_to_be_32(src_ip);
- dst_ip = odp_cpu_to_be_32(dst_ip);
- odp_ipsec_sa_param_init(&sa_param);
- sa_param.proto = ODP_IPSEC_ESP;
- sa_param.mode = ODP_IPSEC_MODE_TUNNEL;
- sa_param.spi = spi;
- sa_param.dest_queue = config->sa_qs[config->num_sas % config->num_sa_qs];
-
- if (dir > 0U) {
- sa_param.dir = ODP_IPSEC_DIR_OUTBOUND;
- sa_param.outbound.tunnel.ipv4.src_addr = &src_ip;
- sa_param.outbound.tunnel.ipv4.dst_addr = &dst_ip;
- } else {
- sa_param.dir = ODP_IPSEC_DIR_INBOUND;
- sa_param.inbound.lookup_mode = ODP_IPSEC_LOOKUP_DISABLED;
- sa_param.inbound.antireplay_ws = ar_ws;
- }
-
- crypto_param.cipher_alg = cipher_idx;
- crypto_param.cipher_key.data = cipher_key;
- crypto_param.cipher_key.length = strlen((const char *)cipher_key);
- crypto_param.cipher_key_extra.data = cipher_key_extra;
- crypto_param.cipher_key_extra.length = strlen((const char *)cipher_key_extra);
- crypto_param.auth_alg = auth_idx;
- crypto_param.auth_key.data = auth_key;
- crypto_param.auth_key.length = strlen((const char *)auth_key);
- crypto_param.auth_key_extra.data = auth_key_extra;
- crypto_param.auth_key_extra.length = strlen((const char *)auth_key_extra);
- crypto_param.icv_len = icv_len;
- sa_param.crypto = crypto_param;
- sa = odp_ipsec_sa_create(&sa_param);
+ sa_param->dest_queue = config->sa_qs[config->num_sas % config->num_sa_qs];
+ sa = odp_ipsec_sa_create(sa_param);
if (sa == ODP_IPSEC_SA_INVALID) {
ODPH_ERR("Error creating SA handle for SA %u\n", spi);
@@ -1023,19 +1220,46 @@ static void create_sa_entry(uint32_t dir, uint32_t spi, const char *src_ip_str,
++config->num_sas;
}
-static void parse_sas(prog_config_t *config)
+static void parse_and_create_sa_entries(config_t *cfg, prog_config_t *config, uint32_t max_num_sa)
{
- odp_ipsec_capability_t ipsec_capa;
- FILE *file;
- int cipher_idx, auth_idx;
- uint32_t ar_ws, max_num_sa, dir, spi, icv_len;
- char src_ip[16U] = { 0 }, dst_ip[16U] = { 0 };
- uint8_t cipher_key[65U] = { 0U }, cipher_key_extra[5U] = { 0U }, auth_key[65U] = { 0U },
- auth_key_extra[5U] = { 0U };
-
- if (config->sa_conf_file == NULL)
+ config_setting_t *cs;
+ int count;
+
+ cs = config_lookup(cfg, "default");
+
+ if (cs != NULL)
+ parse_sa_entry(cs, &config->default_cfg);
+
+ cs = config_lookup(cfg, "sa");
+
+ if (cs == NULL)
return;
+ count = config_setting_length(cs);
+
+ for (int i = 0; i < count; i++) {
+ sa_config_t sa_cfg;
+ config_setting_t *sa;
+ int val;
+
+ sa_cfg = config->default_cfg;
+ sa = config_setting_get_elem(cs, i);
+
+ if (sa == NULL)
+ continue;
+
+ if (config_setting_lookup_int(sa, "spi", &val) == CONFIG_TRUE) {
+ parse_sa_entry(sa, &sa_cfg);
+ create_sa_entry(&sa_cfg.sa_param, config, max_num_sa);
+ }
+ }
+}
+
+static void parse_sas(config_t *cfg, prog_config_t *config)
+{
+ odp_ipsec_capability_t ipsec_capa;
+ uint32_t max_num_sa;
+
if (odp_ipsec_capability(&ipsec_capa) < 0) {
ODPH_ERR("Error querying IPsec capabilities\n");
return;
@@ -1047,24 +1271,8 @@ static void parse_sas(prog_config_t *config)
if (!config->is_dir_rx && !create_sa_dest_queues(&ipsec_capa, config))
return;
- file = fopen(config->sa_conf_file, "r");
-
- if (file == NULL) {
- ODPH_ERR("Error opening SA configuration file: %s\n", strerror(errno));
- return;
- }
-
- ar_ws = MIN(32U, ipsec_capa.max_antireplay_ws);
max_num_sa = MIN(MAX_SAS, ipsec_capa.max_num_sa);
-
- while (fscanf(file, "%u%u%s%s%d%s%s%d%s%s%u", &dir, &spi, src_ip, dst_ip,
- &cipher_idx, cipher_key, cipher_key_extra, &auth_idx, auth_key,
- auth_key_extra, &icv_len) == 11)
- create_sa_entry(!!dir, spi, src_ip, dst_ip, cipher_idx, cipher_key,
- cipher_key_extra, auth_idx, auth_key, auth_key_extra, icv_len,
- ar_ws, max_num_sa, config);
-
- (void)fclose(file);
+ parse_and_create_sa_entries(cfg, config, max_num_sa);
}
static const pktio_t *get_pktio(const char *iface, const prog_config_t *config)
@@ -1077,12 +1285,14 @@ static const pktio_t *get_pktio(const char *iface, const prog_config_t *config)
return NULL;
}
-static void create_fwd_table_entry(const char *dst_ip_str, const char *iface,
- const char *dst_mac_str, uint8_t mask, prog_config_t *config)
+static void create_fwd_table_entry(config_setting_t *cfg, prog_config_t *config)
{
- fwd_entry_t *entry;
+ const char *val_str;
+ char dst_ip_str[16U] = { 0 };
+ uint32_t mask, dst_ip;
odph_ethaddr_t dst_mac;
- uint32_t dst_ip;
+ const pktio_t *pktio = NULL;
+ fwd_entry_t *entry;
odph_iplookup_prefix_t prefix;
if (config->num_fwds == MAX_FWDS) {
@@ -1091,50 +1301,69 @@ static void create_fwd_table_entry(const char *dst_ip_str, const char *iface,
return;
}
- entry = &config->fwd_entries[config->num_fwds];
+ if (config_setting_lookup_string(cfg, "prefix", &val_str) == CONFIG_TRUE) {
+ if (sscanf(val_str, "%[^/]/%u", dst_ip_str, &mask) != 2) {
+ ODPH_ERR("Error parsing IP and subnet mask for forwarding entry\n");
+ return;
+ }
- if (odph_eth_addr_parse(&dst_mac, dst_mac_str) < 0 ||
- odph_ipv4_addr_parse(&dst_ip, dst_ip_str) < 0) {
- ODPH_ERR("Error parsing MAC and IP addresses for forwarding entry\n");
+ if (odph_ipv4_addr_parse(&dst_ip, dst_ip_str) < 0) {
+ ODPH_ERR("Syntax error in IP address for forwarding entry\n");
+ return;
+ }
+ } else {
return;
}
- entry->pktio = get_pktio(iface, config);
+ if (config_setting_lookup_string(cfg, "if", &val_str) == CONFIG_TRUE) {
+ pktio = get_pktio(val_str, config);
+
+ if (pktio == NULL) {
+ ODPH_ERR("Error parsing next interface for forwarding entry\n");
+ return;
+ }
+ } else {
+ return;
+ }
- if (entry->pktio == NULL) {
- ODPH_ERR("Invalid interface in forwarding entry: %s\n", iface);
+ if (config_setting_lookup_string(cfg, "dst_mac", &val_str) == CONFIG_TRUE) {
+ if (odph_eth_addr_parse(&dst_mac, val_str) < 0) {
+ ODPH_ERR("Syntax error in destination MAC for forwarding entry\n");
+ return;
+ }
+ } else {
return;
}
+ entry = &config->fwd_entries[config->num_fwds];
entry->dst_mac = dst_mac;
+ entry->pktio = pktio;
prefix.ip = dst_ip;
prefix.cidr = mask;
entry->prefix = prefix;
++config->num_fwds;
}
-static void parse_fwd_table(prog_config_t *config)
+static void parse_fwd_table(config_t *cfg, prog_config_t *config)
{
- FILE *file;
- char dst_ip[16U] = { 0 }, iface[64U] = { 0 }, dst_mac[18U] = { 0 };
- uint32_t mask;
+ config_setting_t *cs;
+ int count;
- if (config->fwd_conf_file == NULL) {
- ODPH_ERR("Invalid forwarding configuration file\n");
+ cs = config_lookup(cfg, "fwd");
+
+ if (cs == NULL)
return;
- }
- file = fopen(config->fwd_conf_file, "r");
+ count = config_setting_length(cs);
- if (file == NULL) {
- ODPH_ERR("Error opening forwarding configuration file: %s\n", strerror(errno));
- return;
- }
+ for (int i = 0; i < count; i++) {
+ config_setting_t *fwd = config_setting_get_elem(cs, i);
- while (fscanf(file, " %[^/]/%u%s%s", dst_ip, &mask, iface, dst_mac) == 4)
- create_fwd_table_entry(dst_ip, iface, dst_mac, mask, config);
+ if (fwd == NULL)
+ continue;
- (void)fclose(file);
+ create_fwd_table_entry(fwd, config);
+ }
}
static parse_result_t check_options(prog_config_t *config)
@@ -1152,11 +1381,6 @@ static parse_result_t check_options(prog_config_t *config)
return PRS_NOK;
}
- if (config->sa_conf_file != NULL && config->num_sas == 0U) {
- ODPH_ERR("Invalid SA configuration\n");
- return PRS_NOK;
- }
-
if (config->num_fwds == 0U) {
ODPH_ERR("Invalid number of forwarding entries: %u (min: 1, max: %u)\n",
config->num_fwds, MAX_FWDS);
@@ -1198,24 +1422,24 @@ static parse_result_t check_options(prog_config_t *config)
static parse_result_t parse_options(int argc, char **argv, prog_config_t *config)
{
int opt, long_index;
+ config_t cfg;
static const struct option longopts[] = {
- { "interfaces", required_argument, NULL, 'i'},
- { "num_pkts", required_argument, NULL, 'n'},
- { "pkt_len", required_argument, NULL, 'l'},
+ { "interfaces", required_argument, NULL, 'i' },
+ { "num_pkts", required_argument, NULL, 'n' },
+ { "pkt_len", required_argument, NULL, 'l' },
{ "count", required_argument, NULL, 'c' },
{ "mode", required_argument, NULL, 'm' },
- { "sa", required_argument, NULL, 's'},
- { "fwd_table", required_argument, NULL, 'f' },
+ { "conf", required_argument, NULL, 'C' },
{ "num_input_qs", required_argument, NULL, 'I' },
{ "num_sa_qs", required_argument, NULL, 'S' },
{ "num_output_qs", required_argument, NULL, 'O' },
- { "direct_rx", no_argument, NULL, 'd'},
+ { "direct_rx", no_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 }
};
- static const char *shortopts = "i:n:l:c:m:s:f:I:S:O:dh";
+ static const char *shortopts = "i:n:l:c:m:C:I:S:O:dh";
while (true) {
opt = getopt_long(argc, argv, shortopts, longopts, &long_index);
@@ -1239,11 +1463,8 @@ static parse_result_t parse_options(int argc, char **argv, prog_config_t *config
case 'm':
config->mode = !!atoi(optarg);
break;
- case 's':
- config->sa_conf_file = strdup(optarg);
- break;
- case 'f':
- config->fwd_conf_file = strdup(optarg);
+ case 'C':
+ config->conf_file = strdup(optarg);
break;
case 'I':
config->num_input_qs = atoi(optarg);
@@ -1267,8 +1488,17 @@ static parse_result_t parse_options(int argc, char **argv, prog_config_t *config
}
}
- parse_sas(config);
- parse_fwd_table(config);
+ config_init(&cfg);
+
+ if (config_read_file(&cfg, config->conf_file) == CONFIG_FALSE) {
+ ODPH_ERR("Error opening SA configuration file: %s\n", config_error_text(&cfg));
+ config_destroy(&cfg);
+ return PRS_NOK;
+ }
+
+ parse_sas(&cfg, config);
+ parse_fwd_table(&cfg, config);
+ config_destroy(&cfg);
return check_options(config);
}
@@ -1686,8 +1916,7 @@ static void teardown_test(const prog_config_t *config)
if (config->compl_q != ODP_QUEUE_INVALID)
(void)odp_queue_destroy(config->compl_q);
- free(config->sa_conf_file);
- free(config->fwd_conf_file);
+ free(config->conf_file);
}
static void print_stats(const prog_config_t *config)
diff --git a/test/performance/odp_ipsecfwd.conf b/test/performance/odp_ipsecfwd.conf
new file mode 100644
index 000000000..81ddaef7e
--- /dev/null
+++ b/test/performance/odp_ipsecfwd.conf
@@ -0,0 +1,41 @@
+default: {
+ dir = 1
+ proto = 0
+ mode = 0
+ crypto: {
+ cipher_alg = 4
+ cipher_key = "jWnZr4t7w!zwC*F-"
+ auth_alg = 2
+ auth_key = "n2r5u7x!A%D*"
+ icv_len = 12
+ };
+};
+
+sa: (
+ {
+ spi = 1337
+ outbound: {
+ tunnel: {
+ src_addr = "192.168.1.10"
+ dst_addr = "192.168.1.16"
+ };
+ };
+ },
+ {
+ spi = 1338
+ outbound: {
+ tunnel: {
+ src_addr = "192.168.3.110"
+ dst_addr = "192.168.3.116"
+ };
+ };
+ }
+);
+
+fwd: (
+ {
+ prefix: "192.168.1.0/24"
+ if: "ens9f1"
+ dst_mac: "00:00:05:00:07:00"
+ }
+);
diff --git a/test/performance/odp_packet_gen.c b/test/performance/odp_packet_gen.c
index e02ffe95e..85b0c740b 100644
--- a/test/performance/odp_packet_gen.c
+++ b/test/performance/odp_packet_gen.c
@@ -1312,7 +1312,6 @@ static int init_packets(test_global_t *global, int pktio,
void *data;
uint8_t *u8;
odph_ethhdr_t *eth;
- odph_vlanhdr_t *vlan;
odph_ipv4hdr_t *ip;
odph_udphdr_t *udp;
uint16_t tpid;
@@ -1323,6 +1322,7 @@ static int init_packets(test_global_t *global, int pktio,
uint16_t udp_dst = test_options->udp_dst;
uint32_t udp_src_cnt = 0;
uint32_t udp_dst_cnt = 0;
+ odph_vlanhdr_t *vlan = NULL; /* Fixes bogus compiler warning */
if (num_vlan > MAX_VLANS)
num_vlan = MAX_VLANS;
diff --git a/test/performance/odp_timer_perf.c b/test/performance/odp_timer_perf.c
index ccea30a14..3df9a875f 100644
--- a/test/performance/odp_timer_perf.c
+++ b/test/performance/odp_timer_perf.c
@@ -292,6 +292,8 @@ static int create_timer_pools(test_global_t *global)
printf(" num timer %u\n", num_timer);
printf(" resolution %" PRIu64 " nsec\n", res_ns);
printf(" period %" PRIu64 " nsec\n", period_ns);
+ printf(" max timeout %" PRIu64 " nsec\n", max_tmo_ns);
+ printf(" min timeout %" PRIu64 " nsec\n", min_tmo_ns);
printf(" first timer at %.2f sec\n", (double)START_NS / ODP_TIME_SEC_IN_NS);
if (mode == MODE_SCHED_OVERH)
printf(" test duration %.2f sec\n", (double)max_tmo_ns / ODP_TIME_SEC_IN_NS);
diff --git a/test/validation/api/classification/odp_classification_basic.c b/test/validation/api/classification/odp_classification_basic.c
index f7aa96e52..2969dedab 100644
--- a/test/validation/api/classification/odp_classification_basic.c
+++ b/test/validation/api/classification/odp_classification_basic.c
@@ -203,13 +203,14 @@ static void classification_test_create_pmr_match(void)
retval = odp_cls_pmr_destroy(ODP_PMR_INVALID);
CU_ASSERT(retval < 0);
+ odp_cos_destroy(cos);
odp_queue_destroy(queue);
odp_pool_destroy(pool);
odp_pool_destroy(pkt_pool);
- odp_cos_destroy(cos);
+ odp_pktio_default_cos_set(pktio, ODP_COS_INVALID);
+ odp_cos_destroy(default_cos);
odp_queue_destroy(default_queue);
odp_pool_destroy(default_pool);
- odp_cos_destroy(default_cos);
odp_pktio_close(pktio);
}
@@ -401,13 +402,14 @@ static void classification_test_pmr_composite_create(void)
retval = odp_cls_pmr_destroy(pmr_composite);
CU_ASSERT(retval == 0);
+ odp_cos_destroy(cos);
odp_queue_destroy(queue);
odp_pool_destroy(pool);
odp_pool_destroy(pkt_pool);
- odp_cos_destroy(cos);
+ odp_pktio_default_cos_set(pktio, ODP_COS_INVALID);
+ odp_cos_destroy(default_cos);
odp_queue_destroy(default_queue);
odp_pool_destroy(default_pool);
- odp_cos_destroy(default_cos);
odp_pktio_close(pktio);
}
diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c
index 0b29783c0..bf067719b 100644
--- a/test/validation/api/classification/odp_classification_test_pmr.c
+++ b/test/validation/api/classification/odp_classification_test_pmr.c
@@ -194,9 +194,10 @@ static void classification_test_pktin_classifier_flag(void)
CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
odp_packet_free(pkt);
+ odp_cls_pmr_destroy(pmr);
odp_cos_destroy(cos);
+ odp_pktio_default_cos_set(pktio, ODP_COS_INVALID);
odp_cos_destroy(default_cos);
- odp_cls_pmr_destroy(pmr);
stop_pktio(pktio);
odp_queue_destroy(queue);
odp_queue_destroy(default_queue);
@@ -366,9 +367,10 @@ static void _classification_test_pmr_term_tcp_dport(int num_pkt)
CU_ASSERT(sent_queue == recv_queue);
CU_ASSERT(sent_default == recv_default);
+ odp_cls_pmr_destroy(pmr);
odp_cos_destroy(cos);
+ odp_pktio_default_cos_set(pktio, ODP_COS_INVALID);
odp_cos_destroy(default_cos);
- odp_cls_pmr_destroy(pmr);
stop_pktio(pktio);
odp_queue_destroy(queue);
odp_queue_destroy(default_queue);
@@ -457,9 +459,10 @@ static void test_pmr(const odp_pmr_param_t *pmr_param, odp_packet_t pkt,
}
odp_packet_free(pkt);
+ odp_cls_pmr_destroy(pmr);
odp_cos_destroy(cos);
+ odp_pktio_default_cos_set(pktio, ODP_COS_INVALID);
odp_cos_destroy(default_cos);
- odp_cls_pmr_destroy(pmr); /* XXX ordering */
stop_pktio(pktio);
odp_pool_destroy(default_pool);
odp_pool_destroy(pool);
@@ -747,9 +750,10 @@ static void classification_test_pmr_term_dmac(void)
CU_ASSERT(recvpool == default_pool);
CU_ASSERT(retqueue == default_queue);
+ odp_cls_pmr_destroy(pmr);
odp_cos_destroy(cos);
+ odp_pktio_default_cos_set(pktio, ODP_COS_INVALID);
odp_cos_destroy(default_cos);
- odp_cls_pmr_destroy(pmr);
odp_packet_free(pkt);
stop_pktio(pktio);
odp_pool_destroy(default_pool);
@@ -1080,9 +1084,10 @@ static void classification_test_pmr_pool_set(void)
CU_ASSERT(retqueue == queue);
odp_packet_free(pkt);
+ odp_cls_pmr_destroy(pmr);
odp_cos_destroy(cos);
+ odp_pktio_default_cos_set(pktio, ODP_COS_INVALID);
odp_cos_destroy(default_cos);
- odp_cls_pmr_destroy(pmr);
stop_pktio(pktio);
odp_pool_destroy(default_pool);
odp_pool_destroy(pool);
@@ -1180,9 +1185,10 @@ static void classification_test_pmr_queue_set(void)
CU_ASSERT(retqueue == queue_new);
odp_packet_free(pkt);
+ odp_cls_pmr_destroy(pmr);
odp_cos_destroy(cos);
+ odp_pktio_default_cos_set(pktio, ODP_COS_INVALID);
odp_cos_destroy(default_cos);
- odp_cls_pmr_destroy(pmr);
stop_pktio(pktio);
odp_pool_destroy(default_pool);
odp_pool_destroy(pool);
@@ -1603,15 +1609,15 @@ static void test_pmr_series(const int num_udp, int marking)
CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
CU_ASSERT(retqueue == default_queue);
odp_packet_free(pkt);
+ odp_cls_pmr_destroy(pmr_ip);
for (i = 0; i < num_udp; i++) {
- odp_cos_destroy(cos_udp[i]);
odp_cls_pmr_destroy(pmr_udp[i]);
+ odp_cos_destroy(cos_udp[i]);
}
odp_cos_destroy(cos_ip);
- odp_cls_pmr_destroy(pmr_ip);
-
+ odp_pktio_default_cos_set(pktio, ODP_COS_INVALID);
odp_cos_destroy(default_cos);
stop_pktio(pktio);
odp_pool_destroy(default_pool);
diff --git a/test/validation/api/classification/odp_classification_tests.c b/test/validation/api/classification/odp_classification_tests.c
index 962885c06..002beb2aa 100644
--- a/test/validation/api/classification/odp_classification_tests.c
+++ b/test/validation/api/classification/odp_classification_tests.c
@@ -162,6 +162,16 @@ static int classification_suite_common_term(odp_bool_t enable_pktv)
retcode = -1;
}
+ for (i = 0; i < CLS_ENTRIES; i++) {
+ if (pmr_list[i] != ODP_PMR_INVALID)
+ odp_cls_pmr_destroy(pmr_list[i]);
+ }
+
+ for (i = 0; i < CLS_ENTRIES; i++) {
+ if (cos_list[i] != ODP_COS_INVALID)
+ odp_cos_destroy(cos_list[i]);
+ }
+
if (0 != odp_pool_destroy(pool_default)) {
ODPH_ERR("Pool_default destroy failed\n");
retcode = -1;
@@ -175,16 +185,6 @@ static int classification_suite_common_term(odp_bool_t enable_pktv)
}
for (i = 0; i < CLS_ENTRIES; i++) {
- if (cos_list[i] != ODP_COS_INVALID)
- odp_cos_destroy(cos_list[i]);
- }
-
- for (i = 0; i < CLS_ENTRIES; i++) {
- if (pmr_list[i] != ODP_PMR_INVALID)
- odp_cls_pmr_destroy(pmr_list[i]);
- }
-
- for (i = 0; i < CLS_ENTRIES; i++) {
if (queue_list[i] != ODP_QUEUE_INVALID)
odp_queue_destroy(queue_list[i]);
}
diff --git a/test/validation/api/crypto/odp_crypto_test_inp.c b/test/validation/api/crypto/odp_crypto_test_inp.c
index 7d5e50c71..c6a7767cc 100644
--- a/test/validation/api/crypto/odp_crypto_test_inp.c
+++ b/test/validation/api/crypto/odp_crypto_test_inp.c
@@ -6,14 +6,23 @@
*/
#include <string.h>
+#include <stdlib.h>
#include <odp_api.h>
#include <odp/helper/odph_api.h>
#include <odp_cunit_common.h>
#include <packet_common.h>
#include "test_vectors.h"
+/*
+ * If nonzero, run time consuming tests too.
+ * Set through FULL_TEST environment variable.
+ */
+static int full_test;
+
+#define MAX_FAILURE_PRINTS 20
+
#define PKT_POOL_NUM 64
-#define PKT_POOL_LEN (1 * 1024)
+#define PKT_POOL_LEN 1200 /* enough for a test packet and some headroom */
#define UAREA_SIZE 8
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
@@ -40,9 +49,6 @@ static void test_defaults(uint8_t fill)
CU_ASSERT_EQUAL(param.op, ODP_CRYPTO_OP_ENCODE);
CU_ASSERT_EQUAL(param.op_type, ODP_CRYPTO_OP_TYPE_LEGACY);
CU_ASSERT_EQUAL(param.auth_cipher_text, false);
-#if ODP_DEPRECATED_API
- CU_ASSERT_EQUAL(param.pref_mode, ODP_CRYPTO_SYNC);
-#endif
CU_ASSERT_EQUAL(param.op_mode, ODP_CRYPTO_SYNC);
CU_ASSERT_EQUAL(param.cipher_alg, ODP_CIPHER_ALG_NULL);
CU_ASSERT_EQUAL(param.cipher_iv_len, 0);
@@ -151,88 +157,6 @@ static const char *cipher_alg_name(odp_cipher_alg_t cipher)
}
}
-#if ODP_DEPRECATED_API
-static int alg_op(odp_packet_t pkt,
- odp_bool_t *ok,
- odp_crypto_session_t session,
- uint8_t *cipher_iv_ptr,
- uint8_t *auth_iv_ptr,
- odp_packet_data_range_t *cipher_range,
- odp_packet_data_range_t *auth_range,
- uint8_t *aad,
- unsigned int hash_result_offset)
-{
- int rc;
- odp_crypto_op_result_t result;
- odp_crypto_op_param_t op_params;
- odp_bool_t posted;
- odp_event_subtype_t subtype;
-
- /* Prepare input/output params */
- memset(&op_params, 0, sizeof(op_params));
- op_params.session = session;
- op_params.pkt = pkt;
- op_params.out_pkt = pkt;
- op_params.ctx = (void *)0xdeadbeef;
-
- op_params.cipher_range = *cipher_range;
- op_params.auth_range = *auth_range;
- if (cipher_iv_ptr)
- op_params.cipher_iv_ptr = cipher_iv_ptr;
- if (auth_iv_ptr)
- op_params.auth_iv_ptr = auth_iv_ptr;
-
- op_params.aad_ptr = aad;
-
- op_params.hash_result_offset = hash_result_offset;
-
- rc = odp_crypto_operation(&op_params, &posted, &result);
- if (rc < 0) {
- CU_FAIL("Failed odp_crypto_operation()");
- return rc;
- }
-
- if (posted) {
- odp_event_t event;
- odp_crypto_compl_t compl_event;
-
- /* Get crypto completion event from compl_queue. */
- CU_ASSERT_FATAL(NULL != suite_context.compl_queue_deq);
- do {
- event = suite_context.compl_queue_deq();
- } while (event == ODP_EVENT_INVALID);
-
- CU_ASSERT(odp_event_is_valid(event) == 1);
- CU_ASSERT(ODP_EVENT_CRYPTO_COMPL == odp_event_type(event));
- CU_ASSERT(ODP_EVENT_NO_SUBTYPE == odp_event_subtype(event));
- CU_ASSERT(ODP_EVENT_CRYPTO_COMPL ==
- odp_event_types(event, &subtype));
- CU_ASSERT(ODP_EVENT_NO_SUBTYPE == subtype);
-
- compl_event = odp_crypto_compl_from_event(event);
- CU_ASSERT(odp_crypto_compl_to_u64(compl_event) ==
- odp_crypto_compl_to_u64(
- odp_crypto_compl_from_event(event)));
- odp_crypto_compl_result(compl_event, &result);
- odp_crypto_compl_free(compl_event);
- }
-
- CU_ASSERT(result.pkt == pkt);
- CU_ASSERT(result.ctx == (void *)0xdeadbeef);
- CU_ASSERT(ODP_EVENT_PACKET ==
- odp_event_type(odp_packet_to_event(result.pkt)));
- CU_ASSERT(ODP_EVENT_PACKET_BASIC ==
- odp_event_subtype(odp_packet_to_event(result.pkt)));
- CU_ASSERT(ODP_EVENT_PACKET ==
- odp_event_types(odp_packet_to_event(result.pkt), &subtype));
- CU_ASSERT(ODP_EVENT_PACKET_BASIC == subtype);
-
- *ok = result.ok;
-
- return 0;
-}
-#endif
-
static int alg_packet_op(odp_packet_t pkt_in,
odp_packet_t *pkt_out,
odp_bool_t *ok,
@@ -241,8 +165,8 @@ static int alg_packet_op(odp_packet_t pkt_in,
int32_t oop_shift,
uint8_t *cipher_iv_ptr,
uint8_t *auth_iv_ptr,
- odp_packet_data_range_t *cipher_range,
- odp_packet_data_range_t *auth_range,
+ const odp_packet_data_range_t *cipher_range,
+ const odp_packet_data_range_t *auth_range,
uint8_t *aad,
unsigned int hash_result_offset)
{
@@ -319,17 +243,21 @@ static int alg_packet_op(odp_packet_t pkt_in,
CU_ASSERT(odp_packet_subtype(*pkt_out) == ODP_EVENT_PACKET_CRYPTO);
rc = odp_crypto_result(&result, *pkt_out);
- if (rc < 0) {
+ if (rc < -1) {
CU_FAIL("Failed odp_crypto_packet_result()");
return rc;
}
- CU_ASSERT(rc == 0);
+ CU_ASSERT(rc == 0 || rc == -1);
if (op_type == ODP_CRYPTO_OP_TYPE_OOP &&
suite_context.op_mode == ODP_CRYPTO_ASYNC)
CU_ASSERT(result.pkt_in == pkt_in);
- *ok = result.ok;
+ *ok = (rc == 0);
+
+#if ODP_DEPRECATED_API
+ CU_ASSERT(*ok == result.ok);
+#endif
return 0;
}
@@ -342,30 +270,18 @@ static int crypto_op(odp_packet_t pkt_in,
int32_t oop_shift,
uint8_t *cipher_iv,
uint8_t *auth_iv,
- odp_packet_data_range_t *cipher_range,
- odp_packet_data_range_t *auth_range,
+ const odp_packet_data_range_t *cipher_range,
+ const odp_packet_data_range_t *auth_range,
uint8_t *aad,
unsigned int hash_result_offset)
{
int rc;
- if (!suite_context.packet) {
-#if ODP_DEPRECATED_API
- rc = alg_op(pkt_in, ok, session,
- cipher_iv, auth_iv,
- cipher_range, auth_range,
- aad, hash_result_offset);
- *pkt_out = pkt_in;
-#else
- rc = -1;
-#endif
- } else {
- rc = alg_packet_op(pkt_in, pkt_out, ok, session,
- op_type, oop_shift,
- cipher_iv, auth_iv,
- cipher_range, auth_range,
- aad, hash_result_offset);
- }
+ rc = alg_packet_op(pkt_in, pkt_out, ok, session,
+ op_type, oop_shift,
+ cipher_iv, auth_iv,
+ cipher_range, auth_range,
+ aad, hash_result_offset);
if (rc < 0)
odp_packet_free(pkt_in);
@@ -407,8 +323,10 @@ static void adjust_segments(odp_packet_t *pkt, uint32_t first_seg_len)
static void fill_with_pattern(uint8_t *buf, uint32_t len)
{
+ static uint8_t value;
+
for (uint32_t n = 0; n < len; n++)
- buf[n] = n;
+ buf[n] = value++;
}
static void write_header_and_trailer(odp_packet_t pkt,
@@ -435,6 +353,8 @@ typedef struct alg_test_param_t {
odp_cipher_alg_t cipher_alg;
odp_auth_alg_t auth_alg;
crypto_test_reference_t *ref;
+ odp_packet_data_range_t cipher_range;
+ odp_packet_data_range_t auth_range;
uint32_t digest_offset;
odp_bool_t is_bit_mode_cipher;
odp_bool_t is_bit_mode_auth;
@@ -450,23 +370,14 @@ static void prepare_crypto_ranges(const alg_test_param_t *param,
odp_packet_data_range_t *auth_range)
{
odp_packet_data_range_t zero_range = {.offset = 0, .length = 0};
+ uint32_t c_scale = param->is_bit_mode_cipher ? 8 : 1;
+ uint32_t a_scale = param->is_bit_mode_auth ? 8 : 1;
+
+ *cipher_range = param->cipher_range;
+ *auth_range = param->auth_range;
+ cipher_range->offset += c_scale * param->header_len;
+ auth_range->offset += a_scale * param->header_len;
- cipher_range->offset = param->header_len;
- cipher_range->length = ref_length_in_bytes(param->ref);
- auth_range->offset = param->header_len;
- auth_range->length = ref_length_in_bytes(param->ref);
- if (param->is_bit_mode_cipher) {
- cipher_range->offset *= 8;
- cipher_range->length = ref_length_in_bits(param->ref);
- }
- if (param->is_bit_mode_auth) {
- auth_range->offset *= 8;
- auth_range->length = ref_length_in_bits(param->ref);
- }
- /*
- * We did not check the bit mode of the null algorithms, so let's
- * not pass potentially invalid ranges to them.
- */
if (param->cipher_alg == ODP_CIPHER_ALG_NULL)
*cipher_range = zero_range;
if (param->auth_alg == ODP_AUTH_ALG_NULL)
@@ -571,7 +482,7 @@ static int is_in_range(uint32_t offs, uint32_t range_offs, uint32_t range_len)
*/
typedef struct ignore_t {
uint32_t byte_offset; /* offset to a byte which has bits to be ignored */
- uint32_t byte_mask; /* mask of ignored bits in the byte */
+ uint8_t byte_mask; /* mask of ignored bits in the byte */
struct {
uint32_t offset;
uint32_t length;
@@ -619,10 +530,13 @@ static void prepare_ignore_info(const alg_test_param_t *param,
*/
if (param->is_bit_mode_cipher &&
param->cipher_alg != ODP_CIPHER_ALG_NULL) {
- uint8_t leftover_bits = param->ref->length % 8;
+ uint8_t leftover_bits = ref_length_in_bits(param->ref) % 8;
ignore->byte_offset = cipher_offset + cipher_len - 1 + shift;
- ignore->byte_mask = ~(0xff << (8 - leftover_bits));
+ if (leftover_bits > 0)
+ ignore->byte_mask = ~(0xff << (8 - leftover_bits));
+ else
+ ignore->byte_mask = 0;
}
/*
@@ -679,11 +593,13 @@ static void prepare_expected_data(const alg_test_param_t *param,
const int32_t shift = param->op_type == ODP_CRYPTO_OP_TYPE_OOP ? param->oop_shift : 0;
const odp_packet_t base_pkt = param->op_type == ODP_CRYPTO_OP_TYPE_OOP ? pkt_out : pkt_in;
int rc;
+ uint32_t cipher_offset_in_ref = param->cipher_range.offset;
if (param->op == ODP_CRYPTO_OP_ENCODE)
digest_offset += shift;
if (param->is_bit_mode_cipher) {
+ cipher_offset_in_ref /= 8;
cipher_offset /= 8;
cipher_len = (cipher_len + 7) / 8;
}
@@ -725,11 +641,11 @@ static void prepare_expected_data(const alg_test_param_t *param,
* text) does not work in any real use case anyway.
*/
memcpy(ex->data + cipher_offset + shift,
- param->ref->ciphertext,
+ param->ref->ciphertext + cipher_offset_in_ref,
cipher_len);
} else {
memcpy(ex->data + cipher_offset + shift,
- param->ref->plaintext,
+ param->ref->plaintext + cipher_offset_in_ref,
cipher_len);
}
@@ -743,7 +659,7 @@ static void print_data(const char *title, uint8_t *data, uint32_t len)
{
static uint64_t limit;
- if (limit++ > 20)
+ if (limit++ > MAX_FAILURE_PRINTS)
return;
printf("%s\n", title);
@@ -830,14 +746,7 @@ static void alg_test_execute(const alg_test_param_t *param)
param->ref->aad, digest_offset))
return;
- /*
- * API is not explicit about whether a failed crypto op
- * sets the has_error packet flag or leaves it unchanged.
- * Let's allow both behaviours.
- */
test_packet_get_md(pkt_out, &md_out);
- if (param->wrong_digest)
- md_out.has_error = 0;
if (param->op_type == ODP_CRYPTO_OP_TYPE_OOP) {
test_packet_md_t md;
@@ -855,15 +764,89 @@ static void alg_test_execute(const alg_test_param_t *param)
CU_ASSERT(test_packet_is_md_equal(&md_out, &md_in));
}
+ if (param->cipher_alg != ODP_CIPHER_ALG_NULL &&
+ param->auth_alg != ODP_AUTH_ALG_NULL &&
+ param->digest_offset >= cipher_range.offset &&
+ param->digest_offset < cipher_range.offset + cipher_range.length) {
+ /*
+ * Not all implementations support digest offset in cipher
+ * range, so allow crypto op failure without further checks
+ * in this case.
+ */
+ if (!ok)
+ goto out;
+ }
+
if (param->wrong_digest) {
CU_ASSERT(!ok);
} else {
CU_ASSERT(ok);
}
check_output_packet_data(pkt_out, &expected);
+out:
odp_packet_free(pkt_out);
}
+static void print_alg_test_param(const alg_test_param_t *p)
+{
+ const char *cipher_mode = p->is_bit_mode_cipher ? "bit" : "byte";
+ const char *auth_mode = p->is_bit_mode_auth ? "bit" : "byte";
+
+ switch (p->op_type) {
+ case ODP_CRYPTO_OP_TYPE_LEGACY:
+ printf("legacy ");
+ break;
+ case ODP_CRYPTO_OP_TYPE_BASIC:
+ printf("basic ");
+ break;
+ case ODP_CRYPTO_OP_TYPE_OOP:
+ printf("out-of-place ");
+ break;
+ }
+ printf("%s\n", p->op == ODP_CRYPTO_OP_ENCODE ? "encode" : "decode");
+
+ printf("cipher: %s, %s mode\n", cipher_alg_name(p->cipher_alg), cipher_mode);
+ printf(" key length: %d, iv length: %d\n",
+ p->ref->cipher_key_length, p->ref->cipher_iv_length);
+ printf(" range: offset %d, length %d\n",
+ p->cipher_range.offset, p->cipher_range.length);
+
+ printf("auth: %s, %s mode\n", auth_alg_name(p->auth_alg), auth_mode);
+ printf(" key length: %d, iv length: %d\n",
+ p->ref->auth_key_length, p->ref->auth_iv_length);
+ printf(" range: offset %d, length %d; aad length: %d\n",
+ p->auth_range.offset, p->auth_range.length, p->ref->aad_length);
+ printf(" digest offset: %d, digest length %d\n",
+ p->digest_offset, p->ref->digest_length);
+
+ if (p->wrong_digest)
+ printf("wrong digest test\n");
+ printf("header length: %d, trailer length: %d\n", p->header_len, p->trailer_len);
+ if (p->adjust_segmentation)
+ printf("segmentation adjusted, first_seg_len: %d\n", p->first_seg_len);
+ if (p->op_type == ODP_CRYPTO_OP_TYPE_OOP)
+ printf("oop_shift: %d\n", p->oop_shift);
+}
+
+static void alg_test_execute_and_print(alg_test_param_t *param)
+{
+ static int print_limit = MAX_FAILURE_PRINTS;
+ unsigned int num = CU_get_number_of_failures();
+
+ alg_test_execute(param);
+
+ if (CU_get_number_of_failures() > num) {
+ if (print_limit > 0) {
+ printf("\nTest failed:\n");
+ print_alg_test_param(param);
+ printf("\n");
+ print_limit--;
+ if (print_limit == 0)
+ printf("Suppressing further failure output\n");
+ }
+ }
+}
+
static void alg_test_op(alg_test_param_t *param)
{
int32_t oop_shifts[] = {0, 3, 130, -10};
@@ -877,13 +860,15 @@ static void alg_test_op(alg_test_param_t *param)
param->oop_shift = oop_shifts[n];
param->wrong_digest = false;
- alg_test_execute(param);
- alg_test_execute(param); /* rerun with the same parameters */
+ alg_test_execute_and_print(param);
+ if (full_test)
+ alg_test_execute_and_print(param); /* rerun with the same parameters */
param->wrong_digest = true;
- alg_test_execute(param);
+ alg_test_execute_and_print(param);
}
}
+static int combo_warning_shown;
static int oop_warning_shown;
typedef enum {
@@ -891,10 +876,16 @@ typedef enum {
HASH_OVERLAP,
} hash_test_mode_t;
+typedef enum {
+ AUTH_CIPHERTEXT,
+ AUTH_PLAINTEXT
+} alg_order_t;
+
static odp_crypto_session_t session_create(odp_crypto_op_t op,
odp_crypto_op_type_t op_type,
odp_cipher_alg_t cipher_alg,
odp_auth_alg_t auth_alg,
+ alg_order_t order,
crypto_test_reference_t *ref,
hash_test_mode_t hash_mode)
{
@@ -920,11 +911,8 @@ static odp_crypto_session_t session_create(odp_crypto_op_t op,
odp_crypto_session_param_init(&ses_params);
ses_params.op = op;
ses_params.op_type = op_type;
- ses_params.auth_cipher_text = false;
+ ses_params.auth_cipher_text = (order == AUTH_CIPHERTEXT);
ses_params.op_mode = suite_context.op_mode;
-#if ODP_DEPRECATED_API
- ses_params.pref_mode = suite_context.pref_mode;
-#endif
ses_params.cipher_alg = cipher_alg;
ses_params.auth_alg = auth_alg;
ses_params.compl_queue = suite_context.queue;
@@ -936,17 +924,29 @@ static odp_crypto_session_t session_create(odp_crypto_op_t op,
ses_params.auth_digest_len = ref->digest_length;
ses_params.auth_aad_len = ref->aad_length;
ses_params.hash_result_in_auth_range = (hash_mode == HASH_OVERLAP);
-
rc = odp_crypto_session_create(&ses_params, &session, &status);
+
+ if (rc < 0 && status == ODP_CRYPTO_SES_ERR_ALG_COMBO) {
+ if (!combo_warning_shown) {
+ combo_warning_shown = 1;
+ printf("\n Unsupported algorithm combination: %s, %s\n",
+ cipher_alg_name(cipher_alg),
+ auth_alg_name(auth_alg));
+ }
+ return ODP_CRYPTO_SESSION_INVALID;
+ }
+
/*
- * In some cases an individual algorithm cannot be used alone,
- * i.e. with the null cipher/auth algorithm.
+ * Allow ODP_CRYPTO_SES_ERR_ALG_ORDER only in async op mode.
+ * In sync mode an implementation should be able to support both
+ * orders without much difficulty.
*/
- if (rc < 0 &&
- status == ODP_CRYPTO_SES_ERR_ALG_COMBO) {
- printf("\n Unsupported algorithm combination: %s, %s\n",
+ if (rc < 0 && status == ODP_CRYPTO_SES_ERR_ALG_ORDER &&
+ ses_params.op_mode == ODP_CRYPTO_ASYNC) {
+ printf("\n Unsupported algorithm order: %s, %s, auth_cipher_text: %d\n",
cipher_alg_name(cipher_alg),
- auth_alg_name(auth_alg));
+ auth_alg_name(auth_alg),
+ ses_params.auth_cipher_text);
return ODP_CRYPTO_SESSION_INVALID;
}
@@ -959,12 +959,6 @@ static odp_crypto_session_t session_create(odp_crypto_op_t op,
return ODP_CRYPTO_SESSION_INVALID;
}
- /*
- * We do not allow ODP_CRYPTO_SES_ERR_ALG_ORDER since we do
- * not combine individual non-null crypto and auth algorithms
- * with each other in the tests. Both orders should work when
- * only one algorithm is used (i.e. the other one is null).
- */
CU_ASSERT_FATAL(!rc);
CU_ASSERT(status == ODP_CRYPTO_SES_ERR_NONE);
CU_ASSERT(odp_crypto_session_to_u64(session) !=
@@ -985,22 +979,28 @@ static void alg_test_ses(odp_crypto_op_t op,
odp_crypto_op_type_t op_type,
odp_cipher_alg_t cipher_alg,
odp_auth_alg_t auth_alg,
+ alg_order_t order,
crypto_test_reference_t *ref,
+ odp_packet_data_range_t cipher_range,
+ odp_packet_data_range_t auth_range,
uint32_t digest_offset,
odp_bool_t is_bit_mode_cipher,
odp_bool_t is_bit_mode_auth)
{
unsigned int initial_num_failures = CU_get_number_of_failures();
const uint32_t reflength = ref_length_in_bytes(ref);
- const hash_test_mode_t hash_mode = digest_offset < reflength ? HASH_OVERLAP
- : HASH_NO_OVERLAP;
+ hash_test_mode_t hash_mode = HASH_NO_OVERLAP;
odp_crypto_session_t session;
int rc;
uint32_t seg_len;
uint32_t max_shift;
alg_test_param_t test_param;
- session = session_create(op, op_type, cipher_alg, auth_alg, ref, hash_mode);
+ if (digest_offset >= auth_range.offset &&
+ digest_offset < auth_range.offset + auth_range.length)
+ hash_mode = HASH_OVERLAP;
+
+ session = session_create(op, op_type, cipher_alg, auth_alg, order, ref, hash_mode);
if (session == ODP_CRYPTO_SESSION_INVALID)
return;
@@ -1011,6 +1011,8 @@ static void alg_test_ses(odp_crypto_op_t op,
test_param.cipher_alg = cipher_alg;
test_param.auth_alg = auth_alg;
test_param.ref = ref;
+ test_param.cipher_range = cipher_range;
+ test_param.auth_range = auth_range;
test_param.is_bit_mode_cipher = is_bit_mode_cipher;
test_param.is_bit_mode_auth = is_bit_mode_auth;
test_param.digest_offset = digest_offset;
@@ -1018,12 +1020,21 @@ static void alg_test_ses(odp_crypto_op_t op,
alg_test_op(&test_param);
max_shift = reflength + ref->digest_length;
+ seg_len = 0;
+
+ if (!full_test &&
+ cipher_alg != ODP_CIPHER_ALG_NULL &&
+ auth_alg != ODP_AUTH_ALG_NULL) {
+ /* run the loop body just once */
+ seg_len = max_shift / 2;
+ max_shift = seg_len;
+ }
/*
* Test with segmented packets with all possible segment boundaries
* within the packet data
*/
- for (seg_len = 0; seg_len <= max_shift; seg_len++) {
+ for (; seg_len <= max_shift; seg_len++) {
/*
* CUnit chokes on too many assertion failures, so bail
* out if this test has already failed.
@@ -1052,7 +1063,10 @@ static void alg_test_ses(odp_crypto_op_t op,
static void alg_test(odp_crypto_op_t op,
odp_cipher_alg_t cipher_alg,
odp_auth_alg_t auth_alg,
+ alg_order_t order,
crypto_test_reference_t *ref,
+ odp_packet_data_range_t cipher_range,
+ odp_packet_data_range_t auth_range,
uint32_t digest_offset,
odp_bool_t is_bit_mode_cipher,
odp_bool_t is_bit_mode_auth)
@@ -1071,7 +1085,10 @@ static void alg_test(odp_crypto_op_t op,
op_types[n],
cipher_alg,
auth_alg,
+ order,
ref,
+ cipher_range,
+ auth_range,
digest_offset,
is_bit_mode_cipher,
is_bit_mode_auth);
@@ -1131,6 +1148,8 @@ static void check_alg(odp_crypto_op_t op,
odp_bool_t is_bit_mode_cipher = false;
odp_bool_t is_bit_mode_auth = false;
uint32_t digest_offs = ref_length_in_bytes(&ref[idx]);
+ odp_packet_data_range_t cipher_range = {.offset = 0};
+ odp_packet_data_range_t auth_range = {.offset = 0};
if (ref_length_in_bits(&ref[idx]) % 8 != 0)
bit_mode_needed = true;
@@ -1190,7 +1209,18 @@ static void check_alg(odp_crypto_op_t op,
continue;
}
- alg_test(op, cipher_alg, auth_alg, &ref[idx], digest_offs,
+ cipher_range.length = is_bit_mode_cipher ?
+ ref_length_in_bits(&ref[idx]) :
+ ref_length_in_bytes(&ref[idx]);
+ auth_range.length = is_bit_mode_auth ?
+ ref_length_in_bits(&ref[idx]) :
+ ref_length_in_bytes(&ref[idx]);
+
+ alg_test(op, cipher_alg, auth_alg, AUTH_PLAINTEXT, &ref[idx],
+ cipher_range, auth_range, digest_offs,
+ is_bit_mode_cipher, is_bit_mode_auth);
+ alg_test(op, cipher_alg, auth_alg, AUTH_CIPHERTEXT, &ref[idx],
+ cipher_range, auth_range, digest_offs,
is_bit_mode_cipher, is_bit_mode_auth);
cipher_tested[cipher_idx] = true;
@@ -1252,14 +1282,12 @@ static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth)
return ODP_TEST_INACTIVE;
}
- if (suite_context.packet) {
- if (suite_context.op_mode == ODP_CRYPTO_SYNC &&
- capability.sync_mode == ODP_SUPPORT_NO)
- return ODP_TEST_INACTIVE;
- if (suite_context.op_mode == ODP_CRYPTO_ASYNC &&
- capability.async_mode == ODP_SUPPORT_NO)
- return ODP_TEST_INACTIVE;
- }
+ if (suite_context.op_mode == ODP_CRYPTO_SYNC &&
+ capability.sync_mode == ODP_SUPPORT_NO)
+ return ODP_TEST_INACTIVE;
+ if (suite_context.op_mode == ODP_CRYPTO_ASYNC &&
+ capability.async_mode == ODP_SUPPORT_NO)
+ return ODP_TEST_INACTIVE;
/* Cipher algorithms */
switch (cipher) {
@@ -1498,7 +1526,7 @@ static int create_hash_test_reference(odp_auth_alg_t auth,
session = session_create(ODP_CRYPTO_OP_ENCODE,
ODP_CRYPTO_OP_TYPE_LEGACY,
ODP_CIPHER_ALG_NULL,
- auth, ref, HASH_NO_OVERLAP);
+ auth, AUTH_PLAINTEXT, ref, HASH_NO_OVERLAP);
if (session == ODP_CRYPTO_SESSION_INVALID)
return -1;
@@ -1531,10 +1559,16 @@ static int create_hash_test_reference(odp_auth_alg_t auth,
}
static void test_auth_hash_in_auth_range(odp_auth_alg_t auth,
- const odp_crypto_auth_capability_t *capa)
+ const odp_crypto_auth_capability_t *capa,
+ alg_order_t order)
{
static crypto_test_reference_t ref = {.length = 0};
uint32_t digest_offset = 13;
+ const odp_packet_data_range_t cipher_range = {.offset = 0, .length = 0};
+ odp_packet_data_range_t auth_range;
+
+ if (!full_test && capa->digest_len % 4 != 0)
+ return;
/*
* Create test packets with auth hash in the authenticated range and
@@ -1543,6 +1577,11 @@ static void test_auth_hash_in_auth_range(odp_auth_alg_t auth,
if (create_hash_test_reference(auth, capa, &ref, digest_offset, 0))
return;
+ auth_range.offset = 0;
+ auth_range.length = capa->bit_mode ?
+ ref_length_in_bits(&ref) :
+ ref_length_in_bytes(&ref);
+
/*
* Decode the ciphertext packet.
*
@@ -1553,7 +1592,9 @@ static void test_auth_hash_in_auth_range(odp_auth_alg_t auth,
alg_test(ODP_CRYPTO_OP_DECODE,
ODP_CIPHER_ALG_NULL,
auth,
+ order,
&ref,
+ cipher_range, auth_range,
digest_offset,
false,
capa->bit_mode);
@@ -1565,6 +1606,11 @@ static void test_auth_hash_in_auth_range(odp_auth_alg_t auth,
if (create_hash_test_reference(auth, capa, &ref, digest_offset, 1))
return;
+ auth_range.offset = 0;
+ auth_range.length = capa->bit_mode ?
+ ref_length_in_bits(&ref) :
+ ref_length_in_bytes(&ref);
+
/*
* Encode the plaintext packet.
*
@@ -1575,41 +1621,60 @@ static void test_auth_hash_in_auth_range(odp_auth_alg_t auth,
alg_test(ODP_CRYPTO_OP_ENCODE,
ODP_CIPHER_ALG_NULL,
auth,
+ order,
&ref,
+ cipher_range, auth_range,
digest_offset,
false,
capa->bit_mode);
}
+/*
+ * Cipher algorithms that are not AEAD algorithms
+ */
+static odp_cipher_alg_t cipher_algs[] = {
+ ODP_CIPHER_ALG_DES,
+ ODP_CIPHER_ALG_3DES_CBC,
+ ODP_CIPHER_ALG_3DES_ECB,
+ ODP_CIPHER_ALG_AES_CBC,
+ ODP_CIPHER_ALG_AES_CTR,
+ ODP_CIPHER_ALG_AES_ECB,
+ ODP_CIPHER_ALG_AES_CFB128,
+ ODP_CIPHER_ALG_AES_XTS,
+ ODP_CIPHER_ALG_KASUMI_F8,
+ ODP_CIPHER_ALG_SNOW3G_UEA2,
+ ODP_CIPHER_ALG_AES_EEA2,
+ ODP_CIPHER_ALG_ZUC_EEA3,
+};
+
+/*
+ * Authentication algorithms and hashes that use auth_range
+ * parameter. AEAD algorithms are excluded.
+ */
+static odp_auth_alg_t auth_algs[] = {
+ ODP_AUTH_ALG_MD5_HMAC,
+ ODP_AUTH_ALG_SHA1_HMAC,
+ ODP_AUTH_ALG_SHA224_HMAC,
+ ODP_AUTH_ALG_SHA256_HMAC,
+ ODP_AUTH_ALG_SHA384_HMAC,
+ ODP_AUTH_ALG_SHA512_HMAC,
+ ODP_AUTH_ALG_AES_GMAC,
+ ODP_AUTH_ALG_AES_CMAC,
+ ODP_AUTH_ALG_AES_XCBC_MAC,
+ ODP_AUTH_ALG_KASUMI_F9,
+ ODP_AUTH_ALG_SNOW3G_UIA2,
+ ODP_AUTH_ALG_AES_EIA2,
+ ODP_AUTH_ALG_ZUC_EIA3,
+ ODP_AUTH_ALG_MD5,
+ ODP_AUTH_ALG_SHA1,
+ ODP_AUTH_ALG_SHA224,
+ ODP_AUTH_ALG_SHA256,
+ ODP_AUTH_ALG_SHA384,
+ ODP_AUTH_ALG_SHA512,
+};
+
static void test_auth_hashes_in_auth_range(void)
{
- /*
- * Authentication algorithms and hashes that use auth_range
- * parameter. AEAD algorithms are excluded.
- */
- static odp_auth_alg_t auth_algs[] = {
- ODP_AUTH_ALG_NULL,
- ODP_AUTH_ALG_MD5_HMAC,
- ODP_AUTH_ALG_SHA1_HMAC,
- ODP_AUTH_ALG_SHA224_HMAC,
- ODP_AUTH_ALG_SHA256_HMAC,
- ODP_AUTH_ALG_SHA384_HMAC,
- ODP_AUTH_ALG_SHA512_HMAC,
- ODP_AUTH_ALG_AES_GMAC,
- ODP_AUTH_ALG_AES_CMAC,
- ODP_AUTH_ALG_AES_XCBC_MAC,
- ODP_AUTH_ALG_KASUMI_F9,
- ODP_AUTH_ALG_SNOW3G_UIA2,
- ODP_AUTH_ALG_AES_EIA2,
- ODP_AUTH_ALG_ZUC_EIA3,
- ODP_AUTH_ALG_MD5,
- ODP_AUTH_ALG_SHA1,
- ODP_AUTH_ALG_SHA224,
- ODP_AUTH_ALG_SHA256,
- ODP_AUTH_ALG_SHA384,
- ODP_AUTH_ALG_SHA512,
- };
-
for (size_t n = 0; n < ARRAY_SIZE(auth_algs); n++) {
odp_auth_alg_t auth = auth_algs[n];
int num;
@@ -1624,11 +1689,547 @@ static void test_auth_hashes_in_auth_range(void)
num = odp_crypto_auth_capability(auth, capa, num);
- for (int i = 0; i < num; i++)
- test_auth_hash_in_auth_range(auth, &capa[i]);
+ for (int i = 0; i < num; i++) {
+ test_auth_hash_in_auth_range(auth, &capa[i], AUTH_PLAINTEXT);
+ test_auth_hash_in_auth_range(auth, &capa[i], AUTH_CIPHERTEXT);
+ }
}
}
+/*
+ * Encode ref->plaintext and save result in ref->ciphertext.
+ */
+static int crypto_encode_ref(crypto_test_reference_t *ref,
+ odp_cipher_alg_t cipher,
+ odp_auth_alg_t auth,
+ odp_packet_data_range_t cipher_range,
+ odp_packet_data_range_t auth_range,
+ uint32_t hash_result_offset)
+{
+ odp_packet_data_range_t zero_range = {.offset = 0, .length = 0};
+ odp_packet_t pkt;
+ int rc;
+ odp_crypto_session_t session;
+ odp_bool_t ok;
+
+ pkt = odp_packet_alloc(suite_context.pool, ref->length);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+
+ rc = odp_packet_copy_from_mem(pkt, 0, ref->length, ref->plaintext);
+ CU_ASSERT(rc == 0);
+
+ session = session_create(ODP_CRYPTO_OP_ENCODE,
+ ODP_CRYPTO_OP_TYPE_LEGACY,
+ cipher,
+ auth,
+ AUTH_PLAINTEXT,
+ ref,
+ HASH_OVERLAP);
+
+ if (session == ODP_CRYPTO_SESSION_INVALID) {
+ odp_packet_free(pkt);
+ return 1;
+ }
+
+ if (cipher == ODP_CIPHER_ALG_NULL)
+ cipher_range = zero_range;
+ if (auth == ODP_AUTH_ALG_NULL) {
+ auth_range = zero_range;
+ hash_result_offset = 0;
+ }
+
+ CU_ASSERT_FATAL(hash_result_offset + ref->digest_length <= ref->length);
+
+ rc = crypto_op(pkt, &pkt, &ok, session, ODP_CRYPTO_OP_TYPE_LEGACY, 0,
+ ref->cipher_iv, ref->auth_iv,
+ &cipher_range, &auth_range,
+ ref->aad, hash_result_offset);
+ CU_ASSERT(rc == 0);
+ CU_ASSERT(ok);
+
+ rc = odp_crypto_session_destroy(session);
+ CU_ASSERT(rc == 0);
+
+ rc = odp_packet_copy_to_mem(pkt, 0, ref->length, ref->ciphertext);
+ CU_ASSERT(rc == 0);
+
+ odp_packet_free(pkt);
+ return 0;
+}
+
+typedef struct crypto_suite_t {
+ odp_cipher_alg_t cipher;
+ odp_auth_alg_t auth;
+ alg_order_t order;
+ const odp_crypto_cipher_capability_t *cipher_capa;
+ const odp_crypto_auth_capability_t *auth_capa;
+} crypto_suite_t;
+
+/*
+ * Create test reference for combined auth & cipher by doing authentication
+ * and ciphering through separate ODP crypto operations.
+ */
+static int create_combined_ref(const crypto_suite_t *suite,
+ crypto_test_reference_t *ref,
+ odp_packet_data_range_t *cipher_range,
+ odp_packet_data_range_t *auth_range,
+ uint32_t digest_offset)
+{
+ uint32_t total_len;
+ int rc;
+ crypto_test_reference_t ref_cipher_only;
+ crypto_test_reference_t ref_auth_only;
+ crypto_test_reference_t *first_ref, *second_ref;
+ odp_auth_alg_t first_auth, second_auth;
+ odp_cipher_alg_t first_cipher, second_cipher;
+
+ total_len = cipher_range->offset + cipher_range->length;
+ if (auth_range->offset + auth_range->length > total_len)
+ total_len = auth_range->offset + auth_range->length;
+ if (digest_offset + suite->auth_capa->digest_len > total_len)
+ total_len = digest_offset + suite->auth_capa->digest_len;
+
+ ref->cipher_key_length = suite->cipher_capa->key_len;
+ ref->cipher_iv_length = suite->cipher_capa->iv_len;
+ ref->auth_key_length = suite->auth_capa->key_len;
+ ref->auth_iv_length = suite->auth_capa->iv_len;
+ ref->digest_length = suite->auth_capa->digest_len;
+ ref->aad_length = 0;
+ ref->is_length_in_bits = false;
+ ref->length = total_len;
+
+ if (suite->cipher_capa->bit_mode) {
+ cipher_range->offset *= 8;
+ cipher_range->length *= 8;
+ }
+ if (suite->auth_capa->bit_mode) {
+ auth_range->offset *= 8;
+ auth_range->length *= 8;
+ }
+
+ if (ref->auth_key_length > MAX_KEY_LEN ||
+ ref->auth_iv_length > MAX_IV_LEN ||
+ total_len > MAX_DATA_LEN ||
+ digest_offset + ref->digest_length > MAX_DATA_LEN)
+ CU_FAIL_FATAL("Internal error\n");
+
+ fill_with_pattern(ref->cipher_key, ref->cipher_key_length);
+ fill_with_pattern(ref->cipher_iv, ref->cipher_iv_length);
+ fill_with_pattern(ref->auth_key, ref->auth_key_length);
+ fill_with_pattern(ref->auth_iv, ref->auth_iv_length);
+ fill_with_pattern(ref->plaintext, ref->length);
+ memset(ref->plaintext + digest_offset, 0, ref->digest_length);
+
+ ref_cipher_only = *ref;
+ ref_cipher_only.auth_key_length = 0;
+ ref_cipher_only.auth_iv_length = 0;
+ ref_cipher_only.aad_length = 0;
+ ref_cipher_only.digest_length = 0;
+
+ ref_auth_only = *ref;
+ ref_auth_only.cipher_key_length = 0;
+ ref_auth_only.cipher_iv_length = 0;
+
+ if (suite->order == AUTH_CIPHERTEXT) {
+ first_ref = &ref_cipher_only;
+ first_cipher = suite->cipher;
+ first_auth = ODP_AUTH_ALG_NULL;
+ second_ref = &ref_auth_only;
+ second_cipher = ODP_CIPHER_ALG_NULL;
+ second_auth = suite->auth;
+ } else {
+ first_ref = &ref_auth_only;
+ first_cipher = ODP_CIPHER_ALG_NULL;
+ first_auth = suite->auth;
+ second_ref = &ref_cipher_only;
+ second_cipher = suite->cipher;
+ second_auth = ODP_AUTH_ALG_NULL;
+ }
+ rc = crypto_encode_ref(first_ref,
+ first_cipher, first_auth,
+ *cipher_range, *auth_range,
+ digest_offset);
+ if (rc)
+ return 1;
+ memcpy(second_ref->plaintext, first_ref->ciphertext, ref->length);
+ rc = crypto_encode_ref(second_ref,
+ second_cipher, second_auth,
+ *cipher_range, *auth_range,
+ digest_offset);
+ if (rc)
+ return 1;
+ memcpy(ref->ciphertext, second_ref->ciphertext, ref->length);
+ /*
+ * These may be encrypted bytes, but that is what alg_test wants if
+ * the digest is encrypted in the input packet.
+ */
+ memcpy(ref->digest, second_ref->ciphertext + digest_offset, ref->digest_length);
+
+ return 0;
+}
+
+/*
+ * Return cipher range that is at least min_len bytes long, multiple of the
+ * block size and at least 3 blocks.
+ */
+static uint32_t get_cipher_range_len(uint32_t min_len)
+{
+#define MAX_BLOCK_SIZE 16
+ uint32_t bs = MAX_BLOCK_SIZE;
+ uint32_t len = 3 * bs;
+
+ if (min_len > len)
+ len = ((min_len + bs - 1) / bs) * bs;
+ return len;
+}
+
+typedef enum range_overlap_t {
+ SEPARATE_AUTH_AND_CIPHER_RANGES,
+ SAME_AUTH_AND_CIPHER_RANGE,
+ RANGES_PARTIALLY_OVERLAP,
+ AUTH_RANGE_IN_CIPHER_RANGE,
+ CIPHER_RANGE_IN_AUTH_RANGE,
+} range_overlap_t;
+#define NUM_RANGE_OVERLAPS 5
+
+typedef enum hash_location_t {
+ HASH_SEPARATE,
+ HASH_IN_AUTH_RANGE_ONLY,
+ HASH_IN_CIPHER_RANGE_ONLY,
+ HASH_IN_AUTH_AND_CIPHER_RANGE,
+} hash_location_t;
+#define NUM_HASH_LOCATIONS 4
+
+static int make_byte_ranges(range_overlap_t overlap,
+ hash_location_t hash_location,
+ uint32_t hash_len,
+ odp_packet_data_range_t *cipher_range,
+ odp_packet_data_range_t *auth_range,
+ uint32_t *digest_offset)
+{
+ const uint32_t padding = 5; /* padding between parts, could also be zero */
+ const uint32_t nonzero_len = 3;
+ uint32_t c_offs = 0, c_len = 0, a_offs = 0, a_len = 0, digest_offs = 0;
+
+ switch (overlap) {
+ case SEPARATE_AUTH_AND_CIPHER_RANGES:
+ switch (hash_location) {
+ case HASH_SEPARATE:
+ /* |cccc_aaaa_dd| */
+ c_offs = 0;
+ c_len = get_cipher_range_len(nonzero_len);
+ a_offs = c_offs + c_len + padding;
+ a_len = nonzero_len;
+ digest_offs = a_offs + a_len + padding;
+ break;
+ case HASH_IN_AUTH_RANGE_ONLY:
+ /*
+ * |cccc_aaaa|
+ * | _dd_|
+ */
+ c_offs = 0;
+ c_len = get_cipher_range_len(nonzero_len);
+ a_offs = c_offs + c_len + padding;
+ a_len = hash_len + 2 * padding;
+ digest_offs = a_offs + padding;
+ break;
+ case HASH_IN_CIPHER_RANGE_ONLY:
+ /*
+ * |cccc_aaaa|
+ * |_dd_ |
+ */
+ c_offs = 0;
+ c_len = get_cipher_range_len(hash_len + 2 * padding);
+ a_offs = c_offs + c_len + padding;
+ a_len = nonzero_len;
+ digest_offs = c_offs + padding;
+ break;
+ case HASH_IN_AUTH_AND_CIPHER_RANGE:
+ /* not possible when ranges are separate */
+ return 1;
+ }
+ break;
+ case SAME_AUTH_AND_CIPHER_RANGE:
+ c_offs = 0;
+ a_offs = 0;
+ switch (hash_location) {
+ case HASH_SEPARATE:
+ /*
+ * |cccc_dd|
+ * |aaaa |
+ */
+ c_len = get_cipher_range_len(nonzero_len);
+ a_len = c_len;
+ digest_offs = c_len + padding;
+ break;
+ case HASH_IN_AUTH_RANGE_ONLY:
+ case HASH_IN_CIPHER_RANGE_ONLY:
+ /* not possible when ranges are the same */
+ return 1;
+ case HASH_IN_AUTH_AND_CIPHER_RANGE:
+ /*
+ * |cccc|
+ * |aaaa|
+ * |_dd_|
+ */
+ c_len = get_cipher_range_len(hash_len + 2 * padding);
+ a_len = c_len;
+ digest_offs = padding;
+ break;
+ }
+ break;
+ case RANGES_PARTIALLY_OVERLAP:
+ a_offs = 0;
+ switch (hash_location) {
+ case HASH_SEPARATE:
+ /*
+ * |aaaa |
+ * | cccc_dd|
+ */
+ a_len = 2 * nonzero_len;
+ c_offs = nonzero_len;
+ c_len = get_cipher_range_len(a_len);
+ digest_offs = c_offs + c_len + padding;
+ break;
+ case HASH_IN_AUTH_RANGE_ONLY:
+ /*
+ * |aaaaa |
+ * |_dd_ccc|
+ */
+ digest_offs = padding;
+ a_len = hash_len + 2 * padding + nonzero_len;
+ c_offs = hash_len + 2 * padding;
+ c_len = get_cipher_range_len(2 * nonzero_len);
+ break;
+ case HASH_IN_CIPHER_RANGE_ONLY:
+ /* PDCP case when AUTH_PLAINTEXT */
+ /*
+ * |aaaadd|
+ * | ccccc|
+ */
+ c_offs = nonzero_len;
+ c_len = get_cipher_range_len(nonzero_len + hash_len);
+ a_len = nonzero_len + c_len - hash_len;
+ digest_offs = c_offs + c_len - hash_len;
+ break;
+ case HASH_IN_AUTH_AND_CIPHER_RANGE:
+ /*
+ * |aaaaaa |
+ * | cccccc|
+ * |¨_dd_ |
+ */
+ c_offs = nonzero_len;
+ c_len = get_cipher_range_len(hash_len + 2 * padding + nonzero_len);
+ a_len = c_offs + hash_len + 2 * padding;
+ digest_offs = c_offs + padding;
+ break;
+ }
+ break;
+ case AUTH_RANGE_IN_CIPHER_RANGE:
+ c_offs = 0;
+ a_offs = nonzero_len;
+ switch (hash_location) {
+ case HASH_SEPARATE:
+ /*
+ * |cccc_dd|
+ * | aa_ |
+ */
+ a_len = nonzero_len;
+ c_len = get_cipher_range_len(a_offs + a_len + padding);
+ digest_offs = c_len + padding;
+ break;
+ case HASH_IN_AUTH_RANGE_ONLY:
+ /* not possible since auth range is in cipher range */
+ return 1;
+ case HASH_IN_CIPHER_RANGE_ONLY:
+ /*
+ * |ccccccc|
+ * | aa_dd_|
+ */
+ a_len = nonzero_len;
+ digest_offs = a_offs + a_len + padding;
+ c_len = get_cipher_range_len(digest_offs + hash_len + padding);
+ break;
+ case HASH_IN_AUTH_AND_CIPHER_RANGE:
+ /*
+ * |cccccc|
+ * | aaaa_|
+ * | _dd_ |
+ */
+ a_len = /**/ hash_len + 2 * padding;
+ c_len = get_cipher_range_len(a_offs + a_len + padding);
+ digest_offs = a_offs + /**/ padding;
+ break;
+ }
+ break;
+ case CIPHER_RANGE_IN_AUTH_RANGE:
+ a_offs = 0;
+ c_offs = nonzero_len;
+ switch (hash_location) {
+ case HASH_SEPARATE:
+ /*
+ * |aaaa_dd|
+ * | cc_ |
+ */
+ c_len = get_cipher_range_len(nonzero_len);
+ a_len = c_offs + c_len + padding;
+ digest_offs = a_len + padding;
+ break;
+ case HASH_IN_AUTH_RANGE_ONLY:
+ /*
+ * |aaaaaaa|
+ * | cc_dd_|
+ */
+ c_len = get_cipher_range_len(nonzero_len);
+ digest_offs = c_offs + c_len + padding;
+ a_len = digest_offs + hash_len + padding;
+ break;
+ case HASH_IN_CIPHER_RANGE_ONLY:
+ /* not possible since cipher range is in auth range */
+ return 1;
+ case HASH_IN_AUTH_AND_CIPHER_RANGE:
+ /*
+ * |aaaaaa|
+ * | cccc_|
+ * | _dd_ |
+ */
+ c_len = get_cipher_range_len(hash_len + 2 * padding);
+ a_len = c_offs + c_len + padding;
+ digest_offs = c_offs + padding;
+ break;
+ }
+ break;
+ }
+ cipher_range->offset = c_offs;
+ cipher_range->length = c_len;
+ auth_range->offset = a_offs;
+ auth_range->length = a_len;
+ *digest_offset = digest_offs;
+ return 0;
+}
+
+static void test_combo(const crypto_suite_t *suite,
+ range_overlap_t overlap,
+ hash_location_t location)
+{
+ int rc;
+
+ odp_packet_data_range_t cipher_range = {0, 0};
+ odp_packet_data_range_t auth_range = {0, 0};
+ uint32_t digest_offset = 0;
+ crypto_test_reference_t ref;
+
+ rc = make_byte_ranges(overlap,
+ location,
+ suite->auth_capa->digest_len,
+ &cipher_range,
+ &auth_range,
+ &digest_offset);
+ if (rc)
+ return;
+
+ rc = create_combined_ref(suite, &ref,
+ &cipher_range, &auth_range,
+ digest_offset);
+ if (rc)
+ return;
+
+ alg_test(ODP_CRYPTO_OP_ENCODE,
+ suite->cipher,
+ suite->auth,
+ suite->order,
+ &ref,
+ cipher_range, auth_range,
+ digest_offset,
+ suite->cipher_capa->bit_mode,
+ suite->auth_capa->bit_mode);
+
+ alg_test(ODP_CRYPTO_OP_DECODE,
+ suite->cipher,
+ suite->auth,
+ suite->order,
+ &ref,
+ cipher_range, auth_range,
+ digest_offset,
+ suite->cipher_capa->bit_mode,
+ suite->auth_capa->bit_mode);
+}
+
+/* Iterate and test different cipher/auth range and hash locations */
+static void test_combo_ranges(const crypto_suite_t *suite)
+{
+ if (!full_test && suite->auth_capa->digest_len % 4 != 0)
+ return;
+
+ for (int overlap = 0; overlap < NUM_RANGE_OVERLAPS; overlap++)
+ for (int location = 0; location < NUM_HASH_LOCATIONS; location++) {
+ if (suite->order == AUTH_CIPHERTEXT &&
+ (location == HASH_IN_CIPHER_RANGE_ONLY ||
+ location == HASH_IN_AUTH_AND_CIPHER_RANGE)) {
+ /*
+ * This combination ís not valid since
+ * the generated hash would overwrite some
+ * ciphertext, preventing decryption.
+ */
+ continue;
+ }
+ test_combo(suite, overlap, location);
+ }
+}
+
+/* Iterate and test all variants (key sizes etc) of an alg combo */
+static void test_combo_variants(odp_cipher_alg_t cipher, odp_auth_alg_t auth)
+{
+ int num, num_ciphers, num_auths;
+
+ /* ODP API says AES-GMAC can be combined with the null cipher only */
+ if (auth == ODP_AUTH_ALG_AES_GMAC &&
+ cipher != ODP_CIPHER_ALG_NULL)
+ return;
+
+ if (check_alg_support(cipher, auth) == ODP_TEST_INACTIVE)
+ return;
+
+ printf(" %s, %s\n",
+ cipher_alg_name(cipher),
+ auth_alg_name(auth));
+
+ num_ciphers = odp_crypto_cipher_capability(cipher, NULL, 0);
+ num_auths = odp_crypto_auth_capability(auth, NULL, 0);
+ CU_ASSERT_FATAL(num_ciphers > 0);
+ CU_ASSERT_FATAL(num_auths > 0);
+
+ odp_crypto_cipher_capability_t cipher_capa[num_ciphers];
+ odp_crypto_auth_capability_t auth_capa[num_auths];
+
+ num = odp_crypto_cipher_capability(cipher, cipher_capa, num_ciphers);
+ CU_ASSERT(num == num_ciphers);
+ num = odp_crypto_auth_capability(auth, auth_capa, num_auths);
+ CU_ASSERT(num == num_auths);
+
+ combo_warning_shown = 0;
+
+ for (int n = 0; n < num_ciphers; n++)
+ for (int i = 0; i < num_auths; i++) {
+ crypto_suite_t suite = {.cipher = cipher,
+ .auth = auth,
+ .cipher_capa = &cipher_capa[n],
+ .auth_capa = &auth_capa[i]};
+ suite.order = AUTH_PLAINTEXT;
+ test_combo_ranges(&suite);
+ suite.order = AUTH_CIPHERTEXT;
+ test_combo_ranges(&suite);
+ }
+}
+
+static void test_all_combinations(void)
+{
+ printf("\n");
+ for (size_t n = 0; n < ARRAY_SIZE(cipher_algs); n++)
+ for (size_t i = 0; i < ARRAY_SIZE(auth_algs); i++)
+ test_combo_variants(cipher_algs[n], auth_algs[i]);
+}
+
static int check_alg_null(void)
{
return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_NULL);
@@ -2443,64 +3044,8 @@ static odp_event_t plain_compl_queue_deq(void)
return odp_queue_deq(suite_context.queue);
}
-#if ODP_DEPRECATED_API
-static int crypto_suite_sync_init(void)
-{
- suite_context.pool = odp_pool_lookup("packet_pool");
- if (suite_context.pool == ODP_POOL_INVALID)
- return -1;
-
- suite_context.queue = ODP_QUEUE_INVALID;
- suite_context.pref_mode = ODP_CRYPTO_SYNC;
- return 0;
-}
-
-static int crypto_suite_async_plain_init(void)
-{
- odp_queue_t out_queue;
-
- suite_context.pool = odp_pool_lookup("packet_pool");
- if (suite_context.pool == ODP_POOL_INVALID)
- return -1;
-
- out_queue = plain_compl_queue_create();
- if (ODP_QUEUE_INVALID == out_queue) {
- fprintf(stderr, "Crypto outq creation failed.\n");
- return -1;
- }
- suite_context.queue = out_queue;
- suite_context.q_type = ODP_QUEUE_TYPE_PLAIN;
- suite_context.compl_queue_deq = plain_compl_queue_deq;
- suite_context.pref_mode = ODP_CRYPTO_ASYNC;
-
- return 0;
-}
-
-static int crypto_suite_async_sched_init(void)
-{
- odp_queue_t out_queue;
-
- suite_context.pool = odp_pool_lookup("packet_pool");
- if (suite_context.pool == ODP_POOL_INVALID)
- return -1;
-
- out_queue = sched_compl_queue_create();
- if (ODP_QUEUE_INVALID == out_queue) {
- fprintf(stderr, "Crypto outq creation failed.\n");
- return -1;
- }
- suite_context.queue = out_queue;
- suite_context.q_type = ODP_QUEUE_TYPE_SCHED;
- suite_context.compl_queue_deq = sched_compl_queue_deq;
- suite_context.pref_mode = ODP_CRYPTO_ASYNC;
-
- return 0;
-}
-#endif
-
static int crypto_suite_packet_sync_init(void)
{
- suite_context.packet = true;
suite_context.op_mode = ODP_CRYPTO_SYNC;
suite_context.pool = odp_pool_lookup("packet_pool");
@@ -2515,7 +3060,6 @@ static int crypto_suite_packet_async_plain_init(void)
{
odp_queue_t out_queue;
- suite_context.packet = true;
suite_context.op_mode = ODP_CRYPTO_ASYNC;
suite_context.pool = odp_pool_lookup("packet_pool");
@@ -2538,7 +3082,6 @@ static int crypto_suite_packet_async_sched_init(void)
{
odp_queue_t out_queue;
- suite_context.packet = true;
suite_context.op_mode = ODP_CRYPTO_ASYNC;
suite_context.pool = odp_pool_lookup("packet_pool");
@@ -2709,18 +3252,11 @@ odp_testinfo_t crypto_suite[] = {
ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_sha512,
check_alg_sha512),
ODP_TEST_INFO(test_auth_hashes_in_auth_range),
+ ODP_TEST_INFO(test_all_combinations),
ODP_TEST_INFO_NULL,
};
odp_suiteinfo_t crypto_suites[] = {
-#if ODP_DEPRECATED_API
- {"odp_crypto_sync_inp", crypto_suite_sync_init,
- NULL, crypto_suite},
- {"odp_crypto_async_plain_inp", crypto_suite_async_plain_init,
- crypto_suite_term, crypto_suite},
- {"odp_crypto_async_sched_inp", crypto_suite_async_sched_init,
- crypto_suite_term, crypto_suite},
-#endif
{"odp_crypto_packet_sync_inp", crypto_suite_packet_sync_init,
NULL, crypto_suite},
{"odp_crypto_packet_async_plain_inp",
@@ -2834,6 +3370,11 @@ static int crypto_term(odp_instance_t inst)
int main(int argc, char *argv[])
{
int ret;
+ char *env = getenv("FULL_TEST");
+
+ if (env && strcmp(env, "0"))
+ full_test = 1;
+ printf("Test mode: %s\n", full_test ? "full" : "partial");
/* parse common options: */
if (odp_cunit_parse_options(argc, argv))
diff --git a/test/validation/api/dma/dma.c b/test/validation/api/dma/dma.c
index f3e967193..ad42c9bb3 100644
--- a/test/validation/api/dma/dma.c
+++ b/test/validation/api/dma/dma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2021-2022, Nokia
+/* Copyright (c) 2021-2023, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -10,9 +10,8 @@
#define COMPL_POOL_NAME "DMA compl pool"
-#define SHM_SIZE (1024 * 1024)
+#define MIN_SEG_LEN 1024
#define SHM_ALIGN ODP_CACHE_LINE_SIZE
-#define NUM_COMPL 10
#define RETRIES 5
#define TIMEOUT 5
#define OFFSET 10
@@ -21,6 +20,8 @@
#define RESULT 1
#define USER_DATA 0xdeadbeef
+#define MIN(a, b) (a < b ? a : b)
+
typedef struct global_t {
odp_dma_capability_t dma_capa;
odp_shm_t shm;
@@ -47,7 +48,7 @@ static int dma_suite_init(void)
odp_dma_pool_param_t dma_pool_param;
odp_pool_capability_t pool_capa;
odp_queue_param_t queue_param;
- uint32_t pkt_len;
+ uint32_t shm_len, pkt_len;
void *addr;
memset(&global, 0, sizeof(global_t));
@@ -67,7 +68,8 @@ static int dma_suite_init(void)
return 0;
}
- shm = odp_shm_reserve("DMA test", SHM_SIZE, SHM_ALIGN, 0);
+ shm_len = MIN_SEG_LEN * global.dma_capa.max_segs * global.dma_capa.max_transfers;
+ shm = odp_shm_reserve("DMA test", shm_len, SHM_ALIGN, 0);
if (shm == ODP_SHM_INVALID) {
ODPH_ERR("SHM reserve failed\n");
@@ -82,7 +84,7 @@ static int dma_suite_init(void)
}
global.shm = shm;
- global.data_size = SHM_SIZE / 2;
+ global.data_size = shm_len / 2;
global.src_addr = addr;
global.dst_addr = (uint8_t *)global.src_addr + global.data_size;
global.len = global.data_size - OFFSET - TRAILER;
@@ -96,6 +98,7 @@ static int dma_suite_init(void)
if (pkt_len == 0)
pkt_len = 4000;
+ pkt_len = MIN(pkt_len, global.dma_capa.max_seg_len);
odp_pool_param_init(&pool_param);
pool_param.type = ODP_POOL_PACKET;
pool_param.pkt.num = 4;
@@ -124,13 +127,13 @@ static int dma_suite_init(void)
}
if (global.dma_capa.compl_mode_mask & ODP_DMA_COMPL_EVENT) {
- if (global.dma_capa.pool.max_num < NUM_COMPL) {
+ if (global.dma_capa.pool.max_num < global.dma_capa.max_transfers) {
ODPH_ERR("Too small DMA compl pool %u\n", global.dma_capa.pool.max_num);
return -1;
}
odp_dma_pool_param_init(&dma_pool_param);
- dma_pool_param.num = NUM_COMPL;
+ dma_pool_param.num = global.dma_capa.max_transfers;
global.cache_size = dma_pool_param.cache_size;
global.compl_pool = odp_dma_pool_create(COMPL_POOL_NAME, &dma_pool_param);
@@ -178,7 +181,7 @@ static void test_dma_capability(void)
odp_dma_capability_t capa;
memset(&capa, 0, sizeof(odp_dma_capability_t));
- CU_ASSERT(odp_dma_capability(&capa) == 0);
+ CU_ASSERT_FATAL(odp_dma_capability(&capa) == 0);
if (capa.max_sessions == 0)
return;
@@ -193,8 +196,12 @@ static void test_dma_capability(void)
CU_ASSERT(capa.compl_mode_mask & ODP_DMA_COMPL_SYNC);
if (capa.compl_mode_mask & ODP_DMA_COMPL_EVENT) {
+ odp_pool_capability_t pool_capa;
+
+ CU_ASSERT_FATAL(odp_pool_capability(&pool_capa) == 0);
+
CU_ASSERT(capa.queue_type_sched || capa.queue_type_plain);
- CU_ASSERT(capa.pool.max_pools > 0);
+ CU_ASSERT(capa.pool.max_pools > 0 && capa.pool.max_pools <= pool_capa.max_pools);
CU_ASSERT(capa.pool.max_num > 0);
CU_ASSERT(capa.pool.min_cache_size <= capa.pool.max_cache_size);
}
@@ -266,9 +273,10 @@ static void test_dma_compl_pool(void)
{
odp_pool_t pool;
odp_pool_info_t pool_info;
- odp_dma_compl_t compl;
+ odp_dma_compl_t compl[global.dma_capa.max_transfers];
uint64_t u64;
int ret;
+ uint32_t i, j;
const char *name = COMPL_POOL_NAME;
CU_ASSERT_FATAL(global.compl_pool != ODP_POOL_INVALID);
@@ -282,17 +290,24 @@ static void test_dma_compl_pool(void)
CU_ASSERT(strcmp(pool_info.name, name) == 0);
CU_ASSERT(pool_info.pool_ext == 0);
CU_ASSERT(pool_info.type == ODP_POOL_DMA_COMPL);
- CU_ASSERT(pool_info.dma_pool_param.num == NUM_COMPL);
+ CU_ASSERT(pool_info.dma_pool_param.num == global.dma_capa.max_transfers);
CU_ASSERT(pool_info.dma_pool_param.cache_size == global.cache_size);
- compl = odp_dma_compl_alloc(global.compl_pool);
+ for (i = 0; i < global.dma_capa.max_transfers; i++) {
+ compl[i] = odp_dma_compl_alloc(global.compl_pool);
+
+ u64 = odp_dma_compl_to_u64(compl[i]);
+ CU_ASSERT(u64 != odp_dma_compl_to_u64(ODP_DMA_COMPL_INVALID));
+
+ if (compl[i] == ODP_DMA_COMPL_INVALID)
+ break;
- u64 = odp_dma_compl_to_u64(compl);
- CU_ASSERT(u64 != odp_dma_compl_to_u64(ODP_DMA_COMPL_INVALID));
- printf("\n DMA compl handle: 0x%" PRIx64 "\n", u64);
- odp_dma_compl_print(compl);
+ printf("\n DMA compl handle: 0x%" PRIx64 "\n", u64);
+ odp_dma_compl_print(compl[i]);
+ }
- odp_dma_compl_free(compl);
+ for (j = 0; j < i; j++)
+ odp_dma_compl_free(compl[j]);
}
static void test_dma_compl_pool_same_name(void)
@@ -307,7 +322,7 @@ static void test_dma_compl_pool_same_name(void)
CU_ASSERT(pool == pool_a);
odp_dma_pool_param_init(&dma_pool_param);
- dma_pool_param.num = NUM_COMPL;
+ dma_pool_param.num = global.dma_capa.max_transfers;
/* Second pool with the same name */
pool_b = odp_dma_pool_create(name, &dma_pool_param);
@@ -319,6 +334,36 @@ static void test_dma_compl_pool_same_name(void)
CU_ASSERT_FATAL(odp_pool_destroy(pool_b) == 0);
}
+static void test_dma_compl_pool_max_pools(void)
+{
+ odp_dma_pool_param_t dma_pool_param;
+ /* Max pools minus the ones already created in global init */
+ uint32_t num = global.dma_capa.pool.max_pools - 2, i, j;
+ odp_pool_t pools[num];
+ int ret;
+
+ odp_dma_pool_param_init(&dma_pool_param);
+ dma_pool_param.num = global.dma_capa.max_transfers;
+
+ for (i = 0; i < num; i++) {
+ pools[i] = odp_dma_pool_create(NULL, &dma_pool_param);
+ CU_ASSERT(pools[i] != ODP_POOL_INVALID);
+
+ if (pools[i] == ODP_POOL_INVALID) {
+ ODPH_ERR("DMA completion pool create failed: %u / %u\n", i, num);
+ break;
+ }
+ }
+
+ for (j = 0; j < i; j++) {
+ ret = odp_pool_destroy(pools[j]);
+ CU_ASSERT(ret == 0);
+
+ if (ret == -1)
+ ODPH_ERR("DMA completion pool destroy failed: %u / %u\n", j, i);
+ }
+}
+
static void init_source(uint8_t *src, uint32_t len)
{
uint32_t i;
@@ -380,126 +425,132 @@ static int do_transfer(odp_dma_t dma, const odp_dma_transfer_param_t *trs_param,
return ret;
}
-static int do_transfer_async(odp_dma_t dma, const odp_dma_transfer_param_t *trs_param,
+static int do_transfer_async(odp_dma_t dma, odp_dma_transfer_param_t *trs_param,
odp_dma_compl_mode_t compl_mode, int multi)
{
- odp_dma_compl_param_t compl_param;
+ int num_trs = multi ? multi : 1;
+ odp_dma_compl_param_t compl_param[num_trs];
+ const odp_dma_compl_param_t *compl_ptr[num_trs];
+ const odp_dma_transfer_param_t *trs_ptr[num_trs];
odp_event_t ev;
odp_dma_compl_t compl;
- int i, ret, done;
+ int i, j, ret, done;
uint32_t user_data = USER_DATA;
odp_dma_result_t result;
- odp_dma_transfer_id_t transfer_id = ODP_DMA_TRANSFER_ID_INVALID;
uint64_t wait_ns = 500 * ODP_TIME_MSEC_IN_NS;
uint64_t sched_wait = odp_schedule_wait_time(wait_ns);
void *user_ptr = &user_data;
- odp_dma_compl_param_init(&compl_param);
- compl_param.compl_mode = compl_mode;
-
- if (compl_mode == ODP_DMA_COMPL_EVENT) {
- compl = odp_dma_compl_alloc(global.compl_pool);
-
- CU_ASSERT(compl != ODP_DMA_COMPL_INVALID);
- if (compl == ODP_DMA_COMPL_INVALID)
+ for (i = 0; i < num_trs; i++) {
+ odp_dma_compl_param_init(&compl_param[i]);
+ compl_param[i].compl_mode = compl_mode;
+
+ if (compl_mode == ODP_DMA_COMPL_EVENT) {
+ compl = odp_dma_compl_alloc(global.compl_pool);
+
+ CU_ASSERT(compl != ODP_DMA_COMPL_INVALID);
+ if (compl == ODP_DMA_COMPL_INVALID)
+ return -1;
+
+ compl_param[i].event = odp_dma_compl_to_event(compl);
+ compl_param[i].queue = global.queue;
+ } else if (compl_mode == ODP_DMA_COMPL_POLL) {
+ compl_param[i].transfer_id = odp_dma_transfer_id_alloc(dma);
+
+ CU_ASSERT(compl_param[i].transfer_id != ODP_DMA_TRANSFER_ID_INVALID);
+ if (compl_param[i].transfer_id == ODP_DMA_TRANSFER_ID_INVALID)
+ return -1;
+ } else if (compl_mode != ODP_DMA_COMPL_NONE) {
+ ODPH_ERR("Wrong compl mode: %u\n", compl_mode);
return -1;
+ }
- compl_param.event = odp_dma_compl_to_event(compl);
- compl_param.queue = global.queue;
- } else if (compl_mode == ODP_DMA_COMPL_POLL) {
- transfer_id = odp_dma_transfer_id_alloc(dma);
-
- CU_ASSERT(transfer_id != ODP_DMA_TRANSFER_ID_INVALID);
- if (transfer_id == ODP_DMA_TRANSFER_ID_INVALID)
- return -1;
+ compl_param[i].user_ptr = user_ptr;
- compl_param.transfer_id = transfer_id;
- } else if (compl_mode != ODP_DMA_COMPL_NONE) {
- ODPH_ERR("Wrong compl mode: %u\n", compl_mode);
- return -1;
+ if (multi) {
+ trs_ptr[i] = &trs_param[i];
+ compl_ptr[i] = &compl_param[i];
+ }
}
for (i = 0; i < RETRIES; i++) {
- compl_param.user_ptr = user_ptr;
-
- if (multi) {
- const odp_dma_compl_param_t *compl_ptr[1] = {&compl_param};
- const odp_dma_transfer_param_t *trs_ptr[1] = {trs_param};
-
- ret = odp_dma_transfer_start_multi(dma, trs_ptr, compl_ptr, 1);
- } else {
- ret = odp_dma_transfer_start(dma, trs_param, &compl_param);
- }
+ if (multi)
+ ret = odp_dma_transfer_start_multi(dma, trs_ptr, compl_ptr, num_trs);
+ else
+ ret = odp_dma_transfer_start(dma, trs_param, compl_param);
if (ret)
break;
}
- CU_ASSERT(ret == 1);
+ CU_ASSERT(ret == num_trs);
if (ret < 1)
return ret;
- memset(&result, 0, sizeof(odp_dma_result_t));
+ for (i = 0; i < ret; i++) {
+ memset(&result, 0, sizeof(odp_dma_result_t));
- if (compl_mode == ODP_DMA_COMPL_POLL) {
- for (i = 0; i < TIMEOUT; i++) {
- done = odp_dma_transfer_done(dma, transfer_id, &result);
- if (done)
- break;
+ if (compl_mode == ODP_DMA_COMPL_POLL) {
+ for (j = 0; j < TIMEOUT; j++) {
+ done = odp_dma_transfer_done(dma, compl_param[i].transfer_id,
+ &result);
+ if (done)
+ break;
- odp_time_wait_ns(wait_ns);
- }
+ odp_time_wait_ns(wait_ns);
+ }
- CU_ASSERT(done == 1);
- CU_ASSERT(result.success);
- CU_ASSERT(result.user_ptr == user_ptr);
- CU_ASSERT(user_data == USER_DATA);
+ CU_ASSERT(done == 1);
+ CU_ASSERT(result.success);
+ CU_ASSERT(result.user_ptr == user_ptr);
+ CU_ASSERT(user_data == USER_DATA);
- odp_dma_transfer_id_free(dma, transfer_id);
+ odp_dma_transfer_id_free(dma, compl_param[i].transfer_id);
- return done;
+ return done;
- } else if (compl_mode == ODP_DMA_COMPL_EVENT) {
- odp_queue_t from = ODP_QUEUE_INVALID;
+ } else if (compl_mode == ODP_DMA_COMPL_EVENT) {
+ odp_queue_t from = ODP_QUEUE_INVALID;
- for (i = 0; i < TIMEOUT; i++) {
- ev = odp_schedule(&from, sched_wait);
- if (ev != ODP_EVENT_INVALID)
- break;
- }
+ for (j = 0; j < TIMEOUT; j++) {
+ ev = odp_schedule(&from, sched_wait);
+ if (ev != ODP_EVENT_INVALID)
+ break;
+ }
- CU_ASSERT(ev != ODP_EVENT_INVALID);
- if (ev == ODP_EVENT_INVALID)
- return -1;
+ CU_ASSERT(ev != ODP_EVENT_INVALID);
+ if (ev == ODP_EVENT_INVALID)
+ return -1;
- CU_ASSERT(from == global.queue);
- CU_ASSERT(odp_event_type(ev) == ODP_EVENT_DMA_COMPL);
+ CU_ASSERT(from == global.queue);
+ CU_ASSERT(odp_event_type(ev) == ODP_EVENT_DMA_COMPL);
- compl = odp_dma_compl_from_event(ev);
- CU_ASSERT(compl != ODP_DMA_COMPL_INVALID);
+ compl = odp_dma_compl_from_event(ev);
+ CU_ASSERT(compl != ODP_DMA_COMPL_INVALID);
- CU_ASSERT(odp_dma_compl_result(compl, &result) == 0);
- CU_ASSERT(result.success);
- CU_ASSERT(result.user_ptr == user_ptr);
- CU_ASSERT(user_data == USER_DATA);
+ CU_ASSERT(odp_dma_compl_result(compl, &result) == 0);
+ CU_ASSERT(result.success);
+ CU_ASSERT(result.user_ptr == user_ptr);
+ CU_ASSERT(user_data == USER_DATA);
- /* Test also without result struct output */
- CU_ASSERT(odp_dma_compl_result(compl, NULL) == 0);
+ /* Test also without result struct output */
+ CU_ASSERT(odp_dma_compl_result(compl, NULL) == 0);
- /* Test compl event print on the first event */
- if (global.event_count == 0) {
- printf("\n\n");
- odp_dma_compl_print(compl);
- }
+ /* Test compl event print on the first event */
+ if (global.event_count == 0) {
+ printf("\n\n");
+ odp_dma_compl_print(compl);
+ }
- /* Test both ways to free the event */
- if (global.event_count % 2)
- odp_event_free(ev);
- else
- odp_dma_compl_free(compl);
+ /* Test both ways to free the event */
+ if (global.event_count % 2)
+ odp_event_free(ev);
+ else
+ odp_dma_compl_free(compl);
- global.event_count++;
+ global.event_count++;
+ }
}
return 1;
@@ -517,8 +568,8 @@ static void test_dma_addr_to_addr(odp_dma_compl_mode_t compl_mode_mask, uint32_t
uint32_t i, cur_len;
uint8_t *src = global.src_addr + OFFSET;
uint8_t *dst = global.dst_addr + OFFSET;
- uint32_t len = global.len;
- uint32_t seg_len = len / num;
+ uint32_t seg_len = MIN(global.len / num, global.dma_capa.max_seg_len);
+ uint32_t len = seg_len * num;
uint32_t offset = 0;
init_source(global.src_addr, global.data_size);
@@ -558,7 +609,7 @@ static void test_dma_addr_to_addr(odp_dma_compl_mode_t compl_mode_mask, uint32_t
if (ret > 0) {
CU_ASSERT(check_equal(src, dst, len) == 0);
CU_ASSERT(check_zero(global.dst_addr, OFFSET) == 0);
- CU_ASSERT(check_zero(dst + len, TRAILER) == 0);
+ CU_ASSERT(check_zero(dst + len, global.len - len + TRAILER) == 0);
}
CU_ASSERT(odp_dma_destroy(dma) == 0);
@@ -577,8 +628,8 @@ static void test_dma_addr_to_addr_trs(odp_dma_compl_mode_t compl_mode_mask, uint
odp_dma_compl_mode_t compl_mode;
uint8_t *src = global.src_addr + OFFSET;
uint8_t *dst = global.dst_addr + OFFSET;
- uint32_t len = global.len;
- uint32_t trs_len = len / num_trs;
+ uint32_t trs_len = MIN(global.len / num_trs, global.dma_capa.max_seg_len);
+ uint32_t len = trs_len * num_trs;
uint32_t offset = 0;
int ret = -1;
@@ -630,7 +681,65 @@ static void test_dma_addr_to_addr_trs(odp_dma_compl_mode_t compl_mode_mask, uint
if (ret > 0) {
CU_ASSERT(check_equal(src, dst, len) == 0);
CU_ASSERT(check_zero(global.dst_addr, OFFSET) == 0);
- CU_ASSERT(check_zero(dst + len, TRAILER) == 0);
+ CU_ASSERT(check_zero(dst + len, global.len - len + TRAILER) == 0);
+ }
+
+ CU_ASSERT(odp_dma_destroy(dma) == 0);
+}
+
+static void test_dma_addr_to_addr_max_trs(odp_dma_compl_mode_t compl_mode_mask)
+{
+ odp_dma_param_t dma_param;
+ uint32_t num_trs = global.dma_capa.max_transfers;
+ odp_dma_transfer_param_t trs_param[num_trs];
+ odp_dma_t dma;
+ odp_dma_seg_t src_seg[num_trs];
+ odp_dma_seg_t dst_seg[num_trs];
+ int ret;
+ uint32_t i, cur_len;
+ uint8_t *src = global.src_addr + OFFSET;
+ uint8_t *dst = global.dst_addr + OFFSET;
+ uint32_t seg_len = MIN(global.len / num_trs, global.dma_capa.max_seg_len);
+ uint32_t len = seg_len * num_trs;
+ uint32_t offset = 0;
+
+ init_source(global.src_addr, global.data_size);
+ memset(global.dst_addr, 0, global.data_size);
+
+ odp_dma_param_init(&dma_param);
+ dma_param.compl_mode_mask = compl_mode_mask;
+ dma = odp_dma_create("addr_to_addr", &dma_param);
+ CU_ASSERT_FATAL(dma != ODP_DMA_INVALID);
+
+ memset(src_seg, 0, sizeof(src_seg));
+ memset(dst_seg, 0, sizeof(dst_seg));
+
+ for (i = 0; i < num_trs; i++) {
+ cur_len = seg_len;
+ if (i == num_trs - 1)
+ cur_len = len - seg_len * i;
+
+ src_seg[i].addr = src + offset;
+ src_seg[i].len = cur_len;
+ dst_seg[i].addr = dst + offset;
+ dst_seg[i].len = cur_len;
+ offset += cur_len;
+ }
+
+ for (i = 0; i < num_trs; i++) {
+ odp_dma_transfer_param_init(&trs_param[i]);
+ trs_param[i].num_src = 1;
+ trs_param[i].num_dst = 1;
+ trs_param[i].src_seg = &src_seg[i];
+ trs_param[i].dst_seg = &dst_seg[i];
+ }
+
+ ret = do_transfer_async(dma, trs_param, compl_mode_mask, num_trs);
+
+ if (ret > 0) {
+ CU_ASSERT(check_equal(src, dst, len) == 0);
+ CU_ASSERT(check_zero(global.dst_addr, OFFSET) == 0);
+ CU_ASSERT(check_zero(dst + len, global.len - len + TRAILER) == 0);
}
CU_ASSERT(odp_dma_destroy(dma) == 0);
@@ -1000,7 +1109,7 @@ static void test_dma_addr_to_addr_sync(void)
static void test_dma_addr_to_addr_sync_mtrs(void)
{
- test_dma_addr_to_addr_trs(ODP_DMA_COMPL_SYNC, 2, 0, 0);
+ test_dma_addr_to_addr_trs(ODP_DMA_COMPL_SYNC, global.dma_capa.max_transfers * 2, 0, 0);
}
static void test_dma_addr_to_addr_sync_mseg(void)
@@ -1140,6 +1249,11 @@ static void test_dma_multi_addr_to_addr_poll(void)
test_dma_addr_to_addr(ODP_DMA_COMPL_POLL, 1, MULTI, 0);
}
+static void test_dma_multi_addr_to_addr_poll_max_trs(void)
+{
+ test_dma_addr_to_addr_max_trs(ODP_DMA_COMPL_POLL);
+}
+
static void test_dma_multi_addr_to_pkt_poll(void)
{
test_dma_addr_to_pkt(ODP_DMA_COMPL_POLL, MULTI);
@@ -1160,6 +1274,11 @@ static void test_dma_multi_addr_to_addr_event(void)
test_dma_addr_to_addr(ODP_DMA_COMPL_EVENT, 1, MULTI, 0);
}
+static void test_dma_multi_addr_to_addr_event_max_trs(void)
+{
+ test_dma_addr_to_addr_max_trs(ODP_DMA_COMPL_EVENT);
+}
+
static void test_dma_multi_addr_to_pkt_event(void)
{
test_dma_addr_to_pkt(ODP_DMA_COMPL_EVENT, MULTI);
@@ -1181,6 +1300,7 @@ odp_testinfo_t dma_suite[] = {
ODP_TEST_INFO_CONDITIONAL(test_dma_debug, check_sync),
ODP_TEST_INFO_CONDITIONAL(test_dma_compl_pool, check_event),
ODP_TEST_INFO_CONDITIONAL(test_dma_compl_pool_same_name, check_event),
+ ODP_TEST_INFO_CONDITIONAL(test_dma_compl_pool_max_pools, check_event),
ODP_TEST_INFO_CONDITIONAL(test_dma_addr_to_addr_sync, check_sync),
ODP_TEST_INFO_CONDITIONAL(test_dma_addr_to_addr_sync_mtrs, check_sync),
ODP_TEST_INFO_CONDITIONAL(test_dma_addr_to_addr_sync_mseg, check_sync),
@@ -1208,10 +1328,12 @@ odp_testinfo_t dma_suite[] = {
ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_addr_sync, check_sync),
ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_pkt_sync, check_sync),
ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_addr_poll, check_poll),
+ ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_addr_poll_max_trs, check_poll),
ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_pkt_poll, check_poll),
ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_addr_poll, check_poll),
ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_pkt_poll, check_poll),
ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_addr_event, check_scheduled),
+ ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_addr_event_max_trs, check_scheduled),
ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_pkt_event, check_scheduled),
ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_addr_event, check_scheduled),
ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_pkt_event, check_scheduled),
diff --git a/test/validation/api/ipsec/ipsec_test_out.c b/test/validation/api/ipsec/ipsec_test_out.c
index bb318edad..1a013289b 100644
--- a/test/validation/api/ipsec/ipsec_test_out.c
+++ b/test/validation/api/ipsec/ipsec_test_out.c
@@ -475,6 +475,30 @@ static void ipsec_check_out_in_one(const ipsec_test_part *part_outbound,
}
}
+static int sa_creation_failure_ok(const odp_ipsec_sa_param_t *param)
+{
+ odp_cipher_alg_t cipher = param->crypto.cipher_alg;
+ odp_auth_alg_t auth = param->crypto.auth_alg;
+
+ /* Single algorithm must not fail */
+ if (cipher == ODP_CIPHER_ALG_NULL || auth == ODP_AUTH_ALG_NULL)
+ return 0;
+
+ /* Combined mode algorithms must not fail */
+ if (cipher == ODP_CIPHER_ALG_AES_GCM ||
+ cipher == ODP_CIPHER_ALG_AES_CCM ||
+ cipher == ODP_CIPHER_ALG_CHACHA20_POLY1305)
+ return 0;
+
+ /* Combination of mandatory algorithms must not fail */
+ if (cipher == ODP_CIPHER_ALG_AES_CBC && auth == ODP_AUTH_ALG_SHA1_HMAC)
+ return 0;
+
+ printf("\n Algorithm combination (%d, %d) maybe not supported.\n", cipher, auth);
+ printf(" SA creation failed, skipping test.\n");
+ return 1;
+}
+
static void test_out_in_common(const ipsec_test_flags *flags,
odp_cipher_alg_t cipher,
const odp_crypto_key_t *cipher_key,
@@ -539,6 +563,9 @@ static void test_out_in_common(const ipsec_test_flags *flags,
sa_out = odp_ipsec_sa_create(&param);
+ if (sa_out == ODP_IPSEC_SA_INVALID && sa_creation_failure_ok(&param))
+ return;
+
CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa_out);
ipsec_sa_param_fill(&param,
diff --git a/test/validation/api/pktio/pktio.c b/test/validation/api/pktio/pktio.c
index 446411b22..2f4dda4a4 100644
--- a/test/validation/api/pktio/pktio.c
+++ b/test/validation/api/pktio/pktio.c
@@ -300,6 +300,8 @@ static void pktio_init_packet_eth_ipv4(odp_packet_t pkt, uint8_t proto)
seq = odp_atomic_fetch_inc_u32(&ip_seq);
ip->id = odp_cpu_to_be_16(seq);
ip->chksum = 0;
+ ip->frag_offset = 0;
+ ip->tos = 0;
odph_ipv4_csum_update(pkt);
}
@@ -1681,7 +1683,6 @@ static void pktio_test_lookup(void)
pktio_inval = odp_pktio_open(iface_name[0], default_pkt_pool,
&pktio_param);
- CU_ASSERT(odp_errno() != 0);
CU_ASSERT(pktio_inval == ODP_PKTIO_INVALID);
CU_ASSERT(odp_pktio_close(pktio) == 0);
@@ -2039,8 +2040,10 @@ static void pktio_config_flow_control(int pfc, int rx, int tx)
if (cos != ODP_COS_INVALID)
odp_cos_destroy(cos);
- if (default_cos != ODP_COS_INVALID)
+ if (default_cos != ODP_COS_INVALID) {
+ odp_pktio_default_cos_set(pktio, ODP_COS_INVALID);
odp_cos_destroy(default_cos);
+ }
if (queue != ODP_QUEUE_INVALID)
odp_queue_destroy(queue);
@@ -4433,7 +4436,7 @@ static int create_pool(const char *iface, int num)
pool[num] = odp_pool_create(pool_name, &params);
if (ODP_POOL_INVALID == pool[num]) {
- ODPH_ERR("failed to create pool: %d", odp_errno());
+ ODPH_ERR("failed to create pool: %s\n", pool_name);
return -1;
}
@@ -4463,7 +4466,7 @@ static int create_pktv_pool(const char *iface, int num)
pktv_pool[num] = odp_pool_create(pool_name, &params);
if (ODP_POOL_INVALID == pktv_pool[num]) {
- ODPH_ERR("failed to create pool: %d", odp_errno());
+ ODPH_ERR("failed to create pool: %s\n", pool_name);
return -1;
}
diff --git a/test/validation/api/stash/stash.c b/test/validation/api/stash/stash.c
index f4ddfa2e1..fd4c04577 100644
--- a/test/validation/api/stash/stash.c
+++ b/test/validation/api/stash/stash.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2020-2022, Nokia
+/* Copyright (c) 2020-2023, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -7,6 +7,8 @@
#include <odp_api.h>
#include "odp_cunit_common.h"
+#include <string.h>
+
#define MAGIC_U64 0x8b7438fa56c82e96
#define MAGIC_U32 0x74a13b94
#define MAGIC_U16 0x25bf
@@ -111,10 +113,9 @@ static int stash_suite_init(void)
static void stash_capability(void)
{
odp_stash_capability_t capa;
- int ret;
memset(&capa, 0, sizeof(odp_stash_capability_t));
- CU_ASSERT(odp_stash_capability(&capa, ODP_STASH_TYPE_DEFAULT) == 0);
+ CU_ASSERT_FATAL(odp_stash_capability(&capa, ODP_STASH_TYPE_DEFAULT) == 0);
CU_ASSERT(capa.max_stashes_any_type > 0);
CU_ASSERT(capa.max_stashes > 0);
CU_ASSERT(capa.max_num_obj > 0);
@@ -122,16 +123,43 @@ static void stash_capability(void)
CU_ASSERT(capa.max_get_batch >= 1);
CU_ASSERT(capa.max_put_batch >= 1);
+ CU_ASSERT(capa.max_num.u8 >= capa.max_num_obj);
+ CU_ASSERT(capa.max_num.u16 >= capa.max_num_obj);
+ CU_ASSERT(capa.max_num.u32 >= capa.max_num_obj);
+ CU_ASSERT(capa.max_num.max_obj_size >= capa.max_num_obj);
+ if (capa.max_obj_size >= 8)
+ CU_ASSERT(capa.max_num.u64 >= capa.max_num_obj);
+ if (capa.max_obj_size < 8)
+ CU_ASSERT(capa.max_num.u64 == 0);
+ if (capa.max_obj_size >= 16)
+ CU_ASSERT(capa.max_num.u128 >= capa.max_num_obj);
+ if (capa.max_obj_size < 16)
+ CU_ASSERT(capa.max_num.u128 == 0);
+
memset(&capa, 0, sizeof(odp_stash_capability_t));
- ret = odp_stash_capability(&capa, ODP_STASH_TYPE_FIFO);
- CU_ASSERT(ret == 0);
+ CU_ASSERT_FATAL(odp_stash_capability(&capa, ODP_STASH_TYPE_FIFO) == 0);
CU_ASSERT(capa.max_stashes_any_type > 0);
- if (ret == 0 && capa.max_stashes) {
- CU_ASSERT(capa.max_num_obj > 0);
- CU_ASSERT(capa.max_obj_size >= sizeof(uint32_t));
- CU_ASSERT(capa.max_get_batch >= 1);
- CU_ASSERT(capa.max_put_batch >= 1);
- }
+
+ if (capa.max_stashes == 0)
+ return;
+
+ CU_ASSERT(capa.max_num_obj > 0);
+ CU_ASSERT(capa.max_obj_size >= sizeof(uint32_t));
+ CU_ASSERT(capa.max_get_batch >= 1);
+ CU_ASSERT(capa.max_put_batch >= 1);
+
+ CU_ASSERT(capa.max_num.u8 >= capa.max_num_obj);
+ CU_ASSERT(capa.max_num.u16 >= capa.max_num_obj);
+ CU_ASSERT(capa.max_num.u32 >= capa.max_num_obj);
+ CU_ASSERT(capa.max_num.max_obj_size >= capa.max_num_obj);
+ if (capa.max_obj_size >= 8)
+ CU_ASSERT(capa.max_num.u64 >= capa.max_num_obj);
+ if (capa.max_obj_size < 8)
+ CU_ASSERT(capa.max_num.u64 == 0);
+ if (capa.max_obj_size >= 16)
+ CU_ASSERT(capa.max_num.u128 >= capa.max_num_obj);
+ if (capa.max_obj_size < 16)
+ CU_ASSERT(capa.max_num.u128 == 0);
}
static void param_defaults(uint8_t fill)
@@ -147,6 +175,7 @@ static void param_defaults(uint8_t fill)
CU_ASSERT(param.stats.all == 0);
CU_ASSERT(param.stats.bit.count == 0);
CU_ASSERT(param.stats.bit.cache_count == 0);
+ CU_ASSERT(param.strict_size == 0);
}
static void stash_param_defaults(void)
@@ -449,12 +478,13 @@ static void stash_stats_u32(void)
CU_ASSERT_FATAL(odp_stash_destroy(stash) == 0);
}
-static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int batch)
+static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int batch,
+ odp_bool_t strict_size)
{
odp_stash_t stash;
odp_stash_param_t param;
int32_t i, ret, retry, num_left;
- int32_t num, max_burst;
+ int32_t num, max_burst, num_stashed;
void *input, *output;
if (batch) {
@@ -505,6 +535,7 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b
param.num_obj = num;
param.obj_size = size;
param.cache_size = global.cache_size_default;
+ param.strict_size = strict_size;
stash = odp_stash_create("test_stash_default", &param);
@@ -516,6 +547,12 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b
retry = MAX_RETRY;
num_left = num;
max_burst = burst;
+ num_stashed = 0;
+
+ /* Try to store extra objects if strict mode is not enabled */
+ if (!strict_size)
+ num_left += burst;
+
while (num_left > 0) {
if (op == STASH_GEN) {
if (batch)
@@ -542,6 +579,9 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b
}
CU_ASSERT_FATAL(ret >= 0);
CU_ASSERT_FATAL(ret <= burst);
+
+ num_stashed += ret;
+
if (batch) {
CU_ASSERT(ret == 0 || ret == burst);
if (num_left - ret < burst)
@@ -552,6 +592,9 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b
num_left -= ret;
retry = MAX_RETRY;
} else {
+ /* Stash full */
+ if (num_stashed >= num)
+ break;
retry--;
CU_ASSERT_FATAL(retry > 0);
}
@@ -559,7 +602,7 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b
burst = max_burst;
retry = MAX_RETRY;
- num_left = num;
+ num_left = num_stashed;
while (num_left > 0) {
memset(output, 0, burst * size);
@@ -652,12 +695,13 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b
CU_ASSERT_FATAL(odp_stash_destroy(stash) == 0);
}
-static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batch)
+static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batch,
+ odp_bool_t strict_size)
{
odp_stash_t stash;
odp_stash_param_t param;
int32_t i, ret, retry, num_left;
- int32_t num, max_burst;
+ int32_t num, max_burst, num_stashed;
void *input, *output;
if (batch) {
@@ -701,6 +745,7 @@ static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batc
param.type = ODP_STASH_TYPE_FIFO;
param.num_obj = num;
param.obj_size = size;
+ param.strict_size = strict_size;
stash = odp_stash_create("test_stash_fifo", &param);
@@ -712,6 +757,12 @@ static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batc
retry = MAX_RETRY;
num_left = num;
max_burst = burst;
+ num_stashed = 0;
+
+ /* Try to store extra objects if strict mode is not enabled */
+ if (!strict_size)
+ num_left += burst;
+
while (num_left > 0) {
for (i = 0; i < burst; i++) {
if (size == sizeof(uint64_t))
@@ -750,6 +801,8 @@ static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batc
CU_ASSERT_FATAL(ret >= 0);
CU_ASSERT_FATAL(ret <= burst);
+ num_stashed += ret;
+
if (batch) {
CU_ASSERT(ret == 0 || ret == burst);
if (num_left - ret < burst)
@@ -760,6 +813,9 @@ static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batc
num_left -= ret;
retry = MAX_RETRY;
} else {
+ /* Stash full */
+ if (num_stashed >= num)
+ break;
retry--;
CU_ASSERT_FATAL(retry > 0);
}
@@ -767,7 +823,7 @@ static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batc
burst = max_burst;
retry = MAX_RETRY;
- num_left = num;
+ num_left = num_stashed;
while (num_left > 0) {
memset(output, 0, burst * size);
@@ -912,282 +968,338 @@ static int check_support_fifo(void)
static void stash_default_put_u64_1(void)
{
- stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 0);
+ stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 0, false);
+ stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 0, true);
}
static void stash_default_put_u64_n(void)
{
- stash_default_put(sizeof(uint64_t), BURST, STASH_GEN, 0);
+ stash_default_put(sizeof(uint64_t), BURST, STASH_GEN, 0, false);
+ stash_default_put(sizeof(uint64_t), BURST, STASH_GEN, 0, true);
}
static void stash_default_u64_put_u64_1(void)
{
- stash_default_put(sizeof(uint64_t), 1, STASH_U64, 0);
+ stash_default_put(sizeof(uint64_t), 1, STASH_U64, 0, false);
+ stash_default_put(sizeof(uint64_t), 1, STASH_U64, 0, true);
}
static void stash_default_u64_put_u64_n(void)
{
- stash_default_put(sizeof(uint64_t), BURST, STASH_U64, 0);
+ stash_default_put(sizeof(uint64_t), BURST, STASH_U64, 0, false);
+ stash_default_put(sizeof(uint64_t), BURST, STASH_U64, 0, true);
}
static void stash_default_put_ptr_1(void)
{
- stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 0);
+ stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 0, false);
+ stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 0, true);
}
static void stash_default_put_ptr_n(void)
{
- stash_default_put(sizeof(uintptr_t), BURST, STASH_PTR, 0);
+ stash_default_put(sizeof(uintptr_t), BURST, STASH_PTR, 0, false);
+ stash_default_put(sizeof(uintptr_t), BURST, STASH_PTR, 0, true);
}
static void stash_default_put_u64_1_batch(void)
{
- stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 1);
+ stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 1, false);
+ stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 1, true);
}
static void stash_default_put_u64_n_batch(void)
{
- stash_default_put(sizeof(uint64_t), BATCH, STASH_GEN, 1);
+ stash_default_put(sizeof(uint64_t), BATCH, STASH_GEN, 1, false);
+ stash_default_put(sizeof(uint64_t), BATCH, STASH_GEN, 1, true);
}
static void stash_default_u64_put_u64_1_batch(void)
{
- stash_default_put(sizeof(uint64_t), 1, STASH_U64, 1);
+ stash_default_put(sizeof(uint64_t), 1, STASH_U64, 1, false);
+ stash_default_put(sizeof(uint64_t), 1, STASH_U64, 1, true);
}
static void stash_default_u64_put_u64_n_batch(void)
{
- stash_default_put(sizeof(uint64_t), BATCH, STASH_U64, 1);
+ stash_default_put(sizeof(uint64_t), BATCH, STASH_U64, 1, false);
+ stash_default_put(sizeof(uint64_t), BATCH, STASH_U64, 1, true);
}
static void stash_default_put_ptr_1_batch(void)
{
- stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 1);
+ stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 1, false);
+ stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 1, true);
}
static void stash_default_put_ptr_n_batch(void)
{
- stash_default_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1);
+ stash_default_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1, false);
+ stash_default_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1, true);
}
static void stash_default_put_u32_1(void)
{
- stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 0);
+ stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 0, false);
+ stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 0, true);
}
static void stash_default_put_u32_n(void)
{
- stash_default_put(sizeof(uint32_t), BURST, STASH_GEN, 0);
+ stash_default_put(sizeof(uint32_t), BURST, STASH_GEN, 0, false);
+ stash_default_put(sizeof(uint32_t), BURST, STASH_GEN, 0, true);
}
static void stash_default_u32_put_u32_1(void)
{
- stash_default_put(sizeof(uint32_t), 1, STASH_U32, 0);
+ stash_default_put(sizeof(uint32_t), 1, STASH_U32, 0, false);
+ stash_default_put(sizeof(uint32_t), 1, STASH_U32, 0, true);
}
static void stash_default_u32_put_u32_n(void)
{
- stash_default_put(sizeof(uint32_t), BURST, STASH_U32, 0);
+ stash_default_put(sizeof(uint32_t), BURST, STASH_U32, 0, false);
+ stash_default_put(sizeof(uint32_t), BURST, STASH_U32, 0, true);
}
static void stash_default_put_u16_1(void)
{
- stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 0);
+ stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 0, false);
+ stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 0, true);
}
static void stash_default_put_u16_n(void)
{
- stash_default_put(sizeof(uint16_t), BURST, STASH_GEN, 0);
+ stash_default_put(sizeof(uint16_t), BURST, STASH_GEN, 0, false);
+ stash_default_put(sizeof(uint16_t), BURST, STASH_GEN, 0, true);
}
static void stash_default_put_u8_1(void)
{
- stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 0);
+ stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 0, false);
+ stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 0, true);
}
static void stash_default_put_u8_n(void)
{
- stash_default_put(sizeof(uint8_t), BURST, STASH_GEN, 0);
+ stash_default_put(sizeof(uint8_t), BURST, STASH_GEN, 0, false);
+ stash_default_put(sizeof(uint8_t), BURST, STASH_GEN, 0, true);
}
static void stash_default_put_u32_1_batch(void)
{
- stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 1);
+ stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 1, false);
+ stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 1, true);
}
static void stash_default_put_u32_n_batch(void)
{
- stash_default_put(sizeof(uint32_t), BATCH, STASH_GEN, 1);
+ stash_default_put(sizeof(uint32_t), BATCH, STASH_GEN, 1, false);
+ stash_default_put(sizeof(uint32_t), BATCH, STASH_GEN, 1, true);
}
static void stash_default_u32_put_u32_1_batch(void)
{
- stash_default_put(sizeof(uint32_t), 1, STASH_U32, 1);
+ stash_default_put(sizeof(uint32_t), 1, STASH_U32, 1, false);
+ stash_default_put(sizeof(uint32_t), 1, STASH_U32, 1, true);
}
static void stash_default_u32_put_u32_n_batch(void)
{
- stash_default_put(sizeof(uint32_t), BATCH, STASH_U32, 1);
+ stash_default_put(sizeof(uint32_t), BATCH, STASH_U32, 1, false);
+ stash_default_put(sizeof(uint32_t), BATCH, STASH_U32, 1, true);
}
static void stash_default_put_u16_1_batch(void)
{
- stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 1);
+ stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 1, false);
+ stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 1, true);
}
static void stash_default_put_u16_n_batch(void)
{
- stash_default_put(sizeof(uint16_t), BATCH, STASH_GEN, 1);
+ stash_default_put(sizeof(uint16_t), BATCH, STASH_GEN, 1, false);
+ stash_default_put(sizeof(uint16_t), BATCH, STASH_GEN, 1, true);
}
static void stash_default_put_u8_1_batch(void)
{
- stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 1);
+ stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 1, false);
+ stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 1, true);
}
static void stash_default_put_u8_n_batch(void)
{
- stash_default_put(sizeof(uint8_t), BATCH, STASH_GEN, 1);
+ stash_default_put(sizeof(uint8_t), BATCH, STASH_GEN, 1, false);
+ stash_default_put(sizeof(uint8_t), BATCH, STASH_GEN, 1, true);
}
static void stash_fifo_put_u64_1(void)
{
- stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 0);
+ stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 0, false);
+ stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 0, true);
}
static void stash_fifo_put_u64_n(void)
{
- stash_fifo_put(sizeof(uint64_t), BURST, STASH_GEN, 0);
+ stash_fifo_put(sizeof(uint64_t), BURST, STASH_GEN, 0, false);
+ stash_fifo_put(sizeof(uint64_t), BURST, STASH_GEN, 0, true);
}
static void stash_fifo_u64_put_u64_1(void)
{
- stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 0);
+ stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 0, false);
+ stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 0, true);
}
static void stash_fifo_u64_put_u64_n(void)
{
- stash_fifo_put(sizeof(uint64_t), BURST, STASH_U64, 0);
+ stash_fifo_put(sizeof(uint64_t), BURST, STASH_U64, 0, false);
+ stash_fifo_put(sizeof(uint64_t), BURST, STASH_U64, 0, true);
}
static void stash_fifo_put_ptr_1(void)
{
- stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 0);
+ stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 0, false);
+ stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 0, true);
}
static void stash_fifo_put_ptr_n(void)
{
- stash_fifo_put(sizeof(uintptr_t), BURST, STASH_PTR, 0);
+ stash_fifo_put(sizeof(uintptr_t), BURST, STASH_PTR, 0, false);
+ stash_fifo_put(sizeof(uintptr_t), BURST, STASH_PTR, 0, true);
}
static void stash_fifo_put_u32_1(void)
{
- stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 0);
+ stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 0, false);
+ stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 0, true);
}
static void stash_fifo_put_u32_n(void)
{
- stash_fifo_put(sizeof(uint32_t), BURST, STASH_GEN, 0);
+ stash_fifo_put(sizeof(uint32_t), BURST, STASH_GEN, 0, false);
+ stash_fifo_put(sizeof(uint32_t), BURST, STASH_GEN, 0, true);
}
static void stash_fifo_u32_put_u32_1(void)
{
- stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 0);
+ stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 0, false);
+ stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 0, true);
}
static void stash_fifo_u32_put_u32_n(void)
{
- stash_fifo_put(sizeof(uint32_t), BURST, STASH_U32, 0);
+ stash_fifo_put(sizeof(uint32_t), BURST, STASH_U32, 0, false);
+ stash_fifo_put(sizeof(uint32_t), BURST, STASH_U32, 0, true);
}
static void stash_fifo_put_u16_1(void)
{
- stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 0);
+ stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 0, false);
+ stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 0, true);
}
static void stash_fifo_put_u16_n(void)
{
- stash_fifo_put(sizeof(uint16_t), BURST, STASH_GEN, 0);
+ stash_fifo_put(sizeof(uint16_t), BURST, STASH_GEN, 0, false);
+ stash_fifo_put(sizeof(uint16_t), BURST, STASH_GEN, 0, true);
}
static void stash_fifo_put_u8_1(void)
{
- stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 0);
+ stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 0, false);
+ stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 0, true);
}
static void stash_fifo_put_u8_n(void)
{
- stash_fifo_put(sizeof(uint8_t), BURST, STASH_GEN, 0);
+ stash_fifo_put(sizeof(uint8_t), BURST, STASH_GEN, 0, false);
+ stash_fifo_put(sizeof(uint8_t), BURST, STASH_GEN, 0, true);
}
static void stash_fifo_put_u64_1_batch(void)
{
- stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 1);
+ stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 1, false);
+ stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 1, true);
}
static void stash_fifo_put_u64_n_batch(void)
{
- stash_fifo_put(sizeof(uint64_t), BATCH, STASH_GEN, 1);
+ stash_fifo_put(sizeof(uint64_t), BATCH, STASH_GEN, 1, false);
+ stash_fifo_put(sizeof(uint64_t), BATCH, STASH_GEN, 1, true);
}
static void stash_fifo_u64_put_u64_1_batch(void)
{
- stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 1);
+ stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 1, false);
+ stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 1, true);
}
static void stash_fifo_u64_put_u64_n_batch(void)
{
- stash_fifo_put(sizeof(uint64_t), BATCH, STASH_U64, 1);
+ stash_fifo_put(sizeof(uint64_t), BATCH, STASH_U64, 1, false);
+ stash_fifo_put(sizeof(uint64_t), BATCH, STASH_U64, 1, true);
}
static void stash_fifo_put_ptr_1_batch(void)
{
- stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 1);
+ stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 1, false);
+ stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 1, true);
}
static void stash_fifo_put_ptr_n_batch(void)
{
- stash_fifo_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1);
+ stash_fifo_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1, false);
+ stash_fifo_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1, true);
}
static void stash_fifo_put_u32_1_batch(void)
{
- stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 1);
+ stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 1, false);
+ stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 1, true);
}
static void stash_fifo_put_u32_n_batch(void)
{
- stash_fifo_put(sizeof(uint32_t), BATCH, STASH_GEN, 1);
+ stash_fifo_put(sizeof(uint32_t), BATCH, STASH_GEN, 1, false);
+ stash_fifo_put(sizeof(uint32_t), BATCH, STASH_GEN, 1, true);
}
static void stash_fifo_u32_put_u32_1_batch(void)
{
- stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 1);
+ stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 1, false);
+ stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 1, true);
}
static void stash_fifo_u32_put_u32_n_batch(void)
{
- stash_fifo_put(sizeof(uint32_t), BATCH, STASH_U32, 1);
+ stash_fifo_put(sizeof(uint32_t), BATCH, STASH_U32, 1, false);
+ stash_fifo_put(sizeof(uint32_t), BATCH, STASH_U32, 1, true);
}
static void stash_fifo_put_u16_1_batch(void)
{
- stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 1);
+ stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 1, false);
+ stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 1, true);
}
static void stash_fifo_put_u16_n_batch(void)
{
- stash_fifo_put(sizeof(uint16_t), BATCH, STASH_GEN, 1);
+ stash_fifo_put(sizeof(uint16_t), BATCH, STASH_GEN, 1, false);
+ stash_fifo_put(sizeof(uint16_t), BATCH, STASH_GEN, 1, true);
}
static void stash_fifo_put_u8_1_batch(void)
{
- stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 1);
+ stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 1, false);
+ stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 1, true);
}
static void stash_fifo_put_u8_n_batch(void)
{
- stash_fifo_put(sizeof(uint8_t), BATCH, STASH_GEN, 1);
+ stash_fifo_put(sizeof(uint8_t), BATCH, STASH_GEN, 1, false);
+ stash_fifo_put(sizeof(uint8_t), BATCH, STASH_GEN, 1, true);
}
odp_testinfo_t stash_suite[] = {
diff --git a/test/validation/api/timer/timer.c b/test/validation/api/timer/timer.c
index 0e3919b73..eb7f0772a 100644
--- a/test/validation/api/timer/timer.c
+++ b/test/validation/api/timer/timer.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2015-2018, Linaro Limited
- * Copyright (c) 2019-2022, Nokia
+ * Copyright (c) 2019-2023, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -244,6 +244,14 @@ check_plain_queue_support(void)
return ODP_TEST_INACTIVE;
}
+static int check_periodic_support(void)
+{
+ if (global_mem->periodic)
+ return ODP_TEST_ACTIVE;
+
+ return ODP_TEST_INACTIVE;
+}
+
static int check_periodic_sched_support(void)
{
if (global_mem->periodic && global_mem->param.queue_type_sched)
@@ -2377,6 +2385,139 @@ static void timer_test_sched_all(void)
timer_test_all(ODP_QUEUE_TYPE_SCHED);
}
+static void timer_test_periodic_capa(void)
+{
+ odp_timer_capability_t timer_capa;
+ odp_timer_periodic_capability_t capa;
+ odp_fract_u64_t min_fract, max_fract, base_freq;
+ uint64_t freq_range, freq_step, first_hz, res_ns, max_multiplier;
+ double freq, min_freq, max_freq;
+ int ret;
+ uint32_t i, j;
+ uint32_t num = 100;
+
+ memset(&timer_capa, 0, sizeof(odp_timer_capability_t));
+ CU_ASSERT_FATAL(odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa) == 0);
+ CU_ASSERT(timer_capa.periodic.max_pools);
+ CU_ASSERT(timer_capa.periodic.max_timers);
+
+ min_fract = timer_capa.periodic.min_base_freq_hz;
+ max_fract = timer_capa.periodic.max_base_freq_hz;
+
+ CU_ASSERT_FATAL(min_fract.integer || min_fract.numer);
+ CU_ASSERT_FATAL(max_fract.integer || max_fract.numer);
+
+ if (min_fract.numer)
+ CU_ASSERT_FATAL(min_fract.denom);
+
+ if (max_fract.numer)
+ CU_ASSERT_FATAL(max_fract.denom);
+
+ min_freq = odp_fract_u64_to_dbl(&min_fract);
+ max_freq = odp_fract_u64_to_dbl(&max_fract);
+ CU_ASSERT(min_freq <= max_freq);
+
+ memset(&capa, 0, sizeof(odp_timer_periodic_capability_t));
+
+ /* Min freq, capa fills in resolution */
+ capa.base_freq_hz = min_fract;
+ capa.max_multiplier = 1;
+ capa.res_ns = 0;
+
+ CU_ASSERT(odp_timer_periodic_capability(ODP_CLOCK_DEFAULT, &capa) == 1);
+ CU_ASSERT(capa.base_freq_hz.integer == min_fract.integer);
+ CU_ASSERT(capa.base_freq_hz.numer == min_fract.numer);
+ CU_ASSERT(capa.base_freq_hz.denom == min_fract.denom);
+ CU_ASSERT(capa.max_multiplier >= 1);
+ CU_ASSERT(capa.res_ns > 0);
+
+ /* Max freq, capa fills in resolution */
+ capa.base_freq_hz = max_fract;
+ capa.max_multiplier = 1;
+ capa.res_ns = 0;
+
+ CU_ASSERT(odp_timer_periodic_capability(ODP_CLOCK_DEFAULT, &capa) == 1);
+ CU_ASSERT(capa.base_freq_hz.integer == max_fract.integer);
+ CU_ASSERT(capa.base_freq_hz.numer == max_fract.numer);
+ CU_ASSERT(capa.base_freq_hz.denom == max_fract.denom);
+ CU_ASSERT(capa.max_multiplier >= 1);
+ CU_ASSERT(capa.res_ns > 0);
+
+ freq_range = max_fract.integer - min_fract.integer;
+
+ if (freq_range < 10 * num)
+ num = freq_range / 10;
+
+ /* Too short frequency range */
+ if (num == 0)
+ return;
+
+ freq_step = freq_range / num;
+ first_hz = min_fract.integer + 1;
+
+ ODPH_DBG("min %" PRIu64 ", max %" PRIu64 ", range %" PRIu64 ", step %" PRIu64 "\n",
+ min_fract.integer, max_fract.integer, freq_range, freq_step);
+
+ for (i = 0; i < num; i++) {
+ base_freq.integer = first_hz + i * freq_step;
+ base_freq.numer = 0;
+ base_freq.denom = 0;
+
+ freq = odp_fract_u64_to_dbl(&base_freq);
+
+ if (freq > max_freq)
+ base_freq = max_fract;
+
+ for (j = 0; j < 4; j++) {
+ capa.base_freq_hz = base_freq;
+
+ max_multiplier = 1;
+ res_ns = 0;
+
+ if (j & 0x1)
+ max_multiplier = 2;
+
+ if (j & 0x2)
+ res_ns = 1 + (ODP_TIME_SEC_IN_NS / (10 * base_freq.integer));
+
+ capa.max_multiplier = max_multiplier;
+ capa.res_ns = res_ns;
+
+ ODPH_DBG("freq %" PRIu64 ", multip %" PRIu64 ", res %" PRIu64 ",\n",
+ base_freq.integer, max_multiplier, res_ns);
+
+ ret = odp_timer_periodic_capability(ODP_CLOCK_DEFAULT, &capa);
+
+ if (ret == 1) {
+ CU_ASSERT(capa.base_freq_hz.integer == base_freq.integer);
+ CU_ASSERT(capa.base_freq_hz.numer == base_freq.numer);
+ CU_ASSERT(capa.base_freq_hz.denom == base_freq.denom);
+ } else if (ret == 0) {
+ CU_ASSERT(capa.base_freq_hz.integer != base_freq.integer ||
+ capa.base_freq_hz.numer != base_freq.numer ||
+ capa.base_freq_hz.denom != base_freq.denom)
+
+ if (capa.base_freq_hz.numer)
+ CU_ASSERT_FATAL(capa.base_freq_hz.denom);
+
+ CU_ASSERT(odp_fract_u64_to_dbl(&capa.base_freq_hz) >= min_freq);
+ CU_ASSERT(odp_fract_u64_to_dbl(&capa.base_freq_hz) <= max_freq);
+ }
+
+ if (ret >= 0) {
+ CU_ASSERT(capa.max_multiplier >= max_multiplier);
+
+ if (res_ns) {
+ /* Same or better resolution */
+ CU_ASSERT(capa.res_ns <= res_ns);
+ } else {
+ CU_ASSERT(capa.res_ns > 0);
+ }
+ }
+ }
+ }
+}
+
static void timer_test_periodic(odp_queue_type_t queue_type, int use_first)
{
odp_timer_capability_t timer_capa;
@@ -2392,7 +2533,7 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first)
odp_event_t ev;
odp_timer_t timer;
odp_time_t t1, t2;
- uint64_t tick, cur_tick, period_ns, duration_ns, diff_ns;
+ uint64_t tick, cur_tick, period_ns, duration_ns, diff_ns, offset_ns;
double freq, freq_out, min_freq, max_freq;
int ret;
const char *user_ctx = "User context";
@@ -2509,10 +2650,14 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first)
memset(&start_param, 0, sizeof(odp_timer_periodic_start_t));
cur_tick = odp_timer_current_tick(timer_pool);
- tick = cur_tick + odp_timer_ns_to_tick(timer_pool, period_ns / 2);
+ offset_ns = period_ns / 2;
+ tick = cur_tick + odp_timer_ns_to_tick(timer_pool, offset_ns);
- if (use_first)
+ if (use_first) {
+ /* First tick moves timer to start before the first period */
+ duration_ns -= (period_ns - offset_ns);
start_param.first_tick = tick;
+ }
start_param.freq_multiplier = multiplier;
start_param.tmo_ev = ev;
@@ -2521,7 +2666,8 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first)
ODPH_DBG(" Current tick: %" PRIu64 "\n", cur_tick);
ODPH_DBG(" First tick: %" PRIu64 "\n", start_param.first_tick);
ODPH_DBG(" Multiplier: %" PRIu64 "\n", start_param.freq_multiplier);
- ODPH_DBG("Test duration ns: %" PRIu64 "\n", duration_ns);
+ ODPH_DBG(" Period: %" PRIu64 " nsec\n", period_ns);
+ ODPH_DBG("Expected duration: %" PRIu64 " nsec\n", duration_ns);
ret = odp_timer_periodic_start(timer, &start_param);
@@ -2576,6 +2722,8 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first)
ret = odp_timer_periodic_cancel(timer);
CU_ASSERT_FATAL(ret == 0);
+ ODPH_DBG("Measured duration: %" PRIu64 " nsec\n", diff_ns);
+
t1 = odp_time_local();
while (1) {
if (queue_type == ODP_QUEUE_TYPE_SCHED)
@@ -2714,6 +2862,8 @@ odp_testinfo_t timer_suite[] = {
check_plain_queue_support),
ODP_TEST_INFO_CONDITIONAL(timer_test_sched_all,
check_sched_queue_support),
+ ODP_TEST_INFO_CONDITIONAL(timer_test_periodic_capa,
+ check_periodic_support),
ODP_TEST_INFO_CONDITIONAL(timer_test_periodic_sched,
check_periodic_sched_support),
ODP_TEST_INFO_CONDITIONAL(timer_test_periodic_sched_first,