dpdk/drivers/event/dpaa2/dpaa2_eventdev_selftest.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright 2018-2019 NXP
   3 */
   4
   5#include <rte_atomic.h>
   6#include <rte_common.h>
   7#include <rte_cycles.h>
   8#include <rte_debug.h>
   9#include <rte_eal.h>
  10#include <rte_ethdev.h>
  11#include <rte_eventdev.h>
  12#include <rte_hexdump.h>
  13#include <rte_mbuf.h>
  14#include <rte_malloc.h>
  15#include <rte_memcpy.h>
  16#include <rte_launch.h>
  17#include <rte_lcore.h>
  18#include <rte_per_lcore.h>
  19#include <rte_random.h>
  20#include <rte_bus_vdev.h>
  21#include <rte_test.h>
  22#include <rte_fslmc.h>
  23
  24#include "dpaa2_eventdev.h"
  25#include "dpaa2_eventdev_logs.h"
  26
  27#define MAX_PORTS 4
  28#define NUM_PACKETS (1 << 18)
  29#define MAX_EVENTS  8
  30#define DPAA2_TEST_RUN(setup, teardown, test) \
  31        dpaa2_test_run(setup, teardown, test, #test)
  32
  33static int total;
  34static int passed;
  35static int failed;
  36static int unsupported;
  37
  38static int evdev;
  39static struct rte_mempool *eventdev_test_mempool;
  40
  41struct event_attr {
  42        uint32_t flow_id;
  43        uint8_t event_type;
  44        uint8_t sub_event_type;
  45        uint8_t sched_type;
  46        uint8_t queue;
  47        uint8_t port;
  48        uint8_t seq;
  49};
  50
  51struct test_core_param {
  52        rte_atomic32_t *total_events;
  53        uint64_t dequeue_tmo_ticks;
  54        uint8_t port;
  55        uint8_t sched_type;
  56};
  57
  58static int
  59testsuite_setup(void)
  60{
  61        const char *eventdev_name = "event_dpaa2";
  62
  63        evdev = rte_event_dev_get_dev_id(eventdev_name);
  64        if (evdev < 0) {
  65                dpaa2_evdev_dbg("%d: Eventdev %s not found - creating.",
  66                                __LINE__, eventdev_name);
  67                if (rte_vdev_init(eventdev_name, NULL) < 0) {
  68                        dpaa2_evdev_err("Error creating eventdev %s",
  69                                        eventdev_name);
  70                        return -1;
  71                }
  72                evdev = rte_event_dev_get_dev_id(eventdev_name);
  73                if (evdev < 0) {
  74                        dpaa2_evdev_err("Error finding newly created eventdev");
  75                        return -1;
  76                }
  77        }
  78
  79        return 0;
  80}
  81
  82static void
  83testsuite_teardown(void)
  84{
  85        rte_event_dev_close(evdev);
  86}
  87
  88static void
  89devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf,
  90                        struct rte_event_dev_info *info)
  91{
  92        memset(dev_conf, 0, sizeof(struct rte_event_dev_config));
  93        dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns;
  94        dev_conf->nb_event_ports = info->max_event_ports;
  95        dev_conf->nb_event_queues = info->max_event_queues;
  96        dev_conf->nb_event_queue_flows = info->max_event_queue_flows;
  97        dev_conf->nb_event_port_dequeue_depth =
  98                        info->max_event_port_dequeue_depth;
  99        dev_conf->nb_event_port_enqueue_depth =
 100                        info->max_event_port_enqueue_depth;
 101        dev_conf->nb_event_port_enqueue_depth =
 102                        info->max_event_port_enqueue_depth;
 103        dev_conf->nb_events_limit =
 104                        info->max_num_events;
 105}
 106
 107enum {
 108        TEST_EVENTDEV_SETUP_DEFAULT,
 109        TEST_EVENTDEV_SETUP_PRIORITY,
 110        TEST_EVENTDEV_SETUP_DEQUEUE_TIMEOUT,
 111};
 112
 113static int
 114_eventdev_setup(int mode)
 115{
 116        int i, ret;
 117        struct rte_event_dev_config dev_conf;
 118        struct rte_event_dev_info info;
 119        const char *pool_name = "evdev_dpaa2_test_pool";
 120
 121        /* Create and destrory pool for each test case to make it standalone */
 122        eventdev_test_mempool = rte_pktmbuf_pool_create(pool_name,
 123                                        MAX_EVENTS,
 124                                        0 /*MBUF_CACHE_SIZE*/,
 125                                        0,
 126                                        512, /* Use very small mbufs */
 127                                        rte_socket_id());
 128        if (!eventdev_test_mempool) {
 129                dpaa2_evdev_err("ERROR creating mempool");
 130                return -1;
 131        }
 132
 133        ret = rte_event_dev_info_get(evdev, &info);
 134        RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info");
 135        RTE_TEST_ASSERT(info.max_num_events >= (int32_t)MAX_EVENTS,
 136                        "ERROR max_num_events=%d < max_events=%d",
 137                                info.max_num_events, MAX_EVENTS);
 138
 139        devconf_set_default_sane_values(&dev_conf, &info);
 140        if (mode == TEST_EVENTDEV_SETUP_DEQUEUE_TIMEOUT)
 141                dev_conf.event_dev_cfg |= RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT;
 142
 143        ret = rte_event_dev_configure(evdev, &dev_conf);
 144        RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev");
 145
 146        uint32_t queue_count;
 147        RTE_TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(evdev,
 148                            RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
 149                            &queue_count), "Queue count get failed");
 150
 151        if (mode == TEST_EVENTDEV_SETUP_PRIORITY) {
 152                if (queue_count > 8) {
 153                        dpaa2_evdev_err(
 154                                "test expects the unique priority per queue");
 155                        return -ENOTSUP;
 156                }
 157
 158                /* Configure event queues(0 to n) with
 159                 * RTE_EVENT_DEV_PRIORITY_HIGHEST to
 160                 * RTE_EVENT_DEV_PRIORITY_LOWEST
 161                 */
 162                uint8_t step = (RTE_EVENT_DEV_PRIORITY_LOWEST + 1) /
 163                                queue_count;
 164                for (i = 0; i < (int)queue_count; i++) {
 165                        struct rte_event_queue_conf queue_conf;
 166
 167                        ret = rte_event_queue_default_conf_get(evdev, i,
 168                                                &queue_conf);
 169                        RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get def_conf%d",
 170                                        i);
 171                        queue_conf.priority = i * step;
 172                        ret = rte_event_queue_setup(evdev, i, &queue_conf);
 173                        RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup queue=%d",
 174                                        i);
 175                }
 176
 177        } else {
 178                /* Configure event queues with default priority */
 179                for (i = 0; i < (int)queue_count; i++) {
 180                        ret = rte_event_queue_setup(evdev, i, NULL);
 181                        RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup queue=%d",
 182                                        i);
 183                }
 184        }
 185        /* Configure event ports */
 186        uint32_t port_count;
 187        RTE_TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(evdev,
 188                                RTE_EVENT_DEV_ATTR_PORT_COUNT,
 189                                &port_count), "Port count get failed");
 190        for (i = 0; i < (int)port_count; i++) {
 191                ret = rte_event_port_setup(evdev, i, NULL);
 192                RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup port=%d", i);
 193                ret = rte_event_port_link(evdev, i, NULL, NULL, 0);
 194                RTE_TEST_ASSERT(ret >= 0, "Failed to link all queues port=%d",
 195                                i);
 196        }
 197
 198        ret = rte_event_dev_start(evdev);
 199        RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start device");
 200
 201        return 0;
 202}
 203
 204static int
 205eventdev_setup(void)
 206{
 207        return _eventdev_setup(TEST_EVENTDEV_SETUP_DEFAULT);
 208}
 209
 210static void
 211eventdev_teardown(void)
 212{
 213        rte_event_dev_stop(evdev);
 214        rte_mempool_free(eventdev_test_mempool);
 215}
 216
 217static void
 218update_event_and_validation_attr(struct rte_mbuf *m, struct rte_event *ev,
 219                        uint32_t flow_id, uint8_t event_type,
 220                        uint8_t sub_event_type, uint8_t sched_type,
 221                        uint8_t queue, uint8_t port, uint8_t seq)
 222{
 223        struct event_attr *attr;
 224
 225        /* Store the event attributes in mbuf for future reference */
 226        attr = rte_pktmbuf_mtod(m, struct event_attr *);
 227        attr->flow_id = flow_id;
 228        attr->event_type = event_type;
 229        attr->sub_event_type = sub_event_type;
 230        attr->sched_type = sched_type;
 231        attr->queue = queue;
 232        attr->port = port;
 233        attr->seq = seq;
 234
 235        ev->flow_id = flow_id;
 236        ev->sub_event_type = sub_event_type;
 237        ev->event_type = event_type;
 238        /* Inject the new event */
 239        ev->op = RTE_EVENT_OP_NEW;
 240        ev->sched_type = sched_type;
 241        ev->queue_id = queue;
 242        ev->mbuf = m;
 243}
 244
 245static int
 246inject_events(uint32_t flow_id, uint8_t event_type, uint8_t sub_event_type,
 247                uint8_t sched_type, uint8_t queue, uint8_t port,
 248                unsigned int events)
 249{
 250        struct rte_mbuf *m;
 251        unsigned int i;
 252
 253        for (i = 0; i < events; i++) {
 254                struct rte_event ev = {.event = 0, .u64 = 0};
 255
 256                m = rte_pktmbuf_alloc(eventdev_test_mempool);
 257                RTE_TEST_ASSERT_NOT_NULL(m, "mempool alloc failed");
 258
 259                update_event_and_validation_attr(m, &ev, flow_id, event_type,
 260                        sub_event_type, sched_type, queue, port, i);
 261                rte_event_enqueue_burst(evdev, port, &ev, 1);
 262        }
 263        return 0;
 264}
 265
 266static int
 267check_excess_events(uint8_t port)
 268{
 269        int i;
 270        uint16_t valid_event;
 271        struct rte_event ev;
 272
 273        /* Check for excess events, try for a few times and exit */
 274        for (i = 0; i < 32; i++) {
 275                valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
 276
 277                RTE_TEST_ASSERT_SUCCESS(valid_event,
 278                                "Unexpected valid event=%d",
 279                                *dpaa2_seqn(ev.mbuf));
 280        }
 281        return 0;
 282}
 283
 284static int
 285generate_random_events(const unsigned int total_events)
 286{
 287        struct rte_event_dev_info info;
 288        unsigned int i;
 289        int ret;
 290
 291        uint32_t queue_count;
 292        RTE_TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(evdev,
 293                            RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
 294                            &queue_count), "Queue count get failed");
 295
 296        ret = rte_event_dev_info_get(evdev, &info);
 297        RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info");
 298        for (i = 0; i < total_events; i++) {
 299                ret = inject_events(
 300                        rte_rand() % info.max_event_queue_flows /*flow_id */,
 301                        RTE_EVENT_TYPE_CPU /* event_type */,
 302                        rte_rand() % 256 /* sub_event_type */,
 303                        rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1),
 304                        rte_rand() % queue_count /* queue */,
 305                        0 /* port */,
 306                        1 /* events */);
 307                if (ret)
 308                        return -1;
 309        }
 310        return ret;
 311}
 312
 313
 314static int
 315validate_event(struct rte_event *ev)
 316{
 317        struct event_attr *attr;
 318
 319        attr = rte_pktmbuf_mtod(ev->mbuf, struct event_attr *);
 320        RTE_TEST_ASSERT_EQUAL(attr->flow_id, ev->flow_id,
 321                        "flow_id mismatch enq=%d deq =%d",
 322                        attr->flow_id, ev->flow_id);
 323        RTE_TEST_ASSERT_EQUAL(attr->event_type, ev->event_type,
 324                        "event_type mismatch enq=%d deq =%d",
 325                        attr->event_type, ev->event_type);
 326        RTE_TEST_ASSERT_EQUAL(attr->sub_event_type, ev->sub_event_type,
 327                        "sub_event_type mismatch enq=%d deq =%d",
 328                        attr->sub_event_type, ev->sub_event_type);
 329        RTE_TEST_ASSERT_EQUAL(attr->sched_type, ev->sched_type,
 330                        "sched_type mismatch enq=%d deq =%d",
 331                        attr->sched_type, ev->sched_type);
 332        RTE_TEST_ASSERT_EQUAL(attr->queue, ev->queue_id,
 333                        "queue mismatch enq=%d deq =%d",
 334                        attr->queue, ev->queue_id);
 335        return 0;
 336}
 337
 338typedef int (*validate_event_cb)(uint32_t index, uint8_t port,
 339                                 struct rte_event *ev);
 340
 341static int
 342consume_events(uint8_t port, const uint32_t total_events, validate_event_cb fn)
 343{
 344        int ret;
 345        uint16_t valid_event;
 346        uint32_t events = 0, forward_progress_cnt = 0, index = 0;
 347        struct rte_event ev;
 348
 349        while (1) {
 350                if (++forward_progress_cnt > UINT16_MAX) {
 351                        dpaa2_evdev_err("Detected deadlock");
 352                        return -1;
 353                }
 354
 355                valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
 356                if (!valid_event)
 357                        continue;
 358
 359                forward_progress_cnt = 0;
 360                ret = validate_event(&ev);
 361                if (ret)
 362                        return -1;
 363
 364                if (fn != NULL) {
 365                        ret = fn(index, port, &ev);
 366                        RTE_TEST_ASSERT_SUCCESS(ret,
 367                                "Failed to validate test specific event");
 368                }
 369
 370                ++index;
 371
 372                rte_pktmbuf_free(ev.mbuf);
 373                if (++events >= total_events)
 374                        break;
 375        }
 376
 377        return check_excess_events(port);
 378}
 379
 380static int
 381validate_simple_enqdeq(uint32_t index, uint8_t port, struct rte_event *ev)
 382{
 383        struct event_attr *attr;
 384
 385        attr = rte_pktmbuf_mtod(ev->mbuf, struct event_attr *);
 386
 387        RTE_SET_USED(port);
 388        RTE_TEST_ASSERT_EQUAL(index, attr->seq,
 389                "index=%d != seqn=%d", index, attr->seq);
 390        return 0;
 391}
 392
 393static int
 394test_simple_enqdeq(uint8_t sched_type)
 395{
 396        int ret;
 397
 398        ret = inject_events(0 /*flow_id */,
 399                                RTE_EVENT_TYPE_CPU /* event_type */,
 400                                0 /* sub_event_type */,
 401                                sched_type,
 402                                0 /* queue */,
 403                                0 /* port */,
 404                                MAX_EVENTS);
 405        if (ret)
 406                return -1;
 407
 408        return consume_events(0 /* port */, MAX_EVENTS, validate_simple_enqdeq);
 409}
 410
 411static int
 412test_simple_enqdeq_atomic(void)
 413{
 414        return test_simple_enqdeq(RTE_SCHED_TYPE_ATOMIC);
 415}
 416
 417static int
 418test_simple_enqdeq_parallel(void)
 419{
 420        return test_simple_enqdeq(RTE_SCHED_TYPE_PARALLEL);
 421}
 422
 423/*
 424 * Generate a prescribed number of events and spread them across available
 425 * queues. On dequeue, using single event port(port 0) verify the enqueued
 426 * event attributes
 427 */
 428static int
 429test_multi_queue_enq_single_port_deq(void)
 430{
 431        int ret;
 432
 433        ret = generate_random_events(MAX_EVENTS);
 434        if (ret)
 435                return -1;
 436
 437        return consume_events(0 /* port */, MAX_EVENTS, NULL);
 438}
 439
 440static int
 441worker_multi_port_fn(void *arg)
 442{
 443        struct test_core_param *param = arg;
 444        struct rte_event ev;
 445        uint16_t valid_event;
 446        uint8_t port = param->port;
 447        rte_atomic32_t *total_events = param->total_events;
 448        int ret;
 449
 450        while (rte_atomic32_read(total_events) > 0) {
 451                valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
 452                if (!valid_event)
 453                        continue;
 454
 455                ret = validate_event(&ev);
 456                RTE_TEST_ASSERT_SUCCESS(ret, "Failed to validate event");
 457                rte_pktmbuf_free(ev.mbuf);
 458                rte_atomic32_sub(total_events, 1);
 459        }
 460        return 0;
 461}
 462
 463static int
 464wait_workers_to_join(int lcore, const rte_atomic32_t *count)
 465{
 466        uint64_t cycles, print_cycles;
 467
 468        RTE_SET_USED(count);
 469
 470        print_cycles = cycles = rte_get_timer_cycles();
 471        while (rte_eal_get_lcore_state(lcore) != FINISHED) {
 472                uint64_t new_cycles = rte_get_timer_cycles();
 473
 474                if (new_cycles - print_cycles > rte_get_timer_hz()) {
 475                        dpaa2_evdev_dbg("\r%s: events %d", __func__,
 476                                rte_atomic32_read(count));
 477                        print_cycles = new_cycles;
 478                }
 479                if (new_cycles - cycles > rte_get_timer_hz() * 10) {
 480                        dpaa2_evdev_info(
 481                                "%s: No schedules for seconds, deadlock (%d)",
 482                                __func__,
 483                                rte_atomic32_read(count));
 484                        rte_event_dev_dump(evdev, stdout);
 485                        cycles = new_cycles;
 486                        return -1;
 487                }
 488        }
 489        rte_eal_mp_wait_lcore();
 490        return 0;
 491}
 492
 493
 494static int
 495launch_workers_and_wait(int (*main_worker)(void *),
 496                        int (*workers)(void *), uint32_t total_events,
 497                        uint8_t nb_workers, uint8_t sched_type)
 498{
 499        uint8_t port = 0;
 500        int w_lcore;
 501        int ret;
 502        struct test_core_param *param;
 503        rte_atomic32_t atomic_total_events;
 504        uint64_t dequeue_tmo_ticks;
 505
 506        if (!nb_workers)
 507                return 0;
 508
 509        rte_atomic32_set(&atomic_total_events, total_events);
 510        RTE_BUILD_BUG_ON(NUM_PACKETS < MAX_EVENTS);
 511
 512        param = malloc(sizeof(struct test_core_param) * nb_workers);
 513        if (!param)
 514                return -1;
 515
 516        ret = rte_event_dequeue_timeout_ticks(evdev,
 517                rte_rand() % 10000000/* 10ms */, &dequeue_tmo_ticks);
 518        if (ret) {
 519                free(param);
 520                return -1;
 521        }
 522
 523        param[0].total_events = &atomic_total_events;
 524        param[0].sched_type = sched_type;
 525        param[0].port = 0;
 526        param[0].dequeue_tmo_ticks = dequeue_tmo_ticks;
 527        rte_smp_wmb();
 528
 529        w_lcore = rte_get_next_lcore(
 530                        /* start core */ -1,
 531                        /* skip main */ 1,
 532                        /* wrap */ 0);
 533        rte_eal_remote_launch(main_worker, &param[0], w_lcore);
 534
 535        for (port = 1; port < nb_workers; port++) {
 536                param[port].total_events = &atomic_total_events;
 537                param[port].sched_type = sched_type;
 538                param[port].port = port;
 539                param[port].dequeue_tmo_ticks = dequeue_tmo_ticks;
 540                rte_smp_wmb();
 541                w_lcore = rte_get_next_lcore(w_lcore, 1, 0);
 542                rte_eal_remote_launch(workers, &param[port], w_lcore);
 543        }
 544
 545        ret = wait_workers_to_join(w_lcore, &atomic_total_events);
 546        free(param);
 547        return ret;
 548}
 549
 550/*
 551 * Generate a prescribed number of events and spread them across available
 552 * queues. Dequeue the events through multiple ports and verify the enqueued
 553 * event attributes
 554 */
 555static int
 556test_multi_queue_enq_multi_port_deq(void)
 557{
 558        const unsigned int total_events = MAX_EVENTS;
 559        uint32_t nr_ports;
 560        int ret;
 561
 562        ret = generate_random_events(total_events);
 563        if (ret)
 564                return -1;
 565
 566        RTE_TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(evdev,
 567                                RTE_EVENT_DEV_ATTR_PORT_COUNT,
 568                                &nr_ports), "Port count get failed");
 569        nr_ports = RTE_MIN(nr_ports, rte_lcore_count() - 1);
 570
 571        if (!nr_ports) {
 572                dpaa2_evdev_err("%s: Not enough ports=%d or workers=%d",
 573                                __func__, nr_ports, rte_lcore_count() - 1);
 574                return 0;
 575        }
 576
 577        return launch_workers_and_wait(worker_multi_port_fn,
 578                                        worker_multi_port_fn, total_events,
 579                                        nr_ports, 0xff /* invalid */);
 580}
 581
 582static
 583void flush(uint8_t dev_id, struct rte_event event, void *arg)
 584{
 585        unsigned int *count = arg;
 586
 587        RTE_SET_USED(dev_id);
 588        if (event.event_type == RTE_EVENT_TYPE_CPU)
 589                *count = *count + 1;
 590
 591}
 592
 593static int
 594test_dev_stop_flush(void)
 595{
 596        unsigned int total_events = MAX_EVENTS, count = 0;
 597        int ret;
 598
 599        ret = generate_random_events(total_events);
 600        if (ret)
 601                return -1;
 602
 603        ret = rte_event_dev_stop_flush_callback_register(evdev, flush, &count);
 604        if (ret)
 605                return -2;
 606        rte_event_dev_stop(evdev);
 607        ret = rte_event_dev_stop_flush_callback_register(evdev, NULL, NULL);
 608        if (ret)
 609                return -3;
 610        RTE_TEST_ASSERT_EQUAL(total_events, count,
 611                                "count mismatch total_events=%d count=%d",
 612                                total_events, count);
 613        return 0;
 614}
 615
 616static int
 617validate_queue_to_port_single_link(uint32_t index, uint8_t port,
 618                        struct rte_event *ev)
 619{
 620        RTE_SET_USED(index);
 621        RTE_TEST_ASSERT_EQUAL(port, ev->queue_id,
 622                                "queue mismatch enq=%d deq =%d",
 623                                port, ev->queue_id);
 624        return 0;
 625}
 626
 627/*
 628 * Link queue x to port x and check correctness of link by checking
 629 * queue_id == x on dequeue on the specific port x
 630 */
 631static int
 632test_queue_to_port_single_link(void)
 633{
 634        int i, nr_links, ret;
 635
 636        uint32_t port_count;
 637
 638        RTE_TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(evdev,
 639                                RTE_EVENT_DEV_ATTR_PORT_COUNT,
 640                                &port_count), "Port count get failed");
 641
 642        /* Unlink all connections that created in eventdev_setup */
 643        for (i = 0; i < (int)port_count; i++) {
 644                ret = rte_event_port_unlink(evdev, i, NULL, 0);
 645                RTE_TEST_ASSERT(ret >= 0,
 646                                "Failed to unlink all queues port=%d", i);
 647        }
 648
 649        uint32_t queue_count;
 650
 651        RTE_TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(evdev,
 652                            RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
 653                            &queue_count), "Queue count get failed");
 654
 655        nr_links = RTE_MIN(port_count, queue_count);
 656        const unsigned int total_events = MAX_EVENTS / nr_links;
 657
 658        /* Link queue x to port x and inject events to queue x through port x */
 659        for (i = 0; i < nr_links; i++) {
 660                uint8_t queue = (uint8_t)i;
 661
 662                ret = rte_event_port_link(evdev, i, &queue, NULL, 1);
 663                RTE_TEST_ASSERT(ret == 1, "Failed to link queue to port %d", i);
 664
 665                ret = inject_events(
 666                        0x100 /*flow_id */,
 667                        RTE_EVENT_TYPE_CPU /* event_type */,
 668                        rte_rand() % 256 /* sub_event_type */,
 669                        rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1),
 670                        queue /* queue */,
 671                        i /* port */,
 672                        total_events /* events */);
 673                if (ret)
 674                        return -1;
 675        }
 676
 677        /* Verify the events generated from correct queue */
 678        for (i = 0; i < nr_links; i++) {
 679                ret = consume_events(i /* port */, total_events,
 680                                validate_queue_to_port_single_link);
 681                if (ret)
 682                        return -1;
 683        }
 684
 685        return 0;
 686}
 687
 688static int
 689validate_queue_to_port_multi_link(uint32_t index, uint8_t port,
 690                        struct rte_event *ev)
 691{
 692        RTE_SET_USED(index);
 693        RTE_TEST_ASSERT_EQUAL(port, (ev->queue_id & 0x1),
 694                                "queue mismatch enq=%d deq =%d",
 695                                port, ev->queue_id);
 696        return 0;
 697}
 698
 699/*
 700 * Link all even number of queues to port 0 and all odd number of queues to
 701 * port 1 and verify the link connection on dequeue
 702 */
 703static int
 704test_queue_to_port_multi_link(void)
 705{
 706        int ret, port0_events = 0, port1_events = 0;
 707        uint8_t queue, port;
 708        uint32_t nr_queues = 0;
 709        uint32_t nr_ports = 0;
 710
 711        RTE_TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(evdev,
 712                            RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
 713                            &nr_queues), "Queue count get failed");
 714
 715        RTE_TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(evdev,
 716                                RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
 717                                &nr_queues), "Queue count get failed");
 718        RTE_TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(evdev,
 719                                RTE_EVENT_DEV_ATTR_PORT_COUNT,
 720                                &nr_ports), "Port count get failed");
 721
 722        if (nr_ports < 2) {
 723                dpaa2_evdev_err("%s: Not enough ports to test ports=%d",
 724                                __func__, nr_ports);
 725                return 0;
 726        }
 727
 728        /* Unlink all connections that created in eventdev_setup */
 729        for (port = 0; port < nr_ports; port++) {
 730                ret = rte_event_port_unlink(evdev, port, NULL, 0);
 731                RTE_TEST_ASSERT(ret >= 0, "Failed to unlink all queues port=%d",
 732                                        port);
 733        }
 734
 735        const unsigned int total_events = MAX_EVENTS / nr_queues;
 736
 737        /* Link all even number of queues to port0 and odd numbers to port 1*/
 738        for (queue = 0; queue < nr_queues; queue++) {
 739                port = queue & 0x1;
 740                ret = rte_event_port_link(evdev, port, &queue, NULL, 1);
 741                RTE_TEST_ASSERT(ret == 1, "Failed to link queue=%d to port=%d",
 742                                        queue, port);
 743
 744                ret = inject_events(
 745                        0x100 /*flow_id */,
 746                        RTE_EVENT_TYPE_CPU /* event_type */,
 747                        rte_rand() % 256 /* sub_event_type */,
 748                        rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1),
 749                        queue /* queue */,
 750                        port /* port */,
 751                        total_events /* events */);
 752                if (ret)
 753                        return -1;
 754
 755                if (port == 0)
 756                        port0_events += total_events;
 757                else
 758                        port1_events += total_events;
 759        }
 760
 761        ret = consume_events(0 /* port */, port0_events,
 762                                validate_queue_to_port_multi_link);
 763        if (ret)
 764                return -1;
 765        ret = consume_events(1 /* port */, port1_events,
 766                                validate_queue_to_port_multi_link);
 767        if (ret)
 768                return -1;
 769
 770        return 0;
 771}
 772
 773static void dpaa2_test_run(int (*setup)(void), void (*tdown)(void),
 774                int (*test)(void), const char *name)
 775{
 776        if (setup() < 0) {
 777                RTE_LOG(INFO, PMD, "Error setting up test %s", name);
 778                unsupported++;
 779        } else {
 780                if (test() < 0) {
 781                        failed++;
 782                        RTE_LOG(INFO, PMD, "%s Failed\n", name);
 783                } else {
 784                        passed++;
 785                        RTE_LOG(INFO, PMD, "%s Passed", name);
 786                }
 787        }
 788
 789        total++;
 790        tdown();
 791}
 792
 793int
 794test_eventdev_dpaa2(void)
 795{
 796        testsuite_setup();
 797
 798        DPAA2_TEST_RUN(eventdev_setup, eventdev_teardown,
 799                        test_simple_enqdeq_atomic);
 800        DPAA2_TEST_RUN(eventdev_setup, eventdev_teardown,
 801                        test_simple_enqdeq_parallel);
 802        DPAA2_TEST_RUN(eventdev_setup, eventdev_teardown,
 803                        test_multi_queue_enq_single_port_deq);
 804        DPAA2_TEST_RUN(eventdev_setup, eventdev_teardown,
 805                        test_dev_stop_flush);
 806        DPAA2_TEST_RUN(eventdev_setup, eventdev_teardown,
 807                        test_multi_queue_enq_multi_port_deq);
 808        DPAA2_TEST_RUN(eventdev_setup, eventdev_teardown,
 809                        test_queue_to_port_single_link);
 810        DPAA2_TEST_RUN(eventdev_setup, eventdev_teardown,
 811                        test_queue_to_port_multi_link);
 812
 813        DPAA2_EVENTDEV_INFO("Total tests   : %d", total);
 814        DPAA2_EVENTDEV_INFO("Passed        : %d", passed);
 815        DPAA2_EVENTDEV_INFO("Failed        : %d", failed);
 816        DPAA2_EVENTDEV_INFO("Not supported : %d", unsupported);
 817
 818        testsuite_teardown();
 819
 820        if (failed)
 821                return -1;
 822
 823        return 0;
 824}
 825