199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2010-2017 Intel Corporation 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #include <errno.h> 699a2dd95SBruce Richardson #include <inttypes.h> 799a2dd95SBruce Richardson #include <stdbool.h> 899a2dd95SBruce Richardson #include <stdint.h> 98af559f9SChengwen Feng #include <stdio.h> 1099a2dd95SBruce Richardson #include <stdlib.h> 1199a2dd95SBruce Richardson #include <string.h> 1299a2dd95SBruce Richardson #include <sys/queue.h> 1399a2dd95SBruce Richardson 14a04322f6SDavid Marchand #include <bus_driver.h> 1599a2dd95SBruce Richardson #include <rte_log.h> 1699a2dd95SBruce Richardson #include <rte_interrupts.h> 1750e374c6SChengwen Feng #include <rte_kvargs.h> 1899a2dd95SBruce Richardson #include <rte_memcpy.h> 1999a2dd95SBruce Richardson #include <rte_common.h> 2099a2dd95SBruce Richardson #include <rte_mempool.h> 2199a2dd95SBruce Richardson #include <rte_malloc.h> 2299a2dd95SBruce Richardson #include <rte_mbuf.h> 2399a2dd95SBruce Richardson #include <rte_errno.h> 2499a2dd95SBruce Richardson #include <rte_spinlock.h> 2599a2dd95SBruce Richardson #include <rte_string_fns.h> 2699a2dd95SBruce Richardson #include <rte_class.h> 2799a2dd95SBruce Richardson #include <rte_ether.h> 2899a2dd95SBruce Richardson #include <rte_telemetry.h> 2999a2dd95SBruce Richardson 3099a2dd95SBruce Richardson #include "rte_ethdev.h" 316679cf21SAnkur Dwivedi #include "rte_ethdev_trace_fp.h" 3299a2dd95SBruce Richardson #include "ethdev_driver.h" 33fca8cba4SDavid Marchand #include "rte_flow_driver.h" 3499a2dd95SBruce Richardson #include "ethdev_profile.h" 3599a2dd95SBruce Richardson #include "ethdev_private.h" 366679cf21SAnkur Dwivedi #include "ethdev_trace.h" 377546a2cdSRobin Zhang #include "sff_telemetry.h" 3899a2dd95SBruce Richardson 3999a2dd95SBruce Richardson struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS]; 4099a2dd95SBruce Richardson 41c87d435aSKonstantin Ananyev /* public fast-path API */ 42c87d435aSKonstantin Ananyev struct rte_eth_fp_ops rte_eth_fp_ops[RTE_MAX_ETHPORTS]; 43c87d435aSKonstantin Ananyev 4409fd4227SAndrew Rybchenko /* spinlock for add/remove Rx callbacks */ 4599a2dd95SBruce Richardson static rte_spinlock_t eth_dev_rx_cb_lock = RTE_SPINLOCK_INITIALIZER; 4699a2dd95SBruce Richardson 4709fd4227SAndrew Rybchenko /* spinlock for add/remove Tx callbacks */ 4899a2dd95SBruce Richardson static rte_spinlock_t eth_dev_tx_cb_lock = RTE_SPINLOCK_INITIALIZER; 4999a2dd95SBruce Richardson 5099a2dd95SBruce Richardson /* store statistics names and its offset in stats structure */ 5199a2dd95SBruce Richardson struct rte_eth_xstats_name_off { 5299a2dd95SBruce Richardson char name[RTE_ETH_XSTATS_NAME_SIZE]; 5399a2dd95SBruce Richardson unsigned offset; 5499a2dd95SBruce Richardson }; 5599a2dd95SBruce Richardson 5699a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_stats_strings[] = { 5799a2dd95SBruce Richardson {"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)}, 5899a2dd95SBruce Richardson {"tx_good_packets", offsetof(struct rte_eth_stats, opackets)}, 5999a2dd95SBruce Richardson {"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)}, 6099a2dd95SBruce Richardson {"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)}, 6199a2dd95SBruce Richardson {"rx_missed_errors", offsetof(struct rte_eth_stats, imissed)}, 6299a2dd95SBruce Richardson {"rx_errors", offsetof(struct rte_eth_stats, ierrors)}, 6399a2dd95SBruce Richardson {"tx_errors", offsetof(struct rte_eth_stats, oerrors)}, 6499a2dd95SBruce Richardson {"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats, 6599a2dd95SBruce Richardson rx_nombuf)}, 6699a2dd95SBruce Richardson }; 6799a2dd95SBruce Richardson 6899a2dd95SBruce Richardson #define RTE_NB_STATS RTE_DIM(eth_dev_stats_strings) 6999a2dd95SBruce Richardson 7099a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_rxq_stats_strings[] = { 7199a2dd95SBruce Richardson {"packets", offsetof(struct rte_eth_stats, q_ipackets)}, 7299a2dd95SBruce Richardson {"bytes", offsetof(struct rte_eth_stats, q_ibytes)}, 7399a2dd95SBruce Richardson {"errors", offsetof(struct rte_eth_stats, q_errors)}, 7499a2dd95SBruce Richardson }; 7599a2dd95SBruce Richardson 7699a2dd95SBruce Richardson #define RTE_NB_RXQ_STATS RTE_DIM(eth_dev_rxq_stats_strings) 7799a2dd95SBruce Richardson 7899a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_txq_stats_strings[] = { 7999a2dd95SBruce Richardson {"packets", offsetof(struct rte_eth_stats, q_opackets)}, 8099a2dd95SBruce Richardson {"bytes", offsetof(struct rte_eth_stats, q_obytes)}, 8199a2dd95SBruce Richardson }; 8299a2dd95SBruce Richardson #define RTE_NB_TXQ_STATS RTE_DIM(eth_dev_txq_stats_strings) 8399a2dd95SBruce Richardson 8499a2dd95SBruce Richardson #define RTE_RX_OFFLOAD_BIT2STR(_name) \ 8599a2dd95SBruce Richardson { RTE_ETH_RX_OFFLOAD_##_name, #_name } 8699a2dd95SBruce Richardson 8799a2dd95SBruce Richardson static const struct { 8899a2dd95SBruce Richardson uint64_t offload; 8999a2dd95SBruce Richardson const char *name; 9099a2dd95SBruce Richardson } eth_dev_rx_offload_names[] = { 9199a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(VLAN_STRIP), 9299a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(IPV4_CKSUM), 9399a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(UDP_CKSUM), 9499a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(TCP_CKSUM), 9599a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(TCP_LRO), 9699a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(QINQ_STRIP), 9799a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM), 9899a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(MACSEC_STRIP), 9999a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(VLAN_FILTER), 10099a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(VLAN_EXTEND), 10199a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(SCATTER), 10299a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(TIMESTAMP), 10399a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(SECURITY), 10499a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(KEEP_CRC), 10599a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(SCTP_CKSUM), 10699a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM), 10799a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(RSS_HASH), 108295968d1SFerruh Yigit RTE_RX_OFFLOAD_BIT2STR(BUFFER_SPLIT), 10999a2dd95SBruce Richardson }; 11099a2dd95SBruce Richardson 11199a2dd95SBruce Richardson #undef RTE_RX_OFFLOAD_BIT2STR 11299a2dd95SBruce Richardson #undef RTE_ETH_RX_OFFLOAD_BIT2STR 11399a2dd95SBruce Richardson 11499a2dd95SBruce Richardson #define RTE_TX_OFFLOAD_BIT2STR(_name) \ 115295968d1SFerruh Yigit { RTE_ETH_TX_OFFLOAD_##_name, #_name } 11699a2dd95SBruce Richardson 11799a2dd95SBruce Richardson static const struct { 11899a2dd95SBruce Richardson uint64_t offload; 11999a2dd95SBruce Richardson const char *name; 12099a2dd95SBruce Richardson } eth_dev_tx_offload_names[] = { 12199a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(VLAN_INSERT), 12299a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(IPV4_CKSUM), 12399a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(UDP_CKSUM), 12499a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(TCP_CKSUM), 12599a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(SCTP_CKSUM), 12699a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(TCP_TSO), 12799a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(UDP_TSO), 12899a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM), 12999a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(QINQ_INSERT), 13099a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(VXLAN_TNL_TSO), 13199a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(GRE_TNL_TSO), 13299a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(IPIP_TNL_TSO), 13399a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(GENEVE_TNL_TSO), 13499a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MACSEC_INSERT), 13599a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MT_LOCKFREE), 13699a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MULTI_SEGS), 13799a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MBUF_FAST_FREE), 13899a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(SECURITY), 13999a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(UDP_TNL_TSO), 14099a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(IP_TNL_TSO), 14199a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM), 14299a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(SEND_ON_TIMESTAMP), 14399a2dd95SBruce Richardson }; 14499a2dd95SBruce Richardson 14599a2dd95SBruce Richardson #undef RTE_TX_OFFLOAD_BIT2STR 14699a2dd95SBruce Richardson 14793e441c9SXueming Li static const struct { 14893e441c9SXueming Li uint64_t offload; 14993e441c9SXueming Li const char *name; 15093e441c9SXueming Li } rte_eth_dev_capa_names[] = { 15193e441c9SXueming Li {RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP, "RUNTIME_RX_QUEUE_SETUP"}, 15293e441c9SXueming Li {RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP, "RUNTIME_TX_QUEUE_SETUP"}, 15393e441c9SXueming Li {RTE_ETH_DEV_CAPA_RXQ_SHARE, "RXQ_SHARE"}, 15464be0e77SDmitry Kozlyuk {RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP, "FLOW_RULE_KEEP"}, 15564be0e77SDmitry Kozlyuk {RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"}, 15693e441c9SXueming Li }; 15793e441c9SXueming Li 15899a2dd95SBruce Richardson enum { 15999a2dd95SBruce Richardson STAT_QMAP_TX = 0, 16099a2dd95SBruce Richardson STAT_QMAP_RX 16199a2dd95SBruce Richardson }; 16299a2dd95SBruce Richardson 16392628e2bSJie Hai static const struct { 16492628e2bSJie Hai enum rte_eth_hash_function algo; 16592628e2bSJie Hai const char *name; 16692628e2bSJie Hai } rte_eth_dev_rss_algo_names[] = { 16792628e2bSJie Hai {RTE_ETH_HASH_FUNCTION_DEFAULT, "default"}, 16892628e2bSJie Hai {RTE_ETH_HASH_FUNCTION_SIMPLE_XOR, "simple_xor"}, 16992628e2bSJie Hai {RTE_ETH_HASH_FUNCTION_TOEPLITZ, "toeplitz"}, 17092628e2bSJie Hai {RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ, "symmetric_toeplitz"}, 17192628e2bSJie Hai {RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ_SORT, "symmetric_toeplitz_sort"}, 17292628e2bSJie Hai }; 17392628e2bSJie Hai 17499a2dd95SBruce Richardson int 17599a2dd95SBruce Richardson rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) 17699a2dd95SBruce Richardson { 17799a2dd95SBruce Richardson int ret; 17899a2dd95SBruce Richardson struct rte_devargs devargs; 17999a2dd95SBruce Richardson const char *bus_param_key; 18099a2dd95SBruce Richardson char *bus_str = NULL; 18199a2dd95SBruce Richardson char *cls_str = NULL; 18299a2dd95SBruce Richardson int str_size; 18399a2dd95SBruce Richardson 18453ef1b34SMin Hu (Connor) if (iter == NULL) { 1850e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot initialize NULL iterator"); 18653ef1b34SMin Hu (Connor) return -EINVAL; 18753ef1b34SMin Hu (Connor) } 18853ef1b34SMin Hu (Connor) 18953ef1b34SMin Hu (Connor) if (devargs_str == NULL) { 1900e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 1910e21c7c0SDavid Marchand "Cannot initialize iterator from NULL device description string"); 19253ef1b34SMin Hu (Connor) return -EINVAL; 19353ef1b34SMin Hu (Connor) } 19453ef1b34SMin Hu (Connor) 19599a2dd95SBruce Richardson memset(iter, 0, sizeof(*iter)); 19699a2dd95SBruce Richardson memset(&devargs, 0, sizeof(devargs)); 19799a2dd95SBruce Richardson 19899a2dd95SBruce Richardson /* 19999a2dd95SBruce Richardson * The devargs string may use various syntaxes: 20099a2dd95SBruce Richardson * - 0000:08:00.0,representor=[1-3] 20199a2dd95SBruce Richardson * - pci:0000:06:00.0,representor=[0,5] 20299a2dd95SBruce Richardson * - class=eth,mac=00:11:22:33:44:55 20399a2dd95SBruce Richardson * - bus=X,paramX=x/class=Y,paramY=y/driver=Z,paramZ=z 20499a2dd95SBruce Richardson */ 20599a2dd95SBruce Richardson 20699a2dd95SBruce Richardson /* 20799a2dd95SBruce Richardson * Handle pure class filter (i.e. without any bus-level argument), 20899a2dd95SBruce Richardson * from future new syntax. 20999a2dd95SBruce Richardson * rte_devargs_parse() is not yet supporting the new syntax, 21099a2dd95SBruce Richardson * that's why this simple case is temporarily parsed here. 21199a2dd95SBruce Richardson */ 21299a2dd95SBruce Richardson #define iter_anybus_str "class=eth," 21399a2dd95SBruce Richardson if (strncmp(devargs_str, iter_anybus_str, 21499a2dd95SBruce Richardson strlen(iter_anybus_str)) == 0) { 21599a2dd95SBruce Richardson iter->cls_str = devargs_str + strlen(iter_anybus_str); 21699a2dd95SBruce Richardson goto end; 21799a2dd95SBruce Richardson } 21899a2dd95SBruce Richardson 21999a2dd95SBruce Richardson /* Split bus, device and parameters. */ 22099a2dd95SBruce Richardson ret = rte_devargs_parse(&devargs, devargs_str); 22199a2dd95SBruce Richardson if (ret != 0) 22299a2dd95SBruce Richardson goto error; 22399a2dd95SBruce Richardson 22499a2dd95SBruce Richardson /* 22599a2dd95SBruce Richardson * Assume parameters of old syntax can match only at ethdev level. 22699a2dd95SBruce Richardson * Extra parameters will be ignored, thanks to "+" prefix. 22799a2dd95SBruce Richardson */ 22899a2dd95SBruce Richardson str_size = strlen(devargs.args) + 2; 22999a2dd95SBruce Richardson cls_str = malloc(str_size); 23099a2dd95SBruce Richardson if (cls_str == NULL) { 23199a2dd95SBruce Richardson ret = -ENOMEM; 23299a2dd95SBruce Richardson goto error; 23399a2dd95SBruce Richardson } 23499a2dd95SBruce Richardson ret = snprintf(cls_str, str_size, "+%s", devargs.args); 23599a2dd95SBruce Richardson if (ret != str_size - 1) { 23699a2dd95SBruce Richardson ret = -EINVAL; 23799a2dd95SBruce Richardson goto error; 23899a2dd95SBruce Richardson } 23999a2dd95SBruce Richardson iter->cls_str = cls_str; 24099a2dd95SBruce Richardson 24199a2dd95SBruce Richardson iter->bus = devargs.bus; 24299a2dd95SBruce Richardson if (iter->bus->dev_iterate == NULL) { 24399a2dd95SBruce Richardson ret = -ENOTSUP; 24499a2dd95SBruce Richardson goto error; 24599a2dd95SBruce Richardson } 24699a2dd95SBruce Richardson 24799a2dd95SBruce Richardson /* Convert bus args to new syntax for use with new API dev_iterate. */ 248a956adb2SHemant Agrawal if ((strcmp(iter->bus->name, "vdev") == 0) || 249a956adb2SHemant Agrawal (strcmp(iter->bus->name, "fslmc") == 0) || 250a956adb2SHemant Agrawal (strcmp(iter->bus->name, "dpaa_bus") == 0)) { 25199a2dd95SBruce Richardson bus_param_key = "name"; 25299a2dd95SBruce Richardson } else if (strcmp(iter->bus->name, "pci") == 0) { 25399a2dd95SBruce Richardson bus_param_key = "addr"; 25499a2dd95SBruce Richardson } else { 25599a2dd95SBruce Richardson ret = -ENOTSUP; 25699a2dd95SBruce Richardson goto error; 25799a2dd95SBruce Richardson } 25899a2dd95SBruce Richardson str_size = strlen(bus_param_key) + strlen(devargs.name) + 2; 25999a2dd95SBruce Richardson bus_str = malloc(str_size); 26099a2dd95SBruce Richardson if (bus_str == NULL) { 26199a2dd95SBruce Richardson ret = -ENOMEM; 26299a2dd95SBruce Richardson goto error; 26399a2dd95SBruce Richardson } 26499a2dd95SBruce Richardson ret = snprintf(bus_str, str_size, "%s=%s", 26599a2dd95SBruce Richardson bus_param_key, devargs.name); 26699a2dd95SBruce Richardson if (ret != str_size - 1) { 26799a2dd95SBruce Richardson ret = -EINVAL; 26899a2dd95SBruce Richardson goto error; 26999a2dd95SBruce Richardson } 27099a2dd95SBruce Richardson iter->bus_str = bus_str; 27199a2dd95SBruce Richardson 27299a2dd95SBruce Richardson end: 27399a2dd95SBruce Richardson iter->cls = rte_class_find_by_name("eth"); 27499a2dd95SBruce Richardson rte_devargs_reset(&devargs); 2756679cf21SAnkur Dwivedi 2766679cf21SAnkur Dwivedi rte_eth_trace_iterator_init(devargs_str); 2776679cf21SAnkur Dwivedi 27899a2dd95SBruce Richardson return 0; 27999a2dd95SBruce Richardson 28099a2dd95SBruce Richardson error: 28199a2dd95SBruce Richardson if (ret == -ENOTSUP) 2820e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Bus %s does not support iterating.", 28399a2dd95SBruce Richardson iter->bus->name); 28499a2dd95SBruce Richardson rte_devargs_reset(&devargs); 28599a2dd95SBruce Richardson free(bus_str); 28699a2dd95SBruce Richardson free(cls_str); 28799a2dd95SBruce Richardson return ret; 28899a2dd95SBruce Richardson } 28999a2dd95SBruce Richardson 29099a2dd95SBruce Richardson uint16_t 29199a2dd95SBruce Richardson rte_eth_iterator_next(struct rte_dev_iterator *iter) 29299a2dd95SBruce Richardson { 29353ef1b34SMin Hu (Connor) if (iter == NULL) { 2940e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 2950e21c7c0SDavid Marchand "Cannot get next device from NULL iterator"); 29653ef1b34SMin Hu (Connor) return RTE_MAX_ETHPORTS; 29753ef1b34SMin Hu (Connor) } 29853ef1b34SMin Hu (Connor) 29999a2dd95SBruce Richardson if (iter->cls == NULL) /* invalid ethdev iterator */ 30099a2dd95SBruce Richardson return RTE_MAX_ETHPORTS; 30199a2dd95SBruce Richardson 30299a2dd95SBruce Richardson do { /* loop to try all matching rte_device */ 30399a2dd95SBruce Richardson /* If not pure ethdev filter and */ 30499a2dd95SBruce Richardson if (iter->bus != NULL && 30599a2dd95SBruce Richardson /* not in middle of rte_eth_dev iteration, */ 30699a2dd95SBruce Richardson iter->class_device == NULL) { 30799a2dd95SBruce Richardson /* get next rte_device to try. */ 30899a2dd95SBruce Richardson iter->device = iter->bus->dev_iterate( 30999a2dd95SBruce Richardson iter->device, iter->bus_str, iter); 31099a2dd95SBruce Richardson if (iter->device == NULL) 31199a2dd95SBruce Richardson break; /* no more rte_device candidate */ 31299a2dd95SBruce Richardson } 31399a2dd95SBruce Richardson /* A device is matching bus part, need to check ethdev part. */ 31499a2dd95SBruce Richardson iter->class_device = iter->cls->dev_iterate( 31599a2dd95SBruce Richardson iter->class_device, iter->cls_str, iter); 3166679cf21SAnkur Dwivedi if (iter->class_device != NULL) { 3176679cf21SAnkur Dwivedi uint16_t id = eth_dev_to_id(iter->class_device); 3186679cf21SAnkur Dwivedi 3196679cf21SAnkur Dwivedi rte_eth_trace_iterator_next(iter, id); 3206679cf21SAnkur Dwivedi 3216679cf21SAnkur Dwivedi return id; /* match */ 3226679cf21SAnkur Dwivedi } 32399a2dd95SBruce Richardson } while (iter->bus != NULL); /* need to try next rte_device */ 32499a2dd95SBruce Richardson 32599a2dd95SBruce Richardson /* No more ethdev port to iterate. */ 32699a2dd95SBruce Richardson rte_eth_iterator_cleanup(iter); 32799a2dd95SBruce Richardson return RTE_MAX_ETHPORTS; 32899a2dd95SBruce Richardson } 32999a2dd95SBruce Richardson 33099a2dd95SBruce Richardson void 33199a2dd95SBruce Richardson rte_eth_iterator_cleanup(struct rte_dev_iterator *iter) 33299a2dd95SBruce Richardson { 33353ef1b34SMin Hu (Connor) if (iter == NULL) { 3340e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot do clean up from NULL iterator"); 33553ef1b34SMin Hu (Connor) return; 33653ef1b34SMin Hu (Connor) } 33753ef1b34SMin Hu (Connor) 33899a2dd95SBruce Richardson if (iter->bus_str == NULL) 33999a2dd95SBruce Richardson return; /* nothing to free in pure class filter */ 3406679cf21SAnkur Dwivedi 3416679cf21SAnkur Dwivedi rte_eth_trace_iterator_cleanup(iter); 3426679cf21SAnkur Dwivedi 34399a2dd95SBruce Richardson free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */ 34499a2dd95SBruce Richardson free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */ 34599a2dd95SBruce Richardson memset(iter, 0, sizeof(*iter)); 34699a2dd95SBruce Richardson } 34799a2dd95SBruce Richardson 34899a2dd95SBruce Richardson uint16_t 34999a2dd95SBruce Richardson rte_eth_find_next(uint16_t port_id) 35099a2dd95SBruce Richardson { 35199a2dd95SBruce Richardson while (port_id < RTE_MAX_ETHPORTS && 35299a2dd95SBruce Richardson rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED) 35399a2dd95SBruce Richardson port_id++; 35499a2dd95SBruce Richardson 35599a2dd95SBruce Richardson if (port_id >= RTE_MAX_ETHPORTS) 35699a2dd95SBruce Richardson return RTE_MAX_ETHPORTS; 35799a2dd95SBruce Richardson 3586679cf21SAnkur Dwivedi rte_eth_trace_find_next(port_id); 3596679cf21SAnkur Dwivedi 36099a2dd95SBruce Richardson return port_id; 36199a2dd95SBruce Richardson } 36299a2dd95SBruce Richardson 36399a2dd95SBruce Richardson /* 36499a2dd95SBruce Richardson * Macro to iterate over all valid ports for internal usage. 36599a2dd95SBruce Richardson * Note: RTE_ETH_FOREACH_DEV is different because filtering owned ports. 36699a2dd95SBruce Richardson */ 36799a2dd95SBruce Richardson #define RTE_ETH_FOREACH_VALID_DEV(port_id) \ 36899a2dd95SBruce Richardson for (port_id = rte_eth_find_next(0); \ 36999a2dd95SBruce Richardson port_id < RTE_MAX_ETHPORTS; \ 37099a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id + 1)) 37199a2dd95SBruce Richardson 37299a2dd95SBruce Richardson uint16_t 37399a2dd95SBruce Richardson rte_eth_find_next_of(uint16_t port_id, const struct rte_device *parent) 37499a2dd95SBruce Richardson { 37599a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id); 37699a2dd95SBruce Richardson while (port_id < RTE_MAX_ETHPORTS && 37799a2dd95SBruce Richardson rte_eth_devices[port_id].device != parent) 37899a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id + 1); 37999a2dd95SBruce Richardson 3806679cf21SAnkur Dwivedi rte_eth_trace_find_next_of(port_id, parent); 3816679cf21SAnkur Dwivedi 38299a2dd95SBruce Richardson return port_id; 38399a2dd95SBruce Richardson } 38499a2dd95SBruce Richardson 38599a2dd95SBruce Richardson uint16_t 38699a2dd95SBruce Richardson rte_eth_find_next_sibling(uint16_t port_id, uint16_t ref_port_id) 38799a2dd95SBruce Richardson { 3886679cf21SAnkur Dwivedi uint16_t ret; 3896679cf21SAnkur Dwivedi 39099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(ref_port_id, RTE_MAX_ETHPORTS); 3916679cf21SAnkur Dwivedi ret = rte_eth_find_next_of(port_id, 39299a2dd95SBruce Richardson rte_eth_devices[ref_port_id].device); 3936679cf21SAnkur Dwivedi 3946679cf21SAnkur Dwivedi rte_eth_trace_find_next_sibling(port_id, ref_port_id, ret); 3956679cf21SAnkur Dwivedi 3966679cf21SAnkur Dwivedi return ret; 39799a2dd95SBruce Richardson } 39899a2dd95SBruce Richardson 39999a2dd95SBruce Richardson static bool 40099a2dd95SBruce Richardson eth_dev_is_allocated(const struct rte_eth_dev *ethdev) 40199a2dd95SBruce Richardson { 4027fe371ebSDavid Marchand return ethdev->data != NULL && ethdev->data->name[0] != '\0'; 40399a2dd95SBruce Richardson } 40499a2dd95SBruce Richardson 40599a2dd95SBruce Richardson int 40699a2dd95SBruce Richardson rte_eth_dev_is_valid_port(uint16_t port_id) 40799a2dd95SBruce Richardson { 4086679cf21SAnkur Dwivedi int is_valid; 4096679cf21SAnkur Dwivedi 41099a2dd95SBruce Richardson if (port_id >= RTE_MAX_ETHPORTS || 41199a2dd95SBruce Richardson (rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED)) 4126679cf21SAnkur Dwivedi is_valid = 0; 41399a2dd95SBruce Richardson else 4146679cf21SAnkur Dwivedi is_valid = 1; 4156679cf21SAnkur Dwivedi 4166679cf21SAnkur Dwivedi rte_ethdev_trace_is_valid_port(port_id, is_valid); 4176679cf21SAnkur Dwivedi 4186679cf21SAnkur Dwivedi return is_valid; 41999a2dd95SBruce Richardson } 42099a2dd95SBruce Richardson 42199a2dd95SBruce Richardson static int 42299a2dd95SBruce Richardson eth_is_valid_owner_id(uint64_t owner_id) 4235fa33785SDavid Marchand __rte_exclusive_locks_required(rte_mcfg_ethdev_get_lock()) 42499a2dd95SBruce Richardson { 42599a2dd95SBruce Richardson if (owner_id == RTE_ETH_DEV_NO_OWNER || 42699a2dd95SBruce Richardson eth_dev_shared_data->next_owner_id <= owner_id) 42799a2dd95SBruce Richardson return 0; 42899a2dd95SBruce Richardson return 1; 42999a2dd95SBruce Richardson } 43099a2dd95SBruce Richardson 43199a2dd95SBruce Richardson uint64_t 43299a2dd95SBruce Richardson rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id) 43399a2dd95SBruce Richardson { 43499a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id); 43599a2dd95SBruce Richardson while (port_id < RTE_MAX_ETHPORTS && 43699a2dd95SBruce Richardson rte_eth_devices[port_id].data->owner.id != owner_id) 43799a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id + 1); 43899a2dd95SBruce Richardson 4396679cf21SAnkur Dwivedi rte_eth_trace_find_next_owned_by(port_id, owner_id); 4406679cf21SAnkur Dwivedi 44199a2dd95SBruce Richardson return port_id; 44299a2dd95SBruce Richardson } 44399a2dd95SBruce Richardson 44499a2dd95SBruce Richardson int 44599a2dd95SBruce Richardson rte_eth_dev_owner_new(uint64_t *owner_id) 44699a2dd95SBruce Richardson { 4477fe371ebSDavid Marchand int ret; 4487fe371ebSDavid Marchand 44953ef1b34SMin Hu (Connor) if (owner_id == NULL) { 4500e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get new owner ID to NULL"); 45153ef1b34SMin Hu (Connor) return -EINVAL; 45253ef1b34SMin Hu (Connor) } 45353ef1b34SMin Hu (Connor) 4545fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 4555fa33785SDavid Marchand 4567fe371ebSDavid Marchand if (eth_dev_shared_data_prepare() != NULL) { 45799a2dd95SBruce Richardson *owner_id = eth_dev_shared_data->next_owner_id++; 45836c46e73SDavid Marchand eth_dev_shared_data->allocated_owners++; 4597fe371ebSDavid Marchand ret = 0; 4607fe371ebSDavid Marchand } else { 4617fe371ebSDavid Marchand ret = -ENOMEM; 4627fe371ebSDavid Marchand } 46399a2dd95SBruce Richardson 4645fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 4656679cf21SAnkur Dwivedi 4667fe371ebSDavid Marchand rte_ethdev_trace_owner_new(*owner_id, ret); 4676679cf21SAnkur Dwivedi 4687fe371ebSDavid Marchand return ret; 46999a2dd95SBruce Richardson } 47099a2dd95SBruce Richardson 47199a2dd95SBruce Richardson static int 47299a2dd95SBruce Richardson eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id, 47399a2dd95SBruce Richardson const struct rte_eth_dev_owner *new_owner) 4745fa33785SDavid Marchand __rte_exclusive_locks_required(rte_mcfg_ethdev_get_lock()) 47599a2dd95SBruce Richardson { 47699a2dd95SBruce Richardson struct rte_eth_dev *ethdev = &rte_eth_devices[port_id]; 47799a2dd95SBruce Richardson struct rte_eth_dev_owner *port_owner; 47899a2dd95SBruce Richardson 47999a2dd95SBruce Richardson if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) { 4800e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Port ID %"PRIu16" is not allocated", 48199a2dd95SBruce Richardson port_id); 48299a2dd95SBruce Richardson return -ENODEV; 48399a2dd95SBruce Richardson } 48499a2dd95SBruce Richardson 48553ef1b34SMin Hu (Connor) if (new_owner == NULL) { 4860e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 4870e21c7c0SDavid Marchand "Cannot set ethdev port %u owner from NULL owner", 48853ef1b34SMin Hu (Connor) port_id); 48953ef1b34SMin Hu (Connor) return -EINVAL; 49053ef1b34SMin Hu (Connor) } 49153ef1b34SMin Hu (Connor) 49299a2dd95SBruce Richardson if (!eth_is_valid_owner_id(new_owner->id) && 49399a2dd95SBruce Richardson !eth_is_valid_owner_id(old_owner_id)) { 4940e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 4950e21c7c0SDavid Marchand "Invalid owner old_id=%016"PRIx64" new_id=%016"PRIx64, 49699a2dd95SBruce Richardson old_owner_id, new_owner->id); 49799a2dd95SBruce Richardson return -EINVAL; 49899a2dd95SBruce Richardson } 49999a2dd95SBruce Richardson 50099a2dd95SBruce Richardson port_owner = &rte_eth_devices[port_id].data->owner; 50199a2dd95SBruce Richardson if (port_owner->id != old_owner_id) { 5020e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 5030e21c7c0SDavid Marchand "Cannot set owner to port %u already owned by %s_%016"PRIX64, 50499a2dd95SBruce Richardson port_id, port_owner->name, port_owner->id); 50599a2dd95SBruce Richardson return -EPERM; 50699a2dd95SBruce Richardson } 50799a2dd95SBruce Richardson 50899a2dd95SBruce Richardson /* can not truncate (same structure) */ 50999a2dd95SBruce Richardson strlcpy(port_owner->name, new_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN); 51099a2dd95SBruce Richardson 51199a2dd95SBruce Richardson port_owner->id = new_owner->id; 51299a2dd95SBruce Richardson 5130e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(DEBUG, "Port %u owner is %s_%016"PRIx64, 51499a2dd95SBruce Richardson port_id, new_owner->name, new_owner->id); 51599a2dd95SBruce Richardson 51699a2dd95SBruce Richardson return 0; 51799a2dd95SBruce Richardson } 51899a2dd95SBruce Richardson 51999a2dd95SBruce Richardson int 52099a2dd95SBruce Richardson rte_eth_dev_owner_set(const uint16_t port_id, 52199a2dd95SBruce Richardson const struct rte_eth_dev_owner *owner) 52299a2dd95SBruce Richardson { 52399a2dd95SBruce Richardson int ret; 52499a2dd95SBruce Richardson 5255fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 5265fa33785SDavid Marchand 5277fe371ebSDavid Marchand if (eth_dev_shared_data_prepare() != NULL) 52899a2dd95SBruce Richardson ret = eth_dev_owner_set(port_id, RTE_ETH_DEV_NO_OWNER, owner); 5297fe371ebSDavid Marchand else 5307fe371ebSDavid Marchand ret = -ENOMEM; 53199a2dd95SBruce Richardson 5325fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 5336679cf21SAnkur Dwivedi 5346679cf21SAnkur Dwivedi rte_ethdev_trace_owner_set(port_id, owner, ret); 5356679cf21SAnkur Dwivedi 53699a2dd95SBruce Richardson return ret; 53799a2dd95SBruce Richardson } 53899a2dd95SBruce Richardson 53999a2dd95SBruce Richardson int 54099a2dd95SBruce Richardson rte_eth_dev_owner_unset(const uint16_t port_id, const uint64_t owner_id) 54199a2dd95SBruce Richardson { 54299a2dd95SBruce Richardson const struct rte_eth_dev_owner new_owner = (struct rte_eth_dev_owner) 54399a2dd95SBruce Richardson {.id = RTE_ETH_DEV_NO_OWNER, .name = ""}; 54499a2dd95SBruce Richardson int ret; 54599a2dd95SBruce Richardson 5465fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 5475fa33785SDavid Marchand 5487fe371ebSDavid Marchand if (eth_dev_shared_data_prepare() != NULL) 54999a2dd95SBruce Richardson ret = eth_dev_owner_set(port_id, owner_id, &new_owner); 5507fe371ebSDavid Marchand else 5517fe371ebSDavid Marchand ret = -ENOMEM; 55299a2dd95SBruce Richardson 5535fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 5546679cf21SAnkur Dwivedi 5556679cf21SAnkur Dwivedi rte_ethdev_trace_owner_unset(port_id, owner_id, ret); 5566679cf21SAnkur Dwivedi 55799a2dd95SBruce Richardson return ret; 55899a2dd95SBruce Richardson } 55999a2dd95SBruce Richardson 56099a2dd95SBruce Richardson int 56199a2dd95SBruce Richardson rte_eth_dev_owner_delete(const uint64_t owner_id) 56299a2dd95SBruce Richardson { 56399a2dd95SBruce Richardson uint16_t port_id; 56499a2dd95SBruce Richardson int ret = 0; 56599a2dd95SBruce Richardson 5665fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 5675fa33785SDavid Marchand 5687fe371ebSDavid Marchand if (eth_dev_shared_data_prepare() == NULL) { 5697fe371ebSDavid Marchand ret = -ENOMEM; 5707fe371ebSDavid Marchand } else if (eth_is_valid_owner_id(owner_id)) { 571b7ade5d3SFerruh Yigit for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { 572b7ade5d3SFerruh Yigit struct rte_eth_dev_data *data = 573b7ade5d3SFerruh Yigit rte_eth_devices[port_id].data; 574b7ade5d3SFerruh Yigit if (data != NULL && data->owner.id == owner_id) 575b7ade5d3SFerruh Yigit memset(&data->owner, 0, 57699a2dd95SBruce Richardson sizeof(struct rte_eth_dev_owner)); 577b7ade5d3SFerruh Yigit } 5780e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(NOTICE, 5790e21c7c0SDavid Marchand "All port owners owned by %016"PRIx64" identifier have removed", 58099a2dd95SBruce Richardson owner_id); 58136c46e73SDavid Marchand eth_dev_shared_data->allocated_owners--; 58236c46e73SDavid Marchand eth_dev_shared_data_release(); 58399a2dd95SBruce Richardson } else { 5840e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 5850e21c7c0SDavid Marchand "Invalid owner ID=%016"PRIx64, 58699a2dd95SBruce Richardson owner_id); 58799a2dd95SBruce Richardson ret = -EINVAL; 58899a2dd95SBruce Richardson } 58999a2dd95SBruce Richardson 5905fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 59199a2dd95SBruce Richardson 5926679cf21SAnkur Dwivedi rte_ethdev_trace_owner_delete(owner_id, ret); 5936679cf21SAnkur Dwivedi 59499a2dd95SBruce Richardson return ret; 59599a2dd95SBruce Richardson } 59699a2dd95SBruce Richardson 59799a2dd95SBruce Richardson int 59899a2dd95SBruce Richardson rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner) 59999a2dd95SBruce Richardson { 60053ef1b34SMin Hu (Connor) struct rte_eth_dev *ethdev; 6017fe371ebSDavid Marchand int ret; 60253ef1b34SMin Hu (Connor) 60353ef1b34SMin Hu (Connor) RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 60453ef1b34SMin Hu (Connor) ethdev = &rte_eth_devices[port_id]; 60553ef1b34SMin Hu (Connor) 60653ef1b34SMin Hu (Connor) if (!eth_dev_is_allocated(ethdev)) { 6070e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Port ID %"PRIu16" is not allocated", 60853ef1b34SMin Hu (Connor) port_id); 60953ef1b34SMin Hu (Connor) return -ENODEV; 61053ef1b34SMin Hu (Connor) } 61153ef1b34SMin Hu (Connor) 61253ef1b34SMin Hu (Connor) if (owner == NULL) { 6130e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u owner to NULL", 61453ef1b34SMin Hu (Connor) port_id); 61553ef1b34SMin Hu (Connor) return -EINVAL; 61653ef1b34SMin Hu (Connor) } 61799a2dd95SBruce Richardson 6185fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 61999a2dd95SBruce Richardson 6207fe371ebSDavid Marchand if (eth_dev_shared_data_prepare() != NULL) { 62199a2dd95SBruce Richardson rte_memcpy(owner, ðdev->data->owner, sizeof(*owner)); 6227fe371ebSDavid Marchand ret = 0; 6237fe371ebSDavid Marchand } else { 6247fe371ebSDavid Marchand ret = -ENOMEM; 6257fe371ebSDavid Marchand } 6265fa33785SDavid Marchand 6275fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 62853ef1b34SMin Hu (Connor) 6297fe371ebSDavid Marchand rte_ethdev_trace_owner_get(port_id, owner, ret); 6306679cf21SAnkur Dwivedi 6317fe371ebSDavid Marchand return ret; 63299a2dd95SBruce Richardson } 63399a2dd95SBruce Richardson 63499a2dd95SBruce Richardson int 63599a2dd95SBruce Richardson rte_eth_dev_socket_id(uint16_t port_id) 63699a2dd95SBruce Richardson { 6377dcd73e3SOlivier Matz int socket_id = SOCKET_ID_ANY; 6387dcd73e3SOlivier Matz 6397dcd73e3SOlivier Matz if (!rte_eth_dev_is_valid_port(port_id)) { 6407dcd73e3SOlivier Matz rte_errno = EINVAL; 6417dcd73e3SOlivier Matz } else { 6427dcd73e3SOlivier Matz socket_id = rte_eth_devices[port_id].data->numa_node; 6437dcd73e3SOlivier Matz if (socket_id == SOCKET_ID_ANY) 6447dcd73e3SOlivier Matz rte_errno = 0; 6457dcd73e3SOlivier Matz } 6466679cf21SAnkur Dwivedi 6476679cf21SAnkur Dwivedi rte_ethdev_trace_socket_id(port_id, socket_id); 6486679cf21SAnkur Dwivedi 6497dcd73e3SOlivier Matz return socket_id; 65099a2dd95SBruce Richardson } 65199a2dd95SBruce Richardson 65299a2dd95SBruce Richardson void * 65399a2dd95SBruce Richardson rte_eth_dev_get_sec_ctx(uint16_t port_id) 65499a2dd95SBruce Richardson { 6556679cf21SAnkur Dwivedi void *ctx; 6566679cf21SAnkur Dwivedi 65799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL); 6586679cf21SAnkur Dwivedi ctx = rte_eth_devices[port_id].security_ctx; 6596679cf21SAnkur Dwivedi 6606679cf21SAnkur Dwivedi rte_ethdev_trace_get_sec_ctx(port_id, ctx); 6616679cf21SAnkur Dwivedi 6626679cf21SAnkur Dwivedi return ctx; 66399a2dd95SBruce Richardson } 66499a2dd95SBruce Richardson 66599a2dd95SBruce Richardson uint16_t 66699a2dd95SBruce Richardson rte_eth_dev_count_avail(void) 66799a2dd95SBruce Richardson { 66899a2dd95SBruce Richardson uint16_t p; 66999a2dd95SBruce Richardson uint16_t count; 67099a2dd95SBruce Richardson 67199a2dd95SBruce Richardson count = 0; 67299a2dd95SBruce Richardson 67399a2dd95SBruce Richardson RTE_ETH_FOREACH_DEV(p) 67499a2dd95SBruce Richardson count++; 67599a2dd95SBruce Richardson 6766679cf21SAnkur Dwivedi rte_ethdev_trace_count_avail(count); 6776679cf21SAnkur Dwivedi 67899a2dd95SBruce Richardson return count; 67999a2dd95SBruce Richardson } 68099a2dd95SBruce Richardson 68199a2dd95SBruce Richardson uint16_t 68299a2dd95SBruce Richardson rte_eth_dev_count_total(void) 68399a2dd95SBruce Richardson { 68499a2dd95SBruce Richardson uint16_t port, count = 0; 68599a2dd95SBruce Richardson 68699a2dd95SBruce Richardson RTE_ETH_FOREACH_VALID_DEV(port) 68799a2dd95SBruce Richardson count++; 68899a2dd95SBruce Richardson 6896679cf21SAnkur Dwivedi rte_ethdev_trace_count_total(count); 6906679cf21SAnkur Dwivedi 69199a2dd95SBruce Richardson return count; 69299a2dd95SBruce Richardson } 69399a2dd95SBruce Richardson 69499a2dd95SBruce Richardson int 69599a2dd95SBruce Richardson rte_eth_dev_get_name_by_port(uint16_t port_id, char *name) 69699a2dd95SBruce Richardson { 69799a2dd95SBruce Richardson char *tmp; 69899a2dd95SBruce Richardson 69999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 70099a2dd95SBruce Richardson 70199a2dd95SBruce Richardson if (name == NULL) { 7020e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u name to NULL", 70353ef1b34SMin Hu (Connor) port_id); 70499a2dd95SBruce Richardson return -EINVAL; 70599a2dd95SBruce Richardson } 70699a2dd95SBruce Richardson 7075fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 70899a2dd95SBruce Richardson /* shouldn't check 'rte_eth_devices[i].data', 70999a2dd95SBruce Richardson * because it might be overwritten by VDEV PMD */ 71099a2dd95SBruce Richardson tmp = eth_dev_shared_data->data[port_id].name; 7115fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 7125fa33785SDavid Marchand 71399a2dd95SBruce Richardson strcpy(name, tmp); 7146679cf21SAnkur Dwivedi 7156679cf21SAnkur Dwivedi rte_ethdev_trace_get_name_by_port(port_id, name); 7166679cf21SAnkur Dwivedi 71799a2dd95SBruce Richardson return 0; 71899a2dd95SBruce Richardson } 71999a2dd95SBruce Richardson 72099a2dd95SBruce Richardson int 72199a2dd95SBruce Richardson rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id) 72299a2dd95SBruce Richardson { 7235fa33785SDavid Marchand int ret = -ENODEV; 72499a2dd95SBruce Richardson uint16_t pid; 72599a2dd95SBruce Richardson 72699a2dd95SBruce Richardson if (name == NULL) { 7270e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get port ID from NULL name"); 72853ef1b34SMin Hu (Connor) return -EINVAL; 72953ef1b34SMin Hu (Connor) } 73053ef1b34SMin Hu (Connor) 73153ef1b34SMin Hu (Connor) if (port_id == NULL) { 7320e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 7330e21c7c0SDavid Marchand "Cannot get port ID to NULL for %s", name); 73499a2dd95SBruce Richardson return -EINVAL; 73599a2dd95SBruce Richardson } 73699a2dd95SBruce Richardson 7375fa33785SDavid Marchand rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 7385fa33785SDavid Marchand RTE_ETH_FOREACH_VALID_DEV(pid) { 7395fa33785SDavid Marchand if (strcmp(name, eth_dev_shared_data->data[pid].name) != 0) 7405fa33785SDavid Marchand continue; 7415fa33785SDavid Marchand 74299a2dd95SBruce Richardson *port_id = pid; 7436679cf21SAnkur Dwivedi rte_ethdev_trace_get_port_by_name(name, *port_id); 7445fa33785SDavid Marchand ret = 0; 7455fa33785SDavid Marchand break; 74699a2dd95SBruce Richardson } 7475fa33785SDavid Marchand rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 74899a2dd95SBruce Richardson 7495fa33785SDavid Marchand return ret; 75099a2dd95SBruce Richardson } 75199a2dd95SBruce Richardson 7526b81dddbSJerin Jacob int 75399a2dd95SBruce Richardson eth_err(uint16_t port_id, int ret) 75499a2dd95SBruce Richardson { 75599a2dd95SBruce Richardson if (ret == 0) 75699a2dd95SBruce Richardson return 0; 75799a2dd95SBruce Richardson if (rte_eth_dev_is_removed(port_id)) 75899a2dd95SBruce Richardson return -EIO; 75999a2dd95SBruce Richardson return ret; 76099a2dd95SBruce Richardson } 76199a2dd95SBruce Richardson 76299a2dd95SBruce Richardson static int 76399a2dd95SBruce Richardson eth_dev_validate_rx_queue(const struct rte_eth_dev *dev, uint16_t rx_queue_id) 76499a2dd95SBruce Richardson { 76599a2dd95SBruce Richardson uint16_t port_id; 76699a2dd95SBruce Richardson 76799a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 76899a2dd95SBruce Richardson port_id = dev->data->port_id; 7690e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 7700e21c7c0SDavid Marchand "Invalid Rx queue_id=%u of device with port_id=%u", 77199a2dd95SBruce Richardson rx_queue_id, port_id); 77299a2dd95SBruce Richardson return -EINVAL; 77399a2dd95SBruce Richardson } 77499a2dd95SBruce Richardson 77599a2dd95SBruce Richardson if (dev->data->rx_queues[rx_queue_id] == NULL) { 77699a2dd95SBruce Richardson port_id = dev->data->port_id; 7770e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 7780e21c7c0SDavid Marchand "Queue %u of device with port_id=%u has not been setup", 77999a2dd95SBruce Richardson rx_queue_id, port_id); 78099a2dd95SBruce Richardson return -EINVAL; 78199a2dd95SBruce Richardson } 78299a2dd95SBruce Richardson 78399a2dd95SBruce Richardson return 0; 78499a2dd95SBruce Richardson } 78599a2dd95SBruce Richardson 78699a2dd95SBruce Richardson static int 78799a2dd95SBruce Richardson eth_dev_validate_tx_queue(const struct rte_eth_dev *dev, uint16_t tx_queue_id) 78899a2dd95SBruce Richardson { 78999a2dd95SBruce Richardson uint16_t port_id; 79099a2dd95SBruce Richardson 79199a2dd95SBruce Richardson if (tx_queue_id >= dev->data->nb_tx_queues) { 79299a2dd95SBruce Richardson port_id = dev->data->port_id; 7930e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 7940e21c7c0SDavid Marchand "Invalid Tx queue_id=%u of device with port_id=%u", 79599a2dd95SBruce Richardson tx_queue_id, port_id); 79699a2dd95SBruce Richardson return -EINVAL; 79799a2dd95SBruce Richardson } 79899a2dd95SBruce Richardson 79999a2dd95SBruce Richardson if (dev->data->tx_queues[tx_queue_id] == NULL) { 80099a2dd95SBruce Richardson port_id = dev->data->port_id; 8010e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 8020e21c7c0SDavid Marchand "Queue %u of device with port_id=%u has not been setup", 80399a2dd95SBruce Richardson tx_queue_id, port_id); 80499a2dd95SBruce Richardson return -EINVAL; 80599a2dd95SBruce Richardson } 80699a2dd95SBruce Richardson 80799a2dd95SBruce Richardson return 0; 80899a2dd95SBruce Richardson } 80999a2dd95SBruce Richardson 81099a2dd95SBruce Richardson int 81166a1e115SThomas Monjalon rte_eth_rx_queue_is_valid(uint16_t port_id, uint16_t queue_id) 8127ea7e0cdSDengdui Huang { 8137ea7e0cdSDengdui Huang struct rte_eth_dev *dev; 8147ea7e0cdSDengdui Huang 8157ea7e0cdSDengdui Huang RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 8167ea7e0cdSDengdui Huang dev = &rte_eth_devices[port_id]; 8177ea7e0cdSDengdui Huang 8187ea7e0cdSDengdui Huang return eth_dev_validate_rx_queue(dev, queue_id); 8197ea7e0cdSDengdui Huang } 8207ea7e0cdSDengdui Huang 8217ea7e0cdSDengdui Huang int 82266a1e115SThomas Monjalon rte_eth_tx_queue_is_valid(uint16_t port_id, uint16_t queue_id) 8237ea7e0cdSDengdui Huang { 8247ea7e0cdSDengdui Huang struct rte_eth_dev *dev; 8257ea7e0cdSDengdui Huang 8267ea7e0cdSDengdui Huang RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 8277ea7e0cdSDengdui Huang dev = &rte_eth_devices[port_id]; 8287ea7e0cdSDengdui Huang 8297ea7e0cdSDengdui Huang return eth_dev_validate_tx_queue(dev, queue_id); 8307ea7e0cdSDengdui Huang } 8317ea7e0cdSDengdui Huang 8327ea7e0cdSDengdui Huang int 83399a2dd95SBruce Richardson rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id) 83499a2dd95SBruce Richardson { 83599a2dd95SBruce Richardson struct rte_eth_dev *dev; 83699a2dd95SBruce Richardson int ret; 83799a2dd95SBruce Richardson 83899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 83999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 84053ef1b34SMin Hu (Connor) 84199a2dd95SBruce Richardson if (!dev->data->dev_started) { 8420e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 8430e21c7c0SDavid Marchand "Port %u must be started before start any queue", 84499a2dd95SBruce Richardson port_id); 84599a2dd95SBruce Richardson return -EINVAL; 84699a2dd95SBruce Richardson } 84799a2dd95SBruce Richardson 84899a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, rx_queue_id); 84999a2dd95SBruce Richardson if (ret != 0) 85099a2dd95SBruce Richardson return ret; 85199a2dd95SBruce Richardson 8528f1d23ecSDavid Marchand if (*dev->dev_ops->rx_queue_start == NULL) 8538f1d23ecSDavid Marchand return -ENOTSUP; 85499a2dd95SBruce Richardson 85599a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) { 8560e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 8570e21c7c0SDavid Marchand "Can't start Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16, 85899a2dd95SBruce Richardson rx_queue_id, port_id); 85999a2dd95SBruce Richardson return -EINVAL; 86099a2dd95SBruce Richardson } 86199a2dd95SBruce Richardson 86299a2dd95SBruce Richardson if (dev->data->rx_queue_state[rx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) { 8630e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 8640e21c7c0SDavid Marchand "Queue %"PRIu16" of device with port_id=%"PRIu16" already started", 86599a2dd95SBruce Richardson rx_queue_id, port_id); 86699a2dd95SBruce Richardson return 0; 86799a2dd95SBruce Richardson } 86899a2dd95SBruce Richardson 8696679cf21SAnkur Dwivedi ret = eth_err(port_id, dev->dev_ops->rx_queue_start(dev, rx_queue_id)); 8706679cf21SAnkur Dwivedi 8716679cf21SAnkur Dwivedi rte_ethdev_trace_rx_queue_start(port_id, rx_queue_id, ret); 8726679cf21SAnkur Dwivedi 8736679cf21SAnkur Dwivedi return ret; 87499a2dd95SBruce Richardson } 87599a2dd95SBruce Richardson 87699a2dd95SBruce Richardson int 87799a2dd95SBruce Richardson rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id) 87899a2dd95SBruce Richardson { 87999a2dd95SBruce Richardson struct rte_eth_dev *dev; 88099a2dd95SBruce Richardson int ret; 88199a2dd95SBruce Richardson 88299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 88399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 88499a2dd95SBruce Richardson 88599a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, rx_queue_id); 88699a2dd95SBruce Richardson if (ret != 0) 88799a2dd95SBruce Richardson return ret; 88899a2dd95SBruce Richardson 8898f1d23ecSDavid Marchand if (*dev->dev_ops->rx_queue_stop == NULL) 8908f1d23ecSDavid Marchand return -ENOTSUP; 89199a2dd95SBruce Richardson 89299a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) { 8930e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 8940e21c7c0SDavid Marchand "Can't stop Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16, 89599a2dd95SBruce Richardson rx_queue_id, port_id); 89699a2dd95SBruce Richardson return -EINVAL; 89799a2dd95SBruce Richardson } 89899a2dd95SBruce Richardson 89999a2dd95SBruce Richardson if (dev->data->rx_queue_state[rx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) { 9000e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 9010e21c7c0SDavid Marchand "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped", 90299a2dd95SBruce Richardson rx_queue_id, port_id); 90399a2dd95SBruce Richardson return 0; 90499a2dd95SBruce Richardson } 90599a2dd95SBruce Richardson 9066679cf21SAnkur Dwivedi ret = eth_err(port_id, dev->dev_ops->rx_queue_stop(dev, rx_queue_id)); 9076679cf21SAnkur Dwivedi 9086679cf21SAnkur Dwivedi rte_ethdev_trace_rx_queue_stop(port_id, rx_queue_id, ret); 9096679cf21SAnkur Dwivedi 9106679cf21SAnkur Dwivedi return ret; 91199a2dd95SBruce Richardson } 91299a2dd95SBruce Richardson 91399a2dd95SBruce Richardson int 91499a2dd95SBruce Richardson rte_eth_dev_tx_queue_start(uint16_t port_id, uint16_t tx_queue_id) 91599a2dd95SBruce Richardson { 91699a2dd95SBruce Richardson struct rte_eth_dev *dev; 91799a2dd95SBruce Richardson int ret; 91899a2dd95SBruce Richardson 91999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 92099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 92153ef1b34SMin Hu (Connor) 92299a2dd95SBruce Richardson if (!dev->data->dev_started) { 9230e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 9240e21c7c0SDavid Marchand "Port %u must be started before start any queue", 92599a2dd95SBruce Richardson port_id); 92699a2dd95SBruce Richardson return -EINVAL; 92799a2dd95SBruce Richardson } 92899a2dd95SBruce Richardson 92999a2dd95SBruce Richardson ret = eth_dev_validate_tx_queue(dev, tx_queue_id); 93099a2dd95SBruce Richardson if (ret != 0) 93199a2dd95SBruce Richardson return ret; 93299a2dd95SBruce Richardson 9338f1d23ecSDavid Marchand if (*dev->dev_ops->tx_queue_start == NULL) 9348f1d23ecSDavid Marchand return -ENOTSUP; 93599a2dd95SBruce Richardson 93699a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) { 9370e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 9380e21c7c0SDavid Marchand "Can't start Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16, 93999a2dd95SBruce Richardson tx_queue_id, port_id); 94099a2dd95SBruce Richardson return -EINVAL; 94199a2dd95SBruce Richardson } 94299a2dd95SBruce Richardson 94399a2dd95SBruce Richardson if (dev->data->tx_queue_state[tx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) { 9440e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 9450e21c7c0SDavid Marchand "Queue %"PRIu16" of device with port_id=%"PRIu16" already started", 94699a2dd95SBruce Richardson tx_queue_id, port_id); 94799a2dd95SBruce Richardson return 0; 94899a2dd95SBruce Richardson } 94999a2dd95SBruce Richardson 9506679cf21SAnkur Dwivedi ret = eth_err(port_id, dev->dev_ops->tx_queue_start(dev, tx_queue_id)); 9516679cf21SAnkur Dwivedi 9526679cf21SAnkur Dwivedi rte_ethdev_trace_tx_queue_start(port_id, tx_queue_id, ret); 9536679cf21SAnkur Dwivedi 9546679cf21SAnkur Dwivedi return ret; 95599a2dd95SBruce Richardson } 95699a2dd95SBruce Richardson 95799a2dd95SBruce Richardson int 95899a2dd95SBruce Richardson rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id) 95999a2dd95SBruce Richardson { 96099a2dd95SBruce Richardson struct rte_eth_dev *dev; 96199a2dd95SBruce Richardson int ret; 96299a2dd95SBruce Richardson 96399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 96499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 96599a2dd95SBruce Richardson 96699a2dd95SBruce Richardson ret = eth_dev_validate_tx_queue(dev, tx_queue_id); 96799a2dd95SBruce Richardson if (ret != 0) 96899a2dd95SBruce Richardson return ret; 96999a2dd95SBruce Richardson 9708f1d23ecSDavid Marchand if (*dev->dev_ops->tx_queue_stop == NULL) 9718f1d23ecSDavid Marchand return -ENOTSUP; 97299a2dd95SBruce Richardson 97399a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) { 9740e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 9750e21c7c0SDavid Marchand "Can't stop Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16, 97699a2dd95SBruce Richardson tx_queue_id, port_id); 97799a2dd95SBruce Richardson return -EINVAL; 97899a2dd95SBruce Richardson } 97999a2dd95SBruce Richardson 98099a2dd95SBruce Richardson if (dev->data->tx_queue_state[tx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) { 9810e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 9820e21c7c0SDavid Marchand "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped", 98399a2dd95SBruce Richardson tx_queue_id, port_id); 98499a2dd95SBruce Richardson return 0; 98599a2dd95SBruce Richardson } 98699a2dd95SBruce Richardson 9876679cf21SAnkur Dwivedi ret = eth_err(port_id, dev->dev_ops->tx_queue_stop(dev, tx_queue_id)); 9886679cf21SAnkur Dwivedi 9896679cf21SAnkur Dwivedi rte_ethdev_trace_tx_queue_stop(port_id, tx_queue_id, ret); 9906679cf21SAnkur Dwivedi 9916679cf21SAnkur Dwivedi return ret; 99299a2dd95SBruce Richardson } 99399a2dd95SBruce Richardson 99499a2dd95SBruce Richardson uint32_t 99599a2dd95SBruce Richardson rte_eth_speed_bitflag(uint32_t speed, int duplex) 99699a2dd95SBruce Richardson { 9976679cf21SAnkur Dwivedi uint32_t ret; 9986679cf21SAnkur Dwivedi 99999a2dd95SBruce Richardson switch (speed) { 1000295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_10M: 10016679cf21SAnkur Dwivedi ret = duplex ? RTE_ETH_LINK_SPEED_10M : RTE_ETH_LINK_SPEED_10M_HD; 10026679cf21SAnkur Dwivedi break; 1003295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_100M: 10046679cf21SAnkur Dwivedi ret = duplex ? RTE_ETH_LINK_SPEED_100M : RTE_ETH_LINK_SPEED_100M_HD; 10056679cf21SAnkur Dwivedi break; 1006295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_1G: 10076679cf21SAnkur Dwivedi ret = RTE_ETH_LINK_SPEED_1G; 10086679cf21SAnkur Dwivedi break; 1009295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_2_5G: 10106679cf21SAnkur Dwivedi ret = RTE_ETH_LINK_SPEED_2_5G; 10116679cf21SAnkur Dwivedi break; 1012295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_5G: 10136679cf21SAnkur Dwivedi ret = RTE_ETH_LINK_SPEED_5G; 10146679cf21SAnkur Dwivedi break; 1015295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_10G: 10166679cf21SAnkur Dwivedi ret = RTE_ETH_LINK_SPEED_10G; 10176679cf21SAnkur Dwivedi break; 1018295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_20G: 10196679cf21SAnkur Dwivedi ret = RTE_ETH_LINK_SPEED_20G; 10206679cf21SAnkur Dwivedi break; 1021295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_25G: 10226679cf21SAnkur Dwivedi ret = RTE_ETH_LINK_SPEED_25G; 10236679cf21SAnkur Dwivedi break; 1024295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_40G: 10256679cf21SAnkur Dwivedi ret = RTE_ETH_LINK_SPEED_40G; 10266679cf21SAnkur Dwivedi break; 1027295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_50G: 10286679cf21SAnkur Dwivedi ret = RTE_ETH_LINK_SPEED_50G; 10296679cf21SAnkur Dwivedi break; 1030295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_56G: 10316679cf21SAnkur Dwivedi ret = RTE_ETH_LINK_SPEED_56G; 10326679cf21SAnkur Dwivedi break; 1033295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_100G: 10346679cf21SAnkur Dwivedi ret = RTE_ETH_LINK_SPEED_100G; 10356679cf21SAnkur Dwivedi break; 1036295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_200G: 10376679cf21SAnkur Dwivedi ret = RTE_ETH_LINK_SPEED_200G; 10386679cf21SAnkur Dwivedi break; 1039a131d9ecSThomas Monjalon case RTE_ETH_SPEED_NUM_400G: 1040a131d9ecSThomas Monjalon ret = RTE_ETH_LINK_SPEED_400G; 1041a131d9ecSThomas Monjalon break; 104299a2dd95SBruce Richardson default: 10436679cf21SAnkur Dwivedi ret = 0; 104499a2dd95SBruce Richardson } 10456679cf21SAnkur Dwivedi 10466679cf21SAnkur Dwivedi rte_eth_trace_speed_bitflag(speed, duplex, ret); 10476679cf21SAnkur Dwivedi 10486679cf21SAnkur Dwivedi return ret; 104999a2dd95SBruce Richardson } 105099a2dd95SBruce Richardson 105199a2dd95SBruce Richardson const char * 105299a2dd95SBruce Richardson rte_eth_dev_rx_offload_name(uint64_t offload) 105399a2dd95SBruce Richardson { 105499a2dd95SBruce Richardson const char *name = "UNKNOWN"; 105599a2dd95SBruce Richardson unsigned int i; 105699a2dd95SBruce Richardson 105799a2dd95SBruce Richardson for (i = 0; i < RTE_DIM(eth_dev_rx_offload_names); ++i) { 105899a2dd95SBruce Richardson if (offload == eth_dev_rx_offload_names[i].offload) { 105999a2dd95SBruce Richardson name = eth_dev_rx_offload_names[i].name; 106099a2dd95SBruce Richardson break; 106199a2dd95SBruce Richardson } 106299a2dd95SBruce Richardson } 106399a2dd95SBruce Richardson 10646679cf21SAnkur Dwivedi rte_ethdev_trace_rx_offload_name(offload, name); 10656679cf21SAnkur Dwivedi 106699a2dd95SBruce Richardson return name; 106799a2dd95SBruce Richardson } 106899a2dd95SBruce Richardson 106999a2dd95SBruce Richardson const char * 107099a2dd95SBruce Richardson rte_eth_dev_tx_offload_name(uint64_t offload) 107199a2dd95SBruce Richardson { 107299a2dd95SBruce Richardson const char *name = "UNKNOWN"; 107399a2dd95SBruce Richardson unsigned int i; 107499a2dd95SBruce Richardson 107599a2dd95SBruce Richardson for (i = 0; i < RTE_DIM(eth_dev_tx_offload_names); ++i) { 107699a2dd95SBruce Richardson if (offload == eth_dev_tx_offload_names[i].offload) { 107799a2dd95SBruce Richardson name = eth_dev_tx_offload_names[i].name; 107899a2dd95SBruce Richardson break; 107999a2dd95SBruce Richardson } 108099a2dd95SBruce Richardson } 108199a2dd95SBruce Richardson 10826679cf21SAnkur Dwivedi rte_ethdev_trace_tx_offload_name(offload, name); 10836679cf21SAnkur Dwivedi 108499a2dd95SBruce Richardson return name; 108599a2dd95SBruce Richardson } 108699a2dd95SBruce Richardson 10878bddc981SDavid Marchand static char * 10888bddc981SDavid Marchand eth_dev_offload_names(uint64_t bitmask, char *buf, size_t size, 10898bddc981SDavid Marchand const char *(*offload_name)(uint64_t)) 10908bddc981SDavid Marchand { 10918bddc981SDavid Marchand unsigned int pos = 0; 10928bddc981SDavid Marchand int ret; 10938bddc981SDavid Marchand 10948bddc981SDavid Marchand /* There should be at least enough space to handle those cases */ 10958bddc981SDavid Marchand RTE_ASSERT(size >= sizeof("none") && size >= sizeof("...")); 10968bddc981SDavid Marchand 10978bddc981SDavid Marchand if (bitmask == 0) { 10988bddc981SDavid Marchand ret = snprintf(&buf[pos], size - pos, "none"); 10998bddc981SDavid Marchand if (ret < 0 || pos + ret >= size) 11008bddc981SDavid Marchand ret = 0; 11018bddc981SDavid Marchand pos += ret; 11028bddc981SDavid Marchand goto out; 11038bddc981SDavid Marchand } 11048bddc981SDavid Marchand 11058bddc981SDavid Marchand while (bitmask != 0) { 11063d4e27fdSDavid Marchand uint64_t offload = RTE_BIT64(rte_ctz64(bitmask)); 11078bddc981SDavid Marchand const char *name = offload_name(offload); 11088bddc981SDavid Marchand 11098bddc981SDavid Marchand ret = snprintf(&buf[pos], size - pos, "%s,", name); 11108bddc981SDavid Marchand if (ret < 0 || pos + ret >= size) { 11118bddc981SDavid Marchand if (pos + sizeof("...") >= size) 11128bddc981SDavid Marchand pos = size - sizeof("..."); 11138bddc981SDavid Marchand ret = snprintf(&buf[pos], size - pos, "..."); 11148bddc981SDavid Marchand if (ret > 0 && pos + ret < size) 11158bddc981SDavid Marchand pos += ret; 11168bddc981SDavid Marchand goto out; 11178bddc981SDavid Marchand } 11188bddc981SDavid Marchand 11198bddc981SDavid Marchand pos += ret; 11208bddc981SDavid Marchand bitmask &= ~offload; 11218bddc981SDavid Marchand } 11228bddc981SDavid Marchand 11238bddc981SDavid Marchand /* Eliminate trailing comma */ 11248bddc981SDavid Marchand pos--; 11258bddc981SDavid Marchand out: 11268bddc981SDavid Marchand buf[pos] = '\0'; 11278bddc981SDavid Marchand return buf; 11288bddc981SDavid Marchand } 11298bddc981SDavid Marchand 113093e441c9SXueming Li const char * 113193e441c9SXueming Li rte_eth_dev_capability_name(uint64_t capability) 113293e441c9SXueming Li { 113393e441c9SXueming Li const char *name = "UNKNOWN"; 113493e441c9SXueming Li unsigned int i; 113593e441c9SXueming Li 113693e441c9SXueming Li for (i = 0; i < RTE_DIM(rte_eth_dev_capa_names); ++i) { 113793e441c9SXueming Li if (capability == rte_eth_dev_capa_names[i].offload) { 113893e441c9SXueming Li name = rte_eth_dev_capa_names[i].name; 113993e441c9SXueming Li break; 114093e441c9SXueming Li } 114193e441c9SXueming Li } 114293e441c9SXueming Li 11436679cf21SAnkur Dwivedi rte_ethdev_trace_capability_name(capability, name); 11446679cf21SAnkur Dwivedi 114593e441c9SXueming Li return name; 114693e441c9SXueming Li } 114793e441c9SXueming Li 114899a2dd95SBruce Richardson static inline int 114999a2dd95SBruce Richardson eth_dev_check_lro_pkt_size(uint16_t port_id, uint32_t config_size, 115099a2dd95SBruce Richardson uint32_t max_rx_pkt_len, uint32_t dev_info_size) 115199a2dd95SBruce Richardson { 115299a2dd95SBruce Richardson int ret = 0; 115399a2dd95SBruce Richardson 115499a2dd95SBruce Richardson if (dev_info_size == 0) { 115599a2dd95SBruce Richardson if (config_size != max_rx_pkt_len) { 11560e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%d max_lro_pkt_size" 11570e21c7c0SDavid Marchand " %u != %u is not allowed", 115899a2dd95SBruce Richardson port_id, config_size, max_rx_pkt_len); 115999a2dd95SBruce Richardson ret = -EINVAL; 116099a2dd95SBruce Richardson } 116199a2dd95SBruce Richardson } else if (config_size > dev_info_size) { 11620e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%d max_lro_pkt_size %u " 11630e21c7c0SDavid Marchand "> max allowed value %u", port_id, config_size, 116499a2dd95SBruce Richardson dev_info_size); 116599a2dd95SBruce Richardson ret = -EINVAL; 116699a2dd95SBruce Richardson } else if (config_size < RTE_ETHER_MIN_LEN) { 11670e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%d max_lro_pkt_size %u " 11680e21c7c0SDavid Marchand "< min allowed value %u", port_id, config_size, 116999a2dd95SBruce Richardson (unsigned int)RTE_ETHER_MIN_LEN); 117099a2dd95SBruce Richardson ret = -EINVAL; 117199a2dd95SBruce Richardson } 117299a2dd95SBruce Richardson return ret; 117399a2dd95SBruce Richardson } 117499a2dd95SBruce Richardson 117599a2dd95SBruce Richardson /* 117699a2dd95SBruce Richardson * Validate offloads that are requested through rte_eth_dev_configure against 11770d9f56a8SAndrew Rybchenko * the offloads successfully set by the Ethernet device. 117899a2dd95SBruce Richardson * 117999a2dd95SBruce Richardson * @param port_id 118099a2dd95SBruce Richardson * The port identifier of the Ethernet device. 118199a2dd95SBruce Richardson * @param req_offloads 118299a2dd95SBruce Richardson * The offloads that have been requested through `rte_eth_dev_configure`. 118399a2dd95SBruce Richardson * @param set_offloads 11840d9f56a8SAndrew Rybchenko * The offloads successfully set by the Ethernet device. 118599a2dd95SBruce Richardson * @param offload_type 118699a2dd95SBruce Richardson * The offload type i.e. Rx/Tx string. 118799a2dd95SBruce Richardson * @param offload_name 118899a2dd95SBruce Richardson * The function that prints the offload name. 118999a2dd95SBruce Richardson * @return 119099a2dd95SBruce Richardson * - (0) if validation successful. 119199a2dd95SBruce Richardson * - (-EINVAL) if requested offload has been silently disabled. 119299a2dd95SBruce Richardson */ 119399a2dd95SBruce Richardson static int 119499a2dd95SBruce Richardson eth_dev_validate_offloads(uint16_t port_id, uint64_t req_offloads, 119599a2dd95SBruce Richardson uint64_t set_offloads, const char *offload_type, 119699a2dd95SBruce Richardson const char *(*offload_name)(uint64_t)) 119799a2dd95SBruce Richardson { 119899a2dd95SBruce Richardson uint64_t offloads_diff = req_offloads ^ set_offloads; 119999a2dd95SBruce Richardson uint64_t offload; 120099a2dd95SBruce Richardson int ret = 0; 120199a2dd95SBruce Richardson 120299a2dd95SBruce Richardson while (offloads_diff != 0) { 120399a2dd95SBruce Richardson /* Check if any offload is requested but not enabled. */ 12043d4e27fdSDavid Marchand offload = RTE_BIT64(rte_ctz64(offloads_diff)); 120599a2dd95SBruce Richardson if (offload & req_offloads) { 12060e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 12070e21c7c0SDavid Marchand "Port %u failed to enable %s offload %s", 120899a2dd95SBruce Richardson port_id, offload_type, offload_name(offload)); 120999a2dd95SBruce Richardson ret = -EINVAL; 121099a2dd95SBruce Richardson } 121199a2dd95SBruce Richardson 121299a2dd95SBruce Richardson /* Check if offload couldn't be disabled. */ 121399a2dd95SBruce Richardson if (offload & set_offloads) { 12140e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(DEBUG, 12150e21c7c0SDavid Marchand "Port %u %s offload %s is not requested but enabled", 121699a2dd95SBruce Richardson port_id, offload_type, offload_name(offload)); 121799a2dd95SBruce Richardson } 121899a2dd95SBruce Richardson 121999a2dd95SBruce Richardson offloads_diff &= ~offload; 122099a2dd95SBruce Richardson } 122199a2dd95SBruce Richardson 122299a2dd95SBruce Richardson return ret; 122399a2dd95SBruce Richardson } 122499a2dd95SBruce Richardson 12251bb4a528SFerruh Yigit static uint32_t 12261bb4a528SFerruh Yigit eth_dev_get_overhead_len(uint32_t max_rx_pktlen, uint16_t max_mtu) 12271bb4a528SFerruh Yigit { 12281bb4a528SFerruh Yigit uint32_t overhead_len; 12291bb4a528SFerruh Yigit 12301bb4a528SFerruh Yigit if (max_mtu != UINT16_MAX && max_rx_pktlen > max_mtu) 12311bb4a528SFerruh Yigit overhead_len = max_rx_pktlen - max_mtu; 12321bb4a528SFerruh Yigit else 12331bb4a528SFerruh Yigit overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; 12341bb4a528SFerruh Yigit 12351bb4a528SFerruh Yigit return overhead_len; 12361bb4a528SFerruh Yigit } 12371bb4a528SFerruh Yigit 1238990912e6SFerruh Yigit /* rte_eth_dev_info_get() should be called prior to this function */ 1239990912e6SFerruh Yigit static int 1240990912e6SFerruh Yigit eth_dev_validate_mtu(uint16_t port_id, struct rte_eth_dev_info *dev_info, 1241990912e6SFerruh Yigit uint16_t mtu) 1242990912e6SFerruh Yigit { 1243990912e6SFerruh Yigit uint32_t overhead_len; 1244990912e6SFerruh Yigit uint32_t frame_size; 1245990912e6SFerruh Yigit 1246990912e6SFerruh Yigit if (mtu < dev_info->min_mtu) { 12470e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 12480e21c7c0SDavid Marchand "MTU (%u) < device min MTU (%u) for port_id %u", 1249990912e6SFerruh Yigit mtu, dev_info->min_mtu, port_id); 1250990912e6SFerruh Yigit return -EINVAL; 1251990912e6SFerruh Yigit } 1252990912e6SFerruh Yigit if (mtu > dev_info->max_mtu) { 12530e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 12540e21c7c0SDavid Marchand "MTU (%u) > device max MTU (%u) for port_id %u", 1255990912e6SFerruh Yigit mtu, dev_info->max_mtu, port_id); 1256990912e6SFerruh Yigit return -EINVAL; 1257990912e6SFerruh Yigit } 1258990912e6SFerruh Yigit 1259990912e6SFerruh Yigit overhead_len = eth_dev_get_overhead_len(dev_info->max_rx_pktlen, 1260990912e6SFerruh Yigit dev_info->max_mtu); 1261990912e6SFerruh Yigit frame_size = mtu + overhead_len; 1262990912e6SFerruh Yigit if (frame_size < RTE_ETHER_MIN_LEN) { 12630e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 12640e21c7c0SDavid Marchand "Frame size (%u) < min frame size (%u) for port_id %u", 1265990912e6SFerruh Yigit frame_size, RTE_ETHER_MIN_LEN, port_id); 1266990912e6SFerruh Yigit return -EINVAL; 1267990912e6SFerruh Yigit } 1268990912e6SFerruh Yigit 1269990912e6SFerruh Yigit if (frame_size > dev_info->max_rx_pktlen) { 12700e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 12710e21c7c0SDavid Marchand "Frame size (%u) > device max frame size (%u) for port_id %u", 1272990912e6SFerruh Yigit frame_size, dev_info->max_rx_pktlen, port_id); 1273990912e6SFerruh Yigit return -EINVAL; 1274990912e6SFerruh Yigit } 1275990912e6SFerruh Yigit 1276990912e6SFerruh Yigit return 0; 1277990912e6SFerruh Yigit } 1278990912e6SFerruh Yigit 127999a2dd95SBruce Richardson int 128099a2dd95SBruce Richardson rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, 128199a2dd95SBruce Richardson const struct rte_eth_conf *dev_conf) 128299a2dd95SBruce Richardson { 128334ff088cSJie Hai enum rte_eth_hash_function algorithm; 128499a2dd95SBruce Richardson struct rte_eth_dev *dev; 128599a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 128699a2dd95SBruce Richardson struct rte_eth_conf orig_conf; 128799a2dd95SBruce Richardson int diag; 128899a2dd95SBruce Richardson int ret; 128999a2dd95SBruce Richardson uint16_t old_mtu; 129099a2dd95SBruce Richardson 129199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 129299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 129399a2dd95SBruce Richardson 129453ef1b34SMin Hu (Connor) if (dev_conf == NULL) { 12950e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 12960e21c7c0SDavid Marchand "Cannot configure ethdev port %u from NULL config", 129753ef1b34SMin Hu (Connor) port_id); 129853ef1b34SMin Hu (Connor) return -EINVAL; 129953ef1b34SMin Hu (Connor) } 130053ef1b34SMin Hu (Connor) 13018f1d23ecSDavid Marchand if (*dev->dev_ops->dev_configure == NULL) 13028f1d23ecSDavid Marchand return -ENOTSUP; 130399a2dd95SBruce Richardson 130499a2dd95SBruce Richardson if (dev->data->dev_started) { 13050e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 13060e21c7c0SDavid Marchand "Port %u must be stopped to allow configuration", 130799a2dd95SBruce Richardson port_id); 130899a2dd95SBruce Richardson return -EBUSY; 130999a2dd95SBruce Richardson } 131099a2dd95SBruce Richardson 131102edbfabSHuisong Li /* 131202edbfabSHuisong Li * Ensure that "dev_configured" is always 0 each time prepare to do 131302edbfabSHuisong Li * dev_configure() to avoid any non-anticipated behaviour. 131402edbfabSHuisong Li * And set to 1 when dev_configure() is executed successfully. 131502edbfabSHuisong Li */ 131602edbfabSHuisong Li dev->data->dev_configured = 0; 131702edbfabSHuisong Li 131899a2dd95SBruce Richardson /* Store original config, as rollback required on failure */ 131999a2dd95SBruce Richardson memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf)); 132099a2dd95SBruce Richardson 132199a2dd95SBruce Richardson /* 132299a2dd95SBruce Richardson * Copy the dev_conf parameter into the dev structure. 132399a2dd95SBruce Richardson * rte_eth_dev_info_get() requires dev_conf, copy it before dev_info get 132499a2dd95SBruce Richardson */ 132599a2dd95SBruce Richardson if (dev_conf != &dev->data->dev_conf) 132699a2dd95SBruce Richardson memcpy(&dev->data->dev_conf, dev_conf, 132799a2dd95SBruce Richardson sizeof(dev->data->dev_conf)); 132899a2dd95SBruce Richardson 132999a2dd95SBruce Richardson /* Backup mtu for rollback */ 133099a2dd95SBruce Richardson old_mtu = dev->data->mtu; 133199a2dd95SBruce Richardson 13325551f62eSStephen Hemminger /* fields must be zero to reserve them for future ABI changes */ 13335551f62eSStephen Hemminger if (dev_conf->rxmode.reserved_64s[0] != 0 || 13345551f62eSStephen Hemminger dev_conf->rxmode.reserved_64s[1] != 0 || 13355551f62eSStephen Hemminger dev_conf->rxmode.reserved_ptrs[0] != NULL || 13365551f62eSStephen Hemminger dev_conf->rxmode.reserved_ptrs[1] != NULL) { 13370e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Rxmode reserved fields not zero"); 13385551f62eSStephen Hemminger ret = -EINVAL; 13395551f62eSStephen Hemminger goto rollback; 13405551f62eSStephen Hemminger } 13415551f62eSStephen Hemminger 13425551f62eSStephen Hemminger if (dev_conf->txmode.reserved_64s[0] != 0 || 13435551f62eSStephen Hemminger dev_conf->txmode.reserved_64s[1] != 0 || 13445551f62eSStephen Hemminger dev_conf->txmode.reserved_ptrs[0] != NULL || 13455551f62eSStephen Hemminger dev_conf->txmode.reserved_ptrs[1] != NULL) { 13460e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "txmode reserved fields not zero"); 13475551f62eSStephen Hemminger ret = -EINVAL; 13485551f62eSStephen Hemminger goto rollback; 13495551f62eSStephen Hemminger } 13505551f62eSStephen Hemminger 135199a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 135299a2dd95SBruce Richardson if (ret != 0) 135399a2dd95SBruce Richardson goto rollback; 135499a2dd95SBruce Richardson 135599a2dd95SBruce Richardson /* If number of queues specified by application for both Rx and Tx is 135699a2dd95SBruce Richardson * zero, use driver preferred values. This cannot be done individually 135799a2dd95SBruce Richardson * as it is valid for either Tx or Rx (but not both) to be zero. 135899a2dd95SBruce Richardson * If driver does not provide any preferred valued, fall back on 135999a2dd95SBruce Richardson * EAL defaults. 136099a2dd95SBruce Richardson */ 136199a2dd95SBruce Richardson if (nb_rx_q == 0 && nb_tx_q == 0) { 136299a2dd95SBruce Richardson nb_rx_q = dev_info.default_rxportconf.nb_queues; 136399a2dd95SBruce Richardson if (nb_rx_q == 0) 136499a2dd95SBruce Richardson nb_rx_q = RTE_ETH_DEV_FALLBACK_RX_NBQUEUES; 136599a2dd95SBruce Richardson nb_tx_q = dev_info.default_txportconf.nb_queues; 136699a2dd95SBruce Richardson if (nb_tx_q == 0) 136799a2dd95SBruce Richardson nb_tx_q = RTE_ETH_DEV_FALLBACK_TX_NBQUEUES; 136899a2dd95SBruce Richardson } 136999a2dd95SBruce Richardson 137099a2dd95SBruce Richardson if (nb_rx_q > RTE_MAX_QUEUES_PER_PORT) { 13710e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 13720e21c7c0SDavid Marchand "Number of Rx queues requested (%u) is greater than max supported(%d)", 137399a2dd95SBruce Richardson nb_rx_q, RTE_MAX_QUEUES_PER_PORT); 137499a2dd95SBruce Richardson ret = -EINVAL; 137599a2dd95SBruce Richardson goto rollback; 137699a2dd95SBruce Richardson } 137799a2dd95SBruce Richardson 137899a2dd95SBruce Richardson if (nb_tx_q > RTE_MAX_QUEUES_PER_PORT) { 13790e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 13800e21c7c0SDavid Marchand "Number of Tx queues requested (%u) is greater than max supported(%d)", 138199a2dd95SBruce Richardson nb_tx_q, RTE_MAX_QUEUES_PER_PORT); 138299a2dd95SBruce Richardson ret = -EINVAL; 138399a2dd95SBruce Richardson goto rollback; 138499a2dd95SBruce Richardson } 138599a2dd95SBruce Richardson 138699a2dd95SBruce Richardson /* 138709fd4227SAndrew Rybchenko * Check that the numbers of Rx and Tx queues are not greater 138809fd4227SAndrew Rybchenko * than the maximum number of Rx and Tx queues supported by the 138999a2dd95SBruce Richardson * configured device. 139099a2dd95SBruce Richardson */ 139199a2dd95SBruce Richardson if (nb_rx_q > dev_info.max_rx_queues) { 13920e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u nb_rx_queues=%u > %u", 139399a2dd95SBruce Richardson port_id, nb_rx_q, dev_info.max_rx_queues); 139499a2dd95SBruce Richardson ret = -EINVAL; 139599a2dd95SBruce Richardson goto rollback; 139699a2dd95SBruce Richardson } 139799a2dd95SBruce Richardson 139899a2dd95SBruce Richardson if (nb_tx_q > dev_info.max_tx_queues) { 13990e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u nb_tx_queues=%u > %u", 140099a2dd95SBruce Richardson port_id, nb_tx_q, dev_info.max_tx_queues); 140199a2dd95SBruce Richardson ret = -EINVAL; 140299a2dd95SBruce Richardson goto rollback; 140399a2dd95SBruce Richardson } 140499a2dd95SBruce Richardson 140599a2dd95SBruce Richardson /* Check that the device supports requested interrupts */ 140699a2dd95SBruce Richardson if ((dev_conf->intr_conf.lsc == 1) && 140799a2dd95SBruce Richardson (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) { 14080e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Driver %s does not support lsc", 140999a2dd95SBruce Richardson dev->device->driver->name); 141099a2dd95SBruce Richardson ret = -EINVAL; 141199a2dd95SBruce Richardson goto rollback; 141299a2dd95SBruce Richardson } 141399a2dd95SBruce Richardson if ((dev_conf->intr_conf.rmv == 1) && 141499a2dd95SBruce Richardson (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) { 14150e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Driver %s does not support rmv", 141699a2dd95SBruce Richardson dev->device->driver->name); 141799a2dd95SBruce Richardson ret = -EINVAL; 141899a2dd95SBruce Richardson goto rollback; 141999a2dd95SBruce Richardson } 142099a2dd95SBruce Richardson 14211bb4a528SFerruh Yigit if (dev_conf->rxmode.mtu == 0) 1422da266c65SJoshua Washington dev->data->dev_conf.rxmode.mtu = 1423da266c65SJoshua Washington (dev_info.max_mtu == 0) ? RTE_ETHER_MTU : 1424da266c65SJoshua Washington RTE_MIN(dev_info.max_mtu, RTE_ETHER_MTU); 1425990912e6SFerruh Yigit 1426990912e6SFerruh Yigit ret = eth_dev_validate_mtu(port_id, &dev_info, 1427990912e6SFerruh Yigit dev->data->dev_conf.rxmode.mtu); 1428990912e6SFerruh Yigit if (ret != 0) 142999a2dd95SBruce Richardson goto rollback; 143099a2dd95SBruce Richardson 14311bb4a528SFerruh Yigit dev->data->mtu = dev->data->dev_conf.rxmode.mtu; 14321bb4a528SFerruh Yigit 143399a2dd95SBruce Richardson /* 143499a2dd95SBruce Richardson * If LRO is enabled, check that the maximum aggregated packet 143599a2dd95SBruce Richardson * size is supported by the configured device. 143699a2dd95SBruce Richardson */ 1437295968d1SFerruh Yigit if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) { 1438990912e6SFerruh Yigit uint32_t max_rx_pktlen; 1439990912e6SFerruh Yigit uint32_t overhead_len; 1440990912e6SFerruh Yigit 1441990912e6SFerruh Yigit overhead_len = eth_dev_get_overhead_len(dev_info.max_rx_pktlen, 1442990912e6SFerruh Yigit dev_info.max_mtu); 1443990912e6SFerruh Yigit max_rx_pktlen = dev->data->dev_conf.rxmode.mtu + overhead_len; 144499a2dd95SBruce Richardson if (dev_conf->rxmode.max_lro_pkt_size == 0) 14451bb4a528SFerruh Yigit dev->data->dev_conf.rxmode.max_lro_pkt_size = max_rx_pktlen; 144699a2dd95SBruce Richardson ret = eth_dev_check_lro_pkt_size(port_id, 144799a2dd95SBruce Richardson dev->data->dev_conf.rxmode.max_lro_pkt_size, 14481bb4a528SFerruh Yigit max_rx_pktlen, 144999a2dd95SBruce Richardson dev_info.max_lro_pkt_size); 145099a2dd95SBruce Richardson if (ret != 0) 145199a2dd95SBruce Richardson goto rollback; 145299a2dd95SBruce Richardson } 145399a2dd95SBruce Richardson 145499a2dd95SBruce Richardson /* Any requested offloading must be within its device capabilities */ 145599a2dd95SBruce Richardson if ((dev_conf->rxmode.offloads & dev_info.rx_offload_capa) != 145699a2dd95SBruce Richardson dev_conf->rxmode.offloads) { 14578bddc981SDavid Marchand char buffer[512]; 14588bddc981SDavid Marchand 14590e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does not support Rx offloads %s", 14608bddc981SDavid Marchand port_id, eth_dev_offload_names( 14618bddc981SDavid Marchand dev_conf->rxmode.offloads & ~dev_info.rx_offload_capa, 14628bddc981SDavid Marchand buffer, sizeof(buffer), rte_eth_dev_rx_offload_name)); 14630e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(DEBUG, "Ethdev port_id=%u was requested Rx offloads %s", 14648bddc981SDavid Marchand port_id, eth_dev_offload_names(dev_conf->rxmode.offloads, 14658bddc981SDavid Marchand buffer, sizeof(buffer), rte_eth_dev_rx_offload_name)); 14660e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(DEBUG, "Ethdev port_id=%u supports Rx offloads %s", 14678bddc981SDavid Marchand port_id, eth_dev_offload_names(dev_info.rx_offload_capa, 14688bddc981SDavid Marchand buffer, sizeof(buffer), rte_eth_dev_rx_offload_name)); 14698bddc981SDavid Marchand 147099a2dd95SBruce Richardson ret = -EINVAL; 147199a2dd95SBruce Richardson goto rollback; 147299a2dd95SBruce Richardson } 147399a2dd95SBruce Richardson if ((dev_conf->txmode.offloads & dev_info.tx_offload_capa) != 147499a2dd95SBruce Richardson dev_conf->txmode.offloads) { 14758bddc981SDavid Marchand char buffer[512]; 14768bddc981SDavid Marchand 14770e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does not support Tx offloads %s", 14788bddc981SDavid Marchand port_id, eth_dev_offload_names( 14798bddc981SDavid Marchand dev_conf->txmode.offloads & ~dev_info.tx_offload_capa, 14808bddc981SDavid Marchand buffer, sizeof(buffer), rte_eth_dev_tx_offload_name)); 14810e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(DEBUG, "Ethdev port_id=%u was requested Tx offloads %s", 14828bddc981SDavid Marchand port_id, eth_dev_offload_names(dev_conf->txmode.offloads, 14838bddc981SDavid Marchand buffer, sizeof(buffer), rte_eth_dev_tx_offload_name)); 14840e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(DEBUG, "Ethdev port_id=%u supports Tx offloads %s", 14858bddc981SDavid Marchand port_id, eth_dev_offload_names(dev_info.tx_offload_capa, 14868bddc981SDavid Marchand buffer, sizeof(buffer), rte_eth_dev_tx_offload_name)); 148799a2dd95SBruce Richardson ret = -EINVAL; 148899a2dd95SBruce Richardson goto rollback; 148999a2dd95SBruce Richardson } 149099a2dd95SBruce Richardson 149199a2dd95SBruce Richardson dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = 149299a2dd95SBruce Richardson rte_eth_rss_hf_refine(dev_conf->rx_adv_conf.rss_conf.rss_hf); 149399a2dd95SBruce Richardson 149499a2dd95SBruce Richardson /* Check that device supports requested rss hash functions. */ 149599a2dd95SBruce Richardson if ((dev_info.flow_type_rss_offloads | 149699a2dd95SBruce Richardson dev_conf->rx_adv_conf.rss_conf.rss_hf) != 149799a2dd95SBruce Richardson dev_info.flow_type_rss_offloads) { 14980e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 14990e21c7c0SDavid Marchand "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64, 150099a2dd95SBruce Richardson port_id, dev_conf->rx_adv_conf.rss_conf.rss_hf, 150199a2dd95SBruce Richardson dev_info.flow_type_rss_offloads); 150299a2dd95SBruce Richardson ret = -EINVAL; 150399a2dd95SBruce Richardson goto rollback; 150499a2dd95SBruce Richardson } 150599a2dd95SBruce Richardson 150699a2dd95SBruce Richardson /* Check if Rx RSS distribution is disabled but RSS hash is enabled. */ 1507295968d1SFerruh Yigit if (((dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) == 0) && 1508295968d1SFerruh Yigit (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)) { 15090e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 15100e21c7c0SDavid Marchand "Ethdev port_id=%u config invalid Rx mq_mode without RSS but %s offload is requested", 151199a2dd95SBruce Richardson port_id, 1512295968d1SFerruh Yigit rte_eth_dev_rx_offload_name(RTE_ETH_RX_OFFLOAD_RSS_HASH)); 151399a2dd95SBruce Richardson ret = -EINVAL; 151499a2dd95SBruce Richardson goto rollback; 151599a2dd95SBruce Richardson } 151699a2dd95SBruce Richardson 1517bae3cfa5SJie Hai if (dev_conf->rx_adv_conf.rss_conf.rss_key != NULL && 1518bae3cfa5SJie Hai dev_conf->rx_adv_conf.rss_conf.rss_key_len != dev_info.hash_key_size) { 15190e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 15200e21c7c0SDavid Marchand "Ethdev port_id=%u invalid RSS key len: %u, valid value: %u", 1521bae3cfa5SJie Hai port_id, dev_conf->rx_adv_conf.rss_conf.rss_key_len, 1522bae3cfa5SJie Hai dev_info.hash_key_size); 1523bae3cfa5SJie Hai ret = -EINVAL; 1524bae3cfa5SJie Hai goto rollback; 1525bae3cfa5SJie Hai } 1526bae3cfa5SJie Hai 152734ff088cSJie Hai algorithm = dev_conf->rx_adv_conf.rss_conf.algorithm; 152834ff088cSJie Hai if ((size_t)algorithm >= CHAR_BIT * sizeof(dev_info.rss_algo_capa) || 152934ff088cSJie Hai (dev_info.rss_algo_capa & RTE_ETH_HASH_ALGO_TO_CAPA(algorithm)) == 0) { 15300e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 153134ff088cSJie Hai "Ethdev port_id=%u configured RSS hash algorithm (%u)" 15320e21c7c0SDavid Marchand "is not in the algorithm capability (0x%" PRIx32 ")", 153334ff088cSJie Hai port_id, algorithm, dev_info.rss_algo_capa); 153434ff088cSJie Hai ret = -EINVAL; 153534ff088cSJie Hai goto rollback; 153634ff088cSJie Hai } 153734ff088cSJie Hai 153899a2dd95SBruce Richardson /* 153909fd4227SAndrew Rybchenko * Setup new number of Rx/Tx queues and reconfigure device. 154099a2dd95SBruce Richardson */ 154199a2dd95SBruce Richardson diag = eth_dev_rx_queue_config(dev, nb_rx_q); 154299a2dd95SBruce Richardson if (diag != 0) { 15430e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 15440e21c7c0SDavid Marchand "Port%u eth_dev_rx_queue_config = %d", 154599a2dd95SBruce Richardson port_id, diag); 154699a2dd95SBruce Richardson ret = diag; 154799a2dd95SBruce Richardson goto rollback; 154899a2dd95SBruce Richardson } 154999a2dd95SBruce Richardson 155099a2dd95SBruce Richardson diag = eth_dev_tx_queue_config(dev, nb_tx_q); 155199a2dd95SBruce Richardson if (diag != 0) { 15520e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 15530e21c7c0SDavid Marchand "Port%u eth_dev_tx_queue_config = %d", 155499a2dd95SBruce Richardson port_id, diag); 155599a2dd95SBruce Richardson eth_dev_rx_queue_config(dev, 0); 155699a2dd95SBruce Richardson ret = diag; 155799a2dd95SBruce Richardson goto rollback; 155899a2dd95SBruce Richardson } 155999a2dd95SBruce Richardson 156099a2dd95SBruce Richardson diag = (*dev->dev_ops->dev_configure)(dev); 156199a2dd95SBruce Richardson if (diag != 0) { 15620e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Port%u dev_configure = %d", 156399a2dd95SBruce Richardson port_id, diag); 156499a2dd95SBruce Richardson ret = eth_err(port_id, diag); 156599a2dd95SBruce Richardson goto reset_queues; 156699a2dd95SBruce Richardson } 156799a2dd95SBruce Richardson 156899a2dd95SBruce Richardson /* Initialize Rx profiling if enabled at compilation time. */ 156999a2dd95SBruce Richardson diag = __rte_eth_dev_profile_init(port_id, dev); 157099a2dd95SBruce Richardson if (diag != 0) { 15710e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Port%u __rte_eth_dev_profile_init = %d", 157299a2dd95SBruce Richardson port_id, diag); 157399a2dd95SBruce Richardson ret = eth_err(port_id, diag); 157499a2dd95SBruce Richardson goto reset_queues; 157599a2dd95SBruce Richardson } 157699a2dd95SBruce Richardson 157799a2dd95SBruce Richardson /* Validate Rx offloads. */ 157899a2dd95SBruce Richardson diag = eth_dev_validate_offloads(port_id, 157999a2dd95SBruce Richardson dev_conf->rxmode.offloads, 158099a2dd95SBruce Richardson dev->data->dev_conf.rxmode.offloads, "Rx", 158199a2dd95SBruce Richardson rte_eth_dev_rx_offload_name); 158299a2dd95SBruce Richardson if (diag != 0) { 158399a2dd95SBruce Richardson ret = diag; 158499a2dd95SBruce Richardson goto reset_queues; 158599a2dd95SBruce Richardson } 158699a2dd95SBruce Richardson 158799a2dd95SBruce Richardson /* Validate Tx offloads. */ 158899a2dd95SBruce Richardson diag = eth_dev_validate_offloads(port_id, 158999a2dd95SBruce Richardson dev_conf->txmode.offloads, 159099a2dd95SBruce Richardson dev->data->dev_conf.txmode.offloads, "Tx", 159199a2dd95SBruce Richardson rte_eth_dev_tx_offload_name); 159299a2dd95SBruce Richardson if (diag != 0) { 159399a2dd95SBruce Richardson ret = diag; 159499a2dd95SBruce Richardson goto reset_queues; 159599a2dd95SBruce Richardson } 159699a2dd95SBruce Richardson 159702edbfabSHuisong Li dev->data->dev_configured = 1; 159899a2dd95SBruce Richardson rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, 0); 159999a2dd95SBruce Richardson return 0; 160099a2dd95SBruce Richardson reset_queues: 160199a2dd95SBruce Richardson eth_dev_rx_queue_config(dev, 0); 160299a2dd95SBruce Richardson eth_dev_tx_queue_config(dev, 0); 160399a2dd95SBruce Richardson rollback: 160499a2dd95SBruce Richardson memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf)); 160599a2dd95SBruce Richardson if (old_mtu != dev->data->mtu) 160699a2dd95SBruce Richardson dev->data->mtu = old_mtu; 160799a2dd95SBruce Richardson 160899a2dd95SBruce Richardson rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, ret); 160999a2dd95SBruce Richardson return ret; 161099a2dd95SBruce Richardson } 161199a2dd95SBruce Richardson 161299a2dd95SBruce Richardson static void 161399a2dd95SBruce Richardson eth_dev_mac_restore(struct rte_eth_dev *dev, 161499a2dd95SBruce Richardson struct rte_eth_dev_info *dev_info) 161599a2dd95SBruce Richardson { 161699a2dd95SBruce Richardson struct rte_ether_addr *addr; 161799a2dd95SBruce Richardson uint16_t i; 161899a2dd95SBruce Richardson uint32_t pool = 0; 161999a2dd95SBruce Richardson uint64_t pool_mask; 162099a2dd95SBruce Richardson 162199a2dd95SBruce Richardson /* replay MAC address configuration including default MAC */ 162299a2dd95SBruce Richardson addr = &dev->data->mac_addrs[0]; 162399a2dd95SBruce Richardson if (*dev->dev_ops->mac_addr_set != NULL) 162499a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_set)(dev, addr); 162599a2dd95SBruce Richardson else if (*dev->dev_ops->mac_addr_add != NULL) 162699a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_add)(dev, addr, 0, pool); 162799a2dd95SBruce Richardson 162899a2dd95SBruce Richardson if (*dev->dev_ops->mac_addr_add != NULL) { 162999a2dd95SBruce Richardson for (i = 1; i < dev_info->max_mac_addrs; i++) { 163099a2dd95SBruce Richardson addr = &dev->data->mac_addrs[i]; 163199a2dd95SBruce Richardson 163299a2dd95SBruce Richardson /* skip zero address */ 163399a2dd95SBruce Richardson if (rte_is_zero_ether_addr(addr)) 163499a2dd95SBruce Richardson continue; 163599a2dd95SBruce Richardson 163699a2dd95SBruce Richardson pool = 0; 163799a2dd95SBruce Richardson pool_mask = dev->data->mac_pool_sel[i]; 163899a2dd95SBruce Richardson 163999a2dd95SBruce Richardson do { 1640e1823e08SThomas Monjalon if (pool_mask & UINT64_C(1)) 164199a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_add)(dev, 164299a2dd95SBruce Richardson addr, i, pool); 164399a2dd95SBruce Richardson pool_mask >>= 1; 164499a2dd95SBruce Richardson pool++; 164599a2dd95SBruce Richardson } while (pool_mask); 164699a2dd95SBruce Richardson } 164799a2dd95SBruce Richardson } 164899a2dd95SBruce Richardson } 164999a2dd95SBruce Richardson 165099a2dd95SBruce Richardson static int 1651a98bd0feSDariusz Sosnowski eth_dev_promiscuous_restore(struct rte_eth_dev *dev, uint16_t port_id) 165299a2dd95SBruce Richardson { 165399a2dd95SBruce Richardson int ret; 165499a2dd95SBruce Richardson 165599a2dd95SBruce Richardson /* replay promiscuous configuration */ 165699a2dd95SBruce Richardson /* 165799a2dd95SBruce Richardson * use callbacks directly since we don't need port_id check and 165899a2dd95SBruce Richardson * would like to bypass the same value set 165999a2dd95SBruce Richardson */ 166099a2dd95SBruce Richardson if (rte_eth_promiscuous_get(port_id) == 1 && 166199a2dd95SBruce Richardson *dev->dev_ops->promiscuous_enable != NULL) { 166299a2dd95SBruce Richardson ret = eth_err(port_id, 166399a2dd95SBruce Richardson (*dev->dev_ops->promiscuous_enable)(dev)); 166499a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 16650e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 16660e21c7c0SDavid Marchand "Failed to enable promiscuous mode for device (port %u): %s", 166799a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 166899a2dd95SBruce Richardson return ret; 166999a2dd95SBruce Richardson } 167099a2dd95SBruce Richardson } else if (rte_eth_promiscuous_get(port_id) == 0 && 167199a2dd95SBruce Richardson *dev->dev_ops->promiscuous_disable != NULL) { 167299a2dd95SBruce Richardson ret = eth_err(port_id, 167399a2dd95SBruce Richardson (*dev->dev_ops->promiscuous_disable)(dev)); 167499a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 16750e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 16760e21c7c0SDavid Marchand "Failed to disable promiscuous mode for device (port %u): %s", 167799a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 167899a2dd95SBruce Richardson return ret; 167999a2dd95SBruce Richardson } 168099a2dd95SBruce Richardson } 168199a2dd95SBruce Richardson 1682a98bd0feSDariusz Sosnowski return 0; 1683a98bd0feSDariusz Sosnowski } 1684a98bd0feSDariusz Sosnowski 1685a98bd0feSDariusz Sosnowski static int 1686a98bd0feSDariusz Sosnowski eth_dev_allmulticast_restore(struct rte_eth_dev *dev, uint16_t port_id) 1687a98bd0feSDariusz Sosnowski { 1688a98bd0feSDariusz Sosnowski int ret; 1689a98bd0feSDariusz Sosnowski 169099a2dd95SBruce Richardson /* replay all multicast configuration */ 169199a2dd95SBruce Richardson /* 169299a2dd95SBruce Richardson * use callbacks directly since we don't need port_id check and 169399a2dd95SBruce Richardson * would like to bypass the same value set 169499a2dd95SBruce Richardson */ 169599a2dd95SBruce Richardson if (rte_eth_allmulticast_get(port_id) == 1 && 169699a2dd95SBruce Richardson *dev->dev_ops->allmulticast_enable != NULL) { 169799a2dd95SBruce Richardson ret = eth_err(port_id, 169899a2dd95SBruce Richardson (*dev->dev_ops->allmulticast_enable)(dev)); 169999a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 17000e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 17010e21c7c0SDavid Marchand "Failed to enable allmulticast mode for device (port %u): %s", 170299a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 170399a2dd95SBruce Richardson return ret; 170499a2dd95SBruce Richardson } 170599a2dd95SBruce Richardson } else if (rte_eth_allmulticast_get(port_id) == 0 && 170699a2dd95SBruce Richardson *dev->dev_ops->allmulticast_disable != NULL) { 170799a2dd95SBruce Richardson ret = eth_err(port_id, 170899a2dd95SBruce Richardson (*dev->dev_ops->allmulticast_disable)(dev)); 170999a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 17100e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 17110e21c7c0SDavid Marchand "Failed to disable allmulticast mode for device (port %u): %s", 171299a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 171399a2dd95SBruce Richardson return ret; 171499a2dd95SBruce Richardson } 171599a2dd95SBruce Richardson } 171699a2dd95SBruce Richardson 171799a2dd95SBruce Richardson return 0; 171899a2dd95SBruce Richardson } 171999a2dd95SBruce Richardson 1720a98bd0feSDariusz Sosnowski static int 1721a98bd0feSDariusz Sosnowski eth_dev_config_restore(struct rte_eth_dev *dev, 1722e14ebecfSDariusz Sosnowski struct rte_eth_dev_info *dev_info, 1723e14ebecfSDariusz Sosnowski uint64_t restore_flags, 1724e14ebecfSDariusz Sosnowski uint16_t port_id) 1725a98bd0feSDariusz Sosnowski { 1726a98bd0feSDariusz Sosnowski int ret; 1727a98bd0feSDariusz Sosnowski 1728e14ebecfSDariusz Sosnowski if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR) && 1729e14ebecfSDariusz Sosnowski (restore_flags & RTE_ETH_RESTORE_MAC_ADDR)) 1730a98bd0feSDariusz Sosnowski eth_dev_mac_restore(dev, dev_info); 1731a98bd0feSDariusz Sosnowski 1732e14ebecfSDariusz Sosnowski if (restore_flags & RTE_ETH_RESTORE_PROMISC) { 1733a98bd0feSDariusz Sosnowski ret = eth_dev_promiscuous_restore(dev, port_id); 1734a98bd0feSDariusz Sosnowski if (ret != 0) 1735a98bd0feSDariusz Sosnowski return ret; 1736e14ebecfSDariusz Sosnowski } 1737a98bd0feSDariusz Sosnowski 1738e14ebecfSDariusz Sosnowski if (restore_flags & RTE_ETH_RESTORE_ALLMULTI) { 1739a98bd0feSDariusz Sosnowski ret = eth_dev_allmulticast_restore(dev, port_id); 1740a98bd0feSDariusz Sosnowski if (ret != 0) 1741a98bd0feSDariusz Sosnowski return ret; 1742e14ebecfSDariusz Sosnowski } 1743a98bd0feSDariusz Sosnowski 1744a98bd0feSDariusz Sosnowski return 0; 1745a98bd0feSDariusz Sosnowski } 1746a98bd0feSDariusz Sosnowski 174799a2dd95SBruce Richardson int 174899a2dd95SBruce Richardson rte_eth_dev_start(uint16_t port_id) 174999a2dd95SBruce Richardson { 175099a2dd95SBruce Richardson struct rte_eth_dev *dev; 175199a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 1752e14ebecfSDariusz Sosnowski uint64_t restore_flags; 175399a2dd95SBruce Richardson int diag; 175499a2dd95SBruce Richardson int ret, ret_stop; 175599a2dd95SBruce Richardson 175699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 175799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 175899a2dd95SBruce Richardson 17598f1d23ecSDavid Marchand if (*dev->dev_ops->dev_start == NULL) 17608f1d23ecSDavid Marchand return -ENOTSUP; 176199a2dd95SBruce Richardson 176202edbfabSHuisong Li if (dev->data->dev_configured == 0) { 17630e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 17640e21c7c0SDavid Marchand "Device with port_id=%"PRIu16" is not configured.", 176502edbfabSHuisong Li port_id); 176602edbfabSHuisong Li return -EINVAL; 176702edbfabSHuisong Li } 176802edbfabSHuisong Li 176999a2dd95SBruce Richardson if (dev->data->dev_started != 0) { 17700e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 17710e21c7c0SDavid Marchand "Device with port_id=%"PRIu16" already started", 177299a2dd95SBruce Richardson port_id); 177399a2dd95SBruce Richardson return 0; 177499a2dd95SBruce Richardson } 177599a2dd95SBruce Richardson 177699a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 177799a2dd95SBruce Richardson if (ret != 0) 177899a2dd95SBruce Richardson return ret; 177999a2dd95SBruce Richardson 1780e14ebecfSDariusz Sosnowski restore_flags = rte_eth_get_restore_flags(dev, RTE_ETH_START); 1781e14ebecfSDariusz Sosnowski 178299a2dd95SBruce Richardson /* Lets restore MAC now if device does not support live change */ 1783e14ebecfSDariusz Sosnowski if ((*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR) && 1784e14ebecfSDariusz Sosnowski (restore_flags & RTE_ETH_RESTORE_MAC_ADDR)) 178599a2dd95SBruce Richardson eth_dev_mac_restore(dev, &dev_info); 178699a2dd95SBruce Richardson 178799a2dd95SBruce Richardson diag = (*dev->dev_ops->dev_start)(dev); 178899a2dd95SBruce Richardson if (diag == 0) 178999a2dd95SBruce Richardson dev->data->dev_started = 1; 179099a2dd95SBruce Richardson else 179199a2dd95SBruce Richardson return eth_err(port_id, diag); 179299a2dd95SBruce Richardson 1793e14ebecfSDariusz Sosnowski ret = eth_dev_config_restore(dev, &dev_info, restore_flags, port_id); 179499a2dd95SBruce Richardson if (ret != 0) { 17950e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 17960e21c7c0SDavid Marchand "Error during restoring configuration for device (port %u): %s", 179799a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 179899a2dd95SBruce Richardson ret_stop = rte_eth_dev_stop(port_id); 179999a2dd95SBruce Richardson if (ret_stop != 0) { 18000e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 18010e21c7c0SDavid Marchand "Failed to stop device (port %u): %s", 180299a2dd95SBruce Richardson port_id, rte_strerror(-ret_stop)); 180399a2dd95SBruce Richardson } 180499a2dd95SBruce Richardson 180599a2dd95SBruce Richardson return ret; 180699a2dd95SBruce Richardson } 180799a2dd95SBruce Richardson 180899a2dd95SBruce Richardson if (dev->data->dev_conf.intr_conf.lsc == 0) { 18098f1d23ecSDavid Marchand if (*dev->dev_ops->link_update == NULL) 18108f1d23ecSDavid Marchand return -ENOTSUP; 181199a2dd95SBruce Richardson (*dev->dev_ops->link_update)(dev, 0); 181299a2dd95SBruce Richardson } 181399a2dd95SBruce Richardson 1814c87d435aSKonstantin Ananyev /* expose selection of PMD fast-path functions */ 1815c87d435aSKonstantin Ananyev eth_dev_fp_ops_setup(rte_eth_fp_ops + port_id, dev); 1816c87d435aSKonstantin Ananyev 181799a2dd95SBruce Richardson rte_ethdev_trace_start(port_id); 181899a2dd95SBruce Richardson return 0; 181999a2dd95SBruce Richardson } 182099a2dd95SBruce Richardson 182199a2dd95SBruce Richardson int 182299a2dd95SBruce Richardson rte_eth_dev_stop(uint16_t port_id) 182399a2dd95SBruce Richardson { 182499a2dd95SBruce Richardson struct rte_eth_dev *dev; 182599a2dd95SBruce Richardson int ret; 182699a2dd95SBruce Richardson 182799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 182899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 182999a2dd95SBruce Richardson 18308f1d23ecSDavid Marchand if (*dev->dev_ops->dev_stop == NULL) 18318f1d23ecSDavid Marchand return -ENOTSUP; 183299a2dd95SBruce Richardson 183399a2dd95SBruce Richardson if (dev->data->dev_started == 0) { 18340e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 18350e21c7c0SDavid Marchand "Device with port_id=%"PRIu16" already stopped", 183699a2dd95SBruce Richardson port_id); 183799a2dd95SBruce Richardson return 0; 183899a2dd95SBruce Richardson } 183999a2dd95SBruce Richardson 1840c87d435aSKonstantin Ananyev /* point fast-path functions to dummy ones */ 1841c87d435aSKonstantin Ananyev eth_dev_fp_ops_reset(rte_eth_fp_ops + port_id); 1842c87d435aSKonstantin Ananyev 184399a2dd95SBruce Richardson ret = (*dev->dev_ops->dev_stop)(dev); 184474b74269SMin Hu (Connor) if (ret == 0) 184574b74269SMin Hu (Connor) dev->data->dev_started = 0; 184699a2dd95SBruce Richardson rte_ethdev_trace_stop(port_id, ret); 184799a2dd95SBruce Richardson 184899a2dd95SBruce Richardson return ret; 184999a2dd95SBruce Richardson } 185099a2dd95SBruce Richardson 185199a2dd95SBruce Richardson int 185299a2dd95SBruce Richardson rte_eth_dev_set_link_up(uint16_t port_id) 185399a2dd95SBruce Richardson { 185499a2dd95SBruce Richardson struct rte_eth_dev *dev; 18556679cf21SAnkur Dwivedi int ret; 185699a2dd95SBruce Richardson 185799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 185899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 185999a2dd95SBruce Richardson 18608f1d23ecSDavid Marchand if (*dev->dev_ops->dev_set_link_up == NULL) 18618f1d23ecSDavid Marchand return -ENOTSUP; 18626679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->dev_set_link_up)(dev)); 18636679cf21SAnkur Dwivedi 18646679cf21SAnkur Dwivedi rte_ethdev_trace_set_link_up(port_id, ret); 18656679cf21SAnkur Dwivedi 18666679cf21SAnkur Dwivedi return ret; 186799a2dd95SBruce Richardson } 186899a2dd95SBruce Richardson 186999a2dd95SBruce Richardson int 187099a2dd95SBruce Richardson rte_eth_dev_set_link_down(uint16_t port_id) 187199a2dd95SBruce Richardson { 187299a2dd95SBruce Richardson struct rte_eth_dev *dev; 18736679cf21SAnkur Dwivedi int ret; 187499a2dd95SBruce Richardson 187599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 187699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 187799a2dd95SBruce Richardson 18788f1d23ecSDavid Marchand if (*dev->dev_ops->dev_set_link_down == NULL) 18798f1d23ecSDavid Marchand return -ENOTSUP; 18806679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->dev_set_link_down)(dev)); 18816679cf21SAnkur Dwivedi 18826679cf21SAnkur Dwivedi rte_ethdev_trace_set_link_down(port_id, ret); 18836679cf21SAnkur Dwivedi 18846679cf21SAnkur Dwivedi return ret; 188599a2dd95SBruce Richardson } 188699a2dd95SBruce Richardson 188799a2dd95SBruce Richardson int 188860bac722SDamodharam Ammepalli rte_eth_speed_lanes_get(uint16_t port_id, uint32_t *lane) 188960bac722SDamodharam Ammepalli { 189060bac722SDamodharam Ammepalli struct rte_eth_dev *dev; 189160bac722SDamodharam Ammepalli 189260bac722SDamodharam Ammepalli RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 189360bac722SDamodharam Ammepalli dev = &rte_eth_devices[port_id]; 189460bac722SDamodharam Ammepalli 189560bac722SDamodharam Ammepalli if (*dev->dev_ops->speed_lanes_get == NULL) 189660bac722SDamodharam Ammepalli return -ENOTSUP; 189760bac722SDamodharam Ammepalli return eth_err(port_id, (*dev->dev_ops->speed_lanes_get)(dev, lane)); 189860bac722SDamodharam Ammepalli } 189960bac722SDamodharam Ammepalli 190060bac722SDamodharam Ammepalli int 190160bac722SDamodharam Ammepalli rte_eth_speed_lanes_get_capability(uint16_t port_id, 190260bac722SDamodharam Ammepalli struct rte_eth_speed_lanes_capa *speed_lanes_capa, 190360bac722SDamodharam Ammepalli unsigned int num) 190460bac722SDamodharam Ammepalli { 190560bac722SDamodharam Ammepalli struct rte_eth_dev *dev; 190660bac722SDamodharam Ammepalli int ret; 190760bac722SDamodharam Ammepalli 190860bac722SDamodharam Ammepalli RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 190960bac722SDamodharam Ammepalli dev = &rte_eth_devices[port_id]; 191060bac722SDamodharam Ammepalli 191160bac722SDamodharam Ammepalli if (*dev->dev_ops->speed_lanes_get_capa == NULL) 191260bac722SDamodharam Ammepalli return -ENOTSUP; 191360bac722SDamodharam Ammepalli 191460bac722SDamodharam Ammepalli if (speed_lanes_capa == NULL && num > 0) { 191560bac722SDamodharam Ammepalli RTE_ETHDEV_LOG_LINE(ERR, 191660bac722SDamodharam Ammepalli "Cannot get ethdev port %u speed lanes capability to NULL when array size is non zero", 191760bac722SDamodharam Ammepalli port_id); 191860bac722SDamodharam Ammepalli return -EINVAL; 191960bac722SDamodharam Ammepalli } 192060bac722SDamodharam Ammepalli 192160bac722SDamodharam Ammepalli ret = (*dev->dev_ops->speed_lanes_get_capa)(dev, speed_lanes_capa, num); 192260bac722SDamodharam Ammepalli 192360bac722SDamodharam Ammepalli return ret; 192460bac722SDamodharam Ammepalli } 192560bac722SDamodharam Ammepalli 192660bac722SDamodharam Ammepalli int 192760bac722SDamodharam Ammepalli rte_eth_speed_lanes_set(uint16_t port_id, uint32_t speed_lanes_capa) 192860bac722SDamodharam Ammepalli { 192960bac722SDamodharam Ammepalli struct rte_eth_dev *dev; 193060bac722SDamodharam Ammepalli 193160bac722SDamodharam Ammepalli RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 193260bac722SDamodharam Ammepalli dev = &rte_eth_devices[port_id]; 193360bac722SDamodharam Ammepalli 193460bac722SDamodharam Ammepalli if (*dev->dev_ops->speed_lanes_set == NULL) 193560bac722SDamodharam Ammepalli return -ENOTSUP; 193660bac722SDamodharam Ammepalli return eth_err(port_id, (*dev->dev_ops->speed_lanes_set)(dev, speed_lanes_capa)); 193760bac722SDamodharam Ammepalli } 193860bac722SDamodharam Ammepalli 193960bac722SDamodharam Ammepalli int 194099a2dd95SBruce Richardson rte_eth_dev_close(uint16_t port_id) 194199a2dd95SBruce Richardson { 194299a2dd95SBruce Richardson struct rte_eth_dev *dev; 194399a2dd95SBruce Richardson int firsterr, binerr; 194499a2dd95SBruce Richardson int *lasterr = &firsterr; 194599a2dd95SBruce Richardson 194699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 194799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 194899a2dd95SBruce Richardson 1949ea6101a8SMin Hu (Connor) /* 1950ea6101a8SMin Hu (Connor) * Secondary process needs to close device to release process private 1951ea6101a8SMin Hu (Connor) * resources. But secondary process should not be obliged to wait 1952ea6101a8SMin Hu (Connor) * for device stop before closing ethdev. 1953ea6101a8SMin Hu (Connor) */ 1954ea6101a8SMin Hu (Connor) if (rte_eal_process_type() == RTE_PROC_PRIMARY && 1955ea6101a8SMin Hu (Connor) dev->data->dev_started) { 19560e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot close started device (port %u)", 1957febc855bSAndrew Rybchenko port_id); 1958febc855bSAndrew Rybchenko return -EINVAL; 1959febc855bSAndrew Rybchenko } 1960febc855bSAndrew Rybchenko 19618f1d23ecSDavid Marchand if (*dev->dev_ops->dev_close == NULL) 19628f1d23ecSDavid Marchand return -ENOTSUP; 196399a2dd95SBruce Richardson *lasterr = (*dev->dev_ops->dev_close)(dev); 196499a2dd95SBruce Richardson if (*lasterr != 0) 196599a2dd95SBruce Richardson lasterr = &binerr; 196699a2dd95SBruce Richardson 196799a2dd95SBruce Richardson rte_ethdev_trace_close(port_id); 196899a2dd95SBruce Richardson *lasterr = rte_eth_dev_release_port(dev); 196999a2dd95SBruce Richardson 197099a2dd95SBruce Richardson return firsterr; 197199a2dd95SBruce Richardson } 197299a2dd95SBruce Richardson 197399a2dd95SBruce Richardson int 197499a2dd95SBruce Richardson rte_eth_dev_reset(uint16_t port_id) 197599a2dd95SBruce Richardson { 197699a2dd95SBruce Richardson struct rte_eth_dev *dev; 197799a2dd95SBruce Richardson int ret; 197899a2dd95SBruce Richardson 197999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 198099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 198199a2dd95SBruce Richardson 19828f1d23ecSDavid Marchand if (*dev->dev_ops->dev_reset == NULL) 19838f1d23ecSDavid Marchand return -ENOTSUP; 198499a2dd95SBruce Richardson 198599a2dd95SBruce Richardson ret = rte_eth_dev_stop(port_id); 198699a2dd95SBruce Richardson if (ret != 0) { 19870e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 19880e21c7c0SDavid Marchand "Failed to stop device (port %u) before reset: %s - ignore", 198999a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 199099a2dd95SBruce Richardson } 19916679cf21SAnkur Dwivedi ret = eth_err(port_id, dev->dev_ops->dev_reset(dev)); 199299a2dd95SBruce Richardson 19936679cf21SAnkur Dwivedi rte_ethdev_trace_reset(port_id, ret); 19946679cf21SAnkur Dwivedi 19956679cf21SAnkur Dwivedi return ret; 199699a2dd95SBruce Richardson } 199799a2dd95SBruce Richardson 199899a2dd95SBruce Richardson int 199999a2dd95SBruce Richardson rte_eth_dev_is_removed(uint16_t port_id) 200099a2dd95SBruce Richardson { 200199a2dd95SBruce Richardson struct rte_eth_dev *dev; 200299a2dd95SBruce Richardson int ret; 200399a2dd95SBruce Richardson 200499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0); 200599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 200699a2dd95SBruce Richardson 200799a2dd95SBruce Richardson if (dev->state == RTE_ETH_DEV_REMOVED) 200899a2dd95SBruce Richardson return 1; 200999a2dd95SBruce Richardson 20108f1d23ecSDavid Marchand if (*dev->dev_ops->is_removed == NULL) 20118f1d23ecSDavid Marchand return 0; 201299a2dd95SBruce Richardson 201399a2dd95SBruce Richardson ret = dev->dev_ops->is_removed(dev); 201499a2dd95SBruce Richardson if (ret != 0) 201599a2dd95SBruce Richardson /* Device is physically removed. */ 201699a2dd95SBruce Richardson dev->state = RTE_ETH_DEV_REMOVED; 201799a2dd95SBruce Richardson 20186679cf21SAnkur Dwivedi rte_ethdev_trace_is_removed(port_id, ret); 20196679cf21SAnkur Dwivedi 202099a2dd95SBruce Richardson return ret; 202199a2dd95SBruce Richardson } 202299a2dd95SBruce Richardson 202399a2dd95SBruce Richardson static int 2024b7fc7c53SAndrew Rybchenko rte_eth_check_rx_mempool(struct rte_mempool *mp, uint16_t offset, 2025b7fc7c53SAndrew Rybchenko uint16_t min_length) 2026b7fc7c53SAndrew Rybchenko { 2027b7fc7c53SAndrew Rybchenko uint16_t data_room_size; 2028b7fc7c53SAndrew Rybchenko 2029b7fc7c53SAndrew Rybchenko /* 2030b7fc7c53SAndrew Rybchenko * Check the size of the mbuf data buffer, this value 2031b7fc7c53SAndrew Rybchenko * must be provided in the private data of the memory pool. 2032b7fc7c53SAndrew Rybchenko * First check that the memory pool(s) has a valid private data. 2033b7fc7c53SAndrew Rybchenko */ 2034b7fc7c53SAndrew Rybchenko if (mp->private_data_size < 2035b7fc7c53SAndrew Rybchenko sizeof(struct rte_pktmbuf_pool_private)) { 20360e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "%s private_data_size %u < %u", 2037b7fc7c53SAndrew Rybchenko mp->name, mp->private_data_size, 2038b7fc7c53SAndrew Rybchenko (unsigned int) 2039b7fc7c53SAndrew Rybchenko sizeof(struct rte_pktmbuf_pool_private)); 2040b7fc7c53SAndrew Rybchenko return -ENOSPC; 2041b7fc7c53SAndrew Rybchenko } 2042b7fc7c53SAndrew Rybchenko data_room_size = rte_pktmbuf_data_room_size(mp); 2043b7fc7c53SAndrew Rybchenko if (data_room_size < offset + min_length) { 20440e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 20450e21c7c0SDavid Marchand "%s mbuf_data_room_size %u < %u (%u + %u)", 2046b7fc7c53SAndrew Rybchenko mp->name, data_room_size, 2047b7fc7c53SAndrew Rybchenko offset + min_length, offset, min_length); 2048b7fc7c53SAndrew Rybchenko return -EINVAL; 2049b7fc7c53SAndrew Rybchenko } 2050b7fc7c53SAndrew Rybchenko return 0; 2051b7fc7c53SAndrew Rybchenko } 2052b7fc7c53SAndrew Rybchenko 2053b7fc7c53SAndrew Rybchenko static int 2054605975b8SYuan Wang eth_dev_buffer_split_get_supported_hdrs_helper(uint16_t port_id, uint32_t **ptypes) 2055605975b8SYuan Wang { 2056605975b8SYuan Wang int cnt; 2057605975b8SYuan Wang 2058605975b8SYuan Wang cnt = rte_eth_buffer_split_get_supported_hdr_ptypes(port_id, NULL, 0); 2059605975b8SYuan Wang if (cnt <= 0) 2060605975b8SYuan Wang return cnt; 2061605975b8SYuan Wang 2062605975b8SYuan Wang *ptypes = malloc(sizeof(uint32_t) * cnt); 2063605975b8SYuan Wang if (*ptypes == NULL) 2064605975b8SYuan Wang return -ENOMEM; 2065605975b8SYuan Wang 2066605975b8SYuan Wang cnt = rte_eth_buffer_split_get_supported_hdr_ptypes(port_id, *ptypes, cnt); 2067605975b8SYuan Wang if (cnt <= 0) { 2068605975b8SYuan Wang free(*ptypes); 2069605975b8SYuan Wang *ptypes = NULL; 2070605975b8SYuan Wang } 2071605975b8SYuan Wang return cnt; 2072605975b8SYuan Wang } 2073605975b8SYuan Wang 2074605975b8SYuan Wang static int 2075605975b8SYuan Wang rte_eth_rx_queue_check_split(uint16_t port_id, 2076605975b8SYuan Wang const struct rte_eth_rxseg_split *rx_seg, 207799a2dd95SBruce Richardson uint16_t n_seg, uint32_t *mbp_buf_size, 207899a2dd95SBruce Richardson const struct rte_eth_dev_info *dev_info) 207999a2dd95SBruce Richardson { 208099a2dd95SBruce Richardson const struct rte_eth_rxseg_capa *seg_capa = &dev_info->rx_seg_capa; 208199a2dd95SBruce Richardson struct rte_mempool *mp_first; 208299a2dd95SBruce Richardson uint32_t offset_mask; 208399a2dd95SBruce Richardson uint16_t seg_idx; 2084605975b8SYuan Wang int ret = 0; 2085605975b8SYuan Wang int ptype_cnt; 2086605975b8SYuan Wang uint32_t *ptypes; 2087605975b8SYuan Wang uint32_t prev_proto_hdrs = RTE_PTYPE_UNKNOWN; 2088605975b8SYuan Wang int i; 208999a2dd95SBruce Richardson 209099a2dd95SBruce Richardson if (n_seg > seg_capa->max_nseg) { 20910e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 20920e21c7c0SDavid Marchand "Requested Rx segments %u exceed supported %u", 209399a2dd95SBruce Richardson n_seg, seg_capa->max_nseg); 209499a2dd95SBruce Richardson return -EINVAL; 209599a2dd95SBruce Richardson } 209699a2dd95SBruce Richardson /* 209799a2dd95SBruce Richardson * Check the sizes and offsets against buffer sizes 209899a2dd95SBruce Richardson * for each segment specified in extended configuration. 209999a2dd95SBruce Richardson */ 210099a2dd95SBruce Richardson mp_first = rx_seg[0].mp; 2101e1823e08SThomas Monjalon offset_mask = RTE_BIT32(seg_capa->offset_align_log2) - 1; 2102605975b8SYuan Wang 2103605975b8SYuan Wang ptypes = NULL; 2104605975b8SYuan Wang ptype_cnt = eth_dev_buffer_split_get_supported_hdrs_helper(port_id, &ptypes); 2105605975b8SYuan Wang 210699a2dd95SBruce Richardson for (seg_idx = 0; seg_idx < n_seg; seg_idx++) { 210799a2dd95SBruce Richardson struct rte_mempool *mpl = rx_seg[seg_idx].mp; 210899a2dd95SBruce Richardson uint32_t length = rx_seg[seg_idx].length; 210999a2dd95SBruce Richardson uint32_t offset = rx_seg[seg_idx].offset; 2110605975b8SYuan Wang uint32_t proto_hdr = rx_seg[seg_idx].proto_hdr; 211199a2dd95SBruce Richardson 211299a2dd95SBruce Richardson if (mpl == NULL) { 21130e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "null mempool pointer"); 2114605975b8SYuan Wang ret = -EINVAL; 2115605975b8SYuan Wang goto out; 211699a2dd95SBruce Richardson } 211799a2dd95SBruce Richardson if (seg_idx != 0 && mp_first != mpl && 211899a2dd95SBruce Richardson seg_capa->multi_pools == 0) { 21190e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Receiving to multiple pools is not supported"); 2120605975b8SYuan Wang ret = -ENOTSUP; 2121605975b8SYuan Wang goto out; 212299a2dd95SBruce Richardson } 212399a2dd95SBruce Richardson if (offset != 0) { 212499a2dd95SBruce Richardson if (seg_capa->offset_allowed == 0) { 21250e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Rx segmentation with offset is not supported"); 2126605975b8SYuan Wang ret = -ENOTSUP; 2127605975b8SYuan Wang goto out; 212899a2dd95SBruce Richardson } 212999a2dd95SBruce Richardson if (offset & offset_mask) { 21300e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Rx segmentation invalid offset alignment %u, %u", 213199a2dd95SBruce Richardson offset, 213299a2dd95SBruce Richardson seg_capa->offset_align_log2); 2133605975b8SYuan Wang ret = -EINVAL; 2134605975b8SYuan Wang goto out; 213599a2dd95SBruce Richardson } 213699a2dd95SBruce Richardson } 2137b7fc7c53SAndrew Rybchenko 213899a2dd95SBruce Richardson offset += seg_idx != 0 ? 0 : RTE_PKTMBUF_HEADROOM; 213999a2dd95SBruce Richardson *mbp_buf_size = rte_pktmbuf_data_room_size(mpl); 2140605975b8SYuan Wang if (proto_hdr != 0) { 2141605975b8SYuan Wang /* Split based on protocol headers. */ 2142605975b8SYuan Wang if (length != 0) { 21430e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 21440e21c7c0SDavid Marchand "Do not set length split and protocol split within a segment" 2145605975b8SYuan Wang ); 2146605975b8SYuan Wang ret = -EINVAL; 2147605975b8SYuan Wang goto out; 2148605975b8SYuan Wang } 2149605975b8SYuan Wang if ((proto_hdr & prev_proto_hdrs) != 0) { 21500e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 21510e21c7c0SDavid Marchand "Repeat with previous protocol headers or proto-split after length-based split" 2152605975b8SYuan Wang ); 2153605975b8SYuan Wang ret = -EINVAL; 2154605975b8SYuan Wang goto out; 2155605975b8SYuan Wang } 2156605975b8SYuan Wang if (ptype_cnt <= 0) { 21570e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 21580e21c7c0SDavid Marchand "Port %u failed to get supported buffer split header protocols", 2159605975b8SYuan Wang port_id); 2160605975b8SYuan Wang ret = -ENOTSUP; 2161605975b8SYuan Wang goto out; 2162605975b8SYuan Wang } 2163605975b8SYuan Wang for (i = 0; i < ptype_cnt; i++) { 2164605975b8SYuan Wang if ((prev_proto_hdrs | proto_hdr) == ptypes[i]) 2165605975b8SYuan Wang break; 2166605975b8SYuan Wang } 2167605975b8SYuan Wang if (i == ptype_cnt) { 21680e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 21690e21c7c0SDavid Marchand "Requested Rx split header protocols 0x%x is not supported.", 2170605975b8SYuan Wang proto_hdr); 2171605975b8SYuan Wang ret = -EINVAL; 2172605975b8SYuan Wang goto out; 2173605975b8SYuan Wang } 2174605975b8SYuan Wang prev_proto_hdrs |= proto_hdr; 2175605975b8SYuan Wang } else { 2176605975b8SYuan Wang /* Split at fixed length. */ 217799a2dd95SBruce Richardson length = length != 0 ? length : *mbp_buf_size; 2178605975b8SYuan Wang prev_proto_hdrs = RTE_PTYPE_ALL_MASK; 2179605975b8SYuan Wang } 2180b7fc7c53SAndrew Rybchenko 2181b7fc7c53SAndrew Rybchenko ret = rte_eth_check_rx_mempool(mpl, offset, length); 2182b7fc7c53SAndrew Rybchenko if (ret != 0) 2183605975b8SYuan Wang goto out; 218499a2dd95SBruce Richardson } 2185605975b8SYuan Wang out: 2186605975b8SYuan Wang free(ptypes); 2187605975b8SYuan Wang return ret; 218899a2dd95SBruce Richardson } 218999a2dd95SBruce Richardson 2190458485ebSHanumanth Pothula static int 2191458485ebSHanumanth Pothula rte_eth_rx_queue_check_mempools(struct rte_mempool **rx_mempools, 2192458485ebSHanumanth Pothula uint16_t n_mempools, uint32_t *min_buf_size, 2193458485ebSHanumanth Pothula const struct rte_eth_dev_info *dev_info) 2194458485ebSHanumanth Pothula { 2195458485ebSHanumanth Pothula uint16_t pool_idx; 2196458485ebSHanumanth Pothula int ret; 2197458485ebSHanumanth Pothula 2198458485ebSHanumanth Pothula if (n_mempools > dev_info->max_rx_mempools) { 21990e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 22000e21c7c0SDavid Marchand "Too many Rx mempools %u vs maximum %u", 2201458485ebSHanumanth Pothula n_mempools, dev_info->max_rx_mempools); 2202458485ebSHanumanth Pothula return -EINVAL; 2203458485ebSHanumanth Pothula } 2204458485ebSHanumanth Pothula 2205458485ebSHanumanth Pothula for (pool_idx = 0; pool_idx < n_mempools; pool_idx++) { 2206458485ebSHanumanth Pothula struct rte_mempool *mp = rx_mempools[pool_idx]; 2207458485ebSHanumanth Pothula 2208458485ebSHanumanth Pothula if (mp == NULL) { 22090e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "null Rx mempool pointer"); 2210458485ebSHanumanth Pothula return -EINVAL; 2211458485ebSHanumanth Pothula } 2212458485ebSHanumanth Pothula 2213458485ebSHanumanth Pothula ret = rte_eth_check_rx_mempool(mp, RTE_PKTMBUF_HEADROOM, 2214458485ebSHanumanth Pothula dev_info->min_rx_bufsize); 2215458485ebSHanumanth Pothula if (ret != 0) 2216458485ebSHanumanth Pothula return ret; 2217458485ebSHanumanth Pothula 2218458485ebSHanumanth Pothula *min_buf_size = RTE_MIN(*min_buf_size, 2219458485ebSHanumanth Pothula rte_pktmbuf_data_room_size(mp)); 2220458485ebSHanumanth Pothula } 2221458485ebSHanumanth Pothula 2222458485ebSHanumanth Pothula return 0; 2223458485ebSHanumanth Pothula } 2224458485ebSHanumanth Pothula 222599a2dd95SBruce Richardson int 222699a2dd95SBruce Richardson rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id, 222799a2dd95SBruce Richardson uint16_t nb_rx_desc, unsigned int socket_id, 222899a2dd95SBruce Richardson const struct rte_eth_rxconf *rx_conf, 222999a2dd95SBruce Richardson struct rte_mempool *mp) 223099a2dd95SBruce Richardson { 223199a2dd95SBruce Richardson int ret; 2232458485ebSHanumanth Pothula uint64_t rx_offloads; 2233458485ebSHanumanth Pothula uint32_t mbp_buf_size = UINT32_MAX; 223499a2dd95SBruce Richardson struct rte_eth_dev *dev; 223599a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 223699a2dd95SBruce Richardson struct rte_eth_rxconf local_conf; 223775c7849aSHuisong Li uint32_t buf_data_size; 223899a2dd95SBruce Richardson 223999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 224099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 224153ef1b34SMin Hu (Connor) 224299a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 22430e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", rx_queue_id); 224499a2dd95SBruce Richardson return -EINVAL; 224599a2dd95SBruce Richardson } 224699a2dd95SBruce Richardson 22478f1d23ecSDavid Marchand if (*dev->dev_ops->rx_queue_setup == NULL) 22488f1d23ecSDavid Marchand return -ENOTSUP; 224999a2dd95SBruce Richardson 22505551f62eSStephen Hemminger if (rx_conf != NULL && 22515551f62eSStephen Hemminger (rx_conf->reserved_64s[0] != 0 || 22525551f62eSStephen Hemminger rx_conf->reserved_64s[1] != 0 || 22535551f62eSStephen Hemminger rx_conf->reserved_ptrs[0] != NULL || 22545551f62eSStephen Hemminger rx_conf->reserved_ptrs[1] != NULL)) { 22550e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Rx conf reserved fields not zero"); 22565551f62eSStephen Hemminger return -EINVAL; 22575551f62eSStephen Hemminger } 22585551f62eSStephen Hemminger 225999a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 226099a2dd95SBruce Richardson if (ret != 0) 226199a2dd95SBruce Richardson return ret; 226299a2dd95SBruce Richardson 2263458485ebSHanumanth Pothula rx_offloads = dev->data->dev_conf.rxmode.offloads; 2264458485ebSHanumanth Pothula if (rx_conf != NULL) 2265458485ebSHanumanth Pothula rx_offloads |= rx_conf->offloads; 2266458485ebSHanumanth Pothula 2267458485ebSHanumanth Pothula /* Ensure that we have one and only one source of Rx buffers */ 2268458485ebSHanumanth Pothula if ((mp != NULL) + 2269458485ebSHanumanth Pothula (rx_conf != NULL && rx_conf->rx_nseg > 0) + 2270458485ebSHanumanth Pothula (rx_conf != NULL && rx_conf->rx_nmempool > 0) != 1) { 22710e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 22720e21c7c0SDavid Marchand "Ambiguous Rx mempools configuration"); 227399a2dd95SBruce Richardson return -EINVAL; 227499a2dd95SBruce Richardson } 2275b7fc7c53SAndrew Rybchenko 2276458485ebSHanumanth Pothula if (mp != NULL) { 2277458485ebSHanumanth Pothula /* Single pool configuration check. */ 2278b7fc7c53SAndrew Rybchenko ret = rte_eth_check_rx_mempool(mp, RTE_PKTMBUF_HEADROOM, 227999a2dd95SBruce Richardson dev_info.min_rx_bufsize); 2280b7fc7c53SAndrew Rybchenko if (ret != 0) 2281b7fc7c53SAndrew Rybchenko return ret; 2282b7fc7c53SAndrew Rybchenko 2283b7fc7c53SAndrew Rybchenko mbp_buf_size = rte_pktmbuf_data_room_size(mp); 228475c7849aSHuisong Li buf_data_size = mbp_buf_size - RTE_PKTMBUF_HEADROOM; 228575c7849aSHuisong Li if (buf_data_size > dev_info.max_rx_bufsize) 22860e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(DEBUG, 228775c7849aSHuisong Li "For port_id=%u, the mbuf data buffer size (%u) is bigger than " 22880e21c7c0SDavid Marchand "max buffer size (%u) device can utilize, so mbuf size can be reduced.", 228975c7849aSHuisong Li port_id, buf_data_size, dev_info.max_rx_bufsize); 2290458485ebSHanumanth Pothula } else if (rx_conf != NULL && rx_conf->rx_nseg > 0) { 229199a2dd95SBruce Richardson const struct rte_eth_rxseg_split *rx_seg; 229299a2dd95SBruce Richardson uint16_t n_seg; 229399a2dd95SBruce Richardson 229499a2dd95SBruce Richardson /* Extended multi-segment configuration check. */ 2295458485ebSHanumanth Pothula if (rx_conf->rx_seg == NULL) { 22960e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 22970e21c7c0SDavid Marchand "Memory pool is null and no multi-segment configuration provided"); 229899a2dd95SBruce Richardson return -EINVAL; 229999a2dd95SBruce Richardson } 230099a2dd95SBruce Richardson 230199a2dd95SBruce Richardson rx_seg = (const struct rte_eth_rxseg_split *)rx_conf->rx_seg; 230299a2dd95SBruce Richardson n_seg = rx_conf->rx_nseg; 230399a2dd95SBruce Richardson 2304458485ebSHanumanth Pothula if (rx_offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) { 2305605975b8SYuan Wang ret = rte_eth_rx_queue_check_split(port_id, rx_seg, n_seg, 230699a2dd95SBruce Richardson &mbp_buf_size, 230799a2dd95SBruce Richardson &dev_info); 230899a2dd95SBruce Richardson if (ret != 0) 230999a2dd95SBruce Richardson return ret; 231099a2dd95SBruce Richardson } else { 23110e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "No Rx segmentation offload configured"); 231299a2dd95SBruce Richardson return -EINVAL; 231399a2dd95SBruce Richardson } 2314458485ebSHanumanth Pothula } else if (rx_conf != NULL && rx_conf->rx_nmempool > 0) { 2315458485ebSHanumanth Pothula /* Extended multi-pool configuration check. */ 2316458485ebSHanumanth Pothula if (rx_conf->rx_mempools == NULL) { 23170e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Memory pools array is null"); 2318458485ebSHanumanth Pothula return -EINVAL; 2319458485ebSHanumanth Pothula } 2320458485ebSHanumanth Pothula 2321458485ebSHanumanth Pothula ret = rte_eth_rx_queue_check_mempools(rx_conf->rx_mempools, 2322458485ebSHanumanth Pothula rx_conf->rx_nmempool, 2323458485ebSHanumanth Pothula &mbp_buf_size, 2324458485ebSHanumanth Pothula &dev_info); 2325458485ebSHanumanth Pothula if (ret != 0) 2326458485ebSHanumanth Pothula return ret; 2327458485ebSHanumanth Pothula } else { 23280e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Missing Rx mempool configuration"); 2329458485ebSHanumanth Pothula return -EINVAL; 233099a2dd95SBruce Richardson } 233199a2dd95SBruce Richardson 233299a2dd95SBruce Richardson /* Use default specified by driver, if nb_rx_desc is zero */ 233399a2dd95SBruce Richardson if (nb_rx_desc == 0) { 233499a2dd95SBruce Richardson nb_rx_desc = dev_info.default_rxportconf.ring_size; 233599a2dd95SBruce Richardson /* If driver default is also zero, fall back on EAL default */ 233699a2dd95SBruce Richardson if (nb_rx_desc == 0) 233799a2dd95SBruce Richardson nb_rx_desc = RTE_ETH_DEV_FALLBACK_RX_RINGSIZE; 233899a2dd95SBruce Richardson } 233999a2dd95SBruce Richardson 234099a2dd95SBruce Richardson if (nb_rx_desc > dev_info.rx_desc_lim.nb_max || 234199a2dd95SBruce Richardson nb_rx_desc < dev_info.rx_desc_lim.nb_min || 234299a2dd95SBruce Richardson nb_rx_desc % dev_info.rx_desc_lim.nb_align != 0) { 234399a2dd95SBruce Richardson 23440e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 23450e21c7c0SDavid Marchand "Invalid value for nb_rx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu", 234699a2dd95SBruce Richardson nb_rx_desc, dev_info.rx_desc_lim.nb_max, 234799a2dd95SBruce Richardson dev_info.rx_desc_lim.nb_min, 234899a2dd95SBruce Richardson dev_info.rx_desc_lim.nb_align); 234999a2dd95SBruce Richardson return -EINVAL; 235099a2dd95SBruce Richardson } 235199a2dd95SBruce Richardson 235299a2dd95SBruce Richardson if (dev->data->dev_started && 235399a2dd95SBruce Richardson !(dev_info.dev_capa & 235499a2dd95SBruce Richardson RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP)) 235599a2dd95SBruce Richardson return -EBUSY; 235699a2dd95SBruce Richardson 235799a2dd95SBruce Richardson if (dev->data->dev_started && 235899a2dd95SBruce Richardson (dev->data->rx_queue_state[rx_queue_id] != 235999a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_STOPPED)) 236099a2dd95SBruce Richardson return -EBUSY; 236199a2dd95SBruce Richardson 236249ed3224SXueming Li eth_dev_rxq_release(dev, rx_queue_id); 236399a2dd95SBruce Richardson 236499a2dd95SBruce Richardson if (rx_conf == NULL) 236599a2dd95SBruce Richardson rx_conf = &dev_info.default_rxconf; 236699a2dd95SBruce Richardson 236799a2dd95SBruce Richardson local_conf = *rx_conf; 236899a2dd95SBruce Richardson 236999a2dd95SBruce Richardson /* 237099a2dd95SBruce Richardson * If an offloading has already been enabled in 237199a2dd95SBruce Richardson * rte_eth_dev_configure(), it has been enabled on all queues, 237299a2dd95SBruce Richardson * so there is no need to enable it in this queue again. 237399a2dd95SBruce Richardson * The local_conf.offloads input to underlying PMD only carries 237499a2dd95SBruce Richardson * those offloadings which are only enabled on this queue and 237599a2dd95SBruce Richardson * not enabled on all queues. 237699a2dd95SBruce Richardson */ 237799a2dd95SBruce Richardson local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads; 237899a2dd95SBruce Richardson 237999a2dd95SBruce Richardson /* 238099a2dd95SBruce Richardson * New added offloadings for this queue are those not enabled in 238199a2dd95SBruce Richardson * rte_eth_dev_configure() and they must be per-queue type. 238299a2dd95SBruce Richardson * A pure per-port offloading can't be enabled on a queue while 238399a2dd95SBruce Richardson * disabled on another queue. A pure per-port offloading can't 238499a2dd95SBruce Richardson * be enabled for any queue as new added one if it hasn't been 238599a2dd95SBruce Richardson * enabled in rte_eth_dev_configure(). 238699a2dd95SBruce Richardson */ 238799a2dd95SBruce Richardson if ((local_conf.offloads & dev_info.rx_queue_offload_capa) != 238899a2dd95SBruce Richardson local_conf.offloads) { 23890e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 239099a2dd95SBruce Richardson "Ethdev port_id=%d rx_queue_id=%d, new added offloads 0x%"PRIx64" must be " 23910e21c7c0SDavid Marchand "within per-queue offload capabilities 0x%"PRIx64" in %s()", 239299a2dd95SBruce Richardson port_id, rx_queue_id, local_conf.offloads, 239399a2dd95SBruce Richardson dev_info.rx_queue_offload_capa, 239499a2dd95SBruce Richardson __func__); 239599a2dd95SBruce Richardson return -EINVAL; 239699a2dd95SBruce Richardson } 239799a2dd95SBruce Richardson 2398dd22740cSXueming Li if (local_conf.share_group > 0 && 2399dd22740cSXueming Li (dev_info.dev_capa & RTE_ETH_DEV_CAPA_RXQ_SHARE) == 0) { 24000e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 24010e21c7c0SDavid Marchand "Ethdev port_id=%d rx_queue_id=%d, enabled share_group=%hu while device doesn't support Rx queue share", 2402dd22740cSXueming Li port_id, rx_queue_id, local_conf.share_group); 2403dd22740cSXueming Li return -EINVAL; 2404dd22740cSXueming Li } 2405dd22740cSXueming Li 240699a2dd95SBruce Richardson /* 240799a2dd95SBruce Richardson * If LRO is enabled, check that the maximum aggregated packet 240899a2dd95SBruce Richardson * size is supported by the configured device. 240999a2dd95SBruce Richardson */ 24101bb4a528SFerruh Yigit /* Get the real Ethernet overhead length */ 2411295968d1SFerruh Yigit if (local_conf.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) { 24121bb4a528SFerruh Yigit uint32_t overhead_len; 24131bb4a528SFerruh Yigit uint32_t max_rx_pktlen; 24141bb4a528SFerruh Yigit int ret; 24151bb4a528SFerruh Yigit 24161bb4a528SFerruh Yigit overhead_len = eth_dev_get_overhead_len(dev_info.max_rx_pktlen, 24171bb4a528SFerruh Yigit dev_info.max_mtu); 24181bb4a528SFerruh Yigit max_rx_pktlen = dev->data->mtu + overhead_len; 241999a2dd95SBruce Richardson if (dev->data->dev_conf.rxmode.max_lro_pkt_size == 0) 24201bb4a528SFerruh Yigit dev->data->dev_conf.rxmode.max_lro_pkt_size = max_rx_pktlen; 24211bb4a528SFerruh Yigit ret = eth_dev_check_lro_pkt_size(port_id, 242299a2dd95SBruce Richardson dev->data->dev_conf.rxmode.max_lro_pkt_size, 24231bb4a528SFerruh Yigit max_rx_pktlen, 242499a2dd95SBruce Richardson dev_info.max_lro_pkt_size); 242599a2dd95SBruce Richardson if (ret != 0) 242699a2dd95SBruce Richardson return ret; 242799a2dd95SBruce Richardson } 242899a2dd95SBruce Richardson 242999a2dd95SBruce Richardson ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc, 243099a2dd95SBruce Richardson socket_id, &local_conf, mp); 243199a2dd95SBruce Richardson if (!ret) { 243299a2dd95SBruce Richardson if (!dev->data->min_rx_buf_size || 243399a2dd95SBruce Richardson dev->data->min_rx_buf_size > mbp_buf_size) 243499a2dd95SBruce Richardson dev->data->min_rx_buf_size = mbp_buf_size; 243599a2dd95SBruce Richardson } 243699a2dd95SBruce Richardson 243799a2dd95SBruce Richardson rte_ethdev_trace_rxq_setup(port_id, rx_queue_id, nb_rx_desc, mp, 243899a2dd95SBruce Richardson rx_conf, ret); 243999a2dd95SBruce Richardson return eth_err(port_id, ret); 244099a2dd95SBruce Richardson } 244199a2dd95SBruce Richardson 244299a2dd95SBruce Richardson int 244399a2dd95SBruce Richardson rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id, 244499a2dd95SBruce Richardson uint16_t nb_rx_desc, 244599a2dd95SBruce Richardson const struct rte_eth_hairpin_conf *conf) 244699a2dd95SBruce Richardson { 244799a2dd95SBruce Richardson int ret; 244899a2dd95SBruce Richardson struct rte_eth_dev *dev; 244999a2dd95SBruce Richardson struct rte_eth_hairpin_cap cap; 245099a2dd95SBruce Richardson int i; 245199a2dd95SBruce Richardson int count; 245299a2dd95SBruce Richardson 245399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 245499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 245553ef1b34SMin Hu (Connor) 245699a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 24570e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", rx_queue_id); 245899a2dd95SBruce Richardson return -EINVAL; 245999a2dd95SBruce Richardson } 246053ef1b34SMin Hu (Connor) 246153ef1b34SMin Hu (Connor) if (conf == NULL) { 24620e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 24630e21c7c0SDavid Marchand "Cannot setup ethdev port %u Rx hairpin queue from NULL config", 246453ef1b34SMin Hu (Connor) port_id); 246553ef1b34SMin Hu (Connor) return -EINVAL; 246653ef1b34SMin Hu (Connor) } 246753ef1b34SMin Hu (Connor) 24685551f62eSStephen Hemminger if (conf->reserved != 0) { 24690e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 24700e21c7c0SDavid Marchand "Rx hairpin reserved field not zero"); 24715551f62eSStephen Hemminger return -EINVAL; 24725551f62eSStephen Hemminger } 24735551f62eSStephen Hemminger 247499a2dd95SBruce Richardson ret = rte_eth_dev_hairpin_capability_get(port_id, &cap); 247599a2dd95SBruce Richardson if (ret != 0) 247699a2dd95SBruce Richardson return ret; 24778f1d23ecSDavid Marchand if (*dev->dev_ops->rx_hairpin_queue_setup == NULL) 24788f1d23ecSDavid Marchand return -ENOTSUP; 247999a2dd95SBruce Richardson /* if nb_rx_desc is zero use max number of desc from the driver. */ 248099a2dd95SBruce Richardson if (nb_rx_desc == 0) 248199a2dd95SBruce Richardson nb_rx_desc = cap.max_nb_desc; 248299a2dd95SBruce Richardson if (nb_rx_desc > cap.max_nb_desc) { 24830e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 24840e21c7c0SDavid Marchand "Invalid value for nb_rx_desc(=%hu), should be: <= %hu", 248599a2dd95SBruce Richardson nb_rx_desc, cap.max_nb_desc); 248699a2dd95SBruce Richardson return -EINVAL; 248799a2dd95SBruce Richardson } 248899a2dd95SBruce Richardson if (conf->peer_count > cap.max_rx_2_tx) { 24890e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 24900e21c7c0SDavid Marchand "Invalid value for number of peers for Rx queue(=%u), should be: <= %hu", 249199a2dd95SBruce Richardson conf->peer_count, cap.max_rx_2_tx); 249299a2dd95SBruce Richardson return -EINVAL; 249399a2dd95SBruce Richardson } 2494bc705061SDariusz Sosnowski if (conf->use_locked_device_memory && !cap.rx_cap.locked_device_memory) { 24950e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 24960e21c7c0SDavid Marchand "Attempt to use locked device memory for Rx queue, which is not supported"); 2497bc705061SDariusz Sosnowski return -EINVAL; 2498bc705061SDariusz Sosnowski } 2499bc705061SDariusz Sosnowski if (conf->use_rte_memory && !cap.rx_cap.rte_memory) { 25000e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 25010e21c7c0SDavid Marchand "Attempt to use DPDK memory for Rx queue, which is not supported"); 2502bc705061SDariusz Sosnowski return -EINVAL; 2503bc705061SDariusz Sosnowski } 2504bc705061SDariusz Sosnowski if (conf->use_locked_device_memory && conf->use_rte_memory) { 25050e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 25060e21c7c0SDavid Marchand "Attempt to use mutually exclusive memory settings for Rx queue"); 2507bc705061SDariusz Sosnowski return -EINVAL; 2508bc705061SDariusz Sosnowski } 2509bc705061SDariusz Sosnowski if (conf->force_memory && 2510bc705061SDariusz Sosnowski !conf->use_locked_device_memory && 2511bc705061SDariusz Sosnowski !conf->use_rte_memory) { 25120e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 25130e21c7c0SDavid Marchand "Attempt to force Rx queue memory settings, but none is set"); 2514bc705061SDariusz Sosnowski return -EINVAL; 2515bc705061SDariusz Sosnowski } 251699a2dd95SBruce Richardson if (conf->peer_count == 0) { 25170e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 25180e21c7c0SDavid Marchand "Invalid value for number of peers for Rx queue(=%u), should be: > 0", 251999a2dd95SBruce Richardson conf->peer_count); 252099a2dd95SBruce Richardson return -EINVAL; 252199a2dd95SBruce Richardson } 252299a2dd95SBruce Richardson for (i = 0, count = 0; i < dev->data->nb_rx_queues && 252399a2dd95SBruce Richardson cap.max_nb_queues != UINT16_MAX; i++) { 252499a2dd95SBruce Richardson if (i == rx_queue_id || rte_eth_dev_is_rx_hairpin_queue(dev, i)) 252599a2dd95SBruce Richardson count++; 252699a2dd95SBruce Richardson } 252799a2dd95SBruce Richardson if (count > cap.max_nb_queues) { 25280e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "To many Rx hairpin queues max is %d", 252999a2dd95SBruce Richardson cap.max_nb_queues); 253099a2dd95SBruce Richardson return -EINVAL; 253199a2dd95SBruce Richardson } 253299a2dd95SBruce Richardson if (dev->data->dev_started) 253399a2dd95SBruce Richardson return -EBUSY; 253449ed3224SXueming Li eth_dev_rxq_release(dev, rx_queue_id); 253599a2dd95SBruce Richardson ret = (*dev->dev_ops->rx_hairpin_queue_setup)(dev, rx_queue_id, 253699a2dd95SBruce Richardson nb_rx_desc, conf); 253799a2dd95SBruce Richardson if (ret == 0) 253899a2dd95SBruce Richardson dev->data->rx_queue_state[rx_queue_id] = 253999a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_HAIRPIN; 25406679cf21SAnkur Dwivedi ret = eth_err(port_id, ret); 25416679cf21SAnkur Dwivedi 25426679cf21SAnkur Dwivedi rte_eth_trace_rx_hairpin_queue_setup(port_id, rx_queue_id, nb_rx_desc, 25436679cf21SAnkur Dwivedi conf, ret); 25446679cf21SAnkur Dwivedi 25456679cf21SAnkur Dwivedi return ret; 254699a2dd95SBruce Richardson } 254799a2dd95SBruce Richardson 254899a2dd95SBruce Richardson int 254999a2dd95SBruce Richardson rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id, 255099a2dd95SBruce Richardson uint16_t nb_tx_desc, unsigned int socket_id, 255199a2dd95SBruce Richardson const struct rte_eth_txconf *tx_conf) 255299a2dd95SBruce Richardson { 255399a2dd95SBruce Richardson struct rte_eth_dev *dev; 255499a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 255599a2dd95SBruce Richardson struct rte_eth_txconf local_conf; 255699a2dd95SBruce Richardson int ret; 255799a2dd95SBruce Richardson 255899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 255999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 256053ef1b34SMin Hu (Connor) 256199a2dd95SBruce Richardson if (tx_queue_id >= dev->data->nb_tx_queues) { 25620e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", tx_queue_id); 256399a2dd95SBruce Richardson return -EINVAL; 256499a2dd95SBruce Richardson } 256599a2dd95SBruce Richardson 25668f1d23ecSDavid Marchand if (*dev->dev_ops->tx_queue_setup == NULL) 25678f1d23ecSDavid Marchand return -ENOTSUP; 256899a2dd95SBruce Richardson 25695551f62eSStephen Hemminger if (tx_conf != NULL && 25705551f62eSStephen Hemminger (tx_conf->reserved_64s[0] != 0 || 25715551f62eSStephen Hemminger tx_conf->reserved_64s[1] != 0 || 25725551f62eSStephen Hemminger tx_conf->reserved_ptrs[0] != NULL || 25735551f62eSStephen Hemminger tx_conf->reserved_ptrs[1] != NULL)) { 25740e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Tx conf reserved fields not zero"); 25755551f62eSStephen Hemminger return -EINVAL; 25765551f62eSStephen Hemminger } 25775551f62eSStephen Hemminger 257899a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 257999a2dd95SBruce Richardson if (ret != 0) 258099a2dd95SBruce Richardson return ret; 258199a2dd95SBruce Richardson 258299a2dd95SBruce Richardson /* Use default specified by driver, if nb_tx_desc is zero */ 258399a2dd95SBruce Richardson if (nb_tx_desc == 0) { 258499a2dd95SBruce Richardson nb_tx_desc = dev_info.default_txportconf.ring_size; 258599a2dd95SBruce Richardson /* If driver default is zero, fall back on EAL default */ 258699a2dd95SBruce Richardson if (nb_tx_desc == 0) 258799a2dd95SBruce Richardson nb_tx_desc = RTE_ETH_DEV_FALLBACK_TX_RINGSIZE; 258899a2dd95SBruce Richardson } 258999a2dd95SBruce Richardson if (nb_tx_desc > dev_info.tx_desc_lim.nb_max || 259099a2dd95SBruce Richardson nb_tx_desc < dev_info.tx_desc_lim.nb_min || 259199a2dd95SBruce Richardson nb_tx_desc % dev_info.tx_desc_lim.nb_align != 0) { 25920e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 25930e21c7c0SDavid Marchand "Invalid value for nb_tx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu", 259499a2dd95SBruce Richardson nb_tx_desc, dev_info.tx_desc_lim.nb_max, 259599a2dd95SBruce Richardson dev_info.tx_desc_lim.nb_min, 259699a2dd95SBruce Richardson dev_info.tx_desc_lim.nb_align); 259799a2dd95SBruce Richardson return -EINVAL; 259899a2dd95SBruce Richardson } 259999a2dd95SBruce Richardson 260099a2dd95SBruce Richardson if (dev->data->dev_started && 260199a2dd95SBruce Richardson !(dev_info.dev_capa & 260299a2dd95SBruce Richardson RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP)) 260399a2dd95SBruce Richardson return -EBUSY; 260499a2dd95SBruce Richardson 260599a2dd95SBruce Richardson if (dev->data->dev_started && 260699a2dd95SBruce Richardson (dev->data->tx_queue_state[tx_queue_id] != 260799a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_STOPPED)) 260899a2dd95SBruce Richardson return -EBUSY; 260999a2dd95SBruce Richardson 261049ed3224SXueming Li eth_dev_txq_release(dev, tx_queue_id); 261199a2dd95SBruce Richardson 261299a2dd95SBruce Richardson if (tx_conf == NULL) 261399a2dd95SBruce Richardson tx_conf = &dev_info.default_txconf; 261499a2dd95SBruce Richardson 261599a2dd95SBruce Richardson local_conf = *tx_conf; 261699a2dd95SBruce Richardson 261799a2dd95SBruce Richardson /* 261899a2dd95SBruce Richardson * If an offloading has already been enabled in 261999a2dd95SBruce Richardson * rte_eth_dev_configure(), it has been enabled on all queues, 262099a2dd95SBruce Richardson * so there is no need to enable it in this queue again. 262199a2dd95SBruce Richardson * The local_conf.offloads input to underlying PMD only carries 262299a2dd95SBruce Richardson * those offloadings which are only enabled on this queue and 262399a2dd95SBruce Richardson * not enabled on all queues. 262499a2dd95SBruce Richardson */ 262599a2dd95SBruce Richardson local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads; 262699a2dd95SBruce Richardson 262799a2dd95SBruce Richardson /* 262899a2dd95SBruce Richardson * New added offloadings for this queue are those not enabled in 262999a2dd95SBruce Richardson * rte_eth_dev_configure() and they must be per-queue type. 263099a2dd95SBruce Richardson * A pure per-port offloading can't be enabled on a queue while 263199a2dd95SBruce Richardson * disabled on another queue. A pure per-port offloading can't 263299a2dd95SBruce Richardson * be enabled for any queue as new added one if it hasn't been 263399a2dd95SBruce Richardson * enabled in rte_eth_dev_configure(). 263499a2dd95SBruce Richardson */ 263599a2dd95SBruce Richardson if ((local_conf.offloads & dev_info.tx_queue_offload_capa) != 263699a2dd95SBruce Richardson local_conf.offloads) { 26370e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 263899a2dd95SBruce Richardson "Ethdev port_id=%d tx_queue_id=%d, new added offloads 0x%"PRIx64" must be " 26390e21c7c0SDavid Marchand "within per-queue offload capabilities 0x%"PRIx64" in %s()", 264099a2dd95SBruce Richardson port_id, tx_queue_id, local_conf.offloads, 264199a2dd95SBruce Richardson dev_info.tx_queue_offload_capa, 264299a2dd95SBruce Richardson __func__); 264399a2dd95SBruce Richardson return -EINVAL; 264499a2dd95SBruce Richardson } 264599a2dd95SBruce Richardson 264699a2dd95SBruce Richardson rte_ethdev_trace_txq_setup(port_id, tx_queue_id, nb_tx_desc, tx_conf); 264799a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev, 264899a2dd95SBruce Richardson tx_queue_id, nb_tx_desc, socket_id, &local_conf)); 264999a2dd95SBruce Richardson } 265099a2dd95SBruce Richardson 265199a2dd95SBruce Richardson int 265299a2dd95SBruce Richardson rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id, 265399a2dd95SBruce Richardson uint16_t nb_tx_desc, 265499a2dd95SBruce Richardson const struct rte_eth_hairpin_conf *conf) 265599a2dd95SBruce Richardson { 265699a2dd95SBruce Richardson struct rte_eth_dev *dev; 265799a2dd95SBruce Richardson struct rte_eth_hairpin_cap cap; 265899a2dd95SBruce Richardson int i; 265999a2dd95SBruce Richardson int count; 266099a2dd95SBruce Richardson int ret; 266199a2dd95SBruce Richardson 266299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 266399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 266453ef1b34SMin Hu (Connor) 266599a2dd95SBruce Richardson if (tx_queue_id >= dev->data->nb_tx_queues) { 26660e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", tx_queue_id); 266799a2dd95SBruce Richardson return -EINVAL; 266899a2dd95SBruce Richardson } 266953ef1b34SMin Hu (Connor) 267053ef1b34SMin Hu (Connor) if (conf == NULL) { 26710e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 26720e21c7c0SDavid Marchand "Cannot setup ethdev port %u Tx hairpin queue from NULL config", 267353ef1b34SMin Hu (Connor) port_id); 267453ef1b34SMin Hu (Connor) return -EINVAL; 267553ef1b34SMin Hu (Connor) } 267653ef1b34SMin Hu (Connor) 267799a2dd95SBruce Richardson ret = rte_eth_dev_hairpin_capability_get(port_id, &cap); 267899a2dd95SBruce Richardson if (ret != 0) 267999a2dd95SBruce Richardson return ret; 26808f1d23ecSDavid Marchand if (*dev->dev_ops->tx_hairpin_queue_setup == NULL) 26818f1d23ecSDavid Marchand return -ENOTSUP; 268299a2dd95SBruce Richardson /* if nb_rx_desc is zero use max number of desc from the driver. */ 268399a2dd95SBruce Richardson if (nb_tx_desc == 0) 268499a2dd95SBruce Richardson nb_tx_desc = cap.max_nb_desc; 268599a2dd95SBruce Richardson if (nb_tx_desc > cap.max_nb_desc) { 26860e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 26870e21c7c0SDavid Marchand "Invalid value for nb_tx_desc(=%hu), should be: <= %hu", 268899a2dd95SBruce Richardson nb_tx_desc, cap.max_nb_desc); 268999a2dd95SBruce Richardson return -EINVAL; 269099a2dd95SBruce Richardson } 269199a2dd95SBruce Richardson if (conf->peer_count > cap.max_tx_2_rx) { 26920e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 26930e21c7c0SDavid Marchand "Invalid value for number of peers for Tx queue(=%u), should be: <= %hu", 269499a2dd95SBruce Richardson conf->peer_count, cap.max_tx_2_rx); 269599a2dd95SBruce Richardson return -EINVAL; 269699a2dd95SBruce Richardson } 2697bc705061SDariusz Sosnowski if (conf->use_locked_device_memory && !cap.tx_cap.locked_device_memory) { 26980e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 26990e21c7c0SDavid Marchand "Attempt to use locked device memory for Tx queue, which is not supported"); 2700bc705061SDariusz Sosnowski return -EINVAL; 2701bc705061SDariusz Sosnowski } 2702bc705061SDariusz Sosnowski if (conf->use_rte_memory && !cap.tx_cap.rte_memory) { 27030e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 27040e21c7c0SDavid Marchand "Attempt to use DPDK memory for Tx queue, which is not supported"); 2705bc705061SDariusz Sosnowski return -EINVAL; 2706bc705061SDariusz Sosnowski } 2707bc705061SDariusz Sosnowski if (conf->use_locked_device_memory && conf->use_rte_memory) { 27080e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 27090e21c7c0SDavid Marchand "Attempt to use mutually exclusive memory settings for Tx queue"); 2710bc705061SDariusz Sosnowski return -EINVAL; 2711bc705061SDariusz Sosnowski } 2712bc705061SDariusz Sosnowski if (conf->force_memory && 2713bc705061SDariusz Sosnowski !conf->use_locked_device_memory && 2714bc705061SDariusz Sosnowski !conf->use_rte_memory) { 27150e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 27160e21c7c0SDavid Marchand "Attempt to force Tx queue memory settings, but none is set"); 2717bc705061SDariusz Sosnowski return -EINVAL; 2718bc705061SDariusz Sosnowski } 271999a2dd95SBruce Richardson if (conf->peer_count == 0) { 27200e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 27210e21c7c0SDavid Marchand "Invalid value for number of peers for Tx queue(=%u), should be: > 0", 272299a2dd95SBruce Richardson conf->peer_count); 272399a2dd95SBruce Richardson return -EINVAL; 272499a2dd95SBruce Richardson } 272599a2dd95SBruce Richardson for (i = 0, count = 0; i < dev->data->nb_tx_queues && 272699a2dd95SBruce Richardson cap.max_nb_queues != UINT16_MAX; i++) { 272799a2dd95SBruce Richardson if (i == tx_queue_id || rte_eth_dev_is_tx_hairpin_queue(dev, i)) 272899a2dd95SBruce Richardson count++; 272999a2dd95SBruce Richardson } 273099a2dd95SBruce Richardson if (count > cap.max_nb_queues) { 27310e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "To many Tx hairpin queues max is %d", 273299a2dd95SBruce Richardson cap.max_nb_queues); 273399a2dd95SBruce Richardson return -EINVAL; 273499a2dd95SBruce Richardson } 273599a2dd95SBruce Richardson if (dev->data->dev_started) 273699a2dd95SBruce Richardson return -EBUSY; 273749ed3224SXueming Li eth_dev_txq_release(dev, tx_queue_id); 273899a2dd95SBruce Richardson ret = (*dev->dev_ops->tx_hairpin_queue_setup) 273999a2dd95SBruce Richardson (dev, tx_queue_id, nb_tx_desc, conf); 274099a2dd95SBruce Richardson if (ret == 0) 274199a2dd95SBruce Richardson dev->data->tx_queue_state[tx_queue_id] = 274299a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_HAIRPIN; 27436679cf21SAnkur Dwivedi ret = eth_err(port_id, ret); 27446679cf21SAnkur Dwivedi 27456679cf21SAnkur Dwivedi rte_eth_trace_tx_hairpin_queue_setup(port_id, tx_queue_id, nb_tx_desc, 27466679cf21SAnkur Dwivedi conf, ret); 27476679cf21SAnkur Dwivedi 27486679cf21SAnkur Dwivedi return ret; 274999a2dd95SBruce Richardson } 275099a2dd95SBruce Richardson 275199a2dd95SBruce Richardson int 275299a2dd95SBruce Richardson rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port) 275399a2dd95SBruce Richardson { 275499a2dd95SBruce Richardson struct rte_eth_dev *dev; 275599a2dd95SBruce Richardson int ret; 275699a2dd95SBruce Richardson 275799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV); 275899a2dd95SBruce Richardson dev = &rte_eth_devices[tx_port]; 275953ef1b34SMin Hu (Connor) 276099a2dd95SBruce Richardson if (dev->data->dev_started == 0) { 27610e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Tx port %d is not started", tx_port); 276299a2dd95SBruce Richardson return -EBUSY; 276399a2dd95SBruce Richardson } 276499a2dd95SBruce Richardson 27658f1d23ecSDavid Marchand if (*dev->dev_ops->hairpin_bind == NULL) 27668f1d23ecSDavid Marchand return -ENOTSUP; 276799a2dd95SBruce Richardson ret = (*dev->dev_ops->hairpin_bind)(dev, rx_port); 276899a2dd95SBruce Richardson if (ret != 0) 27690e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Failed to bind hairpin Tx %d" 27700e21c7c0SDavid Marchand " to Rx %d (%d - all ports)", 277199a2dd95SBruce Richardson tx_port, rx_port, RTE_MAX_ETHPORTS); 277299a2dd95SBruce Richardson 27736679cf21SAnkur Dwivedi rte_eth_trace_hairpin_bind(tx_port, rx_port, ret); 27746679cf21SAnkur Dwivedi 277599a2dd95SBruce Richardson return ret; 277699a2dd95SBruce Richardson } 277799a2dd95SBruce Richardson 277899a2dd95SBruce Richardson int 277999a2dd95SBruce Richardson rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port) 278099a2dd95SBruce Richardson { 278199a2dd95SBruce Richardson struct rte_eth_dev *dev; 278299a2dd95SBruce Richardson int ret; 278399a2dd95SBruce Richardson 278499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV); 278599a2dd95SBruce Richardson dev = &rte_eth_devices[tx_port]; 278653ef1b34SMin Hu (Connor) 278799a2dd95SBruce Richardson if (dev->data->dev_started == 0) { 27880e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Tx port %d is already stopped", tx_port); 278999a2dd95SBruce Richardson return -EBUSY; 279099a2dd95SBruce Richardson } 279199a2dd95SBruce Richardson 27928f1d23ecSDavid Marchand if (*dev->dev_ops->hairpin_unbind == NULL) 27938f1d23ecSDavid Marchand return -ENOTSUP; 279499a2dd95SBruce Richardson ret = (*dev->dev_ops->hairpin_unbind)(dev, rx_port); 279599a2dd95SBruce Richardson if (ret != 0) 27960e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Failed to unbind hairpin Tx %d" 27970e21c7c0SDavid Marchand " from Rx %d (%d - all ports)", 279899a2dd95SBruce Richardson tx_port, rx_port, RTE_MAX_ETHPORTS); 279999a2dd95SBruce Richardson 28006679cf21SAnkur Dwivedi rte_eth_trace_hairpin_unbind(tx_port, rx_port, ret); 28016679cf21SAnkur Dwivedi 280299a2dd95SBruce Richardson return ret; 280399a2dd95SBruce Richardson } 280499a2dd95SBruce Richardson 280599a2dd95SBruce Richardson int 280699a2dd95SBruce Richardson rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports, 280799a2dd95SBruce Richardson size_t len, uint32_t direction) 280899a2dd95SBruce Richardson { 280999a2dd95SBruce Richardson struct rte_eth_dev *dev; 281099a2dd95SBruce Richardson int ret; 281199a2dd95SBruce Richardson 281299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 281399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 281453ef1b34SMin Hu (Connor) 281553ef1b34SMin Hu (Connor) if (peer_ports == NULL) { 28160e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 28170e21c7c0SDavid Marchand "Cannot get ethdev port %u hairpin peer ports to NULL", 281853ef1b34SMin Hu (Connor) port_id); 281953ef1b34SMin Hu (Connor) return -EINVAL; 282053ef1b34SMin Hu (Connor) } 282153ef1b34SMin Hu (Connor) 282253ef1b34SMin Hu (Connor) if (len == 0) { 28230e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 28240e21c7c0SDavid Marchand "Cannot get ethdev port %u hairpin peer ports to array with zero size", 282553ef1b34SMin Hu (Connor) port_id); 282653ef1b34SMin Hu (Connor) return -EINVAL; 282753ef1b34SMin Hu (Connor) } 282853ef1b34SMin Hu (Connor) 28298f1d23ecSDavid Marchand if (*dev->dev_ops->hairpin_get_peer_ports == NULL) 28308f1d23ecSDavid Marchand return -ENOTSUP; 283199a2dd95SBruce Richardson 283299a2dd95SBruce Richardson ret = (*dev->dev_ops->hairpin_get_peer_ports)(dev, peer_ports, 283399a2dd95SBruce Richardson len, direction); 283499a2dd95SBruce Richardson if (ret < 0) 28350e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Failed to get %d hairpin peer %s ports", 283699a2dd95SBruce Richardson port_id, direction ? "Rx" : "Tx"); 283799a2dd95SBruce Richardson 28386679cf21SAnkur Dwivedi rte_eth_trace_hairpin_get_peer_ports(port_id, peer_ports, len, 28396679cf21SAnkur Dwivedi direction, ret); 28406679cf21SAnkur Dwivedi 284199a2dd95SBruce Richardson return ret; 284299a2dd95SBruce Richardson } 284399a2dd95SBruce Richardson 284499a2dd95SBruce Richardson void 284599a2dd95SBruce Richardson rte_eth_tx_buffer_drop_callback(struct rte_mbuf **pkts, uint16_t unsent, 284699a2dd95SBruce Richardson void *userdata __rte_unused) 284799a2dd95SBruce Richardson { 284899a2dd95SBruce Richardson rte_pktmbuf_free_bulk(pkts, unsent); 28496679cf21SAnkur Dwivedi 28506679cf21SAnkur Dwivedi rte_eth_trace_tx_buffer_drop_callback((void **)pkts, unsent); 285199a2dd95SBruce Richardson } 285299a2dd95SBruce Richardson 285399a2dd95SBruce Richardson void 285499a2dd95SBruce Richardson rte_eth_tx_buffer_count_callback(struct rte_mbuf **pkts, uint16_t unsent, 285599a2dd95SBruce Richardson void *userdata) 285699a2dd95SBruce Richardson { 285799a2dd95SBruce Richardson uint64_t *count = userdata; 285899a2dd95SBruce Richardson 285999a2dd95SBruce Richardson rte_pktmbuf_free_bulk(pkts, unsent); 286099a2dd95SBruce Richardson *count += unsent; 28616679cf21SAnkur Dwivedi 28626679cf21SAnkur Dwivedi rte_eth_trace_tx_buffer_count_callback((void **)pkts, unsent, *count); 286399a2dd95SBruce Richardson } 286499a2dd95SBruce Richardson 286599a2dd95SBruce Richardson int 286699a2dd95SBruce Richardson rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer, 286799a2dd95SBruce Richardson buffer_tx_error_fn cbfn, void *userdata) 286899a2dd95SBruce Richardson { 286953ef1b34SMin Hu (Connor) if (buffer == NULL) { 28700e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 28710e21c7c0SDavid Marchand "Cannot set Tx buffer error callback to NULL buffer"); 287253ef1b34SMin Hu (Connor) return -EINVAL; 287353ef1b34SMin Hu (Connor) } 287453ef1b34SMin Hu (Connor) 287599a2dd95SBruce Richardson buffer->error_callback = cbfn; 287699a2dd95SBruce Richardson buffer->error_userdata = userdata; 28776679cf21SAnkur Dwivedi 28786679cf21SAnkur Dwivedi rte_eth_trace_tx_buffer_set_err_callback(buffer); 28796679cf21SAnkur Dwivedi 288099a2dd95SBruce Richardson return 0; 288199a2dd95SBruce Richardson } 288299a2dd95SBruce Richardson 288399a2dd95SBruce Richardson int 288499a2dd95SBruce Richardson rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size) 288599a2dd95SBruce Richardson { 288699a2dd95SBruce Richardson int ret = 0; 288799a2dd95SBruce Richardson 288853ef1b34SMin Hu (Connor) if (buffer == NULL) { 28890e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot initialize NULL buffer"); 289099a2dd95SBruce Richardson return -EINVAL; 289153ef1b34SMin Hu (Connor) } 289299a2dd95SBruce Richardson 289399a2dd95SBruce Richardson buffer->size = size; 289499a2dd95SBruce Richardson if (buffer->error_callback == NULL) { 289599a2dd95SBruce Richardson ret = rte_eth_tx_buffer_set_err_callback( 289699a2dd95SBruce Richardson buffer, rte_eth_tx_buffer_drop_callback, NULL); 289799a2dd95SBruce Richardson } 289899a2dd95SBruce Richardson 28996679cf21SAnkur Dwivedi rte_eth_trace_tx_buffer_init(buffer, size, ret); 29006679cf21SAnkur Dwivedi 290199a2dd95SBruce Richardson return ret; 290299a2dd95SBruce Richardson } 290399a2dd95SBruce Richardson 290499a2dd95SBruce Richardson int 290599a2dd95SBruce Richardson rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt) 290699a2dd95SBruce Richardson { 290753ef1b34SMin Hu (Connor) struct rte_eth_dev *dev; 290899a2dd95SBruce Richardson int ret; 290999a2dd95SBruce Richardson 291099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 291153ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 291253ef1b34SMin Hu (Connor) 2913*707f50ceSChengwen Feng #ifdef RTE_ETHDEV_DEBUG_TX 2914*707f50ceSChengwen Feng ret = eth_dev_validate_tx_queue(dev, queue_id); 2915*707f50ceSChengwen Feng if (ret != 0) 2916*707f50ceSChengwen Feng return ret; 2917*707f50ceSChengwen Feng #endif 2918*707f50ceSChengwen Feng 29198f1d23ecSDavid Marchand if (*dev->dev_ops->tx_done_cleanup == NULL) 29208f1d23ecSDavid Marchand return -ENOTSUP; 292199a2dd95SBruce Richardson 292299a2dd95SBruce Richardson /* Call driver to free pending mbufs. */ 292399a2dd95SBruce Richardson ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id], 292499a2dd95SBruce Richardson free_cnt); 29256679cf21SAnkur Dwivedi ret = eth_err(port_id, ret); 29266679cf21SAnkur Dwivedi 29276679cf21SAnkur Dwivedi rte_eth_trace_tx_done_cleanup(port_id, queue_id, free_cnt, ret); 29286679cf21SAnkur Dwivedi 29296679cf21SAnkur Dwivedi return ret; 293099a2dd95SBruce Richardson } 293199a2dd95SBruce Richardson 293299a2dd95SBruce Richardson int 293399a2dd95SBruce Richardson rte_eth_promiscuous_enable(uint16_t port_id) 293499a2dd95SBruce Richardson { 293599a2dd95SBruce Richardson struct rte_eth_dev *dev; 293699a2dd95SBruce Richardson int diag = 0; 293799a2dd95SBruce Richardson 293899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 293999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 294099a2dd95SBruce Richardson 294199a2dd95SBruce Richardson if (dev->data->promiscuous == 1) 294299a2dd95SBruce Richardson return 0; 294399a2dd95SBruce Richardson 29448f1d23ecSDavid Marchand if (*dev->dev_ops->promiscuous_enable == NULL) 29458f1d23ecSDavid Marchand return -ENOTSUP; 294699a2dd95SBruce Richardson 294799a2dd95SBruce Richardson diag = (*dev->dev_ops->promiscuous_enable)(dev); 294899a2dd95SBruce Richardson dev->data->promiscuous = (diag == 0) ? 1 : 0; 294999a2dd95SBruce Richardson 29506679cf21SAnkur Dwivedi diag = eth_err(port_id, diag); 29516679cf21SAnkur Dwivedi 29526679cf21SAnkur Dwivedi rte_eth_trace_promiscuous_enable(port_id, dev->data->promiscuous, 29536679cf21SAnkur Dwivedi diag); 29546679cf21SAnkur Dwivedi 29556679cf21SAnkur Dwivedi return diag; 295699a2dd95SBruce Richardson } 295799a2dd95SBruce Richardson 295899a2dd95SBruce Richardson int 295999a2dd95SBruce Richardson rte_eth_promiscuous_disable(uint16_t port_id) 296099a2dd95SBruce Richardson { 296199a2dd95SBruce Richardson struct rte_eth_dev *dev; 296299a2dd95SBruce Richardson int diag = 0; 296399a2dd95SBruce Richardson 296499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 296599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 296699a2dd95SBruce Richardson 296799a2dd95SBruce Richardson if (dev->data->promiscuous == 0) 296899a2dd95SBruce Richardson return 0; 296999a2dd95SBruce Richardson 29708f1d23ecSDavid Marchand if (*dev->dev_ops->promiscuous_disable == NULL) 29718f1d23ecSDavid Marchand return -ENOTSUP; 297299a2dd95SBruce Richardson 297399a2dd95SBruce Richardson dev->data->promiscuous = 0; 297499a2dd95SBruce Richardson diag = (*dev->dev_ops->promiscuous_disable)(dev); 297599a2dd95SBruce Richardson if (diag != 0) 297699a2dd95SBruce Richardson dev->data->promiscuous = 1; 297799a2dd95SBruce Richardson 29786679cf21SAnkur Dwivedi diag = eth_err(port_id, diag); 29796679cf21SAnkur Dwivedi 29806679cf21SAnkur Dwivedi rte_eth_trace_promiscuous_disable(port_id, dev->data->promiscuous, 29816679cf21SAnkur Dwivedi diag); 29826679cf21SAnkur Dwivedi 29836679cf21SAnkur Dwivedi return diag; 298499a2dd95SBruce Richardson } 298599a2dd95SBruce Richardson 298699a2dd95SBruce Richardson int 298799a2dd95SBruce Richardson rte_eth_promiscuous_get(uint16_t port_id) 298899a2dd95SBruce Richardson { 298999a2dd95SBruce Richardson struct rte_eth_dev *dev; 299099a2dd95SBruce Richardson 299199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 299299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 299353ef1b34SMin Hu (Connor) 29946679cf21SAnkur Dwivedi rte_eth_trace_promiscuous_get(port_id, dev->data->promiscuous); 29956679cf21SAnkur Dwivedi 299699a2dd95SBruce Richardson return dev->data->promiscuous; 299799a2dd95SBruce Richardson } 299899a2dd95SBruce Richardson 299999a2dd95SBruce Richardson int 300099a2dd95SBruce Richardson rte_eth_allmulticast_enable(uint16_t port_id) 300199a2dd95SBruce Richardson { 300299a2dd95SBruce Richardson struct rte_eth_dev *dev; 300399a2dd95SBruce Richardson int diag; 300499a2dd95SBruce Richardson 300599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 300699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 300799a2dd95SBruce Richardson 300899a2dd95SBruce Richardson if (dev->data->all_multicast == 1) 300999a2dd95SBruce Richardson return 0; 301099a2dd95SBruce Richardson 30118f1d23ecSDavid Marchand if (*dev->dev_ops->allmulticast_enable == NULL) 30128f1d23ecSDavid Marchand return -ENOTSUP; 301399a2dd95SBruce Richardson diag = (*dev->dev_ops->allmulticast_enable)(dev); 301499a2dd95SBruce Richardson dev->data->all_multicast = (diag == 0) ? 1 : 0; 301599a2dd95SBruce Richardson 30166679cf21SAnkur Dwivedi diag = eth_err(port_id, diag); 30176679cf21SAnkur Dwivedi 30186679cf21SAnkur Dwivedi rte_eth_trace_allmulticast_enable(port_id, dev->data->all_multicast, 30196679cf21SAnkur Dwivedi diag); 30206679cf21SAnkur Dwivedi 30216679cf21SAnkur Dwivedi return diag; 302299a2dd95SBruce Richardson } 302399a2dd95SBruce Richardson 302499a2dd95SBruce Richardson int 302599a2dd95SBruce Richardson rte_eth_allmulticast_disable(uint16_t port_id) 302699a2dd95SBruce Richardson { 302799a2dd95SBruce Richardson struct rte_eth_dev *dev; 302899a2dd95SBruce Richardson int diag; 302999a2dd95SBruce Richardson 303099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 303199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 303299a2dd95SBruce Richardson 303399a2dd95SBruce Richardson if (dev->data->all_multicast == 0) 303499a2dd95SBruce Richardson return 0; 303599a2dd95SBruce Richardson 30368f1d23ecSDavid Marchand if (*dev->dev_ops->allmulticast_disable == NULL) 30378f1d23ecSDavid Marchand return -ENOTSUP; 303899a2dd95SBruce Richardson dev->data->all_multicast = 0; 303999a2dd95SBruce Richardson diag = (*dev->dev_ops->allmulticast_disable)(dev); 304099a2dd95SBruce Richardson if (diag != 0) 304199a2dd95SBruce Richardson dev->data->all_multicast = 1; 304299a2dd95SBruce Richardson 30436679cf21SAnkur Dwivedi diag = eth_err(port_id, diag); 30446679cf21SAnkur Dwivedi 30456679cf21SAnkur Dwivedi rte_eth_trace_allmulticast_disable(port_id, dev->data->all_multicast, 30466679cf21SAnkur Dwivedi diag); 30476679cf21SAnkur Dwivedi 30486679cf21SAnkur Dwivedi return diag; 304999a2dd95SBruce Richardson } 305099a2dd95SBruce Richardson 305199a2dd95SBruce Richardson int 305299a2dd95SBruce Richardson rte_eth_allmulticast_get(uint16_t port_id) 305399a2dd95SBruce Richardson { 305499a2dd95SBruce Richardson struct rte_eth_dev *dev; 305599a2dd95SBruce Richardson 305699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 305799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 305853ef1b34SMin Hu (Connor) 30596679cf21SAnkur Dwivedi rte_eth_trace_allmulticast_get(port_id, dev->data->all_multicast); 30606679cf21SAnkur Dwivedi 306199a2dd95SBruce Richardson return dev->data->all_multicast; 306299a2dd95SBruce Richardson } 306399a2dd95SBruce Richardson 306499a2dd95SBruce Richardson int 306599a2dd95SBruce Richardson rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link) 306699a2dd95SBruce Richardson { 306799a2dd95SBruce Richardson struct rte_eth_dev *dev; 306899a2dd95SBruce Richardson 306999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 307099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 307199a2dd95SBruce Richardson 307253ef1b34SMin Hu (Connor) if (eth_link == NULL) { 30730e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u link to NULL", 307453ef1b34SMin Hu (Connor) port_id); 307553ef1b34SMin Hu (Connor) return -EINVAL; 307653ef1b34SMin Hu (Connor) } 307753ef1b34SMin Hu (Connor) 307853ef1b34SMin Hu (Connor) if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started) 307999a2dd95SBruce Richardson rte_eth_linkstatus_get(dev, eth_link); 308099a2dd95SBruce Richardson else { 30818f1d23ecSDavid Marchand if (*dev->dev_ops->link_update == NULL) 30828f1d23ecSDavid Marchand return -ENOTSUP; 308399a2dd95SBruce Richardson (*dev->dev_ops->link_update)(dev, 1); 308499a2dd95SBruce Richardson *eth_link = dev->data->dev_link; 308599a2dd95SBruce Richardson } 308699a2dd95SBruce Richardson 30876679cf21SAnkur Dwivedi rte_eth_trace_link_get(port_id, eth_link); 30886679cf21SAnkur Dwivedi 308999a2dd95SBruce Richardson return 0; 309099a2dd95SBruce Richardson } 309199a2dd95SBruce Richardson 309299a2dd95SBruce Richardson int 309399a2dd95SBruce Richardson rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link) 309499a2dd95SBruce Richardson { 309599a2dd95SBruce Richardson struct rte_eth_dev *dev; 309699a2dd95SBruce Richardson 309799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 309899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 309999a2dd95SBruce Richardson 310053ef1b34SMin Hu (Connor) if (eth_link == NULL) { 31010e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u link to NULL", 310253ef1b34SMin Hu (Connor) port_id); 310353ef1b34SMin Hu (Connor) return -EINVAL; 310453ef1b34SMin Hu (Connor) } 310553ef1b34SMin Hu (Connor) 310653ef1b34SMin Hu (Connor) if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started) 310799a2dd95SBruce Richardson rte_eth_linkstatus_get(dev, eth_link); 310899a2dd95SBruce Richardson else { 31098f1d23ecSDavid Marchand if (*dev->dev_ops->link_update == NULL) 31108f1d23ecSDavid Marchand return -ENOTSUP; 311199a2dd95SBruce Richardson (*dev->dev_ops->link_update)(dev, 0); 311299a2dd95SBruce Richardson *eth_link = dev->data->dev_link; 311399a2dd95SBruce Richardson } 311499a2dd95SBruce Richardson 31156679cf21SAnkur Dwivedi rte_eth_trace_link_get_nowait(port_id, eth_link); 31166679cf21SAnkur Dwivedi 311799a2dd95SBruce Richardson return 0; 311899a2dd95SBruce Richardson } 311999a2dd95SBruce Richardson 312099a2dd95SBruce Richardson const char * 312199a2dd95SBruce Richardson rte_eth_link_speed_to_str(uint32_t link_speed) 312299a2dd95SBruce Richardson { 31236679cf21SAnkur Dwivedi const char *ret; 31246679cf21SAnkur Dwivedi 312599a2dd95SBruce Richardson switch (link_speed) { 31266679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_NONE: 31276679cf21SAnkur Dwivedi ret = "None"; 31286679cf21SAnkur Dwivedi break; 31296679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_10M: 31306679cf21SAnkur Dwivedi ret = "10 Mbps"; 31316679cf21SAnkur Dwivedi break; 31326679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_100M: 31336679cf21SAnkur Dwivedi ret = "100 Mbps"; 31346679cf21SAnkur Dwivedi break; 31356679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_1G: 31366679cf21SAnkur Dwivedi ret = "1 Gbps"; 31376679cf21SAnkur Dwivedi break; 31386679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_2_5G: 31396679cf21SAnkur Dwivedi ret = "2.5 Gbps"; 31406679cf21SAnkur Dwivedi break; 31416679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_5G: 31426679cf21SAnkur Dwivedi ret = "5 Gbps"; 31436679cf21SAnkur Dwivedi break; 31446679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_10G: 31456679cf21SAnkur Dwivedi ret = "10 Gbps"; 31466679cf21SAnkur Dwivedi break; 31476679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_20G: 31486679cf21SAnkur Dwivedi ret = "20 Gbps"; 31496679cf21SAnkur Dwivedi break; 31506679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_25G: 31516679cf21SAnkur Dwivedi ret = "25 Gbps"; 31526679cf21SAnkur Dwivedi break; 31536679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_40G: 31546679cf21SAnkur Dwivedi ret = "40 Gbps"; 31556679cf21SAnkur Dwivedi break; 31566679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_50G: 31576679cf21SAnkur Dwivedi ret = "50 Gbps"; 31586679cf21SAnkur Dwivedi break; 31596679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_56G: 31606679cf21SAnkur Dwivedi ret = "56 Gbps"; 31616679cf21SAnkur Dwivedi break; 31626679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_100G: 31636679cf21SAnkur Dwivedi ret = "100 Gbps"; 31646679cf21SAnkur Dwivedi break; 31656679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_200G: 31666679cf21SAnkur Dwivedi ret = "200 Gbps"; 31676679cf21SAnkur Dwivedi break; 3168a131d9ecSThomas Monjalon case RTE_ETH_SPEED_NUM_400G: 3169a131d9ecSThomas Monjalon ret = "400 Gbps"; 3170a131d9ecSThomas Monjalon break; 31716679cf21SAnkur Dwivedi case RTE_ETH_SPEED_NUM_UNKNOWN: 31726679cf21SAnkur Dwivedi ret = "Unknown"; 31736679cf21SAnkur Dwivedi break; 31746679cf21SAnkur Dwivedi default: 31756679cf21SAnkur Dwivedi ret = "Invalid"; 317699a2dd95SBruce Richardson } 31776679cf21SAnkur Dwivedi 31786679cf21SAnkur Dwivedi rte_eth_trace_link_speed_to_str(link_speed, ret); 31796679cf21SAnkur Dwivedi 31806679cf21SAnkur Dwivedi return ret; 318199a2dd95SBruce Richardson } 318299a2dd95SBruce Richardson 318399a2dd95SBruce Richardson int 318499a2dd95SBruce Richardson rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link) 318599a2dd95SBruce Richardson { 31866679cf21SAnkur Dwivedi int ret; 31876679cf21SAnkur Dwivedi 318853ef1b34SMin Hu (Connor) if (str == NULL) { 31890e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot convert link to NULL string"); 319053ef1b34SMin Hu (Connor) return -EINVAL; 319153ef1b34SMin Hu (Connor) } 319253ef1b34SMin Hu (Connor) 319353ef1b34SMin Hu (Connor) if (len == 0) { 31940e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 31950e21c7c0SDavid Marchand "Cannot convert link to string with zero size"); 319653ef1b34SMin Hu (Connor) return -EINVAL; 319753ef1b34SMin Hu (Connor) } 319853ef1b34SMin Hu (Connor) 319953ef1b34SMin Hu (Connor) if (eth_link == NULL) { 32000e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot convert to string from NULL link"); 320153ef1b34SMin Hu (Connor) return -EINVAL; 320253ef1b34SMin Hu (Connor) } 320353ef1b34SMin Hu (Connor) 3204295968d1SFerruh Yigit if (eth_link->link_status == RTE_ETH_LINK_DOWN) 32056679cf21SAnkur Dwivedi ret = snprintf(str, len, "Link down"); 320699a2dd95SBruce Richardson else 32076679cf21SAnkur Dwivedi ret = snprintf(str, len, "Link up at %s %s %s", 320899a2dd95SBruce Richardson rte_eth_link_speed_to_str(eth_link->link_speed), 3209295968d1SFerruh Yigit (eth_link->link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ? 321099a2dd95SBruce Richardson "FDX" : "HDX", 3211295968d1SFerruh Yigit (eth_link->link_autoneg == RTE_ETH_LINK_AUTONEG) ? 321299a2dd95SBruce Richardson "Autoneg" : "Fixed"); 32136679cf21SAnkur Dwivedi 32146679cf21SAnkur Dwivedi rte_eth_trace_link_to_str(len, eth_link, str, ret); 32156679cf21SAnkur Dwivedi 32166679cf21SAnkur Dwivedi return ret; 321799a2dd95SBruce Richardson } 321899a2dd95SBruce Richardson 321999a2dd95SBruce Richardson int 322099a2dd95SBruce Richardson rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats) 322199a2dd95SBruce Richardson { 322299a2dd95SBruce Richardson struct rte_eth_dev *dev; 32236679cf21SAnkur Dwivedi int ret; 322499a2dd95SBruce Richardson 322599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 322699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 322753ef1b34SMin Hu (Connor) 322853ef1b34SMin Hu (Connor) if (stats == NULL) { 32290e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u stats to NULL", 323053ef1b34SMin Hu (Connor) port_id); 323153ef1b34SMin Hu (Connor) return -EINVAL; 323253ef1b34SMin Hu (Connor) } 323353ef1b34SMin Hu (Connor) 323499a2dd95SBruce Richardson memset(stats, 0, sizeof(*stats)); 323599a2dd95SBruce Richardson 32368f1d23ecSDavid Marchand if (*dev->dev_ops->stats_get == NULL) 32378f1d23ecSDavid Marchand return -ENOTSUP; 323899a2dd95SBruce Richardson stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed; 32396679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->stats_get)(dev, stats)); 32406679cf21SAnkur Dwivedi 32416679cf21SAnkur Dwivedi rte_eth_trace_stats_get(port_id, stats, ret); 32426679cf21SAnkur Dwivedi 32436679cf21SAnkur Dwivedi return ret; 324499a2dd95SBruce Richardson } 324599a2dd95SBruce Richardson 324699a2dd95SBruce Richardson int 324799a2dd95SBruce Richardson rte_eth_stats_reset(uint16_t port_id) 324899a2dd95SBruce Richardson { 324999a2dd95SBruce Richardson struct rte_eth_dev *dev; 325099a2dd95SBruce Richardson int ret; 325199a2dd95SBruce Richardson 325299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 325399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 325499a2dd95SBruce Richardson 32558f1d23ecSDavid Marchand if (*dev->dev_ops->stats_reset == NULL) 32568f1d23ecSDavid Marchand return -ENOTSUP; 325799a2dd95SBruce Richardson ret = (*dev->dev_ops->stats_reset)(dev); 325899a2dd95SBruce Richardson if (ret != 0) 325999a2dd95SBruce Richardson return eth_err(port_id, ret); 326099a2dd95SBruce Richardson 326199a2dd95SBruce Richardson dev->data->rx_mbuf_alloc_failed = 0; 326299a2dd95SBruce Richardson 32636679cf21SAnkur Dwivedi rte_eth_trace_stats_reset(port_id); 32646679cf21SAnkur Dwivedi 326599a2dd95SBruce Richardson return 0; 326699a2dd95SBruce Richardson } 326799a2dd95SBruce Richardson 326899a2dd95SBruce Richardson static inline int 326999a2dd95SBruce Richardson eth_dev_get_xstats_basic_count(struct rte_eth_dev *dev) 327099a2dd95SBruce Richardson { 327199a2dd95SBruce Richardson uint16_t nb_rxqs, nb_txqs; 327299a2dd95SBruce Richardson int count; 327399a2dd95SBruce Richardson 327499a2dd95SBruce Richardson nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 327599a2dd95SBruce Richardson nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 327699a2dd95SBruce Richardson 327799a2dd95SBruce Richardson count = RTE_NB_STATS; 327899a2dd95SBruce Richardson if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) { 327999a2dd95SBruce Richardson count += nb_rxqs * RTE_NB_RXQ_STATS; 328099a2dd95SBruce Richardson count += nb_txqs * RTE_NB_TXQ_STATS; 328199a2dd95SBruce Richardson } 328299a2dd95SBruce Richardson 328399a2dd95SBruce Richardson return count; 328499a2dd95SBruce Richardson } 328599a2dd95SBruce Richardson 328699a2dd95SBruce Richardson static int 328799a2dd95SBruce Richardson eth_dev_get_xstats_count(uint16_t port_id) 328899a2dd95SBruce Richardson { 328999a2dd95SBruce Richardson struct rte_eth_dev *dev; 329099a2dd95SBruce Richardson int count; 329199a2dd95SBruce Richardson 329299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 329399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 329499a2dd95SBruce Richardson if (dev->dev_ops->xstats_get_names != NULL) { 329599a2dd95SBruce Richardson count = (*dev->dev_ops->xstats_get_names)(dev, NULL, 0); 329699a2dd95SBruce Richardson if (count < 0) 329799a2dd95SBruce Richardson return eth_err(port_id, count); 329899a2dd95SBruce Richardson } else 329999a2dd95SBruce Richardson count = 0; 330099a2dd95SBruce Richardson 330199a2dd95SBruce Richardson 330299a2dd95SBruce Richardson count += eth_dev_get_xstats_basic_count(dev); 330399a2dd95SBruce Richardson 330499a2dd95SBruce Richardson return count; 330599a2dd95SBruce Richardson } 330699a2dd95SBruce Richardson 330799a2dd95SBruce Richardson int 330899a2dd95SBruce Richardson rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name, 330999a2dd95SBruce Richardson uint64_t *id) 331099a2dd95SBruce Richardson { 331199a2dd95SBruce Richardson int cnt_xstats, idx_xstat; 331299a2dd95SBruce Richardson 331399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 331499a2dd95SBruce Richardson 331553ef1b34SMin Hu (Connor) if (xstat_name == NULL) { 33160e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 33170e21c7c0SDavid Marchand "Cannot get ethdev port %u xstats ID from NULL xstat name", 331853ef1b34SMin Hu (Connor) port_id); 331999a2dd95SBruce Richardson return -ENOMEM; 332099a2dd95SBruce Richardson } 332199a2dd95SBruce Richardson 332253ef1b34SMin Hu (Connor) if (id == NULL) { 33230e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 33240e21c7c0SDavid Marchand "Cannot get ethdev port %u xstats ID to NULL", 332553ef1b34SMin Hu (Connor) port_id); 332699a2dd95SBruce Richardson return -ENOMEM; 332799a2dd95SBruce Richardson } 332899a2dd95SBruce Richardson 332999a2dd95SBruce Richardson /* Get count */ 333099a2dd95SBruce Richardson cnt_xstats = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL); 333199a2dd95SBruce Richardson if (cnt_xstats < 0) { 33320e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get count of xstats"); 333399a2dd95SBruce Richardson return -ENODEV; 333499a2dd95SBruce Richardson } 333599a2dd95SBruce Richardson 333699a2dd95SBruce Richardson /* Get id-name lookup table */ 333799a2dd95SBruce Richardson struct rte_eth_xstat_name xstats_names[cnt_xstats]; 333899a2dd95SBruce Richardson 333999a2dd95SBruce Richardson if (cnt_xstats != rte_eth_xstats_get_names_by_id( 334099a2dd95SBruce Richardson port_id, xstats_names, cnt_xstats, NULL)) { 33410e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get xstats lookup"); 334299a2dd95SBruce Richardson return -1; 334399a2dd95SBruce Richardson } 334499a2dd95SBruce Richardson 334599a2dd95SBruce Richardson for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) { 334699a2dd95SBruce Richardson if (!strcmp(xstats_names[idx_xstat].name, xstat_name)) { 334799a2dd95SBruce Richardson *id = idx_xstat; 33486679cf21SAnkur Dwivedi 33496679cf21SAnkur Dwivedi rte_eth_trace_xstats_get_id_by_name(port_id, 33506679cf21SAnkur Dwivedi xstat_name, *id); 33516679cf21SAnkur Dwivedi 335299a2dd95SBruce Richardson return 0; 335399a2dd95SBruce Richardson }; 335499a2dd95SBruce Richardson } 335599a2dd95SBruce Richardson 335699a2dd95SBruce Richardson return -EINVAL; 335799a2dd95SBruce Richardson } 335899a2dd95SBruce Richardson 335999a2dd95SBruce Richardson /* retrieve basic stats names */ 336099a2dd95SBruce Richardson static int 336199a2dd95SBruce Richardson eth_basic_stats_get_names(struct rte_eth_dev *dev, 336299a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names) 336399a2dd95SBruce Richardson { 336499a2dd95SBruce Richardson int cnt_used_entries = 0; 336599a2dd95SBruce Richardson uint32_t idx, id_queue; 336699a2dd95SBruce Richardson uint16_t num_q; 336799a2dd95SBruce Richardson 336899a2dd95SBruce Richardson for (idx = 0; idx < RTE_NB_STATS; idx++) { 336999a2dd95SBruce Richardson strlcpy(xstats_names[cnt_used_entries].name, 337099a2dd95SBruce Richardson eth_dev_stats_strings[idx].name, 337199a2dd95SBruce Richardson sizeof(xstats_names[0].name)); 337299a2dd95SBruce Richardson cnt_used_entries++; 337399a2dd95SBruce Richardson } 337499a2dd95SBruce Richardson 337599a2dd95SBruce Richardson if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0) 337699a2dd95SBruce Richardson return cnt_used_entries; 337799a2dd95SBruce Richardson 337899a2dd95SBruce Richardson num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 337999a2dd95SBruce Richardson for (id_queue = 0; id_queue < num_q; id_queue++) { 338099a2dd95SBruce Richardson for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) { 338199a2dd95SBruce Richardson snprintf(xstats_names[cnt_used_entries].name, 338299a2dd95SBruce Richardson sizeof(xstats_names[0].name), 338399a2dd95SBruce Richardson "rx_q%u_%s", 338499a2dd95SBruce Richardson id_queue, eth_dev_rxq_stats_strings[idx].name); 338599a2dd95SBruce Richardson cnt_used_entries++; 338699a2dd95SBruce Richardson } 338799a2dd95SBruce Richardson 338899a2dd95SBruce Richardson } 338999a2dd95SBruce Richardson num_q = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 339099a2dd95SBruce Richardson for (id_queue = 0; id_queue < num_q; id_queue++) { 339199a2dd95SBruce Richardson for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) { 339299a2dd95SBruce Richardson snprintf(xstats_names[cnt_used_entries].name, 339399a2dd95SBruce Richardson sizeof(xstats_names[0].name), 339499a2dd95SBruce Richardson "tx_q%u_%s", 339599a2dd95SBruce Richardson id_queue, eth_dev_txq_stats_strings[idx].name); 339699a2dd95SBruce Richardson cnt_used_entries++; 339799a2dd95SBruce Richardson } 339899a2dd95SBruce Richardson } 339999a2dd95SBruce Richardson return cnt_used_entries; 340099a2dd95SBruce Richardson } 340199a2dd95SBruce Richardson 340299a2dd95SBruce Richardson /* retrieve ethdev extended statistics names */ 340399a2dd95SBruce Richardson int 340499a2dd95SBruce Richardson rte_eth_xstats_get_names_by_id(uint16_t port_id, 340599a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names, unsigned int size, 340699a2dd95SBruce Richardson uint64_t *ids) 340799a2dd95SBruce Richardson { 340899a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names_copy; 340999a2dd95SBruce Richardson unsigned int no_basic_stat_requested = 1; 341099a2dd95SBruce Richardson unsigned int no_ext_stat_requested = 1; 341199a2dd95SBruce Richardson unsigned int expected_entries; 341299a2dd95SBruce Richardson unsigned int basic_count; 341399a2dd95SBruce Richardson struct rte_eth_dev *dev; 341499a2dd95SBruce Richardson unsigned int i; 341599a2dd95SBruce Richardson int ret; 341699a2dd95SBruce Richardson 341799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 341899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 341999a2dd95SBruce Richardson 342099a2dd95SBruce Richardson basic_count = eth_dev_get_xstats_basic_count(dev); 342199a2dd95SBruce Richardson ret = eth_dev_get_xstats_count(port_id); 342299a2dd95SBruce Richardson if (ret < 0) 342399a2dd95SBruce Richardson return ret; 342499a2dd95SBruce Richardson expected_entries = (unsigned int)ret; 342599a2dd95SBruce Richardson 342699a2dd95SBruce Richardson /* Return max number of stats if no ids given */ 342799a2dd95SBruce Richardson if (!ids) { 342899a2dd95SBruce Richardson if (!xstats_names) 342999a2dd95SBruce Richardson return expected_entries; 343099a2dd95SBruce Richardson else if (xstats_names && size < expected_entries) 343199a2dd95SBruce Richardson return expected_entries; 343299a2dd95SBruce Richardson } 343399a2dd95SBruce Richardson 343499a2dd95SBruce Richardson if (ids && !xstats_names) 343599a2dd95SBruce Richardson return -EINVAL; 343699a2dd95SBruce Richardson 343799a2dd95SBruce Richardson if (ids && dev->dev_ops->xstats_get_names_by_id != NULL && size > 0) { 343899a2dd95SBruce Richardson uint64_t ids_copy[size]; 343999a2dd95SBruce Richardson 344099a2dd95SBruce Richardson for (i = 0; i < size; i++) { 344199a2dd95SBruce Richardson if (ids[i] < basic_count) { 344299a2dd95SBruce Richardson no_basic_stat_requested = 0; 344399a2dd95SBruce Richardson break; 344499a2dd95SBruce Richardson } 344599a2dd95SBruce Richardson 344699a2dd95SBruce Richardson /* 344799a2dd95SBruce Richardson * Convert ids to xstats ids that PMD knows. 344899a2dd95SBruce Richardson * ids known by user are basic + extended stats. 344999a2dd95SBruce Richardson */ 345099a2dd95SBruce Richardson ids_copy[i] = ids[i] - basic_count; 345199a2dd95SBruce Richardson } 345299a2dd95SBruce Richardson 345399a2dd95SBruce Richardson if (no_basic_stat_requested) 345499a2dd95SBruce Richardson return (*dev->dev_ops->xstats_get_names_by_id)(dev, 34558c9f976fSAndrew Rybchenko ids_copy, xstats_names, size); 345699a2dd95SBruce Richardson } 345799a2dd95SBruce Richardson 345899a2dd95SBruce Richardson /* Retrieve all stats */ 345999a2dd95SBruce Richardson if (!ids) { 346099a2dd95SBruce Richardson int num_stats = rte_eth_xstats_get_names(port_id, xstats_names, 346199a2dd95SBruce Richardson expected_entries); 346299a2dd95SBruce Richardson if (num_stats < 0 || num_stats > (int)expected_entries) 346399a2dd95SBruce Richardson return num_stats; 346499a2dd95SBruce Richardson else 346599a2dd95SBruce Richardson return expected_entries; 346699a2dd95SBruce Richardson } 346799a2dd95SBruce Richardson 346899a2dd95SBruce Richardson xstats_names_copy = calloc(expected_entries, 346999a2dd95SBruce Richardson sizeof(struct rte_eth_xstat_name)); 347099a2dd95SBruce Richardson 347199a2dd95SBruce Richardson if (!xstats_names_copy) { 34720e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Can't allocate memory"); 347399a2dd95SBruce Richardson return -ENOMEM; 347499a2dd95SBruce Richardson } 347599a2dd95SBruce Richardson 347699a2dd95SBruce Richardson if (ids) { 347799a2dd95SBruce Richardson for (i = 0; i < size; i++) { 347899a2dd95SBruce Richardson if (ids[i] >= basic_count) { 347999a2dd95SBruce Richardson no_ext_stat_requested = 0; 348099a2dd95SBruce Richardson break; 348199a2dd95SBruce Richardson } 348299a2dd95SBruce Richardson } 348399a2dd95SBruce Richardson } 348499a2dd95SBruce Richardson 348599a2dd95SBruce Richardson /* Fill xstats_names_copy structure */ 348699a2dd95SBruce Richardson if (ids && no_ext_stat_requested) { 348799a2dd95SBruce Richardson eth_basic_stats_get_names(dev, xstats_names_copy); 348899a2dd95SBruce Richardson } else { 348999a2dd95SBruce Richardson ret = rte_eth_xstats_get_names(port_id, xstats_names_copy, 349099a2dd95SBruce Richardson expected_entries); 349199a2dd95SBruce Richardson if (ret < 0) { 349299a2dd95SBruce Richardson free(xstats_names_copy); 349399a2dd95SBruce Richardson return ret; 349499a2dd95SBruce Richardson } 349599a2dd95SBruce Richardson } 349699a2dd95SBruce Richardson 349799a2dd95SBruce Richardson /* Filter stats */ 349899a2dd95SBruce Richardson for (i = 0; i < size; i++) { 349999a2dd95SBruce Richardson if (ids[i] >= expected_entries) { 35000e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Id value isn't valid"); 350199a2dd95SBruce Richardson free(xstats_names_copy); 350299a2dd95SBruce Richardson return -1; 350399a2dd95SBruce Richardson } 350499a2dd95SBruce Richardson xstats_names[i] = xstats_names_copy[ids[i]]; 35056679cf21SAnkur Dwivedi 35066679cf21SAnkur Dwivedi rte_eth_trace_xstats_get_names_by_id(port_id, &xstats_names[i], 35076679cf21SAnkur Dwivedi ids[i]); 350899a2dd95SBruce Richardson } 350999a2dd95SBruce Richardson 351099a2dd95SBruce Richardson free(xstats_names_copy); 351199a2dd95SBruce Richardson return size; 351299a2dd95SBruce Richardson } 351399a2dd95SBruce Richardson 351499a2dd95SBruce Richardson int 351599a2dd95SBruce Richardson rte_eth_xstats_get_names(uint16_t port_id, 351699a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names, 351799a2dd95SBruce Richardson unsigned int size) 351899a2dd95SBruce Richardson { 351999a2dd95SBruce Richardson struct rte_eth_dev *dev; 352099a2dd95SBruce Richardson int cnt_used_entries; 352199a2dd95SBruce Richardson int cnt_expected_entries; 352299a2dd95SBruce Richardson int cnt_driver_entries; 35236679cf21SAnkur Dwivedi int i; 352499a2dd95SBruce Richardson 352599a2dd95SBruce Richardson cnt_expected_entries = eth_dev_get_xstats_count(port_id); 352699a2dd95SBruce Richardson if (xstats_names == NULL || cnt_expected_entries < 0 || 352799a2dd95SBruce Richardson (int)size < cnt_expected_entries) 352899a2dd95SBruce Richardson return cnt_expected_entries; 352999a2dd95SBruce Richardson 353099a2dd95SBruce Richardson /* port_id checked in eth_dev_get_xstats_count() */ 353199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 353299a2dd95SBruce Richardson 353399a2dd95SBruce Richardson cnt_used_entries = eth_basic_stats_get_names(dev, xstats_names); 353499a2dd95SBruce Richardson 353599a2dd95SBruce Richardson if (dev->dev_ops->xstats_get_names != NULL) { 353699a2dd95SBruce Richardson /* If there are any driver-specific xstats, append them 353799a2dd95SBruce Richardson * to end of list. 353899a2dd95SBruce Richardson */ 353999a2dd95SBruce Richardson cnt_driver_entries = (*dev->dev_ops->xstats_get_names)( 354099a2dd95SBruce Richardson dev, 354199a2dd95SBruce Richardson xstats_names + cnt_used_entries, 354299a2dd95SBruce Richardson size - cnt_used_entries); 354399a2dd95SBruce Richardson if (cnt_driver_entries < 0) 354499a2dd95SBruce Richardson return eth_err(port_id, cnt_driver_entries); 354599a2dd95SBruce Richardson cnt_used_entries += cnt_driver_entries; 354699a2dd95SBruce Richardson } 354799a2dd95SBruce Richardson 35486679cf21SAnkur Dwivedi for (i = 0; i < cnt_used_entries; i++) 354926749cd1SAnkur Dwivedi rte_eth_trace_xstats_get_names(port_id, i, &xstats_names[i], 35506679cf21SAnkur Dwivedi size, cnt_used_entries); 35516679cf21SAnkur Dwivedi 355299a2dd95SBruce Richardson return cnt_used_entries; 355399a2dd95SBruce Richardson } 355499a2dd95SBruce Richardson 355599a2dd95SBruce Richardson 355699a2dd95SBruce Richardson static int 355799a2dd95SBruce Richardson eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats) 355899a2dd95SBruce Richardson { 355999a2dd95SBruce Richardson struct rte_eth_dev *dev; 356099a2dd95SBruce Richardson struct rte_eth_stats eth_stats; 356199a2dd95SBruce Richardson unsigned int count = 0, i, q; 356299a2dd95SBruce Richardson uint64_t val, *stats_ptr; 356399a2dd95SBruce Richardson uint16_t nb_rxqs, nb_txqs; 356499a2dd95SBruce Richardson int ret; 356599a2dd95SBruce Richardson 356699a2dd95SBruce Richardson ret = rte_eth_stats_get(port_id, ð_stats); 356799a2dd95SBruce Richardson if (ret < 0) 356899a2dd95SBruce Richardson return ret; 356999a2dd95SBruce Richardson 357099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 357199a2dd95SBruce Richardson 357299a2dd95SBruce Richardson nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 357399a2dd95SBruce Richardson nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 357499a2dd95SBruce Richardson 357599a2dd95SBruce Richardson /* global stats */ 357699a2dd95SBruce Richardson for (i = 0; i < RTE_NB_STATS; i++) { 357799a2dd95SBruce Richardson stats_ptr = RTE_PTR_ADD(ð_stats, 357899a2dd95SBruce Richardson eth_dev_stats_strings[i].offset); 357999a2dd95SBruce Richardson val = *stats_ptr; 358099a2dd95SBruce Richardson xstats[count++].value = val; 358199a2dd95SBruce Richardson } 358299a2dd95SBruce Richardson 358399a2dd95SBruce Richardson if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0) 358499a2dd95SBruce Richardson return count; 358599a2dd95SBruce Richardson 358699a2dd95SBruce Richardson /* per-rxq stats */ 358799a2dd95SBruce Richardson for (q = 0; q < nb_rxqs; q++) { 358899a2dd95SBruce Richardson for (i = 0; i < RTE_NB_RXQ_STATS; i++) { 358999a2dd95SBruce Richardson stats_ptr = RTE_PTR_ADD(ð_stats, 359099a2dd95SBruce Richardson eth_dev_rxq_stats_strings[i].offset + 359199a2dd95SBruce Richardson q * sizeof(uint64_t)); 359299a2dd95SBruce Richardson val = *stats_ptr; 359399a2dd95SBruce Richardson xstats[count++].value = val; 359499a2dd95SBruce Richardson } 359599a2dd95SBruce Richardson } 359699a2dd95SBruce Richardson 359799a2dd95SBruce Richardson /* per-txq stats */ 359899a2dd95SBruce Richardson for (q = 0; q < nb_txqs; q++) { 359999a2dd95SBruce Richardson for (i = 0; i < RTE_NB_TXQ_STATS; i++) { 360099a2dd95SBruce Richardson stats_ptr = RTE_PTR_ADD(ð_stats, 360199a2dd95SBruce Richardson eth_dev_txq_stats_strings[i].offset + 360299a2dd95SBruce Richardson q * sizeof(uint64_t)); 360399a2dd95SBruce Richardson val = *stats_ptr; 360499a2dd95SBruce Richardson xstats[count++].value = val; 360599a2dd95SBruce Richardson } 360699a2dd95SBruce Richardson } 360799a2dd95SBruce Richardson return count; 360899a2dd95SBruce Richardson } 360999a2dd95SBruce Richardson 361099a2dd95SBruce Richardson /* retrieve ethdev extended statistics */ 361199a2dd95SBruce Richardson int 361299a2dd95SBruce Richardson rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids, 361399a2dd95SBruce Richardson uint64_t *values, unsigned int size) 361499a2dd95SBruce Richardson { 361599a2dd95SBruce Richardson unsigned int no_basic_stat_requested = 1; 361699a2dd95SBruce Richardson unsigned int no_ext_stat_requested = 1; 361799a2dd95SBruce Richardson unsigned int num_xstats_filled; 361899a2dd95SBruce Richardson unsigned int basic_count; 361999a2dd95SBruce Richardson uint16_t expected_entries; 362099a2dd95SBruce Richardson struct rte_eth_dev *dev; 362199a2dd95SBruce Richardson unsigned int i; 362299a2dd95SBruce Richardson int ret; 362399a2dd95SBruce Richardson 362499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 362553ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 362653ef1b34SMin Hu (Connor) 362799a2dd95SBruce Richardson ret = eth_dev_get_xstats_count(port_id); 362899a2dd95SBruce Richardson if (ret < 0) 362999a2dd95SBruce Richardson return ret; 363099a2dd95SBruce Richardson expected_entries = (uint16_t)ret; 363199a2dd95SBruce Richardson struct rte_eth_xstat xstats[expected_entries]; 363299a2dd95SBruce Richardson basic_count = eth_dev_get_xstats_basic_count(dev); 363399a2dd95SBruce Richardson 363499a2dd95SBruce Richardson /* Return max number of stats if no ids given */ 363599a2dd95SBruce Richardson if (!ids) { 363699a2dd95SBruce Richardson if (!values) 363799a2dd95SBruce Richardson return expected_entries; 363899a2dd95SBruce Richardson else if (values && size < expected_entries) 363999a2dd95SBruce Richardson return expected_entries; 364099a2dd95SBruce Richardson } 364199a2dd95SBruce Richardson 364299a2dd95SBruce Richardson if (ids && !values) 364399a2dd95SBruce Richardson return -EINVAL; 364499a2dd95SBruce Richardson 364599a2dd95SBruce Richardson if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) { 364699a2dd95SBruce Richardson unsigned int basic_count = eth_dev_get_xstats_basic_count(dev); 364799a2dd95SBruce Richardson uint64_t ids_copy[size]; 364899a2dd95SBruce Richardson 364999a2dd95SBruce Richardson for (i = 0; i < size; i++) { 365099a2dd95SBruce Richardson if (ids[i] < basic_count) { 365199a2dd95SBruce Richardson no_basic_stat_requested = 0; 365299a2dd95SBruce Richardson break; 365399a2dd95SBruce Richardson } 365499a2dd95SBruce Richardson 365599a2dd95SBruce Richardson /* 365699a2dd95SBruce Richardson * Convert ids to xstats ids that PMD knows. 365799a2dd95SBruce Richardson * ids known by user are basic + extended stats. 365899a2dd95SBruce Richardson */ 365999a2dd95SBruce Richardson ids_copy[i] = ids[i] - basic_count; 366099a2dd95SBruce Richardson } 366199a2dd95SBruce Richardson 366299a2dd95SBruce Richardson if (no_basic_stat_requested) 366399a2dd95SBruce Richardson return (*dev->dev_ops->xstats_get_by_id)(dev, ids_copy, 366499a2dd95SBruce Richardson values, size); 366599a2dd95SBruce Richardson } 366699a2dd95SBruce Richardson 366799a2dd95SBruce Richardson if (ids) { 366899a2dd95SBruce Richardson for (i = 0; i < size; i++) { 366999a2dd95SBruce Richardson if (ids[i] >= basic_count) { 367099a2dd95SBruce Richardson no_ext_stat_requested = 0; 367199a2dd95SBruce Richardson break; 367299a2dd95SBruce Richardson } 367399a2dd95SBruce Richardson } 367499a2dd95SBruce Richardson } 367599a2dd95SBruce Richardson 367699a2dd95SBruce Richardson /* Fill the xstats structure */ 367799a2dd95SBruce Richardson if (ids && no_ext_stat_requested) 367899a2dd95SBruce Richardson ret = eth_basic_stats_get(port_id, xstats); 367999a2dd95SBruce Richardson else 368099a2dd95SBruce Richardson ret = rte_eth_xstats_get(port_id, xstats, expected_entries); 368199a2dd95SBruce Richardson 368299a2dd95SBruce Richardson if (ret < 0) 368399a2dd95SBruce Richardson return ret; 368499a2dd95SBruce Richardson num_xstats_filled = (unsigned int)ret; 368599a2dd95SBruce Richardson 368699a2dd95SBruce Richardson /* Return all stats */ 368799a2dd95SBruce Richardson if (!ids) { 368899a2dd95SBruce Richardson for (i = 0; i < num_xstats_filled; i++) 368999a2dd95SBruce Richardson values[i] = xstats[i].value; 369099a2dd95SBruce Richardson return expected_entries; 369199a2dd95SBruce Richardson } 369299a2dd95SBruce Richardson 369399a2dd95SBruce Richardson /* Filter stats */ 369499a2dd95SBruce Richardson for (i = 0; i < size; i++) { 369599a2dd95SBruce Richardson if (ids[i] >= expected_entries) { 36960e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Id value isn't valid"); 369799a2dd95SBruce Richardson return -1; 369899a2dd95SBruce Richardson } 369999a2dd95SBruce Richardson values[i] = xstats[ids[i]].value; 370099a2dd95SBruce Richardson } 37016679cf21SAnkur Dwivedi 37026679cf21SAnkur Dwivedi rte_eth_trace_xstats_get_by_id(port_id, ids, values, size); 37036679cf21SAnkur Dwivedi 370499a2dd95SBruce Richardson return size; 370599a2dd95SBruce Richardson } 370699a2dd95SBruce Richardson 370799a2dd95SBruce Richardson int 370899a2dd95SBruce Richardson rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats, 370999a2dd95SBruce Richardson unsigned int n) 371099a2dd95SBruce Richardson { 371199a2dd95SBruce Richardson struct rte_eth_dev *dev; 3712b8fcb65cSChengwen Feng unsigned int count, i; 371399a2dd95SBruce Richardson signed int xcount = 0; 371499a2dd95SBruce Richardson int ret; 371599a2dd95SBruce Richardson 371699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3717485df884SChengwen Feng if (xstats == NULL && n > 0) 3718485df884SChengwen Feng return -EINVAL; 371999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 372099a2dd95SBruce Richardson 3721b8fcb65cSChengwen Feng count = eth_dev_get_xstats_basic_count(dev); 372299a2dd95SBruce Richardson 372399a2dd95SBruce Richardson /* implemented by the driver */ 372499a2dd95SBruce Richardson if (dev->dev_ops->xstats_get != NULL) { 372599a2dd95SBruce Richardson /* Retrieve the xstats from the driver at the end of the 372699a2dd95SBruce Richardson * xstats struct. 372799a2dd95SBruce Richardson */ 372899a2dd95SBruce Richardson xcount = (*dev->dev_ops->xstats_get)(dev, 3729485df884SChengwen Feng (n > count) ? xstats + count : NULL, 373099a2dd95SBruce Richardson (n > count) ? n - count : 0); 373199a2dd95SBruce Richardson 373299a2dd95SBruce Richardson if (xcount < 0) 373399a2dd95SBruce Richardson return eth_err(port_id, xcount); 373499a2dd95SBruce Richardson } 373599a2dd95SBruce Richardson 373699a2dd95SBruce Richardson if (n < count + xcount || xstats == NULL) 373799a2dd95SBruce Richardson return count + xcount; 373899a2dd95SBruce Richardson 373999a2dd95SBruce Richardson /* now fill the xstats structure */ 374099a2dd95SBruce Richardson ret = eth_basic_stats_get(port_id, xstats); 374199a2dd95SBruce Richardson if (ret < 0) 374299a2dd95SBruce Richardson return ret; 374399a2dd95SBruce Richardson count = ret; 374499a2dd95SBruce Richardson 374599a2dd95SBruce Richardson for (i = 0; i < count; i++) 374699a2dd95SBruce Richardson xstats[i].id = i; 374799a2dd95SBruce Richardson /* add an offset to driver-specific stats */ 374899a2dd95SBruce Richardson for ( ; i < count + xcount; i++) 374999a2dd95SBruce Richardson xstats[i].id += count; 375099a2dd95SBruce Richardson 37516679cf21SAnkur Dwivedi for (i = 0; i < n; i++) 37526679cf21SAnkur Dwivedi rte_eth_trace_xstats_get(port_id, xstats[i]); 37536679cf21SAnkur Dwivedi 375499a2dd95SBruce Richardson return count + xcount; 375599a2dd95SBruce Richardson } 375699a2dd95SBruce Richardson 375799a2dd95SBruce Richardson /* reset ethdev extended statistics */ 375899a2dd95SBruce Richardson int 375999a2dd95SBruce Richardson rte_eth_xstats_reset(uint16_t port_id) 376099a2dd95SBruce Richardson { 376199a2dd95SBruce Richardson struct rte_eth_dev *dev; 376299a2dd95SBruce Richardson 376399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 376499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 376599a2dd95SBruce Richardson 376699a2dd95SBruce Richardson /* implemented by the driver */ 37676679cf21SAnkur Dwivedi if (dev->dev_ops->xstats_reset != NULL) { 37686679cf21SAnkur Dwivedi int ret = eth_err(port_id, (*dev->dev_ops->xstats_reset)(dev)); 37696679cf21SAnkur Dwivedi 37706679cf21SAnkur Dwivedi rte_eth_trace_xstats_reset(port_id, ret); 37716679cf21SAnkur Dwivedi 37726679cf21SAnkur Dwivedi return ret; 37736679cf21SAnkur Dwivedi } 377499a2dd95SBruce Richardson 377599a2dd95SBruce Richardson /* fallback to default */ 377699a2dd95SBruce Richardson return rte_eth_stats_reset(port_id); 377799a2dd95SBruce Richardson } 377899a2dd95SBruce Richardson 377999a2dd95SBruce Richardson static int 378099a2dd95SBruce Richardson eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id, 378199a2dd95SBruce Richardson uint8_t stat_idx, uint8_t is_rx) 378299a2dd95SBruce Richardson { 378399a2dd95SBruce Richardson struct rte_eth_dev *dev; 378499a2dd95SBruce Richardson 378599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 378699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 378799a2dd95SBruce Richardson 378899a2dd95SBruce Richardson if (is_rx && (queue_id >= dev->data->nb_rx_queues)) 378999a2dd95SBruce Richardson return -EINVAL; 379099a2dd95SBruce Richardson 379199a2dd95SBruce Richardson if (!is_rx && (queue_id >= dev->data->nb_tx_queues)) 379299a2dd95SBruce Richardson return -EINVAL; 379399a2dd95SBruce Richardson 379499a2dd95SBruce Richardson if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS) 379599a2dd95SBruce Richardson return -EINVAL; 379699a2dd95SBruce Richardson 37978f1d23ecSDavid Marchand if (*dev->dev_ops->queue_stats_mapping_set == NULL) 37988f1d23ecSDavid Marchand return -ENOTSUP; 379953ef1b34SMin Hu (Connor) return (*dev->dev_ops->queue_stats_mapping_set) (dev, queue_id, stat_idx, is_rx); 380099a2dd95SBruce Richardson } 380199a2dd95SBruce Richardson 380299a2dd95SBruce Richardson int 380399a2dd95SBruce Richardson rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id, 380499a2dd95SBruce Richardson uint8_t stat_idx) 380599a2dd95SBruce Richardson { 38066679cf21SAnkur Dwivedi int ret; 38076679cf21SAnkur Dwivedi 38086679cf21SAnkur Dwivedi ret = eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id, 380999a2dd95SBruce Richardson tx_queue_id, 381099a2dd95SBruce Richardson stat_idx, STAT_QMAP_TX)); 38116679cf21SAnkur Dwivedi 38126679cf21SAnkur Dwivedi rte_ethdev_trace_set_tx_queue_stats_mapping(port_id, tx_queue_id, 38136679cf21SAnkur Dwivedi stat_idx, ret); 38146679cf21SAnkur Dwivedi 38156679cf21SAnkur Dwivedi return ret; 381699a2dd95SBruce Richardson } 381799a2dd95SBruce Richardson 381899a2dd95SBruce Richardson int 381999a2dd95SBruce Richardson rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id, 382099a2dd95SBruce Richardson uint8_t stat_idx) 382199a2dd95SBruce Richardson { 38226679cf21SAnkur Dwivedi int ret; 38236679cf21SAnkur Dwivedi 38246679cf21SAnkur Dwivedi ret = eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id, 382599a2dd95SBruce Richardson rx_queue_id, 382699a2dd95SBruce Richardson stat_idx, STAT_QMAP_RX)); 38276679cf21SAnkur Dwivedi 38286679cf21SAnkur Dwivedi rte_ethdev_trace_set_rx_queue_stats_mapping(port_id, rx_queue_id, 38296679cf21SAnkur Dwivedi stat_idx, ret); 38306679cf21SAnkur Dwivedi 38316679cf21SAnkur Dwivedi return ret; 383299a2dd95SBruce Richardson } 383399a2dd95SBruce Richardson 383499a2dd95SBruce Richardson int 383599a2dd95SBruce Richardson rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size) 383699a2dd95SBruce Richardson { 383799a2dd95SBruce Richardson struct rte_eth_dev *dev; 38386679cf21SAnkur Dwivedi int ret; 383999a2dd95SBruce Richardson 384099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 384199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 384299a2dd95SBruce Richardson 384353ef1b34SMin Hu (Connor) if (fw_version == NULL && fw_size > 0) { 38440e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 38450e21c7c0SDavid Marchand "Cannot get ethdev port %u FW version to NULL when string size is non zero", 384653ef1b34SMin Hu (Connor) port_id); 384753ef1b34SMin Hu (Connor) return -EINVAL; 384853ef1b34SMin Hu (Connor) } 384953ef1b34SMin Hu (Connor) 38508f1d23ecSDavid Marchand if (*dev->dev_ops->fw_version_get == NULL) 38518f1d23ecSDavid Marchand return -ENOTSUP; 38526679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev, 385399a2dd95SBruce Richardson fw_version, fw_size)); 38546679cf21SAnkur Dwivedi 38556679cf21SAnkur Dwivedi rte_ethdev_trace_fw_version_get(port_id, fw_version, fw_size, ret); 38566679cf21SAnkur Dwivedi 38576679cf21SAnkur Dwivedi return ret; 385899a2dd95SBruce Richardson } 385999a2dd95SBruce Richardson 386099a2dd95SBruce Richardson int 386199a2dd95SBruce Richardson rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info) 386299a2dd95SBruce Richardson { 386399a2dd95SBruce Richardson struct rte_eth_dev *dev; 386499a2dd95SBruce Richardson const struct rte_eth_desc_lim lim = { 386599a2dd95SBruce Richardson .nb_max = UINT16_MAX, 386699a2dd95SBruce Richardson .nb_min = 0, 386799a2dd95SBruce Richardson .nb_align = 1, 386899a2dd95SBruce Richardson .nb_seg_max = UINT16_MAX, 386999a2dd95SBruce Richardson .nb_mtu_seg_max = UINT16_MAX, 387099a2dd95SBruce Richardson }; 387199a2dd95SBruce Richardson int diag; 387299a2dd95SBruce Richardson 387353ef1b34SMin Hu (Connor) RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 387453ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 387553ef1b34SMin Hu (Connor) 387653ef1b34SMin Hu (Connor) if (dev_info == NULL) { 38770e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u info to NULL", 387853ef1b34SMin Hu (Connor) port_id); 387953ef1b34SMin Hu (Connor) return -EINVAL; 388053ef1b34SMin Hu (Connor) } 388153ef1b34SMin Hu (Connor) 388299a2dd95SBruce Richardson /* 388399a2dd95SBruce Richardson * Init dev_info before port_id check since caller does not have 388499a2dd95SBruce Richardson * return status and does not know if get is successful or not. 388599a2dd95SBruce Richardson */ 388699a2dd95SBruce Richardson memset(dev_info, 0, sizeof(struct rte_eth_dev_info)); 388799a2dd95SBruce Richardson dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID; 388899a2dd95SBruce Richardson 388999a2dd95SBruce Richardson dev_info->rx_desc_lim = lim; 389099a2dd95SBruce Richardson dev_info->tx_desc_lim = lim; 389199a2dd95SBruce Richardson dev_info->device = dev->device; 3892990912e6SFerruh Yigit dev_info->min_mtu = RTE_ETHER_MIN_LEN - RTE_ETHER_HDR_LEN - 3893990912e6SFerruh Yigit RTE_ETHER_CRC_LEN; 389499a2dd95SBruce Richardson dev_info->max_mtu = UINT16_MAX; 389534ff088cSJie Hai dev_info->rss_algo_capa = RTE_ETH_HASH_ALGO_CAPA_MASK(DEFAULT); 389675c7849aSHuisong Li dev_info->max_rx_bufsize = UINT32_MAX; 389799a2dd95SBruce Richardson 38988f1d23ecSDavid Marchand if (*dev->dev_ops->dev_infos_get == NULL) 38998f1d23ecSDavid Marchand return -ENOTSUP; 390099a2dd95SBruce Richardson diag = (*dev->dev_ops->dev_infos_get)(dev, dev_info); 390199a2dd95SBruce Richardson if (diag != 0) { 390299a2dd95SBruce Richardson /* Cleanup already filled in device information */ 390399a2dd95SBruce Richardson memset(dev_info, 0, sizeof(struct rte_eth_dev_info)); 390499a2dd95SBruce Richardson return eth_err(port_id, diag); 390599a2dd95SBruce Richardson } 390699a2dd95SBruce Richardson 390799a2dd95SBruce Richardson /* Maximum number of queues should be <= RTE_MAX_QUEUES_PER_PORT */ 390899a2dd95SBruce Richardson dev_info->max_rx_queues = RTE_MIN(dev_info->max_rx_queues, 390999a2dd95SBruce Richardson RTE_MAX_QUEUES_PER_PORT); 391099a2dd95SBruce Richardson dev_info->max_tx_queues = RTE_MIN(dev_info->max_tx_queues, 391199a2dd95SBruce Richardson RTE_MAX_QUEUES_PER_PORT); 391299a2dd95SBruce Richardson 391399a2dd95SBruce Richardson dev_info->driver_name = dev->device->driver->name; 391499a2dd95SBruce Richardson dev_info->nb_rx_queues = dev->data->nb_rx_queues; 391599a2dd95SBruce Richardson dev_info->nb_tx_queues = dev->data->nb_tx_queues; 391699a2dd95SBruce Richardson 391799a2dd95SBruce Richardson dev_info->dev_flags = &dev->data->dev_flags; 391899a2dd95SBruce Richardson 39196679cf21SAnkur Dwivedi rte_ethdev_trace_info_get(port_id, dev_info); 39206679cf21SAnkur Dwivedi 392199a2dd95SBruce Richardson return 0; 392299a2dd95SBruce Richardson } 392399a2dd95SBruce Richardson 392499a2dd95SBruce Richardson int 3925632be327SJie Wang rte_eth_dev_conf_get(uint16_t port_id, struct rte_eth_conf *dev_conf) 3926632be327SJie Wang { 3927632be327SJie Wang struct rte_eth_dev *dev; 3928632be327SJie Wang 3929632be327SJie Wang RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3930632be327SJie Wang dev = &rte_eth_devices[port_id]; 3931632be327SJie Wang 3932632be327SJie Wang if (dev_conf == NULL) { 39330e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 39340e21c7c0SDavid Marchand "Cannot get ethdev port %u configuration to NULL", 3935632be327SJie Wang port_id); 3936632be327SJie Wang return -EINVAL; 3937632be327SJie Wang } 3938632be327SJie Wang 3939632be327SJie Wang memcpy(dev_conf, &dev->data->dev_conf, sizeof(struct rte_eth_conf)); 3940632be327SJie Wang 39416679cf21SAnkur Dwivedi rte_ethdev_trace_conf_get(port_id, dev_conf); 39426679cf21SAnkur Dwivedi 3943632be327SJie Wang return 0; 3944632be327SJie Wang } 3945632be327SJie Wang 3946632be327SJie Wang int 394799a2dd95SBruce Richardson rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask, 394899a2dd95SBruce Richardson uint32_t *ptypes, int num) 394999a2dd95SBruce Richardson { 3950ba6a168aSSivaramakrishnan Venkat size_t i; 3951ba6a168aSSivaramakrishnan Venkat int j; 395299a2dd95SBruce Richardson struct rte_eth_dev *dev; 395399a2dd95SBruce Richardson const uint32_t *all_ptypes; 3954ba6a168aSSivaramakrishnan Venkat size_t no_of_elements = 0; 395599a2dd95SBruce Richardson 395699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 395799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 395853ef1b34SMin Hu (Connor) 395953ef1b34SMin Hu (Connor) if (ptypes == NULL && num > 0) { 39600e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 39610e21c7c0SDavid Marchand "Cannot get ethdev port %u supported packet types to NULL when array size is non zero", 396253ef1b34SMin Hu (Connor) port_id); 396353ef1b34SMin Hu (Connor) return -EINVAL; 396453ef1b34SMin Hu (Connor) } 396553ef1b34SMin Hu (Connor) 39668f1d23ecSDavid Marchand if (*dev->dev_ops->dev_supported_ptypes_get == NULL) 39678f1d23ecSDavid Marchand return 0; 3968ba6a168aSSivaramakrishnan Venkat all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev, 3969ba6a168aSSivaramakrishnan Venkat &no_of_elements); 397099a2dd95SBruce Richardson 397199a2dd95SBruce Richardson if (!all_ptypes) 397299a2dd95SBruce Richardson return 0; 397399a2dd95SBruce Richardson 3974ba6a168aSSivaramakrishnan Venkat for (i = 0, j = 0; i < no_of_elements; ++i) 397599a2dd95SBruce Richardson if (all_ptypes[i] & ptype_mask) { 39766679cf21SAnkur Dwivedi if (j < num) { 397799a2dd95SBruce Richardson ptypes[j] = all_ptypes[i]; 39786679cf21SAnkur Dwivedi 39796679cf21SAnkur Dwivedi rte_ethdev_trace_get_supported_ptypes(port_id, 39806679cf21SAnkur Dwivedi j, num, ptypes[j]); 39816679cf21SAnkur Dwivedi } 398299a2dd95SBruce Richardson j++; 398399a2dd95SBruce Richardson } 398499a2dd95SBruce Richardson 398599a2dd95SBruce Richardson return j; 398699a2dd95SBruce Richardson } 398799a2dd95SBruce Richardson 398899a2dd95SBruce Richardson int 398999a2dd95SBruce Richardson rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask, 399099a2dd95SBruce Richardson uint32_t *set_ptypes, unsigned int num) 399199a2dd95SBruce Richardson { 399299a2dd95SBruce Richardson const uint32_t valid_ptype_masks[] = { 399399a2dd95SBruce Richardson RTE_PTYPE_L2_MASK, 399499a2dd95SBruce Richardson RTE_PTYPE_L3_MASK, 399599a2dd95SBruce Richardson RTE_PTYPE_L4_MASK, 399699a2dd95SBruce Richardson RTE_PTYPE_TUNNEL_MASK, 399799a2dd95SBruce Richardson RTE_PTYPE_INNER_L2_MASK, 399899a2dd95SBruce Richardson RTE_PTYPE_INNER_L3_MASK, 399999a2dd95SBruce Richardson RTE_PTYPE_INNER_L4_MASK, 400099a2dd95SBruce Richardson }; 400199a2dd95SBruce Richardson const uint32_t *all_ptypes; 400299a2dd95SBruce Richardson struct rte_eth_dev *dev; 400399a2dd95SBruce Richardson uint32_t unused_mask; 4004ba6a168aSSivaramakrishnan Venkat size_t i; 4005ba6a168aSSivaramakrishnan Venkat unsigned int j; 400699a2dd95SBruce Richardson int ret; 4007ba6a168aSSivaramakrishnan Venkat size_t no_of_elements = 0; 400899a2dd95SBruce Richardson 400999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 401099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 401199a2dd95SBruce Richardson 401253ef1b34SMin Hu (Connor) if (num > 0 && set_ptypes == NULL) { 40130e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 40140e21c7c0SDavid Marchand "Cannot get ethdev port %u set packet types to NULL when array size is non zero", 401553ef1b34SMin Hu (Connor) port_id); 401699a2dd95SBruce Richardson return -EINVAL; 401753ef1b34SMin Hu (Connor) } 401899a2dd95SBruce Richardson 401999a2dd95SBruce Richardson if (*dev->dev_ops->dev_supported_ptypes_get == NULL || 402099a2dd95SBruce Richardson *dev->dev_ops->dev_ptypes_set == NULL) { 402199a2dd95SBruce Richardson ret = 0; 402299a2dd95SBruce Richardson goto ptype_unknown; 402399a2dd95SBruce Richardson } 402499a2dd95SBruce Richardson 402599a2dd95SBruce Richardson if (ptype_mask == 0) { 402699a2dd95SBruce Richardson ret = (*dev->dev_ops->dev_ptypes_set)(dev, 402799a2dd95SBruce Richardson ptype_mask); 402899a2dd95SBruce Richardson goto ptype_unknown; 402999a2dd95SBruce Richardson } 403099a2dd95SBruce Richardson 403199a2dd95SBruce Richardson unused_mask = ptype_mask; 403299a2dd95SBruce Richardson for (i = 0; i < RTE_DIM(valid_ptype_masks); i++) { 403399a2dd95SBruce Richardson uint32_t mask = ptype_mask & valid_ptype_masks[i]; 403499a2dd95SBruce Richardson if (mask && mask != valid_ptype_masks[i]) { 403599a2dd95SBruce Richardson ret = -EINVAL; 403699a2dd95SBruce Richardson goto ptype_unknown; 403799a2dd95SBruce Richardson } 403899a2dd95SBruce Richardson unused_mask &= ~valid_ptype_masks[i]; 403999a2dd95SBruce Richardson } 404099a2dd95SBruce Richardson 404199a2dd95SBruce Richardson if (unused_mask) { 404299a2dd95SBruce Richardson ret = -EINVAL; 404399a2dd95SBruce Richardson goto ptype_unknown; 404499a2dd95SBruce Richardson } 404599a2dd95SBruce Richardson 4046ba6a168aSSivaramakrishnan Venkat all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev, 4047ba6a168aSSivaramakrishnan Venkat &no_of_elements); 404899a2dd95SBruce Richardson if (all_ptypes == NULL) { 404999a2dd95SBruce Richardson ret = 0; 405099a2dd95SBruce Richardson goto ptype_unknown; 405199a2dd95SBruce Richardson } 405299a2dd95SBruce Richardson 405399a2dd95SBruce Richardson /* 405499a2dd95SBruce Richardson * Accommodate as many set_ptypes as possible. If the supplied 405599a2dd95SBruce Richardson * set_ptypes array is insufficient fill it partially. 405699a2dd95SBruce Richardson */ 405799a2dd95SBruce Richardson for (i = 0, j = 0; set_ptypes != NULL && 4058ba6a168aSSivaramakrishnan Venkat (i < no_of_elements); ++i) { 405999a2dd95SBruce Richardson if (ptype_mask & all_ptypes[i]) { 406099a2dd95SBruce Richardson if (j < num - 1) { 406199a2dd95SBruce Richardson set_ptypes[j] = all_ptypes[i]; 40626679cf21SAnkur Dwivedi 40636679cf21SAnkur Dwivedi rte_ethdev_trace_set_ptypes(port_id, j, num, 40646679cf21SAnkur Dwivedi set_ptypes[j]); 40656679cf21SAnkur Dwivedi 406699a2dd95SBruce Richardson j++; 406799a2dd95SBruce Richardson continue; 406899a2dd95SBruce Richardson } 406999a2dd95SBruce Richardson break; 407099a2dd95SBruce Richardson } 407199a2dd95SBruce Richardson } 407299a2dd95SBruce Richardson 407399a2dd95SBruce Richardson if (set_ptypes != NULL && j < num) 407499a2dd95SBruce Richardson set_ptypes[j] = RTE_PTYPE_UNKNOWN; 407599a2dd95SBruce Richardson 407699a2dd95SBruce Richardson return (*dev->dev_ops->dev_ptypes_set)(dev, ptype_mask); 407799a2dd95SBruce Richardson 407899a2dd95SBruce Richardson ptype_unknown: 407999a2dd95SBruce Richardson if (num > 0) 408099a2dd95SBruce Richardson set_ptypes[0] = RTE_PTYPE_UNKNOWN; 408199a2dd95SBruce Richardson 408299a2dd95SBruce Richardson return ret; 408399a2dd95SBruce Richardson } 408499a2dd95SBruce Richardson 408599a2dd95SBruce Richardson int 408627a300e6SKonstantin Ananyev rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr *ma, 408727a300e6SKonstantin Ananyev unsigned int num) 408827a300e6SKonstantin Ananyev { 408927a300e6SKonstantin Ananyev int32_t ret; 409027a300e6SKonstantin Ananyev struct rte_eth_dev *dev; 409127a300e6SKonstantin Ananyev struct rte_eth_dev_info dev_info; 409227a300e6SKonstantin Ananyev 409327a300e6SKonstantin Ananyev if (ma == NULL) { 40940e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "%s: invalid parameters", __func__); 409527a300e6SKonstantin Ananyev return -EINVAL; 409627a300e6SKonstantin Ananyev } 409727a300e6SKonstantin Ananyev 409827a300e6SKonstantin Ananyev /* will check for us that port_id is a valid one */ 409927a300e6SKonstantin Ananyev ret = rte_eth_dev_info_get(port_id, &dev_info); 410027a300e6SKonstantin Ananyev if (ret != 0) 410127a300e6SKonstantin Ananyev return ret; 410227a300e6SKonstantin Ananyev 410327a300e6SKonstantin Ananyev dev = &rte_eth_devices[port_id]; 410427a300e6SKonstantin Ananyev num = RTE_MIN(dev_info.max_mac_addrs, num); 410527a300e6SKonstantin Ananyev memcpy(ma, dev->data->mac_addrs, num * sizeof(ma[0])); 410627a300e6SKonstantin Ananyev 41076679cf21SAnkur Dwivedi rte_eth_trace_macaddrs_get(port_id, num); 41086679cf21SAnkur Dwivedi 410927a300e6SKonstantin Ananyev return num; 411027a300e6SKonstantin Ananyev } 411127a300e6SKonstantin Ananyev 411227a300e6SKonstantin Ananyev int 411399a2dd95SBruce Richardson rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr) 411499a2dd95SBruce Richardson { 411599a2dd95SBruce Richardson struct rte_eth_dev *dev; 411699a2dd95SBruce Richardson 411799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 411899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 411953ef1b34SMin Hu (Connor) 412053ef1b34SMin Hu (Connor) if (mac_addr == NULL) { 41210e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 41220e21c7c0SDavid Marchand "Cannot get ethdev port %u MAC address to NULL", 412353ef1b34SMin Hu (Connor) port_id); 412453ef1b34SMin Hu (Connor) return -EINVAL; 412553ef1b34SMin Hu (Connor) } 412653ef1b34SMin Hu (Connor) 412799a2dd95SBruce Richardson rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr); 412899a2dd95SBruce Richardson 41296679cf21SAnkur Dwivedi rte_eth_trace_macaddr_get(port_id, mac_addr); 41306679cf21SAnkur Dwivedi 413199a2dd95SBruce Richardson return 0; 413299a2dd95SBruce Richardson } 413399a2dd95SBruce Richardson 413499a2dd95SBruce Richardson int 413599a2dd95SBruce Richardson rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu) 413699a2dd95SBruce Richardson { 413799a2dd95SBruce Richardson struct rte_eth_dev *dev; 413899a2dd95SBruce Richardson 413999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 414099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 414153ef1b34SMin Hu (Connor) 414253ef1b34SMin Hu (Connor) if (mtu == NULL) { 41430e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u MTU to NULL", 414453ef1b34SMin Hu (Connor) port_id); 414553ef1b34SMin Hu (Connor) return -EINVAL; 414653ef1b34SMin Hu (Connor) } 414753ef1b34SMin Hu (Connor) 414899a2dd95SBruce Richardson *mtu = dev->data->mtu; 41496679cf21SAnkur Dwivedi 41506679cf21SAnkur Dwivedi rte_ethdev_trace_get_mtu(port_id, *mtu); 41516679cf21SAnkur Dwivedi 415299a2dd95SBruce Richardson return 0; 415399a2dd95SBruce Richardson } 415499a2dd95SBruce Richardson 415599a2dd95SBruce Richardson int 415699a2dd95SBruce Richardson rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu) 415799a2dd95SBruce Richardson { 415899a2dd95SBruce Richardson int ret; 415999a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 416099a2dd95SBruce Richardson struct rte_eth_dev *dev; 416199a2dd95SBruce Richardson 416299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 416399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 41648f1d23ecSDavid Marchand if (*dev->dev_ops->mtu_set == NULL) 41658f1d23ecSDavid Marchand return -ENOTSUP; 416699a2dd95SBruce Richardson 416799a2dd95SBruce Richardson /* 416899a2dd95SBruce Richardson * Check if the device supports dev_infos_get, if it does not 416999a2dd95SBruce Richardson * skip min_mtu/max_mtu validation here as this requires values 417099a2dd95SBruce Richardson * that are populated within the call to rte_eth_dev_info_get() 417199a2dd95SBruce Richardson * which relies on dev->dev_ops->dev_infos_get. 417299a2dd95SBruce Richardson */ 417399a2dd95SBruce Richardson if (*dev->dev_ops->dev_infos_get != NULL) { 417499a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 417599a2dd95SBruce Richardson if (ret != 0) 417699a2dd95SBruce Richardson return ret; 417799a2dd95SBruce Richardson 4178990912e6SFerruh Yigit ret = eth_dev_validate_mtu(port_id, &dev_info, mtu); 4179990912e6SFerruh Yigit if (ret != 0) 4180990912e6SFerruh Yigit return ret; 418199a2dd95SBruce Richardson } 418299a2dd95SBruce Richardson 4183b26bee10SIvan Ilchenko if (dev->data->dev_configured == 0) { 41840e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 41850e21c7c0SDavid Marchand "Port %u must be configured before MTU set", 4186b26bee10SIvan Ilchenko port_id); 4187b26bee10SIvan Ilchenko return -EINVAL; 4188b26bee10SIvan Ilchenko } 4189b26bee10SIvan Ilchenko 419099a2dd95SBruce Richardson ret = (*dev->dev_ops->mtu_set)(dev, mtu); 4191b563c142SFerruh Yigit if (ret == 0) 419299a2dd95SBruce Richardson dev->data->mtu = mtu; 419399a2dd95SBruce Richardson 41946679cf21SAnkur Dwivedi ret = eth_err(port_id, ret); 41956679cf21SAnkur Dwivedi 41966679cf21SAnkur Dwivedi rte_ethdev_trace_set_mtu(port_id, mtu, ret); 41976679cf21SAnkur Dwivedi 41986679cf21SAnkur Dwivedi return ret; 419999a2dd95SBruce Richardson } 420099a2dd95SBruce Richardson 420199a2dd95SBruce Richardson int 420299a2dd95SBruce Richardson rte_eth_dev_vlan_filter(uint16_t port_id, uint16_t vlan_id, int on) 420399a2dd95SBruce Richardson { 420499a2dd95SBruce Richardson struct rte_eth_dev *dev; 420599a2dd95SBruce Richardson int ret; 420699a2dd95SBruce Richardson 420799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 420899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 420953ef1b34SMin Hu (Connor) 421099a2dd95SBruce Richardson if (!(dev->data->dev_conf.rxmode.offloads & 4211295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_VLAN_FILTER)) { 42120e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Port %u: VLAN-filtering disabled", 421399a2dd95SBruce Richardson port_id); 421499a2dd95SBruce Richardson return -ENOSYS; 421599a2dd95SBruce Richardson } 421699a2dd95SBruce Richardson 421799a2dd95SBruce Richardson if (vlan_id > 4095) { 42180e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Port_id=%u invalid vlan_id=%u > 4095", 421999a2dd95SBruce Richardson port_id, vlan_id); 422099a2dd95SBruce Richardson return -EINVAL; 422199a2dd95SBruce Richardson } 42228f1d23ecSDavid Marchand if (*dev->dev_ops->vlan_filter_set == NULL) 42238f1d23ecSDavid Marchand return -ENOTSUP; 422499a2dd95SBruce Richardson 422599a2dd95SBruce Richardson ret = (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); 422699a2dd95SBruce Richardson if (ret == 0) { 422799a2dd95SBruce Richardson struct rte_vlan_filter_conf *vfc; 422899a2dd95SBruce Richardson int vidx; 422999a2dd95SBruce Richardson int vbit; 423099a2dd95SBruce Richardson 423199a2dd95SBruce Richardson vfc = &dev->data->vlan_filter_conf; 423299a2dd95SBruce Richardson vidx = vlan_id / 64; 423399a2dd95SBruce Richardson vbit = vlan_id % 64; 423499a2dd95SBruce Richardson 423599a2dd95SBruce Richardson if (on) 4236e1823e08SThomas Monjalon vfc->ids[vidx] |= RTE_BIT64(vbit); 423799a2dd95SBruce Richardson else 4238e1823e08SThomas Monjalon vfc->ids[vidx] &= ~RTE_BIT64(vbit); 423999a2dd95SBruce Richardson } 424099a2dd95SBruce Richardson 42416679cf21SAnkur Dwivedi ret = eth_err(port_id, ret); 42426679cf21SAnkur Dwivedi 42436679cf21SAnkur Dwivedi rte_ethdev_trace_vlan_filter(port_id, vlan_id, on, ret); 42446679cf21SAnkur Dwivedi 42456679cf21SAnkur Dwivedi return ret; 424699a2dd95SBruce Richardson } 424799a2dd95SBruce Richardson 424899a2dd95SBruce Richardson int 424999a2dd95SBruce Richardson rte_eth_dev_set_vlan_strip_on_queue(uint16_t port_id, uint16_t rx_queue_id, 425099a2dd95SBruce Richardson int on) 425199a2dd95SBruce Richardson { 425299a2dd95SBruce Richardson struct rte_eth_dev *dev; 425399a2dd95SBruce Richardson 425499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 425599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 425653ef1b34SMin Hu (Connor) 425799a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 42580e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid rx_queue_id=%u", rx_queue_id); 425999a2dd95SBruce Richardson return -EINVAL; 426099a2dd95SBruce Richardson } 426199a2dd95SBruce Richardson 42628f1d23ecSDavid Marchand if (*dev->dev_ops->vlan_strip_queue_set == NULL) 42638f1d23ecSDavid Marchand return -ENOTSUP; 426499a2dd95SBruce Richardson (*dev->dev_ops->vlan_strip_queue_set)(dev, rx_queue_id, on); 426599a2dd95SBruce Richardson 42666679cf21SAnkur Dwivedi rte_ethdev_trace_set_vlan_strip_on_queue(port_id, rx_queue_id, on); 42676679cf21SAnkur Dwivedi 426899a2dd95SBruce Richardson return 0; 426999a2dd95SBruce Richardson } 427099a2dd95SBruce Richardson 427199a2dd95SBruce Richardson int 427299a2dd95SBruce Richardson rte_eth_dev_set_vlan_ether_type(uint16_t port_id, 427399a2dd95SBruce Richardson enum rte_vlan_type vlan_type, 427499a2dd95SBruce Richardson uint16_t tpid) 427599a2dd95SBruce Richardson { 427699a2dd95SBruce Richardson struct rte_eth_dev *dev; 42776679cf21SAnkur Dwivedi int ret; 427899a2dd95SBruce Richardson 427999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 428099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 428199a2dd95SBruce Richardson 42828f1d23ecSDavid Marchand if (*dev->dev_ops->vlan_tpid_set == NULL) 42838f1d23ecSDavid Marchand return -ENOTSUP; 42846679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->vlan_tpid_set)(dev, vlan_type, 428599a2dd95SBruce Richardson tpid)); 42866679cf21SAnkur Dwivedi 42876679cf21SAnkur Dwivedi rte_ethdev_trace_set_vlan_ether_type(port_id, vlan_type, tpid, ret); 42886679cf21SAnkur Dwivedi 42896679cf21SAnkur Dwivedi return ret; 429099a2dd95SBruce Richardson } 429199a2dd95SBruce Richardson 429299a2dd95SBruce Richardson int 429399a2dd95SBruce Richardson rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask) 429499a2dd95SBruce Richardson { 429599a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 429699a2dd95SBruce Richardson struct rte_eth_dev *dev; 429799a2dd95SBruce Richardson int ret = 0; 429899a2dd95SBruce Richardson int mask = 0; 429999a2dd95SBruce Richardson int cur, org = 0; 430099a2dd95SBruce Richardson uint64_t orig_offloads; 430199a2dd95SBruce Richardson uint64_t dev_offloads; 430299a2dd95SBruce Richardson uint64_t new_offloads; 430399a2dd95SBruce Richardson 430499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 430599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 430699a2dd95SBruce Richardson 430799a2dd95SBruce Richardson /* save original values in case of failure */ 430899a2dd95SBruce Richardson orig_offloads = dev->data->dev_conf.rxmode.offloads; 430999a2dd95SBruce Richardson dev_offloads = orig_offloads; 431099a2dd95SBruce Richardson 431199a2dd95SBruce Richardson /* check which option changed by application */ 4312295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_VLAN_STRIP_OFFLOAD); 4313295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP); 431499a2dd95SBruce Richardson if (cur != org) { 431599a2dd95SBruce Richardson if (cur) 4316295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP; 431799a2dd95SBruce Richardson else 4318295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP; 4319295968d1SFerruh Yigit mask |= RTE_ETH_VLAN_STRIP_MASK; 432099a2dd95SBruce Richardson } 432199a2dd95SBruce Richardson 4322295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_VLAN_FILTER_OFFLOAD); 4323295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER); 432499a2dd95SBruce Richardson if (cur != org) { 432599a2dd95SBruce Richardson if (cur) 4326295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER; 432799a2dd95SBruce Richardson else 4328295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_FILTER; 4329295968d1SFerruh Yigit mask |= RTE_ETH_VLAN_FILTER_MASK; 433099a2dd95SBruce Richardson } 433199a2dd95SBruce Richardson 4332295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_VLAN_EXTEND_OFFLOAD); 4333295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND); 433499a2dd95SBruce Richardson if (cur != org) { 433599a2dd95SBruce Richardson if (cur) 4336295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_EXTEND; 433799a2dd95SBruce Richardson else 4338295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_EXTEND; 4339295968d1SFerruh Yigit mask |= RTE_ETH_VLAN_EXTEND_MASK; 434099a2dd95SBruce Richardson } 434199a2dd95SBruce Richardson 4342295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_QINQ_STRIP_OFFLOAD); 4343295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP); 434499a2dd95SBruce Richardson if (cur != org) { 434599a2dd95SBruce Richardson if (cur) 4346295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP; 434799a2dd95SBruce Richardson else 4348295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_QINQ_STRIP; 4349295968d1SFerruh Yigit mask |= RTE_ETH_QINQ_STRIP_MASK; 435099a2dd95SBruce Richardson } 435199a2dd95SBruce Richardson 435299a2dd95SBruce Richardson /*no change*/ 435399a2dd95SBruce Richardson if (mask == 0) 435499a2dd95SBruce Richardson return ret; 435599a2dd95SBruce Richardson 435699a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 435799a2dd95SBruce Richardson if (ret != 0) 435899a2dd95SBruce Richardson return ret; 435999a2dd95SBruce Richardson 436099a2dd95SBruce Richardson /* Rx VLAN offloading must be within its device capabilities */ 436199a2dd95SBruce Richardson if ((dev_offloads & dev_info.rx_offload_capa) != dev_offloads) { 436299a2dd95SBruce Richardson new_offloads = dev_offloads & ~orig_offloads; 43630e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 436499a2dd95SBruce Richardson "Ethdev port_id=%u requested new added VLAN offloads " 436599a2dd95SBruce Richardson "0x%" PRIx64 " must be within Rx offloads capabilities " 43660e21c7c0SDavid Marchand "0x%" PRIx64 " in %s()", 436799a2dd95SBruce Richardson port_id, new_offloads, dev_info.rx_offload_capa, 436899a2dd95SBruce Richardson __func__); 436999a2dd95SBruce Richardson return -EINVAL; 437099a2dd95SBruce Richardson } 437199a2dd95SBruce Richardson 43728f1d23ecSDavid Marchand if (*dev->dev_ops->vlan_offload_set == NULL) 43738f1d23ecSDavid Marchand return -ENOTSUP; 437499a2dd95SBruce Richardson dev->data->dev_conf.rxmode.offloads = dev_offloads; 437599a2dd95SBruce Richardson ret = (*dev->dev_ops->vlan_offload_set)(dev, mask); 437699a2dd95SBruce Richardson if (ret) { 437799a2dd95SBruce Richardson /* hit an error restore original values */ 437899a2dd95SBruce Richardson dev->data->dev_conf.rxmode.offloads = orig_offloads; 437999a2dd95SBruce Richardson } 438099a2dd95SBruce Richardson 43816679cf21SAnkur Dwivedi ret = eth_err(port_id, ret); 43826679cf21SAnkur Dwivedi 43836679cf21SAnkur Dwivedi rte_ethdev_trace_set_vlan_offload(port_id, offload_mask, ret); 43846679cf21SAnkur Dwivedi 43856679cf21SAnkur Dwivedi return ret; 438699a2dd95SBruce Richardson } 438799a2dd95SBruce Richardson 438899a2dd95SBruce Richardson int 438999a2dd95SBruce Richardson rte_eth_dev_get_vlan_offload(uint16_t port_id) 439099a2dd95SBruce Richardson { 439199a2dd95SBruce Richardson struct rte_eth_dev *dev; 439299a2dd95SBruce Richardson uint64_t *dev_offloads; 439399a2dd95SBruce Richardson int ret = 0; 439499a2dd95SBruce Richardson 439599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 439699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 439799a2dd95SBruce Richardson dev_offloads = &dev->data->dev_conf.rxmode.offloads; 439899a2dd95SBruce Richardson 4399295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) 4400295968d1SFerruh Yigit ret |= RTE_ETH_VLAN_STRIP_OFFLOAD; 440199a2dd95SBruce Richardson 4402295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) 4403295968d1SFerruh Yigit ret |= RTE_ETH_VLAN_FILTER_OFFLOAD; 440499a2dd95SBruce Richardson 4405295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND) 4406295968d1SFerruh Yigit ret |= RTE_ETH_VLAN_EXTEND_OFFLOAD; 440799a2dd95SBruce Richardson 4408295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP) 4409295968d1SFerruh Yigit ret |= RTE_ETH_QINQ_STRIP_OFFLOAD; 441099a2dd95SBruce Richardson 44116679cf21SAnkur Dwivedi rte_ethdev_trace_get_vlan_offload(port_id, ret); 44126679cf21SAnkur Dwivedi 441399a2dd95SBruce Richardson return ret; 441499a2dd95SBruce Richardson } 441599a2dd95SBruce Richardson 441699a2dd95SBruce Richardson int 441799a2dd95SBruce Richardson rte_eth_dev_set_vlan_pvid(uint16_t port_id, uint16_t pvid, int on) 441899a2dd95SBruce Richardson { 441999a2dd95SBruce Richardson struct rte_eth_dev *dev; 44206679cf21SAnkur Dwivedi int ret; 442199a2dd95SBruce Richardson 442299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 442399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 442499a2dd95SBruce Richardson 44258f1d23ecSDavid Marchand if (*dev->dev_ops->vlan_pvid_set == NULL) 44268f1d23ecSDavid Marchand return -ENOTSUP; 44276679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->vlan_pvid_set)(dev, pvid, on)); 44286679cf21SAnkur Dwivedi 44296679cf21SAnkur Dwivedi rte_ethdev_trace_set_vlan_pvid(port_id, pvid, on, ret); 44306679cf21SAnkur Dwivedi 44316679cf21SAnkur Dwivedi return ret; 443299a2dd95SBruce Richardson } 443399a2dd95SBruce Richardson 443499a2dd95SBruce Richardson int 443599a2dd95SBruce Richardson rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf) 443699a2dd95SBruce Richardson { 443799a2dd95SBruce Richardson struct rte_eth_dev *dev; 44386679cf21SAnkur Dwivedi int ret; 443999a2dd95SBruce Richardson 444099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 444199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 444253ef1b34SMin Hu (Connor) 444353ef1b34SMin Hu (Connor) if (fc_conf == NULL) { 44440e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 44450e21c7c0SDavid Marchand "Cannot get ethdev port %u flow control config to NULL", 444653ef1b34SMin Hu (Connor) port_id); 444753ef1b34SMin Hu (Connor) return -EINVAL; 444853ef1b34SMin Hu (Connor) } 444953ef1b34SMin Hu (Connor) 44508f1d23ecSDavid Marchand if (*dev->dev_ops->flow_ctrl_get == NULL) 44518f1d23ecSDavid Marchand return -ENOTSUP; 445299a2dd95SBruce Richardson memset(fc_conf, 0, sizeof(*fc_conf)); 44536679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf)); 44546679cf21SAnkur Dwivedi 44556679cf21SAnkur Dwivedi rte_ethdev_trace_flow_ctrl_get(port_id, fc_conf, ret); 44566679cf21SAnkur Dwivedi 44576679cf21SAnkur Dwivedi return ret; 445899a2dd95SBruce Richardson } 445999a2dd95SBruce Richardson 446099a2dd95SBruce Richardson int 446199a2dd95SBruce Richardson rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf) 446299a2dd95SBruce Richardson { 446399a2dd95SBruce Richardson struct rte_eth_dev *dev; 44646679cf21SAnkur Dwivedi int ret; 446599a2dd95SBruce Richardson 446699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 446753ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 446853ef1b34SMin Hu (Connor) 446953ef1b34SMin Hu (Connor) if (fc_conf == NULL) { 44700e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 44710e21c7c0SDavid Marchand "Cannot set ethdev port %u flow control from NULL config", 447253ef1b34SMin Hu (Connor) port_id); 447353ef1b34SMin Hu (Connor) return -EINVAL; 447453ef1b34SMin Hu (Connor) } 447553ef1b34SMin Hu (Connor) 447699a2dd95SBruce Richardson if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) { 44770e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid send_xon, only 0/1 allowed"); 447899a2dd95SBruce Richardson return -EINVAL; 447999a2dd95SBruce Richardson } 448099a2dd95SBruce Richardson 44818f1d23ecSDavid Marchand if (*dev->dev_ops->flow_ctrl_set == NULL) 44828f1d23ecSDavid Marchand return -ENOTSUP; 44836679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf)); 44846679cf21SAnkur Dwivedi 44856679cf21SAnkur Dwivedi rte_ethdev_trace_flow_ctrl_set(port_id, fc_conf, ret); 44866679cf21SAnkur Dwivedi 44876679cf21SAnkur Dwivedi return ret; 448899a2dd95SBruce Richardson } 448999a2dd95SBruce Richardson 449099a2dd95SBruce Richardson int 449199a2dd95SBruce Richardson rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id, 449299a2dd95SBruce Richardson struct rte_eth_pfc_conf *pfc_conf) 449399a2dd95SBruce Richardson { 449499a2dd95SBruce Richardson struct rte_eth_dev *dev; 44956679cf21SAnkur Dwivedi int ret; 449699a2dd95SBruce Richardson 449799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 449853ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 449953ef1b34SMin Hu (Connor) 450053ef1b34SMin Hu (Connor) if (pfc_conf == NULL) { 45010e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 45020e21c7c0SDavid Marchand "Cannot set ethdev port %u priority flow control from NULL config", 450353ef1b34SMin Hu (Connor) port_id); 450453ef1b34SMin Hu (Connor) return -EINVAL; 450553ef1b34SMin Hu (Connor) } 450653ef1b34SMin Hu (Connor) 4507295968d1SFerruh Yigit if (pfc_conf->priority > (RTE_ETH_DCB_NUM_USER_PRIORITIES - 1)) { 45080e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid priority, only 0-7 allowed"); 450999a2dd95SBruce Richardson return -EINVAL; 451099a2dd95SBruce Richardson } 451199a2dd95SBruce Richardson 451299a2dd95SBruce Richardson /* High water, low water validation are device specific */ 45136679cf21SAnkur Dwivedi if (*dev->dev_ops->priority_flow_ctrl_set == NULL) 451499a2dd95SBruce Richardson return -ENOTSUP; 45156679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set) 45166679cf21SAnkur Dwivedi (dev, pfc_conf)); 45176679cf21SAnkur Dwivedi 45186679cf21SAnkur Dwivedi rte_ethdev_trace_priority_flow_ctrl_set(port_id, pfc_conf, ret); 45196679cf21SAnkur Dwivedi 45206679cf21SAnkur Dwivedi return ret; 452199a2dd95SBruce Richardson } 452299a2dd95SBruce Richardson 452399a2dd95SBruce Richardson static int 45240de345e9SJerin Jacob validate_rx_pause_config(struct rte_eth_dev_info *dev_info, uint8_t tc_max, 45250de345e9SJerin Jacob struct rte_eth_pfc_queue_conf *pfc_queue_conf) 45260de345e9SJerin Jacob { 45270de345e9SJerin Jacob if ((pfc_queue_conf->mode == RTE_ETH_FC_RX_PAUSE) || 45280de345e9SJerin Jacob (pfc_queue_conf->mode == RTE_ETH_FC_FULL)) { 45290de345e9SJerin Jacob if (pfc_queue_conf->rx_pause.tx_qid >= dev_info->nb_tx_queues) { 45300e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 45310e21c7c0SDavid Marchand "PFC Tx queue not in range for Rx pause requested:%d configured:%d", 45320de345e9SJerin Jacob pfc_queue_conf->rx_pause.tx_qid, 45330de345e9SJerin Jacob dev_info->nb_tx_queues); 45340de345e9SJerin Jacob return -EINVAL; 45350de345e9SJerin Jacob } 45360de345e9SJerin Jacob 45370de345e9SJerin Jacob if (pfc_queue_conf->rx_pause.tc >= tc_max) { 45380e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 45390e21c7c0SDavid Marchand "PFC TC not in range for Rx pause requested:%d max:%d", 45400de345e9SJerin Jacob pfc_queue_conf->rx_pause.tc, tc_max); 45410de345e9SJerin Jacob return -EINVAL; 45420de345e9SJerin Jacob } 45430de345e9SJerin Jacob } 45440de345e9SJerin Jacob 45450de345e9SJerin Jacob return 0; 45460de345e9SJerin Jacob } 45470de345e9SJerin Jacob 45480de345e9SJerin Jacob static int 45490de345e9SJerin Jacob validate_tx_pause_config(struct rte_eth_dev_info *dev_info, uint8_t tc_max, 45500de345e9SJerin Jacob struct rte_eth_pfc_queue_conf *pfc_queue_conf) 45510de345e9SJerin Jacob { 45520de345e9SJerin Jacob if ((pfc_queue_conf->mode == RTE_ETH_FC_TX_PAUSE) || 45530de345e9SJerin Jacob (pfc_queue_conf->mode == RTE_ETH_FC_FULL)) { 45540de345e9SJerin Jacob if (pfc_queue_conf->tx_pause.rx_qid >= dev_info->nb_rx_queues) { 45550e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 45560e21c7c0SDavid Marchand "PFC Rx queue not in range for Tx pause requested:%d configured:%d", 45570de345e9SJerin Jacob pfc_queue_conf->tx_pause.rx_qid, 45580de345e9SJerin Jacob dev_info->nb_rx_queues); 45590de345e9SJerin Jacob return -EINVAL; 45600de345e9SJerin Jacob } 45610de345e9SJerin Jacob 45620de345e9SJerin Jacob if (pfc_queue_conf->tx_pause.tc >= tc_max) { 45630e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 45640e21c7c0SDavid Marchand "PFC TC not in range for Tx pause requested:%d max:%d", 45650de345e9SJerin Jacob pfc_queue_conf->tx_pause.tc, tc_max); 45660de345e9SJerin Jacob return -EINVAL; 45670de345e9SJerin Jacob } 45680de345e9SJerin Jacob } 45690de345e9SJerin Jacob 45700de345e9SJerin Jacob return 0; 45710de345e9SJerin Jacob } 45720de345e9SJerin Jacob 45730de345e9SJerin Jacob int 45740de345e9SJerin Jacob rte_eth_dev_priority_flow_ctrl_queue_info_get(uint16_t port_id, 45750de345e9SJerin Jacob struct rte_eth_pfc_queue_info *pfc_queue_info) 45760de345e9SJerin Jacob { 45770de345e9SJerin Jacob struct rte_eth_dev *dev; 45786679cf21SAnkur Dwivedi int ret; 45790de345e9SJerin Jacob 45800de345e9SJerin Jacob RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 45810de345e9SJerin Jacob dev = &rte_eth_devices[port_id]; 45820de345e9SJerin Jacob 45830de345e9SJerin Jacob if (pfc_queue_info == NULL) { 45840e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "PFC info param is NULL for port (%u)", 45850de345e9SJerin Jacob port_id); 45860de345e9SJerin Jacob return -EINVAL; 45870de345e9SJerin Jacob } 45880de345e9SJerin Jacob 45896679cf21SAnkur Dwivedi if (*dev->dev_ops->priority_flow_ctrl_queue_info_get == NULL) 45900de345e9SJerin Jacob return -ENOTSUP; 45916679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_queue_info_get) 45926679cf21SAnkur Dwivedi (dev, pfc_queue_info)); 45936679cf21SAnkur Dwivedi 45946679cf21SAnkur Dwivedi rte_ethdev_trace_priority_flow_ctrl_queue_info_get(port_id, 45956679cf21SAnkur Dwivedi pfc_queue_info, ret); 45966679cf21SAnkur Dwivedi 45976679cf21SAnkur Dwivedi return ret; 45980de345e9SJerin Jacob } 45990de345e9SJerin Jacob 46000de345e9SJerin Jacob int 46010de345e9SJerin Jacob rte_eth_dev_priority_flow_ctrl_queue_configure(uint16_t port_id, 46020de345e9SJerin Jacob struct rte_eth_pfc_queue_conf *pfc_queue_conf) 46030de345e9SJerin Jacob { 46040de345e9SJerin Jacob struct rte_eth_pfc_queue_info pfc_info; 46050de345e9SJerin Jacob struct rte_eth_dev_info dev_info; 46060de345e9SJerin Jacob struct rte_eth_dev *dev; 46070de345e9SJerin Jacob int ret; 46080de345e9SJerin Jacob 46090de345e9SJerin Jacob RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 46100de345e9SJerin Jacob dev = &rte_eth_devices[port_id]; 46110de345e9SJerin Jacob 46120de345e9SJerin Jacob if (pfc_queue_conf == NULL) { 46130e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "PFC parameters are NULL for port (%u)", 46140de345e9SJerin Jacob port_id); 46150de345e9SJerin Jacob return -EINVAL; 46160de345e9SJerin Jacob } 46170de345e9SJerin Jacob 46180de345e9SJerin Jacob ret = rte_eth_dev_info_get(port_id, &dev_info); 46190de345e9SJerin Jacob if (ret != 0) 46200de345e9SJerin Jacob return ret; 46210de345e9SJerin Jacob 46220de345e9SJerin Jacob ret = rte_eth_dev_priority_flow_ctrl_queue_info_get(port_id, &pfc_info); 46230de345e9SJerin Jacob if (ret != 0) 46240de345e9SJerin Jacob return ret; 46250de345e9SJerin Jacob 46260de345e9SJerin Jacob if (pfc_info.tc_max == 0) { 46270e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port %u does not support PFC TC values", 46280de345e9SJerin Jacob port_id); 46290de345e9SJerin Jacob return -ENOTSUP; 46300de345e9SJerin Jacob } 46310de345e9SJerin Jacob 46320de345e9SJerin Jacob /* Check requested mode supported or not */ 46330de345e9SJerin Jacob if (pfc_info.mode_capa == RTE_ETH_FC_RX_PAUSE && 46340de345e9SJerin Jacob pfc_queue_conf->mode == RTE_ETH_FC_TX_PAUSE) { 46350e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "PFC Tx pause unsupported for port (%d)", 46360de345e9SJerin Jacob port_id); 46370de345e9SJerin Jacob return -EINVAL; 46380de345e9SJerin Jacob } 46390de345e9SJerin Jacob 46400de345e9SJerin Jacob if (pfc_info.mode_capa == RTE_ETH_FC_TX_PAUSE && 46410de345e9SJerin Jacob pfc_queue_conf->mode == RTE_ETH_FC_RX_PAUSE) { 46420e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "PFC Rx pause unsupported for port (%d)", 46430de345e9SJerin Jacob port_id); 46440de345e9SJerin Jacob return -EINVAL; 46450de345e9SJerin Jacob } 46460de345e9SJerin Jacob 46470de345e9SJerin Jacob /* Validate Rx pause parameters */ 46480de345e9SJerin Jacob if (pfc_info.mode_capa == RTE_ETH_FC_FULL || 46490de345e9SJerin Jacob pfc_info.mode_capa == RTE_ETH_FC_RX_PAUSE) { 46500de345e9SJerin Jacob ret = validate_rx_pause_config(&dev_info, pfc_info.tc_max, 46510de345e9SJerin Jacob pfc_queue_conf); 46520de345e9SJerin Jacob if (ret != 0) 46530de345e9SJerin Jacob return ret; 46540de345e9SJerin Jacob } 46550de345e9SJerin Jacob 46560de345e9SJerin Jacob /* Validate Tx pause parameters */ 46570de345e9SJerin Jacob if (pfc_info.mode_capa == RTE_ETH_FC_FULL || 46580de345e9SJerin Jacob pfc_info.mode_capa == RTE_ETH_FC_TX_PAUSE) { 46590de345e9SJerin Jacob ret = validate_tx_pause_config(&dev_info, pfc_info.tc_max, 46600de345e9SJerin Jacob pfc_queue_conf); 46610de345e9SJerin Jacob if (ret != 0) 46620de345e9SJerin Jacob return ret; 46630de345e9SJerin Jacob } 46640de345e9SJerin Jacob 46656679cf21SAnkur Dwivedi if (*dev->dev_ops->priority_flow_ctrl_queue_config == NULL) 46660de345e9SJerin Jacob return -ENOTSUP; 46676679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_queue_config) 46686679cf21SAnkur Dwivedi (dev, pfc_queue_conf)); 46696679cf21SAnkur Dwivedi 46706679cf21SAnkur Dwivedi rte_ethdev_trace_priority_flow_ctrl_queue_configure(port_id, 46716679cf21SAnkur Dwivedi pfc_queue_conf, ret); 46726679cf21SAnkur Dwivedi 46736679cf21SAnkur Dwivedi return ret; 46740de345e9SJerin Jacob } 46750de345e9SJerin Jacob 46760de345e9SJerin Jacob static int 467799a2dd95SBruce Richardson eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf, 467899a2dd95SBruce Richardson uint16_t reta_size) 467999a2dd95SBruce Richardson { 468099a2dd95SBruce Richardson uint16_t i, num; 468199a2dd95SBruce Richardson 4682295968d1SFerruh Yigit num = (reta_size + RTE_ETH_RETA_GROUP_SIZE - 1) / RTE_ETH_RETA_GROUP_SIZE; 468399a2dd95SBruce Richardson for (i = 0; i < num; i++) { 468499a2dd95SBruce Richardson if (reta_conf[i].mask) 468599a2dd95SBruce Richardson return 0; 468699a2dd95SBruce Richardson } 468799a2dd95SBruce Richardson 468899a2dd95SBruce Richardson return -EINVAL; 468999a2dd95SBruce Richardson } 469099a2dd95SBruce Richardson 469199a2dd95SBruce Richardson static int 469299a2dd95SBruce Richardson eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf, 469399a2dd95SBruce Richardson uint16_t reta_size, 469499a2dd95SBruce Richardson uint16_t max_rxq) 469599a2dd95SBruce Richardson { 469699a2dd95SBruce Richardson uint16_t i, idx, shift; 469799a2dd95SBruce Richardson 469899a2dd95SBruce Richardson if (max_rxq == 0) { 46990e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "No receive queue is available"); 470099a2dd95SBruce Richardson return -EINVAL; 470199a2dd95SBruce Richardson } 470299a2dd95SBruce Richardson 470399a2dd95SBruce Richardson for (i = 0; i < reta_size; i++) { 4704295968d1SFerruh Yigit idx = i / RTE_ETH_RETA_GROUP_SIZE; 4705295968d1SFerruh Yigit shift = i % RTE_ETH_RETA_GROUP_SIZE; 4706e1823e08SThomas Monjalon if ((reta_conf[idx].mask & RTE_BIT64(shift)) && 470799a2dd95SBruce Richardson (reta_conf[idx].reta[shift] >= max_rxq)) { 47080e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 47090e21c7c0SDavid Marchand "reta_conf[%u]->reta[%u]: %u exceeds the maximum rxq index: %u", 471099a2dd95SBruce Richardson idx, shift, 471199a2dd95SBruce Richardson reta_conf[idx].reta[shift], max_rxq); 471299a2dd95SBruce Richardson return -EINVAL; 471399a2dd95SBruce Richardson } 471499a2dd95SBruce Richardson } 471599a2dd95SBruce Richardson 471699a2dd95SBruce Richardson return 0; 471799a2dd95SBruce Richardson } 471899a2dd95SBruce Richardson 471999a2dd95SBruce Richardson int 472099a2dd95SBruce Richardson rte_eth_dev_rss_reta_update(uint16_t port_id, 472199a2dd95SBruce Richardson struct rte_eth_rss_reta_entry64 *reta_conf, 472299a2dd95SBruce Richardson uint16_t reta_size) 472399a2dd95SBruce Richardson { 472493e1ea6dSHuisong Li enum rte_eth_rx_mq_mode mq_mode; 472599a2dd95SBruce Richardson struct rte_eth_dev *dev; 472699a2dd95SBruce Richardson int ret; 472799a2dd95SBruce Richardson 472899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 472953ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 473053ef1b34SMin Hu (Connor) 473153ef1b34SMin Hu (Connor) if (reta_conf == NULL) { 47320e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 47330e21c7c0SDavid Marchand "Cannot update ethdev port %u RSS RETA to NULL", 473453ef1b34SMin Hu (Connor) port_id); 473553ef1b34SMin Hu (Connor) return -EINVAL; 473653ef1b34SMin Hu (Connor) } 473753ef1b34SMin Hu (Connor) 473853ef1b34SMin Hu (Connor) if (reta_size == 0) { 47390e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 47400e21c7c0SDavid Marchand "Cannot update ethdev port %u RSS RETA with zero size", 474153ef1b34SMin Hu (Connor) port_id); 474253ef1b34SMin Hu (Connor) return -EINVAL; 474353ef1b34SMin Hu (Connor) } 474453ef1b34SMin Hu (Connor) 474599a2dd95SBruce Richardson /* Check mask bits */ 474699a2dd95SBruce Richardson ret = eth_check_reta_mask(reta_conf, reta_size); 474799a2dd95SBruce Richardson if (ret < 0) 474899a2dd95SBruce Richardson return ret; 474999a2dd95SBruce Richardson 475099a2dd95SBruce Richardson /* Check entry value */ 475199a2dd95SBruce Richardson ret = eth_check_reta_entry(reta_conf, reta_size, 475299a2dd95SBruce Richardson dev->data->nb_rx_queues); 475399a2dd95SBruce Richardson if (ret < 0) 475499a2dd95SBruce Richardson return ret; 475599a2dd95SBruce Richardson 475693e1ea6dSHuisong Li mq_mode = dev->data->dev_conf.rxmode.mq_mode; 475793e1ea6dSHuisong Li if (!(mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)) { 47580e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Multi-queue RSS mode isn't enabled."); 475993e1ea6dSHuisong Li return -ENOTSUP; 476093e1ea6dSHuisong Li } 476193e1ea6dSHuisong Li 47628f1d23ecSDavid Marchand if (*dev->dev_ops->reta_update == NULL) 47638f1d23ecSDavid Marchand return -ENOTSUP; 47646679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->reta_update)(dev, reta_conf, 476599a2dd95SBruce Richardson reta_size)); 47666679cf21SAnkur Dwivedi 47676679cf21SAnkur Dwivedi rte_ethdev_trace_rss_reta_update(port_id, reta_conf, reta_size, ret); 47686679cf21SAnkur Dwivedi 47696679cf21SAnkur Dwivedi return ret; 477099a2dd95SBruce Richardson } 477199a2dd95SBruce Richardson 477299a2dd95SBruce Richardson int 477399a2dd95SBruce Richardson rte_eth_dev_rss_reta_query(uint16_t port_id, 477499a2dd95SBruce Richardson struct rte_eth_rss_reta_entry64 *reta_conf, 477599a2dd95SBruce Richardson uint16_t reta_size) 477699a2dd95SBruce Richardson { 477799a2dd95SBruce Richardson struct rte_eth_dev *dev; 477899a2dd95SBruce Richardson int ret; 477999a2dd95SBruce Richardson 478099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 478153ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 478253ef1b34SMin Hu (Connor) 478353ef1b34SMin Hu (Connor) if (reta_conf == NULL) { 47840e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 47850e21c7c0SDavid Marchand "Cannot query ethdev port %u RSS RETA from NULL config", 478653ef1b34SMin Hu (Connor) port_id); 478753ef1b34SMin Hu (Connor) return -EINVAL; 478853ef1b34SMin Hu (Connor) } 478999a2dd95SBruce Richardson 479099a2dd95SBruce Richardson /* Check mask bits */ 479199a2dd95SBruce Richardson ret = eth_check_reta_mask(reta_conf, reta_size); 479299a2dd95SBruce Richardson if (ret < 0) 479399a2dd95SBruce Richardson return ret; 479499a2dd95SBruce Richardson 47958f1d23ecSDavid Marchand if (*dev->dev_ops->reta_query == NULL) 47968f1d23ecSDavid Marchand return -ENOTSUP; 47976679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf, 479899a2dd95SBruce Richardson reta_size)); 47996679cf21SAnkur Dwivedi 48006679cf21SAnkur Dwivedi rte_ethdev_trace_rss_reta_query(port_id, reta_conf, reta_size, ret); 48016679cf21SAnkur Dwivedi 48026679cf21SAnkur Dwivedi return ret; 480399a2dd95SBruce Richardson } 480499a2dd95SBruce Richardson 480599a2dd95SBruce Richardson int 480699a2dd95SBruce Richardson rte_eth_dev_rss_hash_update(uint16_t port_id, 480799a2dd95SBruce Richardson struct rte_eth_rss_conf *rss_conf) 480899a2dd95SBruce Richardson { 480999a2dd95SBruce Richardson struct rte_eth_dev *dev; 481099a2dd95SBruce Richardson struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, }; 481193e1ea6dSHuisong Li enum rte_eth_rx_mq_mode mq_mode; 481299a2dd95SBruce Richardson int ret; 481399a2dd95SBruce Richardson 481499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 481553ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 481653ef1b34SMin Hu (Connor) 481753ef1b34SMin Hu (Connor) if (rss_conf == NULL) { 48180e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 48190e21c7c0SDavid Marchand "Cannot update ethdev port %u RSS hash from NULL config", 482053ef1b34SMin Hu (Connor) port_id); 482153ef1b34SMin Hu (Connor) return -EINVAL; 482253ef1b34SMin Hu (Connor) } 482399a2dd95SBruce Richardson 482499a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 482599a2dd95SBruce Richardson if (ret != 0) 482699a2dd95SBruce Richardson return ret; 482799a2dd95SBruce Richardson 482899a2dd95SBruce Richardson rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf); 482999a2dd95SBruce Richardson if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) != 483099a2dd95SBruce Richardson dev_info.flow_type_rss_offloads) { 48310e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 48320e21c7c0SDavid Marchand "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64, 483399a2dd95SBruce Richardson port_id, rss_conf->rss_hf, 483499a2dd95SBruce Richardson dev_info.flow_type_rss_offloads); 483599a2dd95SBruce Richardson return -EINVAL; 483699a2dd95SBruce Richardson } 483793e1ea6dSHuisong Li 483893e1ea6dSHuisong Li mq_mode = dev->data->dev_conf.rxmode.mq_mode; 483993e1ea6dSHuisong Li if (!(mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)) { 48400e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Multi-queue RSS mode isn't enabled."); 484193e1ea6dSHuisong Li return -ENOTSUP; 484293e1ea6dSHuisong Li } 484393e1ea6dSHuisong Li 4844bae3cfa5SJie Hai if (rss_conf->rss_key != NULL && 4845bae3cfa5SJie Hai rss_conf->rss_key_len != dev_info.hash_key_size) { 48460e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 48470e21c7c0SDavid Marchand "Ethdev port_id=%u invalid RSS key len: %u, valid value: %u", 4848bae3cfa5SJie Hai port_id, rss_conf->rss_key_len, dev_info.hash_key_size); 4849bae3cfa5SJie Hai return -EINVAL; 4850bae3cfa5SJie Hai } 4851bae3cfa5SJie Hai 485234ff088cSJie Hai if ((size_t)rss_conf->algorithm >= CHAR_BIT * sizeof(dev_info.rss_algo_capa) || 485334ff088cSJie Hai (dev_info.rss_algo_capa & 485434ff088cSJie Hai RTE_ETH_HASH_ALGO_TO_CAPA(rss_conf->algorithm)) == 0) { 48550e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 485634ff088cSJie Hai "Ethdev port_id=%u configured RSS hash algorithm (%u)" 48570e21c7c0SDavid Marchand "is not in the algorithm capability (0x%" PRIx32 ")", 485834ff088cSJie Hai port_id, rss_conf->algorithm, dev_info.rss_algo_capa); 485934ff088cSJie Hai return -EINVAL; 486034ff088cSJie Hai } 486134ff088cSJie Hai 48628f1d23ecSDavid Marchand if (*dev->dev_ops->rss_hash_update == NULL) 48638f1d23ecSDavid Marchand return -ENOTSUP; 48646679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->rss_hash_update)(dev, 486599a2dd95SBruce Richardson rss_conf)); 48666679cf21SAnkur Dwivedi 48676679cf21SAnkur Dwivedi rte_ethdev_trace_rss_hash_update(port_id, rss_conf, ret); 48686679cf21SAnkur Dwivedi 48696679cf21SAnkur Dwivedi return ret; 487099a2dd95SBruce Richardson } 487199a2dd95SBruce Richardson 487299a2dd95SBruce Richardson int 487399a2dd95SBruce Richardson rte_eth_dev_rss_hash_conf_get(uint16_t port_id, 487499a2dd95SBruce Richardson struct rte_eth_rss_conf *rss_conf) 487599a2dd95SBruce Richardson { 4876bae3cfa5SJie Hai struct rte_eth_dev_info dev_info = { 0 }; 487799a2dd95SBruce Richardson struct rte_eth_dev *dev; 48786679cf21SAnkur Dwivedi int ret; 487999a2dd95SBruce Richardson 488099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 488199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 488253ef1b34SMin Hu (Connor) 488353ef1b34SMin Hu (Connor) if (rss_conf == NULL) { 48840e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 48850e21c7c0SDavid Marchand "Cannot get ethdev port %u RSS hash config to NULL", 488653ef1b34SMin Hu (Connor) port_id); 488753ef1b34SMin Hu (Connor) return -EINVAL; 488853ef1b34SMin Hu (Connor) } 488953ef1b34SMin Hu (Connor) 4890bae3cfa5SJie Hai ret = rte_eth_dev_info_get(port_id, &dev_info); 4891bae3cfa5SJie Hai if (ret != 0) 4892bae3cfa5SJie Hai return ret; 4893bae3cfa5SJie Hai 4894bae3cfa5SJie Hai if (rss_conf->rss_key != NULL && 4895bae3cfa5SJie Hai rss_conf->rss_key_len < dev_info.hash_key_size) { 48960e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 48970e21c7c0SDavid Marchand "Ethdev port_id=%u invalid RSS key len: %u, should not be less than: %u", 4898bae3cfa5SJie Hai port_id, rss_conf->rss_key_len, dev_info.hash_key_size); 4899bae3cfa5SJie Hai return -EINVAL; 4900bae3cfa5SJie Hai } 4901bae3cfa5SJie Hai 490234ff088cSJie Hai rss_conf->algorithm = RTE_ETH_HASH_FUNCTION_DEFAULT; 490334ff088cSJie Hai 49048f1d23ecSDavid Marchand if (*dev->dev_ops->rss_hash_conf_get == NULL) 49058f1d23ecSDavid Marchand return -ENOTSUP; 49066679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev, 490799a2dd95SBruce Richardson rss_conf)); 49086679cf21SAnkur Dwivedi 49096679cf21SAnkur Dwivedi rte_ethdev_trace_rss_hash_conf_get(port_id, rss_conf, ret); 49106679cf21SAnkur Dwivedi 49116679cf21SAnkur Dwivedi return ret; 491299a2dd95SBruce Richardson } 491399a2dd95SBruce Richardson 491492628e2bSJie Hai const char * 491592628e2bSJie Hai rte_eth_dev_rss_algo_name(enum rte_eth_hash_function rss_algo) 491692628e2bSJie Hai { 491792628e2bSJie Hai const char *name = "Unknown function"; 491892628e2bSJie Hai unsigned int i; 491992628e2bSJie Hai 492092628e2bSJie Hai for (i = 0; i < RTE_DIM(rte_eth_dev_rss_algo_names); i++) { 492192628e2bSJie Hai if (rss_algo == rte_eth_dev_rss_algo_names[i].algo) 492292628e2bSJie Hai return rte_eth_dev_rss_algo_names[i].name; 492392628e2bSJie Hai } 492492628e2bSJie Hai 492592628e2bSJie Hai return name; 492692628e2bSJie Hai } 492792628e2bSJie Hai 492899a2dd95SBruce Richardson int 4929c9884dfbSJie Hai rte_eth_find_rss_algo(const char *name, uint32_t *algo) 4930c9884dfbSJie Hai { 4931c9884dfbSJie Hai unsigned int i; 4932c9884dfbSJie Hai 4933c9884dfbSJie Hai for (i = 0; i < RTE_DIM(rte_eth_dev_rss_algo_names); i++) { 4934c9884dfbSJie Hai if (strcmp(name, rte_eth_dev_rss_algo_names[i].name) == 0) { 4935c9884dfbSJie Hai *algo = rte_eth_dev_rss_algo_names[i].algo; 4936c9884dfbSJie Hai return 0; 4937c9884dfbSJie Hai } 4938c9884dfbSJie Hai } 4939c9884dfbSJie Hai 4940c9884dfbSJie Hai return -EINVAL; 4941c9884dfbSJie Hai } 4942c9884dfbSJie Hai 4943c9884dfbSJie Hai int 494499a2dd95SBruce Richardson rte_eth_dev_udp_tunnel_port_add(uint16_t port_id, 494599a2dd95SBruce Richardson struct rte_eth_udp_tunnel *udp_tunnel) 494699a2dd95SBruce Richardson { 494799a2dd95SBruce Richardson struct rte_eth_dev *dev; 49486679cf21SAnkur Dwivedi int ret; 494999a2dd95SBruce Richardson 495099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 495153ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 495253ef1b34SMin Hu (Connor) 495399a2dd95SBruce Richardson if (udp_tunnel == NULL) { 49540e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 49550e21c7c0SDavid Marchand "Cannot add ethdev port %u UDP tunnel port from NULL UDP tunnel", 495653ef1b34SMin Hu (Connor) port_id); 495799a2dd95SBruce Richardson return -EINVAL; 495899a2dd95SBruce Richardson } 495999a2dd95SBruce Richardson 4960295968d1SFerruh Yigit if (udp_tunnel->prot_type >= RTE_ETH_TUNNEL_TYPE_MAX) { 49610e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid tunnel type"); 496299a2dd95SBruce Richardson return -EINVAL; 496399a2dd95SBruce Richardson } 496499a2dd95SBruce Richardson 49658f1d23ecSDavid Marchand if (*dev->dev_ops->udp_tunnel_port_add == NULL) 49668f1d23ecSDavid Marchand return -ENOTSUP; 49676679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_add)(dev, 496899a2dd95SBruce Richardson udp_tunnel)); 49696679cf21SAnkur Dwivedi 49706679cf21SAnkur Dwivedi rte_ethdev_trace_udp_tunnel_port_add(port_id, udp_tunnel, ret); 49716679cf21SAnkur Dwivedi 49726679cf21SAnkur Dwivedi return ret; 497399a2dd95SBruce Richardson } 497499a2dd95SBruce Richardson 497599a2dd95SBruce Richardson int 497699a2dd95SBruce Richardson rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id, 497799a2dd95SBruce Richardson struct rte_eth_udp_tunnel *udp_tunnel) 497899a2dd95SBruce Richardson { 497999a2dd95SBruce Richardson struct rte_eth_dev *dev; 49806679cf21SAnkur Dwivedi int ret; 498199a2dd95SBruce Richardson 498299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 498399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 498499a2dd95SBruce Richardson 498599a2dd95SBruce Richardson if (udp_tunnel == NULL) { 49860e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 49870e21c7c0SDavid Marchand "Cannot delete ethdev port %u UDP tunnel port from NULL UDP tunnel", 498853ef1b34SMin Hu (Connor) port_id); 498999a2dd95SBruce Richardson return -EINVAL; 499099a2dd95SBruce Richardson } 499199a2dd95SBruce Richardson 4992295968d1SFerruh Yigit if (udp_tunnel->prot_type >= RTE_ETH_TUNNEL_TYPE_MAX) { 49930e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid tunnel type"); 499499a2dd95SBruce Richardson return -EINVAL; 499599a2dd95SBruce Richardson } 499699a2dd95SBruce Richardson 49978f1d23ecSDavid Marchand if (*dev->dev_ops->udp_tunnel_port_del == NULL) 49988f1d23ecSDavid Marchand return -ENOTSUP; 49996679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_del)(dev, 500099a2dd95SBruce Richardson udp_tunnel)); 50016679cf21SAnkur Dwivedi 50026679cf21SAnkur Dwivedi rte_ethdev_trace_udp_tunnel_port_delete(port_id, udp_tunnel, ret); 50036679cf21SAnkur Dwivedi 50046679cf21SAnkur Dwivedi return ret; 500599a2dd95SBruce Richardson } 500699a2dd95SBruce Richardson 500799a2dd95SBruce Richardson int 500899a2dd95SBruce Richardson rte_eth_led_on(uint16_t port_id) 500999a2dd95SBruce Richardson { 501099a2dd95SBruce Richardson struct rte_eth_dev *dev; 50116679cf21SAnkur Dwivedi int ret; 501299a2dd95SBruce Richardson 501399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 501499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 501553ef1b34SMin Hu (Connor) 50168f1d23ecSDavid Marchand if (*dev->dev_ops->dev_led_on == NULL) 50178f1d23ecSDavid Marchand return -ENOTSUP; 50186679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->dev_led_on)(dev)); 50196679cf21SAnkur Dwivedi 50206679cf21SAnkur Dwivedi rte_eth_trace_led_on(port_id, ret); 50216679cf21SAnkur Dwivedi 50226679cf21SAnkur Dwivedi return ret; 502399a2dd95SBruce Richardson } 502499a2dd95SBruce Richardson 502599a2dd95SBruce Richardson int 502699a2dd95SBruce Richardson rte_eth_led_off(uint16_t port_id) 502799a2dd95SBruce Richardson { 502899a2dd95SBruce Richardson struct rte_eth_dev *dev; 50296679cf21SAnkur Dwivedi int ret; 503099a2dd95SBruce Richardson 503199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 503299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 503353ef1b34SMin Hu (Connor) 50348f1d23ecSDavid Marchand if (*dev->dev_ops->dev_led_off == NULL) 50358f1d23ecSDavid Marchand return -ENOTSUP; 50366679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->dev_led_off)(dev)); 50376679cf21SAnkur Dwivedi 50386679cf21SAnkur Dwivedi rte_eth_trace_led_off(port_id, ret); 50396679cf21SAnkur Dwivedi 50406679cf21SAnkur Dwivedi return ret; 504199a2dd95SBruce Richardson } 504299a2dd95SBruce Richardson 504399a2dd95SBruce Richardson int 504499a2dd95SBruce Richardson rte_eth_fec_get_capability(uint16_t port_id, 504599a2dd95SBruce Richardson struct rte_eth_fec_capa *speed_fec_capa, 504699a2dd95SBruce Richardson unsigned int num) 504799a2dd95SBruce Richardson { 504899a2dd95SBruce Richardson struct rte_eth_dev *dev; 504999a2dd95SBruce Richardson int ret; 505099a2dd95SBruce Richardson 505199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 505299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 505353ef1b34SMin Hu (Connor) 505453ef1b34SMin Hu (Connor) if (speed_fec_capa == NULL && num > 0) { 50550e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 50560e21c7c0SDavid Marchand "Cannot get ethdev port %u FEC capability to NULL when array size is non zero", 505753ef1b34SMin Hu (Connor) port_id); 505853ef1b34SMin Hu (Connor) return -EINVAL; 505953ef1b34SMin Hu (Connor) } 506053ef1b34SMin Hu (Connor) 50618f1d23ecSDavid Marchand if (*dev->dev_ops->fec_get_capability == NULL) 50628f1d23ecSDavid Marchand return -ENOTSUP; 506399a2dd95SBruce Richardson ret = (*dev->dev_ops->fec_get_capability)(dev, speed_fec_capa, num); 506499a2dd95SBruce Richardson 50656679cf21SAnkur Dwivedi rte_eth_trace_fec_get_capability(port_id, speed_fec_capa, num, ret); 50666679cf21SAnkur Dwivedi 506799a2dd95SBruce Richardson return ret; 506899a2dd95SBruce Richardson } 506999a2dd95SBruce Richardson 507099a2dd95SBruce Richardson int 507199a2dd95SBruce Richardson rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa) 507299a2dd95SBruce Richardson { 507399a2dd95SBruce Richardson struct rte_eth_dev *dev; 50746679cf21SAnkur Dwivedi int ret; 507599a2dd95SBruce Richardson 507699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 507799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 507853ef1b34SMin Hu (Connor) 507953ef1b34SMin Hu (Connor) if (fec_capa == NULL) { 50800e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 50810e21c7c0SDavid Marchand "Cannot get ethdev port %u current FEC mode to NULL", 508253ef1b34SMin Hu (Connor) port_id); 508353ef1b34SMin Hu (Connor) return -EINVAL; 508453ef1b34SMin Hu (Connor) } 508553ef1b34SMin Hu (Connor) 50868f1d23ecSDavid Marchand if (*dev->dev_ops->fec_get == NULL) 50878f1d23ecSDavid Marchand return -ENOTSUP; 50886679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->fec_get)(dev, fec_capa)); 50896679cf21SAnkur Dwivedi 50906679cf21SAnkur Dwivedi rte_eth_trace_fec_get(port_id, fec_capa, ret); 50916679cf21SAnkur Dwivedi 50926679cf21SAnkur Dwivedi return ret; 509399a2dd95SBruce Richardson } 509499a2dd95SBruce Richardson 509599a2dd95SBruce Richardson int 509699a2dd95SBruce Richardson rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa) 509799a2dd95SBruce Richardson { 509899a2dd95SBruce Richardson struct rte_eth_dev *dev; 50996679cf21SAnkur Dwivedi int ret; 510099a2dd95SBruce Richardson 510199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 510299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 510353ef1b34SMin Hu (Connor) 51049fdcf2beSDenis Pryazhennikov if (fec_capa == 0) { 51050e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "At least one FEC mode should be specified"); 51069fdcf2beSDenis Pryazhennikov return -EINVAL; 51079fdcf2beSDenis Pryazhennikov } 51089fdcf2beSDenis Pryazhennikov 51098f1d23ecSDavid Marchand if (*dev->dev_ops->fec_set == NULL) 51108f1d23ecSDavid Marchand return -ENOTSUP; 51116679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->fec_set)(dev, fec_capa)); 51126679cf21SAnkur Dwivedi 51136679cf21SAnkur Dwivedi rte_eth_trace_fec_set(port_id, fec_capa, ret); 51146679cf21SAnkur Dwivedi 51156679cf21SAnkur Dwivedi return ret; 511699a2dd95SBruce Richardson } 511799a2dd95SBruce Richardson 511899a2dd95SBruce Richardson /* 511999a2dd95SBruce Richardson * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find 512099a2dd95SBruce Richardson * an empty spot. 512199a2dd95SBruce Richardson */ 512299a2dd95SBruce Richardson static int 512399a2dd95SBruce Richardson eth_dev_get_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr) 512499a2dd95SBruce Richardson { 512599a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 512699a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 512799a2dd95SBruce Richardson unsigned i; 512899a2dd95SBruce Richardson int ret; 512999a2dd95SBruce Richardson 513099a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 513199a2dd95SBruce Richardson if (ret != 0) 513299a2dd95SBruce Richardson return -1; 513399a2dd95SBruce Richardson 513499a2dd95SBruce Richardson for (i = 0; i < dev_info.max_mac_addrs; i++) 513599a2dd95SBruce Richardson if (memcmp(addr, &dev->data->mac_addrs[i], 513699a2dd95SBruce Richardson RTE_ETHER_ADDR_LEN) == 0) 513799a2dd95SBruce Richardson return i; 513899a2dd95SBruce Richardson 513999a2dd95SBruce Richardson return -1; 514099a2dd95SBruce Richardson } 514199a2dd95SBruce Richardson 514299a2dd95SBruce Richardson static const struct rte_ether_addr null_mac_addr; 514399a2dd95SBruce Richardson 514499a2dd95SBruce Richardson int 514599a2dd95SBruce Richardson rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, 514699a2dd95SBruce Richardson uint32_t pool) 514799a2dd95SBruce Richardson { 514899a2dd95SBruce Richardson struct rte_eth_dev *dev; 514999a2dd95SBruce Richardson int index; 515099a2dd95SBruce Richardson uint64_t pool_mask; 515199a2dd95SBruce Richardson int ret; 515299a2dd95SBruce Richardson 515399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 515499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 515553ef1b34SMin Hu (Connor) 515653ef1b34SMin Hu (Connor) if (addr == NULL) { 51570e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 51580e21c7c0SDavid Marchand "Cannot add ethdev port %u MAC address from NULL address", 515953ef1b34SMin Hu (Connor) port_id); 516053ef1b34SMin Hu (Connor) return -EINVAL; 516153ef1b34SMin Hu (Connor) } 516253ef1b34SMin Hu (Connor) 51638f1d23ecSDavid Marchand if (*dev->dev_ops->mac_addr_add == NULL) 51648f1d23ecSDavid Marchand return -ENOTSUP; 516599a2dd95SBruce Richardson 516699a2dd95SBruce Richardson if (rte_is_zero_ether_addr(addr)) { 51670e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Port %u: Cannot add NULL MAC address", 516899a2dd95SBruce Richardson port_id); 516999a2dd95SBruce Richardson return -EINVAL; 517099a2dd95SBruce Richardson } 5171295968d1SFerruh Yigit if (pool >= RTE_ETH_64_POOLS) { 51720e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Pool ID must be 0-%d", RTE_ETH_64_POOLS - 1); 517399a2dd95SBruce Richardson return -EINVAL; 517499a2dd95SBruce Richardson } 517599a2dd95SBruce Richardson 517699a2dd95SBruce Richardson index = eth_dev_get_mac_addr_index(port_id, addr); 517799a2dd95SBruce Richardson if (index < 0) { 517899a2dd95SBruce Richardson index = eth_dev_get_mac_addr_index(port_id, &null_mac_addr); 517999a2dd95SBruce Richardson if (index < 0) { 51800e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Port %u: MAC address array full", 518199a2dd95SBruce Richardson port_id); 518299a2dd95SBruce Richardson return -ENOSPC; 518399a2dd95SBruce Richardson } 518499a2dd95SBruce Richardson } else { 518599a2dd95SBruce Richardson pool_mask = dev->data->mac_pool_sel[index]; 518699a2dd95SBruce Richardson 518799a2dd95SBruce Richardson /* Check if both MAC address and pool is already there, and do nothing */ 5188e1823e08SThomas Monjalon if (pool_mask & RTE_BIT64(pool)) 518999a2dd95SBruce Richardson return 0; 519099a2dd95SBruce Richardson } 519199a2dd95SBruce Richardson 519299a2dd95SBruce Richardson /* Update NIC */ 519399a2dd95SBruce Richardson ret = (*dev->dev_ops->mac_addr_add)(dev, addr, index, pool); 519499a2dd95SBruce Richardson 519599a2dd95SBruce Richardson if (ret == 0) { 519699a2dd95SBruce Richardson /* Update address in NIC data structure */ 519799a2dd95SBruce Richardson rte_ether_addr_copy(addr, &dev->data->mac_addrs[index]); 519899a2dd95SBruce Richardson 519999a2dd95SBruce Richardson /* Update pool bitmap in NIC data structure */ 5200e1823e08SThomas Monjalon dev->data->mac_pool_sel[index] |= RTE_BIT64(pool); 520199a2dd95SBruce Richardson } 520299a2dd95SBruce Richardson 52036679cf21SAnkur Dwivedi ret = eth_err(port_id, ret); 52046679cf21SAnkur Dwivedi 52056679cf21SAnkur Dwivedi rte_ethdev_trace_mac_addr_add(port_id, addr, pool, ret); 52066679cf21SAnkur Dwivedi 52076679cf21SAnkur Dwivedi return ret; 520899a2dd95SBruce Richardson } 520999a2dd95SBruce Richardson 521099a2dd95SBruce Richardson int 521199a2dd95SBruce Richardson rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) 521299a2dd95SBruce Richardson { 521399a2dd95SBruce Richardson struct rte_eth_dev *dev; 521499a2dd95SBruce Richardson int index; 521599a2dd95SBruce Richardson 521699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 521799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 521853ef1b34SMin Hu (Connor) 521953ef1b34SMin Hu (Connor) if (addr == NULL) { 52200e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 52210e21c7c0SDavid Marchand "Cannot remove ethdev port %u MAC address from NULL address", 522253ef1b34SMin Hu (Connor) port_id); 522353ef1b34SMin Hu (Connor) return -EINVAL; 522453ef1b34SMin Hu (Connor) } 522553ef1b34SMin Hu (Connor) 52268f1d23ecSDavid Marchand if (*dev->dev_ops->mac_addr_remove == NULL) 52278f1d23ecSDavid Marchand return -ENOTSUP; 522899a2dd95SBruce Richardson 522999a2dd95SBruce Richardson index = eth_dev_get_mac_addr_index(port_id, addr); 523099a2dd95SBruce Richardson if (index == 0) { 52310e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 52320e21c7c0SDavid Marchand "Port %u: Cannot remove default MAC address", 523399a2dd95SBruce Richardson port_id); 523499a2dd95SBruce Richardson return -EADDRINUSE; 523599a2dd95SBruce Richardson } else if (index < 0) 523699a2dd95SBruce Richardson return 0; /* Do nothing if address wasn't found */ 523799a2dd95SBruce Richardson 523899a2dd95SBruce Richardson /* Update NIC */ 523999a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_remove)(dev, index); 524099a2dd95SBruce Richardson 524199a2dd95SBruce Richardson /* Update address in NIC data structure */ 524299a2dd95SBruce Richardson rte_ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]); 524399a2dd95SBruce Richardson 524499a2dd95SBruce Richardson /* reset pool bitmap */ 524599a2dd95SBruce Richardson dev->data->mac_pool_sel[index] = 0; 524699a2dd95SBruce Richardson 52476679cf21SAnkur Dwivedi rte_ethdev_trace_mac_addr_remove(port_id, addr); 52486679cf21SAnkur Dwivedi 524999a2dd95SBruce Richardson return 0; 525099a2dd95SBruce Richardson } 525199a2dd95SBruce Richardson 525299a2dd95SBruce Richardson int 525399a2dd95SBruce Richardson rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) 525499a2dd95SBruce Richardson { 525599a2dd95SBruce Richardson struct rte_eth_dev *dev; 52568f02f472SHuisong Li int index; 525799a2dd95SBruce Richardson int ret; 525899a2dd95SBruce Richardson 525999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 526053ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 526153ef1b34SMin Hu (Connor) 526253ef1b34SMin Hu (Connor) if (addr == NULL) { 52630e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 52640e21c7c0SDavid Marchand "Cannot set ethdev port %u default MAC address from NULL address", 526553ef1b34SMin Hu (Connor) port_id); 526653ef1b34SMin Hu (Connor) return -EINVAL; 526753ef1b34SMin Hu (Connor) } 526899a2dd95SBruce Richardson 526999a2dd95SBruce Richardson if (!rte_is_valid_assigned_ether_addr(addr)) 527099a2dd95SBruce Richardson return -EINVAL; 527199a2dd95SBruce Richardson 52728f1d23ecSDavid Marchand if (*dev->dev_ops->mac_addr_set == NULL) 52738f1d23ecSDavid Marchand return -ENOTSUP; 527499a2dd95SBruce Richardson 52758f02f472SHuisong Li /* Keep address unique in dev->data->mac_addrs[]. */ 52768f02f472SHuisong Li index = eth_dev_get_mac_addr_index(port_id, addr); 52778f02f472SHuisong Li if (index > 0) { 52780e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 52790e21c7c0SDavid Marchand "New default address for port %u was already in the address list. Please remove it first.", 52808f02f472SHuisong Li port_id); 52818f02f472SHuisong Li return -EEXIST; 52828f02f472SHuisong Li } 52838f02f472SHuisong Li 528499a2dd95SBruce Richardson ret = (*dev->dev_ops->mac_addr_set)(dev, addr); 528599a2dd95SBruce Richardson if (ret < 0) 528699a2dd95SBruce Richardson return ret; 528799a2dd95SBruce Richardson 528899a2dd95SBruce Richardson /* Update default address in NIC data structure */ 528999a2dd95SBruce Richardson rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); 529099a2dd95SBruce Richardson 52916679cf21SAnkur Dwivedi rte_ethdev_trace_default_mac_addr_set(port_id, addr); 52926679cf21SAnkur Dwivedi 529399a2dd95SBruce Richardson return 0; 529499a2dd95SBruce Richardson } 529599a2dd95SBruce Richardson 529699a2dd95SBruce Richardson 529799a2dd95SBruce Richardson /* 529899a2dd95SBruce Richardson * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find 529999a2dd95SBruce Richardson * an empty spot. 530099a2dd95SBruce Richardson */ 530199a2dd95SBruce Richardson static int 530299a2dd95SBruce Richardson eth_dev_get_hash_mac_addr_index(uint16_t port_id, 530399a2dd95SBruce Richardson const struct rte_ether_addr *addr) 530499a2dd95SBruce Richardson { 530599a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 530699a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 530799a2dd95SBruce Richardson unsigned i; 530899a2dd95SBruce Richardson int ret; 530999a2dd95SBruce Richardson 531099a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 531199a2dd95SBruce Richardson if (ret != 0) 531299a2dd95SBruce Richardson return -1; 531399a2dd95SBruce Richardson 531499a2dd95SBruce Richardson if (!dev->data->hash_mac_addrs) 531599a2dd95SBruce Richardson return -1; 531699a2dd95SBruce Richardson 531799a2dd95SBruce Richardson for (i = 0; i < dev_info.max_hash_mac_addrs; i++) 531899a2dd95SBruce Richardson if (memcmp(addr, &dev->data->hash_mac_addrs[i], 531999a2dd95SBruce Richardson RTE_ETHER_ADDR_LEN) == 0) 532099a2dd95SBruce Richardson return i; 532199a2dd95SBruce Richardson 532299a2dd95SBruce Richardson return -1; 532399a2dd95SBruce Richardson } 532499a2dd95SBruce Richardson 532599a2dd95SBruce Richardson int 532699a2dd95SBruce Richardson rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr, 532799a2dd95SBruce Richardson uint8_t on) 532899a2dd95SBruce Richardson { 532999a2dd95SBruce Richardson int index; 533099a2dd95SBruce Richardson int ret; 533199a2dd95SBruce Richardson struct rte_eth_dev *dev; 533299a2dd95SBruce Richardson 533399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 533499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 533553ef1b34SMin Hu (Connor) 533653ef1b34SMin Hu (Connor) if (addr == NULL) { 53370e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 53380e21c7c0SDavid Marchand "Cannot set ethdev port %u unicast hash table from NULL address", 533953ef1b34SMin Hu (Connor) port_id); 534053ef1b34SMin Hu (Connor) return -EINVAL; 534153ef1b34SMin Hu (Connor) } 534253ef1b34SMin Hu (Connor) 534399a2dd95SBruce Richardson if (rte_is_zero_ether_addr(addr)) { 53440e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Port %u: Cannot add NULL MAC address", 534599a2dd95SBruce Richardson port_id); 534699a2dd95SBruce Richardson return -EINVAL; 534799a2dd95SBruce Richardson } 534899a2dd95SBruce Richardson 534999a2dd95SBruce Richardson index = eth_dev_get_hash_mac_addr_index(port_id, addr); 535099a2dd95SBruce Richardson /* Check if it's already there, and do nothing */ 535199a2dd95SBruce Richardson if ((index >= 0) && on) 535299a2dd95SBruce Richardson return 0; 535399a2dd95SBruce Richardson 535499a2dd95SBruce Richardson if (index < 0) { 535599a2dd95SBruce Richardson if (!on) { 53560e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 53570e21c7c0SDavid Marchand "Port %u: the MAC address was not set in UTA", 535899a2dd95SBruce Richardson port_id); 535999a2dd95SBruce Richardson return -EINVAL; 536099a2dd95SBruce Richardson } 536199a2dd95SBruce Richardson 536299a2dd95SBruce Richardson index = eth_dev_get_hash_mac_addr_index(port_id, &null_mac_addr); 536399a2dd95SBruce Richardson if (index < 0) { 53640e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Port %u: MAC address array full", 536599a2dd95SBruce Richardson port_id); 536699a2dd95SBruce Richardson return -ENOSPC; 536799a2dd95SBruce Richardson } 536899a2dd95SBruce Richardson } 536999a2dd95SBruce Richardson 53708f1d23ecSDavid Marchand if (*dev->dev_ops->uc_hash_table_set == NULL) 53718f1d23ecSDavid Marchand return -ENOTSUP; 537299a2dd95SBruce Richardson ret = (*dev->dev_ops->uc_hash_table_set)(dev, addr, on); 537399a2dd95SBruce Richardson if (ret == 0) { 537499a2dd95SBruce Richardson /* Update address in NIC data structure */ 537599a2dd95SBruce Richardson if (on) 537699a2dd95SBruce Richardson rte_ether_addr_copy(addr, 537799a2dd95SBruce Richardson &dev->data->hash_mac_addrs[index]); 537899a2dd95SBruce Richardson else 537999a2dd95SBruce Richardson rte_ether_addr_copy(&null_mac_addr, 538099a2dd95SBruce Richardson &dev->data->hash_mac_addrs[index]); 538199a2dd95SBruce Richardson } 538299a2dd95SBruce Richardson 53836679cf21SAnkur Dwivedi ret = eth_err(port_id, ret); 53846679cf21SAnkur Dwivedi 53856679cf21SAnkur Dwivedi rte_ethdev_trace_uc_hash_table_set(port_id, on, ret); 53866679cf21SAnkur Dwivedi 53876679cf21SAnkur Dwivedi return ret; 538899a2dd95SBruce Richardson } 538999a2dd95SBruce Richardson 539099a2dd95SBruce Richardson int 539199a2dd95SBruce Richardson rte_eth_dev_uc_all_hash_table_set(uint16_t port_id, uint8_t on) 539299a2dd95SBruce Richardson { 539399a2dd95SBruce Richardson struct rte_eth_dev *dev; 53946679cf21SAnkur Dwivedi int ret; 539599a2dd95SBruce Richardson 539699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 539799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 539899a2dd95SBruce Richardson 53998f1d23ecSDavid Marchand if (*dev->dev_ops->uc_all_hash_table_set == NULL) 54008f1d23ecSDavid Marchand return -ENOTSUP; 54016679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->uc_all_hash_table_set)(dev, on)); 54026679cf21SAnkur Dwivedi 54036679cf21SAnkur Dwivedi rte_ethdev_trace_uc_all_hash_table_set(port_id, on, ret); 54046679cf21SAnkur Dwivedi 54056679cf21SAnkur Dwivedi return ret; 540699a2dd95SBruce Richardson } 540799a2dd95SBruce Richardson 540899a2dd95SBruce Richardson int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx, 54093a26e41eSSatha Rao uint32_t tx_rate) 541099a2dd95SBruce Richardson { 541199a2dd95SBruce Richardson struct rte_eth_dev *dev; 541299a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 541399a2dd95SBruce Richardson struct rte_eth_link link; 541499a2dd95SBruce Richardson int ret; 541599a2dd95SBruce Richardson 541699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 541753ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 541899a2dd95SBruce Richardson 541999a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 542099a2dd95SBruce Richardson if (ret != 0) 542199a2dd95SBruce Richardson return ret; 542299a2dd95SBruce Richardson 542399a2dd95SBruce Richardson link = dev->data->dev_link; 542499a2dd95SBruce Richardson 542599a2dd95SBruce Richardson if (queue_idx > dev_info.max_tx_queues) { 54260e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 54270e21c7c0SDavid Marchand "Set queue rate limit:port %u: invalid queue ID=%u", 542899a2dd95SBruce Richardson port_id, queue_idx); 542999a2dd95SBruce Richardson return -EINVAL; 543099a2dd95SBruce Richardson } 543199a2dd95SBruce Richardson 543299a2dd95SBruce Richardson if (tx_rate > link.link_speed) { 54330e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 54340e21c7c0SDavid Marchand "Set queue rate limit:invalid tx_rate=%u, bigger than link speed= %d", 543599a2dd95SBruce Richardson tx_rate, link.link_speed); 543699a2dd95SBruce Richardson return -EINVAL; 543799a2dd95SBruce Richardson } 543899a2dd95SBruce Richardson 54398f1d23ecSDavid Marchand if (*dev->dev_ops->set_queue_rate_limit == NULL) 54408f1d23ecSDavid Marchand return -ENOTSUP; 54416679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->set_queue_rate_limit)(dev, 544299a2dd95SBruce Richardson queue_idx, tx_rate)); 54436679cf21SAnkur Dwivedi 54446679cf21SAnkur Dwivedi rte_eth_trace_set_queue_rate_limit(port_id, queue_idx, tx_rate, ret); 54456679cf21SAnkur Dwivedi 54466679cf21SAnkur Dwivedi return ret; 544799a2dd95SBruce Richardson } 544899a2dd95SBruce Richardson 5449bc70e559SSpike Du int rte_eth_rx_avail_thresh_set(uint16_t port_id, uint16_t queue_id, 5450bc70e559SSpike Du uint8_t avail_thresh) 5451bc70e559SSpike Du { 5452bc70e559SSpike Du struct rte_eth_dev *dev; 54536679cf21SAnkur Dwivedi int ret; 5454bc70e559SSpike Du 5455bc70e559SSpike Du RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 5456bc70e559SSpike Du dev = &rte_eth_devices[port_id]; 5457bc70e559SSpike Du 5458bc70e559SSpike Du if (queue_id > dev->data->nb_rx_queues) { 54590e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 54600e21c7c0SDavid Marchand "Set queue avail thresh: port %u: invalid queue ID=%u.", 5461bc70e559SSpike Du port_id, queue_id); 5462bc70e559SSpike Du return -EINVAL; 5463bc70e559SSpike Du } 5464bc70e559SSpike Du 5465bc70e559SSpike Du if (avail_thresh > 99) { 54660e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 54670e21c7c0SDavid Marchand "Set queue avail thresh: port %u: threshold should be <= 99.", 5468bc70e559SSpike Du port_id); 5469bc70e559SSpike Du return -EINVAL; 5470bc70e559SSpike Du } 54718f1d23ecSDavid Marchand if (*dev->dev_ops->rx_queue_avail_thresh_set == NULL) 54728f1d23ecSDavid Marchand return -ENOTSUP; 54736679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->rx_queue_avail_thresh_set)(dev, 5474bc70e559SSpike Du queue_id, avail_thresh)); 54756679cf21SAnkur Dwivedi 54766679cf21SAnkur Dwivedi rte_eth_trace_rx_avail_thresh_set(port_id, queue_id, avail_thresh, ret); 54776679cf21SAnkur Dwivedi 54786679cf21SAnkur Dwivedi return ret; 5479bc70e559SSpike Du } 5480bc70e559SSpike Du 5481bc70e559SSpike Du int rte_eth_rx_avail_thresh_query(uint16_t port_id, uint16_t *queue_id, 5482bc70e559SSpike Du uint8_t *avail_thresh) 5483bc70e559SSpike Du { 5484bc70e559SSpike Du struct rte_eth_dev *dev; 54856679cf21SAnkur Dwivedi int ret; 5486bc70e559SSpike Du 5487bc70e559SSpike Du RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 5488bc70e559SSpike Du dev = &rte_eth_devices[port_id]; 5489bc70e559SSpike Du 5490bc70e559SSpike Du if (queue_id == NULL) 5491bc70e559SSpike Du return -EINVAL; 5492bc70e559SSpike Du if (*queue_id >= dev->data->nb_rx_queues) 5493bc70e559SSpike Du *queue_id = 0; 5494bc70e559SSpike Du 54958f1d23ecSDavid Marchand if (*dev->dev_ops->rx_queue_avail_thresh_query == NULL) 54968f1d23ecSDavid Marchand return -ENOTSUP; 54976679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->rx_queue_avail_thresh_query)(dev, 5498bc70e559SSpike Du queue_id, avail_thresh)); 54996679cf21SAnkur Dwivedi 55006679cf21SAnkur Dwivedi rte_eth_trace_rx_avail_thresh_query(port_id, *queue_id, ret); 55016679cf21SAnkur Dwivedi 55026679cf21SAnkur Dwivedi return ret; 5503bc70e559SSpike Du } 5504bc70e559SSpike Du 5505c87d435aSKonstantin Ananyev RTE_INIT(eth_dev_init_fp_ops) 5506c87d435aSKonstantin Ananyev { 5507c87d435aSKonstantin Ananyev uint32_t i; 5508c87d435aSKonstantin Ananyev 5509c87d435aSKonstantin Ananyev for (i = 0; i != RTE_DIM(rte_eth_fp_ops); i++) 5510c87d435aSKonstantin Ananyev eth_dev_fp_ops_reset(rte_eth_fp_ops + i); 5511c87d435aSKonstantin Ananyev } 5512c87d435aSKonstantin Ananyev 551399a2dd95SBruce Richardson RTE_INIT(eth_dev_init_cb_lists) 551499a2dd95SBruce Richardson { 551599a2dd95SBruce Richardson uint16_t i; 551699a2dd95SBruce Richardson 551799a2dd95SBruce Richardson for (i = 0; i < RTE_MAX_ETHPORTS; i++) 551899a2dd95SBruce Richardson TAILQ_INIT(&rte_eth_devices[i].link_intr_cbs); 551999a2dd95SBruce Richardson } 552099a2dd95SBruce Richardson 552199a2dd95SBruce Richardson int 552299a2dd95SBruce Richardson rte_eth_dev_callback_register(uint16_t port_id, 552399a2dd95SBruce Richardson enum rte_eth_event_type event, 552499a2dd95SBruce Richardson rte_eth_dev_cb_fn cb_fn, void *cb_arg) 552599a2dd95SBruce Richardson { 552699a2dd95SBruce Richardson struct rte_eth_dev *dev; 552799a2dd95SBruce Richardson struct rte_eth_dev_callback *user_cb; 552899a2dd95SBruce Richardson uint16_t next_port; 552999a2dd95SBruce Richardson uint16_t last_port; 553099a2dd95SBruce Richardson 553153ef1b34SMin Hu (Connor) if (cb_fn == NULL) { 55320e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 55330e21c7c0SDavid Marchand "Cannot register ethdev port %u callback from NULL", 553453ef1b34SMin Hu (Connor) port_id); 553599a2dd95SBruce Richardson return -EINVAL; 553653ef1b34SMin Hu (Connor) } 553799a2dd95SBruce Richardson 553899a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) { 55390e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid port_id=%d", port_id); 554099a2dd95SBruce Richardson return -EINVAL; 554199a2dd95SBruce Richardson } 554299a2dd95SBruce Richardson 554399a2dd95SBruce Richardson if (port_id == RTE_ETH_ALL) { 554499a2dd95SBruce Richardson next_port = 0; 554599a2dd95SBruce Richardson last_port = RTE_MAX_ETHPORTS - 1; 554699a2dd95SBruce Richardson } else { 554799a2dd95SBruce Richardson next_port = last_port = port_id; 554899a2dd95SBruce Richardson } 554999a2dd95SBruce Richardson 555099a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_cb_lock); 555199a2dd95SBruce Richardson 555299a2dd95SBruce Richardson do { 555399a2dd95SBruce Richardson dev = &rte_eth_devices[next_port]; 555499a2dd95SBruce Richardson 555599a2dd95SBruce Richardson TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) { 555699a2dd95SBruce Richardson if (user_cb->cb_fn == cb_fn && 555799a2dd95SBruce Richardson user_cb->cb_arg == cb_arg && 555899a2dd95SBruce Richardson user_cb->event == event) { 555999a2dd95SBruce Richardson break; 556099a2dd95SBruce Richardson } 556199a2dd95SBruce Richardson } 556299a2dd95SBruce Richardson 556399a2dd95SBruce Richardson /* create a new callback. */ 556499a2dd95SBruce Richardson if (user_cb == NULL) { 556599a2dd95SBruce Richardson user_cb = rte_zmalloc("INTR_USER_CALLBACK", 556699a2dd95SBruce Richardson sizeof(struct rte_eth_dev_callback), 0); 556799a2dd95SBruce Richardson if (user_cb != NULL) { 556899a2dd95SBruce Richardson user_cb->cb_fn = cb_fn; 556999a2dd95SBruce Richardson user_cb->cb_arg = cb_arg; 557099a2dd95SBruce Richardson user_cb->event = event; 557199a2dd95SBruce Richardson TAILQ_INSERT_TAIL(&(dev->link_intr_cbs), 557299a2dd95SBruce Richardson user_cb, next); 557399a2dd95SBruce Richardson } else { 557499a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_cb_lock); 557599a2dd95SBruce Richardson rte_eth_dev_callback_unregister(port_id, event, 557699a2dd95SBruce Richardson cb_fn, cb_arg); 557799a2dd95SBruce Richardson return -ENOMEM; 557899a2dd95SBruce Richardson } 557999a2dd95SBruce Richardson 558099a2dd95SBruce Richardson } 558199a2dd95SBruce Richardson } while (++next_port <= last_port); 558299a2dd95SBruce Richardson 558399a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_cb_lock); 55846679cf21SAnkur Dwivedi 55856679cf21SAnkur Dwivedi rte_ethdev_trace_callback_register(port_id, event, cb_fn, cb_arg); 55866679cf21SAnkur Dwivedi 558799a2dd95SBruce Richardson return 0; 558899a2dd95SBruce Richardson } 558999a2dd95SBruce Richardson 559099a2dd95SBruce Richardson int 559199a2dd95SBruce Richardson rte_eth_dev_callback_unregister(uint16_t port_id, 559299a2dd95SBruce Richardson enum rte_eth_event_type event, 559399a2dd95SBruce Richardson rte_eth_dev_cb_fn cb_fn, void *cb_arg) 559499a2dd95SBruce Richardson { 559599a2dd95SBruce Richardson int ret; 559699a2dd95SBruce Richardson struct rte_eth_dev *dev; 559799a2dd95SBruce Richardson struct rte_eth_dev_callback *cb, *next; 559899a2dd95SBruce Richardson uint16_t next_port; 559999a2dd95SBruce Richardson uint16_t last_port; 560099a2dd95SBruce Richardson 560153ef1b34SMin Hu (Connor) if (cb_fn == NULL) { 56020e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 56030e21c7c0SDavid Marchand "Cannot unregister ethdev port %u callback from NULL", 560453ef1b34SMin Hu (Connor) port_id); 560599a2dd95SBruce Richardson return -EINVAL; 560653ef1b34SMin Hu (Connor) } 560799a2dd95SBruce Richardson 560899a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) { 56090e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid port_id=%d", port_id); 561099a2dd95SBruce Richardson return -EINVAL; 561199a2dd95SBruce Richardson } 561299a2dd95SBruce Richardson 561399a2dd95SBruce Richardson if (port_id == RTE_ETH_ALL) { 561499a2dd95SBruce Richardson next_port = 0; 561599a2dd95SBruce Richardson last_port = RTE_MAX_ETHPORTS - 1; 561699a2dd95SBruce Richardson } else { 561799a2dd95SBruce Richardson next_port = last_port = port_id; 561899a2dd95SBruce Richardson } 561999a2dd95SBruce Richardson 562099a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_cb_lock); 562199a2dd95SBruce Richardson 562299a2dd95SBruce Richardson do { 562399a2dd95SBruce Richardson dev = &rte_eth_devices[next_port]; 562499a2dd95SBruce Richardson ret = 0; 562599a2dd95SBruce Richardson for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL; 562699a2dd95SBruce Richardson cb = next) { 562799a2dd95SBruce Richardson 562899a2dd95SBruce Richardson next = TAILQ_NEXT(cb, next); 562999a2dd95SBruce Richardson 563099a2dd95SBruce Richardson if (cb->cb_fn != cb_fn || cb->event != event || 563199a2dd95SBruce Richardson (cb_arg != (void *)-1 && cb->cb_arg != cb_arg)) 563299a2dd95SBruce Richardson continue; 563399a2dd95SBruce Richardson 563499a2dd95SBruce Richardson /* 563599a2dd95SBruce Richardson * if this callback is not executing right now, 563699a2dd95SBruce Richardson * then remove it. 563799a2dd95SBruce Richardson */ 563899a2dd95SBruce Richardson if (cb->active == 0) { 563999a2dd95SBruce Richardson TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next); 564099a2dd95SBruce Richardson rte_free(cb); 564199a2dd95SBruce Richardson } else { 564299a2dd95SBruce Richardson ret = -EAGAIN; 564399a2dd95SBruce Richardson } 564499a2dd95SBruce Richardson } 564599a2dd95SBruce Richardson } while (++next_port <= last_port); 564699a2dd95SBruce Richardson 564799a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_cb_lock); 56486679cf21SAnkur Dwivedi 56496679cf21SAnkur Dwivedi rte_ethdev_trace_callback_unregister(port_id, event, cb_fn, cb_arg, 56506679cf21SAnkur Dwivedi ret); 56516679cf21SAnkur Dwivedi 565299a2dd95SBruce Richardson return ret; 565399a2dd95SBruce Richardson } 565499a2dd95SBruce Richardson 565599a2dd95SBruce Richardson int 565699a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data) 565799a2dd95SBruce Richardson { 565899a2dd95SBruce Richardson uint32_t vec; 565999a2dd95SBruce Richardson struct rte_eth_dev *dev; 566099a2dd95SBruce Richardson struct rte_intr_handle *intr_handle; 566199a2dd95SBruce Richardson uint16_t qid; 566299a2dd95SBruce Richardson int rc; 566399a2dd95SBruce Richardson 566499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 566599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 566699a2dd95SBruce Richardson 566799a2dd95SBruce Richardson if (!dev->intr_handle) { 56680e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr handle unset"); 566999a2dd95SBruce Richardson return -ENOTSUP; 567099a2dd95SBruce Richardson } 567199a2dd95SBruce Richardson 567299a2dd95SBruce Richardson intr_handle = dev->intr_handle; 5673c2bd9367SHarman Kalra if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { 56740e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr vector unset"); 567599a2dd95SBruce Richardson return -EPERM; 567699a2dd95SBruce Richardson } 567799a2dd95SBruce Richardson 567899a2dd95SBruce Richardson for (qid = 0; qid < dev->data->nb_rx_queues; qid++) { 5679c2bd9367SHarman Kalra vec = rte_intr_vec_list_index_get(intr_handle, qid); 568099a2dd95SBruce Richardson rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data); 56816679cf21SAnkur Dwivedi 56826679cf21SAnkur Dwivedi rte_ethdev_trace_rx_intr_ctl(port_id, qid, epfd, op, data, rc); 56836679cf21SAnkur Dwivedi 568499a2dd95SBruce Richardson if (rc && rc != -EEXIST) { 56850e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 56860e21c7c0SDavid Marchand "p %u q %u Rx ctl error op %d epfd %d vec %u", 568799a2dd95SBruce Richardson port_id, qid, op, epfd, vec); 568899a2dd95SBruce Richardson } 568999a2dd95SBruce Richardson } 569099a2dd95SBruce Richardson 569199a2dd95SBruce Richardson return 0; 569299a2dd95SBruce Richardson } 569399a2dd95SBruce Richardson 569499a2dd95SBruce Richardson int 569599a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id, uint16_t queue_id) 569699a2dd95SBruce Richardson { 569799a2dd95SBruce Richardson struct rte_intr_handle *intr_handle; 569899a2dd95SBruce Richardson struct rte_eth_dev *dev; 569999a2dd95SBruce Richardson unsigned int efd_idx; 570099a2dd95SBruce Richardson uint32_t vec; 570199a2dd95SBruce Richardson int fd; 570299a2dd95SBruce Richardson 570399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); 570499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 570599a2dd95SBruce Richardson 570699a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 57070e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id); 570899a2dd95SBruce Richardson return -1; 570999a2dd95SBruce Richardson } 571099a2dd95SBruce Richardson 571199a2dd95SBruce Richardson if (!dev->intr_handle) { 57120e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr handle unset"); 571399a2dd95SBruce Richardson return -1; 571499a2dd95SBruce Richardson } 571599a2dd95SBruce Richardson 571699a2dd95SBruce Richardson intr_handle = dev->intr_handle; 5717c2bd9367SHarman Kalra if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { 57180e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr vector unset"); 571999a2dd95SBruce Richardson return -1; 572099a2dd95SBruce Richardson } 572199a2dd95SBruce Richardson 5722c2bd9367SHarman Kalra vec = rte_intr_vec_list_index_get(intr_handle, queue_id); 572399a2dd95SBruce Richardson efd_idx = (vec >= RTE_INTR_VEC_RXTX_OFFSET) ? 572499a2dd95SBruce Richardson (vec - RTE_INTR_VEC_RXTX_OFFSET) : vec; 5725c2bd9367SHarman Kalra fd = rte_intr_efds_index_get(intr_handle, efd_idx); 572699a2dd95SBruce Richardson 57276679cf21SAnkur Dwivedi rte_ethdev_trace_rx_intr_ctl_q_get_fd(port_id, queue_id, fd); 57286679cf21SAnkur Dwivedi 572999a2dd95SBruce Richardson return fd; 573099a2dd95SBruce Richardson } 573199a2dd95SBruce Richardson 573299a2dd95SBruce Richardson int 573399a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id, 573499a2dd95SBruce Richardson int epfd, int op, void *data) 573599a2dd95SBruce Richardson { 573699a2dd95SBruce Richardson uint32_t vec; 573799a2dd95SBruce Richardson struct rte_eth_dev *dev; 573899a2dd95SBruce Richardson struct rte_intr_handle *intr_handle; 573999a2dd95SBruce Richardson int rc; 574099a2dd95SBruce Richardson 574199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 574299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 574353ef1b34SMin Hu (Connor) 574499a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 57450e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id); 574699a2dd95SBruce Richardson return -EINVAL; 574799a2dd95SBruce Richardson } 574899a2dd95SBruce Richardson 574999a2dd95SBruce Richardson if (!dev->intr_handle) { 57500e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr handle unset"); 575199a2dd95SBruce Richardson return -ENOTSUP; 575299a2dd95SBruce Richardson } 575399a2dd95SBruce Richardson 575499a2dd95SBruce Richardson intr_handle = dev->intr_handle; 5755c2bd9367SHarman Kalra if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { 57560e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr vector unset"); 575799a2dd95SBruce Richardson return -EPERM; 575899a2dd95SBruce Richardson } 575999a2dd95SBruce Richardson 5760c2bd9367SHarman Kalra vec = rte_intr_vec_list_index_get(intr_handle, queue_id); 576199a2dd95SBruce Richardson rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data); 57626679cf21SAnkur Dwivedi 57636679cf21SAnkur Dwivedi rte_ethdev_trace_rx_intr_ctl_q(port_id, queue_id, epfd, op, data, rc); 57646679cf21SAnkur Dwivedi 576599a2dd95SBruce Richardson if (rc && rc != -EEXIST) { 57660e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 57670e21c7c0SDavid Marchand "p %u q %u Rx ctl error op %d epfd %d vec %u", 576899a2dd95SBruce Richardson port_id, queue_id, op, epfd, vec); 576999a2dd95SBruce Richardson return rc; 577099a2dd95SBruce Richardson } 577199a2dd95SBruce Richardson 577299a2dd95SBruce Richardson return 0; 577399a2dd95SBruce Richardson } 577499a2dd95SBruce Richardson 577599a2dd95SBruce Richardson int 577699a2dd95SBruce Richardson rte_eth_dev_rx_intr_enable(uint16_t port_id, 577799a2dd95SBruce Richardson uint16_t queue_id) 577899a2dd95SBruce Richardson { 577999a2dd95SBruce Richardson struct rte_eth_dev *dev; 578099a2dd95SBruce Richardson int ret; 578199a2dd95SBruce Richardson 578299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 578399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 578499a2dd95SBruce Richardson 578599a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, queue_id); 578699a2dd95SBruce Richardson if (ret != 0) 578799a2dd95SBruce Richardson return ret; 578899a2dd95SBruce Richardson 57898f1d23ecSDavid Marchand if (*dev->dev_ops->rx_queue_intr_enable == NULL) 57908f1d23ecSDavid Marchand return -ENOTSUP; 57916679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->rx_queue_intr_enable)(dev, queue_id)); 57926679cf21SAnkur Dwivedi 57936679cf21SAnkur Dwivedi rte_ethdev_trace_rx_intr_enable(port_id, queue_id, ret); 57946679cf21SAnkur Dwivedi 57956679cf21SAnkur Dwivedi return ret; 579699a2dd95SBruce Richardson } 579799a2dd95SBruce Richardson 579899a2dd95SBruce Richardson int 579999a2dd95SBruce Richardson rte_eth_dev_rx_intr_disable(uint16_t port_id, 580099a2dd95SBruce Richardson uint16_t queue_id) 580199a2dd95SBruce Richardson { 580299a2dd95SBruce Richardson struct rte_eth_dev *dev; 580399a2dd95SBruce Richardson int ret; 580499a2dd95SBruce Richardson 580599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 580699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 580799a2dd95SBruce Richardson 580899a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, queue_id); 580999a2dd95SBruce Richardson if (ret != 0) 581099a2dd95SBruce Richardson return ret; 581199a2dd95SBruce Richardson 58128f1d23ecSDavid Marchand if (*dev->dev_ops->rx_queue_intr_disable == NULL) 58138f1d23ecSDavid Marchand return -ENOTSUP; 58146679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->rx_queue_intr_disable)(dev, queue_id)); 58156679cf21SAnkur Dwivedi 58166679cf21SAnkur Dwivedi rte_ethdev_trace_rx_intr_disable(port_id, queue_id, ret); 58176679cf21SAnkur Dwivedi 58186679cf21SAnkur Dwivedi return ret; 581999a2dd95SBruce Richardson } 582099a2dd95SBruce Richardson 582199a2dd95SBruce Richardson 582299a2dd95SBruce Richardson const struct rte_eth_rxtx_callback * 582399a2dd95SBruce Richardson rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id, 582499a2dd95SBruce Richardson rte_rx_callback_fn fn, void *user_param) 582599a2dd95SBruce Richardson { 582699a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 582799a2dd95SBruce Richardson rte_errno = ENOTSUP; 582899a2dd95SBruce Richardson return NULL; 582999a2dd95SBruce Richardson #endif 583099a2dd95SBruce Richardson struct rte_eth_dev *dev; 583199a2dd95SBruce Richardson 583299a2dd95SBruce Richardson /* check input parameters */ 583399a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 583499a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) { 583599a2dd95SBruce Richardson rte_errno = EINVAL; 583699a2dd95SBruce Richardson return NULL; 583799a2dd95SBruce Richardson } 583899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 583999a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) { 584099a2dd95SBruce Richardson rte_errno = EINVAL; 584199a2dd95SBruce Richardson return NULL; 584299a2dd95SBruce Richardson } 584399a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 584499a2dd95SBruce Richardson 584599a2dd95SBruce Richardson if (cb == NULL) { 584699a2dd95SBruce Richardson rte_errno = ENOMEM; 584799a2dd95SBruce Richardson return NULL; 584899a2dd95SBruce Richardson } 584999a2dd95SBruce Richardson 585099a2dd95SBruce Richardson cb->fn.rx = fn; 585199a2dd95SBruce Richardson cb->param = user_param; 585299a2dd95SBruce Richardson 585399a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_rx_cb_lock); 585499a2dd95SBruce Richardson /* Add the callbacks in fifo order. */ 585599a2dd95SBruce Richardson struct rte_eth_rxtx_callback *tail = 585699a2dd95SBruce Richardson rte_eth_devices[port_id].post_rx_burst_cbs[queue_id]; 585799a2dd95SBruce Richardson 585899a2dd95SBruce Richardson if (!tail) { 585999a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 586099a2dd95SBruce Richardson * cb is visible to data plane. 586199a2dd95SBruce Richardson */ 5862f7053f01STyler Retzlaff rte_atomic_store_explicit( 586399a2dd95SBruce Richardson &rte_eth_devices[port_id].post_rx_burst_cbs[queue_id], 5864f7053f01STyler Retzlaff cb, rte_memory_order_release); 586599a2dd95SBruce Richardson 586699a2dd95SBruce Richardson } else { 586799a2dd95SBruce Richardson while (tail->next) 586899a2dd95SBruce Richardson tail = tail->next; 586999a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 587099a2dd95SBruce Richardson * cb is visible to data plane. 587199a2dd95SBruce Richardson */ 5872f7053f01STyler Retzlaff rte_atomic_store_explicit(&tail->next, cb, rte_memory_order_release); 587399a2dd95SBruce Richardson } 587499a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_rx_cb_lock); 587599a2dd95SBruce Richardson 58766679cf21SAnkur Dwivedi rte_eth_trace_add_rx_callback(port_id, queue_id, fn, user_param, cb); 58776679cf21SAnkur Dwivedi 587899a2dd95SBruce Richardson return cb; 587999a2dd95SBruce Richardson } 588099a2dd95SBruce Richardson 588199a2dd95SBruce Richardson const struct rte_eth_rxtx_callback * 588299a2dd95SBruce Richardson rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id, 588399a2dd95SBruce Richardson rte_rx_callback_fn fn, void *user_param) 588499a2dd95SBruce Richardson { 588599a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 588699a2dd95SBruce Richardson rte_errno = ENOTSUP; 588799a2dd95SBruce Richardson return NULL; 588899a2dd95SBruce Richardson #endif 588999a2dd95SBruce Richardson /* check input parameters */ 589099a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 589199a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) { 589299a2dd95SBruce Richardson rte_errno = EINVAL; 589399a2dd95SBruce Richardson return NULL; 589499a2dd95SBruce Richardson } 589599a2dd95SBruce Richardson 589699a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 589799a2dd95SBruce Richardson 589899a2dd95SBruce Richardson if (cb == NULL) { 589999a2dd95SBruce Richardson rte_errno = ENOMEM; 590099a2dd95SBruce Richardson return NULL; 590199a2dd95SBruce Richardson } 590299a2dd95SBruce Richardson 590399a2dd95SBruce Richardson cb->fn.rx = fn; 590499a2dd95SBruce Richardson cb->param = user_param; 590599a2dd95SBruce Richardson 590699a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_rx_cb_lock); 590799a2dd95SBruce Richardson /* Add the callbacks at first position */ 590899a2dd95SBruce Richardson cb->next = rte_eth_devices[port_id].post_rx_burst_cbs[queue_id]; 590999a2dd95SBruce Richardson /* Stores to cb->fn, cb->param and cb->next should complete before 591099a2dd95SBruce Richardson * cb is visible to data plane threads. 591199a2dd95SBruce Richardson */ 5912f7053f01STyler Retzlaff rte_atomic_store_explicit( 591399a2dd95SBruce Richardson &rte_eth_devices[port_id].post_rx_burst_cbs[queue_id], 5914f7053f01STyler Retzlaff cb, rte_memory_order_release); 591599a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_rx_cb_lock); 591699a2dd95SBruce Richardson 59176679cf21SAnkur Dwivedi rte_eth_trace_add_first_rx_callback(port_id, queue_id, fn, user_param, 59186679cf21SAnkur Dwivedi cb); 59196679cf21SAnkur Dwivedi 592099a2dd95SBruce Richardson return cb; 592199a2dd95SBruce Richardson } 592299a2dd95SBruce Richardson 592399a2dd95SBruce Richardson const struct rte_eth_rxtx_callback * 592499a2dd95SBruce Richardson rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id, 592599a2dd95SBruce Richardson rte_tx_callback_fn fn, void *user_param) 592699a2dd95SBruce Richardson { 592799a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 592899a2dd95SBruce Richardson rte_errno = ENOTSUP; 592999a2dd95SBruce Richardson return NULL; 593099a2dd95SBruce Richardson #endif 593199a2dd95SBruce Richardson struct rte_eth_dev *dev; 593299a2dd95SBruce Richardson 593399a2dd95SBruce Richardson /* check input parameters */ 593499a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 593599a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) { 593699a2dd95SBruce Richardson rte_errno = EINVAL; 593799a2dd95SBruce Richardson return NULL; 593899a2dd95SBruce Richardson } 593999a2dd95SBruce Richardson 594099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 594199a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) { 594299a2dd95SBruce Richardson rte_errno = EINVAL; 594399a2dd95SBruce Richardson return NULL; 594499a2dd95SBruce Richardson } 594599a2dd95SBruce Richardson 594699a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 594799a2dd95SBruce Richardson 594899a2dd95SBruce Richardson if (cb == NULL) { 594999a2dd95SBruce Richardson rte_errno = ENOMEM; 595099a2dd95SBruce Richardson return NULL; 595199a2dd95SBruce Richardson } 595299a2dd95SBruce Richardson 595399a2dd95SBruce Richardson cb->fn.tx = fn; 595499a2dd95SBruce Richardson cb->param = user_param; 595599a2dd95SBruce Richardson 595699a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_tx_cb_lock); 595799a2dd95SBruce Richardson /* Add the callbacks in fifo order. */ 595899a2dd95SBruce Richardson struct rte_eth_rxtx_callback *tail = 595999a2dd95SBruce Richardson rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id]; 596099a2dd95SBruce Richardson 596199a2dd95SBruce Richardson if (!tail) { 596299a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 596399a2dd95SBruce Richardson * cb is visible to data plane. 596499a2dd95SBruce Richardson */ 5965f7053f01STyler Retzlaff rte_atomic_store_explicit( 596699a2dd95SBruce Richardson &rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id], 5967f7053f01STyler Retzlaff cb, rte_memory_order_release); 596899a2dd95SBruce Richardson 596999a2dd95SBruce Richardson } else { 597099a2dd95SBruce Richardson while (tail->next) 597199a2dd95SBruce Richardson tail = tail->next; 597299a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 597399a2dd95SBruce Richardson * cb is visible to data plane. 597499a2dd95SBruce Richardson */ 5975f7053f01STyler Retzlaff rte_atomic_store_explicit(&tail->next, cb, rte_memory_order_release); 597699a2dd95SBruce Richardson } 597799a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_tx_cb_lock); 597899a2dd95SBruce Richardson 59796679cf21SAnkur Dwivedi rte_eth_trace_add_tx_callback(port_id, queue_id, fn, user_param, cb); 59806679cf21SAnkur Dwivedi 598199a2dd95SBruce Richardson return cb; 598299a2dd95SBruce Richardson } 598399a2dd95SBruce Richardson 598499a2dd95SBruce Richardson int 598599a2dd95SBruce Richardson rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id, 598699a2dd95SBruce Richardson const struct rte_eth_rxtx_callback *user_cb) 598799a2dd95SBruce Richardson { 598899a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 598999a2dd95SBruce Richardson return -ENOTSUP; 599099a2dd95SBruce Richardson #endif 599199a2dd95SBruce Richardson /* Check input parameters. */ 599299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 599399a2dd95SBruce Richardson if (user_cb == NULL || 599499a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) 599599a2dd95SBruce Richardson return -EINVAL; 599699a2dd95SBruce Richardson 599799a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 599899a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb; 5999f7053f01STyler Retzlaff RTE_ATOMIC(struct rte_eth_rxtx_callback *) *prev_cb; 600099a2dd95SBruce Richardson int ret = -EINVAL; 600199a2dd95SBruce Richardson 600299a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_rx_cb_lock); 600399a2dd95SBruce Richardson prev_cb = &dev->post_rx_burst_cbs[queue_id]; 600499a2dd95SBruce Richardson for (; *prev_cb != NULL; prev_cb = &cb->next) { 600599a2dd95SBruce Richardson cb = *prev_cb; 600699a2dd95SBruce Richardson if (cb == user_cb) { 600799a2dd95SBruce Richardson /* Remove the user cb from the callback list. */ 6008f7053f01STyler Retzlaff rte_atomic_store_explicit(prev_cb, cb->next, rte_memory_order_relaxed); 600999a2dd95SBruce Richardson ret = 0; 601099a2dd95SBruce Richardson break; 601199a2dd95SBruce Richardson } 601299a2dd95SBruce Richardson } 601399a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_rx_cb_lock); 601499a2dd95SBruce Richardson 60156679cf21SAnkur Dwivedi rte_eth_trace_remove_rx_callback(port_id, queue_id, user_cb, ret); 60166679cf21SAnkur Dwivedi 601799a2dd95SBruce Richardson return ret; 601899a2dd95SBruce Richardson } 601999a2dd95SBruce Richardson 602099a2dd95SBruce Richardson int 602199a2dd95SBruce Richardson rte_eth_remove_tx_callback(uint16_t port_id, uint16_t queue_id, 602299a2dd95SBruce Richardson const struct rte_eth_rxtx_callback *user_cb) 602399a2dd95SBruce Richardson { 602499a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 602599a2dd95SBruce Richardson return -ENOTSUP; 602699a2dd95SBruce Richardson #endif 602799a2dd95SBruce Richardson /* Check input parameters. */ 602899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 602999a2dd95SBruce Richardson if (user_cb == NULL || 603099a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) 603199a2dd95SBruce Richardson return -EINVAL; 603299a2dd95SBruce Richardson 603399a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 603499a2dd95SBruce Richardson int ret = -EINVAL; 603599a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb; 6036f7053f01STyler Retzlaff RTE_ATOMIC(struct rte_eth_rxtx_callback *) *prev_cb; 603799a2dd95SBruce Richardson 603899a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_tx_cb_lock); 603999a2dd95SBruce Richardson prev_cb = &dev->pre_tx_burst_cbs[queue_id]; 604099a2dd95SBruce Richardson for (; *prev_cb != NULL; prev_cb = &cb->next) { 604199a2dd95SBruce Richardson cb = *prev_cb; 604299a2dd95SBruce Richardson if (cb == user_cb) { 604399a2dd95SBruce Richardson /* Remove the user cb from the callback list. */ 6044f7053f01STyler Retzlaff rte_atomic_store_explicit(prev_cb, cb->next, rte_memory_order_relaxed); 604599a2dd95SBruce Richardson ret = 0; 604699a2dd95SBruce Richardson break; 604799a2dd95SBruce Richardson } 604899a2dd95SBruce Richardson } 604999a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_tx_cb_lock); 605099a2dd95SBruce Richardson 60516679cf21SAnkur Dwivedi rte_eth_trace_remove_tx_callback(port_id, queue_id, user_cb, ret); 60526679cf21SAnkur Dwivedi 605399a2dd95SBruce Richardson return ret; 605499a2dd95SBruce Richardson } 605599a2dd95SBruce Richardson 605699a2dd95SBruce Richardson int 605799a2dd95SBruce Richardson rte_eth_rx_queue_info_get(uint16_t port_id, uint16_t queue_id, 605899a2dd95SBruce Richardson struct rte_eth_rxq_info *qinfo) 605999a2dd95SBruce Richardson { 606099a2dd95SBruce Richardson struct rte_eth_dev *dev; 606199a2dd95SBruce Richardson 606299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 606399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 606453ef1b34SMin Hu (Connor) 606599a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 60660e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id); 606799a2dd95SBruce Richardson return -EINVAL; 606899a2dd95SBruce Richardson } 606999a2dd95SBruce Richardson 607053ef1b34SMin Hu (Connor) if (qinfo == NULL) { 60710e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u Rx queue %u info to NULL", 607253ef1b34SMin Hu (Connor) port_id, queue_id); 607353ef1b34SMin Hu (Connor) return -EINVAL; 607453ef1b34SMin Hu (Connor) } 607553ef1b34SMin Hu (Connor) 607699a2dd95SBruce Richardson if (dev->data->rx_queues == NULL || 607799a2dd95SBruce Richardson dev->data->rx_queues[queue_id] == NULL) { 60780e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 607999a2dd95SBruce Richardson "Rx queue %"PRIu16" of device with port_id=%" 60800e21c7c0SDavid Marchand PRIu16" has not been setup", 608199a2dd95SBruce Richardson queue_id, port_id); 608299a2dd95SBruce Richardson return -EINVAL; 608399a2dd95SBruce Richardson } 608499a2dd95SBruce Richardson 608599a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) { 60860e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 60870e21c7c0SDavid Marchand "Can't get hairpin Rx queue %"PRIu16" info of device with port_id=%"PRIu16, 608899a2dd95SBruce Richardson queue_id, port_id); 608999a2dd95SBruce Richardson return -EINVAL; 609099a2dd95SBruce Richardson } 609199a2dd95SBruce Richardson 60928f1d23ecSDavid Marchand if (*dev->dev_ops->rxq_info_get == NULL) 60938f1d23ecSDavid Marchand return -ENOTSUP; 609499a2dd95SBruce Richardson 609599a2dd95SBruce Richardson memset(qinfo, 0, sizeof(*qinfo)); 609699a2dd95SBruce Richardson dev->dev_ops->rxq_info_get(dev, queue_id, qinfo); 60979ad9ff47SLijun Ou qinfo->queue_state = dev->data->rx_queue_state[queue_id]; 60989ad9ff47SLijun Ou 60996679cf21SAnkur Dwivedi rte_eth_trace_rx_queue_info_get(port_id, queue_id, qinfo); 61006679cf21SAnkur Dwivedi 610199a2dd95SBruce Richardson return 0; 610299a2dd95SBruce Richardson } 610399a2dd95SBruce Richardson 610499a2dd95SBruce Richardson int 610599a2dd95SBruce Richardson rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id, 610699a2dd95SBruce Richardson struct rte_eth_txq_info *qinfo) 610799a2dd95SBruce Richardson { 610899a2dd95SBruce Richardson struct rte_eth_dev *dev; 610999a2dd95SBruce Richardson 611099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 611199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 611253ef1b34SMin Hu (Connor) 611399a2dd95SBruce Richardson if (queue_id >= dev->data->nb_tx_queues) { 61140e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", queue_id); 611599a2dd95SBruce Richardson return -EINVAL; 611699a2dd95SBruce Richardson } 611799a2dd95SBruce Richardson 611853ef1b34SMin Hu (Connor) if (qinfo == NULL) { 61190e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u Tx queue %u info to NULL", 612053ef1b34SMin Hu (Connor) port_id, queue_id); 612153ef1b34SMin Hu (Connor) return -EINVAL; 612253ef1b34SMin Hu (Connor) } 612353ef1b34SMin Hu (Connor) 612499a2dd95SBruce Richardson if (dev->data->tx_queues == NULL || 612599a2dd95SBruce Richardson dev->data->tx_queues[queue_id] == NULL) { 61260e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 612799a2dd95SBruce Richardson "Tx queue %"PRIu16" of device with port_id=%" 61280e21c7c0SDavid Marchand PRIu16" has not been setup", 612999a2dd95SBruce Richardson queue_id, port_id); 613099a2dd95SBruce Richardson return -EINVAL; 613199a2dd95SBruce Richardson } 613299a2dd95SBruce Richardson 613399a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) { 61340e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(INFO, 61350e21c7c0SDavid Marchand "Can't get hairpin Tx queue %"PRIu16" info of device with port_id=%"PRIu16, 613699a2dd95SBruce Richardson queue_id, port_id); 613799a2dd95SBruce Richardson return -EINVAL; 613899a2dd95SBruce Richardson } 613999a2dd95SBruce Richardson 61408f1d23ecSDavid Marchand if (*dev->dev_ops->txq_info_get == NULL) 61418f1d23ecSDavid Marchand return -ENOTSUP; 614299a2dd95SBruce Richardson 614399a2dd95SBruce Richardson memset(qinfo, 0, sizeof(*qinfo)); 614499a2dd95SBruce Richardson dev->dev_ops->txq_info_get(dev, queue_id, qinfo); 61459ad9ff47SLijun Ou qinfo->queue_state = dev->data->tx_queue_state[queue_id]; 614699a2dd95SBruce Richardson 61476679cf21SAnkur Dwivedi rte_eth_trace_tx_queue_info_get(port_id, queue_id, qinfo); 61486679cf21SAnkur Dwivedi 614999a2dd95SBruce Richardson return 0; 615099a2dd95SBruce Richardson } 615199a2dd95SBruce Richardson 615299a2dd95SBruce Richardson int 6153e43d2b89SFeifei Wang rte_eth_recycle_rx_queue_info_get(uint16_t port_id, uint16_t queue_id, 6154e43d2b89SFeifei Wang struct rte_eth_recycle_rxq_info *recycle_rxq_info) 6155e43d2b89SFeifei Wang { 6156e43d2b89SFeifei Wang struct rte_eth_dev *dev; 6157e43d2b89SFeifei Wang int ret; 6158e43d2b89SFeifei Wang 6159e43d2b89SFeifei Wang RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 6160e43d2b89SFeifei Wang dev = &rte_eth_devices[port_id]; 6161e43d2b89SFeifei Wang 6162e43d2b89SFeifei Wang ret = eth_dev_validate_rx_queue(dev, queue_id); 6163e43d2b89SFeifei Wang if (unlikely(ret != 0)) 6164e43d2b89SFeifei Wang return ret; 6165e43d2b89SFeifei Wang 6166e43d2b89SFeifei Wang if (*dev->dev_ops->recycle_rxq_info_get == NULL) 6167e43d2b89SFeifei Wang return -ENOTSUP; 6168e43d2b89SFeifei Wang 6169e43d2b89SFeifei Wang dev->dev_ops->recycle_rxq_info_get(dev, queue_id, recycle_rxq_info); 6170e43d2b89SFeifei Wang 6171e43d2b89SFeifei Wang return 0; 6172e43d2b89SFeifei Wang } 6173e43d2b89SFeifei Wang 6174e43d2b89SFeifei Wang int 617599a2dd95SBruce Richardson rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id, 617699a2dd95SBruce Richardson struct rte_eth_burst_mode *mode) 617799a2dd95SBruce Richardson { 617899a2dd95SBruce Richardson struct rte_eth_dev *dev; 61796679cf21SAnkur Dwivedi int ret; 618099a2dd95SBruce Richardson 618199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 618299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 618399a2dd95SBruce Richardson 618499a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 61850e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id); 618699a2dd95SBruce Richardson return -EINVAL; 618799a2dd95SBruce Richardson } 618899a2dd95SBruce Richardson 618953ef1b34SMin Hu (Connor) if (mode == NULL) { 61900e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 61910e21c7c0SDavid Marchand "Cannot get ethdev port %u Rx queue %u burst mode to NULL", 619253ef1b34SMin Hu (Connor) port_id, queue_id); 619353ef1b34SMin Hu (Connor) return -EINVAL; 619453ef1b34SMin Hu (Connor) } 619553ef1b34SMin Hu (Connor) 61968f1d23ecSDavid Marchand if (*dev->dev_ops->rx_burst_mode_get == NULL) 61978f1d23ecSDavid Marchand return -ENOTSUP; 619899a2dd95SBruce Richardson memset(mode, 0, sizeof(*mode)); 61996679cf21SAnkur Dwivedi ret = eth_err(port_id, 620099a2dd95SBruce Richardson dev->dev_ops->rx_burst_mode_get(dev, queue_id, mode)); 62016679cf21SAnkur Dwivedi 62026679cf21SAnkur Dwivedi rte_eth_trace_rx_burst_mode_get(port_id, queue_id, mode, ret); 62036679cf21SAnkur Dwivedi 62046679cf21SAnkur Dwivedi return ret; 620599a2dd95SBruce Richardson } 620699a2dd95SBruce Richardson 620799a2dd95SBruce Richardson int 620899a2dd95SBruce Richardson rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id, 620999a2dd95SBruce Richardson struct rte_eth_burst_mode *mode) 621099a2dd95SBruce Richardson { 621199a2dd95SBruce Richardson struct rte_eth_dev *dev; 62126679cf21SAnkur Dwivedi int ret; 621399a2dd95SBruce Richardson 621499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 621599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 621699a2dd95SBruce Richardson 621799a2dd95SBruce Richardson if (queue_id >= dev->data->nb_tx_queues) { 62180e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", queue_id); 621999a2dd95SBruce Richardson return -EINVAL; 622099a2dd95SBruce Richardson } 622199a2dd95SBruce Richardson 622253ef1b34SMin Hu (Connor) if (mode == NULL) { 62230e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 62240e21c7c0SDavid Marchand "Cannot get ethdev port %u Tx queue %u burst mode to NULL", 622553ef1b34SMin Hu (Connor) port_id, queue_id); 622653ef1b34SMin Hu (Connor) return -EINVAL; 622753ef1b34SMin Hu (Connor) } 622853ef1b34SMin Hu (Connor) 62298f1d23ecSDavid Marchand if (*dev->dev_ops->tx_burst_mode_get == NULL) 62308f1d23ecSDavid Marchand return -ENOTSUP; 623199a2dd95SBruce Richardson memset(mode, 0, sizeof(*mode)); 62326679cf21SAnkur Dwivedi ret = eth_err(port_id, 623399a2dd95SBruce Richardson dev->dev_ops->tx_burst_mode_get(dev, queue_id, mode)); 62346679cf21SAnkur Dwivedi 62356679cf21SAnkur Dwivedi rte_eth_trace_tx_burst_mode_get(port_id, queue_id, mode, ret); 62366679cf21SAnkur Dwivedi 62376679cf21SAnkur Dwivedi return ret; 623899a2dd95SBruce Richardson } 623999a2dd95SBruce Richardson 624099a2dd95SBruce Richardson int 624199a2dd95SBruce Richardson rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id, 624299a2dd95SBruce Richardson struct rte_power_monitor_cond *pmc) 624399a2dd95SBruce Richardson { 624499a2dd95SBruce Richardson struct rte_eth_dev *dev; 62456679cf21SAnkur Dwivedi int ret; 624699a2dd95SBruce Richardson 624799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 624899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 624999a2dd95SBruce Richardson 625099a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 62510e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id); 625299a2dd95SBruce Richardson return -EINVAL; 625399a2dd95SBruce Richardson } 625499a2dd95SBruce Richardson 625599a2dd95SBruce Richardson if (pmc == NULL) { 62560e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 62570e21c7c0SDavid Marchand "Cannot get ethdev port %u Rx queue %u power monitor condition to NULL", 625853ef1b34SMin Hu (Connor) port_id, queue_id); 625999a2dd95SBruce Richardson return -EINVAL; 626099a2dd95SBruce Richardson } 626199a2dd95SBruce Richardson 62628f1d23ecSDavid Marchand if (*dev->dev_ops->get_monitor_addr == NULL) 62638f1d23ecSDavid Marchand return -ENOTSUP; 62646679cf21SAnkur Dwivedi ret = eth_err(port_id, 626553ef1b34SMin Hu (Connor) dev->dev_ops->get_monitor_addr(dev->data->rx_queues[queue_id], pmc)); 62666679cf21SAnkur Dwivedi 62676679cf21SAnkur Dwivedi rte_eth_trace_get_monitor_addr(port_id, queue_id, pmc, ret); 62686679cf21SAnkur Dwivedi 62696679cf21SAnkur Dwivedi return ret; 627099a2dd95SBruce Richardson } 627199a2dd95SBruce Richardson 627299a2dd95SBruce Richardson int 627399a2dd95SBruce Richardson rte_eth_dev_set_mc_addr_list(uint16_t port_id, 627499a2dd95SBruce Richardson struct rte_ether_addr *mc_addr_set, 627599a2dd95SBruce Richardson uint32_t nb_mc_addr) 627699a2dd95SBruce Richardson { 627799a2dd95SBruce Richardson struct rte_eth_dev *dev; 62786679cf21SAnkur Dwivedi int ret; 627999a2dd95SBruce Richardson 628099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 628199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 628253ef1b34SMin Hu (Connor) 62838f1d23ecSDavid Marchand if (*dev->dev_ops->set_mc_addr_list == NULL) 62848f1d23ecSDavid Marchand return -ENOTSUP; 62856679cf21SAnkur Dwivedi ret = eth_err(port_id, dev->dev_ops->set_mc_addr_list(dev, 628699a2dd95SBruce Richardson mc_addr_set, nb_mc_addr)); 62876679cf21SAnkur Dwivedi 62886679cf21SAnkur Dwivedi rte_ethdev_trace_set_mc_addr_list(port_id, mc_addr_set, nb_mc_addr, 62896679cf21SAnkur Dwivedi ret); 62906679cf21SAnkur Dwivedi 62916679cf21SAnkur Dwivedi return ret; 629299a2dd95SBruce Richardson } 629399a2dd95SBruce Richardson 629499a2dd95SBruce Richardson int 629599a2dd95SBruce Richardson rte_eth_timesync_enable(uint16_t port_id) 629699a2dd95SBruce Richardson { 629799a2dd95SBruce Richardson struct rte_eth_dev *dev; 62986679cf21SAnkur Dwivedi int ret; 629999a2dd95SBruce Richardson 630099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 630199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 630299a2dd95SBruce Richardson 63038f1d23ecSDavid Marchand if (*dev->dev_ops->timesync_enable == NULL) 63048f1d23ecSDavid Marchand return -ENOTSUP; 63056679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->timesync_enable)(dev)); 63066679cf21SAnkur Dwivedi 63076679cf21SAnkur Dwivedi rte_eth_trace_timesync_enable(port_id, ret); 63086679cf21SAnkur Dwivedi 63096679cf21SAnkur Dwivedi return ret; 631099a2dd95SBruce Richardson } 631199a2dd95SBruce Richardson 631299a2dd95SBruce Richardson int 631399a2dd95SBruce Richardson rte_eth_timesync_disable(uint16_t port_id) 631499a2dd95SBruce Richardson { 631599a2dd95SBruce Richardson struct rte_eth_dev *dev; 63166679cf21SAnkur Dwivedi int ret; 631799a2dd95SBruce Richardson 631899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 631999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 632099a2dd95SBruce Richardson 63218f1d23ecSDavid Marchand if (*dev->dev_ops->timesync_disable == NULL) 63228f1d23ecSDavid Marchand return -ENOTSUP; 63236679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->timesync_disable)(dev)); 63246679cf21SAnkur Dwivedi 63256679cf21SAnkur Dwivedi rte_eth_trace_timesync_disable(port_id, ret); 63266679cf21SAnkur Dwivedi 63276679cf21SAnkur Dwivedi return ret; 632899a2dd95SBruce Richardson } 632999a2dd95SBruce Richardson 633099a2dd95SBruce Richardson int 633199a2dd95SBruce Richardson rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp, 633299a2dd95SBruce Richardson uint32_t flags) 633399a2dd95SBruce Richardson { 633499a2dd95SBruce Richardson struct rte_eth_dev *dev; 63356679cf21SAnkur Dwivedi int ret; 633699a2dd95SBruce Richardson 633799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 633899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 633999a2dd95SBruce Richardson 634053ef1b34SMin Hu (Connor) if (timestamp == NULL) { 63410e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 63420e21c7c0SDavid Marchand "Cannot read ethdev port %u Rx timestamp to NULL", 634353ef1b34SMin Hu (Connor) port_id); 634453ef1b34SMin Hu (Connor) return -EINVAL; 634553ef1b34SMin Hu (Connor) } 634653ef1b34SMin Hu (Connor) 63478f1d23ecSDavid Marchand if (*dev->dev_ops->timesync_read_rx_timestamp == NULL) 63488f1d23ecSDavid Marchand return -ENOTSUP; 63496679cf21SAnkur Dwivedi 63506679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp) 635199a2dd95SBruce Richardson (dev, timestamp, flags)); 63526679cf21SAnkur Dwivedi 63536679cf21SAnkur Dwivedi rte_eth_trace_timesync_read_rx_timestamp(port_id, timestamp, flags, 63546679cf21SAnkur Dwivedi ret); 63556679cf21SAnkur Dwivedi 63566679cf21SAnkur Dwivedi return ret; 635799a2dd95SBruce Richardson } 635899a2dd95SBruce Richardson 635999a2dd95SBruce Richardson int 636099a2dd95SBruce Richardson rte_eth_timesync_read_tx_timestamp(uint16_t port_id, 636199a2dd95SBruce Richardson struct timespec *timestamp) 636299a2dd95SBruce Richardson { 636399a2dd95SBruce Richardson struct rte_eth_dev *dev; 63646679cf21SAnkur Dwivedi int ret; 636599a2dd95SBruce Richardson 636699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 636799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 636899a2dd95SBruce Richardson 636953ef1b34SMin Hu (Connor) if (timestamp == NULL) { 63700e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 63710e21c7c0SDavid Marchand "Cannot read ethdev port %u Tx timestamp to NULL", 637253ef1b34SMin Hu (Connor) port_id); 637353ef1b34SMin Hu (Connor) return -EINVAL; 637453ef1b34SMin Hu (Connor) } 637553ef1b34SMin Hu (Connor) 63768f1d23ecSDavid Marchand if (*dev->dev_ops->timesync_read_tx_timestamp == NULL) 63778f1d23ecSDavid Marchand return -ENOTSUP; 63786679cf21SAnkur Dwivedi 63796679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp) 638099a2dd95SBruce Richardson (dev, timestamp)); 63816679cf21SAnkur Dwivedi 63826679cf21SAnkur Dwivedi rte_eth_trace_timesync_read_tx_timestamp(port_id, timestamp, ret); 63836679cf21SAnkur Dwivedi 63846679cf21SAnkur Dwivedi return ret; 63856679cf21SAnkur Dwivedi 638699a2dd95SBruce Richardson } 638799a2dd95SBruce Richardson 638899a2dd95SBruce Richardson int 638999a2dd95SBruce Richardson rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta) 639099a2dd95SBruce Richardson { 639199a2dd95SBruce Richardson struct rte_eth_dev *dev; 63926679cf21SAnkur Dwivedi int ret; 639399a2dd95SBruce Richardson 639499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 639599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 639699a2dd95SBruce Richardson 63978f1d23ecSDavid Marchand if (*dev->dev_ops->timesync_adjust_time == NULL) 63988f1d23ecSDavid Marchand return -ENOTSUP; 63996679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->timesync_adjust_time)(dev, delta)); 64006679cf21SAnkur Dwivedi 64016679cf21SAnkur Dwivedi rte_eth_trace_timesync_adjust_time(port_id, delta, ret); 64026679cf21SAnkur Dwivedi 64036679cf21SAnkur Dwivedi return ret; 640499a2dd95SBruce Richardson } 640599a2dd95SBruce Richardson 640699a2dd95SBruce Richardson int 6407be86a682SMingjin Ye rte_eth_timesync_adjust_freq(uint16_t port_id, int64_t ppm) 6408be86a682SMingjin Ye { 6409be86a682SMingjin Ye struct rte_eth_dev *dev; 6410be86a682SMingjin Ye int ret; 6411be86a682SMingjin Ye 6412be86a682SMingjin Ye RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 6413be86a682SMingjin Ye dev = &rte_eth_devices[port_id]; 6414be86a682SMingjin Ye 6415be86a682SMingjin Ye if (*dev->dev_ops->timesync_adjust_freq == NULL) 6416be86a682SMingjin Ye return -ENOTSUP; 6417be86a682SMingjin Ye ret = eth_err(port_id, (*dev->dev_ops->timesync_adjust_freq)(dev, ppm)); 6418be86a682SMingjin Ye 6419be86a682SMingjin Ye rte_eth_trace_timesync_adjust_freq(port_id, ppm, ret); 6420be86a682SMingjin Ye 6421be86a682SMingjin Ye return ret; 6422be86a682SMingjin Ye } 6423be86a682SMingjin Ye 6424be86a682SMingjin Ye int 642599a2dd95SBruce Richardson rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp) 642699a2dd95SBruce Richardson { 642799a2dd95SBruce Richardson struct rte_eth_dev *dev; 64286679cf21SAnkur Dwivedi int ret; 642999a2dd95SBruce Richardson 643099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 643199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 643299a2dd95SBruce Richardson 643353ef1b34SMin Hu (Connor) if (timestamp == NULL) { 64340e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 64350e21c7c0SDavid Marchand "Cannot read ethdev port %u timesync time to NULL", 643653ef1b34SMin Hu (Connor) port_id); 643753ef1b34SMin Hu (Connor) return -EINVAL; 643853ef1b34SMin Hu (Connor) } 643953ef1b34SMin Hu (Connor) 64408f1d23ecSDavid Marchand if (*dev->dev_ops->timesync_read_time == NULL) 64418f1d23ecSDavid Marchand return -ENOTSUP; 64426679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev, 644399a2dd95SBruce Richardson timestamp)); 64446679cf21SAnkur Dwivedi 64456679cf21SAnkur Dwivedi rte_eth_trace_timesync_read_time(port_id, timestamp, ret); 64466679cf21SAnkur Dwivedi 64476679cf21SAnkur Dwivedi return ret; 644899a2dd95SBruce Richardson } 644999a2dd95SBruce Richardson 645099a2dd95SBruce Richardson int 645199a2dd95SBruce Richardson rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp) 645299a2dd95SBruce Richardson { 645399a2dd95SBruce Richardson struct rte_eth_dev *dev; 64546679cf21SAnkur Dwivedi int ret; 645599a2dd95SBruce Richardson 645699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 645799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 645899a2dd95SBruce Richardson 645953ef1b34SMin Hu (Connor) if (timestamp == NULL) { 64600e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 64610e21c7c0SDavid Marchand "Cannot write ethdev port %u timesync from NULL time", 646253ef1b34SMin Hu (Connor) port_id); 646353ef1b34SMin Hu (Connor) return -EINVAL; 646453ef1b34SMin Hu (Connor) } 646553ef1b34SMin Hu (Connor) 64668f1d23ecSDavid Marchand if (*dev->dev_ops->timesync_write_time == NULL) 64678f1d23ecSDavid Marchand return -ENOTSUP; 64686679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev, 646999a2dd95SBruce Richardson timestamp)); 64706679cf21SAnkur Dwivedi 64716679cf21SAnkur Dwivedi rte_eth_trace_timesync_write_time(port_id, timestamp, ret); 64726679cf21SAnkur Dwivedi 64736679cf21SAnkur Dwivedi return ret; 647499a2dd95SBruce Richardson } 647599a2dd95SBruce Richardson 647699a2dd95SBruce Richardson int 647799a2dd95SBruce Richardson rte_eth_read_clock(uint16_t port_id, uint64_t *clock) 647899a2dd95SBruce Richardson { 647999a2dd95SBruce Richardson struct rte_eth_dev *dev; 64806679cf21SAnkur Dwivedi int ret; 648199a2dd95SBruce Richardson 648299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 648399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 648499a2dd95SBruce Richardson 648553ef1b34SMin Hu (Connor) if (clock == NULL) { 64860e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot read ethdev port %u clock to NULL", 648753ef1b34SMin Hu (Connor) port_id); 648853ef1b34SMin Hu (Connor) return -EINVAL; 648953ef1b34SMin Hu (Connor) } 649053ef1b34SMin Hu (Connor) 64918f1d23ecSDavid Marchand if (*dev->dev_ops->read_clock == NULL) 64928f1d23ecSDavid Marchand return -ENOTSUP; 64936679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock)); 64946679cf21SAnkur Dwivedi 64956679cf21SAnkur Dwivedi rte_eth_trace_read_clock(port_id, clock, ret); 64966679cf21SAnkur Dwivedi 64976679cf21SAnkur Dwivedi return ret; 649899a2dd95SBruce Richardson } 649999a2dd95SBruce Richardson 650099a2dd95SBruce Richardson int 650199a2dd95SBruce Richardson rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info) 650299a2dd95SBruce Richardson { 6503083db2edSJie Hai struct rte_dev_reg_info reg_info = { 0 }; 6504083db2edSJie Hai int ret; 6505083db2edSJie Hai 6506083db2edSJie Hai if (info == NULL) { 6507083db2edSJie Hai RTE_ETHDEV_LOG_LINE(ERR, 6508083db2edSJie Hai "Cannot get ethdev port %u register info to NULL", 6509083db2edSJie Hai port_id); 6510083db2edSJie Hai return -EINVAL; 6511083db2edSJie Hai } 6512083db2edSJie Hai 6513083db2edSJie Hai reg_info.length = info->length; 6514083db2edSJie Hai reg_info.data = info->data; 6515083db2edSJie Hai 6516083db2edSJie Hai ret = rte_eth_dev_get_reg_info_ext(port_id, ®_info); 6517083db2edSJie Hai if (ret != 0) 6518083db2edSJie Hai return ret; 6519083db2edSJie Hai 6520083db2edSJie Hai info->length = reg_info.length; 6521083db2edSJie Hai info->width = reg_info.width; 6522083db2edSJie Hai info->version = reg_info.version; 6523083db2edSJie Hai info->offset = reg_info.offset; 6524083db2edSJie Hai 6525083db2edSJie Hai return 0; 6526083db2edSJie Hai } 6527083db2edSJie Hai 6528083db2edSJie Hai int 6529083db2edSJie Hai rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info) 6530083db2edSJie Hai { 653199a2dd95SBruce Richardson struct rte_eth_dev *dev; 6532083db2edSJie Hai uint32_t i; 65336679cf21SAnkur Dwivedi int ret; 653499a2dd95SBruce Richardson 653599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 653699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 653753ef1b34SMin Hu (Connor) 653853ef1b34SMin Hu (Connor) if (info == NULL) { 65390e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 65400e21c7c0SDavid Marchand "Cannot get ethdev port %u register info to NULL", 654153ef1b34SMin Hu (Connor) port_id); 654253ef1b34SMin Hu (Connor) return -EINVAL; 654353ef1b34SMin Hu (Connor) } 654453ef1b34SMin Hu (Connor) 6545083db2edSJie Hai if (info->names != NULL && info->length != 0) 6546083db2edSJie Hai memset(info->names, 0, sizeof(struct rte_eth_reg_name) * info->length); 6547083db2edSJie Hai 65488f1d23ecSDavid Marchand if (*dev->dev_ops->get_reg == NULL) 65498f1d23ecSDavid Marchand return -ENOTSUP; 65506679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info)); 65516679cf21SAnkur Dwivedi 65526679cf21SAnkur Dwivedi rte_ethdev_trace_get_reg_info(port_id, info, ret); 65536679cf21SAnkur Dwivedi 6554083db2edSJie Hai /* Report the default names if drivers not report. */ 6555083db2edSJie Hai if (ret == 0 && info->names != NULL && strlen(info->names[0].name) == 0) { 6556083db2edSJie Hai for (i = 0; i < info->length; i++) 6557083db2edSJie Hai snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE, 6558083db2edSJie Hai "index_%u", info->offset + i); 6559083db2edSJie Hai } 65606679cf21SAnkur Dwivedi return ret; 656199a2dd95SBruce Richardson } 656299a2dd95SBruce Richardson 656399a2dd95SBruce Richardson int 656499a2dd95SBruce Richardson rte_eth_dev_get_eeprom_length(uint16_t port_id) 656599a2dd95SBruce Richardson { 656699a2dd95SBruce Richardson struct rte_eth_dev *dev; 65676679cf21SAnkur Dwivedi int ret; 656899a2dd95SBruce Richardson 656999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 657099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 657153ef1b34SMin Hu (Connor) 65728f1d23ecSDavid Marchand if (*dev->dev_ops->get_eeprom_length == NULL) 65738f1d23ecSDavid Marchand return -ENOTSUP; 65746679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->get_eeprom_length)(dev)); 65756679cf21SAnkur Dwivedi 65766679cf21SAnkur Dwivedi rte_ethdev_trace_get_eeprom_length(port_id, ret); 65776679cf21SAnkur Dwivedi 65786679cf21SAnkur Dwivedi return ret; 657999a2dd95SBruce Richardson } 658099a2dd95SBruce Richardson 658199a2dd95SBruce Richardson int 658299a2dd95SBruce Richardson rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) 658399a2dd95SBruce Richardson { 658499a2dd95SBruce Richardson struct rte_eth_dev *dev; 65856679cf21SAnkur Dwivedi int ret; 658699a2dd95SBruce Richardson 658799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 658899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 658953ef1b34SMin Hu (Connor) 659053ef1b34SMin Hu (Connor) if (info == NULL) { 65910e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 65920e21c7c0SDavid Marchand "Cannot get ethdev port %u EEPROM info to NULL", 659353ef1b34SMin Hu (Connor) port_id); 659453ef1b34SMin Hu (Connor) return -EINVAL; 659553ef1b34SMin Hu (Connor) } 659653ef1b34SMin Hu (Connor) 65978f1d23ecSDavid Marchand if (*dev->dev_ops->get_eeprom == NULL) 65988f1d23ecSDavid Marchand return -ENOTSUP; 65996679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->get_eeprom)(dev, info)); 66006679cf21SAnkur Dwivedi 66016679cf21SAnkur Dwivedi rte_ethdev_trace_get_eeprom(port_id, info, ret); 66026679cf21SAnkur Dwivedi 66036679cf21SAnkur Dwivedi return ret; 660499a2dd95SBruce Richardson } 660599a2dd95SBruce Richardson 660699a2dd95SBruce Richardson int 660799a2dd95SBruce Richardson rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) 660899a2dd95SBruce Richardson { 660999a2dd95SBruce Richardson struct rte_eth_dev *dev; 66106679cf21SAnkur Dwivedi int ret; 661199a2dd95SBruce Richardson 661299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 661399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 661453ef1b34SMin Hu (Connor) 661553ef1b34SMin Hu (Connor) if (info == NULL) { 66160e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 66170e21c7c0SDavid Marchand "Cannot set ethdev port %u EEPROM from NULL info", 661853ef1b34SMin Hu (Connor) port_id); 661953ef1b34SMin Hu (Connor) return -EINVAL; 662053ef1b34SMin Hu (Connor) } 662153ef1b34SMin Hu (Connor) 66228f1d23ecSDavid Marchand if (*dev->dev_ops->set_eeprom == NULL) 66238f1d23ecSDavid Marchand return -ENOTSUP; 66246679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->set_eeprom)(dev, info)); 66256679cf21SAnkur Dwivedi 66266679cf21SAnkur Dwivedi rte_ethdev_trace_set_eeprom(port_id, info, ret); 66276679cf21SAnkur Dwivedi 66286679cf21SAnkur Dwivedi return ret; 662999a2dd95SBruce Richardson } 663099a2dd95SBruce Richardson 663199a2dd95SBruce Richardson int 663299a2dd95SBruce Richardson rte_eth_dev_get_module_info(uint16_t port_id, 663399a2dd95SBruce Richardson struct rte_eth_dev_module_info *modinfo) 663499a2dd95SBruce Richardson { 663599a2dd95SBruce Richardson struct rte_eth_dev *dev; 66366679cf21SAnkur Dwivedi int ret; 663799a2dd95SBruce Richardson 663899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 663999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 664053ef1b34SMin Hu (Connor) 664153ef1b34SMin Hu (Connor) if (modinfo == NULL) { 66420e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 66430e21c7c0SDavid Marchand "Cannot get ethdev port %u EEPROM module info to NULL", 664453ef1b34SMin Hu (Connor) port_id); 664553ef1b34SMin Hu (Connor) return -EINVAL; 664653ef1b34SMin Hu (Connor) } 664753ef1b34SMin Hu (Connor) 66488f1d23ecSDavid Marchand if (*dev->dev_ops->get_module_info == NULL) 66498f1d23ecSDavid Marchand return -ENOTSUP; 66506679cf21SAnkur Dwivedi ret = (*dev->dev_ops->get_module_info)(dev, modinfo); 66516679cf21SAnkur Dwivedi 66526679cf21SAnkur Dwivedi rte_ethdev_trace_get_module_info(port_id, modinfo, ret); 66536679cf21SAnkur Dwivedi 66546679cf21SAnkur Dwivedi return ret; 665599a2dd95SBruce Richardson } 665699a2dd95SBruce Richardson 665799a2dd95SBruce Richardson int 665899a2dd95SBruce Richardson rte_eth_dev_get_module_eeprom(uint16_t port_id, 665999a2dd95SBruce Richardson struct rte_dev_eeprom_info *info) 666099a2dd95SBruce Richardson { 666199a2dd95SBruce Richardson struct rte_eth_dev *dev; 66626679cf21SAnkur Dwivedi int ret; 666399a2dd95SBruce Richardson 666499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 666599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 666653ef1b34SMin Hu (Connor) 666753ef1b34SMin Hu (Connor) if (info == NULL) { 66680e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 66690e21c7c0SDavid Marchand "Cannot get ethdev port %u module EEPROM info to NULL", 667053ef1b34SMin Hu (Connor) port_id); 667153ef1b34SMin Hu (Connor) return -EINVAL; 667253ef1b34SMin Hu (Connor) } 667353ef1b34SMin Hu (Connor) 667453ef1b34SMin Hu (Connor) if (info->data == NULL) { 66750e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 66760e21c7c0SDavid Marchand "Cannot get ethdev port %u module EEPROM data to NULL", 667753ef1b34SMin Hu (Connor) port_id); 667853ef1b34SMin Hu (Connor) return -EINVAL; 667953ef1b34SMin Hu (Connor) } 668053ef1b34SMin Hu (Connor) 668153ef1b34SMin Hu (Connor) if (info->length == 0) { 66820e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 66830e21c7c0SDavid Marchand "Cannot get ethdev port %u module EEPROM to data with zero size", 668453ef1b34SMin Hu (Connor) port_id); 668553ef1b34SMin Hu (Connor) return -EINVAL; 668653ef1b34SMin Hu (Connor) } 668753ef1b34SMin Hu (Connor) 66888f1d23ecSDavid Marchand if (*dev->dev_ops->get_module_eeprom == NULL) 66898f1d23ecSDavid Marchand return -ENOTSUP; 66906679cf21SAnkur Dwivedi ret = (*dev->dev_ops->get_module_eeprom)(dev, info); 66916679cf21SAnkur Dwivedi 66926679cf21SAnkur Dwivedi rte_ethdev_trace_get_module_eeprom(port_id, info, ret); 66936679cf21SAnkur Dwivedi 66946679cf21SAnkur Dwivedi return ret; 669599a2dd95SBruce Richardson } 669699a2dd95SBruce Richardson 669799a2dd95SBruce Richardson int 669899a2dd95SBruce Richardson rte_eth_dev_get_dcb_info(uint16_t port_id, 669999a2dd95SBruce Richardson struct rte_eth_dcb_info *dcb_info) 670099a2dd95SBruce Richardson { 670199a2dd95SBruce Richardson struct rte_eth_dev *dev; 67026679cf21SAnkur Dwivedi int ret; 670399a2dd95SBruce Richardson 670499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 670599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 670653ef1b34SMin Hu (Connor) 670753ef1b34SMin Hu (Connor) if (dcb_info == NULL) { 67080e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 67090e21c7c0SDavid Marchand "Cannot get ethdev port %u DCB info to NULL", 671053ef1b34SMin Hu (Connor) port_id); 671153ef1b34SMin Hu (Connor) return -EINVAL; 671253ef1b34SMin Hu (Connor) } 671353ef1b34SMin Hu (Connor) 671499a2dd95SBruce Richardson memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info)); 671599a2dd95SBruce Richardson 67168f1d23ecSDavid Marchand if (*dev->dev_ops->get_dcb_info == NULL) 67178f1d23ecSDavid Marchand return -ENOTSUP; 67186679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->get_dcb_info)(dev, dcb_info)); 67196679cf21SAnkur Dwivedi 67206679cf21SAnkur Dwivedi rte_ethdev_trace_get_dcb_info(port_id, dcb_info, ret); 67216679cf21SAnkur Dwivedi 67226679cf21SAnkur Dwivedi return ret; 672399a2dd95SBruce Richardson } 672499a2dd95SBruce Richardson 672599a2dd95SBruce Richardson static void 672699a2dd95SBruce Richardson eth_dev_adjust_nb_desc(uint16_t *nb_desc, 672799a2dd95SBruce Richardson const struct rte_eth_desc_lim *desc_lim) 672899a2dd95SBruce Richardson { 672930efe60dSNiall Meade /* Upcast to uint32 to avoid potential overflow with RTE_ALIGN_CEIL(). */ 673030efe60dSNiall Meade uint32_t nb_desc_32 = (uint32_t)*nb_desc; 673130efe60dSNiall Meade 673299a2dd95SBruce Richardson if (desc_lim->nb_align != 0) 673330efe60dSNiall Meade nb_desc_32 = RTE_ALIGN_CEIL(nb_desc_32, desc_lim->nb_align); 673499a2dd95SBruce Richardson 673599a2dd95SBruce Richardson if (desc_lim->nb_max != 0) 673630efe60dSNiall Meade nb_desc_32 = RTE_MIN(nb_desc_32, desc_lim->nb_max); 673799a2dd95SBruce Richardson 673830efe60dSNiall Meade nb_desc_32 = RTE_MAX(nb_desc_32, desc_lim->nb_min); 673930efe60dSNiall Meade 674030efe60dSNiall Meade /* Assign clipped u32 back to u16. */ 674130efe60dSNiall Meade *nb_desc = (uint16_t)nb_desc_32; 674299a2dd95SBruce Richardson } 674399a2dd95SBruce Richardson 674499a2dd95SBruce Richardson int 674599a2dd95SBruce Richardson rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id, 674699a2dd95SBruce Richardson uint16_t *nb_rx_desc, 674799a2dd95SBruce Richardson uint16_t *nb_tx_desc) 674899a2dd95SBruce Richardson { 674999a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 675099a2dd95SBruce Richardson int ret; 675199a2dd95SBruce Richardson 675299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 675399a2dd95SBruce Richardson 675499a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 675599a2dd95SBruce Richardson if (ret != 0) 675699a2dd95SBruce Richardson return ret; 675799a2dd95SBruce Richardson 675899a2dd95SBruce Richardson if (nb_rx_desc != NULL) 675999a2dd95SBruce Richardson eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim); 676099a2dd95SBruce Richardson 676199a2dd95SBruce Richardson if (nb_tx_desc != NULL) 676299a2dd95SBruce Richardson eth_dev_adjust_nb_desc(nb_tx_desc, &dev_info.tx_desc_lim); 676399a2dd95SBruce Richardson 67646679cf21SAnkur Dwivedi rte_ethdev_trace_adjust_nb_rx_tx_desc(port_id); 67656679cf21SAnkur Dwivedi 676699a2dd95SBruce Richardson return 0; 676799a2dd95SBruce Richardson } 676899a2dd95SBruce Richardson 676999a2dd95SBruce Richardson int 677099a2dd95SBruce Richardson rte_eth_dev_hairpin_capability_get(uint16_t port_id, 677199a2dd95SBruce Richardson struct rte_eth_hairpin_cap *cap) 677299a2dd95SBruce Richardson { 677399a2dd95SBruce Richardson struct rte_eth_dev *dev; 67746679cf21SAnkur Dwivedi int ret; 677599a2dd95SBruce Richardson 677699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 677799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 677853ef1b34SMin Hu (Connor) 677953ef1b34SMin Hu (Connor) if (cap == NULL) { 67800e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 67810e21c7c0SDavid Marchand "Cannot get ethdev port %u hairpin capability to NULL", 678253ef1b34SMin Hu (Connor) port_id); 678353ef1b34SMin Hu (Connor) return -EINVAL; 678453ef1b34SMin Hu (Connor) } 678553ef1b34SMin Hu (Connor) 67868f1d23ecSDavid Marchand if (*dev->dev_ops->hairpin_cap_get == NULL) 67878f1d23ecSDavid Marchand return -ENOTSUP; 678899a2dd95SBruce Richardson memset(cap, 0, sizeof(*cap)); 67896679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap)); 67906679cf21SAnkur Dwivedi 67916679cf21SAnkur Dwivedi rte_ethdev_trace_hairpin_capability_get(port_id, cap, ret); 67926679cf21SAnkur Dwivedi 67936679cf21SAnkur Dwivedi return ret; 679499a2dd95SBruce Richardson } 679599a2dd95SBruce Richardson 679699a2dd95SBruce Richardson int 679799a2dd95SBruce Richardson rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) 679899a2dd95SBruce Richardson { 679999a2dd95SBruce Richardson struct rte_eth_dev *dev; 68006679cf21SAnkur Dwivedi int ret; 680199a2dd95SBruce Richardson 680299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 680399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 680499a2dd95SBruce Richardson 680553ef1b34SMin Hu (Connor) if (pool == NULL) { 68060e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 68070e21c7c0SDavid Marchand "Cannot test ethdev port %u mempool operation from NULL pool", 680853ef1b34SMin Hu (Connor) port_id); 680953ef1b34SMin Hu (Connor) return -EINVAL; 681053ef1b34SMin Hu (Connor) } 681153ef1b34SMin Hu (Connor) 681299a2dd95SBruce Richardson if (*dev->dev_ops->pool_ops_supported == NULL) 681399a2dd95SBruce Richardson return 1; /* all pools are supported */ 681499a2dd95SBruce Richardson 68156679cf21SAnkur Dwivedi ret = (*dev->dev_ops->pool_ops_supported)(dev, pool); 68166679cf21SAnkur Dwivedi 68176679cf21SAnkur Dwivedi rte_ethdev_trace_pool_ops_supported(port_id, pool, ret); 68186679cf21SAnkur Dwivedi 68196679cf21SAnkur Dwivedi return ret; 682099a2dd95SBruce Richardson } 682199a2dd95SBruce Richardson 682299a2dd95SBruce Richardson int 682399a2dd95SBruce Richardson rte_eth_representor_info_get(uint16_t port_id, 682499a2dd95SBruce Richardson struct rte_eth_representor_info *info) 682599a2dd95SBruce Richardson { 682699a2dd95SBruce Richardson struct rte_eth_dev *dev; 68276679cf21SAnkur Dwivedi int ret; 682899a2dd95SBruce Richardson 682999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 683099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 683199a2dd95SBruce Richardson 68328f1d23ecSDavid Marchand if (*dev->dev_ops->representor_info_get == NULL) 68338f1d23ecSDavid Marchand return -ENOTSUP; 68346679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->representor_info_get)(dev, info)); 68356679cf21SAnkur Dwivedi 68366679cf21SAnkur Dwivedi rte_eth_trace_representor_info_get(port_id, info, ret); 68376679cf21SAnkur Dwivedi 68386679cf21SAnkur Dwivedi return ret; 683999a2dd95SBruce Richardson } 684099a2dd95SBruce Richardson 6841f6d8a6d3SIvan Malov int 6842f6d8a6d3SIvan Malov rte_eth_rx_metadata_negotiate(uint16_t port_id, uint64_t *features) 6843f6d8a6d3SIvan Malov { 6844f6d8a6d3SIvan Malov struct rte_eth_dev *dev; 68456679cf21SAnkur Dwivedi int ret; 6846f6d8a6d3SIvan Malov 6847f6d8a6d3SIvan Malov RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 6848f6d8a6d3SIvan Malov dev = &rte_eth_devices[port_id]; 6849f6d8a6d3SIvan Malov 6850f6d8a6d3SIvan Malov if (dev->data->dev_configured != 0) { 68510e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 68520e21c7c0SDavid Marchand "The port (ID=%"PRIu16") is already configured", 6853f6d8a6d3SIvan Malov port_id); 6854f6d8a6d3SIvan Malov return -EBUSY; 6855f6d8a6d3SIvan Malov } 6856f6d8a6d3SIvan Malov 6857f6d8a6d3SIvan Malov if (features == NULL) { 68580e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid features (NULL)"); 6859f6d8a6d3SIvan Malov return -EINVAL; 6860f6d8a6d3SIvan Malov } 6861f6d8a6d3SIvan Malov 6862fca8cba4SDavid Marchand if ((*features & RTE_ETH_RX_METADATA_TUNNEL_ID) != 0 && 6863fca8cba4SDavid Marchand rte_flow_restore_info_dynflag_register() < 0) 6864fca8cba4SDavid Marchand *features &= ~RTE_ETH_RX_METADATA_TUNNEL_ID; 6865fca8cba4SDavid Marchand 68668f1d23ecSDavid Marchand if (*dev->dev_ops->rx_metadata_negotiate == NULL) 68678f1d23ecSDavid Marchand return -ENOTSUP; 68686679cf21SAnkur Dwivedi ret = eth_err(port_id, 6869f6d8a6d3SIvan Malov (*dev->dev_ops->rx_metadata_negotiate)(dev, features)); 68706679cf21SAnkur Dwivedi 68716679cf21SAnkur Dwivedi rte_eth_trace_rx_metadata_negotiate(port_id, *features, ret); 68726679cf21SAnkur Dwivedi 68736679cf21SAnkur Dwivedi return ret; 6874f6d8a6d3SIvan Malov } 6875f6d8a6d3SIvan Malov 6876a75ab6e5SAkhil Goyal int 6877a75ab6e5SAkhil Goyal rte_eth_ip_reassembly_capability_get(uint16_t port_id, 6878a75ab6e5SAkhil Goyal struct rte_eth_ip_reassembly_params *reassembly_capa) 6879a75ab6e5SAkhil Goyal { 6880a75ab6e5SAkhil Goyal struct rte_eth_dev *dev; 68816679cf21SAnkur Dwivedi int ret; 6882a75ab6e5SAkhil Goyal 6883a75ab6e5SAkhil Goyal RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 6884a75ab6e5SAkhil Goyal dev = &rte_eth_devices[port_id]; 6885a75ab6e5SAkhil Goyal 6886a75ab6e5SAkhil Goyal if (dev->data->dev_configured == 0) { 68870e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 68880e21c7c0SDavid Marchand "port_id=%u is not configured, cannot get IP reassembly capability", 6889a75ab6e5SAkhil Goyal port_id); 6890a75ab6e5SAkhil Goyal return -EINVAL; 6891a75ab6e5SAkhil Goyal } 6892a75ab6e5SAkhil Goyal 6893a75ab6e5SAkhil Goyal if (reassembly_capa == NULL) { 68940e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get reassembly capability to NULL"); 6895a75ab6e5SAkhil Goyal return -EINVAL; 6896a75ab6e5SAkhil Goyal } 6897a75ab6e5SAkhil Goyal 68988f1d23ecSDavid Marchand if (*dev->dev_ops->ip_reassembly_capability_get == NULL) 68998f1d23ecSDavid Marchand return -ENOTSUP; 6900a75ab6e5SAkhil Goyal memset(reassembly_capa, 0, sizeof(struct rte_eth_ip_reassembly_params)); 6901a75ab6e5SAkhil Goyal 69026679cf21SAnkur Dwivedi ret = eth_err(port_id, (*dev->dev_ops->ip_reassembly_capability_get) 6903a75ab6e5SAkhil Goyal (dev, reassembly_capa)); 69046679cf21SAnkur Dwivedi 69056679cf21SAnkur Dwivedi rte_eth_trace_ip_reassembly_capability_get(port_id, reassembly_capa, 69066679cf21SAnkur Dwivedi ret); 69076679cf21SAnkur Dwivedi 69086679cf21SAnkur Dwivedi return ret; 6909a75ab6e5SAkhil Goyal } 6910a75ab6e5SAkhil Goyal 6911a75ab6e5SAkhil Goyal int 6912a75ab6e5SAkhil Goyal rte_eth_ip_reassembly_conf_get(uint16_t port_id, 6913a75ab6e5SAkhil Goyal struct rte_eth_ip_reassembly_params *conf) 6914a75ab6e5SAkhil Goyal { 6915a75ab6e5SAkhil Goyal struct rte_eth_dev *dev; 69166679cf21SAnkur Dwivedi int ret; 6917a75ab6e5SAkhil Goyal 6918a75ab6e5SAkhil Goyal RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 6919a75ab6e5SAkhil Goyal dev = &rte_eth_devices[port_id]; 6920a75ab6e5SAkhil Goyal 6921a75ab6e5SAkhil Goyal if (dev->data->dev_configured == 0) { 69220e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 69230e21c7c0SDavid Marchand "port_id=%u is not configured, cannot get IP reassembly configuration", 6924a75ab6e5SAkhil Goyal port_id); 6925a75ab6e5SAkhil Goyal return -EINVAL; 6926a75ab6e5SAkhil Goyal } 6927a75ab6e5SAkhil Goyal 6928a75ab6e5SAkhil Goyal if (conf == NULL) { 69290e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Cannot get reassembly info to NULL"); 6930a75ab6e5SAkhil Goyal return -EINVAL; 6931a75ab6e5SAkhil Goyal } 6932a75ab6e5SAkhil Goyal 69338f1d23ecSDavid Marchand if (*dev->dev_ops->ip_reassembly_conf_get == NULL) 69348f1d23ecSDavid Marchand return -ENOTSUP; 6935a75ab6e5SAkhil Goyal memset(conf, 0, sizeof(struct rte_eth_ip_reassembly_params)); 69366679cf21SAnkur Dwivedi ret = eth_err(port_id, 6937a75ab6e5SAkhil Goyal (*dev->dev_ops->ip_reassembly_conf_get)(dev, conf)); 69386679cf21SAnkur Dwivedi 69396679cf21SAnkur Dwivedi rte_eth_trace_ip_reassembly_conf_get(port_id, conf, ret); 69406679cf21SAnkur Dwivedi 69416679cf21SAnkur Dwivedi return ret; 6942a75ab6e5SAkhil Goyal } 6943a75ab6e5SAkhil Goyal 6944a75ab6e5SAkhil Goyal int 6945a75ab6e5SAkhil Goyal rte_eth_ip_reassembly_conf_set(uint16_t port_id, 6946a75ab6e5SAkhil Goyal const struct rte_eth_ip_reassembly_params *conf) 6947a75ab6e5SAkhil Goyal { 6948a75ab6e5SAkhil Goyal struct rte_eth_dev *dev; 69496679cf21SAnkur Dwivedi int ret; 6950a75ab6e5SAkhil Goyal 6951a75ab6e5SAkhil Goyal RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 6952a75ab6e5SAkhil Goyal dev = &rte_eth_devices[port_id]; 6953a75ab6e5SAkhil Goyal 6954a75ab6e5SAkhil Goyal if (dev->data->dev_configured == 0) { 69550e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 69560e21c7c0SDavid Marchand "port_id=%u is not configured, cannot set IP reassembly configuration", 6957a75ab6e5SAkhil Goyal port_id); 6958a75ab6e5SAkhil Goyal return -EINVAL; 6959a75ab6e5SAkhil Goyal } 6960a75ab6e5SAkhil Goyal 6961a75ab6e5SAkhil Goyal if (dev->data->dev_started != 0) { 69620e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 69630e21c7c0SDavid Marchand "port_id=%u is started, cannot configure IP reassembly params.", 6964a75ab6e5SAkhil Goyal port_id); 6965a75ab6e5SAkhil Goyal return -EINVAL; 6966a75ab6e5SAkhil Goyal } 6967a75ab6e5SAkhil Goyal 6968a75ab6e5SAkhil Goyal if (conf == NULL) { 69690e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 69700e21c7c0SDavid Marchand "Invalid IP reassembly configuration (NULL)"); 6971a75ab6e5SAkhil Goyal return -EINVAL; 6972a75ab6e5SAkhil Goyal } 6973a75ab6e5SAkhil Goyal 69748f1d23ecSDavid Marchand if (*dev->dev_ops->ip_reassembly_conf_set == NULL) 69758f1d23ecSDavid Marchand return -ENOTSUP; 69766679cf21SAnkur Dwivedi ret = eth_err(port_id, 6977a75ab6e5SAkhil Goyal (*dev->dev_ops->ip_reassembly_conf_set)(dev, conf)); 69786679cf21SAnkur Dwivedi 69796679cf21SAnkur Dwivedi rte_eth_trace_ip_reassembly_conf_set(port_id, conf, ret); 69806679cf21SAnkur Dwivedi 69816679cf21SAnkur Dwivedi return ret; 6982a75ab6e5SAkhil Goyal } 6983a75ab6e5SAkhil Goyal 69843c059b2cSAkhil Goyal int 6985edcf22c6SMin Hu (Connor) rte_eth_dev_priv_dump(uint16_t port_id, FILE *file) 6986edcf22c6SMin Hu (Connor) { 6987edcf22c6SMin Hu (Connor) struct rte_eth_dev *dev; 6988edcf22c6SMin Hu (Connor) 6989edcf22c6SMin Hu (Connor) RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 6990edcf22c6SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 6991edcf22c6SMin Hu (Connor) 6992edcf22c6SMin Hu (Connor) if (file == NULL) { 69930e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid file (NULL)"); 6994edcf22c6SMin Hu (Connor) return -EINVAL; 6995edcf22c6SMin Hu (Connor) } 6996edcf22c6SMin Hu (Connor) 69978f1d23ecSDavid Marchand if (*dev->dev_ops->eth_dev_priv_dump == NULL) 69988f1d23ecSDavid Marchand return -ENOTSUP; 6999edcf22c6SMin Hu (Connor) return eth_err(port_id, (*dev->dev_ops->eth_dev_priv_dump)(dev, file)); 7000edcf22c6SMin Hu (Connor) } 7001edcf22c6SMin Hu (Connor) 7002092b701fSDongdong Liu int 7003092b701fSDongdong Liu rte_eth_rx_descriptor_dump(uint16_t port_id, uint16_t queue_id, 7004092b701fSDongdong Liu uint16_t offset, uint16_t num, FILE *file) 7005092b701fSDongdong Liu { 7006092b701fSDongdong Liu struct rte_eth_dev *dev; 7007092b701fSDongdong Liu 7008092b701fSDongdong Liu RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 7009092b701fSDongdong Liu dev = &rte_eth_devices[port_id]; 7010092b701fSDongdong Liu 7011092b701fSDongdong Liu if (queue_id >= dev->data->nb_rx_queues) { 70120e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id); 7013092b701fSDongdong Liu return -EINVAL; 7014092b701fSDongdong Liu } 7015092b701fSDongdong Liu 7016092b701fSDongdong Liu if (file == NULL) { 70170e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid file (NULL)"); 7018092b701fSDongdong Liu return -EINVAL; 7019092b701fSDongdong Liu } 7020092b701fSDongdong Liu 7021092b701fSDongdong Liu if (*dev->dev_ops->eth_rx_descriptor_dump == NULL) 7022092b701fSDongdong Liu return -ENOTSUP; 7023092b701fSDongdong Liu 7024092b701fSDongdong Liu return eth_err(port_id, (*dev->dev_ops->eth_rx_descriptor_dump)(dev, 7025092b701fSDongdong Liu queue_id, offset, num, file)); 7026092b701fSDongdong Liu } 7027092b701fSDongdong Liu 7028092b701fSDongdong Liu int 7029092b701fSDongdong Liu rte_eth_tx_descriptor_dump(uint16_t port_id, uint16_t queue_id, 7030092b701fSDongdong Liu uint16_t offset, uint16_t num, FILE *file) 7031092b701fSDongdong Liu { 7032092b701fSDongdong Liu struct rte_eth_dev *dev; 7033092b701fSDongdong Liu 7034092b701fSDongdong Liu RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 7035092b701fSDongdong Liu dev = &rte_eth_devices[port_id]; 7036092b701fSDongdong Liu 7037092b701fSDongdong Liu if (queue_id >= dev->data->nb_tx_queues) { 70380e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", queue_id); 7039092b701fSDongdong Liu return -EINVAL; 7040092b701fSDongdong Liu } 7041092b701fSDongdong Liu 7042092b701fSDongdong Liu if (file == NULL) { 70430e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid file (NULL)"); 7044092b701fSDongdong Liu return -EINVAL; 7045092b701fSDongdong Liu } 7046092b701fSDongdong Liu 7047092b701fSDongdong Liu if (*dev->dev_ops->eth_tx_descriptor_dump == NULL) 7048092b701fSDongdong Liu return -ENOTSUP; 7049092b701fSDongdong Liu 7050092b701fSDongdong Liu return eth_err(port_id, (*dev->dev_ops->eth_tx_descriptor_dump)(dev, 7051092b701fSDongdong Liu queue_id, offset, num, file)); 7052092b701fSDongdong Liu } 7053092b701fSDongdong Liu 7054e4e6f4cbSYuan Wang int 7055e4e6f4cbSYuan Wang rte_eth_buffer_split_get_supported_hdr_ptypes(uint16_t port_id, uint32_t *ptypes, int num) 7056e4e6f4cbSYuan Wang { 7057ba6a168aSSivaramakrishnan Venkat size_t i; 7058ba6a168aSSivaramakrishnan Venkat int j; 7059e4e6f4cbSYuan Wang struct rte_eth_dev *dev; 7060e4e6f4cbSYuan Wang const uint32_t *all_types; 7061ba6a168aSSivaramakrishnan Venkat size_t no_of_elements = 0; 7062e4e6f4cbSYuan Wang 7063e4e6f4cbSYuan Wang RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 7064e4e6f4cbSYuan Wang dev = &rte_eth_devices[port_id]; 7065e4e6f4cbSYuan Wang 7066e4e6f4cbSYuan Wang if (ptypes == NULL && num > 0) { 70670e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 70680e21c7c0SDavid Marchand "Cannot get ethdev port %u supported header protocol types to NULL when array size is non zero", 7069e4e6f4cbSYuan Wang port_id); 7070e4e6f4cbSYuan Wang return -EINVAL; 7071e4e6f4cbSYuan Wang } 7072e4e6f4cbSYuan Wang 7073e4e6f4cbSYuan Wang if (*dev->dev_ops->buffer_split_supported_hdr_ptypes_get == NULL) 7074e4e6f4cbSYuan Wang return -ENOTSUP; 7075ba6a168aSSivaramakrishnan Venkat all_types = (*dev->dev_ops->buffer_split_supported_hdr_ptypes_get)(dev, 7076ba6a168aSSivaramakrishnan Venkat &no_of_elements); 7077e4e6f4cbSYuan Wang 7078e4e6f4cbSYuan Wang if (all_types == NULL) 7079e4e6f4cbSYuan Wang return 0; 7080e4e6f4cbSYuan Wang 7081ba6a168aSSivaramakrishnan Venkat for (i = 0, j = 0; i < no_of_elements; ++i) { 70826679cf21SAnkur Dwivedi if (j < num) { 7083e4e6f4cbSYuan Wang ptypes[j] = all_types[i]; 70846679cf21SAnkur Dwivedi 70856679cf21SAnkur Dwivedi rte_eth_trace_buffer_split_get_supported_hdr_ptypes( 70866679cf21SAnkur Dwivedi port_id, j, ptypes[j]); 70876679cf21SAnkur Dwivedi } 7088e4e6f4cbSYuan Wang j++; 7089e4e6f4cbSYuan Wang } 7090e4e6f4cbSYuan Wang 7091e4e6f4cbSYuan Wang return j; 7092e4e6f4cbSYuan Wang } 7093e4e6f4cbSYuan Wang 709406ea5479SJiawei Wang int rte_eth_dev_count_aggr_ports(uint16_t port_id) 709506ea5479SJiawei Wang { 709606ea5479SJiawei Wang struct rte_eth_dev *dev; 709706ea5479SJiawei Wang int ret; 709806ea5479SJiawei Wang 709906ea5479SJiawei Wang RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 710006ea5479SJiawei Wang dev = &rte_eth_devices[port_id]; 710106ea5479SJiawei Wang 710206ea5479SJiawei Wang if (*dev->dev_ops->count_aggr_ports == NULL) 710306ea5479SJiawei Wang return 0; 710406ea5479SJiawei Wang ret = eth_err(port_id, (*dev->dev_ops->count_aggr_ports)(dev)); 710506ea5479SJiawei Wang 710606ea5479SJiawei Wang rte_eth_trace_count_aggr_ports(port_id, ret); 710706ea5479SJiawei Wang 710806ea5479SJiawei Wang return ret; 710906ea5479SJiawei Wang } 711006ea5479SJiawei Wang 711106ea5479SJiawei Wang int rte_eth_dev_map_aggr_tx_affinity(uint16_t port_id, uint16_t tx_queue_id, 711206ea5479SJiawei Wang uint8_t affinity) 711306ea5479SJiawei Wang { 711406ea5479SJiawei Wang struct rte_eth_dev *dev; 711506ea5479SJiawei Wang int aggr_ports; 711606ea5479SJiawei Wang int ret; 711706ea5479SJiawei Wang 711806ea5479SJiawei Wang RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 711906ea5479SJiawei Wang dev = &rte_eth_devices[port_id]; 712006ea5479SJiawei Wang 712106ea5479SJiawei Wang if (tx_queue_id >= dev->data->nb_tx_queues) { 71220e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", tx_queue_id); 712306ea5479SJiawei Wang return -EINVAL; 712406ea5479SJiawei Wang } 712506ea5479SJiawei Wang 712606ea5479SJiawei Wang if (*dev->dev_ops->map_aggr_tx_affinity == NULL) 712706ea5479SJiawei Wang return -ENOTSUP; 712806ea5479SJiawei Wang 712906ea5479SJiawei Wang if (dev->data->dev_configured == 0) { 71300e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 71310e21c7c0SDavid Marchand "Port %u must be configured before Tx affinity mapping", 713206ea5479SJiawei Wang port_id); 713306ea5479SJiawei Wang return -EINVAL; 713406ea5479SJiawei Wang } 713506ea5479SJiawei Wang 713606ea5479SJiawei Wang if (dev->data->dev_started) { 71370e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 71380e21c7c0SDavid Marchand "Port %u must be stopped to allow configuration", 713906ea5479SJiawei Wang port_id); 714006ea5479SJiawei Wang return -EBUSY; 714106ea5479SJiawei Wang } 714206ea5479SJiawei Wang 714306ea5479SJiawei Wang aggr_ports = rte_eth_dev_count_aggr_ports(port_id); 714406ea5479SJiawei Wang if (aggr_ports == 0) { 71450e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 71460e21c7c0SDavid Marchand "Port %u has no aggregated port", 714706ea5479SJiawei Wang port_id); 714806ea5479SJiawei Wang return -ENOTSUP; 714906ea5479SJiawei Wang } 715006ea5479SJiawei Wang 715106ea5479SJiawei Wang if (affinity > aggr_ports) { 71520e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 71530e21c7c0SDavid Marchand "Port %u map invalid affinity %u exceeds the maximum number %u", 715406ea5479SJiawei Wang port_id, affinity, aggr_ports); 715506ea5479SJiawei Wang return -EINVAL; 715606ea5479SJiawei Wang } 715706ea5479SJiawei Wang 715806ea5479SJiawei Wang ret = eth_err(port_id, (*dev->dev_ops->map_aggr_tx_affinity)(dev, 715906ea5479SJiawei Wang tx_queue_id, affinity)); 716006ea5479SJiawei Wang 716106ea5479SJiawei Wang rte_eth_trace_map_aggr_tx_affinity(port_id, tx_queue_id, affinity, ret); 716206ea5479SJiawei Wang 716306ea5479SJiawei Wang return ret; 716406ea5479SJiawei Wang } 716506ea5479SJiawei Wang 7166eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO); 7167