199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2010-2017 Intel Corporation 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #include <ctype.h> 699a2dd95SBruce Richardson #include <errno.h> 799a2dd95SBruce Richardson #include <inttypes.h> 899a2dd95SBruce Richardson #include <stdbool.h> 999a2dd95SBruce Richardson #include <stdint.h> 1099a2dd95SBruce Richardson #include <stdlib.h> 1199a2dd95SBruce Richardson #include <string.h> 1299a2dd95SBruce Richardson #include <sys/queue.h> 1399a2dd95SBruce Richardson 1499a2dd95SBruce Richardson #include <rte_byteorder.h> 1599a2dd95SBruce Richardson #include <rte_log.h> 1699a2dd95SBruce Richardson #include <rte_debug.h> 1799a2dd95SBruce Richardson #include <rte_interrupts.h> 1899a2dd95SBruce Richardson #include <rte_memory.h> 1999a2dd95SBruce Richardson #include <rte_memcpy.h> 2099a2dd95SBruce Richardson #include <rte_memzone.h> 2199a2dd95SBruce Richardson #include <rte_launch.h> 2299a2dd95SBruce Richardson #include <rte_eal.h> 2399a2dd95SBruce Richardson #include <rte_per_lcore.h> 2499a2dd95SBruce Richardson #include <rte_lcore.h> 2599a2dd95SBruce Richardson #include <rte_branch_prediction.h> 2699a2dd95SBruce Richardson #include <rte_common.h> 2799a2dd95SBruce Richardson #include <rte_mempool.h> 2899a2dd95SBruce Richardson #include <rte_malloc.h> 2999a2dd95SBruce Richardson #include <rte_mbuf.h> 3099a2dd95SBruce Richardson #include <rte_errno.h> 3199a2dd95SBruce Richardson #include <rte_spinlock.h> 3299a2dd95SBruce Richardson #include <rte_string_fns.h> 3399a2dd95SBruce Richardson #include <rte_kvargs.h> 3499a2dd95SBruce Richardson #include <rte_class.h> 3599a2dd95SBruce Richardson #include <rte_ether.h> 3699a2dd95SBruce Richardson #include <rte_telemetry.h> 3799a2dd95SBruce Richardson 3899a2dd95SBruce Richardson #include "rte_ethdev_trace.h" 3999a2dd95SBruce Richardson #include "rte_ethdev.h" 4099a2dd95SBruce Richardson #include "ethdev_driver.h" 4199a2dd95SBruce Richardson #include "ethdev_profile.h" 4299a2dd95SBruce Richardson #include "ethdev_private.h" 4399a2dd95SBruce Richardson 4499a2dd95SBruce Richardson static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data"; 4599a2dd95SBruce Richardson struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS]; 4699a2dd95SBruce Richardson 47c87d435aSKonstantin Ananyev /* public fast-path API */ 48c87d435aSKonstantin Ananyev struct rte_eth_fp_ops rte_eth_fp_ops[RTE_MAX_ETHPORTS]; 49c87d435aSKonstantin Ananyev 5099a2dd95SBruce Richardson /* spinlock for eth device callbacks */ 5199a2dd95SBruce Richardson static rte_spinlock_t eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER; 5299a2dd95SBruce Richardson 5309fd4227SAndrew Rybchenko /* spinlock for add/remove Rx callbacks */ 5499a2dd95SBruce Richardson static rte_spinlock_t eth_dev_rx_cb_lock = RTE_SPINLOCK_INITIALIZER; 5599a2dd95SBruce Richardson 5609fd4227SAndrew Rybchenko /* spinlock for add/remove Tx callbacks */ 5799a2dd95SBruce Richardson static rte_spinlock_t eth_dev_tx_cb_lock = RTE_SPINLOCK_INITIALIZER; 5899a2dd95SBruce Richardson 5999a2dd95SBruce Richardson /* spinlock for shared data allocation */ 6099a2dd95SBruce Richardson static rte_spinlock_t eth_dev_shared_data_lock = RTE_SPINLOCK_INITIALIZER; 6199a2dd95SBruce Richardson 6299a2dd95SBruce Richardson /* store statistics names and its offset in stats structure */ 6399a2dd95SBruce Richardson struct rte_eth_xstats_name_off { 6499a2dd95SBruce Richardson char name[RTE_ETH_XSTATS_NAME_SIZE]; 6599a2dd95SBruce Richardson unsigned offset; 6699a2dd95SBruce Richardson }; 6799a2dd95SBruce Richardson 6899a2dd95SBruce Richardson /* Shared memory between primary and secondary processes. */ 6999a2dd95SBruce Richardson static struct { 7099a2dd95SBruce Richardson uint64_t next_owner_id; 7199a2dd95SBruce Richardson rte_spinlock_t ownership_lock; 7299a2dd95SBruce Richardson struct rte_eth_dev_data data[RTE_MAX_ETHPORTS]; 7399a2dd95SBruce Richardson } *eth_dev_shared_data; 7499a2dd95SBruce Richardson 7599a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_stats_strings[] = { 7699a2dd95SBruce Richardson {"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)}, 7799a2dd95SBruce Richardson {"tx_good_packets", offsetof(struct rte_eth_stats, opackets)}, 7899a2dd95SBruce Richardson {"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)}, 7999a2dd95SBruce Richardson {"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)}, 8099a2dd95SBruce Richardson {"rx_missed_errors", offsetof(struct rte_eth_stats, imissed)}, 8199a2dd95SBruce Richardson {"rx_errors", offsetof(struct rte_eth_stats, ierrors)}, 8299a2dd95SBruce Richardson {"tx_errors", offsetof(struct rte_eth_stats, oerrors)}, 8399a2dd95SBruce Richardson {"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats, 8499a2dd95SBruce Richardson rx_nombuf)}, 8599a2dd95SBruce Richardson }; 8699a2dd95SBruce Richardson 8799a2dd95SBruce Richardson #define RTE_NB_STATS RTE_DIM(eth_dev_stats_strings) 8899a2dd95SBruce Richardson 8999a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_rxq_stats_strings[] = { 9099a2dd95SBruce Richardson {"packets", offsetof(struct rte_eth_stats, q_ipackets)}, 9199a2dd95SBruce Richardson {"bytes", offsetof(struct rte_eth_stats, q_ibytes)}, 9299a2dd95SBruce Richardson {"errors", offsetof(struct rte_eth_stats, q_errors)}, 9399a2dd95SBruce Richardson }; 9499a2dd95SBruce Richardson 9599a2dd95SBruce Richardson #define RTE_NB_RXQ_STATS RTE_DIM(eth_dev_rxq_stats_strings) 9699a2dd95SBruce Richardson 9799a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_txq_stats_strings[] = { 9899a2dd95SBruce Richardson {"packets", offsetof(struct rte_eth_stats, q_opackets)}, 9999a2dd95SBruce Richardson {"bytes", offsetof(struct rte_eth_stats, q_obytes)}, 10099a2dd95SBruce Richardson }; 10199a2dd95SBruce Richardson #define RTE_NB_TXQ_STATS RTE_DIM(eth_dev_txq_stats_strings) 10299a2dd95SBruce Richardson 10399a2dd95SBruce Richardson #define RTE_RX_OFFLOAD_BIT2STR(_name) \ 10499a2dd95SBruce Richardson { RTE_ETH_RX_OFFLOAD_##_name, #_name } 10599a2dd95SBruce Richardson 10699a2dd95SBruce Richardson static const struct { 10799a2dd95SBruce Richardson uint64_t offload; 10899a2dd95SBruce Richardson const char *name; 10999a2dd95SBruce Richardson } eth_dev_rx_offload_names[] = { 11099a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(VLAN_STRIP), 11199a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(IPV4_CKSUM), 11299a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(UDP_CKSUM), 11399a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(TCP_CKSUM), 11499a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(TCP_LRO), 11599a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(QINQ_STRIP), 11699a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM), 11799a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(MACSEC_STRIP), 11899a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(HEADER_SPLIT), 11999a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(VLAN_FILTER), 12099a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(VLAN_EXTEND), 12199a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(SCATTER), 12299a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(TIMESTAMP), 12399a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(SECURITY), 12499a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(KEEP_CRC), 12599a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(SCTP_CKSUM), 12699a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM), 12799a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(RSS_HASH), 128295968d1SFerruh Yigit RTE_RX_OFFLOAD_BIT2STR(BUFFER_SPLIT), 12999a2dd95SBruce Richardson }; 13099a2dd95SBruce Richardson 13199a2dd95SBruce Richardson #undef RTE_RX_OFFLOAD_BIT2STR 13299a2dd95SBruce Richardson #undef RTE_ETH_RX_OFFLOAD_BIT2STR 13399a2dd95SBruce Richardson 13499a2dd95SBruce Richardson #define RTE_TX_OFFLOAD_BIT2STR(_name) \ 135295968d1SFerruh Yigit { RTE_ETH_TX_OFFLOAD_##_name, #_name } 13699a2dd95SBruce Richardson 13799a2dd95SBruce Richardson static const struct { 13899a2dd95SBruce Richardson uint64_t offload; 13999a2dd95SBruce Richardson const char *name; 14099a2dd95SBruce Richardson } eth_dev_tx_offload_names[] = { 14199a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(VLAN_INSERT), 14299a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(IPV4_CKSUM), 14399a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(UDP_CKSUM), 14499a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(TCP_CKSUM), 14599a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(SCTP_CKSUM), 14699a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(TCP_TSO), 14799a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(UDP_TSO), 14899a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM), 14999a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(QINQ_INSERT), 15099a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(VXLAN_TNL_TSO), 15199a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(GRE_TNL_TSO), 15299a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(IPIP_TNL_TSO), 15399a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(GENEVE_TNL_TSO), 15499a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MACSEC_INSERT), 15599a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MT_LOCKFREE), 15699a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MULTI_SEGS), 15799a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MBUF_FAST_FREE), 15899a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(SECURITY), 15999a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(UDP_TNL_TSO), 16099a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(IP_TNL_TSO), 16199a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM), 16299a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(SEND_ON_TIMESTAMP), 16399a2dd95SBruce Richardson }; 16499a2dd95SBruce Richardson 16599a2dd95SBruce Richardson #undef RTE_TX_OFFLOAD_BIT2STR 16699a2dd95SBruce Richardson 16793e441c9SXueming Li static const struct { 16893e441c9SXueming Li uint64_t offload; 16993e441c9SXueming Li const char *name; 17093e441c9SXueming Li } rte_eth_dev_capa_names[] = { 17193e441c9SXueming Li {RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP, "RUNTIME_RX_QUEUE_SETUP"}, 17293e441c9SXueming Li {RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP, "RUNTIME_TX_QUEUE_SETUP"}, 17393e441c9SXueming Li {RTE_ETH_DEV_CAPA_RXQ_SHARE, "RXQ_SHARE"}, 17464be0e77SDmitry Kozlyuk {RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP, "FLOW_RULE_KEEP"}, 17564be0e77SDmitry Kozlyuk {RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"}, 17693e441c9SXueming Li }; 17793e441c9SXueming Li 17899a2dd95SBruce Richardson /** 17999a2dd95SBruce Richardson * The user application callback description. 18099a2dd95SBruce Richardson * 18199a2dd95SBruce Richardson * It contains callback address to be registered by user application, 18299a2dd95SBruce Richardson * the pointer to the parameters for callback, and the event type. 18399a2dd95SBruce Richardson */ 18499a2dd95SBruce Richardson struct rte_eth_dev_callback { 18599a2dd95SBruce Richardson TAILQ_ENTRY(rte_eth_dev_callback) next; /**< Callbacks list */ 18699a2dd95SBruce Richardson rte_eth_dev_cb_fn cb_fn; /**< Callback address */ 18799a2dd95SBruce Richardson void *cb_arg; /**< Parameter for callback */ 18899a2dd95SBruce Richardson void *ret_param; /**< Return parameter */ 18999a2dd95SBruce Richardson enum rte_eth_event_type event; /**< Interrupt event type */ 19099a2dd95SBruce Richardson uint32_t active; /**< Callback is executing */ 19199a2dd95SBruce Richardson }; 19299a2dd95SBruce Richardson 19399a2dd95SBruce Richardson enum { 19499a2dd95SBruce Richardson STAT_QMAP_TX = 0, 19599a2dd95SBruce Richardson STAT_QMAP_RX 19699a2dd95SBruce Richardson }; 19799a2dd95SBruce Richardson 19899a2dd95SBruce Richardson int 19999a2dd95SBruce Richardson rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) 20099a2dd95SBruce Richardson { 20199a2dd95SBruce Richardson int ret; 20299a2dd95SBruce Richardson struct rte_devargs devargs; 20399a2dd95SBruce Richardson const char *bus_param_key; 20499a2dd95SBruce Richardson char *bus_str = NULL; 20599a2dd95SBruce Richardson char *cls_str = NULL; 20699a2dd95SBruce Richardson int str_size; 20799a2dd95SBruce Richardson 20853ef1b34SMin Hu (Connor) if (iter == NULL) { 20953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot initialize NULL iterator\n"); 21053ef1b34SMin Hu (Connor) return -EINVAL; 21153ef1b34SMin Hu (Connor) } 21253ef1b34SMin Hu (Connor) 21353ef1b34SMin Hu (Connor) if (devargs_str == NULL) { 21453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 21553ef1b34SMin Hu (Connor) "Cannot initialize iterator from NULL device description string\n"); 21653ef1b34SMin Hu (Connor) return -EINVAL; 21753ef1b34SMin Hu (Connor) } 21853ef1b34SMin Hu (Connor) 21999a2dd95SBruce Richardson memset(iter, 0, sizeof(*iter)); 22099a2dd95SBruce Richardson memset(&devargs, 0, sizeof(devargs)); 22199a2dd95SBruce Richardson 22299a2dd95SBruce Richardson /* 22399a2dd95SBruce Richardson * The devargs string may use various syntaxes: 22499a2dd95SBruce Richardson * - 0000:08:00.0,representor=[1-3] 22599a2dd95SBruce Richardson * - pci:0000:06:00.0,representor=[0,5] 22699a2dd95SBruce Richardson * - class=eth,mac=00:11:22:33:44:55 22799a2dd95SBruce Richardson * - bus=X,paramX=x/class=Y,paramY=y/driver=Z,paramZ=z 22899a2dd95SBruce Richardson */ 22999a2dd95SBruce Richardson 23099a2dd95SBruce Richardson /* 23199a2dd95SBruce Richardson * Handle pure class filter (i.e. without any bus-level argument), 23299a2dd95SBruce Richardson * from future new syntax. 23399a2dd95SBruce Richardson * rte_devargs_parse() is not yet supporting the new syntax, 23499a2dd95SBruce Richardson * that's why this simple case is temporarily parsed here. 23599a2dd95SBruce Richardson */ 23699a2dd95SBruce Richardson #define iter_anybus_str "class=eth," 23799a2dd95SBruce Richardson if (strncmp(devargs_str, iter_anybus_str, 23899a2dd95SBruce Richardson strlen(iter_anybus_str)) == 0) { 23999a2dd95SBruce Richardson iter->cls_str = devargs_str + strlen(iter_anybus_str); 24099a2dd95SBruce Richardson goto end; 24199a2dd95SBruce Richardson } 24299a2dd95SBruce Richardson 24399a2dd95SBruce Richardson /* Split bus, device and parameters. */ 24499a2dd95SBruce Richardson ret = rte_devargs_parse(&devargs, devargs_str); 24599a2dd95SBruce Richardson if (ret != 0) 24699a2dd95SBruce Richardson goto error; 24799a2dd95SBruce Richardson 24899a2dd95SBruce Richardson /* 24999a2dd95SBruce Richardson * Assume parameters of old syntax can match only at ethdev level. 25099a2dd95SBruce Richardson * Extra parameters will be ignored, thanks to "+" prefix. 25199a2dd95SBruce Richardson */ 25299a2dd95SBruce Richardson str_size = strlen(devargs.args) + 2; 25399a2dd95SBruce Richardson cls_str = malloc(str_size); 25499a2dd95SBruce Richardson if (cls_str == NULL) { 25599a2dd95SBruce Richardson ret = -ENOMEM; 25699a2dd95SBruce Richardson goto error; 25799a2dd95SBruce Richardson } 25899a2dd95SBruce Richardson ret = snprintf(cls_str, str_size, "+%s", devargs.args); 25999a2dd95SBruce Richardson if (ret != str_size - 1) { 26099a2dd95SBruce Richardson ret = -EINVAL; 26199a2dd95SBruce Richardson goto error; 26299a2dd95SBruce Richardson } 26399a2dd95SBruce Richardson iter->cls_str = cls_str; 26499a2dd95SBruce Richardson 26599a2dd95SBruce Richardson iter->bus = devargs.bus; 26699a2dd95SBruce Richardson if (iter->bus->dev_iterate == NULL) { 26799a2dd95SBruce Richardson ret = -ENOTSUP; 26899a2dd95SBruce Richardson goto error; 26999a2dd95SBruce Richardson } 27099a2dd95SBruce Richardson 27199a2dd95SBruce Richardson /* Convert bus args to new syntax for use with new API dev_iterate. */ 272a956adb2SHemant Agrawal if ((strcmp(iter->bus->name, "vdev") == 0) || 273a956adb2SHemant Agrawal (strcmp(iter->bus->name, "fslmc") == 0) || 274a956adb2SHemant Agrawal (strcmp(iter->bus->name, "dpaa_bus") == 0)) { 27599a2dd95SBruce Richardson bus_param_key = "name"; 27699a2dd95SBruce Richardson } else if (strcmp(iter->bus->name, "pci") == 0) { 27799a2dd95SBruce Richardson bus_param_key = "addr"; 27899a2dd95SBruce Richardson } else { 27999a2dd95SBruce Richardson ret = -ENOTSUP; 28099a2dd95SBruce Richardson goto error; 28199a2dd95SBruce Richardson } 28299a2dd95SBruce Richardson str_size = strlen(bus_param_key) + strlen(devargs.name) + 2; 28399a2dd95SBruce Richardson bus_str = malloc(str_size); 28499a2dd95SBruce Richardson if (bus_str == NULL) { 28599a2dd95SBruce Richardson ret = -ENOMEM; 28699a2dd95SBruce Richardson goto error; 28799a2dd95SBruce Richardson } 28899a2dd95SBruce Richardson ret = snprintf(bus_str, str_size, "%s=%s", 28999a2dd95SBruce Richardson bus_param_key, devargs.name); 29099a2dd95SBruce Richardson if (ret != str_size - 1) { 29199a2dd95SBruce Richardson ret = -EINVAL; 29299a2dd95SBruce Richardson goto error; 29399a2dd95SBruce Richardson } 29499a2dd95SBruce Richardson iter->bus_str = bus_str; 29599a2dd95SBruce Richardson 29699a2dd95SBruce Richardson end: 29799a2dd95SBruce Richardson iter->cls = rte_class_find_by_name("eth"); 29899a2dd95SBruce Richardson rte_devargs_reset(&devargs); 29999a2dd95SBruce Richardson return 0; 30099a2dd95SBruce Richardson 30199a2dd95SBruce Richardson error: 30299a2dd95SBruce Richardson if (ret == -ENOTSUP) 30399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Bus %s does not support iterating.\n", 30499a2dd95SBruce Richardson iter->bus->name); 30599a2dd95SBruce Richardson rte_devargs_reset(&devargs); 30699a2dd95SBruce Richardson free(bus_str); 30799a2dd95SBruce Richardson free(cls_str); 30899a2dd95SBruce Richardson return ret; 30999a2dd95SBruce Richardson } 31099a2dd95SBruce Richardson 31199a2dd95SBruce Richardson uint16_t 31299a2dd95SBruce Richardson rte_eth_iterator_next(struct rte_dev_iterator *iter) 31399a2dd95SBruce Richardson { 31453ef1b34SMin Hu (Connor) if (iter == NULL) { 31553ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 31653ef1b34SMin Hu (Connor) "Cannot get next device from NULL iterator\n"); 31753ef1b34SMin Hu (Connor) return RTE_MAX_ETHPORTS; 31853ef1b34SMin Hu (Connor) } 31953ef1b34SMin Hu (Connor) 32099a2dd95SBruce Richardson if (iter->cls == NULL) /* invalid ethdev iterator */ 32199a2dd95SBruce Richardson return RTE_MAX_ETHPORTS; 32299a2dd95SBruce Richardson 32399a2dd95SBruce Richardson do { /* loop to try all matching rte_device */ 32499a2dd95SBruce Richardson /* If not pure ethdev filter and */ 32599a2dd95SBruce Richardson if (iter->bus != NULL && 32699a2dd95SBruce Richardson /* not in middle of rte_eth_dev iteration, */ 32799a2dd95SBruce Richardson iter->class_device == NULL) { 32899a2dd95SBruce Richardson /* get next rte_device to try. */ 32999a2dd95SBruce Richardson iter->device = iter->bus->dev_iterate( 33099a2dd95SBruce Richardson iter->device, iter->bus_str, iter); 33199a2dd95SBruce Richardson if (iter->device == NULL) 33299a2dd95SBruce Richardson break; /* no more rte_device candidate */ 33399a2dd95SBruce Richardson } 33499a2dd95SBruce Richardson /* A device is matching bus part, need to check ethdev part. */ 33599a2dd95SBruce Richardson iter->class_device = iter->cls->dev_iterate( 33699a2dd95SBruce Richardson iter->class_device, iter->cls_str, iter); 33799a2dd95SBruce Richardson if (iter->class_device != NULL) 33899a2dd95SBruce Richardson return eth_dev_to_id(iter->class_device); /* match */ 33999a2dd95SBruce Richardson } while (iter->bus != NULL); /* need to try next rte_device */ 34099a2dd95SBruce Richardson 34199a2dd95SBruce Richardson /* No more ethdev port to iterate. */ 34299a2dd95SBruce Richardson rte_eth_iterator_cleanup(iter); 34399a2dd95SBruce Richardson return RTE_MAX_ETHPORTS; 34499a2dd95SBruce Richardson } 34599a2dd95SBruce Richardson 34699a2dd95SBruce Richardson void 34799a2dd95SBruce Richardson rte_eth_iterator_cleanup(struct rte_dev_iterator *iter) 34899a2dd95SBruce Richardson { 34953ef1b34SMin Hu (Connor) if (iter == NULL) { 35053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot do clean up from NULL iterator\n"); 35153ef1b34SMin Hu (Connor) return; 35253ef1b34SMin Hu (Connor) } 35353ef1b34SMin Hu (Connor) 35499a2dd95SBruce Richardson if (iter->bus_str == NULL) 35599a2dd95SBruce Richardson return; /* nothing to free in pure class filter */ 35699a2dd95SBruce Richardson free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */ 35799a2dd95SBruce Richardson free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */ 35899a2dd95SBruce Richardson memset(iter, 0, sizeof(*iter)); 35999a2dd95SBruce Richardson } 36099a2dd95SBruce Richardson 36199a2dd95SBruce Richardson uint16_t 36299a2dd95SBruce Richardson rte_eth_find_next(uint16_t port_id) 36399a2dd95SBruce Richardson { 36499a2dd95SBruce Richardson while (port_id < RTE_MAX_ETHPORTS && 36599a2dd95SBruce Richardson rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED) 36699a2dd95SBruce Richardson port_id++; 36799a2dd95SBruce Richardson 36899a2dd95SBruce Richardson if (port_id >= RTE_MAX_ETHPORTS) 36999a2dd95SBruce Richardson return RTE_MAX_ETHPORTS; 37099a2dd95SBruce Richardson 37199a2dd95SBruce Richardson return port_id; 37299a2dd95SBruce Richardson } 37399a2dd95SBruce Richardson 37499a2dd95SBruce Richardson /* 37599a2dd95SBruce Richardson * Macro to iterate over all valid ports for internal usage. 37699a2dd95SBruce Richardson * Note: RTE_ETH_FOREACH_DEV is different because filtering owned ports. 37799a2dd95SBruce Richardson */ 37899a2dd95SBruce Richardson #define RTE_ETH_FOREACH_VALID_DEV(port_id) \ 37999a2dd95SBruce Richardson for (port_id = rte_eth_find_next(0); \ 38099a2dd95SBruce Richardson port_id < RTE_MAX_ETHPORTS; \ 38199a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id + 1)) 38299a2dd95SBruce Richardson 38399a2dd95SBruce Richardson uint16_t 38499a2dd95SBruce Richardson rte_eth_find_next_of(uint16_t port_id, const struct rte_device *parent) 38599a2dd95SBruce Richardson { 38699a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id); 38799a2dd95SBruce Richardson while (port_id < RTE_MAX_ETHPORTS && 38899a2dd95SBruce Richardson rte_eth_devices[port_id].device != parent) 38999a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id + 1); 39099a2dd95SBruce Richardson 39199a2dd95SBruce Richardson return port_id; 39299a2dd95SBruce Richardson } 39399a2dd95SBruce Richardson 39499a2dd95SBruce Richardson uint16_t 39599a2dd95SBruce Richardson rte_eth_find_next_sibling(uint16_t port_id, uint16_t ref_port_id) 39699a2dd95SBruce Richardson { 39799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(ref_port_id, RTE_MAX_ETHPORTS); 39899a2dd95SBruce Richardson return rte_eth_find_next_of(port_id, 39999a2dd95SBruce Richardson rte_eth_devices[ref_port_id].device); 40099a2dd95SBruce Richardson } 40199a2dd95SBruce Richardson 40299a2dd95SBruce Richardson static void 40399a2dd95SBruce Richardson eth_dev_shared_data_prepare(void) 40499a2dd95SBruce Richardson { 40599a2dd95SBruce Richardson const unsigned flags = 0; 40699a2dd95SBruce Richardson const struct rte_memzone *mz; 40799a2dd95SBruce Richardson 40899a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data_lock); 40999a2dd95SBruce Richardson 41099a2dd95SBruce Richardson if (eth_dev_shared_data == NULL) { 41199a2dd95SBruce Richardson if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 41299a2dd95SBruce Richardson /* Allocate port data and ownership shared memory. */ 41399a2dd95SBruce Richardson mz = rte_memzone_reserve(MZ_RTE_ETH_DEV_DATA, 41499a2dd95SBruce Richardson sizeof(*eth_dev_shared_data), 41599a2dd95SBruce Richardson rte_socket_id(), flags); 41699a2dd95SBruce Richardson } else 41799a2dd95SBruce Richardson mz = rte_memzone_lookup(MZ_RTE_ETH_DEV_DATA); 41899a2dd95SBruce Richardson if (mz == NULL) 41999a2dd95SBruce Richardson rte_panic("Cannot allocate ethdev shared data\n"); 42099a2dd95SBruce Richardson 42199a2dd95SBruce Richardson eth_dev_shared_data = mz->addr; 42299a2dd95SBruce Richardson if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 42399a2dd95SBruce Richardson eth_dev_shared_data->next_owner_id = 42499a2dd95SBruce Richardson RTE_ETH_DEV_NO_OWNER + 1; 42599a2dd95SBruce Richardson rte_spinlock_init(ð_dev_shared_data->ownership_lock); 42699a2dd95SBruce Richardson memset(eth_dev_shared_data->data, 0, 42799a2dd95SBruce Richardson sizeof(eth_dev_shared_data->data)); 42899a2dd95SBruce Richardson } 42999a2dd95SBruce Richardson } 43099a2dd95SBruce Richardson 43199a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data_lock); 43299a2dd95SBruce Richardson } 43399a2dd95SBruce Richardson 43499a2dd95SBruce Richardson static bool 43599a2dd95SBruce Richardson eth_dev_is_allocated(const struct rte_eth_dev *ethdev) 43699a2dd95SBruce Richardson { 43799a2dd95SBruce Richardson return ethdev->data->name[0] != '\0'; 43899a2dd95SBruce Richardson } 43999a2dd95SBruce Richardson 44099a2dd95SBruce Richardson static struct rte_eth_dev * 44199a2dd95SBruce Richardson eth_dev_allocated(const char *name) 44299a2dd95SBruce Richardson { 44399a2dd95SBruce Richardson uint16_t i; 44499a2dd95SBruce Richardson 44599a2dd95SBruce Richardson RTE_BUILD_BUG_ON(RTE_MAX_ETHPORTS >= UINT16_MAX); 44699a2dd95SBruce Richardson 44799a2dd95SBruce Richardson for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 44899a2dd95SBruce Richardson if (rte_eth_devices[i].data != NULL && 44999a2dd95SBruce Richardson strcmp(rte_eth_devices[i].data->name, name) == 0) 45099a2dd95SBruce Richardson return &rte_eth_devices[i]; 45199a2dd95SBruce Richardson } 45299a2dd95SBruce Richardson return NULL; 45399a2dd95SBruce Richardson } 45499a2dd95SBruce Richardson 45599a2dd95SBruce Richardson struct rte_eth_dev * 45699a2dd95SBruce Richardson rte_eth_dev_allocated(const char *name) 45799a2dd95SBruce Richardson { 45899a2dd95SBruce Richardson struct rte_eth_dev *ethdev; 45999a2dd95SBruce Richardson 46099a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 46199a2dd95SBruce Richardson 46299a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 46399a2dd95SBruce Richardson 46499a2dd95SBruce Richardson ethdev = eth_dev_allocated(name); 46599a2dd95SBruce Richardson 46699a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 46799a2dd95SBruce Richardson 46899a2dd95SBruce Richardson return ethdev; 46999a2dd95SBruce Richardson } 47099a2dd95SBruce Richardson 47199a2dd95SBruce Richardson static uint16_t 47299a2dd95SBruce Richardson eth_dev_find_free_port(void) 47399a2dd95SBruce Richardson { 47499a2dd95SBruce Richardson uint16_t i; 47599a2dd95SBruce Richardson 47699a2dd95SBruce Richardson for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 47799a2dd95SBruce Richardson /* Using shared name field to find a free port. */ 47899a2dd95SBruce Richardson if (eth_dev_shared_data->data[i].name[0] == '\0') { 47999a2dd95SBruce Richardson RTE_ASSERT(rte_eth_devices[i].state == 48099a2dd95SBruce Richardson RTE_ETH_DEV_UNUSED); 48199a2dd95SBruce Richardson return i; 48299a2dd95SBruce Richardson } 48399a2dd95SBruce Richardson } 48499a2dd95SBruce Richardson return RTE_MAX_ETHPORTS; 48599a2dd95SBruce Richardson } 48699a2dd95SBruce Richardson 48799a2dd95SBruce Richardson static struct rte_eth_dev * 48899a2dd95SBruce Richardson eth_dev_get(uint16_t port_id) 48999a2dd95SBruce Richardson { 49099a2dd95SBruce Richardson struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id]; 49199a2dd95SBruce Richardson 49299a2dd95SBruce Richardson eth_dev->data = ð_dev_shared_data->data[port_id]; 49399a2dd95SBruce Richardson 49499a2dd95SBruce Richardson return eth_dev; 49599a2dd95SBruce Richardson } 49699a2dd95SBruce Richardson 49799a2dd95SBruce Richardson struct rte_eth_dev * 49899a2dd95SBruce Richardson rte_eth_dev_allocate(const char *name) 49999a2dd95SBruce Richardson { 50099a2dd95SBruce Richardson uint16_t port_id; 50199a2dd95SBruce Richardson struct rte_eth_dev *eth_dev = NULL; 50299a2dd95SBruce Richardson size_t name_len; 50399a2dd95SBruce Richardson 50499a2dd95SBruce Richardson name_len = strnlen(name, RTE_ETH_NAME_MAX_LEN); 50599a2dd95SBruce Richardson if (name_len == 0) { 50699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Zero length Ethernet device name\n"); 50799a2dd95SBruce Richardson return NULL; 50899a2dd95SBruce Richardson } 50999a2dd95SBruce Richardson 51099a2dd95SBruce Richardson if (name_len >= RTE_ETH_NAME_MAX_LEN) { 51199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Ethernet device name is too long\n"); 51299a2dd95SBruce Richardson return NULL; 51399a2dd95SBruce Richardson } 51499a2dd95SBruce Richardson 51599a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 51699a2dd95SBruce Richardson 51799a2dd95SBruce Richardson /* Synchronize port creation between primary and secondary threads. */ 51899a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 51999a2dd95SBruce Richardson 52099a2dd95SBruce Richardson if (eth_dev_allocated(name) != NULL) { 52199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 52299a2dd95SBruce Richardson "Ethernet device with name %s already allocated\n", 52399a2dd95SBruce Richardson name); 52499a2dd95SBruce Richardson goto unlock; 52599a2dd95SBruce Richardson } 52699a2dd95SBruce Richardson 52799a2dd95SBruce Richardson port_id = eth_dev_find_free_port(); 52899a2dd95SBruce Richardson if (port_id == RTE_MAX_ETHPORTS) { 52999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 53099a2dd95SBruce Richardson "Reached maximum number of Ethernet ports\n"); 53199a2dd95SBruce Richardson goto unlock; 53299a2dd95SBruce Richardson } 53399a2dd95SBruce Richardson 53499a2dd95SBruce Richardson eth_dev = eth_dev_get(port_id); 53599a2dd95SBruce Richardson strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name)); 53699a2dd95SBruce Richardson eth_dev->data->port_id = port_id; 537ff4e52efSViacheslav Galaktionov eth_dev->data->backer_port_id = RTE_MAX_ETHPORTS; 53899a2dd95SBruce Richardson eth_dev->data->mtu = RTE_ETHER_MTU; 53999a2dd95SBruce Richardson pthread_mutex_init(ð_dev->data->flow_ops_mutex, NULL); 54099a2dd95SBruce Richardson 54199a2dd95SBruce Richardson unlock: 54299a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 54399a2dd95SBruce Richardson 54499a2dd95SBruce Richardson return eth_dev; 54599a2dd95SBruce Richardson } 54699a2dd95SBruce Richardson 54799a2dd95SBruce Richardson /* 54899a2dd95SBruce Richardson * Attach to a port already registered by the primary process, which 5495906be5aSAndrew Rybchenko * makes sure that the same device would have the same port ID both 55099a2dd95SBruce Richardson * in the primary and secondary process. 55199a2dd95SBruce Richardson */ 55299a2dd95SBruce Richardson struct rte_eth_dev * 55399a2dd95SBruce Richardson rte_eth_dev_attach_secondary(const char *name) 55499a2dd95SBruce Richardson { 55599a2dd95SBruce Richardson uint16_t i; 55699a2dd95SBruce Richardson struct rte_eth_dev *eth_dev = NULL; 55799a2dd95SBruce Richardson 55899a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 55999a2dd95SBruce Richardson 56099a2dd95SBruce Richardson /* Synchronize port attachment to primary port creation and release. */ 56199a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 56299a2dd95SBruce Richardson 56399a2dd95SBruce Richardson for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 56499a2dd95SBruce Richardson if (strcmp(eth_dev_shared_data->data[i].name, name) == 0) 56599a2dd95SBruce Richardson break; 56699a2dd95SBruce Richardson } 56799a2dd95SBruce Richardson if (i == RTE_MAX_ETHPORTS) { 56899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 56999a2dd95SBruce Richardson "Device %s is not driven by the primary process\n", 57099a2dd95SBruce Richardson name); 57199a2dd95SBruce Richardson } else { 57299a2dd95SBruce Richardson eth_dev = eth_dev_get(i); 57399a2dd95SBruce Richardson RTE_ASSERT(eth_dev->data->port_id == i); 57499a2dd95SBruce Richardson } 57599a2dd95SBruce Richardson 57699a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 57799a2dd95SBruce Richardson return eth_dev; 57899a2dd95SBruce Richardson } 57999a2dd95SBruce Richardson 58099a2dd95SBruce Richardson int 58199a2dd95SBruce Richardson rte_eth_dev_release_port(struct rte_eth_dev *eth_dev) 58299a2dd95SBruce Richardson { 58399a2dd95SBruce Richardson if (eth_dev == NULL) 58499a2dd95SBruce Richardson return -EINVAL; 58599a2dd95SBruce Richardson 58699a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 58799a2dd95SBruce Richardson 58899a2dd95SBruce Richardson if (eth_dev->state != RTE_ETH_DEV_UNUSED) 58999a2dd95SBruce Richardson rte_eth_dev_callback_process(eth_dev, 59099a2dd95SBruce Richardson RTE_ETH_EVENT_DESTROY, NULL); 59199a2dd95SBruce Richardson 592c87d435aSKonstantin Ananyev eth_dev_fp_ops_reset(rte_eth_fp_ops + eth_dev->data->port_id); 593c87d435aSKonstantin Ananyev 59499a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 59599a2dd95SBruce Richardson 59699a2dd95SBruce Richardson eth_dev->state = RTE_ETH_DEV_UNUSED; 59799a2dd95SBruce Richardson eth_dev->device = NULL; 59899a2dd95SBruce Richardson eth_dev->process_private = NULL; 59999a2dd95SBruce Richardson eth_dev->intr_handle = NULL; 60099a2dd95SBruce Richardson eth_dev->rx_pkt_burst = NULL; 60199a2dd95SBruce Richardson eth_dev->tx_pkt_burst = NULL; 60299a2dd95SBruce Richardson eth_dev->tx_pkt_prepare = NULL; 60399a2dd95SBruce Richardson eth_dev->rx_queue_count = NULL; 60499a2dd95SBruce Richardson eth_dev->rx_descriptor_status = NULL; 60599a2dd95SBruce Richardson eth_dev->tx_descriptor_status = NULL; 60699a2dd95SBruce Richardson eth_dev->dev_ops = NULL; 60799a2dd95SBruce Richardson 60899a2dd95SBruce Richardson if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 60999a2dd95SBruce Richardson rte_free(eth_dev->data->rx_queues); 61099a2dd95SBruce Richardson rte_free(eth_dev->data->tx_queues); 61199a2dd95SBruce Richardson rte_free(eth_dev->data->mac_addrs); 61299a2dd95SBruce Richardson rte_free(eth_dev->data->hash_mac_addrs); 61399a2dd95SBruce Richardson rte_free(eth_dev->data->dev_private); 61499a2dd95SBruce Richardson pthread_mutex_destroy(ð_dev->data->flow_ops_mutex); 61599a2dd95SBruce Richardson memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data)); 61699a2dd95SBruce Richardson } 61799a2dd95SBruce Richardson 61899a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 61999a2dd95SBruce Richardson 62099a2dd95SBruce Richardson return 0; 62199a2dd95SBruce Richardson } 62299a2dd95SBruce Richardson 62399a2dd95SBruce Richardson int 62499a2dd95SBruce Richardson rte_eth_dev_is_valid_port(uint16_t port_id) 62599a2dd95SBruce Richardson { 62699a2dd95SBruce Richardson if (port_id >= RTE_MAX_ETHPORTS || 62799a2dd95SBruce Richardson (rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED)) 62899a2dd95SBruce Richardson return 0; 62999a2dd95SBruce Richardson else 63099a2dd95SBruce Richardson return 1; 63199a2dd95SBruce Richardson } 63299a2dd95SBruce Richardson 63399a2dd95SBruce Richardson static int 63499a2dd95SBruce Richardson eth_is_valid_owner_id(uint64_t owner_id) 63599a2dd95SBruce Richardson { 63699a2dd95SBruce Richardson if (owner_id == RTE_ETH_DEV_NO_OWNER || 63799a2dd95SBruce Richardson eth_dev_shared_data->next_owner_id <= owner_id) 63899a2dd95SBruce Richardson return 0; 63999a2dd95SBruce Richardson return 1; 64099a2dd95SBruce Richardson } 64199a2dd95SBruce Richardson 64299a2dd95SBruce Richardson uint64_t 64399a2dd95SBruce Richardson rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id) 64499a2dd95SBruce Richardson { 64599a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id); 64699a2dd95SBruce Richardson while (port_id < RTE_MAX_ETHPORTS && 64799a2dd95SBruce Richardson rte_eth_devices[port_id].data->owner.id != owner_id) 64899a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id + 1); 64999a2dd95SBruce Richardson 65099a2dd95SBruce Richardson return port_id; 65199a2dd95SBruce Richardson } 65299a2dd95SBruce Richardson 65399a2dd95SBruce Richardson int 65499a2dd95SBruce Richardson rte_eth_dev_owner_new(uint64_t *owner_id) 65599a2dd95SBruce Richardson { 65653ef1b34SMin Hu (Connor) if (owner_id == NULL) { 65753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get new owner ID to NULL\n"); 65853ef1b34SMin Hu (Connor) return -EINVAL; 65953ef1b34SMin Hu (Connor) } 66053ef1b34SMin Hu (Connor) 66199a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 66299a2dd95SBruce Richardson 66399a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 66499a2dd95SBruce Richardson 66599a2dd95SBruce Richardson *owner_id = eth_dev_shared_data->next_owner_id++; 66699a2dd95SBruce Richardson 66799a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 66899a2dd95SBruce Richardson return 0; 66999a2dd95SBruce Richardson } 67099a2dd95SBruce Richardson 67199a2dd95SBruce Richardson static int 67299a2dd95SBruce Richardson eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id, 67399a2dd95SBruce Richardson const struct rte_eth_dev_owner *new_owner) 67499a2dd95SBruce Richardson { 67599a2dd95SBruce Richardson struct rte_eth_dev *ethdev = &rte_eth_devices[port_id]; 67699a2dd95SBruce Richardson struct rte_eth_dev_owner *port_owner; 67799a2dd95SBruce Richardson 67899a2dd95SBruce Richardson if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) { 6795906be5aSAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Port ID %"PRIu16" is not allocated\n", 68099a2dd95SBruce Richardson port_id); 68199a2dd95SBruce Richardson return -ENODEV; 68299a2dd95SBruce Richardson } 68399a2dd95SBruce Richardson 68453ef1b34SMin Hu (Connor) if (new_owner == NULL) { 68553ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 68653ef1b34SMin Hu (Connor) "Cannot set ethdev port %u owner from NULL owner\n", 68753ef1b34SMin Hu (Connor) port_id); 68853ef1b34SMin Hu (Connor) return -EINVAL; 68953ef1b34SMin Hu (Connor) } 69053ef1b34SMin Hu (Connor) 69199a2dd95SBruce Richardson if (!eth_is_valid_owner_id(new_owner->id) && 69299a2dd95SBruce Richardson !eth_is_valid_owner_id(old_owner_id)) { 69399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 69499a2dd95SBruce Richardson "Invalid owner old_id=%016"PRIx64" new_id=%016"PRIx64"\n", 69599a2dd95SBruce Richardson old_owner_id, new_owner->id); 69699a2dd95SBruce Richardson return -EINVAL; 69799a2dd95SBruce Richardson } 69899a2dd95SBruce Richardson 69999a2dd95SBruce Richardson port_owner = &rte_eth_devices[port_id].data->owner; 70099a2dd95SBruce Richardson if (port_owner->id != old_owner_id) { 70199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 70299a2dd95SBruce Richardson "Cannot set owner to port %u already owned by %s_%016"PRIX64"\n", 70399a2dd95SBruce Richardson port_id, port_owner->name, port_owner->id); 70499a2dd95SBruce Richardson return -EPERM; 70599a2dd95SBruce Richardson } 70699a2dd95SBruce Richardson 70799a2dd95SBruce Richardson /* can not truncate (same structure) */ 70899a2dd95SBruce Richardson strlcpy(port_owner->name, new_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN); 70999a2dd95SBruce Richardson 71099a2dd95SBruce Richardson port_owner->id = new_owner->id; 71199a2dd95SBruce Richardson 71299a2dd95SBruce Richardson RTE_ETHDEV_LOG(DEBUG, "Port %u owner is %s_%016"PRIx64"\n", 71399a2dd95SBruce Richardson port_id, new_owner->name, new_owner->id); 71499a2dd95SBruce Richardson 71599a2dd95SBruce Richardson return 0; 71699a2dd95SBruce Richardson } 71799a2dd95SBruce Richardson 71899a2dd95SBruce Richardson int 71999a2dd95SBruce Richardson rte_eth_dev_owner_set(const uint16_t port_id, 72099a2dd95SBruce Richardson const struct rte_eth_dev_owner *owner) 72199a2dd95SBruce Richardson { 72299a2dd95SBruce Richardson int ret; 72399a2dd95SBruce Richardson 72499a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 72599a2dd95SBruce Richardson 72699a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 72799a2dd95SBruce Richardson 72899a2dd95SBruce Richardson ret = eth_dev_owner_set(port_id, RTE_ETH_DEV_NO_OWNER, owner); 72999a2dd95SBruce Richardson 73099a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 73199a2dd95SBruce Richardson return ret; 73299a2dd95SBruce Richardson } 73399a2dd95SBruce Richardson 73499a2dd95SBruce Richardson int 73599a2dd95SBruce Richardson rte_eth_dev_owner_unset(const uint16_t port_id, const uint64_t owner_id) 73699a2dd95SBruce Richardson { 73799a2dd95SBruce Richardson const struct rte_eth_dev_owner new_owner = (struct rte_eth_dev_owner) 73899a2dd95SBruce Richardson {.id = RTE_ETH_DEV_NO_OWNER, .name = ""}; 73999a2dd95SBruce Richardson int ret; 74099a2dd95SBruce Richardson 74199a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 74299a2dd95SBruce Richardson 74399a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 74499a2dd95SBruce Richardson 74599a2dd95SBruce Richardson ret = eth_dev_owner_set(port_id, owner_id, &new_owner); 74699a2dd95SBruce Richardson 74799a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 74899a2dd95SBruce Richardson return ret; 74999a2dd95SBruce Richardson } 75099a2dd95SBruce Richardson 75199a2dd95SBruce Richardson int 75299a2dd95SBruce Richardson rte_eth_dev_owner_delete(const uint64_t owner_id) 75399a2dd95SBruce Richardson { 75499a2dd95SBruce Richardson uint16_t port_id; 75599a2dd95SBruce Richardson int ret = 0; 75699a2dd95SBruce Richardson 75799a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 75899a2dd95SBruce Richardson 75999a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 76099a2dd95SBruce Richardson 76199a2dd95SBruce Richardson if (eth_is_valid_owner_id(owner_id)) { 762b7ade5d3SFerruh Yigit for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { 763b7ade5d3SFerruh Yigit struct rte_eth_dev_data *data = 764b7ade5d3SFerruh Yigit rte_eth_devices[port_id].data; 765b7ade5d3SFerruh Yigit if (data != NULL && data->owner.id == owner_id) 766b7ade5d3SFerruh Yigit memset(&data->owner, 0, 76799a2dd95SBruce Richardson sizeof(struct rte_eth_dev_owner)); 768b7ade5d3SFerruh Yigit } 76999a2dd95SBruce Richardson RTE_ETHDEV_LOG(NOTICE, 77099a2dd95SBruce Richardson "All port owners owned by %016"PRIx64" identifier have removed\n", 77199a2dd95SBruce Richardson owner_id); 77299a2dd95SBruce Richardson } else { 77399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 7745906be5aSAndrew Rybchenko "Invalid owner ID=%016"PRIx64"\n", 77599a2dd95SBruce Richardson owner_id); 77699a2dd95SBruce Richardson ret = -EINVAL; 77799a2dd95SBruce Richardson } 77899a2dd95SBruce Richardson 77999a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 78099a2dd95SBruce Richardson 78199a2dd95SBruce Richardson return ret; 78299a2dd95SBruce Richardson } 78399a2dd95SBruce Richardson 78499a2dd95SBruce Richardson int 78599a2dd95SBruce Richardson rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner) 78699a2dd95SBruce Richardson { 78753ef1b34SMin Hu (Connor) struct rte_eth_dev *ethdev; 78853ef1b34SMin Hu (Connor) 78953ef1b34SMin Hu (Connor) RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 79053ef1b34SMin Hu (Connor) ethdev = &rte_eth_devices[port_id]; 79153ef1b34SMin Hu (Connor) 79253ef1b34SMin Hu (Connor) if (!eth_dev_is_allocated(ethdev)) { 7935906be5aSAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Port ID %"PRIu16" is not allocated\n", 79453ef1b34SMin Hu (Connor) port_id); 79553ef1b34SMin Hu (Connor) return -ENODEV; 79653ef1b34SMin Hu (Connor) } 79753ef1b34SMin Hu (Connor) 79853ef1b34SMin Hu (Connor) if (owner == NULL) { 79953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u owner to NULL\n", 80053ef1b34SMin Hu (Connor) port_id); 80153ef1b34SMin Hu (Connor) return -EINVAL; 80253ef1b34SMin Hu (Connor) } 80399a2dd95SBruce Richardson 80499a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 80599a2dd95SBruce Richardson 80699a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 80799a2dd95SBruce Richardson rte_memcpy(owner, ðdev->data->owner, sizeof(*owner)); 80899a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 80953ef1b34SMin Hu (Connor) 81053ef1b34SMin Hu (Connor) return 0; 81199a2dd95SBruce Richardson } 81299a2dd95SBruce Richardson 81399a2dd95SBruce Richardson int 81499a2dd95SBruce Richardson rte_eth_dev_socket_id(uint16_t port_id) 81599a2dd95SBruce Richardson { 81699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); 81799a2dd95SBruce Richardson return rte_eth_devices[port_id].data->numa_node; 81899a2dd95SBruce Richardson } 81999a2dd95SBruce Richardson 82099a2dd95SBruce Richardson void * 82199a2dd95SBruce Richardson rte_eth_dev_get_sec_ctx(uint16_t port_id) 82299a2dd95SBruce Richardson { 82399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL); 82499a2dd95SBruce Richardson return rte_eth_devices[port_id].security_ctx; 82599a2dd95SBruce Richardson } 82699a2dd95SBruce Richardson 82799a2dd95SBruce Richardson uint16_t 82899a2dd95SBruce Richardson rte_eth_dev_count_avail(void) 82999a2dd95SBruce Richardson { 83099a2dd95SBruce Richardson uint16_t p; 83199a2dd95SBruce Richardson uint16_t count; 83299a2dd95SBruce Richardson 83399a2dd95SBruce Richardson count = 0; 83499a2dd95SBruce Richardson 83599a2dd95SBruce Richardson RTE_ETH_FOREACH_DEV(p) 83699a2dd95SBruce Richardson count++; 83799a2dd95SBruce Richardson 83899a2dd95SBruce Richardson return count; 83999a2dd95SBruce Richardson } 84099a2dd95SBruce Richardson 84199a2dd95SBruce Richardson uint16_t 84299a2dd95SBruce Richardson rte_eth_dev_count_total(void) 84399a2dd95SBruce Richardson { 84499a2dd95SBruce Richardson uint16_t port, count = 0; 84599a2dd95SBruce Richardson 84699a2dd95SBruce Richardson RTE_ETH_FOREACH_VALID_DEV(port) 84799a2dd95SBruce Richardson count++; 84899a2dd95SBruce Richardson 84999a2dd95SBruce Richardson return count; 85099a2dd95SBruce Richardson } 85199a2dd95SBruce Richardson 85299a2dd95SBruce Richardson int 85399a2dd95SBruce Richardson rte_eth_dev_get_name_by_port(uint16_t port_id, char *name) 85499a2dd95SBruce Richardson { 85599a2dd95SBruce Richardson char *tmp; 85699a2dd95SBruce Richardson 85799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 85899a2dd95SBruce Richardson 85999a2dd95SBruce Richardson if (name == NULL) { 86053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u name to NULL\n", 86153ef1b34SMin Hu (Connor) port_id); 86299a2dd95SBruce Richardson return -EINVAL; 86399a2dd95SBruce Richardson } 86499a2dd95SBruce Richardson 86599a2dd95SBruce Richardson /* shouldn't check 'rte_eth_devices[i].data', 86699a2dd95SBruce Richardson * because it might be overwritten by VDEV PMD */ 86799a2dd95SBruce Richardson tmp = eth_dev_shared_data->data[port_id].name; 86899a2dd95SBruce Richardson strcpy(name, tmp); 86999a2dd95SBruce Richardson return 0; 87099a2dd95SBruce Richardson } 87199a2dd95SBruce Richardson 87299a2dd95SBruce Richardson int 87399a2dd95SBruce Richardson rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id) 87499a2dd95SBruce Richardson { 87599a2dd95SBruce Richardson uint16_t pid; 87699a2dd95SBruce Richardson 87799a2dd95SBruce Richardson if (name == NULL) { 87853ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name"); 87953ef1b34SMin Hu (Connor) return -EINVAL; 88053ef1b34SMin Hu (Connor) } 88153ef1b34SMin Hu (Connor) 88253ef1b34SMin Hu (Connor) if (port_id == NULL) { 88353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 88453ef1b34SMin Hu (Connor) "Cannot get port ID to NULL for %s\n", name); 88599a2dd95SBruce Richardson return -EINVAL; 88699a2dd95SBruce Richardson } 88799a2dd95SBruce Richardson 88899a2dd95SBruce Richardson RTE_ETH_FOREACH_VALID_DEV(pid) 88999a2dd95SBruce Richardson if (!strcmp(name, eth_dev_shared_data->data[pid].name)) { 89099a2dd95SBruce Richardson *port_id = pid; 89199a2dd95SBruce Richardson return 0; 89299a2dd95SBruce Richardson } 89399a2dd95SBruce Richardson 89499a2dd95SBruce Richardson return -ENODEV; 89599a2dd95SBruce Richardson } 89699a2dd95SBruce Richardson 89799a2dd95SBruce Richardson static int 89899a2dd95SBruce Richardson eth_err(uint16_t port_id, int ret) 89999a2dd95SBruce Richardson { 90099a2dd95SBruce Richardson if (ret == 0) 90199a2dd95SBruce Richardson return 0; 90299a2dd95SBruce Richardson if (rte_eth_dev_is_removed(port_id)) 90399a2dd95SBruce Richardson return -EIO; 90499a2dd95SBruce Richardson return ret; 90599a2dd95SBruce Richardson } 90699a2dd95SBruce Richardson 90749ed3224SXueming Li static void 90849ed3224SXueming Li eth_dev_rxq_release(struct rte_eth_dev *dev, uint16_t qid) 90949ed3224SXueming Li { 91049ed3224SXueming Li void **rxq = dev->data->rx_queues; 91149ed3224SXueming Li 91249ed3224SXueming Li if (rxq[qid] == NULL) 91349ed3224SXueming Li return; 91449ed3224SXueming Li 91549ed3224SXueming Li if (dev->dev_ops->rx_queue_release != NULL) 9167483341aSXueming Li (*dev->dev_ops->rx_queue_release)(dev, qid); 91749ed3224SXueming Li rxq[qid] = NULL; 91849ed3224SXueming Li } 91949ed3224SXueming Li 92049ed3224SXueming Li static void 92149ed3224SXueming Li eth_dev_txq_release(struct rte_eth_dev *dev, uint16_t qid) 92249ed3224SXueming Li { 92349ed3224SXueming Li void **txq = dev->data->tx_queues; 92449ed3224SXueming Li 92549ed3224SXueming Li if (txq[qid] == NULL) 92649ed3224SXueming Li return; 92749ed3224SXueming Li 92849ed3224SXueming Li if (dev->dev_ops->tx_queue_release != NULL) 9297483341aSXueming Li (*dev->dev_ops->tx_queue_release)(dev, qid); 93049ed3224SXueming Li txq[qid] = NULL; 93149ed3224SXueming Li } 93249ed3224SXueming Li 93399a2dd95SBruce Richardson static int 93499a2dd95SBruce Richardson eth_dev_rx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues) 93599a2dd95SBruce Richardson { 93699a2dd95SBruce Richardson uint16_t old_nb_queues = dev->data->nb_rx_queues; 93799a2dd95SBruce Richardson unsigned i; 93899a2dd95SBruce Richardson 93999a2dd95SBruce Richardson if (dev->data->rx_queues == NULL && nb_queues != 0) { /* first time configuration */ 94099a2dd95SBruce Richardson dev->data->rx_queues = rte_zmalloc("ethdev->rx_queues", 941c024496aSKonstantin Ananyev sizeof(dev->data->rx_queues[0]) * 942c024496aSKonstantin Ananyev RTE_MAX_QUEUES_PER_PORT, 94399a2dd95SBruce Richardson RTE_CACHE_LINE_SIZE); 94499a2dd95SBruce Richardson if (dev->data->rx_queues == NULL) { 94599a2dd95SBruce Richardson dev->data->nb_rx_queues = 0; 94699a2dd95SBruce Richardson return -(ENOMEM); 94799a2dd95SBruce Richardson } 94899a2dd95SBruce Richardson } else if (dev->data->rx_queues != NULL && nb_queues != 0) { /* re-configure */ 94949ed3224SXueming Li for (i = nb_queues; i < old_nb_queues; i++) 95049ed3224SXueming Li eth_dev_rxq_release(dev, i); 95199a2dd95SBruce Richardson 95299a2dd95SBruce Richardson } else if (dev->data->rx_queues != NULL && nb_queues == 0) { 95399a2dd95SBruce Richardson for (i = nb_queues; i < old_nb_queues; i++) 95449ed3224SXueming Li eth_dev_rxq_release(dev, i); 95599a2dd95SBruce Richardson 95699a2dd95SBruce Richardson rte_free(dev->data->rx_queues); 95799a2dd95SBruce Richardson dev->data->rx_queues = NULL; 95899a2dd95SBruce Richardson } 95999a2dd95SBruce Richardson dev->data->nb_rx_queues = nb_queues; 96099a2dd95SBruce Richardson return 0; 96199a2dd95SBruce Richardson } 96299a2dd95SBruce Richardson 96399a2dd95SBruce Richardson static int 96499a2dd95SBruce Richardson eth_dev_validate_rx_queue(const struct rte_eth_dev *dev, uint16_t rx_queue_id) 96599a2dd95SBruce Richardson { 96699a2dd95SBruce Richardson uint16_t port_id; 96799a2dd95SBruce Richardson 96899a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 96999a2dd95SBruce Richardson port_id = dev->data->port_id; 97099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 97199a2dd95SBruce Richardson "Invalid Rx queue_id=%u of device with port_id=%u\n", 97299a2dd95SBruce Richardson rx_queue_id, port_id); 97399a2dd95SBruce Richardson return -EINVAL; 97499a2dd95SBruce Richardson } 97599a2dd95SBruce Richardson 97699a2dd95SBruce Richardson if (dev->data->rx_queues[rx_queue_id] == NULL) { 97799a2dd95SBruce Richardson port_id = dev->data->port_id; 97899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 97999a2dd95SBruce Richardson "Queue %u of device with port_id=%u has not been setup\n", 98099a2dd95SBruce Richardson rx_queue_id, port_id); 98199a2dd95SBruce Richardson return -EINVAL; 98299a2dd95SBruce Richardson } 98399a2dd95SBruce Richardson 98499a2dd95SBruce Richardson return 0; 98599a2dd95SBruce Richardson } 98699a2dd95SBruce Richardson 98799a2dd95SBruce Richardson static int 98899a2dd95SBruce Richardson eth_dev_validate_tx_queue(const struct rte_eth_dev *dev, uint16_t tx_queue_id) 98999a2dd95SBruce Richardson { 99099a2dd95SBruce Richardson uint16_t port_id; 99199a2dd95SBruce Richardson 99299a2dd95SBruce Richardson if (tx_queue_id >= dev->data->nb_tx_queues) { 99399a2dd95SBruce Richardson port_id = dev->data->port_id; 99499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 99599a2dd95SBruce Richardson "Invalid Tx queue_id=%u of device with port_id=%u\n", 99699a2dd95SBruce Richardson tx_queue_id, port_id); 99799a2dd95SBruce Richardson return -EINVAL; 99899a2dd95SBruce Richardson } 99999a2dd95SBruce Richardson 100099a2dd95SBruce Richardson if (dev->data->tx_queues[tx_queue_id] == NULL) { 100199a2dd95SBruce Richardson port_id = dev->data->port_id; 100299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 100399a2dd95SBruce Richardson "Queue %u of device with port_id=%u has not been setup\n", 100499a2dd95SBruce Richardson tx_queue_id, port_id); 100599a2dd95SBruce Richardson return -EINVAL; 100699a2dd95SBruce Richardson } 100799a2dd95SBruce Richardson 100899a2dd95SBruce Richardson return 0; 100999a2dd95SBruce Richardson } 101099a2dd95SBruce Richardson 101199a2dd95SBruce Richardson int 101299a2dd95SBruce Richardson rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id) 101399a2dd95SBruce Richardson { 101499a2dd95SBruce Richardson struct rte_eth_dev *dev; 101599a2dd95SBruce Richardson int ret; 101699a2dd95SBruce Richardson 101799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 101899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 101953ef1b34SMin Hu (Connor) 102099a2dd95SBruce Richardson if (!dev->data->dev_started) { 102199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 102299a2dd95SBruce Richardson "Port %u must be started before start any queue\n", 102399a2dd95SBruce Richardson port_id); 102499a2dd95SBruce Richardson return -EINVAL; 102599a2dd95SBruce Richardson } 102699a2dd95SBruce Richardson 102799a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, rx_queue_id); 102899a2dd95SBruce Richardson if (ret != 0) 102999a2dd95SBruce Richardson return ret; 103099a2dd95SBruce Richardson 103199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_start, -ENOTSUP); 103299a2dd95SBruce Richardson 103399a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) { 103499a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 103599a2dd95SBruce Richardson "Can't start Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n", 103699a2dd95SBruce Richardson rx_queue_id, port_id); 103799a2dd95SBruce Richardson return -EINVAL; 103899a2dd95SBruce Richardson } 103999a2dd95SBruce Richardson 104099a2dd95SBruce Richardson if (dev->data->rx_queue_state[rx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) { 104199a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 104299a2dd95SBruce Richardson "Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n", 104399a2dd95SBruce Richardson rx_queue_id, port_id); 104499a2dd95SBruce Richardson return 0; 104599a2dd95SBruce Richardson } 104699a2dd95SBruce Richardson 104753ef1b34SMin Hu (Connor) return eth_err(port_id, dev->dev_ops->rx_queue_start(dev, rx_queue_id)); 104899a2dd95SBruce Richardson } 104999a2dd95SBruce Richardson 105099a2dd95SBruce Richardson int 105199a2dd95SBruce Richardson rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id) 105299a2dd95SBruce Richardson { 105399a2dd95SBruce Richardson struct rte_eth_dev *dev; 105499a2dd95SBruce Richardson int ret; 105599a2dd95SBruce Richardson 105699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 105799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 105899a2dd95SBruce Richardson 105999a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, rx_queue_id); 106099a2dd95SBruce Richardson if (ret != 0) 106199a2dd95SBruce Richardson return ret; 106299a2dd95SBruce Richardson 106399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_stop, -ENOTSUP); 106499a2dd95SBruce Richardson 106599a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) { 106699a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 106799a2dd95SBruce Richardson "Can't stop Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n", 106899a2dd95SBruce Richardson rx_queue_id, port_id); 106999a2dd95SBruce Richardson return -EINVAL; 107099a2dd95SBruce Richardson } 107199a2dd95SBruce Richardson 107299a2dd95SBruce Richardson if (dev->data->rx_queue_state[rx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) { 107399a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 107499a2dd95SBruce Richardson "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n", 107599a2dd95SBruce Richardson rx_queue_id, port_id); 107699a2dd95SBruce Richardson return 0; 107799a2dd95SBruce Richardson } 107899a2dd95SBruce Richardson 107999a2dd95SBruce Richardson return eth_err(port_id, dev->dev_ops->rx_queue_stop(dev, rx_queue_id)); 108099a2dd95SBruce Richardson } 108199a2dd95SBruce Richardson 108299a2dd95SBruce Richardson int 108399a2dd95SBruce Richardson rte_eth_dev_tx_queue_start(uint16_t port_id, uint16_t tx_queue_id) 108499a2dd95SBruce Richardson { 108599a2dd95SBruce Richardson struct rte_eth_dev *dev; 108699a2dd95SBruce Richardson int ret; 108799a2dd95SBruce Richardson 108899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 108999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 109053ef1b34SMin Hu (Connor) 109199a2dd95SBruce Richardson if (!dev->data->dev_started) { 109299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 109399a2dd95SBruce Richardson "Port %u must be started before start any queue\n", 109499a2dd95SBruce Richardson port_id); 109599a2dd95SBruce Richardson return -EINVAL; 109699a2dd95SBruce Richardson } 109799a2dd95SBruce Richardson 109899a2dd95SBruce Richardson ret = eth_dev_validate_tx_queue(dev, tx_queue_id); 109999a2dd95SBruce Richardson if (ret != 0) 110099a2dd95SBruce Richardson return ret; 110199a2dd95SBruce Richardson 110299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_start, -ENOTSUP); 110399a2dd95SBruce Richardson 110499a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) { 110599a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 110699a2dd95SBruce Richardson "Can't start Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n", 110799a2dd95SBruce Richardson tx_queue_id, port_id); 110899a2dd95SBruce Richardson return -EINVAL; 110999a2dd95SBruce Richardson } 111099a2dd95SBruce Richardson 111199a2dd95SBruce Richardson if (dev->data->tx_queue_state[tx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) { 111299a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 111399a2dd95SBruce Richardson "Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n", 111499a2dd95SBruce Richardson tx_queue_id, port_id); 111599a2dd95SBruce Richardson return 0; 111699a2dd95SBruce Richardson } 111799a2dd95SBruce Richardson 111899a2dd95SBruce Richardson return eth_err(port_id, dev->dev_ops->tx_queue_start(dev, tx_queue_id)); 111999a2dd95SBruce Richardson } 112099a2dd95SBruce Richardson 112199a2dd95SBruce Richardson int 112299a2dd95SBruce Richardson rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id) 112399a2dd95SBruce Richardson { 112499a2dd95SBruce Richardson struct rte_eth_dev *dev; 112599a2dd95SBruce Richardson int ret; 112699a2dd95SBruce Richardson 112799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 112899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 112999a2dd95SBruce Richardson 113099a2dd95SBruce Richardson ret = eth_dev_validate_tx_queue(dev, tx_queue_id); 113199a2dd95SBruce Richardson if (ret != 0) 113299a2dd95SBruce Richardson return ret; 113399a2dd95SBruce Richardson 113499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_stop, -ENOTSUP); 113599a2dd95SBruce Richardson 113699a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) { 113799a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 113899a2dd95SBruce Richardson "Can't stop Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n", 113999a2dd95SBruce Richardson tx_queue_id, port_id); 114099a2dd95SBruce Richardson return -EINVAL; 114199a2dd95SBruce Richardson } 114299a2dd95SBruce Richardson 114399a2dd95SBruce Richardson if (dev->data->tx_queue_state[tx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) { 114499a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 114599a2dd95SBruce Richardson "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n", 114699a2dd95SBruce Richardson tx_queue_id, port_id); 114799a2dd95SBruce Richardson return 0; 114899a2dd95SBruce Richardson } 114999a2dd95SBruce Richardson 115099a2dd95SBruce Richardson return eth_err(port_id, dev->dev_ops->tx_queue_stop(dev, tx_queue_id)); 115199a2dd95SBruce Richardson } 115299a2dd95SBruce Richardson 115399a2dd95SBruce Richardson static int 115499a2dd95SBruce Richardson eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues) 115599a2dd95SBruce Richardson { 115699a2dd95SBruce Richardson uint16_t old_nb_queues = dev->data->nb_tx_queues; 115799a2dd95SBruce Richardson unsigned i; 115899a2dd95SBruce Richardson 115999a2dd95SBruce Richardson if (dev->data->tx_queues == NULL && nb_queues != 0) { /* first time configuration */ 116099a2dd95SBruce Richardson dev->data->tx_queues = rte_zmalloc("ethdev->tx_queues", 1161c024496aSKonstantin Ananyev sizeof(dev->data->tx_queues[0]) * 1162c024496aSKonstantin Ananyev RTE_MAX_QUEUES_PER_PORT, 116399a2dd95SBruce Richardson RTE_CACHE_LINE_SIZE); 116499a2dd95SBruce Richardson if (dev->data->tx_queues == NULL) { 116599a2dd95SBruce Richardson dev->data->nb_tx_queues = 0; 116699a2dd95SBruce Richardson return -(ENOMEM); 116799a2dd95SBruce Richardson } 116899a2dd95SBruce Richardson } else if (dev->data->tx_queues != NULL && nb_queues != 0) { /* re-configure */ 116949ed3224SXueming Li for (i = nb_queues; i < old_nb_queues; i++) 117049ed3224SXueming Li eth_dev_txq_release(dev, i); 117199a2dd95SBruce Richardson 117299a2dd95SBruce Richardson } else if (dev->data->tx_queues != NULL && nb_queues == 0) { 117399a2dd95SBruce Richardson for (i = nb_queues; i < old_nb_queues; i++) 117449ed3224SXueming Li eth_dev_txq_release(dev, i); 117599a2dd95SBruce Richardson 117699a2dd95SBruce Richardson rte_free(dev->data->tx_queues); 117799a2dd95SBruce Richardson dev->data->tx_queues = NULL; 117899a2dd95SBruce Richardson } 117999a2dd95SBruce Richardson dev->data->nb_tx_queues = nb_queues; 118099a2dd95SBruce Richardson return 0; 118199a2dd95SBruce Richardson } 118299a2dd95SBruce Richardson 118399a2dd95SBruce Richardson uint32_t 118499a2dd95SBruce Richardson rte_eth_speed_bitflag(uint32_t speed, int duplex) 118599a2dd95SBruce Richardson { 118699a2dd95SBruce Richardson switch (speed) { 1187295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_10M: 1188295968d1SFerruh Yigit return duplex ? RTE_ETH_LINK_SPEED_10M : RTE_ETH_LINK_SPEED_10M_HD; 1189295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_100M: 1190295968d1SFerruh Yigit return duplex ? RTE_ETH_LINK_SPEED_100M : RTE_ETH_LINK_SPEED_100M_HD; 1191295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_1G: 1192295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_1G; 1193295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_2_5G: 1194295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_2_5G; 1195295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_5G: 1196295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_5G; 1197295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_10G: 1198295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_10G; 1199295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_20G: 1200295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_20G; 1201295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_25G: 1202295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_25G; 1203295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_40G: 1204295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_40G; 1205295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_50G: 1206295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_50G; 1207295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_56G: 1208295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_56G; 1209295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_100G: 1210295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_100G; 1211295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_200G: 1212295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_200G; 121399a2dd95SBruce Richardson default: 121499a2dd95SBruce Richardson return 0; 121599a2dd95SBruce Richardson } 121699a2dd95SBruce Richardson } 121799a2dd95SBruce Richardson 121899a2dd95SBruce Richardson const char * 121999a2dd95SBruce Richardson rte_eth_dev_rx_offload_name(uint64_t offload) 122099a2dd95SBruce Richardson { 122199a2dd95SBruce Richardson const char *name = "UNKNOWN"; 122299a2dd95SBruce Richardson unsigned int i; 122399a2dd95SBruce Richardson 122499a2dd95SBruce Richardson for (i = 0; i < RTE_DIM(eth_dev_rx_offload_names); ++i) { 122599a2dd95SBruce Richardson if (offload == eth_dev_rx_offload_names[i].offload) { 122699a2dd95SBruce Richardson name = eth_dev_rx_offload_names[i].name; 122799a2dd95SBruce Richardson break; 122899a2dd95SBruce Richardson } 122999a2dd95SBruce Richardson } 123099a2dd95SBruce Richardson 123199a2dd95SBruce Richardson return name; 123299a2dd95SBruce Richardson } 123399a2dd95SBruce Richardson 123499a2dd95SBruce Richardson const char * 123599a2dd95SBruce Richardson rte_eth_dev_tx_offload_name(uint64_t offload) 123699a2dd95SBruce Richardson { 123799a2dd95SBruce Richardson const char *name = "UNKNOWN"; 123899a2dd95SBruce Richardson unsigned int i; 123999a2dd95SBruce Richardson 124099a2dd95SBruce Richardson for (i = 0; i < RTE_DIM(eth_dev_tx_offload_names); ++i) { 124199a2dd95SBruce Richardson if (offload == eth_dev_tx_offload_names[i].offload) { 124299a2dd95SBruce Richardson name = eth_dev_tx_offload_names[i].name; 124399a2dd95SBruce Richardson break; 124499a2dd95SBruce Richardson } 124599a2dd95SBruce Richardson } 124699a2dd95SBruce Richardson 124799a2dd95SBruce Richardson return name; 124899a2dd95SBruce Richardson } 124999a2dd95SBruce Richardson 125093e441c9SXueming Li const char * 125193e441c9SXueming Li rte_eth_dev_capability_name(uint64_t capability) 125293e441c9SXueming Li { 125393e441c9SXueming Li const char *name = "UNKNOWN"; 125493e441c9SXueming Li unsigned int i; 125593e441c9SXueming Li 125693e441c9SXueming Li for (i = 0; i < RTE_DIM(rte_eth_dev_capa_names); ++i) { 125793e441c9SXueming Li if (capability == rte_eth_dev_capa_names[i].offload) { 125893e441c9SXueming Li name = rte_eth_dev_capa_names[i].name; 125993e441c9SXueming Li break; 126093e441c9SXueming Li } 126193e441c9SXueming Li } 126293e441c9SXueming Li 126393e441c9SXueming Li return name; 126493e441c9SXueming Li } 126593e441c9SXueming Li 126699a2dd95SBruce Richardson static inline int 126799a2dd95SBruce Richardson eth_dev_check_lro_pkt_size(uint16_t port_id, uint32_t config_size, 126899a2dd95SBruce Richardson uint32_t max_rx_pkt_len, uint32_t dev_info_size) 126999a2dd95SBruce Richardson { 127099a2dd95SBruce Richardson int ret = 0; 127199a2dd95SBruce Richardson 127299a2dd95SBruce Richardson if (dev_info_size == 0) { 127399a2dd95SBruce Richardson if (config_size != max_rx_pkt_len) { 127499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size" 127599a2dd95SBruce Richardson " %u != %u is not allowed\n", 127699a2dd95SBruce Richardson port_id, config_size, max_rx_pkt_len); 127799a2dd95SBruce Richardson ret = -EINVAL; 127899a2dd95SBruce Richardson } 127999a2dd95SBruce Richardson } else if (config_size > dev_info_size) { 128099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size %u " 128199a2dd95SBruce Richardson "> max allowed value %u\n", port_id, config_size, 128299a2dd95SBruce Richardson dev_info_size); 128399a2dd95SBruce Richardson ret = -EINVAL; 128499a2dd95SBruce Richardson } else if (config_size < RTE_ETHER_MIN_LEN) { 128599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size %u " 128699a2dd95SBruce Richardson "< min allowed value %u\n", port_id, config_size, 128799a2dd95SBruce Richardson (unsigned int)RTE_ETHER_MIN_LEN); 128899a2dd95SBruce Richardson ret = -EINVAL; 128999a2dd95SBruce Richardson } 129099a2dd95SBruce Richardson return ret; 129199a2dd95SBruce Richardson } 129299a2dd95SBruce Richardson 129399a2dd95SBruce Richardson /* 129499a2dd95SBruce Richardson * Validate offloads that are requested through rte_eth_dev_configure against 12950d9f56a8SAndrew Rybchenko * the offloads successfully set by the Ethernet device. 129699a2dd95SBruce Richardson * 129799a2dd95SBruce Richardson * @param port_id 129899a2dd95SBruce Richardson * The port identifier of the Ethernet device. 129999a2dd95SBruce Richardson * @param req_offloads 130099a2dd95SBruce Richardson * The offloads that have been requested through `rte_eth_dev_configure`. 130199a2dd95SBruce Richardson * @param set_offloads 13020d9f56a8SAndrew Rybchenko * The offloads successfully set by the Ethernet device. 130399a2dd95SBruce Richardson * @param offload_type 130499a2dd95SBruce Richardson * The offload type i.e. Rx/Tx string. 130599a2dd95SBruce Richardson * @param offload_name 130699a2dd95SBruce Richardson * The function that prints the offload name. 130799a2dd95SBruce Richardson * @return 130899a2dd95SBruce Richardson * - (0) if validation successful. 130999a2dd95SBruce Richardson * - (-EINVAL) if requested offload has been silently disabled. 131099a2dd95SBruce Richardson * 131199a2dd95SBruce Richardson */ 131299a2dd95SBruce Richardson static int 131399a2dd95SBruce Richardson eth_dev_validate_offloads(uint16_t port_id, uint64_t req_offloads, 131499a2dd95SBruce Richardson uint64_t set_offloads, const char *offload_type, 131599a2dd95SBruce Richardson const char *(*offload_name)(uint64_t)) 131699a2dd95SBruce Richardson { 131799a2dd95SBruce Richardson uint64_t offloads_diff = req_offloads ^ set_offloads; 131899a2dd95SBruce Richardson uint64_t offload; 131999a2dd95SBruce Richardson int ret = 0; 132099a2dd95SBruce Richardson 132199a2dd95SBruce Richardson while (offloads_diff != 0) { 132299a2dd95SBruce Richardson /* Check if any offload is requested but not enabled. */ 1323e1823e08SThomas Monjalon offload = RTE_BIT64(__builtin_ctzll(offloads_diff)); 132499a2dd95SBruce Richardson if (offload & req_offloads) { 132599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 132699a2dd95SBruce Richardson "Port %u failed to enable %s offload %s\n", 132799a2dd95SBruce Richardson port_id, offload_type, offload_name(offload)); 132899a2dd95SBruce Richardson ret = -EINVAL; 132999a2dd95SBruce Richardson } 133099a2dd95SBruce Richardson 133199a2dd95SBruce Richardson /* Check if offload couldn't be disabled. */ 133299a2dd95SBruce Richardson if (offload & set_offloads) { 133399a2dd95SBruce Richardson RTE_ETHDEV_LOG(DEBUG, 133499a2dd95SBruce Richardson "Port %u %s offload %s is not requested but enabled\n", 133599a2dd95SBruce Richardson port_id, offload_type, offload_name(offload)); 133699a2dd95SBruce Richardson } 133799a2dd95SBruce Richardson 133899a2dd95SBruce Richardson offloads_diff &= ~offload; 133999a2dd95SBruce Richardson } 134099a2dd95SBruce Richardson 134199a2dd95SBruce Richardson return ret; 134299a2dd95SBruce Richardson } 134399a2dd95SBruce Richardson 13441bb4a528SFerruh Yigit static uint32_t 13451bb4a528SFerruh Yigit eth_dev_get_overhead_len(uint32_t max_rx_pktlen, uint16_t max_mtu) 13461bb4a528SFerruh Yigit { 13471bb4a528SFerruh Yigit uint32_t overhead_len; 13481bb4a528SFerruh Yigit 13491bb4a528SFerruh Yigit if (max_mtu != UINT16_MAX && max_rx_pktlen > max_mtu) 13501bb4a528SFerruh Yigit overhead_len = max_rx_pktlen - max_mtu; 13511bb4a528SFerruh Yigit else 13521bb4a528SFerruh Yigit overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; 13531bb4a528SFerruh Yigit 13541bb4a528SFerruh Yigit return overhead_len; 13551bb4a528SFerruh Yigit } 13561bb4a528SFerruh Yigit 1357990912e6SFerruh Yigit /* rte_eth_dev_info_get() should be called prior to this function */ 1358990912e6SFerruh Yigit static int 1359990912e6SFerruh Yigit eth_dev_validate_mtu(uint16_t port_id, struct rte_eth_dev_info *dev_info, 1360990912e6SFerruh Yigit uint16_t mtu) 1361990912e6SFerruh Yigit { 1362990912e6SFerruh Yigit uint32_t overhead_len; 1363990912e6SFerruh Yigit uint32_t frame_size; 1364990912e6SFerruh Yigit 1365990912e6SFerruh Yigit if (mtu < dev_info->min_mtu) { 1366990912e6SFerruh Yigit RTE_ETHDEV_LOG(ERR, 1367990912e6SFerruh Yigit "MTU (%u) < device min MTU (%u) for port_id %u\n", 1368990912e6SFerruh Yigit mtu, dev_info->min_mtu, port_id); 1369990912e6SFerruh Yigit return -EINVAL; 1370990912e6SFerruh Yigit } 1371990912e6SFerruh Yigit if (mtu > dev_info->max_mtu) { 1372990912e6SFerruh Yigit RTE_ETHDEV_LOG(ERR, 1373990912e6SFerruh Yigit "MTU (%u) > device max MTU (%u) for port_id %u\n", 1374990912e6SFerruh Yigit mtu, dev_info->max_mtu, port_id); 1375990912e6SFerruh Yigit return -EINVAL; 1376990912e6SFerruh Yigit } 1377990912e6SFerruh Yigit 1378990912e6SFerruh Yigit overhead_len = eth_dev_get_overhead_len(dev_info->max_rx_pktlen, 1379990912e6SFerruh Yigit dev_info->max_mtu); 1380990912e6SFerruh Yigit frame_size = mtu + overhead_len; 1381990912e6SFerruh Yigit if (frame_size < RTE_ETHER_MIN_LEN) { 1382990912e6SFerruh Yigit RTE_ETHDEV_LOG(ERR, 1383990912e6SFerruh Yigit "Frame size (%u) < min frame size (%u) for port_id %u\n", 1384990912e6SFerruh Yigit frame_size, RTE_ETHER_MIN_LEN, port_id); 1385990912e6SFerruh Yigit return -EINVAL; 1386990912e6SFerruh Yigit } 1387990912e6SFerruh Yigit 1388990912e6SFerruh Yigit if (frame_size > dev_info->max_rx_pktlen) { 1389990912e6SFerruh Yigit RTE_ETHDEV_LOG(ERR, 1390990912e6SFerruh Yigit "Frame size (%u) > device max frame size (%u) for port_id %u\n", 1391990912e6SFerruh Yigit frame_size, dev_info->max_rx_pktlen, port_id); 1392990912e6SFerruh Yigit return -EINVAL; 1393990912e6SFerruh Yigit } 1394990912e6SFerruh Yigit 1395990912e6SFerruh Yigit return 0; 1396990912e6SFerruh Yigit } 1397990912e6SFerruh Yigit 139899a2dd95SBruce Richardson int 139999a2dd95SBruce Richardson rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, 140099a2dd95SBruce Richardson const struct rte_eth_conf *dev_conf) 140199a2dd95SBruce Richardson { 140299a2dd95SBruce Richardson struct rte_eth_dev *dev; 140399a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 140499a2dd95SBruce Richardson struct rte_eth_conf orig_conf; 140599a2dd95SBruce Richardson int diag; 140699a2dd95SBruce Richardson int ret; 140799a2dd95SBruce Richardson uint16_t old_mtu; 140899a2dd95SBruce Richardson 140999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 141099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 141199a2dd95SBruce Richardson 141253ef1b34SMin Hu (Connor) if (dev_conf == NULL) { 141353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 141453ef1b34SMin Hu (Connor) "Cannot configure ethdev port %u from NULL config\n", 141553ef1b34SMin Hu (Connor) port_id); 141653ef1b34SMin Hu (Connor) return -EINVAL; 141753ef1b34SMin Hu (Connor) } 141853ef1b34SMin Hu (Connor) 141999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP); 142099a2dd95SBruce Richardson 142199a2dd95SBruce Richardson if (dev->data->dev_started) { 142299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 142399a2dd95SBruce Richardson "Port %u must be stopped to allow configuration\n", 142499a2dd95SBruce Richardson port_id); 142599a2dd95SBruce Richardson return -EBUSY; 142699a2dd95SBruce Richardson } 142799a2dd95SBruce Richardson 142802edbfabSHuisong Li /* 142902edbfabSHuisong Li * Ensure that "dev_configured" is always 0 each time prepare to do 143002edbfabSHuisong Li * dev_configure() to avoid any non-anticipated behaviour. 143102edbfabSHuisong Li * And set to 1 when dev_configure() is executed successfully. 143202edbfabSHuisong Li */ 143302edbfabSHuisong Li dev->data->dev_configured = 0; 143402edbfabSHuisong Li 143599a2dd95SBruce Richardson /* Store original config, as rollback required on failure */ 143699a2dd95SBruce Richardson memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf)); 143799a2dd95SBruce Richardson 143899a2dd95SBruce Richardson /* 143999a2dd95SBruce Richardson * Copy the dev_conf parameter into the dev structure. 144099a2dd95SBruce Richardson * rte_eth_dev_info_get() requires dev_conf, copy it before dev_info get 144199a2dd95SBruce Richardson */ 144299a2dd95SBruce Richardson if (dev_conf != &dev->data->dev_conf) 144399a2dd95SBruce Richardson memcpy(&dev->data->dev_conf, dev_conf, 144499a2dd95SBruce Richardson sizeof(dev->data->dev_conf)); 144599a2dd95SBruce Richardson 144699a2dd95SBruce Richardson /* Backup mtu for rollback */ 144799a2dd95SBruce Richardson old_mtu = dev->data->mtu; 144899a2dd95SBruce Richardson 144999a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 145099a2dd95SBruce Richardson if (ret != 0) 145199a2dd95SBruce Richardson goto rollback; 145299a2dd95SBruce Richardson 145399a2dd95SBruce Richardson /* If number of queues specified by application for both Rx and Tx is 145499a2dd95SBruce Richardson * zero, use driver preferred values. This cannot be done individually 145599a2dd95SBruce Richardson * as it is valid for either Tx or Rx (but not both) to be zero. 145699a2dd95SBruce Richardson * If driver does not provide any preferred valued, fall back on 145799a2dd95SBruce Richardson * EAL defaults. 145899a2dd95SBruce Richardson */ 145999a2dd95SBruce Richardson if (nb_rx_q == 0 && nb_tx_q == 0) { 146099a2dd95SBruce Richardson nb_rx_q = dev_info.default_rxportconf.nb_queues; 146199a2dd95SBruce Richardson if (nb_rx_q == 0) 146299a2dd95SBruce Richardson nb_rx_q = RTE_ETH_DEV_FALLBACK_RX_NBQUEUES; 146399a2dd95SBruce Richardson nb_tx_q = dev_info.default_txportconf.nb_queues; 146499a2dd95SBruce Richardson if (nb_tx_q == 0) 146599a2dd95SBruce Richardson nb_tx_q = RTE_ETH_DEV_FALLBACK_TX_NBQUEUES; 146699a2dd95SBruce Richardson } 146799a2dd95SBruce Richardson 146899a2dd95SBruce Richardson if (nb_rx_q > RTE_MAX_QUEUES_PER_PORT) { 146999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 147009fd4227SAndrew Rybchenko "Number of Rx queues requested (%u) is greater than max supported(%d)\n", 147199a2dd95SBruce Richardson nb_rx_q, RTE_MAX_QUEUES_PER_PORT); 147299a2dd95SBruce Richardson ret = -EINVAL; 147399a2dd95SBruce Richardson goto rollback; 147499a2dd95SBruce Richardson } 147599a2dd95SBruce Richardson 147699a2dd95SBruce Richardson if (nb_tx_q > RTE_MAX_QUEUES_PER_PORT) { 147799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 147809fd4227SAndrew Rybchenko "Number of Tx queues requested (%u) is greater than max supported(%d)\n", 147999a2dd95SBruce Richardson nb_tx_q, RTE_MAX_QUEUES_PER_PORT); 148099a2dd95SBruce Richardson ret = -EINVAL; 148199a2dd95SBruce Richardson goto rollback; 148299a2dd95SBruce Richardson } 148399a2dd95SBruce Richardson 148499a2dd95SBruce Richardson /* 148509fd4227SAndrew Rybchenko * Check that the numbers of Rx and Tx queues are not greater 148609fd4227SAndrew Rybchenko * than the maximum number of Rx and Tx queues supported by the 148799a2dd95SBruce Richardson * configured device. 148899a2dd95SBruce Richardson */ 148999a2dd95SBruce Richardson if (nb_rx_q > dev_info.max_rx_queues) { 149099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_rx_queues=%u > %u\n", 149199a2dd95SBruce Richardson port_id, nb_rx_q, dev_info.max_rx_queues); 149299a2dd95SBruce Richardson ret = -EINVAL; 149399a2dd95SBruce Richardson goto rollback; 149499a2dd95SBruce Richardson } 149599a2dd95SBruce Richardson 149699a2dd95SBruce Richardson if (nb_tx_q > dev_info.max_tx_queues) { 149799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_tx_queues=%u > %u\n", 149899a2dd95SBruce Richardson port_id, nb_tx_q, dev_info.max_tx_queues); 149999a2dd95SBruce Richardson ret = -EINVAL; 150099a2dd95SBruce Richardson goto rollback; 150199a2dd95SBruce Richardson } 150299a2dd95SBruce Richardson 150399a2dd95SBruce Richardson /* Check that the device supports requested interrupts */ 150499a2dd95SBruce Richardson if ((dev_conf->intr_conf.lsc == 1) && 150599a2dd95SBruce Richardson (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) { 150699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Driver %s does not support lsc\n", 150799a2dd95SBruce Richardson dev->device->driver->name); 150899a2dd95SBruce Richardson ret = -EINVAL; 150999a2dd95SBruce Richardson goto rollback; 151099a2dd95SBruce Richardson } 151199a2dd95SBruce Richardson if ((dev_conf->intr_conf.rmv == 1) && 151299a2dd95SBruce Richardson (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) { 151399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Driver %s does not support rmv\n", 151499a2dd95SBruce Richardson dev->device->driver->name); 151599a2dd95SBruce Richardson ret = -EINVAL; 151699a2dd95SBruce Richardson goto rollback; 151799a2dd95SBruce Richardson } 151899a2dd95SBruce Richardson 15191bb4a528SFerruh Yigit if (dev_conf->rxmode.mtu == 0) 15201bb4a528SFerruh Yigit dev->data->dev_conf.rxmode.mtu = RTE_ETHER_MTU; 1521990912e6SFerruh Yigit 1522990912e6SFerruh Yigit ret = eth_dev_validate_mtu(port_id, &dev_info, 1523990912e6SFerruh Yigit dev->data->dev_conf.rxmode.mtu); 1524990912e6SFerruh Yigit if (ret != 0) 152599a2dd95SBruce Richardson goto rollback; 152699a2dd95SBruce Richardson 15271bb4a528SFerruh Yigit dev->data->mtu = dev->data->dev_conf.rxmode.mtu; 15281bb4a528SFerruh Yigit 152999a2dd95SBruce Richardson /* 153099a2dd95SBruce Richardson * If LRO is enabled, check that the maximum aggregated packet 153199a2dd95SBruce Richardson * size is supported by the configured device. 153299a2dd95SBruce Richardson */ 1533295968d1SFerruh Yigit if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) { 1534990912e6SFerruh Yigit uint32_t max_rx_pktlen; 1535990912e6SFerruh Yigit uint32_t overhead_len; 1536990912e6SFerruh Yigit 1537990912e6SFerruh Yigit overhead_len = eth_dev_get_overhead_len(dev_info.max_rx_pktlen, 1538990912e6SFerruh Yigit dev_info.max_mtu); 1539990912e6SFerruh Yigit max_rx_pktlen = dev->data->dev_conf.rxmode.mtu + overhead_len; 154099a2dd95SBruce Richardson if (dev_conf->rxmode.max_lro_pkt_size == 0) 15411bb4a528SFerruh Yigit dev->data->dev_conf.rxmode.max_lro_pkt_size = max_rx_pktlen; 154299a2dd95SBruce Richardson ret = eth_dev_check_lro_pkt_size(port_id, 154399a2dd95SBruce Richardson dev->data->dev_conf.rxmode.max_lro_pkt_size, 15441bb4a528SFerruh Yigit max_rx_pktlen, 154599a2dd95SBruce Richardson dev_info.max_lro_pkt_size); 154699a2dd95SBruce Richardson if (ret != 0) 154799a2dd95SBruce Richardson goto rollback; 154899a2dd95SBruce Richardson } 154999a2dd95SBruce Richardson 155099a2dd95SBruce Richardson /* Any requested offloading must be within its device capabilities */ 155199a2dd95SBruce Richardson if ((dev_conf->rxmode.offloads & dev_info.rx_offload_capa) != 155299a2dd95SBruce Richardson dev_conf->rxmode.offloads) { 155399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 155499a2dd95SBruce Richardson "Ethdev port_id=%u requested Rx offloads 0x%"PRIx64" doesn't match Rx offloads " 155599a2dd95SBruce Richardson "capabilities 0x%"PRIx64" in %s()\n", 155699a2dd95SBruce Richardson port_id, dev_conf->rxmode.offloads, 155799a2dd95SBruce Richardson dev_info.rx_offload_capa, 155899a2dd95SBruce Richardson __func__); 155999a2dd95SBruce Richardson ret = -EINVAL; 156099a2dd95SBruce Richardson goto rollback; 156199a2dd95SBruce Richardson } 156299a2dd95SBruce Richardson if ((dev_conf->txmode.offloads & dev_info.tx_offload_capa) != 156399a2dd95SBruce Richardson dev_conf->txmode.offloads) { 156499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 156599a2dd95SBruce Richardson "Ethdev port_id=%u requested Tx offloads 0x%"PRIx64" doesn't match Tx offloads " 156699a2dd95SBruce Richardson "capabilities 0x%"PRIx64" in %s()\n", 156799a2dd95SBruce Richardson port_id, dev_conf->txmode.offloads, 156899a2dd95SBruce Richardson dev_info.tx_offload_capa, 156999a2dd95SBruce Richardson __func__); 157099a2dd95SBruce Richardson ret = -EINVAL; 157199a2dd95SBruce Richardson goto rollback; 157299a2dd95SBruce Richardson } 157399a2dd95SBruce Richardson 157499a2dd95SBruce Richardson dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = 157599a2dd95SBruce Richardson rte_eth_rss_hf_refine(dev_conf->rx_adv_conf.rss_conf.rss_hf); 157699a2dd95SBruce Richardson 157799a2dd95SBruce Richardson /* Check that device supports requested rss hash functions. */ 157899a2dd95SBruce Richardson if ((dev_info.flow_type_rss_offloads | 157999a2dd95SBruce Richardson dev_conf->rx_adv_conf.rss_conf.rss_hf) != 158099a2dd95SBruce Richardson dev_info.flow_type_rss_offloads) { 158199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 158299a2dd95SBruce Richardson "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n", 158399a2dd95SBruce Richardson port_id, dev_conf->rx_adv_conf.rss_conf.rss_hf, 158499a2dd95SBruce Richardson dev_info.flow_type_rss_offloads); 158599a2dd95SBruce Richardson ret = -EINVAL; 158699a2dd95SBruce Richardson goto rollback; 158799a2dd95SBruce Richardson } 158899a2dd95SBruce Richardson 158999a2dd95SBruce Richardson /* Check if Rx RSS distribution is disabled but RSS hash is enabled. */ 1590295968d1SFerruh Yigit if (((dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) == 0) && 1591295968d1SFerruh Yigit (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)) { 159299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 159399a2dd95SBruce Richardson "Ethdev port_id=%u config invalid Rx mq_mode without RSS but %s offload is requested\n", 159499a2dd95SBruce Richardson port_id, 1595295968d1SFerruh Yigit rte_eth_dev_rx_offload_name(RTE_ETH_RX_OFFLOAD_RSS_HASH)); 159699a2dd95SBruce Richardson ret = -EINVAL; 159799a2dd95SBruce Richardson goto rollback; 159899a2dd95SBruce Richardson } 159999a2dd95SBruce Richardson 160099a2dd95SBruce Richardson /* 160109fd4227SAndrew Rybchenko * Setup new number of Rx/Tx queues and reconfigure device. 160299a2dd95SBruce Richardson */ 160399a2dd95SBruce Richardson diag = eth_dev_rx_queue_config(dev, nb_rx_q); 160499a2dd95SBruce Richardson if (diag != 0) { 160599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 160699a2dd95SBruce Richardson "Port%u eth_dev_rx_queue_config = %d\n", 160799a2dd95SBruce Richardson port_id, diag); 160899a2dd95SBruce Richardson ret = diag; 160999a2dd95SBruce Richardson goto rollback; 161099a2dd95SBruce Richardson } 161199a2dd95SBruce Richardson 161299a2dd95SBruce Richardson diag = eth_dev_tx_queue_config(dev, nb_tx_q); 161399a2dd95SBruce Richardson if (diag != 0) { 161499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 161599a2dd95SBruce Richardson "Port%u eth_dev_tx_queue_config = %d\n", 161699a2dd95SBruce Richardson port_id, diag); 161799a2dd95SBruce Richardson eth_dev_rx_queue_config(dev, 0); 161899a2dd95SBruce Richardson ret = diag; 161999a2dd95SBruce Richardson goto rollback; 162099a2dd95SBruce Richardson } 162199a2dd95SBruce Richardson 162299a2dd95SBruce Richardson diag = (*dev->dev_ops->dev_configure)(dev); 162399a2dd95SBruce Richardson if (diag != 0) { 162499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port%u dev_configure = %d\n", 162599a2dd95SBruce Richardson port_id, diag); 162699a2dd95SBruce Richardson ret = eth_err(port_id, diag); 162799a2dd95SBruce Richardson goto reset_queues; 162899a2dd95SBruce Richardson } 162999a2dd95SBruce Richardson 163099a2dd95SBruce Richardson /* Initialize Rx profiling if enabled at compilation time. */ 163199a2dd95SBruce Richardson diag = __rte_eth_dev_profile_init(port_id, dev); 163299a2dd95SBruce Richardson if (diag != 0) { 163399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port%u __rte_eth_dev_profile_init = %d\n", 163499a2dd95SBruce Richardson port_id, diag); 163599a2dd95SBruce Richardson ret = eth_err(port_id, diag); 163699a2dd95SBruce Richardson goto reset_queues; 163799a2dd95SBruce Richardson } 163899a2dd95SBruce Richardson 163999a2dd95SBruce Richardson /* Validate Rx offloads. */ 164099a2dd95SBruce Richardson diag = eth_dev_validate_offloads(port_id, 164199a2dd95SBruce Richardson dev_conf->rxmode.offloads, 164299a2dd95SBruce Richardson dev->data->dev_conf.rxmode.offloads, "Rx", 164399a2dd95SBruce Richardson rte_eth_dev_rx_offload_name); 164499a2dd95SBruce Richardson if (diag != 0) { 164599a2dd95SBruce Richardson ret = diag; 164699a2dd95SBruce Richardson goto reset_queues; 164799a2dd95SBruce Richardson } 164899a2dd95SBruce Richardson 164999a2dd95SBruce Richardson /* Validate Tx offloads. */ 165099a2dd95SBruce Richardson diag = eth_dev_validate_offloads(port_id, 165199a2dd95SBruce Richardson dev_conf->txmode.offloads, 165299a2dd95SBruce Richardson dev->data->dev_conf.txmode.offloads, "Tx", 165399a2dd95SBruce Richardson rte_eth_dev_tx_offload_name); 165499a2dd95SBruce Richardson if (diag != 0) { 165599a2dd95SBruce Richardson ret = diag; 165699a2dd95SBruce Richardson goto reset_queues; 165799a2dd95SBruce Richardson } 165899a2dd95SBruce Richardson 165902edbfabSHuisong Li dev->data->dev_configured = 1; 166099a2dd95SBruce Richardson rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, 0); 166199a2dd95SBruce Richardson return 0; 166299a2dd95SBruce Richardson reset_queues: 166399a2dd95SBruce Richardson eth_dev_rx_queue_config(dev, 0); 166499a2dd95SBruce Richardson eth_dev_tx_queue_config(dev, 0); 166599a2dd95SBruce Richardson rollback: 166699a2dd95SBruce Richardson memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf)); 166799a2dd95SBruce Richardson if (old_mtu != dev->data->mtu) 166899a2dd95SBruce Richardson dev->data->mtu = old_mtu; 166999a2dd95SBruce Richardson 167099a2dd95SBruce Richardson rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, ret); 167199a2dd95SBruce Richardson return ret; 167299a2dd95SBruce Richardson } 167399a2dd95SBruce Richardson 167499a2dd95SBruce Richardson void 167599a2dd95SBruce Richardson rte_eth_dev_internal_reset(struct rte_eth_dev *dev) 167699a2dd95SBruce Richardson { 167799a2dd95SBruce Richardson if (dev->data->dev_started) { 167899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port %u must be stopped to allow reset\n", 167999a2dd95SBruce Richardson dev->data->port_id); 168099a2dd95SBruce Richardson return; 168199a2dd95SBruce Richardson } 168299a2dd95SBruce Richardson 168399a2dd95SBruce Richardson eth_dev_rx_queue_config(dev, 0); 168499a2dd95SBruce Richardson eth_dev_tx_queue_config(dev, 0); 168599a2dd95SBruce Richardson 168699a2dd95SBruce Richardson memset(&dev->data->dev_conf, 0, sizeof(dev->data->dev_conf)); 168799a2dd95SBruce Richardson } 168899a2dd95SBruce Richardson 168999a2dd95SBruce Richardson static void 169099a2dd95SBruce Richardson eth_dev_mac_restore(struct rte_eth_dev *dev, 169199a2dd95SBruce Richardson struct rte_eth_dev_info *dev_info) 169299a2dd95SBruce Richardson { 169399a2dd95SBruce Richardson struct rte_ether_addr *addr; 169499a2dd95SBruce Richardson uint16_t i; 169599a2dd95SBruce Richardson uint32_t pool = 0; 169699a2dd95SBruce Richardson uint64_t pool_mask; 169799a2dd95SBruce Richardson 169899a2dd95SBruce Richardson /* replay MAC address configuration including default MAC */ 169999a2dd95SBruce Richardson addr = &dev->data->mac_addrs[0]; 170099a2dd95SBruce Richardson if (*dev->dev_ops->mac_addr_set != NULL) 170199a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_set)(dev, addr); 170299a2dd95SBruce Richardson else if (*dev->dev_ops->mac_addr_add != NULL) 170399a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_add)(dev, addr, 0, pool); 170499a2dd95SBruce Richardson 170599a2dd95SBruce Richardson if (*dev->dev_ops->mac_addr_add != NULL) { 170699a2dd95SBruce Richardson for (i = 1; i < dev_info->max_mac_addrs; i++) { 170799a2dd95SBruce Richardson addr = &dev->data->mac_addrs[i]; 170899a2dd95SBruce Richardson 170999a2dd95SBruce Richardson /* skip zero address */ 171099a2dd95SBruce Richardson if (rte_is_zero_ether_addr(addr)) 171199a2dd95SBruce Richardson continue; 171299a2dd95SBruce Richardson 171399a2dd95SBruce Richardson pool = 0; 171499a2dd95SBruce Richardson pool_mask = dev->data->mac_pool_sel[i]; 171599a2dd95SBruce Richardson 171699a2dd95SBruce Richardson do { 1717e1823e08SThomas Monjalon if (pool_mask & UINT64_C(1)) 171899a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_add)(dev, 171999a2dd95SBruce Richardson addr, i, pool); 172099a2dd95SBruce Richardson pool_mask >>= 1; 172199a2dd95SBruce Richardson pool++; 172299a2dd95SBruce Richardson } while (pool_mask); 172399a2dd95SBruce Richardson } 172499a2dd95SBruce Richardson } 172599a2dd95SBruce Richardson } 172699a2dd95SBruce Richardson 172799a2dd95SBruce Richardson static int 172899a2dd95SBruce Richardson eth_dev_config_restore(struct rte_eth_dev *dev, 172999a2dd95SBruce Richardson struct rte_eth_dev_info *dev_info, uint16_t port_id) 173099a2dd95SBruce Richardson { 173199a2dd95SBruce Richardson int ret; 173299a2dd95SBruce Richardson 173399a2dd95SBruce Richardson if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR)) 173499a2dd95SBruce Richardson eth_dev_mac_restore(dev, dev_info); 173599a2dd95SBruce Richardson 173699a2dd95SBruce Richardson /* replay promiscuous configuration */ 173799a2dd95SBruce Richardson /* 173899a2dd95SBruce Richardson * use callbacks directly since we don't need port_id check and 173999a2dd95SBruce Richardson * would like to bypass the same value set 174099a2dd95SBruce Richardson */ 174199a2dd95SBruce Richardson if (rte_eth_promiscuous_get(port_id) == 1 && 174299a2dd95SBruce Richardson *dev->dev_ops->promiscuous_enable != NULL) { 174399a2dd95SBruce Richardson ret = eth_err(port_id, 174499a2dd95SBruce Richardson (*dev->dev_ops->promiscuous_enable)(dev)); 174599a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 174699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 174799a2dd95SBruce Richardson "Failed to enable promiscuous mode for device (port %u): %s\n", 174899a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 174999a2dd95SBruce Richardson return ret; 175099a2dd95SBruce Richardson } 175199a2dd95SBruce Richardson } else if (rte_eth_promiscuous_get(port_id) == 0 && 175299a2dd95SBruce Richardson *dev->dev_ops->promiscuous_disable != NULL) { 175399a2dd95SBruce Richardson ret = eth_err(port_id, 175499a2dd95SBruce Richardson (*dev->dev_ops->promiscuous_disable)(dev)); 175599a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 175699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 175799a2dd95SBruce Richardson "Failed to disable promiscuous mode for device (port %u): %s\n", 175899a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 175999a2dd95SBruce Richardson return ret; 176099a2dd95SBruce Richardson } 176199a2dd95SBruce Richardson } 176299a2dd95SBruce Richardson 176399a2dd95SBruce Richardson /* replay all multicast configuration */ 176499a2dd95SBruce Richardson /* 176599a2dd95SBruce Richardson * use callbacks directly since we don't need port_id check and 176699a2dd95SBruce Richardson * would like to bypass the same value set 176799a2dd95SBruce Richardson */ 176899a2dd95SBruce Richardson if (rte_eth_allmulticast_get(port_id) == 1 && 176999a2dd95SBruce Richardson *dev->dev_ops->allmulticast_enable != NULL) { 177099a2dd95SBruce Richardson ret = eth_err(port_id, 177199a2dd95SBruce Richardson (*dev->dev_ops->allmulticast_enable)(dev)); 177299a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 177399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 177499a2dd95SBruce Richardson "Failed to enable allmulticast mode for device (port %u): %s\n", 177599a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 177699a2dd95SBruce Richardson return ret; 177799a2dd95SBruce Richardson } 177899a2dd95SBruce Richardson } else if (rte_eth_allmulticast_get(port_id) == 0 && 177999a2dd95SBruce Richardson *dev->dev_ops->allmulticast_disable != NULL) { 178099a2dd95SBruce Richardson ret = eth_err(port_id, 178199a2dd95SBruce Richardson (*dev->dev_ops->allmulticast_disable)(dev)); 178299a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 178399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 178499a2dd95SBruce Richardson "Failed to disable allmulticast mode for device (port %u): %s\n", 178599a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 178699a2dd95SBruce Richardson return ret; 178799a2dd95SBruce Richardson } 178899a2dd95SBruce Richardson } 178999a2dd95SBruce Richardson 179099a2dd95SBruce Richardson return 0; 179199a2dd95SBruce Richardson } 179299a2dd95SBruce Richardson 179399a2dd95SBruce Richardson int 179499a2dd95SBruce Richardson rte_eth_dev_start(uint16_t port_id) 179599a2dd95SBruce Richardson { 179699a2dd95SBruce Richardson struct rte_eth_dev *dev; 179799a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 179899a2dd95SBruce Richardson int diag; 179999a2dd95SBruce Richardson int ret, ret_stop; 180099a2dd95SBruce Richardson 180199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 180299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 180399a2dd95SBruce Richardson 180499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP); 180599a2dd95SBruce Richardson 180602edbfabSHuisong Li if (dev->data->dev_configured == 0) { 180702edbfabSHuisong Li RTE_ETHDEV_LOG(INFO, 180802edbfabSHuisong Li "Device with port_id=%"PRIu16" is not configured.\n", 180902edbfabSHuisong Li port_id); 181002edbfabSHuisong Li return -EINVAL; 181102edbfabSHuisong Li } 181202edbfabSHuisong Li 181399a2dd95SBruce Richardson if (dev->data->dev_started != 0) { 181499a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 181599a2dd95SBruce Richardson "Device with port_id=%"PRIu16" already started\n", 181699a2dd95SBruce Richardson port_id); 181799a2dd95SBruce Richardson return 0; 181899a2dd95SBruce Richardson } 181999a2dd95SBruce Richardson 182099a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 182199a2dd95SBruce Richardson if (ret != 0) 182299a2dd95SBruce Richardson return ret; 182399a2dd95SBruce Richardson 182499a2dd95SBruce Richardson /* Lets restore MAC now if device does not support live change */ 182599a2dd95SBruce Richardson if (*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR) 182699a2dd95SBruce Richardson eth_dev_mac_restore(dev, &dev_info); 182799a2dd95SBruce Richardson 182899a2dd95SBruce Richardson diag = (*dev->dev_ops->dev_start)(dev); 182999a2dd95SBruce Richardson if (diag == 0) 183099a2dd95SBruce Richardson dev->data->dev_started = 1; 183199a2dd95SBruce Richardson else 183299a2dd95SBruce Richardson return eth_err(port_id, diag); 183399a2dd95SBruce Richardson 183499a2dd95SBruce Richardson ret = eth_dev_config_restore(dev, &dev_info, port_id); 183599a2dd95SBruce Richardson if (ret != 0) { 183699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 183799a2dd95SBruce Richardson "Error during restoring configuration for device (port %u): %s\n", 183899a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 183999a2dd95SBruce Richardson ret_stop = rte_eth_dev_stop(port_id); 184099a2dd95SBruce Richardson if (ret_stop != 0) { 184199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 184299a2dd95SBruce Richardson "Failed to stop device (port %u): %s\n", 184399a2dd95SBruce Richardson port_id, rte_strerror(-ret_stop)); 184499a2dd95SBruce Richardson } 184599a2dd95SBruce Richardson 184699a2dd95SBruce Richardson return ret; 184799a2dd95SBruce Richardson } 184899a2dd95SBruce Richardson 184999a2dd95SBruce Richardson if (dev->data->dev_conf.intr_conf.lsc == 0) { 185099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP); 185199a2dd95SBruce Richardson (*dev->dev_ops->link_update)(dev, 0); 185299a2dd95SBruce Richardson } 185399a2dd95SBruce Richardson 1854c87d435aSKonstantin Ananyev /* expose selection of PMD fast-path functions */ 1855c87d435aSKonstantin Ananyev eth_dev_fp_ops_setup(rte_eth_fp_ops + port_id, dev); 1856c87d435aSKonstantin Ananyev 185799a2dd95SBruce Richardson rte_ethdev_trace_start(port_id); 185899a2dd95SBruce Richardson return 0; 185999a2dd95SBruce Richardson } 186099a2dd95SBruce Richardson 186199a2dd95SBruce Richardson int 186299a2dd95SBruce Richardson rte_eth_dev_stop(uint16_t port_id) 186399a2dd95SBruce Richardson { 186499a2dd95SBruce Richardson struct rte_eth_dev *dev; 186599a2dd95SBruce Richardson int ret; 186699a2dd95SBruce Richardson 186799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 186899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 186999a2dd95SBruce Richardson 187099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_stop, -ENOTSUP); 187199a2dd95SBruce Richardson 187299a2dd95SBruce Richardson if (dev->data->dev_started == 0) { 187399a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 187499a2dd95SBruce Richardson "Device with port_id=%"PRIu16" already stopped\n", 187599a2dd95SBruce Richardson port_id); 187699a2dd95SBruce Richardson return 0; 187799a2dd95SBruce Richardson } 187899a2dd95SBruce Richardson 1879c87d435aSKonstantin Ananyev /* point fast-path functions to dummy ones */ 1880c87d435aSKonstantin Ananyev eth_dev_fp_ops_reset(rte_eth_fp_ops + port_id); 1881c87d435aSKonstantin Ananyev 188299a2dd95SBruce Richardson dev->data->dev_started = 0; 188399a2dd95SBruce Richardson ret = (*dev->dev_ops->dev_stop)(dev); 188499a2dd95SBruce Richardson rte_ethdev_trace_stop(port_id, ret); 188599a2dd95SBruce Richardson 188699a2dd95SBruce Richardson return ret; 188799a2dd95SBruce Richardson } 188899a2dd95SBruce Richardson 188999a2dd95SBruce Richardson int 189099a2dd95SBruce Richardson rte_eth_dev_set_link_up(uint16_t port_id) 189199a2dd95SBruce Richardson { 189299a2dd95SBruce Richardson struct rte_eth_dev *dev; 189399a2dd95SBruce Richardson 189499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 189599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 189699a2dd95SBruce Richardson 189799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_up, -ENOTSUP); 189899a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->dev_set_link_up)(dev)); 189999a2dd95SBruce Richardson } 190099a2dd95SBruce Richardson 190199a2dd95SBruce Richardson int 190299a2dd95SBruce Richardson rte_eth_dev_set_link_down(uint16_t port_id) 190399a2dd95SBruce Richardson { 190499a2dd95SBruce Richardson struct rte_eth_dev *dev; 190599a2dd95SBruce Richardson 190699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 190799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 190899a2dd95SBruce Richardson 190999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_down, -ENOTSUP); 191099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->dev_set_link_down)(dev)); 191199a2dd95SBruce Richardson } 191299a2dd95SBruce Richardson 191399a2dd95SBruce Richardson int 191499a2dd95SBruce Richardson rte_eth_dev_close(uint16_t port_id) 191599a2dd95SBruce Richardson { 191699a2dd95SBruce Richardson struct rte_eth_dev *dev; 191799a2dd95SBruce Richardson int firsterr, binerr; 191899a2dd95SBruce Richardson int *lasterr = &firsterr; 191999a2dd95SBruce Richardson 192099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 192199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 192299a2dd95SBruce Richardson 1923febc855bSAndrew Rybchenko if (dev->data->dev_started) { 1924febc855bSAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Cannot close started device (port %u)\n", 1925febc855bSAndrew Rybchenko port_id); 1926febc855bSAndrew Rybchenko return -EINVAL; 1927febc855bSAndrew Rybchenko } 1928febc855bSAndrew Rybchenko 192999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP); 193099a2dd95SBruce Richardson *lasterr = (*dev->dev_ops->dev_close)(dev); 193199a2dd95SBruce Richardson if (*lasterr != 0) 193299a2dd95SBruce Richardson lasterr = &binerr; 193399a2dd95SBruce Richardson 193499a2dd95SBruce Richardson rte_ethdev_trace_close(port_id); 193599a2dd95SBruce Richardson *lasterr = rte_eth_dev_release_port(dev); 193699a2dd95SBruce Richardson 193799a2dd95SBruce Richardson return firsterr; 193899a2dd95SBruce Richardson } 193999a2dd95SBruce Richardson 194099a2dd95SBruce Richardson int 194199a2dd95SBruce Richardson rte_eth_dev_reset(uint16_t port_id) 194299a2dd95SBruce Richardson { 194399a2dd95SBruce Richardson struct rte_eth_dev *dev; 194499a2dd95SBruce Richardson int ret; 194599a2dd95SBruce Richardson 194699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 194799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 194899a2dd95SBruce Richardson 194999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP); 195099a2dd95SBruce Richardson 195199a2dd95SBruce Richardson ret = rte_eth_dev_stop(port_id); 195299a2dd95SBruce Richardson if (ret != 0) { 195399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 195499a2dd95SBruce Richardson "Failed to stop device (port %u) before reset: %s - ignore\n", 195599a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 195699a2dd95SBruce Richardson } 195799a2dd95SBruce Richardson ret = dev->dev_ops->dev_reset(dev); 195899a2dd95SBruce Richardson 195999a2dd95SBruce Richardson return eth_err(port_id, ret); 196099a2dd95SBruce Richardson } 196199a2dd95SBruce Richardson 196299a2dd95SBruce Richardson int 196399a2dd95SBruce Richardson rte_eth_dev_is_removed(uint16_t port_id) 196499a2dd95SBruce Richardson { 196599a2dd95SBruce Richardson struct rte_eth_dev *dev; 196699a2dd95SBruce Richardson int ret; 196799a2dd95SBruce Richardson 196899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0); 196999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 197099a2dd95SBruce Richardson 197199a2dd95SBruce Richardson if (dev->state == RTE_ETH_DEV_REMOVED) 197299a2dd95SBruce Richardson return 1; 197399a2dd95SBruce Richardson 197499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->is_removed, 0); 197599a2dd95SBruce Richardson 197699a2dd95SBruce Richardson ret = dev->dev_ops->is_removed(dev); 197799a2dd95SBruce Richardson if (ret != 0) 197899a2dd95SBruce Richardson /* Device is physically removed. */ 197999a2dd95SBruce Richardson dev->state = RTE_ETH_DEV_REMOVED; 198099a2dd95SBruce Richardson 198199a2dd95SBruce Richardson return ret; 198299a2dd95SBruce Richardson } 198399a2dd95SBruce Richardson 198499a2dd95SBruce Richardson static int 198599a2dd95SBruce Richardson rte_eth_rx_queue_check_split(const struct rte_eth_rxseg_split *rx_seg, 198699a2dd95SBruce Richardson uint16_t n_seg, uint32_t *mbp_buf_size, 198799a2dd95SBruce Richardson const struct rte_eth_dev_info *dev_info) 198899a2dd95SBruce Richardson { 198999a2dd95SBruce Richardson const struct rte_eth_rxseg_capa *seg_capa = &dev_info->rx_seg_capa; 199099a2dd95SBruce Richardson struct rte_mempool *mp_first; 199199a2dd95SBruce Richardson uint32_t offset_mask; 199299a2dd95SBruce Richardson uint16_t seg_idx; 199399a2dd95SBruce Richardson 199499a2dd95SBruce Richardson if (n_seg > seg_capa->max_nseg) { 199599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 199699a2dd95SBruce Richardson "Requested Rx segments %u exceed supported %u\n", 199799a2dd95SBruce Richardson n_seg, seg_capa->max_nseg); 199899a2dd95SBruce Richardson return -EINVAL; 199999a2dd95SBruce Richardson } 200099a2dd95SBruce Richardson /* 200199a2dd95SBruce Richardson * Check the sizes and offsets against buffer sizes 200299a2dd95SBruce Richardson * for each segment specified in extended configuration. 200399a2dd95SBruce Richardson */ 200499a2dd95SBruce Richardson mp_first = rx_seg[0].mp; 2005e1823e08SThomas Monjalon offset_mask = RTE_BIT32(seg_capa->offset_align_log2) - 1; 200699a2dd95SBruce Richardson for (seg_idx = 0; seg_idx < n_seg; seg_idx++) { 200799a2dd95SBruce Richardson struct rte_mempool *mpl = rx_seg[seg_idx].mp; 200899a2dd95SBruce Richardson uint32_t length = rx_seg[seg_idx].length; 200999a2dd95SBruce Richardson uint32_t offset = rx_seg[seg_idx].offset; 201099a2dd95SBruce Richardson 201199a2dd95SBruce Richardson if (mpl == NULL) { 201299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "null mempool pointer\n"); 201399a2dd95SBruce Richardson return -EINVAL; 201499a2dd95SBruce Richardson } 201599a2dd95SBruce Richardson if (seg_idx != 0 && mp_first != mpl && 201699a2dd95SBruce Richardson seg_capa->multi_pools == 0) { 201799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Receiving to multiple pools is not supported\n"); 201899a2dd95SBruce Richardson return -ENOTSUP; 201999a2dd95SBruce Richardson } 202099a2dd95SBruce Richardson if (offset != 0) { 202199a2dd95SBruce Richardson if (seg_capa->offset_allowed == 0) { 202299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Rx segmentation with offset is not supported\n"); 202399a2dd95SBruce Richardson return -ENOTSUP; 202499a2dd95SBruce Richardson } 202599a2dd95SBruce Richardson if (offset & offset_mask) { 202699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Rx segmentation invalid offset alignment %u, %u\n", 202799a2dd95SBruce Richardson offset, 202899a2dd95SBruce Richardson seg_capa->offset_align_log2); 202999a2dd95SBruce Richardson return -EINVAL; 203099a2dd95SBruce Richardson } 203199a2dd95SBruce Richardson } 203299a2dd95SBruce Richardson if (mpl->private_data_size < 203399a2dd95SBruce Richardson sizeof(struct rte_pktmbuf_pool_private)) { 203499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 203599a2dd95SBruce Richardson "%s private_data_size %u < %u\n", 203699a2dd95SBruce Richardson mpl->name, mpl->private_data_size, 203799a2dd95SBruce Richardson (unsigned int)sizeof 203899a2dd95SBruce Richardson (struct rte_pktmbuf_pool_private)); 203999a2dd95SBruce Richardson return -ENOSPC; 204099a2dd95SBruce Richardson } 204199a2dd95SBruce Richardson offset += seg_idx != 0 ? 0 : RTE_PKTMBUF_HEADROOM; 204299a2dd95SBruce Richardson *mbp_buf_size = rte_pktmbuf_data_room_size(mpl); 204399a2dd95SBruce Richardson length = length != 0 ? length : *mbp_buf_size; 204499a2dd95SBruce Richardson if (*mbp_buf_size < length + offset) { 204599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 204699a2dd95SBruce Richardson "%s mbuf_data_room_size %u < %u (segment length=%u + segment offset=%u)\n", 204799a2dd95SBruce Richardson mpl->name, *mbp_buf_size, 204899a2dd95SBruce Richardson length + offset, length, offset); 204999a2dd95SBruce Richardson return -EINVAL; 205099a2dd95SBruce Richardson } 205199a2dd95SBruce Richardson } 205299a2dd95SBruce Richardson return 0; 205399a2dd95SBruce Richardson } 205499a2dd95SBruce Richardson 205599a2dd95SBruce Richardson int 205699a2dd95SBruce Richardson rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id, 205799a2dd95SBruce Richardson uint16_t nb_rx_desc, unsigned int socket_id, 205899a2dd95SBruce Richardson const struct rte_eth_rxconf *rx_conf, 205999a2dd95SBruce Richardson struct rte_mempool *mp) 206099a2dd95SBruce Richardson { 206199a2dd95SBruce Richardson int ret; 206299a2dd95SBruce Richardson uint32_t mbp_buf_size; 206399a2dd95SBruce Richardson struct rte_eth_dev *dev; 206499a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 206599a2dd95SBruce Richardson struct rte_eth_rxconf local_conf; 206699a2dd95SBruce Richardson 206799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 206899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 206953ef1b34SMin Hu (Connor) 207099a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 207109fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", rx_queue_id); 207299a2dd95SBruce Richardson return -EINVAL; 207399a2dd95SBruce Richardson } 207499a2dd95SBruce Richardson 207599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP); 207699a2dd95SBruce Richardson 207799a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 207899a2dd95SBruce Richardson if (ret != 0) 207999a2dd95SBruce Richardson return ret; 208099a2dd95SBruce Richardson 208199a2dd95SBruce Richardson if (mp != NULL) { 208299a2dd95SBruce Richardson /* Single pool configuration check. */ 208399a2dd95SBruce Richardson if (rx_conf != NULL && rx_conf->rx_nseg != 0) { 208499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 208599a2dd95SBruce Richardson "Ambiguous segment configuration\n"); 208699a2dd95SBruce Richardson return -EINVAL; 208799a2dd95SBruce Richardson } 208899a2dd95SBruce Richardson /* 208999a2dd95SBruce Richardson * Check the size of the mbuf data buffer, this value 209099a2dd95SBruce Richardson * must be provided in the private data of the memory pool. 209199a2dd95SBruce Richardson * First check that the memory pool(s) has a valid private data. 209299a2dd95SBruce Richardson */ 209399a2dd95SBruce Richardson if (mp->private_data_size < 209499a2dd95SBruce Richardson sizeof(struct rte_pktmbuf_pool_private)) { 209599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "%s private_data_size %u < %u\n", 209699a2dd95SBruce Richardson mp->name, mp->private_data_size, 209799a2dd95SBruce Richardson (unsigned int) 209899a2dd95SBruce Richardson sizeof(struct rte_pktmbuf_pool_private)); 209999a2dd95SBruce Richardson return -ENOSPC; 210099a2dd95SBruce Richardson } 210199a2dd95SBruce Richardson mbp_buf_size = rte_pktmbuf_data_room_size(mp); 210299a2dd95SBruce Richardson if (mbp_buf_size < dev_info.min_rx_bufsize + 210399a2dd95SBruce Richardson RTE_PKTMBUF_HEADROOM) { 210499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 210599a2dd95SBruce Richardson "%s mbuf_data_room_size %u < %u (RTE_PKTMBUF_HEADROOM=%u + min_rx_bufsize(dev)=%u)\n", 210699a2dd95SBruce Richardson mp->name, mbp_buf_size, 210799a2dd95SBruce Richardson RTE_PKTMBUF_HEADROOM + 210899a2dd95SBruce Richardson dev_info.min_rx_bufsize, 210999a2dd95SBruce Richardson RTE_PKTMBUF_HEADROOM, 211099a2dd95SBruce Richardson dev_info.min_rx_bufsize); 211199a2dd95SBruce Richardson return -EINVAL; 211299a2dd95SBruce Richardson } 211399a2dd95SBruce Richardson } else { 211499a2dd95SBruce Richardson const struct rte_eth_rxseg_split *rx_seg; 211599a2dd95SBruce Richardson uint16_t n_seg; 211699a2dd95SBruce Richardson 211799a2dd95SBruce Richardson /* Extended multi-segment configuration check. */ 211899a2dd95SBruce Richardson if (rx_conf == NULL || rx_conf->rx_seg == NULL || rx_conf->rx_nseg == 0) { 211999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 212099a2dd95SBruce Richardson "Memory pool is null and no extended configuration provided\n"); 212199a2dd95SBruce Richardson return -EINVAL; 212299a2dd95SBruce Richardson } 212399a2dd95SBruce Richardson 212499a2dd95SBruce Richardson rx_seg = (const struct rte_eth_rxseg_split *)rx_conf->rx_seg; 212599a2dd95SBruce Richardson n_seg = rx_conf->rx_nseg; 212699a2dd95SBruce Richardson 212799a2dd95SBruce Richardson if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) { 212899a2dd95SBruce Richardson ret = rte_eth_rx_queue_check_split(rx_seg, n_seg, 212999a2dd95SBruce Richardson &mbp_buf_size, 213099a2dd95SBruce Richardson &dev_info); 213199a2dd95SBruce Richardson if (ret != 0) 213299a2dd95SBruce Richardson return ret; 213399a2dd95SBruce Richardson } else { 213499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "No Rx segmentation offload configured\n"); 213599a2dd95SBruce Richardson return -EINVAL; 213699a2dd95SBruce Richardson } 213799a2dd95SBruce Richardson } 213899a2dd95SBruce Richardson 213999a2dd95SBruce Richardson /* Use default specified by driver, if nb_rx_desc is zero */ 214099a2dd95SBruce Richardson if (nb_rx_desc == 0) { 214199a2dd95SBruce Richardson nb_rx_desc = dev_info.default_rxportconf.ring_size; 214299a2dd95SBruce Richardson /* If driver default is also zero, fall back on EAL default */ 214399a2dd95SBruce Richardson if (nb_rx_desc == 0) 214499a2dd95SBruce Richardson nb_rx_desc = RTE_ETH_DEV_FALLBACK_RX_RINGSIZE; 214599a2dd95SBruce Richardson } 214699a2dd95SBruce Richardson 214799a2dd95SBruce Richardson if (nb_rx_desc > dev_info.rx_desc_lim.nb_max || 214899a2dd95SBruce Richardson nb_rx_desc < dev_info.rx_desc_lim.nb_min || 214999a2dd95SBruce Richardson nb_rx_desc % dev_info.rx_desc_lim.nb_align != 0) { 215099a2dd95SBruce Richardson 215199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 215299a2dd95SBruce Richardson "Invalid value for nb_rx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n", 215399a2dd95SBruce Richardson nb_rx_desc, dev_info.rx_desc_lim.nb_max, 215499a2dd95SBruce Richardson dev_info.rx_desc_lim.nb_min, 215599a2dd95SBruce Richardson dev_info.rx_desc_lim.nb_align); 215699a2dd95SBruce Richardson return -EINVAL; 215799a2dd95SBruce Richardson } 215899a2dd95SBruce Richardson 215999a2dd95SBruce Richardson if (dev->data->dev_started && 216099a2dd95SBruce Richardson !(dev_info.dev_capa & 216199a2dd95SBruce Richardson RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP)) 216299a2dd95SBruce Richardson return -EBUSY; 216399a2dd95SBruce Richardson 216499a2dd95SBruce Richardson if (dev->data->dev_started && 216599a2dd95SBruce Richardson (dev->data->rx_queue_state[rx_queue_id] != 216699a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_STOPPED)) 216799a2dd95SBruce Richardson return -EBUSY; 216899a2dd95SBruce Richardson 216949ed3224SXueming Li eth_dev_rxq_release(dev, rx_queue_id); 217099a2dd95SBruce Richardson 217199a2dd95SBruce Richardson if (rx_conf == NULL) 217299a2dd95SBruce Richardson rx_conf = &dev_info.default_rxconf; 217399a2dd95SBruce Richardson 217499a2dd95SBruce Richardson local_conf = *rx_conf; 217599a2dd95SBruce Richardson 217699a2dd95SBruce Richardson /* 217799a2dd95SBruce Richardson * If an offloading has already been enabled in 217899a2dd95SBruce Richardson * rte_eth_dev_configure(), it has been enabled on all queues, 217999a2dd95SBruce Richardson * so there is no need to enable it in this queue again. 218099a2dd95SBruce Richardson * The local_conf.offloads input to underlying PMD only carries 218199a2dd95SBruce Richardson * those offloadings which are only enabled on this queue and 218299a2dd95SBruce Richardson * not enabled on all queues. 218399a2dd95SBruce Richardson */ 218499a2dd95SBruce Richardson local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads; 218599a2dd95SBruce Richardson 218699a2dd95SBruce Richardson /* 218799a2dd95SBruce Richardson * New added offloadings for this queue are those not enabled in 218899a2dd95SBruce Richardson * rte_eth_dev_configure() and they must be per-queue type. 218999a2dd95SBruce Richardson * A pure per-port offloading can't be enabled on a queue while 219099a2dd95SBruce Richardson * disabled on another queue. A pure per-port offloading can't 219199a2dd95SBruce Richardson * be enabled for any queue as new added one if it hasn't been 219299a2dd95SBruce Richardson * enabled in rte_eth_dev_configure(). 219399a2dd95SBruce Richardson */ 219499a2dd95SBruce Richardson if ((local_conf.offloads & dev_info.rx_queue_offload_capa) != 219599a2dd95SBruce Richardson local_conf.offloads) { 219699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 219799a2dd95SBruce Richardson "Ethdev port_id=%d rx_queue_id=%d, new added offloads 0x%"PRIx64" must be " 219899a2dd95SBruce Richardson "within per-queue offload capabilities 0x%"PRIx64" in %s()\n", 219999a2dd95SBruce Richardson port_id, rx_queue_id, local_conf.offloads, 220099a2dd95SBruce Richardson dev_info.rx_queue_offload_capa, 220199a2dd95SBruce Richardson __func__); 220299a2dd95SBruce Richardson return -EINVAL; 220399a2dd95SBruce Richardson } 220499a2dd95SBruce Richardson 2205dd22740cSXueming Li if (local_conf.share_group > 0 && 2206dd22740cSXueming Li (dev_info.dev_capa & RTE_ETH_DEV_CAPA_RXQ_SHARE) == 0) { 2207dd22740cSXueming Li RTE_ETHDEV_LOG(ERR, 2208dd22740cSXueming Li "Ethdev port_id=%d rx_queue_id=%d, enabled share_group=%hu while device doesn't support Rx queue share\n", 2209dd22740cSXueming Li port_id, rx_queue_id, local_conf.share_group); 2210dd22740cSXueming Li return -EINVAL; 2211dd22740cSXueming Li } 2212dd22740cSXueming Li 221399a2dd95SBruce Richardson /* 221499a2dd95SBruce Richardson * If LRO is enabled, check that the maximum aggregated packet 221599a2dd95SBruce Richardson * size is supported by the configured device. 221699a2dd95SBruce Richardson */ 22171bb4a528SFerruh Yigit /* Get the real Ethernet overhead length */ 2218295968d1SFerruh Yigit if (local_conf.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) { 22191bb4a528SFerruh Yigit uint32_t overhead_len; 22201bb4a528SFerruh Yigit uint32_t max_rx_pktlen; 22211bb4a528SFerruh Yigit int ret; 22221bb4a528SFerruh Yigit 22231bb4a528SFerruh Yigit overhead_len = eth_dev_get_overhead_len(dev_info.max_rx_pktlen, 22241bb4a528SFerruh Yigit dev_info.max_mtu); 22251bb4a528SFerruh Yigit max_rx_pktlen = dev->data->mtu + overhead_len; 222699a2dd95SBruce Richardson if (dev->data->dev_conf.rxmode.max_lro_pkt_size == 0) 22271bb4a528SFerruh Yigit dev->data->dev_conf.rxmode.max_lro_pkt_size = max_rx_pktlen; 22281bb4a528SFerruh Yigit ret = eth_dev_check_lro_pkt_size(port_id, 222999a2dd95SBruce Richardson dev->data->dev_conf.rxmode.max_lro_pkt_size, 22301bb4a528SFerruh Yigit max_rx_pktlen, 223199a2dd95SBruce Richardson dev_info.max_lro_pkt_size); 223299a2dd95SBruce Richardson if (ret != 0) 223399a2dd95SBruce Richardson return ret; 223499a2dd95SBruce Richardson } 223599a2dd95SBruce Richardson 223699a2dd95SBruce Richardson ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc, 223799a2dd95SBruce Richardson socket_id, &local_conf, mp); 223899a2dd95SBruce Richardson if (!ret) { 223999a2dd95SBruce Richardson if (!dev->data->min_rx_buf_size || 224099a2dd95SBruce Richardson dev->data->min_rx_buf_size > mbp_buf_size) 224199a2dd95SBruce Richardson dev->data->min_rx_buf_size = mbp_buf_size; 224299a2dd95SBruce Richardson } 224399a2dd95SBruce Richardson 224499a2dd95SBruce Richardson rte_ethdev_trace_rxq_setup(port_id, rx_queue_id, nb_rx_desc, mp, 224599a2dd95SBruce Richardson rx_conf, ret); 224699a2dd95SBruce Richardson return eth_err(port_id, ret); 224799a2dd95SBruce Richardson } 224899a2dd95SBruce Richardson 224999a2dd95SBruce Richardson int 225099a2dd95SBruce Richardson rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id, 225199a2dd95SBruce Richardson uint16_t nb_rx_desc, 225299a2dd95SBruce Richardson const struct rte_eth_hairpin_conf *conf) 225399a2dd95SBruce Richardson { 225499a2dd95SBruce Richardson int ret; 225599a2dd95SBruce Richardson struct rte_eth_dev *dev; 225699a2dd95SBruce Richardson struct rte_eth_hairpin_cap cap; 225799a2dd95SBruce Richardson int i; 225899a2dd95SBruce Richardson int count; 225999a2dd95SBruce Richardson 226099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 226199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 226253ef1b34SMin Hu (Connor) 226399a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 226409fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", rx_queue_id); 226599a2dd95SBruce Richardson return -EINVAL; 226699a2dd95SBruce Richardson } 226753ef1b34SMin Hu (Connor) 226853ef1b34SMin Hu (Connor) if (conf == NULL) { 226953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 227053ef1b34SMin Hu (Connor) "Cannot setup ethdev port %u Rx hairpin queue from NULL config\n", 227153ef1b34SMin Hu (Connor) port_id); 227253ef1b34SMin Hu (Connor) return -EINVAL; 227353ef1b34SMin Hu (Connor) } 227453ef1b34SMin Hu (Connor) 227599a2dd95SBruce Richardson ret = rte_eth_dev_hairpin_capability_get(port_id, &cap); 227699a2dd95SBruce Richardson if (ret != 0) 227799a2dd95SBruce Richardson return ret; 227899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_hairpin_queue_setup, 227999a2dd95SBruce Richardson -ENOTSUP); 228099a2dd95SBruce Richardson /* if nb_rx_desc is zero use max number of desc from the driver. */ 228199a2dd95SBruce Richardson if (nb_rx_desc == 0) 228299a2dd95SBruce Richardson nb_rx_desc = cap.max_nb_desc; 228399a2dd95SBruce Richardson if (nb_rx_desc > cap.max_nb_desc) { 228499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 228599a2dd95SBruce Richardson "Invalid value for nb_rx_desc(=%hu), should be: <= %hu", 228699a2dd95SBruce Richardson nb_rx_desc, cap.max_nb_desc); 228799a2dd95SBruce Richardson return -EINVAL; 228899a2dd95SBruce Richardson } 228999a2dd95SBruce Richardson if (conf->peer_count > cap.max_rx_2_tx) { 229099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 229199a2dd95SBruce Richardson "Invalid value for number of peers for Rx queue(=%u), should be: <= %hu", 229299a2dd95SBruce Richardson conf->peer_count, cap.max_rx_2_tx); 229399a2dd95SBruce Richardson return -EINVAL; 229499a2dd95SBruce Richardson } 229599a2dd95SBruce Richardson if (conf->peer_count == 0) { 229699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 229799a2dd95SBruce Richardson "Invalid value for number of peers for Rx queue(=%u), should be: > 0", 229899a2dd95SBruce Richardson conf->peer_count); 229999a2dd95SBruce Richardson return -EINVAL; 230099a2dd95SBruce Richardson } 230199a2dd95SBruce Richardson for (i = 0, count = 0; i < dev->data->nb_rx_queues && 230299a2dd95SBruce Richardson cap.max_nb_queues != UINT16_MAX; i++) { 230399a2dd95SBruce Richardson if (i == rx_queue_id || rte_eth_dev_is_rx_hairpin_queue(dev, i)) 230499a2dd95SBruce Richardson count++; 230599a2dd95SBruce Richardson } 230699a2dd95SBruce Richardson if (count > cap.max_nb_queues) { 230799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "To many Rx hairpin queues max is %d", 230899a2dd95SBruce Richardson cap.max_nb_queues); 230999a2dd95SBruce Richardson return -EINVAL; 231099a2dd95SBruce Richardson } 231199a2dd95SBruce Richardson if (dev->data->dev_started) 231299a2dd95SBruce Richardson return -EBUSY; 231349ed3224SXueming Li eth_dev_rxq_release(dev, rx_queue_id); 231499a2dd95SBruce Richardson ret = (*dev->dev_ops->rx_hairpin_queue_setup)(dev, rx_queue_id, 231599a2dd95SBruce Richardson nb_rx_desc, conf); 231699a2dd95SBruce Richardson if (ret == 0) 231799a2dd95SBruce Richardson dev->data->rx_queue_state[rx_queue_id] = 231899a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_HAIRPIN; 231999a2dd95SBruce Richardson return eth_err(port_id, ret); 232099a2dd95SBruce Richardson } 232199a2dd95SBruce Richardson 232299a2dd95SBruce Richardson int 232399a2dd95SBruce Richardson rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id, 232499a2dd95SBruce Richardson uint16_t nb_tx_desc, unsigned int socket_id, 232599a2dd95SBruce Richardson const struct rte_eth_txconf *tx_conf) 232699a2dd95SBruce Richardson { 232799a2dd95SBruce Richardson struct rte_eth_dev *dev; 232899a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 232999a2dd95SBruce Richardson struct rte_eth_txconf local_conf; 233099a2dd95SBruce Richardson int ret; 233199a2dd95SBruce Richardson 233299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 233399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 233453ef1b34SMin Hu (Connor) 233599a2dd95SBruce Richardson if (tx_queue_id >= dev->data->nb_tx_queues) { 233609fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", tx_queue_id); 233799a2dd95SBruce Richardson return -EINVAL; 233899a2dd95SBruce Richardson } 233999a2dd95SBruce Richardson 234099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -ENOTSUP); 234199a2dd95SBruce Richardson 234299a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 234399a2dd95SBruce Richardson if (ret != 0) 234499a2dd95SBruce Richardson return ret; 234599a2dd95SBruce Richardson 234699a2dd95SBruce Richardson /* Use default specified by driver, if nb_tx_desc is zero */ 234799a2dd95SBruce Richardson if (nb_tx_desc == 0) { 234899a2dd95SBruce Richardson nb_tx_desc = dev_info.default_txportconf.ring_size; 234999a2dd95SBruce Richardson /* If driver default is zero, fall back on EAL default */ 235099a2dd95SBruce Richardson if (nb_tx_desc == 0) 235199a2dd95SBruce Richardson nb_tx_desc = RTE_ETH_DEV_FALLBACK_TX_RINGSIZE; 235299a2dd95SBruce Richardson } 235399a2dd95SBruce Richardson if (nb_tx_desc > dev_info.tx_desc_lim.nb_max || 235499a2dd95SBruce Richardson nb_tx_desc < dev_info.tx_desc_lim.nb_min || 235599a2dd95SBruce Richardson nb_tx_desc % dev_info.tx_desc_lim.nb_align != 0) { 235699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 235799a2dd95SBruce Richardson "Invalid value for nb_tx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n", 235899a2dd95SBruce Richardson nb_tx_desc, dev_info.tx_desc_lim.nb_max, 235999a2dd95SBruce Richardson dev_info.tx_desc_lim.nb_min, 236099a2dd95SBruce Richardson dev_info.tx_desc_lim.nb_align); 236199a2dd95SBruce Richardson return -EINVAL; 236299a2dd95SBruce Richardson } 236399a2dd95SBruce Richardson 236499a2dd95SBruce Richardson if (dev->data->dev_started && 236599a2dd95SBruce Richardson !(dev_info.dev_capa & 236699a2dd95SBruce Richardson RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP)) 236799a2dd95SBruce Richardson return -EBUSY; 236899a2dd95SBruce Richardson 236999a2dd95SBruce Richardson if (dev->data->dev_started && 237099a2dd95SBruce Richardson (dev->data->tx_queue_state[tx_queue_id] != 237199a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_STOPPED)) 237299a2dd95SBruce Richardson return -EBUSY; 237399a2dd95SBruce Richardson 237449ed3224SXueming Li eth_dev_txq_release(dev, tx_queue_id); 237599a2dd95SBruce Richardson 237699a2dd95SBruce Richardson if (tx_conf == NULL) 237799a2dd95SBruce Richardson tx_conf = &dev_info.default_txconf; 237899a2dd95SBruce Richardson 237999a2dd95SBruce Richardson local_conf = *tx_conf; 238099a2dd95SBruce Richardson 238199a2dd95SBruce Richardson /* 238299a2dd95SBruce Richardson * If an offloading has already been enabled in 238399a2dd95SBruce Richardson * rte_eth_dev_configure(), it has been enabled on all queues, 238499a2dd95SBruce Richardson * so there is no need to enable it in this queue again. 238599a2dd95SBruce Richardson * The local_conf.offloads input to underlying PMD only carries 238699a2dd95SBruce Richardson * those offloadings which are only enabled on this queue and 238799a2dd95SBruce Richardson * not enabled on all queues. 238899a2dd95SBruce Richardson */ 238999a2dd95SBruce Richardson local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads; 239099a2dd95SBruce Richardson 239199a2dd95SBruce Richardson /* 239299a2dd95SBruce Richardson * New added offloadings for this queue are those not enabled in 239399a2dd95SBruce Richardson * rte_eth_dev_configure() and they must be per-queue type. 239499a2dd95SBruce Richardson * A pure per-port offloading can't be enabled on a queue while 239599a2dd95SBruce Richardson * disabled on another queue. A pure per-port offloading can't 239699a2dd95SBruce Richardson * be enabled for any queue as new added one if it hasn't been 239799a2dd95SBruce Richardson * enabled in rte_eth_dev_configure(). 239899a2dd95SBruce Richardson */ 239999a2dd95SBruce Richardson if ((local_conf.offloads & dev_info.tx_queue_offload_capa) != 240099a2dd95SBruce Richardson local_conf.offloads) { 240199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 240299a2dd95SBruce Richardson "Ethdev port_id=%d tx_queue_id=%d, new added offloads 0x%"PRIx64" must be " 240399a2dd95SBruce Richardson "within per-queue offload capabilities 0x%"PRIx64" in %s()\n", 240499a2dd95SBruce Richardson port_id, tx_queue_id, local_conf.offloads, 240599a2dd95SBruce Richardson dev_info.tx_queue_offload_capa, 240699a2dd95SBruce Richardson __func__); 240799a2dd95SBruce Richardson return -EINVAL; 240899a2dd95SBruce Richardson } 240999a2dd95SBruce Richardson 241099a2dd95SBruce Richardson rte_ethdev_trace_txq_setup(port_id, tx_queue_id, nb_tx_desc, tx_conf); 241199a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev, 241299a2dd95SBruce Richardson tx_queue_id, nb_tx_desc, socket_id, &local_conf)); 241399a2dd95SBruce Richardson } 241499a2dd95SBruce Richardson 241599a2dd95SBruce Richardson int 241699a2dd95SBruce Richardson rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id, 241799a2dd95SBruce Richardson uint16_t nb_tx_desc, 241899a2dd95SBruce Richardson const struct rte_eth_hairpin_conf *conf) 241999a2dd95SBruce Richardson { 242099a2dd95SBruce Richardson struct rte_eth_dev *dev; 242199a2dd95SBruce Richardson struct rte_eth_hairpin_cap cap; 242299a2dd95SBruce Richardson int i; 242399a2dd95SBruce Richardson int count; 242499a2dd95SBruce Richardson int ret; 242599a2dd95SBruce Richardson 242699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 242799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 242853ef1b34SMin Hu (Connor) 242999a2dd95SBruce Richardson if (tx_queue_id >= dev->data->nb_tx_queues) { 243009fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", tx_queue_id); 243199a2dd95SBruce Richardson return -EINVAL; 243299a2dd95SBruce Richardson } 243353ef1b34SMin Hu (Connor) 243453ef1b34SMin Hu (Connor) if (conf == NULL) { 243553ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 243653ef1b34SMin Hu (Connor) "Cannot setup ethdev port %u Tx hairpin queue from NULL config\n", 243753ef1b34SMin Hu (Connor) port_id); 243853ef1b34SMin Hu (Connor) return -EINVAL; 243953ef1b34SMin Hu (Connor) } 244053ef1b34SMin Hu (Connor) 244199a2dd95SBruce Richardson ret = rte_eth_dev_hairpin_capability_get(port_id, &cap); 244299a2dd95SBruce Richardson if (ret != 0) 244399a2dd95SBruce Richardson return ret; 244499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_hairpin_queue_setup, 244599a2dd95SBruce Richardson -ENOTSUP); 244699a2dd95SBruce Richardson /* if nb_rx_desc is zero use max number of desc from the driver. */ 244799a2dd95SBruce Richardson if (nb_tx_desc == 0) 244899a2dd95SBruce Richardson nb_tx_desc = cap.max_nb_desc; 244999a2dd95SBruce Richardson if (nb_tx_desc > cap.max_nb_desc) { 245099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 245199a2dd95SBruce Richardson "Invalid value for nb_tx_desc(=%hu), should be: <= %hu", 245299a2dd95SBruce Richardson nb_tx_desc, cap.max_nb_desc); 245399a2dd95SBruce Richardson return -EINVAL; 245499a2dd95SBruce Richardson } 245599a2dd95SBruce Richardson if (conf->peer_count > cap.max_tx_2_rx) { 245699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 245799a2dd95SBruce Richardson "Invalid value for number of peers for Tx queue(=%u), should be: <= %hu", 245899a2dd95SBruce Richardson conf->peer_count, cap.max_tx_2_rx); 245999a2dd95SBruce Richardson return -EINVAL; 246099a2dd95SBruce Richardson } 246199a2dd95SBruce Richardson if (conf->peer_count == 0) { 246299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 246399a2dd95SBruce Richardson "Invalid value for number of peers for Tx queue(=%u), should be: > 0", 246499a2dd95SBruce Richardson conf->peer_count); 246599a2dd95SBruce Richardson return -EINVAL; 246699a2dd95SBruce Richardson } 246799a2dd95SBruce Richardson for (i = 0, count = 0; i < dev->data->nb_tx_queues && 246899a2dd95SBruce Richardson cap.max_nb_queues != UINT16_MAX; i++) { 246999a2dd95SBruce Richardson if (i == tx_queue_id || rte_eth_dev_is_tx_hairpin_queue(dev, i)) 247099a2dd95SBruce Richardson count++; 247199a2dd95SBruce Richardson } 247299a2dd95SBruce Richardson if (count > cap.max_nb_queues) { 247399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "To many Tx hairpin queues max is %d", 247499a2dd95SBruce Richardson cap.max_nb_queues); 247599a2dd95SBruce Richardson return -EINVAL; 247699a2dd95SBruce Richardson } 247799a2dd95SBruce Richardson if (dev->data->dev_started) 247899a2dd95SBruce Richardson return -EBUSY; 247949ed3224SXueming Li eth_dev_txq_release(dev, tx_queue_id); 248099a2dd95SBruce Richardson ret = (*dev->dev_ops->tx_hairpin_queue_setup) 248199a2dd95SBruce Richardson (dev, tx_queue_id, nb_tx_desc, conf); 248299a2dd95SBruce Richardson if (ret == 0) 248399a2dd95SBruce Richardson dev->data->tx_queue_state[tx_queue_id] = 248499a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_HAIRPIN; 248599a2dd95SBruce Richardson return eth_err(port_id, ret); 248699a2dd95SBruce Richardson } 248799a2dd95SBruce Richardson 248899a2dd95SBruce Richardson int 248999a2dd95SBruce Richardson rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port) 249099a2dd95SBruce Richardson { 249199a2dd95SBruce Richardson struct rte_eth_dev *dev; 249299a2dd95SBruce Richardson int ret; 249399a2dd95SBruce Richardson 249499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV); 249599a2dd95SBruce Richardson dev = &rte_eth_devices[tx_port]; 249653ef1b34SMin Hu (Connor) 249799a2dd95SBruce Richardson if (dev->data->dev_started == 0) { 249899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Tx port %d is not started\n", tx_port); 249999a2dd95SBruce Richardson return -EBUSY; 250099a2dd95SBruce Richardson } 250199a2dd95SBruce Richardson 250299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_bind, -ENOTSUP); 250399a2dd95SBruce Richardson ret = (*dev->dev_ops->hairpin_bind)(dev, rx_port); 250499a2dd95SBruce Richardson if (ret != 0) 250599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Failed to bind hairpin Tx %d" 250699a2dd95SBruce Richardson " to Rx %d (%d - all ports)\n", 250799a2dd95SBruce Richardson tx_port, rx_port, RTE_MAX_ETHPORTS); 250899a2dd95SBruce Richardson 250999a2dd95SBruce Richardson return ret; 251099a2dd95SBruce Richardson } 251199a2dd95SBruce Richardson 251299a2dd95SBruce Richardson int 251399a2dd95SBruce Richardson rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port) 251499a2dd95SBruce Richardson { 251599a2dd95SBruce Richardson struct rte_eth_dev *dev; 251699a2dd95SBruce Richardson int ret; 251799a2dd95SBruce Richardson 251899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV); 251999a2dd95SBruce Richardson dev = &rte_eth_devices[tx_port]; 252053ef1b34SMin Hu (Connor) 252199a2dd95SBruce Richardson if (dev->data->dev_started == 0) { 252299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Tx port %d is already stopped\n", tx_port); 252399a2dd95SBruce Richardson return -EBUSY; 252499a2dd95SBruce Richardson } 252599a2dd95SBruce Richardson 252699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_unbind, -ENOTSUP); 252799a2dd95SBruce Richardson ret = (*dev->dev_ops->hairpin_unbind)(dev, rx_port); 252899a2dd95SBruce Richardson if (ret != 0) 252999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Failed to unbind hairpin Tx %d" 253099a2dd95SBruce Richardson " from Rx %d (%d - all ports)\n", 253199a2dd95SBruce Richardson tx_port, rx_port, RTE_MAX_ETHPORTS); 253299a2dd95SBruce Richardson 253399a2dd95SBruce Richardson return ret; 253499a2dd95SBruce Richardson } 253599a2dd95SBruce Richardson 253699a2dd95SBruce Richardson int 253799a2dd95SBruce Richardson rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports, 253899a2dd95SBruce Richardson size_t len, uint32_t direction) 253999a2dd95SBruce Richardson { 254099a2dd95SBruce Richardson struct rte_eth_dev *dev; 254199a2dd95SBruce Richardson int ret; 254299a2dd95SBruce Richardson 254399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 254499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 254553ef1b34SMin Hu (Connor) 254653ef1b34SMin Hu (Connor) if (peer_ports == NULL) { 254753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 254853ef1b34SMin Hu (Connor) "Cannot get ethdev port %u hairpin peer ports to NULL\n", 254953ef1b34SMin Hu (Connor) port_id); 255053ef1b34SMin Hu (Connor) return -EINVAL; 255153ef1b34SMin Hu (Connor) } 255253ef1b34SMin Hu (Connor) 255353ef1b34SMin Hu (Connor) if (len == 0) { 255453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 255553ef1b34SMin Hu (Connor) "Cannot get ethdev port %u hairpin peer ports to array with zero size\n", 255653ef1b34SMin Hu (Connor) port_id); 255753ef1b34SMin Hu (Connor) return -EINVAL; 255853ef1b34SMin Hu (Connor) } 255953ef1b34SMin Hu (Connor) 256099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_get_peer_ports, 256199a2dd95SBruce Richardson -ENOTSUP); 256299a2dd95SBruce Richardson 256399a2dd95SBruce Richardson ret = (*dev->dev_ops->hairpin_get_peer_ports)(dev, peer_ports, 256499a2dd95SBruce Richardson len, direction); 256599a2dd95SBruce Richardson if (ret < 0) 256699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Failed to get %d hairpin peer %s ports\n", 256799a2dd95SBruce Richardson port_id, direction ? "Rx" : "Tx"); 256899a2dd95SBruce Richardson 256999a2dd95SBruce Richardson return ret; 257099a2dd95SBruce Richardson } 257199a2dd95SBruce Richardson 257299a2dd95SBruce Richardson void 257399a2dd95SBruce Richardson rte_eth_tx_buffer_drop_callback(struct rte_mbuf **pkts, uint16_t unsent, 257499a2dd95SBruce Richardson void *userdata __rte_unused) 257599a2dd95SBruce Richardson { 257699a2dd95SBruce Richardson rte_pktmbuf_free_bulk(pkts, unsent); 257799a2dd95SBruce Richardson } 257899a2dd95SBruce Richardson 257999a2dd95SBruce Richardson void 258099a2dd95SBruce Richardson rte_eth_tx_buffer_count_callback(struct rte_mbuf **pkts, uint16_t unsent, 258199a2dd95SBruce Richardson void *userdata) 258299a2dd95SBruce Richardson { 258399a2dd95SBruce Richardson uint64_t *count = userdata; 258499a2dd95SBruce Richardson 258599a2dd95SBruce Richardson rte_pktmbuf_free_bulk(pkts, unsent); 258699a2dd95SBruce Richardson *count += unsent; 258799a2dd95SBruce Richardson } 258899a2dd95SBruce Richardson 258999a2dd95SBruce Richardson int 259099a2dd95SBruce Richardson rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer, 259199a2dd95SBruce Richardson buffer_tx_error_fn cbfn, void *userdata) 259299a2dd95SBruce Richardson { 259353ef1b34SMin Hu (Connor) if (buffer == NULL) { 259453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 259553ef1b34SMin Hu (Connor) "Cannot set Tx buffer error callback to NULL buffer\n"); 259653ef1b34SMin Hu (Connor) return -EINVAL; 259753ef1b34SMin Hu (Connor) } 259853ef1b34SMin Hu (Connor) 259999a2dd95SBruce Richardson buffer->error_callback = cbfn; 260099a2dd95SBruce Richardson buffer->error_userdata = userdata; 260199a2dd95SBruce Richardson return 0; 260299a2dd95SBruce Richardson } 260399a2dd95SBruce Richardson 260499a2dd95SBruce Richardson int 260599a2dd95SBruce Richardson rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size) 260699a2dd95SBruce Richardson { 260799a2dd95SBruce Richardson int ret = 0; 260899a2dd95SBruce Richardson 260953ef1b34SMin Hu (Connor) if (buffer == NULL) { 261053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot initialize NULL buffer\n"); 261199a2dd95SBruce Richardson return -EINVAL; 261253ef1b34SMin Hu (Connor) } 261399a2dd95SBruce Richardson 261499a2dd95SBruce Richardson buffer->size = size; 261599a2dd95SBruce Richardson if (buffer->error_callback == NULL) { 261699a2dd95SBruce Richardson ret = rte_eth_tx_buffer_set_err_callback( 261799a2dd95SBruce Richardson buffer, rte_eth_tx_buffer_drop_callback, NULL); 261899a2dd95SBruce Richardson } 261999a2dd95SBruce Richardson 262099a2dd95SBruce Richardson return ret; 262199a2dd95SBruce Richardson } 262299a2dd95SBruce Richardson 262399a2dd95SBruce Richardson int 262499a2dd95SBruce Richardson rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt) 262599a2dd95SBruce Richardson { 262653ef1b34SMin Hu (Connor) struct rte_eth_dev *dev; 262799a2dd95SBruce Richardson int ret; 262899a2dd95SBruce Richardson 262999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 263053ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 263153ef1b34SMin Hu (Connor) 263299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP); 263399a2dd95SBruce Richardson 263499a2dd95SBruce Richardson /* Call driver to free pending mbufs. */ 263599a2dd95SBruce Richardson ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id], 263699a2dd95SBruce Richardson free_cnt); 263799a2dd95SBruce Richardson return eth_err(port_id, ret); 263899a2dd95SBruce Richardson } 263999a2dd95SBruce Richardson 264099a2dd95SBruce Richardson int 264199a2dd95SBruce Richardson rte_eth_promiscuous_enable(uint16_t port_id) 264299a2dd95SBruce Richardson { 264399a2dd95SBruce Richardson struct rte_eth_dev *dev; 264499a2dd95SBruce Richardson int diag = 0; 264599a2dd95SBruce Richardson 264699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 264799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 264899a2dd95SBruce Richardson 264999a2dd95SBruce Richardson if (dev->data->promiscuous == 1) 265099a2dd95SBruce Richardson return 0; 265199a2dd95SBruce Richardson 265299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_enable, -ENOTSUP); 265399a2dd95SBruce Richardson 265499a2dd95SBruce Richardson diag = (*dev->dev_ops->promiscuous_enable)(dev); 265599a2dd95SBruce Richardson dev->data->promiscuous = (diag == 0) ? 1 : 0; 265699a2dd95SBruce Richardson 265799a2dd95SBruce Richardson return eth_err(port_id, diag); 265899a2dd95SBruce Richardson } 265999a2dd95SBruce Richardson 266099a2dd95SBruce Richardson int 266199a2dd95SBruce Richardson rte_eth_promiscuous_disable(uint16_t port_id) 266299a2dd95SBruce Richardson { 266399a2dd95SBruce Richardson struct rte_eth_dev *dev; 266499a2dd95SBruce Richardson int diag = 0; 266599a2dd95SBruce Richardson 266699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 266799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 266899a2dd95SBruce Richardson 266999a2dd95SBruce Richardson if (dev->data->promiscuous == 0) 267099a2dd95SBruce Richardson return 0; 267199a2dd95SBruce Richardson 267299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_disable, -ENOTSUP); 267399a2dd95SBruce Richardson 267499a2dd95SBruce Richardson dev->data->promiscuous = 0; 267599a2dd95SBruce Richardson diag = (*dev->dev_ops->promiscuous_disable)(dev); 267699a2dd95SBruce Richardson if (diag != 0) 267799a2dd95SBruce Richardson dev->data->promiscuous = 1; 267899a2dd95SBruce Richardson 267999a2dd95SBruce Richardson return eth_err(port_id, diag); 268099a2dd95SBruce Richardson } 268199a2dd95SBruce Richardson 268299a2dd95SBruce Richardson int 268399a2dd95SBruce Richardson rte_eth_promiscuous_get(uint16_t port_id) 268499a2dd95SBruce Richardson { 268599a2dd95SBruce Richardson struct rte_eth_dev *dev; 268699a2dd95SBruce Richardson 268799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 268899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 268953ef1b34SMin Hu (Connor) 269099a2dd95SBruce Richardson return dev->data->promiscuous; 269199a2dd95SBruce Richardson } 269299a2dd95SBruce Richardson 269399a2dd95SBruce Richardson int 269499a2dd95SBruce Richardson rte_eth_allmulticast_enable(uint16_t port_id) 269599a2dd95SBruce Richardson { 269699a2dd95SBruce Richardson struct rte_eth_dev *dev; 269799a2dd95SBruce Richardson int diag; 269899a2dd95SBruce Richardson 269999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 270099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 270199a2dd95SBruce Richardson 270299a2dd95SBruce Richardson if (dev->data->all_multicast == 1) 270399a2dd95SBruce Richardson return 0; 270499a2dd95SBruce Richardson 270599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_enable, -ENOTSUP); 270699a2dd95SBruce Richardson diag = (*dev->dev_ops->allmulticast_enable)(dev); 270799a2dd95SBruce Richardson dev->data->all_multicast = (diag == 0) ? 1 : 0; 270899a2dd95SBruce Richardson 270999a2dd95SBruce Richardson return eth_err(port_id, diag); 271099a2dd95SBruce Richardson } 271199a2dd95SBruce Richardson 271299a2dd95SBruce Richardson int 271399a2dd95SBruce Richardson rte_eth_allmulticast_disable(uint16_t port_id) 271499a2dd95SBruce Richardson { 271599a2dd95SBruce Richardson struct rte_eth_dev *dev; 271699a2dd95SBruce Richardson int diag; 271799a2dd95SBruce Richardson 271899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 271999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 272099a2dd95SBruce Richardson 272199a2dd95SBruce Richardson if (dev->data->all_multicast == 0) 272299a2dd95SBruce Richardson return 0; 272399a2dd95SBruce Richardson 272499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_disable, -ENOTSUP); 272599a2dd95SBruce Richardson dev->data->all_multicast = 0; 272699a2dd95SBruce Richardson diag = (*dev->dev_ops->allmulticast_disable)(dev); 272799a2dd95SBruce Richardson if (diag != 0) 272899a2dd95SBruce Richardson dev->data->all_multicast = 1; 272999a2dd95SBruce Richardson 273099a2dd95SBruce Richardson return eth_err(port_id, diag); 273199a2dd95SBruce Richardson } 273299a2dd95SBruce Richardson 273399a2dd95SBruce Richardson int 273499a2dd95SBruce Richardson rte_eth_allmulticast_get(uint16_t port_id) 273599a2dd95SBruce Richardson { 273699a2dd95SBruce Richardson struct rte_eth_dev *dev; 273799a2dd95SBruce Richardson 273899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 273999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 274053ef1b34SMin Hu (Connor) 274199a2dd95SBruce Richardson return dev->data->all_multicast; 274299a2dd95SBruce Richardson } 274399a2dd95SBruce Richardson 274499a2dd95SBruce Richardson int 274599a2dd95SBruce Richardson rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link) 274699a2dd95SBruce Richardson { 274799a2dd95SBruce Richardson struct rte_eth_dev *dev; 274899a2dd95SBruce Richardson 274999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 275099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 275199a2dd95SBruce Richardson 275253ef1b34SMin Hu (Connor) if (eth_link == NULL) { 275353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u link to NULL\n", 275453ef1b34SMin Hu (Connor) port_id); 275553ef1b34SMin Hu (Connor) return -EINVAL; 275653ef1b34SMin Hu (Connor) } 275753ef1b34SMin Hu (Connor) 275853ef1b34SMin Hu (Connor) if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started) 275999a2dd95SBruce Richardson rte_eth_linkstatus_get(dev, eth_link); 276099a2dd95SBruce Richardson else { 276199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP); 276299a2dd95SBruce Richardson (*dev->dev_ops->link_update)(dev, 1); 276399a2dd95SBruce Richardson *eth_link = dev->data->dev_link; 276499a2dd95SBruce Richardson } 276599a2dd95SBruce Richardson 276699a2dd95SBruce Richardson return 0; 276799a2dd95SBruce Richardson } 276899a2dd95SBruce Richardson 276999a2dd95SBruce Richardson int 277099a2dd95SBruce Richardson rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link) 277199a2dd95SBruce Richardson { 277299a2dd95SBruce Richardson struct rte_eth_dev *dev; 277399a2dd95SBruce Richardson 277499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 277599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 277699a2dd95SBruce Richardson 277753ef1b34SMin Hu (Connor) if (eth_link == NULL) { 277853ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u link to NULL\n", 277953ef1b34SMin Hu (Connor) port_id); 278053ef1b34SMin Hu (Connor) return -EINVAL; 278153ef1b34SMin Hu (Connor) } 278253ef1b34SMin Hu (Connor) 278353ef1b34SMin Hu (Connor) if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started) 278499a2dd95SBruce Richardson rte_eth_linkstatus_get(dev, eth_link); 278599a2dd95SBruce Richardson else { 278699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP); 278799a2dd95SBruce Richardson (*dev->dev_ops->link_update)(dev, 0); 278899a2dd95SBruce Richardson *eth_link = dev->data->dev_link; 278999a2dd95SBruce Richardson } 279099a2dd95SBruce Richardson 279199a2dd95SBruce Richardson return 0; 279299a2dd95SBruce Richardson } 279399a2dd95SBruce Richardson 279499a2dd95SBruce Richardson const char * 279599a2dd95SBruce Richardson rte_eth_link_speed_to_str(uint32_t link_speed) 279699a2dd95SBruce Richardson { 279799a2dd95SBruce Richardson switch (link_speed) { 2798295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_NONE: return "None"; 2799295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_10M: return "10 Mbps"; 2800295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_100M: return "100 Mbps"; 2801295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_1G: return "1 Gbps"; 2802295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_2_5G: return "2.5 Gbps"; 2803295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_5G: return "5 Gbps"; 2804295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_10G: return "10 Gbps"; 2805295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_20G: return "20 Gbps"; 2806295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_25G: return "25 Gbps"; 2807295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_40G: return "40 Gbps"; 2808295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_50G: return "50 Gbps"; 2809295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_56G: return "56 Gbps"; 2810295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_100G: return "100 Gbps"; 2811295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_200G: return "200 Gbps"; 2812295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_UNKNOWN: return "Unknown"; 281399a2dd95SBruce Richardson default: return "Invalid"; 281499a2dd95SBruce Richardson } 281599a2dd95SBruce Richardson } 281699a2dd95SBruce Richardson 281799a2dd95SBruce Richardson int 281899a2dd95SBruce Richardson rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link) 281999a2dd95SBruce Richardson { 282053ef1b34SMin Hu (Connor) if (str == NULL) { 282153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot convert link to NULL string\n"); 282253ef1b34SMin Hu (Connor) return -EINVAL; 282353ef1b34SMin Hu (Connor) } 282453ef1b34SMin Hu (Connor) 282553ef1b34SMin Hu (Connor) if (len == 0) { 282653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 282753ef1b34SMin Hu (Connor) "Cannot convert link to string with zero size\n"); 282853ef1b34SMin Hu (Connor) return -EINVAL; 282953ef1b34SMin Hu (Connor) } 283053ef1b34SMin Hu (Connor) 283153ef1b34SMin Hu (Connor) if (eth_link == NULL) { 283253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot convert to string from NULL link\n"); 283353ef1b34SMin Hu (Connor) return -EINVAL; 283453ef1b34SMin Hu (Connor) } 283553ef1b34SMin Hu (Connor) 2836295968d1SFerruh Yigit if (eth_link->link_status == RTE_ETH_LINK_DOWN) 283799a2dd95SBruce Richardson return snprintf(str, len, "Link down"); 283899a2dd95SBruce Richardson else 283999a2dd95SBruce Richardson return snprintf(str, len, "Link up at %s %s %s", 284099a2dd95SBruce Richardson rte_eth_link_speed_to_str(eth_link->link_speed), 2841295968d1SFerruh Yigit (eth_link->link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ? 284299a2dd95SBruce Richardson "FDX" : "HDX", 2843295968d1SFerruh Yigit (eth_link->link_autoneg == RTE_ETH_LINK_AUTONEG) ? 284499a2dd95SBruce Richardson "Autoneg" : "Fixed"); 284599a2dd95SBruce Richardson } 284699a2dd95SBruce Richardson 284799a2dd95SBruce Richardson int 284899a2dd95SBruce Richardson rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats) 284999a2dd95SBruce Richardson { 285099a2dd95SBruce Richardson struct rte_eth_dev *dev; 285199a2dd95SBruce Richardson 285299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 285399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 285453ef1b34SMin Hu (Connor) 285553ef1b34SMin Hu (Connor) if (stats == NULL) { 285653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u stats to NULL\n", 285753ef1b34SMin Hu (Connor) port_id); 285853ef1b34SMin Hu (Connor) return -EINVAL; 285953ef1b34SMin Hu (Connor) } 286053ef1b34SMin Hu (Connor) 286199a2dd95SBruce Richardson memset(stats, 0, sizeof(*stats)); 286299a2dd95SBruce Richardson 286399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP); 286499a2dd95SBruce Richardson stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed; 286599a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->stats_get)(dev, stats)); 286699a2dd95SBruce Richardson } 286799a2dd95SBruce Richardson 286899a2dd95SBruce Richardson int 286999a2dd95SBruce Richardson rte_eth_stats_reset(uint16_t port_id) 287099a2dd95SBruce Richardson { 287199a2dd95SBruce Richardson struct rte_eth_dev *dev; 287299a2dd95SBruce Richardson int ret; 287399a2dd95SBruce Richardson 287499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 287599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 287699a2dd95SBruce Richardson 287799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_reset, -ENOTSUP); 287899a2dd95SBruce Richardson ret = (*dev->dev_ops->stats_reset)(dev); 287999a2dd95SBruce Richardson if (ret != 0) 288099a2dd95SBruce Richardson return eth_err(port_id, ret); 288199a2dd95SBruce Richardson 288299a2dd95SBruce Richardson dev->data->rx_mbuf_alloc_failed = 0; 288399a2dd95SBruce Richardson 288499a2dd95SBruce Richardson return 0; 288599a2dd95SBruce Richardson } 288699a2dd95SBruce Richardson 288799a2dd95SBruce Richardson static inline int 288899a2dd95SBruce Richardson eth_dev_get_xstats_basic_count(struct rte_eth_dev *dev) 288999a2dd95SBruce Richardson { 289099a2dd95SBruce Richardson uint16_t nb_rxqs, nb_txqs; 289199a2dd95SBruce Richardson int count; 289299a2dd95SBruce Richardson 289399a2dd95SBruce Richardson nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 289499a2dd95SBruce Richardson nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 289599a2dd95SBruce Richardson 289699a2dd95SBruce Richardson count = RTE_NB_STATS; 289799a2dd95SBruce Richardson if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) { 289899a2dd95SBruce Richardson count += nb_rxqs * RTE_NB_RXQ_STATS; 289999a2dd95SBruce Richardson count += nb_txqs * RTE_NB_TXQ_STATS; 290099a2dd95SBruce Richardson } 290199a2dd95SBruce Richardson 290299a2dd95SBruce Richardson return count; 290399a2dd95SBruce Richardson } 290499a2dd95SBruce Richardson 290599a2dd95SBruce Richardson static int 290699a2dd95SBruce Richardson eth_dev_get_xstats_count(uint16_t port_id) 290799a2dd95SBruce Richardson { 290899a2dd95SBruce Richardson struct rte_eth_dev *dev; 290999a2dd95SBruce Richardson int count; 291099a2dd95SBruce Richardson 291199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 291299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 291399a2dd95SBruce Richardson if (dev->dev_ops->xstats_get_names != NULL) { 291499a2dd95SBruce Richardson count = (*dev->dev_ops->xstats_get_names)(dev, NULL, 0); 291599a2dd95SBruce Richardson if (count < 0) 291699a2dd95SBruce Richardson return eth_err(port_id, count); 291799a2dd95SBruce Richardson } else 291899a2dd95SBruce Richardson count = 0; 291999a2dd95SBruce Richardson 292099a2dd95SBruce Richardson 292199a2dd95SBruce Richardson count += eth_dev_get_xstats_basic_count(dev); 292299a2dd95SBruce Richardson 292399a2dd95SBruce Richardson return count; 292499a2dd95SBruce Richardson } 292599a2dd95SBruce Richardson 292699a2dd95SBruce Richardson int 292799a2dd95SBruce Richardson rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name, 292899a2dd95SBruce Richardson uint64_t *id) 292999a2dd95SBruce Richardson { 293099a2dd95SBruce Richardson int cnt_xstats, idx_xstat; 293199a2dd95SBruce Richardson 293299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 293399a2dd95SBruce Richardson 293453ef1b34SMin Hu (Connor) if (xstat_name == NULL) { 293553ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 293653ef1b34SMin Hu (Connor) "Cannot get ethdev port %u xstats ID from NULL xstat name\n", 293753ef1b34SMin Hu (Connor) port_id); 293899a2dd95SBruce Richardson return -ENOMEM; 293999a2dd95SBruce Richardson } 294099a2dd95SBruce Richardson 294153ef1b34SMin Hu (Connor) if (id == NULL) { 294253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 294353ef1b34SMin Hu (Connor) "Cannot get ethdev port %u xstats ID to NULL\n", 294453ef1b34SMin Hu (Connor) port_id); 294599a2dd95SBruce Richardson return -ENOMEM; 294699a2dd95SBruce Richardson } 294799a2dd95SBruce Richardson 294899a2dd95SBruce Richardson /* Get count */ 294999a2dd95SBruce Richardson cnt_xstats = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL); 295099a2dd95SBruce Richardson if (cnt_xstats < 0) { 295199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Cannot get count of xstats\n"); 295299a2dd95SBruce Richardson return -ENODEV; 295399a2dd95SBruce Richardson } 295499a2dd95SBruce Richardson 295599a2dd95SBruce Richardson /* Get id-name lookup table */ 295699a2dd95SBruce Richardson struct rte_eth_xstat_name xstats_names[cnt_xstats]; 295799a2dd95SBruce Richardson 295899a2dd95SBruce Richardson if (cnt_xstats != rte_eth_xstats_get_names_by_id( 295999a2dd95SBruce Richardson port_id, xstats_names, cnt_xstats, NULL)) { 296099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Cannot get xstats lookup\n"); 296199a2dd95SBruce Richardson return -1; 296299a2dd95SBruce Richardson } 296399a2dd95SBruce Richardson 296499a2dd95SBruce Richardson for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) { 296599a2dd95SBruce Richardson if (!strcmp(xstats_names[idx_xstat].name, xstat_name)) { 296699a2dd95SBruce Richardson *id = idx_xstat; 296799a2dd95SBruce Richardson return 0; 296899a2dd95SBruce Richardson }; 296999a2dd95SBruce Richardson } 297099a2dd95SBruce Richardson 297199a2dd95SBruce Richardson return -EINVAL; 297299a2dd95SBruce Richardson } 297399a2dd95SBruce Richardson 297499a2dd95SBruce Richardson /* retrieve basic stats names */ 297599a2dd95SBruce Richardson static int 297699a2dd95SBruce Richardson eth_basic_stats_get_names(struct rte_eth_dev *dev, 297799a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names) 297899a2dd95SBruce Richardson { 297999a2dd95SBruce Richardson int cnt_used_entries = 0; 298099a2dd95SBruce Richardson uint32_t idx, id_queue; 298199a2dd95SBruce Richardson uint16_t num_q; 298299a2dd95SBruce Richardson 298399a2dd95SBruce Richardson for (idx = 0; idx < RTE_NB_STATS; idx++) { 298499a2dd95SBruce Richardson strlcpy(xstats_names[cnt_used_entries].name, 298599a2dd95SBruce Richardson eth_dev_stats_strings[idx].name, 298699a2dd95SBruce Richardson sizeof(xstats_names[0].name)); 298799a2dd95SBruce Richardson cnt_used_entries++; 298899a2dd95SBruce Richardson } 298999a2dd95SBruce Richardson 299099a2dd95SBruce Richardson if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0) 299199a2dd95SBruce Richardson return cnt_used_entries; 299299a2dd95SBruce Richardson 299399a2dd95SBruce Richardson num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 299499a2dd95SBruce Richardson for (id_queue = 0; id_queue < num_q; id_queue++) { 299599a2dd95SBruce Richardson for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) { 299699a2dd95SBruce Richardson snprintf(xstats_names[cnt_used_entries].name, 299799a2dd95SBruce Richardson sizeof(xstats_names[0].name), 299899a2dd95SBruce Richardson "rx_q%u_%s", 299999a2dd95SBruce Richardson id_queue, eth_dev_rxq_stats_strings[idx].name); 300099a2dd95SBruce Richardson cnt_used_entries++; 300199a2dd95SBruce Richardson } 300299a2dd95SBruce Richardson 300399a2dd95SBruce Richardson } 300499a2dd95SBruce Richardson num_q = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 300599a2dd95SBruce Richardson for (id_queue = 0; id_queue < num_q; id_queue++) { 300699a2dd95SBruce Richardson for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) { 300799a2dd95SBruce Richardson snprintf(xstats_names[cnt_used_entries].name, 300899a2dd95SBruce Richardson sizeof(xstats_names[0].name), 300999a2dd95SBruce Richardson "tx_q%u_%s", 301099a2dd95SBruce Richardson id_queue, eth_dev_txq_stats_strings[idx].name); 301199a2dd95SBruce Richardson cnt_used_entries++; 301299a2dd95SBruce Richardson } 301399a2dd95SBruce Richardson } 301499a2dd95SBruce Richardson return cnt_used_entries; 301599a2dd95SBruce Richardson } 301699a2dd95SBruce Richardson 301799a2dd95SBruce Richardson /* retrieve ethdev extended statistics names */ 301899a2dd95SBruce Richardson int 301999a2dd95SBruce Richardson rte_eth_xstats_get_names_by_id(uint16_t port_id, 302099a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names, unsigned int size, 302199a2dd95SBruce Richardson uint64_t *ids) 302299a2dd95SBruce Richardson { 302399a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names_copy; 302499a2dd95SBruce Richardson unsigned int no_basic_stat_requested = 1; 302599a2dd95SBruce Richardson unsigned int no_ext_stat_requested = 1; 302699a2dd95SBruce Richardson unsigned int expected_entries; 302799a2dd95SBruce Richardson unsigned int basic_count; 302899a2dd95SBruce Richardson struct rte_eth_dev *dev; 302999a2dd95SBruce Richardson unsigned int i; 303099a2dd95SBruce Richardson int ret; 303199a2dd95SBruce Richardson 303299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 303399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 303499a2dd95SBruce Richardson 303599a2dd95SBruce Richardson basic_count = eth_dev_get_xstats_basic_count(dev); 303699a2dd95SBruce Richardson ret = eth_dev_get_xstats_count(port_id); 303799a2dd95SBruce Richardson if (ret < 0) 303899a2dd95SBruce Richardson return ret; 303999a2dd95SBruce Richardson expected_entries = (unsigned int)ret; 304099a2dd95SBruce Richardson 304199a2dd95SBruce Richardson /* Return max number of stats if no ids given */ 304299a2dd95SBruce Richardson if (!ids) { 304399a2dd95SBruce Richardson if (!xstats_names) 304499a2dd95SBruce Richardson return expected_entries; 304599a2dd95SBruce Richardson else if (xstats_names && size < expected_entries) 304699a2dd95SBruce Richardson return expected_entries; 304799a2dd95SBruce Richardson } 304899a2dd95SBruce Richardson 304999a2dd95SBruce Richardson if (ids && !xstats_names) 305099a2dd95SBruce Richardson return -EINVAL; 305199a2dd95SBruce Richardson 305299a2dd95SBruce Richardson if (ids && dev->dev_ops->xstats_get_names_by_id != NULL && size > 0) { 305399a2dd95SBruce Richardson uint64_t ids_copy[size]; 305499a2dd95SBruce Richardson 305599a2dd95SBruce Richardson for (i = 0; i < size; i++) { 305699a2dd95SBruce Richardson if (ids[i] < basic_count) { 305799a2dd95SBruce Richardson no_basic_stat_requested = 0; 305899a2dd95SBruce Richardson break; 305999a2dd95SBruce Richardson } 306099a2dd95SBruce Richardson 306199a2dd95SBruce Richardson /* 306299a2dd95SBruce Richardson * Convert ids to xstats ids that PMD knows. 306399a2dd95SBruce Richardson * ids known by user are basic + extended stats. 306499a2dd95SBruce Richardson */ 306599a2dd95SBruce Richardson ids_copy[i] = ids[i] - basic_count; 306699a2dd95SBruce Richardson } 306799a2dd95SBruce Richardson 306899a2dd95SBruce Richardson if (no_basic_stat_requested) 306999a2dd95SBruce Richardson return (*dev->dev_ops->xstats_get_names_by_id)(dev, 30708c9f976fSAndrew Rybchenko ids_copy, xstats_names, size); 307199a2dd95SBruce Richardson } 307299a2dd95SBruce Richardson 307399a2dd95SBruce Richardson /* Retrieve all stats */ 307499a2dd95SBruce Richardson if (!ids) { 307599a2dd95SBruce Richardson int num_stats = rte_eth_xstats_get_names(port_id, xstats_names, 307699a2dd95SBruce Richardson expected_entries); 307799a2dd95SBruce Richardson if (num_stats < 0 || num_stats > (int)expected_entries) 307899a2dd95SBruce Richardson return num_stats; 307999a2dd95SBruce Richardson else 308099a2dd95SBruce Richardson return expected_entries; 308199a2dd95SBruce Richardson } 308299a2dd95SBruce Richardson 308399a2dd95SBruce Richardson xstats_names_copy = calloc(expected_entries, 308499a2dd95SBruce Richardson sizeof(struct rte_eth_xstat_name)); 308599a2dd95SBruce Richardson 308699a2dd95SBruce Richardson if (!xstats_names_copy) { 308799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Can't allocate memory\n"); 308899a2dd95SBruce Richardson return -ENOMEM; 308999a2dd95SBruce Richardson } 309099a2dd95SBruce Richardson 309199a2dd95SBruce Richardson if (ids) { 309299a2dd95SBruce Richardson for (i = 0; i < size; i++) { 309399a2dd95SBruce Richardson if (ids[i] >= basic_count) { 309499a2dd95SBruce Richardson no_ext_stat_requested = 0; 309599a2dd95SBruce Richardson break; 309699a2dd95SBruce Richardson } 309799a2dd95SBruce Richardson } 309899a2dd95SBruce Richardson } 309999a2dd95SBruce Richardson 310099a2dd95SBruce Richardson /* Fill xstats_names_copy structure */ 310199a2dd95SBruce Richardson if (ids && no_ext_stat_requested) { 310299a2dd95SBruce Richardson eth_basic_stats_get_names(dev, xstats_names_copy); 310399a2dd95SBruce Richardson } else { 310499a2dd95SBruce Richardson ret = rte_eth_xstats_get_names(port_id, xstats_names_copy, 310599a2dd95SBruce Richardson expected_entries); 310699a2dd95SBruce Richardson if (ret < 0) { 310799a2dd95SBruce Richardson free(xstats_names_copy); 310899a2dd95SBruce Richardson return ret; 310999a2dd95SBruce Richardson } 311099a2dd95SBruce Richardson } 311199a2dd95SBruce Richardson 311299a2dd95SBruce Richardson /* Filter stats */ 311399a2dd95SBruce Richardson for (i = 0; i < size; i++) { 311499a2dd95SBruce Richardson if (ids[i] >= expected_entries) { 311599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n"); 311699a2dd95SBruce Richardson free(xstats_names_copy); 311799a2dd95SBruce Richardson return -1; 311899a2dd95SBruce Richardson } 311999a2dd95SBruce Richardson xstats_names[i] = xstats_names_copy[ids[i]]; 312099a2dd95SBruce Richardson } 312199a2dd95SBruce Richardson 312299a2dd95SBruce Richardson free(xstats_names_copy); 312399a2dd95SBruce Richardson return size; 312499a2dd95SBruce Richardson } 312599a2dd95SBruce Richardson 312699a2dd95SBruce Richardson int 312799a2dd95SBruce Richardson rte_eth_xstats_get_names(uint16_t port_id, 312899a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names, 312999a2dd95SBruce Richardson unsigned int size) 313099a2dd95SBruce Richardson { 313199a2dd95SBruce Richardson struct rte_eth_dev *dev; 313299a2dd95SBruce Richardson int cnt_used_entries; 313399a2dd95SBruce Richardson int cnt_expected_entries; 313499a2dd95SBruce Richardson int cnt_driver_entries; 313599a2dd95SBruce Richardson 313699a2dd95SBruce Richardson cnt_expected_entries = eth_dev_get_xstats_count(port_id); 313799a2dd95SBruce Richardson if (xstats_names == NULL || cnt_expected_entries < 0 || 313899a2dd95SBruce Richardson (int)size < cnt_expected_entries) 313999a2dd95SBruce Richardson return cnt_expected_entries; 314099a2dd95SBruce Richardson 314199a2dd95SBruce Richardson /* port_id checked in eth_dev_get_xstats_count() */ 314299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 314399a2dd95SBruce Richardson 314499a2dd95SBruce Richardson cnt_used_entries = eth_basic_stats_get_names(dev, xstats_names); 314599a2dd95SBruce Richardson 314699a2dd95SBruce Richardson if (dev->dev_ops->xstats_get_names != NULL) { 314799a2dd95SBruce Richardson /* If there are any driver-specific xstats, append them 314899a2dd95SBruce Richardson * to end of list. 314999a2dd95SBruce Richardson */ 315099a2dd95SBruce Richardson cnt_driver_entries = (*dev->dev_ops->xstats_get_names)( 315199a2dd95SBruce Richardson dev, 315299a2dd95SBruce Richardson xstats_names + cnt_used_entries, 315399a2dd95SBruce Richardson size - cnt_used_entries); 315499a2dd95SBruce Richardson if (cnt_driver_entries < 0) 315599a2dd95SBruce Richardson return eth_err(port_id, cnt_driver_entries); 315699a2dd95SBruce Richardson cnt_used_entries += cnt_driver_entries; 315799a2dd95SBruce Richardson } 315899a2dd95SBruce Richardson 315999a2dd95SBruce Richardson return cnt_used_entries; 316099a2dd95SBruce Richardson } 316199a2dd95SBruce Richardson 316299a2dd95SBruce Richardson 316399a2dd95SBruce Richardson static int 316499a2dd95SBruce Richardson eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats) 316599a2dd95SBruce Richardson { 316699a2dd95SBruce Richardson struct rte_eth_dev *dev; 316799a2dd95SBruce Richardson struct rte_eth_stats eth_stats; 316899a2dd95SBruce Richardson unsigned int count = 0, i, q; 316999a2dd95SBruce Richardson uint64_t val, *stats_ptr; 317099a2dd95SBruce Richardson uint16_t nb_rxqs, nb_txqs; 317199a2dd95SBruce Richardson int ret; 317299a2dd95SBruce Richardson 317399a2dd95SBruce Richardson ret = rte_eth_stats_get(port_id, ð_stats); 317499a2dd95SBruce Richardson if (ret < 0) 317599a2dd95SBruce Richardson return ret; 317699a2dd95SBruce Richardson 317799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 317899a2dd95SBruce Richardson 317999a2dd95SBruce Richardson nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 318099a2dd95SBruce Richardson nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 318199a2dd95SBruce Richardson 318299a2dd95SBruce Richardson /* global stats */ 318399a2dd95SBruce Richardson for (i = 0; i < RTE_NB_STATS; i++) { 318499a2dd95SBruce Richardson stats_ptr = RTE_PTR_ADD(ð_stats, 318599a2dd95SBruce Richardson eth_dev_stats_strings[i].offset); 318699a2dd95SBruce Richardson val = *stats_ptr; 318799a2dd95SBruce Richardson xstats[count++].value = val; 318899a2dd95SBruce Richardson } 318999a2dd95SBruce Richardson 319099a2dd95SBruce Richardson if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0) 319199a2dd95SBruce Richardson return count; 319299a2dd95SBruce Richardson 319399a2dd95SBruce Richardson /* per-rxq stats */ 319499a2dd95SBruce Richardson for (q = 0; q < nb_rxqs; q++) { 319599a2dd95SBruce Richardson for (i = 0; i < RTE_NB_RXQ_STATS; i++) { 319699a2dd95SBruce Richardson stats_ptr = RTE_PTR_ADD(ð_stats, 319799a2dd95SBruce Richardson eth_dev_rxq_stats_strings[i].offset + 319899a2dd95SBruce Richardson q * sizeof(uint64_t)); 319999a2dd95SBruce Richardson val = *stats_ptr; 320099a2dd95SBruce Richardson xstats[count++].value = val; 320199a2dd95SBruce Richardson } 320299a2dd95SBruce Richardson } 320399a2dd95SBruce Richardson 320499a2dd95SBruce Richardson /* per-txq stats */ 320599a2dd95SBruce Richardson for (q = 0; q < nb_txqs; q++) { 320699a2dd95SBruce Richardson for (i = 0; i < RTE_NB_TXQ_STATS; i++) { 320799a2dd95SBruce Richardson stats_ptr = RTE_PTR_ADD(ð_stats, 320899a2dd95SBruce Richardson eth_dev_txq_stats_strings[i].offset + 320999a2dd95SBruce Richardson q * sizeof(uint64_t)); 321099a2dd95SBruce Richardson val = *stats_ptr; 321199a2dd95SBruce Richardson xstats[count++].value = val; 321299a2dd95SBruce Richardson } 321399a2dd95SBruce Richardson } 321499a2dd95SBruce Richardson return count; 321599a2dd95SBruce Richardson } 321699a2dd95SBruce Richardson 321799a2dd95SBruce Richardson /* retrieve ethdev extended statistics */ 321899a2dd95SBruce Richardson int 321999a2dd95SBruce Richardson rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids, 322099a2dd95SBruce Richardson uint64_t *values, unsigned int size) 322199a2dd95SBruce Richardson { 322299a2dd95SBruce Richardson unsigned int no_basic_stat_requested = 1; 322399a2dd95SBruce Richardson unsigned int no_ext_stat_requested = 1; 322499a2dd95SBruce Richardson unsigned int num_xstats_filled; 322599a2dd95SBruce Richardson unsigned int basic_count; 322699a2dd95SBruce Richardson uint16_t expected_entries; 322799a2dd95SBruce Richardson struct rte_eth_dev *dev; 322899a2dd95SBruce Richardson unsigned int i; 322999a2dd95SBruce Richardson int ret; 323099a2dd95SBruce Richardson 323199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 323253ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 323353ef1b34SMin Hu (Connor) 323499a2dd95SBruce Richardson ret = eth_dev_get_xstats_count(port_id); 323599a2dd95SBruce Richardson if (ret < 0) 323699a2dd95SBruce Richardson return ret; 323799a2dd95SBruce Richardson expected_entries = (uint16_t)ret; 323899a2dd95SBruce Richardson struct rte_eth_xstat xstats[expected_entries]; 323999a2dd95SBruce Richardson basic_count = eth_dev_get_xstats_basic_count(dev); 324099a2dd95SBruce Richardson 324199a2dd95SBruce Richardson /* Return max number of stats if no ids given */ 324299a2dd95SBruce Richardson if (!ids) { 324399a2dd95SBruce Richardson if (!values) 324499a2dd95SBruce Richardson return expected_entries; 324599a2dd95SBruce Richardson else if (values && size < expected_entries) 324699a2dd95SBruce Richardson return expected_entries; 324799a2dd95SBruce Richardson } 324899a2dd95SBruce Richardson 324999a2dd95SBruce Richardson if (ids && !values) 325099a2dd95SBruce Richardson return -EINVAL; 325199a2dd95SBruce Richardson 325299a2dd95SBruce Richardson if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) { 325399a2dd95SBruce Richardson unsigned int basic_count = eth_dev_get_xstats_basic_count(dev); 325499a2dd95SBruce Richardson uint64_t ids_copy[size]; 325599a2dd95SBruce Richardson 325699a2dd95SBruce Richardson for (i = 0; i < size; i++) { 325799a2dd95SBruce Richardson if (ids[i] < basic_count) { 325899a2dd95SBruce Richardson no_basic_stat_requested = 0; 325999a2dd95SBruce Richardson break; 326099a2dd95SBruce Richardson } 326199a2dd95SBruce Richardson 326299a2dd95SBruce Richardson /* 326399a2dd95SBruce Richardson * Convert ids to xstats ids that PMD knows. 326499a2dd95SBruce Richardson * ids known by user are basic + extended stats. 326599a2dd95SBruce Richardson */ 326699a2dd95SBruce Richardson ids_copy[i] = ids[i] - basic_count; 326799a2dd95SBruce Richardson } 326899a2dd95SBruce Richardson 326999a2dd95SBruce Richardson if (no_basic_stat_requested) 327099a2dd95SBruce Richardson return (*dev->dev_ops->xstats_get_by_id)(dev, ids_copy, 327199a2dd95SBruce Richardson values, size); 327299a2dd95SBruce Richardson } 327399a2dd95SBruce Richardson 327499a2dd95SBruce Richardson if (ids) { 327599a2dd95SBruce Richardson for (i = 0; i < size; i++) { 327699a2dd95SBruce Richardson if (ids[i] >= basic_count) { 327799a2dd95SBruce Richardson no_ext_stat_requested = 0; 327899a2dd95SBruce Richardson break; 327999a2dd95SBruce Richardson } 328099a2dd95SBruce Richardson } 328199a2dd95SBruce Richardson } 328299a2dd95SBruce Richardson 328399a2dd95SBruce Richardson /* Fill the xstats structure */ 328499a2dd95SBruce Richardson if (ids && no_ext_stat_requested) 328599a2dd95SBruce Richardson ret = eth_basic_stats_get(port_id, xstats); 328699a2dd95SBruce Richardson else 328799a2dd95SBruce Richardson ret = rte_eth_xstats_get(port_id, xstats, expected_entries); 328899a2dd95SBruce Richardson 328999a2dd95SBruce Richardson if (ret < 0) 329099a2dd95SBruce Richardson return ret; 329199a2dd95SBruce Richardson num_xstats_filled = (unsigned int)ret; 329299a2dd95SBruce Richardson 329399a2dd95SBruce Richardson /* Return all stats */ 329499a2dd95SBruce Richardson if (!ids) { 329599a2dd95SBruce Richardson for (i = 0; i < num_xstats_filled; i++) 329699a2dd95SBruce Richardson values[i] = xstats[i].value; 329799a2dd95SBruce Richardson return expected_entries; 329899a2dd95SBruce Richardson } 329999a2dd95SBruce Richardson 330099a2dd95SBruce Richardson /* Filter stats */ 330199a2dd95SBruce Richardson for (i = 0; i < size; i++) { 330299a2dd95SBruce Richardson if (ids[i] >= expected_entries) { 330399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n"); 330499a2dd95SBruce Richardson return -1; 330599a2dd95SBruce Richardson } 330699a2dd95SBruce Richardson values[i] = xstats[ids[i]].value; 330799a2dd95SBruce Richardson } 330899a2dd95SBruce Richardson return size; 330999a2dd95SBruce Richardson } 331099a2dd95SBruce Richardson 331199a2dd95SBruce Richardson int 331299a2dd95SBruce Richardson rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats, 331399a2dd95SBruce Richardson unsigned int n) 331499a2dd95SBruce Richardson { 331599a2dd95SBruce Richardson struct rte_eth_dev *dev; 331699a2dd95SBruce Richardson unsigned int count = 0, i; 331799a2dd95SBruce Richardson signed int xcount = 0; 331899a2dd95SBruce Richardson uint16_t nb_rxqs, nb_txqs; 331999a2dd95SBruce Richardson int ret; 332099a2dd95SBruce Richardson 332199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 332299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 332399a2dd95SBruce Richardson 332499a2dd95SBruce Richardson nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 332599a2dd95SBruce Richardson nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 332699a2dd95SBruce Richardson 332799a2dd95SBruce Richardson /* Return generic statistics */ 332899a2dd95SBruce Richardson count = RTE_NB_STATS; 332999a2dd95SBruce Richardson if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) 333099a2dd95SBruce Richardson count += (nb_rxqs * RTE_NB_RXQ_STATS) + (nb_txqs * RTE_NB_TXQ_STATS); 333199a2dd95SBruce Richardson 333299a2dd95SBruce Richardson /* implemented by the driver */ 333399a2dd95SBruce Richardson if (dev->dev_ops->xstats_get != NULL) { 333499a2dd95SBruce Richardson /* Retrieve the xstats from the driver at the end of the 333599a2dd95SBruce Richardson * xstats struct. 333699a2dd95SBruce Richardson */ 333799a2dd95SBruce Richardson xcount = (*dev->dev_ops->xstats_get)(dev, 333899a2dd95SBruce Richardson xstats ? xstats + count : NULL, 333999a2dd95SBruce Richardson (n > count) ? n - count : 0); 334099a2dd95SBruce Richardson 334199a2dd95SBruce Richardson if (xcount < 0) 334299a2dd95SBruce Richardson return eth_err(port_id, xcount); 334399a2dd95SBruce Richardson } 334499a2dd95SBruce Richardson 334599a2dd95SBruce Richardson if (n < count + xcount || xstats == NULL) 334699a2dd95SBruce Richardson return count + xcount; 334799a2dd95SBruce Richardson 334899a2dd95SBruce Richardson /* now fill the xstats structure */ 334999a2dd95SBruce Richardson ret = eth_basic_stats_get(port_id, xstats); 335099a2dd95SBruce Richardson if (ret < 0) 335199a2dd95SBruce Richardson return ret; 335299a2dd95SBruce Richardson count = ret; 335399a2dd95SBruce Richardson 335499a2dd95SBruce Richardson for (i = 0; i < count; i++) 335599a2dd95SBruce Richardson xstats[i].id = i; 335699a2dd95SBruce Richardson /* add an offset to driver-specific stats */ 335799a2dd95SBruce Richardson for ( ; i < count + xcount; i++) 335899a2dd95SBruce Richardson xstats[i].id += count; 335999a2dd95SBruce Richardson 336099a2dd95SBruce Richardson return count + xcount; 336199a2dd95SBruce Richardson } 336299a2dd95SBruce Richardson 336399a2dd95SBruce Richardson /* reset ethdev extended statistics */ 336499a2dd95SBruce Richardson int 336599a2dd95SBruce Richardson rte_eth_xstats_reset(uint16_t port_id) 336699a2dd95SBruce Richardson { 336799a2dd95SBruce Richardson struct rte_eth_dev *dev; 336899a2dd95SBruce Richardson 336999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 337099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 337199a2dd95SBruce Richardson 337299a2dd95SBruce Richardson /* implemented by the driver */ 337399a2dd95SBruce Richardson if (dev->dev_ops->xstats_reset != NULL) 337499a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->xstats_reset)(dev)); 337599a2dd95SBruce Richardson 337699a2dd95SBruce Richardson /* fallback to default */ 337799a2dd95SBruce Richardson return rte_eth_stats_reset(port_id); 337899a2dd95SBruce Richardson } 337999a2dd95SBruce Richardson 338099a2dd95SBruce Richardson static int 338199a2dd95SBruce Richardson eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id, 338299a2dd95SBruce Richardson uint8_t stat_idx, uint8_t is_rx) 338399a2dd95SBruce Richardson { 338499a2dd95SBruce Richardson struct rte_eth_dev *dev; 338599a2dd95SBruce Richardson 338699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 338799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 338899a2dd95SBruce Richardson 338999a2dd95SBruce Richardson if (is_rx && (queue_id >= dev->data->nb_rx_queues)) 339099a2dd95SBruce Richardson return -EINVAL; 339199a2dd95SBruce Richardson 339299a2dd95SBruce Richardson if (!is_rx && (queue_id >= dev->data->nb_tx_queues)) 339399a2dd95SBruce Richardson return -EINVAL; 339499a2dd95SBruce Richardson 339599a2dd95SBruce Richardson if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS) 339699a2dd95SBruce Richardson return -EINVAL; 339799a2dd95SBruce Richardson 339853ef1b34SMin Hu (Connor) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set, -ENOTSUP); 339953ef1b34SMin Hu (Connor) return (*dev->dev_ops->queue_stats_mapping_set) (dev, queue_id, stat_idx, is_rx); 340099a2dd95SBruce Richardson } 340199a2dd95SBruce Richardson 340299a2dd95SBruce Richardson int 340399a2dd95SBruce Richardson rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id, 340499a2dd95SBruce Richardson uint8_t stat_idx) 340599a2dd95SBruce Richardson { 340699a2dd95SBruce Richardson return eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id, 340799a2dd95SBruce Richardson tx_queue_id, 340899a2dd95SBruce Richardson stat_idx, STAT_QMAP_TX)); 340999a2dd95SBruce Richardson } 341099a2dd95SBruce Richardson 341199a2dd95SBruce Richardson int 341299a2dd95SBruce Richardson rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id, 341399a2dd95SBruce Richardson uint8_t stat_idx) 341499a2dd95SBruce Richardson { 341599a2dd95SBruce Richardson return eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id, 341699a2dd95SBruce Richardson rx_queue_id, 341799a2dd95SBruce Richardson stat_idx, STAT_QMAP_RX)); 341899a2dd95SBruce Richardson } 341999a2dd95SBruce Richardson 342099a2dd95SBruce Richardson int 342199a2dd95SBruce Richardson rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size) 342299a2dd95SBruce Richardson { 342399a2dd95SBruce Richardson struct rte_eth_dev *dev; 342499a2dd95SBruce Richardson 342599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 342699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 342799a2dd95SBruce Richardson 342853ef1b34SMin Hu (Connor) if (fw_version == NULL && fw_size > 0) { 342953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 343053ef1b34SMin Hu (Connor) "Cannot get ethdev port %u FW version to NULL when string size is non zero\n", 343153ef1b34SMin Hu (Connor) port_id); 343253ef1b34SMin Hu (Connor) return -EINVAL; 343353ef1b34SMin Hu (Connor) } 343453ef1b34SMin Hu (Connor) 343599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP); 343699a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev, 343799a2dd95SBruce Richardson fw_version, fw_size)); 343899a2dd95SBruce Richardson } 343999a2dd95SBruce Richardson 344099a2dd95SBruce Richardson int 344199a2dd95SBruce Richardson rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info) 344299a2dd95SBruce Richardson { 344399a2dd95SBruce Richardson struct rte_eth_dev *dev; 344499a2dd95SBruce Richardson const struct rte_eth_desc_lim lim = { 344599a2dd95SBruce Richardson .nb_max = UINT16_MAX, 344699a2dd95SBruce Richardson .nb_min = 0, 344799a2dd95SBruce Richardson .nb_align = 1, 344899a2dd95SBruce Richardson .nb_seg_max = UINT16_MAX, 344999a2dd95SBruce Richardson .nb_mtu_seg_max = UINT16_MAX, 345099a2dd95SBruce Richardson }; 345199a2dd95SBruce Richardson int diag; 345299a2dd95SBruce Richardson 345353ef1b34SMin Hu (Connor) RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 345453ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 345553ef1b34SMin Hu (Connor) 345653ef1b34SMin Hu (Connor) if (dev_info == NULL) { 345753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u info to NULL\n", 345853ef1b34SMin Hu (Connor) port_id); 345953ef1b34SMin Hu (Connor) return -EINVAL; 346053ef1b34SMin Hu (Connor) } 346153ef1b34SMin Hu (Connor) 346299a2dd95SBruce Richardson /* 346399a2dd95SBruce Richardson * Init dev_info before port_id check since caller does not have 346499a2dd95SBruce Richardson * return status and does not know if get is successful or not. 346599a2dd95SBruce Richardson */ 346699a2dd95SBruce Richardson memset(dev_info, 0, sizeof(struct rte_eth_dev_info)); 346799a2dd95SBruce Richardson dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID; 346899a2dd95SBruce Richardson 346999a2dd95SBruce Richardson dev_info->rx_desc_lim = lim; 347099a2dd95SBruce Richardson dev_info->tx_desc_lim = lim; 347199a2dd95SBruce Richardson dev_info->device = dev->device; 3472990912e6SFerruh Yigit dev_info->min_mtu = RTE_ETHER_MIN_LEN - RTE_ETHER_HDR_LEN - 3473990912e6SFerruh Yigit RTE_ETHER_CRC_LEN; 347499a2dd95SBruce Richardson dev_info->max_mtu = UINT16_MAX; 347599a2dd95SBruce Richardson 347699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP); 347799a2dd95SBruce Richardson diag = (*dev->dev_ops->dev_infos_get)(dev, dev_info); 347899a2dd95SBruce Richardson if (diag != 0) { 347999a2dd95SBruce Richardson /* Cleanup already filled in device information */ 348099a2dd95SBruce Richardson memset(dev_info, 0, sizeof(struct rte_eth_dev_info)); 348199a2dd95SBruce Richardson return eth_err(port_id, diag); 348299a2dd95SBruce Richardson } 348399a2dd95SBruce Richardson 348499a2dd95SBruce Richardson /* Maximum number of queues should be <= RTE_MAX_QUEUES_PER_PORT */ 348599a2dd95SBruce Richardson dev_info->max_rx_queues = RTE_MIN(dev_info->max_rx_queues, 348699a2dd95SBruce Richardson RTE_MAX_QUEUES_PER_PORT); 348799a2dd95SBruce Richardson dev_info->max_tx_queues = RTE_MIN(dev_info->max_tx_queues, 348899a2dd95SBruce Richardson RTE_MAX_QUEUES_PER_PORT); 348999a2dd95SBruce Richardson 349099a2dd95SBruce Richardson dev_info->driver_name = dev->device->driver->name; 349199a2dd95SBruce Richardson dev_info->nb_rx_queues = dev->data->nb_rx_queues; 349299a2dd95SBruce Richardson dev_info->nb_tx_queues = dev->data->nb_tx_queues; 349399a2dd95SBruce Richardson 349499a2dd95SBruce Richardson dev_info->dev_flags = &dev->data->dev_flags; 349599a2dd95SBruce Richardson 349699a2dd95SBruce Richardson return 0; 349799a2dd95SBruce Richardson } 349899a2dd95SBruce Richardson 349999a2dd95SBruce Richardson int 3500632be327SJie Wang rte_eth_dev_conf_get(uint16_t port_id, struct rte_eth_conf *dev_conf) 3501632be327SJie Wang { 3502632be327SJie Wang struct rte_eth_dev *dev; 3503632be327SJie Wang 3504632be327SJie Wang RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3505632be327SJie Wang dev = &rte_eth_devices[port_id]; 3506632be327SJie Wang 3507632be327SJie Wang if (dev_conf == NULL) { 3508632be327SJie Wang RTE_ETHDEV_LOG(ERR, 3509632be327SJie Wang "Cannot get ethdev port %u configuration to NULL\n", 3510632be327SJie Wang port_id); 3511632be327SJie Wang return -EINVAL; 3512632be327SJie Wang } 3513632be327SJie Wang 3514632be327SJie Wang memcpy(dev_conf, &dev->data->dev_conf, sizeof(struct rte_eth_conf)); 3515632be327SJie Wang 3516632be327SJie Wang return 0; 3517632be327SJie Wang } 3518632be327SJie Wang 3519632be327SJie Wang int 352099a2dd95SBruce Richardson rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask, 352199a2dd95SBruce Richardson uint32_t *ptypes, int num) 352299a2dd95SBruce Richardson { 352399a2dd95SBruce Richardson int i, j; 352499a2dd95SBruce Richardson struct rte_eth_dev *dev; 352599a2dd95SBruce Richardson const uint32_t *all_ptypes; 352699a2dd95SBruce Richardson 352799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 352899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 352953ef1b34SMin Hu (Connor) 353053ef1b34SMin Hu (Connor) if (ptypes == NULL && num > 0) { 353153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 353253ef1b34SMin Hu (Connor) "Cannot get ethdev port %u supported packet types to NULL when array size is non zero\n", 353353ef1b34SMin Hu (Connor) port_id); 353453ef1b34SMin Hu (Connor) return -EINVAL; 353553ef1b34SMin Hu (Connor) } 353653ef1b34SMin Hu (Connor) 353799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0); 353899a2dd95SBruce Richardson all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev); 353999a2dd95SBruce Richardson 354099a2dd95SBruce Richardson if (!all_ptypes) 354199a2dd95SBruce Richardson return 0; 354299a2dd95SBruce Richardson 354399a2dd95SBruce Richardson for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i) 354499a2dd95SBruce Richardson if (all_ptypes[i] & ptype_mask) { 354599a2dd95SBruce Richardson if (j < num) 354699a2dd95SBruce Richardson ptypes[j] = all_ptypes[i]; 354799a2dd95SBruce Richardson j++; 354899a2dd95SBruce Richardson } 354999a2dd95SBruce Richardson 355099a2dd95SBruce Richardson return j; 355199a2dd95SBruce Richardson } 355299a2dd95SBruce Richardson 355399a2dd95SBruce Richardson int 355499a2dd95SBruce Richardson rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask, 355599a2dd95SBruce Richardson uint32_t *set_ptypes, unsigned int num) 355699a2dd95SBruce Richardson { 355799a2dd95SBruce Richardson const uint32_t valid_ptype_masks[] = { 355899a2dd95SBruce Richardson RTE_PTYPE_L2_MASK, 355999a2dd95SBruce Richardson RTE_PTYPE_L3_MASK, 356099a2dd95SBruce Richardson RTE_PTYPE_L4_MASK, 356199a2dd95SBruce Richardson RTE_PTYPE_TUNNEL_MASK, 356299a2dd95SBruce Richardson RTE_PTYPE_INNER_L2_MASK, 356399a2dd95SBruce Richardson RTE_PTYPE_INNER_L3_MASK, 356499a2dd95SBruce Richardson RTE_PTYPE_INNER_L4_MASK, 356599a2dd95SBruce Richardson }; 356699a2dd95SBruce Richardson const uint32_t *all_ptypes; 356799a2dd95SBruce Richardson struct rte_eth_dev *dev; 356899a2dd95SBruce Richardson uint32_t unused_mask; 356999a2dd95SBruce Richardson unsigned int i, j; 357099a2dd95SBruce Richardson int ret; 357199a2dd95SBruce Richardson 357299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 357399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 357499a2dd95SBruce Richardson 357553ef1b34SMin Hu (Connor) if (num > 0 && set_ptypes == NULL) { 357653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 357753ef1b34SMin Hu (Connor) "Cannot get ethdev port %u set packet types to NULL when array size is non zero\n", 357853ef1b34SMin Hu (Connor) port_id); 357999a2dd95SBruce Richardson return -EINVAL; 358053ef1b34SMin Hu (Connor) } 358199a2dd95SBruce Richardson 358299a2dd95SBruce Richardson if (*dev->dev_ops->dev_supported_ptypes_get == NULL || 358399a2dd95SBruce Richardson *dev->dev_ops->dev_ptypes_set == NULL) { 358499a2dd95SBruce Richardson ret = 0; 358599a2dd95SBruce Richardson goto ptype_unknown; 358699a2dd95SBruce Richardson } 358799a2dd95SBruce Richardson 358899a2dd95SBruce Richardson if (ptype_mask == 0) { 358999a2dd95SBruce Richardson ret = (*dev->dev_ops->dev_ptypes_set)(dev, 359099a2dd95SBruce Richardson ptype_mask); 359199a2dd95SBruce Richardson goto ptype_unknown; 359299a2dd95SBruce Richardson } 359399a2dd95SBruce Richardson 359499a2dd95SBruce Richardson unused_mask = ptype_mask; 359599a2dd95SBruce Richardson for (i = 0; i < RTE_DIM(valid_ptype_masks); i++) { 359699a2dd95SBruce Richardson uint32_t mask = ptype_mask & valid_ptype_masks[i]; 359799a2dd95SBruce Richardson if (mask && mask != valid_ptype_masks[i]) { 359899a2dd95SBruce Richardson ret = -EINVAL; 359999a2dd95SBruce Richardson goto ptype_unknown; 360099a2dd95SBruce Richardson } 360199a2dd95SBruce Richardson unused_mask &= ~valid_ptype_masks[i]; 360299a2dd95SBruce Richardson } 360399a2dd95SBruce Richardson 360499a2dd95SBruce Richardson if (unused_mask) { 360599a2dd95SBruce Richardson ret = -EINVAL; 360699a2dd95SBruce Richardson goto ptype_unknown; 360799a2dd95SBruce Richardson } 360899a2dd95SBruce Richardson 360999a2dd95SBruce Richardson all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev); 361099a2dd95SBruce Richardson if (all_ptypes == NULL) { 361199a2dd95SBruce Richardson ret = 0; 361299a2dd95SBruce Richardson goto ptype_unknown; 361399a2dd95SBruce Richardson } 361499a2dd95SBruce Richardson 361599a2dd95SBruce Richardson /* 361699a2dd95SBruce Richardson * Accommodate as many set_ptypes as possible. If the supplied 361799a2dd95SBruce Richardson * set_ptypes array is insufficient fill it partially. 361899a2dd95SBruce Richardson */ 361999a2dd95SBruce Richardson for (i = 0, j = 0; set_ptypes != NULL && 362099a2dd95SBruce Richardson (all_ptypes[i] != RTE_PTYPE_UNKNOWN); ++i) { 362199a2dd95SBruce Richardson if (ptype_mask & all_ptypes[i]) { 362299a2dd95SBruce Richardson if (j < num - 1) { 362399a2dd95SBruce Richardson set_ptypes[j] = all_ptypes[i]; 362499a2dd95SBruce Richardson j++; 362599a2dd95SBruce Richardson continue; 362699a2dd95SBruce Richardson } 362799a2dd95SBruce Richardson break; 362899a2dd95SBruce Richardson } 362999a2dd95SBruce Richardson } 363099a2dd95SBruce Richardson 363199a2dd95SBruce Richardson if (set_ptypes != NULL && j < num) 363299a2dd95SBruce Richardson set_ptypes[j] = RTE_PTYPE_UNKNOWN; 363399a2dd95SBruce Richardson 363499a2dd95SBruce Richardson return (*dev->dev_ops->dev_ptypes_set)(dev, ptype_mask); 363599a2dd95SBruce Richardson 363699a2dd95SBruce Richardson ptype_unknown: 363799a2dd95SBruce Richardson if (num > 0) 363899a2dd95SBruce Richardson set_ptypes[0] = RTE_PTYPE_UNKNOWN; 363999a2dd95SBruce Richardson 364099a2dd95SBruce Richardson return ret; 364199a2dd95SBruce Richardson } 364299a2dd95SBruce Richardson 364399a2dd95SBruce Richardson int 364427a300e6SKonstantin Ananyev rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr *ma, 364527a300e6SKonstantin Ananyev unsigned int num) 364627a300e6SKonstantin Ananyev { 364727a300e6SKonstantin Ananyev int32_t ret; 364827a300e6SKonstantin Ananyev struct rte_eth_dev *dev; 364927a300e6SKonstantin Ananyev struct rte_eth_dev_info dev_info; 365027a300e6SKonstantin Ananyev 365127a300e6SKonstantin Ananyev if (ma == NULL) { 365227a300e6SKonstantin Ananyev RTE_ETHDEV_LOG(ERR, "%s: invalid parameters\n", __func__); 365327a300e6SKonstantin Ananyev return -EINVAL; 365427a300e6SKonstantin Ananyev } 365527a300e6SKonstantin Ananyev 365627a300e6SKonstantin Ananyev /* will check for us that port_id is a valid one */ 365727a300e6SKonstantin Ananyev ret = rte_eth_dev_info_get(port_id, &dev_info); 365827a300e6SKonstantin Ananyev if (ret != 0) 365927a300e6SKonstantin Ananyev return ret; 366027a300e6SKonstantin Ananyev 366127a300e6SKonstantin Ananyev dev = &rte_eth_devices[port_id]; 366227a300e6SKonstantin Ananyev num = RTE_MIN(dev_info.max_mac_addrs, num); 366327a300e6SKonstantin Ananyev memcpy(ma, dev->data->mac_addrs, num * sizeof(ma[0])); 366427a300e6SKonstantin Ananyev 366527a300e6SKonstantin Ananyev return num; 366627a300e6SKonstantin Ananyev } 366727a300e6SKonstantin Ananyev 366827a300e6SKonstantin Ananyev int 366999a2dd95SBruce Richardson rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr) 367099a2dd95SBruce Richardson { 367199a2dd95SBruce Richardson struct rte_eth_dev *dev; 367299a2dd95SBruce Richardson 367399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 367499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 367553ef1b34SMin Hu (Connor) 367653ef1b34SMin Hu (Connor) if (mac_addr == NULL) { 367753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 367853ef1b34SMin Hu (Connor) "Cannot get ethdev port %u MAC address to NULL\n", 367953ef1b34SMin Hu (Connor) port_id); 368053ef1b34SMin Hu (Connor) return -EINVAL; 368153ef1b34SMin Hu (Connor) } 368253ef1b34SMin Hu (Connor) 368399a2dd95SBruce Richardson rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr); 368499a2dd95SBruce Richardson 368599a2dd95SBruce Richardson return 0; 368699a2dd95SBruce Richardson } 368799a2dd95SBruce Richardson 368899a2dd95SBruce Richardson int 368999a2dd95SBruce Richardson rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu) 369099a2dd95SBruce Richardson { 369199a2dd95SBruce Richardson struct rte_eth_dev *dev; 369299a2dd95SBruce Richardson 369399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 369499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 369553ef1b34SMin Hu (Connor) 369653ef1b34SMin Hu (Connor) if (mtu == NULL) { 369753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u MTU to NULL\n", 369853ef1b34SMin Hu (Connor) port_id); 369953ef1b34SMin Hu (Connor) return -EINVAL; 370053ef1b34SMin Hu (Connor) } 370153ef1b34SMin Hu (Connor) 370299a2dd95SBruce Richardson *mtu = dev->data->mtu; 370399a2dd95SBruce Richardson return 0; 370499a2dd95SBruce Richardson } 370599a2dd95SBruce Richardson 370699a2dd95SBruce Richardson int 370799a2dd95SBruce Richardson rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu) 370899a2dd95SBruce Richardson { 370999a2dd95SBruce Richardson int ret; 371099a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 371199a2dd95SBruce Richardson struct rte_eth_dev *dev; 371299a2dd95SBruce Richardson 371399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 371499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 371599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mtu_set, -ENOTSUP); 371699a2dd95SBruce Richardson 371799a2dd95SBruce Richardson /* 371899a2dd95SBruce Richardson * Check if the device supports dev_infos_get, if it does not 371999a2dd95SBruce Richardson * skip min_mtu/max_mtu validation here as this requires values 372099a2dd95SBruce Richardson * that are populated within the call to rte_eth_dev_info_get() 372199a2dd95SBruce Richardson * which relies on dev->dev_ops->dev_infos_get. 372299a2dd95SBruce Richardson */ 372399a2dd95SBruce Richardson if (*dev->dev_ops->dev_infos_get != NULL) { 372499a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 372599a2dd95SBruce Richardson if (ret != 0) 372699a2dd95SBruce Richardson return ret; 372799a2dd95SBruce Richardson 3728990912e6SFerruh Yigit ret = eth_dev_validate_mtu(port_id, &dev_info, mtu); 3729990912e6SFerruh Yigit if (ret != 0) 3730990912e6SFerruh Yigit return ret; 373199a2dd95SBruce Richardson } 373299a2dd95SBruce Richardson 3733b26bee10SIvan Ilchenko if (dev->data->dev_configured == 0) { 3734b26bee10SIvan Ilchenko RTE_ETHDEV_LOG(ERR, 3735b26bee10SIvan Ilchenko "Port %u must be configured before MTU set\n", 3736b26bee10SIvan Ilchenko port_id); 3737b26bee10SIvan Ilchenko return -EINVAL; 3738b26bee10SIvan Ilchenko } 3739b26bee10SIvan Ilchenko 374099a2dd95SBruce Richardson ret = (*dev->dev_ops->mtu_set)(dev, mtu); 3741b563c142SFerruh Yigit if (ret == 0) 374299a2dd95SBruce Richardson dev->data->mtu = mtu; 374399a2dd95SBruce Richardson 374499a2dd95SBruce Richardson return eth_err(port_id, ret); 374599a2dd95SBruce Richardson } 374699a2dd95SBruce Richardson 374799a2dd95SBruce Richardson int 374899a2dd95SBruce Richardson rte_eth_dev_vlan_filter(uint16_t port_id, uint16_t vlan_id, int on) 374999a2dd95SBruce Richardson { 375099a2dd95SBruce Richardson struct rte_eth_dev *dev; 375199a2dd95SBruce Richardson int ret; 375299a2dd95SBruce Richardson 375399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 375499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 375553ef1b34SMin Hu (Connor) 375699a2dd95SBruce Richardson if (!(dev->data->dev_conf.rxmode.offloads & 3757295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_VLAN_FILTER)) { 37585b49ba65SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Port %u: VLAN-filtering disabled\n", 375999a2dd95SBruce Richardson port_id); 376099a2dd95SBruce Richardson return -ENOSYS; 376199a2dd95SBruce Richardson } 376299a2dd95SBruce Richardson 376399a2dd95SBruce Richardson if (vlan_id > 4095) { 376499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port_id=%u invalid vlan_id=%u > 4095\n", 376599a2dd95SBruce Richardson port_id, vlan_id); 376699a2dd95SBruce Richardson return -EINVAL; 376799a2dd95SBruce Richardson } 376899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_filter_set, -ENOTSUP); 376999a2dd95SBruce Richardson 377099a2dd95SBruce Richardson ret = (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); 377199a2dd95SBruce Richardson if (ret == 0) { 377299a2dd95SBruce Richardson struct rte_vlan_filter_conf *vfc; 377399a2dd95SBruce Richardson int vidx; 377499a2dd95SBruce Richardson int vbit; 377599a2dd95SBruce Richardson 377699a2dd95SBruce Richardson vfc = &dev->data->vlan_filter_conf; 377799a2dd95SBruce Richardson vidx = vlan_id / 64; 377899a2dd95SBruce Richardson vbit = vlan_id % 64; 377999a2dd95SBruce Richardson 378099a2dd95SBruce Richardson if (on) 3781e1823e08SThomas Monjalon vfc->ids[vidx] |= RTE_BIT64(vbit); 378299a2dd95SBruce Richardson else 3783e1823e08SThomas Monjalon vfc->ids[vidx] &= ~RTE_BIT64(vbit); 378499a2dd95SBruce Richardson } 378599a2dd95SBruce Richardson 378699a2dd95SBruce Richardson return eth_err(port_id, ret); 378799a2dd95SBruce Richardson } 378899a2dd95SBruce Richardson 378999a2dd95SBruce Richardson int 379099a2dd95SBruce Richardson rte_eth_dev_set_vlan_strip_on_queue(uint16_t port_id, uint16_t rx_queue_id, 379199a2dd95SBruce Richardson int on) 379299a2dd95SBruce Richardson { 379399a2dd95SBruce Richardson struct rte_eth_dev *dev; 379499a2dd95SBruce Richardson 379599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 379699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 379753ef1b34SMin Hu (Connor) 379899a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 379999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid rx_queue_id=%u\n", rx_queue_id); 380099a2dd95SBruce Richardson return -EINVAL; 380199a2dd95SBruce Richardson } 380299a2dd95SBruce Richardson 380399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP); 380499a2dd95SBruce Richardson (*dev->dev_ops->vlan_strip_queue_set)(dev, rx_queue_id, on); 380599a2dd95SBruce Richardson 380699a2dd95SBruce Richardson return 0; 380799a2dd95SBruce Richardson } 380899a2dd95SBruce Richardson 380999a2dd95SBruce Richardson int 381099a2dd95SBruce Richardson rte_eth_dev_set_vlan_ether_type(uint16_t port_id, 381199a2dd95SBruce Richardson enum rte_vlan_type vlan_type, 381299a2dd95SBruce Richardson uint16_t tpid) 381399a2dd95SBruce Richardson { 381499a2dd95SBruce Richardson struct rte_eth_dev *dev; 381599a2dd95SBruce Richardson 381699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 381799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 381899a2dd95SBruce Richardson 381953ef1b34SMin Hu (Connor) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP); 382099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->vlan_tpid_set)(dev, vlan_type, 382199a2dd95SBruce Richardson tpid)); 382299a2dd95SBruce Richardson } 382399a2dd95SBruce Richardson 382499a2dd95SBruce Richardson int 382599a2dd95SBruce Richardson rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask) 382699a2dd95SBruce Richardson { 382799a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 382899a2dd95SBruce Richardson struct rte_eth_dev *dev; 382999a2dd95SBruce Richardson int ret = 0; 383099a2dd95SBruce Richardson int mask = 0; 383199a2dd95SBruce Richardson int cur, org = 0; 383299a2dd95SBruce Richardson uint64_t orig_offloads; 383399a2dd95SBruce Richardson uint64_t dev_offloads; 383499a2dd95SBruce Richardson uint64_t new_offloads; 383599a2dd95SBruce Richardson 383699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 383799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 383899a2dd95SBruce Richardson 383999a2dd95SBruce Richardson /* save original values in case of failure */ 384099a2dd95SBruce Richardson orig_offloads = dev->data->dev_conf.rxmode.offloads; 384199a2dd95SBruce Richardson dev_offloads = orig_offloads; 384299a2dd95SBruce Richardson 384399a2dd95SBruce Richardson /* check which option changed by application */ 3844295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_VLAN_STRIP_OFFLOAD); 3845295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP); 384699a2dd95SBruce Richardson if (cur != org) { 384799a2dd95SBruce Richardson if (cur) 3848295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP; 384999a2dd95SBruce Richardson else 3850295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP; 3851295968d1SFerruh Yigit mask |= RTE_ETH_VLAN_STRIP_MASK; 385299a2dd95SBruce Richardson } 385399a2dd95SBruce Richardson 3854295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_VLAN_FILTER_OFFLOAD); 3855295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER); 385699a2dd95SBruce Richardson if (cur != org) { 385799a2dd95SBruce Richardson if (cur) 3858295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER; 385999a2dd95SBruce Richardson else 3860295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_FILTER; 3861295968d1SFerruh Yigit mask |= RTE_ETH_VLAN_FILTER_MASK; 386299a2dd95SBruce Richardson } 386399a2dd95SBruce Richardson 3864295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_VLAN_EXTEND_OFFLOAD); 3865295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND); 386699a2dd95SBruce Richardson if (cur != org) { 386799a2dd95SBruce Richardson if (cur) 3868295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_EXTEND; 386999a2dd95SBruce Richardson else 3870295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_EXTEND; 3871295968d1SFerruh Yigit mask |= RTE_ETH_VLAN_EXTEND_MASK; 387299a2dd95SBruce Richardson } 387399a2dd95SBruce Richardson 3874295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_QINQ_STRIP_OFFLOAD); 3875295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP); 387699a2dd95SBruce Richardson if (cur != org) { 387799a2dd95SBruce Richardson if (cur) 3878295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP; 387999a2dd95SBruce Richardson else 3880295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_QINQ_STRIP; 3881295968d1SFerruh Yigit mask |= RTE_ETH_QINQ_STRIP_MASK; 388299a2dd95SBruce Richardson } 388399a2dd95SBruce Richardson 388499a2dd95SBruce Richardson /*no change*/ 388599a2dd95SBruce Richardson if (mask == 0) 388699a2dd95SBruce Richardson return ret; 388799a2dd95SBruce Richardson 388899a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 388999a2dd95SBruce Richardson if (ret != 0) 389099a2dd95SBruce Richardson return ret; 389199a2dd95SBruce Richardson 389299a2dd95SBruce Richardson /* Rx VLAN offloading must be within its device capabilities */ 389399a2dd95SBruce Richardson if ((dev_offloads & dev_info.rx_offload_capa) != dev_offloads) { 389499a2dd95SBruce Richardson new_offloads = dev_offloads & ~orig_offloads; 389599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 389699a2dd95SBruce Richardson "Ethdev port_id=%u requested new added VLAN offloads " 389799a2dd95SBruce Richardson "0x%" PRIx64 " must be within Rx offloads capabilities " 389899a2dd95SBruce Richardson "0x%" PRIx64 " in %s()\n", 389999a2dd95SBruce Richardson port_id, new_offloads, dev_info.rx_offload_capa, 390099a2dd95SBruce Richardson __func__); 390199a2dd95SBruce Richardson return -EINVAL; 390299a2dd95SBruce Richardson } 390399a2dd95SBruce Richardson 390499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_offload_set, -ENOTSUP); 390599a2dd95SBruce Richardson dev->data->dev_conf.rxmode.offloads = dev_offloads; 390699a2dd95SBruce Richardson ret = (*dev->dev_ops->vlan_offload_set)(dev, mask); 390799a2dd95SBruce Richardson if (ret) { 390899a2dd95SBruce Richardson /* hit an error restore original values */ 390999a2dd95SBruce Richardson dev->data->dev_conf.rxmode.offloads = orig_offloads; 391099a2dd95SBruce Richardson } 391199a2dd95SBruce Richardson 391299a2dd95SBruce Richardson return eth_err(port_id, ret); 391399a2dd95SBruce Richardson } 391499a2dd95SBruce Richardson 391599a2dd95SBruce Richardson int 391699a2dd95SBruce Richardson rte_eth_dev_get_vlan_offload(uint16_t port_id) 391799a2dd95SBruce Richardson { 391899a2dd95SBruce Richardson struct rte_eth_dev *dev; 391999a2dd95SBruce Richardson uint64_t *dev_offloads; 392099a2dd95SBruce Richardson int ret = 0; 392199a2dd95SBruce Richardson 392299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 392399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 392499a2dd95SBruce Richardson dev_offloads = &dev->data->dev_conf.rxmode.offloads; 392599a2dd95SBruce Richardson 3926295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) 3927295968d1SFerruh Yigit ret |= RTE_ETH_VLAN_STRIP_OFFLOAD; 392899a2dd95SBruce Richardson 3929295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) 3930295968d1SFerruh Yigit ret |= RTE_ETH_VLAN_FILTER_OFFLOAD; 393199a2dd95SBruce Richardson 3932295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND) 3933295968d1SFerruh Yigit ret |= RTE_ETH_VLAN_EXTEND_OFFLOAD; 393499a2dd95SBruce Richardson 3935295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP) 3936295968d1SFerruh Yigit ret |= RTE_ETH_QINQ_STRIP_OFFLOAD; 393799a2dd95SBruce Richardson 393899a2dd95SBruce Richardson return ret; 393999a2dd95SBruce Richardson } 394099a2dd95SBruce Richardson 394199a2dd95SBruce Richardson int 394299a2dd95SBruce Richardson rte_eth_dev_set_vlan_pvid(uint16_t port_id, uint16_t pvid, int on) 394399a2dd95SBruce Richardson { 394499a2dd95SBruce Richardson struct rte_eth_dev *dev; 394599a2dd95SBruce Richardson 394699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 394799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 394899a2dd95SBruce Richardson 394953ef1b34SMin Hu (Connor) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_pvid_set, -ENOTSUP); 395099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->vlan_pvid_set)(dev, pvid, on)); 395199a2dd95SBruce Richardson } 395299a2dd95SBruce Richardson 395399a2dd95SBruce Richardson int 395499a2dd95SBruce Richardson rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf) 395599a2dd95SBruce Richardson { 395699a2dd95SBruce Richardson struct rte_eth_dev *dev; 395799a2dd95SBruce Richardson 395899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 395999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 396053ef1b34SMin Hu (Connor) 396153ef1b34SMin Hu (Connor) if (fc_conf == NULL) { 396253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 396353ef1b34SMin Hu (Connor) "Cannot get ethdev port %u flow control config to NULL\n", 396453ef1b34SMin Hu (Connor) port_id); 396553ef1b34SMin Hu (Connor) return -EINVAL; 396653ef1b34SMin Hu (Connor) } 396753ef1b34SMin Hu (Connor) 396899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP); 396999a2dd95SBruce Richardson memset(fc_conf, 0, sizeof(*fc_conf)); 397099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf)); 397199a2dd95SBruce Richardson } 397299a2dd95SBruce Richardson 397399a2dd95SBruce Richardson int 397499a2dd95SBruce Richardson rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf) 397599a2dd95SBruce Richardson { 397699a2dd95SBruce Richardson struct rte_eth_dev *dev; 397799a2dd95SBruce Richardson 397899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 397953ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 398053ef1b34SMin Hu (Connor) 398153ef1b34SMin Hu (Connor) if (fc_conf == NULL) { 398253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 398353ef1b34SMin Hu (Connor) "Cannot set ethdev port %u flow control from NULL config\n", 398453ef1b34SMin Hu (Connor) port_id); 398553ef1b34SMin Hu (Connor) return -EINVAL; 398653ef1b34SMin Hu (Connor) } 398753ef1b34SMin Hu (Connor) 398899a2dd95SBruce Richardson if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) { 398999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n"); 399099a2dd95SBruce Richardson return -EINVAL; 399199a2dd95SBruce Richardson } 399299a2dd95SBruce Richardson 399399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP); 399499a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf)); 399599a2dd95SBruce Richardson } 399699a2dd95SBruce Richardson 399799a2dd95SBruce Richardson int 399899a2dd95SBruce Richardson rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id, 399999a2dd95SBruce Richardson struct rte_eth_pfc_conf *pfc_conf) 400099a2dd95SBruce Richardson { 400199a2dd95SBruce Richardson struct rte_eth_dev *dev; 400299a2dd95SBruce Richardson 400399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 400453ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 400553ef1b34SMin Hu (Connor) 400653ef1b34SMin Hu (Connor) if (pfc_conf == NULL) { 400753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 400853ef1b34SMin Hu (Connor) "Cannot set ethdev port %u priority flow control from NULL config\n", 400953ef1b34SMin Hu (Connor) port_id); 401053ef1b34SMin Hu (Connor) return -EINVAL; 401153ef1b34SMin Hu (Connor) } 401253ef1b34SMin Hu (Connor) 4013295968d1SFerruh Yigit if (pfc_conf->priority > (RTE_ETH_DCB_NUM_USER_PRIORITIES - 1)) { 401499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n"); 401599a2dd95SBruce Richardson return -EINVAL; 401699a2dd95SBruce Richardson } 401799a2dd95SBruce Richardson 401899a2dd95SBruce Richardson /* High water, low water validation are device specific */ 401999a2dd95SBruce Richardson if (*dev->dev_ops->priority_flow_ctrl_set) 402099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set) 402199a2dd95SBruce Richardson (dev, pfc_conf)); 402299a2dd95SBruce Richardson return -ENOTSUP; 402399a2dd95SBruce Richardson } 402499a2dd95SBruce Richardson 402599a2dd95SBruce Richardson static int 402699a2dd95SBruce Richardson eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf, 402799a2dd95SBruce Richardson uint16_t reta_size) 402899a2dd95SBruce Richardson { 402999a2dd95SBruce Richardson uint16_t i, num; 403099a2dd95SBruce Richardson 4031295968d1SFerruh Yigit num = (reta_size + RTE_ETH_RETA_GROUP_SIZE - 1) / RTE_ETH_RETA_GROUP_SIZE; 403299a2dd95SBruce Richardson for (i = 0; i < num; i++) { 403399a2dd95SBruce Richardson if (reta_conf[i].mask) 403499a2dd95SBruce Richardson return 0; 403599a2dd95SBruce Richardson } 403699a2dd95SBruce Richardson 403799a2dd95SBruce Richardson return -EINVAL; 403899a2dd95SBruce Richardson } 403999a2dd95SBruce Richardson 404099a2dd95SBruce Richardson static int 404199a2dd95SBruce Richardson eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf, 404299a2dd95SBruce Richardson uint16_t reta_size, 404399a2dd95SBruce Richardson uint16_t max_rxq) 404499a2dd95SBruce Richardson { 404599a2dd95SBruce Richardson uint16_t i, idx, shift; 404699a2dd95SBruce Richardson 404799a2dd95SBruce Richardson if (max_rxq == 0) { 404899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "No receive queue is available\n"); 404999a2dd95SBruce Richardson return -EINVAL; 405099a2dd95SBruce Richardson } 405199a2dd95SBruce Richardson 405299a2dd95SBruce Richardson for (i = 0; i < reta_size; i++) { 4053295968d1SFerruh Yigit idx = i / RTE_ETH_RETA_GROUP_SIZE; 4054295968d1SFerruh Yigit shift = i % RTE_ETH_RETA_GROUP_SIZE; 4055e1823e08SThomas Monjalon if ((reta_conf[idx].mask & RTE_BIT64(shift)) && 405699a2dd95SBruce Richardson (reta_conf[idx].reta[shift] >= max_rxq)) { 405799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 405899a2dd95SBruce Richardson "reta_conf[%u]->reta[%u]: %u exceeds the maximum rxq index: %u\n", 405999a2dd95SBruce Richardson idx, shift, 406099a2dd95SBruce Richardson reta_conf[idx].reta[shift], max_rxq); 406199a2dd95SBruce Richardson return -EINVAL; 406299a2dd95SBruce Richardson } 406399a2dd95SBruce Richardson } 406499a2dd95SBruce Richardson 406599a2dd95SBruce Richardson return 0; 406699a2dd95SBruce Richardson } 406799a2dd95SBruce Richardson 406899a2dd95SBruce Richardson int 406999a2dd95SBruce Richardson rte_eth_dev_rss_reta_update(uint16_t port_id, 407099a2dd95SBruce Richardson struct rte_eth_rss_reta_entry64 *reta_conf, 407199a2dd95SBruce Richardson uint16_t reta_size) 407299a2dd95SBruce Richardson { 407399a2dd95SBruce Richardson struct rte_eth_dev *dev; 407499a2dd95SBruce Richardson int ret; 407599a2dd95SBruce Richardson 407699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 407753ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 407853ef1b34SMin Hu (Connor) 407953ef1b34SMin Hu (Connor) if (reta_conf == NULL) { 408053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 408153ef1b34SMin Hu (Connor) "Cannot update ethdev port %u RSS RETA to NULL\n", 408253ef1b34SMin Hu (Connor) port_id); 408353ef1b34SMin Hu (Connor) return -EINVAL; 408453ef1b34SMin Hu (Connor) } 408553ef1b34SMin Hu (Connor) 408653ef1b34SMin Hu (Connor) if (reta_size == 0) { 408753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 408853ef1b34SMin Hu (Connor) "Cannot update ethdev port %u RSS RETA with zero size\n", 408953ef1b34SMin Hu (Connor) port_id); 409053ef1b34SMin Hu (Connor) return -EINVAL; 409153ef1b34SMin Hu (Connor) } 409253ef1b34SMin Hu (Connor) 409399a2dd95SBruce Richardson /* Check mask bits */ 409499a2dd95SBruce Richardson ret = eth_check_reta_mask(reta_conf, reta_size); 409599a2dd95SBruce Richardson if (ret < 0) 409699a2dd95SBruce Richardson return ret; 409799a2dd95SBruce Richardson 409899a2dd95SBruce Richardson /* Check entry value */ 409999a2dd95SBruce Richardson ret = eth_check_reta_entry(reta_conf, reta_size, 410099a2dd95SBruce Richardson dev->data->nb_rx_queues); 410199a2dd95SBruce Richardson if (ret < 0) 410299a2dd95SBruce Richardson return ret; 410399a2dd95SBruce Richardson 410499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_update, -ENOTSUP); 410599a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->reta_update)(dev, reta_conf, 410699a2dd95SBruce Richardson reta_size)); 410799a2dd95SBruce Richardson } 410899a2dd95SBruce Richardson 410999a2dd95SBruce Richardson int 411099a2dd95SBruce Richardson rte_eth_dev_rss_reta_query(uint16_t port_id, 411199a2dd95SBruce Richardson struct rte_eth_rss_reta_entry64 *reta_conf, 411299a2dd95SBruce Richardson uint16_t reta_size) 411399a2dd95SBruce Richardson { 411499a2dd95SBruce Richardson struct rte_eth_dev *dev; 411599a2dd95SBruce Richardson int ret; 411699a2dd95SBruce Richardson 411799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 411853ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 411953ef1b34SMin Hu (Connor) 412053ef1b34SMin Hu (Connor) if (reta_conf == NULL) { 412153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 412253ef1b34SMin Hu (Connor) "Cannot query ethdev port %u RSS RETA from NULL config\n", 412353ef1b34SMin Hu (Connor) port_id); 412453ef1b34SMin Hu (Connor) return -EINVAL; 412553ef1b34SMin Hu (Connor) } 412699a2dd95SBruce Richardson 412799a2dd95SBruce Richardson /* Check mask bits */ 412899a2dd95SBruce Richardson ret = eth_check_reta_mask(reta_conf, reta_size); 412999a2dd95SBruce Richardson if (ret < 0) 413099a2dd95SBruce Richardson return ret; 413199a2dd95SBruce Richardson 413299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP); 413399a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf, 413499a2dd95SBruce Richardson reta_size)); 413599a2dd95SBruce Richardson } 413699a2dd95SBruce Richardson 413799a2dd95SBruce Richardson int 413899a2dd95SBruce Richardson rte_eth_dev_rss_hash_update(uint16_t port_id, 413999a2dd95SBruce Richardson struct rte_eth_rss_conf *rss_conf) 414099a2dd95SBruce Richardson { 414199a2dd95SBruce Richardson struct rte_eth_dev *dev; 414299a2dd95SBruce Richardson struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, }; 414399a2dd95SBruce Richardson int ret; 414499a2dd95SBruce Richardson 414599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 414653ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 414753ef1b34SMin Hu (Connor) 414853ef1b34SMin Hu (Connor) if (rss_conf == NULL) { 414953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 415053ef1b34SMin Hu (Connor) "Cannot update ethdev port %u RSS hash from NULL config\n", 415153ef1b34SMin Hu (Connor) port_id); 415253ef1b34SMin Hu (Connor) return -EINVAL; 415353ef1b34SMin Hu (Connor) } 415499a2dd95SBruce Richardson 415599a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 415699a2dd95SBruce Richardson if (ret != 0) 415799a2dd95SBruce Richardson return ret; 415899a2dd95SBruce Richardson 415999a2dd95SBruce Richardson rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf); 416099a2dd95SBruce Richardson if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) != 416199a2dd95SBruce Richardson dev_info.flow_type_rss_offloads) { 416299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 416399a2dd95SBruce Richardson "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n", 416499a2dd95SBruce Richardson port_id, rss_conf->rss_hf, 416599a2dd95SBruce Richardson dev_info.flow_type_rss_offloads); 416699a2dd95SBruce Richardson return -EINVAL; 416799a2dd95SBruce Richardson } 416899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP); 416999a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->rss_hash_update)(dev, 417099a2dd95SBruce Richardson rss_conf)); 417199a2dd95SBruce Richardson } 417299a2dd95SBruce Richardson 417399a2dd95SBruce Richardson int 417499a2dd95SBruce Richardson rte_eth_dev_rss_hash_conf_get(uint16_t port_id, 417599a2dd95SBruce Richardson struct rte_eth_rss_conf *rss_conf) 417699a2dd95SBruce Richardson { 417799a2dd95SBruce Richardson struct rte_eth_dev *dev; 417899a2dd95SBruce Richardson 417999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 418099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 418153ef1b34SMin Hu (Connor) 418253ef1b34SMin Hu (Connor) if (rss_conf == NULL) { 418353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 418453ef1b34SMin Hu (Connor) "Cannot get ethdev port %u RSS hash config to NULL\n", 418553ef1b34SMin Hu (Connor) port_id); 418653ef1b34SMin Hu (Connor) return -EINVAL; 418753ef1b34SMin Hu (Connor) } 418853ef1b34SMin Hu (Connor) 418999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP); 419099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev, 419199a2dd95SBruce Richardson rss_conf)); 419299a2dd95SBruce Richardson } 419399a2dd95SBruce Richardson 419499a2dd95SBruce Richardson int 419599a2dd95SBruce Richardson rte_eth_dev_udp_tunnel_port_add(uint16_t port_id, 419699a2dd95SBruce Richardson struct rte_eth_udp_tunnel *udp_tunnel) 419799a2dd95SBruce Richardson { 419899a2dd95SBruce Richardson struct rte_eth_dev *dev; 419999a2dd95SBruce Richardson 420099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 420153ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 420253ef1b34SMin Hu (Connor) 420399a2dd95SBruce Richardson if (udp_tunnel == NULL) { 420453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 420553ef1b34SMin Hu (Connor) "Cannot add ethdev port %u UDP tunnel port from NULL UDP tunnel\n", 420653ef1b34SMin Hu (Connor) port_id); 420799a2dd95SBruce Richardson return -EINVAL; 420899a2dd95SBruce Richardson } 420999a2dd95SBruce Richardson 4210295968d1SFerruh Yigit if (udp_tunnel->prot_type >= RTE_ETH_TUNNEL_TYPE_MAX) { 421199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n"); 421299a2dd95SBruce Richardson return -EINVAL; 421399a2dd95SBruce Richardson } 421499a2dd95SBruce Richardson 421599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_add, -ENOTSUP); 421699a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_add)(dev, 421799a2dd95SBruce Richardson udp_tunnel)); 421899a2dd95SBruce Richardson } 421999a2dd95SBruce Richardson 422099a2dd95SBruce Richardson int 422199a2dd95SBruce Richardson rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id, 422299a2dd95SBruce Richardson struct rte_eth_udp_tunnel *udp_tunnel) 422399a2dd95SBruce Richardson { 422499a2dd95SBruce Richardson struct rte_eth_dev *dev; 422599a2dd95SBruce Richardson 422699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 422799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 422899a2dd95SBruce Richardson 422999a2dd95SBruce Richardson if (udp_tunnel == NULL) { 423053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 423153ef1b34SMin Hu (Connor) "Cannot delete ethdev port %u UDP tunnel port from NULL UDP tunnel\n", 423253ef1b34SMin Hu (Connor) port_id); 423399a2dd95SBruce Richardson return -EINVAL; 423499a2dd95SBruce Richardson } 423599a2dd95SBruce Richardson 4236295968d1SFerruh Yigit if (udp_tunnel->prot_type >= RTE_ETH_TUNNEL_TYPE_MAX) { 423799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n"); 423899a2dd95SBruce Richardson return -EINVAL; 423999a2dd95SBruce Richardson } 424099a2dd95SBruce Richardson 424199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_del, -ENOTSUP); 424299a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_del)(dev, 424399a2dd95SBruce Richardson udp_tunnel)); 424499a2dd95SBruce Richardson } 424599a2dd95SBruce Richardson 424699a2dd95SBruce Richardson int 424799a2dd95SBruce Richardson rte_eth_led_on(uint16_t port_id) 424899a2dd95SBruce Richardson { 424999a2dd95SBruce Richardson struct rte_eth_dev *dev; 425099a2dd95SBruce Richardson 425199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 425299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 425353ef1b34SMin Hu (Connor) 425499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_on, -ENOTSUP); 425599a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->dev_led_on)(dev)); 425699a2dd95SBruce Richardson } 425799a2dd95SBruce Richardson 425899a2dd95SBruce Richardson int 425999a2dd95SBruce Richardson rte_eth_led_off(uint16_t port_id) 426099a2dd95SBruce Richardson { 426199a2dd95SBruce Richardson struct rte_eth_dev *dev; 426299a2dd95SBruce Richardson 426399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 426499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 426553ef1b34SMin Hu (Connor) 426699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_off, -ENOTSUP); 426799a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->dev_led_off)(dev)); 426899a2dd95SBruce Richardson } 426999a2dd95SBruce Richardson 427099a2dd95SBruce Richardson int 427199a2dd95SBruce Richardson rte_eth_fec_get_capability(uint16_t port_id, 427299a2dd95SBruce Richardson struct rte_eth_fec_capa *speed_fec_capa, 427399a2dd95SBruce Richardson unsigned int num) 427499a2dd95SBruce Richardson { 427599a2dd95SBruce Richardson struct rte_eth_dev *dev; 427699a2dd95SBruce Richardson int ret; 427799a2dd95SBruce Richardson 427899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 427999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 428053ef1b34SMin Hu (Connor) 428153ef1b34SMin Hu (Connor) if (speed_fec_capa == NULL && num > 0) { 428253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 428353ef1b34SMin Hu (Connor) "Cannot get ethdev port %u FEC capability to NULL when array size is non zero\n", 428453ef1b34SMin Hu (Connor) port_id); 428553ef1b34SMin Hu (Connor) return -EINVAL; 428653ef1b34SMin Hu (Connor) } 428753ef1b34SMin Hu (Connor) 428899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get_capability, -ENOTSUP); 428999a2dd95SBruce Richardson ret = (*dev->dev_ops->fec_get_capability)(dev, speed_fec_capa, num); 429099a2dd95SBruce Richardson 429199a2dd95SBruce Richardson return ret; 429299a2dd95SBruce Richardson } 429399a2dd95SBruce Richardson 429499a2dd95SBruce Richardson int 429599a2dd95SBruce Richardson rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa) 429699a2dd95SBruce Richardson { 429799a2dd95SBruce Richardson struct rte_eth_dev *dev; 429899a2dd95SBruce Richardson 429999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 430099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 430153ef1b34SMin Hu (Connor) 430253ef1b34SMin Hu (Connor) if (fec_capa == NULL) { 430353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 430453ef1b34SMin Hu (Connor) "Cannot get ethdev port %u current FEC mode to NULL\n", 430553ef1b34SMin Hu (Connor) port_id); 430653ef1b34SMin Hu (Connor) return -EINVAL; 430753ef1b34SMin Hu (Connor) } 430853ef1b34SMin Hu (Connor) 430999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get, -ENOTSUP); 431099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->fec_get)(dev, fec_capa)); 431199a2dd95SBruce Richardson } 431299a2dd95SBruce Richardson 431399a2dd95SBruce Richardson int 431499a2dd95SBruce Richardson rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa) 431599a2dd95SBruce Richardson { 431699a2dd95SBruce Richardson struct rte_eth_dev *dev; 431799a2dd95SBruce Richardson 431899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 431999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 432053ef1b34SMin Hu (Connor) 432199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_set, -ENOTSUP); 432299a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->fec_set)(dev, fec_capa)); 432399a2dd95SBruce Richardson } 432499a2dd95SBruce Richardson 432599a2dd95SBruce Richardson /* 432699a2dd95SBruce Richardson * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find 432799a2dd95SBruce Richardson * an empty spot. 432899a2dd95SBruce Richardson */ 432999a2dd95SBruce Richardson static int 433099a2dd95SBruce Richardson eth_dev_get_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr) 433199a2dd95SBruce Richardson { 433299a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 433399a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 433499a2dd95SBruce Richardson unsigned i; 433599a2dd95SBruce Richardson int ret; 433699a2dd95SBruce Richardson 433799a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 433899a2dd95SBruce Richardson if (ret != 0) 433999a2dd95SBruce Richardson return -1; 434099a2dd95SBruce Richardson 434199a2dd95SBruce Richardson for (i = 0; i < dev_info.max_mac_addrs; i++) 434299a2dd95SBruce Richardson if (memcmp(addr, &dev->data->mac_addrs[i], 434399a2dd95SBruce Richardson RTE_ETHER_ADDR_LEN) == 0) 434499a2dd95SBruce Richardson return i; 434599a2dd95SBruce Richardson 434699a2dd95SBruce Richardson return -1; 434799a2dd95SBruce Richardson } 434899a2dd95SBruce Richardson 434999a2dd95SBruce Richardson static const struct rte_ether_addr null_mac_addr; 435099a2dd95SBruce Richardson 435199a2dd95SBruce Richardson int 435299a2dd95SBruce Richardson rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, 435399a2dd95SBruce Richardson uint32_t pool) 435499a2dd95SBruce Richardson { 435599a2dd95SBruce Richardson struct rte_eth_dev *dev; 435699a2dd95SBruce Richardson int index; 435799a2dd95SBruce Richardson uint64_t pool_mask; 435899a2dd95SBruce Richardson int ret; 435999a2dd95SBruce Richardson 436099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 436199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 436253ef1b34SMin Hu (Connor) 436353ef1b34SMin Hu (Connor) if (addr == NULL) { 436453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 436553ef1b34SMin Hu (Connor) "Cannot add ethdev port %u MAC address from NULL address\n", 436653ef1b34SMin Hu (Connor) port_id); 436753ef1b34SMin Hu (Connor) return -EINVAL; 436853ef1b34SMin Hu (Connor) } 436953ef1b34SMin Hu (Connor) 437099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP); 437199a2dd95SBruce Richardson 437299a2dd95SBruce Richardson if (rte_is_zero_ether_addr(addr)) { 437399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n", 437499a2dd95SBruce Richardson port_id); 437599a2dd95SBruce Richardson return -EINVAL; 437699a2dd95SBruce Richardson } 4377295968d1SFerruh Yigit if (pool >= RTE_ETH_64_POOLS) { 4378295968d1SFerruh Yigit RTE_ETHDEV_LOG(ERR, "Pool ID must be 0-%d\n", RTE_ETH_64_POOLS - 1); 437999a2dd95SBruce Richardson return -EINVAL; 438099a2dd95SBruce Richardson } 438199a2dd95SBruce Richardson 438299a2dd95SBruce Richardson index = eth_dev_get_mac_addr_index(port_id, addr); 438399a2dd95SBruce Richardson if (index < 0) { 438499a2dd95SBruce Richardson index = eth_dev_get_mac_addr_index(port_id, &null_mac_addr); 438599a2dd95SBruce Richardson if (index < 0) { 438699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n", 438799a2dd95SBruce Richardson port_id); 438899a2dd95SBruce Richardson return -ENOSPC; 438999a2dd95SBruce Richardson } 439099a2dd95SBruce Richardson } else { 439199a2dd95SBruce Richardson pool_mask = dev->data->mac_pool_sel[index]; 439299a2dd95SBruce Richardson 439399a2dd95SBruce Richardson /* Check if both MAC address and pool is already there, and do nothing */ 4394e1823e08SThomas Monjalon if (pool_mask & RTE_BIT64(pool)) 439599a2dd95SBruce Richardson return 0; 439699a2dd95SBruce Richardson } 439799a2dd95SBruce Richardson 439899a2dd95SBruce Richardson /* Update NIC */ 439999a2dd95SBruce Richardson ret = (*dev->dev_ops->mac_addr_add)(dev, addr, index, pool); 440099a2dd95SBruce Richardson 440199a2dd95SBruce Richardson if (ret == 0) { 440299a2dd95SBruce Richardson /* Update address in NIC data structure */ 440399a2dd95SBruce Richardson rte_ether_addr_copy(addr, &dev->data->mac_addrs[index]); 440499a2dd95SBruce Richardson 440599a2dd95SBruce Richardson /* Update pool bitmap in NIC data structure */ 4406e1823e08SThomas Monjalon dev->data->mac_pool_sel[index] |= RTE_BIT64(pool); 440799a2dd95SBruce Richardson } 440899a2dd95SBruce Richardson 440999a2dd95SBruce Richardson return eth_err(port_id, ret); 441099a2dd95SBruce Richardson } 441199a2dd95SBruce Richardson 441299a2dd95SBruce Richardson int 441399a2dd95SBruce Richardson rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) 441499a2dd95SBruce Richardson { 441599a2dd95SBruce Richardson struct rte_eth_dev *dev; 441699a2dd95SBruce Richardson int index; 441799a2dd95SBruce Richardson 441899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 441999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 442053ef1b34SMin Hu (Connor) 442153ef1b34SMin Hu (Connor) if (addr == NULL) { 442253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 442353ef1b34SMin Hu (Connor) "Cannot remove ethdev port %u MAC address from NULL address\n", 442453ef1b34SMin Hu (Connor) port_id); 442553ef1b34SMin Hu (Connor) return -EINVAL; 442653ef1b34SMin Hu (Connor) } 442753ef1b34SMin Hu (Connor) 442899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP); 442999a2dd95SBruce Richardson 443099a2dd95SBruce Richardson index = eth_dev_get_mac_addr_index(port_id, addr); 443199a2dd95SBruce Richardson if (index == 0) { 443299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 443399a2dd95SBruce Richardson "Port %u: Cannot remove default MAC address\n", 443499a2dd95SBruce Richardson port_id); 443599a2dd95SBruce Richardson return -EADDRINUSE; 443699a2dd95SBruce Richardson } else if (index < 0) 443799a2dd95SBruce Richardson return 0; /* Do nothing if address wasn't found */ 443899a2dd95SBruce Richardson 443999a2dd95SBruce Richardson /* Update NIC */ 444099a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_remove)(dev, index); 444199a2dd95SBruce Richardson 444299a2dd95SBruce Richardson /* Update address in NIC data structure */ 444399a2dd95SBruce Richardson rte_ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]); 444499a2dd95SBruce Richardson 444599a2dd95SBruce Richardson /* reset pool bitmap */ 444699a2dd95SBruce Richardson dev->data->mac_pool_sel[index] = 0; 444799a2dd95SBruce Richardson 444899a2dd95SBruce Richardson return 0; 444999a2dd95SBruce Richardson } 445099a2dd95SBruce Richardson 445199a2dd95SBruce Richardson int 445299a2dd95SBruce Richardson rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) 445399a2dd95SBruce Richardson { 445499a2dd95SBruce Richardson struct rte_eth_dev *dev; 445599a2dd95SBruce Richardson int ret; 445699a2dd95SBruce Richardson 445799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 445853ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 445953ef1b34SMin Hu (Connor) 446053ef1b34SMin Hu (Connor) if (addr == NULL) { 446153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 446253ef1b34SMin Hu (Connor) "Cannot set ethdev port %u default MAC address from NULL address\n", 446353ef1b34SMin Hu (Connor) port_id); 446453ef1b34SMin Hu (Connor) return -EINVAL; 446553ef1b34SMin Hu (Connor) } 446699a2dd95SBruce Richardson 446799a2dd95SBruce Richardson if (!rte_is_valid_assigned_ether_addr(addr)) 446899a2dd95SBruce Richardson return -EINVAL; 446999a2dd95SBruce Richardson 447099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP); 447199a2dd95SBruce Richardson 447299a2dd95SBruce Richardson ret = (*dev->dev_ops->mac_addr_set)(dev, addr); 447399a2dd95SBruce Richardson if (ret < 0) 447499a2dd95SBruce Richardson return ret; 447599a2dd95SBruce Richardson 447699a2dd95SBruce Richardson /* Update default address in NIC data structure */ 447799a2dd95SBruce Richardson rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); 447899a2dd95SBruce Richardson 447999a2dd95SBruce Richardson return 0; 448099a2dd95SBruce Richardson } 448199a2dd95SBruce Richardson 448299a2dd95SBruce Richardson 448399a2dd95SBruce Richardson /* 448499a2dd95SBruce Richardson * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find 448599a2dd95SBruce Richardson * an empty spot. 448699a2dd95SBruce Richardson */ 448799a2dd95SBruce Richardson static int 448899a2dd95SBruce Richardson eth_dev_get_hash_mac_addr_index(uint16_t port_id, 448999a2dd95SBruce Richardson const struct rte_ether_addr *addr) 449099a2dd95SBruce Richardson { 449199a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 449299a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 449399a2dd95SBruce Richardson unsigned i; 449499a2dd95SBruce Richardson int ret; 449599a2dd95SBruce Richardson 449699a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 449799a2dd95SBruce Richardson if (ret != 0) 449899a2dd95SBruce Richardson return -1; 449999a2dd95SBruce Richardson 450099a2dd95SBruce Richardson if (!dev->data->hash_mac_addrs) 450199a2dd95SBruce Richardson return -1; 450299a2dd95SBruce Richardson 450399a2dd95SBruce Richardson for (i = 0; i < dev_info.max_hash_mac_addrs; i++) 450499a2dd95SBruce Richardson if (memcmp(addr, &dev->data->hash_mac_addrs[i], 450599a2dd95SBruce Richardson RTE_ETHER_ADDR_LEN) == 0) 450699a2dd95SBruce Richardson return i; 450799a2dd95SBruce Richardson 450899a2dd95SBruce Richardson return -1; 450999a2dd95SBruce Richardson } 451099a2dd95SBruce Richardson 451199a2dd95SBruce Richardson int 451299a2dd95SBruce Richardson rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr, 451399a2dd95SBruce Richardson uint8_t on) 451499a2dd95SBruce Richardson { 451599a2dd95SBruce Richardson int index; 451699a2dd95SBruce Richardson int ret; 451799a2dd95SBruce Richardson struct rte_eth_dev *dev; 451899a2dd95SBruce Richardson 451999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 452099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 452153ef1b34SMin Hu (Connor) 452253ef1b34SMin Hu (Connor) if (addr == NULL) { 452353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 452453ef1b34SMin Hu (Connor) "Cannot set ethdev port %u unicast hash table from NULL address\n", 452553ef1b34SMin Hu (Connor) port_id); 452653ef1b34SMin Hu (Connor) return -EINVAL; 452753ef1b34SMin Hu (Connor) } 452853ef1b34SMin Hu (Connor) 452999a2dd95SBruce Richardson if (rte_is_zero_ether_addr(addr)) { 453099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n", 453199a2dd95SBruce Richardson port_id); 453299a2dd95SBruce Richardson return -EINVAL; 453399a2dd95SBruce Richardson } 453499a2dd95SBruce Richardson 453599a2dd95SBruce Richardson index = eth_dev_get_hash_mac_addr_index(port_id, addr); 453699a2dd95SBruce Richardson /* Check if it's already there, and do nothing */ 453799a2dd95SBruce Richardson if ((index >= 0) && on) 453899a2dd95SBruce Richardson return 0; 453999a2dd95SBruce Richardson 454099a2dd95SBruce Richardson if (index < 0) { 454199a2dd95SBruce Richardson if (!on) { 454299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 454399a2dd95SBruce Richardson "Port %u: the MAC address was not set in UTA\n", 454499a2dd95SBruce Richardson port_id); 454599a2dd95SBruce Richardson return -EINVAL; 454699a2dd95SBruce Richardson } 454799a2dd95SBruce Richardson 454899a2dd95SBruce Richardson index = eth_dev_get_hash_mac_addr_index(port_id, &null_mac_addr); 454999a2dd95SBruce Richardson if (index < 0) { 455099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n", 455199a2dd95SBruce Richardson port_id); 455299a2dd95SBruce Richardson return -ENOSPC; 455399a2dd95SBruce Richardson } 455499a2dd95SBruce Richardson } 455599a2dd95SBruce Richardson 455699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_hash_table_set, -ENOTSUP); 455799a2dd95SBruce Richardson ret = (*dev->dev_ops->uc_hash_table_set)(dev, addr, on); 455899a2dd95SBruce Richardson if (ret == 0) { 455999a2dd95SBruce Richardson /* Update address in NIC data structure */ 456099a2dd95SBruce Richardson if (on) 456199a2dd95SBruce Richardson rte_ether_addr_copy(addr, 456299a2dd95SBruce Richardson &dev->data->hash_mac_addrs[index]); 456399a2dd95SBruce Richardson else 456499a2dd95SBruce Richardson rte_ether_addr_copy(&null_mac_addr, 456599a2dd95SBruce Richardson &dev->data->hash_mac_addrs[index]); 456699a2dd95SBruce Richardson } 456799a2dd95SBruce Richardson 456899a2dd95SBruce Richardson return eth_err(port_id, ret); 456999a2dd95SBruce Richardson } 457099a2dd95SBruce Richardson 457199a2dd95SBruce Richardson int 457299a2dd95SBruce Richardson rte_eth_dev_uc_all_hash_table_set(uint16_t port_id, uint8_t on) 457399a2dd95SBruce Richardson { 457499a2dd95SBruce Richardson struct rte_eth_dev *dev; 457599a2dd95SBruce Richardson 457699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 457799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 457899a2dd95SBruce Richardson 457999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_all_hash_table_set, -ENOTSUP); 458099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->uc_all_hash_table_set)(dev, 458199a2dd95SBruce Richardson on)); 458299a2dd95SBruce Richardson } 458399a2dd95SBruce Richardson 458499a2dd95SBruce Richardson int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx, 458599a2dd95SBruce Richardson uint16_t tx_rate) 458699a2dd95SBruce Richardson { 458799a2dd95SBruce Richardson struct rte_eth_dev *dev; 458899a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 458999a2dd95SBruce Richardson struct rte_eth_link link; 459099a2dd95SBruce Richardson int ret; 459199a2dd95SBruce Richardson 459299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 459353ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 459499a2dd95SBruce Richardson 459599a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 459699a2dd95SBruce Richardson if (ret != 0) 459799a2dd95SBruce Richardson return ret; 459899a2dd95SBruce Richardson 459999a2dd95SBruce Richardson link = dev->data->dev_link; 460099a2dd95SBruce Richardson 460199a2dd95SBruce Richardson if (queue_idx > dev_info.max_tx_queues) { 460299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 46035906be5aSAndrew Rybchenko "Set queue rate limit:port %u: invalid queue ID=%u\n", 460499a2dd95SBruce Richardson port_id, queue_idx); 460599a2dd95SBruce Richardson return -EINVAL; 460699a2dd95SBruce Richardson } 460799a2dd95SBruce Richardson 460899a2dd95SBruce Richardson if (tx_rate > link.link_speed) { 460999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 461099a2dd95SBruce Richardson "Set queue rate limit:invalid tx_rate=%u, bigger than link speed= %d\n", 461199a2dd95SBruce Richardson tx_rate, link.link_speed); 461299a2dd95SBruce Richardson return -EINVAL; 461399a2dd95SBruce Richardson } 461499a2dd95SBruce Richardson 461599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_queue_rate_limit, -ENOTSUP); 461699a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->set_queue_rate_limit)(dev, 461799a2dd95SBruce Richardson queue_idx, tx_rate)); 461899a2dd95SBruce Richardson } 461999a2dd95SBruce Richardson 4620c87d435aSKonstantin Ananyev RTE_INIT(eth_dev_init_fp_ops) 4621c87d435aSKonstantin Ananyev { 4622c87d435aSKonstantin Ananyev uint32_t i; 4623c87d435aSKonstantin Ananyev 4624c87d435aSKonstantin Ananyev for (i = 0; i != RTE_DIM(rte_eth_fp_ops); i++) 4625c87d435aSKonstantin Ananyev eth_dev_fp_ops_reset(rte_eth_fp_ops + i); 4626c87d435aSKonstantin Ananyev } 4627c87d435aSKonstantin Ananyev 462899a2dd95SBruce Richardson RTE_INIT(eth_dev_init_cb_lists) 462999a2dd95SBruce Richardson { 463099a2dd95SBruce Richardson uint16_t i; 463199a2dd95SBruce Richardson 463299a2dd95SBruce Richardson for (i = 0; i < RTE_MAX_ETHPORTS; i++) 463399a2dd95SBruce Richardson TAILQ_INIT(&rte_eth_devices[i].link_intr_cbs); 463499a2dd95SBruce Richardson } 463599a2dd95SBruce Richardson 463699a2dd95SBruce Richardson int 463799a2dd95SBruce Richardson rte_eth_dev_callback_register(uint16_t port_id, 463899a2dd95SBruce Richardson enum rte_eth_event_type event, 463999a2dd95SBruce Richardson rte_eth_dev_cb_fn cb_fn, void *cb_arg) 464099a2dd95SBruce Richardson { 464199a2dd95SBruce Richardson struct rte_eth_dev *dev; 464299a2dd95SBruce Richardson struct rte_eth_dev_callback *user_cb; 464399a2dd95SBruce Richardson uint16_t next_port; 464499a2dd95SBruce Richardson uint16_t last_port; 464599a2dd95SBruce Richardson 464653ef1b34SMin Hu (Connor) if (cb_fn == NULL) { 464753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 464853ef1b34SMin Hu (Connor) "Cannot register ethdev port %u callback from NULL\n", 464953ef1b34SMin Hu (Connor) port_id); 465099a2dd95SBruce Richardson return -EINVAL; 465153ef1b34SMin Hu (Connor) } 465299a2dd95SBruce Richardson 465399a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) { 465499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id); 465599a2dd95SBruce Richardson return -EINVAL; 465699a2dd95SBruce Richardson } 465799a2dd95SBruce Richardson 465899a2dd95SBruce Richardson if (port_id == RTE_ETH_ALL) { 465999a2dd95SBruce Richardson next_port = 0; 466099a2dd95SBruce Richardson last_port = RTE_MAX_ETHPORTS - 1; 466199a2dd95SBruce Richardson } else { 466299a2dd95SBruce Richardson next_port = last_port = port_id; 466399a2dd95SBruce Richardson } 466499a2dd95SBruce Richardson 466599a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_cb_lock); 466699a2dd95SBruce Richardson 466799a2dd95SBruce Richardson do { 466899a2dd95SBruce Richardson dev = &rte_eth_devices[next_port]; 466999a2dd95SBruce Richardson 467099a2dd95SBruce Richardson TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) { 467199a2dd95SBruce Richardson if (user_cb->cb_fn == cb_fn && 467299a2dd95SBruce Richardson user_cb->cb_arg == cb_arg && 467399a2dd95SBruce Richardson user_cb->event == event) { 467499a2dd95SBruce Richardson break; 467599a2dd95SBruce Richardson } 467699a2dd95SBruce Richardson } 467799a2dd95SBruce Richardson 467899a2dd95SBruce Richardson /* create a new callback. */ 467999a2dd95SBruce Richardson if (user_cb == NULL) { 468099a2dd95SBruce Richardson user_cb = rte_zmalloc("INTR_USER_CALLBACK", 468199a2dd95SBruce Richardson sizeof(struct rte_eth_dev_callback), 0); 468299a2dd95SBruce Richardson if (user_cb != NULL) { 468399a2dd95SBruce Richardson user_cb->cb_fn = cb_fn; 468499a2dd95SBruce Richardson user_cb->cb_arg = cb_arg; 468599a2dd95SBruce Richardson user_cb->event = event; 468699a2dd95SBruce Richardson TAILQ_INSERT_TAIL(&(dev->link_intr_cbs), 468799a2dd95SBruce Richardson user_cb, next); 468899a2dd95SBruce Richardson } else { 468999a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_cb_lock); 469099a2dd95SBruce Richardson rte_eth_dev_callback_unregister(port_id, event, 469199a2dd95SBruce Richardson cb_fn, cb_arg); 469299a2dd95SBruce Richardson return -ENOMEM; 469399a2dd95SBruce Richardson } 469499a2dd95SBruce Richardson 469599a2dd95SBruce Richardson } 469699a2dd95SBruce Richardson } while (++next_port <= last_port); 469799a2dd95SBruce Richardson 469899a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_cb_lock); 469999a2dd95SBruce Richardson return 0; 470099a2dd95SBruce Richardson } 470199a2dd95SBruce Richardson 470299a2dd95SBruce Richardson int 470399a2dd95SBruce Richardson rte_eth_dev_callback_unregister(uint16_t port_id, 470499a2dd95SBruce Richardson enum rte_eth_event_type event, 470599a2dd95SBruce Richardson rte_eth_dev_cb_fn cb_fn, void *cb_arg) 470699a2dd95SBruce Richardson { 470799a2dd95SBruce Richardson int ret; 470899a2dd95SBruce Richardson struct rte_eth_dev *dev; 470999a2dd95SBruce Richardson struct rte_eth_dev_callback *cb, *next; 471099a2dd95SBruce Richardson uint16_t next_port; 471199a2dd95SBruce Richardson uint16_t last_port; 471299a2dd95SBruce Richardson 471353ef1b34SMin Hu (Connor) if (cb_fn == NULL) { 471453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 471553ef1b34SMin Hu (Connor) "Cannot unregister ethdev port %u callback from NULL\n", 471653ef1b34SMin Hu (Connor) port_id); 471799a2dd95SBruce Richardson return -EINVAL; 471853ef1b34SMin Hu (Connor) } 471999a2dd95SBruce Richardson 472099a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) { 472199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id); 472299a2dd95SBruce Richardson return -EINVAL; 472399a2dd95SBruce Richardson } 472499a2dd95SBruce Richardson 472599a2dd95SBruce Richardson if (port_id == RTE_ETH_ALL) { 472699a2dd95SBruce Richardson next_port = 0; 472799a2dd95SBruce Richardson last_port = RTE_MAX_ETHPORTS - 1; 472899a2dd95SBruce Richardson } else { 472999a2dd95SBruce Richardson next_port = last_port = port_id; 473099a2dd95SBruce Richardson } 473199a2dd95SBruce Richardson 473299a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_cb_lock); 473399a2dd95SBruce Richardson 473499a2dd95SBruce Richardson do { 473599a2dd95SBruce Richardson dev = &rte_eth_devices[next_port]; 473699a2dd95SBruce Richardson ret = 0; 473799a2dd95SBruce Richardson for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL; 473899a2dd95SBruce Richardson cb = next) { 473999a2dd95SBruce Richardson 474099a2dd95SBruce Richardson next = TAILQ_NEXT(cb, next); 474199a2dd95SBruce Richardson 474299a2dd95SBruce Richardson if (cb->cb_fn != cb_fn || cb->event != event || 474399a2dd95SBruce Richardson (cb_arg != (void *)-1 && cb->cb_arg != cb_arg)) 474499a2dd95SBruce Richardson continue; 474599a2dd95SBruce Richardson 474699a2dd95SBruce Richardson /* 474799a2dd95SBruce Richardson * if this callback is not executing right now, 474899a2dd95SBruce Richardson * then remove it. 474999a2dd95SBruce Richardson */ 475099a2dd95SBruce Richardson if (cb->active == 0) { 475199a2dd95SBruce Richardson TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next); 475299a2dd95SBruce Richardson rte_free(cb); 475399a2dd95SBruce Richardson } else { 475499a2dd95SBruce Richardson ret = -EAGAIN; 475599a2dd95SBruce Richardson } 475699a2dd95SBruce Richardson } 475799a2dd95SBruce Richardson } while (++next_port <= last_port); 475899a2dd95SBruce Richardson 475999a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_cb_lock); 476099a2dd95SBruce Richardson return ret; 476199a2dd95SBruce Richardson } 476299a2dd95SBruce Richardson 476399a2dd95SBruce Richardson int 476499a2dd95SBruce Richardson rte_eth_dev_callback_process(struct rte_eth_dev *dev, 476599a2dd95SBruce Richardson enum rte_eth_event_type event, void *ret_param) 476699a2dd95SBruce Richardson { 476799a2dd95SBruce Richardson struct rte_eth_dev_callback *cb_lst; 476899a2dd95SBruce Richardson struct rte_eth_dev_callback dev_cb; 476999a2dd95SBruce Richardson int rc = 0; 477099a2dd95SBruce Richardson 477199a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_cb_lock); 477299a2dd95SBruce Richardson TAILQ_FOREACH(cb_lst, &(dev->link_intr_cbs), next) { 477399a2dd95SBruce Richardson if (cb_lst->cb_fn == NULL || cb_lst->event != event) 477499a2dd95SBruce Richardson continue; 477599a2dd95SBruce Richardson dev_cb = *cb_lst; 477699a2dd95SBruce Richardson cb_lst->active = 1; 477799a2dd95SBruce Richardson if (ret_param != NULL) 477899a2dd95SBruce Richardson dev_cb.ret_param = ret_param; 477999a2dd95SBruce Richardson 478099a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_cb_lock); 478199a2dd95SBruce Richardson rc = dev_cb.cb_fn(dev->data->port_id, dev_cb.event, 478299a2dd95SBruce Richardson dev_cb.cb_arg, dev_cb.ret_param); 478399a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_cb_lock); 478499a2dd95SBruce Richardson cb_lst->active = 0; 478599a2dd95SBruce Richardson } 478699a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_cb_lock); 478799a2dd95SBruce Richardson return rc; 478899a2dd95SBruce Richardson } 478999a2dd95SBruce Richardson 479099a2dd95SBruce Richardson void 479199a2dd95SBruce Richardson rte_eth_dev_probing_finish(struct rte_eth_dev *dev) 479299a2dd95SBruce Richardson { 479399a2dd95SBruce Richardson if (dev == NULL) 479499a2dd95SBruce Richardson return; 479599a2dd95SBruce Richardson 4796c87d435aSKonstantin Ananyev /* 4797c87d435aSKonstantin Ananyev * for secondary process, at that point we expect device 4798c87d435aSKonstantin Ananyev * to be already 'usable', so shared data and all function pointers 4799c87d435aSKonstantin Ananyev * for fast-path devops have to be setup properly inside rte_eth_dev. 4800c87d435aSKonstantin Ananyev */ 4801c87d435aSKonstantin Ananyev if (rte_eal_process_type() == RTE_PROC_SECONDARY) 4802c87d435aSKonstantin Ananyev eth_dev_fp_ops_setup(rte_eth_fp_ops + dev->data->port_id, dev); 4803c87d435aSKonstantin Ananyev 480499a2dd95SBruce Richardson rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_NEW, NULL); 480599a2dd95SBruce Richardson 480699a2dd95SBruce Richardson dev->state = RTE_ETH_DEV_ATTACHED; 480799a2dd95SBruce Richardson } 480899a2dd95SBruce Richardson 480999a2dd95SBruce Richardson int 481099a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data) 481199a2dd95SBruce Richardson { 481299a2dd95SBruce Richardson uint32_t vec; 481399a2dd95SBruce Richardson struct rte_eth_dev *dev; 481499a2dd95SBruce Richardson struct rte_intr_handle *intr_handle; 481599a2dd95SBruce Richardson uint16_t qid; 481699a2dd95SBruce Richardson int rc; 481799a2dd95SBruce Richardson 481899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 481999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 482099a2dd95SBruce Richardson 482199a2dd95SBruce Richardson if (!dev->intr_handle) { 482209fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr handle unset\n"); 482399a2dd95SBruce Richardson return -ENOTSUP; 482499a2dd95SBruce Richardson } 482599a2dd95SBruce Richardson 482699a2dd95SBruce Richardson intr_handle = dev->intr_handle; 4827c2bd9367SHarman Kalra if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { 482809fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n"); 482999a2dd95SBruce Richardson return -EPERM; 483099a2dd95SBruce Richardson } 483199a2dd95SBruce Richardson 483299a2dd95SBruce Richardson for (qid = 0; qid < dev->data->nb_rx_queues; qid++) { 4833c2bd9367SHarman Kalra vec = rte_intr_vec_list_index_get(intr_handle, qid); 483499a2dd95SBruce Richardson rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data); 483599a2dd95SBruce Richardson if (rc && rc != -EEXIST) { 483699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 483709fd4227SAndrew Rybchenko "p %u q %u Rx ctl error op %d epfd %d vec %u\n", 483899a2dd95SBruce Richardson port_id, qid, op, epfd, vec); 483999a2dd95SBruce Richardson } 484099a2dd95SBruce Richardson } 484199a2dd95SBruce Richardson 484299a2dd95SBruce Richardson return 0; 484399a2dd95SBruce Richardson } 484499a2dd95SBruce Richardson 484599a2dd95SBruce Richardson int 484699a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id, uint16_t queue_id) 484799a2dd95SBruce Richardson { 484899a2dd95SBruce Richardson struct rte_intr_handle *intr_handle; 484999a2dd95SBruce Richardson struct rte_eth_dev *dev; 485099a2dd95SBruce Richardson unsigned int efd_idx; 485199a2dd95SBruce Richardson uint32_t vec; 485299a2dd95SBruce Richardson int fd; 485399a2dd95SBruce Richardson 485499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); 485599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 485699a2dd95SBruce Richardson 485799a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 485809fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id); 485999a2dd95SBruce Richardson return -1; 486099a2dd95SBruce Richardson } 486199a2dd95SBruce Richardson 486299a2dd95SBruce Richardson if (!dev->intr_handle) { 486309fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr handle unset\n"); 486499a2dd95SBruce Richardson return -1; 486599a2dd95SBruce Richardson } 486699a2dd95SBruce Richardson 486799a2dd95SBruce Richardson intr_handle = dev->intr_handle; 4868c2bd9367SHarman Kalra if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { 486909fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n"); 487099a2dd95SBruce Richardson return -1; 487199a2dd95SBruce Richardson } 487299a2dd95SBruce Richardson 4873c2bd9367SHarman Kalra vec = rte_intr_vec_list_index_get(intr_handle, queue_id); 487499a2dd95SBruce Richardson efd_idx = (vec >= RTE_INTR_VEC_RXTX_OFFSET) ? 487599a2dd95SBruce Richardson (vec - RTE_INTR_VEC_RXTX_OFFSET) : vec; 4876c2bd9367SHarman Kalra fd = rte_intr_efds_index_get(intr_handle, efd_idx); 487799a2dd95SBruce Richardson 487899a2dd95SBruce Richardson return fd; 487999a2dd95SBruce Richardson } 488099a2dd95SBruce Richardson 488199a2dd95SBruce Richardson static inline int 488299a2dd95SBruce Richardson eth_dev_dma_mzone_name(char *name, size_t len, uint16_t port_id, uint16_t queue_id, 488399a2dd95SBruce Richardson const char *ring_name) 488499a2dd95SBruce Richardson { 488599a2dd95SBruce Richardson return snprintf(name, len, "eth_p%d_q%d_%s", 488699a2dd95SBruce Richardson port_id, queue_id, ring_name); 488799a2dd95SBruce Richardson } 488899a2dd95SBruce Richardson 488999a2dd95SBruce Richardson const struct rte_memzone * 489099a2dd95SBruce Richardson rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name, 489199a2dd95SBruce Richardson uint16_t queue_id, size_t size, unsigned align, 489299a2dd95SBruce Richardson int socket_id) 489399a2dd95SBruce Richardson { 489499a2dd95SBruce Richardson char z_name[RTE_MEMZONE_NAMESIZE]; 489599a2dd95SBruce Richardson const struct rte_memzone *mz; 489699a2dd95SBruce Richardson int rc; 489799a2dd95SBruce Richardson 489899a2dd95SBruce Richardson rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id, 489999a2dd95SBruce Richardson queue_id, ring_name); 490099a2dd95SBruce Richardson if (rc >= RTE_MEMZONE_NAMESIZE) { 490199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "ring name too long\n"); 490299a2dd95SBruce Richardson rte_errno = ENAMETOOLONG; 490399a2dd95SBruce Richardson return NULL; 490499a2dd95SBruce Richardson } 490599a2dd95SBruce Richardson 490699a2dd95SBruce Richardson mz = rte_memzone_lookup(z_name); 490799a2dd95SBruce Richardson if (mz) { 490899a2dd95SBruce Richardson if ((socket_id != SOCKET_ID_ANY && socket_id != mz->socket_id) || 490999a2dd95SBruce Richardson size > mz->len || 491099a2dd95SBruce Richardson ((uintptr_t)mz->addr & (align - 1)) != 0) { 491199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 491299a2dd95SBruce Richardson "memzone %s does not justify the requested attributes\n", 491399a2dd95SBruce Richardson mz->name); 491499a2dd95SBruce Richardson return NULL; 491599a2dd95SBruce Richardson } 491699a2dd95SBruce Richardson 491799a2dd95SBruce Richardson return mz; 491899a2dd95SBruce Richardson } 491999a2dd95SBruce Richardson 492099a2dd95SBruce Richardson return rte_memzone_reserve_aligned(z_name, size, socket_id, 492199a2dd95SBruce Richardson RTE_MEMZONE_IOVA_CONTIG, align); 492299a2dd95SBruce Richardson } 492399a2dd95SBruce Richardson 492499a2dd95SBruce Richardson int 492599a2dd95SBruce Richardson rte_eth_dma_zone_free(const struct rte_eth_dev *dev, const char *ring_name, 492699a2dd95SBruce Richardson uint16_t queue_id) 492799a2dd95SBruce Richardson { 492899a2dd95SBruce Richardson char z_name[RTE_MEMZONE_NAMESIZE]; 492999a2dd95SBruce Richardson const struct rte_memzone *mz; 493099a2dd95SBruce Richardson int rc = 0; 493199a2dd95SBruce Richardson 493299a2dd95SBruce Richardson rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id, 493399a2dd95SBruce Richardson queue_id, ring_name); 493499a2dd95SBruce Richardson if (rc >= RTE_MEMZONE_NAMESIZE) { 493599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "ring name too long\n"); 493699a2dd95SBruce Richardson return -ENAMETOOLONG; 493799a2dd95SBruce Richardson } 493899a2dd95SBruce Richardson 493999a2dd95SBruce Richardson mz = rte_memzone_lookup(z_name); 494099a2dd95SBruce Richardson if (mz) 494199a2dd95SBruce Richardson rc = rte_memzone_free(mz); 494299a2dd95SBruce Richardson else 494399a2dd95SBruce Richardson rc = -ENOENT; 494499a2dd95SBruce Richardson 494599a2dd95SBruce Richardson return rc; 494699a2dd95SBruce Richardson } 494799a2dd95SBruce Richardson 494899a2dd95SBruce Richardson int 494999a2dd95SBruce Richardson rte_eth_dev_create(struct rte_device *device, const char *name, 495099a2dd95SBruce Richardson size_t priv_data_size, 495199a2dd95SBruce Richardson ethdev_bus_specific_init ethdev_bus_specific_init, 495299a2dd95SBruce Richardson void *bus_init_params, 495399a2dd95SBruce Richardson ethdev_init_t ethdev_init, void *init_params) 495499a2dd95SBruce Richardson { 495599a2dd95SBruce Richardson struct rte_eth_dev *ethdev; 495699a2dd95SBruce Richardson int retval; 495799a2dd95SBruce Richardson 495899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL); 495999a2dd95SBruce Richardson 496099a2dd95SBruce Richardson if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 496199a2dd95SBruce Richardson ethdev = rte_eth_dev_allocate(name); 496299a2dd95SBruce Richardson if (!ethdev) 496399a2dd95SBruce Richardson return -ENODEV; 496499a2dd95SBruce Richardson 496599a2dd95SBruce Richardson if (priv_data_size) { 496699a2dd95SBruce Richardson ethdev->data->dev_private = rte_zmalloc_socket( 496799a2dd95SBruce Richardson name, priv_data_size, RTE_CACHE_LINE_SIZE, 496899a2dd95SBruce Richardson device->numa_node); 496999a2dd95SBruce Richardson 497099a2dd95SBruce Richardson if (!ethdev->data->dev_private) { 497199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 497299a2dd95SBruce Richardson "failed to allocate private data\n"); 497399a2dd95SBruce Richardson retval = -ENOMEM; 497499a2dd95SBruce Richardson goto probe_failed; 497599a2dd95SBruce Richardson } 497699a2dd95SBruce Richardson } 497799a2dd95SBruce Richardson } else { 497899a2dd95SBruce Richardson ethdev = rte_eth_dev_attach_secondary(name); 497999a2dd95SBruce Richardson if (!ethdev) { 498099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 498199a2dd95SBruce Richardson "secondary process attach failed, ethdev doesn't exist\n"); 498299a2dd95SBruce Richardson return -ENODEV; 498399a2dd95SBruce Richardson } 498499a2dd95SBruce Richardson } 498599a2dd95SBruce Richardson 498699a2dd95SBruce Richardson ethdev->device = device; 498799a2dd95SBruce Richardson 498899a2dd95SBruce Richardson if (ethdev_bus_specific_init) { 498999a2dd95SBruce Richardson retval = ethdev_bus_specific_init(ethdev, bus_init_params); 499099a2dd95SBruce Richardson if (retval) { 499199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 499299a2dd95SBruce Richardson "ethdev bus specific initialisation failed\n"); 499399a2dd95SBruce Richardson goto probe_failed; 499499a2dd95SBruce Richardson } 499599a2dd95SBruce Richardson } 499699a2dd95SBruce Richardson 499799a2dd95SBruce Richardson retval = ethdev_init(ethdev, init_params); 499899a2dd95SBruce Richardson if (retval) { 499999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "ethdev initialisation failed\n"); 500099a2dd95SBruce Richardson goto probe_failed; 500199a2dd95SBruce Richardson } 500299a2dd95SBruce Richardson 500399a2dd95SBruce Richardson rte_eth_dev_probing_finish(ethdev); 500499a2dd95SBruce Richardson 500599a2dd95SBruce Richardson return retval; 500699a2dd95SBruce Richardson 500799a2dd95SBruce Richardson probe_failed: 500899a2dd95SBruce Richardson rte_eth_dev_release_port(ethdev); 500999a2dd95SBruce Richardson return retval; 501099a2dd95SBruce Richardson } 501199a2dd95SBruce Richardson 501299a2dd95SBruce Richardson int 501399a2dd95SBruce Richardson rte_eth_dev_destroy(struct rte_eth_dev *ethdev, 501499a2dd95SBruce Richardson ethdev_uninit_t ethdev_uninit) 501599a2dd95SBruce Richardson { 501699a2dd95SBruce Richardson int ret; 501799a2dd95SBruce Richardson 501899a2dd95SBruce Richardson ethdev = rte_eth_dev_allocated(ethdev->data->name); 501999a2dd95SBruce Richardson if (!ethdev) 502099a2dd95SBruce Richardson return -ENODEV; 502199a2dd95SBruce Richardson 502299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL); 502399a2dd95SBruce Richardson 502499a2dd95SBruce Richardson ret = ethdev_uninit(ethdev); 502599a2dd95SBruce Richardson if (ret) 502699a2dd95SBruce Richardson return ret; 502799a2dd95SBruce Richardson 502899a2dd95SBruce Richardson return rte_eth_dev_release_port(ethdev); 502999a2dd95SBruce Richardson } 503099a2dd95SBruce Richardson 503199a2dd95SBruce Richardson int 503299a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id, 503399a2dd95SBruce Richardson int epfd, int op, void *data) 503499a2dd95SBruce Richardson { 503599a2dd95SBruce Richardson uint32_t vec; 503699a2dd95SBruce Richardson struct rte_eth_dev *dev; 503799a2dd95SBruce Richardson struct rte_intr_handle *intr_handle; 503899a2dd95SBruce Richardson int rc; 503999a2dd95SBruce Richardson 504099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 504199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 504253ef1b34SMin Hu (Connor) 504399a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 504409fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id); 504599a2dd95SBruce Richardson return -EINVAL; 504699a2dd95SBruce Richardson } 504799a2dd95SBruce Richardson 504899a2dd95SBruce Richardson if (!dev->intr_handle) { 504909fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr handle unset\n"); 505099a2dd95SBruce Richardson return -ENOTSUP; 505199a2dd95SBruce Richardson } 505299a2dd95SBruce Richardson 505399a2dd95SBruce Richardson intr_handle = dev->intr_handle; 5054c2bd9367SHarman Kalra if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { 505509fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n"); 505699a2dd95SBruce Richardson return -EPERM; 505799a2dd95SBruce Richardson } 505899a2dd95SBruce Richardson 5059c2bd9367SHarman Kalra vec = rte_intr_vec_list_index_get(intr_handle, queue_id); 506099a2dd95SBruce Richardson rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data); 506199a2dd95SBruce Richardson if (rc && rc != -EEXIST) { 506299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 506309fd4227SAndrew Rybchenko "p %u q %u Rx ctl error op %d epfd %d vec %u\n", 506499a2dd95SBruce Richardson port_id, queue_id, op, epfd, vec); 506599a2dd95SBruce Richardson return rc; 506699a2dd95SBruce Richardson } 506799a2dd95SBruce Richardson 506899a2dd95SBruce Richardson return 0; 506999a2dd95SBruce Richardson } 507099a2dd95SBruce Richardson 507199a2dd95SBruce Richardson int 507299a2dd95SBruce Richardson rte_eth_dev_rx_intr_enable(uint16_t port_id, 507399a2dd95SBruce Richardson uint16_t queue_id) 507499a2dd95SBruce Richardson { 507599a2dd95SBruce Richardson struct rte_eth_dev *dev; 507699a2dd95SBruce Richardson int ret; 507799a2dd95SBruce Richardson 507899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 507999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 508099a2dd95SBruce Richardson 508199a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, queue_id); 508299a2dd95SBruce Richardson if (ret != 0) 508399a2dd95SBruce Richardson return ret; 508499a2dd95SBruce Richardson 508599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_enable, -ENOTSUP); 508653ef1b34SMin Hu (Connor) return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_enable)(dev, queue_id)); 508799a2dd95SBruce Richardson } 508899a2dd95SBruce Richardson 508999a2dd95SBruce Richardson int 509099a2dd95SBruce Richardson rte_eth_dev_rx_intr_disable(uint16_t port_id, 509199a2dd95SBruce Richardson uint16_t queue_id) 509299a2dd95SBruce Richardson { 509399a2dd95SBruce Richardson struct rte_eth_dev *dev; 509499a2dd95SBruce Richardson int ret; 509599a2dd95SBruce Richardson 509699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 509799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 509899a2dd95SBruce Richardson 509999a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, queue_id); 510099a2dd95SBruce Richardson if (ret != 0) 510199a2dd95SBruce Richardson return ret; 510299a2dd95SBruce Richardson 510399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_disable, -ENOTSUP); 510453ef1b34SMin Hu (Connor) return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_disable)(dev, queue_id)); 510599a2dd95SBruce Richardson } 510699a2dd95SBruce Richardson 510799a2dd95SBruce Richardson 510899a2dd95SBruce Richardson const struct rte_eth_rxtx_callback * 510999a2dd95SBruce Richardson rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id, 511099a2dd95SBruce Richardson rte_rx_callback_fn fn, void *user_param) 511199a2dd95SBruce Richardson { 511299a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 511399a2dd95SBruce Richardson rte_errno = ENOTSUP; 511499a2dd95SBruce Richardson return NULL; 511599a2dd95SBruce Richardson #endif 511699a2dd95SBruce Richardson struct rte_eth_dev *dev; 511799a2dd95SBruce Richardson 511899a2dd95SBruce Richardson /* check input parameters */ 511999a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 512099a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) { 512199a2dd95SBruce Richardson rte_errno = EINVAL; 512299a2dd95SBruce Richardson return NULL; 512399a2dd95SBruce Richardson } 512499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 512599a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) { 512699a2dd95SBruce Richardson rte_errno = EINVAL; 512799a2dd95SBruce Richardson return NULL; 512899a2dd95SBruce Richardson } 512999a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 513099a2dd95SBruce Richardson 513199a2dd95SBruce Richardson if (cb == NULL) { 513299a2dd95SBruce Richardson rte_errno = ENOMEM; 513399a2dd95SBruce Richardson return NULL; 513499a2dd95SBruce Richardson } 513599a2dd95SBruce Richardson 513699a2dd95SBruce Richardson cb->fn.rx = fn; 513799a2dd95SBruce Richardson cb->param = user_param; 513899a2dd95SBruce Richardson 513999a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_rx_cb_lock); 514099a2dd95SBruce Richardson /* Add the callbacks in fifo order. */ 514199a2dd95SBruce Richardson struct rte_eth_rxtx_callback *tail = 514299a2dd95SBruce Richardson rte_eth_devices[port_id].post_rx_burst_cbs[queue_id]; 514399a2dd95SBruce Richardson 514499a2dd95SBruce Richardson if (!tail) { 514599a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 514699a2dd95SBruce Richardson * cb is visible to data plane. 514799a2dd95SBruce Richardson */ 514899a2dd95SBruce Richardson __atomic_store_n( 514999a2dd95SBruce Richardson &rte_eth_devices[port_id].post_rx_burst_cbs[queue_id], 515099a2dd95SBruce Richardson cb, __ATOMIC_RELEASE); 515199a2dd95SBruce Richardson 515299a2dd95SBruce Richardson } else { 515399a2dd95SBruce Richardson while (tail->next) 515499a2dd95SBruce Richardson tail = tail->next; 515599a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 515699a2dd95SBruce Richardson * cb is visible to data plane. 515799a2dd95SBruce Richardson */ 515899a2dd95SBruce Richardson __atomic_store_n(&tail->next, cb, __ATOMIC_RELEASE); 515999a2dd95SBruce Richardson } 516099a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_rx_cb_lock); 516199a2dd95SBruce Richardson 516299a2dd95SBruce Richardson return cb; 516399a2dd95SBruce Richardson } 516499a2dd95SBruce Richardson 516599a2dd95SBruce Richardson const struct rte_eth_rxtx_callback * 516699a2dd95SBruce Richardson rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id, 516799a2dd95SBruce Richardson rte_rx_callback_fn fn, void *user_param) 516899a2dd95SBruce Richardson { 516999a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 517099a2dd95SBruce Richardson rte_errno = ENOTSUP; 517199a2dd95SBruce Richardson return NULL; 517299a2dd95SBruce Richardson #endif 517399a2dd95SBruce Richardson /* check input parameters */ 517499a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 517599a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) { 517699a2dd95SBruce Richardson rte_errno = EINVAL; 517799a2dd95SBruce Richardson return NULL; 517899a2dd95SBruce Richardson } 517999a2dd95SBruce Richardson 518099a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 518199a2dd95SBruce Richardson 518299a2dd95SBruce Richardson if (cb == NULL) { 518399a2dd95SBruce Richardson rte_errno = ENOMEM; 518499a2dd95SBruce Richardson return NULL; 518599a2dd95SBruce Richardson } 518699a2dd95SBruce Richardson 518799a2dd95SBruce Richardson cb->fn.rx = fn; 518899a2dd95SBruce Richardson cb->param = user_param; 518999a2dd95SBruce Richardson 519099a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_rx_cb_lock); 519199a2dd95SBruce Richardson /* Add the callbacks at first position */ 519299a2dd95SBruce Richardson cb->next = rte_eth_devices[port_id].post_rx_burst_cbs[queue_id]; 519399a2dd95SBruce Richardson /* Stores to cb->fn, cb->param and cb->next should complete before 519499a2dd95SBruce Richardson * cb is visible to data plane threads. 519599a2dd95SBruce Richardson */ 519699a2dd95SBruce Richardson __atomic_store_n( 519799a2dd95SBruce Richardson &rte_eth_devices[port_id].post_rx_burst_cbs[queue_id], 519899a2dd95SBruce Richardson cb, __ATOMIC_RELEASE); 519999a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_rx_cb_lock); 520099a2dd95SBruce Richardson 520199a2dd95SBruce Richardson return cb; 520299a2dd95SBruce Richardson } 520399a2dd95SBruce Richardson 520499a2dd95SBruce Richardson const struct rte_eth_rxtx_callback * 520599a2dd95SBruce Richardson rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id, 520699a2dd95SBruce Richardson rte_tx_callback_fn fn, void *user_param) 520799a2dd95SBruce Richardson { 520899a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 520999a2dd95SBruce Richardson rte_errno = ENOTSUP; 521099a2dd95SBruce Richardson return NULL; 521199a2dd95SBruce Richardson #endif 521299a2dd95SBruce Richardson struct rte_eth_dev *dev; 521399a2dd95SBruce Richardson 521499a2dd95SBruce Richardson /* check input parameters */ 521599a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 521699a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) { 521799a2dd95SBruce Richardson rte_errno = EINVAL; 521899a2dd95SBruce Richardson return NULL; 521999a2dd95SBruce Richardson } 522099a2dd95SBruce Richardson 522199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 522299a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) { 522399a2dd95SBruce Richardson rte_errno = EINVAL; 522499a2dd95SBruce Richardson return NULL; 522599a2dd95SBruce Richardson } 522699a2dd95SBruce Richardson 522799a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 522899a2dd95SBruce Richardson 522999a2dd95SBruce Richardson if (cb == NULL) { 523099a2dd95SBruce Richardson rte_errno = ENOMEM; 523199a2dd95SBruce Richardson return NULL; 523299a2dd95SBruce Richardson } 523399a2dd95SBruce Richardson 523499a2dd95SBruce Richardson cb->fn.tx = fn; 523599a2dd95SBruce Richardson cb->param = user_param; 523699a2dd95SBruce Richardson 523799a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_tx_cb_lock); 523899a2dd95SBruce Richardson /* Add the callbacks in fifo order. */ 523999a2dd95SBruce Richardson struct rte_eth_rxtx_callback *tail = 524099a2dd95SBruce Richardson rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id]; 524199a2dd95SBruce Richardson 524299a2dd95SBruce Richardson if (!tail) { 524399a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 524499a2dd95SBruce Richardson * cb is visible to data plane. 524599a2dd95SBruce Richardson */ 524699a2dd95SBruce Richardson __atomic_store_n( 524799a2dd95SBruce Richardson &rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id], 524899a2dd95SBruce Richardson cb, __ATOMIC_RELEASE); 524999a2dd95SBruce Richardson 525099a2dd95SBruce Richardson } else { 525199a2dd95SBruce Richardson while (tail->next) 525299a2dd95SBruce Richardson tail = tail->next; 525399a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 525499a2dd95SBruce Richardson * cb is visible to data plane. 525599a2dd95SBruce Richardson */ 525699a2dd95SBruce Richardson __atomic_store_n(&tail->next, cb, __ATOMIC_RELEASE); 525799a2dd95SBruce Richardson } 525899a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_tx_cb_lock); 525999a2dd95SBruce Richardson 526099a2dd95SBruce Richardson return cb; 526199a2dd95SBruce Richardson } 526299a2dd95SBruce Richardson 526399a2dd95SBruce Richardson int 526499a2dd95SBruce Richardson rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id, 526599a2dd95SBruce Richardson const struct rte_eth_rxtx_callback *user_cb) 526699a2dd95SBruce Richardson { 526799a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 526899a2dd95SBruce Richardson return -ENOTSUP; 526999a2dd95SBruce Richardson #endif 527099a2dd95SBruce Richardson /* Check input parameters. */ 527199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 527299a2dd95SBruce Richardson if (user_cb == NULL || 527399a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) 527499a2dd95SBruce Richardson return -EINVAL; 527599a2dd95SBruce Richardson 527699a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 527799a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb; 527899a2dd95SBruce Richardson struct rte_eth_rxtx_callback **prev_cb; 527999a2dd95SBruce Richardson int ret = -EINVAL; 528099a2dd95SBruce Richardson 528199a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_rx_cb_lock); 528299a2dd95SBruce Richardson prev_cb = &dev->post_rx_burst_cbs[queue_id]; 528399a2dd95SBruce Richardson for (; *prev_cb != NULL; prev_cb = &cb->next) { 528499a2dd95SBruce Richardson cb = *prev_cb; 528599a2dd95SBruce Richardson if (cb == user_cb) { 528699a2dd95SBruce Richardson /* Remove the user cb from the callback list. */ 528799a2dd95SBruce Richardson __atomic_store_n(prev_cb, cb->next, __ATOMIC_RELAXED); 528899a2dd95SBruce Richardson ret = 0; 528999a2dd95SBruce Richardson break; 529099a2dd95SBruce Richardson } 529199a2dd95SBruce Richardson } 529299a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_rx_cb_lock); 529399a2dd95SBruce Richardson 529499a2dd95SBruce Richardson return ret; 529599a2dd95SBruce Richardson } 529699a2dd95SBruce Richardson 529799a2dd95SBruce Richardson int 529899a2dd95SBruce Richardson rte_eth_remove_tx_callback(uint16_t port_id, uint16_t queue_id, 529999a2dd95SBruce Richardson const struct rte_eth_rxtx_callback *user_cb) 530099a2dd95SBruce Richardson { 530199a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 530299a2dd95SBruce Richardson return -ENOTSUP; 530399a2dd95SBruce Richardson #endif 530499a2dd95SBruce Richardson /* Check input parameters. */ 530599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 530699a2dd95SBruce Richardson if (user_cb == NULL || 530799a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) 530899a2dd95SBruce Richardson return -EINVAL; 530999a2dd95SBruce Richardson 531099a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 531199a2dd95SBruce Richardson int ret = -EINVAL; 531299a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb; 531399a2dd95SBruce Richardson struct rte_eth_rxtx_callback **prev_cb; 531499a2dd95SBruce Richardson 531599a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_tx_cb_lock); 531699a2dd95SBruce Richardson prev_cb = &dev->pre_tx_burst_cbs[queue_id]; 531799a2dd95SBruce Richardson for (; *prev_cb != NULL; prev_cb = &cb->next) { 531899a2dd95SBruce Richardson cb = *prev_cb; 531999a2dd95SBruce Richardson if (cb == user_cb) { 532099a2dd95SBruce Richardson /* Remove the user cb from the callback list. */ 532199a2dd95SBruce Richardson __atomic_store_n(prev_cb, cb->next, __ATOMIC_RELAXED); 532299a2dd95SBruce Richardson ret = 0; 532399a2dd95SBruce Richardson break; 532499a2dd95SBruce Richardson } 532599a2dd95SBruce Richardson } 532699a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_tx_cb_lock); 532799a2dd95SBruce Richardson 532899a2dd95SBruce Richardson return ret; 532999a2dd95SBruce Richardson } 533099a2dd95SBruce Richardson 533199a2dd95SBruce Richardson int 533299a2dd95SBruce Richardson rte_eth_rx_queue_info_get(uint16_t port_id, uint16_t queue_id, 533399a2dd95SBruce Richardson struct rte_eth_rxq_info *qinfo) 533499a2dd95SBruce Richardson { 533599a2dd95SBruce Richardson struct rte_eth_dev *dev; 533699a2dd95SBruce Richardson 533799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 533899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 533953ef1b34SMin Hu (Connor) 534099a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 534109fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id); 534299a2dd95SBruce Richardson return -EINVAL; 534399a2dd95SBruce Richardson } 534499a2dd95SBruce Richardson 534553ef1b34SMin Hu (Connor) if (qinfo == NULL) { 534653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u Rx queue %u info to NULL\n", 534753ef1b34SMin Hu (Connor) port_id, queue_id); 534853ef1b34SMin Hu (Connor) return -EINVAL; 534953ef1b34SMin Hu (Connor) } 535053ef1b34SMin Hu (Connor) 535199a2dd95SBruce Richardson if (dev->data->rx_queues == NULL || 535299a2dd95SBruce Richardson dev->data->rx_queues[queue_id] == NULL) { 535399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 535499a2dd95SBruce Richardson "Rx queue %"PRIu16" of device with port_id=%" 535599a2dd95SBruce Richardson PRIu16" has not been setup\n", 535699a2dd95SBruce Richardson queue_id, port_id); 535799a2dd95SBruce Richardson return -EINVAL; 535899a2dd95SBruce Richardson } 535999a2dd95SBruce Richardson 536099a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) { 536199a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 536299a2dd95SBruce Richardson "Can't get hairpin Rx queue %"PRIu16" info of device with port_id=%"PRIu16"\n", 536399a2dd95SBruce Richardson queue_id, port_id); 536499a2dd95SBruce Richardson return -EINVAL; 536599a2dd95SBruce Richardson } 536699a2dd95SBruce Richardson 536799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rxq_info_get, -ENOTSUP); 536899a2dd95SBruce Richardson 536999a2dd95SBruce Richardson memset(qinfo, 0, sizeof(*qinfo)); 537099a2dd95SBruce Richardson dev->dev_ops->rxq_info_get(dev, queue_id, qinfo); 53719ad9ff47SLijun Ou qinfo->queue_state = dev->data->rx_queue_state[queue_id]; 53729ad9ff47SLijun Ou 537399a2dd95SBruce Richardson return 0; 537499a2dd95SBruce Richardson } 537599a2dd95SBruce Richardson 537699a2dd95SBruce Richardson int 537799a2dd95SBruce Richardson rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id, 537899a2dd95SBruce Richardson struct rte_eth_txq_info *qinfo) 537999a2dd95SBruce Richardson { 538099a2dd95SBruce Richardson struct rte_eth_dev *dev; 538199a2dd95SBruce Richardson 538299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 538399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 538453ef1b34SMin Hu (Connor) 538599a2dd95SBruce Richardson if (queue_id >= dev->data->nb_tx_queues) { 538609fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", queue_id); 538799a2dd95SBruce Richardson return -EINVAL; 538899a2dd95SBruce Richardson } 538999a2dd95SBruce Richardson 539053ef1b34SMin Hu (Connor) if (qinfo == NULL) { 539153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u Tx queue %u info to NULL\n", 539253ef1b34SMin Hu (Connor) port_id, queue_id); 539353ef1b34SMin Hu (Connor) return -EINVAL; 539453ef1b34SMin Hu (Connor) } 539553ef1b34SMin Hu (Connor) 539699a2dd95SBruce Richardson if (dev->data->tx_queues == NULL || 539799a2dd95SBruce Richardson dev->data->tx_queues[queue_id] == NULL) { 539899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 539999a2dd95SBruce Richardson "Tx queue %"PRIu16" of device with port_id=%" 540099a2dd95SBruce Richardson PRIu16" has not been setup\n", 540199a2dd95SBruce Richardson queue_id, port_id); 540299a2dd95SBruce Richardson return -EINVAL; 540399a2dd95SBruce Richardson } 540499a2dd95SBruce Richardson 540599a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) { 540699a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 540799a2dd95SBruce Richardson "Can't get hairpin Tx queue %"PRIu16" info of device with port_id=%"PRIu16"\n", 540899a2dd95SBruce Richardson queue_id, port_id); 540999a2dd95SBruce Richardson return -EINVAL; 541099a2dd95SBruce Richardson } 541199a2dd95SBruce Richardson 541299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->txq_info_get, -ENOTSUP); 541399a2dd95SBruce Richardson 541499a2dd95SBruce Richardson memset(qinfo, 0, sizeof(*qinfo)); 541599a2dd95SBruce Richardson dev->dev_ops->txq_info_get(dev, queue_id, qinfo); 54169ad9ff47SLijun Ou qinfo->queue_state = dev->data->tx_queue_state[queue_id]; 541799a2dd95SBruce Richardson 541899a2dd95SBruce Richardson return 0; 541999a2dd95SBruce Richardson } 542099a2dd95SBruce Richardson 542199a2dd95SBruce Richardson int 542299a2dd95SBruce Richardson rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id, 542399a2dd95SBruce Richardson struct rte_eth_burst_mode *mode) 542499a2dd95SBruce Richardson { 542599a2dd95SBruce Richardson struct rte_eth_dev *dev; 542699a2dd95SBruce Richardson 542799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 542899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 542999a2dd95SBruce Richardson 543099a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 543109fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id); 543299a2dd95SBruce Richardson return -EINVAL; 543399a2dd95SBruce Richardson } 543499a2dd95SBruce Richardson 543553ef1b34SMin Hu (Connor) if (mode == NULL) { 543653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 543753ef1b34SMin Hu (Connor) "Cannot get ethdev port %u Rx queue %u burst mode to NULL\n", 543853ef1b34SMin Hu (Connor) port_id, queue_id); 543953ef1b34SMin Hu (Connor) return -EINVAL; 544053ef1b34SMin Hu (Connor) } 544153ef1b34SMin Hu (Connor) 544299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_burst_mode_get, -ENOTSUP); 544399a2dd95SBruce Richardson memset(mode, 0, sizeof(*mode)); 544499a2dd95SBruce Richardson return eth_err(port_id, 544599a2dd95SBruce Richardson dev->dev_ops->rx_burst_mode_get(dev, queue_id, mode)); 544699a2dd95SBruce Richardson } 544799a2dd95SBruce Richardson 544899a2dd95SBruce Richardson int 544999a2dd95SBruce Richardson rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id, 545099a2dd95SBruce Richardson struct rte_eth_burst_mode *mode) 545199a2dd95SBruce Richardson { 545299a2dd95SBruce Richardson struct rte_eth_dev *dev; 545399a2dd95SBruce Richardson 545499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 545599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 545699a2dd95SBruce Richardson 545799a2dd95SBruce Richardson if (queue_id >= dev->data->nb_tx_queues) { 545809fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", queue_id); 545999a2dd95SBruce Richardson return -EINVAL; 546099a2dd95SBruce Richardson } 546199a2dd95SBruce Richardson 546253ef1b34SMin Hu (Connor) if (mode == NULL) { 546353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 546453ef1b34SMin Hu (Connor) "Cannot get ethdev port %u Tx queue %u burst mode to NULL\n", 546553ef1b34SMin Hu (Connor) port_id, queue_id); 546653ef1b34SMin Hu (Connor) return -EINVAL; 546753ef1b34SMin Hu (Connor) } 546853ef1b34SMin Hu (Connor) 546999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_burst_mode_get, -ENOTSUP); 547099a2dd95SBruce Richardson memset(mode, 0, sizeof(*mode)); 547199a2dd95SBruce Richardson return eth_err(port_id, 547299a2dd95SBruce Richardson dev->dev_ops->tx_burst_mode_get(dev, queue_id, mode)); 547399a2dd95SBruce Richardson } 547499a2dd95SBruce Richardson 547599a2dd95SBruce Richardson int 547699a2dd95SBruce Richardson rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id, 547799a2dd95SBruce Richardson struct rte_power_monitor_cond *pmc) 547899a2dd95SBruce Richardson { 547999a2dd95SBruce Richardson struct rte_eth_dev *dev; 548099a2dd95SBruce Richardson 548199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 548299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 548399a2dd95SBruce Richardson 548499a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 548599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id); 548699a2dd95SBruce Richardson return -EINVAL; 548799a2dd95SBruce Richardson } 548899a2dd95SBruce Richardson 548999a2dd95SBruce Richardson if (pmc == NULL) { 549053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 549153ef1b34SMin Hu (Connor) "Cannot get ethdev port %u Rx queue %u power monitor condition to NULL\n", 549253ef1b34SMin Hu (Connor) port_id, queue_id); 549399a2dd95SBruce Richardson return -EINVAL; 549499a2dd95SBruce Richardson } 549599a2dd95SBruce Richardson 549653ef1b34SMin Hu (Connor) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_monitor_addr, -ENOTSUP); 549799a2dd95SBruce Richardson return eth_err(port_id, 549853ef1b34SMin Hu (Connor) dev->dev_ops->get_monitor_addr(dev->data->rx_queues[queue_id], pmc)); 549999a2dd95SBruce Richardson } 550099a2dd95SBruce Richardson 550199a2dd95SBruce Richardson int 550299a2dd95SBruce Richardson rte_eth_dev_set_mc_addr_list(uint16_t port_id, 550399a2dd95SBruce Richardson struct rte_ether_addr *mc_addr_set, 550499a2dd95SBruce Richardson uint32_t nb_mc_addr) 550599a2dd95SBruce Richardson { 550699a2dd95SBruce Richardson struct rte_eth_dev *dev; 550799a2dd95SBruce Richardson 550899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 550999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 551053ef1b34SMin Hu (Connor) 551199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_mc_addr_list, -ENOTSUP); 551299a2dd95SBruce Richardson return eth_err(port_id, dev->dev_ops->set_mc_addr_list(dev, 551399a2dd95SBruce Richardson mc_addr_set, nb_mc_addr)); 551499a2dd95SBruce Richardson } 551599a2dd95SBruce Richardson 551699a2dd95SBruce Richardson int 551799a2dd95SBruce Richardson rte_eth_timesync_enable(uint16_t port_id) 551899a2dd95SBruce Richardson { 551999a2dd95SBruce Richardson struct rte_eth_dev *dev; 552099a2dd95SBruce Richardson 552199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 552299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 552399a2dd95SBruce Richardson 552499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_enable, -ENOTSUP); 552599a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_enable)(dev)); 552699a2dd95SBruce Richardson } 552799a2dd95SBruce Richardson 552899a2dd95SBruce Richardson int 552999a2dd95SBruce Richardson rte_eth_timesync_disable(uint16_t port_id) 553099a2dd95SBruce Richardson { 553199a2dd95SBruce Richardson struct rte_eth_dev *dev; 553299a2dd95SBruce Richardson 553399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 553499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 553599a2dd95SBruce Richardson 553699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_disable, -ENOTSUP); 553799a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_disable)(dev)); 553899a2dd95SBruce Richardson } 553999a2dd95SBruce Richardson 554099a2dd95SBruce Richardson int 554199a2dd95SBruce Richardson rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp, 554299a2dd95SBruce Richardson uint32_t flags) 554399a2dd95SBruce Richardson { 554499a2dd95SBruce Richardson struct rte_eth_dev *dev; 554599a2dd95SBruce Richardson 554699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 554799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 554899a2dd95SBruce Richardson 554953ef1b34SMin Hu (Connor) if (timestamp == NULL) { 555053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 555153ef1b34SMin Hu (Connor) "Cannot read ethdev port %u Rx timestamp to NULL\n", 555253ef1b34SMin Hu (Connor) port_id); 555353ef1b34SMin Hu (Connor) return -EINVAL; 555453ef1b34SMin Hu (Connor) } 555553ef1b34SMin Hu (Connor) 555699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP); 555799a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp) 555899a2dd95SBruce Richardson (dev, timestamp, flags)); 555999a2dd95SBruce Richardson } 556099a2dd95SBruce Richardson 556199a2dd95SBruce Richardson int 556299a2dd95SBruce Richardson rte_eth_timesync_read_tx_timestamp(uint16_t port_id, 556399a2dd95SBruce Richardson struct timespec *timestamp) 556499a2dd95SBruce Richardson { 556599a2dd95SBruce Richardson struct rte_eth_dev *dev; 556699a2dd95SBruce Richardson 556799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 556899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 556999a2dd95SBruce Richardson 557053ef1b34SMin Hu (Connor) if (timestamp == NULL) { 557153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 557253ef1b34SMin Hu (Connor) "Cannot read ethdev port %u Tx timestamp to NULL\n", 557353ef1b34SMin Hu (Connor) port_id); 557453ef1b34SMin Hu (Connor) return -EINVAL; 557553ef1b34SMin Hu (Connor) } 557653ef1b34SMin Hu (Connor) 557799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP); 557899a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp) 557999a2dd95SBruce Richardson (dev, timestamp)); 558099a2dd95SBruce Richardson } 558199a2dd95SBruce Richardson 558299a2dd95SBruce Richardson int 558399a2dd95SBruce Richardson rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta) 558499a2dd95SBruce Richardson { 558599a2dd95SBruce Richardson struct rte_eth_dev *dev; 558699a2dd95SBruce Richardson 558799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 558899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 558999a2dd95SBruce Richardson 559099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_adjust_time, -ENOTSUP); 559153ef1b34SMin Hu (Connor) return eth_err(port_id, (*dev->dev_ops->timesync_adjust_time)(dev, delta)); 559299a2dd95SBruce Richardson } 559399a2dd95SBruce Richardson 559499a2dd95SBruce Richardson int 559599a2dd95SBruce Richardson rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp) 559699a2dd95SBruce Richardson { 559799a2dd95SBruce Richardson struct rte_eth_dev *dev; 559899a2dd95SBruce Richardson 559999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 560099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 560199a2dd95SBruce Richardson 560253ef1b34SMin Hu (Connor) if (timestamp == NULL) { 560353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 560453ef1b34SMin Hu (Connor) "Cannot read ethdev port %u timesync time to NULL\n", 560553ef1b34SMin Hu (Connor) port_id); 560653ef1b34SMin Hu (Connor) return -EINVAL; 560753ef1b34SMin Hu (Connor) } 560853ef1b34SMin Hu (Connor) 560999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP); 561099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev, 561199a2dd95SBruce Richardson timestamp)); 561299a2dd95SBruce Richardson } 561399a2dd95SBruce Richardson 561499a2dd95SBruce Richardson int 561599a2dd95SBruce Richardson rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp) 561699a2dd95SBruce Richardson { 561799a2dd95SBruce Richardson struct rte_eth_dev *dev; 561899a2dd95SBruce Richardson 561999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 562099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 562199a2dd95SBruce Richardson 562253ef1b34SMin Hu (Connor) if (timestamp == NULL) { 562353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 562453ef1b34SMin Hu (Connor) "Cannot write ethdev port %u timesync from NULL time\n", 562553ef1b34SMin Hu (Connor) port_id); 562653ef1b34SMin Hu (Connor) return -EINVAL; 562753ef1b34SMin Hu (Connor) } 562853ef1b34SMin Hu (Connor) 562999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP); 563099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev, 563199a2dd95SBruce Richardson timestamp)); 563299a2dd95SBruce Richardson } 563399a2dd95SBruce Richardson 563499a2dd95SBruce Richardson int 563599a2dd95SBruce Richardson rte_eth_read_clock(uint16_t port_id, uint64_t *clock) 563699a2dd95SBruce Richardson { 563799a2dd95SBruce Richardson struct rte_eth_dev *dev; 563899a2dd95SBruce Richardson 563999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 564099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 564199a2dd95SBruce Richardson 564253ef1b34SMin Hu (Connor) if (clock == NULL) { 564353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot read ethdev port %u clock to NULL\n", 564453ef1b34SMin Hu (Connor) port_id); 564553ef1b34SMin Hu (Connor) return -EINVAL; 564653ef1b34SMin Hu (Connor) } 564753ef1b34SMin Hu (Connor) 564899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP); 564999a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock)); 565099a2dd95SBruce Richardson } 565199a2dd95SBruce Richardson 565299a2dd95SBruce Richardson int 565399a2dd95SBruce Richardson rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info) 565499a2dd95SBruce Richardson { 565599a2dd95SBruce Richardson struct rte_eth_dev *dev; 565699a2dd95SBruce Richardson 565799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 565899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 565953ef1b34SMin Hu (Connor) 566053ef1b34SMin Hu (Connor) if (info == NULL) { 566153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 566253ef1b34SMin Hu (Connor) "Cannot get ethdev port %u register info to NULL\n", 566353ef1b34SMin Hu (Connor) port_id); 566453ef1b34SMin Hu (Connor) return -EINVAL; 566553ef1b34SMin Hu (Connor) } 566653ef1b34SMin Hu (Connor) 566799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_reg, -ENOTSUP); 566899a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info)); 566999a2dd95SBruce Richardson } 567099a2dd95SBruce Richardson 567199a2dd95SBruce Richardson int 567299a2dd95SBruce Richardson rte_eth_dev_get_eeprom_length(uint16_t port_id) 567399a2dd95SBruce Richardson { 567499a2dd95SBruce Richardson struct rte_eth_dev *dev; 567599a2dd95SBruce Richardson 567699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 567799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 567853ef1b34SMin Hu (Connor) 567999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom_length, -ENOTSUP); 568099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->get_eeprom_length)(dev)); 568199a2dd95SBruce Richardson } 568299a2dd95SBruce Richardson 568399a2dd95SBruce Richardson int 568499a2dd95SBruce Richardson rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) 568599a2dd95SBruce Richardson { 568699a2dd95SBruce Richardson struct rte_eth_dev *dev; 568799a2dd95SBruce Richardson 568899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 568999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 569053ef1b34SMin Hu (Connor) 569153ef1b34SMin Hu (Connor) if (info == NULL) { 569253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 569353ef1b34SMin Hu (Connor) "Cannot get ethdev port %u EEPROM info to NULL\n", 569453ef1b34SMin Hu (Connor) port_id); 569553ef1b34SMin Hu (Connor) return -EINVAL; 569653ef1b34SMin Hu (Connor) } 569753ef1b34SMin Hu (Connor) 569899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom, -ENOTSUP); 569999a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->get_eeprom)(dev, info)); 570099a2dd95SBruce Richardson } 570199a2dd95SBruce Richardson 570299a2dd95SBruce Richardson int 570399a2dd95SBruce Richardson rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) 570499a2dd95SBruce Richardson { 570599a2dd95SBruce Richardson struct rte_eth_dev *dev; 570699a2dd95SBruce Richardson 570799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 570899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 570953ef1b34SMin Hu (Connor) 571053ef1b34SMin Hu (Connor) if (info == NULL) { 571153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 571253ef1b34SMin Hu (Connor) "Cannot set ethdev port %u EEPROM from NULL info\n", 571353ef1b34SMin Hu (Connor) port_id); 571453ef1b34SMin Hu (Connor) return -EINVAL; 571553ef1b34SMin Hu (Connor) } 571653ef1b34SMin Hu (Connor) 571799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_eeprom, -ENOTSUP); 571899a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->set_eeprom)(dev, info)); 571999a2dd95SBruce Richardson } 572099a2dd95SBruce Richardson 572199a2dd95SBruce Richardson int 572299a2dd95SBruce Richardson rte_eth_dev_get_module_info(uint16_t port_id, 572399a2dd95SBruce Richardson struct rte_eth_dev_module_info *modinfo) 572499a2dd95SBruce Richardson { 572599a2dd95SBruce Richardson struct rte_eth_dev *dev; 572699a2dd95SBruce Richardson 572799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 572899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 572953ef1b34SMin Hu (Connor) 573053ef1b34SMin Hu (Connor) if (modinfo == NULL) { 573153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 573253ef1b34SMin Hu (Connor) "Cannot get ethdev port %u EEPROM module info to NULL\n", 573353ef1b34SMin Hu (Connor) port_id); 573453ef1b34SMin Hu (Connor) return -EINVAL; 573553ef1b34SMin Hu (Connor) } 573653ef1b34SMin Hu (Connor) 573799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_info, -ENOTSUP); 573899a2dd95SBruce Richardson return (*dev->dev_ops->get_module_info)(dev, modinfo); 573999a2dd95SBruce Richardson } 574099a2dd95SBruce Richardson 574199a2dd95SBruce Richardson int 574299a2dd95SBruce Richardson rte_eth_dev_get_module_eeprom(uint16_t port_id, 574399a2dd95SBruce Richardson struct rte_dev_eeprom_info *info) 574499a2dd95SBruce Richardson { 574599a2dd95SBruce Richardson struct rte_eth_dev *dev; 574699a2dd95SBruce Richardson 574799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 574899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 574953ef1b34SMin Hu (Connor) 575053ef1b34SMin Hu (Connor) if (info == NULL) { 575153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 575253ef1b34SMin Hu (Connor) "Cannot get ethdev port %u module EEPROM info to NULL\n", 575353ef1b34SMin Hu (Connor) port_id); 575453ef1b34SMin Hu (Connor) return -EINVAL; 575553ef1b34SMin Hu (Connor) } 575653ef1b34SMin Hu (Connor) 575753ef1b34SMin Hu (Connor) if (info->data == NULL) { 575853ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 575953ef1b34SMin Hu (Connor) "Cannot get ethdev port %u module EEPROM data to NULL\n", 576053ef1b34SMin Hu (Connor) port_id); 576153ef1b34SMin Hu (Connor) return -EINVAL; 576253ef1b34SMin Hu (Connor) } 576353ef1b34SMin Hu (Connor) 576453ef1b34SMin Hu (Connor) if (info->length == 0) { 576553ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 576653ef1b34SMin Hu (Connor) "Cannot get ethdev port %u module EEPROM to data with zero size\n", 576753ef1b34SMin Hu (Connor) port_id); 576853ef1b34SMin Hu (Connor) return -EINVAL; 576953ef1b34SMin Hu (Connor) } 577053ef1b34SMin Hu (Connor) 577199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_eeprom, -ENOTSUP); 577299a2dd95SBruce Richardson return (*dev->dev_ops->get_module_eeprom)(dev, info); 577399a2dd95SBruce Richardson } 577499a2dd95SBruce Richardson 577599a2dd95SBruce Richardson int 577699a2dd95SBruce Richardson rte_eth_dev_get_dcb_info(uint16_t port_id, 577799a2dd95SBruce Richardson struct rte_eth_dcb_info *dcb_info) 577899a2dd95SBruce Richardson { 577999a2dd95SBruce Richardson struct rte_eth_dev *dev; 578099a2dd95SBruce Richardson 578199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 578299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 578353ef1b34SMin Hu (Connor) 578453ef1b34SMin Hu (Connor) if (dcb_info == NULL) { 578553ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 578653ef1b34SMin Hu (Connor) "Cannot get ethdev port %u DCB info to NULL\n", 578753ef1b34SMin Hu (Connor) port_id); 578853ef1b34SMin Hu (Connor) return -EINVAL; 578953ef1b34SMin Hu (Connor) } 579053ef1b34SMin Hu (Connor) 579199a2dd95SBruce Richardson memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info)); 579299a2dd95SBruce Richardson 579399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_dcb_info, -ENOTSUP); 579499a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->get_dcb_info)(dev, dcb_info)); 579599a2dd95SBruce Richardson } 579699a2dd95SBruce Richardson 579799a2dd95SBruce Richardson static void 579899a2dd95SBruce Richardson eth_dev_adjust_nb_desc(uint16_t *nb_desc, 579999a2dd95SBruce Richardson const struct rte_eth_desc_lim *desc_lim) 580099a2dd95SBruce Richardson { 580199a2dd95SBruce Richardson if (desc_lim->nb_align != 0) 580299a2dd95SBruce Richardson *nb_desc = RTE_ALIGN_CEIL(*nb_desc, desc_lim->nb_align); 580399a2dd95SBruce Richardson 580499a2dd95SBruce Richardson if (desc_lim->nb_max != 0) 580599a2dd95SBruce Richardson *nb_desc = RTE_MIN(*nb_desc, desc_lim->nb_max); 580699a2dd95SBruce Richardson 580799a2dd95SBruce Richardson *nb_desc = RTE_MAX(*nb_desc, desc_lim->nb_min); 580899a2dd95SBruce Richardson } 580999a2dd95SBruce Richardson 581099a2dd95SBruce Richardson int 581199a2dd95SBruce Richardson rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id, 581299a2dd95SBruce Richardson uint16_t *nb_rx_desc, 581399a2dd95SBruce Richardson uint16_t *nb_tx_desc) 581499a2dd95SBruce Richardson { 581599a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 581699a2dd95SBruce Richardson int ret; 581799a2dd95SBruce Richardson 581899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 581999a2dd95SBruce Richardson 582099a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 582199a2dd95SBruce Richardson if (ret != 0) 582299a2dd95SBruce Richardson return ret; 582399a2dd95SBruce Richardson 582499a2dd95SBruce Richardson if (nb_rx_desc != NULL) 582599a2dd95SBruce Richardson eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim); 582699a2dd95SBruce Richardson 582799a2dd95SBruce Richardson if (nb_tx_desc != NULL) 582899a2dd95SBruce Richardson eth_dev_adjust_nb_desc(nb_tx_desc, &dev_info.tx_desc_lim); 582999a2dd95SBruce Richardson 583099a2dd95SBruce Richardson return 0; 583199a2dd95SBruce Richardson } 583299a2dd95SBruce Richardson 583399a2dd95SBruce Richardson int 583499a2dd95SBruce Richardson rte_eth_dev_hairpin_capability_get(uint16_t port_id, 583599a2dd95SBruce Richardson struct rte_eth_hairpin_cap *cap) 583699a2dd95SBruce Richardson { 583799a2dd95SBruce Richardson struct rte_eth_dev *dev; 583899a2dd95SBruce Richardson 583999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 584099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 584153ef1b34SMin Hu (Connor) 584253ef1b34SMin Hu (Connor) if (cap == NULL) { 584353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 584453ef1b34SMin Hu (Connor) "Cannot get ethdev port %u hairpin capability to NULL\n", 584553ef1b34SMin Hu (Connor) port_id); 584653ef1b34SMin Hu (Connor) return -EINVAL; 584753ef1b34SMin Hu (Connor) } 584853ef1b34SMin Hu (Connor) 584999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP); 585099a2dd95SBruce Richardson memset(cap, 0, sizeof(*cap)); 585199a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap)); 585299a2dd95SBruce Richardson } 585399a2dd95SBruce Richardson 585499a2dd95SBruce Richardson int 585599a2dd95SBruce Richardson rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id) 585699a2dd95SBruce Richardson { 585753ef1b34SMin Hu (Connor) if (dev->data->rx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN) 585899a2dd95SBruce Richardson return 1; 585999a2dd95SBruce Richardson return 0; 586099a2dd95SBruce Richardson } 586199a2dd95SBruce Richardson 586299a2dd95SBruce Richardson int 586399a2dd95SBruce Richardson rte_eth_dev_is_tx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id) 586499a2dd95SBruce Richardson { 586553ef1b34SMin Hu (Connor) if (dev->data->tx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN) 586699a2dd95SBruce Richardson return 1; 586799a2dd95SBruce Richardson return 0; 586899a2dd95SBruce Richardson } 586999a2dd95SBruce Richardson 587099a2dd95SBruce Richardson int 587199a2dd95SBruce Richardson rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) 587299a2dd95SBruce Richardson { 587399a2dd95SBruce Richardson struct rte_eth_dev *dev; 587499a2dd95SBruce Richardson 587599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 587699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 587799a2dd95SBruce Richardson 587853ef1b34SMin Hu (Connor) if (pool == NULL) { 587953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 588053ef1b34SMin Hu (Connor) "Cannot test ethdev port %u mempool operation from NULL pool\n", 588153ef1b34SMin Hu (Connor) port_id); 588253ef1b34SMin Hu (Connor) return -EINVAL; 588353ef1b34SMin Hu (Connor) } 588453ef1b34SMin Hu (Connor) 588599a2dd95SBruce Richardson if (*dev->dev_ops->pool_ops_supported == NULL) 588699a2dd95SBruce Richardson return 1; /* all pools are supported */ 588799a2dd95SBruce Richardson 588899a2dd95SBruce Richardson return (*dev->dev_ops->pool_ops_supported)(dev, pool); 588999a2dd95SBruce Richardson } 589099a2dd95SBruce Richardson 589199a2dd95SBruce Richardson /** 589299a2dd95SBruce Richardson * A set of values to describe the possible states of a switch domain. 589399a2dd95SBruce Richardson */ 589499a2dd95SBruce Richardson enum rte_eth_switch_domain_state { 589599a2dd95SBruce Richardson RTE_ETH_SWITCH_DOMAIN_UNUSED = 0, 589699a2dd95SBruce Richardson RTE_ETH_SWITCH_DOMAIN_ALLOCATED 589799a2dd95SBruce Richardson }; 589899a2dd95SBruce Richardson 589999a2dd95SBruce Richardson /** 590099a2dd95SBruce Richardson * Array of switch domains available for allocation. Array is sized to 590199a2dd95SBruce Richardson * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than 590299a2dd95SBruce Richardson * ethdev ports in a single process. 590399a2dd95SBruce Richardson */ 590499a2dd95SBruce Richardson static struct rte_eth_dev_switch { 590599a2dd95SBruce Richardson enum rte_eth_switch_domain_state state; 590699a2dd95SBruce Richardson } eth_dev_switch_domains[RTE_MAX_ETHPORTS]; 590799a2dd95SBruce Richardson 590899a2dd95SBruce Richardson int 590999a2dd95SBruce Richardson rte_eth_switch_domain_alloc(uint16_t *domain_id) 591099a2dd95SBruce Richardson { 591199a2dd95SBruce Richardson uint16_t i; 591299a2dd95SBruce Richardson 591399a2dd95SBruce Richardson *domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID; 591499a2dd95SBruce Richardson 591599a2dd95SBruce Richardson for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 591699a2dd95SBruce Richardson if (eth_dev_switch_domains[i].state == 591799a2dd95SBruce Richardson RTE_ETH_SWITCH_DOMAIN_UNUSED) { 591899a2dd95SBruce Richardson eth_dev_switch_domains[i].state = 591999a2dd95SBruce Richardson RTE_ETH_SWITCH_DOMAIN_ALLOCATED; 592099a2dd95SBruce Richardson *domain_id = i; 592199a2dd95SBruce Richardson return 0; 592299a2dd95SBruce Richardson } 592399a2dd95SBruce Richardson } 592499a2dd95SBruce Richardson 592599a2dd95SBruce Richardson return -ENOSPC; 592699a2dd95SBruce Richardson } 592799a2dd95SBruce Richardson 592899a2dd95SBruce Richardson int 592999a2dd95SBruce Richardson rte_eth_switch_domain_free(uint16_t domain_id) 593099a2dd95SBruce Richardson { 593199a2dd95SBruce Richardson if (domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID || 593299a2dd95SBruce Richardson domain_id >= RTE_MAX_ETHPORTS) 593399a2dd95SBruce Richardson return -EINVAL; 593499a2dd95SBruce Richardson 593599a2dd95SBruce Richardson if (eth_dev_switch_domains[domain_id].state != 593699a2dd95SBruce Richardson RTE_ETH_SWITCH_DOMAIN_ALLOCATED) 593799a2dd95SBruce Richardson return -EINVAL; 593899a2dd95SBruce Richardson 593999a2dd95SBruce Richardson eth_dev_switch_domains[domain_id].state = RTE_ETH_SWITCH_DOMAIN_UNUSED; 594099a2dd95SBruce Richardson 594199a2dd95SBruce Richardson return 0; 594299a2dd95SBruce Richardson } 594399a2dd95SBruce Richardson 594499a2dd95SBruce Richardson static int 594599a2dd95SBruce Richardson eth_dev_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in) 594699a2dd95SBruce Richardson { 594799a2dd95SBruce Richardson int state; 594899a2dd95SBruce Richardson struct rte_kvargs_pair *pair; 594999a2dd95SBruce Richardson char *letter; 595099a2dd95SBruce Richardson 595199a2dd95SBruce Richardson arglist->str = strdup(str_in); 595299a2dd95SBruce Richardson if (arglist->str == NULL) 595399a2dd95SBruce Richardson return -ENOMEM; 595499a2dd95SBruce Richardson 595599a2dd95SBruce Richardson letter = arglist->str; 595699a2dd95SBruce Richardson state = 0; 595799a2dd95SBruce Richardson arglist->count = 0; 595899a2dd95SBruce Richardson pair = &arglist->pairs[0]; 595999a2dd95SBruce Richardson while (1) { 596099a2dd95SBruce Richardson switch (state) { 596199a2dd95SBruce Richardson case 0: /* Initial */ 596299a2dd95SBruce Richardson if (*letter == '=') 596399a2dd95SBruce Richardson return -EINVAL; 596499a2dd95SBruce Richardson else if (*letter == '\0') 596599a2dd95SBruce Richardson return 0; 596699a2dd95SBruce Richardson 596799a2dd95SBruce Richardson state = 1; 596899a2dd95SBruce Richardson pair->key = letter; 596999a2dd95SBruce Richardson /* fall-thru */ 597099a2dd95SBruce Richardson 597199a2dd95SBruce Richardson case 1: /* Parsing key */ 597299a2dd95SBruce Richardson if (*letter == '=') { 597399a2dd95SBruce Richardson *letter = '\0'; 597499a2dd95SBruce Richardson pair->value = letter + 1; 597599a2dd95SBruce Richardson state = 2; 597699a2dd95SBruce Richardson } else if (*letter == ',' || *letter == '\0') 597799a2dd95SBruce Richardson return -EINVAL; 597899a2dd95SBruce Richardson break; 597999a2dd95SBruce Richardson 598099a2dd95SBruce Richardson 598199a2dd95SBruce Richardson case 2: /* Parsing value */ 598299a2dd95SBruce Richardson if (*letter == '[') 598399a2dd95SBruce Richardson state = 3; 598499a2dd95SBruce Richardson else if (*letter == ',') { 598599a2dd95SBruce Richardson *letter = '\0'; 598699a2dd95SBruce Richardson arglist->count++; 598799a2dd95SBruce Richardson pair = &arglist->pairs[arglist->count]; 598899a2dd95SBruce Richardson state = 0; 598999a2dd95SBruce Richardson } else if (*letter == '\0') { 599099a2dd95SBruce Richardson letter--; 599199a2dd95SBruce Richardson arglist->count++; 599299a2dd95SBruce Richardson pair = &arglist->pairs[arglist->count]; 599399a2dd95SBruce Richardson state = 0; 599499a2dd95SBruce Richardson } 599599a2dd95SBruce Richardson break; 599699a2dd95SBruce Richardson 599799a2dd95SBruce Richardson case 3: /* Parsing list */ 599899a2dd95SBruce Richardson if (*letter == ']') 599999a2dd95SBruce Richardson state = 2; 600099a2dd95SBruce Richardson else if (*letter == '\0') 600199a2dd95SBruce Richardson return -EINVAL; 600299a2dd95SBruce Richardson break; 600399a2dd95SBruce Richardson } 600499a2dd95SBruce Richardson letter++; 600599a2dd95SBruce Richardson } 600699a2dd95SBruce Richardson } 600799a2dd95SBruce Richardson 600899a2dd95SBruce Richardson int 600999a2dd95SBruce Richardson rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da) 601099a2dd95SBruce Richardson { 601199a2dd95SBruce Richardson struct rte_kvargs args; 601299a2dd95SBruce Richardson struct rte_kvargs_pair *pair; 601399a2dd95SBruce Richardson unsigned int i; 601499a2dd95SBruce Richardson int result = 0; 601599a2dd95SBruce Richardson 601699a2dd95SBruce Richardson memset(eth_da, 0, sizeof(*eth_da)); 601799a2dd95SBruce Richardson 601899a2dd95SBruce Richardson result = eth_dev_devargs_tokenise(&args, dargs); 601999a2dd95SBruce Richardson if (result < 0) 602099a2dd95SBruce Richardson goto parse_cleanup; 602199a2dd95SBruce Richardson 602299a2dd95SBruce Richardson for (i = 0; i < args.count; i++) { 602399a2dd95SBruce Richardson pair = &args.pairs[i]; 602499a2dd95SBruce Richardson if (strcmp("representor", pair->key) == 0) { 602599a2dd95SBruce Richardson if (eth_da->type != RTE_ETH_REPRESENTOR_NONE) { 602699a2dd95SBruce Richardson RTE_LOG(ERR, EAL, "duplicated representor key: %s\n", 602799a2dd95SBruce Richardson dargs); 602899a2dd95SBruce Richardson result = -1; 602999a2dd95SBruce Richardson goto parse_cleanup; 603099a2dd95SBruce Richardson } 603199a2dd95SBruce Richardson result = rte_eth_devargs_parse_representor_ports( 603299a2dd95SBruce Richardson pair->value, eth_da); 603399a2dd95SBruce Richardson if (result < 0) 603499a2dd95SBruce Richardson goto parse_cleanup; 603599a2dd95SBruce Richardson } 603699a2dd95SBruce Richardson } 603799a2dd95SBruce Richardson 603899a2dd95SBruce Richardson parse_cleanup: 603999a2dd95SBruce Richardson if (args.str) 604099a2dd95SBruce Richardson free(args.str); 604199a2dd95SBruce Richardson 604299a2dd95SBruce Richardson return result; 604399a2dd95SBruce Richardson } 604499a2dd95SBruce Richardson 604599a2dd95SBruce Richardson int 6046ff4e52efSViacheslav Galaktionov rte_eth_representor_id_get(uint16_t port_id, 604799a2dd95SBruce Richardson enum rte_eth_representor_type type, 604899a2dd95SBruce Richardson int controller, int pf, int representor_port, 604999a2dd95SBruce Richardson uint16_t *repr_id) 605099a2dd95SBruce Richardson { 605110eaf41dSViacheslav Galaktionov int ret, n, count; 605210eaf41dSViacheslav Galaktionov uint32_t i; 605399a2dd95SBruce Richardson struct rte_eth_representor_info *info = NULL; 605499a2dd95SBruce Richardson size_t size; 605599a2dd95SBruce Richardson 605699a2dd95SBruce Richardson if (type == RTE_ETH_REPRESENTOR_NONE) 605799a2dd95SBruce Richardson return 0; 605899a2dd95SBruce Richardson if (repr_id == NULL) 605999a2dd95SBruce Richardson return -EINVAL; 606099a2dd95SBruce Richardson 606199a2dd95SBruce Richardson /* Get PMD representor range info. */ 6062ff4e52efSViacheslav Galaktionov ret = rte_eth_representor_info_get(port_id, NULL); 606399a2dd95SBruce Richardson if (ret == -ENOTSUP && type == RTE_ETH_REPRESENTOR_VF && 606499a2dd95SBruce Richardson controller == -1 && pf == -1) { 606599a2dd95SBruce Richardson /* Direct mapping for legacy VF representor. */ 606699a2dd95SBruce Richardson *repr_id = representor_port; 606799a2dd95SBruce Richardson return 0; 606899a2dd95SBruce Richardson } else if (ret < 0) { 606999a2dd95SBruce Richardson return ret; 607099a2dd95SBruce Richardson } 607199a2dd95SBruce Richardson n = ret; 607299a2dd95SBruce Richardson size = sizeof(*info) + n * sizeof(info->ranges[0]); 607399a2dd95SBruce Richardson info = calloc(1, size); 607499a2dd95SBruce Richardson if (info == NULL) 607599a2dd95SBruce Richardson return -ENOMEM; 607610eaf41dSViacheslav Galaktionov info->nb_ranges_alloc = n; 6077ff4e52efSViacheslav Galaktionov ret = rte_eth_representor_info_get(port_id, info); 607899a2dd95SBruce Richardson if (ret < 0) 607999a2dd95SBruce Richardson goto out; 608099a2dd95SBruce Richardson 608199a2dd95SBruce Richardson /* Default controller and pf to caller. */ 608299a2dd95SBruce Richardson if (controller == -1) 608399a2dd95SBruce Richardson controller = info->controller; 608499a2dd95SBruce Richardson if (pf == -1) 608599a2dd95SBruce Richardson pf = info->pf; 608699a2dd95SBruce Richardson 608799a2dd95SBruce Richardson /* Locate representor ID. */ 608899a2dd95SBruce Richardson ret = -ENOENT; 608910eaf41dSViacheslav Galaktionov for (i = 0; i < info->nb_ranges; ++i) { 609099a2dd95SBruce Richardson if (info->ranges[i].type != type) 609199a2dd95SBruce Richardson continue; 609299a2dd95SBruce Richardson if (info->ranges[i].controller != controller) 609399a2dd95SBruce Richardson continue; 609499a2dd95SBruce Richardson if (info->ranges[i].id_end < info->ranges[i].id_base) { 609599a2dd95SBruce Richardson RTE_LOG(WARNING, EAL, "Port %hu invalid representor ID Range %u - %u, entry %d\n", 6096ff4e52efSViacheslav Galaktionov port_id, info->ranges[i].id_base, 609799a2dd95SBruce Richardson info->ranges[i].id_end, i); 609899a2dd95SBruce Richardson continue; 609999a2dd95SBruce Richardson 610099a2dd95SBruce Richardson } 610199a2dd95SBruce Richardson count = info->ranges[i].id_end - info->ranges[i].id_base + 1; 610299a2dd95SBruce Richardson switch (info->ranges[i].type) { 610399a2dd95SBruce Richardson case RTE_ETH_REPRESENTOR_PF: 610499a2dd95SBruce Richardson if (pf < info->ranges[i].pf || 610599a2dd95SBruce Richardson pf >= info->ranges[i].pf + count) 610699a2dd95SBruce Richardson continue; 610799a2dd95SBruce Richardson *repr_id = info->ranges[i].id_base + 610899a2dd95SBruce Richardson (pf - info->ranges[i].pf); 610999a2dd95SBruce Richardson ret = 0; 611099a2dd95SBruce Richardson goto out; 611199a2dd95SBruce Richardson case RTE_ETH_REPRESENTOR_VF: 611299a2dd95SBruce Richardson if (info->ranges[i].pf != pf) 611399a2dd95SBruce Richardson continue; 611499a2dd95SBruce Richardson if (representor_port < info->ranges[i].vf || 611599a2dd95SBruce Richardson representor_port >= info->ranges[i].vf + count) 611699a2dd95SBruce Richardson continue; 611799a2dd95SBruce Richardson *repr_id = info->ranges[i].id_base + 611899a2dd95SBruce Richardson (representor_port - info->ranges[i].vf); 611999a2dd95SBruce Richardson ret = 0; 612099a2dd95SBruce Richardson goto out; 612199a2dd95SBruce Richardson case RTE_ETH_REPRESENTOR_SF: 612299a2dd95SBruce Richardson if (info->ranges[i].pf != pf) 612399a2dd95SBruce Richardson continue; 612499a2dd95SBruce Richardson if (representor_port < info->ranges[i].sf || 612599a2dd95SBruce Richardson representor_port >= info->ranges[i].sf + count) 612699a2dd95SBruce Richardson continue; 612799a2dd95SBruce Richardson *repr_id = info->ranges[i].id_base + 612899a2dd95SBruce Richardson (representor_port - info->ranges[i].sf); 612999a2dd95SBruce Richardson ret = 0; 613099a2dd95SBruce Richardson goto out; 613199a2dd95SBruce Richardson default: 613299a2dd95SBruce Richardson break; 613399a2dd95SBruce Richardson } 613499a2dd95SBruce Richardson } 613599a2dd95SBruce Richardson out: 613699a2dd95SBruce Richardson free(info); 613799a2dd95SBruce Richardson return ret; 613899a2dd95SBruce Richardson } 613999a2dd95SBruce Richardson 614099a2dd95SBruce Richardson static int 614199a2dd95SBruce Richardson eth_dev_handle_port_list(const char *cmd __rte_unused, 614299a2dd95SBruce Richardson const char *params __rte_unused, 614399a2dd95SBruce Richardson struct rte_tel_data *d) 614499a2dd95SBruce Richardson { 614599a2dd95SBruce Richardson int port_id; 614699a2dd95SBruce Richardson 614799a2dd95SBruce Richardson rte_tel_data_start_array(d, RTE_TEL_INT_VAL); 614899a2dd95SBruce Richardson RTE_ETH_FOREACH_DEV(port_id) 614999a2dd95SBruce Richardson rte_tel_data_add_array_int(d, port_id); 615099a2dd95SBruce Richardson return 0; 615199a2dd95SBruce Richardson } 615299a2dd95SBruce Richardson 615399a2dd95SBruce Richardson static void 615499a2dd95SBruce Richardson eth_dev_add_port_queue_stats(struct rte_tel_data *d, uint64_t *q_stats, 615599a2dd95SBruce Richardson const char *stat_name) 615699a2dd95SBruce Richardson { 615799a2dd95SBruce Richardson int q; 615899a2dd95SBruce Richardson struct rte_tel_data *q_data = rte_tel_data_alloc(); 615999a2dd95SBruce Richardson rte_tel_data_start_array(q_data, RTE_TEL_U64_VAL); 616099a2dd95SBruce Richardson for (q = 0; q < RTE_ETHDEV_QUEUE_STAT_CNTRS; q++) 616199a2dd95SBruce Richardson rte_tel_data_add_array_u64(q_data, q_stats[q]); 616299a2dd95SBruce Richardson rte_tel_data_add_dict_container(d, stat_name, q_data, 0); 616399a2dd95SBruce Richardson } 616499a2dd95SBruce Richardson 616599a2dd95SBruce Richardson #define ADD_DICT_STAT(stats, s) rte_tel_data_add_dict_u64(d, #s, stats.s) 616699a2dd95SBruce Richardson 616799a2dd95SBruce Richardson static int 616899a2dd95SBruce Richardson eth_dev_handle_port_stats(const char *cmd __rte_unused, 616999a2dd95SBruce Richardson const char *params, 617099a2dd95SBruce Richardson struct rte_tel_data *d) 617199a2dd95SBruce Richardson { 617299a2dd95SBruce Richardson struct rte_eth_stats stats; 617399a2dd95SBruce Richardson int port_id, ret; 617499a2dd95SBruce Richardson 617599a2dd95SBruce Richardson if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 617699a2dd95SBruce Richardson return -1; 617799a2dd95SBruce Richardson 617899a2dd95SBruce Richardson port_id = atoi(params); 617999a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id)) 618099a2dd95SBruce Richardson return -1; 618199a2dd95SBruce Richardson 618299a2dd95SBruce Richardson ret = rte_eth_stats_get(port_id, &stats); 618399a2dd95SBruce Richardson if (ret < 0) 618499a2dd95SBruce Richardson return -1; 618599a2dd95SBruce Richardson 618699a2dd95SBruce Richardson rte_tel_data_start_dict(d); 618799a2dd95SBruce Richardson ADD_DICT_STAT(stats, ipackets); 618899a2dd95SBruce Richardson ADD_DICT_STAT(stats, opackets); 618999a2dd95SBruce Richardson ADD_DICT_STAT(stats, ibytes); 619099a2dd95SBruce Richardson ADD_DICT_STAT(stats, obytes); 619199a2dd95SBruce Richardson ADD_DICT_STAT(stats, imissed); 619299a2dd95SBruce Richardson ADD_DICT_STAT(stats, ierrors); 619399a2dd95SBruce Richardson ADD_DICT_STAT(stats, oerrors); 619499a2dd95SBruce Richardson ADD_DICT_STAT(stats, rx_nombuf); 619599a2dd95SBruce Richardson eth_dev_add_port_queue_stats(d, stats.q_ipackets, "q_ipackets"); 619699a2dd95SBruce Richardson eth_dev_add_port_queue_stats(d, stats.q_opackets, "q_opackets"); 619799a2dd95SBruce Richardson eth_dev_add_port_queue_stats(d, stats.q_ibytes, "q_ibytes"); 619899a2dd95SBruce Richardson eth_dev_add_port_queue_stats(d, stats.q_obytes, "q_obytes"); 619999a2dd95SBruce Richardson eth_dev_add_port_queue_stats(d, stats.q_errors, "q_errors"); 620099a2dd95SBruce Richardson 620199a2dd95SBruce Richardson return 0; 620299a2dd95SBruce Richardson } 620399a2dd95SBruce Richardson 620499a2dd95SBruce Richardson static int 620599a2dd95SBruce Richardson eth_dev_handle_port_xstats(const char *cmd __rte_unused, 620699a2dd95SBruce Richardson const char *params, 620799a2dd95SBruce Richardson struct rte_tel_data *d) 620899a2dd95SBruce Richardson { 620999a2dd95SBruce Richardson struct rte_eth_xstat *eth_xstats; 621099a2dd95SBruce Richardson struct rte_eth_xstat_name *xstat_names; 621199a2dd95SBruce Richardson int port_id, num_xstats; 621299a2dd95SBruce Richardson int i, ret; 621399a2dd95SBruce Richardson char *end_param; 621499a2dd95SBruce Richardson 621599a2dd95SBruce Richardson if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 621699a2dd95SBruce Richardson return -1; 621799a2dd95SBruce Richardson 621899a2dd95SBruce Richardson port_id = strtoul(params, &end_param, 0); 621999a2dd95SBruce Richardson if (*end_param != '\0') 622099a2dd95SBruce Richardson RTE_ETHDEV_LOG(NOTICE, 622199a2dd95SBruce Richardson "Extra parameters passed to ethdev telemetry command, ignoring"); 622299a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id)) 622399a2dd95SBruce Richardson return -1; 622499a2dd95SBruce Richardson 622599a2dd95SBruce Richardson num_xstats = rte_eth_xstats_get(port_id, NULL, 0); 622699a2dd95SBruce Richardson if (num_xstats < 0) 622799a2dd95SBruce Richardson return -1; 622899a2dd95SBruce Richardson 622999a2dd95SBruce Richardson /* use one malloc for both names and stats */ 623099a2dd95SBruce Richardson eth_xstats = malloc((sizeof(struct rte_eth_xstat) + 623199a2dd95SBruce Richardson sizeof(struct rte_eth_xstat_name)) * num_xstats); 623299a2dd95SBruce Richardson if (eth_xstats == NULL) 623399a2dd95SBruce Richardson return -1; 623499a2dd95SBruce Richardson xstat_names = (void *)ð_xstats[num_xstats]; 623599a2dd95SBruce Richardson 623699a2dd95SBruce Richardson ret = rte_eth_xstats_get_names(port_id, xstat_names, num_xstats); 623799a2dd95SBruce Richardson if (ret < 0 || ret > num_xstats) { 623899a2dd95SBruce Richardson free(eth_xstats); 623999a2dd95SBruce Richardson return -1; 624099a2dd95SBruce Richardson } 624199a2dd95SBruce Richardson 624299a2dd95SBruce Richardson ret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats); 624399a2dd95SBruce Richardson if (ret < 0 || ret > num_xstats) { 624499a2dd95SBruce Richardson free(eth_xstats); 624599a2dd95SBruce Richardson return -1; 624699a2dd95SBruce Richardson } 624799a2dd95SBruce Richardson 624899a2dd95SBruce Richardson rte_tel_data_start_dict(d); 624999a2dd95SBruce Richardson for (i = 0; i < num_xstats; i++) 625099a2dd95SBruce Richardson rte_tel_data_add_dict_u64(d, xstat_names[i].name, 625199a2dd95SBruce Richardson eth_xstats[i].value); 625299a2dd95SBruce Richardson return 0; 625399a2dd95SBruce Richardson } 625499a2dd95SBruce Richardson 625599a2dd95SBruce Richardson static int 625699a2dd95SBruce Richardson eth_dev_handle_port_link_status(const char *cmd __rte_unused, 625799a2dd95SBruce Richardson const char *params, 625899a2dd95SBruce Richardson struct rte_tel_data *d) 625999a2dd95SBruce Richardson { 626099a2dd95SBruce Richardson static const char *status_str = "status"; 626199a2dd95SBruce Richardson int ret, port_id; 626299a2dd95SBruce Richardson struct rte_eth_link link; 626399a2dd95SBruce Richardson char *end_param; 626499a2dd95SBruce Richardson 626599a2dd95SBruce Richardson if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 626699a2dd95SBruce Richardson return -1; 626799a2dd95SBruce Richardson 626899a2dd95SBruce Richardson port_id = strtoul(params, &end_param, 0); 626999a2dd95SBruce Richardson if (*end_param != '\0') 627099a2dd95SBruce Richardson RTE_ETHDEV_LOG(NOTICE, 627199a2dd95SBruce Richardson "Extra parameters passed to ethdev telemetry command, ignoring"); 627299a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id)) 627399a2dd95SBruce Richardson return -1; 627499a2dd95SBruce Richardson 627599a2dd95SBruce Richardson ret = rte_eth_link_get_nowait(port_id, &link); 627699a2dd95SBruce Richardson if (ret < 0) 627799a2dd95SBruce Richardson return -1; 627899a2dd95SBruce Richardson 627999a2dd95SBruce Richardson rte_tel_data_start_dict(d); 628099a2dd95SBruce Richardson if (!link.link_status) { 628199a2dd95SBruce Richardson rte_tel_data_add_dict_string(d, status_str, "DOWN"); 628299a2dd95SBruce Richardson return 0; 628399a2dd95SBruce Richardson } 628499a2dd95SBruce Richardson rte_tel_data_add_dict_string(d, status_str, "UP"); 628599a2dd95SBruce Richardson rte_tel_data_add_dict_u64(d, "speed", link.link_speed); 628699a2dd95SBruce Richardson rte_tel_data_add_dict_string(d, "duplex", 6287295968d1SFerruh Yigit (link.link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ? 628899a2dd95SBruce Richardson "full-duplex" : "half-duplex"); 628999a2dd95SBruce Richardson return 0; 629099a2dd95SBruce Richardson } 629199a2dd95SBruce Richardson 629258b43c1dSGowrishankar Muthukrishnan static int 629358b43c1dSGowrishankar Muthukrishnan eth_dev_handle_port_info(const char *cmd __rte_unused, 629458b43c1dSGowrishankar Muthukrishnan const char *params, 629558b43c1dSGowrishankar Muthukrishnan struct rte_tel_data *d) 629658b43c1dSGowrishankar Muthukrishnan { 629758b43c1dSGowrishankar Muthukrishnan struct rte_tel_data *rxq_state, *txq_state; 629858b43c1dSGowrishankar Muthukrishnan char mac_addr[RTE_ETHER_ADDR_LEN]; 629958b43c1dSGowrishankar Muthukrishnan struct rte_eth_dev *eth_dev; 630058b43c1dSGowrishankar Muthukrishnan char *end_param; 630158b43c1dSGowrishankar Muthukrishnan int port_id, i; 630258b43c1dSGowrishankar Muthukrishnan 630358b43c1dSGowrishankar Muthukrishnan if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 630458b43c1dSGowrishankar Muthukrishnan return -1; 630558b43c1dSGowrishankar Muthukrishnan 630658b43c1dSGowrishankar Muthukrishnan port_id = strtoul(params, &end_param, 0); 630758b43c1dSGowrishankar Muthukrishnan if (*end_param != '\0') 630858b43c1dSGowrishankar Muthukrishnan RTE_ETHDEV_LOG(NOTICE, 630958b43c1dSGowrishankar Muthukrishnan "Extra parameters passed to ethdev telemetry command, ignoring"); 631058b43c1dSGowrishankar Muthukrishnan 631158b43c1dSGowrishankar Muthukrishnan if (!rte_eth_dev_is_valid_port(port_id)) 631258b43c1dSGowrishankar Muthukrishnan return -EINVAL; 631358b43c1dSGowrishankar Muthukrishnan 631458b43c1dSGowrishankar Muthukrishnan eth_dev = &rte_eth_devices[port_id]; 631558b43c1dSGowrishankar Muthukrishnan if (!eth_dev) 631658b43c1dSGowrishankar Muthukrishnan return -EINVAL; 631758b43c1dSGowrishankar Muthukrishnan 631858b43c1dSGowrishankar Muthukrishnan rxq_state = rte_tel_data_alloc(); 631958b43c1dSGowrishankar Muthukrishnan if (!rxq_state) 632058b43c1dSGowrishankar Muthukrishnan return -ENOMEM; 632158b43c1dSGowrishankar Muthukrishnan 632258b43c1dSGowrishankar Muthukrishnan txq_state = rte_tel_data_alloc(); 6323*52b49ea0SYunjian Wang if (!txq_state) { 6324*52b49ea0SYunjian Wang rte_tel_data_free(rxq_state); 632558b43c1dSGowrishankar Muthukrishnan return -ENOMEM; 6326*52b49ea0SYunjian Wang } 632758b43c1dSGowrishankar Muthukrishnan 632858b43c1dSGowrishankar Muthukrishnan rte_tel_data_start_dict(d); 632958b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_string(d, "name", eth_dev->data->name); 633058b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "state", eth_dev->state); 633158b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "nb_rx_queues", 633258b43c1dSGowrishankar Muthukrishnan eth_dev->data->nb_rx_queues); 633358b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "nb_tx_queues", 633458b43c1dSGowrishankar Muthukrishnan eth_dev->data->nb_tx_queues); 633558b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "port_id", eth_dev->data->port_id); 633658b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "mtu", eth_dev->data->mtu); 633758b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "rx_mbuf_size_min", 633858b43c1dSGowrishankar Muthukrishnan eth_dev->data->min_rx_buf_size); 633958b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "rx_mbuf_alloc_fail", 634058b43c1dSGowrishankar Muthukrishnan eth_dev->data->rx_mbuf_alloc_failed); 634158b43c1dSGowrishankar Muthukrishnan snprintf(mac_addr, RTE_ETHER_ADDR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x", 634258b43c1dSGowrishankar Muthukrishnan eth_dev->data->mac_addrs->addr_bytes[0], 634358b43c1dSGowrishankar Muthukrishnan eth_dev->data->mac_addrs->addr_bytes[1], 634458b43c1dSGowrishankar Muthukrishnan eth_dev->data->mac_addrs->addr_bytes[2], 634558b43c1dSGowrishankar Muthukrishnan eth_dev->data->mac_addrs->addr_bytes[3], 634658b43c1dSGowrishankar Muthukrishnan eth_dev->data->mac_addrs->addr_bytes[4], 634758b43c1dSGowrishankar Muthukrishnan eth_dev->data->mac_addrs->addr_bytes[5]); 634858b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_string(d, "mac_addr", mac_addr); 634958b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "promiscuous", 635058b43c1dSGowrishankar Muthukrishnan eth_dev->data->promiscuous); 635158b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "scattered_rx", 635258b43c1dSGowrishankar Muthukrishnan eth_dev->data->scattered_rx); 635358b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "all_multicast", 635458b43c1dSGowrishankar Muthukrishnan eth_dev->data->all_multicast); 635558b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "dev_started", eth_dev->data->dev_started); 635658b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "lro", eth_dev->data->lro); 635758b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "dev_configured", 635858b43c1dSGowrishankar Muthukrishnan eth_dev->data->dev_configured); 635958b43c1dSGowrishankar Muthukrishnan 636058b43c1dSGowrishankar Muthukrishnan rte_tel_data_start_array(rxq_state, RTE_TEL_INT_VAL); 636158b43c1dSGowrishankar Muthukrishnan for (i = 0; i < eth_dev->data->nb_rx_queues; i++) 636258b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_array_int(rxq_state, 636358b43c1dSGowrishankar Muthukrishnan eth_dev->data->rx_queue_state[i]); 636458b43c1dSGowrishankar Muthukrishnan 636558b43c1dSGowrishankar Muthukrishnan rte_tel_data_start_array(txq_state, RTE_TEL_INT_VAL); 636658b43c1dSGowrishankar Muthukrishnan for (i = 0; i < eth_dev->data->nb_tx_queues; i++) 636758b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_array_int(txq_state, 636858b43c1dSGowrishankar Muthukrishnan eth_dev->data->tx_queue_state[i]); 636958b43c1dSGowrishankar Muthukrishnan 637058b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_container(d, "rxq_state", rxq_state, 0); 637158b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_container(d, "txq_state", txq_state, 0); 637258b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "numa_node", eth_dev->data->numa_node); 637358b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "dev_flags", eth_dev->data->dev_flags); 637458b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "rx_offloads", 637558b43c1dSGowrishankar Muthukrishnan eth_dev->data->dev_conf.rxmode.offloads); 637658b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "tx_offloads", 637758b43c1dSGowrishankar Muthukrishnan eth_dev->data->dev_conf.txmode.offloads); 637858b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "ethdev_rss_hf", 637958b43c1dSGowrishankar Muthukrishnan eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf); 638058b43c1dSGowrishankar Muthukrishnan 638158b43c1dSGowrishankar Muthukrishnan return 0; 638258b43c1dSGowrishankar Muthukrishnan } 638358b43c1dSGowrishankar Muthukrishnan 638499a2dd95SBruce Richardson int 638599a2dd95SBruce Richardson rte_eth_hairpin_queue_peer_update(uint16_t peer_port, uint16_t peer_queue, 638699a2dd95SBruce Richardson struct rte_hairpin_peer_info *cur_info, 638799a2dd95SBruce Richardson struct rte_hairpin_peer_info *peer_info, 638899a2dd95SBruce Richardson uint32_t direction) 638999a2dd95SBruce Richardson { 639099a2dd95SBruce Richardson struct rte_eth_dev *dev; 639199a2dd95SBruce Richardson 639299a2dd95SBruce Richardson /* Current queue information is not mandatory. */ 639399a2dd95SBruce Richardson if (peer_info == NULL) 639499a2dd95SBruce Richardson return -EINVAL; 639599a2dd95SBruce Richardson 639699a2dd95SBruce Richardson /* No need to check the validity again. */ 639799a2dd95SBruce Richardson dev = &rte_eth_devices[peer_port]; 639899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_update, 639999a2dd95SBruce Richardson -ENOTSUP); 640099a2dd95SBruce Richardson 640199a2dd95SBruce Richardson return (*dev->dev_ops->hairpin_queue_peer_update)(dev, peer_queue, 640299a2dd95SBruce Richardson cur_info, peer_info, direction); 640399a2dd95SBruce Richardson } 640499a2dd95SBruce Richardson 640599a2dd95SBruce Richardson int 640699a2dd95SBruce Richardson rte_eth_hairpin_queue_peer_bind(uint16_t cur_port, uint16_t cur_queue, 640799a2dd95SBruce Richardson struct rte_hairpin_peer_info *peer_info, 640899a2dd95SBruce Richardson uint32_t direction) 640999a2dd95SBruce Richardson { 641099a2dd95SBruce Richardson struct rte_eth_dev *dev; 641199a2dd95SBruce Richardson 641299a2dd95SBruce Richardson if (peer_info == NULL) 641399a2dd95SBruce Richardson return -EINVAL; 641499a2dd95SBruce Richardson 641599a2dd95SBruce Richardson /* No need to check the validity again. */ 641699a2dd95SBruce Richardson dev = &rte_eth_devices[cur_port]; 641799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_bind, 641899a2dd95SBruce Richardson -ENOTSUP); 641999a2dd95SBruce Richardson 642099a2dd95SBruce Richardson return (*dev->dev_ops->hairpin_queue_peer_bind)(dev, cur_queue, 642199a2dd95SBruce Richardson peer_info, direction); 642299a2dd95SBruce Richardson } 642399a2dd95SBruce Richardson 642499a2dd95SBruce Richardson int 642599a2dd95SBruce Richardson rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue, 642699a2dd95SBruce Richardson uint32_t direction) 642799a2dd95SBruce Richardson { 642899a2dd95SBruce Richardson struct rte_eth_dev *dev; 642999a2dd95SBruce Richardson 643099a2dd95SBruce Richardson /* No need to check the validity again. */ 643199a2dd95SBruce Richardson dev = &rte_eth_devices[cur_port]; 643299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_unbind, 643399a2dd95SBruce Richardson -ENOTSUP); 643499a2dd95SBruce Richardson 643599a2dd95SBruce Richardson return (*dev->dev_ops->hairpin_queue_peer_unbind)(dev, cur_queue, 643699a2dd95SBruce Richardson direction); 643799a2dd95SBruce Richardson } 643899a2dd95SBruce Richardson 643999a2dd95SBruce Richardson int 644099a2dd95SBruce Richardson rte_eth_representor_info_get(uint16_t port_id, 644199a2dd95SBruce Richardson struct rte_eth_representor_info *info) 644299a2dd95SBruce Richardson { 644399a2dd95SBruce Richardson struct rte_eth_dev *dev; 644499a2dd95SBruce Richardson 644599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 644699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 644799a2dd95SBruce Richardson 644899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->representor_info_get, -ENOTSUP); 644953ef1b34SMin Hu (Connor) return eth_err(port_id, (*dev->dev_ops->representor_info_get)(dev, info)); 645099a2dd95SBruce Richardson } 645199a2dd95SBruce Richardson 6452f6d8a6d3SIvan Malov int 6453f6d8a6d3SIvan Malov rte_eth_rx_metadata_negotiate(uint16_t port_id, uint64_t *features) 6454f6d8a6d3SIvan Malov { 6455f6d8a6d3SIvan Malov struct rte_eth_dev *dev; 6456f6d8a6d3SIvan Malov 6457f6d8a6d3SIvan Malov RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 6458f6d8a6d3SIvan Malov dev = &rte_eth_devices[port_id]; 6459f6d8a6d3SIvan Malov 6460f6d8a6d3SIvan Malov if (dev->data->dev_configured != 0) { 6461f6d8a6d3SIvan Malov RTE_ETHDEV_LOG(ERR, 64625906be5aSAndrew Rybchenko "The port (ID=%"PRIu16") is already configured\n", 6463f6d8a6d3SIvan Malov port_id); 6464f6d8a6d3SIvan Malov return -EBUSY; 6465f6d8a6d3SIvan Malov } 6466f6d8a6d3SIvan Malov 6467f6d8a6d3SIvan Malov if (features == NULL) { 6468f6d8a6d3SIvan Malov RTE_ETHDEV_LOG(ERR, "Invalid features (NULL)\n"); 6469f6d8a6d3SIvan Malov return -EINVAL; 6470f6d8a6d3SIvan Malov } 6471f6d8a6d3SIvan Malov 6472f6d8a6d3SIvan Malov RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_metadata_negotiate, -ENOTSUP); 6473f6d8a6d3SIvan Malov return eth_err(port_id, 6474f6d8a6d3SIvan Malov (*dev->dev_ops->rx_metadata_negotiate)(dev, features)); 6475f6d8a6d3SIvan Malov } 6476f6d8a6d3SIvan Malov 6477eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO); 647899a2dd95SBruce Richardson 647999a2dd95SBruce Richardson RTE_INIT(ethdev_init_telemetry) 648099a2dd95SBruce Richardson { 648199a2dd95SBruce Richardson rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list, 648299a2dd95SBruce Richardson "Returns list of available ethdev ports. Takes no parameters"); 648399a2dd95SBruce Richardson rte_telemetry_register_cmd("/ethdev/stats", eth_dev_handle_port_stats, 648499a2dd95SBruce Richardson "Returns the common stats for a port. Parameters: int port_id"); 648599a2dd95SBruce Richardson rte_telemetry_register_cmd("/ethdev/xstats", eth_dev_handle_port_xstats, 648699a2dd95SBruce Richardson "Returns the extended stats for a port. Parameters: int port_id"); 648799a2dd95SBruce Richardson rte_telemetry_register_cmd("/ethdev/link_status", 648899a2dd95SBruce Richardson eth_dev_handle_port_link_status, 648999a2dd95SBruce Richardson "Returns the link status for a port. Parameters: int port_id"); 649058b43c1dSGowrishankar Muthukrishnan rte_telemetry_register_cmd("/ethdev/info", eth_dev_handle_port_info, 649158b43c1dSGowrishankar Muthukrishnan "Returns the device info for a port. Parameters: int port_id"); 649299a2dd95SBruce Richardson } 6493