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 5099a2dd95SBruce Richardson #define RTE_EVENT_ETH_TX_ADAPTER_ID_VALID_OR_ERR_RET(id, retval) \ 5199a2dd95SBruce Richardson do { \ 5299a2dd95SBruce Richardson if (!txa_valid_id(id)) { \ 532ab9869cSNaga Harish K S V RTE_EDEV_LOG_ERR("Invalid eth Tx adapter id = %d", id); \ 5499a2dd95SBruce Richardson return retval; \ 5599a2dd95SBruce Richardson } \ 5699a2dd95SBruce Richardson } while (0) 5799a2dd95SBruce Richardson 5899a2dd95SBruce Richardson #define TXA_CHECK_OR_ERR_RET(id) \ 5999a2dd95SBruce Richardson do {\ 6099a2dd95SBruce Richardson int ret; \ 6199a2dd95SBruce Richardson RTE_EVENT_ETH_TX_ADAPTER_ID_VALID_OR_ERR_RET((id), -EINVAL); \ 6299a2dd95SBruce Richardson ret = txa_init(); \ 6399a2dd95SBruce Richardson if (ret != 0) \ 6499a2dd95SBruce Richardson return ret; \ 6599a2dd95SBruce Richardson if (!txa_adapter_exist((id))) \ 6699a2dd95SBruce Richardson return -EINVAL; \ 6799a2dd95SBruce Richardson } while (0) 6899a2dd95SBruce Richardson 6999a2dd95SBruce Richardson #define TXA_CHECK_TXQ(dev, queue) \ 7099a2dd95SBruce Richardson do {\ 7199a2dd95SBruce Richardson if ((dev)->data->nb_tx_queues == 0) { \ 7299a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("No tx queues configured"); \ 7399a2dd95SBruce Richardson return -EINVAL; \ 7499a2dd95SBruce Richardson } \ 7599a2dd95SBruce Richardson if ((queue) != -1 && \ 7699a2dd95SBruce Richardson (uint16_t)(queue) >= (dev)->data->nb_tx_queues) { \ 7799a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("Invalid tx queue_id %" PRIu16, \ 7899a2dd95SBruce Richardson (uint16_t)(queue)); \ 7999a2dd95SBruce Richardson return -EINVAL; \ 8099a2dd95SBruce Richardson } \ 8199a2dd95SBruce Richardson } while (0) 8299a2dd95SBruce Richardson 8399a2dd95SBruce Richardson /* Tx retry callback structure */ 8499a2dd95SBruce Richardson struct txa_retry { 8599a2dd95SBruce Richardson /* Ethernet port id */ 8699a2dd95SBruce Richardson uint16_t port_id; 8799a2dd95SBruce Richardson /* Tx queue */ 8899a2dd95SBruce Richardson uint16_t tx_queue; 8999a2dd95SBruce Richardson /* Adapter ID */ 9099a2dd95SBruce Richardson uint8_t id; 9199a2dd95SBruce Richardson }; 9299a2dd95SBruce Richardson 9399a2dd95SBruce Richardson /* Per queue structure */ 9499a2dd95SBruce Richardson struct txa_service_queue_info { 9599a2dd95SBruce Richardson /* Queue has been added */ 9699a2dd95SBruce Richardson uint8_t added; 9799a2dd95SBruce Richardson /* Retry callback argument */ 9899a2dd95SBruce Richardson struct txa_retry txa_retry; 9999a2dd95SBruce Richardson /* Tx buffer */ 10099a2dd95SBruce Richardson struct rte_eth_dev_tx_buffer *tx_buf; 10199a2dd95SBruce Richardson }; 10299a2dd95SBruce Richardson 10399a2dd95SBruce Richardson /* PMD private structure */ 10499a2dd95SBruce Richardson struct txa_service_data { 10599a2dd95SBruce Richardson /* Max mbufs processed in any service function invocation */ 10699a2dd95SBruce Richardson uint32_t max_nb_tx; 10799a2dd95SBruce Richardson /* Number of Tx queues in adapter */ 10899a2dd95SBruce Richardson uint32_t nb_queues; 10999a2dd95SBruce Richardson /* Synchronization with data path */ 11099a2dd95SBruce Richardson rte_spinlock_t tx_lock; 11199a2dd95SBruce Richardson /* Event port ID */ 11299a2dd95SBruce Richardson uint8_t port_id; 11399a2dd95SBruce Richardson /* Event device identifier */ 11499a2dd95SBruce Richardson uint8_t eventdev_id; 11599a2dd95SBruce Richardson /* Highest port id supported + 1 */ 11699a2dd95SBruce Richardson uint16_t dev_count; 11799a2dd95SBruce Richardson /* Loop count to flush Tx buffers */ 11899a2dd95SBruce Richardson int loop_cnt; 11999a2dd95SBruce Richardson /* Per ethernet device structure */ 12099a2dd95SBruce Richardson struct txa_service_ethdev *txa_ethdev; 12199a2dd95SBruce Richardson /* Statistics */ 12299a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats stats; 12399a2dd95SBruce Richardson /* Adapter Identifier */ 12499a2dd95SBruce Richardson uint8_t id; 12599a2dd95SBruce Richardson /* Conf arg must be freed */ 12699a2dd95SBruce Richardson uint8_t conf_free; 12799a2dd95SBruce Richardson /* Configuration callback */ 12899a2dd95SBruce Richardson rte_event_eth_tx_adapter_conf_cb conf_cb; 12999a2dd95SBruce Richardson /* Configuration callback argument */ 13099a2dd95SBruce Richardson void *conf_arg; 13199a2dd95SBruce Richardson /* socket id */ 13299a2dd95SBruce Richardson int socket_id; 13399a2dd95SBruce Richardson /* Per adapter EAL service */ 13499a2dd95SBruce Richardson int64_t service_id; 13599a2dd95SBruce Richardson /* Memory allocation name */ 13699a2dd95SBruce Richardson char mem_name[TXA_MEM_NAME_LEN]; 13799a2dd95SBruce Richardson } __rte_cache_aligned; 13899a2dd95SBruce Richardson 13999a2dd95SBruce Richardson /* Per eth device structure */ 14099a2dd95SBruce Richardson struct txa_service_ethdev { 14199a2dd95SBruce Richardson /* Pointer to ethernet device */ 14299a2dd95SBruce Richardson struct rte_eth_dev *dev; 14399a2dd95SBruce Richardson /* Number of queues added */ 14499a2dd95SBruce Richardson uint16_t nb_queues; 14599a2dd95SBruce Richardson /* PMD specific queue data */ 14699a2dd95SBruce Richardson void *queues; 14799a2dd95SBruce Richardson }; 14899a2dd95SBruce Richardson 14999a2dd95SBruce Richardson /* Array of adapter instances, initialized with event device id 15099a2dd95SBruce Richardson * when adapter is created 15199a2dd95SBruce Richardson */ 15299a2dd95SBruce Richardson static int *txa_dev_id_array; 15399a2dd95SBruce Richardson 15499a2dd95SBruce Richardson /* Array of pointers to service implementation data */ 15599a2dd95SBruce Richardson static struct txa_service_data **txa_service_data_array; 15699a2dd95SBruce Richardson 15799a2dd95SBruce Richardson static int32_t txa_service_func(void *args); 15899a2dd95SBruce Richardson static int txa_service_adapter_create_ext(uint8_t id, 15999a2dd95SBruce Richardson struct rte_eventdev *dev, 16099a2dd95SBruce Richardson rte_event_eth_tx_adapter_conf_cb conf_cb, 16199a2dd95SBruce Richardson void *conf_arg); 16299a2dd95SBruce Richardson static int txa_service_queue_del(uint8_t id, 16399a2dd95SBruce Richardson const struct rte_eth_dev *dev, 16499a2dd95SBruce Richardson int32_t tx_queue_id); 16599a2dd95SBruce Richardson 16699a2dd95SBruce Richardson static int 16799a2dd95SBruce Richardson txa_adapter_exist(uint8_t id) 16899a2dd95SBruce Richardson { 16999a2dd95SBruce Richardson return txa_dev_id_array[id] != TXA_INVALID_DEV_ID; 17099a2dd95SBruce Richardson } 17199a2dd95SBruce Richardson 17299a2dd95SBruce Richardson static inline int 17399a2dd95SBruce Richardson txa_valid_id(uint8_t id) 17499a2dd95SBruce Richardson { 17599a2dd95SBruce Richardson return id < RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE; 17699a2dd95SBruce Richardson } 17799a2dd95SBruce Richardson 17899a2dd95SBruce Richardson static void * 17999a2dd95SBruce Richardson txa_memzone_array_get(const char *name, unsigned int elt_size, int nb_elems) 18099a2dd95SBruce Richardson { 18199a2dd95SBruce Richardson const struct rte_memzone *mz; 18299a2dd95SBruce Richardson unsigned int sz; 18399a2dd95SBruce Richardson 18499a2dd95SBruce Richardson sz = elt_size * nb_elems; 18599a2dd95SBruce Richardson sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE); 18699a2dd95SBruce Richardson 18799a2dd95SBruce Richardson mz = rte_memzone_lookup(name); 18899a2dd95SBruce Richardson if (mz == NULL) { 18999a2dd95SBruce Richardson mz = rte_memzone_reserve_aligned(name, sz, rte_socket_id(), 0, 19099a2dd95SBruce Richardson RTE_CACHE_LINE_SIZE); 19199a2dd95SBruce Richardson if (mz == NULL) { 19299a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("failed to reserve memzone" 19399a2dd95SBruce Richardson " name = %s err = %" 19499a2dd95SBruce Richardson PRId32, name, rte_errno); 19599a2dd95SBruce Richardson return NULL; 19699a2dd95SBruce Richardson } 19799a2dd95SBruce Richardson } 19899a2dd95SBruce Richardson 19999a2dd95SBruce Richardson return mz->addr; 20099a2dd95SBruce Richardson } 20199a2dd95SBruce Richardson 20299a2dd95SBruce Richardson static int 203b2963cbdSGanapati Kundapura txa_lookup(void) 204b2963cbdSGanapati Kundapura { 205b2963cbdSGanapati Kundapura const struct rte_memzone *mz; 206b2963cbdSGanapati Kundapura 207b2963cbdSGanapati Kundapura if (txa_dev_id_array == NULL) { 208b2963cbdSGanapati Kundapura mz = rte_memzone_lookup(TXA_ADAPTER_ARRAY); 209b2963cbdSGanapati Kundapura if (mz == NULL) 210b2963cbdSGanapati Kundapura return -ENOMEM; 211b2963cbdSGanapati Kundapura txa_dev_id_array = mz->addr; 212b2963cbdSGanapati Kundapura } 213b2963cbdSGanapati Kundapura 214b2963cbdSGanapati Kundapura if (txa_service_data_array == NULL) { 215b2963cbdSGanapati Kundapura mz = rte_memzone_lookup(TXA_SERVICE_DATA_ARRAY); 216b2963cbdSGanapati Kundapura if (mz == NULL) 217b2963cbdSGanapati Kundapura return -ENOMEM; 218b2963cbdSGanapati Kundapura txa_service_data_array = mz->addr; 219b2963cbdSGanapati Kundapura } 220b2963cbdSGanapati Kundapura 221b2963cbdSGanapati Kundapura return 0; 222b2963cbdSGanapati Kundapura } 223b2963cbdSGanapati Kundapura 224b2963cbdSGanapati Kundapura static int 22599a2dd95SBruce Richardson txa_dev_id_array_init(void) 22699a2dd95SBruce Richardson { 22799a2dd95SBruce Richardson if (txa_dev_id_array == NULL) { 22899a2dd95SBruce Richardson int i; 22999a2dd95SBruce Richardson 230b2963cbdSGanapati Kundapura txa_dev_id_array = txa_memzone_array_get(TXA_ADAPTER_ARRAY, 23199a2dd95SBruce Richardson sizeof(int), 23299a2dd95SBruce Richardson RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE); 23399a2dd95SBruce Richardson if (txa_dev_id_array == NULL) 23499a2dd95SBruce Richardson return -ENOMEM; 23599a2dd95SBruce Richardson 23699a2dd95SBruce Richardson for (i = 0; i < RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE; i++) 23799a2dd95SBruce Richardson txa_dev_id_array[i] = TXA_INVALID_DEV_ID; 23899a2dd95SBruce Richardson } 23999a2dd95SBruce Richardson 24099a2dd95SBruce Richardson return 0; 24199a2dd95SBruce Richardson } 24299a2dd95SBruce Richardson 24399a2dd95SBruce Richardson static int 24499a2dd95SBruce Richardson txa_init(void) 24599a2dd95SBruce Richardson { 24699a2dd95SBruce Richardson return txa_dev_id_array_init(); 24799a2dd95SBruce Richardson } 24899a2dd95SBruce Richardson 24999a2dd95SBruce Richardson static int 25099a2dd95SBruce Richardson txa_service_data_init(void) 25199a2dd95SBruce Richardson { 25299a2dd95SBruce Richardson if (txa_service_data_array == NULL) { 253b2963cbdSGanapati Kundapura int i; 254b2963cbdSGanapati Kundapura 25599a2dd95SBruce Richardson txa_service_data_array = 256b2963cbdSGanapati Kundapura txa_memzone_array_get(TXA_SERVICE_DATA_ARRAY, 2573d6e9dd4SNaga Harish K S V sizeof(*txa_service_data_array), 25899a2dd95SBruce Richardson RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE); 25999a2dd95SBruce Richardson if (txa_service_data_array == NULL) 26099a2dd95SBruce Richardson return -ENOMEM; 261b2963cbdSGanapati Kundapura 262b2963cbdSGanapati Kundapura /* Reset the txa service pointers */ 263b2963cbdSGanapati Kundapura for (i = 0; i < RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE; i++) 264b2963cbdSGanapati Kundapura txa_service_data_array[i] = NULL; 26599a2dd95SBruce Richardson } 26699a2dd95SBruce Richardson 26799a2dd95SBruce Richardson return 0; 26899a2dd95SBruce Richardson } 26999a2dd95SBruce Richardson 27099a2dd95SBruce Richardson static inline struct txa_service_data * 27199a2dd95SBruce Richardson txa_service_id_to_data(uint8_t id) 27299a2dd95SBruce Richardson { 27399a2dd95SBruce Richardson return txa_service_data_array[id]; 27499a2dd95SBruce Richardson } 27599a2dd95SBruce Richardson 27699a2dd95SBruce Richardson static inline struct txa_service_queue_info * 27799a2dd95SBruce Richardson txa_service_queue(struct txa_service_data *txa, uint16_t port_id, 27899a2dd95SBruce Richardson uint16_t tx_queue_id) 27999a2dd95SBruce Richardson { 28099a2dd95SBruce Richardson struct txa_service_queue_info *tqi; 28199a2dd95SBruce Richardson 28299a2dd95SBruce Richardson if (unlikely(txa->txa_ethdev == NULL || txa->dev_count < port_id + 1)) 28399a2dd95SBruce Richardson return NULL; 28499a2dd95SBruce Richardson 28599a2dd95SBruce Richardson tqi = txa->txa_ethdev[port_id].queues; 28699a2dd95SBruce Richardson 28799a2dd95SBruce Richardson return likely(tqi != NULL) ? tqi + tx_queue_id : NULL; 28899a2dd95SBruce Richardson } 28999a2dd95SBruce Richardson 29099a2dd95SBruce Richardson static int 29199a2dd95SBruce Richardson txa_service_conf_cb(uint8_t __rte_unused id, uint8_t dev_id, 29299a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_conf *conf, void *arg) 29399a2dd95SBruce Richardson { 29499a2dd95SBruce Richardson int ret; 29599a2dd95SBruce Richardson struct rte_eventdev *dev; 29699a2dd95SBruce Richardson struct rte_event_port_conf *pc; 29799a2dd95SBruce Richardson struct rte_event_dev_config dev_conf; 29899a2dd95SBruce Richardson int started; 29999a2dd95SBruce Richardson uint8_t port_id; 30099a2dd95SBruce Richardson 30199a2dd95SBruce Richardson pc = arg; 30299a2dd95SBruce Richardson dev = &rte_eventdevs[dev_id]; 30399a2dd95SBruce Richardson dev_conf = dev->data->dev_conf; 30499a2dd95SBruce Richardson 30599a2dd95SBruce Richardson started = dev->data->dev_started; 30699a2dd95SBruce Richardson if (started) 30799a2dd95SBruce Richardson rte_event_dev_stop(dev_id); 30899a2dd95SBruce Richardson 30999a2dd95SBruce Richardson port_id = dev_conf.nb_event_ports; 31099a2dd95SBruce Richardson dev_conf.nb_event_ports += 1; 31199a2dd95SBruce Richardson 31299a2dd95SBruce Richardson ret = rte_event_dev_configure(dev_id, &dev_conf); 31399a2dd95SBruce Richardson if (ret) { 31499a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("failed to configure event dev %u", 31599a2dd95SBruce Richardson dev_id); 31699a2dd95SBruce Richardson if (started) { 31799a2dd95SBruce Richardson if (rte_event_dev_start(dev_id)) 31899a2dd95SBruce Richardson return -EIO; 31999a2dd95SBruce Richardson } 32099a2dd95SBruce Richardson return ret; 32199a2dd95SBruce Richardson } 32299a2dd95SBruce Richardson 32399a2dd95SBruce Richardson ret = rte_event_port_setup(dev_id, port_id, pc); 32499a2dd95SBruce Richardson if (ret) { 32599a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("failed to setup event port %u\n", 32699a2dd95SBruce Richardson port_id); 32799a2dd95SBruce Richardson if (started) { 32899a2dd95SBruce Richardson if (rte_event_dev_start(dev_id)) 32999a2dd95SBruce Richardson return -EIO; 33099a2dd95SBruce Richardson } 33199a2dd95SBruce Richardson return ret; 33299a2dd95SBruce Richardson } 33399a2dd95SBruce Richardson 33499a2dd95SBruce Richardson conf->event_port_id = port_id; 33599a2dd95SBruce Richardson conf->max_nb_tx = TXA_MAX_NB_TX; 33699a2dd95SBruce Richardson if (started) 33799a2dd95SBruce Richardson ret = rte_event_dev_start(dev_id); 33899a2dd95SBruce Richardson return ret; 33999a2dd95SBruce Richardson } 34099a2dd95SBruce Richardson 34199a2dd95SBruce Richardson static int 34299a2dd95SBruce Richardson txa_service_ethdev_alloc(struct txa_service_data *txa) 34399a2dd95SBruce Richardson { 34499a2dd95SBruce Richardson struct txa_service_ethdev *txa_ethdev; 34599a2dd95SBruce Richardson uint16_t i, dev_count; 34699a2dd95SBruce Richardson 34799a2dd95SBruce Richardson dev_count = rte_eth_dev_count_avail(); 34899a2dd95SBruce Richardson if (txa->txa_ethdev && dev_count == txa->dev_count) 34999a2dd95SBruce Richardson return 0; 35099a2dd95SBruce Richardson 35199a2dd95SBruce Richardson txa_ethdev = rte_zmalloc_socket(txa->mem_name, 35299a2dd95SBruce Richardson dev_count * sizeof(*txa_ethdev), 35399a2dd95SBruce Richardson 0, 35499a2dd95SBruce Richardson txa->socket_id); 35599a2dd95SBruce Richardson if (txa_ethdev == NULL) { 35699a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("Failed to alloc txa::txa_ethdev "); 35799a2dd95SBruce Richardson return -ENOMEM; 35899a2dd95SBruce Richardson } 35999a2dd95SBruce Richardson 36099a2dd95SBruce Richardson if (txa->dev_count) 36199a2dd95SBruce Richardson memcpy(txa_ethdev, txa->txa_ethdev, 36299a2dd95SBruce Richardson txa->dev_count * sizeof(*txa_ethdev)); 36399a2dd95SBruce Richardson 36499a2dd95SBruce Richardson RTE_ETH_FOREACH_DEV(i) { 36599a2dd95SBruce Richardson if (i == dev_count) 36699a2dd95SBruce Richardson break; 36799a2dd95SBruce Richardson txa_ethdev[i].dev = &rte_eth_devices[i]; 36899a2dd95SBruce Richardson } 36999a2dd95SBruce Richardson 37099a2dd95SBruce Richardson txa->txa_ethdev = txa_ethdev; 37199a2dd95SBruce Richardson txa->dev_count = dev_count; 37299a2dd95SBruce Richardson return 0; 37399a2dd95SBruce Richardson } 37499a2dd95SBruce Richardson 37599a2dd95SBruce Richardson static int 37699a2dd95SBruce Richardson txa_service_queue_array_alloc(struct txa_service_data *txa, 37799a2dd95SBruce Richardson uint16_t port_id) 37899a2dd95SBruce Richardson { 37999a2dd95SBruce Richardson struct txa_service_queue_info *tqi; 38099a2dd95SBruce Richardson uint16_t nb_queue; 38199a2dd95SBruce Richardson int ret; 38299a2dd95SBruce Richardson 38399a2dd95SBruce Richardson ret = txa_service_ethdev_alloc(txa); 38499a2dd95SBruce Richardson if (ret != 0) 38599a2dd95SBruce Richardson return ret; 38699a2dd95SBruce Richardson 38799a2dd95SBruce Richardson if (txa->txa_ethdev[port_id].queues) 38899a2dd95SBruce Richardson return 0; 38999a2dd95SBruce Richardson 39099a2dd95SBruce Richardson nb_queue = txa->txa_ethdev[port_id].dev->data->nb_tx_queues; 39199a2dd95SBruce Richardson tqi = rte_zmalloc_socket(txa->mem_name, 39299a2dd95SBruce Richardson nb_queue * 39399a2dd95SBruce Richardson sizeof(struct txa_service_queue_info), 0, 39499a2dd95SBruce Richardson txa->socket_id); 39599a2dd95SBruce Richardson if (tqi == NULL) 39699a2dd95SBruce Richardson return -ENOMEM; 39799a2dd95SBruce Richardson txa->txa_ethdev[port_id].queues = tqi; 39899a2dd95SBruce Richardson return 0; 39999a2dd95SBruce Richardson } 40099a2dd95SBruce Richardson 40199a2dd95SBruce Richardson static void 40299a2dd95SBruce Richardson txa_service_queue_array_free(struct txa_service_data *txa, 40399a2dd95SBruce Richardson uint16_t port_id) 40499a2dd95SBruce Richardson { 40599a2dd95SBruce Richardson struct txa_service_ethdev *txa_ethdev; 40699a2dd95SBruce Richardson struct txa_service_queue_info *tqi; 40799a2dd95SBruce Richardson 40899a2dd95SBruce Richardson txa_ethdev = &txa->txa_ethdev[port_id]; 40999a2dd95SBruce Richardson if (txa->txa_ethdev == NULL || txa_ethdev->nb_queues != 0) 41099a2dd95SBruce Richardson return; 41199a2dd95SBruce Richardson 41299a2dd95SBruce Richardson tqi = txa_ethdev->queues; 41399a2dd95SBruce Richardson txa_ethdev->queues = NULL; 41499a2dd95SBruce Richardson rte_free(tqi); 41599a2dd95SBruce Richardson 41699a2dd95SBruce Richardson if (txa->nb_queues == 0) { 41799a2dd95SBruce Richardson rte_free(txa->txa_ethdev); 41899a2dd95SBruce Richardson txa->txa_ethdev = NULL; 41999a2dd95SBruce Richardson } 42099a2dd95SBruce Richardson } 42199a2dd95SBruce Richardson 42299a2dd95SBruce Richardson static void 42399a2dd95SBruce Richardson txa_service_unregister(struct txa_service_data *txa) 42499a2dd95SBruce Richardson { 42599a2dd95SBruce Richardson if (txa->service_id != TXA_INVALID_SERVICE_ID) { 42699a2dd95SBruce Richardson rte_service_component_runstate_set(txa->service_id, 0); 42799a2dd95SBruce Richardson while (rte_service_may_be_active(txa->service_id)) 42899a2dd95SBruce Richardson rte_pause(); 42999a2dd95SBruce Richardson rte_service_component_unregister(txa->service_id); 43099a2dd95SBruce Richardson } 43199a2dd95SBruce Richardson txa->service_id = TXA_INVALID_SERVICE_ID; 43299a2dd95SBruce Richardson } 43399a2dd95SBruce Richardson 43499a2dd95SBruce Richardson static int 43599a2dd95SBruce Richardson txa_service_register(struct txa_service_data *txa) 43699a2dd95SBruce Richardson { 43799a2dd95SBruce Richardson int ret; 43899a2dd95SBruce Richardson struct rte_service_spec service; 43999a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_conf conf; 44099a2dd95SBruce Richardson 44199a2dd95SBruce Richardson if (txa->service_id != TXA_INVALID_SERVICE_ID) 44299a2dd95SBruce Richardson return 0; 44399a2dd95SBruce Richardson 44499a2dd95SBruce Richardson memset(&service, 0, sizeof(service)); 44599a2dd95SBruce Richardson snprintf(service.name, TXA_SERVICE_NAME_LEN, "txa_%d", txa->id); 44699a2dd95SBruce Richardson service.socket_id = txa->socket_id; 44799a2dd95SBruce Richardson service.callback = txa_service_func; 44899a2dd95SBruce Richardson service.callback_userdata = txa; 44999a2dd95SBruce Richardson service.capabilities = RTE_SERVICE_CAP_MT_SAFE; 45099a2dd95SBruce Richardson ret = rte_service_component_register(&service, 45199a2dd95SBruce Richardson (uint32_t *)&txa->service_id); 45299a2dd95SBruce Richardson if (ret) { 45399a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("failed to register service %s err = %" 45499a2dd95SBruce Richardson PRId32, service.name, ret); 45599a2dd95SBruce Richardson return ret; 45699a2dd95SBruce Richardson } 45799a2dd95SBruce Richardson 45899a2dd95SBruce Richardson ret = txa->conf_cb(txa->id, txa->eventdev_id, &conf, txa->conf_arg); 45999a2dd95SBruce Richardson if (ret) { 46099a2dd95SBruce Richardson txa_service_unregister(txa); 46199a2dd95SBruce Richardson return ret; 46299a2dd95SBruce Richardson } 46399a2dd95SBruce Richardson 46499a2dd95SBruce Richardson rte_service_component_runstate_set(txa->service_id, 1); 46599a2dd95SBruce Richardson txa->port_id = conf.event_port_id; 46699a2dd95SBruce Richardson txa->max_nb_tx = conf.max_nb_tx; 46799a2dd95SBruce Richardson return 0; 46899a2dd95SBruce Richardson } 46999a2dd95SBruce Richardson 47099a2dd95SBruce Richardson static struct rte_eth_dev_tx_buffer * 47199a2dd95SBruce Richardson txa_service_tx_buf_alloc(struct txa_service_data *txa, 47299a2dd95SBruce Richardson const struct rte_eth_dev *dev) 47399a2dd95SBruce Richardson { 47499a2dd95SBruce Richardson struct rte_eth_dev_tx_buffer *tb; 47599a2dd95SBruce Richardson uint16_t port_id; 47699a2dd95SBruce Richardson 47799a2dd95SBruce Richardson port_id = dev->data->port_id; 47899a2dd95SBruce Richardson tb = rte_zmalloc_socket(txa->mem_name, 47999a2dd95SBruce Richardson RTE_ETH_TX_BUFFER_SIZE(TXA_BATCH_SIZE), 48099a2dd95SBruce Richardson 0, 48199a2dd95SBruce Richardson rte_eth_dev_socket_id(port_id)); 48299a2dd95SBruce Richardson if (tb == NULL) 48399a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("Failed to allocate memory for tx buffer"); 48499a2dd95SBruce Richardson return tb; 48599a2dd95SBruce Richardson } 48699a2dd95SBruce Richardson 48799a2dd95SBruce Richardson static int 48899a2dd95SBruce Richardson txa_service_is_queue_added(struct txa_service_data *txa, 48999a2dd95SBruce Richardson const struct rte_eth_dev *dev, 49099a2dd95SBruce Richardson uint16_t tx_queue_id) 49199a2dd95SBruce Richardson { 49299a2dd95SBruce Richardson struct txa_service_queue_info *tqi; 49399a2dd95SBruce Richardson 49499a2dd95SBruce Richardson tqi = txa_service_queue(txa, dev->data->port_id, tx_queue_id); 49599a2dd95SBruce Richardson return tqi && tqi->added; 49699a2dd95SBruce Richardson } 49799a2dd95SBruce Richardson 49899a2dd95SBruce Richardson static int 49999a2dd95SBruce Richardson txa_service_ctrl(uint8_t id, int start) 50099a2dd95SBruce Richardson { 50199a2dd95SBruce Richardson int ret; 50299a2dd95SBruce Richardson struct txa_service_data *txa; 50399a2dd95SBruce Richardson 50499a2dd95SBruce Richardson txa = txa_service_id_to_data(id); 5052ab9869cSNaga Harish K S V if (txa == NULL || txa->service_id == TXA_INVALID_SERVICE_ID) 50699a2dd95SBruce Richardson return 0; 50799a2dd95SBruce Richardson 5082ab9869cSNaga Harish K S V rte_spinlock_lock(&txa->tx_lock); 50999a2dd95SBruce Richardson ret = rte_service_runstate_set(txa->service_id, start); 5102ab9869cSNaga Harish K S V rte_spinlock_unlock(&txa->tx_lock); 5112ab9869cSNaga Harish K S V 51299a2dd95SBruce Richardson return ret; 51399a2dd95SBruce Richardson } 51499a2dd95SBruce Richardson 51599a2dd95SBruce Richardson static void 51699a2dd95SBruce Richardson txa_service_buffer_retry(struct rte_mbuf **pkts, uint16_t unsent, 51799a2dd95SBruce Richardson void *userdata) 51899a2dd95SBruce Richardson { 51999a2dd95SBruce Richardson struct txa_retry *tr; 52099a2dd95SBruce Richardson struct txa_service_data *data; 52199a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats *stats; 52299a2dd95SBruce Richardson uint16_t sent = 0; 52399a2dd95SBruce Richardson unsigned int retry = 0; 52499a2dd95SBruce Richardson uint16_t i, n; 52599a2dd95SBruce Richardson 52699a2dd95SBruce Richardson tr = (struct txa_retry *)(uintptr_t)userdata; 52799a2dd95SBruce Richardson data = txa_service_id_to_data(tr->id); 52899a2dd95SBruce Richardson stats = &data->stats; 52999a2dd95SBruce Richardson 53099a2dd95SBruce Richardson do { 53199a2dd95SBruce Richardson n = rte_eth_tx_burst(tr->port_id, tr->tx_queue, 53299a2dd95SBruce Richardson &pkts[sent], unsent - sent); 53399a2dd95SBruce Richardson 53499a2dd95SBruce Richardson sent += n; 53599a2dd95SBruce Richardson } while (sent != unsent && retry++ < TXA_RETRY_CNT); 53699a2dd95SBruce Richardson 53799a2dd95SBruce Richardson for (i = sent; i < unsent; i++) 53899a2dd95SBruce Richardson rte_pktmbuf_free(pkts[i]); 53999a2dd95SBruce Richardson 54099a2dd95SBruce Richardson stats->tx_retry += retry; 54199a2dd95SBruce Richardson stats->tx_packets += sent; 54299a2dd95SBruce Richardson stats->tx_dropped += unsent - sent; 54399a2dd95SBruce Richardson } 54499a2dd95SBruce Richardson 54599a2dd95SBruce Richardson static uint16_t 54699a2dd95SBruce Richardson txa_process_event_vector(struct txa_service_data *txa, 54799a2dd95SBruce Richardson struct rte_event_vector *vec) 54899a2dd95SBruce Richardson { 54999a2dd95SBruce Richardson struct txa_service_queue_info *tqi; 55099a2dd95SBruce Richardson uint16_t port, queue, nb_tx = 0; 55199a2dd95SBruce Richardson struct rte_mbuf **mbufs; 55299a2dd95SBruce Richardson int i; 55399a2dd95SBruce Richardson 55499a2dd95SBruce Richardson mbufs = (struct rte_mbuf **)vec->mbufs; 55599a2dd95SBruce Richardson if (vec->attr_valid) { 55699a2dd95SBruce Richardson port = vec->port; 55799a2dd95SBruce Richardson queue = vec->queue; 55899a2dd95SBruce Richardson tqi = txa_service_queue(txa, port, queue); 55999a2dd95SBruce Richardson if (unlikely(tqi == NULL || !tqi->added)) { 560*0fbb55efSPavan Nikhilesh rte_pktmbuf_free_bulk(&mbufs[vec->elem_offset], 561*0fbb55efSPavan Nikhilesh vec->nb_elem); 56299a2dd95SBruce Richardson rte_mempool_put(rte_mempool_from_obj(vec), vec); 56399a2dd95SBruce Richardson return 0; 56499a2dd95SBruce Richardson } 56599a2dd95SBruce Richardson for (i = 0; i < vec->nb_elem; i++) { 56699a2dd95SBruce Richardson nb_tx += rte_eth_tx_buffer(port, queue, tqi->tx_buf, 567*0fbb55efSPavan Nikhilesh mbufs[i + vec->elem_offset]); 56899a2dd95SBruce Richardson } 56999a2dd95SBruce Richardson } else { 570*0fbb55efSPavan Nikhilesh for (i = vec->elem_offset; i < vec->elem_offset + vec->nb_elem; 571*0fbb55efSPavan Nikhilesh i++) { 57299a2dd95SBruce Richardson port = mbufs[i]->port; 57399a2dd95SBruce Richardson queue = rte_event_eth_tx_adapter_txq_get(mbufs[i]); 57499a2dd95SBruce Richardson tqi = txa_service_queue(txa, port, queue); 57599a2dd95SBruce Richardson if (unlikely(tqi == NULL || !tqi->added)) { 57699a2dd95SBruce Richardson rte_pktmbuf_free(mbufs[i]); 57799a2dd95SBruce Richardson continue; 57899a2dd95SBruce Richardson } 57999a2dd95SBruce Richardson nb_tx += rte_eth_tx_buffer(port, queue, tqi->tx_buf, 58099a2dd95SBruce Richardson mbufs[i]); 58199a2dd95SBruce Richardson } 58299a2dd95SBruce Richardson } 58399a2dd95SBruce Richardson rte_mempool_put(rte_mempool_from_obj(vec), vec); 58499a2dd95SBruce Richardson 58599a2dd95SBruce Richardson return nb_tx; 58699a2dd95SBruce Richardson } 58799a2dd95SBruce Richardson 58899a2dd95SBruce Richardson static void 58999a2dd95SBruce Richardson txa_service_tx(struct txa_service_data *txa, struct rte_event *ev, 59099a2dd95SBruce Richardson uint32_t n) 59199a2dd95SBruce Richardson { 59299a2dd95SBruce Richardson uint32_t i; 59399a2dd95SBruce Richardson uint16_t nb_tx; 59499a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats *stats; 59599a2dd95SBruce Richardson 59699a2dd95SBruce Richardson stats = &txa->stats; 59799a2dd95SBruce Richardson 59899a2dd95SBruce Richardson nb_tx = 0; 59999a2dd95SBruce Richardson for (i = 0; i < n; i++) { 60099a2dd95SBruce Richardson uint16_t port; 60199a2dd95SBruce Richardson uint16_t queue; 60299a2dd95SBruce Richardson struct txa_service_queue_info *tqi; 60399a2dd95SBruce Richardson 60499a2dd95SBruce Richardson if (!(ev[i].event_type & RTE_EVENT_TYPE_VECTOR)) { 60599a2dd95SBruce Richardson struct rte_mbuf *m; 60699a2dd95SBruce Richardson 60799a2dd95SBruce Richardson m = ev[i].mbuf; 60899a2dd95SBruce Richardson port = m->port; 60999a2dd95SBruce Richardson queue = rte_event_eth_tx_adapter_txq_get(m); 61099a2dd95SBruce Richardson 61199a2dd95SBruce Richardson tqi = txa_service_queue(txa, port, queue); 61299a2dd95SBruce Richardson if (unlikely(tqi == NULL || !tqi->added)) { 61399a2dd95SBruce Richardson rte_pktmbuf_free(m); 61499a2dd95SBruce Richardson continue; 61599a2dd95SBruce Richardson } 61699a2dd95SBruce Richardson 61799a2dd95SBruce Richardson nb_tx += rte_eth_tx_buffer(port, queue, tqi->tx_buf, m); 61899a2dd95SBruce Richardson } else { 61999a2dd95SBruce Richardson nb_tx += txa_process_event_vector(txa, ev[i].vec); 62099a2dd95SBruce Richardson } 62199a2dd95SBruce Richardson } 62299a2dd95SBruce Richardson 62399a2dd95SBruce Richardson stats->tx_packets += nb_tx; 62499a2dd95SBruce Richardson } 62599a2dd95SBruce Richardson 62699a2dd95SBruce Richardson static int32_t 62799a2dd95SBruce Richardson txa_service_func(void *args) 62899a2dd95SBruce Richardson { 62999a2dd95SBruce Richardson struct txa_service_data *txa = args; 63099a2dd95SBruce Richardson uint8_t dev_id; 63199a2dd95SBruce Richardson uint8_t port; 63299a2dd95SBruce Richardson uint16_t n; 63399a2dd95SBruce Richardson uint32_t nb_tx, max_nb_tx; 63499a2dd95SBruce Richardson struct rte_event ev[TXA_BATCH_SIZE]; 63599a2dd95SBruce Richardson 63699a2dd95SBruce Richardson dev_id = txa->eventdev_id; 63799a2dd95SBruce Richardson max_nb_tx = txa->max_nb_tx; 63899a2dd95SBruce Richardson port = txa->port_id; 63999a2dd95SBruce Richardson 64099a2dd95SBruce Richardson if (txa->nb_queues == 0) 64199a2dd95SBruce Richardson return 0; 64299a2dd95SBruce Richardson 64399a2dd95SBruce Richardson if (!rte_spinlock_trylock(&txa->tx_lock)) 64499a2dd95SBruce Richardson return 0; 64599a2dd95SBruce Richardson 64699a2dd95SBruce Richardson for (nb_tx = 0; nb_tx < max_nb_tx; nb_tx += n) { 64799a2dd95SBruce Richardson 64899a2dd95SBruce Richardson n = rte_event_dequeue_burst(dev_id, port, ev, RTE_DIM(ev), 0); 64999a2dd95SBruce Richardson if (!n) 65099a2dd95SBruce Richardson break; 65199a2dd95SBruce Richardson txa_service_tx(txa, ev, n); 65299a2dd95SBruce Richardson } 65399a2dd95SBruce Richardson 65499a2dd95SBruce Richardson if ((txa->loop_cnt++ & (TXA_FLUSH_THRESHOLD - 1)) == 0) { 65599a2dd95SBruce Richardson 65699a2dd95SBruce Richardson struct txa_service_ethdev *tdi; 65799a2dd95SBruce Richardson struct txa_service_queue_info *tqi; 65899a2dd95SBruce Richardson struct rte_eth_dev *dev; 65999a2dd95SBruce Richardson uint16_t i; 66099a2dd95SBruce Richardson 66199a2dd95SBruce Richardson tdi = txa->txa_ethdev; 66299a2dd95SBruce Richardson nb_tx = 0; 66399a2dd95SBruce Richardson 66499a2dd95SBruce Richardson RTE_ETH_FOREACH_DEV(i) { 66599a2dd95SBruce Richardson uint16_t q; 66699a2dd95SBruce Richardson 66799a2dd95SBruce Richardson if (i == txa->dev_count) 66899a2dd95SBruce Richardson break; 66999a2dd95SBruce Richardson 67099a2dd95SBruce Richardson dev = tdi[i].dev; 67199a2dd95SBruce Richardson if (tdi[i].nb_queues == 0) 67299a2dd95SBruce Richardson continue; 67399a2dd95SBruce Richardson for (q = 0; q < dev->data->nb_tx_queues; q++) { 67499a2dd95SBruce Richardson 67599a2dd95SBruce Richardson tqi = txa_service_queue(txa, i, q); 67699a2dd95SBruce Richardson if (unlikely(tqi == NULL || !tqi->added)) 67799a2dd95SBruce Richardson continue; 67899a2dd95SBruce Richardson 67999a2dd95SBruce Richardson nb_tx += rte_eth_tx_buffer_flush(i, q, 68099a2dd95SBruce Richardson tqi->tx_buf); 68199a2dd95SBruce Richardson } 68299a2dd95SBruce Richardson } 68399a2dd95SBruce Richardson 68499a2dd95SBruce Richardson txa->stats.tx_packets += nb_tx; 68599a2dd95SBruce Richardson } 68699a2dd95SBruce Richardson rte_spinlock_unlock(&txa->tx_lock); 68799a2dd95SBruce Richardson return 0; 68899a2dd95SBruce Richardson } 68999a2dd95SBruce Richardson 69099a2dd95SBruce Richardson static int 69199a2dd95SBruce Richardson txa_service_adapter_create(uint8_t id, struct rte_eventdev *dev, 69299a2dd95SBruce Richardson struct rte_event_port_conf *port_conf) 69399a2dd95SBruce Richardson { 69499a2dd95SBruce Richardson struct txa_service_data *txa; 69599a2dd95SBruce Richardson struct rte_event_port_conf *cb_conf; 69699a2dd95SBruce Richardson int ret; 69799a2dd95SBruce Richardson 69899a2dd95SBruce Richardson cb_conf = rte_malloc(NULL, sizeof(*cb_conf), 0); 69999a2dd95SBruce Richardson if (cb_conf == NULL) 70099a2dd95SBruce Richardson return -ENOMEM; 70199a2dd95SBruce Richardson 70299a2dd95SBruce Richardson *cb_conf = *port_conf; 70399a2dd95SBruce Richardson ret = txa_service_adapter_create_ext(id, dev, txa_service_conf_cb, 70499a2dd95SBruce Richardson cb_conf); 70599a2dd95SBruce Richardson if (ret) { 70699a2dd95SBruce Richardson rte_free(cb_conf); 70799a2dd95SBruce Richardson return ret; 70899a2dd95SBruce Richardson } 70999a2dd95SBruce Richardson 71099a2dd95SBruce Richardson txa = txa_service_id_to_data(id); 71199a2dd95SBruce Richardson txa->conf_free = 1; 71299a2dd95SBruce Richardson return ret; 71399a2dd95SBruce Richardson } 71499a2dd95SBruce Richardson 71599a2dd95SBruce Richardson static int 71699a2dd95SBruce Richardson txa_service_adapter_create_ext(uint8_t id, struct rte_eventdev *dev, 71799a2dd95SBruce Richardson rte_event_eth_tx_adapter_conf_cb conf_cb, 71899a2dd95SBruce Richardson void *conf_arg) 71999a2dd95SBruce Richardson { 72099a2dd95SBruce Richardson struct txa_service_data *txa; 72199a2dd95SBruce Richardson int socket_id; 72299a2dd95SBruce Richardson char mem_name[TXA_SERVICE_NAME_LEN]; 72399a2dd95SBruce Richardson int ret; 72499a2dd95SBruce Richardson 72599a2dd95SBruce Richardson if (conf_cb == NULL) 72699a2dd95SBruce Richardson return -EINVAL; 72799a2dd95SBruce Richardson 72899a2dd95SBruce Richardson socket_id = dev->data->socket_id; 72999a2dd95SBruce Richardson snprintf(mem_name, TXA_MEM_NAME_LEN, 73099a2dd95SBruce Richardson "rte_event_eth_txa_%d", 73199a2dd95SBruce Richardson id); 73299a2dd95SBruce Richardson 73399a2dd95SBruce Richardson ret = txa_service_data_init(); 73499a2dd95SBruce Richardson if (ret != 0) 73599a2dd95SBruce Richardson return ret; 73699a2dd95SBruce Richardson 73799a2dd95SBruce Richardson txa = rte_zmalloc_socket(mem_name, 73899a2dd95SBruce Richardson sizeof(*txa), 73999a2dd95SBruce Richardson RTE_CACHE_LINE_SIZE, socket_id); 74099a2dd95SBruce Richardson if (txa == NULL) { 74199a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("failed to get mem for tx adapter"); 74299a2dd95SBruce Richardson return -ENOMEM; 74399a2dd95SBruce Richardson } 74499a2dd95SBruce Richardson 74599a2dd95SBruce Richardson txa->id = id; 74699a2dd95SBruce Richardson txa->eventdev_id = dev->data->dev_id; 74799a2dd95SBruce Richardson txa->socket_id = socket_id; 74899a2dd95SBruce Richardson strncpy(txa->mem_name, mem_name, TXA_SERVICE_NAME_LEN); 74999a2dd95SBruce Richardson txa->conf_cb = conf_cb; 75099a2dd95SBruce Richardson txa->conf_arg = conf_arg; 75199a2dd95SBruce Richardson txa->service_id = TXA_INVALID_SERVICE_ID; 75299a2dd95SBruce Richardson rte_spinlock_init(&txa->tx_lock); 75399a2dd95SBruce Richardson txa_service_data_array[id] = txa; 75499a2dd95SBruce Richardson 75599a2dd95SBruce Richardson return 0; 75699a2dd95SBruce Richardson } 75799a2dd95SBruce Richardson 75899a2dd95SBruce Richardson static int 75999a2dd95SBruce Richardson txa_service_event_port_get(uint8_t id, uint8_t *port) 76099a2dd95SBruce Richardson { 76199a2dd95SBruce Richardson struct txa_service_data *txa; 76299a2dd95SBruce Richardson 76399a2dd95SBruce Richardson txa = txa_service_id_to_data(id); 76499a2dd95SBruce Richardson if (txa->service_id == TXA_INVALID_SERVICE_ID) 76599a2dd95SBruce Richardson return -ENODEV; 76699a2dd95SBruce Richardson 76799a2dd95SBruce Richardson *port = txa->port_id; 76899a2dd95SBruce Richardson return 0; 76999a2dd95SBruce Richardson } 77099a2dd95SBruce Richardson 77199a2dd95SBruce Richardson static int 77299a2dd95SBruce Richardson txa_service_adapter_free(uint8_t id) 77399a2dd95SBruce Richardson { 77499a2dd95SBruce Richardson struct txa_service_data *txa; 77599a2dd95SBruce Richardson 77699a2dd95SBruce Richardson txa = txa_service_id_to_data(id); 77799a2dd95SBruce Richardson if (txa->nb_queues) { 77899a2dd95SBruce Richardson RTE_EDEV_LOG_ERR("%" PRIu16 " Tx queues not deleted", 77999a2dd95SBruce Richardson txa->nb_queues); 78099a2dd95SBruce Richardson return -EBUSY; 78199a2dd95SBruce Richardson } 78299a2dd95SBruce Richardson 78399a2dd95SBruce Richardson if (txa->conf_free) 78499a2dd95SBruce Richardson rte_free(txa->conf_arg); 78599a2dd95SBruce Richardson rte_free(txa); 78699a2dd95SBruce Richardson return 0; 78799a2dd95SBruce Richardson } 78899a2dd95SBruce Richardson 78999a2dd95SBruce Richardson static int 79099a2dd95SBruce Richardson txa_service_queue_add(uint8_t id, 79199a2dd95SBruce Richardson __rte_unused struct rte_eventdev *dev, 79299a2dd95SBruce Richardson const struct rte_eth_dev *eth_dev, 79399a2dd95SBruce Richardson int32_t tx_queue_id) 79499a2dd95SBruce Richardson { 79599a2dd95SBruce Richardson struct txa_service_data *txa; 79699a2dd95SBruce Richardson struct txa_service_ethdev *tdi; 79799a2dd95SBruce Richardson struct txa_service_queue_info *tqi; 79899a2dd95SBruce Richardson struct rte_eth_dev_tx_buffer *tb; 79999a2dd95SBruce Richardson struct txa_retry *txa_retry; 80099a2dd95SBruce Richardson int ret = 0; 80199a2dd95SBruce Richardson 80299a2dd95SBruce Richardson txa = txa_service_id_to_data(id); 80399a2dd95SBruce Richardson 80499a2dd95SBruce Richardson if (tx_queue_id == -1) { 80599a2dd95SBruce Richardson int nb_queues; 80699a2dd95SBruce Richardson uint16_t i, j; 80799a2dd95SBruce Richardson uint16_t *qdone; 80899a2dd95SBruce Richardson 80999a2dd95SBruce Richardson nb_queues = eth_dev->data->nb_tx_queues; 81099a2dd95SBruce Richardson if (txa->dev_count > eth_dev->data->port_id) { 81199a2dd95SBruce Richardson tdi = &txa->txa_ethdev[eth_dev->data->port_id]; 81299a2dd95SBruce Richardson nb_queues -= tdi->nb_queues; 81399a2dd95SBruce Richardson } 81499a2dd95SBruce Richardson 81599a2dd95SBruce Richardson qdone = rte_zmalloc(txa->mem_name, 81699a2dd95SBruce Richardson nb_queues * sizeof(*qdone), 0); 81799a2dd95SBruce Richardson if (qdone == NULL) 81899a2dd95SBruce Richardson return -ENOMEM; 81999a2dd95SBruce Richardson j = 0; 82099a2dd95SBruce Richardson for (i = 0; i < nb_queues; i++) { 82199a2dd95SBruce Richardson if (txa_service_is_queue_added(txa, eth_dev, i)) 82299a2dd95SBruce Richardson continue; 82399a2dd95SBruce Richardson ret = txa_service_queue_add(id, dev, eth_dev, i); 82499a2dd95SBruce Richardson if (ret == 0) 82599a2dd95SBruce Richardson qdone[j++] = i; 82699a2dd95SBruce Richardson else 82799a2dd95SBruce Richardson break; 82899a2dd95SBruce Richardson } 82999a2dd95SBruce Richardson 83099a2dd95SBruce Richardson if (i != nb_queues) { 83199a2dd95SBruce Richardson for (i = 0; i < j; i++) 83299a2dd95SBruce Richardson txa_service_queue_del(id, eth_dev, qdone[i]); 83399a2dd95SBruce Richardson } 83499a2dd95SBruce Richardson rte_free(qdone); 83599a2dd95SBruce Richardson return ret; 83699a2dd95SBruce Richardson } 83799a2dd95SBruce Richardson 83899a2dd95SBruce Richardson ret = txa_service_register(txa); 83999a2dd95SBruce Richardson if (ret) 84099a2dd95SBruce Richardson return ret; 84199a2dd95SBruce Richardson 84299a2dd95SBruce Richardson rte_spinlock_lock(&txa->tx_lock); 84399a2dd95SBruce Richardson 844bd0a32d1SNaga Harish K S V if (txa_service_is_queue_added(txa, eth_dev, tx_queue_id)) 845bd0a32d1SNaga Harish K S V goto ret_unlock; 84699a2dd95SBruce Richardson 84799a2dd95SBruce Richardson ret = txa_service_queue_array_alloc(txa, eth_dev->data->port_id); 84899a2dd95SBruce Richardson if (ret) 84999a2dd95SBruce Richardson goto err_unlock; 85099a2dd95SBruce Richardson 85199a2dd95SBruce Richardson tb = txa_service_tx_buf_alloc(txa, eth_dev); 85299a2dd95SBruce Richardson if (tb == NULL) 85399a2dd95SBruce Richardson goto err_unlock; 85499a2dd95SBruce Richardson 85599a2dd95SBruce Richardson tdi = &txa->txa_ethdev[eth_dev->data->port_id]; 85699a2dd95SBruce Richardson tqi = txa_service_queue(txa, eth_dev->data->port_id, tx_queue_id); 857bd0a32d1SNaga Harish K S V if (tqi == NULL) 858bd0a32d1SNaga Harish K S V goto err_unlock; 85999a2dd95SBruce Richardson 86099a2dd95SBruce Richardson txa_retry = &tqi->txa_retry; 86199a2dd95SBruce Richardson txa_retry->id = txa->id; 86299a2dd95SBruce Richardson txa_retry->port_id = eth_dev->data->port_id; 86399a2dd95SBruce Richardson txa_retry->tx_queue = tx_queue_id; 86499a2dd95SBruce Richardson 86599a2dd95SBruce Richardson rte_eth_tx_buffer_init(tb, TXA_BATCH_SIZE); 86699a2dd95SBruce Richardson rte_eth_tx_buffer_set_err_callback(tb, 86799a2dd95SBruce Richardson txa_service_buffer_retry, txa_retry); 86899a2dd95SBruce Richardson 86999a2dd95SBruce Richardson tqi->tx_buf = tb; 87099a2dd95SBruce Richardson tqi->added = 1; 87199a2dd95SBruce Richardson tdi->nb_queues++; 87299a2dd95SBruce Richardson txa->nb_queues++; 87399a2dd95SBruce Richardson 874bd0a32d1SNaga Harish K S V ret_unlock: 875bd0a32d1SNaga Harish K S V rte_spinlock_unlock(&txa->tx_lock); 876bd0a32d1SNaga Harish K S V return 0; 877bd0a32d1SNaga Harish K S V 87899a2dd95SBruce Richardson err_unlock: 87999a2dd95SBruce Richardson if (txa->nb_queues == 0) { 88099a2dd95SBruce Richardson txa_service_queue_array_free(txa, 88199a2dd95SBruce Richardson eth_dev->data->port_id); 88299a2dd95SBruce Richardson txa_service_unregister(txa); 88399a2dd95SBruce Richardson } 88499a2dd95SBruce Richardson 88599a2dd95SBruce Richardson rte_spinlock_unlock(&txa->tx_lock); 886bd0a32d1SNaga Harish K S V return -1; 88799a2dd95SBruce Richardson } 88899a2dd95SBruce Richardson 88999a2dd95SBruce Richardson static int 89099a2dd95SBruce Richardson txa_service_queue_del(uint8_t id, 89199a2dd95SBruce Richardson const struct rte_eth_dev *dev, 89299a2dd95SBruce Richardson int32_t tx_queue_id) 89399a2dd95SBruce Richardson { 89499a2dd95SBruce Richardson struct txa_service_data *txa; 89599a2dd95SBruce Richardson struct txa_service_queue_info *tqi; 89699a2dd95SBruce Richardson struct rte_eth_dev_tx_buffer *tb; 89799a2dd95SBruce Richardson uint16_t port_id; 89899a2dd95SBruce Richardson 89999a2dd95SBruce Richardson txa = txa_service_id_to_data(id); 90099a2dd95SBruce Richardson port_id = dev->data->port_id; 90199a2dd95SBruce Richardson 90299a2dd95SBruce Richardson if (tx_queue_id == -1) { 90399a2dd95SBruce Richardson uint16_t i, q, nb_queues; 90499a2dd95SBruce Richardson int ret = 0; 90599a2dd95SBruce Richardson 906741b499eSNaga Harish K S V nb_queues = txa->txa_ethdev[port_id].nb_queues; 90799a2dd95SBruce Richardson if (nb_queues == 0) 90899a2dd95SBruce Richardson return 0; 90999a2dd95SBruce Richardson 91099a2dd95SBruce Richardson i = 0; 91199a2dd95SBruce Richardson q = 0; 91299a2dd95SBruce Richardson tqi = txa->txa_ethdev[port_id].queues; 91399a2dd95SBruce Richardson 91499a2dd95SBruce Richardson while (i < nb_queues) { 91599a2dd95SBruce Richardson 91699a2dd95SBruce Richardson if (tqi[q].added) { 91799a2dd95SBruce Richardson ret = txa_service_queue_del(id, dev, q); 91899a2dd95SBruce Richardson if (ret != 0) 91999a2dd95SBruce Richardson break; 92099a2dd95SBruce Richardson } 92199a2dd95SBruce Richardson i++; 92299a2dd95SBruce Richardson q++; 92399a2dd95SBruce Richardson } 92499a2dd95SBruce Richardson return ret; 92599a2dd95SBruce Richardson } 92699a2dd95SBruce Richardson 92799a2dd95SBruce Richardson txa = txa_service_id_to_data(id); 92899a2dd95SBruce Richardson 929881d4b4dSNaga Harish K S V rte_spinlock_lock(&txa->tx_lock); 93099a2dd95SBruce Richardson tqi = txa_service_queue(txa, port_id, tx_queue_id); 93199a2dd95SBruce Richardson if (tqi == NULL || !tqi->added) 932881d4b4dSNaga Harish K S V goto ret_unlock; 93399a2dd95SBruce Richardson 93499a2dd95SBruce Richardson tb = tqi->tx_buf; 93599a2dd95SBruce Richardson tqi->added = 0; 93699a2dd95SBruce Richardson tqi->tx_buf = NULL; 93799a2dd95SBruce Richardson rte_free(tb); 93899a2dd95SBruce Richardson txa->nb_queues--; 93999a2dd95SBruce Richardson txa->txa_ethdev[port_id].nb_queues--; 94099a2dd95SBruce Richardson 94199a2dd95SBruce Richardson txa_service_queue_array_free(txa, port_id); 942881d4b4dSNaga Harish K S V 943881d4b4dSNaga Harish K S V ret_unlock: 944881d4b4dSNaga Harish K S V rte_spinlock_unlock(&txa->tx_lock); 94599a2dd95SBruce Richardson return 0; 94699a2dd95SBruce Richardson } 94799a2dd95SBruce Richardson 94899a2dd95SBruce Richardson static int 94999a2dd95SBruce Richardson txa_service_id_get(uint8_t id, uint32_t *service_id) 95099a2dd95SBruce Richardson { 95199a2dd95SBruce Richardson struct txa_service_data *txa; 95299a2dd95SBruce Richardson 95399a2dd95SBruce Richardson txa = txa_service_id_to_data(id); 95499a2dd95SBruce Richardson if (txa->service_id == TXA_INVALID_SERVICE_ID) 95599a2dd95SBruce Richardson return -ESRCH; 95699a2dd95SBruce Richardson 95799a2dd95SBruce Richardson if (service_id == NULL) 95899a2dd95SBruce Richardson return -EINVAL; 95999a2dd95SBruce Richardson 96099a2dd95SBruce Richardson *service_id = txa->service_id; 96199a2dd95SBruce Richardson return 0; 96299a2dd95SBruce Richardson } 96399a2dd95SBruce Richardson 96499a2dd95SBruce Richardson static int 96599a2dd95SBruce Richardson txa_service_start(uint8_t id) 96699a2dd95SBruce Richardson { 96799a2dd95SBruce Richardson return txa_service_ctrl(id, 1); 96899a2dd95SBruce Richardson } 96999a2dd95SBruce Richardson 97099a2dd95SBruce Richardson static int 97199a2dd95SBruce Richardson txa_service_stats_get(uint8_t id, 97299a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats *stats) 97399a2dd95SBruce Richardson { 97499a2dd95SBruce Richardson struct txa_service_data *txa; 97599a2dd95SBruce Richardson 97699a2dd95SBruce Richardson txa = txa_service_id_to_data(id); 97799a2dd95SBruce Richardson *stats = txa->stats; 97899a2dd95SBruce Richardson return 0; 97999a2dd95SBruce Richardson } 98099a2dd95SBruce Richardson 98199a2dd95SBruce Richardson static int 98299a2dd95SBruce Richardson txa_service_stats_reset(uint8_t id) 98399a2dd95SBruce Richardson { 98499a2dd95SBruce Richardson struct txa_service_data *txa; 98599a2dd95SBruce Richardson 98699a2dd95SBruce Richardson txa = txa_service_id_to_data(id); 98799a2dd95SBruce Richardson memset(&txa->stats, 0, sizeof(txa->stats)); 98899a2dd95SBruce Richardson return 0; 98999a2dd95SBruce Richardson } 99099a2dd95SBruce Richardson 99199a2dd95SBruce Richardson static int 99299a2dd95SBruce Richardson txa_service_stop(uint8_t id) 99399a2dd95SBruce Richardson { 99499a2dd95SBruce Richardson return txa_service_ctrl(id, 0); 99599a2dd95SBruce Richardson } 99699a2dd95SBruce Richardson 99799a2dd95SBruce Richardson 99899a2dd95SBruce Richardson int 99999a2dd95SBruce Richardson rte_event_eth_tx_adapter_create(uint8_t id, uint8_t dev_id, 100099a2dd95SBruce Richardson struct rte_event_port_conf *port_conf) 100199a2dd95SBruce Richardson { 100299a2dd95SBruce Richardson struct rte_eventdev *dev; 100399a2dd95SBruce Richardson int ret; 100499a2dd95SBruce Richardson 100599a2dd95SBruce Richardson if (port_conf == NULL) 100699a2dd95SBruce Richardson return -EINVAL; 100799a2dd95SBruce Richardson 100899a2dd95SBruce Richardson RTE_EVENT_ETH_TX_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL); 100999a2dd95SBruce Richardson RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 101099a2dd95SBruce Richardson 101199a2dd95SBruce Richardson dev = &rte_eventdevs[dev_id]; 101299a2dd95SBruce Richardson 101399a2dd95SBruce Richardson ret = txa_init(); 101499a2dd95SBruce Richardson if (ret != 0) 101599a2dd95SBruce Richardson return ret; 101699a2dd95SBruce Richardson 101799a2dd95SBruce Richardson if (txa_adapter_exist(id)) 101899a2dd95SBruce Richardson return -EEXIST; 101999a2dd95SBruce Richardson 102099a2dd95SBruce Richardson txa_dev_id_array[id] = dev_id; 102199a2dd95SBruce Richardson if (txa_dev_adapter_create(id)) 102299a2dd95SBruce Richardson ret = txa_dev_adapter_create(id)(id, dev); 102399a2dd95SBruce Richardson 102499a2dd95SBruce Richardson if (ret != 0) { 102599a2dd95SBruce Richardson txa_dev_id_array[id] = TXA_INVALID_DEV_ID; 102699a2dd95SBruce Richardson return ret; 102799a2dd95SBruce Richardson } 102899a2dd95SBruce Richardson 102999a2dd95SBruce Richardson ret = txa_service_adapter_create(id, dev, port_conf); 103099a2dd95SBruce Richardson if (ret != 0) { 103199a2dd95SBruce Richardson if (txa_dev_adapter_free(id)) 103299a2dd95SBruce Richardson txa_dev_adapter_free(id)(id, dev); 103399a2dd95SBruce Richardson txa_dev_id_array[id] = TXA_INVALID_DEV_ID; 103499a2dd95SBruce Richardson return ret; 103599a2dd95SBruce Richardson } 103699a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_create(id, dev_id, NULL, port_conf, 103799a2dd95SBruce Richardson ret); 103899a2dd95SBruce Richardson txa_dev_id_array[id] = dev_id; 103999a2dd95SBruce Richardson return 0; 104099a2dd95SBruce Richardson } 104199a2dd95SBruce Richardson 104299a2dd95SBruce Richardson int 104399a2dd95SBruce Richardson rte_event_eth_tx_adapter_create_ext(uint8_t id, uint8_t dev_id, 104499a2dd95SBruce Richardson rte_event_eth_tx_adapter_conf_cb conf_cb, 104599a2dd95SBruce Richardson void *conf_arg) 104699a2dd95SBruce Richardson { 104799a2dd95SBruce Richardson struct rte_eventdev *dev; 104899a2dd95SBruce Richardson int ret; 104999a2dd95SBruce Richardson 105099a2dd95SBruce Richardson RTE_EVENT_ETH_TX_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL); 105199a2dd95SBruce Richardson RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 105299a2dd95SBruce Richardson 105399a2dd95SBruce Richardson ret = txa_init(); 105499a2dd95SBruce Richardson if (ret != 0) 105599a2dd95SBruce Richardson return ret; 105699a2dd95SBruce Richardson 105799a2dd95SBruce Richardson if (txa_adapter_exist(id)) 105899a2dd95SBruce Richardson return -EINVAL; 105999a2dd95SBruce Richardson 106099a2dd95SBruce Richardson dev = &rte_eventdevs[dev_id]; 106199a2dd95SBruce Richardson 106299a2dd95SBruce Richardson txa_dev_id_array[id] = dev_id; 106399a2dd95SBruce Richardson if (txa_dev_adapter_create_ext(id)) 106499a2dd95SBruce Richardson ret = txa_dev_adapter_create_ext(id)(id, dev); 106599a2dd95SBruce Richardson 106699a2dd95SBruce Richardson if (ret != 0) { 106799a2dd95SBruce Richardson txa_dev_id_array[id] = TXA_INVALID_DEV_ID; 106899a2dd95SBruce Richardson return ret; 106999a2dd95SBruce Richardson } 107099a2dd95SBruce Richardson 107199a2dd95SBruce Richardson ret = txa_service_adapter_create_ext(id, dev, conf_cb, conf_arg); 107299a2dd95SBruce Richardson if (ret != 0) { 107399a2dd95SBruce Richardson if (txa_dev_adapter_free(id)) 107499a2dd95SBruce Richardson txa_dev_adapter_free(id)(id, dev); 107599a2dd95SBruce Richardson txa_dev_id_array[id] = TXA_INVALID_DEV_ID; 107699a2dd95SBruce Richardson return ret; 107799a2dd95SBruce Richardson } 107899a2dd95SBruce Richardson 107999a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_create(id, dev_id, conf_cb, conf_arg, 108099a2dd95SBruce Richardson ret); 108199a2dd95SBruce Richardson txa_dev_id_array[id] = dev_id; 108299a2dd95SBruce Richardson return 0; 108399a2dd95SBruce Richardson } 108499a2dd95SBruce Richardson 108599a2dd95SBruce Richardson 108699a2dd95SBruce Richardson int 108799a2dd95SBruce Richardson rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id) 108899a2dd95SBruce Richardson { 108999a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id); 109099a2dd95SBruce Richardson 109199a2dd95SBruce Richardson return txa_service_event_port_get(id, event_port_id); 109299a2dd95SBruce Richardson } 109399a2dd95SBruce Richardson 109499a2dd95SBruce Richardson int 109599a2dd95SBruce Richardson rte_event_eth_tx_adapter_free(uint8_t id) 109699a2dd95SBruce Richardson { 109799a2dd95SBruce Richardson int ret; 109899a2dd95SBruce Richardson 109999a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id); 110099a2dd95SBruce Richardson 110199a2dd95SBruce Richardson ret = txa_dev_adapter_free(id) ? 110299a2dd95SBruce Richardson txa_dev_adapter_free(id)(id, txa_evdev(id)) : 110399a2dd95SBruce Richardson 0; 110499a2dd95SBruce Richardson 110599a2dd95SBruce Richardson if (ret == 0) 110699a2dd95SBruce Richardson ret = txa_service_adapter_free(id); 110799a2dd95SBruce Richardson txa_dev_id_array[id] = TXA_INVALID_DEV_ID; 110899a2dd95SBruce Richardson 110999a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_free(id, ret); 111099a2dd95SBruce Richardson return ret; 111199a2dd95SBruce Richardson } 111299a2dd95SBruce Richardson 111399a2dd95SBruce Richardson int 111499a2dd95SBruce Richardson rte_event_eth_tx_adapter_queue_add(uint8_t id, 111599a2dd95SBruce Richardson uint16_t eth_dev_id, 111699a2dd95SBruce Richardson int32_t queue) 111799a2dd95SBruce Richardson { 111899a2dd95SBruce Richardson struct rte_eth_dev *eth_dev; 111999a2dd95SBruce Richardson int ret; 112099a2dd95SBruce Richardson uint32_t caps; 112199a2dd95SBruce Richardson 112299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(eth_dev_id, -EINVAL); 112399a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id); 112499a2dd95SBruce Richardson 112599a2dd95SBruce Richardson eth_dev = &rte_eth_devices[eth_dev_id]; 112699a2dd95SBruce Richardson TXA_CHECK_TXQ(eth_dev, queue); 112799a2dd95SBruce Richardson 112899a2dd95SBruce Richardson caps = 0; 112999a2dd95SBruce Richardson if (txa_dev_caps_get(id)) 113099a2dd95SBruce Richardson txa_dev_caps_get(id)(txa_evdev(id), eth_dev, &caps); 113199a2dd95SBruce Richardson 113299a2dd95SBruce Richardson if (caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) 113399a2dd95SBruce Richardson ret = txa_dev_queue_add(id) ? 113499a2dd95SBruce Richardson txa_dev_queue_add(id)(id, 113599a2dd95SBruce Richardson txa_evdev(id), 113699a2dd95SBruce Richardson eth_dev, 113799a2dd95SBruce Richardson queue) : 0; 113899a2dd95SBruce Richardson else 113999a2dd95SBruce Richardson ret = txa_service_queue_add(id, txa_evdev(id), eth_dev, queue); 114099a2dd95SBruce Richardson 114199a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_queue_add(id, eth_dev_id, queue, 114299a2dd95SBruce Richardson ret); 114399a2dd95SBruce Richardson return ret; 114499a2dd95SBruce Richardson } 114599a2dd95SBruce Richardson 114699a2dd95SBruce Richardson int 114799a2dd95SBruce Richardson rte_event_eth_tx_adapter_queue_del(uint8_t id, 114899a2dd95SBruce Richardson uint16_t eth_dev_id, 114999a2dd95SBruce Richardson int32_t queue) 115099a2dd95SBruce Richardson { 115199a2dd95SBruce Richardson struct rte_eth_dev *eth_dev; 115299a2dd95SBruce Richardson int ret; 115399a2dd95SBruce Richardson uint32_t caps; 115499a2dd95SBruce Richardson 115599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(eth_dev_id, -EINVAL); 115699a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id); 115799a2dd95SBruce Richardson 115899a2dd95SBruce Richardson eth_dev = &rte_eth_devices[eth_dev_id]; 115999a2dd95SBruce Richardson 116099a2dd95SBruce Richardson caps = 0; 116199a2dd95SBruce Richardson 116299a2dd95SBruce Richardson if (txa_dev_caps_get(id)) 116399a2dd95SBruce Richardson txa_dev_caps_get(id)(txa_evdev(id), eth_dev, &caps); 116499a2dd95SBruce Richardson 116599a2dd95SBruce Richardson if (caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) 116699a2dd95SBruce Richardson ret = txa_dev_queue_del(id) ? 116799a2dd95SBruce Richardson txa_dev_queue_del(id)(id, txa_evdev(id), 116899a2dd95SBruce Richardson eth_dev, 116999a2dd95SBruce Richardson queue) : 0; 117099a2dd95SBruce Richardson else 117199a2dd95SBruce Richardson ret = txa_service_queue_del(id, eth_dev, queue); 117299a2dd95SBruce Richardson 117399a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_queue_del(id, eth_dev_id, queue, 117499a2dd95SBruce Richardson ret); 117599a2dd95SBruce Richardson return ret; 117699a2dd95SBruce Richardson } 117799a2dd95SBruce Richardson 117899a2dd95SBruce Richardson int 117999a2dd95SBruce Richardson rte_event_eth_tx_adapter_service_id_get(uint8_t id, uint32_t *service_id) 118099a2dd95SBruce Richardson { 118199a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id); 118299a2dd95SBruce Richardson 118399a2dd95SBruce Richardson return txa_service_id_get(id, service_id); 118499a2dd95SBruce Richardson } 118599a2dd95SBruce Richardson 118699a2dd95SBruce Richardson int 118799a2dd95SBruce Richardson rte_event_eth_tx_adapter_start(uint8_t id) 118899a2dd95SBruce Richardson { 118999a2dd95SBruce Richardson int ret; 119099a2dd95SBruce Richardson 119199a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id); 119299a2dd95SBruce Richardson 119399a2dd95SBruce Richardson ret = txa_dev_start(id) ? txa_dev_start(id)(id, txa_evdev(id)) : 0; 119499a2dd95SBruce Richardson if (ret == 0) 119599a2dd95SBruce Richardson ret = txa_service_start(id); 119699a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_start(id, ret); 119799a2dd95SBruce Richardson return ret; 119899a2dd95SBruce Richardson } 119999a2dd95SBruce Richardson 120099a2dd95SBruce Richardson int 120199a2dd95SBruce Richardson rte_event_eth_tx_adapter_stats_get(uint8_t id, 120299a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats *stats) 120399a2dd95SBruce Richardson { 120499a2dd95SBruce Richardson int ret; 120599a2dd95SBruce Richardson 120699a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id); 120799a2dd95SBruce Richardson 120899a2dd95SBruce Richardson if (stats == NULL) 120999a2dd95SBruce Richardson return -EINVAL; 121099a2dd95SBruce Richardson 121199a2dd95SBruce Richardson *stats = (struct rte_event_eth_tx_adapter_stats){0}; 121299a2dd95SBruce Richardson 121399a2dd95SBruce Richardson ret = txa_dev_stats_get(id) ? 121499a2dd95SBruce Richardson txa_dev_stats_get(id)(id, txa_evdev(id), stats) : 0; 121599a2dd95SBruce Richardson 121699a2dd95SBruce Richardson if (ret == 0 && txa_service_id_get(id, NULL) != ESRCH) { 121799a2dd95SBruce Richardson if (txa_dev_stats_get(id)) { 121899a2dd95SBruce Richardson struct rte_event_eth_tx_adapter_stats service_stats; 121999a2dd95SBruce Richardson 122099a2dd95SBruce Richardson ret = txa_service_stats_get(id, &service_stats); 122199a2dd95SBruce Richardson if (ret == 0) { 122299a2dd95SBruce Richardson stats->tx_retry += service_stats.tx_retry; 122399a2dd95SBruce Richardson stats->tx_packets += service_stats.tx_packets; 122499a2dd95SBruce Richardson stats->tx_dropped += service_stats.tx_dropped; 122599a2dd95SBruce Richardson } 122699a2dd95SBruce Richardson } else 122799a2dd95SBruce Richardson ret = txa_service_stats_get(id, stats); 122899a2dd95SBruce Richardson } 122999a2dd95SBruce Richardson 123099a2dd95SBruce Richardson return ret; 123199a2dd95SBruce Richardson } 123299a2dd95SBruce Richardson 123399a2dd95SBruce Richardson int 123499a2dd95SBruce Richardson rte_event_eth_tx_adapter_stats_reset(uint8_t id) 123599a2dd95SBruce Richardson { 123699a2dd95SBruce Richardson int ret; 123799a2dd95SBruce Richardson 123899a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id); 123999a2dd95SBruce Richardson 124099a2dd95SBruce Richardson ret = txa_dev_stats_reset(id) ? 124199a2dd95SBruce Richardson txa_dev_stats_reset(id)(id, txa_evdev(id)) : 0; 124299a2dd95SBruce Richardson if (ret == 0) 124399a2dd95SBruce Richardson ret = txa_service_stats_reset(id); 124499a2dd95SBruce Richardson return ret; 124599a2dd95SBruce Richardson } 124699a2dd95SBruce Richardson 124799a2dd95SBruce Richardson int 124899a2dd95SBruce Richardson rte_event_eth_tx_adapter_stop(uint8_t id) 124999a2dd95SBruce Richardson { 125099a2dd95SBruce Richardson int ret; 125199a2dd95SBruce Richardson 125299a2dd95SBruce Richardson TXA_CHECK_OR_ERR_RET(id); 125399a2dd95SBruce Richardson 125499a2dd95SBruce Richardson ret = txa_dev_stop(id) ? txa_dev_stop(id)(id, txa_evdev(id)) : 0; 125599a2dd95SBruce Richardson if (ret == 0) 125699a2dd95SBruce Richardson ret = txa_service_stop(id); 125799a2dd95SBruce Richardson rte_eventdev_trace_eth_tx_adapter_stop(id, ret); 125899a2dd95SBruce Richardson return ret; 125999a2dd95SBruce Richardson } 1260b2963cbdSGanapati Kundapura 1261b2963cbdSGanapati Kundapura int 1262b2963cbdSGanapati Kundapura rte_event_eth_tx_adapter_instance_get(uint16_t eth_dev_id, 1263b2963cbdSGanapati Kundapura uint16_t tx_queue_id, 1264b2963cbdSGanapati Kundapura uint8_t *txa_inst_id) 1265b2963cbdSGanapati Kundapura { 1266b2963cbdSGanapati Kundapura uint8_t id; 1267b2963cbdSGanapati Kundapura int ret = -EINVAL; 1268b2963cbdSGanapati Kundapura uint32_t caps; 1269b2963cbdSGanapati Kundapura struct txa_service_data *txa; 1270b2963cbdSGanapati Kundapura 1271b2963cbdSGanapati Kundapura if (txa_lookup()) 1272b2963cbdSGanapati Kundapura return -ENOMEM; 1273b2963cbdSGanapati Kundapura 1274b2963cbdSGanapati Kundapura if (eth_dev_id >= rte_eth_dev_count_avail()) { 1275b2963cbdSGanapati Kundapura RTE_EDEV_LOG_ERR("Invalid ethernet port id %u", eth_dev_id); 1276b2963cbdSGanapati Kundapura return -EINVAL; 1277b2963cbdSGanapati Kundapura } 1278b2963cbdSGanapati Kundapura 1279b2963cbdSGanapati Kundapura if (tx_queue_id >= rte_eth_devices[eth_dev_id].data->nb_tx_queues) { 1280b2963cbdSGanapati Kundapura RTE_EDEV_LOG_ERR("Invalid tx queue id %u", tx_queue_id); 1281b2963cbdSGanapati Kundapura return -EINVAL; 1282b2963cbdSGanapati Kundapura } 1283b2963cbdSGanapati Kundapura 1284b2963cbdSGanapati Kundapura if (txa_inst_id == NULL) { 1285b2963cbdSGanapati Kundapura RTE_EDEV_LOG_ERR("txa_instance_id cannot be NULL"); 1286b2963cbdSGanapati Kundapura return -EINVAL; 1287b2963cbdSGanapati Kundapura } 1288b2963cbdSGanapati Kundapura 1289b2963cbdSGanapati Kundapura /* Iterate through all Tx adapter instances */ 1290b2963cbdSGanapati Kundapura for (id = 0; id < RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE; id++) { 1291b2963cbdSGanapati Kundapura txa = txa_service_id_to_data(id); 1292b2963cbdSGanapati Kundapura if (!txa) 1293b2963cbdSGanapati Kundapura continue; 1294b2963cbdSGanapati Kundapura 1295b2963cbdSGanapati Kundapura caps = 0; 1296b2963cbdSGanapati Kundapura if (rte_event_eth_tx_adapter_caps_get(txa->eventdev_id, 1297b2963cbdSGanapati Kundapura eth_dev_id, 1298b2963cbdSGanapati Kundapura &caps)) 1299b2963cbdSGanapati Kundapura continue; 1300b2963cbdSGanapati Kundapura 1301b2963cbdSGanapati Kundapura if (caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) { 1302b2963cbdSGanapati Kundapura ret = txa_dev_instance_get(id) ? 1303b2963cbdSGanapati Kundapura txa_dev_instance_get(id)(eth_dev_id, 1304b2963cbdSGanapati Kundapura tx_queue_id, 1305b2963cbdSGanapati Kundapura txa_inst_id) 1306b2963cbdSGanapati Kundapura : -EINVAL; 1307b2963cbdSGanapati Kundapura if (ret == 0) 1308b2963cbdSGanapati Kundapura return ret; 1309b2963cbdSGanapati Kundapura } else { 1310b2963cbdSGanapati Kundapura struct rte_eth_dev *eth_dev; 1311b2963cbdSGanapati Kundapura 1312b2963cbdSGanapati Kundapura eth_dev = &rte_eth_devices[eth_dev_id]; 1313b2963cbdSGanapati Kundapura 1314b2963cbdSGanapati Kundapura if (txa_service_is_queue_added(txa, eth_dev, 1315b2963cbdSGanapati Kundapura tx_queue_id)) { 1316b2963cbdSGanapati Kundapura *txa_inst_id = txa->id; 1317b2963cbdSGanapati Kundapura return 0; 1318b2963cbdSGanapati Kundapura } 1319b2963cbdSGanapati Kundapura } 1320b2963cbdSGanapati Kundapura } 1321b2963cbdSGanapati Kundapura 1322b2963cbdSGanapati Kundapura return -EINVAL; 1323b2963cbdSGanapati Kundapura } 1324