+int
+pipeline_event_port_setup(struct evt_test *test, struct evt_options *opt,
+ uint8_t *queue_arr, uint8_t nb_queues,
+ const struct rte_event_port_conf p_conf)
+{
+ int ret;
+ uint8_t port;
+ struct test_pipeline *t = evt_test_priv(test);
+
+
+ /* setup one port per worker, linking to all queues */
+ for (port = 0; port < evt_nr_active_lcores(opt->wlcores); port++) {
+ struct worker_data *w = &t->worker[port];
+
+ w->dev_id = opt->dev_id;
+ w->port_id = port;
+ w->t = t;
+ w->processed_pkts = 0;
+
+ ret = rte_event_port_setup(opt->dev_id, port, &p_conf);
+ if (ret) {
+ evt_err("failed to setup port %d", port);
+ return ret;
+ }
+
+ if (rte_event_port_link(opt->dev_id, port, queue_arr, NULL,
+ nb_queues) != nb_queues)
+ goto link_fail;
+ }
+
+ return 0;
+
+link_fail:
+ evt_err("failed to link queues to port %d", port);
+ return -EINVAL;
+}
+
+int
+pipeline_event_rx_adapter_setup(struct evt_options *opt, uint8_t stride,
+ struct rte_event_port_conf prod_conf)
+{
+ int ret = 0;
+ uint16_t prod;
+ struct rte_mempool *vector_pool = NULL;
+ struct rte_event_eth_rx_adapter_queue_conf queue_conf;
+
+ memset(&queue_conf, 0,
+ sizeof(struct rte_event_eth_rx_adapter_queue_conf));
+ queue_conf.ev.sched_type = opt->sched_type_list[0];
+ if (opt->ena_vector) {
+ unsigned int nb_elem = (opt->pool_sz / opt->vector_size) << 1;
+
+ nb_elem = nb_elem ? nb_elem : 1;
+ vector_pool = rte_event_vector_pool_create(
+ "vector_pool", nb_elem, 0, opt->vector_size,
+ opt->socket_id);
+ if (vector_pool == NULL) {
+ evt_err("failed to create event vector pool");
+ return -ENOMEM;
+ }
+ }
+ RTE_ETH_FOREACH_DEV(prod) {
+ struct rte_event_eth_rx_adapter_vector_limits limits;
+ uint32_t cap;
+
+ ret = rte_event_eth_rx_adapter_caps_get(opt->dev_id,
+ prod, &cap);
+ if (ret) {
+ evt_err("failed to get event rx adapter[%d]"
+ " capabilities",
+ opt->dev_id);
+ return ret;
+ }
+
+ if (opt->ena_vector) {
+ memset(&limits, 0, sizeof(limits));
+ ret = rte_event_eth_rx_adapter_vector_limits_get(
+ opt->dev_id, prod, &limits);
+ if (ret) {
+ evt_err("failed to get vector limits");
+ return ret;
+ }
+
+ if (opt->vector_size < limits.min_sz ||
+ opt->vector_size > limits.max_sz) {
+ evt_err("Vector size [%d] not within limits max[%d] min[%d]",
+ opt->vector_size, limits.min_sz,
+ limits.max_sz);
+ return -EINVAL;
+ }
+
+ if (limits.log2_sz &&
+ !rte_is_power_of_2(opt->vector_size)) {
+ evt_err("Vector size [%d] not power of 2",
+ opt->vector_size);
+ return -EINVAL;
+ }
+
+ if (opt->vector_tmo_nsec > limits.max_timeout_ns ||
+ opt->vector_tmo_nsec < limits.min_timeout_ns) {
+ evt_err("Vector timeout [%" PRIu64
+ "] not within limits max[%" PRIu64
+ "] min[%" PRIu64 "]",
+ opt->vector_tmo_nsec,
+ limits.max_timeout_ns,
+ limits.min_timeout_ns);
+ return -EINVAL;
+ }
+
+ if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_EVENT_VECTOR) {
+ queue_conf.vector_sz = opt->vector_size;
+ queue_conf.vector_timeout_ns =
+ opt->vector_tmo_nsec;
+ queue_conf.rx_queue_flags |=
+ RTE_EVENT_ETH_RX_ADAPTER_QUEUE_EVENT_VECTOR;
+ queue_conf.vector_mp = vector_pool;
+ } else {
+ evt_err("Rx adapter doesn't support event vector");
+ return -EINVAL;
+ }
+ }
+ queue_conf.ev.queue_id = prod * stride;
+ ret = rte_event_eth_rx_adapter_create(prod, opt->dev_id,
+ &prod_conf);
+ if (ret) {
+ evt_err("failed to create rx adapter[%d]", prod);
+ return ret;
+ }
+ ret = rte_event_eth_rx_adapter_queue_add(prod, prod, -1,
+ &queue_conf);
+ if (ret) {
+ evt_err("failed to add rx queues to adapter[%d]", prod);
+ return ret;
+ }
+
+ if (!(cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT)) {
+ uint32_t service_id = -1U;
+
+ rte_event_eth_rx_adapter_service_id_get(prod,
+ &service_id);
+ ret = evt_service_setup(service_id);
+ if (ret) {
+ evt_err("Failed to setup service core"
+ " for Rx adapter");
+ return ret;
+ }
+ }
+
+ evt_info("Port[%d] using Rx adapter[%d] configured", prod,
+ prod);
+ }
+
+ return ret;
+}
+
+int
+pipeline_event_tx_adapter_setup(struct evt_options *opt,
+ struct rte_event_port_conf port_conf)
+{
+ int ret = 0;
+ uint16_t consm;
+
+ RTE_ETH_FOREACH_DEV(consm) {
+ uint32_t cap;
+
+ ret = rte_event_eth_tx_adapter_caps_get(opt->dev_id,
+ consm, &cap);
+ if (ret) {
+ evt_err("failed to get event tx adapter[%d] caps",
+ consm);
+ return ret;
+ }
+
+ if (opt->ena_vector) {
+ if (!(cap &
+ RTE_EVENT_ETH_TX_ADAPTER_CAP_EVENT_VECTOR)) {
+ evt_err("Tx adapter doesn't support event vector");
+ return -EINVAL;
+ }
+ }
+
+ ret = rte_event_eth_tx_adapter_create(consm, opt->dev_id,
+ &port_conf);
+ if (ret) {
+ evt_err("failed to create tx adapter[%d]", consm);
+ return ret;
+ }
+
+ ret = rte_event_eth_tx_adapter_queue_add(consm, consm, -1);
+ if (ret) {
+ evt_err("failed to add tx queues to adapter[%d]",
+ consm);
+ return ret;
+ }
+
+ if (!(cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)) {
+ uint32_t service_id = -1U;
+
+ ret = rte_event_eth_tx_adapter_service_id_get(consm,
+ &service_id);
+ if (ret != -ESRCH && ret != 0) {
+ evt_err("Failed to get Tx adptr service ID");
+ return ret;
+ }
+ ret = evt_service_setup(service_id);
+ if (ret) {
+ evt_err("Failed to setup service core"
+ " for Tx adapter");
+ return ret;
+ }
+ }
+
+ evt_info("Port[%d] using Tx adapter[%d] Configured", consm,
+ consm);
+ }
+
+ return ret;
+}
+
+static void
+pipeline_vector_array_free(struct rte_event events[], uint16_t num)
+{
+ uint16_t i;
+
+ for (i = 0; i < num; i++) {
+ rte_pktmbuf_free_bulk(events[i].vec->mbufs,
+ events[i].vec->nb_elem);
+ rte_mempool_put(rte_mempool_from_obj(events[i].vec),
+ events[i].vec);
+ }
+}
+
+static void
+pipeline_event_port_flush(uint8_t dev_id __rte_unused, struct rte_event ev,
+ void *args __rte_unused)
+{
+ if (ev.event_type & RTE_EVENT_TYPE_VECTOR)
+ pipeline_vector_array_free(&ev, 1);
+ else
+ rte_pktmbuf_free(ev.mbuf);
+}
+