199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson * Copyright(c) 2018 Intel Corporation.
399a2dd95SBruce Richardson */
499a2dd95SBruce Richardson #include <rte_spinlock.h>
599a2dd95SBruce Richardson #include <rte_service_component.h>
6f9bdee26SKonstantin Ananyev #include <ethdev_driver.h>
799a2dd95SBruce Richardson
899a2dd95SBruce Richardson #include "eventdev_pmd.h"
9f26f2ca6SPavan Nikhilesh #include "eventdev_trace.h"
1099a2dd95SBruce Richardson #include "rte_event_eth_tx_adapter.h"
1199a2dd95SBruce Richardson
1299a2dd95SBruce Richardson #define TXA_BATCH_SIZE 32
1399a2dd95SBruce Richardson #define TXA_SERVICE_NAME_LEN 32
1499a2dd95SBruce Richardson #define TXA_MEM_NAME_LEN 32
1599a2dd95SBruce Richardson #define TXA_FLUSH_THRESHOLD 1024
1699a2dd95SBruce Richardson #define TXA_RETRY_CNT 100
1799a2dd95SBruce Richardson #define TXA_MAX_NB_TX 128
1899a2dd95SBruce Richardson #define TXA_INVALID_DEV_ID INT32_C(-1)
1999a2dd95SBruce Richardson #define TXA_INVALID_SERVICE_ID INT64_C(-1)
2099a2dd95SBruce Richardson
21b2963cbdSGanapati Kundapura #define TXA_ADAPTER_ARRAY "txa_adapter_array"
22b2963cbdSGanapati Kundapura #define TXA_SERVICE_DATA_ARRAY "txa_service_data_array"
23b2963cbdSGanapati Kundapura
2499a2dd95SBruce Richardson #define txa_evdev(id) (&rte_eventdevs[txa_dev_id_array[(id)]])
2599a2dd95SBruce Richardson
2699a2dd95SBruce Richardson #define txa_dev_caps_get(id) txa_evdev((id))->dev_ops->eth_tx_adapter_caps_get
2799a2dd95SBruce Richardson
2899a2dd95SBruce Richardson #define txa_dev_adapter_create(t) txa_evdev(t)->dev_ops->eth_tx_adapter_create
2999a2dd95SBruce Richardson
3099a2dd95SBruce Richardson #define txa_dev_adapter_create_ext(t) \
3199a2dd95SBruce Richardson txa_evdev(t)->dev_ops->eth_tx_adapter_create
3299a2dd95SBruce Richardson
3399a2dd95SBruce Richardson #define txa_dev_adapter_free(t) txa_evdev(t)->dev_ops->eth_tx_adapter_free
3499a2dd95SBruce Richardson
3599a2dd95SBruce Richardson #define txa_dev_queue_add(id) txa_evdev(id)->dev_ops->eth_tx_adapter_queue_add
3699a2dd95SBruce Richardson
3799a2dd95SBruce Richardson #define txa_dev_queue_del(t) txa_evdev(t)->dev_ops->eth_tx_adapter_queue_del
3899a2dd95SBruce Richardson
3999a2dd95SBruce Richardson #define txa_dev_start(t) txa_evdev(t)->dev_ops->eth_tx_adapter_start
4099a2dd95SBruce Richardson
4199a2dd95SBruce Richardson #define txa_dev_stop(t) txa_evdev(t)->dev_ops->eth_tx_adapter_stop
4299a2dd95SBruce Richardson
4399a2dd95SBruce Richardson #define txa_dev_stats_reset(t) txa_evdev(t)->dev_ops->eth_tx_adapter_stats_reset
4499a2dd95SBruce Richardson
4599a2dd95SBruce Richardson #define txa_dev_stats_get(t) txa_evdev(t)->dev_ops->eth_tx_adapter_stats_get
4699a2dd95SBruce Richardson
47b2963cbdSGanapati Kundapura #define txa_dev_instance_get(id) \
48b2963cbdSGanapati Kundapura txa_evdev(id)->dev_ops->eth_tx_adapter_instance_get
49b2963cbdSGanapati Kundapura
503c3328aeSNaga Harish K S V #define txa_dev_queue_start(id) \
513c3328aeSNaga Harish K S V txa_evdev(id)->dev_ops->eth_tx_adapter_queue_start
523c3328aeSNaga Harish K S V
533c3328aeSNaga Harish K S V #define txa_dev_queue_stop(id) \
543c3328aeSNaga Harish K S V txa_evdev(id)->dev_ops->eth_tx_adapter_queue_stop
553c3328aeSNaga Harish K S V
5699a2dd95SBruce Richardson #define RTE_EVENT_ETH_TX_ADAPTER_ID_VALID_OR_ERR_RET(id, retval) \
5799a2dd95SBruce Richardson do { \
5899a2dd95SBruce Richardson if (!txa_valid_id(id)) { \
592ab9869cSNaga Harish K S V RTE_EDEV_LOG_ERR("Invalid eth Tx adapter id = %d", id); \
6099a2dd95SBruce Richardson return retval; \
6199a2dd95SBruce Richardson } \
6299a2dd95SBruce Richardson } while (0)
6399a2dd95SBruce Richardson
6499a2dd95SBruce Richardson #define TXA_CHECK_OR_ERR_RET(id) \
6599a2dd95SBruce Richardson do {\
6699a2dd95SBruce Richardson int ret; \
6799a2dd95SBruce Richardson RTE_EVENT_ETH_TX_ADAPTER_ID_VALID_OR_ERR_RET((id), -EINVAL); \
6899a2dd95SBruce Richardson ret = txa_init(); \
6999a2dd95SBruce Richardson if (ret != 0) \
7099a2dd95SBruce Richardson return ret; \
7199a2dd95SBruce Richardson if (!txa_adapter_exist((id))) \
7299a2dd95SBruce Richardson return -EINVAL; \
7399a2dd95SBruce Richardson } while (0)
7499a2dd95SBruce Richardson
7599a2dd95SBruce Richardson #define TXA_CHECK_TXQ(dev, queue) \
7699a2dd95SBruce Richardson do {\
7799a2dd95SBruce Richardson if ((dev)->data->nb_tx_queues == 0) { \
7899a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("No tx queues configured"); \
7999a2dd95SBruce Richardson return -EINVAL; \
8099a2dd95SBruce Richardson } \
8199a2dd95SBruce Richardson if ((queue) != -1 && \
8299a2dd95SBruce Richardson (uint16_t)(queue) >= (dev)->data->nb_tx_queues) { \
8399a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("Invalid tx queue_id %" PRIu16, \
8499a2dd95SBruce Richardson (uint16_t)(queue)); \
8599a2dd95SBruce Richardson return -EINVAL; \
8699a2dd95SBruce Richardson } \
8799a2dd95SBruce Richardson } while (0)
8899a2dd95SBruce Richardson
8999a2dd95SBruce Richardson /* Tx retry callback structure */
9099a2dd95SBruce Richardson struct txa_retry {
9199a2dd95SBruce Richardson /* Ethernet port id */
9299a2dd95SBruce Richardson uint16_t port_id;
9399a2dd95SBruce Richardson /* Tx queue */
9499a2dd95SBruce Richardson uint16_t tx_queue;
9599a2dd95SBruce Richardson /* Adapter ID */
9699a2dd95SBruce Richardson uint8_t id;
9799a2dd95SBruce Richardson };
9899a2dd95SBruce Richardson
9999a2dd95SBruce Richardson /* Per queue structure */
10099a2dd95SBruce Richardson struct txa_service_queue_info {
10199a2dd95SBruce Richardson /* Queue has been added */
10299a2dd95SBruce Richardson uint8_t added;
1033c3328aeSNaga Harish K S V /* Queue is stopped */
1043c3328aeSNaga Harish K S V bool stopped;
10599a2dd95SBruce Richardson /* Retry callback argument */
10699a2dd95SBruce Richardson struct txa_retry txa_retry;
10799a2dd95SBruce Richardson /* Tx buffer */
10899a2dd95SBruce Richardson struct rte_eth_dev_tx_buffer *tx_buf;
10999a2dd95SBruce Richardson };
11099a2dd95SBruce Richardson
11199a2dd95SBruce Richardson /* PMD private structure */
112*c6552d9aSTyler Retzlaff struct __rte_cache_aligned txa_service_data {
11399a2dd95SBruce Richardson /* Max mbufs processed in any service function invocation */
11499a2dd95SBruce Richardson uint32_t max_nb_tx;
11599a2dd95SBruce Richardson /* Number of Tx queues in adapter */
11699a2dd95SBruce Richardson uint32_t nb_queues;
11799a2dd95SBruce Richardson /* Synchronization with data path */
11899a2dd95SBruce Richardson rte_spinlock_t tx_lock;
11999a2dd95SBruce Richardson /* Event port ID */
12099a2dd95SBruce Richardson uint8_t port_id;
12199a2dd95SBruce Richardson /* Event device identifier */
12299a2dd95SBruce Richardson uint8_t eventdev_id;
12399a2dd95SBruce Richardson /* Highest port id supported + 1 */
12499a2dd95SBruce Richardson uint16_t dev_count;
12599a2dd95SBruce Richardson /* Loop count to flush Tx buffers */
12699a2dd95SBruce Richardson int loop_cnt;
1271d176c7aSNaga Harish K S V /* Loop count threshold to flush Tx buffers */
1281d176c7aSNaga Harish K S V uint16_t flush_threshold;
12999a2dd95SBruce Richardson /* Per ethernet device structure */
13099a2dd95SBruce Richardson struct txa_service_ethdev *txa_ethdev;
13199a2dd95SBruce Richardson /* Statistics */
13299a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats stats;
13399a2dd95SBruce Richardson /* Adapter Identifier */
13499a2dd95SBruce Richardson uint8_t id;
13599a2dd95SBruce Richardson /* Conf arg must be freed */
13699a2dd95SBruce Richardson uint8_t conf_free;
13799a2dd95SBruce Richardson /* Configuration callback */
13899a2dd95SBruce Richardson rte_event_eth_tx_adapter_conf_cb conf_cb;
13999a2dd95SBruce Richardson /* Configuration callback argument */
14099a2dd95SBruce Richardson void *conf_arg;
14199a2dd95SBruce Richardson /* socket id */
14299a2dd95SBruce Richardson int socket_id;
14399a2dd95SBruce Richardson /* Per adapter EAL service */
14499a2dd95SBruce Richardson int64_t service_id;
14599a2dd95SBruce Richardson /* Memory allocation name */
14699a2dd95SBruce Richardson char mem_name[TXA_MEM_NAME_LEN];
147*c6552d9aSTyler Retzlaff };
14899a2dd95SBruce Richardson
14999a2dd95SBruce Richardson /* Per eth device structure */
15099a2dd95SBruce Richardson struct txa_service_ethdev {
15199a2dd95SBruce Richardson /* Pointer to ethernet device */
15299a2dd95SBruce Richardson struct rte_eth_dev *dev;
15399a2dd95SBruce Richardson /* Number of queues added */
15499a2dd95SBruce Richardson uint16_t nb_queues;
15599a2dd95SBruce Richardson /* PMD specific queue data */
15699a2dd95SBruce Richardson void *queues;
15799a2dd95SBruce Richardson };
15899a2dd95SBruce Richardson
15999a2dd95SBruce Richardson /* Array of adapter instances, initialized with event device id
16099a2dd95SBruce Richardson * when adapter is created
16199a2dd95SBruce Richardson */
16299a2dd95SBruce Richardson static int *txa_dev_id_array;
16399a2dd95SBruce Richardson
16499a2dd95SBruce Richardson /* Array of pointers to service implementation data */
16599a2dd95SBruce Richardson static struct txa_service_data **txa_service_data_array;
16699a2dd95SBruce Richardson
16799a2dd95SBruce Richardson static int32_t txa_service_func(void *args);
16899a2dd95SBruce Richardson static int txa_service_adapter_create_ext(uint8_t id,
16999a2dd95SBruce Richardson struct rte_eventdev *dev,
17099a2dd95SBruce Richardson rte_event_eth_tx_adapter_conf_cb conf_cb,
17199a2dd95SBruce Richardson void *conf_arg);
17299a2dd95SBruce Richardson static int txa_service_queue_del(uint8_t id,
17399a2dd95SBruce Richardson const struct rte_eth_dev *dev,
17499a2dd95SBruce Richardson int32_t tx_queue_id);
17599a2dd95SBruce Richardson
17699a2dd95SBruce Richardson static int
txa_adapter_exist(uint8_t id)17799a2dd95SBruce Richardson txa_adapter_exist(uint8_t id)
17899a2dd95SBruce Richardson {
17999a2dd95SBruce Richardson return txa_dev_id_array[id] != TXA_INVALID_DEV_ID;
18099a2dd95SBruce Richardson }
18199a2dd95SBruce Richardson
18299a2dd95SBruce Richardson static inline int
txa_valid_id(uint8_t id)18399a2dd95SBruce Richardson txa_valid_id(uint8_t id)
18499a2dd95SBruce Richardson {
18599a2dd95SBruce Richardson return id < RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE;
18699a2dd95SBruce Richardson }
18799a2dd95SBruce Richardson
18899a2dd95SBruce Richardson static void *
txa_memzone_array_get(const char * name,unsigned int elt_size,int nb_elems)18999a2dd95SBruce Richardson txa_memzone_array_get(const char *name, unsigned int elt_size, int nb_elems)
19099a2dd95SBruce Richardson {
19199a2dd95SBruce Richardson const struct rte_memzone *mz;
19299a2dd95SBruce Richardson unsigned int sz;
19399a2dd95SBruce Richardson
19499a2dd95SBruce Richardson sz = elt_size * nb_elems;
19599a2dd95SBruce Richardson sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE);
19699a2dd95SBruce Richardson
19799a2dd95SBruce Richardson mz = rte_memzone_lookup(name);
19899a2dd95SBruce Richardson if (mz == NULL) {
19999a2dd95SBruce Richardson mz = rte_memzone_reserve_aligned(name, sz, rte_socket_id(), 0,
20099a2dd95SBruce Richardson RTE_CACHE_LINE_SIZE);
20199a2dd95SBruce Richardson if (mz == NULL) {
20299a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("failed to reserve memzone"
20399a2dd95SBruce Richardson " name = %s err = %"
20499a2dd95SBruce Richardson PRId32, name, rte_errno);
20599a2dd95SBruce Richardson return NULL;
20699a2dd95SBruce Richardson }
20799a2dd95SBruce Richardson }
20899a2dd95SBruce Richardson
20999a2dd95SBruce Richardson return mz->addr;
21099a2dd95SBruce Richardson }
21199a2dd95SBruce Richardson
21299a2dd95SBruce Richardson static int
txa_lookup(void)213b2963cbdSGanapati Kundapura txa_lookup(void)
214b2963cbdSGanapati Kundapura {
215b2963cbdSGanapati Kundapura const struct rte_memzone *mz;
216b2963cbdSGanapati Kundapura
217b2963cbdSGanapati Kundapura if (txa_dev_id_array == NULL) {
218b2963cbdSGanapati Kundapura mz = rte_memzone_lookup(TXA_ADAPTER_ARRAY);
219b2963cbdSGanapati Kundapura if (mz == NULL)
220b2963cbdSGanapati Kundapura return -ENOMEM;
221b2963cbdSGanapati Kundapura txa_dev_id_array = mz->addr;
222b2963cbdSGanapati Kundapura }
223b2963cbdSGanapati Kundapura
224b2963cbdSGanapati Kundapura if (txa_service_data_array == NULL) {
225b2963cbdSGanapati Kundapura mz = rte_memzone_lookup(TXA_SERVICE_DATA_ARRAY);
226b2963cbdSGanapati Kundapura if (mz == NULL)
227b2963cbdSGanapati Kundapura return -ENOMEM;
228b2963cbdSGanapati Kundapura txa_service_data_array = mz->addr;
229b2963cbdSGanapati Kundapura }
230b2963cbdSGanapati Kundapura
231b2963cbdSGanapati Kundapura return 0;
232b2963cbdSGanapati Kundapura }
233b2963cbdSGanapati Kundapura
234b2963cbdSGanapati Kundapura static int
txa_dev_id_array_init(void)23599a2dd95SBruce Richardson txa_dev_id_array_init(void)
23699a2dd95SBruce Richardson {
23799a2dd95SBruce Richardson if (txa_dev_id_array == NULL) {
23899a2dd95SBruce Richardson int i;
23999a2dd95SBruce Richardson
240b2963cbdSGanapati Kundapura txa_dev_id_array = txa_memzone_array_get(TXA_ADAPTER_ARRAY,
24199a2dd95SBruce Richardson sizeof(int),
24299a2dd95SBruce Richardson RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE);
24399a2dd95SBruce Richardson if (txa_dev_id_array == NULL)
24499a2dd95SBruce Richardson return -ENOMEM;
24599a2dd95SBruce Richardson
24699a2dd95SBruce Richardson for (i = 0; i < RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE; i++)
24799a2dd95SBruce Richardson txa_dev_id_array[i] = TXA_INVALID_DEV_ID;
24899a2dd95SBruce Richardson }
24999a2dd95SBruce Richardson
25099a2dd95SBruce Richardson return 0;
25199a2dd95SBruce Richardson }
25299a2dd95SBruce Richardson
25399a2dd95SBruce Richardson static int
txa_init(void)25499a2dd95SBruce Richardson txa_init(void)
25599a2dd95SBruce Richardson {
25699a2dd95SBruce Richardson return txa_dev_id_array_init();
25799a2dd95SBruce Richardson }
25899a2dd95SBruce Richardson
25999a2dd95SBruce Richardson static int
txa_service_data_init(void)26099a2dd95SBruce Richardson txa_service_data_init(void)
26199a2dd95SBruce Richardson {
26299a2dd95SBruce Richardson if (txa_service_data_array == NULL) {
263b2963cbdSGanapati Kundapura int i;
264b2963cbdSGanapati Kundapura
26599a2dd95SBruce Richardson txa_service_data_array =
266b2963cbdSGanapati Kundapura txa_memzone_array_get(TXA_SERVICE_DATA_ARRAY,
2673d6e9dd4SNaga Harish K S V sizeof(*txa_service_data_array),
26899a2dd95SBruce Richardson RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE);
26999a2dd95SBruce Richardson if (txa_service_data_array == NULL)
27099a2dd95SBruce Richardson return -ENOMEM;
271b2963cbdSGanapati Kundapura
272b2963cbdSGanapati Kundapura /* Reset the txa service pointers */
273b2963cbdSGanapati Kundapura for (i = 0; i < RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE; i++)
274b2963cbdSGanapati Kundapura txa_service_data_array[i] = NULL;
27599a2dd95SBruce Richardson }
27699a2dd95SBruce Richardson
27799a2dd95SBruce Richardson return 0;
27899a2dd95SBruce Richardson }
27999a2dd95SBruce Richardson
28099a2dd95SBruce Richardson static inline struct txa_service_data *
txa_service_id_to_data(uint8_t id)28199a2dd95SBruce Richardson txa_service_id_to_data(uint8_t id)
28299a2dd95SBruce Richardson {
28399a2dd95SBruce Richardson return txa_service_data_array[id];
28499a2dd95SBruce Richardson }
28599a2dd95SBruce Richardson
28699a2dd95SBruce Richardson static inline struct txa_service_queue_info *
txa_service_queue(struct txa_service_data * txa,uint16_t port_id,uint16_t tx_queue_id)28799a2dd95SBruce Richardson txa_service_queue(struct txa_service_data *txa, uint16_t port_id,
28899a2dd95SBruce Richardson uint16_t tx_queue_id)
28999a2dd95SBruce Richardson {
29099a2dd95SBruce Richardson struct txa_service_queue_info *tqi;
29199a2dd95SBruce Richardson
29299a2dd95SBruce Richardson if (unlikely(txa->txa_ethdev == NULL || txa->dev_count < port_id + 1))
29399a2dd95SBruce Richardson return NULL;
29499a2dd95SBruce Richardson
29599a2dd95SBruce Richardson tqi = txa->txa_ethdev[port_id].queues;
29699a2dd95SBruce Richardson
29799a2dd95SBruce Richardson return likely(tqi != NULL) ? tqi + tx_queue_id : NULL;
29899a2dd95SBruce Richardson }
29999a2dd95SBruce Richardson
30099a2dd95SBruce Richardson static int
txa_service_conf_cb(uint8_t __rte_unused id,uint8_t dev_id,struct rte_event_eth_tx_adapter_conf * conf,void * arg)30199a2dd95SBruce Richardson txa_service_conf_cb(uint8_t __rte_unused id, uint8_t dev_id,
30299a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_conf *conf, void *arg)
30399a2dd95SBruce Richardson {
30499a2dd95SBruce Richardson int ret;
30599a2dd95SBruce Richardson struct rte_eventdev *dev;
30699a2dd95SBruce Richardson struct rte_event_port_conf *pc;
30799a2dd95SBruce Richardson struct rte_event_dev_config dev_conf;
30899a2dd95SBruce Richardson int started;
30999a2dd95SBruce Richardson uint8_t port_id;
31099a2dd95SBruce Richardson
31199a2dd95SBruce Richardson pc = arg;
31299a2dd95SBruce Richardson dev = &rte_eventdevs[dev_id];
31399a2dd95SBruce Richardson dev_conf = dev->data->dev_conf;
31499a2dd95SBruce Richardson
31599a2dd95SBruce Richardson started = dev->data->dev_started;
31699a2dd95SBruce Richardson if (started)
31799a2dd95SBruce Richardson rte_event_dev_stop(dev_id);
31899a2dd95SBruce Richardson
31999a2dd95SBruce Richardson port_id = dev_conf.nb_event_ports;
32099a2dd95SBruce Richardson dev_conf.nb_event_ports += 1;
32172fc5337SNaga Harish K S V if (pc->event_port_cfg & RTE_EVENT_PORT_CFG_SINGLE_LINK)
32272fc5337SNaga Harish K S V dev_conf.nb_single_link_event_port_queues += 1;
32399a2dd95SBruce Richardson
32499a2dd95SBruce Richardson ret = rte_event_dev_configure(dev_id, &dev_conf);
32599a2dd95SBruce Richardson if (ret) {
32699a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("failed to configure event dev %u",
32799a2dd95SBruce Richardson dev_id);
32899a2dd95SBruce Richardson if (started) {
32999a2dd95SBruce Richardson if (rte_event_dev_start(dev_id))
33099a2dd95SBruce Richardson return -EIO;
33199a2dd95SBruce Richardson }
33299a2dd95SBruce Richardson return ret;
33399a2dd95SBruce Richardson }
33499a2dd95SBruce Richardson
33599a2dd95SBruce Richardson ret = rte_event_port_setup(dev_id, port_id, pc);
33699a2dd95SBruce Richardson if (ret) {
337ae282b06SDavid Marchand RTE_EDEV_LOG_ERR("failed to setup event port %u",
33899a2dd95SBruce Richardson port_id);
33999a2dd95SBruce Richardson if (started) {
34099a2dd95SBruce Richardson if (rte_event_dev_start(dev_id))
34199a2dd95SBruce Richardson return -EIO;
34299a2dd95SBruce Richardson }
34399a2dd95SBruce Richardson return ret;
34499a2dd95SBruce Richardson }
34599a2dd95SBruce Richardson
34699a2dd95SBruce Richardson conf->event_port_id = port_id;
34799a2dd95SBruce Richardson conf->max_nb_tx = TXA_MAX_NB_TX;
34899a2dd95SBruce Richardson if (started)
34999a2dd95SBruce Richardson ret = rte_event_dev_start(dev_id);
35099a2dd95SBruce Richardson return ret;
35199a2dd95SBruce Richardson }
35299a2dd95SBruce Richardson
35399a2dd95SBruce Richardson static int
txa_service_ethdev_alloc(struct txa_service_data * txa)35499a2dd95SBruce Richardson txa_service_ethdev_alloc(struct txa_service_data *txa)
35599a2dd95SBruce Richardson {
35699a2dd95SBruce Richardson struct txa_service_ethdev *txa_ethdev;
35799a2dd95SBruce Richardson uint16_t i, dev_count;
35899a2dd95SBruce Richardson
35999a2dd95SBruce Richardson dev_count = rte_eth_dev_count_avail();
36099a2dd95SBruce Richardson if (txa->txa_ethdev && dev_count == txa->dev_count)
36199a2dd95SBruce Richardson return 0;
36299a2dd95SBruce Richardson
36399a2dd95SBruce Richardson txa_ethdev = rte_zmalloc_socket(txa->mem_name,
36499a2dd95SBruce Richardson dev_count * sizeof(*txa_ethdev),
36599a2dd95SBruce Richardson 0,
36699a2dd95SBruce Richardson txa->socket_id);
36799a2dd95SBruce Richardson if (txa_ethdev == NULL) {
36899a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("Failed to alloc txa::txa_ethdev ");
36999a2dd95SBruce Richardson return -ENOMEM;
37099a2dd95SBruce Richardson }
37199a2dd95SBruce Richardson
37299a2dd95SBruce Richardson if (txa->dev_count)
37399a2dd95SBruce Richardson memcpy(txa_ethdev, txa->txa_ethdev,
37499a2dd95SBruce Richardson txa->dev_count * sizeof(*txa_ethdev));
37599a2dd95SBruce Richardson
37699a2dd95SBruce Richardson RTE_ETH_FOREACH_DEV(i) {
37799a2dd95SBruce Richardson if (i == dev_count)
37899a2dd95SBruce Richardson break;
37999a2dd95SBruce Richardson txa_ethdev[i].dev = &rte_eth_devices[i];
38099a2dd95SBruce Richardson }
38199a2dd95SBruce Richardson
38299a2dd95SBruce Richardson txa->txa_ethdev = txa_ethdev;
38399a2dd95SBruce Richardson txa->dev_count = dev_count;
38499a2dd95SBruce Richardson return 0;
38599a2dd95SBruce Richardson }
38699a2dd95SBruce Richardson
38799a2dd95SBruce Richardson static int
txa_service_queue_array_alloc(struct txa_service_data * txa,uint16_t port_id)38899a2dd95SBruce Richardson txa_service_queue_array_alloc(struct txa_service_data *txa,
38999a2dd95SBruce Richardson uint16_t port_id)
39099a2dd95SBruce Richardson {
39199a2dd95SBruce Richardson struct txa_service_queue_info *tqi;
39299a2dd95SBruce Richardson uint16_t nb_queue;
39399a2dd95SBruce Richardson int ret;
39499a2dd95SBruce Richardson
39599a2dd95SBruce Richardson ret = txa_service_ethdev_alloc(txa);
39699a2dd95SBruce Richardson if (ret != 0)
39799a2dd95SBruce Richardson return ret;
39899a2dd95SBruce Richardson
39999a2dd95SBruce Richardson if (txa->txa_ethdev[port_id].queues)
40099a2dd95SBruce Richardson return 0;
40199a2dd95SBruce Richardson
40299a2dd95SBruce Richardson nb_queue = txa->txa_ethdev[port_id].dev->data->nb_tx_queues;
40399a2dd95SBruce Richardson tqi = rte_zmalloc_socket(txa->mem_name,
40499a2dd95SBruce Richardson nb_queue *
40599a2dd95SBruce Richardson sizeof(struct txa_service_queue_info), 0,
40699a2dd95SBruce Richardson txa->socket_id);
40799a2dd95SBruce Richardson if (tqi == NULL)
40899a2dd95SBruce Richardson return -ENOMEM;
40999a2dd95SBruce Richardson txa->txa_ethdev[port_id].queues = tqi;
41099a2dd95SBruce Richardson return 0;
41199a2dd95SBruce Richardson }
41299a2dd95SBruce Richardson
41399a2dd95SBruce Richardson static void
txa_service_queue_array_free(struct txa_service_data * txa,uint16_t port_id)41499a2dd95SBruce Richardson txa_service_queue_array_free(struct txa_service_data *txa,
41599a2dd95SBruce Richardson uint16_t port_id)
41699a2dd95SBruce Richardson {
41799a2dd95SBruce Richardson struct txa_service_ethdev *txa_ethdev;
41899a2dd95SBruce Richardson struct txa_service_queue_info *tqi;
41999a2dd95SBruce Richardson
42099a2dd95SBruce Richardson txa_ethdev = &txa->txa_ethdev[port_id];
42199a2dd95SBruce Richardson if (txa->txa_ethdev == NULL || txa_ethdev->nb_queues != 0)
42299a2dd95SBruce Richardson return;
42399a2dd95SBruce Richardson
42499a2dd95SBruce Richardson tqi = txa_ethdev->queues;
42599a2dd95SBruce Richardson txa_ethdev->queues = NULL;
42699a2dd95SBruce Richardson rte_free(tqi);
42799a2dd95SBruce Richardson
42899a2dd95SBruce Richardson if (txa->nb_queues == 0) {
42999a2dd95SBruce Richardson rte_free(txa->txa_ethdev);
43099a2dd95SBruce Richardson txa->txa_ethdev = NULL;
43199a2dd95SBruce Richardson }
43299a2dd95SBruce Richardson }
43399a2dd95SBruce Richardson
43499a2dd95SBruce Richardson static void
txa_service_unregister(struct txa_service_data * txa)43599a2dd95SBruce Richardson txa_service_unregister(struct txa_service_data *txa)
43699a2dd95SBruce Richardson {
43799a2dd95SBruce Richardson if (txa->service_id != TXA_INVALID_SERVICE_ID) {
43899a2dd95SBruce Richardson rte_service_component_runstate_set(txa->service_id, 0);
43999a2dd95SBruce Richardson while (rte_service_may_be_active(txa->service_id))
44099a2dd95SBruce Richardson rte_pause();
44199a2dd95SBruce Richardson rte_service_component_unregister(txa->service_id);
44299a2dd95SBruce Richardson }
44399a2dd95SBruce Richardson txa->service_id = TXA_INVALID_SERVICE_ID;
44499a2dd95SBruce Richardson }
44599a2dd95SBruce Richardson
44699a2dd95SBruce Richardson static int
txa_service_register(struct txa_service_data * txa)44799a2dd95SBruce Richardson txa_service_register(struct txa_service_data *txa)
44899a2dd95SBruce Richardson {
44999a2dd95SBruce Richardson int ret;
45099a2dd95SBruce Richardson struct rte_service_spec service;
45199a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_conf conf;
45299a2dd95SBruce Richardson
45399a2dd95SBruce Richardson if (txa->service_id != TXA_INVALID_SERVICE_ID)
45499a2dd95SBruce Richardson return 0;
45599a2dd95SBruce Richardson
45699a2dd95SBruce Richardson memset(&service, 0, sizeof(service));
45799a2dd95SBruce Richardson snprintf(service.name, TXA_SERVICE_NAME_LEN, "txa_%d", txa->id);
45899a2dd95SBruce Richardson service.socket_id = txa->socket_id;
45999a2dd95SBruce Richardson service.callback = txa_service_func;
46099a2dd95SBruce Richardson service.callback_userdata = txa;
46199a2dd95SBruce Richardson service.capabilities = RTE_SERVICE_CAP_MT_SAFE;
46299a2dd95SBruce Richardson ret = rte_service_component_register(&service,
46399a2dd95SBruce Richardson (uint32_t *)&txa->service_id);
46499a2dd95SBruce Richardson if (ret) {
46599a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("failed to register service %s err = %"
46699a2dd95SBruce Richardson PRId32, service.name, ret);
46799a2dd95SBruce Richardson return ret;
46899a2dd95SBruce Richardson }
46999a2dd95SBruce Richardson
47099a2dd95SBruce Richardson ret = txa->conf_cb(txa->id, txa->eventdev_id, &conf, txa->conf_arg);
47199a2dd95SBruce Richardson if (ret) {
47299a2dd95SBruce Richardson txa_service_unregister(txa);
47399a2dd95SBruce Richardson return ret;
47499a2dd95SBruce Richardson }
47599a2dd95SBruce Richardson
47699a2dd95SBruce Richardson rte_service_component_runstate_set(txa->service_id, 1);
47799a2dd95SBruce Richardson txa->port_id = conf.event_port_id;
47899a2dd95SBruce Richardson txa->max_nb_tx = conf.max_nb_tx;
47999a2dd95SBruce Richardson return 0;
48099a2dd95SBruce Richardson }
48199a2dd95SBruce Richardson
48299a2dd95SBruce Richardson static struct rte_eth_dev_tx_buffer *
txa_service_tx_buf_alloc(struct txa_service_data * txa,const struct rte_eth_dev * dev)48399a2dd95SBruce Richardson txa_service_tx_buf_alloc(struct txa_service_data *txa,
48499a2dd95SBruce Richardson const struct rte_eth_dev *dev)
48599a2dd95SBruce Richardson {
48699a2dd95SBruce Richardson struct rte_eth_dev_tx_buffer *tb;
48799a2dd95SBruce Richardson uint16_t port_id;
48899a2dd95SBruce Richardson
48999a2dd95SBruce Richardson port_id = dev->data->port_id;
49099a2dd95SBruce Richardson tb = rte_zmalloc_socket(txa->mem_name,
49199a2dd95SBruce Richardson RTE_ETH_TX_BUFFER_SIZE(TXA_BATCH_SIZE),
49299a2dd95SBruce Richardson 0,
49399a2dd95SBruce Richardson rte_eth_dev_socket_id(port_id));
49499a2dd95SBruce Richardson if (tb == NULL)
49599a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("Failed to allocate memory for tx buffer");
49699a2dd95SBruce Richardson return tb;
49799a2dd95SBruce Richardson }
49899a2dd95SBruce Richardson
49999a2dd95SBruce Richardson static int
txa_service_is_queue_added(struct txa_service_data * txa,const struct rte_eth_dev * dev,uint16_t tx_queue_id)50099a2dd95SBruce Richardson txa_service_is_queue_added(struct txa_service_data *txa,
50199a2dd95SBruce Richardson const struct rte_eth_dev *dev,
50299a2dd95SBruce Richardson uint16_t tx_queue_id)
50399a2dd95SBruce Richardson {
50499a2dd95SBruce Richardson struct txa_service_queue_info *tqi;
50599a2dd95SBruce Richardson
50699a2dd95SBruce Richardson tqi = txa_service_queue(txa, dev->data->port_id, tx_queue_id);
50799a2dd95SBruce Richardson return tqi && tqi->added;
50899a2dd95SBruce Richardson }
50999a2dd95SBruce Richardson
51099a2dd95SBruce Richardson static int
txa_service_ctrl(uint8_t id,int start)51199a2dd95SBruce Richardson txa_service_ctrl(uint8_t id, int start)
51299a2dd95SBruce Richardson {
51399a2dd95SBruce Richardson int ret;
51499a2dd95SBruce Richardson struct txa_service_data *txa;
51599a2dd95SBruce Richardson
51699a2dd95SBruce Richardson txa = txa_service_id_to_data(id);
5172ab9869cSNaga Harish K S V if (txa == NULL || txa->service_id == TXA_INVALID_SERVICE_ID)
51899a2dd95SBruce Richardson return 0;
51999a2dd95SBruce Richardson
5202ab9869cSNaga Harish K S V rte_spinlock_lock(&txa->tx_lock);
52199a2dd95SBruce Richardson ret = rte_service_runstate_set(txa->service_id, start);
5222ab9869cSNaga Harish K S V rte_spinlock_unlock(&txa->tx_lock);
5232ab9869cSNaga Harish K S V
52499a2dd95SBruce Richardson return ret;
52599a2dd95SBruce Richardson }
52699a2dd95SBruce Richardson
52799a2dd95SBruce Richardson static void
txa_service_buffer_retry(struct rte_mbuf ** pkts,uint16_t unsent,void * userdata)52899a2dd95SBruce Richardson txa_service_buffer_retry(struct rte_mbuf **pkts, uint16_t unsent,
52999a2dd95SBruce Richardson void *userdata)
53099a2dd95SBruce Richardson {
53199a2dd95SBruce Richardson struct txa_retry *tr;
53299a2dd95SBruce Richardson struct txa_service_data *data;
53399a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats *stats;
53499a2dd95SBruce Richardson uint16_t sent = 0;
53599a2dd95SBruce Richardson unsigned int retry = 0;
53699a2dd95SBruce Richardson uint16_t i, n;
53799a2dd95SBruce Richardson
53899a2dd95SBruce Richardson tr = (struct txa_retry *)(uintptr_t)userdata;
53999a2dd95SBruce Richardson data = txa_service_id_to_data(tr->id);
54099a2dd95SBruce Richardson stats = &data->stats;
54199a2dd95SBruce Richardson
54299a2dd95SBruce Richardson do {
54399a2dd95SBruce Richardson n = rte_eth_tx_burst(tr->port_id, tr->tx_queue,
54499a2dd95SBruce Richardson &pkts[sent], unsent - sent);
54599a2dd95SBruce Richardson
54699a2dd95SBruce Richardson sent += n;
54799a2dd95SBruce Richardson } while (sent != unsent && retry++ < TXA_RETRY_CNT);
54899a2dd95SBruce Richardson
54999a2dd95SBruce Richardson for (i = sent; i < unsent; i++)
55099a2dd95SBruce Richardson rte_pktmbuf_free(pkts[i]);
55199a2dd95SBruce Richardson
55299a2dd95SBruce Richardson stats->tx_retry += retry;
55399a2dd95SBruce Richardson stats->tx_packets += sent;
55499a2dd95SBruce Richardson stats->tx_dropped += unsent - sent;
55599a2dd95SBruce Richardson }
55699a2dd95SBruce Richardson
55799a2dd95SBruce Richardson static uint16_t
txa_process_event_vector(struct txa_service_data * txa,struct rte_event_vector * vec)55899a2dd95SBruce Richardson txa_process_event_vector(struct txa_service_data *txa,
55999a2dd95SBruce Richardson struct rte_event_vector *vec)
56099a2dd95SBruce Richardson {
56199a2dd95SBruce Richardson struct txa_service_queue_info *tqi;
56299a2dd95SBruce Richardson uint16_t port, queue, nb_tx = 0;
56399a2dd95SBruce Richardson struct rte_mbuf **mbufs;
56499a2dd95SBruce Richardson int i;
56599a2dd95SBruce Richardson
56699a2dd95SBruce Richardson mbufs = (struct rte_mbuf **)vec->mbufs;
56799a2dd95SBruce Richardson if (vec->attr_valid) {
56899a2dd95SBruce Richardson port = vec->port;
56999a2dd95SBruce Richardson queue = vec->queue;
57099a2dd95SBruce Richardson tqi = txa_service_queue(txa, port, queue);
5713c3328aeSNaga Harish K S V if (unlikely(tqi == NULL || !tqi->added || tqi->stopped)) {
5720fbb55efSPavan Nikhilesh rte_pktmbuf_free_bulk(&mbufs[vec->elem_offset],
5730fbb55efSPavan Nikhilesh vec->nb_elem);
57499a2dd95SBruce Richardson rte_mempool_put(rte_mempool_from_obj(vec), vec);
57599a2dd95SBruce Richardson return 0;
57699a2dd95SBruce Richardson }
57799a2dd95SBruce Richardson for (i = 0; i < vec->nb_elem; i++) {
57899a2dd95SBruce Richardson nb_tx += rte_eth_tx_buffer(port, queue, tqi->tx_buf,
5790fbb55efSPavan Nikhilesh mbufs[i + vec->elem_offset]);
58099a2dd95SBruce Richardson }
58199a2dd95SBruce Richardson } else {
5820fbb55efSPavan Nikhilesh for (i = vec->elem_offset; i < vec->elem_offset + vec->nb_elem;
5830fbb55efSPavan Nikhilesh i++) {
58499a2dd95SBruce Richardson port = mbufs[i]->port;
58599a2dd95SBruce Richardson queue = rte_event_eth_tx_adapter_txq_get(mbufs[i]);
58699a2dd95SBruce Richardson tqi = txa_service_queue(txa, port, queue);
5873c3328aeSNaga Harish K S V if (unlikely(tqi == NULL || !tqi->added ||
5883c3328aeSNaga Harish K S V tqi->stopped)) {
58999a2dd95SBruce Richardson rte_pktmbuf_free(mbufs[i]);
59099a2dd95SBruce Richardson continue;
59199a2dd95SBruce Richardson }
59299a2dd95SBruce Richardson nb_tx += rte_eth_tx_buffer(port, queue, tqi->tx_buf,
59399a2dd95SBruce Richardson mbufs[i]);
59499a2dd95SBruce Richardson }
59599a2dd95SBruce Richardson }
59699a2dd95SBruce Richardson rte_mempool_put(rte_mempool_from_obj(vec), vec);
59799a2dd95SBruce Richardson
59899a2dd95SBruce Richardson return nb_tx;
59999a2dd95SBruce Richardson }
60099a2dd95SBruce Richardson
60199a2dd95SBruce Richardson static void
txa_service_tx(struct txa_service_data * txa,struct rte_event * ev,uint32_t n)60299a2dd95SBruce Richardson txa_service_tx(struct txa_service_data *txa, struct rte_event *ev,
60399a2dd95SBruce Richardson uint32_t n)
60499a2dd95SBruce Richardson {
60599a2dd95SBruce Richardson uint32_t i;
60699a2dd95SBruce Richardson uint16_t nb_tx;
60799a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats *stats;
60899a2dd95SBruce Richardson
60999a2dd95SBruce Richardson stats = &txa->stats;
61099a2dd95SBruce Richardson
61199a2dd95SBruce Richardson nb_tx = 0;
61299a2dd95SBruce Richardson for (i = 0; i < n; i++) {
61399a2dd95SBruce Richardson uint16_t port;
61499a2dd95SBruce Richardson uint16_t queue;
61599a2dd95SBruce Richardson struct txa_service_queue_info *tqi;
61699a2dd95SBruce Richardson
61799a2dd95SBruce Richardson if (!(ev[i].event_type & RTE_EVENT_TYPE_VECTOR)) {
61899a2dd95SBruce Richardson struct rte_mbuf *m;
61999a2dd95SBruce Richardson
62099a2dd95SBruce Richardson m = ev[i].mbuf;
62199a2dd95SBruce Richardson port = m->port;
62299a2dd95SBruce Richardson queue = rte_event_eth_tx_adapter_txq_get(m);
62399a2dd95SBruce Richardson
62499a2dd95SBruce Richardson tqi = txa_service_queue(txa, port, queue);
6253c3328aeSNaga Harish K S V if (unlikely(tqi == NULL || !tqi->added ||
6263c3328aeSNaga Harish K S V tqi->stopped)) {
62799a2dd95SBruce Richardson rte_pktmbuf_free(m);
62899a2dd95SBruce Richardson continue;
62999a2dd95SBruce Richardson }
63099a2dd95SBruce Richardson
63199a2dd95SBruce Richardson nb_tx += rte_eth_tx_buffer(port, queue, tqi->tx_buf, m);
63299a2dd95SBruce Richardson } else {
63399a2dd95SBruce Richardson nb_tx += txa_process_event_vector(txa, ev[i].vec);
63499a2dd95SBruce Richardson }
63599a2dd95SBruce Richardson }
63699a2dd95SBruce Richardson
63799a2dd95SBruce Richardson stats->tx_packets += nb_tx;
63899a2dd95SBruce Richardson }
63999a2dd95SBruce Richardson
64099a2dd95SBruce Richardson static int32_t
txa_service_func(void * args)64199a2dd95SBruce Richardson txa_service_func(void *args)
64299a2dd95SBruce Richardson {
64399a2dd95SBruce Richardson struct txa_service_data *txa = args;
64499a2dd95SBruce Richardson uint8_t dev_id;
64599a2dd95SBruce Richardson uint8_t port;
64635d05235SMattias Rönnblom int ret = -EAGAIN;
64799a2dd95SBruce Richardson uint16_t n;
64899a2dd95SBruce Richardson uint32_t nb_tx, max_nb_tx;
64999a2dd95SBruce Richardson struct rte_event ev[TXA_BATCH_SIZE];
65099a2dd95SBruce Richardson
65199a2dd95SBruce Richardson dev_id = txa->eventdev_id;
65299a2dd95SBruce Richardson max_nb_tx = txa->max_nb_tx;
65399a2dd95SBruce Richardson port = txa->port_id;
65499a2dd95SBruce Richardson
65599a2dd95SBruce Richardson if (txa->nb_queues == 0)
65635d05235SMattias Rönnblom return ret;
65799a2dd95SBruce Richardson
65899a2dd95SBruce Richardson if (!rte_spinlock_trylock(&txa->tx_lock))
65935d05235SMattias Rönnblom return ret;
66099a2dd95SBruce Richardson
66199a2dd95SBruce Richardson for (nb_tx = 0; nb_tx < max_nb_tx; nb_tx += n) {
66299a2dd95SBruce Richardson
66399a2dd95SBruce Richardson n = rte_event_dequeue_burst(dev_id, port, ev, RTE_DIM(ev), 0);
66499a2dd95SBruce Richardson if (!n)
66599a2dd95SBruce Richardson break;
66699a2dd95SBruce Richardson txa_service_tx(txa, ev, n);
66735d05235SMattias Rönnblom ret = 0;
66899a2dd95SBruce Richardson }
66999a2dd95SBruce Richardson
6701d176c7aSNaga Harish K S V if (txa->loop_cnt++ == txa->flush_threshold) {
67199a2dd95SBruce Richardson
67299a2dd95SBruce Richardson struct txa_service_ethdev *tdi;
67399a2dd95SBruce Richardson struct txa_service_queue_info *tqi;
67499a2dd95SBruce Richardson struct rte_eth_dev *dev;
67599a2dd95SBruce Richardson uint16_t i;
67699a2dd95SBruce Richardson
6771d176c7aSNaga Harish K S V txa->loop_cnt = 0;
67899a2dd95SBruce Richardson tdi = txa->txa_ethdev;
67999a2dd95SBruce Richardson nb_tx = 0;
68099a2dd95SBruce Richardson
68199a2dd95SBruce Richardson RTE_ETH_FOREACH_DEV(i) {
68299a2dd95SBruce Richardson uint16_t q;
68399a2dd95SBruce Richardson
684a870c7e8SNaga Harish K S V if (i >= txa->dev_count)
68599a2dd95SBruce Richardson break;
68699a2dd95SBruce Richardson
68799a2dd95SBruce Richardson dev = tdi[i].dev;
68899a2dd95SBruce Richardson if (tdi[i].nb_queues == 0)
68999a2dd95SBruce Richardson continue;
69099a2dd95SBruce Richardson for (q = 0; q < dev->data->nb_tx_queues; q++) {
69199a2dd95SBruce Richardson
69299a2dd95SBruce Richardson tqi = txa_service_queue(txa, i, q);
6933c3328aeSNaga Harish K S V if (unlikely(tqi == NULL || !tqi->added ||
6943c3328aeSNaga Harish K S V tqi->stopped))
69599a2dd95SBruce Richardson continue;
69699a2dd95SBruce Richardson
69799a2dd95SBruce Richardson nb_tx += rte_eth_tx_buffer_flush(i, q,
69899a2dd95SBruce Richardson tqi->tx_buf);
69999a2dd95SBruce Richardson }
70099a2dd95SBruce Richardson }
70199a2dd95SBruce Richardson
70235d05235SMattias Rönnblom if (likely(nb_tx > 0)) {
70399a2dd95SBruce Richardson txa->stats.tx_packets += nb_tx;
70435d05235SMattias Rönnblom ret = 0;
70535d05235SMattias Rönnblom }
70699a2dd95SBruce Richardson }
70799a2dd95SBruce Richardson rte_spinlock_unlock(&txa->tx_lock);
70835d05235SMattias Rönnblom return ret;
70999a2dd95SBruce Richardson }
71099a2dd95SBruce Richardson
71199a2dd95SBruce Richardson static int
txa_service_adapter_create(uint8_t id,struct rte_eventdev * dev,struct rte_event_port_conf * port_conf)71299a2dd95SBruce Richardson txa_service_adapter_create(uint8_t id, struct rte_eventdev *dev,
71399a2dd95SBruce Richardson struct rte_event_port_conf *port_conf)
71499a2dd95SBruce Richardson {
71599a2dd95SBruce Richardson struct txa_service_data *txa;
71699a2dd95SBruce Richardson struct rte_event_port_conf *cb_conf;
71799a2dd95SBruce Richardson int ret;
71899a2dd95SBruce Richardson
71999a2dd95SBruce Richardson cb_conf = rte_malloc(NULL, sizeof(*cb_conf), 0);
72099a2dd95SBruce Richardson if (cb_conf == NULL)
72199a2dd95SBruce Richardson return -ENOMEM;
72299a2dd95SBruce Richardson
72399a2dd95SBruce Richardson *cb_conf = *port_conf;
72499a2dd95SBruce Richardson ret = txa_service_adapter_create_ext(id, dev, txa_service_conf_cb,
72599a2dd95SBruce Richardson cb_conf);
72699a2dd95SBruce Richardson if (ret) {
72799a2dd95SBruce Richardson rte_free(cb_conf);
72899a2dd95SBruce Richardson return ret;
72999a2dd95SBruce Richardson }
73099a2dd95SBruce Richardson
73199a2dd95SBruce Richardson txa = txa_service_id_to_data(id);
73299a2dd95SBruce Richardson txa->conf_free = 1;
73399a2dd95SBruce Richardson return ret;
73499a2dd95SBruce Richardson }
73599a2dd95SBruce Richardson
73699a2dd95SBruce Richardson static int
txa_service_adapter_create_ext(uint8_t id,struct rte_eventdev * dev,rte_event_eth_tx_adapter_conf_cb conf_cb,void * conf_arg)73799a2dd95SBruce Richardson txa_service_adapter_create_ext(uint8_t id, struct rte_eventdev *dev,
73899a2dd95SBruce Richardson rte_event_eth_tx_adapter_conf_cb conf_cb,
73999a2dd95SBruce Richardson void *conf_arg)
74099a2dd95SBruce Richardson {
74199a2dd95SBruce Richardson struct txa_service_data *txa;
74299a2dd95SBruce Richardson int socket_id;
74399a2dd95SBruce Richardson char mem_name[TXA_SERVICE_NAME_LEN];
74499a2dd95SBruce Richardson int ret;
74599a2dd95SBruce Richardson
74699a2dd95SBruce Richardson if (conf_cb == NULL)
74799a2dd95SBruce Richardson return -EINVAL;
74899a2dd95SBruce Richardson
74999a2dd95SBruce Richardson socket_id = dev->data->socket_id;
75099a2dd95SBruce Richardson snprintf(mem_name, TXA_MEM_NAME_LEN,
75199a2dd95SBruce Richardson "rte_event_eth_txa_%d",
75299a2dd95SBruce Richardson id);
75399a2dd95SBruce Richardson
75499a2dd95SBruce Richardson ret = txa_service_data_init();
75599a2dd95SBruce Richardson if (ret != 0)
75699a2dd95SBruce Richardson return ret;
75799a2dd95SBruce Richardson
75899a2dd95SBruce Richardson txa = rte_zmalloc_socket(mem_name,
75999a2dd95SBruce Richardson sizeof(*txa),
76099a2dd95SBruce Richardson RTE_CACHE_LINE_SIZE, socket_id);
76199a2dd95SBruce Richardson if (txa == NULL) {
76299a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("failed to get mem for tx adapter");
76399a2dd95SBruce Richardson return -ENOMEM;
76499a2dd95SBruce Richardson }
76599a2dd95SBruce Richardson
76699a2dd95SBruce Richardson txa->id = id;
76799a2dd95SBruce Richardson txa->eventdev_id = dev->data->dev_id;
76899a2dd95SBruce Richardson txa->socket_id = socket_id;
76999a2dd95SBruce Richardson strncpy(txa->mem_name, mem_name, TXA_SERVICE_NAME_LEN);
77099a2dd95SBruce Richardson txa->conf_cb = conf_cb;
77199a2dd95SBruce Richardson txa->conf_arg = conf_arg;
77299a2dd95SBruce Richardson txa->service_id = TXA_INVALID_SERVICE_ID;
77399a2dd95SBruce Richardson rte_spinlock_init(&txa->tx_lock);
77499a2dd95SBruce Richardson txa_service_data_array[id] = txa;
7751d176c7aSNaga Harish K S V txa->flush_threshold = TXA_FLUSH_THRESHOLD;
77699a2dd95SBruce Richardson
77799a2dd95SBruce Richardson return 0;
77899a2dd95SBruce Richardson }
77999a2dd95SBruce Richardson
78099a2dd95SBruce Richardson static int
txa_service_event_port_get(uint8_t id,uint8_t * port)78199a2dd95SBruce Richardson txa_service_event_port_get(uint8_t id, uint8_t *port)
78299a2dd95SBruce Richardson {
78399a2dd95SBruce Richardson struct txa_service_data *txa;
78499a2dd95SBruce Richardson
78599a2dd95SBruce Richardson txa = txa_service_id_to_data(id);
78699a2dd95SBruce Richardson if (txa->service_id == TXA_INVALID_SERVICE_ID)
78799a2dd95SBruce Richardson return -ENODEV;
78899a2dd95SBruce Richardson
78999a2dd95SBruce Richardson *port = txa->port_id;
79099a2dd95SBruce Richardson return 0;
79199a2dd95SBruce Richardson }
79299a2dd95SBruce Richardson
79399a2dd95SBruce Richardson static int
txa_service_adapter_free(uint8_t id)79499a2dd95SBruce Richardson txa_service_adapter_free(uint8_t id)
79599a2dd95SBruce Richardson {
79699a2dd95SBruce Richardson struct txa_service_data *txa;
79799a2dd95SBruce Richardson
79899a2dd95SBruce Richardson txa = txa_service_id_to_data(id);
79999a2dd95SBruce Richardson if (txa->nb_queues) {
80099a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("%" PRIu16 " Tx queues not deleted",
80199a2dd95SBruce Richardson txa->nb_queues);
80299a2dd95SBruce Richardson return -EBUSY;
80399a2dd95SBruce Richardson }
80499a2dd95SBruce Richardson
80599a2dd95SBruce Richardson if (txa->conf_free)
80699a2dd95SBruce Richardson rte_free(txa->conf_arg);
80799a2dd95SBruce Richardson rte_free(txa);
80899a2dd95SBruce Richardson return 0;
80999a2dd95SBruce Richardson }
81099a2dd95SBruce Richardson
81199a2dd95SBruce Richardson static int
txa_service_queue_add(uint8_t id,__rte_unused struct rte_eventdev * dev,const struct rte_eth_dev * eth_dev,int32_t tx_queue_id)81299a2dd95SBruce Richardson txa_service_queue_add(uint8_t id,
81399a2dd95SBruce Richardson __rte_unused struct rte_eventdev *dev,
81499a2dd95SBruce Richardson const struct rte_eth_dev *eth_dev,
81599a2dd95SBruce Richardson int32_t tx_queue_id)
81699a2dd95SBruce Richardson {
81799a2dd95SBruce Richardson struct txa_service_data *txa;
81899a2dd95SBruce Richardson struct txa_service_ethdev *tdi;
81999a2dd95SBruce Richardson struct txa_service_queue_info *tqi;
82099a2dd95SBruce Richardson struct rte_eth_dev_tx_buffer *tb;
82199a2dd95SBruce Richardson struct txa_retry *txa_retry;
82299a2dd95SBruce Richardson int ret = 0;
82399a2dd95SBruce Richardson
82499a2dd95SBruce Richardson txa = txa_service_id_to_data(id);
82599a2dd95SBruce Richardson
82699a2dd95SBruce Richardson if (tx_queue_id == -1) {
82799a2dd95SBruce Richardson int nb_queues;
82899a2dd95SBruce Richardson uint16_t i, j;
82999a2dd95SBruce Richardson uint16_t *qdone;
83099a2dd95SBruce Richardson
83199a2dd95SBruce Richardson nb_queues = eth_dev->data->nb_tx_queues;
83299a2dd95SBruce Richardson if (txa->dev_count > eth_dev->data->port_id) {
83399a2dd95SBruce Richardson tdi = &txa->txa_ethdev[eth_dev->data->port_id];
83499a2dd95SBruce Richardson nb_queues -= tdi->nb_queues;
83599a2dd95SBruce Richardson }
83699a2dd95SBruce Richardson
83799a2dd95SBruce Richardson qdone = rte_zmalloc(txa->mem_name,
83899a2dd95SBruce Richardson nb_queues * sizeof(*qdone), 0);
83999a2dd95SBruce Richardson if (qdone == NULL)
84099a2dd95SBruce Richardson return -ENOMEM;
84199a2dd95SBruce Richardson j = 0;
84299a2dd95SBruce Richardson for (i = 0; i < nb_queues; i++) {
84399a2dd95SBruce Richardson if (txa_service_is_queue_added(txa, eth_dev, i))
84499a2dd95SBruce Richardson continue;
84599a2dd95SBruce Richardson ret = txa_service_queue_add(id, dev, eth_dev, i);
84699a2dd95SBruce Richardson if (ret == 0)
84799a2dd95SBruce Richardson qdone[j++] = i;
84899a2dd95SBruce Richardson else
84999a2dd95SBruce Richardson break;
85099a2dd95SBruce Richardson }
85199a2dd95SBruce Richardson
85299a2dd95SBruce Richardson if (i != nb_queues) {
85399a2dd95SBruce Richardson for (i = 0; i < j; i++)
85499a2dd95SBruce Richardson txa_service_queue_del(id, eth_dev, qdone[i]);
85599a2dd95SBruce Richardson }
85699a2dd95SBruce Richardson rte_free(qdone);
85799a2dd95SBruce Richardson return ret;
85899a2dd95SBruce Richardson }
85999a2dd95SBruce Richardson
86099a2dd95SBruce Richardson ret = txa_service_register(txa);
86199a2dd95SBruce Richardson if (ret)
86299a2dd95SBruce Richardson return ret;
86399a2dd95SBruce Richardson
86499a2dd95SBruce Richardson rte_spinlock_lock(&txa->tx_lock);
86599a2dd95SBruce Richardson
866bd0a32d1SNaga Harish K S V if (txa_service_is_queue_added(txa, eth_dev, tx_queue_id))
867bd0a32d1SNaga Harish K S V goto ret_unlock;
86899a2dd95SBruce Richardson
86999a2dd95SBruce Richardson ret = txa_service_queue_array_alloc(txa, eth_dev->data->port_id);
87099a2dd95SBruce Richardson if (ret)
87199a2dd95SBruce Richardson goto err_unlock;
87299a2dd95SBruce Richardson
87399a2dd95SBruce Richardson tb = txa_service_tx_buf_alloc(txa, eth_dev);
87499a2dd95SBruce Richardson if (tb == NULL)
87599a2dd95SBruce Richardson goto err_unlock;
87699a2dd95SBruce Richardson
87799a2dd95SBruce Richardson tdi = &txa->txa_ethdev[eth_dev->data->port_id];
87899a2dd95SBruce Richardson tqi = txa_service_queue(txa, eth_dev->data->port_id, tx_queue_id);
879bd0a32d1SNaga Harish K S V if (tqi == NULL)
880bd0a32d1SNaga Harish K S V goto err_unlock;
88199a2dd95SBruce Richardson
88299a2dd95SBruce Richardson txa_retry = &tqi->txa_retry;
88399a2dd95SBruce Richardson txa_retry->id = txa->id;
88499a2dd95SBruce Richardson txa_retry->port_id = eth_dev->data->port_id;
88599a2dd95SBruce Richardson txa_retry->tx_queue = tx_queue_id;
88699a2dd95SBruce Richardson
88799a2dd95SBruce Richardson rte_eth_tx_buffer_init(tb, TXA_BATCH_SIZE);
88899a2dd95SBruce Richardson rte_eth_tx_buffer_set_err_callback(tb,
88999a2dd95SBruce Richardson txa_service_buffer_retry, txa_retry);
89099a2dd95SBruce Richardson
89199a2dd95SBruce Richardson tqi->tx_buf = tb;
89299a2dd95SBruce Richardson tqi->added = 1;
8933c3328aeSNaga Harish K S V tqi->stopped = false;
89499a2dd95SBruce Richardson tdi->nb_queues++;
89599a2dd95SBruce Richardson txa->nb_queues++;
89699a2dd95SBruce Richardson
897bd0a32d1SNaga Harish K S V ret_unlock:
898bd0a32d1SNaga Harish K S V rte_spinlock_unlock(&txa->tx_lock);
899bd0a32d1SNaga Harish K S V return 0;
900bd0a32d1SNaga Harish K S V
90199a2dd95SBruce Richardson err_unlock:
90299a2dd95SBruce Richardson if (txa->nb_queues == 0) {
90399a2dd95SBruce Richardson txa_service_queue_array_free(txa,
90499a2dd95SBruce Richardson eth_dev->data->port_id);
90599a2dd95SBruce Richardson txa_service_unregister(txa);
90699a2dd95SBruce Richardson }
90799a2dd95SBruce Richardson
90899a2dd95SBruce Richardson rte_spinlock_unlock(&txa->tx_lock);
909bd0a32d1SNaga Harish K S V return -1;
91099a2dd95SBruce Richardson }
91199a2dd95SBruce Richardson
9123c3328aeSNaga Harish K S V static inline void
txa_txq_buffer_drain(struct txa_service_queue_info * tqi)9133c3328aeSNaga Harish K S V txa_txq_buffer_drain(struct txa_service_queue_info *tqi)
9143c3328aeSNaga Harish K S V {
9153c3328aeSNaga Harish K S V struct rte_eth_dev_tx_buffer *b;
9163c3328aeSNaga Harish K S V uint16_t i;
9173c3328aeSNaga Harish K S V
9183c3328aeSNaga Harish K S V b = tqi->tx_buf;
9193c3328aeSNaga Harish K S V
9203c3328aeSNaga Harish K S V for (i = 0; i < b->length; i++)
9213c3328aeSNaga Harish K S V rte_pktmbuf_free(b->pkts[i]);
9223c3328aeSNaga Harish K S V
9233c3328aeSNaga Harish K S V b->length = 0;
9243c3328aeSNaga Harish K S V }
9253c3328aeSNaga Harish K S V
92699a2dd95SBruce Richardson static int
txa_service_queue_del(uint8_t id,const struct rte_eth_dev * dev,int32_t tx_queue_id)92799a2dd95SBruce Richardson txa_service_queue_del(uint8_t id,
92899a2dd95SBruce Richardson const struct rte_eth_dev *dev,
92999a2dd95SBruce Richardson int32_t tx_queue_id)
93099a2dd95SBruce Richardson {
93199a2dd95SBruce Richardson struct txa_service_data *txa;
93299a2dd95SBruce Richardson struct txa_service_queue_info *tqi;
93399a2dd95SBruce Richardson struct rte_eth_dev_tx_buffer *tb;
93499a2dd95SBruce Richardson uint16_t port_id;
93599a2dd95SBruce Richardson
93699a2dd95SBruce Richardson txa = txa_service_id_to_data(id);
93799a2dd95SBruce Richardson port_id = dev->data->port_id;
93899a2dd95SBruce Richardson
93999a2dd95SBruce Richardson if (tx_queue_id == -1) {
94099a2dd95SBruce Richardson uint16_t i, q, nb_queues;
94199a2dd95SBruce Richardson int ret = 0;
94299a2dd95SBruce Richardson
94375c5bfc3SNaga Harish K S V if (txa->txa_ethdev == NULL)
94475c5bfc3SNaga Harish K S V return 0;
945741b499eSNaga Harish K S V nb_queues = txa->txa_ethdev[port_id].nb_queues;
94699a2dd95SBruce Richardson if (nb_queues == 0)
94799a2dd95SBruce Richardson return 0;
94899a2dd95SBruce Richardson
94999a2dd95SBruce Richardson i = 0;
95099a2dd95SBruce Richardson q = 0;
95199a2dd95SBruce Richardson tqi = txa->txa_ethdev[port_id].queues;
95299a2dd95SBruce Richardson
95399a2dd95SBruce Richardson while (i < nb_queues) {
95499a2dd95SBruce Richardson
95599a2dd95SBruce Richardson if (tqi[q].added) {
95699a2dd95SBruce Richardson ret = txa_service_queue_del(id, dev, q);
95775c5bfc3SNaga Harish K S V i++;
95899a2dd95SBruce Richardson if (ret != 0)
95999a2dd95SBruce Richardson break;
96099a2dd95SBruce Richardson }
96199a2dd95SBruce Richardson q++;
96299a2dd95SBruce Richardson }
96399a2dd95SBruce Richardson return ret;
96499a2dd95SBruce Richardson }
96599a2dd95SBruce Richardson
96699a2dd95SBruce Richardson txa = txa_service_id_to_data(id);
96799a2dd95SBruce Richardson
968881d4b4dSNaga Harish K S V rte_spinlock_lock(&txa->tx_lock);
96999a2dd95SBruce Richardson tqi = txa_service_queue(txa, port_id, tx_queue_id);
97099a2dd95SBruce Richardson if (tqi == NULL || !tqi->added)
971881d4b4dSNaga Harish K S V goto ret_unlock;
97299a2dd95SBruce Richardson
9733c3328aeSNaga Harish K S V /* Drain the buffered mbufs */
9743c3328aeSNaga Harish K S V txa_txq_buffer_drain(tqi);
97599a2dd95SBruce Richardson tb = tqi->tx_buf;
97699a2dd95SBruce Richardson tqi->added = 0;
97799a2dd95SBruce Richardson tqi->tx_buf = NULL;
97899a2dd95SBruce Richardson rte_free(tb);
97999a2dd95SBruce Richardson txa->nb_queues--;
98099a2dd95SBruce Richardson txa->txa_ethdev[port_id].nb_queues--;
98199a2dd95SBruce Richardson
98299a2dd95SBruce Richardson txa_service_queue_array_free(txa, port_id);
983881d4b4dSNaga Harish K S V
984881d4b4dSNaga Harish K S V ret_unlock:
985881d4b4dSNaga Harish K S V rte_spinlock_unlock(&txa->tx_lock);
98699a2dd95SBruce Richardson return 0;
98799a2dd95SBruce Richardson }
98899a2dd95SBruce Richardson
98999a2dd95SBruce Richardson static int
txa_service_id_get(uint8_t id,uint32_t * service_id)99099a2dd95SBruce Richardson txa_service_id_get(uint8_t id, uint32_t *service_id)
99199a2dd95SBruce Richardson {
99299a2dd95SBruce Richardson struct txa_service_data *txa;
99399a2dd95SBruce Richardson
99499a2dd95SBruce Richardson txa = txa_service_id_to_data(id);
99599a2dd95SBruce Richardson if (txa->service_id == TXA_INVALID_SERVICE_ID)
99699a2dd95SBruce Richardson return -ESRCH;
99799a2dd95SBruce Richardson
99899a2dd95SBruce Richardson if (service_id == NULL)
99999a2dd95SBruce Richardson return -EINVAL;
100099a2dd95SBruce Richardson
100199a2dd95SBruce Richardson *service_id = txa->service_id;
10027f2d9df6SAmit Prakash Shukla
10037f2d9df6SAmit Prakash Shukla rte_eventdev_trace_eth_tx_adapter_service_id_get(id, *service_id);
100499a2dd95SBruce Richardson return 0;
100599a2dd95SBruce Richardson }
100699a2dd95SBruce Richardson
100799a2dd95SBruce Richardson static int
txa_service_start(uint8_t id)100899a2dd95SBruce Richardson txa_service_start(uint8_t id)
100999a2dd95SBruce Richardson {
101099a2dd95SBruce Richardson return txa_service_ctrl(id, 1);
101199a2dd95SBruce Richardson }
101299a2dd95SBruce Richardson
101399a2dd95SBruce Richardson static int
txa_service_stats_get(uint8_t id,struct rte_event_eth_tx_adapter_stats * stats)101499a2dd95SBruce Richardson txa_service_stats_get(uint8_t id,
101599a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats *stats)
101699a2dd95SBruce Richardson {
101799a2dd95SBruce Richardson struct txa_service_data *txa;
101899a2dd95SBruce Richardson
101999a2dd95SBruce Richardson txa = txa_service_id_to_data(id);
102099a2dd95SBruce Richardson *stats = txa->stats;
102199a2dd95SBruce Richardson return 0;
102299a2dd95SBruce Richardson }
102399a2dd95SBruce Richardson
102499a2dd95SBruce Richardson static int
txa_service_stats_reset(uint8_t id)102599a2dd95SBruce Richardson txa_service_stats_reset(uint8_t id)
102699a2dd95SBruce Richardson {
102799a2dd95SBruce Richardson struct txa_service_data *txa;
102899a2dd95SBruce Richardson
102999a2dd95SBruce Richardson txa = txa_service_id_to_data(id);
103099a2dd95SBruce Richardson memset(&txa->stats, 0, sizeof(txa->stats));
103199a2dd95SBruce Richardson return 0;
103299a2dd95SBruce Richardson }
103399a2dd95SBruce Richardson
103499a2dd95SBruce Richardson static int
txa_service_stop(uint8_t id)103599a2dd95SBruce Richardson txa_service_stop(uint8_t id)
103699a2dd95SBruce Richardson {
103799a2dd95SBruce Richardson return txa_service_ctrl(id, 0);
103899a2dd95SBruce Richardson }
103999a2dd95SBruce Richardson
104099a2dd95SBruce Richardson
104199a2dd95SBruce Richardson int
rte_event_eth_tx_adapter_create(uint8_t id,uint8_t dev_id,struct rte_event_port_conf * port_conf)104299a2dd95SBruce Richardson rte_event_eth_tx_adapter_create(uint8_t id, uint8_t dev_id,
104399a2dd95SBruce Richardson struct rte_event_port_conf *port_conf)
104499a2dd95SBruce Richardson {
104599a2dd95SBruce Richardson struct rte_eventdev *dev;
104699a2dd95SBruce Richardson int ret;
104799a2dd95SBruce Richardson
104899a2dd95SBruce Richardson if (port_conf == NULL)
104999a2dd95SBruce Richardson return -EINVAL;
105099a2dd95SBruce Richardson
105199a2dd95SBruce Richardson RTE_EVENT_ETH_TX_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
105299a2dd95SBruce Richardson RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
105399a2dd95SBruce Richardson
105499a2dd95SBruce Richardson dev = &rte_eventdevs[dev_id];
105599a2dd95SBruce Richardson
105699a2dd95SBruce Richardson ret = txa_init();
105799a2dd95SBruce Richardson if (ret != 0)
105899a2dd95SBruce Richardson return ret;
105999a2dd95SBruce Richardson
106099a2dd95SBruce Richardson if (txa_adapter_exist(id))
106199a2dd95SBruce Richardson return -EEXIST;
106299a2dd95SBruce Richardson
106399a2dd95SBruce Richardson txa_dev_id_array[id] = dev_id;
106499a2dd95SBruce Richardson if (txa_dev_adapter_create(id))
106599a2dd95SBruce Richardson ret = txa_dev_adapter_create(id)(id, dev);
106699a2dd95SBruce Richardson
106799a2dd95SBruce Richardson if (ret != 0) {
106899a2dd95SBruce Richardson txa_dev_id_array[id] = TXA_INVALID_DEV_ID;
106999a2dd95SBruce Richardson return ret;
107099a2dd95SBruce Richardson }
107199a2dd95SBruce Richardson
107299a2dd95SBruce Richardson ret = txa_service_adapter_create(id, dev, port_conf);
107399a2dd95SBruce Richardson if (ret != 0) {
107499a2dd95SBruce Richardson if (txa_dev_adapter_free(id))
107599a2dd95SBruce Richardson txa_dev_adapter_free(id)(id, dev);
107699a2dd95SBruce Richardson txa_dev_id_array[id] = TXA_INVALID_DEV_ID;
107799a2dd95SBruce Richardson return ret;
107899a2dd95SBruce Richardson }
107999a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_create(id, dev_id, NULL, port_conf,
108099a2dd95SBruce Richardson ret);
108199a2dd95SBruce Richardson txa_dev_id_array[id] = dev_id;
108299a2dd95SBruce Richardson return 0;
108399a2dd95SBruce Richardson }
108499a2dd95SBruce Richardson
108599a2dd95SBruce Richardson int
rte_event_eth_tx_adapter_create_ext(uint8_t id,uint8_t dev_id,rte_event_eth_tx_adapter_conf_cb conf_cb,void * conf_arg)108699a2dd95SBruce Richardson rte_event_eth_tx_adapter_create_ext(uint8_t id, uint8_t dev_id,
108799a2dd95SBruce Richardson rte_event_eth_tx_adapter_conf_cb conf_cb,
108899a2dd95SBruce Richardson void *conf_arg)
108999a2dd95SBruce Richardson {
109099a2dd95SBruce Richardson struct rte_eventdev *dev;
109199a2dd95SBruce Richardson int ret;
109299a2dd95SBruce Richardson
109399a2dd95SBruce Richardson RTE_EVENT_ETH_TX_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
109499a2dd95SBruce Richardson RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
109599a2dd95SBruce Richardson
109699a2dd95SBruce Richardson ret = txa_init();
109799a2dd95SBruce Richardson if (ret != 0)
109899a2dd95SBruce Richardson return ret;
109999a2dd95SBruce Richardson
110099a2dd95SBruce Richardson if (txa_adapter_exist(id))
110199a2dd95SBruce Richardson return -EINVAL;
110299a2dd95SBruce Richardson
110399a2dd95SBruce Richardson dev = &rte_eventdevs[dev_id];
110499a2dd95SBruce Richardson
110599a2dd95SBruce Richardson txa_dev_id_array[id] = dev_id;
110699a2dd95SBruce Richardson if (txa_dev_adapter_create_ext(id))
110799a2dd95SBruce Richardson ret = txa_dev_adapter_create_ext(id)(id, dev);
110899a2dd95SBruce Richardson
110999a2dd95SBruce Richardson if (ret != 0) {
111099a2dd95SBruce Richardson txa_dev_id_array[id] = TXA_INVALID_DEV_ID;
111199a2dd95SBruce Richardson return ret;
111299a2dd95SBruce Richardson }
111399a2dd95SBruce Richardson
111499a2dd95SBruce Richardson ret = txa_service_adapter_create_ext(id, dev, conf_cb, conf_arg);
111599a2dd95SBruce Richardson if (ret != 0) {
111699a2dd95SBruce Richardson if (txa_dev_adapter_free(id))
111799a2dd95SBruce Richardson txa_dev_adapter_free(id)(id, dev);
111899a2dd95SBruce Richardson txa_dev_id_array[id] = TXA_INVALID_DEV_ID;
111999a2dd95SBruce Richardson return ret;
112099a2dd95SBruce Richardson }
112199a2dd95SBruce Richardson
112299a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_create(id, dev_id, conf_cb, conf_arg,
112399a2dd95SBruce Richardson ret);
112499a2dd95SBruce Richardson txa_dev_id_array[id] = dev_id;
112599a2dd95SBruce Richardson return 0;
112699a2dd95SBruce Richardson }
112799a2dd95SBruce Richardson
112899a2dd95SBruce Richardson
112999a2dd95SBruce Richardson int
rte_event_eth_tx_adapter_event_port_get(uint8_t id,uint8_t * event_port_id)113099a2dd95SBruce Richardson rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id)
113199a2dd95SBruce Richardson {
11327f2d9df6SAmit Prakash Shukla rte_eventdev_trace_eth_tx_adapter_event_port_get(id);
11337f2d9df6SAmit Prakash Shukla
113499a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id);
113599a2dd95SBruce Richardson
113699a2dd95SBruce Richardson return txa_service_event_port_get(id, event_port_id);
113799a2dd95SBruce Richardson }
113899a2dd95SBruce Richardson
113999a2dd95SBruce Richardson int
rte_event_eth_tx_adapter_free(uint8_t id)114099a2dd95SBruce Richardson rte_event_eth_tx_adapter_free(uint8_t id)
114199a2dd95SBruce Richardson {
114299a2dd95SBruce Richardson int ret;
114399a2dd95SBruce Richardson
114499a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id);
114599a2dd95SBruce Richardson
114699a2dd95SBruce Richardson ret = txa_dev_adapter_free(id) ?
114799a2dd95SBruce Richardson txa_dev_adapter_free(id)(id, txa_evdev(id)) :
114899a2dd95SBruce Richardson 0;
114999a2dd95SBruce Richardson
115099a2dd95SBruce Richardson if (ret == 0)
115199a2dd95SBruce Richardson ret = txa_service_adapter_free(id);
115299a2dd95SBruce Richardson txa_dev_id_array[id] = TXA_INVALID_DEV_ID;
115399a2dd95SBruce Richardson
115499a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_free(id, ret);
115599a2dd95SBruce Richardson return ret;
115699a2dd95SBruce Richardson }
115799a2dd95SBruce Richardson
115899a2dd95SBruce Richardson int
rte_event_eth_tx_adapter_queue_add(uint8_t id,uint16_t eth_dev_id,int32_t queue)115999a2dd95SBruce Richardson rte_event_eth_tx_adapter_queue_add(uint8_t id,
116099a2dd95SBruce Richardson uint16_t eth_dev_id,
116199a2dd95SBruce Richardson int32_t queue)
116299a2dd95SBruce Richardson {
116399a2dd95SBruce Richardson struct rte_eth_dev *eth_dev;
116499a2dd95SBruce Richardson int ret;
116599a2dd95SBruce Richardson uint32_t caps;
116699a2dd95SBruce Richardson
116799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(eth_dev_id, -EINVAL);
116899a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id);
116999a2dd95SBruce Richardson
117099a2dd95SBruce Richardson eth_dev = &rte_eth_devices[eth_dev_id];
117199a2dd95SBruce Richardson TXA_CHECK_TXQ(eth_dev, queue);
117299a2dd95SBruce Richardson
117399a2dd95SBruce Richardson caps = 0;
117499a2dd95SBruce Richardson if (txa_dev_caps_get(id))
117599a2dd95SBruce Richardson txa_dev_caps_get(id)(txa_evdev(id), eth_dev, &caps);
117699a2dd95SBruce Richardson
117799a2dd95SBruce Richardson if (caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)
117899a2dd95SBruce Richardson ret = txa_dev_queue_add(id) ?
117999a2dd95SBruce Richardson txa_dev_queue_add(id)(id,
118099a2dd95SBruce Richardson txa_evdev(id),
118199a2dd95SBruce Richardson eth_dev,
118299a2dd95SBruce Richardson queue) : 0;
118399a2dd95SBruce Richardson else
118499a2dd95SBruce Richardson ret = txa_service_queue_add(id, txa_evdev(id), eth_dev, queue);
118599a2dd95SBruce Richardson
118699a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_queue_add(id, eth_dev_id, queue,
118799a2dd95SBruce Richardson ret);
118899a2dd95SBruce Richardson return ret;
118999a2dd95SBruce Richardson }
119099a2dd95SBruce Richardson
119199a2dd95SBruce Richardson int
rte_event_eth_tx_adapter_queue_del(uint8_t id,uint16_t eth_dev_id,int32_t queue)119299a2dd95SBruce Richardson rte_event_eth_tx_adapter_queue_del(uint8_t id,
119399a2dd95SBruce Richardson uint16_t eth_dev_id,
119499a2dd95SBruce Richardson int32_t queue)
119599a2dd95SBruce Richardson {
119699a2dd95SBruce Richardson struct rte_eth_dev *eth_dev;
119799a2dd95SBruce Richardson int ret;
119899a2dd95SBruce Richardson uint32_t caps;
119999a2dd95SBruce Richardson
120099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(eth_dev_id, -EINVAL);
120199a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id);
120299a2dd95SBruce Richardson
120399a2dd95SBruce Richardson eth_dev = &rte_eth_devices[eth_dev_id];
120499a2dd95SBruce Richardson
120599a2dd95SBruce Richardson caps = 0;
120699a2dd95SBruce Richardson
120799a2dd95SBruce Richardson if (txa_dev_caps_get(id))
120899a2dd95SBruce Richardson txa_dev_caps_get(id)(txa_evdev(id), eth_dev, &caps);
120999a2dd95SBruce Richardson
121099a2dd95SBruce Richardson if (caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)
121199a2dd95SBruce Richardson ret = txa_dev_queue_del(id) ?
121299a2dd95SBruce Richardson txa_dev_queue_del(id)(id, txa_evdev(id),
121399a2dd95SBruce Richardson eth_dev,
121499a2dd95SBruce Richardson queue) : 0;
121599a2dd95SBruce Richardson else
121699a2dd95SBruce Richardson ret = txa_service_queue_del(id, eth_dev, queue);
121799a2dd95SBruce Richardson
121899a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_queue_del(id, eth_dev_id, queue,
121999a2dd95SBruce Richardson ret);
122099a2dd95SBruce Richardson return ret;
122199a2dd95SBruce Richardson }
122299a2dd95SBruce Richardson
122399a2dd95SBruce Richardson int
rte_event_eth_tx_adapter_service_id_get(uint8_t id,uint32_t * service_id)122499a2dd95SBruce Richardson rte_event_eth_tx_adapter_service_id_get(uint8_t id, uint32_t *service_id)
122599a2dd95SBruce Richardson {
122699a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id);
122799a2dd95SBruce Richardson
122899a2dd95SBruce Richardson return txa_service_id_get(id, service_id);
122999a2dd95SBruce Richardson }
123099a2dd95SBruce Richardson
123199a2dd95SBruce Richardson int
rte_event_eth_tx_adapter_start(uint8_t id)123299a2dd95SBruce Richardson rte_event_eth_tx_adapter_start(uint8_t id)
123399a2dd95SBruce Richardson {
123499a2dd95SBruce Richardson int ret;
123599a2dd95SBruce Richardson
123699a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id);
123799a2dd95SBruce Richardson
123899a2dd95SBruce Richardson ret = txa_dev_start(id) ? txa_dev_start(id)(id, txa_evdev(id)) : 0;
123999a2dd95SBruce Richardson if (ret == 0)
124099a2dd95SBruce Richardson ret = txa_service_start(id);
124199a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_start(id, ret);
124299a2dd95SBruce Richardson return ret;
124399a2dd95SBruce Richardson }
124499a2dd95SBruce Richardson
124599a2dd95SBruce Richardson int
rte_event_eth_tx_adapter_stats_get(uint8_t id,struct rte_event_eth_tx_adapter_stats * stats)124699a2dd95SBruce Richardson rte_event_eth_tx_adapter_stats_get(uint8_t id,
124799a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats *stats)
124899a2dd95SBruce Richardson {
124999a2dd95SBruce Richardson int ret;
125099a2dd95SBruce Richardson
125199a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id);
125299a2dd95SBruce Richardson
125399a2dd95SBruce Richardson if (stats == NULL)
125499a2dd95SBruce Richardson return -EINVAL;
125599a2dd95SBruce Richardson
125699a2dd95SBruce Richardson *stats = (struct rte_event_eth_tx_adapter_stats){0};
125799a2dd95SBruce Richardson
125899a2dd95SBruce Richardson ret = txa_dev_stats_get(id) ?
125999a2dd95SBruce Richardson txa_dev_stats_get(id)(id, txa_evdev(id), stats) : 0;
126099a2dd95SBruce Richardson
126199a2dd95SBruce Richardson if (ret == 0 && txa_service_id_get(id, NULL) != ESRCH) {
126299a2dd95SBruce Richardson if (txa_dev_stats_get(id)) {
126399a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats service_stats;
126499a2dd95SBruce Richardson
126599a2dd95SBruce Richardson ret = txa_service_stats_get(id, &service_stats);
126699a2dd95SBruce Richardson if (ret == 0) {
126799a2dd95SBruce Richardson stats->tx_retry += service_stats.tx_retry;
126899a2dd95SBruce Richardson stats->tx_packets += service_stats.tx_packets;
126999a2dd95SBruce Richardson stats->tx_dropped += service_stats.tx_dropped;
127099a2dd95SBruce Richardson }
127199a2dd95SBruce Richardson } else
127299a2dd95SBruce Richardson ret = txa_service_stats_get(id, stats);
127399a2dd95SBruce Richardson }
127499a2dd95SBruce Richardson
12757f2d9df6SAmit Prakash Shukla rte_eventdev_trace_eth_tx_adapter_stats_get(id, stats->tx_retry, stats->tx_packets,
12767f2d9df6SAmit Prakash Shukla stats->tx_dropped, ret);
12777f2d9df6SAmit Prakash Shukla
127899a2dd95SBruce Richardson return ret;
127999a2dd95SBruce Richardson }
128099a2dd95SBruce Richardson
128199a2dd95SBruce Richardson int
rte_event_eth_tx_adapter_stats_reset(uint8_t id)128299a2dd95SBruce Richardson rte_event_eth_tx_adapter_stats_reset(uint8_t id)
128399a2dd95SBruce Richardson {
128499a2dd95SBruce Richardson int ret;
128599a2dd95SBruce Richardson
128699a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id);
128799a2dd95SBruce Richardson
128899a2dd95SBruce Richardson ret = txa_dev_stats_reset(id) ?
128999a2dd95SBruce Richardson txa_dev_stats_reset(id)(id, txa_evdev(id)) : 0;
129099a2dd95SBruce Richardson if (ret == 0)
129199a2dd95SBruce Richardson ret = txa_service_stats_reset(id);
12927f2d9df6SAmit Prakash Shukla
12937f2d9df6SAmit Prakash Shukla rte_eventdev_trace_eth_tx_adapter_stats_reset(id, ret);
12947f2d9df6SAmit Prakash Shukla
129599a2dd95SBruce Richardson return ret;
129699a2dd95SBruce Richardson }
129799a2dd95SBruce Richardson
129899a2dd95SBruce Richardson int
rte_event_eth_tx_adapter_runtime_params_init(struct rte_event_eth_tx_adapter_runtime_params * txa_params)12991d176c7aSNaga Harish K S V rte_event_eth_tx_adapter_runtime_params_init(
13001d176c7aSNaga Harish K S V struct rte_event_eth_tx_adapter_runtime_params *txa_params)
13011d176c7aSNaga Harish K S V {
13021d176c7aSNaga Harish K S V if (txa_params == NULL)
13031d176c7aSNaga Harish K S V return -EINVAL;
13041d176c7aSNaga Harish K S V
13051d176c7aSNaga Harish K S V memset(txa_params, 0, sizeof(*txa_params));
13061d176c7aSNaga Harish K S V txa_params->max_nb_tx = TXA_MAX_NB_TX;
13071d176c7aSNaga Harish K S V txa_params->flush_threshold = TXA_FLUSH_THRESHOLD;
13081d176c7aSNaga Harish K S V
13091d176c7aSNaga Harish K S V return 0;
13101d176c7aSNaga Harish K S V }
13111d176c7aSNaga Harish K S V
13121d176c7aSNaga Harish K S V static int
txa_caps_check(struct txa_service_data * txa)131345ced711SNaga Harish K S V txa_caps_check(struct txa_service_data *txa)
13141d176c7aSNaga Harish K S V {
13151d176c7aSNaga Harish K S V if (!txa->dev_count)
13161d176c7aSNaga Harish K S V return -EINVAL;
13171d176c7aSNaga Harish K S V
131845ced711SNaga Harish K S V if (txa->service_id != TXA_INVALID_SERVICE_ID)
13191d176c7aSNaga Harish K S V return 0;
132045ced711SNaga Harish K S V
132145ced711SNaga Harish K S V return -ENOTSUP;
13221d176c7aSNaga Harish K S V }
13231d176c7aSNaga Harish K S V
13241d176c7aSNaga Harish K S V int
rte_event_eth_tx_adapter_runtime_params_set(uint8_t id,struct rte_event_eth_tx_adapter_runtime_params * txa_params)13251d176c7aSNaga Harish K S V rte_event_eth_tx_adapter_runtime_params_set(uint8_t id,
13261d176c7aSNaga Harish K S V struct rte_event_eth_tx_adapter_runtime_params *txa_params)
13271d176c7aSNaga Harish K S V {
13281d176c7aSNaga Harish K S V struct txa_service_data *txa;
13291d176c7aSNaga Harish K S V int ret;
13301d176c7aSNaga Harish K S V
13311d176c7aSNaga Harish K S V if (txa_lookup())
13321d176c7aSNaga Harish K S V return -ENOMEM;
13331d176c7aSNaga Harish K S V
13341d176c7aSNaga Harish K S V TXA_CHECK_OR_ERR_RET(id);
13351d176c7aSNaga Harish K S V
13361d176c7aSNaga Harish K S V if (txa_params == NULL)
13371d176c7aSNaga Harish K S V return -EINVAL;
13381d176c7aSNaga Harish K S V
13391d176c7aSNaga Harish K S V txa = txa_service_id_to_data(id);
13401d176c7aSNaga Harish K S V if (txa == NULL)
13411d176c7aSNaga Harish K S V return -EINVAL;
13421d176c7aSNaga Harish K S V
134345ced711SNaga Harish K S V ret = txa_caps_check(txa);
13441d176c7aSNaga Harish K S V if (ret)
13451d176c7aSNaga Harish K S V return ret;
13461d176c7aSNaga Harish K S V
13471d176c7aSNaga Harish K S V rte_spinlock_lock(&txa->tx_lock);
13481d176c7aSNaga Harish K S V txa->flush_threshold = txa_params->flush_threshold;
13491d176c7aSNaga Harish K S V txa->max_nb_tx = txa_params->max_nb_tx;
13501d176c7aSNaga Harish K S V rte_spinlock_unlock(&txa->tx_lock);
13511d176c7aSNaga Harish K S V
13521d176c7aSNaga Harish K S V return 0;
13531d176c7aSNaga Harish K S V }
13541d176c7aSNaga Harish K S V
13551d176c7aSNaga Harish K S V int
rte_event_eth_tx_adapter_runtime_params_get(uint8_t id,struct rte_event_eth_tx_adapter_runtime_params * txa_params)13561d176c7aSNaga Harish K S V rte_event_eth_tx_adapter_runtime_params_get(uint8_t id,
13571d176c7aSNaga Harish K S V struct rte_event_eth_tx_adapter_runtime_params *txa_params)
13581d176c7aSNaga Harish K S V {
13591d176c7aSNaga Harish K S V struct txa_service_data *txa;
13601d176c7aSNaga Harish K S V int ret;
13611d176c7aSNaga Harish K S V
13621d176c7aSNaga Harish K S V if (txa_lookup())
13631d176c7aSNaga Harish K S V return -ENOMEM;
13641d176c7aSNaga Harish K S V
13651d176c7aSNaga Harish K S V TXA_CHECK_OR_ERR_RET(id);
13661d176c7aSNaga Harish K S V
13671d176c7aSNaga Harish K S V if (txa_params == NULL)
13681d176c7aSNaga Harish K S V return -EINVAL;
13691d176c7aSNaga Harish K S V
13701d176c7aSNaga Harish K S V txa = txa_service_id_to_data(id);
13711d176c7aSNaga Harish K S V if (txa == NULL)
13721d176c7aSNaga Harish K S V return -EINVAL;
13731d176c7aSNaga Harish K S V
137445ced711SNaga Harish K S V ret = txa_caps_check(txa);
13751d176c7aSNaga Harish K S V if (ret)
13761d176c7aSNaga Harish K S V return ret;
13771d176c7aSNaga Harish K S V
13781d176c7aSNaga Harish K S V rte_spinlock_lock(&txa->tx_lock);
13791d176c7aSNaga Harish K S V txa_params->flush_threshold = txa->flush_threshold;
13801d176c7aSNaga Harish K S V txa_params->max_nb_tx = txa->max_nb_tx;
13811d176c7aSNaga Harish K S V rte_spinlock_unlock(&txa->tx_lock);
13821d176c7aSNaga Harish K S V
13831d176c7aSNaga Harish K S V return 0;
13841d176c7aSNaga Harish K S V }
13851d176c7aSNaga Harish K S V
13861d176c7aSNaga Harish K S V int
rte_event_eth_tx_adapter_stop(uint8_t id)138799a2dd95SBruce Richardson rte_event_eth_tx_adapter_stop(uint8_t id)
138899a2dd95SBruce Richardson {
138999a2dd95SBruce Richardson int ret;
139099a2dd95SBruce Richardson
139199a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id);
139299a2dd95SBruce Richardson
139399a2dd95SBruce Richardson ret = txa_dev_stop(id) ? txa_dev_stop(id)(id, txa_evdev(id)) : 0;
139499a2dd95SBruce Richardson if (ret == 0)
139599a2dd95SBruce Richardson ret = txa_service_stop(id);
139699a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_stop(id, ret);
139799a2dd95SBruce Richardson return ret;
139899a2dd95SBruce Richardson }
1399b2963cbdSGanapati Kundapura
1400b2963cbdSGanapati Kundapura int
rte_event_eth_tx_adapter_instance_get(uint16_t eth_dev_id,uint16_t tx_queue_id,uint8_t * txa_inst_id)1401b2963cbdSGanapati Kundapura rte_event_eth_tx_adapter_instance_get(uint16_t eth_dev_id,
1402b2963cbdSGanapati Kundapura uint16_t tx_queue_id,
1403b2963cbdSGanapati Kundapura uint8_t *txa_inst_id)
1404b2963cbdSGanapati Kundapura {
1405b2963cbdSGanapati Kundapura uint8_t id;
1406b2963cbdSGanapati Kundapura int ret = -EINVAL;
1407b2963cbdSGanapati Kundapura uint32_t caps;
1408b2963cbdSGanapati Kundapura struct txa_service_data *txa;
1409b2963cbdSGanapati Kundapura
1410b2963cbdSGanapati Kundapura if (txa_lookup())
1411b2963cbdSGanapati Kundapura return -ENOMEM;
1412b2963cbdSGanapati Kundapura
1413b2963cbdSGanapati Kundapura if (eth_dev_id >= rte_eth_dev_count_avail()) {
1414b2963cbdSGanapati Kundapura RTE_EDEV_LOG_ERR("Invalid ethernet port id %u", eth_dev_id);
1415b2963cbdSGanapati Kundapura return -EINVAL;
1416b2963cbdSGanapati Kundapura }
1417b2963cbdSGanapati Kundapura
1418b2963cbdSGanapati Kundapura if (tx_queue_id >= rte_eth_devices[eth_dev_id].data->nb_tx_queues) {
1419b2963cbdSGanapati Kundapura RTE_EDEV_LOG_ERR("Invalid tx queue id %u", tx_queue_id);
1420b2963cbdSGanapati Kundapura return -EINVAL;
1421b2963cbdSGanapati Kundapura }
1422b2963cbdSGanapati Kundapura
1423b2963cbdSGanapati Kundapura if (txa_inst_id == NULL) {
1424b2963cbdSGanapati Kundapura RTE_EDEV_LOG_ERR("txa_instance_id cannot be NULL");
1425b2963cbdSGanapati Kundapura return -EINVAL;
1426b2963cbdSGanapati Kundapura }
1427b2963cbdSGanapati Kundapura
1428b2963cbdSGanapati Kundapura /* Iterate through all Tx adapter instances */
1429b2963cbdSGanapati Kundapura for (id = 0; id < RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE; id++) {
1430b2963cbdSGanapati Kundapura txa = txa_service_id_to_data(id);
1431b2963cbdSGanapati Kundapura if (!txa)
1432b2963cbdSGanapati Kundapura continue;
1433b2963cbdSGanapati Kundapura
1434b2963cbdSGanapati Kundapura caps = 0;
1435b2963cbdSGanapati Kundapura if (rte_event_eth_tx_adapter_caps_get(txa->eventdev_id,
1436b2963cbdSGanapati Kundapura eth_dev_id,
1437b2963cbdSGanapati Kundapura &caps))
1438b2963cbdSGanapati Kundapura continue;
1439b2963cbdSGanapati Kundapura
1440b2963cbdSGanapati Kundapura if (caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
1441b2963cbdSGanapati Kundapura ret = txa_dev_instance_get(id) ?
1442b2963cbdSGanapati Kundapura txa_dev_instance_get(id)(eth_dev_id,
1443b2963cbdSGanapati Kundapura tx_queue_id,
1444b2963cbdSGanapati Kundapura txa_inst_id)
1445b2963cbdSGanapati Kundapura : -EINVAL;
14467f2d9df6SAmit Prakash Shukla if (ret == 0) {
14477f2d9df6SAmit Prakash Shukla rte_eventdev_trace_eth_tx_adapter_instance_get(eth_dev_id,
14487f2d9df6SAmit Prakash Shukla tx_queue_id, *txa_inst_id);
1449b2963cbdSGanapati Kundapura return ret;
14507f2d9df6SAmit Prakash Shukla }
1451b2963cbdSGanapati Kundapura } else {
1452b2963cbdSGanapati Kundapura struct rte_eth_dev *eth_dev;
1453b2963cbdSGanapati Kundapura
1454b2963cbdSGanapati Kundapura eth_dev = &rte_eth_devices[eth_dev_id];
1455b2963cbdSGanapati Kundapura
1456b2963cbdSGanapati Kundapura if (txa_service_is_queue_added(txa, eth_dev,
1457b2963cbdSGanapati Kundapura tx_queue_id)) {
1458b2963cbdSGanapati Kundapura *txa_inst_id = txa->id;
14597f2d9df6SAmit Prakash Shukla rte_eventdev_trace_eth_tx_adapter_instance_get(eth_dev_id,
14607f2d9df6SAmit Prakash Shukla tx_queue_id, *txa_inst_id);
1461b2963cbdSGanapati Kundapura return 0;
1462b2963cbdSGanapati Kundapura }
1463b2963cbdSGanapati Kundapura }
1464b2963cbdSGanapati Kundapura }
1465b2963cbdSGanapati Kundapura
1466b2963cbdSGanapati Kundapura return -EINVAL;
1467b2963cbdSGanapati Kundapura }
14683c3328aeSNaga Harish K S V
14693c3328aeSNaga Harish K S V static inline int
txa_sw_queue_start_state_set(uint16_t eth_dev_id,uint16_t tx_queue_id,bool start_state,struct txa_service_data * txa)14703c3328aeSNaga Harish K S V txa_sw_queue_start_state_set(uint16_t eth_dev_id, uint16_t tx_queue_id,
14713c3328aeSNaga Harish K S V bool start_state, struct txa_service_data *txa)
14723c3328aeSNaga Harish K S V {
14733c3328aeSNaga Harish K S V struct txa_service_queue_info *tqi = NULL;
14743c3328aeSNaga Harish K S V
14753c3328aeSNaga Harish K S V rte_spinlock_lock(&txa->tx_lock);
14763c3328aeSNaga Harish K S V tqi = txa_service_queue(txa, eth_dev_id, tx_queue_id);
14773c3328aeSNaga Harish K S V if (unlikely(tqi == NULL || !tqi->added)) {
14783c3328aeSNaga Harish K S V rte_spinlock_unlock(&txa->tx_lock);
14793c3328aeSNaga Harish K S V return -EINVAL;
14803c3328aeSNaga Harish K S V }
14813c3328aeSNaga Harish K S V if (start_state == false)
14823c3328aeSNaga Harish K S V txa_txq_buffer_drain(tqi);
14833c3328aeSNaga Harish K S V
14843c3328aeSNaga Harish K S V tqi->stopped = !start_state;
14853c3328aeSNaga Harish K S V rte_spinlock_unlock(&txa->tx_lock);
14863c3328aeSNaga Harish K S V return 0;
14873c3328aeSNaga Harish K S V }
14883c3328aeSNaga Harish K S V
14893c3328aeSNaga Harish K S V static int
txa_queue_start_state_set(uint16_t eth_dev_id,uint16_t tx_queue_id,bool start_state)14903c3328aeSNaga Harish K S V txa_queue_start_state_set(uint16_t eth_dev_id, uint16_t tx_queue_id,
14913c3328aeSNaga Harish K S V bool start_state)
14923c3328aeSNaga Harish K S V {
14933c3328aeSNaga Harish K S V struct txa_service_data *txa;
14943c3328aeSNaga Harish K S V uint8_t txa_inst_id;
14953c3328aeSNaga Harish K S V int ret;
14963c3328aeSNaga Harish K S V uint32_t caps = 0;
14973c3328aeSNaga Harish K S V
14983c3328aeSNaga Harish K S V /* Below API already does validation of input parameters.
14993c3328aeSNaga Harish K S V * Hence skipping the validation here.
15003c3328aeSNaga Harish K S V */
15013c3328aeSNaga Harish K S V ret = rte_event_eth_tx_adapter_instance_get(eth_dev_id,
15023c3328aeSNaga Harish K S V tx_queue_id,
15033c3328aeSNaga Harish K S V &txa_inst_id);
15043c3328aeSNaga Harish K S V if (ret < 0)
15053c3328aeSNaga Harish K S V return -EINVAL;
15063c3328aeSNaga Harish K S V
15073c3328aeSNaga Harish K S V txa = txa_service_id_to_data(txa_inst_id);
15083c3328aeSNaga Harish K S V ret = rte_event_eth_tx_adapter_caps_get(txa->eventdev_id,
15093c3328aeSNaga Harish K S V eth_dev_id,
15103c3328aeSNaga Harish K S V &caps);
15113c3328aeSNaga Harish K S V if (ret < 0)
15123c3328aeSNaga Harish K S V return -EINVAL;
15133c3328aeSNaga Harish K S V
15143c3328aeSNaga Harish K S V if (caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
15153c3328aeSNaga Harish K S V if (start_state == true) {
15163c3328aeSNaga Harish K S V ret = txa_dev_queue_start(txa_inst_id) ?
15173c3328aeSNaga Harish K S V txa_dev_queue_start(txa_inst_id)(txa_inst_id,
15183c3328aeSNaga Harish K S V eth_dev_id,
15193c3328aeSNaga Harish K S V tx_queue_id) : 0;
15203c3328aeSNaga Harish K S V } else {
15213c3328aeSNaga Harish K S V ret = txa_dev_queue_stop(txa_inst_id) ?
15223c3328aeSNaga Harish K S V txa_dev_queue_stop(txa_inst_id)(txa_inst_id,
15233c3328aeSNaga Harish K S V eth_dev_id,
15243c3328aeSNaga Harish K S V tx_queue_id) : 0;
15253c3328aeSNaga Harish K S V }
15263c3328aeSNaga Harish K S V return ret;
15273c3328aeSNaga Harish K S V }
15283c3328aeSNaga Harish K S V
15293c3328aeSNaga Harish K S V return txa_sw_queue_start_state_set(eth_dev_id, tx_queue_id,
15303c3328aeSNaga Harish K S V start_state, txa);
15313c3328aeSNaga Harish K S V }
15323c3328aeSNaga Harish K S V
15333c3328aeSNaga Harish K S V int
rte_event_eth_tx_adapter_queue_start(uint16_t eth_dev_id,uint16_t tx_queue_id)15343c3328aeSNaga Harish K S V rte_event_eth_tx_adapter_queue_start(uint16_t eth_dev_id, uint16_t tx_queue_id)
15353c3328aeSNaga Harish K S V {
15367f2d9df6SAmit Prakash Shukla rte_eventdev_trace_eth_tx_adapter_queue_start(eth_dev_id, tx_queue_id);
15377f2d9df6SAmit Prakash Shukla
15383c3328aeSNaga Harish K S V return txa_queue_start_state_set(eth_dev_id, tx_queue_id, true);
15393c3328aeSNaga Harish K S V }
15403c3328aeSNaga Harish K S V
15413c3328aeSNaga Harish K S V int
rte_event_eth_tx_adapter_queue_stop(uint16_t eth_dev_id,uint16_t tx_queue_id)15423c3328aeSNaga Harish K S V rte_event_eth_tx_adapter_queue_stop(uint16_t eth_dev_id, uint16_t tx_queue_id)
15433c3328aeSNaga Harish K S V {
15447f2d9df6SAmit Prakash Shukla rte_eventdev_trace_eth_tx_adapter_queue_stop(eth_dev_id, tx_queue_id);
15457f2d9df6SAmit Prakash Shukla
15463c3328aeSNaga Harish K S V return txa_queue_start_state_set(eth_dev_id, tx_queue_id, false);
15473c3328aeSNaga Harish K S V }
1548