199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2010-2017 Intel Corporation 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #include <ctype.h> 699a2dd95SBruce Richardson #include <errno.h> 799a2dd95SBruce Richardson #include <inttypes.h> 899a2dd95SBruce Richardson #include <stdbool.h> 999a2dd95SBruce Richardson #include <stdint.h> 1099a2dd95SBruce Richardson #include <stdlib.h> 1199a2dd95SBruce Richardson #include <string.h> 1299a2dd95SBruce Richardson #include <sys/queue.h> 1399a2dd95SBruce Richardson 1499a2dd95SBruce Richardson #include <rte_byteorder.h> 1599a2dd95SBruce Richardson #include <rte_log.h> 1699a2dd95SBruce Richardson #include <rte_debug.h> 1799a2dd95SBruce Richardson #include <rte_interrupts.h> 1899a2dd95SBruce Richardson #include <rte_memory.h> 1999a2dd95SBruce Richardson #include <rte_memcpy.h> 2099a2dd95SBruce Richardson #include <rte_memzone.h> 2199a2dd95SBruce Richardson #include <rte_launch.h> 2299a2dd95SBruce Richardson #include <rte_eal.h> 2399a2dd95SBruce Richardson #include <rte_per_lcore.h> 2499a2dd95SBruce Richardson #include <rte_lcore.h> 2599a2dd95SBruce Richardson #include <rte_branch_prediction.h> 2699a2dd95SBruce Richardson #include <rte_common.h> 2799a2dd95SBruce Richardson #include <rte_mempool.h> 2899a2dd95SBruce Richardson #include <rte_malloc.h> 2999a2dd95SBruce Richardson #include <rte_mbuf.h> 3099a2dd95SBruce Richardson #include <rte_errno.h> 3199a2dd95SBruce Richardson #include <rte_spinlock.h> 3299a2dd95SBruce Richardson #include <rte_string_fns.h> 3399a2dd95SBruce Richardson #include <rte_class.h> 3499a2dd95SBruce Richardson #include <rte_ether.h> 3599a2dd95SBruce Richardson #include <rte_telemetry.h> 3699a2dd95SBruce Richardson 3799a2dd95SBruce Richardson #include "rte_ethdev_trace.h" 3899a2dd95SBruce Richardson #include "rte_ethdev.h" 3999a2dd95SBruce Richardson #include "ethdev_driver.h" 4099a2dd95SBruce Richardson #include "ethdev_profile.h" 4199a2dd95SBruce Richardson #include "ethdev_private.h" 4299a2dd95SBruce Richardson 4399a2dd95SBruce Richardson struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS]; 4499a2dd95SBruce Richardson 45c87d435aSKonstantin Ananyev /* public fast-path API */ 46c87d435aSKonstantin Ananyev struct rte_eth_fp_ops rte_eth_fp_ops[RTE_MAX_ETHPORTS]; 47c87d435aSKonstantin Ananyev 4809fd4227SAndrew Rybchenko /* spinlock for add/remove Rx callbacks */ 4999a2dd95SBruce Richardson static rte_spinlock_t eth_dev_rx_cb_lock = RTE_SPINLOCK_INITIALIZER; 5099a2dd95SBruce Richardson 5109fd4227SAndrew Rybchenko /* spinlock for add/remove Tx callbacks */ 5299a2dd95SBruce Richardson static rte_spinlock_t eth_dev_tx_cb_lock = RTE_SPINLOCK_INITIALIZER; 5399a2dd95SBruce Richardson 5499a2dd95SBruce Richardson /* store statistics names and its offset in stats structure */ 5599a2dd95SBruce Richardson struct rte_eth_xstats_name_off { 5699a2dd95SBruce Richardson char name[RTE_ETH_XSTATS_NAME_SIZE]; 5799a2dd95SBruce Richardson unsigned offset; 5899a2dd95SBruce Richardson }; 5999a2dd95SBruce Richardson 6099a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_stats_strings[] = { 6199a2dd95SBruce Richardson {"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)}, 6299a2dd95SBruce Richardson {"tx_good_packets", offsetof(struct rte_eth_stats, opackets)}, 6399a2dd95SBruce Richardson {"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)}, 6499a2dd95SBruce Richardson {"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)}, 6599a2dd95SBruce Richardson {"rx_missed_errors", offsetof(struct rte_eth_stats, imissed)}, 6699a2dd95SBruce Richardson {"rx_errors", offsetof(struct rte_eth_stats, ierrors)}, 6799a2dd95SBruce Richardson {"tx_errors", offsetof(struct rte_eth_stats, oerrors)}, 6899a2dd95SBruce Richardson {"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats, 6999a2dd95SBruce Richardson rx_nombuf)}, 7099a2dd95SBruce Richardson }; 7199a2dd95SBruce Richardson 7299a2dd95SBruce Richardson #define RTE_NB_STATS RTE_DIM(eth_dev_stats_strings) 7399a2dd95SBruce Richardson 7499a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_rxq_stats_strings[] = { 7599a2dd95SBruce Richardson {"packets", offsetof(struct rte_eth_stats, q_ipackets)}, 7699a2dd95SBruce Richardson {"bytes", offsetof(struct rte_eth_stats, q_ibytes)}, 7799a2dd95SBruce Richardson {"errors", offsetof(struct rte_eth_stats, q_errors)}, 7899a2dd95SBruce Richardson }; 7999a2dd95SBruce Richardson 8099a2dd95SBruce Richardson #define RTE_NB_RXQ_STATS RTE_DIM(eth_dev_rxq_stats_strings) 8199a2dd95SBruce Richardson 8299a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_txq_stats_strings[] = { 8399a2dd95SBruce Richardson {"packets", offsetof(struct rte_eth_stats, q_opackets)}, 8499a2dd95SBruce Richardson {"bytes", offsetof(struct rte_eth_stats, q_obytes)}, 8599a2dd95SBruce Richardson }; 8699a2dd95SBruce Richardson #define RTE_NB_TXQ_STATS RTE_DIM(eth_dev_txq_stats_strings) 8799a2dd95SBruce Richardson 8899a2dd95SBruce Richardson #define RTE_RX_OFFLOAD_BIT2STR(_name) \ 8999a2dd95SBruce Richardson { RTE_ETH_RX_OFFLOAD_##_name, #_name } 9099a2dd95SBruce Richardson 9199a2dd95SBruce Richardson static const struct { 9299a2dd95SBruce Richardson uint64_t offload; 9399a2dd95SBruce Richardson const char *name; 9499a2dd95SBruce Richardson } eth_dev_rx_offload_names[] = { 9599a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(VLAN_STRIP), 9699a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(IPV4_CKSUM), 9799a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(UDP_CKSUM), 9899a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(TCP_CKSUM), 9999a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(TCP_LRO), 10099a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(QINQ_STRIP), 10199a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM), 10299a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(MACSEC_STRIP), 10399a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(HEADER_SPLIT), 10499a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(VLAN_FILTER), 10599a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(VLAN_EXTEND), 10699a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(SCATTER), 10799a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(TIMESTAMP), 10899a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(SECURITY), 10999a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(KEEP_CRC), 11099a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(SCTP_CKSUM), 11199a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM), 11299a2dd95SBruce Richardson RTE_RX_OFFLOAD_BIT2STR(RSS_HASH), 113295968d1SFerruh Yigit RTE_RX_OFFLOAD_BIT2STR(BUFFER_SPLIT), 11499a2dd95SBruce Richardson }; 11599a2dd95SBruce Richardson 11699a2dd95SBruce Richardson #undef RTE_RX_OFFLOAD_BIT2STR 11799a2dd95SBruce Richardson #undef RTE_ETH_RX_OFFLOAD_BIT2STR 11899a2dd95SBruce Richardson 11999a2dd95SBruce Richardson #define RTE_TX_OFFLOAD_BIT2STR(_name) \ 120295968d1SFerruh Yigit { RTE_ETH_TX_OFFLOAD_##_name, #_name } 12199a2dd95SBruce Richardson 12299a2dd95SBruce Richardson static const struct { 12399a2dd95SBruce Richardson uint64_t offload; 12499a2dd95SBruce Richardson const char *name; 12599a2dd95SBruce Richardson } eth_dev_tx_offload_names[] = { 12699a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(VLAN_INSERT), 12799a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(IPV4_CKSUM), 12899a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(UDP_CKSUM), 12999a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(TCP_CKSUM), 13099a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(SCTP_CKSUM), 13199a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(TCP_TSO), 13299a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(UDP_TSO), 13399a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM), 13499a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(QINQ_INSERT), 13599a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(VXLAN_TNL_TSO), 13699a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(GRE_TNL_TSO), 13799a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(IPIP_TNL_TSO), 13899a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(GENEVE_TNL_TSO), 13999a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MACSEC_INSERT), 14099a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MT_LOCKFREE), 14199a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MULTI_SEGS), 14299a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(MBUF_FAST_FREE), 14399a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(SECURITY), 14499a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(UDP_TNL_TSO), 14599a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(IP_TNL_TSO), 14699a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM), 14799a2dd95SBruce Richardson RTE_TX_OFFLOAD_BIT2STR(SEND_ON_TIMESTAMP), 14899a2dd95SBruce Richardson }; 14999a2dd95SBruce Richardson 15099a2dd95SBruce Richardson #undef RTE_TX_OFFLOAD_BIT2STR 15199a2dd95SBruce Richardson 15293e441c9SXueming Li static const struct { 15393e441c9SXueming Li uint64_t offload; 15493e441c9SXueming Li const char *name; 15593e441c9SXueming Li } rte_eth_dev_capa_names[] = { 15693e441c9SXueming Li {RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP, "RUNTIME_RX_QUEUE_SETUP"}, 15793e441c9SXueming Li {RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP, "RUNTIME_TX_QUEUE_SETUP"}, 15893e441c9SXueming Li {RTE_ETH_DEV_CAPA_RXQ_SHARE, "RXQ_SHARE"}, 15964be0e77SDmitry Kozlyuk {RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP, "FLOW_RULE_KEEP"}, 16064be0e77SDmitry Kozlyuk {RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"}, 16193e441c9SXueming Li }; 16293e441c9SXueming Li 16399a2dd95SBruce Richardson enum { 16499a2dd95SBruce Richardson STAT_QMAP_TX = 0, 16599a2dd95SBruce Richardson STAT_QMAP_RX 16699a2dd95SBruce Richardson }; 16799a2dd95SBruce Richardson 16899a2dd95SBruce Richardson int 16999a2dd95SBruce Richardson rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) 17099a2dd95SBruce Richardson { 17199a2dd95SBruce Richardson int ret; 17299a2dd95SBruce Richardson struct rte_devargs devargs; 17399a2dd95SBruce Richardson const char *bus_param_key; 17499a2dd95SBruce Richardson char *bus_str = NULL; 17599a2dd95SBruce Richardson char *cls_str = NULL; 17699a2dd95SBruce Richardson int str_size; 17799a2dd95SBruce Richardson 17853ef1b34SMin Hu (Connor) if (iter == NULL) { 17953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot initialize NULL iterator\n"); 18053ef1b34SMin Hu (Connor) return -EINVAL; 18153ef1b34SMin Hu (Connor) } 18253ef1b34SMin Hu (Connor) 18353ef1b34SMin Hu (Connor) if (devargs_str == NULL) { 18453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 18553ef1b34SMin Hu (Connor) "Cannot initialize iterator from NULL device description string\n"); 18653ef1b34SMin Hu (Connor) return -EINVAL; 18753ef1b34SMin Hu (Connor) } 18853ef1b34SMin Hu (Connor) 18999a2dd95SBruce Richardson memset(iter, 0, sizeof(*iter)); 19099a2dd95SBruce Richardson memset(&devargs, 0, sizeof(devargs)); 19199a2dd95SBruce Richardson 19299a2dd95SBruce Richardson /* 19399a2dd95SBruce Richardson * The devargs string may use various syntaxes: 19499a2dd95SBruce Richardson * - 0000:08:00.0,representor=[1-3] 19599a2dd95SBruce Richardson * - pci:0000:06:00.0,representor=[0,5] 19699a2dd95SBruce Richardson * - class=eth,mac=00:11:22:33:44:55 19799a2dd95SBruce Richardson * - bus=X,paramX=x/class=Y,paramY=y/driver=Z,paramZ=z 19899a2dd95SBruce Richardson */ 19999a2dd95SBruce Richardson 20099a2dd95SBruce Richardson /* 20199a2dd95SBruce Richardson * Handle pure class filter (i.e. without any bus-level argument), 20299a2dd95SBruce Richardson * from future new syntax. 20399a2dd95SBruce Richardson * rte_devargs_parse() is not yet supporting the new syntax, 20499a2dd95SBruce Richardson * that's why this simple case is temporarily parsed here. 20599a2dd95SBruce Richardson */ 20699a2dd95SBruce Richardson #define iter_anybus_str "class=eth," 20799a2dd95SBruce Richardson if (strncmp(devargs_str, iter_anybus_str, 20899a2dd95SBruce Richardson strlen(iter_anybus_str)) == 0) { 20999a2dd95SBruce Richardson iter->cls_str = devargs_str + strlen(iter_anybus_str); 21099a2dd95SBruce Richardson goto end; 21199a2dd95SBruce Richardson } 21299a2dd95SBruce Richardson 21399a2dd95SBruce Richardson /* Split bus, device and parameters. */ 21499a2dd95SBruce Richardson ret = rte_devargs_parse(&devargs, devargs_str); 21599a2dd95SBruce Richardson if (ret != 0) 21699a2dd95SBruce Richardson goto error; 21799a2dd95SBruce Richardson 21899a2dd95SBruce Richardson /* 21999a2dd95SBruce Richardson * Assume parameters of old syntax can match only at ethdev level. 22099a2dd95SBruce Richardson * Extra parameters will be ignored, thanks to "+" prefix. 22199a2dd95SBruce Richardson */ 22299a2dd95SBruce Richardson str_size = strlen(devargs.args) + 2; 22399a2dd95SBruce Richardson cls_str = malloc(str_size); 22499a2dd95SBruce Richardson if (cls_str == NULL) { 22599a2dd95SBruce Richardson ret = -ENOMEM; 22699a2dd95SBruce Richardson goto error; 22799a2dd95SBruce Richardson } 22899a2dd95SBruce Richardson ret = snprintf(cls_str, str_size, "+%s", devargs.args); 22999a2dd95SBruce Richardson if (ret != str_size - 1) { 23099a2dd95SBruce Richardson ret = -EINVAL; 23199a2dd95SBruce Richardson goto error; 23299a2dd95SBruce Richardson } 23399a2dd95SBruce Richardson iter->cls_str = cls_str; 23499a2dd95SBruce Richardson 23599a2dd95SBruce Richardson iter->bus = devargs.bus; 23699a2dd95SBruce Richardson if (iter->bus->dev_iterate == NULL) { 23799a2dd95SBruce Richardson ret = -ENOTSUP; 23899a2dd95SBruce Richardson goto error; 23999a2dd95SBruce Richardson } 24099a2dd95SBruce Richardson 24199a2dd95SBruce Richardson /* Convert bus args to new syntax for use with new API dev_iterate. */ 242a956adb2SHemant Agrawal if ((strcmp(iter->bus->name, "vdev") == 0) || 243a956adb2SHemant Agrawal (strcmp(iter->bus->name, "fslmc") == 0) || 244a956adb2SHemant Agrawal (strcmp(iter->bus->name, "dpaa_bus") == 0)) { 24599a2dd95SBruce Richardson bus_param_key = "name"; 24699a2dd95SBruce Richardson } else if (strcmp(iter->bus->name, "pci") == 0) { 24799a2dd95SBruce Richardson bus_param_key = "addr"; 24899a2dd95SBruce Richardson } else { 24999a2dd95SBruce Richardson ret = -ENOTSUP; 25099a2dd95SBruce Richardson goto error; 25199a2dd95SBruce Richardson } 25299a2dd95SBruce Richardson str_size = strlen(bus_param_key) + strlen(devargs.name) + 2; 25399a2dd95SBruce Richardson bus_str = malloc(str_size); 25499a2dd95SBruce Richardson if (bus_str == NULL) { 25599a2dd95SBruce Richardson ret = -ENOMEM; 25699a2dd95SBruce Richardson goto error; 25799a2dd95SBruce Richardson } 25899a2dd95SBruce Richardson ret = snprintf(bus_str, str_size, "%s=%s", 25999a2dd95SBruce Richardson bus_param_key, devargs.name); 26099a2dd95SBruce Richardson if (ret != str_size - 1) { 26199a2dd95SBruce Richardson ret = -EINVAL; 26299a2dd95SBruce Richardson goto error; 26399a2dd95SBruce Richardson } 26499a2dd95SBruce Richardson iter->bus_str = bus_str; 26599a2dd95SBruce Richardson 26699a2dd95SBruce Richardson end: 26799a2dd95SBruce Richardson iter->cls = rte_class_find_by_name("eth"); 26899a2dd95SBruce Richardson rte_devargs_reset(&devargs); 26999a2dd95SBruce Richardson return 0; 27099a2dd95SBruce Richardson 27199a2dd95SBruce Richardson error: 27299a2dd95SBruce Richardson if (ret == -ENOTSUP) 27399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Bus %s does not support iterating.\n", 27499a2dd95SBruce Richardson iter->bus->name); 27599a2dd95SBruce Richardson rte_devargs_reset(&devargs); 27699a2dd95SBruce Richardson free(bus_str); 27799a2dd95SBruce Richardson free(cls_str); 27899a2dd95SBruce Richardson return ret; 27999a2dd95SBruce Richardson } 28099a2dd95SBruce Richardson 28199a2dd95SBruce Richardson uint16_t 28299a2dd95SBruce Richardson rte_eth_iterator_next(struct rte_dev_iterator *iter) 28399a2dd95SBruce Richardson { 28453ef1b34SMin Hu (Connor) if (iter == NULL) { 28553ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 28653ef1b34SMin Hu (Connor) "Cannot get next device from NULL iterator\n"); 28753ef1b34SMin Hu (Connor) return RTE_MAX_ETHPORTS; 28853ef1b34SMin Hu (Connor) } 28953ef1b34SMin Hu (Connor) 29099a2dd95SBruce Richardson if (iter->cls == NULL) /* invalid ethdev iterator */ 29199a2dd95SBruce Richardson return RTE_MAX_ETHPORTS; 29299a2dd95SBruce Richardson 29399a2dd95SBruce Richardson do { /* loop to try all matching rte_device */ 29499a2dd95SBruce Richardson /* If not pure ethdev filter and */ 29599a2dd95SBruce Richardson if (iter->bus != NULL && 29699a2dd95SBruce Richardson /* not in middle of rte_eth_dev iteration, */ 29799a2dd95SBruce Richardson iter->class_device == NULL) { 29899a2dd95SBruce Richardson /* get next rte_device to try. */ 29999a2dd95SBruce Richardson iter->device = iter->bus->dev_iterate( 30099a2dd95SBruce Richardson iter->device, iter->bus_str, iter); 30199a2dd95SBruce Richardson if (iter->device == NULL) 30299a2dd95SBruce Richardson break; /* no more rte_device candidate */ 30399a2dd95SBruce Richardson } 30499a2dd95SBruce Richardson /* A device is matching bus part, need to check ethdev part. */ 30599a2dd95SBruce Richardson iter->class_device = iter->cls->dev_iterate( 30699a2dd95SBruce Richardson iter->class_device, iter->cls_str, iter); 30799a2dd95SBruce Richardson if (iter->class_device != NULL) 30899a2dd95SBruce Richardson return eth_dev_to_id(iter->class_device); /* match */ 30999a2dd95SBruce Richardson } while (iter->bus != NULL); /* need to try next rte_device */ 31099a2dd95SBruce Richardson 31199a2dd95SBruce Richardson /* No more ethdev port to iterate. */ 31299a2dd95SBruce Richardson rte_eth_iterator_cleanup(iter); 31399a2dd95SBruce Richardson return RTE_MAX_ETHPORTS; 31499a2dd95SBruce Richardson } 31599a2dd95SBruce Richardson 31699a2dd95SBruce Richardson void 31799a2dd95SBruce Richardson rte_eth_iterator_cleanup(struct rte_dev_iterator *iter) 31899a2dd95SBruce Richardson { 31953ef1b34SMin Hu (Connor) if (iter == NULL) { 32053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot do clean up from NULL iterator\n"); 32153ef1b34SMin Hu (Connor) return; 32253ef1b34SMin Hu (Connor) } 32353ef1b34SMin Hu (Connor) 32499a2dd95SBruce Richardson if (iter->bus_str == NULL) 32599a2dd95SBruce Richardson return; /* nothing to free in pure class filter */ 32699a2dd95SBruce Richardson free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */ 32799a2dd95SBruce Richardson free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */ 32899a2dd95SBruce Richardson memset(iter, 0, sizeof(*iter)); 32999a2dd95SBruce Richardson } 33099a2dd95SBruce Richardson 33199a2dd95SBruce Richardson uint16_t 33299a2dd95SBruce Richardson rte_eth_find_next(uint16_t port_id) 33399a2dd95SBruce Richardson { 33499a2dd95SBruce Richardson while (port_id < RTE_MAX_ETHPORTS && 33599a2dd95SBruce Richardson rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED) 33699a2dd95SBruce Richardson port_id++; 33799a2dd95SBruce Richardson 33899a2dd95SBruce Richardson if (port_id >= RTE_MAX_ETHPORTS) 33999a2dd95SBruce Richardson return RTE_MAX_ETHPORTS; 34099a2dd95SBruce Richardson 34199a2dd95SBruce Richardson return port_id; 34299a2dd95SBruce Richardson } 34399a2dd95SBruce Richardson 34499a2dd95SBruce Richardson /* 34599a2dd95SBruce Richardson * Macro to iterate over all valid ports for internal usage. 34699a2dd95SBruce Richardson * Note: RTE_ETH_FOREACH_DEV is different because filtering owned ports. 34799a2dd95SBruce Richardson */ 34899a2dd95SBruce Richardson #define RTE_ETH_FOREACH_VALID_DEV(port_id) \ 34999a2dd95SBruce Richardson for (port_id = rte_eth_find_next(0); \ 35099a2dd95SBruce Richardson port_id < RTE_MAX_ETHPORTS; \ 35199a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id + 1)) 35299a2dd95SBruce Richardson 35399a2dd95SBruce Richardson uint16_t 35499a2dd95SBruce Richardson rte_eth_find_next_of(uint16_t port_id, const struct rte_device *parent) 35599a2dd95SBruce Richardson { 35699a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id); 35799a2dd95SBruce Richardson while (port_id < RTE_MAX_ETHPORTS && 35899a2dd95SBruce Richardson rte_eth_devices[port_id].device != parent) 35999a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id + 1); 36099a2dd95SBruce Richardson 36199a2dd95SBruce Richardson return port_id; 36299a2dd95SBruce Richardson } 36399a2dd95SBruce Richardson 36499a2dd95SBruce Richardson uint16_t 36599a2dd95SBruce Richardson rte_eth_find_next_sibling(uint16_t port_id, uint16_t ref_port_id) 36699a2dd95SBruce Richardson { 36799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(ref_port_id, RTE_MAX_ETHPORTS); 36899a2dd95SBruce Richardson return rte_eth_find_next_of(port_id, 36999a2dd95SBruce Richardson rte_eth_devices[ref_port_id].device); 37099a2dd95SBruce Richardson } 37199a2dd95SBruce Richardson 37299a2dd95SBruce Richardson static bool 37399a2dd95SBruce Richardson eth_dev_is_allocated(const struct rte_eth_dev *ethdev) 37499a2dd95SBruce Richardson { 37599a2dd95SBruce Richardson return ethdev->data->name[0] != '\0'; 37699a2dd95SBruce Richardson } 37799a2dd95SBruce Richardson 37899a2dd95SBruce Richardson int 37999a2dd95SBruce Richardson rte_eth_dev_is_valid_port(uint16_t port_id) 38099a2dd95SBruce Richardson { 38199a2dd95SBruce Richardson if (port_id >= RTE_MAX_ETHPORTS || 38299a2dd95SBruce Richardson (rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED)) 38399a2dd95SBruce Richardson return 0; 38499a2dd95SBruce Richardson else 38599a2dd95SBruce Richardson return 1; 38699a2dd95SBruce Richardson } 38799a2dd95SBruce Richardson 38899a2dd95SBruce Richardson static int 38999a2dd95SBruce Richardson eth_is_valid_owner_id(uint64_t owner_id) 39099a2dd95SBruce Richardson { 39199a2dd95SBruce Richardson if (owner_id == RTE_ETH_DEV_NO_OWNER || 39299a2dd95SBruce Richardson eth_dev_shared_data->next_owner_id <= owner_id) 39399a2dd95SBruce Richardson return 0; 39499a2dd95SBruce Richardson return 1; 39599a2dd95SBruce Richardson } 39699a2dd95SBruce Richardson 39799a2dd95SBruce Richardson uint64_t 39899a2dd95SBruce Richardson rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id) 39999a2dd95SBruce Richardson { 40099a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id); 40199a2dd95SBruce Richardson while (port_id < RTE_MAX_ETHPORTS && 40299a2dd95SBruce Richardson rte_eth_devices[port_id].data->owner.id != owner_id) 40399a2dd95SBruce Richardson port_id = rte_eth_find_next(port_id + 1); 40499a2dd95SBruce Richardson 40599a2dd95SBruce Richardson return port_id; 40699a2dd95SBruce Richardson } 40799a2dd95SBruce Richardson 40899a2dd95SBruce Richardson int 40999a2dd95SBruce Richardson rte_eth_dev_owner_new(uint64_t *owner_id) 41099a2dd95SBruce Richardson { 41153ef1b34SMin Hu (Connor) if (owner_id == NULL) { 41253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get new owner ID to NULL\n"); 41353ef1b34SMin Hu (Connor) return -EINVAL; 41453ef1b34SMin Hu (Connor) } 41553ef1b34SMin Hu (Connor) 41699a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 41799a2dd95SBruce Richardson 41899a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 41999a2dd95SBruce Richardson 42099a2dd95SBruce Richardson *owner_id = eth_dev_shared_data->next_owner_id++; 42199a2dd95SBruce Richardson 42299a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 42399a2dd95SBruce Richardson return 0; 42499a2dd95SBruce Richardson } 42599a2dd95SBruce Richardson 42699a2dd95SBruce Richardson static int 42799a2dd95SBruce Richardson eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id, 42899a2dd95SBruce Richardson const struct rte_eth_dev_owner *new_owner) 42999a2dd95SBruce Richardson { 43099a2dd95SBruce Richardson struct rte_eth_dev *ethdev = &rte_eth_devices[port_id]; 43199a2dd95SBruce Richardson struct rte_eth_dev_owner *port_owner; 43299a2dd95SBruce Richardson 43399a2dd95SBruce Richardson if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) { 4345906be5aSAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Port ID %"PRIu16" is not allocated\n", 43599a2dd95SBruce Richardson port_id); 43699a2dd95SBruce Richardson return -ENODEV; 43799a2dd95SBruce Richardson } 43899a2dd95SBruce Richardson 43953ef1b34SMin Hu (Connor) if (new_owner == NULL) { 44053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 44153ef1b34SMin Hu (Connor) "Cannot set ethdev port %u owner from NULL owner\n", 44253ef1b34SMin Hu (Connor) port_id); 44353ef1b34SMin Hu (Connor) return -EINVAL; 44453ef1b34SMin Hu (Connor) } 44553ef1b34SMin Hu (Connor) 44699a2dd95SBruce Richardson if (!eth_is_valid_owner_id(new_owner->id) && 44799a2dd95SBruce Richardson !eth_is_valid_owner_id(old_owner_id)) { 44899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 44999a2dd95SBruce Richardson "Invalid owner old_id=%016"PRIx64" new_id=%016"PRIx64"\n", 45099a2dd95SBruce Richardson old_owner_id, new_owner->id); 45199a2dd95SBruce Richardson return -EINVAL; 45299a2dd95SBruce Richardson } 45399a2dd95SBruce Richardson 45499a2dd95SBruce Richardson port_owner = &rte_eth_devices[port_id].data->owner; 45599a2dd95SBruce Richardson if (port_owner->id != old_owner_id) { 45699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 45799a2dd95SBruce Richardson "Cannot set owner to port %u already owned by %s_%016"PRIX64"\n", 45899a2dd95SBruce Richardson port_id, port_owner->name, port_owner->id); 45999a2dd95SBruce Richardson return -EPERM; 46099a2dd95SBruce Richardson } 46199a2dd95SBruce Richardson 46299a2dd95SBruce Richardson /* can not truncate (same structure) */ 46399a2dd95SBruce Richardson strlcpy(port_owner->name, new_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN); 46499a2dd95SBruce Richardson 46599a2dd95SBruce Richardson port_owner->id = new_owner->id; 46699a2dd95SBruce Richardson 46799a2dd95SBruce Richardson RTE_ETHDEV_LOG(DEBUG, "Port %u owner is %s_%016"PRIx64"\n", 46899a2dd95SBruce Richardson port_id, new_owner->name, new_owner->id); 46999a2dd95SBruce Richardson 47099a2dd95SBruce Richardson return 0; 47199a2dd95SBruce Richardson } 47299a2dd95SBruce Richardson 47399a2dd95SBruce Richardson int 47499a2dd95SBruce Richardson rte_eth_dev_owner_set(const uint16_t port_id, 47599a2dd95SBruce Richardson const struct rte_eth_dev_owner *owner) 47699a2dd95SBruce Richardson { 47799a2dd95SBruce Richardson int ret; 47899a2dd95SBruce Richardson 47999a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 48099a2dd95SBruce Richardson 48199a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 48299a2dd95SBruce Richardson 48399a2dd95SBruce Richardson ret = eth_dev_owner_set(port_id, RTE_ETH_DEV_NO_OWNER, owner); 48499a2dd95SBruce Richardson 48599a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 48699a2dd95SBruce Richardson return ret; 48799a2dd95SBruce Richardson } 48899a2dd95SBruce Richardson 48999a2dd95SBruce Richardson int 49099a2dd95SBruce Richardson rte_eth_dev_owner_unset(const uint16_t port_id, const uint64_t owner_id) 49199a2dd95SBruce Richardson { 49299a2dd95SBruce Richardson const struct rte_eth_dev_owner new_owner = (struct rte_eth_dev_owner) 49399a2dd95SBruce Richardson {.id = RTE_ETH_DEV_NO_OWNER, .name = ""}; 49499a2dd95SBruce Richardson int ret; 49599a2dd95SBruce Richardson 49699a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 49799a2dd95SBruce Richardson 49899a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 49999a2dd95SBruce Richardson 50099a2dd95SBruce Richardson ret = eth_dev_owner_set(port_id, owner_id, &new_owner); 50199a2dd95SBruce Richardson 50299a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 50399a2dd95SBruce Richardson return ret; 50499a2dd95SBruce Richardson } 50599a2dd95SBruce Richardson 50699a2dd95SBruce Richardson int 50799a2dd95SBruce Richardson rte_eth_dev_owner_delete(const uint64_t owner_id) 50899a2dd95SBruce Richardson { 50999a2dd95SBruce Richardson uint16_t port_id; 51099a2dd95SBruce Richardson int ret = 0; 51199a2dd95SBruce Richardson 51299a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 51399a2dd95SBruce Richardson 51499a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 51599a2dd95SBruce Richardson 51699a2dd95SBruce Richardson if (eth_is_valid_owner_id(owner_id)) { 517b7ade5d3SFerruh Yigit for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { 518b7ade5d3SFerruh Yigit struct rte_eth_dev_data *data = 519b7ade5d3SFerruh Yigit rte_eth_devices[port_id].data; 520b7ade5d3SFerruh Yigit if (data != NULL && data->owner.id == owner_id) 521b7ade5d3SFerruh Yigit memset(&data->owner, 0, 52299a2dd95SBruce Richardson sizeof(struct rte_eth_dev_owner)); 523b7ade5d3SFerruh Yigit } 52499a2dd95SBruce Richardson RTE_ETHDEV_LOG(NOTICE, 52599a2dd95SBruce Richardson "All port owners owned by %016"PRIx64" identifier have removed\n", 52699a2dd95SBruce Richardson owner_id); 52799a2dd95SBruce Richardson } else { 52899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 5295906be5aSAndrew Rybchenko "Invalid owner ID=%016"PRIx64"\n", 53099a2dd95SBruce Richardson owner_id); 53199a2dd95SBruce Richardson ret = -EINVAL; 53299a2dd95SBruce Richardson } 53399a2dd95SBruce Richardson 53499a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 53599a2dd95SBruce Richardson 53699a2dd95SBruce Richardson return ret; 53799a2dd95SBruce Richardson } 53899a2dd95SBruce Richardson 53999a2dd95SBruce Richardson int 54099a2dd95SBruce Richardson rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner) 54199a2dd95SBruce Richardson { 54253ef1b34SMin Hu (Connor) struct rte_eth_dev *ethdev; 54353ef1b34SMin Hu (Connor) 54453ef1b34SMin Hu (Connor) RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 54553ef1b34SMin Hu (Connor) ethdev = &rte_eth_devices[port_id]; 54653ef1b34SMin Hu (Connor) 54753ef1b34SMin Hu (Connor) if (!eth_dev_is_allocated(ethdev)) { 5485906be5aSAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Port ID %"PRIu16" is not allocated\n", 54953ef1b34SMin Hu (Connor) port_id); 55053ef1b34SMin Hu (Connor) return -ENODEV; 55153ef1b34SMin Hu (Connor) } 55253ef1b34SMin Hu (Connor) 55353ef1b34SMin Hu (Connor) if (owner == NULL) { 55453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u owner to NULL\n", 55553ef1b34SMin Hu (Connor) port_id); 55653ef1b34SMin Hu (Connor) return -EINVAL; 55753ef1b34SMin Hu (Connor) } 55899a2dd95SBruce Richardson 55999a2dd95SBruce Richardson eth_dev_shared_data_prepare(); 56099a2dd95SBruce Richardson 56199a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_shared_data->ownership_lock); 56299a2dd95SBruce Richardson rte_memcpy(owner, ðdev->data->owner, sizeof(*owner)); 56399a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_shared_data->ownership_lock); 56453ef1b34SMin Hu (Connor) 56553ef1b34SMin Hu (Connor) return 0; 56699a2dd95SBruce Richardson } 56799a2dd95SBruce Richardson 56899a2dd95SBruce Richardson int 56999a2dd95SBruce Richardson rte_eth_dev_socket_id(uint16_t port_id) 57099a2dd95SBruce Richardson { 57199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); 57299a2dd95SBruce Richardson return rte_eth_devices[port_id].data->numa_node; 57399a2dd95SBruce Richardson } 57499a2dd95SBruce Richardson 57599a2dd95SBruce Richardson void * 57699a2dd95SBruce Richardson rte_eth_dev_get_sec_ctx(uint16_t port_id) 57799a2dd95SBruce Richardson { 57899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL); 57999a2dd95SBruce Richardson return rte_eth_devices[port_id].security_ctx; 58099a2dd95SBruce Richardson } 58199a2dd95SBruce Richardson 58299a2dd95SBruce Richardson uint16_t 58399a2dd95SBruce Richardson rte_eth_dev_count_avail(void) 58499a2dd95SBruce Richardson { 58599a2dd95SBruce Richardson uint16_t p; 58699a2dd95SBruce Richardson uint16_t count; 58799a2dd95SBruce Richardson 58899a2dd95SBruce Richardson count = 0; 58999a2dd95SBruce Richardson 59099a2dd95SBruce Richardson RTE_ETH_FOREACH_DEV(p) 59199a2dd95SBruce Richardson count++; 59299a2dd95SBruce Richardson 59399a2dd95SBruce Richardson return count; 59499a2dd95SBruce Richardson } 59599a2dd95SBruce Richardson 59699a2dd95SBruce Richardson uint16_t 59799a2dd95SBruce Richardson rte_eth_dev_count_total(void) 59899a2dd95SBruce Richardson { 59999a2dd95SBruce Richardson uint16_t port, count = 0; 60099a2dd95SBruce Richardson 60199a2dd95SBruce Richardson RTE_ETH_FOREACH_VALID_DEV(port) 60299a2dd95SBruce Richardson count++; 60399a2dd95SBruce Richardson 60499a2dd95SBruce Richardson return count; 60599a2dd95SBruce Richardson } 60699a2dd95SBruce Richardson 60799a2dd95SBruce Richardson int 60899a2dd95SBruce Richardson rte_eth_dev_get_name_by_port(uint16_t port_id, char *name) 60999a2dd95SBruce Richardson { 61099a2dd95SBruce Richardson char *tmp; 61199a2dd95SBruce Richardson 61299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 61399a2dd95SBruce Richardson 61499a2dd95SBruce Richardson if (name == NULL) { 61553ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u name to NULL\n", 61653ef1b34SMin Hu (Connor) port_id); 61799a2dd95SBruce Richardson return -EINVAL; 61899a2dd95SBruce Richardson } 61999a2dd95SBruce Richardson 62099a2dd95SBruce Richardson /* shouldn't check 'rte_eth_devices[i].data', 62199a2dd95SBruce Richardson * because it might be overwritten by VDEV PMD */ 62299a2dd95SBruce Richardson tmp = eth_dev_shared_data->data[port_id].name; 62399a2dd95SBruce Richardson strcpy(name, tmp); 62499a2dd95SBruce Richardson return 0; 62599a2dd95SBruce Richardson } 62699a2dd95SBruce Richardson 62799a2dd95SBruce Richardson int 62899a2dd95SBruce Richardson rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id) 62999a2dd95SBruce Richardson { 63099a2dd95SBruce Richardson uint16_t pid; 63199a2dd95SBruce Richardson 63299a2dd95SBruce Richardson if (name == NULL) { 63353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name"); 63453ef1b34SMin Hu (Connor) return -EINVAL; 63553ef1b34SMin Hu (Connor) } 63653ef1b34SMin Hu (Connor) 63753ef1b34SMin Hu (Connor) if (port_id == NULL) { 63853ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 63953ef1b34SMin Hu (Connor) "Cannot get port ID to NULL for %s\n", name); 64099a2dd95SBruce Richardson return -EINVAL; 64199a2dd95SBruce Richardson } 64299a2dd95SBruce Richardson 64399a2dd95SBruce Richardson RTE_ETH_FOREACH_VALID_DEV(pid) 64499a2dd95SBruce Richardson if (!strcmp(name, eth_dev_shared_data->data[pid].name)) { 64599a2dd95SBruce Richardson *port_id = pid; 64699a2dd95SBruce Richardson return 0; 64799a2dd95SBruce Richardson } 64899a2dd95SBruce Richardson 64999a2dd95SBruce Richardson return -ENODEV; 65099a2dd95SBruce Richardson } 65199a2dd95SBruce Richardson 65299a2dd95SBruce Richardson static int 65399a2dd95SBruce Richardson eth_err(uint16_t port_id, int ret) 65499a2dd95SBruce Richardson { 65599a2dd95SBruce Richardson if (ret == 0) 65699a2dd95SBruce Richardson return 0; 65799a2dd95SBruce Richardson if (rte_eth_dev_is_removed(port_id)) 65899a2dd95SBruce Richardson return -EIO; 65999a2dd95SBruce Richardson return ret; 66099a2dd95SBruce Richardson } 66199a2dd95SBruce Richardson 66299a2dd95SBruce Richardson static int 66399a2dd95SBruce Richardson eth_dev_validate_rx_queue(const struct rte_eth_dev *dev, uint16_t rx_queue_id) 66499a2dd95SBruce Richardson { 66599a2dd95SBruce Richardson uint16_t port_id; 66699a2dd95SBruce Richardson 66799a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 66899a2dd95SBruce Richardson port_id = dev->data->port_id; 66999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 67099a2dd95SBruce Richardson "Invalid Rx queue_id=%u of device with port_id=%u\n", 67199a2dd95SBruce Richardson rx_queue_id, port_id); 67299a2dd95SBruce Richardson return -EINVAL; 67399a2dd95SBruce Richardson } 67499a2dd95SBruce Richardson 67599a2dd95SBruce Richardson if (dev->data->rx_queues[rx_queue_id] == NULL) { 67699a2dd95SBruce Richardson port_id = dev->data->port_id; 67799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 67899a2dd95SBruce Richardson "Queue %u of device with port_id=%u has not been setup\n", 67999a2dd95SBruce Richardson rx_queue_id, port_id); 68099a2dd95SBruce Richardson return -EINVAL; 68199a2dd95SBruce Richardson } 68299a2dd95SBruce Richardson 68399a2dd95SBruce Richardson return 0; 68499a2dd95SBruce Richardson } 68599a2dd95SBruce Richardson 68699a2dd95SBruce Richardson static int 68799a2dd95SBruce Richardson eth_dev_validate_tx_queue(const struct rte_eth_dev *dev, uint16_t tx_queue_id) 68899a2dd95SBruce Richardson { 68999a2dd95SBruce Richardson uint16_t port_id; 69099a2dd95SBruce Richardson 69199a2dd95SBruce Richardson if (tx_queue_id >= dev->data->nb_tx_queues) { 69299a2dd95SBruce Richardson port_id = dev->data->port_id; 69399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 69499a2dd95SBruce Richardson "Invalid Tx queue_id=%u of device with port_id=%u\n", 69599a2dd95SBruce Richardson tx_queue_id, port_id); 69699a2dd95SBruce Richardson return -EINVAL; 69799a2dd95SBruce Richardson } 69899a2dd95SBruce Richardson 69999a2dd95SBruce Richardson if (dev->data->tx_queues[tx_queue_id] == NULL) { 70099a2dd95SBruce Richardson port_id = dev->data->port_id; 70199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 70299a2dd95SBruce Richardson "Queue %u of device with port_id=%u has not been setup\n", 70399a2dd95SBruce Richardson tx_queue_id, port_id); 70499a2dd95SBruce Richardson return -EINVAL; 70599a2dd95SBruce Richardson } 70699a2dd95SBruce Richardson 70799a2dd95SBruce Richardson return 0; 70899a2dd95SBruce Richardson } 70999a2dd95SBruce Richardson 71099a2dd95SBruce Richardson int 71199a2dd95SBruce Richardson rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id) 71299a2dd95SBruce Richardson { 71399a2dd95SBruce Richardson struct rte_eth_dev *dev; 71499a2dd95SBruce Richardson int ret; 71599a2dd95SBruce Richardson 71699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 71799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 71853ef1b34SMin Hu (Connor) 71999a2dd95SBruce Richardson if (!dev->data->dev_started) { 72099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 72199a2dd95SBruce Richardson "Port %u must be started before start any queue\n", 72299a2dd95SBruce Richardson port_id); 72399a2dd95SBruce Richardson return -EINVAL; 72499a2dd95SBruce Richardson } 72599a2dd95SBruce Richardson 72699a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, rx_queue_id); 72799a2dd95SBruce Richardson if (ret != 0) 72899a2dd95SBruce Richardson return ret; 72999a2dd95SBruce Richardson 73099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_start, -ENOTSUP); 73199a2dd95SBruce Richardson 73299a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) { 73399a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 73499a2dd95SBruce Richardson "Can't start Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n", 73599a2dd95SBruce Richardson rx_queue_id, port_id); 73699a2dd95SBruce Richardson return -EINVAL; 73799a2dd95SBruce Richardson } 73899a2dd95SBruce Richardson 73999a2dd95SBruce Richardson if (dev->data->rx_queue_state[rx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) { 74099a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 74199a2dd95SBruce Richardson "Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n", 74299a2dd95SBruce Richardson rx_queue_id, port_id); 74399a2dd95SBruce Richardson return 0; 74499a2dd95SBruce Richardson } 74599a2dd95SBruce Richardson 74653ef1b34SMin Hu (Connor) return eth_err(port_id, dev->dev_ops->rx_queue_start(dev, rx_queue_id)); 74799a2dd95SBruce Richardson } 74899a2dd95SBruce Richardson 74999a2dd95SBruce Richardson int 75099a2dd95SBruce Richardson rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id) 75199a2dd95SBruce Richardson { 75299a2dd95SBruce Richardson struct rte_eth_dev *dev; 75399a2dd95SBruce Richardson int ret; 75499a2dd95SBruce Richardson 75599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 75699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 75799a2dd95SBruce Richardson 75899a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, rx_queue_id); 75999a2dd95SBruce Richardson if (ret != 0) 76099a2dd95SBruce Richardson return ret; 76199a2dd95SBruce Richardson 76299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_stop, -ENOTSUP); 76399a2dd95SBruce Richardson 76499a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) { 76599a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 76699a2dd95SBruce Richardson "Can't stop Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n", 76799a2dd95SBruce Richardson rx_queue_id, port_id); 76899a2dd95SBruce Richardson return -EINVAL; 76999a2dd95SBruce Richardson } 77099a2dd95SBruce Richardson 77199a2dd95SBruce Richardson if (dev->data->rx_queue_state[rx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) { 77299a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 77399a2dd95SBruce Richardson "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n", 77499a2dd95SBruce Richardson rx_queue_id, port_id); 77599a2dd95SBruce Richardson return 0; 77699a2dd95SBruce Richardson } 77799a2dd95SBruce Richardson 77899a2dd95SBruce Richardson return eth_err(port_id, dev->dev_ops->rx_queue_stop(dev, rx_queue_id)); 77999a2dd95SBruce Richardson } 78099a2dd95SBruce Richardson 78199a2dd95SBruce Richardson int 78299a2dd95SBruce Richardson rte_eth_dev_tx_queue_start(uint16_t port_id, uint16_t tx_queue_id) 78399a2dd95SBruce Richardson { 78499a2dd95SBruce Richardson struct rte_eth_dev *dev; 78599a2dd95SBruce Richardson int ret; 78699a2dd95SBruce Richardson 78799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 78899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 78953ef1b34SMin Hu (Connor) 79099a2dd95SBruce Richardson if (!dev->data->dev_started) { 79199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 79299a2dd95SBruce Richardson "Port %u must be started before start any queue\n", 79399a2dd95SBruce Richardson port_id); 79499a2dd95SBruce Richardson return -EINVAL; 79599a2dd95SBruce Richardson } 79699a2dd95SBruce Richardson 79799a2dd95SBruce Richardson ret = eth_dev_validate_tx_queue(dev, tx_queue_id); 79899a2dd95SBruce Richardson if (ret != 0) 79999a2dd95SBruce Richardson return ret; 80099a2dd95SBruce Richardson 80199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_start, -ENOTSUP); 80299a2dd95SBruce Richardson 80399a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) { 80499a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 80599a2dd95SBruce Richardson "Can't start Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n", 80699a2dd95SBruce Richardson tx_queue_id, port_id); 80799a2dd95SBruce Richardson return -EINVAL; 80899a2dd95SBruce Richardson } 80999a2dd95SBruce Richardson 81099a2dd95SBruce Richardson if (dev->data->tx_queue_state[tx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) { 81199a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 81299a2dd95SBruce Richardson "Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n", 81399a2dd95SBruce Richardson tx_queue_id, port_id); 81499a2dd95SBruce Richardson return 0; 81599a2dd95SBruce Richardson } 81699a2dd95SBruce Richardson 81799a2dd95SBruce Richardson return eth_err(port_id, dev->dev_ops->tx_queue_start(dev, tx_queue_id)); 81899a2dd95SBruce Richardson } 81999a2dd95SBruce Richardson 82099a2dd95SBruce Richardson int 82199a2dd95SBruce Richardson rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id) 82299a2dd95SBruce Richardson { 82399a2dd95SBruce Richardson struct rte_eth_dev *dev; 82499a2dd95SBruce Richardson int ret; 82599a2dd95SBruce Richardson 82699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 82799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 82899a2dd95SBruce Richardson 82999a2dd95SBruce Richardson ret = eth_dev_validate_tx_queue(dev, tx_queue_id); 83099a2dd95SBruce Richardson if (ret != 0) 83199a2dd95SBruce Richardson return ret; 83299a2dd95SBruce Richardson 83399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_stop, -ENOTSUP); 83499a2dd95SBruce Richardson 83599a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) { 83699a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 83799a2dd95SBruce Richardson "Can't stop Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n", 83899a2dd95SBruce Richardson tx_queue_id, port_id); 83999a2dd95SBruce Richardson return -EINVAL; 84099a2dd95SBruce Richardson } 84199a2dd95SBruce Richardson 84299a2dd95SBruce Richardson if (dev->data->tx_queue_state[tx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) { 84399a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 84499a2dd95SBruce Richardson "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n", 84599a2dd95SBruce Richardson tx_queue_id, port_id); 84699a2dd95SBruce Richardson return 0; 84799a2dd95SBruce Richardson } 84899a2dd95SBruce Richardson 84999a2dd95SBruce Richardson return eth_err(port_id, dev->dev_ops->tx_queue_stop(dev, tx_queue_id)); 85099a2dd95SBruce Richardson } 85199a2dd95SBruce Richardson 85299a2dd95SBruce Richardson uint32_t 85399a2dd95SBruce Richardson rte_eth_speed_bitflag(uint32_t speed, int duplex) 85499a2dd95SBruce Richardson { 85599a2dd95SBruce Richardson switch (speed) { 856295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_10M: 857295968d1SFerruh Yigit return duplex ? RTE_ETH_LINK_SPEED_10M : RTE_ETH_LINK_SPEED_10M_HD; 858295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_100M: 859295968d1SFerruh Yigit return duplex ? RTE_ETH_LINK_SPEED_100M : RTE_ETH_LINK_SPEED_100M_HD; 860295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_1G: 861295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_1G; 862295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_2_5G: 863295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_2_5G; 864295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_5G: 865295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_5G; 866295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_10G: 867295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_10G; 868295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_20G: 869295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_20G; 870295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_25G: 871295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_25G; 872295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_40G: 873295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_40G; 874295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_50G: 875295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_50G; 876295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_56G: 877295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_56G; 878295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_100G: 879295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_100G; 880295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_200G: 881295968d1SFerruh Yigit return RTE_ETH_LINK_SPEED_200G; 88299a2dd95SBruce Richardson default: 88399a2dd95SBruce Richardson return 0; 88499a2dd95SBruce Richardson } 88599a2dd95SBruce Richardson } 88699a2dd95SBruce Richardson 88799a2dd95SBruce Richardson const char * 88899a2dd95SBruce Richardson rte_eth_dev_rx_offload_name(uint64_t offload) 88999a2dd95SBruce Richardson { 89099a2dd95SBruce Richardson const char *name = "UNKNOWN"; 89199a2dd95SBruce Richardson unsigned int i; 89299a2dd95SBruce Richardson 89399a2dd95SBruce Richardson for (i = 0; i < RTE_DIM(eth_dev_rx_offload_names); ++i) { 89499a2dd95SBruce Richardson if (offload == eth_dev_rx_offload_names[i].offload) { 89599a2dd95SBruce Richardson name = eth_dev_rx_offload_names[i].name; 89699a2dd95SBruce Richardson break; 89799a2dd95SBruce Richardson } 89899a2dd95SBruce Richardson } 89999a2dd95SBruce Richardson 90099a2dd95SBruce Richardson return name; 90199a2dd95SBruce Richardson } 90299a2dd95SBruce Richardson 90399a2dd95SBruce Richardson const char * 90499a2dd95SBruce Richardson rte_eth_dev_tx_offload_name(uint64_t offload) 90599a2dd95SBruce Richardson { 90699a2dd95SBruce Richardson const char *name = "UNKNOWN"; 90799a2dd95SBruce Richardson unsigned int i; 90899a2dd95SBruce Richardson 90999a2dd95SBruce Richardson for (i = 0; i < RTE_DIM(eth_dev_tx_offload_names); ++i) { 91099a2dd95SBruce Richardson if (offload == eth_dev_tx_offload_names[i].offload) { 91199a2dd95SBruce Richardson name = eth_dev_tx_offload_names[i].name; 91299a2dd95SBruce Richardson break; 91399a2dd95SBruce Richardson } 91499a2dd95SBruce Richardson } 91599a2dd95SBruce Richardson 91699a2dd95SBruce Richardson return name; 91799a2dd95SBruce Richardson } 91899a2dd95SBruce Richardson 91993e441c9SXueming Li const char * 92093e441c9SXueming Li rte_eth_dev_capability_name(uint64_t capability) 92193e441c9SXueming Li { 92293e441c9SXueming Li const char *name = "UNKNOWN"; 92393e441c9SXueming Li unsigned int i; 92493e441c9SXueming Li 92593e441c9SXueming Li for (i = 0; i < RTE_DIM(rte_eth_dev_capa_names); ++i) { 92693e441c9SXueming Li if (capability == rte_eth_dev_capa_names[i].offload) { 92793e441c9SXueming Li name = rte_eth_dev_capa_names[i].name; 92893e441c9SXueming Li break; 92993e441c9SXueming Li } 93093e441c9SXueming Li } 93193e441c9SXueming Li 93293e441c9SXueming Li return name; 93393e441c9SXueming Li } 93493e441c9SXueming Li 93599a2dd95SBruce Richardson static inline int 93699a2dd95SBruce Richardson eth_dev_check_lro_pkt_size(uint16_t port_id, uint32_t config_size, 93799a2dd95SBruce Richardson uint32_t max_rx_pkt_len, uint32_t dev_info_size) 93899a2dd95SBruce Richardson { 93999a2dd95SBruce Richardson int ret = 0; 94099a2dd95SBruce Richardson 94199a2dd95SBruce Richardson if (dev_info_size == 0) { 94299a2dd95SBruce Richardson if (config_size != max_rx_pkt_len) { 94399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size" 94499a2dd95SBruce Richardson " %u != %u is not allowed\n", 94599a2dd95SBruce Richardson port_id, config_size, max_rx_pkt_len); 94699a2dd95SBruce Richardson ret = -EINVAL; 94799a2dd95SBruce Richardson } 94899a2dd95SBruce Richardson } else if (config_size > dev_info_size) { 94999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size %u " 95099a2dd95SBruce Richardson "> max allowed value %u\n", port_id, config_size, 95199a2dd95SBruce Richardson dev_info_size); 95299a2dd95SBruce Richardson ret = -EINVAL; 95399a2dd95SBruce Richardson } else if (config_size < RTE_ETHER_MIN_LEN) { 95499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size %u " 95599a2dd95SBruce Richardson "< min allowed value %u\n", port_id, config_size, 95699a2dd95SBruce Richardson (unsigned int)RTE_ETHER_MIN_LEN); 95799a2dd95SBruce Richardson ret = -EINVAL; 95899a2dd95SBruce Richardson } 95999a2dd95SBruce Richardson return ret; 96099a2dd95SBruce Richardson } 96199a2dd95SBruce Richardson 96299a2dd95SBruce Richardson /* 96399a2dd95SBruce Richardson * Validate offloads that are requested through rte_eth_dev_configure against 9640d9f56a8SAndrew Rybchenko * the offloads successfully set by the Ethernet device. 96599a2dd95SBruce Richardson * 96699a2dd95SBruce Richardson * @param port_id 96799a2dd95SBruce Richardson * The port identifier of the Ethernet device. 96899a2dd95SBruce Richardson * @param req_offloads 96999a2dd95SBruce Richardson * The offloads that have been requested through `rte_eth_dev_configure`. 97099a2dd95SBruce Richardson * @param set_offloads 9710d9f56a8SAndrew Rybchenko * The offloads successfully set by the Ethernet device. 97299a2dd95SBruce Richardson * @param offload_type 97399a2dd95SBruce Richardson * The offload type i.e. Rx/Tx string. 97499a2dd95SBruce Richardson * @param offload_name 97599a2dd95SBruce Richardson * The function that prints the offload name. 97699a2dd95SBruce Richardson * @return 97799a2dd95SBruce Richardson * - (0) if validation successful. 97899a2dd95SBruce Richardson * - (-EINVAL) if requested offload has been silently disabled. 97999a2dd95SBruce Richardson * 98099a2dd95SBruce Richardson */ 98199a2dd95SBruce Richardson static int 98299a2dd95SBruce Richardson eth_dev_validate_offloads(uint16_t port_id, uint64_t req_offloads, 98399a2dd95SBruce Richardson uint64_t set_offloads, const char *offload_type, 98499a2dd95SBruce Richardson const char *(*offload_name)(uint64_t)) 98599a2dd95SBruce Richardson { 98699a2dd95SBruce Richardson uint64_t offloads_diff = req_offloads ^ set_offloads; 98799a2dd95SBruce Richardson uint64_t offload; 98899a2dd95SBruce Richardson int ret = 0; 98999a2dd95SBruce Richardson 99099a2dd95SBruce Richardson while (offloads_diff != 0) { 99199a2dd95SBruce Richardson /* Check if any offload is requested but not enabled. */ 992e1823e08SThomas Monjalon offload = RTE_BIT64(__builtin_ctzll(offloads_diff)); 99399a2dd95SBruce Richardson if (offload & req_offloads) { 99499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 99599a2dd95SBruce Richardson "Port %u failed to enable %s offload %s\n", 99699a2dd95SBruce Richardson port_id, offload_type, offload_name(offload)); 99799a2dd95SBruce Richardson ret = -EINVAL; 99899a2dd95SBruce Richardson } 99999a2dd95SBruce Richardson 100099a2dd95SBruce Richardson /* Check if offload couldn't be disabled. */ 100199a2dd95SBruce Richardson if (offload & set_offloads) { 100299a2dd95SBruce Richardson RTE_ETHDEV_LOG(DEBUG, 100399a2dd95SBruce Richardson "Port %u %s offload %s is not requested but enabled\n", 100499a2dd95SBruce Richardson port_id, offload_type, offload_name(offload)); 100599a2dd95SBruce Richardson } 100699a2dd95SBruce Richardson 100799a2dd95SBruce Richardson offloads_diff &= ~offload; 100899a2dd95SBruce Richardson } 100999a2dd95SBruce Richardson 101099a2dd95SBruce Richardson return ret; 101199a2dd95SBruce Richardson } 101299a2dd95SBruce Richardson 10131bb4a528SFerruh Yigit static uint32_t 10141bb4a528SFerruh Yigit eth_dev_get_overhead_len(uint32_t max_rx_pktlen, uint16_t max_mtu) 10151bb4a528SFerruh Yigit { 10161bb4a528SFerruh Yigit uint32_t overhead_len; 10171bb4a528SFerruh Yigit 10181bb4a528SFerruh Yigit if (max_mtu != UINT16_MAX && max_rx_pktlen > max_mtu) 10191bb4a528SFerruh Yigit overhead_len = max_rx_pktlen - max_mtu; 10201bb4a528SFerruh Yigit else 10211bb4a528SFerruh Yigit overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; 10221bb4a528SFerruh Yigit 10231bb4a528SFerruh Yigit return overhead_len; 10241bb4a528SFerruh Yigit } 10251bb4a528SFerruh Yigit 1026990912e6SFerruh Yigit /* rte_eth_dev_info_get() should be called prior to this function */ 1027990912e6SFerruh Yigit static int 1028990912e6SFerruh Yigit eth_dev_validate_mtu(uint16_t port_id, struct rte_eth_dev_info *dev_info, 1029990912e6SFerruh Yigit uint16_t mtu) 1030990912e6SFerruh Yigit { 1031990912e6SFerruh Yigit uint32_t overhead_len; 1032990912e6SFerruh Yigit uint32_t frame_size; 1033990912e6SFerruh Yigit 1034990912e6SFerruh Yigit if (mtu < dev_info->min_mtu) { 1035990912e6SFerruh Yigit RTE_ETHDEV_LOG(ERR, 1036990912e6SFerruh Yigit "MTU (%u) < device min MTU (%u) for port_id %u\n", 1037990912e6SFerruh Yigit mtu, dev_info->min_mtu, port_id); 1038990912e6SFerruh Yigit return -EINVAL; 1039990912e6SFerruh Yigit } 1040990912e6SFerruh Yigit if (mtu > dev_info->max_mtu) { 1041990912e6SFerruh Yigit RTE_ETHDEV_LOG(ERR, 1042990912e6SFerruh Yigit "MTU (%u) > device max MTU (%u) for port_id %u\n", 1043990912e6SFerruh Yigit mtu, dev_info->max_mtu, port_id); 1044990912e6SFerruh Yigit return -EINVAL; 1045990912e6SFerruh Yigit } 1046990912e6SFerruh Yigit 1047990912e6SFerruh Yigit overhead_len = eth_dev_get_overhead_len(dev_info->max_rx_pktlen, 1048990912e6SFerruh Yigit dev_info->max_mtu); 1049990912e6SFerruh Yigit frame_size = mtu + overhead_len; 1050990912e6SFerruh Yigit if (frame_size < RTE_ETHER_MIN_LEN) { 1051990912e6SFerruh Yigit RTE_ETHDEV_LOG(ERR, 1052990912e6SFerruh Yigit "Frame size (%u) < min frame size (%u) for port_id %u\n", 1053990912e6SFerruh Yigit frame_size, RTE_ETHER_MIN_LEN, port_id); 1054990912e6SFerruh Yigit return -EINVAL; 1055990912e6SFerruh Yigit } 1056990912e6SFerruh Yigit 1057990912e6SFerruh Yigit if (frame_size > dev_info->max_rx_pktlen) { 1058990912e6SFerruh Yigit RTE_ETHDEV_LOG(ERR, 1059990912e6SFerruh Yigit "Frame size (%u) > device max frame size (%u) for port_id %u\n", 1060990912e6SFerruh Yigit frame_size, dev_info->max_rx_pktlen, port_id); 1061990912e6SFerruh Yigit return -EINVAL; 1062990912e6SFerruh Yigit } 1063990912e6SFerruh Yigit 1064990912e6SFerruh Yigit return 0; 1065990912e6SFerruh Yigit } 1066990912e6SFerruh Yigit 106799a2dd95SBruce Richardson int 106899a2dd95SBruce Richardson rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, 106999a2dd95SBruce Richardson const struct rte_eth_conf *dev_conf) 107099a2dd95SBruce Richardson { 107199a2dd95SBruce Richardson struct rte_eth_dev *dev; 107299a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 107399a2dd95SBruce Richardson struct rte_eth_conf orig_conf; 107499a2dd95SBruce Richardson int diag; 107599a2dd95SBruce Richardson int ret; 107699a2dd95SBruce Richardson uint16_t old_mtu; 107799a2dd95SBruce Richardson 107899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 107999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 108099a2dd95SBruce Richardson 108153ef1b34SMin Hu (Connor) if (dev_conf == NULL) { 108253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 108353ef1b34SMin Hu (Connor) "Cannot configure ethdev port %u from NULL config\n", 108453ef1b34SMin Hu (Connor) port_id); 108553ef1b34SMin Hu (Connor) return -EINVAL; 108653ef1b34SMin Hu (Connor) } 108753ef1b34SMin Hu (Connor) 108899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP); 108999a2dd95SBruce Richardson 109099a2dd95SBruce Richardson if (dev->data->dev_started) { 109199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 109299a2dd95SBruce Richardson "Port %u must be stopped to allow configuration\n", 109399a2dd95SBruce Richardson port_id); 109499a2dd95SBruce Richardson return -EBUSY; 109599a2dd95SBruce Richardson } 109699a2dd95SBruce Richardson 109702edbfabSHuisong Li /* 109802edbfabSHuisong Li * Ensure that "dev_configured" is always 0 each time prepare to do 109902edbfabSHuisong Li * dev_configure() to avoid any non-anticipated behaviour. 110002edbfabSHuisong Li * And set to 1 when dev_configure() is executed successfully. 110102edbfabSHuisong Li */ 110202edbfabSHuisong Li dev->data->dev_configured = 0; 110302edbfabSHuisong Li 110499a2dd95SBruce Richardson /* Store original config, as rollback required on failure */ 110599a2dd95SBruce Richardson memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf)); 110699a2dd95SBruce Richardson 110799a2dd95SBruce Richardson /* 110899a2dd95SBruce Richardson * Copy the dev_conf parameter into the dev structure. 110999a2dd95SBruce Richardson * rte_eth_dev_info_get() requires dev_conf, copy it before dev_info get 111099a2dd95SBruce Richardson */ 111199a2dd95SBruce Richardson if (dev_conf != &dev->data->dev_conf) 111299a2dd95SBruce Richardson memcpy(&dev->data->dev_conf, dev_conf, 111399a2dd95SBruce Richardson sizeof(dev->data->dev_conf)); 111499a2dd95SBruce Richardson 111599a2dd95SBruce Richardson /* Backup mtu for rollback */ 111699a2dd95SBruce Richardson old_mtu = dev->data->mtu; 111799a2dd95SBruce Richardson 111899a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 111999a2dd95SBruce Richardson if (ret != 0) 112099a2dd95SBruce Richardson goto rollback; 112199a2dd95SBruce Richardson 112299a2dd95SBruce Richardson /* If number of queues specified by application for both Rx and Tx is 112399a2dd95SBruce Richardson * zero, use driver preferred values. This cannot be done individually 112499a2dd95SBruce Richardson * as it is valid for either Tx or Rx (but not both) to be zero. 112599a2dd95SBruce Richardson * If driver does not provide any preferred valued, fall back on 112699a2dd95SBruce Richardson * EAL defaults. 112799a2dd95SBruce Richardson */ 112899a2dd95SBruce Richardson if (nb_rx_q == 0 && nb_tx_q == 0) { 112999a2dd95SBruce Richardson nb_rx_q = dev_info.default_rxportconf.nb_queues; 113099a2dd95SBruce Richardson if (nb_rx_q == 0) 113199a2dd95SBruce Richardson nb_rx_q = RTE_ETH_DEV_FALLBACK_RX_NBQUEUES; 113299a2dd95SBruce Richardson nb_tx_q = dev_info.default_txportconf.nb_queues; 113399a2dd95SBruce Richardson if (nb_tx_q == 0) 113499a2dd95SBruce Richardson nb_tx_q = RTE_ETH_DEV_FALLBACK_TX_NBQUEUES; 113599a2dd95SBruce Richardson } 113699a2dd95SBruce Richardson 113799a2dd95SBruce Richardson if (nb_rx_q > RTE_MAX_QUEUES_PER_PORT) { 113899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 113909fd4227SAndrew Rybchenko "Number of Rx queues requested (%u) is greater than max supported(%d)\n", 114099a2dd95SBruce Richardson nb_rx_q, RTE_MAX_QUEUES_PER_PORT); 114199a2dd95SBruce Richardson ret = -EINVAL; 114299a2dd95SBruce Richardson goto rollback; 114399a2dd95SBruce Richardson } 114499a2dd95SBruce Richardson 114599a2dd95SBruce Richardson if (nb_tx_q > RTE_MAX_QUEUES_PER_PORT) { 114699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 114709fd4227SAndrew Rybchenko "Number of Tx queues requested (%u) is greater than max supported(%d)\n", 114899a2dd95SBruce Richardson nb_tx_q, RTE_MAX_QUEUES_PER_PORT); 114999a2dd95SBruce Richardson ret = -EINVAL; 115099a2dd95SBruce Richardson goto rollback; 115199a2dd95SBruce Richardson } 115299a2dd95SBruce Richardson 115399a2dd95SBruce Richardson /* 115409fd4227SAndrew Rybchenko * Check that the numbers of Rx and Tx queues are not greater 115509fd4227SAndrew Rybchenko * than the maximum number of Rx and Tx queues supported by the 115699a2dd95SBruce Richardson * configured device. 115799a2dd95SBruce Richardson */ 115899a2dd95SBruce Richardson if (nb_rx_q > dev_info.max_rx_queues) { 115999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_rx_queues=%u > %u\n", 116099a2dd95SBruce Richardson port_id, nb_rx_q, dev_info.max_rx_queues); 116199a2dd95SBruce Richardson ret = -EINVAL; 116299a2dd95SBruce Richardson goto rollback; 116399a2dd95SBruce Richardson } 116499a2dd95SBruce Richardson 116599a2dd95SBruce Richardson if (nb_tx_q > dev_info.max_tx_queues) { 116699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_tx_queues=%u > %u\n", 116799a2dd95SBruce Richardson port_id, nb_tx_q, dev_info.max_tx_queues); 116899a2dd95SBruce Richardson ret = -EINVAL; 116999a2dd95SBruce Richardson goto rollback; 117099a2dd95SBruce Richardson } 117199a2dd95SBruce Richardson 117299a2dd95SBruce Richardson /* Check that the device supports requested interrupts */ 117399a2dd95SBruce Richardson if ((dev_conf->intr_conf.lsc == 1) && 117499a2dd95SBruce Richardson (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) { 117599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Driver %s does not support lsc\n", 117699a2dd95SBruce Richardson dev->device->driver->name); 117799a2dd95SBruce Richardson ret = -EINVAL; 117899a2dd95SBruce Richardson goto rollback; 117999a2dd95SBruce Richardson } 118099a2dd95SBruce Richardson if ((dev_conf->intr_conf.rmv == 1) && 118199a2dd95SBruce Richardson (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) { 118299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Driver %s does not support rmv\n", 118399a2dd95SBruce Richardson dev->device->driver->name); 118499a2dd95SBruce Richardson ret = -EINVAL; 118599a2dd95SBruce Richardson goto rollback; 118699a2dd95SBruce Richardson } 118799a2dd95SBruce Richardson 11881bb4a528SFerruh Yigit if (dev_conf->rxmode.mtu == 0) 11891bb4a528SFerruh Yigit dev->data->dev_conf.rxmode.mtu = RTE_ETHER_MTU; 1190990912e6SFerruh Yigit 1191990912e6SFerruh Yigit ret = eth_dev_validate_mtu(port_id, &dev_info, 1192990912e6SFerruh Yigit dev->data->dev_conf.rxmode.mtu); 1193990912e6SFerruh Yigit if (ret != 0) 119499a2dd95SBruce Richardson goto rollback; 119599a2dd95SBruce Richardson 11961bb4a528SFerruh Yigit dev->data->mtu = dev->data->dev_conf.rxmode.mtu; 11971bb4a528SFerruh Yigit 119899a2dd95SBruce Richardson /* 119999a2dd95SBruce Richardson * If LRO is enabled, check that the maximum aggregated packet 120099a2dd95SBruce Richardson * size is supported by the configured device. 120199a2dd95SBruce Richardson */ 1202295968d1SFerruh Yigit if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) { 1203990912e6SFerruh Yigit uint32_t max_rx_pktlen; 1204990912e6SFerruh Yigit uint32_t overhead_len; 1205990912e6SFerruh Yigit 1206990912e6SFerruh Yigit overhead_len = eth_dev_get_overhead_len(dev_info.max_rx_pktlen, 1207990912e6SFerruh Yigit dev_info.max_mtu); 1208990912e6SFerruh Yigit max_rx_pktlen = dev->data->dev_conf.rxmode.mtu + overhead_len; 120999a2dd95SBruce Richardson if (dev_conf->rxmode.max_lro_pkt_size == 0) 12101bb4a528SFerruh Yigit dev->data->dev_conf.rxmode.max_lro_pkt_size = max_rx_pktlen; 121199a2dd95SBruce Richardson ret = eth_dev_check_lro_pkt_size(port_id, 121299a2dd95SBruce Richardson dev->data->dev_conf.rxmode.max_lro_pkt_size, 12131bb4a528SFerruh Yigit max_rx_pktlen, 121499a2dd95SBruce Richardson dev_info.max_lro_pkt_size); 121599a2dd95SBruce Richardson if (ret != 0) 121699a2dd95SBruce Richardson goto rollback; 121799a2dd95SBruce Richardson } 121899a2dd95SBruce Richardson 121999a2dd95SBruce Richardson /* Any requested offloading must be within its device capabilities */ 122099a2dd95SBruce Richardson if ((dev_conf->rxmode.offloads & dev_info.rx_offload_capa) != 122199a2dd95SBruce Richardson dev_conf->rxmode.offloads) { 122299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 122399a2dd95SBruce Richardson "Ethdev port_id=%u requested Rx offloads 0x%"PRIx64" doesn't match Rx offloads " 122499a2dd95SBruce Richardson "capabilities 0x%"PRIx64" in %s()\n", 122599a2dd95SBruce Richardson port_id, dev_conf->rxmode.offloads, 122699a2dd95SBruce Richardson dev_info.rx_offload_capa, 122799a2dd95SBruce Richardson __func__); 122899a2dd95SBruce Richardson ret = -EINVAL; 122999a2dd95SBruce Richardson goto rollback; 123099a2dd95SBruce Richardson } 123199a2dd95SBruce Richardson if ((dev_conf->txmode.offloads & dev_info.tx_offload_capa) != 123299a2dd95SBruce Richardson dev_conf->txmode.offloads) { 123399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 123499a2dd95SBruce Richardson "Ethdev port_id=%u requested Tx offloads 0x%"PRIx64" doesn't match Tx offloads " 123599a2dd95SBruce Richardson "capabilities 0x%"PRIx64" in %s()\n", 123699a2dd95SBruce Richardson port_id, dev_conf->txmode.offloads, 123799a2dd95SBruce Richardson dev_info.tx_offload_capa, 123899a2dd95SBruce Richardson __func__); 123999a2dd95SBruce Richardson ret = -EINVAL; 124099a2dd95SBruce Richardson goto rollback; 124199a2dd95SBruce Richardson } 124299a2dd95SBruce Richardson 124399a2dd95SBruce Richardson dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = 124499a2dd95SBruce Richardson rte_eth_rss_hf_refine(dev_conf->rx_adv_conf.rss_conf.rss_hf); 124599a2dd95SBruce Richardson 124699a2dd95SBruce Richardson /* Check that device supports requested rss hash functions. */ 124799a2dd95SBruce Richardson if ((dev_info.flow_type_rss_offloads | 124899a2dd95SBruce Richardson dev_conf->rx_adv_conf.rss_conf.rss_hf) != 124999a2dd95SBruce Richardson dev_info.flow_type_rss_offloads) { 125099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 125199a2dd95SBruce Richardson "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n", 125299a2dd95SBruce Richardson port_id, dev_conf->rx_adv_conf.rss_conf.rss_hf, 125399a2dd95SBruce Richardson dev_info.flow_type_rss_offloads); 125499a2dd95SBruce Richardson ret = -EINVAL; 125599a2dd95SBruce Richardson goto rollback; 125699a2dd95SBruce Richardson } 125799a2dd95SBruce Richardson 125899a2dd95SBruce Richardson /* Check if Rx RSS distribution is disabled but RSS hash is enabled. */ 1259295968d1SFerruh Yigit if (((dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) == 0) && 1260295968d1SFerruh Yigit (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)) { 126199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 126299a2dd95SBruce Richardson "Ethdev port_id=%u config invalid Rx mq_mode without RSS but %s offload is requested\n", 126399a2dd95SBruce Richardson port_id, 1264295968d1SFerruh Yigit rte_eth_dev_rx_offload_name(RTE_ETH_RX_OFFLOAD_RSS_HASH)); 126599a2dd95SBruce Richardson ret = -EINVAL; 126699a2dd95SBruce Richardson goto rollback; 126799a2dd95SBruce Richardson } 126899a2dd95SBruce Richardson 126999a2dd95SBruce Richardson /* 127009fd4227SAndrew Rybchenko * Setup new number of Rx/Tx queues and reconfigure device. 127199a2dd95SBruce Richardson */ 127299a2dd95SBruce Richardson diag = eth_dev_rx_queue_config(dev, nb_rx_q); 127399a2dd95SBruce Richardson if (diag != 0) { 127499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 127599a2dd95SBruce Richardson "Port%u eth_dev_rx_queue_config = %d\n", 127699a2dd95SBruce Richardson port_id, diag); 127799a2dd95SBruce Richardson ret = diag; 127899a2dd95SBruce Richardson goto rollback; 127999a2dd95SBruce Richardson } 128099a2dd95SBruce Richardson 128199a2dd95SBruce Richardson diag = eth_dev_tx_queue_config(dev, nb_tx_q); 128299a2dd95SBruce Richardson if (diag != 0) { 128399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 128499a2dd95SBruce Richardson "Port%u eth_dev_tx_queue_config = %d\n", 128599a2dd95SBruce Richardson port_id, diag); 128699a2dd95SBruce Richardson eth_dev_rx_queue_config(dev, 0); 128799a2dd95SBruce Richardson ret = diag; 128899a2dd95SBruce Richardson goto rollback; 128999a2dd95SBruce Richardson } 129099a2dd95SBruce Richardson 129199a2dd95SBruce Richardson diag = (*dev->dev_ops->dev_configure)(dev); 129299a2dd95SBruce Richardson if (diag != 0) { 129399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port%u dev_configure = %d\n", 129499a2dd95SBruce Richardson port_id, diag); 129599a2dd95SBruce Richardson ret = eth_err(port_id, diag); 129699a2dd95SBruce Richardson goto reset_queues; 129799a2dd95SBruce Richardson } 129899a2dd95SBruce Richardson 129999a2dd95SBruce Richardson /* Initialize Rx profiling if enabled at compilation time. */ 130099a2dd95SBruce Richardson diag = __rte_eth_dev_profile_init(port_id, dev); 130199a2dd95SBruce Richardson if (diag != 0) { 130299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port%u __rte_eth_dev_profile_init = %d\n", 130399a2dd95SBruce Richardson port_id, diag); 130499a2dd95SBruce Richardson ret = eth_err(port_id, diag); 130599a2dd95SBruce Richardson goto reset_queues; 130699a2dd95SBruce Richardson } 130799a2dd95SBruce Richardson 130899a2dd95SBruce Richardson /* Validate Rx offloads. */ 130999a2dd95SBruce Richardson diag = eth_dev_validate_offloads(port_id, 131099a2dd95SBruce Richardson dev_conf->rxmode.offloads, 131199a2dd95SBruce Richardson dev->data->dev_conf.rxmode.offloads, "Rx", 131299a2dd95SBruce Richardson rte_eth_dev_rx_offload_name); 131399a2dd95SBruce Richardson if (diag != 0) { 131499a2dd95SBruce Richardson ret = diag; 131599a2dd95SBruce Richardson goto reset_queues; 131699a2dd95SBruce Richardson } 131799a2dd95SBruce Richardson 131899a2dd95SBruce Richardson /* Validate Tx offloads. */ 131999a2dd95SBruce Richardson diag = eth_dev_validate_offloads(port_id, 132099a2dd95SBruce Richardson dev_conf->txmode.offloads, 132199a2dd95SBruce Richardson dev->data->dev_conf.txmode.offloads, "Tx", 132299a2dd95SBruce Richardson rte_eth_dev_tx_offload_name); 132399a2dd95SBruce Richardson if (diag != 0) { 132499a2dd95SBruce Richardson ret = diag; 132599a2dd95SBruce Richardson goto reset_queues; 132699a2dd95SBruce Richardson } 132799a2dd95SBruce Richardson 132802edbfabSHuisong Li dev->data->dev_configured = 1; 132999a2dd95SBruce Richardson rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, 0); 133099a2dd95SBruce Richardson return 0; 133199a2dd95SBruce Richardson reset_queues: 133299a2dd95SBruce Richardson eth_dev_rx_queue_config(dev, 0); 133399a2dd95SBruce Richardson eth_dev_tx_queue_config(dev, 0); 133499a2dd95SBruce Richardson rollback: 133599a2dd95SBruce Richardson memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf)); 133699a2dd95SBruce Richardson if (old_mtu != dev->data->mtu) 133799a2dd95SBruce Richardson dev->data->mtu = old_mtu; 133899a2dd95SBruce Richardson 133999a2dd95SBruce Richardson rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, ret); 134099a2dd95SBruce Richardson return ret; 134199a2dd95SBruce Richardson } 134299a2dd95SBruce Richardson 134399a2dd95SBruce Richardson static void 134499a2dd95SBruce Richardson eth_dev_mac_restore(struct rte_eth_dev *dev, 134599a2dd95SBruce Richardson struct rte_eth_dev_info *dev_info) 134699a2dd95SBruce Richardson { 134799a2dd95SBruce Richardson struct rte_ether_addr *addr; 134899a2dd95SBruce Richardson uint16_t i; 134999a2dd95SBruce Richardson uint32_t pool = 0; 135099a2dd95SBruce Richardson uint64_t pool_mask; 135199a2dd95SBruce Richardson 135299a2dd95SBruce Richardson /* replay MAC address configuration including default MAC */ 135399a2dd95SBruce Richardson addr = &dev->data->mac_addrs[0]; 135499a2dd95SBruce Richardson if (*dev->dev_ops->mac_addr_set != NULL) 135599a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_set)(dev, addr); 135699a2dd95SBruce Richardson else if (*dev->dev_ops->mac_addr_add != NULL) 135799a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_add)(dev, addr, 0, pool); 135899a2dd95SBruce Richardson 135999a2dd95SBruce Richardson if (*dev->dev_ops->mac_addr_add != NULL) { 136099a2dd95SBruce Richardson for (i = 1; i < dev_info->max_mac_addrs; i++) { 136199a2dd95SBruce Richardson addr = &dev->data->mac_addrs[i]; 136299a2dd95SBruce Richardson 136399a2dd95SBruce Richardson /* skip zero address */ 136499a2dd95SBruce Richardson if (rte_is_zero_ether_addr(addr)) 136599a2dd95SBruce Richardson continue; 136699a2dd95SBruce Richardson 136799a2dd95SBruce Richardson pool = 0; 136899a2dd95SBruce Richardson pool_mask = dev->data->mac_pool_sel[i]; 136999a2dd95SBruce Richardson 137099a2dd95SBruce Richardson do { 1371e1823e08SThomas Monjalon if (pool_mask & UINT64_C(1)) 137299a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_add)(dev, 137399a2dd95SBruce Richardson addr, i, pool); 137499a2dd95SBruce Richardson pool_mask >>= 1; 137599a2dd95SBruce Richardson pool++; 137699a2dd95SBruce Richardson } while (pool_mask); 137799a2dd95SBruce Richardson } 137899a2dd95SBruce Richardson } 137999a2dd95SBruce Richardson } 138099a2dd95SBruce Richardson 138199a2dd95SBruce Richardson static int 138299a2dd95SBruce Richardson eth_dev_config_restore(struct rte_eth_dev *dev, 138399a2dd95SBruce Richardson struct rte_eth_dev_info *dev_info, uint16_t port_id) 138499a2dd95SBruce Richardson { 138599a2dd95SBruce Richardson int ret; 138699a2dd95SBruce Richardson 138799a2dd95SBruce Richardson if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR)) 138899a2dd95SBruce Richardson eth_dev_mac_restore(dev, dev_info); 138999a2dd95SBruce Richardson 139099a2dd95SBruce Richardson /* replay promiscuous configuration */ 139199a2dd95SBruce Richardson /* 139299a2dd95SBruce Richardson * use callbacks directly since we don't need port_id check and 139399a2dd95SBruce Richardson * would like to bypass the same value set 139499a2dd95SBruce Richardson */ 139599a2dd95SBruce Richardson if (rte_eth_promiscuous_get(port_id) == 1 && 139699a2dd95SBruce Richardson *dev->dev_ops->promiscuous_enable != NULL) { 139799a2dd95SBruce Richardson ret = eth_err(port_id, 139899a2dd95SBruce Richardson (*dev->dev_ops->promiscuous_enable)(dev)); 139999a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 140099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 140199a2dd95SBruce Richardson "Failed to enable promiscuous mode for device (port %u): %s\n", 140299a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 140399a2dd95SBruce Richardson return ret; 140499a2dd95SBruce Richardson } 140599a2dd95SBruce Richardson } else if (rte_eth_promiscuous_get(port_id) == 0 && 140699a2dd95SBruce Richardson *dev->dev_ops->promiscuous_disable != NULL) { 140799a2dd95SBruce Richardson ret = eth_err(port_id, 140899a2dd95SBruce Richardson (*dev->dev_ops->promiscuous_disable)(dev)); 140999a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 141099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 141199a2dd95SBruce Richardson "Failed to disable promiscuous mode for device (port %u): %s\n", 141299a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 141399a2dd95SBruce Richardson return ret; 141499a2dd95SBruce Richardson } 141599a2dd95SBruce Richardson } 141699a2dd95SBruce Richardson 141799a2dd95SBruce Richardson /* replay all multicast configuration */ 141899a2dd95SBruce Richardson /* 141999a2dd95SBruce Richardson * use callbacks directly since we don't need port_id check and 142099a2dd95SBruce Richardson * would like to bypass the same value set 142199a2dd95SBruce Richardson */ 142299a2dd95SBruce Richardson if (rte_eth_allmulticast_get(port_id) == 1 && 142399a2dd95SBruce Richardson *dev->dev_ops->allmulticast_enable != NULL) { 142499a2dd95SBruce Richardson ret = eth_err(port_id, 142599a2dd95SBruce Richardson (*dev->dev_ops->allmulticast_enable)(dev)); 142699a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 142799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 142899a2dd95SBruce Richardson "Failed to enable allmulticast mode for device (port %u): %s\n", 142999a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 143099a2dd95SBruce Richardson return ret; 143199a2dd95SBruce Richardson } 143299a2dd95SBruce Richardson } else if (rte_eth_allmulticast_get(port_id) == 0 && 143399a2dd95SBruce Richardson *dev->dev_ops->allmulticast_disable != NULL) { 143499a2dd95SBruce Richardson ret = eth_err(port_id, 143599a2dd95SBruce Richardson (*dev->dev_ops->allmulticast_disable)(dev)); 143699a2dd95SBruce Richardson if (ret != 0 && ret != -ENOTSUP) { 143799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 143899a2dd95SBruce Richardson "Failed to disable allmulticast mode for device (port %u): %s\n", 143999a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 144099a2dd95SBruce Richardson return ret; 144199a2dd95SBruce Richardson } 144299a2dd95SBruce Richardson } 144399a2dd95SBruce Richardson 144499a2dd95SBruce Richardson return 0; 144599a2dd95SBruce Richardson } 144699a2dd95SBruce Richardson 144799a2dd95SBruce Richardson int 144899a2dd95SBruce Richardson rte_eth_dev_start(uint16_t port_id) 144999a2dd95SBruce Richardson { 145099a2dd95SBruce Richardson struct rte_eth_dev *dev; 145199a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 145299a2dd95SBruce Richardson int diag; 145399a2dd95SBruce Richardson int ret, ret_stop; 145499a2dd95SBruce Richardson 145599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 145699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 145799a2dd95SBruce Richardson 145899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP); 145999a2dd95SBruce Richardson 146002edbfabSHuisong Li if (dev->data->dev_configured == 0) { 146102edbfabSHuisong Li RTE_ETHDEV_LOG(INFO, 146202edbfabSHuisong Li "Device with port_id=%"PRIu16" is not configured.\n", 146302edbfabSHuisong Li port_id); 146402edbfabSHuisong Li return -EINVAL; 146502edbfabSHuisong Li } 146602edbfabSHuisong Li 146799a2dd95SBruce Richardson if (dev->data->dev_started != 0) { 146899a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 146999a2dd95SBruce Richardson "Device with port_id=%"PRIu16" already started\n", 147099a2dd95SBruce Richardson port_id); 147199a2dd95SBruce Richardson return 0; 147299a2dd95SBruce Richardson } 147399a2dd95SBruce Richardson 147499a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 147599a2dd95SBruce Richardson if (ret != 0) 147699a2dd95SBruce Richardson return ret; 147799a2dd95SBruce Richardson 147899a2dd95SBruce Richardson /* Lets restore MAC now if device does not support live change */ 147999a2dd95SBruce Richardson if (*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR) 148099a2dd95SBruce Richardson eth_dev_mac_restore(dev, &dev_info); 148199a2dd95SBruce Richardson 148299a2dd95SBruce Richardson diag = (*dev->dev_ops->dev_start)(dev); 148399a2dd95SBruce Richardson if (diag == 0) 148499a2dd95SBruce Richardson dev->data->dev_started = 1; 148599a2dd95SBruce Richardson else 148699a2dd95SBruce Richardson return eth_err(port_id, diag); 148799a2dd95SBruce Richardson 148899a2dd95SBruce Richardson ret = eth_dev_config_restore(dev, &dev_info, port_id); 148999a2dd95SBruce Richardson if (ret != 0) { 149099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 149199a2dd95SBruce Richardson "Error during restoring configuration for device (port %u): %s\n", 149299a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 149399a2dd95SBruce Richardson ret_stop = rte_eth_dev_stop(port_id); 149499a2dd95SBruce Richardson if (ret_stop != 0) { 149599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 149699a2dd95SBruce Richardson "Failed to stop device (port %u): %s\n", 149799a2dd95SBruce Richardson port_id, rte_strerror(-ret_stop)); 149899a2dd95SBruce Richardson } 149999a2dd95SBruce Richardson 150099a2dd95SBruce Richardson return ret; 150199a2dd95SBruce Richardson } 150299a2dd95SBruce Richardson 150399a2dd95SBruce Richardson if (dev->data->dev_conf.intr_conf.lsc == 0) { 150499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP); 150599a2dd95SBruce Richardson (*dev->dev_ops->link_update)(dev, 0); 150699a2dd95SBruce Richardson } 150799a2dd95SBruce Richardson 1508c87d435aSKonstantin Ananyev /* expose selection of PMD fast-path functions */ 1509c87d435aSKonstantin Ananyev eth_dev_fp_ops_setup(rte_eth_fp_ops + port_id, dev); 1510c87d435aSKonstantin Ananyev 151199a2dd95SBruce Richardson rte_ethdev_trace_start(port_id); 151299a2dd95SBruce Richardson return 0; 151399a2dd95SBruce Richardson } 151499a2dd95SBruce Richardson 151599a2dd95SBruce Richardson int 151699a2dd95SBruce Richardson rte_eth_dev_stop(uint16_t port_id) 151799a2dd95SBruce Richardson { 151899a2dd95SBruce Richardson struct rte_eth_dev *dev; 151999a2dd95SBruce Richardson int ret; 152099a2dd95SBruce Richardson 152199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 152299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 152399a2dd95SBruce Richardson 152499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_stop, -ENOTSUP); 152599a2dd95SBruce Richardson 152699a2dd95SBruce Richardson if (dev->data->dev_started == 0) { 152799a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 152899a2dd95SBruce Richardson "Device with port_id=%"PRIu16" already stopped\n", 152999a2dd95SBruce Richardson port_id); 153099a2dd95SBruce Richardson return 0; 153199a2dd95SBruce Richardson } 153299a2dd95SBruce Richardson 1533c87d435aSKonstantin Ananyev /* point fast-path functions to dummy ones */ 1534c87d435aSKonstantin Ananyev eth_dev_fp_ops_reset(rte_eth_fp_ops + port_id); 1535c87d435aSKonstantin Ananyev 153699a2dd95SBruce Richardson dev->data->dev_started = 0; 153799a2dd95SBruce Richardson ret = (*dev->dev_ops->dev_stop)(dev); 153899a2dd95SBruce Richardson rte_ethdev_trace_stop(port_id, ret); 153999a2dd95SBruce Richardson 154099a2dd95SBruce Richardson return ret; 154199a2dd95SBruce Richardson } 154299a2dd95SBruce Richardson 154399a2dd95SBruce Richardson int 154499a2dd95SBruce Richardson rte_eth_dev_set_link_up(uint16_t port_id) 154599a2dd95SBruce Richardson { 154699a2dd95SBruce Richardson struct rte_eth_dev *dev; 154799a2dd95SBruce Richardson 154899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 154999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 155099a2dd95SBruce Richardson 155199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_up, -ENOTSUP); 155299a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->dev_set_link_up)(dev)); 155399a2dd95SBruce Richardson } 155499a2dd95SBruce Richardson 155599a2dd95SBruce Richardson int 155699a2dd95SBruce Richardson rte_eth_dev_set_link_down(uint16_t port_id) 155799a2dd95SBruce Richardson { 155899a2dd95SBruce Richardson struct rte_eth_dev *dev; 155999a2dd95SBruce Richardson 156099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 156199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 156299a2dd95SBruce Richardson 156399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_down, -ENOTSUP); 156499a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->dev_set_link_down)(dev)); 156599a2dd95SBruce Richardson } 156699a2dd95SBruce Richardson 156799a2dd95SBruce Richardson int 156899a2dd95SBruce Richardson rte_eth_dev_close(uint16_t port_id) 156999a2dd95SBruce Richardson { 157099a2dd95SBruce Richardson struct rte_eth_dev *dev; 157199a2dd95SBruce Richardson int firsterr, binerr; 157299a2dd95SBruce Richardson int *lasterr = &firsterr; 157399a2dd95SBruce Richardson 157499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 157599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 157699a2dd95SBruce Richardson 1577febc855bSAndrew Rybchenko if (dev->data->dev_started) { 1578febc855bSAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Cannot close started device (port %u)\n", 1579febc855bSAndrew Rybchenko port_id); 1580febc855bSAndrew Rybchenko return -EINVAL; 1581febc855bSAndrew Rybchenko } 1582febc855bSAndrew Rybchenko 158399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP); 158499a2dd95SBruce Richardson *lasterr = (*dev->dev_ops->dev_close)(dev); 158599a2dd95SBruce Richardson if (*lasterr != 0) 158699a2dd95SBruce Richardson lasterr = &binerr; 158799a2dd95SBruce Richardson 158899a2dd95SBruce Richardson rte_ethdev_trace_close(port_id); 158999a2dd95SBruce Richardson *lasterr = rte_eth_dev_release_port(dev); 159099a2dd95SBruce Richardson 159199a2dd95SBruce Richardson return firsterr; 159299a2dd95SBruce Richardson } 159399a2dd95SBruce Richardson 159499a2dd95SBruce Richardson int 159599a2dd95SBruce Richardson rte_eth_dev_reset(uint16_t port_id) 159699a2dd95SBruce Richardson { 159799a2dd95SBruce Richardson struct rte_eth_dev *dev; 159899a2dd95SBruce Richardson int ret; 159999a2dd95SBruce Richardson 160099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 160199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 160299a2dd95SBruce Richardson 160399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP); 160499a2dd95SBruce Richardson 160599a2dd95SBruce Richardson ret = rte_eth_dev_stop(port_id); 160699a2dd95SBruce Richardson if (ret != 0) { 160799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 160899a2dd95SBruce Richardson "Failed to stop device (port %u) before reset: %s - ignore\n", 160999a2dd95SBruce Richardson port_id, rte_strerror(-ret)); 161099a2dd95SBruce Richardson } 161199a2dd95SBruce Richardson ret = dev->dev_ops->dev_reset(dev); 161299a2dd95SBruce Richardson 161399a2dd95SBruce Richardson return eth_err(port_id, ret); 161499a2dd95SBruce Richardson } 161599a2dd95SBruce Richardson 161699a2dd95SBruce Richardson int 161799a2dd95SBruce Richardson rte_eth_dev_is_removed(uint16_t port_id) 161899a2dd95SBruce Richardson { 161999a2dd95SBruce Richardson struct rte_eth_dev *dev; 162099a2dd95SBruce Richardson int ret; 162199a2dd95SBruce Richardson 162299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0); 162399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 162499a2dd95SBruce Richardson 162599a2dd95SBruce Richardson if (dev->state == RTE_ETH_DEV_REMOVED) 162699a2dd95SBruce Richardson return 1; 162799a2dd95SBruce Richardson 162899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->is_removed, 0); 162999a2dd95SBruce Richardson 163099a2dd95SBruce Richardson ret = dev->dev_ops->is_removed(dev); 163199a2dd95SBruce Richardson if (ret != 0) 163299a2dd95SBruce Richardson /* Device is physically removed. */ 163399a2dd95SBruce Richardson dev->state = RTE_ETH_DEV_REMOVED; 163499a2dd95SBruce Richardson 163599a2dd95SBruce Richardson return ret; 163699a2dd95SBruce Richardson } 163799a2dd95SBruce Richardson 163899a2dd95SBruce Richardson static int 163999a2dd95SBruce Richardson rte_eth_rx_queue_check_split(const struct rte_eth_rxseg_split *rx_seg, 164099a2dd95SBruce Richardson uint16_t n_seg, uint32_t *mbp_buf_size, 164199a2dd95SBruce Richardson const struct rte_eth_dev_info *dev_info) 164299a2dd95SBruce Richardson { 164399a2dd95SBruce Richardson const struct rte_eth_rxseg_capa *seg_capa = &dev_info->rx_seg_capa; 164499a2dd95SBruce Richardson struct rte_mempool *mp_first; 164599a2dd95SBruce Richardson uint32_t offset_mask; 164699a2dd95SBruce Richardson uint16_t seg_idx; 164799a2dd95SBruce Richardson 164899a2dd95SBruce Richardson if (n_seg > seg_capa->max_nseg) { 164999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 165099a2dd95SBruce Richardson "Requested Rx segments %u exceed supported %u\n", 165199a2dd95SBruce Richardson n_seg, seg_capa->max_nseg); 165299a2dd95SBruce Richardson return -EINVAL; 165399a2dd95SBruce Richardson } 165499a2dd95SBruce Richardson /* 165599a2dd95SBruce Richardson * Check the sizes and offsets against buffer sizes 165699a2dd95SBruce Richardson * for each segment specified in extended configuration. 165799a2dd95SBruce Richardson */ 165899a2dd95SBruce Richardson mp_first = rx_seg[0].mp; 1659e1823e08SThomas Monjalon offset_mask = RTE_BIT32(seg_capa->offset_align_log2) - 1; 166099a2dd95SBruce Richardson for (seg_idx = 0; seg_idx < n_seg; seg_idx++) { 166199a2dd95SBruce Richardson struct rte_mempool *mpl = rx_seg[seg_idx].mp; 166299a2dd95SBruce Richardson uint32_t length = rx_seg[seg_idx].length; 166399a2dd95SBruce Richardson uint32_t offset = rx_seg[seg_idx].offset; 166499a2dd95SBruce Richardson 166599a2dd95SBruce Richardson if (mpl == NULL) { 166699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "null mempool pointer\n"); 166799a2dd95SBruce Richardson return -EINVAL; 166899a2dd95SBruce Richardson } 166999a2dd95SBruce Richardson if (seg_idx != 0 && mp_first != mpl && 167099a2dd95SBruce Richardson seg_capa->multi_pools == 0) { 167199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Receiving to multiple pools is not supported\n"); 167299a2dd95SBruce Richardson return -ENOTSUP; 167399a2dd95SBruce Richardson } 167499a2dd95SBruce Richardson if (offset != 0) { 167599a2dd95SBruce Richardson if (seg_capa->offset_allowed == 0) { 167699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Rx segmentation with offset is not supported\n"); 167799a2dd95SBruce Richardson return -ENOTSUP; 167899a2dd95SBruce Richardson } 167999a2dd95SBruce Richardson if (offset & offset_mask) { 168099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Rx segmentation invalid offset alignment %u, %u\n", 168199a2dd95SBruce Richardson offset, 168299a2dd95SBruce Richardson seg_capa->offset_align_log2); 168399a2dd95SBruce Richardson return -EINVAL; 168499a2dd95SBruce Richardson } 168599a2dd95SBruce Richardson } 168699a2dd95SBruce Richardson if (mpl->private_data_size < 168799a2dd95SBruce Richardson sizeof(struct rte_pktmbuf_pool_private)) { 168899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 168999a2dd95SBruce Richardson "%s private_data_size %u < %u\n", 169099a2dd95SBruce Richardson mpl->name, mpl->private_data_size, 169199a2dd95SBruce Richardson (unsigned int)sizeof 169299a2dd95SBruce Richardson (struct rte_pktmbuf_pool_private)); 169399a2dd95SBruce Richardson return -ENOSPC; 169499a2dd95SBruce Richardson } 169599a2dd95SBruce Richardson offset += seg_idx != 0 ? 0 : RTE_PKTMBUF_HEADROOM; 169699a2dd95SBruce Richardson *mbp_buf_size = rte_pktmbuf_data_room_size(mpl); 169799a2dd95SBruce Richardson length = length != 0 ? length : *mbp_buf_size; 169899a2dd95SBruce Richardson if (*mbp_buf_size < length + offset) { 169999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 170099a2dd95SBruce Richardson "%s mbuf_data_room_size %u < %u (segment length=%u + segment offset=%u)\n", 170199a2dd95SBruce Richardson mpl->name, *mbp_buf_size, 170299a2dd95SBruce Richardson length + offset, length, offset); 170399a2dd95SBruce Richardson return -EINVAL; 170499a2dd95SBruce Richardson } 170599a2dd95SBruce Richardson } 170699a2dd95SBruce Richardson return 0; 170799a2dd95SBruce Richardson } 170899a2dd95SBruce Richardson 170999a2dd95SBruce Richardson int 171099a2dd95SBruce Richardson rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id, 171199a2dd95SBruce Richardson uint16_t nb_rx_desc, unsigned int socket_id, 171299a2dd95SBruce Richardson const struct rte_eth_rxconf *rx_conf, 171399a2dd95SBruce Richardson struct rte_mempool *mp) 171499a2dd95SBruce Richardson { 171599a2dd95SBruce Richardson int ret; 171699a2dd95SBruce Richardson uint32_t mbp_buf_size; 171799a2dd95SBruce Richardson struct rte_eth_dev *dev; 171899a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 171999a2dd95SBruce Richardson struct rte_eth_rxconf local_conf; 172099a2dd95SBruce Richardson 172199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 172299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 172353ef1b34SMin Hu (Connor) 172499a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 172509fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", rx_queue_id); 172699a2dd95SBruce Richardson return -EINVAL; 172799a2dd95SBruce Richardson } 172899a2dd95SBruce Richardson 172999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP); 173099a2dd95SBruce Richardson 173199a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 173299a2dd95SBruce Richardson if (ret != 0) 173399a2dd95SBruce Richardson return ret; 173499a2dd95SBruce Richardson 173599a2dd95SBruce Richardson if (mp != NULL) { 173699a2dd95SBruce Richardson /* Single pool configuration check. */ 173799a2dd95SBruce Richardson if (rx_conf != NULL && rx_conf->rx_nseg != 0) { 173899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 173999a2dd95SBruce Richardson "Ambiguous segment configuration\n"); 174099a2dd95SBruce Richardson return -EINVAL; 174199a2dd95SBruce Richardson } 174299a2dd95SBruce Richardson /* 174399a2dd95SBruce Richardson * Check the size of the mbuf data buffer, this value 174499a2dd95SBruce Richardson * must be provided in the private data of the memory pool. 174599a2dd95SBruce Richardson * First check that the memory pool(s) has a valid private data. 174699a2dd95SBruce Richardson */ 174799a2dd95SBruce Richardson if (mp->private_data_size < 174899a2dd95SBruce Richardson sizeof(struct rte_pktmbuf_pool_private)) { 174999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "%s private_data_size %u < %u\n", 175099a2dd95SBruce Richardson mp->name, mp->private_data_size, 175199a2dd95SBruce Richardson (unsigned int) 175299a2dd95SBruce Richardson sizeof(struct rte_pktmbuf_pool_private)); 175399a2dd95SBruce Richardson return -ENOSPC; 175499a2dd95SBruce Richardson } 175599a2dd95SBruce Richardson mbp_buf_size = rte_pktmbuf_data_room_size(mp); 175699a2dd95SBruce Richardson if (mbp_buf_size < dev_info.min_rx_bufsize + 175799a2dd95SBruce Richardson RTE_PKTMBUF_HEADROOM) { 175899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 175999a2dd95SBruce Richardson "%s mbuf_data_room_size %u < %u (RTE_PKTMBUF_HEADROOM=%u + min_rx_bufsize(dev)=%u)\n", 176099a2dd95SBruce Richardson mp->name, mbp_buf_size, 176199a2dd95SBruce Richardson RTE_PKTMBUF_HEADROOM + 176299a2dd95SBruce Richardson dev_info.min_rx_bufsize, 176399a2dd95SBruce Richardson RTE_PKTMBUF_HEADROOM, 176499a2dd95SBruce Richardson dev_info.min_rx_bufsize); 176599a2dd95SBruce Richardson return -EINVAL; 176699a2dd95SBruce Richardson } 176799a2dd95SBruce Richardson } else { 176899a2dd95SBruce Richardson const struct rte_eth_rxseg_split *rx_seg; 176999a2dd95SBruce Richardson uint16_t n_seg; 177099a2dd95SBruce Richardson 177199a2dd95SBruce Richardson /* Extended multi-segment configuration check. */ 177299a2dd95SBruce Richardson if (rx_conf == NULL || rx_conf->rx_seg == NULL || rx_conf->rx_nseg == 0) { 177399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 177499a2dd95SBruce Richardson "Memory pool is null and no extended configuration provided\n"); 177599a2dd95SBruce Richardson return -EINVAL; 177699a2dd95SBruce Richardson } 177799a2dd95SBruce Richardson 177899a2dd95SBruce Richardson rx_seg = (const struct rte_eth_rxseg_split *)rx_conf->rx_seg; 177999a2dd95SBruce Richardson n_seg = rx_conf->rx_nseg; 178099a2dd95SBruce Richardson 178199a2dd95SBruce Richardson if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) { 178299a2dd95SBruce Richardson ret = rte_eth_rx_queue_check_split(rx_seg, n_seg, 178399a2dd95SBruce Richardson &mbp_buf_size, 178499a2dd95SBruce Richardson &dev_info); 178599a2dd95SBruce Richardson if (ret != 0) 178699a2dd95SBruce Richardson return ret; 178799a2dd95SBruce Richardson } else { 178899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "No Rx segmentation offload configured\n"); 178999a2dd95SBruce Richardson return -EINVAL; 179099a2dd95SBruce Richardson } 179199a2dd95SBruce Richardson } 179299a2dd95SBruce Richardson 179399a2dd95SBruce Richardson /* Use default specified by driver, if nb_rx_desc is zero */ 179499a2dd95SBruce Richardson if (nb_rx_desc == 0) { 179599a2dd95SBruce Richardson nb_rx_desc = dev_info.default_rxportconf.ring_size; 179699a2dd95SBruce Richardson /* If driver default is also zero, fall back on EAL default */ 179799a2dd95SBruce Richardson if (nb_rx_desc == 0) 179899a2dd95SBruce Richardson nb_rx_desc = RTE_ETH_DEV_FALLBACK_RX_RINGSIZE; 179999a2dd95SBruce Richardson } 180099a2dd95SBruce Richardson 180199a2dd95SBruce Richardson if (nb_rx_desc > dev_info.rx_desc_lim.nb_max || 180299a2dd95SBruce Richardson nb_rx_desc < dev_info.rx_desc_lim.nb_min || 180399a2dd95SBruce Richardson nb_rx_desc % dev_info.rx_desc_lim.nb_align != 0) { 180499a2dd95SBruce Richardson 180599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 180699a2dd95SBruce Richardson "Invalid value for nb_rx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n", 180799a2dd95SBruce Richardson nb_rx_desc, dev_info.rx_desc_lim.nb_max, 180899a2dd95SBruce Richardson dev_info.rx_desc_lim.nb_min, 180999a2dd95SBruce Richardson dev_info.rx_desc_lim.nb_align); 181099a2dd95SBruce Richardson return -EINVAL; 181199a2dd95SBruce Richardson } 181299a2dd95SBruce Richardson 181399a2dd95SBruce Richardson if (dev->data->dev_started && 181499a2dd95SBruce Richardson !(dev_info.dev_capa & 181599a2dd95SBruce Richardson RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP)) 181699a2dd95SBruce Richardson return -EBUSY; 181799a2dd95SBruce Richardson 181899a2dd95SBruce Richardson if (dev->data->dev_started && 181999a2dd95SBruce Richardson (dev->data->rx_queue_state[rx_queue_id] != 182099a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_STOPPED)) 182199a2dd95SBruce Richardson return -EBUSY; 182299a2dd95SBruce Richardson 182349ed3224SXueming Li eth_dev_rxq_release(dev, rx_queue_id); 182499a2dd95SBruce Richardson 182599a2dd95SBruce Richardson if (rx_conf == NULL) 182699a2dd95SBruce Richardson rx_conf = &dev_info.default_rxconf; 182799a2dd95SBruce Richardson 182899a2dd95SBruce Richardson local_conf = *rx_conf; 182999a2dd95SBruce Richardson 183099a2dd95SBruce Richardson /* 183199a2dd95SBruce Richardson * If an offloading has already been enabled in 183299a2dd95SBruce Richardson * rte_eth_dev_configure(), it has been enabled on all queues, 183399a2dd95SBruce Richardson * so there is no need to enable it in this queue again. 183499a2dd95SBruce Richardson * The local_conf.offloads input to underlying PMD only carries 183599a2dd95SBruce Richardson * those offloadings which are only enabled on this queue and 183699a2dd95SBruce Richardson * not enabled on all queues. 183799a2dd95SBruce Richardson */ 183899a2dd95SBruce Richardson local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads; 183999a2dd95SBruce Richardson 184099a2dd95SBruce Richardson /* 184199a2dd95SBruce Richardson * New added offloadings for this queue are those not enabled in 184299a2dd95SBruce Richardson * rte_eth_dev_configure() and they must be per-queue type. 184399a2dd95SBruce Richardson * A pure per-port offloading can't be enabled on a queue while 184499a2dd95SBruce Richardson * disabled on another queue. A pure per-port offloading can't 184599a2dd95SBruce Richardson * be enabled for any queue as new added one if it hasn't been 184699a2dd95SBruce Richardson * enabled in rte_eth_dev_configure(). 184799a2dd95SBruce Richardson */ 184899a2dd95SBruce Richardson if ((local_conf.offloads & dev_info.rx_queue_offload_capa) != 184999a2dd95SBruce Richardson local_conf.offloads) { 185099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 185199a2dd95SBruce Richardson "Ethdev port_id=%d rx_queue_id=%d, new added offloads 0x%"PRIx64" must be " 185299a2dd95SBruce Richardson "within per-queue offload capabilities 0x%"PRIx64" in %s()\n", 185399a2dd95SBruce Richardson port_id, rx_queue_id, local_conf.offloads, 185499a2dd95SBruce Richardson dev_info.rx_queue_offload_capa, 185599a2dd95SBruce Richardson __func__); 185699a2dd95SBruce Richardson return -EINVAL; 185799a2dd95SBruce Richardson } 185899a2dd95SBruce Richardson 1859dd22740cSXueming Li if (local_conf.share_group > 0 && 1860dd22740cSXueming Li (dev_info.dev_capa & RTE_ETH_DEV_CAPA_RXQ_SHARE) == 0) { 1861dd22740cSXueming Li RTE_ETHDEV_LOG(ERR, 1862dd22740cSXueming Li "Ethdev port_id=%d rx_queue_id=%d, enabled share_group=%hu while device doesn't support Rx queue share\n", 1863dd22740cSXueming Li port_id, rx_queue_id, local_conf.share_group); 1864dd22740cSXueming Li return -EINVAL; 1865dd22740cSXueming Li } 1866dd22740cSXueming Li 186799a2dd95SBruce Richardson /* 186899a2dd95SBruce Richardson * If LRO is enabled, check that the maximum aggregated packet 186999a2dd95SBruce Richardson * size is supported by the configured device. 187099a2dd95SBruce Richardson */ 18711bb4a528SFerruh Yigit /* Get the real Ethernet overhead length */ 1872295968d1SFerruh Yigit if (local_conf.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) { 18731bb4a528SFerruh Yigit uint32_t overhead_len; 18741bb4a528SFerruh Yigit uint32_t max_rx_pktlen; 18751bb4a528SFerruh Yigit int ret; 18761bb4a528SFerruh Yigit 18771bb4a528SFerruh Yigit overhead_len = eth_dev_get_overhead_len(dev_info.max_rx_pktlen, 18781bb4a528SFerruh Yigit dev_info.max_mtu); 18791bb4a528SFerruh Yigit max_rx_pktlen = dev->data->mtu + overhead_len; 188099a2dd95SBruce Richardson if (dev->data->dev_conf.rxmode.max_lro_pkt_size == 0) 18811bb4a528SFerruh Yigit dev->data->dev_conf.rxmode.max_lro_pkt_size = max_rx_pktlen; 18821bb4a528SFerruh Yigit ret = eth_dev_check_lro_pkt_size(port_id, 188399a2dd95SBruce Richardson dev->data->dev_conf.rxmode.max_lro_pkt_size, 18841bb4a528SFerruh Yigit max_rx_pktlen, 188599a2dd95SBruce Richardson dev_info.max_lro_pkt_size); 188699a2dd95SBruce Richardson if (ret != 0) 188799a2dd95SBruce Richardson return ret; 188899a2dd95SBruce Richardson } 188999a2dd95SBruce Richardson 189099a2dd95SBruce Richardson ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc, 189199a2dd95SBruce Richardson socket_id, &local_conf, mp); 189299a2dd95SBruce Richardson if (!ret) { 189399a2dd95SBruce Richardson if (!dev->data->min_rx_buf_size || 189499a2dd95SBruce Richardson dev->data->min_rx_buf_size > mbp_buf_size) 189599a2dd95SBruce Richardson dev->data->min_rx_buf_size = mbp_buf_size; 189699a2dd95SBruce Richardson } 189799a2dd95SBruce Richardson 189899a2dd95SBruce Richardson rte_ethdev_trace_rxq_setup(port_id, rx_queue_id, nb_rx_desc, mp, 189999a2dd95SBruce Richardson rx_conf, ret); 190099a2dd95SBruce Richardson return eth_err(port_id, ret); 190199a2dd95SBruce Richardson } 190299a2dd95SBruce Richardson 190399a2dd95SBruce Richardson int 190499a2dd95SBruce Richardson rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id, 190599a2dd95SBruce Richardson uint16_t nb_rx_desc, 190699a2dd95SBruce Richardson const struct rte_eth_hairpin_conf *conf) 190799a2dd95SBruce Richardson { 190899a2dd95SBruce Richardson int ret; 190999a2dd95SBruce Richardson struct rte_eth_dev *dev; 191099a2dd95SBruce Richardson struct rte_eth_hairpin_cap cap; 191199a2dd95SBruce Richardson int i; 191299a2dd95SBruce Richardson int count; 191399a2dd95SBruce Richardson 191499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 191599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 191653ef1b34SMin Hu (Connor) 191799a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 191809fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", rx_queue_id); 191999a2dd95SBruce Richardson return -EINVAL; 192099a2dd95SBruce Richardson } 192153ef1b34SMin Hu (Connor) 192253ef1b34SMin Hu (Connor) if (conf == NULL) { 192353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 192453ef1b34SMin Hu (Connor) "Cannot setup ethdev port %u Rx hairpin queue from NULL config\n", 192553ef1b34SMin Hu (Connor) port_id); 192653ef1b34SMin Hu (Connor) return -EINVAL; 192753ef1b34SMin Hu (Connor) } 192853ef1b34SMin Hu (Connor) 192999a2dd95SBruce Richardson ret = rte_eth_dev_hairpin_capability_get(port_id, &cap); 193099a2dd95SBruce Richardson if (ret != 0) 193199a2dd95SBruce Richardson return ret; 193299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_hairpin_queue_setup, 193399a2dd95SBruce Richardson -ENOTSUP); 193499a2dd95SBruce Richardson /* if nb_rx_desc is zero use max number of desc from the driver. */ 193599a2dd95SBruce Richardson if (nb_rx_desc == 0) 193699a2dd95SBruce Richardson nb_rx_desc = cap.max_nb_desc; 193799a2dd95SBruce Richardson if (nb_rx_desc > cap.max_nb_desc) { 193899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 193999a2dd95SBruce Richardson "Invalid value for nb_rx_desc(=%hu), should be: <= %hu", 194099a2dd95SBruce Richardson nb_rx_desc, cap.max_nb_desc); 194199a2dd95SBruce Richardson return -EINVAL; 194299a2dd95SBruce Richardson } 194399a2dd95SBruce Richardson if (conf->peer_count > cap.max_rx_2_tx) { 194499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 194599a2dd95SBruce Richardson "Invalid value for number of peers for Rx queue(=%u), should be: <= %hu", 194699a2dd95SBruce Richardson conf->peer_count, cap.max_rx_2_tx); 194799a2dd95SBruce Richardson return -EINVAL; 194899a2dd95SBruce Richardson } 194999a2dd95SBruce Richardson if (conf->peer_count == 0) { 195099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 195199a2dd95SBruce Richardson "Invalid value for number of peers for Rx queue(=%u), should be: > 0", 195299a2dd95SBruce Richardson conf->peer_count); 195399a2dd95SBruce Richardson return -EINVAL; 195499a2dd95SBruce Richardson } 195599a2dd95SBruce Richardson for (i = 0, count = 0; i < dev->data->nb_rx_queues && 195699a2dd95SBruce Richardson cap.max_nb_queues != UINT16_MAX; i++) { 195799a2dd95SBruce Richardson if (i == rx_queue_id || rte_eth_dev_is_rx_hairpin_queue(dev, i)) 195899a2dd95SBruce Richardson count++; 195999a2dd95SBruce Richardson } 196099a2dd95SBruce Richardson if (count > cap.max_nb_queues) { 196199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "To many Rx hairpin queues max is %d", 196299a2dd95SBruce Richardson cap.max_nb_queues); 196399a2dd95SBruce Richardson return -EINVAL; 196499a2dd95SBruce Richardson } 196599a2dd95SBruce Richardson if (dev->data->dev_started) 196699a2dd95SBruce Richardson return -EBUSY; 196749ed3224SXueming Li eth_dev_rxq_release(dev, rx_queue_id); 196899a2dd95SBruce Richardson ret = (*dev->dev_ops->rx_hairpin_queue_setup)(dev, rx_queue_id, 196999a2dd95SBruce Richardson nb_rx_desc, conf); 197099a2dd95SBruce Richardson if (ret == 0) 197199a2dd95SBruce Richardson dev->data->rx_queue_state[rx_queue_id] = 197299a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_HAIRPIN; 197399a2dd95SBruce Richardson return eth_err(port_id, ret); 197499a2dd95SBruce Richardson } 197599a2dd95SBruce Richardson 197699a2dd95SBruce Richardson int 197799a2dd95SBruce Richardson rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id, 197899a2dd95SBruce Richardson uint16_t nb_tx_desc, unsigned int socket_id, 197999a2dd95SBruce Richardson const struct rte_eth_txconf *tx_conf) 198099a2dd95SBruce Richardson { 198199a2dd95SBruce Richardson struct rte_eth_dev *dev; 198299a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 198399a2dd95SBruce Richardson struct rte_eth_txconf local_conf; 198499a2dd95SBruce Richardson int ret; 198599a2dd95SBruce Richardson 198699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 198799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 198853ef1b34SMin Hu (Connor) 198999a2dd95SBruce Richardson if (tx_queue_id >= dev->data->nb_tx_queues) { 199009fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", tx_queue_id); 199199a2dd95SBruce Richardson return -EINVAL; 199299a2dd95SBruce Richardson } 199399a2dd95SBruce Richardson 199499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -ENOTSUP); 199599a2dd95SBruce Richardson 199699a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 199799a2dd95SBruce Richardson if (ret != 0) 199899a2dd95SBruce Richardson return ret; 199999a2dd95SBruce Richardson 200099a2dd95SBruce Richardson /* Use default specified by driver, if nb_tx_desc is zero */ 200199a2dd95SBruce Richardson if (nb_tx_desc == 0) { 200299a2dd95SBruce Richardson nb_tx_desc = dev_info.default_txportconf.ring_size; 200399a2dd95SBruce Richardson /* If driver default is zero, fall back on EAL default */ 200499a2dd95SBruce Richardson if (nb_tx_desc == 0) 200599a2dd95SBruce Richardson nb_tx_desc = RTE_ETH_DEV_FALLBACK_TX_RINGSIZE; 200699a2dd95SBruce Richardson } 200799a2dd95SBruce Richardson if (nb_tx_desc > dev_info.tx_desc_lim.nb_max || 200899a2dd95SBruce Richardson nb_tx_desc < dev_info.tx_desc_lim.nb_min || 200999a2dd95SBruce Richardson nb_tx_desc % dev_info.tx_desc_lim.nb_align != 0) { 201099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 201199a2dd95SBruce Richardson "Invalid value for nb_tx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n", 201299a2dd95SBruce Richardson nb_tx_desc, dev_info.tx_desc_lim.nb_max, 201399a2dd95SBruce Richardson dev_info.tx_desc_lim.nb_min, 201499a2dd95SBruce Richardson dev_info.tx_desc_lim.nb_align); 201599a2dd95SBruce Richardson return -EINVAL; 201699a2dd95SBruce Richardson } 201799a2dd95SBruce Richardson 201899a2dd95SBruce Richardson if (dev->data->dev_started && 201999a2dd95SBruce Richardson !(dev_info.dev_capa & 202099a2dd95SBruce Richardson RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP)) 202199a2dd95SBruce Richardson return -EBUSY; 202299a2dd95SBruce Richardson 202399a2dd95SBruce Richardson if (dev->data->dev_started && 202499a2dd95SBruce Richardson (dev->data->tx_queue_state[tx_queue_id] != 202599a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_STOPPED)) 202699a2dd95SBruce Richardson return -EBUSY; 202799a2dd95SBruce Richardson 202849ed3224SXueming Li eth_dev_txq_release(dev, tx_queue_id); 202999a2dd95SBruce Richardson 203099a2dd95SBruce Richardson if (tx_conf == NULL) 203199a2dd95SBruce Richardson tx_conf = &dev_info.default_txconf; 203299a2dd95SBruce Richardson 203399a2dd95SBruce Richardson local_conf = *tx_conf; 203499a2dd95SBruce Richardson 203599a2dd95SBruce Richardson /* 203699a2dd95SBruce Richardson * If an offloading has already been enabled in 203799a2dd95SBruce Richardson * rte_eth_dev_configure(), it has been enabled on all queues, 203899a2dd95SBruce Richardson * so there is no need to enable it in this queue again. 203999a2dd95SBruce Richardson * The local_conf.offloads input to underlying PMD only carries 204099a2dd95SBruce Richardson * those offloadings which are only enabled on this queue and 204199a2dd95SBruce Richardson * not enabled on all queues. 204299a2dd95SBruce Richardson */ 204399a2dd95SBruce Richardson local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads; 204499a2dd95SBruce Richardson 204599a2dd95SBruce Richardson /* 204699a2dd95SBruce Richardson * New added offloadings for this queue are those not enabled in 204799a2dd95SBruce Richardson * rte_eth_dev_configure() and they must be per-queue type. 204899a2dd95SBruce Richardson * A pure per-port offloading can't be enabled on a queue while 204999a2dd95SBruce Richardson * disabled on another queue. A pure per-port offloading can't 205099a2dd95SBruce Richardson * be enabled for any queue as new added one if it hasn't been 205199a2dd95SBruce Richardson * enabled in rte_eth_dev_configure(). 205299a2dd95SBruce Richardson */ 205399a2dd95SBruce Richardson if ((local_conf.offloads & dev_info.tx_queue_offload_capa) != 205499a2dd95SBruce Richardson local_conf.offloads) { 205599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 205699a2dd95SBruce Richardson "Ethdev port_id=%d tx_queue_id=%d, new added offloads 0x%"PRIx64" must be " 205799a2dd95SBruce Richardson "within per-queue offload capabilities 0x%"PRIx64" in %s()\n", 205899a2dd95SBruce Richardson port_id, tx_queue_id, local_conf.offloads, 205999a2dd95SBruce Richardson dev_info.tx_queue_offload_capa, 206099a2dd95SBruce Richardson __func__); 206199a2dd95SBruce Richardson return -EINVAL; 206299a2dd95SBruce Richardson } 206399a2dd95SBruce Richardson 206499a2dd95SBruce Richardson rte_ethdev_trace_txq_setup(port_id, tx_queue_id, nb_tx_desc, tx_conf); 206599a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev, 206699a2dd95SBruce Richardson tx_queue_id, nb_tx_desc, socket_id, &local_conf)); 206799a2dd95SBruce Richardson } 206899a2dd95SBruce Richardson 206999a2dd95SBruce Richardson int 207099a2dd95SBruce Richardson rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id, 207199a2dd95SBruce Richardson uint16_t nb_tx_desc, 207299a2dd95SBruce Richardson const struct rte_eth_hairpin_conf *conf) 207399a2dd95SBruce Richardson { 207499a2dd95SBruce Richardson struct rte_eth_dev *dev; 207599a2dd95SBruce Richardson struct rte_eth_hairpin_cap cap; 207699a2dd95SBruce Richardson int i; 207799a2dd95SBruce Richardson int count; 207899a2dd95SBruce Richardson int ret; 207999a2dd95SBruce Richardson 208099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 208199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 208253ef1b34SMin Hu (Connor) 208399a2dd95SBruce Richardson if (tx_queue_id >= dev->data->nb_tx_queues) { 208409fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", tx_queue_id); 208599a2dd95SBruce Richardson return -EINVAL; 208699a2dd95SBruce Richardson } 208753ef1b34SMin Hu (Connor) 208853ef1b34SMin Hu (Connor) if (conf == NULL) { 208953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 209053ef1b34SMin Hu (Connor) "Cannot setup ethdev port %u Tx hairpin queue from NULL config\n", 209153ef1b34SMin Hu (Connor) port_id); 209253ef1b34SMin Hu (Connor) return -EINVAL; 209353ef1b34SMin Hu (Connor) } 209453ef1b34SMin Hu (Connor) 209599a2dd95SBruce Richardson ret = rte_eth_dev_hairpin_capability_get(port_id, &cap); 209699a2dd95SBruce Richardson if (ret != 0) 209799a2dd95SBruce Richardson return ret; 209899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_hairpin_queue_setup, 209999a2dd95SBruce Richardson -ENOTSUP); 210099a2dd95SBruce Richardson /* if nb_rx_desc is zero use max number of desc from the driver. */ 210199a2dd95SBruce Richardson if (nb_tx_desc == 0) 210299a2dd95SBruce Richardson nb_tx_desc = cap.max_nb_desc; 210399a2dd95SBruce Richardson if (nb_tx_desc > cap.max_nb_desc) { 210499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 210599a2dd95SBruce Richardson "Invalid value for nb_tx_desc(=%hu), should be: <= %hu", 210699a2dd95SBruce Richardson nb_tx_desc, cap.max_nb_desc); 210799a2dd95SBruce Richardson return -EINVAL; 210899a2dd95SBruce Richardson } 210999a2dd95SBruce Richardson if (conf->peer_count > cap.max_tx_2_rx) { 211099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 211199a2dd95SBruce Richardson "Invalid value for number of peers for Tx queue(=%u), should be: <= %hu", 211299a2dd95SBruce Richardson conf->peer_count, cap.max_tx_2_rx); 211399a2dd95SBruce Richardson return -EINVAL; 211499a2dd95SBruce Richardson } 211599a2dd95SBruce Richardson if (conf->peer_count == 0) { 211699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 211799a2dd95SBruce Richardson "Invalid value for number of peers for Tx queue(=%u), should be: > 0", 211899a2dd95SBruce Richardson conf->peer_count); 211999a2dd95SBruce Richardson return -EINVAL; 212099a2dd95SBruce Richardson } 212199a2dd95SBruce Richardson for (i = 0, count = 0; i < dev->data->nb_tx_queues && 212299a2dd95SBruce Richardson cap.max_nb_queues != UINT16_MAX; i++) { 212399a2dd95SBruce Richardson if (i == tx_queue_id || rte_eth_dev_is_tx_hairpin_queue(dev, i)) 212499a2dd95SBruce Richardson count++; 212599a2dd95SBruce Richardson } 212699a2dd95SBruce Richardson if (count > cap.max_nb_queues) { 212799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "To many Tx hairpin queues max is %d", 212899a2dd95SBruce Richardson cap.max_nb_queues); 212999a2dd95SBruce Richardson return -EINVAL; 213099a2dd95SBruce Richardson } 213199a2dd95SBruce Richardson if (dev->data->dev_started) 213299a2dd95SBruce Richardson return -EBUSY; 213349ed3224SXueming Li eth_dev_txq_release(dev, tx_queue_id); 213499a2dd95SBruce Richardson ret = (*dev->dev_ops->tx_hairpin_queue_setup) 213599a2dd95SBruce Richardson (dev, tx_queue_id, nb_tx_desc, conf); 213699a2dd95SBruce Richardson if (ret == 0) 213799a2dd95SBruce Richardson dev->data->tx_queue_state[tx_queue_id] = 213899a2dd95SBruce Richardson RTE_ETH_QUEUE_STATE_HAIRPIN; 213999a2dd95SBruce Richardson return eth_err(port_id, ret); 214099a2dd95SBruce Richardson } 214199a2dd95SBruce Richardson 214299a2dd95SBruce Richardson int 214399a2dd95SBruce Richardson rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port) 214499a2dd95SBruce Richardson { 214599a2dd95SBruce Richardson struct rte_eth_dev *dev; 214699a2dd95SBruce Richardson int ret; 214799a2dd95SBruce Richardson 214899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV); 214999a2dd95SBruce Richardson dev = &rte_eth_devices[tx_port]; 215053ef1b34SMin Hu (Connor) 215199a2dd95SBruce Richardson if (dev->data->dev_started == 0) { 215299a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Tx port %d is not started\n", tx_port); 215399a2dd95SBruce Richardson return -EBUSY; 215499a2dd95SBruce Richardson } 215599a2dd95SBruce Richardson 215699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_bind, -ENOTSUP); 215799a2dd95SBruce Richardson ret = (*dev->dev_ops->hairpin_bind)(dev, rx_port); 215899a2dd95SBruce Richardson if (ret != 0) 215999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Failed to bind hairpin Tx %d" 216099a2dd95SBruce Richardson " to Rx %d (%d - all ports)\n", 216199a2dd95SBruce Richardson tx_port, rx_port, RTE_MAX_ETHPORTS); 216299a2dd95SBruce Richardson 216399a2dd95SBruce Richardson return ret; 216499a2dd95SBruce Richardson } 216599a2dd95SBruce Richardson 216699a2dd95SBruce Richardson int 216799a2dd95SBruce Richardson rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port) 216899a2dd95SBruce Richardson { 216999a2dd95SBruce Richardson struct rte_eth_dev *dev; 217099a2dd95SBruce Richardson int ret; 217199a2dd95SBruce Richardson 217299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV); 217399a2dd95SBruce Richardson dev = &rte_eth_devices[tx_port]; 217453ef1b34SMin Hu (Connor) 217599a2dd95SBruce Richardson if (dev->data->dev_started == 0) { 217699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Tx port %d is already stopped\n", tx_port); 217799a2dd95SBruce Richardson return -EBUSY; 217899a2dd95SBruce Richardson } 217999a2dd95SBruce Richardson 218099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_unbind, -ENOTSUP); 218199a2dd95SBruce Richardson ret = (*dev->dev_ops->hairpin_unbind)(dev, rx_port); 218299a2dd95SBruce Richardson if (ret != 0) 218399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Failed to unbind hairpin Tx %d" 218499a2dd95SBruce Richardson " from Rx %d (%d - all ports)\n", 218599a2dd95SBruce Richardson tx_port, rx_port, RTE_MAX_ETHPORTS); 218699a2dd95SBruce Richardson 218799a2dd95SBruce Richardson return ret; 218899a2dd95SBruce Richardson } 218999a2dd95SBruce Richardson 219099a2dd95SBruce Richardson int 219199a2dd95SBruce Richardson rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports, 219299a2dd95SBruce Richardson size_t len, uint32_t direction) 219399a2dd95SBruce Richardson { 219499a2dd95SBruce Richardson struct rte_eth_dev *dev; 219599a2dd95SBruce Richardson int ret; 219699a2dd95SBruce Richardson 219799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 219899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 219953ef1b34SMin Hu (Connor) 220053ef1b34SMin Hu (Connor) if (peer_ports == NULL) { 220153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 220253ef1b34SMin Hu (Connor) "Cannot get ethdev port %u hairpin peer ports to NULL\n", 220353ef1b34SMin Hu (Connor) port_id); 220453ef1b34SMin Hu (Connor) return -EINVAL; 220553ef1b34SMin Hu (Connor) } 220653ef1b34SMin Hu (Connor) 220753ef1b34SMin Hu (Connor) if (len == 0) { 220853ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 220953ef1b34SMin Hu (Connor) "Cannot get ethdev port %u hairpin peer ports to array with zero size\n", 221053ef1b34SMin Hu (Connor) port_id); 221153ef1b34SMin Hu (Connor) return -EINVAL; 221253ef1b34SMin Hu (Connor) } 221353ef1b34SMin Hu (Connor) 221499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_get_peer_ports, 221599a2dd95SBruce Richardson -ENOTSUP); 221699a2dd95SBruce Richardson 221799a2dd95SBruce Richardson ret = (*dev->dev_ops->hairpin_get_peer_ports)(dev, peer_ports, 221899a2dd95SBruce Richardson len, direction); 221999a2dd95SBruce Richardson if (ret < 0) 222099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Failed to get %d hairpin peer %s ports\n", 222199a2dd95SBruce Richardson port_id, direction ? "Rx" : "Tx"); 222299a2dd95SBruce Richardson 222399a2dd95SBruce Richardson return ret; 222499a2dd95SBruce Richardson } 222599a2dd95SBruce Richardson 222699a2dd95SBruce Richardson void 222799a2dd95SBruce Richardson rte_eth_tx_buffer_drop_callback(struct rte_mbuf **pkts, uint16_t unsent, 222899a2dd95SBruce Richardson void *userdata __rte_unused) 222999a2dd95SBruce Richardson { 223099a2dd95SBruce Richardson rte_pktmbuf_free_bulk(pkts, unsent); 223199a2dd95SBruce Richardson } 223299a2dd95SBruce Richardson 223399a2dd95SBruce Richardson void 223499a2dd95SBruce Richardson rte_eth_tx_buffer_count_callback(struct rte_mbuf **pkts, uint16_t unsent, 223599a2dd95SBruce Richardson void *userdata) 223699a2dd95SBruce Richardson { 223799a2dd95SBruce Richardson uint64_t *count = userdata; 223899a2dd95SBruce Richardson 223999a2dd95SBruce Richardson rte_pktmbuf_free_bulk(pkts, unsent); 224099a2dd95SBruce Richardson *count += unsent; 224199a2dd95SBruce Richardson } 224299a2dd95SBruce Richardson 224399a2dd95SBruce Richardson int 224499a2dd95SBruce Richardson rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer, 224599a2dd95SBruce Richardson buffer_tx_error_fn cbfn, void *userdata) 224699a2dd95SBruce Richardson { 224753ef1b34SMin Hu (Connor) if (buffer == NULL) { 224853ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 224953ef1b34SMin Hu (Connor) "Cannot set Tx buffer error callback to NULL buffer\n"); 225053ef1b34SMin Hu (Connor) return -EINVAL; 225153ef1b34SMin Hu (Connor) } 225253ef1b34SMin Hu (Connor) 225399a2dd95SBruce Richardson buffer->error_callback = cbfn; 225499a2dd95SBruce Richardson buffer->error_userdata = userdata; 225599a2dd95SBruce Richardson return 0; 225699a2dd95SBruce Richardson } 225799a2dd95SBruce Richardson 225899a2dd95SBruce Richardson int 225999a2dd95SBruce Richardson rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size) 226099a2dd95SBruce Richardson { 226199a2dd95SBruce Richardson int ret = 0; 226299a2dd95SBruce Richardson 226353ef1b34SMin Hu (Connor) if (buffer == NULL) { 226453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot initialize NULL buffer\n"); 226599a2dd95SBruce Richardson return -EINVAL; 226653ef1b34SMin Hu (Connor) } 226799a2dd95SBruce Richardson 226899a2dd95SBruce Richardson buffer->size = size; 226999a2dd95SBruce Richardson if (buffer->error_callback == NULL) { 227099a2dd95SBruce Richardson ret = rte_eth_tx_buffer_set_err_callback( 227199a2dd95SBruce Richardson buffer, rte_eth_tx_buffer_drop_callback, NULL); 227299a2dd95SBruce Richardson } 227399a2dd95SBruce Richardson 227499a2dd95SBruce Richardson return ret; 227599a2dd95SBruce Richardson } 227699a2dd95SBruce Richardson 227799a2dd95SBruce Richardson int 227899a2dd95SBruce Richardson rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt) 227999a2dd95SBruce Richardson { 228053ef1b34SMin Hu (Connor) struct rte_eth_dev *dev; 228199a2dd95SBruce Richardson int ret; 228299a2dd95SBruce Richardson 228399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 228453ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 228553ef1b34SMin Hu (Connor) 228699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP); 228799a2dd95SBruce Richardson 228899a2dd95SBruce Richardson /* Call driver to free pending mbufs. */ 228999a2dd95SBruce Richardson ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id], 229099a2dd95SBruce Richardson free_cnt); 229199a2dd95SBruce Richardson return eth_err(port_id, ret); 229299a2dd95SBruce Richardson } 229399a2dd95SBruce Richardson 229499a2dd95SBruce Richardson int 229599a2dd95SBruce Richardson rte_eth_promiscuous_enable(uint16_t port_id) 229699a2dd95SBruce Richardson { 229799a2dd95SBruce Richardson struct rte_eth_dev *dev; 229899a2dd95SBruce Richardson int diag = 0; 229999a2dd95SBruce Richardson 230099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 230199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 230299a2dd95SBruce Richardson 230399a2dd95SBruce Richardson if (dev->data->promiscuous == 1) 230499a2dd95SBruce Richardson return 0; 230599a2dd95SBruce Richardson 230699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_enable, -ENOTSUP); 230799a2dd95SBruce Richardson 230899a2dd95SBruce Richardson diag = (*dev->dev_ops->promiscuous_enable)(dev); 230999a2dd95SBruce Richardson dev->data->promiscuous = (diag == 0) ? 1 : 0; 231099a2dd95SBruce Richardson 231199a2dd95SBruce Richardson return eth_err(port_id, diag); 231299a2dd95SBruce Richardson } 231399a2dd95SBruce Richardson 231499a2dd95SBruce Richardson int 231599a2dd95SBruce Richardson rte_eth_promiscuous_disable(uint16_t port_id) 231699a2dd95SBruce Richardson { 231799a2dd95SBruce Richardson struct rte_eth_dev *dev; 231899a2dd95SBruce Richardson int diag = 0; 231999a2dd95SBruce Richardson 232099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 232199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 232299a2dd95SBruce Richardson 232399a2dd95SBruce Richardson if (dev->data->promiscuous == 0) 232499a2dd95SBruce Richardson return 0; 232599a2dd95SBruce Richardson 232699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_disable, -ENOTSUP); 232799a2dd95SBruce Richardson 232899a2dd95SBruce Richardson dev->data->promiscuous = 0; 232999a2dd95SBruce Richardson diag = (*dev->dev_ops->promiscuous_disable)(dev); 233099a2dd95SBruce Richardson if (diag != 0) 233199a2dd95SBruce Richardson dev->data->promiscuous = 1; 233299a2dd95SBruce Richardson 233399a2dd95SBruce Richardson return eth_err(port_id, diag); 233499a2dd95SBruce Richardson } 233599a2dd95SBruce Richardson 233699a2dd95SBruce Richardson int 233799a2dd95SBruce Richardson rte_eth_promiscuous_get(uint16_t port_id) 233899a2dd95SBruce Richardson { 233999a2dd95SBruce Richardson struct rte_eth_dev *dev; 234099a2dd95SBruce Richardson 234199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 234299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 234353ef1b34SMin Hu (Connor) 234499a2dd95SBruce Richardson return dev->data->promiscuous; 234599a2dd95SBruce Richardson } 234699a2dd95SBruce Richardson 234799a2dd95SBruce Richardson int 234899a2dd95SBruce Richardson rte_eth_allmulticast_enable(uint16_t port_id) 234999a2dd95SBruce Richardson { 235099a2dd95SBruce Richardson struct rte_eth_dev *dev; 235199a2dd95SBruce Richardson int diag; 235299a2dd95SBruce Richardson 235399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 235499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 235599a2dd95SBruce Richardson 235699a2dd95SBruce Richardson if (dev->data->all_multicast == 1) 235799a2dd95SBruce Richardson return 0; 235899a2dd95SBruce Richardson 235999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_enable, -ENOTSUP); 236099a2dd95SBruce Richardson diag = (*dev->dev_ops->allmulticast_enable)(dev); 236199a2dd95SBruce Richardson dev->data->all_multicast = (diag == 0) ? 1 : 0; 236299a2dd95SBruce Richardson 236399a2dd95SBruce Richardson return eth_err(port_id, diag); 236499a2dd95SBruce Richardson } 236599a2dd95SBruce Richardson 236699a2dd95SBruce Richardson int 236799a2dd95SBruce Richardson rte_eth_allmulticast_disable(uint16_t port_id) 236899a2dd95SBruce Richardson { 236999a2dd95SBruce Richardson struct rte_eth_dev *dev; 237099a2dd95SBruce Richardson int diag; 237199a2dd95SBruce Richardson 237299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 237399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 237499a2dd95SBruce Richardson 237599a2dd95SBruce Richardson if (dev->data->all_multicast == 0) 237699a2dd95SBruce Richardson return 0; 237799a2dd95SBruce Richardson 237899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_disable, -ENOTSUP); 237999a2dd95SBruce Richardson dev->data->all_multicast = 0; 238099a2dd95SBruce Richardson diag = (*dev->dev_ops->allmulticast_disable)(dev); 238199a2dd95SBruce Richardson if (diag != 0) 238299a2dd95SBruce Richardson dev->data->all_multicast = 1; 238399a2dd95SBruce Richardson 238499a2dd95SBruce Richardson return eth_err(port_id, diag); 238599a2dd95SBruce Richardson } 238699a2dd95SBruce Richardson 238799a2dd95SBruce Richardson int 238899a2dd95SBruce Richardson rte_eth_allmulticast_get(uint16_t port_id) 238999a2dd95SBruce Richardson { 239099a2dd95SBruce Richardson struct rte_eth_dev *dev; 239199a2dd95SBruce Richardson 239299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 239399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 239453ef1b34SMin Hu (Connor) 239599a2dd95SBruce Richardson return dev->data->all_multicast; 239699a2dd95SBruce Richardson } 239799a2dd95SBruce Richardson 239899a2dd95SBruce Richardson int 239999a2dd95SBruce Richardson rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link) 240099a2dd95SBruce Richardson { 240199a2dd95SBruce Richardson struct rte_eth_dev *dev; 240299a2dd95SBruce Richardson 240399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 240499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 240599a2dd95SBruce Richardson 240653ef1b34SMin Hu (Connor) if (eth_link == NULL) { 240753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u link to NULL\n", 240853ef1b34SMin Hu (Connor) port_id); 240953ef1b34SMin Hu (Connor) return -EINVAL; 241053ef1b34SMin Hu (Connor) } 241153ef1b34SMin Hu (Connor) 241253ef1b34SMin Hu (Connor) if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started) 241399a2dd95SBruce Richardson rte_eth_linkstatus_get(dev, eth_link); 241499a2dd95SBruce Richardson else { 241599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP); 241699a2dd95SBruce Richardson (*dev->dev_ops->link_update)(dev, 1); 241799a2dd95SBruce Richardson *eth_link = dev->data->dev_link; 241899a2dd95SBruce Richardson } 241999a2dd95SBruce Richardson 242099a2dd95SBruce Richardson return 0; 242199a2dd95SBruce Richardson } 242299a2dd95SBruce Richardson 242399a2dd95SBruce Richardson int 242499a2dd95SBruce Richardson rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link) 242599a2dd95SBruce Richardson { 242699a2dd95SBruce Richardson struct rte_eth_dev *dev; 242799a2dd95SBruce Richardson 242899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 242999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 243099a2dd95SBruce Richardson 243153ef1b34SMin Hu (Connor) if (eth_link == NULL) { 243253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u link to NULL\n", 243353ef1b34SMin Hu (Connor) port_id); 243453ef1b34SMin Hu (Connor) return -EINVAL; 243553ef1b34SMin Hu (Connor) } 243653ef1b34SMin Hu (Connor) 243753ef1b34SMin Hu (Connor) if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started) 243899a2dd95SBruce Richardson rte_eth_linkstatus_get(dev, eth_link); 243999a2dd95SBruce Richardson else { 244099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP); 244199a2dd95SBruce Richardson (*dev->dev_ops->link_update)(dev, 0); 244299a2dd95SBruce Richardson *eth_link = dev->data->dev_link; 244399a2dd95SBruce Richardson } 244499a2dd95SBruce Richardson 244599a2dd95SBruce Richardson return 0; 244699a2dd95SBruce Richardson } 244799a2dd95SBruce Richardson 244899a2dd95SBruce Richardson const char * 244999a2dd95SBruce Richardson rte_eth_link_speed_to_str(uint32_t link_speed) 245099a2dd95SBruce Richardson { 245199a2dd95SBruce Richardson switch (link_speed) { 2452295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_NONE: return "None"; 2453295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_10M: return "10 Mbps"; 2454295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_100M: return "100 Mbps"; 2455295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_1G: return "1 Gbps"; 2456295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_2_5G: return "2.5 Gbps"; 2457295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_5G: return "5 Gbps"; 2458295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_10G: return "10 Gbps"; 2459295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_20G: return "20 Gbps"; 2460295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_25G: return "25 Gbps"; 2461295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_40G: return "40 Gbps"; 2462295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_50G: return "50 Gbps"; 2463295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_56G: return "56 Gbps"; 2464295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_100G: return "100 Gbps"; 2465295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_200G: return "200 Gbps"; 2466295968d1SFerruh Yigit case RTE_ETH_SPEED_NUM_UNKNOWN: return "Unknown"; 246799a2dd95SBruce Richardson default: return "Invalid"; 246899a2dd95SBruce Richardson } 246999a2dd95SBruce Richardson } 247099a2dd95SBruce Richardson 247199a2dd95SBruce Richardson int 247299a2dd95SBruce Richardson rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link) 247399a2dd95SBruce Richardson { 247453ef1b34SMin Hu (Connor) if (str == NULL) { 247553ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot convert link to NULL string\n"); 247653ef1b34SMin Hu (Connor) return -EINVAL; 247753ef1b34SMin Hu (Connor) } 247853ef1b34SMin Hu (Connor) 247953ef1b34SMin Hu (Connor) if (len == 0) { 248053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 248153ef1b34SMin Hu (Connor) "Cannot convert link to string with zero size\n"); 248253ef1b34SMin Hu (Connor) return -EINVAL; 248353ef1b34SMin Hu (Connor) } 248453ef1b34SMin Hu (Connor) 248553ef1b34SMin Hu (Connor) if (eth_link == NULL) { 248653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot convert to string from NULL link\n"); 248753ef1b34SMin Hu (Connor) return -EINVAL; 248853ef1b34SMin Hu (Connor) } 248953ef1b34SMin Hu (Connor) 2490295968d1SFerruh Yigit if (eth_link->link_status == RTE_ETH_LINK_DOWN) 249199a2dd95SBruce Richardson return snprintf(str, len, "Link down"); 249299a2dd95SBruce Richardson else 249399a2dd95SBruce Richardson return snprintf(str, len, "Link up at %s %s %s", 249499a2dd95SBruce Richardson rte_eth_link_speed_to_str(eth_link->link_speed), 2495295968d1SFerruh Yigit (eth_link->link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ? 249699a2dd95SBruce Richardson "FDX" : "HDX", 2497295968d1SFerruh Yigit (eth_link->link_autoneg == RTE_ETH_LINK_AUTONEG) ? 249899a2dd95SBruce Richardson "Autoneg" : "Fixed"); 249999a2dd95SBruce Richardson } 250099a2dd95SBruce Richardson 250199a2dd95SBruce Richardson int 250299a2dd95SBruce Richardson rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats) 250399a2dd95SBruce Richardson { 250499a2dd95SBruce Richardson struct rte_eth_dev *dev; 250599a2dd95SBruce Richardson 250699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 250799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 250853ef1b34SMin Hu (Connor) 250953ef1b34SMin Hu (Connor) if (stats == NULL) { 251053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u stats to NULL\n", 251153ef1b34SMin Hu (Connor) port_id); 251253ef1b34SMin Hu (Connor) return -EINVAL; 251353ef1b34SMin Hu (Connor) } 251453ef1b34SMin Hu (Connor) 251599a2dd95SBruce Richardson memset(stats, 0, sizeof(*stats)); 251699a2dd95SBruce Richardson 251799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP); 251899a2dd95SBruce Richardson stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed; 251999a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->stats_get)(dev, stats)); 252099a2dd95SBruce Richardson } 252199a2dd95SBruce Richardson 252299a2dd95SBruce Richardson int 252399a2dd95SBruce Richardson rte_eth_stats_reset(uint16_t port_id) 252499a2dd95SBruce Richardson { 252599a2dd95SBruce Richardson struct rte_eth_dev *dev; 252699a2dd95SBruce Richardson int ret; 252799a2dd95SBruce Richardson 252899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 252999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 253099a2dd95SBruce Richardson 253199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_reset, -ENOTSUP); 253299a2dd95SBruce Richardson ret = (*dev->dev_ops->stats_reset)(dev); 253399a2dd95SBruce Richardson if (ret != 0) 253499a2dd95SBruce Richardson return eth_err(port_id, ret); 253599a2dd95SBruce Richardson 253699a2dd95SBruce Richardson dev->data->rx_mbuf_alloc_failed = 0; 253799a2dd95SBruce Richardson 253899a2dd95SBruce Richardson return 0; 253999a2dd95SBruce Richardson } 254099a2dd95SBruce Richardson 254199a2dd95SBruce Richardson static inline int 254299a2dd95SBruce Richardson eth_dev_get_xstats_basic_count(struct rte_eth_dev *dev) 254399a2dd95SBruce Richardson { 254499a2dd95SBruce Richardson uint16_t nb_rxqs, nb_txqs; 254599a2dd95SBruce Richardson int count; 254699a2dd95SBruce Richardson 254799a2dd95SBruce Richardson nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 254899a2dd95SBruce Richardson nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 254999a2dd95SBruce Richardson 255099a2dd95SBruce Richardson count = RTE_NB_STATS; 255199a2dd95SBruce Richardson if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) { 255299a2dd95SBruce Richardson count += nb_rxqs * RTE_NB_RXQ_STATS; 255399a2dd95SBruce Richardson count += nb_txqs * RTE_NB_TXQ_STATS; 255499a2dd95SBruce Richardson } 255599a2dd95SBruce Richardson 255699a2dd95SBruce Richardson return count; 255799a2dd95SBruce Richardson } 255899a2dd95SBruce Richardson 255999a2dd95SBruce Richardson static int 256099a2dd95SBruce Richardson eth_dev_get_xstats_count(uint16_t port_id) 256199a2dd95SBruce Richardson { 256299a2dd95SBruce Richardson struct rte_eth_dev *dev; 256399a2dd95SBruce Richardson int count; 256499a2dd95SBruce Richardson 256599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 256699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 256799a2dd95SBruce Richardson if (dev->dev_ops->xstats_get_names != NULL) { 256899a2dd95SBruce Richardson count = (*dev->dev_ops->xstats_get_names)(dev, NULL, 0); 256999a2dd95SBruce Richardson if (count < 0) 257099a2dd95SBruce Richardson return eth_err(port_id, count); 257199a2dd95SBruce Richardson } else 257299a2dd95SBruce Richardson count = 0; 257399a2dd95SBruce Richardson 257499a2dd95SBruce Richardson 257599a2dd95SBruce Richardson count += eth_dev_get_xstats_basic_count(dev); 257699a2dd95SBruce Richardson 257799a2dd95SBruce Richardson return count; 257899a2dd95SBruce Richardson } 257999a2dd95SBruce Richardson 258099a2dd95SBruce Richardson int 258199a2dd95SBruce Richardson rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name, 258299a2dd95SBruce Richardson uint64_t *id) 258399a2dd95SBruce Richardson { 258499a2dd95SBruce Richardson int cnt_xstats, idx_xstat; 258599a2dd95SBruce Richardson 258699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 258799a2dd95SBruce Richardson 258853ef1b34SMin Hu (Connor) if (xstat_name == NULL) { 258953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 259053ef1b34SMin Hu (Connor) "Cannot get ethdev port %u xstats ID from NULL xstat name\n", 259153ef1b34SMin Hu (Connor) port_id); 259299a2dd95SBruce Richardson return -ENOMEM; 259399a2dd95SBruce Richardson } 259499a2dd95SBruce Richardson 259553ef1b34SMin Hu (Connor) if (id == NULL) { 259653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 259753ef1b34SMin Hu (Connor) "Cannot get ethdev port %u xstats ID to NULL\n", 259853ef1b34SMin Hu (Connor) port_id); 259999a2dd95SBruce Richardson return -ENOMEM; 260099a2dd95SBruce Richardson } 260199a2dd95SBruce Richardson 260299a2dd95SBruce Richardson /* Get count */ 260399a2dd95SBruce Richardson cnt_xstats = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL); 260499a2dd95SBruce Richardson if (cnt_xstats < 0) { 260599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Cannot get count of xstats\n"); 260699a2dd95SBruce Richardson return -ENODEV; 260799a2dd95SBruce Richardson } 260899a2dd95SBruce Richardson 260999a2dd95SBruce Richardson /* Get id-name lookup table */ 261099a2dd95SBruce Richardson struct rte_eth_xstat_name xstats_names[cnt_xstats]; 261199a2dd95SBruce Richardson 261299a2dd95SBruce Richardson if (cnt_xstats != rte_eth_xstats_get_names_by_id( 261399a2dd95SBruce Richardson port_id, xstats_names, cnt_xstats, NULL)) { 261499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Cannot get xstats lookup\n"); 261599a2dd95SBruce Richardson return -1; 261699a2dd95SBruce Richardson } 261799a2dd95SBruce Richardson 261899a2dd95SBruce Richardson for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) { 261999a2dd95SBruce Richardson if (!strcmp(xstats_names[idx_xstat].name, xstat_name)) { 262099a2dd95SBruce Richardson *id = idx_xstat; 262199a2dd95SBruce Richardson return 0; 262299a2dd95SBruce Richardson }; 262399a2dd95SBruce Richardson } 262499a2dd95SBruce Richardson 262599a2dd95SBruce Richardson return -EINVAL; 262699a2dd95SBruce Richardson } 262799a2dd95SBruce Richardson 262899a2dd95SBruce Richardson /* retrieve basic stats names */ 262999a2dd95SBruce Richardson static int 263099a2dd95SBruce Richardson eth_basic_stats_get_names(struct rte_eth_dev *dev, 263199a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names) 263299a2dd95SBruce Richardson { 263399a2dd95SBruce Richardson int cnt_used_entries = 0; 263499a2dd95SBruce Richardson uint32_t idx, id_queue; 263599a2dd95SBruce Richardson uint16_t num_q; 263699a2dd95SBruce Richardson 263799a2dd95SBruce Richardson for (idx = 0; idx < RTE_NB_STATS; idx++) { 263899a2dd95SBruce Richardson strlcpy(xstats_names[cnt_used_entries].name, 263999a2dd95SBruce Richardson eth_dev_stats_strings[idx].name, 264099a2dd95SBruce Richardson sizeof(xstats_names[0].name)); 264199a2dd95SBruce Richardson cnt_used_entries++; 264299a2dd95SBruce Richardson } 264399a2dd95SBruce Richardson 264499a2dd95SBruce Richardson if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0) 264599a2dd95SBruce Richardson return cnt_used_entries; 264699a2dd95SBruce Richardson 264799a2dd95SBruce Richardson num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 264899a2dd95SBruce Richardson for (id_queue = 0; id_queue < num_q; id_queue++) { 264999a2dd95SBruce Richardson for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) { 265099a2dd95SBruce Richardson snprintf(xstats_names[cnt_used_entries].name, 265199a2dd95SBruce Richardson sizeof(xstats_names[0].name), 265299a2dd95SBruce Richardson "rx_q%u_%s", 265399a2dd95SBruce Richardson id_queue, eth_dev_rxq_stats_strings[idx].name); 265499a2dd95SBruce Richardson cnt_used_entries++; 265599a2dd95SBruce Richardson } 265699a2dd95SBruce Richardson 265799a2dd95SBruce Richardson } 265899a2dd95SBruce Richardson num_q = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 265999a2dd95SBruce Richardson for (id_queue = 0; id_queue < num_q; id_queue++) { 266099a2dd95SBruce Richardson for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) { 266199a2dd95SBruce Richardson snprintf(xstats_names[cnt_used_entries].name, 266299a2dd95SBruce Richardson sizeof(xstats_names[0].name), 266399a2dd95SBruce Richardson "tx_q%u_%s", 266499a2dd95SBruce Richardson id_queue, eth_dev_txq_stats_strings[idx].name); 266599a2dd95SBruce Richardson cnt_used_entries++; 266699a2dd95SBruce Richardson } 266799a2dd95SBruce Richardson } 266899a2dd95SBruce Richardson return cnt_used_entries; 266999a2dd95SBruce Richardson } 267099a2dd95SBruce Richardson 267199a2dd95SBruce Richardson /* retrieve ethdev extended statistics names */ 267299a2dd95SBruce Richardson int 267399a2dd95SBruce Richardson rte_eth_xstats_get_names_by_id(uint16_t port_id, 267499a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names, unsigned int size, 267599a2dd95SBruce Richardson uint64_t *ids) 267699a2dd95SBruce Richardson { 267799a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names_copy; 267899a2dd95SBruce Richardson unsigned int no_basic_stat_requested = 1; 267999a2dd95SBruce Richardson unsigned int no_ext_stat_requested = 1; 268099a2dd95SBruce Richardson unsigned int expected_entries; 268199a2dd95SBruce Richardson unsigned int basic_count; 268299a2dd95SBruce Richardson struct rte_eth_dev *dev; 268399a2dd95SBruce Richardson unsigned int i; 268499a2dd95SBruce Richardson int ret; 268599a2dd95SBruce Richardson 268699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 268799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 268899a2dd95SBruce Richardson 268999a2dd95SBruce Richardson basic_count = eth_dev_get_xstats_basic_count(dev); 269099a2dd95SBruce Richardson ret = eth_dev_get_xstats_count(port_id); 269199a2dd95SBruce Richardson if (ret < 0) 269299a2dd95SBruce Richardson return ret; 269399a2dd95SBruce Richardson expected_entries = (unsigned int)ret; 269499a2dd95SBruce Richardson 269599a2dd95SBruce Richardson /* Return max number of stats if no ids given */ 269699a2dd95SBruce Richardson if (!ids) { 269799a2dd95SBruce Richardson if (!xstats_names) 269899a2dd95SBruce Richardson return expected_entries; 269999a2dd95SBruce Richardson else if (xstats_names && size < expected_entries) 270099a2dd95SBruce Richardson return expected_entries; 270199a2dd95SBruce Richardson } 270299a2dd95SBruce Richardson 270399a2dd95SBruce Richardson if (ids && !xstats_names) 270499a2dd95SBruce Richardson return -EINVAL; 270599a2dd95SBruce Richardson 270699a2dd95SBruce Richardson if (ids && dev->dev_ops->xstats_get_names_by_id != NULL && size > 0) { 270799a2dd95SBruce Richardson uint64_t ids_copy[size]; 270899a2dd95SBruce Richardson 270999a2dd95SBruce Richardson for (i = 0; i < size; i++) { 271099a2dd95SBruce Richardson if (ids[i] < basic_count) { 271199a2dd95SBruce Richardson no_basic_stat_requested = 0; 271299a2dd95SBruce Richardson break; 271399a2dd95SBruce Richardson } 271499a2dd95SBruce Richardson 271599a2dd95SBruce Richardson /* 271699a2dd95SBruce Richardson * Convert ids to xstats ids that PMD knows. 271799a2dd95SBruce Richardson * ids known by user are basic + extended stats. 271899a2dd95SBruce Richardson */ 271999a2dd95SBruce Richardson ids_copy[i] = ids[i] - basic_count; 272099a2dd95SBruce Richardson } 272199a2dd95SBruce Richardson 272299a2dd95SBruce Richardson if (no_basic_stat_requested) 272399a2dd95SBruce Richardson return (*dev->dev_ops->xstats_get_names_by_id)(dev, 27248c9f976fSAndrew Rybchenko ids_copy, xstats_names, size); 272599a2dd95SBruce Richardson } 272699a2dd95SBruce Richardson 272799a2dd95SBruce Richardson /* Retrieve all stats */ 272899a2dd95SBruce Richardson if (!ids) { 272999a2dd95SBruce Richardson int num_stats = rte_eth_xstats_get_names(port_id, xstats_names, 273099a2dd95SBruce Richardson expected_entries); 273199a2dd95SBruce Richardson if (num_stats < 0 || num_stats > (int)expected_entries) 273299a2dd95SBruce Richardson return num_stats; 273399a2dd95SBruce Richardson else 273499a2dd95SBruce Richardson return expected_entries; 273599a2dd95SBruce Richardson } 273699a2dd95SBruce Richardson 273799a2dd95SBruce Richardson xstats_names_copy = calloc(expected_entries, 273899a2dd95SBruce Richardson sizeof(struct rte_eth_xstat_name)); 273999a2dd95SBruce Richardson 274099a2dd95SBruce Richardson if (!xstats_names_copy) { 274199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Can't allocate memory\n"); 274299a2dd95SBruce Richardson return -ENOMEM; 274399a2dd95SBruce Richardson } 274499a2dd95SBruce Richardson 274599a2dd95SBruce Richardson if (ids) { 274699a2dd95SBruce Richardson for (i = 0; i < size; i++) { 274799a2dd95SBruce Richardson if (ids[i] >= basic_count) { 274899a2dd95SBruce Richardson no_ext_stat_requested = 0; 274999a2dd95SBruce Richardson break; 275099a2dd95SBruce Richardson } 275199a2dd95SBruce Richardson } 275299a2dd95SBruce Richardson } 275399a2dd95SBruce Richardson 275499a2dd95SBruce Richardson /* Fill xstats_names_copy structure */ 275599a2dd95SBruce Richardson if (ids && no_ext_stat_requested) { 275699a2dd95SBruce Richardson eth_basic_stats_get_names(dev, xstats_names_copy); 275799a2dd95SBruce Richardson } else { 275899a2dd95SBruce Richardson ret = rte_eth_xstats_get_names(port_id, xstats_names_copy, 275999a2dd95SBruce Richardson expected_entries); 276099a2dd95SBruce Richardson if (ret < 0) { 276199a2dd95SBruce Richardson free(xstats_names_copy); 276299a2dd95SBruce Richardson return ret; 276399a2dd95SBruce Richardson } 276499a2dd95SBruce Richardson } 276599a2dd95SBruce Richardson 276699a2dd95SBruce Richardson /* Filter stats */ 276799a2dd95SBruce Richardson for (i = 0; i < size; i++) { 276899a2dd95SBruce Richardson if (ids[i] >= expected_entries) { 276999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n"); 277099a2dd95SBruce Richardson free(xstats_names_copy); 277199a2dd95SBruce Richardson return -1; 277299a2dd95SBruce Richardson } 277399a2dd95SBruce Richardson xstats_names[i] = xstats_names_copy[ids[i]]; 277499a2dd95SBruce Richardson } 277599a2dd95SBruce Richardson 277699a2dd95SBruce Richardson free(xstats_names_copy); 277799a2dd95SBruce Richardson return size; 277899a2dd95SBruce Richardson } 277999a2dd95SBruce Richardson 278099a2dd95SBruce Richardson int 278199a2dd95SBruce Richardson rte_eth_xstats_get_names(uint16_t port_id, 278299a2dd95SBruce Richardson struct rte_eth_xstat_name *xstats_names, 278399a2dd95SBruce Richardson unsigned int size) 278499a2dd95SBruce Richardson { 278599a2dd95SBruce Richardson struct rte_eth_dev *dev; 278699a2dd95SBruce Richardson int cnt_used_entries; 278799a2dd95SBruce Richardson int cnt_expected_entries; 278899a2dd95SBruce Richardson int cnt_driver_entries; 278999a2dd95SBruce Richardson 279099a2dd95SBruce Richardson cnt_expected_entries = eth_dev_get_xstats_count(port_id); 279199a2dd95SBruce Richardson if (xstats_names == NULL || cnt_expected_entries < 0 || 279299a2dd95SBruce Richardson (int)size < cnt_expected_entries) 279399a2dd95SBruce Richardson return cnt_expected_entries; 279499a2dd95SBruce Richardson 279599a2dd95SBruce Richardson /* port_id checked in eth_dev_get_xstats_count() */ 279699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 279799a2dd95SBruce Richardson 279899a2dd95SBruce Richardson cnt_used_entries = eth_basic_stats_get_names(dev, xstats_names); 279999a2dd95SBruce Richardson 280099a2dd95SBruce Richardson if (dev->dev_ops->xstats_get_names != NULL) { 280199a2dd95SBruce Richardson /* If there are any driver-specific xstats, append them 280299a2dd95SBruce Richardson * to end of list. 280399a2dd95SBruce Richardson */ 280499a2dd95SBruce Richardson cnt_driver_entries = (*dev->dev_ops->xstats_get_names)( 280599a2dd95SBruce Richardson dev, 280699a2dd95SBruce Richardson xstats_names + cnt_used_entries, 280799a2dd95SBruce Richardson size - cnt_used_entries); 280899a2dd95SBruce Richardson if (cnt_driver_entries < 0) 280999a2dd95SBruce Richardson return eth_err(port_id, cnt_driver_entries); 281099a2dd95SBruce Richardson cnt_used_entries += cnt_driver_entries; 281199a2dd95SBruce Richardson } 281299a2dd95SBruce Richardson 281399a2dd95SBruce Richardson return cnt_used_entries; 281499a2dd95SBruce Richardson } 281599a2dd95SBruce Richardson 281699a2dd95SBruce Richardson 281799a2dd95SBruce Richardson static int 281899a2dd95SBruce Richardson eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats) 281999a2dd95SBruce Richardson { 282099a2dd95SBruce Richardson struct rte_eth_dev *dev; 282199a2dd95SBruce Richardson struct rte_eth_stats eth_stats; 282299a2dd95SBruce Richardson unsigned int count = 0, i, q; 282399a2dd95SBruce Richardson uint64_t val, *stats_ptr; 282499a2dd95SBruce Richardson uint16_t nb_rxqs, nb_txqs; 282599a2dd95SBruce Richardson int ret; 282699a2dd95SBruce Richardson 282799a2dd95SBruce Richardson ret = rte_eth_stats_get(port_id, ð_stats); 282899a2dd95SBruce Richardson if (ret < 0) 282999a2dd95SBruce Richardson return ret; 283099a2dd95SBruce Richardson 283199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 283299a2dd95SBruce Richardson 283399a2dd95SBruce Richardson nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 283499a2dd95SBruce Richardson nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 283599a2dd95SBruce Richardson 283699a2dd95SBruce Richardson /* global stats */ 283799a2dd95SBruce Richardson for (i = 0; i < RTE_NB_STATS; i++) { 283899a2dd95SBruce Richardson stats_ptr = RTE_PTR_ADD(ð_stats, 283999a2dd95SBruce Richardson eth_dev_stats_strings[i].offset); 284099a2dd95SBruce Richardson val = *stats_ptr; 284199a2dd95SBruce Richardson xstats[count++].value = val; 284299a2dd95SBruce Richardson } 284399a2dd95SBruce Richardson 284499a2dd95SBruce Richardson if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0) 284599a2dd95SBruce Richardson return count; 284699a2dd95SBruce Richardson 284799a2dd95SBruce Richardson /* per-rxq stats */ 284899a2dd95SBruce Richardson for (q = 0; q < nb_rxqs; q++) { 284999a2dd95SBruce Richardson for (i = 0; i < RTE_NB_RXQ_STATS; i++) { 285099a2dd95SBruce Richardson stats_ptr = RTE_PTR_ADD(ð_stats, 285199a2dd95SBruce Richardson eth_dev_rxq_stats_strings[i].offset + 285299a2dd95SBruce Richardson q * sizeof(uint64_t)); 285399a2dd95SBruce Richardson val = *stats_ptr; 285499a2dd95SBruce Richardson xstats[count++].value = val; 285599a2dd95SBruce Richardson } 285699a2dd95SBruce Richardson } 285799a2dd95SBruce Richardson 285899a2dd95SBruce Richardson /* per-txq stats */ 285999a2dd95SBruce Richardson for (q = 0; q < nb_txqs; q++) { 286099a2dd95SBruce Richardson for (i = 0; i < RTE_NB_TXQ_STATS; i++) { 286199a2dd95SBruce Richardson stats_ptr = RTE_PTR_ADD(ð_stats, 286299a2dd95SBruce Richardson eth_dev_txq_stats_strings[i].offset + 286399a2dd95SBruce Richardson q * sizeof(uint64_t)); 286499a2dd95SBruce Richardson val = *stats_ptr; 286599a2dd95SBruce Richardson xstats[count++].value = val; 286699a2dd95SBruce Richardson } 286799a2dd95SBruce Richardson } 286899a2dd95SBruce Richardson return count; 286999a2dd95SBruce Richardson } 287099a2dd95SBruce Richardson 287199a2dd95SBruce Richardson /* retrieve ethdev extended statistics */ 287299a2dd95SBruce Richardson int 287399a2dd95SBruce Richardson rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids, 287499a2dd95SBruce Richardson uint64_t *values, unsigned int size) 287599a2dd95SBruce Richardson { 287699a2dd95SBruce Richardson unsigned int no_basic_stat_requested = 1; 287799a2dd95SBruce Richardson unsigned int no_ext_stat_requested = 1; 287899a2dd95SBruce Richardson unsigned int num_xstats_filled; 287999a2dd95SBruce Richardson unsigned int basic_count; 288099a2dd95SBruce Richardson uint16_t expected_entries; 288199a2dd95SBruce Richardson struct rte_eth_dev *dev; 288299a2dd95SBruce Richardson unsigned int i; 288399a2dd95SBruce Richardson int ret; 288499a2dd95SBruce Richardson 288599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 288653ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 288753ef1b34SMin Hu (Connor) 288899a2dd95SBruce Richardson ret = eth_dev_get_xstats_count(port_id); 288999a2dd95SBruce Richardson if (ret < 0) 289099a2dd95SBruce Richardson return ret; 289199a2dd95SBruce Richardson expected_entries = (uint16_t)ret; 289299a2dd95SBruce Richardson struct rte_eth_xstat xstats[expected_entries]; 289399a2dd95SBruce Richardson basic_count = eth_dev_get_xstats_basic_count(dev); 289499a2dd95SBruce Richardson 289599a2dd95SBruce Richardson /* Return max number of stats if no ids given */ 289699a2dd95SBruce Richardson if (!ids) { 289799a2dd95SBruce Richardson if (!values) 289899a2dd95SBruce Richardson return expected_entries; 289999a2dd95SBruce Richardson else if (values && size < expected_entries) 290099a2dd95SBruce Richardson return expected_entries; 290199a2dd95SBruce Richardson } 290299a2dd95SBruce Richardson 290399a2dd95SBruce Richardson if (ids && !values) 290499a2dd95SBruce Richardson return -EINVAL; 290599a2dd95SBruce Richardson 290699a2dd95SBruce Richardson if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) { 290799a2dd95SBruce Richardson unsigned int basic_count = eth_dev_get_xstats_basic_count(dev); 290899a2dd95SBruce Richardson uint64_t ids_copy[size]; 290999a2dd95SBruce Richardson 291099a2dd95SBruce Richardson for (i = 0; i < size; i++) { 291199a2dd95SBruce Richardson if (ids[i] < basic_count) { 291299a2dd95SBruce Richardson no_basic_stat_requested = 0; 291399a2dd95SBruce Richardson break; 291499a2dd95SBruce Richardson } 291599a2dd95SBruce Richardson 291699a2dd95SBruce Richardson /* 291799a2dd95SBruce Richardson * Convert ids to xstats ids that PMD knows. 291899a2dd95SBruce Richardson * ids known by user are basic + extended stats. 291999a2dd95SBruce Richardson */ 292099a2dd95SBruce Richardson ids_copy[i] = ids[i] - basic_count; 292199a2dd95SBruce Richardson } 292299a2dd95SBruce Richardson 292399a2dd95SBruce Richardson if (no_basic_stat_requested) 292499a2dd95SBruce Richardson return (*dev->dev_ops->xstats_get_by_id)(dev, ids_copy, 292599a2dd95SBruce Richardson values, size); 292699a2dd95SBruce Richardson } 292799a2dd95SBruce Richardson 292899a2dd95SBruce Richardson if (ids) { 292999a2dd95SBruce Richardson for (i = 0; i < size; i++) { 293099a2dd95SBruce Richardson if (ids[i] >= basic_count) { 293199a2dd95SBruce Richardson no_ext_stat_requested = 0; 293299a2dd95SBruce Richardson break; 293399a2dd95SBruce Richardson } 293499a2dd95SBruce Richardson } 293599a2dd95SBruce Richardson } 293699a2dd95SBruce Richardson 293799a2dd95SBruce Richardson /* Fill the xstats structure */ 293899a2dd95SBruce Richardson if (ids && no_ext_stat_requested) 293999a2dd95SBruce Richardson ret = eth_basic_stats_get(port_id, xstats); 294099a2dd95SBruce Richardson else 294199a2dd95SBruce Richardson ret = rte_eth_xstats_get(port_id, xstats, expected_entries); 294299a2dd95SBruce Richardson 294399a2dd95SBruce Richardson if (ret < 0) 294499a2dd95SBruce Richardson return ret; 294599a2dd95SBruce Richardson num_xstats_filled = (unsigned int)ret; 294699a2dd95SBruce Richardson 294799a2dd95SBruce Richardson /* Return all stats */ 294899a2dd95SBruce Richardson if (!ids) { 294999a2dd95SBruce Richardson for (i = 0; i < num_xstats_filled; i++) 295099a2dd95SBruce Richardson values[i] = xstats[i].value; 295199a2dd95SBruce Richardson return expected_entries; 295299a2dd95SBruce Richardson } 295399a2dd95SBruce Richardson 295499a2dd95SBruce Richardson /* Filter stats */ 295599a2dd95SBruce Richardson for (i = 0; i < size; i++) { 295699a2dd95SBruce Richardson if (ids[i] >= expected_entries) { 295799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n"); 295899a2dd95SBruce Richardson return -1; 295999a2dd95SBruce Richardson } 296099a2dd95SBruce Richardson values[i] = xstats[ids[i]].value; 296199a2dd95SBruce Richardson } 296299a2dd95SBruce Richardson return size; 296399a2dd95SBruce Richardson } 296499a2dd95SBruce Richardson 296599a2dd95SBruce Richardson int 296699a2dd95SBruce Richardson rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats, 296799a2dd95SBruce Richardson unsigned int n) 296899a2dd95SBruce Richardson { 296999a2dd95SBruce Richardson struct rte_eth_dev *dev; 297099a2dd95SBruce Richardson unsigned int count = 0, i; 297199a2dd95SBruce Richardson signed int xcount = 0; 297299a2dd95SBruce Richardson uint16_t nb_rxqs, nb_txqs; 297399a2dd95SBruce Richardson int ret; 297499a2dd95SBruce Richardson 297599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 297699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 297799a2dd95SBruce Richardson 297899a2dd95SBruce Richardson nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 297999a2dd95SBruce Richardson nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 298099a2dd95SBruce Richardson 298199a2dd95SBruce Richardson /* Return generic statistics */ 298299a2dd95SBruce Richardson count = RTE_NB_STATS; 298399a2dd95SBruce Richardson if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) 298499a2dd95SBruce Richardson count += (nb_rxqs * RTE_NB_RXQ_STATS) + (nb_txqs * RTE_NB_TXQ_STATS); 298599a2dd95SBruce Richardson 298699a2dd95SBruce Richardson /* implemented by the driver */ 298799a2dd95SBruce Richardson if (dev->dev_ops->xstats_get != NULL) { 298899a2dd95SBruce Richardson /* Retrieve the xstats from the driver at the end of the 298999a2dd95SBruce Richardson * xstats struct. 299099a2dd95SBruce Richardson */ 299199a2dd95SBruce Richardson xcount = (*dev->dev_ops->xstats_get)(dev, 299299a2dd95SBruce Richardson xstats ? xstats + count : NULL, 299399a2dd95SBruce Richardson (n > count) ? n - count : 0); 299499a2dd95SBruce Richardson 299599a2dd95SBruce Richardson if (xcount < 0) 299699a2dd95SBruce Richardson return eth_err(port_id, xcount); 299799a2dd95SBruce Richardson } 299899a2dd95SBruce Richardson 299999a2dd95SBruce Richardson if (n < count + xcount || xstats == NULL) 300099a2dd95SBruce Richardson return count + xcount; 300199a2dd95SBruce Richardson 300299a2dd95SBruce Richardson /* now fill the xstats structure */ 300399a2dd95SBruce Richardson ret = eth_basic_stats_get(port_id, xstats); 300499a2dd95SBruce Richardson if (ret < 0) 300599a2dd95SBruce Richardson return ret; 300699a2dd95SBruce Richardson count = ret; 300799a2dd95SBruce Richardson 300899a2dd95SBruce Richardson for (i = 0; i < count; i++) 300999a2dd95SBruce Richardson xstats[i].id = i; 301099a2dd95SBruce Richardson /* add an offset to driver-specific stats */ 301199a2dd95SBruce Richardson for ( ; i < count + xcount; i++) 301299a2dd95SBruce Richardson xstats[i].id += count; 301399a2dd95SBruce Richardson 301499a2dd95SBruce Richardson return count + xcount; 301599a2dd95SBruce Richardson } 301699a2dd95SBruce Richardson 301799a2dd95SBruce Richardson /* reset ethdev extended statistics */ 301899a2dd95SBruce Richardson int 301999a2dd95SBruce Richardson rte_eth_xstats_reset(uint16_t port_id) 302099a2dd95SBruce Richardson { 302199a2dd95SBruce Richardson struct rte_eth_dev *dev; 302299a2dd95SBruce Richardson 302399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 302499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 302599a2dd95SBruce Richardson 302699a2dd95SBruce Richardson /* implemented by the driver */ 302799a2dd95SBruce Richardson if (dev->dev_ops->xstats_reset != NULL) 302899a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->xstats_reset)(dev)); 302999a2dd95SBruce Richardson 303099a2dd95SBruce Richardson /* fallback to default */ 303199a2dd95SBruce Richardson return rte_eth_stats_reset(port_id); 303299a2dd95SBruce Richardson } 303399a2dd95SBruce Richardson 303499a2dd95SBruce Richardson static int 303599a2dd95SBruce Richardson eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id, 303699a2dd95SBruce Richardson uint8_t stat_idx, uint8_t is_rx) 303799a2dd95SBruce Richardson { 303899a2dd95SBruce Richardson struct rte_eth_dev *dev; 303999a2dd95SBruce Richardson 304099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 304199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 304299a2dd95SBruce Richardson 304399a2dd95SBruce Richardson if (is_rx && (queue_id >= dev->data->nb_rx_queues)) 304499a2dd95SBruce Richardson return -EINVAL; 304599a2dd95SBruce Richardson 304699a2dd95SBruce Richardson if (!is_rx && (queue_id >= dev->data->nb_tx_queues)) 304799a2dd95SBruce Richardson return -EINVAL; 304899a2dd95SBruce Richardson 304999a2dd95SBruce Richardson if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS) 305099a2dd95SBruce Richardson return -EINVAL; 305199a2dd95SBruce Richardson 305253ef1b34SMin Hu (Connor) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set, -ENOTSUP); 305353ef1b34SMin Hu (Connor) return (*dev->dev_ops->queue_stats_mapping_set) (dev, queue_id, stat_idx, is_rx); 305499a2dd95SBruce Richardson } 305599a2dd95SBruce Richardson 305699a2dd95SBruce Richardson int 305799a2dd95SBruce Richardson rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id, 305899a2dd95SBruce Richardson uint8_t stat_idx) 305999a2dd95SBruce Richardson { 306099a2dd95SBruce Richardson return eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id, 306199a2dd95SBruce Richardson tx_queue_id, 306299a2dd95SBruce Richardson stat_idx, STAT_QMAP_TX)); 306399a2dd95SBruce Richardson } 306499a2dd95SBruce Richardson 306599a2dd95SBruce Richardson int 306699a2dd95SBruce Richardson rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id, 306799a2dd95SBruce Richardson uint8_t stat_idx) 306899a2dd95SBruce Richardson { 306999a2dd95SBruce Richardson return eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id, 307099a2dd95SBruce Richardson rx_queue_id, 307199a2dd95SBruce Richardson stat_idx, STAT_QMAP_RX)); 307299a2dd95SBruce Richardson } 307399a2dd95SBruce Richardson 307499a2dd95SBruce Richardson int 307599a2dd95SBruce Richardson rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size) 307699a2dd95SBruce Richardson { 307799a2dd95SBruce Richardson struct rte_eth_dev *dev; 307899a2dd95SBruce Richardson 307999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 308099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 308199a2dd95SBruce Richardson 308253ef1b34SMin Hu (Connor) if (fw_version == NULL && fw_size > 0) { 308353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 308453ef1b34SMin Hu (Connor) "Cannot get ethdev port %u FW version to NULL when string size is non zero\n", 308553ef1b34SMin Hu (Connor) port_id); 308653ef1b34SMin Hu (Connor) return -EINVAL; 308753ef1b34SMin Hu (Connor) } 308853ef1b34SMin Hu (Connor) 308999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP); 309099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev, 309199a2dd95SBruce Richardson fw_version, fw_size)); 309299a2dd95SBruce Richardson } 309399a2dd95SBruce Richardson 309499a2dd95SBruce Richardson int 309599a2dd95SBruce Richardson rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info) 309699a2dd95SBruce Richardson { 309799a2dd95SBruce Richardson struct rte_eth_dev *dev; 309899a2dd95SBruce Richardson const struct rte_eth_desc_lim lim = { 309999a2dd95SBruce Richardson .nb_max = UINT16_MAX, 310099a2dd95SBruce Richardson .nb_min = 0, 310199a2dd95SBruce Richardson .nb_align = 1, 310299a2dd95SBruce Richardson .nb_seg_max = UINT16_MAX, 310399a2dd95SBruce Richardson .nb_mtu_seg_max = UINT16_MAX, 310499a2dd95SBruce Richardson }; 310599a2dd95SBruce Richardson int diag; 310699a2dd95SBruce Richardson 310753ef1b34SMin Hu (Connor) RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 310853ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 310953ef1b34SMin Hu (Connor) 311053ef1b34SMin Hu (Connor) if (dev_info == NULL) { 311153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u info to NULL\n", 311253ef1b34SMin Hu (Connor) port_id); 311353ef1b34SMin Hu (Connor) return -EINVAL; 311453ef1b34SMin Hu (Connor) } 311553ef1b34SMin Hu (Connor) 311699a2dd95SBruce Richardson /* 311799a2dd95SBruce Richardson * Init dev_info before port_id check since caller does not have 311899a2dd95SBruce Richardson * return status and does not know if get is successful or not. 311999a2dd95SBruce Richardson */ 312099a2dd95SBruce Richardson memset(dev_info, 0, sizeof(struct rte_eth_dev_info)); 312199a2dd95SBruce Richardson dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID; 312299a2dd95SBruce Richardson 312399a2dd95SBruce Richardson dev_info->rx_desc_lim = lim; 312499a2dd95SBruce Richardson dev_info->tx_desc_lim = lim; 312599a2dd95SBruce Richardson dev_info->device = dev->device; 3126990912e6SFerruh Yigit dev_info->min_mtu = RTE_ETHER_MIN_LEN - RTE_ETHER_HDR_LEN - 3127990912e6SFerruh Yigit RTE_ETHER_CRC_LEN; 312899a2dd95SBruce Richardson dev_info->max_mtu = UINT16_MAX; 312999a2dd95SBruce Richardson 313099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP); 313199a2dd95SBruce Richardson diag = (*dev->dev_ops->dev_infos_get)(dev, dev_info); 313299a2dd95SBruce Richardson if (diag != 0) { 313399a2dd95SBruce Richardson /* Cleanup already filled in device information */ 313499a2dd95SBruce Richardson memset(dev_info, 0, sizeof(struct rte_eth_dev_info)); 313599a2dd95SBruce Richardson return eth_err(port_id, diag); 313699a2dd95SBruce Richardson } 313799a2dd95SBruce Richardson 313899a2dd95SBruce Richardson /* Maximum number of queues should be <= RTE_MAX_QUEUES_PER_PORT */ 313999a2dd95SBruce Richardson dev_info->max_rx_queues = RTE_MIN(dev_info->max_rx_queues, 314099a2dd95SBruce Richardson RTE_MAX_QUEUES_PER_PORT); 314199a2dd95SBruce Richardson dev_info->max_tx_queues = RTE_MIN(dev_info->max_tx_queues, 314299a2dd95SBruce Richardson RTE_MAX_QUEUES_PER_PORT); 314399a2dd95SBruce Richardson 314499a2dd95SBruce Richardson dev_info->driver_name = dev->device->driver->name; 314599a2dd95SBruce Richardson dev_info->nb_rx_queues = dev->data->nb_rx_queues; 314699a2dd95SBruce Richardson dev_info->nb_tx_queues = dev->data->nb_tx_queues; 314799a2dd95SBruce Richardson 314899a2dd95SBruce Richardson dev_info->dev_flags = &dev->data->dev_flags; 314999a2dd95SBruce Richardson 315099a2dd95SBruce Richardson return 0; 315199a2dd95SBruce Richardson } 315299a2dd95SBruce Richardson 315399a2dd95SBruce Richardson int 3154632be327SJie Wang rte_eth_dev_conf_get(uint16_t port_id, struct rte_eth_conf *dev_conf) 3155632be327SJie Wang { 3156632be327SJie Wang struct rte_eth_dev *dev; 3157632be327SJie Wang 3158632be327SJie Wang RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3159632be327SJie Wang dev = &rte_eth_devices[port_id]; 3160632be327SJie Wang 3161632be327SJie Wang if (dev_conf == NULL) { 3162632be327SJie Wang RTE_ETHDEV_LOG(ERR, 3163632be327SJie Wang "Cannot get ethdev port %u configuration to NULL\n", 3164632be327SJie Wang port_id); 3165632be327SJie Wang return -EINVAL; 3166632be327SJie Wang } 3167632be327SJie Wang 3168632be327SJie Wang memcpy(dev_conf, &dev->data->dev_conf, sizeof(struct rte_eth_conf)); 3169632be327SJie Wang 3170632be327SJie Wang return 0; 3171632be327SJie Wang } 3172632be327SJie Wang 3173632be327SJie Wang int 317499a2dd95SBruce Richardson rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask, 317599a2dd95SBruce Richardson uint32_t *ptypes, int num) 317699a2dd95SBruce Richardson { 317799a2dd95SBruce Richardson int i, j; 317899a2dd95SBruce Richardson struct rte_eth_dev *dev; 317999a2dd95SBruce Richardson const uint32_t *all_ptypes; 318099a2dd95SBruce Richardson 318199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 318299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 318353ef1b34SMin Hu (Connor) 318453ef1b34SMin Hu (Connor) if (ptypes == NULL && num > 0) { 318553ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 318653ef1b34SMin Hu (Connor) "Cannot get ethdev port %u supported packet types to NULL when array size is non zero\n", 318753ef1b34SMin Hu (Connor) port_id); 318853ef1b34SMin Hu (Connor) return -EINVAL; 318953ef1b34SMin Hu (Connor) } 319053ef1b34SMin Hu (Connor) 319199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0); 319299a2dd95SBruce Richardson all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev); 319399a2dd95SBruce Richardson 319499a2dd95SBruce Richardson if (!all_ptypes) 319599a2dd95SBruce Richardson return 0; 319699a2dd95SBruce Richardson 319799a2dd95SBruce Richardson for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i) 319899a2dd95SBruce Richardson if (all_ptypes[i] & ptype_mask) { 319999a2dd95SBruce Richardson if (j < num) 320099a2dd95SBruce Richardson ptypes[j] = all_ptypes[i]; 320199a2dd95SBruce Richardson j++; 320299a2dd95SBruce Richardson } 320399a2dd95SBruce Richardson 320499a2dd95SBruce Richardson return j; 320599a2dd95SBruce Richardson } 320699a2dd95SBruce Richardson 320799a2dd95SBruce Richardson int 320899a2dd95SBruce Richardson rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask, 320999a2dd95SBruce Richardson uint32_t *set_ptypes, unsigned int num) 321099a2dd95SBruce Richardson { 321199a2dd95SBruce Richardson const uint32_t valid_ptype_masks[] = { 321299a2dd95SBruce Richardson RTE_PTYPE_L2_MASK, 321399a2dd95SBruce Richardson RTE_PTYPE_L3_MASK, 321499a2dd95SBruce Richardson RTE_PTYPE_L4_MASK, 321599a2dd95SBruce Richardson RTE_PTYPE_TUNNEL_MASK, 321699a2dd95SBruce Richardson RTE_PTYPE_INNER_L2_MASK, 321799a2dd95SBruce Richardson RTE_PTYPE_INNER_L3_MASK, 321899a2dd95SBruce Richardson RTE_PTYPE_INNER_L4_MASK, 321999a2dd95SBruce Richardson }; 322099a2dd95SBruce Richardson const uint32_t *all_ptypes; 322199a2dd95SBruce Richardson struct rte_eth_dev *dev; 322299a2dd95SBruce Richardson uint32_t unused_mask; 322399a2dd95SBruce Richardson unsigned int i, j; 322499a2dd95SBruce Richardson int ret; 322599a2dd95SBruce Richardson 322699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 322799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 322899a2dd95SBruce Richardson 322953ef1b34SMin Hu (Connor) if (num > 0 && set_ptypes == NULL) { 323053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 323153ef1b34SMin Hu (Connor) "Cannot get ethdev port %u set packet types to NULL when array size is non zero\n", 323253ef1b34SMin Hu (Connor) port_id); 323399a2dd95SBruce Richardson return -EINVAL; 323453ef1b34SMin Hu (Connor) } 323599a2dd95SBruce Richardson 323699a2dd95SBruce Richardson if (*dev->dev_ops->dev_supported_ptypes_get == NULL || 323799a2dd95SBruce Richardson *dev->dev_ops->dev_ptypes_set == NULL) { 323899a2dd95SBruce Richardson ret = 0; 323999a2dd95SBruce Richardson goto ptype_unknown; 324099a2dd95SBruce Richardson } 324199a2dd95SBruce Richardson 324299a2dd95SBruce Richardson if (ptype_mask == 0) { 324399a2dd95SBruce Richardson ret = (*dev->dev_ops->dev_ptypes_set)(dev, 324499a2dd95SBruce Richardson ptype_mask); 324599a2dd95SBruce Richardson goto ptype_unknown; 324699a2dd95SBruce Richardson } 324799a2dd95SBruce Richardson 324899a2dd95SBruce Richardson unused_mask = ptype_mask; 324999a2dd95SBruce Richardson for (i = 0; i < RTE_DIM(valid_ptype_masks); i++) { 325099a2dd95SBruce Richardson uint32_t mask = ptype_mask & valid_ptype_masks[i]; 325199a2dd95SBruce Richardson if (mask && mask != valid_ptype_masks[i]) { 325299a2dd95SBruce Richardson ret = -EINVAL; 325399a2dd95SBruce Richardson goto ptype_unknown; 325499a2dd95SBruce Richardson } 325599a2dd95SBruce Richardson unused_mask &= ~valid_ptype_masks[i]; 325699a2dd95SBruce Richardson } 325799a2dd95SBruce Richardson 325899a2dd95SBruce Richardson if (unused_mask) { 325999a2dd95SBruce Richardson ret = -EINVAL; 326099a2dd95SBruce Richardson goto ptype_unknown; 326199a2dd95SBruce Richardson } 326299a2dd95SBruce Richardson 326399a2dd95SBruce Richardson all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev); 326499a2dd95SBruce Richardson if (all_ptypes == NULL) { 326599a2dd95SBruce Richardson ret = 0; 326699a2dd95SBruce Richardson goto ptype_unknown; 326799a2dd95SBruce Richardson } 326899a2dd95SBruce Richardson 326999a2dd95SBruce Richardson /* 327099a2dd95SBruce Richardson * Accommodate as many set_ptypes as possible. If the supplied 327199a2dd95SBruce Richardson * set_ptypes array is insufficient fill it partially. 327299a2dd95SBruce Richardson */ 327399a2dd95SBruce Richardson for (i = 0, j = 0; set_ptypes != NULL && 327499a2dd95SBruce Richardson (all_ptypes[i] != RTE_PTYPE_UNKNOWN); ++i) { 327599a2dd95SBruce Richardson if (ptype_mask & all_ptypes[i]) { 327699a2dd95SBruce Richardson if (j < num - 1) { 327799a2dd95SBruce Richardson set_ptypes[j] = all_ptypes[i]; 327899a2dd95SBruce Richardson j++; 327999a2dd95SBruce Richardson continue; 328099a2dd95SBruce Richardson } 328199a2dd95SBruce Richardson break; 328299a2dd95SBruce Richardson } 328399a2dd95SBruce Richardson } 328499a2dd95SBruce Richardson 328599a2dd95SBruce Richardson if (set_ptypes != NULL && j < num) 328699a2dd95SBruce Richardson set_ptypes[j] = RTE_PTYPE_UNKNOWN; 328799a2dd95SBruce Richardson 328899a2dd95SBruce Richardson return (*dev->dev_ops->dev_ptypes_set)(dev, ptype_mask); 328999a2dd95SBruce Richardson 329099a2dd95SBruce Richardson ptype_unknown: 329199a2dd95SBruce Richardson if (num > 0) 329299a2dd95SBruce Richardson set_ptypes[0] = RTE_PTYPE_UNKNOWN; 329399a2dd95SBruce Richardson 329499a2dd95SBruce Richardson return ret; 329599a2dd95SBruce Richardson } 329699a2dd95SBruce Richardson 329799a2dd95SBruce Richardson int 329827a300e6SKonstantin Ananyev rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr *ma, 329927a300e6SKonstantin Ananyev unsigned int num) 330027a300e6SKonstantin Ananyev { 330127a300e6SKonstantin Ananyev int32_t ret; 330227a300e6SKonstantin Ananyev struct rte_eth_dev *dev; 330327a300e6SKonstantin Ananyev struct rte_eth_dev_info dev_info; 330427a300e6SKonstantin Ananyev 330527a300e6SKonstantin Ananyev if (ma == NULL) { 330627a300e6SKonstantin Ananyev RTE_ETHDEV_LOG(ERR, "%s: invalid parameters\n", __func__); 330727a300e6SKonstantin Ananyev return -EINVAL; 330827a300e6SKonstantin Ananyev } 330927a300e6SKonstantin Ananyev 331027a300e6SKonstantin Ananyev /* will check for us that port_id is a valid one */ 331127a300e6SKonstantin Ananyev ret = rte_eth_dev_info_get(port_id, &dev_info); 331227a300e6SKonstantin Ananyev if (ret != 0) 331327a300e6SKonstantin Ananyev return ret; 331427a300e6SKonstantin Ananyev 331527a300e6SKonstantin Ananyev dev = &rte_eth_devices[port_id]; 331627a300e6SKonstantin Ananyev num = RTE_MIN(dev_info.max_mac_addrs, num); 331727a300e6SKonstantin Ananyev memcpy(ma, dev->data->mac_addrs, num * sizeof(ma[0])); 331827a300e6SKonstantin Ananyev 331927a300e6SKonstantin Ananyev return num; 332027a300e6SKonstantin Ananyev } 332127a300e6SKonstantin Ananyev 332227a300e6SKonstantin Ananyev int 332399a2dd95SBruce Richardson rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr) 332499a2dd95SBruce Richardson { 332599a2dd95SBruce Richardson struct rte_eth_dev *dev; 332699a2dd95SBruce Richardson 332799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 332899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 332953ef1b34SMin Hu (Connor) 333053ef1b34SMin Hu (Connor) if (mac_addr == NULL) { 333153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 333253ef1b34SMin Hu (Connor) "Cannot get ethdev port %u MAC address to NULL\n", 333353ef1b34SMin Hu (Connor) port_id); 333453ef1b34SMin Hu (Connor) return -EINVAL; 333553ef1b34SMin Hu (Connor) } 333653ef1b34SMin Hu (Connor) 333799a2dd95SBruce Richardson rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr); 333899a2dd95SBruce Richardson 333999a2dd95SBruce Richardson return 0; 334099a2dd95SBruce Richardson } 334199a2dd95SBruce Richardson 334299a2dd95SBruce Richardson int 334399a2dd95SBruce Richardson rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu) 334499a2dd95SBruce Richardson { 334599a2dd95SBruce Richardson struct rte_eth_dev *dev; 334699a2dd95SBruce Richardson 334799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 334899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 334953ef1b34SMin Hu (Connor) 335053ef1b34SMin Hu (Connor) if (mtu == NULL) { 335153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u MTU to NULL\n", 335253ef1b34SMin Hu (Connor) port_id); 335353ef1b34SMin Hu (Connor) return -EINVAL; 335453ef1b34SMin Hu (Connor) } 335553ef1b34SMin Hu (Connor) 335699a2dd95SBruce Richardson *mtu = dev->data->mtu; 335799a2dd95SBruce Richardson return 0; 335899a2dd95SBruce Richardson } 335999a2dd95SBruce Richardson 336099a2dd95SBruce Richardson int 336199a2dd95SBruce Richardson rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu) 336299a2dd95SBruce Richardson { 336399a2dd95SBruce Richardson int ret; 336499a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 336599a2dd95SBruce Richardson struct rte_eth_dev *dev; 336699a2dd95SBruce Richardson 336799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 336899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 336999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mtu_set, -ENOTSUP); 337099a2dd95SBruce Richardson 337199a2dd95SBruce Richardson /* 337299a2dd95SBruce Richardson * Check if the device supports dev_infos_get, if it does not 337399a2dd95SBruce Richardson * skip min_mtu/max_mtu validation here as this requires values 337499a2dd95SBruce Richardson * that are populated within the call to rte_eth_dev_info_get() 337599a2dd95SBruce Richardson * which relies on dev->dev_ops->dev_infos_get. 337699a2dd95SBruce Richardson */ 337799a2dd95SBruce Richardson if (*dev->dev_ops->dev_infos_get != NULL) { 337899a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 337999a2dd95SBruce Richardson if (ret != 0) 338099a2dd95SBruce Richardson return ret; 338199a2dd95SBruce Richardson 3382990912e6SFerruh Yigit ret = eth_dev_validate_mtu(port_id, &dev_info, mtu); 3383990912e6SFerruh Yigit if (ret != 0) 3384990912e6SFerruh Yigit return ret; 338599a2dd95SBruce Richardson } 338699a2dd95SBruce Richardson 3387b26bee10SIvan Ilchenko if (dev->data->dev_configured == 0) { 3388b26bee10SIvan Ilchenko RTE_ETHDEV_LOG(ERR, 3389b26bee10SIvan Ilchenko "Port %u must be configured before MTU set\n", 3390b26bee10SIvan Ilchenko port_id); 3391b26bee10SIvan Ilchenko return -EINVAL; 3392b26bee10SIvan Ilchenko } 3393b26bee10SIvan Ilchenko 339499a2dd95SBruce Richardson ret = (*dev->dev_ops->mtu_set)(dev, mtu); 3395b563c142SFerruh Yigit if (ret == 0) 339699a2dd95SBruce Richardson dev->data->mtu = mtu; 339799a2dd95SBruce Richardson 339899a2dd95SBruce Richardson return eth_err(port_id, ret); 339999a2dd95SBruce Richardson } 340099a2dd95SBruce Richardson 340199a2dd95SBruce Richardson int 340299a2dd95SBruce Richardson rte_eth_dev_vlan_filter(uint16_t port_id, uint16_t vlan_id, int on) 340399a2dd95SBruce Richardson { 340499a2dd95SBruce Richardson struct rte_eth_dev *dev; 340599a2dd95SBruce Richardson int ret; 340699a2dd95SBruce Richardson 340799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 340899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 340953ef1b34SMin Hu (Connor) 341099a2dd95SBruce Richardson if (!(dev->data->dev_conf.rxmode.offloads & 3411295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_VLAN_FILTER)) { 34125b49ba65SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Port %u: VLAN-filtering disabled\n", 341399a2dd95SBruce Richardson port_id); 341499a2dd95SBruce Richardson return -ENOSYS; 341599a2dd95SBruce Richardson } 341699a2dd95SBruce Richardson 341799a2dd95SBruce Richardson if (vlan_id > 4095) { 341899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port_id=%u invalid vlan_id=%u > 4095\n", 341999a2dd95SBruce Richardson port_id, vlan_id); 342099a2dd95SBruce Richardson return -EINVAL; 342199a2dd95SBruce Richardson } 342299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_filter_set, -ENOTSUP); 342399a2dd95SBruce Richardson 342499a2dd95SBruce Richardson ret = (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); 342599a2dd95SBruce Richardson if (ret == 0) { 342699a2dd95SBruce Richardson struct rte_vlan_filter_conf *vfc; 342799a2dd95SBruce Richardson int vidx; 342899a2dd95SBruce Richardson int vbit; 342999a2dd95SBruce Richardson 343099a2dd95SBruce Richardson vfc = &dev->data->vlan_filter_conf; 343199a2dd95SBruce Richardson vidx = vlan_id / 64; 343299a2dd95SBruce Richardson vbit = vlan_id % 64; 343399a2dd95SBruce Richardson 343499a2dd95SBruce Richardson if (on) 3435e1823e08SThomas Monjalon vfc->ids[vidx] |= RTE_BIT64(vbit); 343699a2dd95SBruce Richardson else 3437e1823e08SThomas Monjalon vfc->ids[vidx] &= ~RTE_BIT64(vbit); 343899a2dd95SBruce Richardson } 343999a2dd95SBruce Richardson 344099a2dd95SBruce Richardson return eth_err(port_id, ret); 344199a2dd95SBruce Richardson } 344299a2dd95SBruce Richardson 344399a2dd95SBruce Richardson int 344499a2dd95SBruce Richardson rte_eth_dev_set_vlan_strip_on_queue(uint16_t port_id, uint16_t rx_queue_id, 344599a2dd95SBruce Richardson int on) 344699a2dd95SBruce Richardson { 344799a2dd95SBruce Richardson struct rte_eth_dev *dev; 344899a2dd95SBruce Richardson 344999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 345099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 345153ef1b34SMin Hu (Connor) 345299a2dd95SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) { 345399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid rx_queue_id=%u\n", rx_queue_id); 345499a2dd95SBruce Richardson return -EINVAL; 345599a2dd95SBruce Richardson } 345699a2dd95SBruce Richardson 345799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP); 345899a2dd95SBruce Richardson (*dev->dev_ops->vlan_strip_queue_set)(dev, rx_queue_id, on); 345999a2dd95SBruce Richardson 346099a2dd95SBruce Richardson return 0; 346199a2dd95SBruce Richardson } 346299a2dd95SBruce Richardson 346399a2dd95SBruce Richardson int 346499a2dd95SBruce Richardson rte_eth_dev_set_vlan_ether_type(uint16_t port_id, 346599a2dd95SBruce Richardson enum rte_vlan_type vlan_type, 346699a2dd95SBruce Richardson uint16_t tpid) 346799a2dd95SBruce Richardson { 346899a2dd95SBruce Richardson struct rte_eth_dev *dev; 346999a2dd95SBruce Richardson 347099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 347199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 347299a2dd95SBruce Richardson 347353ef1b34SMin Hu (Connor) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP); 347499a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->vlan_tpid_set)(dev, vlan_type, 347599a2dd95SBruce Richardson tpid)); 347699a2dd95SBruce Richardson } 347799a2dd95SBruce Richardson 347899a2dd95SBruce Richardson int 347999a2dd95SBruce Richardson rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask) 348099a2dd95SBruce Richardson { 348199a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 348299a2dd95SBruce Richardson struct rte_eth_dev *dev; 348399a2dd95SBruce Richardson int ret = 0; 348499a2dd95SBruce Richardson int mask = 0; 348599a2dd95SBruce Richardson int cur, org = 0; 348699a2dd95SBruce Richardson uint64_t orig_offloads; 348799a2dd95SBruce Richardson uint64_t dev_offloads; 348899a2dd95SBruce Richardson uint64_t new_offloads; 348999a2dd95SBruce Richardson 349099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 349199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 349299a2dd95SBruce Richardson 349399a2dd95SBruce Richardson /* save original values in case of failure */ 349499a2dd95SBruce Richardson orig_offloads = dev->data->dev_conf.rxmode.offloads; 349599a2dd95SBruce Richardson dev_offloads = orig_offloads; 349699a2dd95SBruce Richardson 349799a2dd95SBruce Richardson /* check which option changed by application */ 3498295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_VLAN_STRIP_OFFLOAD); 3499295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP); 350099a2dd95SBruce Richardson if (cur != org) { 350199a2dd95SBruce Richardson if (cur) 3502295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP; 350399a2dd95SBruce Richardson else 3504295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP; 3505295968d1SFerruh Yigit mask |= RTE_ETH_VLAN_STRIP_MASK; 350699a2dd95SBruce Richardson } 350799a2dd95SBruce Richardson 3508295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_VLAN_FILTER_OFFLOAD); 3509295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER); 351099a2dd95SBruce Richardson if (cur != org) { 351199a2dd95SBruce Richardson if (cur) 3512295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER; 351399a2dd95SBruce Richardson else 3514295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_FILTER; 3515295968d1SFerruh Yigit mask |= RTE_ETH_VLAN_FILTER_MASK; 351699a2dd95SBruce Richardson } 351799a2dd95SBruce Richardson 3518295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_VLAN_EXTEND_OFFLOAD); 3519295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND); 352099a2dd95SBruce Richardson if (cur != org) { 352199a2dd95SBruce Richardson if (cur) 3522295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_EXTEND; 352399a2dd95SBruce Richardson else 3524295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_EXTEND; 3525295968d1SFerruh Yigit mask |= RTE_ETH_VLAN_EXTEND_MASK; 352699a2dd95SBruce Richardson } 352799a2dd95SBruce Richardson 3528295968d1SFerruh Yigit cur = !!(offload_mask & RTE_ETH_QINQ_STRIP_OFFLOAD); 3529295968d1SFerruh Yigit org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP); 353099a2dd95SBruce Richardson if (cur != org) { 353199a2dd95SBruce Richardson if (cur) 3532295968d1SFerruh Yigit dev_offloads |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP; 353399a2dd95SBruce Richardson else 3534295968d1SFerruh Yigit dev_offloads &= ~RTE_ETH_RX_OFFLOAD_QINQ_STRIP; 3535295968d1SFerruh Yigit mask |= RTE_ETH_QINQ_STRIP_MASK; 353699a2dd95SBruce Richardson } 353799a2dd95SBruce Richardson 353899a2dd95SBruce Richardson /*no change*/ 353999a2dd95SBruce Richardson if (mask == 0) 354099a2dd95SBruce Richardson return ret; 354199a2dd95SBruce Richardson 354299a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 354399a2dd95SBruce Richardson if (ret != 0) 354499a2dd95SBruce Richardson return ret; 354599a2dd95SBruce Richardson 354699a2dd95SBruce Richardson /* Rx VLAN offloading must be within its device capabilities */ 354799a2dd95SBruce Richardson if ((dev_offloads & dev_info.rx_offload_capa) != dev_offloads) { 354899a2dd95SBruce Richardson new_offloads = dev_offloads & ~orig_offloads; 354999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 355099a2dd95SBruce Richardson "Ethdev port_id=%u requested new added VLAN offloads " 355199a2dd95SBruce Richardson "0x%" PRIx64 " must be within Rx offloads capabilities " 355299a2dd95SBruce Richardson "0x%" PRIx64 " in %s()\n", 355399a2dd95SBruce Richardson port_id, new_offloads, dev_info.rx_offload_capa, 355499a2dd95SBruce Richardson __func__); 355599a2dd95SBruce Richardson return -EINVAL; 355699a2dd95SBruce Richardson } 355799a2dd95SBruce Richardson 355899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_offload_set, -ENOTSUP); 355999a2dd95SBruce Richardson dev->data->dev_conf.rxmode.offloads = dev_offloads; 356099a2dd95SBruce Richardson ret = (*dev->dev_ops->vlan_offload_set)(dev, mask); 356199a2dd95SBruce Richardson if (ret) { 356299a2dd95SBruce Richardson /* hit an error restore original values */ 356399a2dd95SBruce Richardson dev->data->dev_conf.rxmode.offloads = orig_offloads; 356499a2dd95SBruce Richardson } 356599a2dd95SBruce Richardson 356699a2dd95SBruce Richardson return eth_err(port_id, ret); 356799a2dd95SBruce Richardson } 356899a2dd95SBruce Richardson 356999a2dd95SBruce Richardson int 357099a2dd95SBruce Richardson rte_eth_dev_get_vlan_offload(uint16_t port_id) 357199a2dd95SBruce Richardson { 357299a2dd95SBruce Richardson struct rte_eth_dev *dev; 357399a2dd95SBruce Richardson uint64_t *dev_offloads; 357499a2dd95SBruce Richardson int ret = 0; 357599a2dd95SBruce Richardson 357699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 357799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 357899a2dd95SBruce Richardson dev_offloads = &dev->data->dev_conf.rxmode.offloads; 357999a2dd95SBruce Richardson 3580295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) 3581295968d1SFerruh Yigit ret |= RTE_ETH_VLAN_STRIP_OFFLOAD; 358299a2dd95SBruce Richardson 3583295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) 3584295968d1SFerruh Yigit ret |= RTE_ETH_VLAN_FILTER_OFFLOAD; 358599a2dd95SBruce Richardson 3586295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND) 3587295968d1SFerruh Yigit ret |= RTE_ETH_VLAN_EXTEND_OFFLOAD; 358899a2dd95SBruce Richardson 3589295968d1SFerruh Yigit if (*dev_offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP) 3590295968d1SFerruh Yigit ret |= RTE_ETH_QINQ_STRIP_OFFLOAD; 359199a2dd95SBruce Richardson 359299a2dd95SBruce Richardson return ret; 359399a2dd95SBruce Richardson } 359499a2dd95SBruce Richardson 359599a2dd95SBruce Richardson int 359699a2dd95SBruce Richardson rte_eth_dev_set_vlan_pvid(uint16_t port_id, uint16_t pvid, int on) 359799a2dd95SBruce Richardson { 359899a2dd95SBruce Richardson struct rte_eth_dev *dev; 359999a2dd95SBruce Richardson 360099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 360199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 360299a2dd95SBruce Richardson 360353ef1b34SMin Hu (Connor) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_pvid_set, -ENOTSUP); 360499a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->vlan_pvid_set)(dev, pvid, on)); 360599a2dd95SBruce Richardson } 360699a2dd95SBruce Richardson 360799a2dd95SBruce Richardson int 360899a2dd95SBruce Richardson rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf) 360999a2dd95SBruce Richardson { 361099a2dd95SBruce Richardson struct rte_eth_dev *dev; 361199a2dd95SBruce Richardson 361299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 361399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 361453ef1b34SMin Hu (Connor) 361553ef1b34SMin Hu (Connor) if (fc_conf == NULL) { 361653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 361753ef1b34SMin Hu (Connor) "Cannot get ethdev port %u flow control config to NULL\n", 361853ef1b34SMin Hu (Connor) port_id); 361953ef1b34SMin Hu (Connor) return -EINVAL; 362053ef1b34SMin Hu (Connor) } 362153ef1b34SMin Hu (Connor) 362299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP); 362399a2dd95SBruce Richardson memset(fc_conf, 0, sizeof(*fc_conf)); 362499a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf)); 362599a2dd95SBruce Richardson } 362699a2dd95SBruce Richardson 362799a2dd95SBruce Richardson int 362899a2dd95SBruce Richardson rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf) 362999a2dd95SBruce Richardson { 363099a2dd95SBruce Richardson struct rte_eth_dev *dev; 363199a2dd95SBruce Richardson 363299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 363353ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 363453ef1b34SMin Hu (Connor) 363553ef1b34SMin Hu (Connor) if (fc_conf == NULL) { 363653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 363753ef1b34SMin Hu (Connor) "Cannot set ethdev port %u flow control from NULL config\n", 363853ef1b34SMin Hu (Connor) port_id); 363953ef1b34SMin Hu (Connor) return -EINVAL; 364053ef1b34SMin Hu (Connor) } 364153ef1b34SMin Hu (Connor) 364299a2dd95SBruce Richardson if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) { 364399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n"); 364499a2dd95SBruce Richardson return -EINVAL; 364599a2dd95SBruce Richardson } 364699a2dd95SBruce Richardson 364799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP); 364899a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf)); 364999a2dd95SBruce Richardson } 365099a2dd95SBruce Richardson 365199a2dd95SBruce Richardson int 365299a2dd95SBruce Richardson rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id, 365399a2dd95SBruce Richardson struct rte_eth_pfc_conf *pfc_conf) 365499a2dd95SBruce Richardson { 365599a2dd95SBruce Richardson struct rte_eth_dev *dev; 365699a2dd95SBruce Richardson 365799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 365853ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 365953ef1b34SMin Hu (Connor) 366053ef1b34SMin Hu (Connor) if (pfc_conf == NULL) { 366153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 366253ef1b34SMin Hu (Connor) "Cannot set ethdev port %u priority flow control from NULL config\n", 366353ef1b34SMin Hu (Connor) port_id); 366453ef1b34SMin Hu (Connor) return -EINVAL; 366553ef1b34SMin Hu (Connor) } 366653ef1b34SMin Hu (Connor) 3667295968d1SFerruh Yigit if (pfc_conf->priority > (RTE_ETH_DCB_NUM_USER_PRIORITIES - 1)) { 366899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n"); 366999a2dd95SBruce Richardson return -EINVAL; 367099a2dd95SBruce Richardson } 367199a2dd95SBruce Richardson 367299a2dd95SBruce Richardson /* High water, low water validation are device specific */ 367399a2dd95SBruce Richardson if (*dev->dev_ops->priority_flow_ctrl_set) 367499a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set) 367599a2dd95SBruce Richardson (dev, pfc_conf)); 367699a2dd95SBruce Richardson return -ENOTSUP; 367799a2dd95SBruce Richardson } 367899a2dd95SBruce Richardson 367999a2dd95SBruce Richardson static int 36800de345e9SJerin Jacob validate_rx_pause_config(struct rte_eth_dev_info *dev_info, uint8_t tc_max, 36810de345e9SJerin Jacob struct rte_eth_pfc_queue_conf *pfc_queue_conf) 36820de345e9SJerin Jacob { 36830de345e9SJerin Jacob if ((pfc_queue_conf->mode == RTE_ETH_FC_RX_PAUSE) || 36840de345e9SJerin Jacob (pfc_queue_conf->mode == RTE_ETH_FC_FULL)) { 36850de345e9SJerin Jacob if (pfc_queue_conf->rx_pause.tx_qid >= dev_info->nb_tx_queues) { 36860de345e9SJerin Jacob RTE_ETHDEV_LOG(ERR, 36870de345e9SJerin Jacob "PFC Tx queue not in range for Rx pause requested:%d configured:%d\n", 36880de345e9SJerin Jacob pfc_queue_conf->rx_pause.tx_qid, 36890de345e9SJerin Jacob dev_info->nb_tx_queues); 36900de345e9SJerin Jacob return -EINVAL; 36910de345e9SJerin Jacob } 36920de345e9SJerin Jacob 36930de345e9SJerin Jacob if (pfc_queue_conf->rx_pause.tc >= tc_max) { 36940de345e9SJerin Jacob RTE_ETHDEV_LOG(ERR, 36950de345e9SJerin Jacob "PFC TC not in range for Rx pause requested:%d max:%d\n", 36960de345e9SJerin Jacob pfc_queue_conf->rx_pause.tc, tc_max); 36970de345e9SJerin Jacob return -EINVAL; 36980de345e9SJerin Jacob } 36990de345e9SJerin Jacob } 37000de345e9SJerin Jacob 37010de345e9SJerin Jacob return 0; 37020de345e9SJerin Jacob } 37030de345e9SJerin Jacob 37040de345e9SJerin Jacob static int 37050de345e9SJerin Jacob validate_tx_pause_config(struct rte_eth_dev_info *dev_info, uint8_t tc_max, 37060de345e9SJerin Jacob struct rte_eth_pfc_queue_conf *pfc_queue_conf) 37070de345e9SJerin Jacob { 37080de345e9SJerin Jacob if ((pfc_queue_conf->mode == RTE_ETH_FC_TX_PAUSE) || 37090de345e9SJerin Jacob (pfc_queue_conf->mode == RTE_ETH_FC_FULL)) { 37100de345e9SJerin Jacob if (pfc_queue_conf->tx_pause.rx_qid >= dev_info->nb_rx_queues) { 37110de345e9SJerin Jacob RTE_ETHDEV_LOG(ERR, 37120de345e9SJerin Jacob "PFC Rx queue not in range for Tx pause requested:%d configured:%d\n", 37130de345e9SJerin Jacob pfc_queue_conf->tx_pause.rx_qid, 37140de345e9SJerin Jacob dev_info->nb_rx_queues); 37150de345e9SJerin Jacob return -EINVAL; 37160de345e9SJerin Jacob } 37170de345e9SJerin Jacob 37180de345e9SJerin Jacob if (pfc_queue_conf->tx_pause.tc >= tc_max) { 37190de345e9SJerin Jacob RTE_ETHDEV_LOG(ERR, 37200de345e9SJerin Jacob "PFC TC not in range for Tx pause requested:%d max:%d\n", 37210de345e9SJerin Jacob pfc_queue_conf->tx_pause.tc, tc_max); 37220de345e9SJerin Jacob return -EINVAL; 37230de345e9SJerin Jacob } 37240de345e9SJerin Jacob } 37250de345e9SJerin Jacob 37260de345e9SJerin Jacob return 0; 37270de345e9SJerin Jacob } 37280de345e9SJerin Jacob 37290de345e9SJerin Jacob int 37300de345e9SJerin Jacob rte_eth_dev_priority_flow_ctrl_queue_info_get(uint16_t port_id, 37310de345e9SJerin Jacob struct rte_eth_pfc_queue_info *pfc_queue_info) 37320de345e9SJerin Jacob { 37330de345e9SJerin Jacob struct rte_eth_dev *dev; 37340de345e9SJerin Jacob 37350de345e9SJerin Jacob RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 37360de345e9SJerin Jacob dev = &rte_eth_devices[port_id]; 37370de345e9SJerin Jacob 37380de345e9SJerin Jacob if (pfc_queue_info == NULL) { 37390de345e9SJerin Jacob RTE_ETHDEV_LOG(ERR, "PFC info param is NULL for port (%u)\n", 37400de345e9SJerin Jacob port_id); 37410de345e9SJerin Jacob return -EINVAL; 37420de345e9SJerin Jacob } 37430de345e9SJerin Jacob 37440de345e9SJerin Jacob if (*dev->dev_ops->priority_flow_ctrl_queue_info_get) 37450de345e9SJerin Jacob return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_queue_info_get) 37460de345e9SJerin Jacob (dev, pfc_queue_info)); 37470de345e9SJerin Jacob return -ENOTSUP; 37480de345e9SJerin Jacob } 37490de345e9SJerin Jacob 37500de345e9SJerin Jacob int 37510de345e9SJerin Jacob rte_eth_dev_priority_flow_ctrl_queue_configure(uint16_t port_id, 37520de345e9SJerin Jacob struct rte_eth_pfc_queue_conf *pfc_queue_conf) 37530de345e9SJerin Jacob { 37540de345e9SJerin Jacob struct rte_eth_pfc_queue_info pfc_info; 37550de345e9SJerin Jacob struct rte_eth_dev_info dev_info; 37560de345e9SJerin Jacob struct rte_eth_dev *dev; 37570de345e9SJerin Jacob int ret; 37580de345e9SJerin Jacob 37590de345e9SJerin Jacob RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 37600de345e9SJerin Jacob dev = &rte_eth_devices[port_id]; 37610de345e9SJerin Jacob 37620de345e9SJerin Jacob if (pfc_queue_conf == NULL) { 37630de345e9SJerin Jacob RTE_ETHDEV_LOG(ERR, "PFC parameters are NULL for port (%u)\n", 37640de345e9SJerin Jacob port_id); 37650de345e9SJerin Jacob return -EINVAL; 37660de345e9SJerin Jacob } 37670de345e9SJerin Jacob 37680de345e9SJerin Jacob ret = rte_eth_dev_info_get(port_id, &dev_info); 37690de345e9SJerin Jacob if (ret != 0) 37700de345e9SJerin Jacob return ret; 37710de345e9SJerin Jacob 37720de345e9SJerin Jacob ret = rte_eth_dev_priority_flow_ctrl_queue_info_get(port_id, &pfc_info); 37730de345e9SJerin Jacob if (ret != 0) 37740de345e9SJerin Jacob return ret; 37750de345e9SJerin Jacob 37760de345e9SJerin Jacob if (pfc_info.tc_max == 0) { 37770de345e9SJerin Jacob RTE_ETHDEV_LOG(ERR, "Ethdev port %u does not support PFC TC values\n", 37780de345e9SJerin Jacob port_id); 37790de345e9SJerin Jacob return -ENOTSUP; 37800de345e9SJerin Jacob } 37810de345e9SJerin Jacob 37820de345e9SJerin Jacob /* Check requested mode supported or not */ 37830de345e9SJerin Jacob if (pfc_info.mode_capa == RTE_ETH_FC_RX_PAUSE && 37840de345e9SJerin Jacob pfc_queue_conf->mode == RTE_ETH_FC_TX_PAUSE) { 37850de345e9SJerin Jacob RTE_ETHDEV_LOG(ERR, "PFC Tx pause unsupported for port (%d)\n", 37860de345e9SJerin Jacob port_id); 37870de345e9SJerin Jacob return -EINVAL; 37880de345e9SJerin Jacob } 37890de345e9SJerin Jacob 37900de345e9SJerin Jacob if (pfc_info.mode_capa == RTE_ETH_FC_TX_PAUSE && 37910de345e9SJerin Jacob pfc_queue_conf->mode == RTE_ETH_FC_RX_PAUSE) { 37920de345e9SJerin Jacob RTE_ETHDEV_LOG(ERR, "PFC Rx pause unsupported for port (%d)\n", 37930de345e9SJerin Jacob port_id); 37940de345e9SJerin Jacob return -EINVAL; 37950de345e9SJerin Jacob } 37960de345e9SJerin Jacob 37970de345e9SJerin Jacob /* Validate Rx pause parameters */ 37980de345e9SJerin Jacob if (pfc_info.mode_capa == RTE_ETH_FC_FULL || 37990de345e9SJerin Jacob pfc_info.mode_capa == RTE_ETH_FC_RX_PAUSE) { 38000de345e9SJerin Jacob ret = validate_rx_pause_config(&dev_info, pfc_info.tc_max, 38010de345e9SJerin Jacob pfc_queue_conf); 38020de345e9SJerin Jacob if (ret != 0) 38030de345e9SJerin Jacob return ret; 38040de345e9SJerin Jacob } 38050de345e9SJerin Jacob 38060de345e9SJerin Jacob /* Validate Tx pause parameters */ 38070de345e9SJerin Jacob if (pfc_info.mode_capa == RTE_ETH_FC_FULL || 38080de345e9SJerin Jacob pfc_info.mode_capa == RTE_ETH_FC_TX_PAUSE) { 38090de345e9SJerin Jacob ret = validate_tx_pause_config(&dev_info, pfc_info.tc_max, 38100de345e9SJerin Jacob pfc_queue_conf); 38110de345e9SJerin Jacob if (ret != 0) 38120de345e9SJerin Jacob return ret; 38130de345e9SJerin Jacob } 38140de345e9SJerin Jacob 38150de345e9SJerin Jacob if (*dev->dev_ops->priority_flow_ctrl_queue_config) 38160de345e9SJerin Jacob return eth_err(port_id, 38170de345e9SJerin Jacob (*dev->dev_ops->priority_flow_ctrl_queue_config)( 38180de345e9SJerin Jacob dev, pfc_queue_conf)); 38190de345e9SJerin Jacob return -ENOTSUP; 38200de345e9SJerin Jacob } 38210de345e9SJerin Jacob 38220de345e9SJerin Jacob static int 382399a2dd95SBruce Richardson eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf, 382499a2dd95SBruce Richardson uint16_t reta_size) 382599a2dd95SBruce Richardson { 382699a2dd95SBruce Richardson uint16_t i, num; 382799a2dd95SBruce Richardson 3828295968d1SFerruh Yigit num = (reta_size + RTE_ETH_RETA_GROUP_SIZE - 1) / RTE_ETH_RETA_GROUP_SIZE; 382999a2dd95SBruce Richardson for (i = 0; i < num; i++) { 383099a2dd95SBruce Richardson if (reta_conf[i].mask) 383199a2dd95SBruce Richardson return 0; 383299a2dd95SBruce Richardson } 383399a2dd95SBruce Richardson 383499a2dd95SBruce Richardson return -EINVAL; 383599a2dd95SBruce Richardson } 383699a2dd95SBruce Richardson 383799a2dd95SBruce Richardson static int 383899a2dd95SBruce Richardson eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf, 383999a2dd95SBruce Richardson uint16_t reta_size, 384099a2dd95SBruce Richardson uint16_t max_rxq) 384199a2dd95SBruce Richardson { 384299a2dd95SBruce Richardson uint16_t i, idx, shift; 384399a2dd95SBruce Richardson 384499a2dd95SBruce Richardson if (max_rxq == 0) { 384599a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "No receive queue is available\n"); 384699a2dd95SBruce Richardson return -EINVAL; 384799a2dd95SBruce Richardson } 384899a2dd95SBruce Richardson 384999a2dd95SBruce Richardson for (i = 0; i < reta_size; i++) { 3850295968d1SFerruh Yigit idx = i / RTE_ETH_RETA_GROUP_SIZE; 3851295968d1SFerruh Yigit shift = i % RTE_ETH_RETA_GROUP_SIZE; 3852e1823e08SThomas Monjalon if ((reta_conf[idx].mask & RTE_BIT64(shift)) && 385399a2dd95SBruce Richardson (reta_conf[idx].reta[shift] >= max_rxq)) { 385499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 385599a2dd95SBruce Richardson "reta_conf[%u]->reta[%u]: %u exceeds the maximum rxq index: %u\n", 385699a2dd95SBruce Richardson idx, shift, 385799a2dd95SBruce Richardson reta_conf[idx].reta[shift], max_rxq); 385899a2dd95SBruce Richardson return -EINVAL; 385999a2dd95SBruce Richardson } 386099a2dd95SBruce Richardson } 386199a2dd95SBruce Richardson 386299a2dd95SBruce Richardson return 0; 386399a2dd95SBruce Richardson } 386499a2dd95SBruce Richardson 386599a2dd95SBruce Richardson int 386699a2dd95SBruce Richardson rte_eth_dev_rss_reta_update(uint16_t port_id, 386799a2dd95SBruce Richardson struct rte_eth_rss_reta_entry64 *reta_conf, 386899a2dd95SBruce Richardson uint16_t reta_size) 386999a2dd95SBruce Richardson { 387099a2dd95SBruce Richardson struct rte_eth_dev *dev; 387199a2dd95SBruce Richardson int ret; 387299a2dd95SBruce Richardson 387399a2dd95SBruce Richardson 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 (reta_conf == NULL) { 387753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 387853ef1b34SMin Hu (Connor) "Cannot update ethdev port %u RSS RETA to NULL\n", 387953ef1b34SMin Hu (Connor) port_id); 388053ef1b34SMin Hu (Connor) return -EINVAL; 388153ef1b34SMin Hu (Connor) } 388253ef1b34SMin Hu (Connor) 388353ef1b34SMin Hu (Connor) if (reta_size == 0) { 388453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 388553ef1b34SMin Hu (Connor) "Cannot update ethdev port %u RSS RETA with zero size\n", 388653ef1b34SMin Hu (Connor) port_id); 388753ef1b34SMin Hu (Connor) return -EINVAL; 388853ef1b34SMin Hu (Connor) } 388953ef1b34SMin Hu (Connor) 389099a2dd95SBruce Richardson /* Check mask bits */ 389199a2dd95SBruce Richardson ret = eth_check_reta_mask(reta_conf, reta_size); 389299a2dd95SBruce Richardson if (ret < 0) 389399a2dd95SBruce Richardson return ret; 389499a2dd95SBruce Richardson 389599a2dd95SBruce Richardson /* Check entry value */ 389699a2dd95SBruce Richardson ret = eth_check_reta_entry(reta_conf, reta_size, 389799a2dd95SBruce Richardson dev->data->nb_rx_queues); 389899a2dd95SBruce Richardson if (ret < 0) 389999a2dd95SBruce Richardson return ret; 390099a2dd95SBruce Richardson 390199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_update, -ENOTSUP); 390299a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->reta_update)(dev, reta_conf, 390399a2dd95SBruce Richardson reta_size)); 390499a2dd95SBruce Richardson } 390599a2dd95SBruce Richardson 390699a2dd95SBruce Richardson int 390799a2dd95SBruce Richardson rte_eth_dev_rss_reta_query(uint16_t port_id, 390899a2dd95SBruce Richardson struct rte_eth_rss_reta_entry64 *reta_conf, 390999a2dd95SBruce Richardson uint16_t reta_size) 391099a2dd95SBruce Richardson { 391199a2dd95SBruce Richardson struct rte_eth_dev *dev; 391299a2dd95SBruce Richardson int ret; 391399a2dd95SBruce Richardson 391499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 391553ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 391653ef1b34SMin Hu (Connor) 391753ef1b34SMin Hu (Connor) if (reta_conf == NULL) { 391853ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 391953ef1b34SMin Hu (Connor) "Cannot query ethdev port %u RSS RETA from NULL config\n", 392053ef1b34SMin Hu (Connor) port_id); 392153ef1b34SMin Hu (Connor) return -EINVAL; 392253ef1b34SMin Hu (Connor) } 392399a2dd95SBruce Richardson 392499a2dd95SBruce Richardson /* Check mask bits */ 392599a2dd95SBruce Richardson ret = eth_check_reta_mask(reta_conf, reta_size); 392699a2dd95SBruce Richardson if (ret < 0) 392799a2dd95SBruce Richardson return ret; 392899a2dd95SBruce Richardson 392999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP); 393099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf, 393199a2dd95SBruce Richardson reta_size)); 393299a2dd95SBruce Richardson } 393399a2dd95SBruce Richardson 393499a2dd95SBruce Richardson int 393599a2dd95SBruce Richardson rte_eth_dev_rss_hash_update(uint16_t port_id, 393699a2dd95SBruce Richardson struct rte_eth_rss_conf *rss_conf) 393799a2dd95SBruce Richardson { 393899a2dd95SBruce Richardson struct rte_eth_dev *dev; 393999a2dd95SBruce Richardson struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, }; 394099a2dd95SBruce Richardson int ret; 394199a2dd95SBruce Richardson 394299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 394353ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 394453ef1b34SMin Hu (Connor) 394553ef1b34SMin Hu (Connor) if (rss_conf == NULL) { 394653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 394753ef1b34SMin Hu (Connor) "Cannot update ethdev port %u RSS hash from NULL config\n", 394853ef1b34SMin Hu (Connor) port_id); 394953ef1b34SMin Hu (Connor) return -EINVAL; 395053ef1b34SMin Hu (Connor) } 395199a2dd95SBruce Richardson 395299a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 395399a2dd95SBruce Richardson if (ret != 0) 395499a2dd95SBruce Richardson return ret; 395599a2dd95SBruce Richardson 395699a2dd95SBruce Richardson rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf); 395799a2dd95SBruce Richardson if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) != 395899a2dd95SBruce Richardson dev_info.flow_type_rss_offloads) { 395999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 396099a2dd95SBruce Richardson "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n", 396199a2dd95SBruce Richardson port_id, rss_conf->rss_hf, 396299a2dd95SBruce Richardson dev_info.flow_type_rss_offloads); 396399a2dd95SBruce Richardson return -EINVAL; 396499a2dd95SBruce Richardson } 396599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP); 396699a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->rss_hash_update)(dev, 396799a2dd95SBruce Richardson rss_conf)); 396899a2dd95SBruce Richardson } 396999a2dd95SBruce Richardson 397099a2dd95SBruce Richardson int 397199a2dd95SBruce Richardson rte_eth_dev_rss_hash_conf_get(uint16_t port_id, 397299a2dd95SBruce Richardson struct rte_eth_rss_conf *rss_conf) 397399a2dd95SBruce Richardson { 397499a2dd95SBruce Richardson struct rte_eth_dev *dev; 397599a2dd95SBruce Richardson 397699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 397799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 397853ef1b34SMin Hu (Connor) 397953ef1b34SMin Hu (Connor) if (rss_conf == NULL) { 398053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 398153ef1b34SMin Hu (Connor) "Cannot get ethdev port %u RSS hash config to NULL\n", 398253ef1b34SMin Hu (Connor) port_id); 398353ef1b34SMin Hu (Connor) return -EINVAL; 398453ef1b34SMin Hu (Connor) } 398553ef1b34SMin Hu (Connor) 398699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP); 398799a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev, 398899a2dd95SBruce Richardson rss_conf)); 398999a2dd95SBruce Richardson } 399099a2dd95SBruce Richardson 399199a2dd95SBruce Richardson int 399299a2dd95SBruce Richardson rte_eth_dev_udp_tunnel_port_add(uint16_t port_id, 399399a2dd95SBruce Richardson struct rte_eth_udp_tunnel *udp_tunnel) 399499a2dd95SBruce Richardson { 399599a2dd95SBruce Richardson struct rte_eth_dev *dev; 399699a2dd95SBruce Richardson 399799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 399853ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 399953ef1b34SMin Hu (Connor) 400099a2dd95SBruce Richardson if (udp_tunnel == NULL) { 400153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 400253ef1b34SMin Hu (Connor) "Cannot add ethdev port %u UDP tunnel port from NULL UDP tunnel\n", 400353ef1b34SMin Hu (Connor) port_id); 400499a2dd95SBruce Richardson return -EINVAL; 400599a2dd95SBruce Richardson } 400699a2dd95SBruce Richardson 4007295968d1SFerruh Yigit if (udp_tunnel->prot_type >= RTE_ETH_TUNNEL_TYPE_MAX) { 400899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n"); 400999a2dd95SBruce Richardson return -EINVAL; 401099a2dd95SBruce Richardson } 401199a2dd95SBruce Richardson 401299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_add, -ENOTSUP); 401399a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_add)(dev, 401499a2dd95SBruce Richardson udp_tunnel)); 401599a2dd95SBruce Richardson } 401699a2dd95SBruce Richardson 401799a2dd95SBruce Richardson int 401899a2dd95SBruce Richardson rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id, 401999a2dd95SBruce Richardson struct rte_eth_udp_tunnel *udp_tunnel) 402099a2dd95SBruce Richardson { 402199a2dd95SBruce Richardson struct rte_eth_dev *dev; 402299a2dd95SBruce Richardson 402399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 402499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 402599a2dd95SBruce Richardson 402699a2dd95SBruce Richardson if (udp_tunnel == NULL) { 402753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 402853ef1b34SMin Hu (Connor) "Cannot delete ethdev port %u UDP tunnel port from NULL UDP tunnel\n", 402953ef1b34SMin Hu (Connor) port_id); 403099a2dd95SBruce Richardson return -EINVAL; 403199a2dd95SBruce Richardson } 403299a2dd95SBruce Richardson 4033295968d1SFerruh Yigit if (udp_tunnel->prot_type >= RTE_ETH_TUNNEL_TYPE_MAX) { 403499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n"); 403599a2dd95SBruce Richardson return -EINVAL; 403699a2dd95SBruce Richardson } 403799a2dd95SBruce Richardson 403899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_del, -ENOTSUP); 403999a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_del)(dev, 404099a2dd95SBruce Richardson udp_tunnel)); 404199a2dd95SBruce Richardson } 404299a2dd95SBruce Richardson 404399a2dd95SBruce Richardson int 404499a2dd95SBruce Richardson rte_eth_led_on(uint16_t port_id) 404599a2dd95SBruce Richardson { 404699a2dd95SBruce Richardson struct rte_eth_dev *dev; 404799a2dd95SBruce Richardson 404899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 404999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 405053ef1b34SMin Hu (Connor) 405199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_on, -ENOTSUP); 405299a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->dev_led_on)(dev)); 405399a2dd95SBruce Richardson } 405499a2dd95SBruce Richardson 405599a2dd95SBruce Richardson int 405699a2dd95SBruce Richardson rte_eth_led_off(uint16_t port_id) 405799a2dd95SBruce Richardson { 405899a2dd95SBruce Richardson struct rte_eth_dev *dev; 405999a2dd95SBruce Richardson 406099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 406199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 406253ef1b34SMin Hu (Connor) 406399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_off, -ENOTSUP); 406499a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->dev_led_off)(dev)); 406599a2dd95SBruce Richardson } 406699a2dd95SBruce Richardson 406799a2dd95SBruce Richardson int 406899a2dd95SBruce Richardson rte_eth_fec_get_capability(uint16_t port_id, 406999a2dd95SBruce Richardson struct rte_eth_fec_capa *speed_fec_capa, 407099a2dd95SBruce Richardson unsigned int num) 407199a2dd95SBruce Richardson { 407299a2dd95SBruce Richardson struct rte_eth_dev *dev; 407399a2dd95SBruce Richardson int ret; 407499a2dd95SBruce Richardson 407599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 407699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 407753ef1b34SMin Hu (Connor) 407853ef1b34SMin Hu (Connor) if (speed_fec_capa == NULL && num > 0) { 407953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 408053ef1b34SMin Hu (Connor) "Cannot get ethdev port %u FEC capability to NULL when array size is non zero\n", 408153ef1b34SMin Hu (Connor) port_id); 408253ef1b34SMin Hu (Connor) return -EINVAL; 408353ef1b34SMin Hu (Connor) } 408453ef1b34SMin Hu (Connor) 408599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get_capability, -ENOTSUP); 408699a2dd95SBruce Richardson ret = (*dev->dev_ops->fec_get_capability)(dev, speed_fec_capa, num); 408799a2dd95SBruce Richardson 408899a2dd95SBruce Richardson return ret; 408999a2dd95SBruce Richardson } 409099a2dd95SBruce Richardson 409199a2dd95SBruce Richardson int 409299a2dd95SBruce Richardson rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa) 409399a2dd95SBruce Richardson { 409499a2dd95SBruce Richardson struct rte_eth_dev *dev; 409599a2dd95SBruce Richardson 409699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 409799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 409853ef1b34SMin Hu (Connor) 409953ef1b34SMin Hu (Connor) if (fec_capa == NULL) { 410053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 410153ef1b34SMin Hu (Connor) "Cannot get ethdev port %u current FEC mode to NULL\n", 410253ef1b34SMin Hu (Connor) port_id); 410353ef1b34SMin Hu (Connor) return -EINVAL; 410453ef1b34SMin Hu (Connor) } 410553ef1b34SMin Hu (Connor) 410699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get, -ENOTSUP); 410799a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->fec_get)(dev, fec_capa)); 410899a2dd95SBruce Richardson } 410999a2dd95SBruce Richardson 411099a2dd95SBruce Richardson int 411199a2dd95SBruce Richardson rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa) 411299a2dd95SBruce Richardson { 411399a2dd95SBruce Richardson struct rte_eth_dev *dev; 411499a2dd95SBruce Richardson 411599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 411699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 411753ef1b34SMin Hu (Connor) 411899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_set, -ENOTSUP); 411999a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->fec_set)(dev, fec_capa)); 412099a2dd95SBruce Richardson } 412199a2dd95SBruce Richardson 412299a2dd95SBruce Richardson /* 412399a2dd95SBruce Richardson * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find 412499a2dd95SBruce Richardson * an empty spot. 412599a2dd95SBruce Richardson */ 412699a2dd95SBruce Richardson static int 412799a2dd95SBruce Richardson eth_dev_get_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr) 412899a2dd95SBruce Richardson { 412999a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 413099a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 413199a2dd95SBruce Richardson unsigned i; 413299a2dd95SBruce Richardson int ret; 413399a2dd95SBruce Richardson 413499a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 413599a2dd95SBruce Richardson if (ret != 0) 413699a2dd95SBruce Richardson return -1; 413799a2dd95SBruce Richardson 413899a2dd95SBruce Richardson for (i = 0; i < dev_info.max_mac_addrs; i++) 413999a2dd95SBruce Richardson if (memcmp(addr, &dev->data->mac_addrs[i], 414099a2dd95SBruce Richardson RTE_ETHER_ADDR_LEN) == 0) 414199a2dd95SBruce Richardson return i; 414299a2dd95SBruce Richardson 414399a2dd95SBruce Richardson return -1; 414499a2dd95SBruce Richardson } 414599a2dd95SBruce Richardson 414699a2dd95SBruce Richardson static const struct rte_ether_addr null_mac_addr; 414799a2dd95SBruce Richardson 414899a2dd95SBruce Richardson int 414999a2dd95SBruce Richardson rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr, 415099a2dd95SBruce Richardson uint32_t pool) 415199a2dd95SBruce Richardson { 415299a2dd95SBruce Richardson struct rte_eth_dev *dev; 415399a2dd95SBruce Richardson int index; 415499a2dd95SBruce Richardson uint64_t pool_mask; 415599a2dd95SBruce Richardson int ret; 415699a2dd95SBruce Richardson 415799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 415899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 415953ef1b34SMin Hu (Connor) 416053ef1b34SMin Hu (Connor) if (addr == NULL) { 416153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 416253ef1b34SMin Hu (Connor) "Cannot add ethdev port %u MAC address from NULL address\n", 416353ef1b34SMin Hu (Connor) port_id); 416453ef1b34SMin Hu (Connor) return -EINVAL; 416553ef1b34SMin Hu (Connor) } 416653ef1b34SMin Hu (Connor) 416799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP); 416899a2dd95SBruce Richardson 416999a2dd95SBruce Richardson if (rte_is_zero_ether_addr(addr)) { 417099a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n", 417199a2dd95SBruce Richardson port_id); 417299a2dd95SBruce Richardson return -EINVAL; 417399a2dd95SBruce Richardson } 4174295968d1SFerruh Yigit if (pool >= RTE_ETH_64_POOLS) { 4175295968d1SFerruh Yigit RTE_ETHDEV_LOG(ERR, "Pool ID must be 0-%d\n", RTE_ETH_64_POOLS - 1); 417699a2dd95SBruce Richardson return -EINVAL; 417799a2dd95SBruce Richardson } 417899a2dd95SBruce Richardson 417999a2dd95SBruce Richardson index = eth_dev_get_mac_addr_index(port_id, addr); 418099a2dd95SBruce Richardson if (index < 0) { 418199a2dd95SBruce Richardson index = eth_dev_get_mac_addr_index(port_id, &null_mac_addr); 418299a2dd95SBruce Richardson if (index < 0) { 418399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n", 418499a2dd95SBruce Richardson port_id); 418599a2dd95SBruce Richardson return -ENOSPC; 418699a2dd95SBruce Richardson } 418799a2dd95SBruce Richardson } else { 418899a2dd95SBruce Richardson pool_mask = dev->data->mac_pool_sel[index]; 418999a2dd95SBruce Richardson 419099a2dd95SBruce Richardson /* Check if both MAC address and pool is already there, and do nothing */ 4191e1823e08SThomas Monjalon if (pool_mask & RTE_BIT64(pool)) 419299a2dd95SBruce Richardson return 0; 419399a2dd95SBruce Richardson } 419499a2dd95SBruce Richardson 419599a2dd95SBruce Richardson /* Update NIC */ 419699a2dd95SBruce Richardson ret = (*dev->dev_ops->mac_addr_add)(dev, addr, index, pool); 419799a2dd95SBruce Richardson 419899a2dd95SBruce Richardson if (ret == 0) { 419999a2dd95SBruce Richardson /* Update address in NIC data structure */ 420099a2dd95SBruce Richardson rte_ether_addr_copy(addr, &dev->data->mac_addrs[index]); 420199a2dd95SBruce Richardson 420299a2dd95SBruce Richardson /* Update pool bitmap in NIC data structure */ 4203e1823e08SThomas Monjalon dev->data->mac_pool_sel[index] |= RTE_BIT64(pool); 420499a2dd95SBruce Richardson } 420599a2dd95SBruce Richardson 420699a2dd95SBruce Richardson return eth_err(port_id, ret); 420799a2dd95SBruce Richardson } 420899a2dd95SBruce Richardson 420999a2dd95SBruce Richardson int 421099a2dd95SBruce Richardson rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) 421199a2dd95SBruce Richardson { 421299a2dd95SBruce Richardson struct rte_eth_dev *dev; 421399a2dd95SBruce Richardson int index; 421499a2dd95SBruce Richardson 421599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 421699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 421753ef1b34SMin Hu (Connor) 421853ef1b34SMin Hu (Connor) if (addr == NULL) { 421953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 422053ef1b34SMin Hu (Connor) "Cannot remove ethdev port %u MAC address from NULL address\n", 422153ef1b34SMin Hu (Connor) port_id); 422253ef1b34SMin Hu (Connor) return -EINVAL; 422353ef1b34SMin Hu (Connor) } 422453ef1b34SMin Hu (Connor) 422599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP); 422699a2dd95SBruce Richardson 422799a2dd95SBruce Richardson index = eth_dev_get_mac_addr_index(port_id, addr); 422899a2dd95SBruce Richardson if (index == 0) { 422999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 423099a2dd95SBruce Richardson "Port %u: Cannot remove default MAC address\n", 423199a2dd95SBruce Richardson port_id); 423299a2dd95SBruce Richardson return -EADDRINUSE; 423399a2dd95SBruce Richardson } else if (index < 0) 423499a2dd95SBruce Richardson return 0; /* Do nothing if address wasn't found */ 423599a2dd95SBruce Richardson 423699a2dd95SBruce Richardson /* Update NIC */ 423799a2dd95SBruce Richardson (*dev->dev_ops->mac_addr_remove)(dev, index); 423899a2dd95SBruce Richardson 423999a2dd95SBruce Richardson /* Update address in NIC data structure */ 424099a2dd95SBruce Richardson rte_ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]); 424199a2dd95SBruce Richardson 424299a2dd95SBruce Richardson /* reset pool bitmap */ 424399a2dd95SBruce Richardson dev->data->mac_pool_sel[index] = 0; 424499a2dd95SBruce Richardson 424599a2dd95SBruce Richardson return 0; 424699a2dd95SBruce Richardson } 424799a2dd95SBruce Richardson 424899a2dd95SBruce Richardson int 424999a2dd95SBruce Richardson rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) 425099a2dd95SBruce Richardson { 425199a2dd95SBruce Richardson struct rte_eth_dev *dev; 425299a2dd95SBruce Richardson int ret; 425399a2dd95SBruce Richardson 425499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 425553ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 425653ef1b34SMin Hu (Connor) 425753ef1b34SMin Hu (Connor) if (addr == NULL) { 425853ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 425953ef1b34SMin Hu (Connor) "Cannot set ethdev port %u default MAC address from NULL address\n", 426053ef1b34SMin Hu (Connor) port_id); 426153ef1b34SMin Hu (Connor) return -EINVAL; 426253ef1b34SMin Hu (Connor) } 426399a2dd95SBruce Richardson 426499a2dd95SBruce Richardson if (!rte_is_valid_assigned_ether_addr(addr)) 426599a2dd95SBruce Richardson return -EINVAL; 426699a2dd95SBruce Richardson 426799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP); 426899a2dd95SBruce Richardson 426999a2dd95SBruce Richardson ret = (*dev->dev_ops->mac_addr_set)(dev, addr); 427099a2dd95SBruce Richardson if (ret < 0) 427199a2dd95SBruce Richardson return ret; 427299a2dd95SBruce Richardson 427399a2dd95SBruce Richardson /* Update default address in NIC data structure */ 427499a2dd95SBruce Richardson rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); 427599a2dd95SBruce Richardson 427699a2dd95SBruce Richardson return 0; 427799a2dd95SBruce Richardson } 427899a2dd95SBruce Richardson 427999a2dd95SBruce Richardson 428099a2dd95SBruce Richardson /* 428199a2dd95SBruce Richardson * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find 428299a2dd95SBruce Richardson * an empty spot. 428399a2dd95SBruce Richardson */ 428499a2dd95SBruce Richardson static int 428599a2dd95SBruce Richardson eth_dev_get_hash_mac_addr_index(uint16_t port_id, 428699a2dd95SBruce Richardson const struct rte_ether_addr *addr) 428799a2dd95SBruce Richardson { 428899a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 428999a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 429099a2dd95SBruce Richardson unsigned i; 429199a2dd95SBruce Richardson int ret; 429299a2dd95SBruce Richardson 429399a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 429499a2dd95SBruce Richardson if (ret != 0) 429599a2dd95SBruce Richardson return -1; 429699a2dd95SBruce Richardson 429799a2dd95SBruce Richardson if (!dev->data->hash_mac_addrs) 429899a2dd95SBruce Richardson return -1; 429999a2dd95SBruce Richardson 430099a2dd95SBruce Richardson for (i = 0; i < dev_info.max_hash_mac_addrs; i++) 430199a2dd95SBruce Richardson if (memcmp(addr, &dev->data->hash_mac_addrs[i], 430299a2dd95SBruce Richardson RTE_ETHER_ADDR_LEN) == 0) 430399a2dd95SBruce Richardson return i; 430499a2dd95SBruce Richardson 430599a2dd95SBruce Richardson return -1; 430699a2dd95SBruce Richardson } 430799a2dd95SBruce Richardson 430899a2dd95SBruce Richardson int 430999a2dd95SBruce Richardson rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr, 431099a2dd95SBruce Richardson uint8_t on) 431199a2dd95SBruce Richardson { 431299a2dd95SBruce Richardson int index; 431399a2dd95SBruce Richardson int ret; 431499a2dd95SBruce Richardson struct rte_eth_dev *dev; 431599a2dd95SBruce Richardson 431699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 431799a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 431853ef1b34SMin Hu (Connor) 431953ef1b34SMin Hu (Connor) if (addr == NULL) { 432053ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 432153ef1b34SMin Hu (Connor) "Cannot set ethdev port %u unicast hash table from NULL address\n", 432253ef1b34SMin Hu (Connor) port_id); 432353ef1b34SMin Hu (Connor) return -EINVAL; 432453ef1b34SMin Hu (Connor) } 432553ef1b34SMin Hu (Connor) 432699a2dd95SBruce Richardson if (rte_is_zero_ether_addr(addr)) { 432799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n", 432899a2dd95SBruce Richardson port_id); 432999a2dd95SBruce Richardson return -EINVAL; 433099a2dd95SBruce Richardson } 433199a2dd95SBruce Richardson 433299a2dd95SBruce Richardson index = eth_dev_get_hash_mac_addr_index(port_id, addr); 433399a2dd95SBruce Richardson /* Check if it's already there, and do nothing */ 433499a2dd95SBruce Richardson if ((index >= 0) && on) 433599a2dd95SBruce Richardson return 0; 433699a2dd95SBruce Richardson 433799a2dd95SBruce Richardson if (index < 0) { 433899a2dd95SBruce Richardson if (!on) { 433999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 434099a2dd95SBruce Richardson "Port %u: the MAC address was not set in UTA\n", 434199a2dd95SBruce Richardson port_id); 434299a2dd95SBruce Richardson return -EINVAL; 434399a2dd95SBruce Richardson } 434499a2dd95SBruce Richardson 434599a2dd95SBruce Richardson index = eth_dev_get_hash_mac_addr_index(port_id, &null_mac_addr); 434699a2dd95SBruce Richardson if (index < 0) { 434799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n", 434899a2dd95SBruce Richardson port_id); 434999a2dd95SBruce Richardson return -ENOSPC; 435099a2dd95SBruce Richardson } 435199a2dd95SBruce Richardson } 435299a2dd95SBruce Richardson 435399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_hash_table_set, -ENOTSUP); 435499a2dd95SBruce Richardson ret = (*dev->dev_ops->uc_hash_table_set)(dev, addr, on); 435599a2dd95SBruce Richardson if (ret == 0) { 435699a2dd95SBruce Richardson /* Update address in NIC data structure */ 435799a2dd95SBruce Richardson if (on) 435899a2dd95SBruce Richardson rte_ether_addr_copy(addr, 435999a2dd95SBruce Richardson &dev->data->hash_mac_addrs[index]); 436099a2dd95SBruce Richardson else 436199a2dd95SBruce Richardson rte_ether_addr_copy(&null_mac_addr, 436299a2dd95SBruce Richardson &dev->data->hash_mac_addrs[index]); 436399a2dd95SBruce Richardson } 436499a2dd95SBruce Richardson 436599a2dd95SBruce Richardson return eth_err(port_id, ret); 436699a2dd95SBruce Richardson } 436799a2dd95SBruce Richardson 436899a2dd95SBruce Richardson int 436999a2dd95SBruce Richardson rte_eth_dev_uc_all_hash_table_set(uint16_t port_id, uint8_t on) 437099a2dd95SBruce Richardson { 437199a2dd95SBruce Richardson struct rte_eth_dev *dev; 437299a2dd95SBruce Richardson 437399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 437499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 437599a2dd95SBruce Richardson 437699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_all_hash_table_set, -ENOTSUP); 437799a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->uc_all_hash_table_set)(dev, 437899a2dd95SBruce Richardson on)); 437999a2dd95SBruce Richardson } 438099a2dd95SBruce Richardson 438199a2dd95SBruce Richardson int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx, 438299a2dd95SBruce Richardson uint16_t tx_rate) 438399a2dd95SBruce Richardson { 438499a2dd95SBruce Richardson struct rte_eth_dev *dev; 438599a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 438699a2dd95SBruce Richardson struct rte_eth_link link; 438799a2dd95SBruce Richardson int ret; 438899a2dd95SBruce Richardson 438999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 439053ef1b34SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 439199a2dd95SBruce Richardson 439299a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 439399a2dd95SBruce Richardson if (ret != 0) 439499a2dd95SBruce Richardson return ret; 439599a2dd95SBruce Richardson 439699a2dd95SBruce Richardson link = dev->data->dev_link; 439799a2dd95SBruce Richardson 439899a2dd95SBruce Richardson if (queue_idx > dev_info.max_tx_queues) { 439999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 44005906be5aSAndrew Rybchenko "Set queue rate limit:port %u: invalid queue ID=%u\n", 440199a2dd95SBruce Richardson port_id, queue_idx); 440299a2dd95SBruce Richardson return -EINVAL; 440399a2dd95SBruce Richardson } 440499a2dd95SBruce Richardson 440599a2dd95SBruce Richardson if (tx_rate > link.link_speed) { 440699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 440799a2dd95SBruce Richardson "Set queue rate limit:invalid tx_rate=%u, bigger than link speed= %d\n", 440899a2dd95SBruce Richardson tx_rate, link.link_speed); 440999a2dd95SBruce Richardson return -EINVAL; 441099a2dd95SBruce Richardson } 441199a2dd95SBruce Richardson 441299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_queue_rate_limit, -ENOTSUP); 441399a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->set_queue_rate_limit)(dev, 441499a2dd95SBruce Richardson queue_idx, tx_rate)); 441599a2dd95SBruce Richardson } 441699a2dd95SBruce Richardson 4417c87d435aSKonstantin Ananyev RTE_INIT(eth_dev_init_fp_ops) 4418c87d435aSKonstantin Ananyev { 4419c87d435aSKonstantin Ananyev uint32_t i; 4420c87d435aSKonstantin Ananyev 4421c87d435aSKonstantin Ananyev for (i = 0; i != RTE_DIM(rte_eth_fp_ops); i++) 4422c87d435aSKonstantin Ananyev eth_dev_fp_ops_reset(rte_eth_fp_ops + i); 4423c87d435aSKonstantin Ananyev } 4424c87d435aSKonstantin Ananyev 442599a2dd95SBruce Richardson RTE_INIT(eth_dev_init_cb_lists) 442699a2dd95SBruce Richardson { 442799a2dd95SBruce Richardson uint16_t i; 442899a2dd95SBruce Richardson 442999a2dd95SBruce Richardson for (i = 0; i < RTE_MAX_ETHPORTS; i++) 443099a2dd95SBruce Richardson TAILQ_INIT(&rte_eth_devices[i].link_intr_cbs); 443199a2dd95SBruce Richardson } 443299a2dd95SBruce Richardson 443399a2dd95SBruce Richardson int 443499a2dd95SBruce Richardson rte_eth_dev_callback_register(uint16_t port_id, 443599a2dd95SBruce Richardson enum rte_eth_event_type event, 443699a2dd95SBruce Richardson rte_eth_dev_cb_fn cb_fn, void *cb_arg) 443799a2dd95SBruce Richardson { 443899a2dd95SBruce Richardson struct rte_eth_dev *dev; 443999a2dd95SBruce Richardson struct rte_eth_dev_callback *user_cb; 444099a2dd95SBruce Richardson uint16_t next_port; 444199a2dd95SBruce Richardson uint16_t last_port; 444299a2dd95SBruce Richardson 444353ef1b34SMin Hu (Connor) if (cb_fn == NULL) { 444453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 444553ef1b34SMin Hu (Connor) "Cannot register ethdev port %u callback from NULL\n", 444653ef1b34SMin Hu (Connor) port_id); 444799a2dd95SBruce Richardson return -EINVAL; 444853ef1b34SMin Hu (Connor) } 444999a2dd95SBruce Richardson 445099a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) { 445199a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id); 445299a2dd95SBruce Richardson return -EINVAL; 445399a2dd95SBruce Richardson } 445499a2dd95SBruce Richardson 445599a2dd95SBruce Richardson if (port_id == RTE_ETH_ALL) { 445699a2dd95SBruce Richardson next_port = 0; 445799a2dd95SBruce Richardson last_port = RTE_MAX_ETHPORTS - 1; 445899a2dd95SBruce Richardson } else { 445999a2dd95SBruce Richardson next_port = last_port = port_id; 446099a2dd95SBruce Richardson } 446199a2dd95SBruce Richardson 446299a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_cb_lock); 446399a2dd95SBruce Richardson 446499a2dd95SBruce Richardson do { 446599a2dd95SBruce Richardson dev = &rte_eth_devices[next_port]; 446699a2dd95SBruce Richardson 446799a2dd95SBruce Richardson TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) { 446899a2dd95SBruce Richardson if (user_cb->cb_fn == cb_fn && 446999a2dd95SBruce Richardson user_cb->cb_arg == cb_arg && 447099a2dd95SBruce Richardson user_cb->event == event) { 447199a2dd95SBruce Richardson break; 447299a2dd95SBruce Richardson } 447399a2dd95SBruce Richardson } 447499a2dd95SBruce Richardson 447599a2dd95SBruce Richardson /* create a new callback. */ 447699a2dd95SBruce Richardson if (user_cb == NULL) { 447799a2dd95SBruce Richardson user_cb = rte_zmalloc("INTR_USER_CALLBACK", 447899a2dd95SBruce Richardson sizeof(struct rte_eth_dev_callback), 0); 447999a2dd95SBruce Richardson if (user_cb != NULL) { 448099a2dd95SBruce Richardson user_cb->cb_fn = cb_fn; 448199a2dd95SBruce Richardson user_cb->cb_arg = cb_arg; 448299a2dd95SBruce Richardson user_cb->event = event; 448399a2dd95SBruce Richardson TAILQ_INSERT_TAIL(&(dev->link_intr_cbs), 448499a2dd95SBruce Richardson user_cb, next); 448599a2dd95SBruce Richardson } else { 448699a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_cb_lock); 448799a2dd95SBruce Richardson rte_eth_dev_callback_unregister(port_id, event, 448899a2dd95SBruce Richardson cb_fn, cb_arg); 448999a2dd95SBruce Richardson return -ENOMEM; 449099a2dd95SBruce Richardson } 449199a2dd95SBruce Richardson 449299a2dd95SBruce Richardson } 449399a2dd95SBruce Richardson } while (++next_port <= last_port); 449499a2dd95SBruce Richardson 449599a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_cb_lock); 449699a2dd95SBruce Richardson return 0; 449799a2dd95SBruce Richardson } 449899a2dd95SBruce Richardson 449999a2dd95SBruce Richardson int 450099a2dd95SBruce Richardson rte_eth_dev_callback_unregister(uint16_t port_id, 450199a2dd95SBruce Richardson enum rte_eth_event_type event, 450299a2dd95SBruce Richardson rte_eth_dev_cb_fn cb_fn, void *cb_arg) 450399a2dd95SBruce Richardson { 450499a2dd95SBruce Richardson int ret; 450599a2dd95SBruce Richardson struct rte_eth_dev *dev; 450699a2dd95SBruce Richardson struct rte_eth_dev_callback *cb, *next; 450799a2dd95SBruce Richardson uint16_t next_port; 450899a2dd95SBruce Richardson uint16_t last_port; 450999a2dd95SBruce Richardson 451053ef1b34SMin Hu (Connor) if (cb_fn == NULL) { 451153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 451253ef1b34SMin Hu (Connor) "Cannot unregister ethdev port %u callback from NULL\n", 451353ef1b34SMin Hu (Connor) port_id); 451499a2dd95SBruce Richardson return -EINVAL; 451553ef1b34SMin Hu (Connor) } 451699a2dd95SBruce Richardson 451799a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) { 451899a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id); 451999a2dd95SBruce Richardson return -EINVAL; 452099a2dd95SBruce Richardson } 452199a2dd95SBruce Richardson 452299a2dd95SBruce Richardson if (port_id == RTE_ETH_ALL) { 452399a2dd95SBruce Richardson next_port = 0; 452499a2dd95SBruce Richardson last_port = RTE_MAX_ETHPORTS - 1; 452599a2dd95SBruce Richardson } else { 452699a2dd95SBruce Richardson next_port = last_port = port_id; 452799a2dd95SBruce Richardson } 452899a2dd95SBruce Richardson 452999a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_cb_lock); 453099a2dd95SBruce Richardson 453199a2dd95SBruce Richardson do { 453299a2dd95SBruce Richardson dev = &rte_eth_devices[next_port]; 453399a2dd95SBruce Richardson ret = 0; 453499a2dd95SBruce Richardson for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL; 453599a2dd95SBruce Richardson cb = next) { 453699a2dd95SBruce Richardson 453799a2dd95SBruce Richardson next = TAILQ_NEXT(cb, next); 453899a2dd95SBruce Richardson 453999a2dd95SBruce Richardson if (cb->cb_fn != cb_fn || cb->event != event || 454099a2dd95SBruce Richardson (cb_arg != (void *)-1 && cb->cb_arg != cb_arg)) 454199a2dd95SBruce Richardson continue; 454299a2dd95SBruce Richardson 454399a2dd95SBruce Richardson /* 454499a2dd95SBruce Richardson * if this callback is not executing right now, 454599a2dd95SBruce Richardson * then remove it. 454699a2dd95SBruce Richardson */ 454799a2dd95SBruce Richardson if (cb->active == 0) { 454899a2dd95SBruce Richardson TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next); 454999a2dd95SBruce Richardson rte_free(cb); 455099a2dd95SBruce Richardson } else { 455199a2dd95SBruce Richardson ret = -EAGAIN; 455299a2dd95SBruce Richardson } 455399a2dd95SBruce Richardson } 455499a2dd95SBruce Richardson } while (++next_port <= last_port); 455599a2dd95SBruce Richardson 455699a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_cb_lock); 455799a2dd95SBruce Richardson return ret; 455899a2dd95SBruce Richardson } 455999a2dd95SBruce Richardson 456099a2dd95SBruce Richardson int 456199a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data) 456299a2dd95SBruce Richardson { 456399a2dd95SBruce Richardson uint32_t vec; 456499a2dd95SBruce Richardson struct rte_eth_dev *dev; 456599a2dd95SBruce Richardson struct rte_intr_handle *intr_handle; 456699a2dd95SBruce Richardson uint16_t qid; 456799a2dd95SBruce Richardson int rc; 456899a2dd95SBruce Richardson 456999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 457099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 457199a2dd95SBruce Richardson 457299a2dd95SBruce Richardson if (!dev->intr_handle) { 457309fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr handle unset\n"); 457499a2dd95SBruce Richardson return -ENOTSUP; 457599a2dd95SBruce Richardson } 457699a2dd95SBruce Richardson 457799a2dd95SBruce Richardson intr_handle = dev->intr_handle; 4578c2bd9367SHarman Kalra if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { 457909fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n"); 458099a2dd95SBruce Richardson return -EPERM; 458199a2dd95SBruce Richardson } 458299a2dd95SBruce Richardson 458399a2dd95SBruce Richardson for (qid = 0; qid < dev->data->nb_rx_queues; qid++) { 4584c2bd9367SHarman Kalra vec = rte_intr_vec_list_index_get(intr_handle, qid); 458599a2dd95SBruce Richardson rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data); 458699a2dd95SBruce Richardson if (rc && rc != -EEXIST) { 458799a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 458809fd4227SAndrew Rybchenko "p %u q %u Rx ctl error op %d epfd %d vec %u\n", 458999a2dd95SBruce Richardson port_id, qid, op, epfd, vec); 459099a2dd95SBruce Richardson } 459199a2dd95SBruce Richardson } 459299a2dd95SBruce Richardson 459399a2dd95SBruce Richardson return 0; 459499a2dd95SBruce Richardson } 459599a2dd95SBruce Richardson 459699a2dd95SBruce Richardson int 459799a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id, uint16_t queue_id) 459899a2dd95SBruce Richardson { 459999a2dd95SBruce Richardson struct rte_intr_handle *intr_handle; 460099a2dd95SBruce Richardson struct rte_eth_dev *dev; 460199a2dd95SBruce Richardson unsigned int efd_idx; 460299a2dd95SBruce Richardson uint32_t vec; 460399a2dd95SBruce Richardson int fd; 460499a2dd95SBruce Richardson 460599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); 460699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 460799a2dd95SBruce Richardson 460899a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 460909fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id); 461099a2dd95SBruce Richardson return -1; 461199a2dd95SBruce Richardson } 461299a2dd95SBruce Richardson 461399a2dd95SBruce Richardson if (!dev->intr_handle) { 461409fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr handle unset\n"); 461599a2dd95SBruce Richardson return -1; 461699a2dd95SBruce Richardson } 461799a2dd95SBruce Richardson 461899a2dd95SBruce Richardson intr_handle = dev->intr_handle; 4619c2bd9367SHarman Kalra if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { 462009fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n"); 462199a2dd95SBruce Richardson return -1; 462299a2dd95SBruce Richardson } 462399a2dd95SBruce Richardson 4624c2bd9367SHarman Kalra vec = rte_intr_vec_list_index_get(intr_handle, queue_id); 462599a2dd95SBruce Richardson efd_idx = (vec >= RTE_INTR_VEC_RXTX_OFFSET) ? 462699a2dd95SBruce Richardson (vec - RTE_INTR_VEC_RXTX_OFFSET) : vec; 4627c2bd9367SHarman Kalra fd = rte_intr_efds_index_get(intr_handle, efd_idx); 462899a2dd95SBruce Richardson 462999a2dd95SBruce Richardson return fd; 463099a2dd95SBruce Richardson } 463199a2dd95SBruce Richardson 463299a2dd95SBruce Richardson int 463399a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id, 463499a2dd95SBruce Richardson int epfd, int op, void *data) 463599a2dd95SBruce Richardson { 463699a2dd95SBruce Richardson uint32_t vec; 463799a2dd95SBruce Richardson struct rte_eth_dev *dev; 463899a2dd95SBruce Richardson struct rte_intr_handle *intr_handle; 463999a2dd95SBruce Richardson int rc; 464099a2dd95SBruce Richardson 464199a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 464299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 464353ef1b34SMin Hu (Connor) 464499a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 464509fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id); 464699a2dd95SBruce Richardson return -EINVAL; 464799a2dd95SBruce Richardson } 464899a2dd95SBruce Richardson 464999a2dd95SBruce Richardson if (!dev->intr_handle) { 465009fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr handle unset\n"); 465199a2dd95SBruce Richardson return -ENOTSUP; 465299a2dd95SBruce Richardson } 465399a2dd95SBruce Richardson 465499a2dd95SBruce Richardson intr_handle = dev->intr_handle; 4655c2bd9367SHarman Kalra if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) { 465609fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n"); 465799a2dd95SBruce Richardson return -EPERM; 465899a2dd95SBruce Richardson } 465999a2dd95SBruce Richardson 4660c2bd9367SHarman Kalra vec = rte_intr_vec_list_index_get(intr_handle, queue_id); 466199a2dd95SBruce Richardson rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data); 466299a2dd95SBruce Richardson if (rc && rc != -EEXIST) { 466399a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 466409fd4227SAndrew Rybchenko "p %u q %u Rx ctl error op %d epfd %d vec %u\n", 466599a2dd95SBruce Richardson port_id, queue_id, op, epfd, vec); 466699a2dd95SBruce Richardson return rc; 466799a2dd95SBruce Richardson } 466899a2dd95SBruce Richardson 466999a2dd95SBruce Richardson return 0; 467099a2dd95SBruce Richardson } 467199a2dd95SBruce Richardson 467299a2dd95SBruce Richardson int 467399a2dd95SBruce Richardson rte_eth_dev_rx_intr_enable(uint16_t port_id, 467499a2dd95SBruce Richardson uint16_t queue_id) 467599a2dd95SBruce Richardson { 467699a2dd95SBruce Richardson struct rte_eth_dev *dev; 467799a2dd95SBruce Richardson int ret; 467899a2dd95SBruce Richardson 467999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 468099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 468199a2dd95SBruce Richardson 468299a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, queue_id); 468399a2dd95SBruce Richardson if (ret != 0) 468499a2dd95SBruce Richardson return ret; 468599a2dd95SBruce Richardson 468699a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_enable, -ENOTSUP); 468753ef1b34SMin Hu (Connor) return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_enable)(dev, queue_id)); 468899a2dd95SBruce Richardson } 468999a2dd95SBruce Richardson 469099a2dd95SBruce Richardson int 469199a2dd95SBruce Richardson rte_eth_dev_rx_intr_disable(uint16_t port_id, 469299a2dd95SBruce Richardson uint16_t queue_id) 469399a2dd95SBruce Richardson { 469499a2dd95SBruce Richardson struct rte_eth_dev *dev; 469599a2dd95SBruce Richardson int ret; 469699a2dd95SBruce Richardson 469799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 469899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 469999a2dd95SBruce Richardson 470099a2dd95SBruce Richardson ret = eth_dev_validate_rx_queue(dev, queue_id); 470199a2dd95SBruce Richardson if (ret != 0) 470299a2dd95SBruce Richardson return ret; 470399a2dd95SBruce Richardson 470499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_disable, -ENOTSUP); 470553ef1b34SMin Hu (Connor) return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_disable)(dev, queue_id)); 470699a2dd95SBruce Richardson } 470799a2dd95SBruce Richardson 470899a2dd95SBruce Richardson 470999a2dd95SBruce Richardson const struct rte_eth_rxtx_callback * 471099a2dd95SBruce Richardson rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id, 471199a2dd95SBruce Richardson rte_rx_callback_fn fn, void *user_param) 471299a2dd95SBruce Richardson { 471399a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 471499a2dd95SBruce Richardson rte_errno = ENOTSUP; 471599a2dd95SBruce Richardson return NULL; 471699a2dd95SBruce Richardson #endif 471799a2dd95SBruce Richardson struct rte_eth_dev *dev; 471899a2dd95SBruce Richardson 471999a2dd95SBruce Richardson /* check input parameters */ 472099a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 472199a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) { 472299a2dd95SBruce Richardson rte_errno = EINVAL; 472399a2dd95SBruce Richardson return NULL; 472499a2dd95SBruce Richardson } 472599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 472699a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) { 472799a2dd95SBruce Richardson rte_errno = EINVAL; 472899a2dd95SBruce Richardson return NULL; 472999a2dd95SBruce Richardson } 473099a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 473199a2dd95SBruce Richardson 473299a2dd95SBruce Richardson if (cb == NULL) { 473399a2dd95SBruce Richardson rte_errno = ENOMEM; 473499a2dd95SBruce Richardson return NULL; 473599a2dd95SBruce Richardson } 473699a2dd95SBruce Richardson 473799a2dd95SBruce Richardson cb->fn.rx = fn; 473899a2dd95SBruce Richardson cb->param = user_param; 473999a2dd95SBruce Richardson 474099a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_rx_cb_lock); 474199a2dd95SBruce Richardson /* Add the callbacks in fifo order. */ 474299a2dd95SBruce Richardson struct rte_eth_rxtx_callback *tail = 474399a2dd95SBruce Richardson rte_eth_devices[port_id].post_rx_burst_cbs[queue_id]; 474499a2dd95SBruce Richardson 474599a2dd95SBruce Richardson if (!tail) { 474699a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 474799a2dd95SBruce Richardson * cb is visible to data plane. 474899a2dd95SBruce Richardson */ 474999a2dd95SBruce Richardson __atomic_store_n( 475099a2dd95SBruce Richardson &rte_eth_devices[port_id].post_rx_burst_cbs[queue_id], 475199a2dd95SBruce Richardson cb, __ATOMIC_RELEASE); 475299a2dd95SBruce Richardson 475399a2dd95SBruce Richardson } else { 475499a2dd95SBruce Richardson while (tail->next) 475599a2dd95SBruce Richardson tail = tail->next; 475699a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 475799a2dd95SBruce Richardson * cb is visible to data plane. 475899a2dd95SBruce Richardson */ 475999a2dd95SBruce Richardson __atomic_store_n(&tail->next, cb, __ATOMIC_RELEASE); 476099a2dd95SBruce Richardson } 476199a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_rx_cb_lock); 476299a2dd95SBruce Richardson 476399a2dd95SBruce Richardson return cb; 476499a2dd95SBruce Richardson } 476599a2dd95SBruce Richardson 476699a2dd95SBruce Richardson const struct rte_eth_rxtx_callback * 476799a2dd95SBruce Richardson rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id, 476899a2dd95SBruce Richardson rte_rx_callback_fn fn, void *user_param) 476999a2dd95SBruce Richardson { 477099a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 477199a2dd95SBruce Richardson rte_errno = ENOTSUP; 477299a2dd95SBruce Richardson return NULL; 477399a2dd95SBruce Richardson #endif 477499a2dd95SBruce Richardson /* check input parameters */ 477599a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 477699a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) { 477799a2dd95SBruce Richardson rte_errno = EINVAL; 477899a2dd95SBruce Richardson return NULL; 477999a2dd95SBruce Richardson } 478099a2dd95SBruce Richardson 478199a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 478299a2dd95SBruce Richardson 478399a2dd95SBruce Richardson if (cb == NULL) { 478499a2dd95SBruce Richardson rte_errno = ENOMEM; 478599a2dd95SBruce Richardson return NULL; 478699a2dd95SBruce Richardson } 478799a2dd95SBruce Richardson 478899a2dd95SBruce Richardson cb->fn.rx = fn; 478999a2dd95SBruce Richardson cb->param = user_param; 479099a2dd95SBruce Richardson 479199a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_rx_cb_lock); 479299a2dd95SBruce Richardson /* Add the callbacks at first position */ 479399a2dd95SBruce Richardson cb->next = rte_eth_devices[port_id].post_rx_burst_cbs[queue_id]; 479499a2dd95SBruce Richardson /* Stores to cb->fn, cb->param and cb->next should complete before 479599a2dd95SBruce Richardson * cb is visible to data plane threads. 479699a2dd95SBruce Richardson */ 479799a2dd95SBruce Richardson __atomic_store_n( 479899a2dd95SBruce Richardson &rte_eth_devices[port_id].post_rx_burst_cbs[queue_id], 479999a2dd95SBruce Richardson cb, __ATOMIC_RELEASE); 480099a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_rx_cb_lock); 480199a2dd95SBruce Richardson 480299a2dd95SBruce Richardson return cb; 480399a2dd95SBruce Richardson } 480499a2dd95SBruce Richardson 480599a2dd95SBruce Richardson const struct rte_eth_rxtx_callback * 480699a2dd95SBruce Richardson rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id, 480799a2dd95SBruce Richardson rte_tx_callback_fn fn, void *user_param) 480899a2dd95SBruce Richardson { 480999a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 481099a2dd95SBruce Richardson rte_errno = ENOTSUP; 481199a2dd95SBruce Richardson return NULL; 481299a2dd95SBruce Richardson #endif 481399a2dd95SBruce Richardson struct rte_eth_dev *dev; 481499a2dd95SBruce Richardson 481599a2dd95SBruce Richardson /* check input parameters */ 481699a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 481799a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) { 481899a2dd95SBruce Richardson rte_errno = EINVAL; 481999a2dd95SBruce Richardson return NULL; 482099a2dd95SBruce Richardson } 482199a2dd95SBruce Richardson 482299a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 482399a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) { 482499a2dd95SBruce Richardson rte_errno = EINVAL; 482599a2dd95SBruce Richardson return NULL; 482699a2dd95SBruce Richardson } 482799a2dd95SBruce Richardson 482899a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 482999a2dd95SBruce Richardson 483099a2dd95SBruce Richardson if (cb == NULL) { 483199a2dd95SBruce Richardson rte_errno = ENOMEM; 483299a2dd95SBruce Richardson return NULL; 483399a2dd95SBruce Richardson } 483499a2dd95SBruce Richardson 483599a2dd95SBruce Richardson cb->fn.tx = fn; 483699a2dd95SBruce Richardson cb->param = user_param; 483799a2dd95SBruce Richardson 483899a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_tx_cb_lock); 483999a2dd95SBruce Richardson /* Add the callbacks in fifo order. */ 484099a2dd95SBruce Richardson struct rte_eth_rxtx_callback *tail = 484199a2dd95SBruce Richardson rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id]; 484299a2dd95SBruce Richardson 484399a2dd95SBruce Richardson if (!tail) { 484499a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 484599a2dd95SBruce Richardson * cb is visible to data plane. 484699a2dd95SBruce Richardson */ 484799a2dd95SBruce Richardson __atomic_store_n( 484899a2dd95SBruce Richardson &rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id], 484999a2dd95SBruce Richardson cb, __ATOMIC_RELEASE); 485099a2dd95SBruce Richardson 485199a2dd95SBruce Richardson } else { 485299a2dd95SBruce Richardson while (tail->next) 485399a2dd95SBruce Richardson tail = tail->next; 485499a2dd95SBruce Richardson /* Stores to cb->fn and cb->param should complete before 485599a2dd95SBruce Richardson * cb is visible to data plane. 485699a2dd95SBruce Richardson */ 485799a2dd95SBruce Richardson __atomic_store_n(&tail->next, cb, __ATOMIC_RELEASE); 485899a2dd95SBruce Richardson } 485999a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_tx_cb_lock); 486099a2dd95SBruce Richardson 486199a2dd95SBruce Richardson return cb; 486299a2dd95SBruce Richardson } 486399a2dd95SBruce Richardson 486499a2dd95SBruce Richardson int 486599a2dd95SBruce Richardson rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id, 486699a2dd95SBruce Richardson const struct rte_eth_rxtx_callback *user_cb) 486799a2dd95SBruce Richardson { 486899a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 486999a2dd95SBruce Richardson return -ENOTSUP; 487099a2dd95SBruce Richardson #endif 487199a2dd95SBruce Richardson /* Check input parameters. */ 487299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 487399a2dd95SBruce Richardson if (user_cb == NULL || 487499a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) 487599a2dd95SBruce Richardson return -EINVAL; 487699a2dd95SBruce Richardson 487799a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 487899a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb; 487999a2dd95SBruce Richardson struct rte_eth_rxtx_callback **prev_cb; 488099a2dd95SBruce Richardson int ret = -EINVAL; 488199a2dd95SBruce Richardson 488299a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_rx_cb_lock); 488399a2dd95SBruce Richardson prev_cb = &dev->post_rx_burst_cbs[queue_id]; 488499a2dd95SBruce Richardson for (; *prev_cb != NULL; prev_cb = &cb->next) { 488599a2dd95SBruce Richardson cb = *prev_cb; 488699a2dd95SBruce Richardson if (cb == user_cb) { 488799a2dd95SBruce Richardson /* Remove the user cb from the callback list. */ 488899a2dd95SBruce Richardson __atomic_store_n(prev_cb, cb->next, __ATOMIC_RELAXED); 488999a2dd95SBruce Richardson ret = 0; 489099a2dd95SBruce Richardson break; 489199a2dd95SBruce Richardson } 489299a2dd95SBruce Richardson } 489399a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_rx_cb_lock); 489499a2dd95SBruce Richardson 489599a2dd95SBruce Richardson return ret; 489699a2dd95SBruce Richardson } 489799a2dd95SBruce Richardson 489899a2dd95SBruce Richardson int 489999a2dd95SBruce Richardson rte_eth_remove_tx_callback(uint16_t port_id, uint16_t queue_id, 490099a2dd95SBruce Richardson const struct rte_eth_rxtx_callback *user_cb) 490199a2dd95SBruce Richardson { 490299a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS 490399a2dd95SBruce Richardson return -ENOTSUP; 490499a2dd95SBruce Richardson #endif 490599a2dd95SBruce Richardson /* Check input parameters. */ 490699a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 490799a2dd95SBruce Richardson if (user_cb == NULL || 490899a2dd95SBruce Richardson queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) 490999a2dd95SBruce Richardson return -EINVAL; 491099a2dd95SBruce Richardson 491199a2dd95SBruce Richardson struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 491299a2dd95SBruce Richardson int ret = -EINVAL; 491399a2dd95SBruce Richardson struct rte_eth_rxtx_callback *cb; 491499a2dd95SBruce Richardson struct rte_eth_rxtx_callback **prev_cb; 491599a2dd95SBruce Richardson 491699a2dd95SBruce Richardson rte_spinlock_lock(ð_dev_tx_cb_lock); 491799a2dd95SBruce Richardson prev_cb = &dev->pre_tx_burst_cbs[queue_id]; 491899a2dd95SBruce Richardson for (; *prev_cb != NULL; prev_cb = &cb->next) { 491999a2dd95SBruce Richardson cb = *prev_cb; 492099a2dd95SBruce Richardson if (cb == user_cb) { 492199a2dd95SBruce Richardson /* Remove the user cb from the callback list. */ 492299a2dd95SBruce Richardson __atomic_store_n(prev_cb, cb->next, __ATOMIC_RELAXED); 492399a2dd95SBruce Richardson ret = 0; 492499a2dd95SBruce Richardson break; 492599a2dd95SBruce Richardson } 492699a2dd95SBruce Richardson } 492799a2dd95SBruce Richardson rte_spinlock_unlock(ð_dev_tx_cb_lock); 492899a2dd95SBruce Richardson 492999a2dd95SBruce Richardson return ret; 493099a2dd95SBruce Richardson } 493199a2dd95SBruce Richardson 493299a2dd95SBruce Richardson int 493399a2dd95SBruce Richardson rte_eth_rx_queue_info_get(uint16_t port_id, uint16_t queue_id, 493499a2dd95SBruce Richardson struct rte_eth_rxq_info *qinfo) 493599a2dd95SBruce Richardson { 493699a2dd95SBruce Richardson struct rte_eth_dev *dev; 493799a2dd95SBruce Richardson 493899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 493999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 494053ef1b34SMin Hu (Connor) 494199a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 494209fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id); 494399a2dd95SBruce Richardson return -EINVAL; 494499a2dd95SBruce Richardson } 494599a2dd95SBruce Richardson 494653ef1b34SMin Hu (Connor) if (qinfo == NULL) { 494753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u Rx queue %u info to NULL\n", 494853ef1b34SMin Hu (Connor) port_id, queue_id); 494953ef1b34SMin Hu (Connor) return -EINVAL; 495053ef1b34SMin Hu (Connor) } 495153ef1b34SMin Hu (Connor) 495299a2dd95SBruce Richardson if (dev->data->rx_queues == NULL || 495399a2dd95SBruce Richardson dev->data->rx_queues[queue_id] == NULL) { 495499a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 495599a2dd95SBruce Richardson "Rx queue %"PRIu16" of device with port_id=%" 495699a2dd95SBruce Richardson PRIu16" has not been setup\n", 495799a2dd95SBruce Richardson queue_id, port_id); 495899a2dd95SBruce Richardson return -EINVAL; 495999a2dd95SBruce Richardson } 496099a2dd95SBruce Richardson 496199a2dd95SBruce Richardson if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) { 496299a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 496399a2dd95SBruce Richardson "Can't get hairpin Rx queue %"PRIu16" info of device with port_id=%"PRIu16"\n", 496499a2dd95SBruce Richardson queue_id, port_id); 496599a2dd95SBruce Richardson return -EINVAL; 496699a2dd95SBruce Richardson } 496799a2dd95SBruce Richardson 496899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rxq_info_get, -ENOTSUP); 496999a2dd95SBruce Richardson 497099a2dd95SBruce Richardson memset(qinfo, 0, sizeof(*qinfo)); 497199a2dd95SBruce Richardson dev->dev_ops->rxq_info_get(dev, queue_id, qinfo); 49729ad9ff47SLijun Ou qinfo->queue_state = dev->data->rx_queue_state[queue_id]; 49739ad9ff47SLijun Ou 497499a2dd95SBruce Richardson return 0; 497599a2dd95SBruce Richardson } 497699a2dd95SBruce Richardson 497799a2dd95SBruce Richardson int 497899a2dd95SBruce Richardson rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id, 497999a2dd95SBruce Richardson struct rte_eth_txq_info *qinfo) 498099a2dd95SBruce Richardson { 498199a2dd95SBruce Richardson struct rte_eth_dev *dev; 498299a2dd95SBruce Richardson 498399a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 498499a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 498553ef1b34SMin Hu (Connor) 498699a2dd95SBruce Richardson if (queue_id >= dev->data->nb_tx_queues) { 498709fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", queue_id); 498899a2dd95SBruce Richardson return -EINVAL; 498999a2dd95SBruce Richardson } 499099a2dd95SBruce Richardson 499153ef1b34SMin Hu (Connor) if (qinfo == NULL) { 499253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u Tx queue %u info to NULL\n", 499353ef1b34SMin Hu (Connor) port_id, queue_id); 499453ef1b34SMin Hu (Connor) return -EINVAL; 499553ef1b34SMin Hu (Connor) } 499653ef1b34SMin Hu (Connor) 499799a2dd95SBruce Richardson if (dev->data->tx_queues == NULL || 499899a2dd95SBruce Richardson dev->data->tx_queues[queue_id] == NULL) { 499999a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, 500099a2dd95SBruce Richardson "Tx queue %"PRIu16" of device with port_id=%" 500199a2dd95SBruce Richardson PRIu16" has not been setup\n", 500299a2dd95SBruce Richardson queue_id, port_id); 500399a2dd95SBruce Richardson return -EINVAL; 500499a2dd95SBruce Richardson } 500599a2dd95SBruce Richardson 500699a2dd95SBruce Richardson if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) { 500799a2dd95SBruce Richardson RTE_ETHDEV_LOG(INFO, 500899a2dd95SBruce Richardson "Can't get hairpin Tx queue %"PRIu16" info of device with port_id=%"PRIu16"\n", 500999a2dd95SBruce Richardson queue_id, port_id); 501099a2dd95SBruce Richardson return -EINVAL; 501199a2dd95SBruce Richardson } 501299a2dd95SBruce Richardson 501399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->txq_info_get, -ENOTSUP); 501499a2dd95SBruce Richardson 501599a2dd95SBruce Richardson memset(qinfo, 0, sizeof(*qinfo)); 501699a2dd95SBruce Richardson dev->dev_ops->txq_info_get(dev, queue_id, qinfo); 50179ad9ff47SLijun Ou qinfo->queue_state = dev->data->tx_queue_state[queue_id]; 501899a2dd95SBruce Richardson 501999a2dd95SBruce Richardson return 0; 502099a2dd95SBruce Richardson } 502199a2dd95SBruce Richardson 502299a2dd95SBruce Richardson int 502399a2dd95SBruce Richardson rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id, 502499a2dd95SBruce Richardson struct rte_eth_burst_mode *mode) 502599a2dd95SBruce Richardson { 502699a2dd95SBruce Richardson struct rte_eth_dev *dev; 502799a2dd95SBruce Richardson 502899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 502999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 503099a2dd95SBruce Richardson 503199a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 503209fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id); 503399a2dd95SBruce Richardson return -EINVAL; 503499a2dd95SBruce Richardson } 503599a2dd95SBruce Richardson 503653ef1b34SMin Hu (Connor) if (mode == NULL) { 503753ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 503853ef1b34SMin Hu (Connor) "Cannot get ethdev port %u Rx queue %u burst mode to NULL\n", 503953ef1b34SMin Hu (Connor) port_id, queue_id); 504053ef1b34SMin Hu (Connor) return -EINVAL; 504153ef1b34SMin Hu (Connor) } 504253ef1b34SMin Hu (Connor) 504399a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_burst_mode_get, -ENOTSUP); 504499a2dd95SBruce Richardson memset(mode, 0, sizeof(*mode)); 504599a2dd95SBruce Richardson return eth_err(port_id, 504699a2dd95SBruce Richardson dev->dev_ops->rx_burst_mode_get(dev, queue_id, mode)); 504799a2dd95SBruce Richardson } 504899a2dd95SBruce Richardson 504999a2dd95SBruce Richardson int 505099a2dd95SBruce Richardson rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id, 505199a2dd95SBruce Richardson struct rte_eth_burst_mode *mode) 505299a2dd95SBruce Richardson { 505399a2dd95SBruce Richardson struct rte_eth_dev *dev; 505499a2dd95SBruce Richardson 505599a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 505699a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 505799a2dd95SBruce Richardson 505899a2dd95SBruce Richardson if (queue_id >= dev->data->nb_tx_queues) { 505909fd4227SAndrew Rybchenko RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", queue_id); 506099a2dd95SBruce Richardson return -EINVAL; 506199a2dd95SBruce Richardson } 506299a2dd95SBruce Richardson 506353ef1b34SMin Hu (Connor) if (mode == NULL) { 506453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 506553ef1b34SMin Hu (Connor) "Cannot get ethdev port %u Tx queue %u burst mode to NULL\n", 506653ef1b34SMin Hu (Connor) port_id, queue_id); 506753ef1b34SMin Hu (Connor) return -EINVAL; 506853ef1b34SMin Hu (Connor) } 506953ef1b34SMin Hu (Connor) 507099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_burst_mode_get, -ENOTSUP); 507199a2dd95SBruce Richardson memset(mode, 0, sizeof(*mode)); 507299a2dd95SBruce Richardson return eth_err(port_id, 507399a2dd95SBruce Richardson dev->dev_ops->tx_burst_mode_get(dev, queue_id, mode)); 507499a2dd95SBruce Richardson } 507599a2dd95SBruce Richardson 507699a2dd95SBruce Richardson int 507799a2dd95SBruce Richardson rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id, 507899a2dd95SBruce Richardson struct rte_power_monitor_cond *pmc) 507999a2dd95SBruce Richardson { 508099a2dd95SBruce Richardson struct rte_eth_dev *dev; 508199a2dd95SBruce Richardson 508299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 508399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 508499a2dd95SBruce Richardson 508599a2dd95SBruce Richardson if (queue_id >= dev->data->nb_rx_queues) { 508699a2dd95SBruce Richardson RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id); 508799a2dd95SBruce Richardson return -EINVAL; 508899a2dd95SBruce Richardson } 508999a2dd95SBruce Richardson 509099a2dd95SBruce Richardson if (pmc == NULL) { 509153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 509253ef1b34SMin Hu (Connor) "Cannot get ethdev port %u Rx queue %u power monitor condition to NULL\n", 509353ef1b34SMin Hu (Connor) port_id, queue_id); 509499a2dd95SBruce Richardson return -EINVAL; 509599a2dd95SBruce Richardson } 509699a2dd95SBruce Richardson 509753ef1b34SMin Hu (Connor) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_monitor_addr, -ENOTSUP); 509899a2dd95SBruce Richardson return eth_err(port_id, 509953ef1b34SMin Hu (Connor) dev->dev_ops->get_monitor_addr(dev->data->rx_queues[queue_id], pmc)); 510099a2dd95SBruce Richardson } 510199a2dd95SBruce Richardson 510299a2dd95SBruce Richardson int 510399a2dd95SBruce Richardson rte_eth_dev_set_mc_addr_list(uint16_t port_id, 510499a2dd95SBruce Richardson struct rte_ether_addr *mc_addr_set, 510599a2dd95SBruce Richardson uint32_t nb_mc_addr) 510699a2dd95SBruce Richardson { 510799a2dd95SBruce Richardson struct rte_eth_dev *dev; 510899a2dd95SBruce Richardson 510999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 511099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 511153ef1b34SMin Hu (Connor) 511299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_mc_addr_list, -ENOTSUP); 511399a2dd95SBruce Richardson return eth_err(port_id, dev->dev_ops->set_mc_addr_list(dev, 511499a2dd95SBruce Richardson mc_addr_set, nb_mc_addr)); 511599a2dd95SBruce Richardson } 511699a2dd95SBruce Richardson 511799a2dd95SBruce Richardson int 511899a2dd95SBruce Richardson rte_eth_timesync_enable(uint16_t port_id) 511999a2dd95SBruce Richardson { 512099a2dd95SBruce Richardson struct rte_eth_dev *dev; 512199a2dd95SBruce Richardson 512299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 512399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 512499a2dd95SBruce Richardson 512599a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_enable, -ENOTSUP); 512699a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_enable)(dev)); 512799a2dd95SBruce Richardson } 512899a2dd95SBruce Richardson 512999a2dd95SBruce Richardson int 513099a2dd95SBruce Richardson rte_eth_timesync_disable(uint16_t port_id) 513199a2dd95SBruce Richardson { 513299a2dd95SBruce Richardson struct rte_eth_dev *dev; 513399a2dd95SBruce Richardson 513499a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 513599a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 513699a2dd95SBruce Richardson 513799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_disable, -ENOTSUP); 513899a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_disable)(dev)); 513999a2dd95SBruce Richardson } 514099a2dd95SBruce Richardson 514199a2dd95SBruce Richardson int 514299a2dd95SBruce Richardson rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp, 514399a2dd95SBruce Richardson uint32_t flags) 514499a2dd95SBruce Richardson { 514599a2dd95SBruce Richardson struct rte_eth_dev *dev; 514699a2dd95SBruce Richardson 514799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 514899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 514999a2dd95SBruce Richardson 515053ef1b34SMin Hu (Connor) if (timestamp == NULL) { 515153ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 515253ef1b34SMin Hu (Connor) "Cannot read ethdev port %u Rx timestamp to NULL\n", 515353ef1b34SMin Hu (Connor) port_id); 515453ef1b34SMin Hu (Connor) return -EINVAL; 515553ef1b34SMin Hu (Connor) } 515653ef1b34SMin Hu (Connor) 515799a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP); 515899a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp) 515999a2dd95SBruce Richardson (dev, timestamp, flags)); 516099a2dd95SBruce Richardson } 516199a2dd95SBruce Richardson 516299a2dd95SBruce Richardson int 516399a2dd95SBruce Richardson rte_eth_timesync_read_tx_timestamp(uint16_t port_id, 516499a2dd95SBruce Richardson struct timespec *timestamp) 516599a2dd95SBruce Richardson { 516699a2dd95SBruce Richardson struct rte_eth_dev *dev; 516799a2dd95SBruce Richardson 516899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 516999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 517099a2dd95SBruce Richardson 517153ef1b34SMin Hu (Connor) if (timestamp == NULL) { 517253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 517353ef1b34SMin Hu (Connor) "Cannot read ethdev port %u Tx timestamp to NULL\n", 517453ef1b34SMin Hu (Connor) port_id); 517553ef1b34SMin Hu (Connor) return -EINVAL; 517653ef1b34SMin Hu (Connor) } 517753ef1b34SMin Hu (Connor) 517899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP); 517999a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp) 518099a2dd95SBruce Richardson (dev, timestamp)); 518199a2dd95SBruce Richardson } 518299a2dd95SBruce Richardson 518399a2dd95SBruce Richardson int 518499a2dd95SBruce Richardson rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta) 518599a2dd95SBruce Richardson { 518699a2dd95SBruce Richardson struct rte_eth_dev *dev; 518799a2dd95SBruce Richardson 518899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 518999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 519099a2dd95SBruce Richardson 519199a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_adjust_time, -ENOTSUP); 519253ef1b34SMin Hu (Connor) return eth_err(port_id, (*dev->dev_ops->timesync_adjust_time)(dev, delta)); 519399a2dd95SBruce Richardson } 519499a2dd95SBruce Richardson 519599a2dd95SBruce Richardson int 519699a2dd95SBruce Richardson rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp) 519799a2dd95SBruce Richardson { 519899a2dd95SBruce Richardson struct rte_eth_dev *dev; 519999a2dd95SBruce Richardson 520099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 520199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 520299a2dd95SBruce Richardson 520353ef1b34SMin Hu (Connor) if (timestamp == NULL) { 520453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 520553ef1b34SMin Hu (Connor) "Cannot read ethdev port %u timesync time to NULL\n", 520653ef1b34SMin Hu (Connor) port_id); 520753ef1b34SMin Hu (Connor) return -EINVAL; 520853ef1b34SMin Hu (Connor) } 520953ef1b34SMin Hu (Connor) 521099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP); 521199a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev, 521299a2dd95SBruce Richardson timestamp)); 521399a2dd95SBruce Richardson } 521499a2dd95SBruce Richardson 521599a2dd95SBruce Richardson int 521699a2dd95SBruce Richardson rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp) 521799a2dd95SBruce Richardson { 521899a2dd95SBruce Richardson struct rte_eth_dev *dev; 521999a2dd95SBruce Richardson 522099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 522199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 522299a2dd95SBruce Richardson 522353ef1b34SMin Hu (Connor) if (timestamp == NULL) { 522453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 522553ef1b34SMin Hu (Connor) "Cannot write ethdev port %u timesync from NULL time\n", 522653ef1b34SMin Hu (Connor) port_id); 522753ef1b34SMin Hu (Connor) return -EINVAL; 522853ef1b34SMin Hu (Connor) } 522953ef1b34SMin Hu (Connor) 523099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP); 523199a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev, 523299a2dd95SBruce Richardson timestamp)); 523399a2dd95SBruce Richardson } 523499a2dd95SBruce Richardson 523599a2dd95SBruce Richardson int 523699a2dd95SBruce Richardson rte_eth_read_clock(uint16_t port_id, uint64_t *clock) 523799a2dd95SBruce Richardson { 523899a2dd95SBruce Richardson struct rte_eth_dev *dev; 523999a2dd95SBruce Richardson 524099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 524199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 524299a2dd95SBruce Richardson 524353ef1b34SMin Hu (Connor) if (clock == NULL) { 524453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Cannot read ethdev port %u clock to NULL\n", 524553ef1b34SMin Hu (Connor) port_id); 524653ef1b34SMin Hu (Connor) return -EINVAL; 524753ef1b34SMin Hu (Connor) } 524853ef1b34SMin Hu (Connor) 524999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP); 525099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock)); 525199a2dd95SBruce Richardson } 525299a2dd95SBruce Richardson 525399a2dd95SBruce Richardson int 525499a2dd95SBruce Richardson rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info) 525599a2dd95SBruce Richardson { 525699a2dd95SBruce Richardson struct rte_eth_dev *dev; 525799a2dd95SBruce Richardson 525899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 525999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 526053ef1b34SMin Hu (Connor) 526153ef1b34SMin Hu (Connor) if (info == NULL) { 526253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 526353ef1b34SMin Hu (Connor) "Cannot get ethdev port %u register info to NULL\n", 526453ef1b34SMin Hu (Connor) port_id); 526553ef1b34SMin Hu (Connor) return -EINVAL; 526653ef1b34SMin Hu (Connor) } 526753ef1b34SMin Hu (Connor) 526899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_reg, -ENOTSUP); 526999a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info)); 527099a2dd95SBruce Richardson } 527199a2dd95SBruce Richardson 527299a2dd95SBruce Richardson int 527399a2dd95SBruce Richardson rte_eth_dev_get_eeprom_length(uint16_t port_id) 527499a2dd95SBruce Richardson { 527599a2dd95SBruce Richardson struct rte_eth_dev *dev; 527699a2dd95SBruce Richardson 527799a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 527899a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 527953ef1b34SMin Hu (Connor) 528099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom_length, -ENOTSUP); 528199a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->get_eeprom_length)(dev)); 528299a2dd95SBruce Richardson } 528399a2dd95SBruce Richardson 528499a2dd95SBruce Richardson int 528599a2dd95SBruce Richardson rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) 528699a2dd95SBruce Richardson { 528799a2dd95SBruce Richardson struct rte_eth_dev *dev; 528899a2dd95SBruce Richardson 528999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 529099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 529153ef1b34SMin Hu (Connor) 529253ef1b34SMin Hu (Connor) if (info == NULL) { 529353ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 529453ef1b34SMin Hu (Connor) "Cannot get ethdev port %u EEPROM info to NULL\n", 529553ef1b34SMin Hu (Connor) port_id); 529653ef1b34SMin Hu (Connor) return -EINVAL; 529753ef1b34SMin Hu (Connor) } 529853ef1b34SMin Hu (Connor) 529999a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom, -ENOTSUP); 530099a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->get_eeprom)(dev, info)); 530199a2dd95SBruce Richardson } 530299a2dd95SBruce Richardson 530399a2dd95SBruce Richardson int 530499a2dd95SBruce Richardson rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) 530599a2dd95SBruce Richardson { 530699a2dd95SBruce Richardson struct rte_eth_dev *dev; 530799a2dd95SBruce Richardson 530899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 530999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 531053ef1b34SMin Hu (Connor) 531153ef1b34SMin Hu (Connor) if (info == NULL) { 531253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 531353ef1b34SMin Hu (Connor) "Cannot set ethdev port %u EEPROM from NULL info\n", 531453ef1b34SMin Hu (Connor) port_id); 531553ef1b34SMin Hu (Connor) return -EINVAL; 531653ef1b34SMin Hu (Connor) } 531753ef1b34SMin Hu (Connor) 531899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_eeprom, -ENOTSUP); 531999a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->set_eeprom)(dev, info)); 532099a2dd95SBruce Richardson } 532199a2dd95SBruce Richardson 532299a2dd95SBruce Richardson int 532399a2dd95SBruce Richardson rte_eth_dev_get_module_info(uint16_t port_id, 532499a2dd95SBruce Richardson struct rte_eth_dev_module_info *modinfo) 532599a2dd95SBruce Richardson { 532699a2dd95SBruce Richardson struct rte_eth_dev *dev; 532799a2dd95SBruce Richardson 532899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 532999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 533053ef1b34SMin Hu (Connor) 533153ef1b34SMin Hu (Connor) if (modinfo == NULL) { 533253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 533353ef1b34SMin Hu (Connor) "Cannot get ethdev port %u EEPROM module info to NULL\n", 533453ef1b34SMin Hu (Connor) port_id); 533553ef1b34SMin Hu (Connor) return -EINVAL; 533653ef1b34SMin Hu (Connor) } 533753ef1b34SMin Hu (Connor) 533899a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_info, -ENOTSUP); 533999a2dd95SBruce Richardson return (*dev->dev_ops->get_module_info)(dev, modinfo); 534099a2dd95SBruce Richardson } 534199a2dd95SBruce Richardson 534299a2dd95SBruce Richardson int 534399a2dd95SBruce Richardson rte_eth_dev_get_module_eeprom(uint16_t port_id, 534499a2dd95SBruce Richardson struct rte_dev_eeprom_info *info) 534599a2dd95SBruce Richardson { 534699a2dd95SBruce Richardson struct rte_eth_dev *dev; 534799a2dd95SBruce Richardson 534899a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 534999a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 535053ef1b34SMin Hu (Connor) 535153ef1b34SMin Hu (Connor) if (info == NULL) { 535253ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 535353ef1b34SMin Hu (Connor) "Cannot get ethdev port %u module EEPROM info to NULL\n", 535453ef1b34SMin Hu (Connor) port_id); 535553ef1b34SMin Hu (Connor) return -EINVAL; 535653ef1b34SMin Hu (Connor) } 535753ef1b34SMin Hu (Connor) 535853ef1b34SMin Hu (Connor) if (info->data == NULL) { 535953ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 536053ef1b34SMin Hu (Connor) "Cannot get ethdev port %u module EEPROM data to NULL\n", 536153ef1b34SMin Hu (Connor) port_id); 536253ef1b34SMin Hu (Connor) return -EINVAL; 536353ef1b34SMin Hu (Connor) } 536453ef1b34SMin Hu (Connor) 536553ef1b34SMin Hu (Connor) if (info->length == 0) { 536653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 536753ef1b34SMin Hu (Connor) "Cannot get ethdev port %u module EEPROM to data with zero size\n", 536853ef1b34SMin Hu (Connor) port_id); 536953ef1b34SMin Hu (Connor) return -EINVAL; 537053ef1b34SMin Hu (Connor) } 537153ef1b34SMin Hu (Connor) 537299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_eeprom, -ENOTSUP); 537399a2dd95SBruce Richardson return (*dev->dev_ops->get_module_eeprom)(dev, info); 537499a2dd95SBruce Richardson } 537599a2dd95SBruce Richardson 537699a2dd95SBruce Richardson int 537799a2dd95SBruce Richardson rte_eth_dev_get_dcb_info(uint16_t port_id, 537899a2dd95SBruce Richardson struct rte_eth_dcb_info *dcb_info) 537999a2dd95SBruce Richardson { 538099a2dd95SBruce Richardson struct rte_eth_dev *dev; 538199a2dd95SBruce Richardson 538299a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 538399a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 538453ef1b34SMin Hu (Connor) 538553ef1b34SMin Hu (Connor) if (dcb_info == NULL) { 538653ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 538753ef1b34SMin Hu (Connor) "Cannot get ethdev port %u DCB info to NULL\n", 538853ef1b34SMin Hu (Connor) port_id); 538953ef1b34SMin Hu (Connor) return -EINVAL; 539053ef1b34SMin Hu (Connor) } 539153ef1b34SMin Hu (Connor) 539299a2dd95SBruce Richardson memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info)); 539399a2dd95SBruce Richardson 539499a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_dcb_info, -ENOTSUP); 539599a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->get_dcb_info)(dev, dcb_info)); 539699a2dd95SBruce Richardson } 539799a2dd95SBruce Richardson 539899a2dd95SBruce Richardson static void 539999a2dd95SBruce Richardson eth_dev_adjust_nb_desc(uint16_t *nb_desc, 540099a2dd95SBruce Richardson const struct rte_eth_desc_lim *desc_lim) 540199a2dd95SBruce Richardson { 540299a2dd95SBruce Richardson if (desc_lim->nb_align != 0) 540399a2dd95SBruce Richardson *nb_desc = RTE_ALIGN_CEIL(*nb_desc, desc_lim->nb_align); 540499a2dd95SBruce Richardson 540599a2dd95SBruce Richardson if (desc_lim->nb_max != 0) 540699a2dd95SBruce Richardson *nb_desc = RTE_MIN(*nb_desc, desc_lim->nb_max); 540799a2dd95SBruce Richardson 540899a2dd95SBruce Richardson *nb_desc = RTE_MAX(*nb_desc, desc_lim->nb_min); 540999a2dd95SBruce Richardson } 541099a2dd95SBruce Richardson 541199a2dd95SBruce Richardson int 541299a2dd95SBruce Richardson rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id, 541399a2dd95SBruce Richardson uint16_t *nb_rx_desc, 541499a2dd95SBruce Richardson uint16_t *nb_tx_desc) 541599a2dd95SBruce Richardson { 541699a2dd95SBruce Richardson struct rte_eth_dev_info dev_info; 541799a2dd95SBruce Richardson int ret; 541899a2dd95SBruce Richardson 541999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 542099a2dd95SBruce Richardson 542199a2dd95SBruce Richardson ret = rte_eth_dev_info_get(port_id, &dev_info); 542299a2dd95SBruce Richardson if (ret != 0) 542399a2dd95SBruce Richardson return ret; 542499a2dd95SBruce Richardson 542599a2dd95SBruce Richardson if (nb_rx_desc != NULL) 542699a2dd95SBruce Richardson eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim); 542799a2dd95SBruce Richardson 542899a2dd95SBruce Richardson if (nb_tx_desc != NULL) 542999a2dd95SBruce Richardson eth_dev_adjust_nb_desc(nb_tx_desc, &dev_info.tx_desc_lim); 543099a2dd95SBruce Richardson 543199a2dd95SBruce Richardson return 0; 543299a2dd95SBruce Richardson } 543399a2dd95SBruce Richardson 543499a2dd95SBruce Richardson int 543599a2dd95SBruce Richardson rte_eth_dev_hairpin_capability_get(uint16_t port_id, 543699a2dd95SBruce Richardson struct rte_eth_hairpin_cap *cap) 543799a2dd95SBruce Richardson { 543899a2dd95SBruce Richardson struct rte_eth_dev *dev; 543999a2dd95SBruce Richardson 544099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 544199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 544253ef1b34SMin Hu (Connor) 544353ef1b34SMin Hu (Connor) if (cap == NULL) { 544453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 544553ef1b34SMin Hu (Connor) "Cannot get ethdev port %u hairpin capability to NULL\n", 544653ef1b34SMin Hu (Connor) port_id); 544753ef1b34SMin Hu (Connor) return -EINVAL; 544853ef1b34SMin Hu (Connor) } 544953ef1b34SMin Hu (Connor) 545099a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP); 545199a2dd95SBruce Richardson memset(cap, 0, sizeof(*cap)); 545299a2dd95SBruce Richardson return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap)); 545399a2dd95SBruce Richardson } 545499a2dd95SBruce Richardson 545599a2dd95SBruce Richardson int 545699a2dd95SBruce Richardson rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) 545799a2dd95SBruce Richardson { 545899a2dd95SBruce Richardson struct rte_eth_dev *dev; 545999a2dd95SBruce Richardson 546099a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 546199a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 546299a2dd95SBruce Richardson 546353ef1b34SMin Hu (Connor) if (pool == NULL) { 546453ef1b34SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, 546553ef1b34SMin Hu (Connor) "Cannot test ethdev port %u mempool operation from NULL pool\n", 546653ef1b34SMin Hu (Connor) port_id); 546753ef1b34SMin Hu (Connor) return -EINVAL; 546853ef1b34SMin Hu (Connor) } 546953ef1b34SMin Hu (Connor) 547099a2dd95SBruce Richardson if (*dev->dev_ops->pool_ops_supported == NULL) 547199a2dd95SBruce Richardson return 1; /* all pools are supported */ 547299a2dd95SBruce Richardson 547399a2dd95SBruce Richardson return (*dev->dev_ops->pool_ops_supported)(dev, pool); 547499a2dd95SBruce Richardson } 547599a2dd95SBruce Richardson 547699a2dd95SBruce Richardson static int 547799a2dd95SBruce Richardson eth_dev_handle_port_list(const char *cmd __rte_unused, 547899a2dd95SBruce Richardson const char *params __rte_unused, 547999a2dd95SBruce Richardson struct rte_tel_data *d) 548099a2dd95SBruce Richardson { 548199a2dd95SBruce Richardson int port_id; 548299a2dd95SBruce Richardson 548399a2dd95SBruce Richardson rte_tel_data_start_array(d, RTE_TEL_INT_VAL); 548499a2dd95SBruce Richardson RTE_ETH_FOREACH_DEV(port_id) 548599a2dd95SBruce Richardson rte_tel_data_add_array_int(d, port_id); 548699a2dd95SBruce Richardson return 0; 548799a2dd95SBruce Richardson } 548899a2dd95SBruce Richardson 548999a2dd95SBruce Richardson static void 549099a2dd95SBruce Richardson eth_dev_add_port_queue_stats(struct rte_tel_data *d, uint64_t *q_stats, 549199a2dd95SBruce Richardson const char *stat_name) 549299a2dd95SBruce Richardson { 549399a2dd95SBruce Richardson int q; 549499a2dd95SBruce Richardson struct rte_tel_data *q_data = rte_tel_data_alloc(); 549599a2dd95SBruce Richardson rte_tel_data_start_array(q_data, RTE_TEL_U64_VAL); 549699a2dd95SBruce Richardson for (q = 0; q < RTE_ETHDEV_QUEUE_STAT_CNTRS; q++) 549799a2dd95SBruce Richardson rte_tel_data_add_array_u64(q_data, q_stats[q]); 549899a2dd95SBruce Richardson rte_tel_data_add_dict_container(d, stat_name, q_data, 0); 549999a2dd95SBruce Richardson } 550099a2dd95SBruce Richardson 550199a2dd95SBruce Richardson #define ADD_DICT_STAT(stats, s) rte_tel_data_add_dict_u64(d, #s, stats.s) 550299a2dd95SBruce Richardson 550399a2dd95SBruce Richardson static int 550499a2dd95SBruce Richardson eth_dev_handle_port_stats(const char *cmd __rte_unused, 550599a2dd95SBruce Richardson const char *params, 550699a2dd95SBruce Richardson struct rte_tel_data *d) 550799a2dd95SBruce Richardson { 550899a2dd95SBruce Richardson struct rte_eth_stats stats; 550999a2dd95SBruce Richardson int port_id, ret; 551099a2dd95SBruce Richardson 551199a2dd95SBruce Richardson if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 551299a2dd95SBruce Richardson return -1; 551399a2dd95SBruce Richardson 551499a2dd95SBruce Richardson port_id = atoi(params); 551599a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id)) 551699a2dd95SBruce Richardson return -1; 551799a2dd95SBruce Richardson 551899a2dd95SBruce Richardson ret = rte_eth_stats_get(port_id, &stats); 551999a2dd95SBruce Richardson if (ret < 0) 552099a2dd95SBruce Richardson return -1; 552199a2dd95SBruce Richardson 552299a2dd95SBruce Richardson rte_tel_data_start_dict(d); 552399a2dd95SBruce Richardson ADD_DICT_STAT(stats, ipackets); 552499a2dd95SBruce Richardson ADD_DICT_STAT(stats, opackets); 552599a2dd95SBruce Richardson ADD_DICT_STAT(stats, ibytes); 552699a2dd95SBruce Richardson ADD_DICT_STAT(stats, obytes); 552799a2dd95SBruce Richardson ADD_DICT_STAT(stats, imissed); 552899a2dd95SBruce Richardson ADD_DICT_STAT(stats, ierrors); 552999a2dd95SBruce Richardson ADD_DICT_STAT(stats, oerrors); 553099a2dd95SBruce Richardson ADD_DICT_STAT(stats, rx_nombuf); 553199a2dd95SBruce Richardson eth_dev_add_port_queue_stats(d, stats.q_ipackets, "q_ipackets"); 553299a2dd95SBruce Richardson eth_dev_add_port_queue_stats(d, stats.q_opackets, "q_opackets"); 553399a2dd95SBruce Richardson eth_dev_add_port_queue_stats(d, stats.q_ibytes, "q_ibytes"); 553499a2dd95SBruce Richardson eth_dev_add_port_queue_stats(d, stats.q_obytes, "q_obytes"); 553599a2dd95SBruce Richardson eth_dev_add_port_queue_stats(d, stats.q_errors, "q_errors"); 553699a2dd95SBruce Richardson 553799a2dd95SBruce Richardson return 0; 553899a2dd95SBruce Richardson } 553999a2dd95SBruce Richardson 554099a2dd95SBruce Richardson static int 554199a2dd95SBruce Richardson eth_dev_handle_port_xstats(const char *cmd __rte_unused, 554299a2dd95SBruce Richardson const char *params, 554399a2dd95SBruce Richardson struct rte_tel_data *d) 554499a2dd95SBruce Richardson { 554599a2dd95SBruce Richardson struct rte_eth_xstat *eth_xstats; 554699a2dd95SBruce Richardson struct rte_eth_xstat_name *xstat_names; 554799a2dd95SBruce Richardson int port_id, num_xstats; 554899a2dd95SBruce Richardson int i, ret; 554999a2dd95SBruce Richardson char *end_param; 555099a2dd95SBruce Richardson 555199a2dd95SBruce Richardson if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 555299a2dd95SBruce Richardson return -1; 555399a2dd95SBruce Richardson 555499a2dd95SBruce Richardson port_id = strtoul(params, &end_param, 0); 555599a2dd95SBruce Richardson if (*end_param != '\0') 555699a2dd95SBruce Richardson RTE_ETHDEV_LOG(NOTICE, 555799a2dd95SBruce Richardson "Extra parameters passed to ethdev telemetry command, ignoring"); 555899a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id)) 555999a2dd95SBruce Richardson return -1; 556099a2dd95SBruce Richardson 556199a2dd95SBruce Richardson num_xstats = rte_eth_xstats_get(port_id, NULL, 0); 556299a2dd95SBruce Richardson if (num_xstats < 0) 556399a2dd95SBruce Richardson return -1; 556499a2dd95SBruce Richardson 556599a2dd95SBruce Richardson /* use one malloc for both names and stats */ 556699a2dd95SBruce Richardson eth_xstats = malloc((sizeof(struct rte_eth_xstat) + 556799a2dd95SBruce Richardson sizeof(struct rte_eth_xstat_name)) * num_xstats); 556899a2dd95SBruce Richardson if (eth_xstats == NULL) 556999a2dd95SBruce Richardson return -1; 557099a2dd95SBruce Richardson xstat_names = (void *)ð_xstats[num_xstats]; 557199a2dd95SBruce Richardson 557299a2dd95SBruce Richardson ret = rte_eth_xstats_get_names(port_id, xstat_names, num_xstats); 557399a2dd95SBruce Richardson if (ret < 0 || ret > num_xstats) { 557499a2dd95SBruce Richardson free(eth_xstats); 557599a2dd95SBruce Richardson return -1; 557699a2dd95SBruce Richardson } 557799a2dd95SBruce Richardson 557899a2dd95SBruce Richardson ret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats); 557999a2dd95SBruce Richardson if (ret < 0 || ret > num_xstats) { 558099a2dd95SBruce Richardson free(eth_xstats); 558199a2dd95SBruce Richardson return -1; 558299a2dd95SBruce Richardson } 558399a2dd95SBruce Richardson 558499a2dd95SBruce Richardson rte_tel_data_start_dict(d); 558599a2dd95SBruce Richardson for (i = 0; i < num_xstats; i++) 558699a2dd95SBruce Richardson rte_tel_data_add_dict_u64(d, xstat_names[i].name, 558799a2dd95SBruce Richardson eth_xstats[i].value); 558899a2dd95SBruce Richardson return 0; 558999a2dd95SBruce Richardson } 559099a2dd95SBruce Richardson 559199a2dd95SBruce Richardson static int 559299a2dd95SBruce Richardson eth_dev_handle_port_link_status(const char *cmd __rte_unused, 559399a2dd95SBruce Richardson const char *params, 559499a2dd95SBruce Richardson struct rte_tel_data *d) 559599a2dd95SBruce Richardson { 559699a2dd95SBruce Richardson static const char *status_str = "status"; 559799a2dd95SBruce Richardson int ret, port_id; 559899a2dd95SBruce Richardson struct rte_eth_link link; 559999a2dd95SBruce Richardson char *end_param; 560099a2dd95SBruce Richardson 560199a2dd95SBruce Richardson if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 560299a2dd95SBruce Richardson return -1; 560399a2dd95SBruce Richardson 560499a2dd95SBruce Richardson port_id = strtoul(params, &end_param, 0); 560599a2dd95SBruce Richardson if (*end_param != '\0') 560699a2dd95SBruce Richardson RTE_ETHDEV_LOG(NOTICE, 560799a2dd95SBruce Richardson "Extra parameters passed to ethdev telemetry command, ignoring"); 560899a2dd95SBruce Richardson if (!rte_eth_dev_is_valid_port(port_id)) 560999a2dd95SBruce Richardson return -1; 561099a2dd95SBruce Richardson 561199a2dd95SBruce Richardson ret = rte_eth_link_get_nowait(port_id, &link); 561299a2dd95SBruce Richardson if (ret < 0) 561399a2dd95SBruce Richardson return -1; 561499a2dd95SBruce Richardson 561599a2dd95SBruce Richardson rte_tel_data_start_dict(d); 561699a2dd95SBruce Richardson if (!link.link_status) { 561799a2dd95SBruce Richardson rte_tel_data_add_dict_string(d, status_str, "DOWN"); 561899a2dd95SBruce Richardson return 0; 561999a2dd95SBruce Richardson } 562099a2dd95SBruce Richardson rte_tel_data_add_dict_string(d, status_str, "UP"); 562199a2dd95SBruce Richardson rte_tel_data_add_dict_u64(d, "speed", link.link_speed); 562299a2dd95SBruce Richardson rte_tel_data_add_dict_string(d, "duplex", 5623295968d1SFerruh Yigit (link.link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ? 562499a2dd95SBruce Richardson "full-duplex" : "half-duplex"); 562599a2dd95SBruce Richardson return 0; 562699a2dd95SBruce Richardson } 562799a2dd95SBruce Richardson 562858b43c1dSGowrishankar Muthukrishnan static int 562958b43c1dSGowrishankar Muthukrishnan eth_dev_handle_port_info(const char *cmd __rte_unused, 563058b43c1dSGowrishankar Muthukrishnan const char *params, 563158b43c1dSGowrishankar Muthukrishnan struct rte_tel_data *d) 563258b43c1dSGowrishankar Muthukrishnan { 563358b43c1dSGowrishankar Muthukrishnan struct rte_tel_data *rxq_state, *txq_state; 5634*ffe77e91SDavid Marchand char mac_addr[RTE_ETHER_ADDR_FMT_SIZE]; 563558b43c1dSGowrishankar Muthukrishnan struct rte_eth_dev *eth_dev; 563658b43c1dSGowrishankar Muthukrishnan char *end_param; 563758b43c1dSGowrishankar Muthukrishnan int port_id, i; 563858b43c1dSGowrishankar Muthukrishnan 563958b43c1dSGowrishankar Muthukrishnan if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 564058b43c1dSGowrishankar Muthukrishnan return -1; 564158b43c1dSGowrishankar Muthukrishnan 564258b43c1dSGowrishankar Muthukrishnan port_id = strtoul(params, &end_param, 0); 564358b43c1dSGowrishankar Muthukrishnan if (*end_param != '\0') 564458b43c1dSGowrishankar Muthukrishnan RTE_ETHDEV_LOG(NOTICE, 564558b43c1dSGowrishankar Muthukrishnan "Extra parameters passed to ethdev telemetry command, ignoring"); 564658b43c1dSGowrishankar Muthukrishnan 564758b43c1dSGowrishankar Muthukrishnan if (!rte_eth_dev_is_valid_port(port_id)) 564858b43c1dSGowrishankar Muthukrishnan return -EINVAL; 564958b43c1dSGowrishankar Muthukrishnan 565058b43c1dSGowrishankar Muthukrishnan eth_dev = &rte_eth_devices[port_id]; 565158b43c1dSGowrishankar Muthukrishnan 565258b43c1dSGowrishankar Muthukrishnan rxq_state = rte_tel_data_alloc(); 565358b43c1dSGowrishankar Muthukrishnan if (!rxq_state) 565458b43c1dSGowrishankar Muthukrishnan return -ENOMEM; 565558b43c1dSGowrishankar Muthukrishnan 565658b43c1dSGowrishankar Muthukrishnan txq_state = rte_tel_data_alloc(); 565752b49ea0SYunjian Wang if (!txq_state) { 565852b49ea0SYunjian Wang rte_tel_data_free(rxq_state); 565958b43c1dSGowrishankar Muthukrishnan return -ENOMEM; 566052b49ea0SYunjian Wang } 566158b43c1dSGowrishankar Muthukrishnan 566258b43c1dSGowrishankar Muthukrishnan rte_tel_data_start_dict(d); 566358b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_string(d, "name", eth_dev->data->name); 566458b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "state", eth_dev->state); 566558b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "nb_rx_queues", 566658b43c1dSGowrishankar Muthukrishnan eth_dev->data->nb_rx_queues); 566758b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "nb_tx_queues", 566858b43c1dSGowrishankar Muthukrishnan eth_dev->data->nb_tx_queues); 566958b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "port_id", eth_dev->data->port_id); 567058b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "mtu", eth_dev->data->mtu); 567158b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "rx_mbuf_size_min", 567258b43c1dSGowrishankar Muthukrishnan eth_dev->data->min_rx_buf_size); 567358b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "rx_mbuf_alloc_fail", 567458b43c1dSGowrishankar Muthukrishnan eth_dev->data->rx_mbuf_alloc_failed); 5675*ffe77e91SDavid Marchand rte_ether_format_addr(mac_addr, sizeof(mac_addr), 5676*ffe77e91SDavid Marchand eth_dev->data->mac_addrs); 567758b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_string(d, "mac_addr", mac_addr); 567858b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "promiscuous", 567958b43c1dSGowrishankar Muthukrishnan eth_dev->data->promiscuous); 568058b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "scattered_rx", 568158b43c1dSGowrishankar Muthukrishnan eth_dev->data->scattered_rx); 568258b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "all_multicast", 568358b43c1dSGowrishankar Muthukrishnan eth_dev->data->all_multicast); 568458b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "dev_started", eth_dev->data->dev_started); 568558b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "lro", eth_dev->data->lro); 568658b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "dev_configured", 568758b43c1dSGowrishankar Muthukrishnan eth_dev->data->dev_configured); 568858b43c1dSGowrishankar Muthukrishnan 568958b43c1dSGowrishankar Muthukrishnan rte_tel_data_start_array(rxq_state, RTE_TEL_INT_VAL); 569058b43c1dSGowrishankar Muthukrishnan for (i = 0; i < eth_dev->data->nb_rx_queues; i++) 569158b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_array_int(rxq_state, 569258b43c1dSGowrishankar Muthukrishnan eth_dev->data->rx_queue_state[i]); 569358b43c1dSGowrishankar Muthukrishnan 569458b43c1dSGowrishankar Muthukrishnan rte_tel_data_start_array(txq_state, RTE_TEL_INT_VAL); 569558b43c1dSGowrishankar Muthukrishnan for (i = 0; i < eth_dev->data->nb_tx_queues; i++) 569658b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_array_int(txq_state, 569758b43c1dSGowrishankar Muthukrishnan eth_dev->data->tx_queue_state[i]); 569858b43c1dSGowrishankar Muthukrishnan 569958b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_container(d, "rxq_state", rxq_state, 0); 570058b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_container(d, "txq_state", txq_state, 0); 570158b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "numa_node", eth_dev->data->numa_node); 570258b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "dev_flags", eth_dev->data->dev_flags); 570358b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "rx_offloads", 570458b43c1dSGowrishankar Muthukrishnan eth_dev->data->dev_conf.rxmode.offloads); 570558b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "tx_offloads", 570658b43c1dSGowrishankar Muthukrishnan eth_dev->data->dev_conf.txmode.offloads); 570758b43c1dSGowrishankar Muthukrishnan rte_tel_data_add_dict_int(d, "ethdev_rss_hf", 570858b43c1dSGowrishankar Muthukrishnan eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf); 570958b43c1dSGowrishankar Muthukrishnan 571058b43c1dSGowrishankar Muthukrishnan return 0; 571158b43c1dSGowrishankar Muthukrishnan } 571258b43c1dSGowrishankar Muthukrishnan 571399a2dd95SBruce Richardson int 571499a2dd95SBruce Richardson rte_eth_representor_info_get(uint16_t port_id, 571599a2dd95SBruce Richardson struct rte_eth_representor_info *info) 571699a2dd95SBruce Richardson { 571799a2dd95SBruce Richardson struct rte_eth_dev *dev; 571899a2dd95SBruce Richardson 571999a2dd95SBruce Richardson RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 572099a2dd95SBruce Richardson dev = &rte_eth_devices[port_id]; 572199a2dd95SBruce Richardson 572299a2dd95SBruce Richardson RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->representor_info_get, -ENOTSUP); 572353ef1b34SMin Hu (Connor) return eth_err(port_id, (*dev->dev_ops->representor_info_get)(dev, info)); 572499a2dd95SBruce Richardson } 572599a2dd95SBruce Richardson 5726f6d8a6d3SIvan Malov int 5727f6d8a6d3SIvan Malov rte_eth_rx_metadata_negotiate(uint16_t port_id, uint64_t *features) 5728f6d8a6d3SIvan Malov { 5729f6d8a6d3SIvan Malov struct rte_eth_dev *dev; 5730f6d8a6d3SIvan Malov 5731f6d8a6d3SIvan Malov RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 5732f6d8a6d3SIvan Malov dev = &rte_eth_devices[port_id]; 5733f6d8a6d3SIvan Malov 5734f6d8a6d3SIvan Malov if (dev->data->dev_configured != 0) { 5735f6d8a6d3SIvan Malov RTE_ETHDEV_LOG(ERR, 57365906be5aSAndrew Rybchenko "The port (ID=%"PRIu16") is already configured\n", 5737f6d8a6d3SIvan Malov port_id); 5738f6d8a6d3SIvan Malov return -EBUSY; 5739f6d8a6d3SIvan Malov } 5740f6d8a6d3SIvan Malov 5741f6d8a6d3SIvan Malov if (features == NULL) { 5742f6d8a6d3SIvan Malov RTE_ETHDEV_LOG(ERR, "Invalid features (NULL)\n"); 5743f6d8a6d3SIvan Malov return -EINVAL; 5744f6d8a6d3SIvan Malov } 5745f6d8a6d3SIvan Malov 5746f6d8a6d3SIvan Malov RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_metadata_negotiate, -ENOTSUP); 5747f6d8a6d3SIvan Malov return eth_err(port_id, 5748f6d8a6d3SIvan Malov (*dev->dev_ops->rx_metadata_negotiate)(dev, features)); 5749f6d8a6d3SIvan Malov } 5750f6d8a6d3SIvan Malov 5751a75ab6e5SAkhil Goyal int 5752a75ab6e5SAkhil Goyal rte_eth_ip_reassembly_capability_get(uint16_t port_id, 5753a75ab6e5SAkhil Goyal struct rte_eth_ip_reassembly_params *reassembly_capa) 5754a75ab6e5SAkhil Goyal { 5755a75ab6e5SAkhil Goyal struct rte_eth_dev *dev; 5756a75ab6e5SAkhil Goyal 5757a75ab6e5SAkhil Goyal RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 5758a75ab6e5SAkhil Goyal dev = &rte_eth_devices[port_id]; 5759a75ab6e5SAkhil Goyal 5760a75ab6e5SAkhil Goyal if (dev->data->dev_configured == 0) { 5761a75ab6e5SAkhil Goyal RTE_ETHDEV_LOG(ERR, 5762a75ab6e5SAkhil Goyal "Device with port_id=%u is not configured.\n" 5763a75ab6e5SAkhil Goyal "Cannot get IP reassembly capability\n", 5764a75ab6e5SAkhil Goyal port_id); 5765a75ab6e5SAkhil Goyal return -EINVAL; 5766a75ab6e5SAkhil Goyal } 5767a75ab6e5SAkhil Goyal 5768a75ab6e5SAkhil Goyal if (reassembly_capa == NULL) { 5769a75ab6e5SAkhil Goyal RTE_ETHDEV_LOG(ERR, "Cannot get reassembly capability to NULL"); 5770a75ab6e5SAkhil Goyal return -EINVAL; 5771a75ab6e5SAkhil Goyal } 5772a75ab6e5SAkhil Goyal 5773a75ab6e5SAkhil Goyal RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->ip_reassembly_capability_get, 5774a75ab6e5SAkhil Goyal -ENOTSUP); 5775a75ab6e5SAkhil Goyal memset(reassembly_capa, 0, sizeof(struct rte_eth_ip_reassembly_params)); 5776a75ab6e5SAkhil Goyal 5777a75ab6e5SAkhil Goyal return eth_err(port_id, (*dev->dev_ops->ip_reassembly_capability_get) 5778a75ab6e5SAkhil Goyal (dev, reassembly_capa)); 5779a75ab6e5SAkhil Goyal } 5780a75ab6e5SAkhil Goyal 5781a75ab6e5SAkhil Goyal int 5782a75ab6e5SAkhil Goyal rte_eth_ip_reassembly_conf_get(uint16_t port_id, 5783a75ab6e5SAkhil Goyal struct rte_eth_ip_reassembly_params *conf) 5784a75ab6e5SAkhil Goyal { 5785a75ab6e5SAkhil Goyal struct rte_eth_dev *dev; 5786a75ab6e5SAkhil Goyal 5787a75ab6e5SAkhil Goyal RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 5788a75ab6e5SAkhil Goyal dev = &rte_eth_devices[port_id]; 5789a75ab6e5SAkhil Goyal 5790a75ab6e5SAkhil Goyal if (dev->data->dev_configured == 0) { 5791a75ab6e5SAkhil Goyal RTE_ETHDEV_LOG(ERR, 5792a75ab6e5SAkhil Goyal "Device with port_id=%u is not configured.\n" 5793a75ab6e5SAkhil Goyal "Cannot get IP reassembly configuration\n", 5794a75ab6e5SAkhil Goyal port_id); 5795a75ab6e5SAkhil Goyal return -EINVAL; 5796a75ab6e5SAkhil Goyal } 5797a75ab6e5SAkhil Goyal 5798a75ab6e5SAkhil Goyal if (conf == NULL) { 5799a75ab6e5SAkhil Goyal RTE_ETHDEV_LOG(ERR, "Cannot get reassembly info to NULL"); 5800a75ab6e5SAkhil Goyal return -EINVAL; 5801a75ab6e5SAkhil Goyal } 5802a75ab6e5SAkhil Goyal 5803a75ab6e5SAkhil Goyal RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->ip_reassembly_conf_get, 5804a75ab6e5SAkhil Goyal -ENOTSUP); 5805a75ab6e5SAkhil Goyal memset(conf, 0, sizeof(struct rte_eth_ip_reassembly_params)); 5806a75ab6e5SAkhil Goyal return eth_err(port_id, 5807a75ab6e5SAkhil Goyal (*dev->dev_ops->ip_reassembly_conf_get)(dev, conf)); 5808a75ab6e5SAkhil Goyal } 5809a75ab6e5SAkhil Goyal 5810a75ab6e5SAkhil Goyal int 5811a75ab6e5SAkhil Goyal rte_eth_ip_reassembly_conf_set(uint16_t port_id, 5812a75ab6e5SAkhil Goyal const struct rte_eth_ip_reassembly_params *conf) 5813a75ab6e5SAkhil Goyal { 5814a75ab6e5SAkhil Goyal struct rte_eth_dev *dev; 5815a75ab6e5SAkhil Goyal 5816a75ab6e5SAkhil Goyal RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 5817a75ab6e5SAkhil Goyal dev = &rte_eth_devices[port_id]; 5818a75ab6e5SAkhil Goyal 5819a75ab6e5SAkhil Goyal if (dev->data->dev_configured == 0) { 5820a75ab6e5SAkhil Goyal RTE_ETHDEV_LOG(ERR, 5821a75ab6e5SAkhil Goyal "Device with port_id=%u is not configured.\n" 5822a75ab6e5SAkhil Goyal "Cannot set IP reassembly configuration", 5823a75ab6e5SAkhil Goyal port_id); 5824a75ab6e5SAkhil Goyal return -EINVAL; 5825a75ab6e5SAkhil Goyal } 5826a75ab6e5SAkhil Goyal 5827a75ab6e5SAkhil Goyal if (dev->data->dev_started != 0) { 5828a75ab6e5SAkhil Goyal RTE_ETHDEV_LOG(ERR, 5829a75ab6e5SAkhil Goyal "Device with port_id=%u started,\n" 5830a75ab6e5SAkhil Goyal "cannot configure IP reassembly params.\n", 5831a75ab6e5SAkhil Goyal port_id); 5832a75ab6e5SAkhil Goyal return -EINVAL; 5833a75ab6e5SAkhil Goyal } 5834a75ab6e5SAkhil Goyal 5835a75ab6e5SAkhil Goyal if (conf == NULL) { 5836a75ab6e5SAkhil Goyal RTE_ETHDEV_LOG(ERR, 5837a75ab6e5SAkhil Goyal "Invalid IP reassembly configuration (NULL)\n"); 5838a75ab6e5SAkhil Goyal return -EINVAL; 5839a75ab6e5SAkhil Goyal } 5840a75ab6e5SAkhil Goyal 5841a75ab6e5SAkhil Goyal RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->ip_reassembly_conf_set, 5842a75ab6e5SAkhil Goyal -ENOTSUP); 5843a75ab6e5SAkhil Goyal return eth_err(port_id, 5844a75ab6e5SAkhil Goyal (*dev->dev_ops->ip_reassembly_conf_set)(dev, conf)); 5845a75ab6e5SAkhil Goyal } 5846a75ab6e5SAkhil Goyal 58473c059b2cSAkhil Goyal int 5848edcf22c6SMin Hu (Connor) rte_eth_dev_priv_dump(uint16_t port_id, FILE *file) 5849edcf22c6SMin Hu (Connor) { 5850edcf22c6SMin Hu (Connor) struct rte_eth_dev *dev; 5851edcf22c6SMin Hu (Connor) 5852edcf22c6SMin Hu (Connor) RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 5853edcf22c6SMin Hu (Connor) dev = &rte_eth_devices[port_id]; 5854edcf22c6SMin Hu (Connor) 5855edcf22c6SMin Hu (Connor) if (file == NULL) { 5856edcf22c6SMin Hu (Connor) RTE_ETHDEV_LOG(ERR, "Invalid file (NULL)\n"); 5857edcf22c6SMin Hu (Connor) return -EINVAL; 5858edcf22c6SMin Hu (Connor) } 5859edcf22c6SMin Hu (Connor) 5860edcf22c6SMin Hu (Connor) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->eth_dev_priv_dump, -ENOTSUP); 5861edcf22c6SMin Hu (Connor) return eth_err(port_id, (*dev->dev_ops->eth_dev_priv_dump)(dev, file)); 5862edcf22c6SMin Hu (Connor) } 5863edcf22c6SMin Hu (Connor) 5864eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO); 586599a2dd95SBruce Richardson 586699a2dd95SBruce Richardson RTE_INIT(ethdev_init_telemetry) 586799a2dd95SBruce Richardson { 586899a2dd95SBruce Richardson rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list, 586999a2dd95SBruce Richardson "Returns list of available ethdev ports. Takes no parameters"); 587099a2dd95SBruce Richardson rte_telemetry_register_cmd("/ethdev/stats", eth_dev_handle_port_stats, 587199a2dd95SBruce Richardson "Returns the common stats for a port. Parameters: int port_id"); 587299a2dd95SBruce Richardson rte_telemetry_register_cmd("/ethdev/xstats", eth_dev_handle_port_xstats, 587399a2dd95SBruce Richardson "Returns the extended stats for a port. Parameters: int port_id"); 587499a2dd95SBruce Richardson rte_telemetry_register_cmd("/ethdev/link_status", 587599a2dd95SBruce Richardson eth_dev_handle_port_link_status, 587699a2dd95SBruce Richardson "Returns the link status for a port. Parameters: int port_id"); 587758b43c1dSGowrishankar Muthukrishnan rte_telemetry_register_cmd("/ethdev/info", eth_dev_handle_port_info, 587858b43c1dSGowrishankar Muthukrishnan "Returns the device info for a port. Parameters: int port_id"); 587999a2dd95SBruce Richardson } 5880