xref: /dpdk/lib/eventdev/rte_event_eth_tx_adapter.c (revision c6552d9a8deffa448de2d5e2e726f50508c1efd2)
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