1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause 2d30ea906Sjfb8856606 * Copyright(c) 2010-2017 Intel Corporation 3d30ea906Sjfb8856606 */ 4d30ea906Sjfb8856606 5d30ea906Sjfb8856606 #include <sys/types.h> 6d30ea906Sjfb8856606 #include <sys/queue.h> 7d30ea906Sjfb8856606 #include <ctype.h> 8d30ea906Sjfb8856606 #include <stdio.h> 9d30ea906Sjfb8856606 #include <stdlib.h> 10d30ea906Sjfb8856606 #include <string.h> 11d30ea906Sjfb8856606 #include <stdarg.h> 12d30ea906Sjfb8856606 #include <errno.h> 13d30ea906Sjfb8856606 #include <stdbool.h> 14d30ea906Sjfb8856606 #include <stdint.h> 15d30ea906Sjfb8856606 #include <inttypes.h> 16d30ea906Sjfb8856606 #include <netinet/in.h> 17d30ea906Sjfb8856606 18d30ea906Sjfb8856606 #include <rte_byteorder.h> 19d30ea906Sjfb8856606 #include <rte_log.h> 20d30ea906Sjfb8856606 #include <rte_debug.h> 21d30ea906Sjfb8856606 #include <rte_interrupts.h> 22d30ea906Sjfb8856606 #include <rte_memory.h> 23d30ea906Sjfb8856606 #include <rte_memcpy.h> 24d30ea906Sjfb8856606 #include <rte_memzone.h> 25d30ea906Sjfb8856606 #include <rte_launch.h> 26d30ea906Sjfb8856606 #include <rte_eal.h> 27d30ea906Sjfb8856606 #include <rte_per_lcore.h> 28d30ea906Sjfb8856606 #include <rte_lcore.h> 29d30ea906Sjfb8856606 #include <rte_atomic.h> 30d30ea906Sjfb8856606 #include <rte_branch_prediction.h> 31d30ea906Sjfb8856606 #include <rte_common.h> 32d30ea906Sjfb8856606 #include <rte_mempool.h> 33d30ea906Sjfb8856606 #include <rte_malloc.h> 34d30ea906Sjfb8856606 #include <rte_mbuf.h> 35d30ea906Sjfb8856606 #include <rte_errno.h> 36d30ea906Sjfb8856606 #include <rte_spinlock.h> 37d30ea906Sjfb8856606 #include <rte_string_fns.h> 38d30ea906Sjfb8856606 #include <rte_kvargs.h> 39d30ea906Sjfb8856606 #include <rte_class.h> 40d30ea906Sjfb8856606 41d30ea906Sjfb8856606 #include "rte_ether.h" 42d30ea906Sjfb8856606 #include "rte_ethdev.h" 43d30ea906Sjfb8856606 #include "rte_ethdev_driver.h" 44d30ea906Sjfb8856606 #include "ethdev_profile.h" 45d30ea906Sjfb8856606 #include "ethdev_private.h" 46d30ea906Sjfb8856606 47d30ea906Sjfb8856606 int rte_eth_dev_logtype; 48d30ea906Sjfb8856606 49d30ea906Sjfb8856606 static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data"; 50d30ea906Sjfb8856606 struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS]; 51d30ea906Sjfb8856606 52d30ea906Sjfb8856606 /* spinlock for eth device callbacks */ 53d30ea906Sjfb8856606 static rte_spinlock_t rte_eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER; 54d30ea906Sjfb8856606 55d30ea906Sjfb8856606 /* spinlock for add/remove rx callbacks */ 56d30ea906Sjfb8856606 static rte_spinlock_t rte_eth_rx_cb_lock = RTE_SPINLOCK_INITIALIZER; 57d30ea906Sjfb8856606 58d30ea906Sjfb8856606 /* spinlock for add/remove tx callbacks */ 59d30ea906Sjfb8856606 static rte_spinlock_t rte_eth_tx_cb_lock = RTE_SPINLOCK_INITIALIZER; 60d30ea906Sjfb8856606 61d30ea906Sjfb8856606 /* spinlock for shared data allocation */ 62d30ea906Sjfb8856606 static rte_spinlock_t rte_eth_shared_data_lock = RTE_SPINLOCK_INITIALIZER; 63d30ea906Sjfb8856606 64d30ea906Sjfb8856606 /* store statistics names and its offset in stats structure */ 65d30ea906Sjfb8856606 struct rte_eth_xstats_name_off { 66d30ea906Sjfb8856606 char name[RTE_ETH_XSTATS_NAME_SIZE]; 67d30ea906Sjfb8856606 unsigned offset; 68d30ea906Sjfb8856606 }; 69d30ea906Sjfb8856606 70d30ea906Sjfb8856606 /* Shared memory between primary and secondary processes. */ 71d30ea906Sjfb8856606 static struct { 72d30ea906Sjfb8856606 uint64_t next_owner_id; 73d30ea906Sjfb8856606 rte_spinlock_t ownership_lock; 74d30ea906Sjfb8856606 struct rte_eth_dev_data data[RTE_MAX_ETHPORTS]; 75d30ea906Sjfb8856606 } *rte_eth_dev_shared_data; 76d30ea906Sjfb8856606 77d30ea906Sjfb8856606 static const struct rte_eth_xstats_name_off rte_stats_strings[] = { 78d30ea906Sjfb8856606 {"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)}, 79d30ea906Sjfb8856606 {"tx_good_packets", offsetof(struct rte_eth_stats, opackets)}, 80d30ea906Sjfb8856606 {"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)}, 81d30ea906Sjfb8856606 {"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)}, 82d30ea906Sjfb8856606 {"rx_missed_errors", offsetof(struct rte_eth_stats, imissed)}, 83d30ea906Sjfb8856606 {"rx_errors", offsetof(struct rte_eth_stats, ierrors)}, 84d30ea906Sjfb8856606 {"tx_errors", offsetof(struct rte_eth_stats, oerrors)}, 85d30ea906Sjfb8856606 {"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats, 86d30ea906Sjfb8856606 rx_nombuf)}, 87d30ea906Sjfb8856606 }; 88d30ea906Sjfb8856606 89d30ea906Sjfb8856606 #define RTE_NB_STATS (sizeof(rte_stats_strings) / sizeof(rte_stats_strings[0])) 90d30ea906Sjfb8856606 91d30ea906Sjfb8856606 static const struct rte_eth_xstats_name_off rte_rxq_stats_strings[] = { 92d30ea906Sjfb8856606 {"packets", offsetof(struct rte_eth_stats, q_ipackets)}, 93d30ea906Sjfb8856606 {"bytes", offsetof(struct rte_eth_stats, q_ibytes)}, 94d30ea906Sjfb8856606 {"errors", offsetof(struct rte_eth_stats, q_errors)}, 95d30ea906Sjfb8856606 }; 96d30ea906Sjfb8856606 97d30ea906Sjfb8856606 #define RTE_NB_RXQ_STATS (sizeof(rte_rxq_stats_strings) / \ 98d30ea906Sjfb8856606 sizeof(rte_rxq_stats_strings[0])) 99d30ea906Sjfb8856606 100d30ea906Sjfb8856606 static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = { 101d30ea906Sjfb8856606 {"packets", offsetof(struct rte_eth_stats, q_opackets)}, 102d30ea906Sjfb8856606 {"bytes", offsetof(struct rte_eth_stats, q_obytes)}, 103d30ea906Sjfb8856606 }; 104d30ea906Sjfb8856606 #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) / \ 105d30ea906Sjfb8856606 sizeof(rte_txq_stats_strings[0])) 106d30ea906Sjfb8856606 107d30ea906Sjfb8856606 #define RTE_RX_OFFLOAD_BIT2STR(_name) \ 108d30ea906Sjfb8856606 { DEV_RX_OFFLOAD_##_name, #_name } 109d30ea906Sjfb8856606 110d30ea906Sjfb8856606 static const struct { 111d30ea906Sjfb8856606 uint64_t offload; 112d30ea906Sjfb8856606 const char *name; 113d30ea906Sjfb8856606 } rte_rx_offload_names[] = { 114d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(VLAN_STRIP), 115d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(IPV4_CKSUM), 116d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(UDP_CKSUM), 117d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(TCP_CKSUM), 118d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(TCP_LRO), 119d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(QINQ_STRIP), 120d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM), 121d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(MACSEC_STRIP), 122d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(HEADER_SPLIT), 123d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(VLAN_FILTER), 124d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(VLAN_EXTEND), 125d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(JUMBO_FRAME), 126d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(SCATTER), 127d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(TIMESTAMP), 128d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(SECURITY), 129d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(KEEP_CRC), 130d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(SCTP_CKSUM), 131d30ea906Sjfb8856606 RTE_RX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM), 132d30ea906Sjfb8856606 }; 133d30ea906Sjfb8856606 134d30ea906Sjfb8856606 #undef RTE_RX_OFFLOAD_BIT2STR 135d30ea906Sjfb8856606 136d30ea906Sjfb8856606 #define RTE_TX_OFFLOAD_BIT2STR(_name) \ 137d30ea906Sjfb8856606 { DEV_TX_OFFLOAD_##_name, #_name } 138d30ea906Sjfb8856606 139d30ea906Sjfb8856606 static const struct { 140d30ea906Sjfb8856606 uint64_t offload; 141d30ea906Sjfb8856606 const char *name; 142d30ea906Sjfb8856606 } rte_tx_offload_names[] = { 143d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(VLAN_INSERT), 144d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(IPV4_CKSUM), 145d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(UDP_CKSUM), 146d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(TCP_CKSUM), 147d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(SCTP_CKSUM), 148d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(TCP_TSO), 149d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(UDP_TSO), 150d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM), 151d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(QINQ_INSERT), 152d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(VXLAN_TNL_TSO), 153d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(GRE_TNL_TSO), 154d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(IPIP_TNL_TSO), 155d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(GENEVE_TNL_TSO), 156d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(MACSEC_INSERT), 157d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(MT_LOCKFREE), 158d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(MULTI_SEGS), 159d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(MBUF_FAST_FREE), 160d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(SECURITY), 161d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(UDP_TNL_TSO), 162d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(IP_TNL_TSO), 163d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM), 164d30ea906Sjfb8856606 RTE_TX_OFFLOAD_BIT2STR(MATCH_METADATA), 165d30ea906Sjfb8856606 }; 166d30ea906Sjfb8856606 167d30ea906Sjfb8856606 #undef RTE_TX_OFFLOAD_BIT2STR 168d30ea906Sjfb8856606 169d30ea906Sjfb8856606 /** 170d30ea906Sjfb8856606 * The user application callback description. 171d30ea906Sjfb8856606 * 172d30ea906Sjfb8856606 * It contains callback address to be registered by user application, 173d30ea906Sjfb8856606 * the pointer to the parameters for callback, and the event type. 174d30ea906Sjfb8856606 */ 175d30ea906Sjfb8856606 struct rte_eth_dev_callback { 176d30ea906Sjfb8856606 TAILQ_ENTRY(rte_eth_dev_callback) next; /**< Callbacks list */ 177d30ea906Sjfb8856606 rte_eth_dev_cb_fn cb_fn; /**< Callback address */ 178d30ea906Sjfb8856606 void *cb_arg; /**< Parameter for callback */ 179d30ea906Sjfb8856606 void *ret_param; /**< Return parameter */ 180d30ea906Sjfb8856606 enum rte_eth_event_type event; /**< Interrupt event type */ 181d30ea906Sjfb8856606 uint32_t active; /**< Callback is executing */ 182d30ea906Sjfb8856606 }; 183d30ea906Sjfb8856606 184d30ea906Sjfb8856606 enum { 185d30ea906Sjfb8856606 STAT_QMAP_TX = 0, 186d30ea906Sjfb8856606 STAT_QMAP_RX 187d30ea906Sjfb8856606 }; 188d30ea906Sjfb8856606 189d30ea906Sjfb8856606 int 190d30ea906Sjfb8856606 rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) 191d30ea906Sjfb8856606 { 192d30ea906Sjfb8856606 int ret; 193d30ea906Sjfb8856606 struct rte_devargs devargs = {.args = NULL}; 194d30ea906Sjfb8856606 const char *bus_param_key; 195d30ea906Sjfb8856606 char *bus_str = NULL; 196d30ea906Sjfb8856606 char *cls_str = NULL; 197d30ea906Sjfb8856606 int str_size; 198d30ea906Sjfb8856606 199d30ea906Sjfb8856606 memset(iter, 0, sizeof(*iter)); 200d30ea906Sjfb8856606 201d30ea906Sjfb8856606 /* 202d30ea906Sjfb8856606 * The devargs string may use various syntaxes: 203d30ea906Sjfb8856606 * - 0000:08:00.0,representor=[1-3] 204d30ea906Sjfb8856606 * - pci:0000:06:00.0,representor=[0,5] 205d30ea906Sjfb8856606 * - class=eth,mac=00:11:22:33:44:55 206d30ea906Sjfb8856606 * A new syntax is in development (not yet supported): 207d30ea906Sjfb8856606 * - bus=X,paramX=x/class=Y,paramY=y/driver=Z,paramZ=z 208d30ea906Sjfb8856606 */ 209d30ea906Sjfb8856606 210d30ea906Sjfb8856606 /* 211d30ea906Sjfb8856606 * Handle pure class filter (i.e. without any bus-level argument), 212d30ea906Sjfb8856606 * from future new syntax. 213d30ea906Sjfb8856606 * rte_devargs_parse() is not yet supporting the new syntax, 214d30ea906Sjfb8856606 * that's why this simple case is temporarily parsed here. 215d30ea906Sjfb8856606 */ 216d30ea906Sjfb8856606 #define iter_anybus_str "class=eth," 217d30ea906Sjfb8856606 if (strncmp(devargs_str, iter_anybus_str, 218d30ea906Sjfb8856606 strlen(iter_anybus_str)) == 0) { 219d30ea906Sjfb8856606 iter->cls_str = devargs_str + strlen(iter_anybus_str); 220d30ea906Sjfb8856606 goto end; 221d30ea906Sjfb8856606 } 222d30ea906Sjfb8856606 223d30ea906Sjfb8856606 /* Split bus, device and parameters. */ 224d30ea906Sjfb8856606 ret = rte_devargs_parse(&devargs, devargs_str); 225d30ea906Sjfb8856606 if (ret != 0) 226d30ea906Sjfb8856606 goto error; 227d30ea906Sjfb8856606 228d30ea906Sjfb8856606 /* 229d30ea906Sjfb8856606 * Assume parameters of old syntax can match only at ethdev level. 230d30ea906Sjfb8856606 * Extra parameters will be ignored, thanks to "+" prefix. 231d30ea906Sjfb8856606 */ 232d30ea906Sjfb8856606 str_size = strlen(devargs.args) + 2; 233d30ea906Sjfb8856606 cls_str = malloc(str_size); 234d30ea906Sjfb8856606 if (cls_str == NULL) { 235d30ea906Sjfb8856606 ret = -ENOMEM; 236d30ea906Sjfb8856606 goto error; 237d30ea906Sjfb8856606 } 238d30ea906Sjfb8856606 ret = snprintf(cls_str, str_size, "+%s", devargs.args); 239d30ea906Sjfb8856606 if (ret != str_size - 1) { 240d30ea906Sjfb8856606 ret = -EINVAL; 241d30ea906Sjfb8856606 goto error; 242d30ea906Sjfb8856606 } 243d30ea906Sjfb8856606 iter->cls_str = cls_str; 244d30ea906Sjfb8856606 free(devargs.args); /* allocated by rte_devargs_parse() */ 245d30ea906Sjfb8856606 devargs.args = NULL; 246d30ea906Sjfb8856606 247d30ea906Sjfb8856606 iter->bus = devargs.bus; 248d30ea906Sjfb8856606 if (iter->bus->dev_iterate == NULL) { 249d30ea906Sjfb8856606 ret = -ENOTSUP; 250d30ea906Sjfb8856606 goto error; 251d30ea906Sjfb8856606 } 252d30ea906Sjfb8856606 253d30ea906Sjfb8856606 /* Convert bus args to new syntax for use with new API dev_iterate. */ 254d30ea906Sjfb8856606 if (strcmp(iter->bus->name, "vdev") == 0) { 255d30ea906Sjfb8856606 bus_param_key = "name"; 256d30ea906Sjfb8856606 } else if (strcmp(iter->bus->name, "pci") == 0) { 257d30ea906Sjfb8856606 bus_param_key = "addr"; 258d30ea906Sjfb8856606 } else { 259d30ea906Sjfb8856606 ret = -ENOTSUP; 260d30ea906Sjfb8856606 goto error; 261d30ea906Sjfb8856606 } 262d30ea906Sjfb8856606 str_size = strlen(bus_param_key) + strlen(devargs.name) + 2; 263d30ea906Sjfb8856606 bus_str = malloc(str_size); 264d30ea906Sjfb8856606 if (bus_str == NULL) { 265d30ea906Sjfb8856606 ret = -ENOMEM; 266d30ea906Sjfb8856606 goto error; 267d30ea906Sjfb8856606 } 268d30ea906Sjfb8856606 ret = snprintf(bus_str, str_size, "%s=%s", 269d30ea906Sjfb8856606 bus_param_key, devargs.name); 270d30ea906Sjfb8856606 if (ret != str_size - 1) { 271d30ea906Sjfb8856606 ret = -EINVAL; 272d30ea906Sjfb8856606 goto error; 273d30ea906Sjfb8856606 } 274d30ea906Sjfb8856606 iter->bus_str = bus_str; 275d30ea906Sjfb8856606 276d30ea906Sjfb8856606 end: 277d30ea906Sjfb8856606 iter->cls = rte_class_find_by_name("eth"); 278d30ea906Sjfb8856606 return 0; 279d30ea906Sjfb8856606 280d30ea906Sjfb8856606 error: 281d30ea906Sjfb8856606 if (ret == -ENOTSUP) 282d30ea906Sjfb8856606 RTE_LOG(ERR, EAL, "Bus %s does not support iterating.\n", 283d30ea906Sjfb8856606 iter->bus->name); 284d30ea906Sjfb8856606 free(devargs.args); 285d30ea906Sjfb8856606 free(bus_str); 286d30ea906Sjfb8856606 free(cls_str); 287d30ea906Sjfb8856606 return ret; 288d30ea906Sjfb8856606 } 289d30ea906Sjfb8856606 290d30ea906Sjfb8856606 uint16_t 291d30ea906Sjfb8856606 rte_eth_iterator_next(struct rte_dev_iterator *iter) 292d30ea906Sjfb8856606 { 293d30ea906Sjfb8856606 if (iter->cls == NULL) /* invalid ethdev iterator */ 294d30ea906Sjfb8856606 return RTE_MAX_ETHPORTS; 295d30ea906Sjfb8856606 296d30ea906Sjfb8856606 do { /* loop to try all matching rte_device */ 297d30ea906Sjfb8856606 /* If not pure ethdev filter and */ 298d30ea906Sjfb8856606 if (iter->bus != NULL && 299d30ea906Sjfb8856606 /* not in middle of rte_eth_dev iteration, */ 300d30ea906Sjfb8856606 iter->class_device == NULL) { 301d30ea906Sjfb8856606 /* get next rte_device to try. */ 302d30ea906Sjfb8856606 iter->device = iter->bus->dev_iterate( 303d30ea906Sjfb8856606 iter->device, iter->bus_str, iter); 304d30ea906Sjfb8856606 if (iter->device == NULL) 305d30ea906Sjfb8856606 break; /* no more rte_device candidate */ 306d30ea906Sjfb8856606 } 307d30ea906Sjfb8856606 /* A device is matching bus part, need to check ethdev part. */ 308d30ea906Sjfb8856606 iter->class_device = iter->cls->dev_iterate( 309d30ea906Sjfb8856606 iter->class_device, iter->cls_str, iter); 310d30ea906Sjfb8856606 if (iter->class_device != NULL) 311d30ea906Sjfb8856606 return eth_dev_to_id(iter->class_device); /* match */ 312d30ea906Sjfb8856606 } while (iter->bus != NULL); /* need to try next rte_device */ 313d30ea906Sjfb8856606 314d30ea906Sjfb8856606 /* No more ethdev port to iterate. */ 315d30ea906Sjfb8856606 rte_eth_iterator_cleanup(iter); 316d30ea906Sjfb8856606 return RTE_MAX_ETHPORTS; 317d30ea906Sjfb8856606 } 318d30ea906Sjfb8856606 319d30ea906Sjfb8856606 void 320d30ea906Sjfb8856606 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter) 321d30ea906Sjfb8856606 { 322d30ea906Sjfb8856606 if (iter->bus_str == NULL) 323d30ea906Sjfb8856606 return; /* nothing to free in pure class filter */ 324d30ea906Sjfb8856606 free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */ 325d30ea906Sjfb8856606 free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */ 326d30ea906Sjfb8856606 memset(iter, 0, sizeof(*iter)); 327d30ea906Sjfb8856606 } 328d30ea906Sjfb8856606 329d30ea906Sjfb8856606 uint16_t 330d30ea906Sjfb8856606 rte_eth_find_next(uint16_t port_id) 331d30ea906Sjfb8856606 { 332d30ea906Sjfb8856606 while (port_id < RTE_MAX_ETHPORTS && 333d30ea906Sjfb8856606 rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED && 334d30ea906Sjfb8856606 rte_eth_devices[port_id].state != RTE_ETH_DEV_REMOVED) 335d30ea906Sjfb8856606 port_id++; 336d30ea906Sjfb8856606 337d30ea906Sjfb8856606 if (port_id >= RTE_MAX_ETHPORTS) 338d30ea906Sjfb8856606 return RTE_MAX_ETHPORTS; 339d30ea906Sjfb8856606 340d30ea906Sjfb8856606 return port_id; 341d30ea906Sjfb8856606 } 342d30ea906Sjfb8856606 343d30ea906Sjfb8856606 static void 344d30ea906Sjfb8856606 rte_eth_dev_shared_data_prepare(void) 345d30ea906Sjfb8856606 { 346d30ea906Sjfb8856606 const unsigned flags = 0; 347d30ea906Sjfb8856606 const struct rte_memzone *mz; 348d30ea906Sjfb8856606 349d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_shared_data_lock); 350d30ea906Sjfb8856606 351d30ea906Sjfb8856606 if (rte_eth_dev_shared_data == NULL) { 352d30ea906Sjfb8856606 if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 353d30ea906Sjfb8856606 /* Allocate port data and ownership shared memory. */ 354d30ea906Sjfb8856606 mz = rte_memzone_reserve(MZ_RTE_ETH_DEV_DATA, 355d30ea906Sjfb8856606 sizeof(*rte_eth_dev_shared_data), 356d30ea906Sjfb8856606 rte_socket_id(), flags); 357d30ea906Sjfb8856606 } else 358d30ea906Sjfb8856606 mz = rte_memzone_lookup(MZ_RTE_ETH_DEV_DATA); 359d30ea906Sjfb8856606 if (mz == NULL) 360d30ea906Sjfb8856606 rte_panic("Cannot allocate ethdev shared data\n"); 361d30ea906Sjfb8856606 362d30ea906Sjfb8856606 rte_eth_dev_shared_data = mz->addr; 363d30ea906Sjfb8856606 if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 364d30ea906Sjfb8856606 rte_eth_dev_shared_data->next_owner_id = 365d30ea906Sjfb8856606 RTE_ETH_DEV_NO_OWNER + 1; 366d30ea906Sjfb8856606 rte_spinlock_init(&rte_eth_dev_shared_data->ownership_lock); 367d30ea906Sjfb8856606 memset(rte_eth_dev_shared_data->data, 0, 368d30ea906Sjfb8856606 sizeof(rte_eth_dev_shared_data->data)); 369d30ea906Sjfb8856606 } 370d30ea906Sjfb8856606 } 371d30ea906Sjfb8856606 372d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_shared_data_lock); 373d30ea906Sjfb8856606 } 374d30ea906Sjfb8856606 375d30ea906Sjfb8856606 static bool 376d30ea906Sjfb8856606 is_allocated(const struct rte_eth_dev *ethdev) 377d30ea906Sjfb8856606 { 378d30ea906Sjfb8856606 return ethdev->data->name[0] != '\0'; 379d30ea906Sjfb8856606 } 380d30ea906Sjfb8856606 381d30ea906Sjfb8856606 static struct rte_eth_dev * 382d30ea906Sjfb8856606 _rte_eth_dev_allocated(const char *name) 383d30ea906Sjfb8856606 { 384d30ea906Sjfb8856606 unsigned i; 385d30ea906Sjfb8856606 386d30ea906Sjfb8856606 for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 387d30ea906Sjfb8856606 if (rte_eth_devices[i].data != NULL && 388d30ea906Sjfb8856606 strcmp(rte_eth_devices[i].data->name, name) == 0) 389d30ea906Sjfb8856606 return &rte_eth_devices[i]; 390d30ea906Sjfb8856606 } 391d30ea906Sjfb8856606 return NULL; 392d30ea906Sjfb8856606 } 393d30ea906Sjfb8856606 394d30ea906Sjfb8856606 struct rte_eth_dev * 395d30ea906Sjfb8856606 rte_eth_dev_allocated(const char *name) 396d30ea906Sjfb8856606 { 397d30ea906Sjfb8856606 struct rte_eth_dev *ethdev; 398d30ea906Sjfb8856606 399d30ea906Sjfb8856606 rte_eth_dev_shared_data_prepare(); 400d30ea906Sjfb8856606 401d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock); 402d30ea906Sjfb8856606 403d30ea906Sjfb8856606 ethdev = _rte_eth_dev_allocated(name); 404d30ea906Sjfb8856606 405d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock); 406d30ea906Sjfb8856606 407d30ea906Sjfb8856606 return ethdev; 408d30ea906Sjfb8856606 } 409d30ea906Sjfb8856606 410d30ea906Sjfb8856606 static uint16_t 411d30ea906Sjfb8856606 rte_eth_dev_find_free_port(void) 412d30ea906Sjfb8856606 { 413d30ea906Sjfb8856606 unsigned i; 414d30ea906Sjfb8856606 415d30ea906Sjfb8856606 for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 416d30ea906Sjfb8856606 /* Using shared name field to find a free port. */ 417d30ea906Sjfb8856606 if (rte_eth_dev_shared_data->data[i].name[0] == '\0') { 418d30ea906Sjfb8856606 RTE_ASSERT(rte_eth_devices[i].state == 419d30ea906Sjfb8856606 RTE_ETH_DEV_UNUSED); 420d30ea906Sjfb8856606 return i; 421d30ea906Sjfb8856606 } 422d30ea906Sjfb8856606 } 423d30ea906Sjfb8856606 return RTE_MAX_ETHPORTS; 424d30ea906Sjfb8856606 } 425d30ea906Sjfb8856606 426d30ea906Sjfb8856606 static struct rte_eth_dev * 427d30ea906Sjfb8856606 eth_dev_get(uint16_t port_id) 428d30ea906Sjfb8856606 { 429d30ea906Sjfb8856606 struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id]; 430d30ea906Sjfb8856606 431d30ea906Sjfb8856606 eth_dev->data = &rte_eth_dev_shared_data->data[port_id]; 432d30ea906Sjfb8856606 433d30ea906Sjfb8856606 return eth_dev; 434d30ea906Sjfb8856606 } 435d30ea906Sjfb8856606 436d30ea906Sjfb8856606 struct rte_eth_dev * 437d30ea906Sjfb8856606 rte_eth_dev_allocate(const char *name) 438d30ea906Sjfb8856606 { 439d30ea906Sjfb8856606 uint16_t port_id; 440d30ea906Sjfb8856606 struct rte_eth_dev *eth_dev = NULL; 441d30ea906Sjfb8856606 442d30ea906Sjfb8856606 rte_eth_dev_shared_data_prepare(); 443d30ea906Sjfb8856606 444d30ea906Sjfb8856606 /* Synchronize port creation between primary and secondary threads. */ 445d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock); 446d30ea906Sjfb8856606 447d30ea906Sjfb8856606 if (_rte_eth_dev_allocated(name) != NULL) { 448d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 449d30ea906Sjfb8856606 "Ethernet device with name %s already allocated\n", 450d30ea906Sjfb8856606 name); 451d30ea906Sjfb8856606 goto unlock; 452d30ea906Sjfb8856606 } 453d30ea906Sjfb8856606 454d30ea906Sjfb8856606 port_id = rte_eth_dev_find_free_port(); 455d30ea906Sjfb8856606 if (port_id == RTE_MAX_ETHPORTS) { 456d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 457d30ea906Sjfb8856606 "Reached maximum number of Ethernet ports\n"); 458d30ea906Sjfb8856606 goto unlock; 459d30ea906Sjfb8856606 } 460d30ea906Sjfb8856606 461d30ea906Sjfb8856606 eth_dev = eth_dev_get(port_id); 462d30ea906Sjfb8856606 snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name); 463d30ea906Sjfb8856606 eth_dev->data->port_id = port_id; 464d30ea906Sjfb8856606 eth_dev->data->mtu = ETHER_MTU; 465d30ea906Sjfb8856606 466d30ea906Sjfb8856606 unlock: 467d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock); 468d30ea906Sjfb8856606 469d30ea906Sjfb8856606 return eth_dev; 470d30ea906Sjfb8856606 } 471d30ea906Sjfb8856606 472d30ea906Sjfb8856606 /* 473d30ea906Sjfb8856606 * Attach to a port already registered by the primary process, which 474d30ea906Sjfb8856606 * makes sure that the same device would have the same port id both 475d30ea906Sjfb8856606 * in the primary and secondary process. 476d30ea906Sjfb8856606 */ 477d30ea906Sjfb8856606 struct rte_eth_dev * 478d30ea906Sjfb8856606 rte_eth_dev_attach_secondary(const char *name) 479d30ea906Sjfb8856606 { 480d30ea906Sjfb8856606 uint16_t i; 481d30ea906Sjfb8856606 struct rte_eth_dev *eth_dev = NULL; 482d30ea906Sjfb8856606 483d30ea906Sjfb8856606 rte_eth_dev_shared_data_prepare(); 484d30ea906Sjfb8856606 485d30ea906Sjfb8856606 /* Synchronize port attachment to primary port creation and release. */ 486d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock); 487d30ea906Sjfb8856606 488d30ea906Sjfb8856606 for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 489d30ea906Sjfb8856606 if (strcmp(rte_eth_dev_shared_data->data[i].name, name) == 0) 490d30ea906Sjfb8856606 break; 491d30ea906Sjfb8856606 } 492d30ea906Sjfb8856606 if (i == RTE_MAX_ETHPORTS) { 493d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 494d30ea906Sjfb8856606 "Device %s is not driven by the primary process\n", 495d30ea906Sjfb8856606 name); 496d30ea906Sjfb8856606 } else { 497d30ea906Sjfb8856606 eth_dev = eth_dev_get(i); 498d30ea906Sjfb8856606 RTE_ASSERT(eth_dev->data->port_id == i); 499d30ea906Sjfb8856606 } 500d30ea906Sjfb8856606 501d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock); 502d30ea906Sjfb8856606 return eth_dev; 503d30ea906Sjfb8856606 } 504d30ea906Sjfb8856606 505d30ea906Sjfb8856606 int 506d30ea906Sjfb8856606 rte_eth_dev_release_port(struct rte_eth_dev *eth_dev) 507d30ea906Sjfb8856606 { 508d30ea906Sjfb8856606 if (eth_dev == NULL) 509d30ea906Sjfb8856606 return -EINVAL; 510d30ea906Sjfb8856606 511d30ea906Sjfb8856606 rte_eth_dev_shared_data_prepare(); 512d30ea906Sjfb8856606 513d30ea906Sjfb8856606 if (eth_dev->state != RTE_ETH_DEV_UNUSED) 514d30ea906Sjfb8856606 _rte_eth_dev_callback_process(eth_dev, 515d30ea906Sjfb8856606 RTE_ETH_EVENT_DESTROY, NULL); 516d30ea906Sjfb8856606 517d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock); 518d30ea906Sjfb8856606 519d30ea906Sjfb8856606 eth_dev->state = RTE_ETH_DEV_UNUSED; 520d30ea906Sjfb8856606 521d30ea906Sjfb8856606 if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 522d30ea906Sjfb8856606 rte_free(eth_dev->data->rx_queues); 523d30ea906Sjfb8856606 rte_free(eth_dev->data->tx_queues); 524d30ea906Sjfb8856606 rte_free(eth_dev->data->mac_addrs); 525d30ea906Sjfb8856606 rte_free(eth_dev->data->hash_mac_addrs); 526d30ea906Sjfb8856606 rte_free(eth_dev->data->dev_private); 527d30ea906Sjfb8856606 memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data)); 528d30ea906Sjfb8856606 } 529d30ea906Sjfb8856606 530d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock); 531d30ea906Sjfb8856606 532d30ea906Sjfb8856606 return 0; 533d30ea906Sjfb8856606 } 534d30ea906Sjfb8856606 535d30ea906Sjfb8856606 int 536d30ea906Sjfb8856606 rte_eth_dev_is_valid_port(uint16_t port_id) 537d30ea906Sjfb8856606 { 538d30ea906Sjfb8856606 if (port_id >= RTE_MAX_ETHPORTS || 539d30ea906Sjfb8856606 (rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED)) 540d30ea906Sjfb8856606 return 0; 541d30ea906Sjfb8856606 else 542d30ea906Sjfb8856606 return 1; 543d30ea906Sjfb8856606 } 544d30ea906Sjfb8856606 545d30ea906Sjfb8856606 static int 546d30ea906Sjfb8856606 rte_eth_is_valid_owner_id(uint64_t owner_id) 547d30ea906Sjfb8856606 { 548d30ea906Sjfb8856606 if (owner_id == RTE_ETH_DEV_NO_OWNER || 549d30ea906Sjfb8856606 rte_eth_dev_shared_data->next_owner_id <= owner_id) 550d30ea906Sjfb8856606 return 0; 551d30ea906Sjfb8856606 return 1; 552d30ea906Sjfb8856606 } 553d30ea906Sjfb8856606 554d30ea906Sjfb8856606 uint64_t 555d30ea906Sjfb8856606 rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id) 556d30ea906Sjfb8856606 { 557d30ea906Sjfb8856606 while (port_id < RTE_MAX_ETHPORTS && 558d30ea906Sjfb8856606 ((rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED && 559d30ea906Sjfb8856606 rte_eth_devices[port_id].state != RTE_ETH_DEV_REMOVED) || 560d30ea906Sjfb8856606 rte_eth_devices[port_id].data->owner.id != owner_id)) 561d30ea906Sjfb8856606 port_id++; 562d30ea906Sjfb8856606 563d30ea906Sjfb8856606 if (port_id >= RTE_MAX_ETHPORTS) 564d30ea906Sjfb8856606 return RTE_MAX_ETHPORTS; 565d30ea906Sjfb8856606 566d30ea906Sjfb8856606 return port_id; 567d30ea906Sjfb8856606 } 568d30ea906Sjfb8856606 569d30ea906Sjfb8856606 int __rte_experimental 570d30ea906Sjfb8856606 rte_eth_dev_owner_new(uint64_t *owner_id) 571d30ea906Sjfb8856606 { 572d30ea906Sjfb8856606 rte_eth_dev_shared_data_prepare(); 573d30ea906Sjfb8856606 574d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock); 575d30ea906Sjfb8856606 576d30ea906Sjfb8856606 *owner_id = rte_eth_dev_shared_data->next_owner_id++; 577d30ea906Sjfb8856606 578d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock); 579d30ea906Sjfb8856606 return 0; 580d30ea906Sjfb8856606 } 581d30ea906Sjfb8856606 582d30ea906Sjfb8856606 static int 583d30ea906Sjfb8856606 _rte_eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id, 584d30ea906Sjfb8856606 const struct rte_eth_dev_owner *new_owner) 585d30ea906Sjfb8856606 { 586d30ea906Sjfb8856606 struct rte_eth_dev *ethdev = &rte_eth_devices[port_id]; 587d30ea906Sjfb8856606 struct rte_eth_dev_owner *port_owner; 588d30ea906Sjfb8856606 int sret; 589d30ea906Sjfb8856606 590d30ea906Sjfb8856606 if (port_id >= RTE_MAX_ETHPORTS || !is_allocated(ethdev)) { 591d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n", 592d30ea906Sjfb8856606 port_id); 593d30ea906Sjfb8856606 return -ENODEV; 594d30ea906Sjfb8856606 } 595d30ea906Sjfb8856606 596d30ea906Sjfb8856606 if (!rte_eth_is_valid_owner_id(new_owner->id) && 597d30ea906Sjfb8856606 !rte_eth_is_valid_owner_id(old_owner_id)) { 598d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 599d30ea906Sjfb8856606 "Invalid owner old_id=%016"PRIx64" new_id=%016"PRIx64"\n", 600d30ea906Sjfb8856606 old_owner_id, new_owner->id); 601d30ea906Sjfb8856606 return -EINVAL; 602d30ea906Sjfb8856606 } 603d30ea906Sjfb8856606 604d30ea906Sjfb8856606 port_owner = &rte_eth_devices[port_id].data->owner; 605d30ea906Sjfb8856606 if (port_owner->id != old_owner_id) { 606d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 607d30ea906Sjfb8856606 "Cannot set owner to port %u already owned by %s_%016"PRIX64"\n", 608d30ea906Sjfb8856606 port_id, port_owner->name, port_owner->id); 609d30ea906Sjfb8856606 return -EPERM; 610d30ea906Sjfb8856606 } 611d30ea906Sjfb8856606 612d30ea906Sjfb8856606 sret = snprintf(port_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN, "%s", 613d30ea906Sjfb8856606 new_owner->name); 614d30ea906Sjfb8856606 if (sret < 0 || sret >= RTE_ETH_MAX_OWNER_NAME_LEN) 615d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port %u owner name was truncated\n", 616d30ea906Sjfb8856606 port_id); 617d30ea906Sjfb8856606 618d30ea906Sjfb8856606 port_owner->id = new_owner->id; 619d30ea906Sjfb8856606 620d30ea906Sjfb8856606 RTE_ETHDEV_LOG(DEBUG, "Port %u owner is %s_%016"PRIx64"\n", 621d30ea906Sjfb8856606 port_id, new_owner->name, new_owner->id); 622d30ea906Sjfb8856606 623d30ea906Sjfb8856606 return 0; 624d30ea906Sjfb8856606 } 625d30ea906Sjfb8856606 626d30ea906Sjfb8856606 int __rte_experimental 627d30ea906Sjfb8856606 rte_eth_dev_owner_set(const uint16_t port_id, 628d30ea906Sjfb8856606 const struct rte_eth_dev_owner *owner) 629d30ea906Sjfb8856606 { 630d30ea906Sjfb8856606 int ret; 631d30ea906Sjfb8856606 632d30ea906Sjfb8856606 rte_eth_dev_shared_data_prepare(); 633d30ea906Sjfb8856606 634d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock); 635d30ea906Sjfb8856606 636d30ea906Sjfb8856606 ret = _rte_eth_dev_owner_set(port_id, RTE_ETH_DEV_NO_OWNER, owner); 637d30ea906Sjfb8856606 638d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock); 639d30ea906Sjfb8856606 return ret; 640d30ea906Sjfb8856606 } 641d30ea906Sjfb8856606 642d30ea906Sjfb8856606 int __rte_experimental 643d30ea906Sjfb8856606 rte_eth_dev_owner_unset(const uint16_t port_id, const uint64_t owner_id) 644d30ea906Sjfb8856606 { 645d30ea906Sjfb8856606 const struct rte_eth_dev_owner new_owner = (struct rte_eth_dev_owner) 646d30ea906Sjfb8856606 {.id = RTE_ETH_DEV_NO_OWNER, .name = ""}; 647d30ea906Sjfb8856606 int ret; 648d30ea906Sjfb8856606 649d30ea906Sjfb8856606 rte_eth_dev_shared_data_prepare(); 650d30ea906Sjfb8856606 651d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock); 652d30ea906Sjfb8856606 653d30ea906Sjfb8856606 ret = _rte_eth_dev_owner_set(port_id, owner_id, &new_owner); 654d30ea906Sjfb8856606 655d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock); 656d30ea906Sjfb8856606 return ret; 657d30ea906Sjfb8856606 } 658d30ea906Sjfb8856606 659d30ea906Sjfb8856606 void __rte_experimental 660d30ea906Sjfb8856606 rte_eth_dev_owner_delete(const uint64_t owner_id) 661d30ea906Sjfb8856606 { 662d30ea906Sjfb8856606 uint16_t port_id; 663d30ea906Sjfb8856606 664d30ea906Sjfb8856606 rte_eth_dev_shared_data_prepare(); 665d30ea906Sjfb8856606 666d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock); 667d30ea906Sjfb8856606 668d30ea906Sjfb8856606 if (rte_eth_is_valid_owner_id(owner_id)) { 669d30ea906Sjfb8856606 for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) 670d30ea906Sjfb8856606 if (rte_eth_devices[port_id].data->owner.id == owner_id) 671d30ea906Sjfb8856606 memset(&rte_eth_devices[port_id].data->owner, 0, 672d30ea906Sjfb8856606 sizeof(struct rte_eth_dev_owner)); 673d30ea906Sjfb8856606 RTE_ETHDEV_LOG(NOTICE, 674d30ea906Sjfb8856606 "All port owners owned by %016"PRIx64" identifier have removed\n", 675d30ea906Sjfb8856606 owner_id); 676d30ea906Sjfb8856606 } else { 677d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 678d30ea906Sjfb8856606 "Invalid owner id=%016"PRIx64"\n", 679d30ea906Sjfb8856606 owner_id); 680d30ea906Sjfb8856606 } 681d30ea906Sjfb8856606 682d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock); 683d30ea906Sjfb8856606 } 684d30ea906Sjfb8856606 685d30ea906Sjfb8856606 int __rte_experimental 686d30ea906Sjfb8856606 rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner) 687d30ea906Sjfb8856606 { 688d30ea906Sjfb8856606 int ret = 0; 689d30ea906Sjfb8856606 struct rte_eth_dev *ethdev = &rte_eth_devices[port_id]; 690d30ea906Sjfb8856606 691d30ea906Sjfb8856606 rte_eth_dev_shared_data_prepare(); 692d30ea906Sjfb8856606 693d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock); 694d30ea906Sjfb8856606 695d30ea906Sjfb8856606 if (port_id >= RTE_MAX_ETHPORTS || !is_allocated(ethdev)) { 696d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n", 697d30ea906Sjfb8856606 port_id); 698d30ea906Sjfb8856606 ret = -ENODEV; 699d30ea906Sjfb8856606 } else { 700d30ea906Sjfb8856606 rte_memcpy(owner, ðdev->data->owner, sizeof(*owner)); 701d30ea906Sjfb8856606 } 702d30ea906Sjfb8856606 703d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock); 704d30ea906Sjfb8856606 return ret; 705d30ea906Sjfb8856606 } 706d30ea906Sjfb8856606 707d30ea906Sjfb8856606 int 708d30ea906Sjfb8856606 rte_eth_dev_socket_id(uint16_t port_id) 709d30ea906Sjfb8856606 { 710d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); 711d30ea906Sjfb8856606 return rte_eth_devices[port_id].data->numa_node; 712d30ea906Sjfb8856606 } 713d30ea906Sjfb8856606 714d30ea906Sjfb8856606 void * 715d30ea906Sjfb8856606 rte_eth_dev_get_sec_ctx(uint16_t port_id) 716d30ea906Sjfb8856606 { 717d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL); 718d30ea906Sjfb8856606 return rte_eth_devices[port_id].security_ctx; 719d30ea906Sjfb8856606 } 720d30ea906Sjfb8856606 721d30ea906Sjfb8856606 uint16_t 722d30ea906Sjfb8856606 rte_eth_dev_count(void) 723d30ea906Sjfb8856606 { 724d30ea906Sjfb8856606 return rte_eth_dev_count_avail(); 725d30ea906Sjfb8856606 } 726d30ea906Sjfb8856606 727d30ea906Sjfb8856606 uint16_t 728d30ea906Sjfb8856606 rte_eth_dev_count_avail(void) 729d30ea906Sjfb8856606 { 730d30ea906Sjfb8856606 uint16_t p; 731d30ea906Sjfb8856606 uint16_t count; 732d30ea906Sjfb8856606 733d30ea906Sjfb8856606 count = 0; 734d30ea906Sjfb8856606 735d30ea906Sjfb8856606 RTE_ETH_FOREACH_DEV(p) 736d30ea906Sjfb8856606 count++; 737d30ea906Sjfb8856606 738d30ea906Sjfb8856606 return count; 739d30ea906Sjfb8856606 } 740d30ea906Sjfb8856606 741d30ea906Sjfb8856606 uint16_t __rte_experimental 742d30ea906Sjfb8856606 rte_eth_dev_count_total(void) 743d30ea906Sjfb8856606 { 744d30ea906Sjfb8856606 uint16_t port, count = 0; 745d30ea906Sjfb8856606 746d30ea906Sjfb8856606 for (port = 0; port < RTE_MAX_ETHPORTS; port++) 747d30ea906Sjfb8856606 if (rte_eth_devices[port].state != RTE_ETH_DEV_UNUSED) 748d30ea906Sjfb8856606 count++; 749d30ea906Sjfb8856606 750d30ea906Sjfb8856606 return count; 751d30ea906Sjfb8856606 } 752d30ea906Sjfb8856606 753d30ea906Sjfb8856606 int 754d30ea906Sjfb8856606 rte_eth_dev_get_name_by_port(uint16_t port_id, char *name) 755d30ea906Sjfb8856606 { 756d30ea906Sjfb8856606 char *tmp; 757d30ea906Sjfb8856606 758d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 759d30ea906Sjfb8856606 760d30ea906Sjfb8856606 if (name == NULL) { 761d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n"); 762d30ea906Sjfb8856606 return -EINVAL; 763d30ea906Sjfb8856606 } 764d30ea906Sjfb8856606 765d30ea906Sjfb8856606 /* shouldn't check 'rte_eth_devices[i].data', 766d30ea906Sjfb8856606 * because it might be overwritten by VDEV PMD */ 767d30ea906Sjfb8856606 tmp = rte_eth_dev_shared_data->data[port_id].name; 768d30ea906Sjfb8856606 strcpy(name, tmp); 769d30ea906Sjfb8856606 return 0; 770d30ea906Sjfb8856606 } 771d30ea906Sjfb8856606 772d30ea906Sjfb8856606 int 773d30ea906Sjfb8856606 rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id) 774d30ea906Sjfb8856606 { 775d30ea906Sjfb8856606 uint32_t pid; 776d30ea906Sjfb8856606 777d30ea906Sjfb8856606 if (name == NULL) { 778d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n"); 779d30ea906Sjfb8856606 return -EINVAL; 780d30ea906Sjfb8856606 } 781d30ea906Sjfb8856606 782d30ea906Sjfb8856606 for (pid = 0; pid < RTE_MAX_ETHPORTS; pid++) { 783d30ea906Sjfb8856606 if (rte_eth_devices[pid].state != RTE_ETH_DEV_UNUSED && 784d30ea906Sjfb8856606 !strcmp(name, rte_eth_dev_shared_data->data[pid].name)) { 785d30ea906Sjfb8856606 *port_id = pid; 786d30ea906Sjfb8856606 return 0; 787d30ea906Sjfb8856606 } 788d30ea906Sjfb8856606 } 789d30ea906Sjfb8856606 790d30ea906Sjfb8856606 return -ENODEV; 791d30ea906Sjfb8856606 } 792d30ea906Sjfb8856606 793d30ea906Sjfb8856606 static int 794d30ea906Sjfb8856606 eth_err(uint16_t port_id, int ret) 795d30ea906Sjfb8856606 { 796d30ea906Sjfb8856606 if (ret == 0) 797d30ea906Sjfb8856606 return 0; 798d30ea906Sjfb8856606 if (rte_eth_dev_is_removed(port_id)) 799d30ea906Sjfb8856606 return -EIO; 800d30ea906Sjfb8856606 return ret; 801d30ea906Sjfb8856606 } 802d30ea906Sjfb8856606 803d30ea906Sjfb8856606 static int 804d30ea906Sjfb8856606 rte_eth_dev_rx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues) 805d30ea906Sjfb8856606 { 806d30ea906Sjfb8856606 uint16_t old_nb_queues = dev->data->nb_rx_queues; 807d30ea906Sjfb8856606 void **rxq; 808d30ea906Sjfb8856606 unsigned i; 809d30ea906Sjfb8856606 810d30ea906Sjfb8856606 if (dev->data->rx_queues == NULL && nb_queues != 0) { /* first time configuration */ 811d30ea906Sjfb8856606 dev->data->rx_queues = rte_zmalloc("ethdev->rx_queues", 812d30ea906Sjfb8856606 sizeof(dev->data->rx_queues[0]) * nb_queues, 813d30ea906Sjfb8856606 RTE_CACHE_LINE_SIZE); 814d30ea906Sjfb8856606 if (dev->data->rx_queues == NULL) { 815d30ea906Sjfb8856606 dev->data->nb_rx_queues = 0; 816d30ea906Sjfb8856606 return -(ENOMEM); 817d30ea906Sjfb8856606 } 818d30ea906Sjfb8856606 } else if (dev->data->rx_queues != NULL && nb_queues != 0) { /* re-configure */ 819d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_release, -ENOTSUP); 820d30ea906Sjfb8856606 821d30ea906Sjfb8856606 rxq = dev->data->rx_queues; 822d30ea906Sjfb8856606 823d30ea906Sjfb8856606 for (i = nb_queues; i < old_nb_queues; i++) 824d30ea906Sjfb8856606 (*dev->dev_ops->rx_queue_release)(rxq[i]); 825d30ea906Sjfb8856606 rxq = rte_realloc(rxq, sizeof(rxq[0]) * nb_queues, 826d30ea906Sjfb8856606 RTE_CACHE_LINE_SIZE); 827d30ea906Sjfb8856606 if (rxq == NULL) 828d30ea906Sjfb8856606 return -(ENOMEM); 829d30ea906Sjfb8856606 if (nb_queues > old_nb_queues) { 830d30ea906Sjfb8856606 uint16_t new_qs = nb_queues - old_nb_queues; 831d30ea906Sjfb8856606 832d30ea906Sjfb8856606 memset(rxq + old_nb_queues, 0, 833d30ea906Sjfb8856606 sizeof(rxq[0]) * new_qs); 834d30ea906Sjfb8856606 } 835d30ea906Sjfb8856606 836d30ea906Sjfb8856606 dev->data->rx_queues = rxq; 837d30ea906Sjfb8856606 838d30ea906Sjfb8856606 } else if (dev->data->rx_queues != NULL && nb_queues == 0) { 839d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_release, -ENOTSUP); 840d30ea906Sjfb8856606 841d30ea906Sjfb8856606 rxq = dev->data->rx_queues; 842d30ea906Sjfb8856606 843d30ea906Sjfb8856606 for (i = nb_queues; i < old_nb_queues; i++) 844d30ea906Sjfb8856606 (*dev->dev_ops->rx_queue_release)(rxq[i]); 845d30ea906Sjfb8856606 846d30ea906Sjfb8856606 rte_free(dev->data->rx_queues); 847d30ea906Sjfb8856606 dev->data->rx_queues = NULL; 848d30ea906Sjfb8856606 } 849d30ea906Sjfb8856606 dev->data->nb_rx_queues = nb_queues; 850d30ea906Sjfb8856606 return 0; 851d30ea906Sjfb8856606 } 852d30ea906Sjfb8856606 853d30ea906Sjfb8856606 int 854d30ea906Sjfb8856606 rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id) 855d30ea906Sjfb8856606 { 856d30ea906Sjfb8856606 struct rte_eth_dev *dev; 857d30ea906Sjfb8856606 858d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 859d30ea906Sjfb8856606 860d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 861d30ea906Sjfb8856606 if (!dev->data->dev_started) { 862d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 863d30ea906Sjfb8856606 "Port %u must be started before start any queue\n", 864d30ea906Sjfb8856606 port_id); 865d30ea906Sjfb8856606 return -EINVAL; 866d30ea906Sjfb8856606 } 867d30ea906Sjfb8856606 868d30ea906Sjfb8856606 if (rx_queue_id >= dev->data->nb_rx_queues) { 869d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id); 870d30ea906Sjfb8856606 return -EINVAL; 871d30ea906Sjfb8856606 } 872d30ea906Sjfb8856606 873d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_start, -ENOTSUP); 874d30ea906Sjfb8856606 875d30ea906Sjfb8856606 if (dev->data->rx_queue_state[rx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) { 876d30ea906Sjfb8856606 RTE_ETHDEV_LOG(INFO, 877d30ea906Sjfb8856606 "Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n", 878d30ea906Sjfb8856606 rx_queue_id, port_id); 879d30ea906Sjfb8856606 return 0; 880d30ea906Sjfb8856606 } 881d30ea906Sjfb8856606 882d30ea906Sjfb8856606 return eth_err(port_id, dev->dev_ops->rx_queue_start(dev, 883d30ea906Sjfb8856606 rx_queue_id)); 884d30ea906Sjfb8856606 885d30ea906Sjfb8856606 } 886d30ea906Sjfb8856606 887d30ea906Sjfb8856606 int 888d30ea906Sjfb8856606 rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id) 889d30ea906Sjfb8856606 { 890d30ea906Sjfb8856606 struct rte_eth_dev *dev; 891d30ea906Sjfb8856606 892d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 893d30ea906Sjfb8856606 894d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 895d30ea906Sjfb8856606 if (rx_queue_id >= dev->data->nb_rx_queues) { 896d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id); 897d30ea906Sjfb8856606 return -EINVAL; 898d30ea906Sjfb8856606 } 899d30ea906Sjfb8856606 900d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_stop, -ENOTSUP); 901d30ea906Sjfb8856606 902d30ea906Sjfb8856606 if (dev->data->rx_queue_state[rx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) { 903d30ea906Sjfb8856606 RTE_ETHDEV_LOG(INFO, 904d30ea906Sjfb8856606 "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n", 905d30ea906Sjfb8856606 rx_queue_id, port_id); 906d30ea906Sjfb8856606 return 0; 907d30ea906Sjfb8856606 } 908d30ea906Sjfb8856606 909d30ea906Sjfb8856606 return eth_err(port_id, dev->dev_ops->rx_queue_stop(dev, rx_queue_id)); 910d30ea906Sjfb8856606 911d30ea906Sjfb8856606 } 912d30ea906Sjfb8856606 913d30ea906Sjfb8856606 int 914d30ea906Sjfb8856606 rte_eth_dev_tx_queue_start(uint16_t port_id, uint16_t tx_queue_id) 915d30ea906Sjfb8856606 { 916d30ea906Sjfb8856606 struct rte_eth_dev *dev; 917d30ea906Sjfb8856606 918d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 919d30ea906Sjfb8856606 920d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 921d30ea906Sjfb8856606 if (!dev->data->dev_started) { 922d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 923d30ea906Sjfb8856606 "Port %u must be started before start any queue\n", 924d30ea906Sjfb8856606 port_id); 925d30ea906Sjfb8856606 return -EINVAL; 926d30ea906Sjfb8856606 } 927d30ea906Sjfb8856606 928d30ea906Sjfb8856606 if (tx_queue_id >= dev->data->nb_tx_queues) { 929d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id); 930d30ea906Sjfb8856606 return -EINVAL; 931d30ea906Sjfb8856606 } 932d30ea906Sjfb8856606 933d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_start, -ENOTSUP); 934d30ea906Sjfb8856606 935d30ea906Sjfb8856606 if (dev->data->tx_queue_state[tx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) { 936d30ea906Sjfb8856606 RTE_ETHDEV_LOG(INFO, 937d30ea906Sjfb8856606 "Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n", 938d30ea906Sjfb8856606 tx_queue_id, port_id); 939d30ea906Sjfb8856606 return 0; 940d30ea906Sjfb8856606 } 941d30ea906Sjfb8856606 942d30ea906Sjfb8856606 return eth_err(port_id, dev->dev_ops->tx_queue_start(dev, tx_queue_id)); 943d30ea906Sjfb8856606 } 944d30ea906Sjfb8856606 945d30ea906Sjfb8856606 int 946d30ea906Sjfb8856606 rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id) 947d30ea906Sjfb8856606 { 948d30ea906Sjfb8856606 struct rte_eth_dev *dev; 949d30ea906Sjfb8856606 950d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 951d30ea906Sjfb8856606 952d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 953d30ea906Sjfb8856606 if (tx_queue_id >= dev->data->nb_tx_queues) { 954d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id); 955d30ea906Sjfb8856606 return -EINVAL; 956d30ea906Sjfb8856606 } 957d30ea906Sjfb8856606 958d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_stop, -ENOTSUP); 959d30ea906Sjfb8856606 960d30ea906Sjfb8856606 if (dev->data->tx_queue_state[tx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) { 961d30ea906Sjfb8856606 RTE_ETHDEV_LOG(INFO, 962d30ea906Sjfb8856606 "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n", 963d30ea906Sjfb8856606 tx_queue_id, port_id); 964d30ea906Sjfb8856606 return 0; 965d30ea906Sjfb8856606 } 966d30ea906Sjfb8856606 967d30ea906Sjfb8856606 return eth_err(port_id, dev->dev_ops->tx_queue_stop(dev, tx_queue_id)); 968d30ea906Sjfb8856606 969d30ea906Sjfb8856606 } 970d30ea906Sjfb8856606 971d30ea906Sjfb8856606 static int 972d30ea906Sjfb8856606 rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues) 973d30ea906Sjfb8856606 { 974d30ea906Sjfb8856606 uint16_t old_nb_queues = dev->data->nb_tx_queues; 975d30ea906Sjfb8856606 void **txq; 976d30ea906Sjfb8856606 unsigned i; 977d30ea906Sjfb8856606 978d30ea906Sjfb8856606 if (dev->data->tx_queues == NULL && nb_queues != 0) { /* first time configuration */ 979d30ea906Sjfb8856606 dev->data->tx_queues = rte_zmalloc("ethdev->tx_queues", 980d30ea906Sjfb8856606 sizeof(dev->data->tx_queues[0]) * nb_queues, 981d30ea906Sjfb8856606 RTE_CACHE_LINE_SIZE); 982d30ea906Sjfb8856606 if (dev->data->tx_queues == NULL) { 983d30ea906Sjfb8856606 dev->data->nb_tx_queues = 0; 984d30ea906Sjfb8856606 return -(ENOMEM); 985d30ea906Sjfb8856606 } 986d30ea906Sjfb8856606 } else if (dev->data->tx_queues != NULL && nb_queues != 0) { /* re-configure */ 987d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_release, -ENOTSUP); 988d30ea906Sjfb8856606 989d30ea906Sjfb8856606 txq = dev->data->tx_queues; 990d30ea906Sjfb8856606 991d30ea906Sjfb8856606 for (i = nb_queues; i < old_nb_queues; i++) 992d30ea906Sjfb8856606 (*dev->dev_ops->tx_queue_release)(txq[i]); 993d30ea906Sjfb8856606 txq = rte_realloc(txq, sizeof(txq[0]) * nb_queues, 994d30ea906Sjfb8856606 RTE_CACHE_LINE_SIZE); 995d30ea906Sjfb8856606 if (txq == NULL) 996d30ea906Sjfb8856606 return -ENOMEM; 997d30ea906Sjfb8856606 if (nb_queues > old_nb_queues) { 998d30ea906Sjfb8856606 uint16_t new_qs = nb_queues - old_nb_queues; 999d30ea906Sjfb8856606 1000d30ea906Sjfb8856606 memset(txq + old_nb_queues, 0, 1001d30ea906Sjfb8856606 sizeof(txq[0]) * new_qs); 1002d30ea906Sjfb8856606 } 1003d30ea906Sjfb8856606 1004d30ea906Sjfb8856606 dev->data->tx_queues = txq; 1005d30ea906Sjfb8856606 1006d30ea906Sjfb8856606 } else if (dev->data->tx_queues != NULL && nb_queues == 0) { 1007d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_release, -ENOTSUP); 1008d30ea906Sjfb8856606 1009d30ea906Sjfb8856606 txq = dev->data->tx_queues; 1010d30ea906Sjfb8856606 1011d30ea906Sjfb8856606 for (i = nb_queues; i < old_nb_queues; i++) 1012d30ea906Sjfb8856606 (*dev->dev_ops->tx_queue_release)(txq[i]); 1013d30ea906Sjfb8856606 1014d30ea906Sjfb8856606 rte_free(dev->data->tx_queues); 1015d30ea906Sjfb8856606 dev->data->tx_queues = NULL; 1016d30ea906Sjfb8856606 } 1017d30ea906Sjfb8856606 dev->data->nb_tx_queues = nb_queues; 1018d30ea906Sjfb8856606 return 0; 1019d30ea906Sjfb8856606 } 1020d30ea906Sjfb8856606 1021d30ea906Sjfb8856606 uint32_t 1022d30ea906Sjfb8856606 rte_eth_speed_bitflag(uint32_t speed, int duplex) 1023d30ea906Sjfb8856606 { 1024d30ea906Sjfb8856606 switch (speed) { 1025d30ea906Sjfb8856606 case ETH_SPEED_NUM_10M: 1026d30ea906Sjfb8856606 return duplex ? ETH_LINK_SPEED_10M : ETH_LINK_SPEED_10M_HD; 1027d30ea906Sjfb8856606 case ETH_SPEED_NUM_100M: 1028d30ea906Sjfb8856606 return duplex ? ETH_LINK_SPEED_100M : ETH_LINK_SPEED_100M_HD; 1029d30ea906Sjfb8856606 case ETH_SPEED_NUM_1G: 1030d30ea906Sjfb8856606 return ETH_LINK_SPEED_1G; 1031d30ea906Sjfb8856606 case ETH_SPEED_NUM_2_5G: 1032d30ea906Sjfb8856606 return ETH_LINK_SPEED_2_5G; 1033d30ea906Sjfb8856606 case ETH_SPEED_NUM_5G: 1034d30ea906Sjfb8856606 return ETH_LINK_SPEED_5G; 1035d30ea906Sjfb8856606 case ETH_SPEED_NUM_10G: 1036d30ea906Sjfb8856606 return ETH_LINK_SPEED_10G; 1037d30ea906Sjfb8856606 case ETH_SPEED_NUM_20G: 1038d30ea906Sjfb8856606 return ETH_LINK_SPEED_20G; 1039d30ea906Sjfb8856606 case ETH_SPEED_NUM_25G: 1040d30ea906Sjfb8856606 return ETH_LINK_SPEED_25G; 1041d30ea906Sjfb8856606 case ETH_SPEED_NUM_40G: 1042d30ea906Sjfb8856606 return ETH_LINK_SPEED_40G; 1043d30ea906Sjfb8856606 case ETH_SPEED_NUM_50G: 1044d30ea906Sjfb8856606 return ETH_LINK_SPEED_50G; 1045d30ea906Sjfb8856606 case ETH_SPEED_NUM_56G: 1046d30ea906Sjfb8856606 return ETH_LINK_SPEED_56G; 1047d30ea906Sjfb8856606 case ETH_SPEED_NUM_100G: 1048d30ea906Sjfb8856606 return ETH_LINK_SPEED_100G; 1049d30ea906Sjfb8856606 default: 1050d30ea906Sjfb8856606 return 0; 1051d30ea906Sjfb8856606 } 1052d30ea906Sjfb8856606 } 1053d30ea906Sjfb8856606 1054d30ea906Sjfb8856606 const char * 1055d30ea906Sjfb8856606 rte_eth_dev_rx_offload_name(uint64_t offload) 1056d30ea906Sjfb8856606 { 1057d30ea906Sjfb8856606 const char *name = "UNKNOWN"; 1058d30ea906Sjfb8856606 unsigned int i; 1059d30ea906Sjfb8856606 1060d30ea906Sjfb8856606 for (i = 0; i < RTE_DIM(rte_rx_offload_names); ++i) { 1061d30ea906Sjfb8856606 if (offload == rte_rx_offload_names[i].offload) { 1062d30ea906Sjfb8856606 name = rte_rx_offload_names[i].name; 1063d30ea906Sjfb8856606 break; 1064d30ea906Sjfb8856606 } 1065d30ea906Sjfb8856606 } 1066d30ea906Sjfb8856606 1067d30ea906Sjfb8856606 return name; 1068d30ea906Sjfb8856606 } 1069d30ea906Sjfb8856606 1070d30ea906Sjfb8856606 const char * 1071d30ea906Sjfb8856606 rte_eth_dev_tx_offload_name(uint64_t offload) 1072d30ea906Sjfb8856606 { 1073d30ea906Sjfb8856606 const char *name = "UNKNOWN"; 1074d30ea906Sjfb8856606 unsigned int i; 1075d30ea906Sjfb8856606 1076d30ea906Sjfb8856606 for (i = 0; i < RTE_DIM(rte_tx_offload_names); ++i) { 1077d30ea906Sjfb8856606 if (offload == rte_tx_offload_names[i].offload) { 1078d30ea906Sjfb8856606 name = rte_tx_offload_names[i].name; 1079d30ea906Sjfb8856606 break; 1080d30ea906Sjfb8856606 } 1081d30ea906Sjfb8856606 } 1082d30ea906Sjfb8856606 1083d30ea906Sjfb8856606 return name; 1084d30ea906Sjfb8856606 } 1085d30ea906Sjfb8856606 1086d30ea906Sjfb8856606 int 1087d30ea906Sjfb8856606 rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, 1088d30ea906Sjfb8856606 const struct rte_eth_conf *dev_conf) 1089d30ea906Sjfb8856606 { 1090d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1091d30ea906Sjfb8856606 struct rte_eth_dev_info dev_info; 1092d30ea906Sjfb8856606 struct rte_eth_conf orig_conf; 1093d30ea906Sjfb8856606 int diag; 1094d30ea906Sjfb8856606 int ret; 1095d30ea906Sjfb8856606 1096d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 1097d30ea906Sjfb8856606 1098d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1099d30ea906Sjfb8856606 1100d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP); 1101d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP); 1102d30ea906Sjfb8856606 1103d30ea906Sjfb8856606 if (dev->data->dev_started) { 1104d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1105d30ea906Sjfb8856606 "Port %u must be stopped to allow configuration\n", 1106d30ea906Sjfb8856606 port_id); 1107d30ea906Sjfb8856606 return -EBUSY; 1108d30ea906Sjfb8856606 } 1109d30ea906Sjfb8856606 1110d30ea906Sjfb8856606 /* Store original config, as rollback required on failure */ 1111d30ea906Sjfb8856606 memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf)); 1112d30ea906Sjfb8856606 1113d30ea906Sjfb8856606 /* 1114d30ea906Sjfb8856606 * Copy the dev_conf parameter into the dev structure. 1115d30ea906Sjfb8856606 * rte_eth_dev_info_get() requires dev_conf, copy it before dev_info get 1116d30ea906Sjfb8856606 */ 1117d30ea906Sjfb8856606 memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf)); 1118d30ea906Sjfb8856606 1119d30ea906Sjfb8856606 rte_eth_dev_info_get(port_id, &dev_info); 1120d30ea906Sjfb8856606 1121d30ea906Sjfb8856606 /* If number of queues specified by application for both Rx and Tx is 1122d30ea906Sjfb8856606 * zero, use driver preferred values. This cannot be done individually 1123d30ea906Sjfb8856606 * as it is valid for either Tx or Rx (but not both) to be zero. 1124d30ea906Sjfb8856606 * If driver does not provide any preferred valued, fall back on 1125d30ea906Sjfb8856606 * EAL defaults. 1126d30ea906Sjfb8856606 */ 1127d30ea906Sjfb8856606 if (nb_rx_q == 0 && nb_tx_q == 0) { 1128d30ea906Sjfb8856606 nb_rx_q = dev_info.default_rxportconf.nb_queues; 1129d30ea906Sjfb8856606 if (nb_rx_q == 0) 1130d30ea906Sjfb8856606 nb_rx_q = RTE_ETH_DEV_FALLBACK_RX_NBQUEUES; 1131d30ea906Sjfb8856606 nb_tx_q = dev_info.default_txportconf.nb_queues; 1132d30ea906Sjfb8856606 if (nb_tx_q == 0) 1133d30ea906Sjfb8856606 nb_tx_q = RTE_ETH_DEV_FALLBACK_TX_NBQUEUES; 1134d30ea906Sjfb8856606 } 1135d30ea906Sjfb8856606 1136d30ea906Sjfb8856606 if (nb_rx_q > RTE_MAX_QUEUES_PER_PORT) { 1137d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1138d30ea906Sjfb8856606 "Number of RX queues requested (%u) is greater than max supported(%d)\n", 1139d30ea906Sjfb8856606 nb_rx_q, RTE_MAX_QUEUES_PER_PORT); 1140d30ea906Sjfb8856606 ret = -EINVAL; 1141d30ea906Sjfb8856606 goto rollback; 1142d30ea906Sjfb8856606 } 1143d30ea906Sjfb8856606 1144d30ea906Sjfb8856606 if (nb_tx_q > RTE_MAX_QUEUES_PER_PORT) { 1145d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1146d30ea906Sjfb8856606 "Number of TX queues requested (%u) is greater than max supported(%d)\n", 1147d30ea906Sjfb8856606 nb_tx_q, RTE_MAX_QUEUES_PER_PORT); 1148d30ea906Sjfb8856606 ret = -EINVAL; 1149d30ea906Sjfb8856606 goto rollback; 1150d30ea906Sjfb8856606 } 1151d30ea906Sjfb8856606 1152d30ea906Sjfb8856606 /* 1153d30ea906Sjfb8856606 * Check that the numbers of RX and TX queues are not greater 1154d30ea906Sjfb8856606 * than the maximum number of RX and TX queues supported by the 1155d30ea906Sjfb8856606 * configured device. 1156d30ea906Sjfb8856606 */ 1157d30ea906Sjfb8856606 if (nb_rx_q > dev_info.max_rx_queues) { 1158d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_rx_queues=%u > %u\n", 1159d30ea906Sjfb8856606 port_id, nb_rx_q, dev_info.max_rx_queues); 1160d30ea906Sjfb8856606 ret = -EINVAL; 1161d30ea906Sjfb8856606 goto rollback; 1162d30ea906Sjfb8856606 } 1163d30ea906Sjfb8856606 1164d30ea906Sjfb8856606 if (nb_tx_q > dev_info.max_tx_queues) { 1165d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_tx_queues=%u > %u\n", 1166d30ea906Sjfb8856606 port_id, nb_tx_q, dev_info.max_tx_queues); 1167d30ea906Sjfb8856606 ret = -EINVAL; 1168d30ea906Sjfb8856606 goto rollback; 1169d30ea906Sjfb8856606 } 1170d30ea906Sjfb8856606 1171d30ea906Sjfb8856606 /* Check that the device supports requested interrupts */ 1172d30ea906Sjfb8856606 if ((dev_conf->intr_conf.lsc == 1) && 1173d30ea906Sjfb8856606 (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) { 1174d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Driver %s does not support lsc\n", 1175d30ea906Sjfb8856606 dev->device->driver->name); 1176d30ea906Sjfb8856606 ret = -EINVAL; 1177d30ea906Sjfb8856606 goto rollback; 1178d30ea906Sjfb8856606 } 1179d30ea906Sjfb8856606 if ((dev_conf->intr_conf.rmv == 1) && 1180d30ea906Sjfb8856606 (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) { 1181d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Driver %s does not support rmv\n", 1182d30ea906Sjfb8856606 dev->device->driver->name); 1183d30ea906Sjfb8856606 ret = -EINVAL; 1184d30ea906Sjfb8856606 goto rollback; 1185d30ea906Sjfb8856606 } 1186d30ea906Sjfb8856606 1187d30ea906Sjfb8856606 /* 1188d30ea906Sjfb8856606 * If jumbo frames are enabled, check that the maximum RX packet 1189d30ea906Sjfb8856606 * length is supported by the configured device. 1190d30ea906Sjfb8856606 */ 1191d30ea906Sjfb8856606 if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { 1192d30ea906Sjfb8856606 if (dev_conf->rxmode.max_rx_pkt_len > dev_info.max_rx_pktlen) { 1193d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1194d30ea906Sjfb8856606 "Ethdev port_id=%u max_rx_pkt_len %u > max valid value %u\n", 1195d30ea906Sjfb8856606 port_id, dev_conf->rxmode.max_rx_pkt_len, 1196d30ea906Sjfb8856606 dev_info.max_rx_pktlen); 1197d30ea906Sjfb8856606 ret = -EINVAL; 1198d30ea906Sjfb8856606 goto rollback; 1199d30ea906Sjfb8856606 } else if (dev_conf->rxmode.max_rx_pkt_len < ETHER_MIN_LEN) { 1200d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1201d30ea906Sjfb8856606 "Ethdev port_id=%u max_rx_pkt_len %u < min valid value %u\n", 1202d30ea906Sjfb8856606 port_id, dev_conf->rxmode.max_rx_pkt_len, 1203d30ea906Sjfb8856606 (unsigned)ETHER_MIN_LEN); 1204d30ea906Sjfb8856606 ret = -EINVAL; 1205d30ea906Sjfb8856606 goto rollback; 1206d30ea906Sjfb8856606 } 1207d30ea906Sjfb8856606 } else { 1208d30ea906Sjfb8856606 if (dev_conf->rxmode.max_rx_pkt_len < ETHER_MIN_LEN || 1209d30ea906Sjfb8856606 dev_conf->rxmode.max_rx_pkt_len > ETHER_MAX_LEN) 1210d30ea906Sjfb8856606 /* Use default value */ 1211d30ea906Sjfb8856606 dev->data->dev_conf.rxmode.max_rx_pkt_len = 1212d30ea906Sjfb8856606 ETHER_MAX_LEN; 1213d30ea906Sjfb8856606 } 1214d30ea906Sjfb8856606 1215d30ea906Sjfb8856606 /* Any requested offloading must be within its device capabilities */ 1216d30ea906Sjfb8856606 if ((dev_conf->rxmode.offloads & dev_info.rx_offload_capa) != 1217d30ea906Sjfb8856606 dev_conf->rxmode.offloads) { 1218d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1219d30ea906Sjfb8856606 "Ethdev port_id=%u requested Rx offloads 0x%"PRIx64" doesn't match Rx offloads " 1220d30ea906Sjfb8856606 "capabilities 0x%"PRIx64" in %s()\n", 1221d30ea906Sjfb8856606 port_id, dev_conf->rxmode.offloads, 1222d30ea906Sjfb8856606 dev_info.rx_offload_capa, 1223d30ea906Sjfb8856606 __func__); 1224d30ea906Sjfb8856606 ret = -EINVAL; 1225d30ea906Sjfb8856606 goto rollback; 1226d30ea906Sjfb8856606 } 1227d30ea906Sjfb8856606 if ((dev_conf->txmode.offloads & dev_info.tx_offload_capa) != 1228d30ea906Sjfb8856606 dev_conf->txmode.offloads) { 1229d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1230d30ea906Sjfb8856606 "Ethdev port_id=%u requested Tx offloads 0x%"PRIx64" doesn't match Tx offloads " 1231d30ea906Sjfb8856606 "capabilities 0x%"PRIx64" in %s()\n", 1232d30ea906Sjfb8856606 port_id, dev_conf->txmode.offloads, 1233d30ea906Sjfb8856606 dev_info.tx_offload_capa, 1234d30ea906Sjfb8856606 __func__); 1235d30ea906Sjfb8856606 ret = -EINVAL; 1236d30ea906Sjfb8856606 goto rollback; 1237d30ea906Sjfb8856606 } 1238d30ea906Sjfb8856606 1239d30ea906Sjfb8856606 /* Check that device supports requested rss hash functions. */ 1240d30ea906Sjfb8856606 if ((dev_info.flow_type_rss_offloads | 1241d30ea906Sjfb8856606 dev_conf->rx_adv_conf.rss_conf.rss_hf) != 1242d30ea906Sjfb8856606 dev_info.flow_type_rss_offloads) { 1243d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1244d30ea906Sjfb8856606 "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n", 1245d30ea906Sjfb8856606 port_id, dev_conf->rx_adv_conf.rss_conf.rss_hf, 1246d30ea906Sjfb8856606 dev_info.flow_type_rss_offloads); 1247d30ea906Sjfb8856606 ret = -EINVAL; 1248d30ea906Sjfb8856606 goto rollback; 1249d30ea906Sjfb8856606 } 1250d30ea906Sjfb8856606 1251d30ea906Sjfb8856606 /* 1252d30ea906Sjfb8856606 * Setup new number of RX/TX queues and reconfigure device. 1253d30ea906Sjfb8856606 */ 1254d30ea906Sjfb8856606 diag = rte_eth_dev_rx_queue_config(dev, nb_rx_q); 1255d30ea906Sjfb8856606 if (diag != 0) { 1256d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1257d30ea906Sjfb8856606 "Port%u rte_eth_dev_rx_queue_config = %d\n", 1258d30ea906Sjfb8856606 port_id, diag); 1259d30ea906Sjfb8856606 ret = diag; 1260d30ea906Sjfb8856606 goto rollback; 1261d30ea906Sjfb8856606 } 1262d30ea906Sjfb8856606 1263d30ea906Sjfb8856606 diag = rte_eth_dev_tx_queue_config(dev, nb_tx_q); 1264d30ea906Sjfb8856606 if (diag != 0) { 1265d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1266d30ea906Sjfb8856606 "Port%u rte_eth_dev_tx_queue_config = %d\n", 1267d30ea906Sjfb8856606 port_id, diag); 1268d30ea906Sjfb8856606 rte_eth_dev_rx_queue_config(dev, 0); 1269d30ea906Sjfb8856606 ret = diag; 1270d30ea906Sjfb8856606 goto rollback; 1271d30ea906Sjfb8856606 } 1272d30ea906Sjfb8856606 1273d30ea906Sjfb8856606 diag = (*dev->dev_ops->dev_configure)(dev); 1274d30ea906Sjfb8856606 if (diag != 0) { 1275d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port%u dev_configure = %d\n", 1276d30ea906Sjfb8856606 port_id, diag); 1277d30ea906Sjfb8856606 rte_eth_dev_rx_queue_config(dev, 0); 1278d30ea906Sjfb8856606 rte_eth_dev_tx_queue_config(dev, 0); 1279d30ea906Sjfb8856606 ret = eth_err(port_id, diag); 1280d30ea906Sjfb8856606 goto rollback; 1281d30ea906Sjfb8856606 } 1282d30ea906Sjfb8856606 1283d30ea906Sjfb8856606 /* Initialize Rx profiling if enabled at compilation time. */ 1284d30ea906Sjfb8856606 diag = __rte_eth_dev_profile_init(port_id, dev); 1285d30ea906Sjfb8856606 if (diag != 0) { 1286d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port%u __rte_eth_dev_profile_init = %d\n", 1287d30ea906Sjfb8856606 port_id, diag); 1288d30ea906Sjfb8856606 rte_eth_dev_rx_queue_config(dev, 0); 1289d30ea906Sjfb8856606 rte_eth_dev_tx_queue_config(dev, 0); 1290d30ea906Sjfb8856606 ret = eth_err(port_id, diag); 1291d30ea906Sjfb8856606 goto rollback; 1292d30ea906Sjfb8856606 } 1293d30ea906Sjfb8856606 1294d30ea906Sjfb8856606 return 0; 1295d30ea906Sjfb8856606 1296d30ea906Sjfb8856606 rollback: 1297d30ea906Sjfb8856606 memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf)); 1298d30ea906Sjfb8856606 1299d30ea906Sjfb8856606 return ret; 1300d30ea906Sjfb8856606 } 1301d30ea906Sjfb8856606 1302d30ea906Sjfb8856606 void 1303d30ea906Sjfb8856606 _rte_eth_dev_reset(struct rte_eth_dev *dev) 1304d30ea906Sjfb8856606 { 1305d30ea906Sjfb8856606 if (dev->data->dev_started) { 1306d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port %u must be stopped to allow reset\n", 1307d30ea906Sjfb8856606 dev->data->port_id); 1308d30ea906Sjfb8856606 return; 1309d30ea906Sjfb8856606 } 1310d30ea906Sjfb8856606 1311d30ea906Sjfb8856606 rte_eth_dev_rx_queue_config(dev, 0); 1312d30ea906Sjfb8856606 rte_eth_dev_tx_queue_config(dev, 0); 1313d30ea906Sjfb8856606 1314d30ea906Sjfb8856606 memset(&dev->data->dev_conf, 0, sizeof(dev->data->dev_conf)); 1315d30ea906Sjfb8856606 } 1316d30ea906Sjfb8856606 1317d30ea906Sjfb8856606 static void 1318d30ea906Sjfb8856606 rte_eth_dev_mac_restore(struct rte_eth_dev *dev, 1319d30ea906Sjfb8856606 struct rte_eth_dev_info *dev_info) 1320d30ea906Sjfb8856606 { 1321d30ea906Sjfb8856606 struct ether_addr *addr; 1322d30ea906Sjfb8856606 uint16_t i; 1323d30ea906Sjfb8856606 uint32_t pool = 0; 1324d30ea906Sjfb8856606 uint64_t pool_mask; 1325d30ea906Sjfb8856606 1326d30ea906Sjfb8856606 /* replay MAC address configuration including default MAC */ 1327d30ea906Sjfb8856606 addr = &dev->data->mac_addrs[0]; 1328d30ea906Sjfb8856606 if (*dev->dev_ops->mac_addr_set != NULL) 1329d30ea906Sjfb8856606 (*dev->dev_ops->mac_addr_set)(dev, addr); 1330d30ea906Sjfb8856606 else if (*dev->dev_ops->mac_addr_add != NULL) 1331d30ea906Sjfb8856606 (*dev->dev_ops->mac_addr_add)(dev, addr, 0, pool); 1332d30ea906Sjfb8856606 1333d30ea906Sjfb8856606 if (*dev->dev_ops->mac_addr_add != NULL) { 1334d30ea906Sjfb8856606 for (i = 1; i < dev_info->max_mac_addrs; i++) { 1335d30ea906Sjfb8856606 addr = &dev->data->mac_addrs[i]; 1336d30ea906Sjfb8856606 1337d30ea906Sjfb8856606 /* skip zero address */ 1338d30ea906Sjfb8856606 if (is_zero_ether_addr(addr)) 1339d30ea906Sjfb8856606 continue; 1340d30ea906Sjfb8856606 1341d30ea906Sjfb8856606 pool = 0; 1342d30ea906Sjfb8856606 pool_mask = dev->data->mac_pool_sel[i]; 1343d30ea906Sjfb8856606 1344d30ea906Sjfb8856606 do { 1345d30ea906Sjfb8856606 if (pool_mask & 1ULL) 1346d30ea906Sjfb8856606 (*dev->dev_ops->mac_addr_add)(dev, 1347d30ea906Sjfb8856606 addr, i, pool); 1348d30ea906Sjfb8856606 pool_mask >>= 1; 1349d30ea906Sjfb8856606 pool++; 1350d30ea906Sjfb8856606 } while (pool_mask); 1351d30ea906Sjfb8856606 } 1352d30ea906Sjfb8856606 } 1353d30ea906Sjfb8856606 } 1354d30ea906Sjfb8856606 1355d30ea906Sjfb8856606 static void 1356d30ea906Sjfb8856606 rte_eth_dev_config_restore(struct rte_eth_dev *dev, 1357d30ea906Sjfb8856606 struct rte_eth_dev_info *dev_info, uint16_t port_id) 1358d30ea906Sjfb8856606 { 1359d30ea906Sjfb8856606 if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR)) 1360d30ea906Sjfb8856606 rte_eth_dev_mac_restore(dev, dev_info); 1361d30ea906Sjfb8856606 1362d30ea906Sjfb8856606 /* replay promiscuous configuration */ 1363d30ea906Sjfb8856606 if (rte_eth_promiscuous_get(port_id) == 1) 1364d30ea906Sjfb8856606 rte_eth_promiscuous_enable(port_id); 1365d30ea906Sjfb8856606 else if (rte_eth_promiscuous_get(port_id) == 0) 1366d30ea906Sjfb8856606 rte_eth_promiscuous_disable(port_id); 1367d30ea906Sjfb8856606 1368d30ea906Sjfb8856606 /* replay all multicast configuration */ 1369d30ea906Sjfb8856606 if (rte_eth_allmulticast_get(port_id) == 1) 1370d30ea906Sjfb8856606 rte_eth_allmulticast_enable(port_id); 1371d30ea906Sjfb8856606 else if (rte_eth_allmulticast_get(port_id) == 0) 1372d30ea906Sjfb8856606 rte_eth_allmulticast_disable(port_id); 1373d30ea906Sjfb8856606 } 1374d30ea906Sjfb8856606 1375d30ea906Sjfb8856606 int 1376d30ea906Sjfb8856606 rte_eth_dev_start(uint16_t port_id) 1377d30ea906Sjfb8856606 { 1378d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1379d30ea906Sjfb8856606 struct rte_eth_dev_info dev_info; 1380d30ea906Sjfb8856606 int diag; 1381d30ea906Sjfb8856606 1382d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 1383d30ea906Sjfb8856606 1384d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1385d30ea906Sjfb8856606 1386d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP); 1387d30ea906Sjfb8856606 1388d30ea906Sjfb8856606 if (dev->data->dev_started != 0) { 1389d30ea906Sjfb8856606 RTE_ETHDEV_LOG(INFO, 1390d30ea906Sjfb8856606 "Device with port_id=%"PRIu16" already started\n", 1391d30ea906Sjfb8856606 port_id); 1392d30ea906Sjfb8856606 return 0; 1393d30ea906Sjfb8856606 } 1394d30ea906Sjfb8856606 1395d30ea906Sjfb8856606 rte_eth_dev_info_get(port_id, &dev_info); 1396d30ea906Sjfb8856606 1397d30ea906Sjfb8856606 /* Lets restore MAC now if device does not support live change */ 1398d30ea906Sjfb8856606 if (*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR) 1399d30ea906Sjfb8856606 rte_eth_dev_mac_restore(dev, &dev_info); 1400d30ea906Sjfb8856606 1401d30ea906Sjfb8856606 diag = (*dev->dev_ops->dev_start)(dev); 1402d30ea906Sjfb8856606 if (diag == 0) 1403d30ea906Sjfb8856606 dev->data->dev_started = 1; 1404d30ea906Sjfb8856606 else 1405d30ea906Sjfb8856606 return eth_err(port_id, diag); 1406d30ea906Sjfb8856606 1407d30ea906Sjfb8856606 rte_eth_dev_config_restore(dev, &dev_info, port_id); 1408d30ea906Sjfb8856606 1409d30ea906Sjfb8856606 if (dev->data->dev_conf.intr_conf.lsc == 0) { 1410d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP); 1411d30ea906Sjfb8856606 (*dev->dev_ops->link_update)(dev, 0); 1412d30ea906Sjfb8856606 } 1413d30ea906Sjfb8856606 return 0; 1414d30ea906Sjfb8856606 } 1415d30ea906Sjfb8856606 1416d30ea906Sjfb8856606 void 1417d30ea906Sjfb8856606 rte_eth_dev_stop(uint16_t port_id) 1418d30ea906Sjfb8856606 { 1419d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1420d30ea906Sjfb8856606 1421d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_RET(port_id); 1422d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1423d30ea906Sjfb8856606 1424d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_stop); 1425d30ea906Sjfb8856606 1426d30ea906Sjfb8856606 if (dev->data->dev_started == 0) { 1427d30ea906Sjfb8856606 RTE_ETHDEV_LOG(INFO, 1428d30ea906Sjfb8856606 "Device with port_id=%"PRIu16" already stopped\n", 1429d30ea906Sjfb8856606 port_id); 1430d30ea906Sjfb8856606 return; 1431d30ea906Sjfb8856606 } 1432d30ea906Sjfb8856606 1433d30ea906Sjfb8856606 dev->data->dev_started = 0; 1434d30ea906Sjfb8856606 (*dev->dev_ops->dev_stop)(dev); 1435d30ea906Sjfb8856606 } 1436d30ea906Sjfb8856606 1437d30ea906Sjfb8856606 int 1438d30ea906Sjfb8856606 rte_eth_dev_set_link_up(uint16_t port_id) 1439d30ea906Sjfb8856606 { 1440d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1441d30ea906Sjfb8856606 1442d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 1443d30ea906Sjfb8856606 1444d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1445d30ea906Sjfb8856606 1446d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_up, -ENOTSUP); 1447d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->dev_set_link_up)(dev)); 1448d30ea906Sjfb8856606 } 1449d30ea906Sjfb8856606 1450d30ea906Sjfb8856606 int 1451d30ea906Sjfb8856606 rte_eth_dev_set_link_down(uint16_t port_id) 1452d30ea906Sjfb8856606 { 1453d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1454d30ea906Sjfb8856606 1455d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 1456d30ea906Sjfb8856606 1457d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1458d30ea906Sjfb8856606 1459d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_down, -ENOTSUP); 1460d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->dev_set_link_down)(dev)); 1461d30ea906Sjfb8856606 } 1462d30ea906Sjfb8856606 1463d30ea906Sjfb8856606 void 1464d30ea906Sjfb8856606 rte_eth_dev_close(uint16_t port_id) 1465d30ea906Sjfb8856606 { 1466d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1467d30ea906Sjfb8856606 1468d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_RET(port_id); 1469d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1470d30ea906Sjfb8856606 1471d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_close); 1472d30ea906Sjfb8856606 dev->data->dev_started = 0; 1473d30ea906Sjfb8856606 (*dev->dev_ops->dev_close)(dev); 1474d30ea906Sjfb8856606 1475d30ea906Sjfb8856606 /* check behaviour flag - temporary for PMD migration */ 1476d30ea906Sjfb8856606 if ((dev->data->dev_flags & RTE_ETH_DEV_CLOSE_REMOVE) != 0) { 1477d30ea906Sjfb8856606 /* new behaviour: send event + reset state + free all data */ 1478d30ea906Sjfb8856606 rte_eth_dev_release_port(dev); 1479d30ea906Sjfb8856606 return; 1480d30ea906Sjfb8856606 } 1481d30ea906Sjfb8856606 RTE_ETHDEV_LOG(DEBUG, "Port closing is using an old behaviour.\n" 1482d30ea906Sjfb8856606 "The driver %s should migrate to the new behaviour.\n", 1483d30ea906Sjfb8856606 dev->device->driver->name); 1484d30ea906Sjfb8856606 /* old behaviour: only free queue arrays */ 1485d30ea906Sjfb8856606 dev->data->nb_rx_queues = 0; 1486d30ea906Sjfb8856606 rte_free(dev->data->rx_queues); 1487d30ea906Sjfb8856606 dev->data->rx_queues = NULL; 1488d30ea906Sjfb8856606 dev->data->nb_tx_queues = 0; 1489d30ea906Sjfb8856606 rte_free(dev->data->tx_queues); 1490d30ea906Sjfb8856606 dev->data->tx_queues = NULL; 1491d30ea906Sjfb8856606 } 1492d30ea906Sjfb8856606 1493d30ea906Sjfb8856606 int 1494d30ea906Sjfb8856606 rte_eth_dev_reset(uint16_t port_id) 1495d30ea906Sjfb8856606 { 1496d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1497d30ea906Sjfb8856606 int ret; 1498d30ea906Sjfb8856606 1499d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 1500d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1501d30ea906Sjfb8856606 1502d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP); 1503d30ea906Sjfb8856606 1504d30ea906Sjfb8856606 rte_eth_dev_stop(port_id); 1505d30ea906Sjfb8856606 ret = dev->dev_ops->dev_reset(dev); 1506d30ea906Sjfb8856606 1507d30ea906Sjfb8856606 return eth_err(port_id, ret); 1508d30ea906Sjfb8856606 } 1509d30ea906Sjfb8856606 1510d30ea906Sjfb8856606 int __rte_experimental 1511d30ea906Sjfb8856606 rte_eth_dev_is_removed(uint16_t port_id) 1512d30ea906Sjfb8856606 { 1513d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1514d30ea906Sjfb8856606 int ret; 1515d30ea906Sjfb8856606 1516d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0); 1517d30ea906Sjfb8856606 1518d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1519d30ea906Sjfb8856606 1520d30ea906Sjfb8856606 if (dev->state == RTE_ETH_DEV_REMOVED) 1521d30ea906Sjfb8856606 return 1; 1522d30ea906Sjfb8856606 1523d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->is_removed, 0); 1524d30ea906Sjfb8856606 1525d30ea906Sjfb8856606 ret = dev->dev_ops->is_removed(dev); 1526d30ea906Sjfb8856606 if (ret != 0) 1527d30ea906Sjfb8856606 /* Device is physically removed. */ 1528d30ea906Sjfb8856606 dev->state = RTE_ETH_DEV_REMOVED; 1529d30ea906Sjfb8856606 1530d30ea906Sjfb8856606 return ret; 1531d30ea906Sjfb8856606 } 1532d30ea906Sjfb8856606 1533d30ea906Sjfb8856606 int 1534d30ea906Sjfb8856606 rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id, 1535d30ea906Sjfb8856606 uint16_t nb_rx_desc, unsigned int socket_id, 1536d30ea906Sjfb8856606 const struct rte_eth_rxconf *rx_conf, 1537d30ea906Sjfb8856606 struct rte_mempool *mp) 1538d30ea906Sjfb8856606 { 1539d30ea906Sjfb8856606 int ret; 1540d30ea906Sjfb8856606 uint32_t mbp_buf_size; 1541d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1542d30ea906Sjfb8856606 struct rte_eth_dev_info dev_info; 1543d30ea906Sjfb8856606 struct rte_eth_rxconf local_conf; 1544d30ea906Sjfb8856606 void **rxq; 1545d30ea906Sjfb8856606 1546d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 1547d30ea906Sjfb8856606 1548d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1549d30ea906Sjfb8856606 if (rx_queue_id >= dev->data->nb_rx_queues) { 1550d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id); 1551d30ea906Sjfb8856606 return -EINVAL; 1552d30ea906Sjfb8856606 } 1553d30ea906Sjfb8856606 1554d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP); 1555d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP); 1556d30ea906Sjfb8856606 1557d30ea906Sjfb8856606 /* 1558d30ea906Sjfb8856606 * Check the size of the mbuf data buffer. 1559d30ea906Sjfb8856606 * This value must be provided in the private data of the memory pool. 1560d30ea906Sjfb8856606 * First check that the memory pool has a valid private data. 1561d30ea906Sjfb8856606 */ 1562d30ea906Sjfb8856606 rte_eth_dev_info_get(port_id, &dev_info); 1563d30ea906Sjfb8856606 if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) { 1564d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "%s private_data_size %d < %d\n", 1565d30ea906Sjfb8856606 mp->name, (int)mp->private_data_size, 1566d30ea906Sjfb8856606 (int)sizeof(struct rte_pktmbuf_pool_private)); 1567d30ea906Sjfb8856606 return -ENOSPC; 1568d30ea906Sjfb8856606 } 1569d30ea906Sjfb8856606 mbp_buf_size = rte_pktmbuf_data_room_size(mp); 1570d30ea906Sjfb8856606 1571d30ea906Sjfb8856606 if ((mbp_buf_size - RTE_PKTMBUF_HEADROOM) < dev_info.min_rx_bufsize) { 1572d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1573d30ea906Sjfb8856606 "%s mbuf_data_room_size %d < %d (RTE_PKTMBUF_HEADROOM=%d + min_rx_bufsize(dev)=%d)\n", 1574d30ea906Sjfb8856606 mp->name, (int)mbp_buf_size, 1575d30ea906Sjfb8856606 (int)(RTE_PKTMBUF_HEADROOM + dev_info.min_rx_bufsize), 1576d30ea906Sjfb8856606 (int)RTE_PKTMBUF_HEADROOM, 1577d30ea906Sjfb8856606 (int)dev_info.min_rx_bufsize); 1578d30ea906Sjfb8856606 return -EINVAL; 1579d30ea906Sjfb8856606 } 1580d30ea906Sjfb8856606 1581d30ea906Sjfb8856606 /* Use default specified by driver, if nb_rx_desc is zero */ 1582d30ea906Sjfb8856606 if (nb_rx_desc == 0) { 1583d30ea906Sjfb8856606 nb_rx_desc = dev_info.default_rxportconf.ring_size; 1584d30ea906Sjfb8856606 /* If driver default is also zero, fall back on EAL default */ 1585d30ea906Sjfb8856606 if (nb_rx_desc == 0) 1586d30ea906Sjfb8856606 nb_rx_desc = RTE_ETH_DEV_FALLBACK_RX_RINGSIZE; 1587d30ea906Sjfb8856606 } 1588d30ea906Sjfb8856606 1589d30ea906Sjfb8856606 if (nb_rx_desc > dev_info.rx_desc_lim.nb_max || 1590d30ea906Sjfb8856606 nb_rx_desc < dev_info.rx_desc_lim.nb_min || 1591d30ea906Sjfb8856606 nb_rx_desc % dev_info.rx_desc_lim.nb_align != 0) { 1592d30ea906Sjfb8856606 1593d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 15941646932aSjfb8856606 "Invalid value for nb_rx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n", 1595d30ea906Sjfb8856606 nb_rx_desc, dev_info.rx_desc_lim.nb_max, 1596d30ea906Sjfb8856606 dev_info.rx_desc_lim.nb_min, 1597d30ea906Sjfb8856606 dev_info.rx_desc_lim.nb_align); 1598d30ea906Sjfb8856606 return -EINVAL; 1599d30ea906Sjfb8856606 } 1600d30ea906Sjfb8856606 1601d30ea906Sjfb8856606 if (dev->data->dev_started && 1602d30ea906Sjfb8856606 !(dev_info.dev_capa & 1603d30ea906Sjfb8856606 RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP)) 1604d30ea906Sjfb8856606 return -EBUSY; 1605d30ea906Sjfb8856606 1606d30ea906Sjfb8856606 if (dev->data->dev_started && 1607d30ea906Sjfb8856606 (dev->data->rx_queue_state[rx_queue_id] != 1608d30ea906Sjfb8856606 RTE_ETH_QUEUE_STATE_STOPPED)) 1609d30ea906Sjfb8856606 return -EBUSY; 1610d30ea906Sjfb8856606 1611d30ea906Sjfb8856606 rxq = dev->data->rx_queues; 1612d30ea906Sjfb8856606 if (rxq[rx_queue_id]) { 1613d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_release, 1614d30ea906Sjfb8856606 -ENOTSUP); 1615d30ea906Sjfb8856606 (*dev->dev_ops->rx_queue_release)(rxq[rx_queue_id]); 1616d30ea906Sjfb8856606 rxq[rx_queue_id] = NULL; 1617d30ea906Sjfb8856606 } 1618d30ea906Sjfb8856606 1619d30ea906Sjfb8856606 if (rx_conf == NULL) 1620d30ea906Sjfb8856606 rx_conf = &dev_info.default_rxconf; 1621d30ea906Sjfb8856606 1622d30ea906Sjfb8856606 local_conf = *rx_conf; 1623d30ea906Sjfb8856606 1624d30ea906Sjfb8856606 /* 1625d30ea906Sjfb8856606 * If an offloading has already been enabled in 1626d30ea906Sjfb8856606 * rte_eth_dev_configure(), it has been enabled on all queues, 1627d30ea906Sjfb8856606 * so there is no need to enable it in this queue again. 1628d30ea906Sjfb8856606 * The local_conf.offloads input to underlying PMD only carries 1629d30ea906Sjfb8856606 * those offloadings which are only enabled on this queue and 1630d30ea906Sjfb8856606 * not enabled on all queues. 1631d30ea906Sjfb8856606 */ 1632d30ea906Sjfb8856606 local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads; 1633d30ea906Sjfb8856606 1634d30ea906Sjfb8856606 /* 1635d30ea906Sjfb8856606 * New added offloadings for this queue are those not enabled in 1636d30ea906Sjfb8856606 * rte_eth_dev_configure() and they must be per-queue type. 1637d30ea906Sjfb8856606 * A pure per-port offloading can't be enabled on a queue while 1638d30ea906Sjfb8856606 * disabled on another queue. A pure per-port offloading can't 1639d30ea906Sjfb8856606 * be enabled for any queue as new added one if it hasn't been 1640d30ea906Sjfb8856606 * enabled in rte_eth_dev_configure(). 1641d30ea906Sjfb8856606 */ 1642d30ea906Sjfb8856606 if ((local_conf.offloads & dev_info.rx_queue_offload_capa) != 1643d30ea906Sjfb8856606 local_conf.offloads) { 1644d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1645d30ea906Sjfb8856606 "Ethdev port_id=%d rx_queue_id=%d, new added offloads 0x%"PRIx64" must be " 16461646932aSjfb8856606 "within per-queue offload capabilities 0x%"PRIx64" in %s()\n", 1647d30ea906Sjfb8856606 port_id, rx_queue_id, local_conf.offloads, 1648d30ea906Sjfb8856606 dev_info.rx_queue_offload_capa, 1649d30ea906Sjfb8856606 __func__); 1650d30ea906Sjfb8856606 return -EINVAL; 1651d30ea906Sjfb8856606 } 1652d30ea906Sjfb8856606 1653d30ea906Sjfb8856606 ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc, 1654d30ea906Sjfb8856606 socket_id, &local_conf, mp); 1655d30ea906Sjfb8856606 if (!ret) { 1656d30ea906Sjfb8856606 if (!dev->data->min_rx_buf_size || 1657d30ea906Sjfb8856606 dev->data->min_rx_buf_size > mbp_buf_size) 1658d30ea906Sjfb8856606 dev->data->min_rx_buf_size = mbp_buf_size; 1659d30ea906Sjfb8856606 } 1660d30ea906Sjfb8856606 1661d30ea906Sjfb8856606 return eth_err(port_id, ret); 1662d30ea906Sjfb8856606 } 1663d30ea906Sjfb8856606 1664d30ea906Sjfb8856606 int 1665d30ea906Sjfb8856606 rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id, 1666d30ea906Sjfb8856606 uint16_t nb_tx_desc, unsigned int socket_id, 1667d30ea906Sjfb8856606 const struct rte_eth_txconf *tx_conf) 1668d30ea906Sjfb8856606 { 1669d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1670d30ea906Sjfb8856606 struct rte_eth_dev_info dev_info; 1671d30ea906Sjfb8856606 struct rte_eth_txconf local_conf; 1672d30ea906Sjfb8856606 void **txq; 1673d30ea906Sjfb8856606 1674d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 1675d30ea906Sjfb8856606 1676d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1677d30ea906Sjfb8856606 if (tx_queue_id >= dev->data->nb_tx_queues) { 1678d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id); 1679d30ea906Sjfb8856606 return -EINVAL; 1680d30ea906Sjfb8856606 } 1681d30ea906Sjfb8856606 1682d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP); 1683d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -ENOTSUP); 1684d30ea906Sjfb8856606 1685d30ea906Sjfb8856606 rte_eth_dev_info_get(port_id, &dev_info); 1686d30ea906Sjfb8856606 1687d30ea906Sjfb8856606 /* Use default specified by driver, if nb_tx_desc is zero */ 1688d30ea906Sjfb8856606 if (nb_tx_desc == 0) { 1689d30ea906Sjfb8856606 nb_tx_desc = dev_info.default_txportconf.ring_size; 1690d30ea906Sjfb8856606 /* If driver default is zero, fall back on EAL default */ 1691d30ea906Sjfb8856606 if (nb_tx_desc == 0) 1692d30ea906Sjfb8856606 nb_tx_desc = RTE_ETH_DEV_FALLBACK_TX_RINGSIZE; 1693d30ea906Sjfb8856606 } 1694d30ea906Sjfb8856606 if (nb_tx_desc > dev_info.tx_desc_lim.nb_max || 1695d30ea906Sjfb8856606 nb_tx_desc < dev_info.tx_desc_lim.nb_min || 1696d30ea906Sjfb8856606 nb_tx_desc % dev_info.tx_desc_lim.nb_align != 0) { 1697d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 16981646932aSjfb8856606 "Invalid value for nb_tx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n", 1699d30ea906Sjfb8856606 nb_tx_desc, dev_info.tx_desc_lim.nb_max, 1700d30ea906Sjfb8856606 dev_info.tx_desc_lim.nb_min, 1701d30ea906Sjfb8856606 dev_info.tx_desc_lim.nb_align); 1702d30ea906Sjfb8856606 return -EINVAL; 1703d30ea906Sjfb8856606 } 1704d30ea906Sjfb8856606 1705d30ea906Sjfb8856606 if (dev->data->dev_started && 1706d30ea906Sjfb8856606 !(dev_info.dev_capa & 1707d30ea906Sjfb8856606 RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP)) 1708d30ea906Sjfb8856606 return -EBUSY; 1709d30ea906Sjfb8856606 1710d30ea906Sjfb8856606 if (dev->data->dev_started && 1711d30ea906Sjfb8856606 (dev->data->tx_queue_state[tx_queue_id] != 1712d30ea906Sjfb8856606 RTE_ETH_QUEUE_STATE_STOPPED)) 1713d30ea906Sjfb8856606 return -EBUSY; 1714d30ea906Sjfb8856606 1715d30ea906Sjfb8856606 txq = dev->data->tx_queues; 1716d30ea906Sjfb8856606 if (txq[tx_queue_id]) { 1717d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_release, 1718d30ea906Sjfb8856606 -ENOTSUP); 1719d30ea906Sjfb8856606 (*dev->dev_ops->tx_queue_release)(txq[tx_queue_id]); 1720d30ea906Sjfb8856606 txq[tx_queue_id] = NULL; 1721d30ea906Sjfb8856606 } 1722d30ea906Sjfb8856606 1723d30ea906Sjfb8856606 if (tx_conf == NULL) 1724d30ea906Sjfb8856606 tx_conf = &dev_info.default_txconf; 1725d30ea906Sjfb8856606 1726d30ea906Sjfb8856606 local_conf = *tx_conf; 1727d30ea906Sjfb8856606 1728d30ea906Sjfb8856606 /* 1729d30ea906Sjfb8856606 * If an offloading has already been enabled in 1730d30ea906Sjfb8856606 * rte_eth_dev_configure(), it has been enabled on all queues, 1731d30ea906Sjfb8856606 * so there is no need to enable it in this queue again. 1732d30ea906Sjfb8856606 * The local_conf.offloads input to underlying PMD only carries 1733d30ea906Sjfb8856606 * those offloadings which are only enabled on this queue and 1734d30ea906Sjfb8856606 * not enabled on all queues. 1735d30ea906Sjfb8856606 */ 1736d30ea906Sjfb8856606 local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads; 1737d30ea906Sjfb8856606 1738d30ea906Sjfb8856606 /* 1739d30ea906Sjfb8856606 * New added offloadings for this queue are those not enabled in 1740d30ea906Sjfb8856606 * rte_eth_dev_configure() and they must be per-queue type. 1741d30ea906Sjfb8856606 * A pure per-port offloading can't be enabled on a queue while 1742d30ea906Sjfb8856606 * disabled on another queue. A pure per-port offloading can't 1743d30ea906Sjfb8856606 * be enabled for any queue as new added one if it hasn't been 1744d30ea906Sjfb8856606 * enabled in rte_eth_dev_configure(). 1745d30ea906Sjfb8856606 */ 1746d30ea906Sjfb8856606 if ((local_conf.offloads & dev_info.tx_queue_offload_capa) != 1747d30ea906Sjfb8856606 local_conf.offloads) { 1748d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 1749d30ea906Sjfb8856606 "Ethdev port_id=%d tx_queue_id=%d, new added offloads 0x%"PRIx64" must be " 17501646932aSjfb8856606 "within per-queue offload capabilities 0x%"PRIx64" in %s()\n", 1751d30ea906Sjfb8856606 port_id, tx_queue_id, local_conf.offloads, 1752d30ea906Sjfb8856606 dev_info.tx_queue_offload_capa, 1753d30ea906Sjfb8856606 __func__); 1754d30ea906Sjfb8856606 return -EINVAL; 1755d30ea906Sjfb8856606 } 1756d30ea906Sjfb8856606 1757d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev, 1758d30ea906Sjfb8856606 tx_queue_id, nb_tx_desc, socket_id, &local_conf)); 1759d30ea906Sjfb8856606 } 1760d30ea906Sjfb8856606 1761d30ea906Sjfb8856606 void 1762d30ea906Sjfb8856606 rte_eth_tx_buffer_drop_callback(struct rte_mbuf **pkts, uint16_t unsent, 1763d30ea906Sjfb8856606 void *userdata __rte_unused) 1764d30ea906Sjfb8856606 { 1765d30ea906Sjfb8856606 unsigned i; 1766d30ea906Sjfb8856606 1767d30ea906Sjfb8856606 for (i = 0; i < unsent; i++) 1768d30ea906Sjfb8856606 rte_pktmbuf_free(pkts[i]); 1769d30ea906Sjfb8856606 } 1770d30ea906Sjfb8856606 1771d30ea906Sjfb8856606 void 1772d30ea906Sjfb8856606 rte_eth_tx_buffer_count_callback(struct rte_mbuf **pkts, uint16_t unsent, 1773d30ea906Sjfb8856606 void *userdata) 1774d30ea906Sjfb8856606 { 1775d30ea906Sjfb8856606 uint64_t *count = userdata; 1776d30ea906Sjfb8856606 unsigned i; 1777d30ea906Sjfb8856606 1778d30ea906Sjfb8856606 for (i = 0; i < unsent; i++) 1779d30ea906Sjfb8856606 rte_pktmbuf_free(pkts[i]); 1780d30ea906Sjfb8856606 1781d30ea906Sjfb8856606 *count += unsent; 1782d30ea906Sjfb8856606 } 1783d30ea906Sjfb8856606 1784d30ea906Sjfb8856606 int 1785d30ea906Sjfb8856606 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer, 1786d30ea906Sjfb8856606 buffer_tx_error_fn cbfn, void *userdata) 1787d30ea906Sjfb8856606 { 1788d30ea906Sjfb8856606 buffer->error_callback = cbfn; 1789d30ea906Sjfb8856606 buffer->error_userdata = userdata; 1790d30ea906Sjfb8856606 return 0; 1791d30ea906Sjfb8856606 } 1792d30ea906Sjfb8856606 1793d30ea906Sjfb8856606 int 1794d30ea906Sjfb8856606 rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size) 1795d30ea906Sjfb8856606 { 1796d30ea906Sjfb8856606 int ret = 0; 1797d30ea906Sjfb8856606 1798d30ea906Sjfb8856606 if (buffer == NULL) 1799d30ea906Sjfb8856606 return -EINVAL; 1800d30ea906Sjfb8856606 1801d30ea906Sjfb8856606 buffer->size = size; 1802d30ea906Sjfb8856606 if (buffer->error_callback == NULL) { 1803d30ea906Sjfb8856606 ret = rte_eth_tx_buffer_set_err_callback( 1804d30ea906Sjfb8856606 buffer, rte_eth_tx_buffer_drop_callback, NULL); 1805d30ea906Sjfb8856606 } 1806d30ea906Sjfb8856606 1807d30ea906Sjfb8856606 return ret; 1808d30ea906Sjfb8856606 } 1809d30ea906Sjfb8856606 1810d30ea906Sjfb8856606 int 1811d30ea906Sjfb8856606 rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt) 1812d30ea906Sjfb8856606 { 1813d30ea906Sjfb8856606 struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 1814d30ea906Sjfb8856606 int ret; 1815d30ea906Sjfb8856606 1816d30ea906Sjfb8856606 /* Validate Input Data. Bail if not valid or not supported. */ 1817d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 1818d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP); 1819d30ea906Sjfb8856606 1820d30ea906Sjfb8856606 /* Call driver to free pending mbufs. */ 1821d30ea906Sjfb8856606 ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id], 1822d30ea906Sjfb8856606 free_cnt); 1823d30ea906Sjfb8856606 return eth_err(port_id, ret); 1824d30ea906Sjfb8856606 } 1825d30ea906Sjfb8856606 1826d30ea906Sjfb8856606 void 1827d30ea906Sjfb8856606 rte_eth_promiscuous_enable(uint16_t port_id) 1828d30ea906Sjfb8856606 { 1829d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1830d30ea906Sjfb8856606 1831d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_RET(port_id); 1832d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1833d30ea906Sjfb8856606 1834d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_enable); 1835d30ea906Sjfb8856606 (*dev->dev_ops->promiscuous_enable)(dev); 1836d30ea906Sjfb8856606 dev->data->promiscuous = 1; 1837d30ea906Sjfb8856606 } 1838d30ea906Sjfb8856606 1839d30ea906Sjfb8856606 void 1840d30ea906Sjfb8856606 rte_eth_promiscuous_disable(uint16_t port_id) 1841d30ea906Sjfb8856606 { 1842d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1843d30ea906Sjfb8856606 1844d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_RET(port_id); 1845d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1846d30ea906Sjfb8856606 1847d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_disable); 1848d30ea906Sjfb8856606 dev->data->promiscuous = 0; 1849d30ea906Sjfb8856606 (*dev->dev_ops->promiscuous_disable)(dev); 1850d30ea906Sjfb8856606 } 1851d30ea906Sjfb8856606 1852d30ea906Sjfb8856606 int 1853d30ea906Sjfb8856606 rte_eth_promiscuous_get(uint16_t port_id) 1854d30ea906Sjfb8856606 { 1855d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1856d30ea906Sjfb8856606 1857d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 1858d30ea906Sjfb8856606 1859d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1860d30ea906Sjfb8856606 return dev->data->promiscuous; 1861d30ea906Sjfb8856606 } 1862d30ea906Sjfb8856606 1863d30ea906Sjfb8856606 void 1864d30ea906Sjfb8856606 rte_eth_allmulticast_enable(uint16_t port_id) 1865d30ea906Sjfb8856606 { 1866d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1867d30ea906Sjfb8856606 1868d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_RET(port_id); 1869d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1870d30ea906Sjfb8856606 1871d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_RET(*dev->dev_ops->allmulticast_enable); 1872d30ea906Sjfb8856606 (*dev->dev_ops->allmulticast_enable)(dev); 1873d30ea906Sjfb8856606 dev->data->all_multicast = 1; 1874d30ea906Sjfb8856606 } 1875d30ea906Sjfb8856606 1876d30ea906Sjfb8856606 void 1877d30ea906Sjfb8856606 rte_eth_allmulticast_disable(uint16_t port_id) 1878d30ea906Sjfb8856606 { 1879d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1880d30ea906Sjfb8856606 1881d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_RET(port_id); 1882d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1883d30ea906Sjfb8856606 1884d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_RET(*dev->dev_ops->allmulticast_disable); 1885d30ea906Sjfb8856606 dev->data->all_multicast = 0; 1886d30ea906Sjfb8856606 (*dev->dev_ops->allmulticast_disable)(dev); 1887d30ea906Sjfb8856606 } 1888d30ea906Sjfb8856606 1889d30ea906Sjfb8856606 int 1890d30ea906Sjfb8856606 rte_eth_allmulticast_get(uint16_t port_id) 1891d30ea906Sjfb8856606 { 1892d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1893d30ea906Sjfb8856606 1894d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 1895d30ea906Sjfb8856606 1896d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1897d30ea906Sjfb8856606 return dev->data->all_multicast; 1898d30ea906Sjfb8856606 } 1899d30ea906Sjfb8856606 1900d30ea906Sjfb8856606 void 1901d30ea906Sjfb8856606 rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link) 1902d30ea906Sjfb8856606 { 1903d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1904d30ea906Sjfb8856606 1905d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_RET(port_id); 1906d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1907d30ea906Sjfb8856606 1908d30ea906Sjfb8856606 if (dev->data->dev_conf.intr_conf.lsc && 1909d30ea906Sjfb8856606 dev->data->dev_started) 1910d30ea906Sjfb8856606 rte_eth_linkstatus_get(dev, eth_link); 1911d30ea906Sjfb8856606 else { 1912d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update); 1913d30ea906Sjfb8856606 (*dev->dev_ops->link_update)(dev, 1); 1914d30ea906Sjfb8856606 *eth_link = dev->data->dev_link; 1915d30ea906Sjfb8856606 } 1916d30ea906Sjfb8856606 } 1917d30ea906Sjfb8856606 1918d30ea906Sjfb8856606 void 1919d30ea906Sjfb8856606 rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link) 1920d30ea906Sjfb8856606 { 1921d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1922d30ea906Sjfb8856606 1923d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_RET(port_id); 1924d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1925d30ea906Sjfb8856606 1926d30ea906Sjfb8856606 if (dev->data->dev_conf.intr_conf.lsc && 1927d30ea906Sjfb8856606 dev->data->dev_started) 1928d30ea906Sjfb8856606 rte_eth_linkstatus_get(dev, eth_link); 1929d30ea906Sjfb8856606 else { 1930d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update); 1931d30ea906Sjfb8856606 (*dev->dev_ops->link_update)(dev, 0); 1932d30ea906Sjfb8856606 *eth_link = dev->data->dev_link; 1933d30ea906Sjfb8856606 } 1934d30ea906Sjfb8856606 } 1935d30ea906Sjfb8856606 1936d30ea906Sjfb8856606 int 1937d30ea906Sjfb8856606 rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats) 1938d30ea906Sjfb8856606 { 1939d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1940d30ea906Sjfb8856606 1941d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 1942d30ea906Sjfb8856606 1943d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1944d30ea906Sjfb8856606 memset(stats, 0, sizeof(*stats)); 1945d30ea906Sjfb8856606 1946d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP); 1947d30ea906Sjfb8856606 stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed; 1948d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->stats_get)(dev, stats)); 1949d30ea906Sjfb8856606 } 1950d30ea906Sjfb8856606 1951d30ea906Sjfb8856606 int 1952d30ea906Sjfb8856606 rte_eth_stats_reset(uint16_t port_id) 1953d30ea906Sjfb8856606 { 1954d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1955d30ea906Sjfb8856606 1956d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 1957d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1958d30ea906Sjfb8856606 1959d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_reset, -ENOTSUP); 1960d30ea906Sjfb8856606 (*dev->dev_ops->stats_reset)(dev); 1961d30ea906Sjfb8856606 dev->data->rx_mbuf_alloc_failed = 0; 1962d30ea906Sjfb8856606 1963d30ea906Sjfb8856606 return 0; 1964d30ea906Sjfb8856606 } 1965d30ea906Sjfb8856606 1966d30ea906Sjfb8856606 static inline int 1967d30ea906Sjfb8856606 get_xstats_basic_count(struct rte_eth_dev *dev) 1968d30ea906Sjfb8856606 { 1969d30ea906Sjfb8856606 uint16_t nb_rxqs, nb_txqs; 1970d30ea906Sjfb8856606 int count; 1971d30ea906Sjfb8856606 1972d30ea906Sjfb8856606 nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 1973d30ea906Sjfb8856606 nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 1974d30ea906Sjfb8856606 1975d30ea906Sjfb8856606 count = RTE_NB_STATS; 1976d30ea906Sjfb8856606 count += nb_rxqs * RTE_NB_RXQ_STATS; 1977d30ea906Sjfb8856606 count += nb_txqs * RTE_NB_TXQ_STATS; 1978d30ea906Sjfb8856606 1979d30ea906Sjfb8856606 return count; 1980d30ea906Sjfb8856606 } 1981d30ea906Sjfb8856606 1982d30ea906Sjfb8856606 static int 1983d30ea906Sjfb8856606 get_xstats_count(uint16_t port_id) 1984d30ea906Sjfb8856606 { 1985d30ea906Sjfb8856606 struct rte_eth_dev *dev; 1986d30ea906Sjfb8856606 int count; 1987d30ea906Sjfb8856606 1988d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 1989d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 1990d30ea906Sjfb8856606 if (dev->dev_ops->xstats_get_names_by_id != NULL) { 1991d30ea906Sjfb8856606 count = (*dev->dev_ops->xstats_get_names_by_id)(dev, NULL, 1992d30ea906Sjfb8856606 NULL, 0); 1993d30ea906Sjfb8856606 if (count < 0) 1994d30ea906Sjfb8856606 return eth_err(port_id, count); 1995d30ea906Sjfb8856606 } 1996d30ea906Sjfb8856606 if (dev->dev_ops->xstats_get_names != NULL) { 1997d30ea906Sjfb8856606 count = (*dev->dev_ops->xstats_get_names)(dev, NULL, 0); 1998d30ea906Sjfb8856606 if (count < 0) 1999d30ea906Sjfb8856606 return eth_err(port_id, count); 2000d30ea906Sjfb8856606 } else 2001d30ea906Sjfb8856606 count = 0; 2002d30ea906Sjfb8856606 2003d30ea906Sjfb8856606 2004d30ea906Sjfb8856606 count += get_xstats_basic_count(dev); 2005d30ea906Sjfb8856606 2006d30ea906Sjfb8856606 return count; 2007d30ea906Sjfb8856606 } 2008d30ea906Sjfb8856606 2009d30ea906Sjfb8856606 int 2010d30ea906Sjfb8856606 rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name, 2011d30ea906Sjfb8856606 uint64_t *id) 2012d30ea906Sjfb8856606 { 2013d30ea906Sjfb8856606 int cnt_xstats, idx_xstat; 2014d30ea906Sjfb8856606 2015d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2016d30ea906Sjfb8856606 2017d30ea906Sjfb8856606 if (!id) { 2018d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Id pointer is NULL\n"); 2019d30ea906Sjfb8856606 return -ENOMEM; 2020d30ea906Sjfb8856606 } 2021d30ea906Sjfb8856606 2022d30ea906Sjfb8856606 if (!xstat_name) { 2023d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "xstat_name pointer is NULL\n"); 2024d30ea906Sjfb8856606 return -ENOMEM; 2025d30ea906Sjfb8856606 } 2026d30ea906Sjfb8856606 2027d30ea906Sjfb8856606 /* Get count */ 2028d30ea906Sjfb8856606 cnt_xstats = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL); 2029d30ea906Sjfb8856606 if (cnt_xstats < 0) { 2030d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Cannot get count of xstats\n"); 2031d30ea906Sjfb8856606 return -ENODEV; 2032d30ea906Sjfb8856606 } 2033d30ea906Sjfb8856606 2034d30ea906Sjfb8856606 /* Get id-name lookup table */ 2035d30ea906Sjfb8856606 struct rte_eth_xstat_name xstats_names[cnt_xstats]; 2036d30ea906Sjfb8856606 2037d30ea906Sjfb8856606 if (cnt_xstats != rte_eth_xstats_get_names_by_id( 2038d30ea906Sjfb8856606 port_id, xstats_names, cnt_xstats, NULL)) { 2039d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Cannot get xstats lookup\n"); 2040d30ea906Sjfb8856606 return -1; 2041d30ea906Sjfb8856606 } 2042d30ea906Sjfb8856606 2043d30ea906Sjfb8856606 for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) { 2044d30ea906Sjfb8856606 if (!strcmp(xstats_names[idx_xstat].name, xstat_name)) { 2045d30ea906Sjfb8856606 *id = idx_xstat; 2046d30ea906Sjfb8856606 return 0; 2047d30ea906Sjfb8856606 }; 2048d30ea906Sjfb8856606 } 2049d30ea906Sjfb8856606 2050d30ea906Sjfb8856606 return -EINVAL; 2051d30ea906Sjfb8856606 } 2052d30ea906Sjfb8856606 2053d30ea906Sjfb8856606 /* retrieve basic stats names */ 2054d30ea906Sjfb8856606 static int 2055d30ea906Sjfb8856606 rte_eth_basic_stats_get_names(struct rte_eth_dev *dev, 2056d30ea906Sjfb8856606 struct rte_eth_xstat_name *xstats_names) 2057d30ea906Sjfb8856606 { 2058d30ea906Sjfb8856606 int cnt_used_entries = 0; 2059d30ea906Sjfb8856606 uint32_t idx, id_queue; 2060d30ea906Sjfb8856606 uint16_t num_q; 2061d30ea906Sjfb8856606 2062d30ea906Sjfb8856606 for (idx = 0; idx < RTE_NB_STATS; idx++) { 2063d30ea906Sjfb8856606 snprintf(xstats_names[cnt_used_entries].name, 2064d30ea906Sjfb8856606 sizeof(xstats_names[0].name), 2065d30ea906Sjfb8856606 "%s", rte_stats_strings[idx].name); 2066d30ea906Sjfb8856606 cnt_used_entries++; 2067d30ea906Sjfb8856606 } 2068d30ea906Sjfb8856606 num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 2069d30ea906Sjfb8856606 for (id_queue = 0; id_queue < num_q; id_queue++) { 2070d30ea906Sjfb8856606 for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) { 2071d30ea906Sjfb8856606 snprintf(xstats_names[cnt_used_entries].name, 2072d30ea906Sjfb8856606 sizeof(xstats_names[0].name), 2073d30ea906Sjfb8856606 "rx_q%u%s", 2074d30ea906Sjfb8856606 id_queue, rte_rxq_stats_strings[idx].name); 2075d30ea906Sjfb8856606 cnt_used_entries++; 2076d30ea906Sjfb8856606 } 2077d30ea906Sjfb8856606 2078d30ea906Sjfb8856606 } 2079d30ea906Sjfb8856606 num_q = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 2080d30ea906Sjfb8856606 for (id_queue = 0; id_queue < num_q; id_queue++) { 2081d30ea906Sjfb8856606 for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) { 2082d30ea906Sjfb8856606 snprintf(xstats_names[cnt_used_entries].name, 2083d30ea906Sjfb8856606 sizeof(xstats_names[0].name), 2084d30ea906Sjfb8856606 "tx_q%u%s", 2085d30ea906Sjfb8856606 id_queue, rte_txq_stats_strings[idx].name); 2086d30ea906Sjfb8856606 cnt_used_entries++; 2087d30ea906Sjfb8856606 } 2088d30ea906Sjfb8856606 } 2089d30ea906Sjfb8856606 return cnt_used_entries; 2090d30ea906Sjfb8856606 } 2091d30ea906Sjfb8856606 2092d30ea906Sjfb8856606 /* retrieve ethdev extended statistics names */ 2093d30ea906Sjfb8856606 int 2094d30ea906Sjfb8856606 rte_eth_xstats_get_names_by_id(uint16_t port_id, 2095d30ea906Sjfb8856606 struct rte_eth_xstat_name *xstats_names, unsigned int size, 2096d30ea906Sjfb8856606 uint64_t *ids) 2097d30ea906Sjfb8856606 { 2098d30ea906Sjfb8856606 struct rte_eth_xstat_name *xstats_names_copy; 2099d30ea906Sjfb8856606 unsigned int no_basic_stat_requested = 1; 2100d30ea906Sjfb8856606 unsigned int no_ext_stat_requested = 1; 2101d30ea906Sjfb8856606 unsigned int expected_entries; 2102d30ea906Sjfb8856606 unsigned int basic_count; 2103d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2104d30ea906Sjfb8856606 unsigned int i; 2105d30ea906Sjfb8856606 int ret; 2106d30ea906Sjfb8856606 2107d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2108d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2109d30ea906Sjfb8856606 2110d30ea906Sjfb8856606 basic_count = get_xstats_basic_count(dev); 2111d30ea906Sjfb8856606 ret = get_xstats_count(port_id); 2112d30ea906Sjfb8856606 if (ret < 0) 2113d30ea906Sjfb8856606 return ret; 2114d30ea906Sjfb8856606 expected_entries = (unsigned int)ret; 2115d30ea906Sjfb8856606 2116d30ea906Sjfb8856606 /* Return max number of stats if no ids given */ 2117d30ea906Sjfb8856606 if (!ids) { 2118d30ea906Sjfb8856606 if (!xstats_names) 2119d30ea906Sjfb8856606 return expected_entries; 2120d30ea906Sjfb8856606 else if (xstats_names && size < expected_entries) 2121d30ea906Sjfb8856606 return expected_entries; 2122d30ea906Sjfb8856606 } 2123d30ea906Sjfb8856606 2124d30ea906Sjfb8856606 if (ids && !xstats_names) 2125d30ea906Sjfb8856606 return -EINVAL; 2126d30ea906Sjfb8856606 2127d30ea906Sjfb8856606 if (ids && dev->dev_ops->xstats_get_names_by_id != NULL && size > 0) { 2128d30ea906Sjfb8856606 uint64_t ids_copy[size]; 2129d30ea906Sjfb8856606 2130d30ea906Sjfb8856606 for (i = 0; i < size; i++) { 2131d30ea906Sjfb8856606 if (ids[i] < basic_count) { 2132d30ea906Sjfb8856606 no_basic_stat_requested = 0; 2133d30ea906Sjfb8856606 break; 2134d30ea906Sjfb8856606 } 2135d30ea906Sjfb8856606 2136d30ea906Sjfb8856606 /* 2137d30ea906Sjfb8856606 * Convert ids to xstats ids that PMD knows. 2138d30ea906Sjfb8856606 * ids known by user are basic + extended stats. 2139d30ea906Sjfb8856606 */ 2140d30ea906Sjfb8856606 ids_copy[i] = ids[i] - basic_count; 2141d30ea906Sjfb8856606 } 2142d30ea906Sjfb8856606 2143d30ea906Sjfb8856606 if (no_basic_stat_requested) 2144d30ea906Sjfb8856606 return (*dev->dev_ops->xstats_get_names_by_id)(dev, 2145d30ea906Sjfb8856606 xstats_names, ids_copy, size); 2146d30ea906Sjfb8856606 } 2147d30ea906Sjfb8856606 2148d30ea906Sjfb8856606 /* Retrieve all stats */ 2149d30ea906Sjfb8856606 if (!ids) { 2150d30ea906Sjfb8856606 int num_stats = rte_eth_xstats_get_names(port_id, xstats_names, 2151d30ea906Sjfb8856606 expected_entries); 2152d30ea906Sjfb8856606 if (num_stats < 0 || num_stats > (int)expected_entries) 2153d30ea906Sjfb8856606 return num_stats; 2154d30ea906Sjfb8856606 else 2155d30ea906Sjfb8856606 return expected_entries; 2156d30ea906Sjfb8856606 } 2157d30ea906Sjfb8856606 2158d30ea906Sjfb8856606 xstats_names_copy = calloc(expected_entries, 2159d30ea906Sjfb8856606 sizeof(struct rte_eth_xstat_name)); 2160d30ea906Sjfb8856606 2161d30ea906Sjfb8856606 if (!xstats_names_copy) { 2162d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Can't allocate memory\n"); 2163d30ea906Sjfb8856606 return -ENOMEM; 2164d30ea906Sjfb8856606 } 2165d30ea906Sjfb8856606 2166d30ea906Sjfb8856606 if (ids) { 2167d30ea906Sjfb8856606 for (i = 0; i < size; i++) { 2168d30ea906Sjfb8856606 if (ids[i] >= basic_count) { 2169d30ea906Sjfb8856606 no_ext_stat_requested = 0; 2170d30ea906Sjfb8856606 break; 2171d30ea906Sjfb8856606 } 2172d30ea906Sjfb8856606 } 2173d30ea906Sjfb8856606 } 2174d30ea906Sjfb8856606 2175d30ea906Sjfb8856606 /* Fill xstats_names_copy structure */ 2176d30ea906Sjfb8856606 if (ids && no_ext_stat_requested) { 2177d30ea906Sjfb8856606 rte_eth_basic_stats_get_names(dev, xstats_names_copy); 2178d30ea906Sjfb8856606 } else { 2179d30ea906Sjfb8856606 ret = rte_eth_xstats_get_names(port_id, xstats_names_copy, 2180d30ea906Sjfb8856606 expected_entries); 2181d30ea906Sjfb8856606 if (ret < 0) { 2182d30ea906Sjfb8856606 free(xstats_names_copy); 2183d30ea906Sjfb8856606 return ret; 2184d30ea906Sjfb8856606 } 2185d30ea906Sjfb8856606 } 2186d30ea906Sjfb8856606 2187d30ea906Sjfb8856606 /* Filter stats */ 2188d30ea906Sjfb8856606 for (i = 0; i < size; i++) { 2189d30ea906Sjfb8856606 if (ids[i] >= expected_entries) { 2190d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n"); 2191d30ea906Sjfb8856606 free(xstats_names_copy); 2192d30ea906Sjfb8856606 return -1; 2193d30ea906Sjfb8856606 } 2194d30ea906Sjfb8856606 xstats_names[i] = xstats_names_copy[ids[i]]; 2195d30ea906Sjfb8856606 } 2196d30ea906Sjfb8856606 2197d30ea906Sjfb8856606 free(xstats_names_copy); 2198d30ea906Sjfb8856606 return size; 2199d30ea906Sjfb8856606 } 2200d30ea906Sjfb8856606 2201d30ea906Sjfb8856606 int 2202d30ea906Sjfb8856606 rte_eth_xstats_get_names(uint16_t port_id, 2203d30ea906Sjfb8856606 struct rte_eth_xstat_name *xstats_names, 2204d30ea906Sjfb8856606 unsigned int size) 2205d30ea906Sjfb8856606 { 2206d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2207d30ea906Sjfb8856606 int cnt_used_entries; 2208d30ea906Sjfb8856606 int cnt_expected_entries; 2209d30ea906Sjfb8856606 int cnt_driver_entries; 2210d30ea906Sjfb8856606 2211d30ea906Sjfb8856606 cnt_expected_entries = get_xstats_count(port_id); 2212d30ea906Sjfb8856606 if (xstats_names == NULL || cnt_expected_entries < 0 || 2213d30ea906Sjfb8856606 (int)size < cnt_expected_entries) 2214d30ea906Sjfb8856606 return cnt_expected_entries; 2215d30ea906Sjfb8856606 2216d30ea906Sjfb8856606 /* port_id checked in get_xstats_count() */ 2217d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2218d30ea906Sjfb8856606 2219d30ea906Sjfb8856606 cnt_used_entries = rte_eth_basic_stats_get_names( 2220d30ea906Sjfb8856606 dev, xstats_names); 2221d30ea906Sjfb8856606 2222d30ea906Sjfb8856606 if (dev->dev_ops->xstats_get_names != NULL) { 2223d30ea906Sjfb8856606 /* If there are any driver-specific xstats, append them 2224d30ea906Sjfb8856606 * to end of list. 2225d30ea906Sjfb8856606 */ 2226d30ea906Sjfb8856606 cnt_driver_entries = (*dev->dev_ops->xstats_get_names)( 2227d30ea906Sjfb8856606 dev, 2228d30ea906Sjfb8856606 xstats_names + cnt_used_entries, 2229d30ea906Sjfb8856606 size - cnt_used_entries); 2230d30ea906Sjfb8856606 if (cnt_driver_entries < 0) 2231d30ea906Sjfb8856606 return eth_err(port_id, cnt_driver_entries); 2232d30ea906Sjfb8856606 cnt_used_entries += cnt_driver_entries; 2233d30ea906Sjfb8856606 } 2234d30ea906Sjfb8856606 2235d30ea906Sjfb8856606 return cnt_used_entries; 2236d30ea906Sjfb8856606 } 2237d30ea906Sjfb8856606 2238d30ea906Sjfb8856606 2239d30ea906Sjfb8856606 static int 2240d30ea906Sjfb8856606 rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats) 2241d30ea906Sjfb8856606 { 2242d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2243d30ea906Sjfb8856606 struct rte_eth_stats eth_stats; 2244d30ea906Sjfb8856606 unsigned int count = 0, i, q; 2245d30ea906Sjfb8856606 uint64_t val, *stats_ptr; 2246d30ea906Sjfb8856606 uint16_t nb_rxqs, nb_txqs; 2247d30ea906Sjfb8856606 int ret; 2248d30ea906Sjfb8856606 2249d30ea906Sjfb8856606 ret = rte_eth_stats_get(port_id, ð_stats); 2250d30ea906Sjfb8856606 if (ret < 0) 2251d30ea906Sjfb8856606 return ret; 2252d30ea906Sjfb8856606 2253d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2254d30ea906Sjfb8856606 2255d30ea906Sjfb8856606 nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 2256d30ea906Sjfb8856606 nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 2257d30ea906Sjfb8856606 2258d30ea906Sjfb8856606 /* global stats */ 2259d30ea906Sjfb8856606 for (i = 0; i < RTE_NB_STATS; i++) { 2260d30ea906Sjfb8856606 stats_ptr = RTE_PTR_ADD(ð_stats, 2261d30ea906Sjfb8856606 rte_stats_strings[i].offset); 2262d30ea906Sjfb8856606 val = *stats_ptr; 2263d30ea906Sjfb8856606 xstats[count++].value = val; 2264d30ea906Sjfb8856606 } 2265d30ea906Sjfb8856606 2266d30ea906Sjfb8856606 /* per-rxq stats */ 2267d30ea906Sjfb8856606 for (q = 0; q < nb_rxqs; q++) { 2268d30ea906Sjfb8856606 for (i = 0; i < RTE_NB_RXQ_STATS; i++) { 2269d30ea906Sjfb8856606 stats_ptr = RTE_PTR_ADD(ð_stats, 2270d30ea906Sjfb8856606 rte_rxq_stats_strings[i].offset + 2271d30ea906Sjfb8856606 q * sizeof(uint64_t)); 2272d30ea906Sjfb8856606 val = *stats_ptr; 2273d30ea906Sjfb8856606 xstats[count++].value = val; 2274d30ea906Sjfb8856606 } 2275d30ea906Sjfb8856606 } 2276d30ea906Sjfb8856606 2277d30ea906Sjfb8856606 /* per-txq stats */ 2278d30ea906Sjfb8856606 for (q = 0; q < nb_txqs; q++) { 2279d30ea906Sjfb8856606 for (i = 0; i < RTE_NB_TXQ_STATS; i++) { 2280d30ea906Sjfb8856606 stats_ptr = RTE_PTR_ADD(ð_stats, 2281d30ea906Sjfb8856606 rte_txq_stats_strings[i].offset + 2282d30ea906Sjfb8856606 q * sizeof(uint64_t)); 2283d30ea906Sjfb8856606 val = *stats_ptr; 2284d30ea906Sjfb8856606 xstats[count++].value = val; 2285d30ea906Sjfb8856606 } 2286d30ea906Sjfb8856606 } 2287d30ea906Sjfb8856606 return count; 2288d30ea906Sjfb8856606 } 2289d30ea906Sjfb8856606 2290d30ea906Sjfb8856606 /* retrieve ethdev extended statistics */ 2291d30ea906Sjfb8856606 int 2292d30ea906Sjfb8856606 rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids, 2293d30ea906Sjfb8856606 uint64_t *values, unsigned int size) 2294d30ea906Sjfb8856606 { 2295d30ea906Sjfb8856606 unsigned int no_basic_stat_requested = 1; 2296d30ea906Sjfb8856606 unsigned int no_ext_stat_requested = 1; 2297d30ea906Sjfb8856606 unsigned int num_xstats_filled; 2298d30ea906Sjfb8856606 unsigned int basic_count; 2299d30ea906Sjfb8856606 uint16_t expected_entries; 2300d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2301d30ea906Sjfb8856606 unsigned int i; 2302d30ea906Sjfb8856606 int ret; 2303d30ea906Sjfb8856606 2304d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2305d30ea906Sjfb8856606 ret = get_xstats_count(port_id); 2306d30ea906Sjfb8856606 if (ret < 0) 2307d30ea906Sjfb8856606 return ret; 2308d30ea906Sjfb8856606 expected_entries = (uint16_t)ret; 2309d30ea906Sjfb8856606 struct rte_eth_xstat xstats[expected_entries]; 2310d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2311d30ea906Sjfb8856606 basic_count = get_xstats_basic_count(dev); 2312d30ea906Sjfb8856606 2313d30ea906Sjfb8856606 /* Return max number of stats if no ids given */ 2314d30ea906Sjfb8856606 if (!ids) { 2315d30ea906Sjfb8856606 if (!values) 2316d30ea906Sjfb8856606 return expected_entries; 2317d30ea906Sjfb8856606 else if (values && size < expected_entries) 2318d30ea906Sjfb8856606 return expected_entries; 2319d30ea906Sjfb8856606 } 2320d30ea906Sjfb8856606 2321d30ea906Sjfb8856606 if (ids && !values) 2322d30ea906Sjfb8856606 return -EINVAL; 2323d30ea906Sjfb8856606 2324d30ea906Sjfb8856606 if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) { 2325d30ea906Sjfb8856606 unsigned int basic_count = get_xstats_basic_count(dev); 2326d30ea906Sjfb8856606 uint64_t ids_copy[size]; 2327d30ea906Sjfb8856606 2328d30ea906Sjfb8856606 for (i = 0; i < size; i++) { 2329d30ea906Sjfb8856606 if (ids[i] < basic_count) { 2330d30ea906Sjfb8856606 no_basic_stat_requested = 0; 2331d30ea906Sjfb8856606 break; 2332d30ea906Sjfb8856606 } 2333d30ea906Sjfb8856606 2334d30ea906Sjfb8856606 /* 2335d30ea906Sjfb8856606 * Convert ids to xstats ids that PMD knows. 2336d30ea906Sjfb8856606 * ids known by user are basic + extended stats. 2337d30ea906Sjfb8856606 */ 2338d30ea906Sjfb8856606 ids_copy[i] = ids[i] - basic_count; 2339d30ea906Sjfb8856606 } 2340d30ea906Sjfb8856606 2341d30ea906Sjfb8856606 if (no_basic_stat_requested) 2342d30ea906Sjfb8856606 return (*dev->dev_ops->xstats_get_by_id)(dev, ids_copy, 2343d30ea906Sjfb8856606 values, size); 2344d30ea906Sjfb8856606 } 2345d30ea906Sjfb8856606 2346d30ea906Sjfb8856606 if (ids) { 2347d30ea906Sjfb8856606 for (i = 0; i < size; i++) { 2348d30ea906Sjfb8856606 if (ids[i] >= basic_count) { 2349d30ea906Sjfb8856606 no_ext_stat_requested = 0; 2350d30ea906Sjfb8856606 break; 2351d30ea906Sjfb8856606 } 2352d30ea906Sjfb8856606 } 2353d30ea906Sjfb8856606 } 2354d30ea906Sjfb8856606 2355d30ea906Sjfb8856606 /* Fill the xstats structure */ 2356d30ea906Sjfb8856606 if (ids && no_ext_stat_requested) 2357d30ea906Sjfb8856606 ret = rte_eth_basic_stats_get(port_id, xstats); 2358d30ea906Sjfb8856606 else 2359d30ea906Sjfb8856606 ret = rte_eth_xstats_get(port_id, xstats, expected_entries); 2360d30ea906Sjfb8856606 2361d30ea906Sjfb8856606 if (ret < 0) 2362d30ea906Sjfb8856606 return ret; 2363d30ea906Sjfb8856606 num_xstats_filled = (unsigned int)ret; 2364d30ea906Sjfb8856606 2365d30ea906Sjfb8856606 /* Return all stats */ 2366d30ea906Sjfb8856606 if (!ids) { 2367d30ea906Sjfb8856606 for (i = 0; i < num_xstats_filled; i++) 2368d30ea906Sjfb8856606 values[i] = xstats[i].value; 2369d30ea906Sjfb8856606 return expected_entries; 2370d30ea906Sjfb8856606 } 2371d30ea906Sjfb8856606 2372d30ea906Sjfb8856606 /* Filter stats */ 2373d30ea906Sjfb8856606 for (i = 0; i < size; i++) { 2374d30ea906Sjfb8856606 if (ids[i] >= expected_entries) { 2375d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n"); 2376d30ea906Sjfb8856606 return -1; 2377d30ea906Sjfb8856606 } 2378d30ea906Sjfb8856606 values[i] = xstats[ids[i]].value; 2379d30ea906Sjfb8856606 } 2380d30ea906Sjfb8856606 return size; 2381d30ea906Sjfb8856606 } 2382d30ea906Sjfb8856606 2383d30ea906Sjfb8856606 int 2384d30ea906Sjfb8856606 rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats, 2385d30ea906Sjfb8856606 unsigned int n) 2386d30ea906Sjfb8856606 { 2387d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2388d30ea906Sjfb8856606 unsigned int count = 0, i; 2389d30ea906Sjfb8856606 signed int xcount = 0; 2390d30ea906Sjfb8856606 uint16_t nb_rxqs, nb_txqs; 2391d30ea906Sjfb8856606 int ret; 2392d30ea906Sjfb8856606 2393d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 2394d30ea906Sjfb8856606 2395d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2396d30ea906Sjfb8856606 2397d30ea906Sjfb8856606 nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 2398d30ea906Sjfb8856606 nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); 2399d30ea906Sjfb8856606 2400d30ea906Sjfb8856606 /* Return generic statistics */ 2401d30ea906Sjfb8856606 count = RTE_NB_STATS + (nb_rxqs * RTE_NB_RXQ_STATS) + 2402d30ea906Sjfb8856606 (nb_txqs * RTE_NB_TXQ_STATS); 2403d30ea906Sjfb8856606 2404d30ea906Sjfb8856606 /* implemented by the driver */ 2405d30ea906Sjfb8856606 if (dev->dev_ops->xstats_get != NULL) { 2406d30ea906Sjfb8856606 /* Retrieve the xstats from the driver at the end of the 2407d30ea906Sjfb8856606 * xstats struct. 2408d30ea906Sjfb8856606 */ 2409d30ea906Sjfb8856606 xcount = (*dev->dev_ops->xstats_get)(dev, 2410d30ea906Sjfb8856606 xstats ? xstats + count : NULL, 2411d30ea906Sjfb8856606 (n > count) ? n - count : 0); 2412d30ea906Sjfb8856606 2413d30ea906Sjfb8856606 if (xcount < 0) 2414d30ea906Sjfb8856606 return eth_err(port_id, xcount); 2415d30ea906Sjfb8856606 } 2416d30ea906Sjfb8856606 2417d30ea906Sjfb8856606 if (n < count + xcount || xstats == NULL) 2418d30ea906Sjfb8856606 return count + xcount; 2419d30ea906Sjfb8856606 2420d30ea906Sjfb8856606 /* now fill the xstats structure */ 2421d30ea906Sjfb8856606 ret = rte_eth_basic_stats_get(port_id, xstats); 2422d30ea906Sjfb8856606 if (ret < 0) 2423d30ea906Sjfb8856606 return ret; 2424d30ea906Sjfb8856606 count = ret; 2425d30ea906Sjfb8856606 2426d30ea906Sjfb8856606 for (i = 0; i < count; i++) 2427d30ea906Sjfb8856606 xstats[i].id = i; 2428d30ea906Sjfb8856606 /* add an offset to driver-specific stats */ 2429d30ea906Sjfb8856606 for ( ; i < count + xcount; i++) 2430d30ea906Sjfb8856606 xstats[i].id += count; 2431d30ea906Sjfb8856606 2432d30ea906Sjfb8856606 return count + xcount; 2433d30ea906Sjfb8856606 } 2434d30ea906Sjfb8856606 2435d30ea906Sjfb8856606 /* reset ethdev extended statistics */ 2436d30ea906Sjfb8856606 void 2437d30ea906Sjfb8856606 rte_eth_xstats_reset(uint16_t port_id) 2438d30ea906Sjfb8856606 { 2439d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2440d30ea906Sjfb8856606 2441d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_RET(port_id); 2442d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2443d30ea906Sjfb8856606 2444d30ea906Sjfb8856606 /* implemented by the driver */ 2445d30ea906Sjfb8856606 if (dev->dev_ops->xstats_reset != NULL) { 2446d30ea906Sjfb8856606 (*dev->dev_ops->xstats_reset)(dev); 2447d30ea906Sjfb8856606 return; 2448d30ea906Sjfb8856606 } 2449d30ea906Sjfb8856606 2450d30ea906Sjfb8856606 /* fallback to default */ 2451d30ea906Sjfb8856606 rte_eth_stats_reset(port_id); 2452d30ea906Sjfb8856606 } 2453d30ea906Sjfb8856606 2454d30ea906Sjfb8856606 static int 2455d30ea906Sjfb8856606 set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id, uint8_t stat_idx, 2456d30ea906Sjfb8856606 uint8_t is_rx) 2457d30ea906Sjfb8856606 { 2458d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2459d30ea906Sjfb8856606 2460d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2461d30ea906Sjfb8856606 2462d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2463d30ea906Sjfb8856606 2464d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set, -ENOTSUP); 2465d30ea906Sjfb8856606 2466d30ea906Sjfb8856606 if (is_rx && (queue_id >= dev->data->nb_rx_queues)) 2467d30ea906Sjfb8856606 return -EINVAL; 2468d30ea906Sjfb8856606 2469d30ea906Sjfb8856606 if (!is_rx && (queue_id >= dev->data->nb_tx_queues)) 2470d30ea906Sjfb8856606 return -EINVAL; 2471d30ea906Sjfb8856606 2472d30ea906Sjfb8856606 if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS) 2473d30ea906Sjfb8856606 return -EINVAL; 2474d30ea906Sjfb8856606 2475d30ea906Sjfb8856606 return (*dev->dev_ops->queue_stats_mapping_set) 2476d30ea906Sjfb8856606 (dev, queue_id, stat_idx, is_rx); 2477d30ea906Sjfb8856606 } 2478d30ea906Sjfb8856606 2479d30ea906Sjfb8856606 2480d30ea906Sjfb8856606 int 2481d30ea906Sjfb8856606 rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id, 2482d30ea906Sjfb8856606 uint8_t stat_idx) 2483d30ea906Sjfb8856606 { 2484d30ea906Sjfb8856606 return eth_err(port_id, set_queue_stats_mapping(port_id, tx_queue_id, 2485d30ea906Sjfb8856606 stat_idx, STAT_QMAP_TX)); 2486d30ea906Sjfb8856606 } 2487d30ea906Sjfb8856606 2488d30ea906Sjfb8856606 2489d30ea906Sjfb8856606 int 2490d30ea906Sjfb8856606 rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id, 2491d30ea906Sjfb8856606 uint8_t stat_idx) 2492d30ea906Sjfb8856606 { 2493d30ea906Sjfb8856606 return eth_err(port_id, set_queue_stats_mapping(port_id, rx_queue_id, 2494d30ea906Sjfb8856606 stat_idx, STAT_QMAP_RX)); 2495d30ea906Sjfb8856606 } 2496d30ea906Sjfb8856606 2497d30ea906Sjfb8856606 int 2498d30ea906Sjfb8856606 rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size) 2499d30ea906Sjfb8856606 { 2500d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2501d30ea906Sjfb8856606 2502d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2503d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2504d30ea906Sjfb8856606 2505d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP); 2506d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev, 2507d30ea906Sjfb8856606 fw_version, fw_size)); 2508d30ea906Sjfb8856606 } 2509d30ea906Sjfb8856606 2510d30ea906Sjfb8856606 void 2511d30ea906Sjfb8856606 rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info) 2512d30ea906Sjfb8856606 { 2513d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2514d30ea906Sjfb8856606 const struct rte_eth_desc_lim lim = { 2515d30ea906Sjfb8856606 .nb_max = UINT16_MAX, 2516d30ea906Sjfb8856606 .nb_min = 0, 2517d30ea906Sjfb8856606 .nb_align = 1, 2518d30ea906Sjfb8856606 }; 2519d30ea906Sjfb8856606 2520*4b05018fSfengbojiang /* 2521*4b05018fSfengbojiang * Init dev_info before port_id check since caller does not have 2522*4b05018fSfengbojiang * return status and does not know if get is successful or not. 2523*4b05018fSfengbojiang */ 2524*4b05018fSfengbojiang memset(dev_info, 0, sizeof(struct rte_eth_dev_info)); 2525*4b05018fSfengbojiang 2526d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_RET(port_id); 2527d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2528d30ea906Sjfb8856606 2529d30ea906Sjfb8856606 dev_info->rx_desc_lim = lim; 2530d30ea906Sjfb8856606 dev_info->tx_desc_lim = lim; 2531d30ea906Sjfb8856606 dev_info->device = dev->device; 2532d30ea906Sjfb8856606 2533d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get); 2534d30ea906Sjfb8856606 (*dev->dev_ops->dev_infos_get)(dev, dev_info); 2535d30ea906Sjfb8856606 dev_info->driver_name = dev->device->driver->name; 2536d30ea906Sjfb8856606 dev_info->nb_rx_queues = dev->data->nb_rx_queues; 2537d30ea906Sjfb8856606 dev_info->nb_tx_queues = dev->data->nb_tx_queues; 2538d30ea906Sjfb8856606 2539d30ea906Sjfb8856606 dev_info->dev_flags = &dev->data->dev_flags; 2540d30ea906Sjfb8856606 } 2541d30ea906Sjfb8856606 2542d30ea906Sjfb8856606 int 2543d30ea906Sjfb8856606 rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask, 2544d30ea906Sjfb8856606 uint32_t *ptypes, int num) 2545d30ea906Sjfb8856606 { 2546d30ea906Sjfb8856606 int i, j; 2547d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2548d30ea906Sjfb8856606 const uint32_t *all_ptypes; 2549d30ea906Sjfb8856606 2550d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2551d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2552d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0); 2553d30ea906Sjfb8856606 all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev); 2554d30ea906Sjfb8856606 2555d30ea906Sjfb8856606 if (!all_ptypes) 2556d30ea906Sjfb8856606 return 0; 2557d30ea906Sjfb8856606 2558d30ea906Sjfb8856606 for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i) 2559d30ea906Sjfb8856606 if (all_ptypes[i] & ptype_mask) { 2560d30ea906Sjfb8856606 if (j < num) 2561d30ea906Sjfb8856606 ptypes[j] = all_ptypes[i]; 2562d30ea906Sjfb8856606 j++; 2563d30ea906Sjfb8856606 } 2564d30ea906Sjfb8856606 2565d30ea906Sjfb8856606 return j; 2566d30ea906Sjfb8856606 } 2567d30ea906Sjfb8856606 2568d30ea906Sjfb8856606 void 2569d30ea906Sjfb8856606 rte_eth_macaddr_get(uint16_t port_id, struct ether_addr *mac_addr) 2570d30ea906Sjfb8856606 { 2571d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2572d30ea906Sjfb8856606 2573d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_RET(port_id); 2574d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2575d30ea906Sjfb8856606 ether_addr_copy(&dev->data->mac_addrs[0], mac_addr); 2576d30ea906Sjfb8856606 } 2577d30ea906Sjfb8856606 2578d30ea906Sjfb8856606 2579d30ea906Sjfb8856606 int 2580d30ea906Sjfb8856606 rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu) 2581d30ea906Sjfb8856606 { 2582d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2583d30ea906Sjfb8856606 2584d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2585d30ea906Sjfb8856606 2586d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2587d30ea906Sjfb8856606 *mtu = dev->data->mtu; 2588d30ea906Sjfb8856606 return 0; 2589d30ea906Sjfb8856606 } 2590d30ea906Sjfb8856606 2591d30ea906Sjfb8856606 int 2592d30ea906Sjfb8856606 rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu) 2593d30ea906Sjfb8856606 { 2594d30ea906Sjfb8856606 int ret; 2595d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2596d30ea906Sjfb8856606 2597d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2598d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2599d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mtu_set, -ENOTSUP); 2600d30ea906Sjfb8856606 2601d30ea906Sjfb8856606 ret = (*dev->dev_ops->mtu_set)(dev, mtu); 2602d30ea906Sjfb8856606 if (!ret) 2603d30ea906Sjfb8856606 dev->data->mtu = mtu; 2604d30ea906Sjfb8856606 2605d30ea906Sjfb8856606 return eth_err(port_id, ret); 2606d30ea906Sjfb8856606 } 2607d30ea906Sjfb8856606 2608d30ea906Sjfb8856606 int 2609d30ea906Sjfb8856606 rte_eth_dev_vlan_filter(uint16_t port_id, uint16_t vlan_id, int on) 2610d30ea906Sjfb8856606 { 2611d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2612d30ea906Sjfb8856606 int ret; 2613d30ea906Sjfb8856606 2614d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2615d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2616d30ea906Sjfb8856606 if (!(dev->data->dev_conf.rxmode.offloads & 2617d30ea906Sjfb8856606 DEV_RX_OFFLOAD_VLAN_FILTER)) { 2618d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port %u: vlan-filtering disabled\n", 2619d30ea906Sjfb8856606 port_id); 2620d30ea906Sjfb8856606 return -ENOSYS; 2621d30ea906Sjfb8856606 } 2622d30ea906Sjfb8856606 2623d30ea906Sjfb8856606 if (vlan_id > 4095) { 2624d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port_id=%u invalid vlan_id=%u > 4095\n", 2625d30ea906Sjfb8856606 port_id, vlan_id); 2626d30ea906Sjfb8856606 return -EINVAL; 2627d30ea906Sjfb8856606 } 2628d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_filter_set, -ENOTSUP); 2629d30ea906Sjfb8856606 2630d30ea906Sjfb8856606 ret = (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); 2631d30ea906Sjfb8856606 if (ret == 0) { 2632d30ea906Sjfb8856606 struct rte_vlan_filter_conf *vfc; 2633d30ea906Sjfb8856606 int vidx; 2634d30ea906Sjfb8856606 int vbit; 2635d30ea906Sjfb8856606 2636d30ea906Sjfb8856606 vfc = &dev->data->vlan_filter_conf; 2637d30ea906Sjfb8856606 vidx = vlan_id / 64; 2638d30ea906Sjfb8856606 vbit = vlan_id % 64; 2639d30ea906Sjfb8856606 2640d30ea906Sjfb8856606 if (on) 2641d30ea906Sjfb8856606 vfc->ids[vidx] |= UINT64_C(1) << vbit; 2642d30ea906Sjfb8856606 else 2643d30ea906Sjfb8856606 vfc->ids[vidx] &= ~(UINT64_C(1) << vbit); 2644d30ea906Sjfb8856606 } 2645d30ea906Sjfb8856606 2646d30ea906Sjfb8856606 return eth_err(port_id, ret); 2647d30ea906Sjfb8856606 } 2648d30ea906Sjfb8856606 2649d30ea906Sjfb8856606 int 2650d30ea906Sjfb8856606 rte_eth_dev_set_vlan_strip_on_queue(uint16_t port_id, uint16_t rx_queue_id, 2651d30ea906Sjfb8856606 int on) 2652d30ea906Sjfb8856606 { 2653d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2654d30ea906Sjfb8856606 2655d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2656d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2657d30ea906Sjfb8856606 if (rx_queue_id >= dev->data->nb_rx_queues) { 2658d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid rx_queue_id=%u\n", rx_queue_id); 2659d30ea906Sjfb8856606 return -EINVAL; 2660d30ea906Sjfb8856606 } 2661d30ea906Sjfb8856606 2662d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP); 2663d30ea906Sjfb8856606 (*dev->dev_ops->vlan_strip_queue_set)(dev, rx_queue_id, on); 2664d30ea906Sjfb8856606 2665d30ea906Sjfb8856606 return 0; 2666d30ea906Sjfb8856606 } 2667d30ea906Sjfb8856606 2668d30ea906Sjfb8856606 int 2669d30ea906Sjfb8856606 rte_eth_dev_set_vlan_ether_type(uint16_t port_id, 2670d30ea906Sjfb8856606 enum rte_vlan_type vlan_type, 2671d30ea906Sjfb8856606 uint16_t tpid) 2672d30ea906Sjfb8856606 { 2673d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2674d30ea906Sjfb8856606 2675d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2676d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2677d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP); 2678d30ea906Sjfb8856606 2679d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->vlan_tpid_set)(dev, vlan_type, 2680d30ea906Sjfb8856606 tpid)); 2681d30ea906Sjfb8856606 } 2682d30ea906Sjfb8856606 2683d30ea906Sjfb8856606 int 2684d30ea906Sjfb8856606 rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask) 2685d30ea906Sjfb8856606 { 2686d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2687d30ea906Sjfb8856606 int ret = 0; 2688d30ea906Sjfb8856606 int mask = 0; 2689d30ea906Sjfb8856606 int cur, org = 0; 2690d30ea906Sjfb8856606 uint64_t orig_offloads; 2691d30ea906Sjfb8856606 2692d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2693d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2694d30ea906Sjfb8856606 2695d30ea906Sjfb8856606 /* save original values in case of failure */ 2696d30ea906Sjfb8856606 orig_offloads = dev->data->dev_conf.rxmode.offloads; 2697d30ea906Sjfb8856606 2698d30ea906Sjfb8856606 /*check which option changed by application*/ 2699d30ea906Sjfb8856606 cur = !!(offload_mask & ETH_VLAN_STRIP_OFFLOAD); 2700d30ea906Sjfb8856606 org = !!(dev->data->dev_conf.rxmode.offloads & 2701d30ea906Sjfb8856606 DEV_RX_OFFLOAD_VLAN_STRIP); 2702d30ea906Sjfb8856606 if (cur != org) { 2703d30ea906Sjfb8856606 if (cur) 2704d30ea906Sjfb8856606 dev->data->dev_conf.rxmode.offloads |= 2705d30ea906Sjfb8856606 DEV_RX_OFFLOAD_VLAN_STRIP; 2706d30ea906Sjfb8856606 else 2707d30ea906Sjfb8856606 dev->data->dev_conf.rxmode.offloads &= 2708d30ea906Sjfb8856606 ~DEV_RX_OFFLOAD_VLAN_STRIP; 2709d30ea906Sjfb8856606 mask |= ETH_VLAN_STRIP_MASK; 2710d30ea906Sjfb8856606 } 2711d30ea906Sjfb8856606 2712d30ea906Sjfb8856606 cur = !!(offload_mask & ETH_VLAN_FILTER_OFFLOAD); 2713d30ea906Sjfb8856606 org = !!(dev->data->dev_conf.rxmode.offloads & 2714d30ea906Sjfb8856606 DEV_RX_OFFLOAD_VLAN_FILTER); 2715d30ea906Sjfb8856606 if (cur != org) { 2716d30ea906Sjfb8856606 if (cur) 2717d30ea906Sjfb8856606 dev->data->dev_conf.rxmode.offloads |= 2718d30ea906Sjfb8856606 DEV_RX_OFFLOAD_VLAN_FILTER; 2719d30ea906Sjfb8856606 else 2720d30ea906Sjfb8856606 dev->data->dev_conf.rxmode.offloads &= 2721d30ea906Sjfb8856606 ~DEV_RX_OFFLOAD_VLAN_FILTER; 2722d30ea906Sjfb8856606 mask |= ETH_VLAN_FILTER_MASK; 2723d30ea906Sjfb8856606 } 2724d30ea906Sjfb8856606 2725d30ea906Sjfb8856606 cur = !!(offload_mask & ETH_VLAN_EXTEND_OFFLOAD); 2726d30ea906Sjfb8856606 org = !!(dev->data->dev_conf.rxmode.offloads & 2727d30ea906Sjfb8856606 DEV_RX_OFFLOAD_VLAN_EXTEND); 2728d30ea906Sjfb8856606 if (cur != org) { 2729d30ea906Sjfb8856606 if (cur) 2730d30ea906Sjfb8856606 dev->data->dev_conf.rxmode.offloads |= 2731d30ea906Sjfb8856606 DEV_RX_OFFLOAD_VLAN_EXTEND; 2732d30ea906Sjfb8856606 else 2733d30ea906Sjfb8856606 dev->data->dev_conf.rxmode.offloads &= 2734d30ea906Sjfb8856606 ~DEV_RX_OFFLOAD_VLAN_EXTEND; 2735d30ea906Sjfb8856606 mask |= ETH_VLAN_EXTEND_MASK; 2736d30ea906Sjfb8856606 } 2737d30ea906Sjfb8856606 2738d30ea906Sjfb8856606 /*no change*/ 2739d30ea906Sjfb8856606 if (mask == 0) 2740d30ea906Sjfb8856606 return ret; 2741d30ea906Sjfb8856606 2742d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_offload_set, -ENOTSUP); 2743d30ea906Sjfb8856606 ret = (*dev->dev_ops->vlan_offload_set)(dev, mask); 2744d30ea906Sjfb8856606 if (ret) { 2745d30ea906Sjfb8856606 /* hit an error restore original values */ 2746d30ea906Sjfb8856606 dev->data->dev_conf.rxmode.offloads = orig_offloads; 2747d30ea906Sjfb8856606 } 2748d30ea906Sjfb8856606 2749d30ea906Sjfb8856606 return eth_err(port_id, ret); 2750d30ea906Sjfb8856606 } 2751d30ea906Sjfb8856606 2752d30ea906Sjfb8856606 int 2753d30ea906Sjfb8856606 rte_eth_dev_get_vlan_offload(uint16_t port_id) 2754d30ea906Sjfb8856606 { 2755d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2756d30ea906Sjfb8856606 int ret = 0; 2757d30ea906Sjfb8856606 2758d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2759d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2760d30ea906Sjfb8856606 2761d30ea906Sjfb8856606 if (dev->data->dev_conf.rxmode.offloads & 2762d30ea906Sjfb8856606 DEV_RX_OFFLOAD_VLAN_STRIP) 2763d30ea906Sjfb8856606 ret |= ETH_VLAN_STRIP_OFFLOAD; 2764d30ea906Sjfb8856606 2765d30ea906Sjfb8856606 if (dev->data->dev_conf.rxmode.offloads & 2766d30ea906Sjfb8856606 DEV_RX_OFFLOAD_VLAN_FILTER) 2767d30ea906Sjfb8856606 ret |= ETH_VLAN_FILTER_OFFLOAD; 2768d30ea906Sjfb8856606 2769d30ea906Sjfb8856606 if (dev->data->dev_conf.rxmode.offloads & 2770d30ea906Sjfb8856606 DEV_RX_OFFLOAD_VLAN_EXTEND) 2771d30ea906Sjfb8856606 ret |= ETH_VLAN_EXTEND_OFFLOAD; 2772d30ea906Sjfb8856606 2773d30ea906Sjfb8856606 return ret; 2774d30ea906Sjfb8856606 } 2775d30ea906Sjfb8856606 2776d30ea906Sjfb8856606 int 2777d30ea906Sjfb8856606 rte_eth_dev_set_vlan_pvid(uint16_t port_id, uint16_t pvid, int on) 2778d30ea906Sjfb8856606 { 2779d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2780d30ea906Sjfb8856606 2781d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2782d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2783d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_pvid_set, -ENOTSUP); 2784d30ea906Sjfb8856606 2785d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->vlan_pvid_set)(dev, pvid, on)); 2786d30ea906Sjfb8856606 } 2787d30ea906Sjfb8856606 2788d30ea906Sjfb8856606 int 2789d30ea906Sjfb8856606 rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf) 2790d30ea906Sjfb8856606 { 2791d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2792d30ea906Sjfb8856606 2793d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2794d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2795d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP); 2796d30ea906Sjfb8856606 memset(fc_conf, 0, sizeof(*fc_conf)); 2797d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf)); 2798d30ea906Sjfb8856606 } 2799d30ea906Sjfb8856606 2800d30ea906Sjfb8856606 int 2801d30ea906Sjfb8856606 rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf) 2802d30ea906Sjfb8856606 { 2803d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2804d30ea906Sjfb8856606 2805d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2806d30ea906Sjfb8856606 if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) { 2807d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n"); 2808d30ea906Sjfb8856606 return -EINVAL; 2809d30ea906Sjfb8856606 } 2810d30ea906Sjfb8856606 2811d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2812d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP); 2813d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf)); 2814d30ea906Sjfb8856606 } 2815d30ea906Sjfb8856606 2816d30ea906Sjfb8856606 int 2817d30ea906Sjfb8856606 rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id, 2818d30ea906Sjfb8856606 struct rte_eth_pfc_conf *pfc_conf) 2819d30ea906Sjfb8856606 { 2820d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2821d30ea906Sjfb8856606 2822d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2823d30ea906Sjfb8856606 if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) { 2824d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n"); 2825d30ea906Sjfb8856606 return -EINVAL; 2826d30ea906Sjfb8856606 } 2827d30ea906Sjfb8856606 2828d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2829d30ea906Sjfb8856606 /* High water, low water validation are device specific */ 2830d30ea906Sjfb8856606 if (*dev->dev_ops->priority_flow_ctrl_set) 2831d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set) 2832d30ea906Sjfb8856606 (dev, pfc_conf)); 2833d30ea906Sjfb8856606 return -ENOTSUP; 2834d30ea906Sjfb8856606 } 2835d30ea906Sjfb8856606 2836d30ea906Sjfb8856606 static int 2837d30ea906Sjfb8856606 rte_eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf, 2838d30ea906Sjfb8856606 uint16_t reta_size) 2839d30ea906Sjfb8856606 { 2840d30ea906Sjfb8856606 uint16_t i, num; 2841d30ea906Sjfb8856606 2842d30ea906Sjfb8856606 if (!reta_conf) 2843d30ea906Sjfb8856606 return -EINVAL; 2844d30ea906Sjfb8856606 2845d30ea906Sjfb8856606 num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE; 2846d30ea906Sjfb8856606 for (i = 0; i < num; i++) { 2847d30ea906Sjfb8856606 if (reta_conf[i].mask) 2848d30ea906Sjfb8856606 return 0; 2849d30ea906Sjfb8856606 } 2850d30ea906Sjfb8856606 2851d30ea906Sjfb8856606 return -EINVAL; 2852d30ea906Sjfb8856606 } 2853d30ea906Sjfb8856606 2854d30ea906Sjfb8856606 static int 2855d30ea906Sjfb8856606 rte_eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf, 2856d30ea906Sjfb8856606 uint16_t reta_size, 2857d30ea906Sjfb8856606 uint16_t max_rxq) 2858d30ea906Sjfb8856606 { 2859d30ea906Sjfb8856606 uint16_t i, idx, shift; 2860d30ea906Sjfb8856606 2861d30ea906Sjfb8856606 if (!reta_conf) 2862d30ea906Sjfb8856606 return -EINVAL; 2863d30ea906Sjfb8856606 2864d30ea906Sjfb8856606 if (max_rxq == 0) { 2865d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "No receive queue is available\n"); 2866d30ea906Sjfb8856606 return -EINVAL; 2867d30ea906Sjfb8856606 } 2868d30ea906Sjfb8856606 2869d30ea906Sjfb8856606 for (i = 0; i < reta_size; i++) { 2870d30ea906Sjfb8856606 idx = i / RTE_RETA_GROUP_SIZE; 2871d30ea906Sjfb8856606 shift = i % RTE_RETA_GROUP_SIZE; 2872d30ea906Sjfb8856606 if ((reta_conf[idx].mask & (1ULL << shift)) && 2873d30ea906Sjfb8856606 (reta_conf[idx].reta[shift] >= max_rxq)) { 2874d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 2875d30ea906Sjfb8856606 "reta_conf[%u]->reta[%u]: %u exceeds the maximum rxq index: %u\n", 2876d30ea906Sjfb8856606 idx, shift, 2877d30ea906Sjfb8856606 reta_conf[idx].reta[shift], max_rxq); 2878d30ea906Sjfb8856606 return -EINVAL; 2879d30ea906Sjfb8856606 } 2880d30ea906Sjfb8856606 } 2881d30ea906Sjfb8856606 2882d30ea906Sjfb8856606 return 0; 2883d30ea906Sjfb8856606 } 2884d30ea906Sjfb8856606 2885d30ea906Sjfb8856606 int 2886d30ea906Sjfb8856606 rte_eth_dev_rss_reta_update(uint16_t port_id, 2887d30ea906Sjfb8856606 struct rte_eth_rss_reta_entry64 *reta_conf, 2888d30ea906Sjfb8856606 uint16_t reta_size) 2889d30ea906Sjfb8856606 { 2890d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2891d30ea906Sjfb8856606 int ret; 2892d30ea906Sjfb8856606 2893d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2894d30ea906Sjfb8856606 /* Check mask bits */ 2895d30ea906Sjfb8856606 ret = rte_eth_check_reta_mask(reta_conf, reta_size); 2896d30ea906Sjfb8856606 if (ret < 0) 2897d30ea906Sjfb8856606 return ret; 2898d30ea906Sjfb8856606 2899d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2900d30ea906Sjfb8856606 2901d30ea906Sjfb8856606 /* Check entry value */ 2902d30ea906Sjfb8856606 ret = rte_eth_check_reta_entry(reta_conf, reta_size, 2903d30ea906Sjfb8856606 dev->data->nb_rx_queues); 2904d30ea906Sjfb8856606 if (ret < 0) 2905d30ea906Sjfb8856606 return ret; 2906d30ea906Sjfb8856606 2907d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_update, -ENOTSUP); 2908d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->reta_update)(dev, reta_conf, 2909d30ea906Sjfb8856606 reta_size)); 2910d30ea906Sjfb8856606 } 2911d30ea906Sjfb8856606 2912d30ea906Sjfb8856606 int 2913d30ea906Sjfb8856606 rte_eth_dev_rss_reta_query(uint16_t port_id, 2914d30ea906Sjfb8856606 struct rte_eth_rss_reta_entry64 *reta_conf, 2915d30ea906Sjfb8856606 uint16_t reta_size) 2916d30ea906Sjfb8856606 { 2917d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2918d30ea906Sjfb8856606 int ret; 2919d30ea906Sjfb8856606 2920d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2921d30ea906Sjfb8856606 2922d30ea906Sjfb8856606 /* Check mask bits */ 2923d30ea906Sjfb8856606 ret = rte_eth_check_reta_mask(reta_conf, reta_size); 2924d30ea906Sjfb8856606 if (ret < 0) 2925d30ea906Sjfb8856606 return ret; 2926d30ea906Sjfb8856606 2927d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2928d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP); 2929d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf, 2930d30ea906Sjfb8856606 reta_size)); 2931d30ea906Sjfb8856606 } 2932d30ea906Sjfb8856606 2933d30ea906Sjfb8856606 int 2934d30ea906Sjfb8856606 rte_eth_dev_rss_hash_update(uint16_t port_id, 2935d30ea906Sjfb8856606 struct rte_eth_rss_conf *rss_conf) 2936d30ea906Sjfb8856606 { 2937d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2938d30ea906Sjfb8856606 struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, }; 2939d30ea906Sjfb8856606 2940d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2941d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2942d30ea906Sjfb8856606 rte_eth_dev_info_get(port_id, &dev_info); 2943d30ea906Sjfb8856606 if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) != 2944d30ea906Sjfb8856606 dev_info.flow_type_rss_offloads) { 2945d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 2946d30ea906Sjfb8856606 "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n", 2947d30ea906Sjfb8856606 port_id, rss_conf->rss_hf, 2948d30ea906Sjfb8856606 dev_info.flow_type_rss_offloads); 2949d30ea906Sjfb8856606 return -EINVAL; 2950d30ea906Sjfb8856606 } 2951d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP); 2952d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->rss_hash_update)(dev, 2953d30ea906Sjfb8856606 rss_conf)); 2954d30ea906Sjfb8856606 } 2955d30ea906Sjfb8856606 2956d30ea906Sjfb8856606 int 2957d30ea906Sjfb8856606 rte_eth_dev_rss_hash_conf_get(uint16_t port_id, 2958d30ea906Sjfb8856606 struct rte_eth_rss_conf *rss_conf) 2959d30ea906Sjfb8856606 { 2960d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2961d30ea906Sjfb8856606 2962d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2963d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2964d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP); 2965d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev, 2966d30ea906Sjfb8856606 rss_conf)); 2967d30ea906Sjfb8856606 } 2968d30ea906Sjfb8856606 2969d30ea906Sjfb8856606 int 2970d30ea906Sjfb8856606 rte_eth_dev_udp_tunnel_port_add(uint16_t port_id, 2971d30ea906Sjfb8856606 struct rte_eth_udp_tunnel *udp_tunnel) 2972d30ea906Sjfb8856606 { 2973d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2974d30ea906Sjfb8856606 2975d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2976d30ea906Sjfb8856606 if (udp_tunnel == NULL) { 2977d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid udp_tunnel parameter\n"); 2978d30ea906Sjfb8856606 return -EINVAL; 2979d30ea906Sjfb8856606 } 2980d30ea906Sjfb8856606 2981d30ea906Sjfb8856606 if (udp_tunnel->prot_type >= RTE_TUNNEL_TYPE_MAX) { 2982d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n"); 2983d30ea906Sjfb8856606 return -EINVAL; 2984d30ea906Sjfb8856606 } 2985d30ea906Sjfb8856606 2986d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 2987d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_add, -ENOTSUP); 2988d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_add)(dev, 2989d30ea906Sjfb8856606 udp_tunnel)); 2990d30ea906Sjfb8856606 } 2991d30ea906Sjfb8856606 2992d30ea906Sjfb8856606 int 2993d30ea906Sjfb8856606 rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id, 2994d30ea906Sjfb8856606 struct rte_eth_udp_tunnel *udp_tunnel) 2995d30ea906Sjfb8856606 { 2996d30ea906Sjfb8856606 struct rte_eth_dev *dev; 2997d30ea906Sjfb8856606 2998d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 2999d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3000d30ea906Sjfb8856606 3001d30ea906Sjfb8856606 if (udp_tunnel == NULL) { 3002d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid udp_tunnel parameter\n"); 3003d30ea906Sjfb8856606 return -EINVAL; 3004d30ea906Sjfb8856606 } 3005d30ea906Sjfb8856606 3006d30ea906Sjfb8856606 if (udp_tunnel->prot_type >= RTE_TUNNEL_TYPE_MAX) { 3007d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n"); 3008d30ea906Sjfb8856606 return -EINVAL; 3009d30ea906Sjfb8856606 } 3010d30ea906Sjfb8856606 3011d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_del, -ENOTSUP); 3012d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_del)(dev, 3013d30ea906Sjfb8856606 udp_tunnel)); 3014d30ea906Sjfb8856606 } 3015d30ea906Sjfb8856606 3016d30ea906Sjfb8856606 int 3017d30ea906Sjfb8856606 rte_eth_led_on(uint16_t port_id) 3018d30ea906Sjfb8856606 { 3019d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3020d30ea906Sjfb8856606 3021d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3022d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3023d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_on, -ENOTSUP); 3024d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->dev_led_on)(dev)); 3025d30ea906Sjfb8856606 } 3026d30ea906Sjfb8856606 3027d30ea906Sjfb8856606 int 3028d30ea906Sjfb8856606 rte_eth_led_off(uint16_t port_id) 3029d30ea906Sjfb8856606 { 3030d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3031d30ea906Sjfb8856606 3032d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3033d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3034d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_off, -ENOTSUP); 3035d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->dev_led_off)(dev)); 3036d30ea906Sjfb8856606 } 3037d30ea906Sjfb8856606 3038d30ea906Sjfb8856606 /* 3039d30ea906Sjfb8856606 * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find 3040d30ea906Sjfb8856606 * an empty spot. 3041d30ea906Sjfb8856606 */ 3042d30ea906Sjfb8856606 static int 3043d30ea906Sjfb8856606 get_mac_addr_index(uint16_t port_id, const struct ether_addr *addr) 3044d30ea906Sjfb8856606 { 3045d30ea906Sjfb8856606 struct rte_eth_dev_info dev_info; 3046d30ea906Sjfb8856606 struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 3047d30ea906Sjfb8856606 unsigned i; 3048d30ea906Sjfb8856606 3049d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3050d30ea906Sjfb8856606 rte_eth_dev_info_get(port_id, &dev_info); 3051d30ea906Sjfb8856606 3052d30ea906Sjfb8856606 for (i = 0; i < dev_info.max_mac_addrs; i++) 3053d30ea906Sjfb8856606 if (memcmp(addr, &dev->data->mac_addrs[i], ETHER_ADDR_LEN) == 0) 3054d30ea906Sjfb8856606 return i; 3055d30ea906Sjfb8856606 3056d30ea906Sjfb8856606 return -1; 3057d30ea906Sjfb8856606 } 3058d30ea906Sjfb8856606 3059d30ea906Sjfb8856606 static const struct ether_addr null_mac_addr; 3060d30ea906Sjfb8856606 3061d30ea906Sjfb8856606 int 3062d30ea906Sjfb8856606 rte_eth_dev_mac_addr_add(uint16_t port_id, struct ether_addr *addr, 3063d30ea906Sjfb8856606 uint32_t pool) 3064d30ea906Sjfb8856606 { 3065d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3066d30ea906Sjfb8856606 int index; 3067d30ea906Sjfb8856606 uint64_t pool_mask; 3068d30ea906Sjfb8856606 int ret; 3069d30ea906Sjfb8856606 3070d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3071d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3072d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP); 3073d30ea906Sjfb8856606 3074d30ea906Sjfb8856606 if (is_zero_ether_addr(addr)) { 3075d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n", 3076d30ea906Sjfb8856606 port_id); 3077d30ea906Sjfb8856606 return -EINVAL; 3078d30ea906Sjfb8856606 } 3079d30ea906Sjfb8856606 if (pool >= ETH_64_POOLS) { 3080d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Pool id must be 0-%d\n", ETH_64_POOLS - 1); 3081d30ea906Sjfb8856606 return -EINVAL; 3082d30ea906Sjfb8856606 } 3083d30ea906Sjfb8856606 3084d30ea906Sjfb8856606 index = get_mac_addr_index(port_id, addr); 3085d30ea906Sjfb8856606 if (index < 0) { 3086d30ea906Sjfb8856606 index = get_mac_addr_index(port_id, &null_mac_addr); 3087d30ea906Sjfb8856606 if (index < 0) { 3088d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n", 3089d30ea906Sjfb8856606 port_id); 3090d30ea906Sjfb8856606 return -ENOSPC; 3091d30ea906Sjfb8856606 } 3092d30ea906Sjfb8856606 } else { 3093d30ea906Sjfb8856606 pool_mask = dev->data->mac_pool_sel[index]; 3094d30ea906Sjfb8856606 3095d30ea906Sjfb8856606 /* Check if both MAC address and pool is already there, and do nothing */ 3096d30ea906Sjfb8856606 if (pool_mask & (1ULL << pool)) 3097d30ea906Sjfb8856606 return 0; 3098d30ea906Sjfb8856606 } 3099d30ea906Sjfb8856606 3100d30ea906Sjfb8856606 /* Update NIC */ 3101d30ea906Sjfb8856606 ret = (*dev->dev_ops->mac_addr_add)(dev, addr, index, pool); 3102d30ea906Sjfb8856606 3103d30ea906Sjfb8856606 if (ret == 0) { 3104d30ea906Sjfb8856606 /* Update address in NIC data structure */ 3105d30ea906Sjfb8856606 ether_addr_copy(addr, &dev->data->mac_addrs[index]); 3106d30ea906Sjfb8856606 3107d30ea906Sjfb8856606 /* Update pool bitmap in NIC data structure */ 3108d30ea906Sjfb8856606 dev->data->mac_pool_sel[index] |= (1ULL << pool); 3109d30ea906Sjfb8856606 } 3110d30ea906Sjfb8856606 3111d30ea906Sjfb8856606 return eth_err(port_id, ret); 3112d30ea906Sjfb8856606 } 3113d30ea906Sjfb8856606 3114d30ea906Sjfb8856606 int 3115d30ea906Sjfb8856606 rte_eth_dev_mac_addr_remove(uint16_t port_id, struct ether_addr *addr) 3116d30ea906Sjfb8856606 { 3117d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3118d30ea906Sjfb8856606 int index; 3119d30ea906Sjfb8856606 3120d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3121d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3122d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP); 3123d30ea906Sjfb8856606 3124d30ea906Sjfb8856606 index = get_mac_addr_index(port_id, addr); 3125d30ea906Sjfb8856606 if (index == 0) { 3126d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 3127d30ea906Sjfb8856606 "Port %u: Cannot remove default MAC address\n", 3128d30ea906Sjfb8856606 port_id); 3129d30ea906Sjfb8856606 return -EADDRINUSE; 3130d30ea906Sjfb8856606 } else if (index < 0) 3131d30ea906Sjfb8856606 return 0; /* Do nothing if address wasn't found */ 3132d30ea906Sjfb8856606 3133d30ea906Sjfb8856606 /* Update NIC */ 3134d30ea906Sjfb8856606 (*dev->dev_ops->mac_addr_remove)(dev, index); 3135d30ea906Sjfb8856606 3136d30ea906Sjfb8856606 /* Update address in NIC data structure */ 3137d30ea906Sjfb8856606 ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]); 3138d30ea906Sjfb8856606 3139d30ea906Sjfb8856606 /* reset pool bitmap */ 3140d30ea906Sjfb8856606 dev->data->mac_pool_sel[index] = 0; 3141d30ea906Sjfb8856606 3142d30ea906Sjfb8856606 return 0; 3143d30ea906Sjfb8856606 } 3144d30ea906Sjfb8856606 3145d30ea906Sjfb8856606 int 3146d30ea906Sjfb8856606 rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr) 3147d30ea906Sjfb8856606 { 3148d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3149d30ea906Sjfb8856606 int ret; 3150d30ea906Sjfb8856606 3151d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3152d30ea906Sjfb8856606 3153d30ea906Sjfb8856606 if (!is_valid_assigned_ether_addr(addr)) 3154d30ea906Sjfb8856606 return -EINVAL; 3155d30ea906Sjfb8856606 3156d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3157d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP); 3158d30ea906Sjfb8856606 3159d30ea906Sjfb8856606 ret = (*dev->dev_ops->mac_addr_set)(dev, addr); 3160d30ea906Sjfb8856606 if (ret < 0) 3161d30ea906Sjfb8856606 return ret; 3162d30ea906Sjfb8856606 3163d30ea906Sjfb8856606 /* Update default address in NIC data structure */ 3164d30ea906Sjfb8856606 ether_addr_copy(addr, &dev->data->mac_addrs[0]); 3165d30ea906Sjfb8856606 3166d30ea906Sjfb8856606 return 0; 3167d30ea906Sjfb8856606 } 3168d30ea906Sjfb8856606 3169d30ea906Sjfb8856606 3170d30ea906Sjfb8856606 /* 3171d30ea906Sjfb8856606 * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find 3172d30ea906Sjfb8856606 * an empty spot. 3173d30ea906Sjfb8856606 */ 3174d30ea906Sjfb8856606 static int 3175d30ea906Sjfb8856606 get_hash_mac_addr_index(uint16_t port_id, const struct ether_addr *addr) 3176d30ea906Sjfb8856606 { 3177d30ea906Sjfb8856606 struct rte_eth_dev_info dev_info; 3178d30ea906Sjfb8856606 struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 3179d30ea906Sjfb8856606 unsigned i; 3180d30ea906Sjfb8856606 3181d30ea906Sjfb8856606 rte_eth_dev_info_get(port_id, &dev_info); 3182d30ea906Sjfb8856606 if (!dev->data->hash_mac_addrs) 3183d30ea906Sjfb8856606 return -1; 3184d30ea906Sjfb8856606 3185d30ea906Sjfb8856606 for (i = 0; i < dev_info.max_hash_mac_addrs; i++) 3186d30ea906Sjfb8856606 if (memcmp(addr, &dev->data->hash_mac_addrs[i], 3187d30ea906Sjfb8856606 ETHER_ADDR_LEN) == 0) 3188d30ea906Sjfb8856606 return i; 3189d30ea906Sjfb8856606 3190d30ea906Sjfb8856606 return -1; 3191d30ea906Sjfb8856606 } 3192d30ea906Sjfb8856606 3193d30ea906Sjfb8856606 int 3194d30ea906Sjfb8856606 rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct ether_addr *addr, 3195d30ea906Sjfb8856606 uint8_t on) 3196d30ea906Sjfb8856606 { 3197d30ea906Sjfb8856606 int index; 3198d30ea906Sjfb8856606 int ret; 3199d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3200d30ea906Sjfb8856606 3201d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3202d30ea906Sjfb8856606 3203d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3204d30ea906Sjfb8856606 if (is_zero_ether_addr(addr)) { 3205d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n", 3206d30ea906Sjfb8856606 port_id); 3207d30ea906Sjfb8856606 return -EINVAL; 3208d30ea906Sjfb8856606 } 3209d30ea906Sjfb8856606 3210d30ea906Sjfb8856606 index = get_hash_mac_addr_index(port_id, addr); 3211d30ea906Sjfb8856606 /* Check if it's already there, and do nothing */ 3212d30ea906Sjfb8856606 if ((index >= 0) && on) 3213d30ea906Sjfb8856606 return 0; 3214d30ea906Sjfb8856606 3215d30ea906Sjfb8856606 if (index < 0) { 3216d30ea906Sjfb8856606 if (!on) { 3217d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 3218d30ea906Sjfb8856606 "Port %u: the MAC address was not set in UTA\n", 3219d30ea906Sjfb8856606 port_id); 3220d30ea906Sjfb8856606 return -EINVAL; 3221d30ea906Sjfb8856606 } 3222d30ea906Sjfb8856606 3223d30ea906Sjfb8856606 index = get_hash_mac_addr_index(port_id, &null_mac_addr); 3224d30ea906Sjfb8856606 if (index < 0) { 3225d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n", 3226d30ea906Sjfb8856606 port_id); 3227d30ea906Sjfb8856606 return -ENOSPC; 3228d30ea906Sjfb8856606 } 3229d30ea906Sjfb8856606 } 3230d30ea906Sjfb8856606 3231d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_hash_table_set, -ENOTSUP); 3232d30ea906Sjfb8856606 ret = (*dev->dev_ops->uc_hash_table_set)(dev, addr, on); 3233d30ea906Sjfb8856606 if (ret == 0) { 3234d30ea906Sjfb8856606 /* Update address in NIC data structure */ 3235d30ea906Sjfb8856606 if (on) 3236d30ea906Sjfb8856606 ether_addr_copy(addr, 3237d30ea906Sjfb8856606 &dev->data->hash_mac_addrs[index]); 3238d30ea906Sjfb8856606 else 3239d30ea906Sjfb8856606 ether_addr_copy(&null_mac_addr, 3240d30ea906Sjfb8856606 &dev->data->hash_mac_addrs[index]); 3241d30ea906Sjfb8856606 } 3242d30ea906Sjfb8856606 3243d30ea906Sjfb8856606 return eth_err(port_id, ret); 3244d30ea906Sjfb8856606 } 3245d30ea906Sjfb8856606 3246d30ea906Sjfb8856606 int 3247d30ea906Sjfb8856606 rte_eth_dev_uc_all_hash_table_set(uint16_t port_id, uint8_t on) 3248d30ea906Sjfb8856606 { 3249d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3250d30ea906Sjfb8856606 3251d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3252d30ea906Sjfb8856606 3253d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3254d30ea906Sjfb8856606 3255d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_all_hash_table_set, -ENOTSUP); 3256d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->uc_all_hash_table_set)(dev, 3257d30ea906Sjfb8856606 on)); 3258d30ea906Sjfb8856606 } 3259d30ea906Sjfb8856606 3260d30ea906Sjfb8856606 int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx, 3261d30ea906Sjfb8856606 uint16_t tx_rate) 3262d30ea906Sjfb8856606 { 3263d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3264d30ea906Sjfb8856606 struct rte_eth_dev_info dev_info; 3265d30ea906Sjfb8856606 struct rte_eth_link link; 3266d30ea906Sjfb8856606 3267d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3268d30ea906Sjfb8856606 3269d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3270d30ea906Sjfb8856606 rte_eth_dev_info_get(port_id, &dev_info); 3271d30ea906Sjfb8856606 link = dev->data->dev_link; 3272d30ea906Sjfb8856606 3273d30ea906Sjfb8856606 if (queue_idx > dev_info.max_tx_queues) { 3274d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 3275d30ea906Sjfb8856606 "Set queue rate limit:port %u: invalid queue id=%u\n", 3276d30ea906Sjfb8856606 port_id, queue_idx); 3277d30ea906Sjfb8856606 return -EINVAL; 3278d30ea906Sjfb8856606 } 3279d30ea906Sjfb8856606 3280d30ea906Sjfb8856606 if (tx_rate > link.link_speed) { 3281d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 3282d30ea906Sjfb8856606 "Set queue rate limit:invalid tx_rate=%u, bigger than link speed= %d\n", 3283d30ea906Sjfb8856606 tx_rate, link.link_speed); 3284d30ea906Sjfb8856606 return -EINVAL; 3285d30ea906Sjfb8856606 } 3286d30ea906Sjfb8856606 3287d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_queue_rate_limit, -ENOTSUP); 3288d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->set_queue_rate_limit)(dev, 3289d30ea906Sjfb8856606 queue_idx, tx_rate)); 3290d30ea906Sjfb8856606 } 3291d30ea906Sjfb8856606 3292d30ea906Sjfb8856606 int 3293d30ea906Sjfb8856606 rte_eth_mirror_rule_set(uint16_t port_id, 3294d30ea906Sjfb8856606 struct rte_eth_mirror_conf *mirror_conf, 3295d30ea906Sjfb8856606 uint8_t rule_id, uint8_t on) 3296d30ea906Sjfb8856606 { 3297d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3298d30ea906Sjfb8856606 3299d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3300d30ea906Sjfb8856606 if (mirror_conf->rule_type == 0) { 3301d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n"); 3302d30ea906Sjfb8856606 return -EINVAL; 3303d30ea906Sjfb8856606 } 3304d30ea906Sjfb8856606 3305d30ea906Sjfb8856606 if (mirror_conf->dst_pool >= ETH_64_POOLS) { 3306d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid dst pool, pool id must be 0-%d\n", 3307d30ea906Sjfb8856606 ETH_64_POOLS - 1); 3308d30ea906Sjfb8856606 return -EINVAL; 3309d30ea906Sjfb8856606 } 3310d30ea906Sjfb8856606 3311d30ea906Sjfb8856606 if ((mirror_conf->rule_type & (ETH_MIRROR_VIRTUAL_POOL_UP | 3312d30ea906Sjfb8856606 ETH_MIRROR_VIRTUAL_POOL_DOWN)) && 3313d30ea906Sjfb8856606 (mirror_conf->pool_mask == 0)) { 3314d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 3315d30ea906Sjfb8856606 "Invalid mirror pool, pool mask can not be 0\n"); 3316d30ea906Sjfb8856606 return -EINVAL; 3317d30ea906Sjfb8856606 } 3318d30ea906Sjfb8856606 3319d30ea906Sjfb8856606 if ((mirror_conf->rule_type & ETH_MIRROR_VLAN) && 3320d30ea906Sjfb8856606 mirror_conf->vlan.vlan_mask == 0) { 3321d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 3322d30ea906Sjfb8856606 "Invalid vlan mask, vlan mask can not be 0\n"); 3323d30ea906Sjfb8856606 return -EINVAL; 3324d30ea906Sjfb8856606 } 3325d30ea906Sjfb8856606 3326d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3327d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_set, -ENOTSUP); 3328d30ea906Sjfb8856606 3329d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->mirror_rule_set)(dev, 3330d30ea906Sjfb8856606 mirror_conf, rule_id, on)); 3331d30ea906Sjfb8856606 } 3332d30ea906Sjfb8856606 3333d30ea906Sjfb8856606 int 3334d30ea906Sjfb8856606 rte_eth_mirror_rule_reset(uint16_t port_id, uint8_t rule_id) 3335d30ea906Sjfb8856606 { 3336d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3337d30ea906Sjfb8856606 3338d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3339d30ea906Sjfb8856606 3340d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3341d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_reset, -ENOTSUP); 3342d30ea906Sjfb8856606 3343d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->mirror_rule_reset)(dev, 3344d30ea906Sjfb8856606 rule_id)); 3345d30ea906Sjfb8856606 } 3346d30ea906Sjfb8856606 3347d30ea906Sjfb8856606 RTE_INIT(eth_dev_init_cb_lists) 3348d30ea906Sjfb8856606 { 3349d30ea906Sjfb8856606 int i; 3350d30ea906Sjfb8856606 3351d30ea906Sjfb8856606 for (i = 0; i < RTE_MAX_ETHPORTS; i++) 3352d30ea906Sjfb8856606 TAILQ_INIT(&rte_eth_devices[i].link_intr_cbs); 3353d30ea906Sjfb8856606 } 3354d30ea906Sjfb8856606 3355d30ea906Sjfb8856606 int 3356d30ea906Sjfb8856606 rte_eth_dev_callback_register(uint16_t port_id, 3357d30ea906Sjfb8856606 enum rte_eth_event_type event, 3358d30ea906Sjfb8856606 rte_eth_dev_cb_fn cb_fn, void *cb_arg) 3359d30ea906Sjfb8856606 { 3360d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3361d30ea906Sjfb8856606 struct rte_eth_dev_callback *user_cb; 3362d30ea906Sjfb8856606 uint32_t next_port; /* size is 32-bit to prevent loop wrap-around */ 3363d30ea906Sjfb8856606 uint16_t last_port; 3364d30ea906Sjfb8856606 3365d30ea906Sjfb8856606 if (!cb_fn) 3366d30ea906Sjfb8856606 return -EINVAL; 3367d30ea906Sjfb8856606 3368d30ea906Sjfb8856606 if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) { 3369d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id); 3370d30ea906Sjfb8856606 return -EINVAL; 3371d30ea906Sjfb8856606 } 3372d30ea906Sjfb8856606 3373d30ea906Sjfb8856606 if (port_id == RTE_ETH_ALL) { 3374d30ea906Sjfb8856606 next_port = 0; 3375d30ea906Sjfb8856606 last_port = RTE_MAX_ETHPORTS - 1; 3376d30ea906Sjfb8856606 } else { 3377d30ea906Sjfb8856606 next_port = last_port = port_id; 3378d30ea906Sjfb8856606 } 3379d30ea906Sjfb8856606 3380d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_cb_lock); 3381d30ea906Sjfb8856606 3382d30ea906Sjfb8856606 do { 3383d30ea906Sjfb8856606 dev = &rte_eth_devices[next_port]; 3384d30ea906Sjfb8856606 3385d30ea906Sjfb8856606 TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) { 3386d30ea906Sjfb8856606 if (user_cb->cb_fn == cb_fn && 3387d30ea906Sjfb8856606 user_cb->cb_arg == cb_arg && 3388d30ea906Sjfb8856606 user_cb->event == event) { 3389d30ea906Sjfb8856606 break; 3390d30ea906Sjfb8856606 } 3391d30ea906Sjfb8856606 } 3392d30ea906Sjfb8856606 3393d30ea906Sjfb8856606 /* create a new callback. */ 3394d30ea906Sjfb8856606 if (user_cb == NULL) { 3395d30ea906Sjfb8856606 user_cb = rte_zmalloc("INTR_USER_CALLBACK", 3396d30ea906Sjfb8856606 sizeof(struct rte_eth_dev_callback), 0); 3397d30ea906Sjfb8856606 if (user_cb != NULL) { 3398d30ea906Sjfb8856606 user_cb->cb_fn = cb_fn; 3399d30ea906Sjfb8856606 user_cb->cb_arg = cb_arg; 3400d30ea906Sjfb8856606 user_cb->event = event; 3401d30ea906Sjfb8856606 TAILQ_INSERT_TAIL(&(dev->link_intr_cbs), 3402d30ea906Sjfb8856606 user_cb, next); 3403d30ea906Sjfb8856606 } else { 3404d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_cb_lock); 3405d30ea906Sjfb8856606 rte_eth_dev_callback_unregister(port_id, event, 3406d30ea906Sjfb8856606 cb_fn, cb_arg); 3407d30ea906Sjfb8856606 return -ENOMEM; 3408d30ea906Sjfb8856606 } 3409d30ea906Sjfb8856606 3410d30ea906Sjfb8856606 } 3411d30ea906Sjfb8856606 } while (++next_port <= last_port); 3412d30ea906Sjfb8856606 3413d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_cb_lock); 3414d30ea906Sjfb8856606 return 0; 3415d30ea906Sjfb8856606 } 3416d30ea906Sjfb8856606 3417d30ea906Sjfb8856606 int 3418d30ea906Sjfb8856606 rte_eth_dev_callback_unregister(uint16_t port_id, 3419d30ea906Sjfb8856606 enum rte_eth_event_type event, 3420d30ea906Sjfb8856606 rte_eth_dev_cb_fn cb_fn, void *cb_arg) 3421d30ea906Sjfb8856606 { 3422d30ea906Sjfb8856606 int ret; 3423d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3424d30ea906Sjfb8856606 struct rte_eth_dev_callback *cb, *next; 3425d30ea906Sjfb8856606 uint32_t next_port; /* size is 32-bit to prevent loop wrap-around */ 3426d30ea906Sjfb8856606 uint16_t last_port; 3427d30ea906Sjfb8856606 3428d30ea906Sjfb8856606 if (!cb_fn) 3429d30ea906Sjfb8856606 return -EINVAL; 3430d30ea906Sjfb8856606 3431d30ea906Sjfb8856606 if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) { 3432d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id); 3433d30ea906Sjfb8856606 return -EINVAL; 3434d30ea906Sjfb8856606 } 3435d30ea906Sjfb8856606 3436d30ea906Sjfb8856606 if (port_id == RTE_ETH_ALL) { 3437d30ea906Sjfb8856606 next_port = 0; 3438d30ea906Sjfb8856606 last_port = RTE_MAX_ETHPORTS - 1; 3439d30ea906Sjfb8856606 } else { 3440d30ea906Sjfb8856606 next_port = last_port = port_id; 3441d30ea906Sjfb8856606 } 3442d30ea906Sjfb8856606 3443d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_cb_lock); 3444d30ea906Sjfb8856606 3445d30ea906Sjfb8856606 do { 3446d30ea906Sjfb8856606 dev = &rte_eth_devices[next_port]; 3447d30ea906Sjfb8856606 ret = 0; 3448d30ea906Sjfb8856606 for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL; 3449d30ea906Sjfb8856606 cb = next) { 3450d30ea906Sjfb8856606 3451d30ea906Sjfb8856606 next = TAILQ_NEXT(cb, next); 3452d30ea906Sjfb8856606 3453d30ea906Sjfb8856606 if (cb->cb_fn != cb_fn || cb->event != event || 3454d30ea906Sjfb8856606 (cb->cb_arg != (void *)-1 && cb->cb_arg != cb_arg)) 3455d30ea906Sjfb8856606 continue; 3456d30ea906Sjfb8856606 3457d30ea906Sjfb8856606 /* 3458d30ea906Sjfb8856606 * if this callback is not executing right now, 3459d30ea906Sjfb8856606 * then remove it. 3460d30ea906Sjfb8856606 */ 3461d30ea906Sjfb8856606 if (cb->active == 0) { 3462d30ea906Sjfb8856606 TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next); 3463d30ea906Sjfb8856606 rte_free(cb); 3464d30ea906Sjfb8856606 } else { 3465d30ea906Sjfb8856606 ret = -EAGAIN; 3466d30ea906Sjfb8856606 } 3467d30ea906Sjfb8856606 } 3468d30ea906Sjfb8856606 } while (++next_port <= last_port); 3469d30ea906Sjfb8856606 3470d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_cb_lock); 3471d30ea906Sjfb8856606 return ret; 3472d30ea906Sjfb8856606 } 3473d30ea906Sjfb8856606 3474d30ea906Sjfb8856606 int 3475d30ea906Sjfb8856606 _rte_eth_dev_callback_process(struct rte_eth_dev *dev, 3476d30ea906Sjfb8856606 enum rte_eth_event_type event, void *ret_param) 3477d30ea906Sjfb8856606 { 3478d30ea906Sjfb8856606 struct rte_eth_dev_callback *cb_lst; 3479d30ea906Sjfb8856606 struct rte_eth_dev_callback dev_cb; 3480d30ea906Sjfb8856606 int rc = 0; 3481d30ea906Sjfb8856606 3482d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_cb_lock); 3483d30ea906Sjfb8856606 TAILQ_FOREACH(cb_lst, &(dev->link_intr_cbs), next) { 3484d30ea906Sjfb8856606 if (cb_lst->cb_fn == NULL || cb_lst->event != event) 3485d30ea906Sjfb8856606 continue; 3486d30ea906Sjfb8856606 dev_cb = *cb_lst; 3487d30ea906Sjfb8856606 cb_lst->active = 1; 3488d30ea906Sjfb8856606 if (ret_param != NULL) 3489d30ea906Sjfb8856606 dev_cb.ret_param = ret_param; 3490d30ea906Sjfb8856606 3491d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_cb_lock); 3492d30ea906Sjfb8856606 rc = dev_cb.cb_fn(dev->data->port_id, dev_cb.event, 3493d30ea906Sjfb8856606 dev_cb.cb_arg, dev_cb.ret_param); 3494d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_dev_cb_lock); 3495d30ea906Sjfb8856606 cb_lst->active = 0; 3496d30ea906Sjfb8856606 } 3497d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_dev_cb_lock); 3498d30ea906Sjfb8856606 return rc; 3499d30ea906Sjfb8856606 } 3500d30ea906Sjfb8856606 3501d30ea906Sjfb8856606 void 3502d30ea906Sjfb8856606 rte_eth_dev_probing_finish(struct rte_eth_dev *dev) 3503d30ea906Sjfb8856606 { 3504d30ea906Sjfb8856606 if (dev == NULL) 3505d30ea906Sjfb8856606 return; 3506d30ea906Sjfb8856606 3507d30ea906Sjfb8856606 _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_NEW, NULL); 3508d30ea906Sjfb8856606 3509d30ea906Sjfb8856606 dev->state = RTE_ETH_DEV_ATTACHED; 3510d30ea906Sjfb8856606 } 3511d30ea906Sjfb8856606 3512d30ea906Sjfb8856606 int 3513d30ea906Sjfb8856606 rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data) 3514d30ea906Sjfb8856606 { 3515d30ea906Sjfb8856606 uint32_t vec; 3516d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3517d30ea906Sjfb8856606 struct rte_intr_handle *intr_handle; 3518d30ea906Sjfb8856606 uint16_t qid; 3519d30ea906Sjfb8856606 int rc; 3520d30ea906Sjfb8856606 3521d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3522d30ea906Sjfb8856606 3523d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3524d30ea906Sjfb8856606 3525d30ea906Sjfb8856606 if (!dev->intr_handle) { 3526d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "RX Intr handle unset\n"); 3527d30ea906Sjfb8856606 return -ENOTSUP; 3528d30ea906Sjfb8856606 } 3529d30ea906Sjfb8856606 3530d30ea906Sjfb8856606 intr_handle = dev->intr_handle; 3531d30ea906Sjfb8856606 if (!intr_handle->intr_vec) { 3532d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "RX Intr vector unset\n"); 3533d30ea906Sjfb8856606 return -EPERM; 3534d30ea906Sjfb8856606 } 3535d30ea906Sjfb8856606 3536d30ea906Sjfb8856606 for (qid = 0; qid < dev->data->nb_rx_queues; qid++) { 3537d30ea906Sjfb8856606 vec = intr_handle->intr_vec[qid]; 3538d30ea906Sjfb8856606 rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data); 3539d30ea906Sjfb8856606 if (rc && rc != -EEXIST) { 3540d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 3541d30ea906Sjfb8856606 "p %u q %u rx ctl error op %d epfd %d vec %u\n", 3542d30ea906Sjfb8856606 port_id, qid, op, epfd, vec); 3543d30ea906Sjfb8856606 } 3544d30ea906Sjfb8856606 } 3545d30ea906Sjfb8856606 3546d30ea906Sjfb8856606 return 0; 3547d30ea906Sjfb8856606 } 3548d30ea906Sjfb8856606 3549d30ea906Sjfb8856606 int __rte_experimental 3550d30ea906Sjfb8856606 rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id, uint16_t queue_id) 3551d30ea906Sjfb8856606 { 3552d30ea906Sjfb8856606 struct rte_intr_handle *intr_handle; 3553d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3554d30ea906Sjfb8856606 unsigned int efd_idx; 3555d30ea906Sjfb8856606 uint32_t vec; 3556d30ea906Sjfb8856606 int fd; 3557d30ea906Sjfb8856606 3558d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); 3559d30ea906Sjfb8856606 3560d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3561d30ea906Sjfb8856606 3562d30ea906Sjfb8856606 if (queue_id >= dev->data->nb_rx_queues) { 3563d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id); 3564d30ea906Sjfb8856606 return -1; 3565d30ea906Sjfb8856606 } 3566d30ea906Sjfb8856606 3567d30ea906Sjfb8856606 if (!dev->intr_handle) { 3568d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "RX Intr handle unset\n"); 3569d30ea906Sjfb8856606 return -1; 3570d30ea906Sjfb8856606 } 3571d30ea906Sjfb8856606 3572d30ea906Sjfb8856606 intr_handle = dev->intr_handle; 3573d30ea906Sjfb8856606 if (!intr_handle->intr_vec) { 3574d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "RX Intr vector unset\n"); 3575d30ea906Sjfb8856606 return -1; 3576d30ea906Sjfb8856606 } 3577d30ea906Sjfb8856606 3578d30ea906Sjfb8856606 vec = intr_handle->intr_vec[queue_id]; 3579d30ea906Sjfb8856606 efd_idx = (vec >= RTE_INTR_VEC_RXTX_OFFSET) ? 3580d30ea906Sjfb8856606 (vec - RTE_INTR_VEC_RXTX_OFFSET) : vec; 3581d30ea906Sjfb8856606 fd = intr_handle->efds[efd_idx]; 3582d30ea906Sjfb8856606 3583d30ea906Sjfb8856606 return fd; 3584d30ea906Sjfb8856606 } 3585d30ea906Sjfb8856606 3586d30ea906Sjfb8856606 const struct rte_memzone * 3587d30ea906Sjfb8856606 rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name, 3588d30ea906Sjfb8856606 uint16_t queue_id, size_t size, unsigned align, 3589d30ea906Sjfb8856606 int socket_id) 3590d30ea906Sjfb8856606 { 3591d30ea906Sjfb8856606 char z_name[RTE_MEMZONE_NAMESIZE]; 3592d30ea906Sjfb8856606 const struct rte_memzone *mz; 3593d30ea906Sjfb8856606 3594d30ea906Sjfb8856606 snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s", 3595d30ea906Sjfb8856606 dev->data->port_id, queue_id, ring_name); 3596d30ea906Sjfb8856606 3597d30ea906Sjfb8856606 mz = rte_memzone_lookup(z_name); 3598d30ea906Sjfb8856606 if (mz) 3599d30ea906Sjfb8856606 return mz; 3600d30ea906Sjfb8856606 3601d30ea906Sjfb8856606 return rte_memzone_reserve_aligned(z_name, size, socket_id, 3602d30ea906Sjfb8856606 RTE_MEMZONE_IOVA_CONTIG, align); 3603d30ea906Sjfb8856606 } 3604d30ea906Sjfb8856606 3605d30ea906Sjfb8856606 int __rte_experimental 3606d30ea906Sjfb8856606 rte_eth_dev_create(struct rte_device *device, const char *name, 3607d30ea906Sjfb8856606 size_t priv_data_size, 3608d30ea906Sjfb8856606 ethdev_bus_specific_init ethdev_bus_specific_init, 3609d30ea906Sjfb8856606 void *bus_init_params, 3610d30ea906Sjfb8856606 ethdev_init_t ethdev_init, void *init_params) 3611d30ea906Sjfb8856606 { 3612d30ea906Sjfb8856606 struct rte_eth_dev *ethdev; 3613d30ea906Sjfb8856606 int retval; 3614d30ea906Sjfb8856606 3615d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL); 3616d30ea906Sjfb8856606 3617d30ea906Sjfb8856606 if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 3618d30ea906Sjfb8856606 ethdev = rte_eth_dev_allocate(name); 3619d30ea906Sjfb8856606 if (!ethdev) 3620d30ea906Sjfb8856606 return -ENODEV; 3621d30ea906Sjfb8856606 3622d30ea906Sjfb8856606 if (priv_data_size) { 3623d30ea906Sjfb8856606 ethdev->data->dev_private = rte_zmalloc_socket( 3624d30ea906Sjfb8856606 name, priv_data_size, RTE_CACHE_LINE_SIZE, 3625d30ea906Sjfb8856606 device->numa_node); 3626d30ea906Sjfb8856606 3627d30ea906Sjfb8856606 if (!ethdev->data->dev_private) { 3628d30ea906Sjfb8856606 RTE_LOG(ERR, EAL, "failed to allocate private data"); 3629d30ea906Sjfb8856606 retval = -ENOMEM; 3630d30ea906Sjfb8856606 goto probe_failed; 3631d30ea906Sjfb8856606 } 3632d30ea906Sjfb8856606 } 3633d30ea906Sjfb8856606 } else { 3634d30ea906Sjfb8856606 ethdev = rte_eth_dev_attach_secondary(name); 3635d30ea906Sjfb8856606 if (!ethdev) { 3636d30ea906Sjfb8856606 RTE_LOG(ERR, EAL, "secondary process attach failed, " 3637d30ea906Sjfb8856606 "ethdev doesn't exist"); 3638d30ea906Sjfb8856606 return -ENODEV; 3639d30ea906Sjfb8856606 } 3640d30ea906Sjfb8856606 } 3641d30ea906Sjfb8856606 3642d30ea906Sjfb8856606 ethdev->device = device; 3643d30ea906Sjfb8856606 3644d30ea906Sjfb8856606 if (ethdev_bus_specific_init) { 3645d30ea906Sjfb8856606 retval = ethdev_bus_specific_init(ethdev, bus_init_params); 3646d30ea906Sjfb8856606 if (retval) { 3647d30ea906Sjfb8856606 RTE_LOG(ERR, EAL, 3648d30ea906Sjfb8856606 "ethdev bus specific initialisation failed"); 3649d30ea906Sjfb8856606 goto probe_failed; 3650d30ea906Sjfb8856606 } 3651d30ea906Sjfb8856606 } 3652d30ea906Sjfb8856606 3653d30ea906Sjfb8856606 retval = ethdev_init(ethdev, init_params); 3654d30ea906Sjfb8856606 if (retval) { 3655d30ea906Sjfb8856606 RTE_LOG(ERR, EAL, "ethdev initialisation failed"); 3656d30ea906Sjfb8856606 goto probe_failed; 3657d30ea906Sjfb8856606 } 3658d30ea906Sjfb8856606 3659d30ea906Sjfb8856606 rte_eth_dev_probing_finish(ethdev); 3660d30ea906Sjfb8856606 3661d30ea906Sjfb8856606 return retval; 3662d30ea906Sjfb8856606 3663d30ea906Sjfb8856606 probe_failed: 3664d30ea906Sjfb8856606 rte_eth_dev_release_port(ethdev); 3665d30ea906Sjfb8856606 return retval; 3666d30ea906Sjfb8856606 } 3667d30ea906Sjfb8856606 3668d30ea906Sjfb8856606 int __rte_experimental 3669d30ea906Sjfb8856606 rte_eth_dev_destroy(struct rte_eth_dev *ethdev, 3670d30ea906Sjfb8856606 ethdev_uninit_t ethdev_uninit) 3671d30ea906Sjfb8856606 { 3672d30ea906Sjfb8856606 int ret; 3673d30ea906Sjfb8856606 3674d30ea906Sjfb8856606 ethdev = rte_eth_dev_allocated(ethdev->data->name); 3675d30ea906Sjfb8856606 if (!ethdev) 3676d30ea906Sjfb8856606 return -ENODEV; 3677d30ea906Sjfb8856606 3678d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL); 3679d30ea906Sjfb8856606 3680d30ea906Sjfb8856606 ret = ethdev_uninit(ethdev); 3681d30ea906Sjfb8856606 if (ret) 3682d30ea906Sjfb8856606 return ret; 3683d30ea906Sjfb8856606 3684d30ea906Sjfb8856606 return rte_eth_dev_release_port(ethdev); 3685d30ea906Sjfb8856606 } 3686d30ea906Sjfb8856606 3687d30ea906Sjfb8856606 int 3688d30ea906Sjfb8856606 rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id, 3689d30ea906Sjfb8856606 int epfd, int op, void *data) 3690d30ea906Sjfb8856606 { 3691d30ea906Sjfb8856606 uint32_t vec; 3692d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3693d30ea906Sjfb8856606 struct rte_intr_handle *intr_handle; 3694d30ea906Sjfb8856606 int rc; 3695d30ea906Sjfb8856606 3696d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3697d30ea906Sjfb8856606 3698d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3699d30ea906Sjfb8856606 if (queue_id >= dev->data->nb_rx_queues) { 3700d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id); 3701d30ea906Sjfb8856606 return -EINVAL; 3702d30ea906Sjfb8856606 } 3703d30ea906Sjfb8856606 3704d30ea906Sjfb8856606 if (!dev->intr_handle) { 3705d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "RX Intr handle unset\n"); 3706d30ea906Sjfb8856606 return -ENOTSUP; 3707d30ea906Sjfb8856606 } 3708d30ea906Sjfb8856606 3709d30ea906Sjfb8856606 intr_handle = dev->intr_handle; 3710d30ea906Sjfb8856606 if (!intr_handle->intr_vec) { 3711d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "RX Intr vector unset\n"); 3712d30ea906Sjfb8856606 return -EPERM; 3713d30ea906Sjfb8856606 } 3714d30ea906Sjfb8856606 3715d30ea906Sjfb8856606 vec = intr_handle->intr_vec[queue_id]; 3716d30ea906Sjfb8856606 rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data); 3717d30ea906Sjfb8856606 if (rc && rc != -EEXIST) { 3718d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, 3719d30ea906Sjfb8856606 "p %u q %u rx ctl error op %d epfd %d vec %u\n", 3720d30ea906Sjfb8856606 port_id, queue_id, op, epfd, vec); 3721d30ea906Sjfb8856606 return rc; 3722d30ea906Sjfb8856606 } 3723d30ea906Sjfb8856606 3724d30ea906Sjfb8856606 return 0; 3725d30ea906Sjfb8856606 } 3726d30ea906Sjfb8856606 3727d30ea906Sjfb8856606 int 3728d30ea906Sjfb8856606 rte_eth_dev_rx_intr_enable(uint16_t port_id, 3729d30ea906Sjfb8856606 uint16_t queue_id) 3730d30ea906Sjfb8856606 { 3731d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3732d30ea906Sjfb8856606 3733d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3734d30ea906Sjfb8856606 3735d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3736d30ea906Sjfb8856606 3737d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_enable, -ENOTSUP); 3738d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_enable)(dev, 3739d30ea906Sjfb8856606 queue_id)); 3740d30ea906Sjfb8856606 } 3741d30ea906Sjfb8856606 3742d30ea906Sjfb8856606 int 3743d30ea906Sjfb8856606 rte_eth_dev_rx_intr_disable(uint16_t port_id, 3744d30ea906Sjfb8856606 uint16_t queue_id) 3745d30ea906Sjfb8856606 { 3746d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3747d30ea906Sjfb8856606 3748d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3749d30ea906Sjfb8856606 3750d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3751d30ea906Sjfb8856606 3752d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_disable, -ENOTSUP); 3753d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_disable)(dev, 3754d30ea906Sjfb8856606 queue_id)); 3755d30ea906Sjfb8856606 } 3756d30ea906Sjfb8856606 3757d30ea906Sjfb8856606 3758d30ea906Sjfb8856606 int 3759d30ea906Sjfb8856606 rte_eth_dev_filter_supported(uint16_t port_id, 3760d30ea906Sjfb8856606 enum rte_filter_type filter_type) 3761d30ea906Sjfb8856606 { 3762d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3763d30ea906Sjfb8856606 3764d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3765d30ea906Sjfb8856606 3766d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3767d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->filter_ctrl, -ENOTSUP); 3768d30ea906Sjfb8856606 return (*dev->dev_ops->filter_ctrl)(dev, filter_type, 3769d30ea906Sjfb8856606 RTE_ETH_FILTER_NOP, NULL); 3770d30ea906Sjfb8856606 } 3771d30ea906Sjfb8856606 3772d30ea906Sjfb8856606 int 3773d30ea906Sjfb8856606 rte_eth_dev_filter_ctrl(uint16_t port_id, enum rte_filter_type filter_type, 3774d30ea906Sjfb8856606 enum rte_filter_op filter_op, void *arg) 3775d30ea906Sjfb8856606 { 3776d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3777d30ea906Sjfb8856606 3778d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3779d30ea906Sjfb8856606 3780d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3781d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->filter_ctrl, -ENOTSUP); 3782d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->filter_ctrl)(dev, filter_type, 3783d30ea906Sjfb8856606 filter_op, arg)); 3784d30ea906Sjfb8856606 } 3785d30ea906Sjfb8856606 3786d30ea906Sjfb8856606 const struct rte_eth_rxtx_callback * 3787d30ea906Sjfb8856606 rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id, 3788d30ea906Sjfb8856606 rte_rx_callback_fn fn, void *user_param) 3789d30ea906Sjfb8856606 { 3790d30ea906Sjfb8856606 #ifndef RTE_ETHDEV_RXTX_CALLBACKS 3791d30ea906Sjfb8856606 rte_errno = ENOTSUP; 3792d30ea906Sjfb8856606 return NULL; 3793d30ea906Sjfb8856606 #endif 3794d30ea906Sjfb8856606 /* check input parameters */ 3795d30ea906Sjfb8856606 if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 3796d30ea906Sjfb8856606 queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) { 3797d30ea906Sjfb8856606 rte_errno = EINVAL; 3798d30ea906Sjfb8856606 return NULL; 3799d30ea906Sjfb8856606 } 3800d30ea906Sjfb8856606 struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 3801d30ea906Sjfb8856606 3802d30ea906Sjfb8856606 if (cb == NULL) { 3803d30ea906Sjfb8856606 rte_errno = ENOMEM; 3804d30ea906Sjfb8856606 return NULL; 3805d30ea906Sjfb8856606 } 3806d30ea906Sjfb8856606 3807d30ea906Sjfb8856606 cb->fn.rx = fn; 3808d30ea906Sjfb8856606 cb->param = user_param; 3809d30ea906Sjfb8856606 3810d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_rx_cb_lock); 3811d30ea906Sjfb8856606 /* Add the callbacks in fifo order. */ 3812d30ea906Sjfb8856606 struct rte_eth_rxtx_callback *tail = 3813d30ea906Sjfb8856606 rte_eth_devices[port_id].post_rx_burst_cbs[queue_id]; 3814d30ea906Sjfb8856606 3815d30ea906Sjfb8856606 if (!tail) { 3816d30ea906Sjfb8856606 rte_eth_devices[port_id].post_rx_burst_cbs[queue_id] = cb; 3817d30ea906Sjfb8856606 3818d30ea906Sjfb8856606 } else { 3819d30ea906Sjfb8856606 while (tail->next) 3820d30ea906Sjfb8856606 tail = tail->next; 3821d30ea906Sjfb8856606 tail->next = cb; 3822d30ea906Sjfb8856606 } 3823d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_rx_cb_lock); 3824d30ea906Sjfb8856606 3825d30ea906Sjfb8856606 return cb; 3826d30ea906Sjfb8856606 } 3827d30ea906Sjfb8856606 3828d30ea906Sjfb8856606 const struct rte_eth_rxtx_callback * 3829d30ea906Sjfb8856606 rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id, 3830d30ea906Sjfb8856606 rte_rx_callback_fn fn, void *user_param) 3831d30ea906Sjfb8856606 { 3832d30ea906Sjfb8856606 #ifndef RTE_ETHDEV_RXTX_CALLBACKS 3833d30ea906Sjfb8856606 rte_errno = ENOTSUP; 3834d30ea906Sjfb8856606 return NULL; 3835d30ea906Sjfb8856606 #endif 3836d30ea906Sjfb8856606 /* check input parameters */ 3837d30ea906Sjfb8856606 if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 3838d30ea906Sjfb8856606 queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) { 3839d30ea906Sjfb8856606 rte_errno = EINVAL; 3840d30ea906Sjfb8856606 return NULL; 3841d30ea906Sjfb8856606 } 3842d30ea906Sjfb8856606 3843d30ea906Sjfb8856606 struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 3844d30ea906Sjfb8856606 3845d30ea906Sjfb8856606 if (cb == NULL) { 3846d30ea906Sjfb8856606 rte_errno = ENOMEM; 3847d30ea906Sjfb8856606 return NULL; 3848d30ea906Sjfb8856606 } 3849d30ea906Sjfb8856606 3850d30ea906Sjfb8856606 cb->fn.rx = fn; 3851d30ea906Sjfb8856606 cb->param = user_param; 3852d30ea906Sjfb8856606 3853d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_rx_cb_lock); 3854d30ea906Sjfb8856606 /* Add the callbacks at fisrt position*/ 3855d30ea906Sjfb8856606 cb->next = rte_eth_devices[port_id].post_rx_burst_cbs[queue_id]; 3856d30ea906Sjfb8856606 rte_smp_wmb(); 3857d30ea906Sjfb8856606 rte_eth_devices[port_id].post_rx_burst_cbs[queue_id] = cb; 3858d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_rx_cb_lock); 3859d30ea906Sjfb8856606 3860d30ea906Sjfb8856606 return cb; 3861d30ea906Sjfb8856606 } 3862d30ea906Sjfb8856606 3863d30ea906Sjfb8856606 const struct rte_eth_rxtx_callback * 3864d30ea906Sjfb8856606 rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id, 3865d30ea906Sjfb8856606 rte_tx_callback_fn fn, void *user_param) 3866d30ea906Sjfb8856606 { 3867d30ea906Sjfb8856606 #ifndef RTE_ETHDEV_RXTX_CALLBACKS 3868d30ea906Sjfb8856606 rte_errno = ENOTSUP; 3869d30ea906Sjfb8856606 return NULL; 3870d30ea906Sjfb8856606 #endif 3871d30ea906Sjfb8856606 /* check input parameters */ 3872d30ea906Sjfb8856606 if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL || 3873d30ea906Sjfb8856606 queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) { 3874d30ea906Sjfb8856606 rte_errno = EINVAL; 3875d30ea906Sjfb8856606 return NULL; 3876d30ea906Sjfb8856606 } 3877d30ea906Sjfb8856606 3878d30ea906Sjfb8856606 struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); 3879d30ea906Sjfb8856606 3880d30ea906Sjfb8856606 if (cb == NULL) { 3881d30ea906Sjfb8856606 rte_errno = ENOMEM; 3882d30ea906Sjfb8856606 return NULL; 3883d30ea906Sjfb8856606 } 3884d30ea906Sjfb8856606 3885d30ea906Sjfb8856606 cb->fn.tx = fn; 3886d30ea906Sjfb8856606 cb->param = user_param; 3887d30ea906Sjfb8856606 3888d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_tx_cb_lock); 3889d30ea906Sjfb8856606 /* Add the callbacks in fifo order. */ 3890d30ea906Sjfb8856606 struct rte_eth_rxtx_callback *tail = 3891d30ea906Sjfb8856606 rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id]; 3892d30ea906Sjfb8856606 3893d30ea906Sjfb8856606 if (!tail) { 3894d30ea906Sjfb8856606 rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id] = cb; 3895d30ea906Sjfb8856606 3896d30ea906Sjfb8856606 } else { 3897d30ea906Sjfb8856606 while (tail->next) 3898d30ea906Sjfb8856606 tail = tail->next; 3899d30ea906Sjfb8856606 tail->next = cb; 3900d30ea906Sjfb8856606 } 3901d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_tx_cb_lock); 3902d30ea906Sjfb8856606 3903d30ea906Sjfb8856606 return cb; 3904d30ea906Sjfb8856606 } 3905d30ea906Sjfb8856606 3906d30ea906Sjfb8856606 int 3907d30ea906Sjfb8856606 rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id, 3908d30ea906Sjfb8856606 const struct rte_eth_rxtx_callback *user_cb) 3909d30ea906Sjfb8856606 { 3910d30ea906Sjfb8856606 #ifndef RTE_ETHDEV_RXTX_CALLBACKS 3911d30ea906Sjfb8856606 return -ENOTSUP; 3912d30ea906Sjfb8856606 #endif 3913d30ea906Sjfb8856606 /* Check input parameters. */ 3914d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 3915d30ea906Sjfb8856606 if (user_cb == NULL || 3916d30ea906Sjfb8856606 queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) 3917d30ea906Sjfb8856606 return -EINVAL; 3918d30ea906Sjfb8856606 3919d30ea906Sjfb8856606 struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 3920d30ea906Sjfb8856606 struct rte_eth_rxtx_callback *cb; 3921d30ea906Sjfb8856606 struct rte_eth_rxtx_callback **prev_cb; 3922d30ea906Sjfb8856606 int ret = -EINVAL; 3923d30ea906Sjfb8856606 3924d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_rx_cb_lock); 3925d30ea906Sjfb8856606 prev_cb = &dev->post_rx_burst_cbs[queue_id]; 3926d30ea906Sjfb8856606 for (; *prev_cb != NULL; prev_cb = &cb->next) { 3927d30ea906Sjfb8856606 cb = *prev_cb; 3928d30ea906Sjfb8856606 if (cb == user_cb) { 3929d30ea906Sjfb8856606 /* Remove the user cb from the callback list. */ 3930d30ea906Sjfb8856606 *prev_cb = cb->next; 3931d30ea906Sjfb8856606 ret = 0; 3932d30ea906Sjfb8856606 break; 3933d30ea906Sjfb8856606 } 3934d30ea906Sjfb8856606 } 3935d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_rx_cb_lock); 3936d30ea906Sjfb8856606 3937d30ea906Sjfb8856606 return ret; 3938d30ea906Sjfb8856606 } 3939d30ea906Sjfb8856606 3940d30ea906Sjfb8856606 int 3941d30ea906Sjfb8856606 rte_eth_remove_tx_callback(uint16_t port_id, uint16_t queue_id, 3942d30ea906Sjfb8856606 const struct rte_eth_rxtx_callback *user_cb) 3943d30ea906Sjfb8856606 { 3944d30ea906Sjfb8856606 #ifndef RTE_ETHDEV_RXTX_CALLBACKS 3945d30ea906Sjfb8856606 return -ENOTSUP; 3946d30ea906Sjfb8856606 #endif 3947d30ea906Sjfb8856606 /* Check input parameters. */ 3948d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); 3949d30ea906Sjfb8856606 if (user_cb == NULL || 3950d30ea906Sjfb8856606 queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) 3951d30ea906Sjfb8856606 return -EINVAL; 3952d30ea906Sjfb8856606 3953d30ea906Sjfb8856606 struct rte_eth_dev *dev = &rte_eth_devices[port_id]; 3954d30ea906Sjfb8856606 int ret = -EINVAL; 3955d30ea906Sjfb8856606 struct rte_eth_rxtx_callback *cb; 3956d30ea906Sjfb8856606 struct rte_eth_rxtx_callback **prev_cb; 3957d30ea906Sjfb8856606 3958d30ea906Sjfb8856606 rte_spinlock_lock(&rte_eth_tx_cb_lock); 3959d30ea906Sjfb8856606 prev_cb = &dev->pre_tx_burst_cbs[queue_id]; 3960d30ea906Sjfb8856606 for (; *prev_cb != NULL; prev_cb = &cb->next) { 3961d30ea906Sjfb8856606 cb = *prev_cb; 3962d30ea906Sjfb8856606 if (cb == user_cb) { 3963d30ea906Sjfb8856606 /* Remove the user cb from the callback list. */ 3964d30ea906Sjfb8856606 *prev_cb = cb->next; 3965d30ea906Sjfb8856606 ret = 0; 3966d30ea906Sjfb8856606 break; 3967d30ea906Sjfb8856606 } 3968d30ea906Sjfb8856606 } 3969d30ea906Sjfb8856606 rte_spinlock_unlock(&rte_eth_tx_cb_lock); 3970d30ea906Sjfb8856606 3971d30ea906Sjfb8856606 return ret; 3972d30ea906Sjfb8856606 } 3973d30ea906Sjfb8856606 3974d30ea906Sjfb8856606 int 3975d30ea906Sjfb8856606 rte_eth_rx_queue_info_get(uint16_t port_id, uint16_t queue_id, 3976d30ea906Sjfb8856606 struct rte_eth_rxq_info *qinfo) 3977d30ea906Sjfb8856606 { 3978d30ea906Sjfb8856606 struct rte_eth_dev *dev; 3979d30ea906Sjfb8856606 3980d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 3981d30ea906Sjfb8856606 3982d30ea906Sjfb8856606 if (qinfo == NULL) 3983d30ea906Sjfb8856606 return -EINVAL; 3984d30ea906Sjfb8856606 3985d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 3986d30ea906Sjfb8856606 if (queue_id >= dev->data->nb_rx_queues) { 3987d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id); 3988d30ea906Sjfb8856606 return -EINVAL; 3989d30ea906Sjfb8856606 } 3990d30ea906Sjfb8856606 3991d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rxq_info_get, -ENOTSUP); 3992d30ea906Sjfb8856606 3993d30ea906Sjfb8856606 memset(qinfo, 0, sizeof(*qinfo)); 3994d30ea906Sjfb8856606 dev->dev_ops->rxq_info_get(dev, queue_id, qinfo); 3995d30ea906Sjfb8856606 return 0; 3996d30ea906Sjfb8856606 } 3997d30ea906Sjfb8856606 3998d30ea906Sjfb8856606 int 3999d30ea906Sjfb8856606 rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id, 4000d30ea906Sjfb8856606 struct rte_eth_txq_info *qinfo) 4001d30ea906Sjfb8856606 { 4002d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4003d30ea906Sjfb8856606 4004d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4005d30ea906Sjfb8856606 4006d30ea906Sjfb8856606 if (qinfo == NULL) 4007d30ea906Sjfb8856606 return -EINVAL; 4008d30ea906Sjfb8856606 4009d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4010d30ea906Sjfb8856606 if (queue_id >= dev->data->nb_tx_queues) { 4011d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id); 4012d30ea906Sjfb8856606 return -EINVAL; 4013d30ea906Sjfb8856606 } 4014d30ea906Sjfb8856606 4015d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->txq_info_get, -ENOTSUP); 4016d30ea906Sjfb8856606 4017d30ea906Sjfb8856606 memset(qinfo, 0, sizeof(*qinfo)); 4018d30ea906Sjfb8856606 dev->dev_ops->txq_info_get(dev, queue_id, qinfo); 4019d30ea906Sjfb8856606 4020d30ea906Sjfb8856606 return 0; 4021d30ea906Sjfb8856606 } 4022d30ea906Sjfb8856606 4023d30ea906Sjfb8856606 int 4024d30ea906Sjfb8856606 rte_eth_dev_set_mc_addr_list(uint16_t port_id, 4025d30ea906Sjfb8856606 struct ether_addr *mc_addr_set, 4026d30ea906Sjfb8856606 uint32_t nb_mc_addr) 4027d30ea906Sjfb8856606 { 4028d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4029d30ea906Sjfb8856606 4030d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4031d30ea906Sjfb8856606 4032d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4033d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_mc_addr_list, -ENOTSUP); 4034d30ea906Sjfb8856606 return eth_err(port_id, dev->dev_ops->set_mc_addr_list(dev, 4035d30ea906Sjfb8856606 mc_addr_set, nb_mc_addr)); 4036d30ea906Sjfb8856606 } 4037d30ea906Sjfb8856606 4038d30ea906Sjfb8856606 int 4039d30ea906Sjfb8856606 rte_eth_timesync_enable(uint16_t port_id) 4040d30ea906Sjfb8856606 { 4041d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4042d30ea906Sjfb8856606 4043d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4044d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4045d30ea906Sjfb8856606 4046d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_enable, -ENOTSUP); 4047d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->timesync_enable)(dev)); 4048d30ea906Sjfb8856606 } 4049d30ea906Sjfb8856606 4050d30ea906Sjfb8856606 int 4051d30ea906Sjfb8856606 rte_eth_timesync_disable(uint16_t port_id) 4052d30ea906Sjfb8856606 { 4053d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4054d30ea906Sjfb8856606 4055d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4056d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4057d30ea906Sjfb8856606 4058d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_disable, -ENOTSUP); 4059d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->timesync_disable)(dev)); 4060d30ea906Sjfb8856606 } 4061d30ea906Sjfb8856606 4062d30ea906Sjfb8856606 int 4063d30ea906Sjfb8856606 rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp, 4064d30ea906Sjfb8856606 uint32_t flags) 4065d30ea906Sjfb8856606 { 4066d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4067d30ea906Sjfb8856606 4068d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4069d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4070d30ea906Sjfb8856606 4071d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP); 4072d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp) 4073d30ea906Sjfb8856606 (dev, timestamp, flags)); 4074d30ea906Sjfb8856606 } 4075d30ea906Sjfb8856606 4076d30ea906Sjfb8856606 int 4077d30ea906Sjfb8856606 rte_eth_timesync_read_tx_timestamp(uint16_t port_id, 4078d30ea906Sjfb8856606 struct timespec *timestamp) 4079d30ea906Sjfb8856606 { 4080d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4081d30ea906Sjfb8856606 4082d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4083d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4084d30ea906Sjfb8856606 4085d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP); 4086d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp) 4087d30ea906Sjfb8856606 (dev, timestamp)); 4088d30ea906Sjfb8856606 } 4089d30ea906Sjfb8856606 4090d30ea906Sjfb8856606 int 4091d30ea906Sjfb8856606 rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta) 4092d30ea906Sjfb8856606 { 4093d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4094d30ea906Sjfb8856606 4095d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4096d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4097d30ea906Sjfb8856606 4098d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_adjust_time, -ENOTSUP); 4099d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->timesync_adjust_time)(dev, 4100d30ea906Sjfb8856606 delta)); 4101d30ea906Sjfb8856606 } 4102d30ea906Sjfb8856606 4103d30ea906Sjfb8856606 int 4104d30ea906Sjfb8856606 rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp) 4105d30ea906Sjfb8856606 { 4106d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4107d30ea906Sjfb8856606 4108d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4109d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4110d30ea906Sjfb8856606 4111d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP); 4112d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev, 4113d30ea906Sjfb8856606 timestamp)); 4114d30ea906Sjfb8856606 } 4115d30ea906Sjfb8856606 4116d30ea906Sjfb8856606 int 4117d30ea906Sjfb8856606 rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp) 4118d30ea906Sjfb8856606 { 4119d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4120d30ea906Sjfb8856606 4121d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4122d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4123d30ea906Sjfb8856606 4124d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP); 4125d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev, 4126d30ea906Sjfb8856606 timestamp)); 4127d30ea906Sjfb8856606 } 4128d30ea906Sjfb8856606 4129d30ea906Sjfb8856606 int 4130d30ea906Sjfb8856606 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info) 4131d30ea906Sjfb8856606 { 4132d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4133d30ea906Sjfb8856606 4134d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4135d30ea906Sjfb8856606 4136d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4137d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_reg, -ENOTSUP); 4138d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info)); 4139d30ea906Sjfb8856606 } 4140d30ea906Sjfb8856606 4141d30ea906Sjfb8856606 int 4142d30ea906Sjfb8856606 rte_eth_dev_get_eeprom_length(uint16_t port_id) 4143d30ea906Sjfb8856606 { 4144d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4145d30ea906Sjfb8856606 4146d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4147d30ea906Sjfb8856606 4148d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4149d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom_length, -ENOTSUP); 4150d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->get_eeprom_length)(dev)); 4151d30ea906Sjfb8856606 } 4152d30ea906Sjfb8856606 4153d30ea906Sjfb8856606 int 4154d30ea906Sjfb8856606 rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) 4155d30ea906Sjfb8856606 { 4156d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4157d30ea906Sjfb8856606 4158d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4159d30ea906Sjfb8856606 4160d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4161d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom, -ENOTSUP); 4162d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->get_eeprom)(dev, info)); 4163d30ea906Sjfb8856606 } 4164d30ea906Sjfb8856606 4165d30ea906Sjfb8856606 int 4166d30ea906Sjfb8856606 rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) 4167d30ea906Sjfb8856606 { 4168d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4169d30ea906Sjfb8856606 4170d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4171d30ea906Sjfb8856606 4172d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4173d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_eeprom, -ENOTSUP); 4174d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->set_eeprom)(dev, info)); 4175d30ea906Sjfb8856606 } 4176d30ea906Sjfb8856606 4177d30ea906Sjfb8856606 int __rte_experimental 4178d30ea906Sjfb8856606 rte_eth_dev_get_module_info(uint16_t port_id, 4179d30ea906Sjfb8856606 struct rte_eth_dev_module_info *modinfo) 4180d30ea906Sjfb8856606 { 4181d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4182d30ea906Sjfb8856606 4183d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4184d30ea906Sjfb8856606 4185d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4186d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_info, -ENOTSUP); 4187d30ea906Sjfb8856606 return (*dev->dev_ops->get_module_info)(dev, modinfo); 4188d30ea906Sjfb8856606 } 4189d30ea906Sjfb8856606 4190d30ea906Sjfb8856606 int __rte_experimental 4191d30ea906Sjfb8856606 rte_eth_dev_get_module_eeprom(uint16_t port_id, 4192d30ea906Sjfb8856606 struct rte_dev_eeprom_info *info) 4193d30ea906Sjfb8856606 { 4194d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4195d30ea906Sjfb8856606 4196d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4197d30ea906Sjfb8856606 4198d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4199d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_eeprom, -ENOTSUP); 4200d30ea906Sjfb8856606 return (*dev->dev_ops->get_module_eeprom)(dev, info); 4201d30ea906Sjfb8856606 } 4202d30ea906Sjfb8856606 4203d30ea906Sjfb8856606 int 4204d30ea906Sjfb8856606 rte_eth_dev_get_dcb_info(uint16_t port_id, 4205d30ea906Sjfb8856606 struct rte_eth_dcb_info *dcb_info) 4206d30ea906Sjfb8856606 { 4207d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4208d30ea906Sjfb8856606 4209d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4210d30ea906Sjfb8856606 4211d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4212d30ea906Sjfb8856606 memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info)); 4213d30ea906Sjfb8856606 4214d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_dcb_info, -ENOTSUP); 4215d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->get_dcb_info)(dev, dcb_info)); 4216d30ea906Sjfb8856606 } 4217d30ea906Sjfb8856606 4218d30ea906Sjfb8856606 int 4219d30ea906Sjfb8856606 rte_eth_dev_l2_tunnel_eth_type_conf(uint16_t port_id, 4220d30ea906Sjfb8856606 struct rte_eth_l2_tunnel_conf *l2_tunnel) 4221d30ea906Sjfb8856606 { 4222d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4223d30ea906Sjfb8856606 4224d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4225d30ea906Sjfb8856606 if (l2_tunnel == NULL) { 4226d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid l2_tunnel parameter\n"); 4227d30ea906Sjfb8856606 return -EINVAL; 4228d30ea906Sjfb8856606 } 4229d30ea906Sjfb8856606 4230d30ea906Sjfb8856606 if (l2_tunnel->l2_tunnel_type >= RTE_TUNNEL_TYPE_MAX) { 4231d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n"); 4232d30ea906Sjfb8856606 return -EINVAL; 4233d30ea906Sjfb8856606 } 4234d30ea906Sjfb8856606 4235d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4236d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->l2_tunnel_eth_type_conf, 4237d30ea906Sjfb8856606 -ENOTSUP); 4238d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->l2_tunnel_eth_type_conf)(dev, 4239d30ea906Sjfb8856606 l2_tunnel)); 4240d30ea906Sjfb8856606 } 4241d30ea906Sjfb8856606 4242d30ea906Sjfb8856606 int 4243d30ea906Sjfb8856606 rte_eth_dev_l2_tunnel_offload_set(uint16_t port_id, 4244d30ea906Sjfb8856606 struct rte_eth_l2_tunnel_conf *l2_tunnel, 4245d30ea906Sjfb8856606 uint32_t mask, 4246d30ea906Sjfb8856606 uint8_t en) 4247d30ea906Sjfb8856606 { 4248d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4249d30ea906Sjfb8856606 4250d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4251d30ea906Sjfb8856606 4252d30ea906Sjfb8856606 if (l2_tunnel == NULL) { 4253d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid l2_tunnel parameter\n"); 4254d30ea906Sjfb8856606 return -EINVAL; 4255d30ea906Sjfb8856606 } 4256d30ea906Sjfb8856606 4257d30ea906Sjfb8856606 if (l2_tunnel->l2_tunnel_type >= RTE_TUNNEL_TYPE_MAX) { 4258d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n"); 4259d30ea906Sjfb8856606 return -EINVAL; 4260d30ea906Sjfb8856606 } 4261d30ea906Sjfb8856606 4262d30ea906Sjfb8856606 if (mask == 0) { 4263d30ea906Sjfb8856606 RTE_ETHDEV_LOG(ERR, "Mask should have a value\n"); 4264d30ea906Sjfb8856606 return -EINVAL; 4265d30ea906Sjfb8856606 } 4266d30ea906Sjfb8856606 4267d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4268d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->l2_tunnel_offload_set, 4269d30ea906Sjfb8856606 -ENOTSUP); 4270d30ea906Sjfb8856606 return eth_err(port_id, (*dev->dev_ops->l2_tunnel_offload_set)(dev, 4271d30ea906Sjfb8856606 l2_tunnel, mask, en)); 4272d30ea906Sjfb8856606 } 4273d30ea906Sjfb8856606 4274d30ea906Sjfb8856606 static void 4275d30ea906Sjfb8856606 rte_eth_dev_adjust_nb_desc(uint16_t *nb_desc, 4276d30ea906Sjfb8856606 const struct rte_eth_desc_lim *desc_lim) 4277d30ea906Sjfb8856606 { 4278d30ea906Sjfb8856606 if (desc_lim->nb_align != 0) 4279d30ea906Sjfb8856606 *nb_desc = RTE_ALIGN_CEIL(*nb_desc, desc_lim->nb_align); 4280d30ea906Sjfb8856606 4281d30ea906Sjfb8856606 if (desc_lim->nb_max != 0) 4282d30ea906Sjfb8856606 *nb_desc = RTE_MIN(*nb_desc, desc_lim->nb_max); 4283d30ea906Sjfb8856606 4284d30ea906Sjfb8856606 *nb_desc = RTE_MAX(*nb_desc, desc_lim->nb_min); 4285d30ea906Sjfb8856606 } 4286d30ea906Sjfb8856606 4287d30ea906Sjfb8856606 int 4288d30ea906Sjfb8856606 rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id, 4289d30ea906Sjfb8856606 uint16_t *nb_rx_desc, 4290d30ea906Sjfb8856606 uint16_t *nb_tx_desc) 4291d30ea906Sjfb8856606 { 4292d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4293d30ea906Sjfb8856606 struct rte_eth_dev_info dev_info; 4294d30ea906Sjfb8856606 4295d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4296d30ea906Sjfb8856606 4297d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4298d30ea906Sjfb8856606 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP); 4299d30ea906Sjfb8856606 4300d30ea906Sjfb8856606 rte_eth_dev_info_get(port_id, &dev_info); 4301d30ea906Sjfb8856606 4302d30ea906Sjfb8856606 if (nb_rx_desc != NULL) 4303d30ea906Sjfb8856606 rte_eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim); 4304d30ea906Sjfb8856606 4305d30ea906Sjfb8856606 if (nb_tx_desc != NULL) 4306d30ea906Sjfb8856606 rte_eth_dev_adjust_nb_desc(nb_tx_desc, &dev_info.tx_desc_lim); 4307d30ea906Sjfb8856606 4308d30ea906Sjfb8856606 return 0; 4309d30ea906Sjfb8856606 } 4310d30ea906Sjfb8856606 4311d30ea906Sjfb8856606 int 4312d30ea906Sjfb8856606 rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) 4313d30ea906Sjfb8856606 { 4314d30ea906Sjfb8856606 struct rte_eth_dev *dev; 4315d30ea906Sjfb8856606 4316d30ea906Sjfb8856606 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); 4317d30ea906Sjfb8856606 4318d30ea906Sjfb8856606 if (pool == NULL) 4319d30ea906Sjfb8856606 return -EINVAL; 4320d30ea906Sjfb8856606 4321d30ea906Sjfb8856606 dev = &rte_eth_devices[port_id]; 4322d30ea906Sjfb8856606 4323d30ea906Sjfb8856606 if (*dev->dev_ops->pool_ops_supported == NULL) 4324d30ea906Sjfb8856606 return 1; /* all pools are supported */ 4325d30ea906Sjfb8856606 4326d30ea906Sjfb8856606 return (*dev->dev_ops->pool_ops_supported)(dev, pool); 4327d30ea906Sjfb8856606 } 4328d30ea906Sjfb8856606 4329d30ea906Sjfb8856606 /** 4330d30ea906Sjfb8856606 * A set of values to describe the possible states of a switch domain. 4331d30ea906Sjfb8856606 */ 4332d30ea906Sjfb8856606 enum rte_eth_switch_domain_state { 4333d30ea906Sjfb8856606 RTE_ETH_SWITCH_DOMAIN_UNUSED = 0, 4334d30ea906Sjfb8856606 RTE_ETH_SWITCH_DOMAIN_ALLOCATED 4335d30ea906Sjfb8856606 }; 4336d30ea906Sjfb8856606 4337d30ea906Sjfb8856606 /** 4338d30ea906Sjfb8856606 * Array of switch domains available for allocation. Array is sized to 4339d30ea906Sjfb8856606 * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than 4340d30ea906Sjfb8856606 * ethdev ports in a single process. 4341d30ea906Sjfb8856606 */ 4342d30ea906Sjfb8856606 static struct rte_eth_dev_switch { 4343d30ea906Sjfb8856606 enum rte_eth_switch_domain_state state; 4344d30ea906Sjfb8856606 } rte_eth_switch_domains[RTE_MAX_ETHPORTS]; 4345d30ea906Sjfb8856606 4346d30ea906Sjfb8856606 int __rte_experimental 4347d30ea906Sjfb8856606 rte_eth_switch_domain_alloc(uint16_t *domain_id) 4348d30ea906Sjfb8856606 { 4349d30ea906Sjfb8856606 unsigned int i; 4350d30ea906Sjfb8856606 4351d30ea906Sjfb8856606 *domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID; 4352d30ea906Sjfb8856606 4353d30ea906Sjfb8856606 for (i = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID + 1; 4354d30ea906Sjfb8856606 i < RTE_MAX_ETHPORTS; i++) { 4355d30ea906Sjfb8856606 if (rte_eth_switch_domains[i].state == 4356d30ea906Sjfb8856606 RTE_ETH_SWITCH_DOMAIN_UNUSED) { 4357d30ea906Sjfb8856606 rte_eth_switch_domains[i].state = 4358d30ea906Sjfb8856606 RTE_ETH_SWITCH_DOMAIN_ALLOCATED; 4359d30ea906Sjfb8856606 *domain_id = i; 4360d30ea906Sjfb8856606 return 0; 4361d30ea906Sjfb8856606 } 4362d30ea906Sjfb8856606 } 4363d30ea906Sjfb8856606 4364d30ea906Sjfb8856606 return -ENOSPC; 4365d30ea906Sjfb8856606 } 4366d30ea906Sjfb8856606 4367d30ea906Sjfb8856606 int __rte_experimental 4368d30ea906Sjfb8856606 rte_eth_switch_domain_free(uint16_t domain_id) 4369d30ea906Sjfb8856606 { 4370d30ea906Sjfb8856606 if (domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID || 4371d30ea906Sjfb8856606 domain_id >= RTE_MAX_ETHPORTS) 4372d30ea906Sjfb8856606 return -EINVAL; 4373d30ea906Sjfb8856606 4374d30ea906Sjfb8856606 if (rte_eth_switch_domains[domain_id].state != 4375d30ea906Sjfb8856606 RTE_ETH_SWITCH_DOMAIN_ALLOCATED) 4376d30ea906Sjfb8856606 return -EINVAL; 4377d30ea906Sjfb8856606 4378d30ea906Sjfb8856606 rte_eth_switch_domains[domain_id].state = RTE_ETH_SWITCH_DOMAIN_UNUSED; 4379d30ea906Sjfb8856606 4380d30ea906Sjfb8856606 return 0; 4381d30ea906Sjfb8856606 } 4382d30ea906Sjfb8856606 4383d30ea906Sjfb8856606 static int 4384d30ea906Sjfb8856606 rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in) 4385d30ea906Sjfb8856606 { 4386d30ea906Sjfb8856606 int state; 4387d30ea906Sjfb8856606 struct rte_kvargs_pair *pair; 4388d30ea906Sjfb8856606 char *letter; 4389d30ea906Sjfb8856606 4390d30ea906Sjfb8856606 arglist->str = strdup(str_in); 4391d30ea906Sjfb8856606 if (arglist->str == NULL) 4392d30ea906Sjfb8856606 return -ENOMEM; 4393d30ea906Sjfb8856606 4394d30ea906Sjfb8856606 letter = arglist->str; 4395d30ea906Sjfb8856606 state = 0; 4396d30ea906Sjfb8856606 arglist->count = 0; 4397d30ea906Sjfb8856606 pair = &arglist->pairs[0]; 4398d30ea906Sjfb8856606 while (1) { 4399d30ea906Sjfb8856606 switch (state) { 4400d30ea906Sjfb8856606 case 0: /* Initial */ 4401d30ea906Sjfb8856606 if (*letter == '=') 4402d30ea906Sjfb8856606 return -EINVAL; 4403d30ea906Sjfb8856606 else if (*letter == '\0') 4404d30ea906Sjfb8856606 return 0; 4405d30ea906Sjfb8856606 4406d30ea906Sjfb8856606 state = 1; 4407d30ea906Sjfb8856606 pair->key = letter; 4408d30ea906Sjfb8856606 /* fall-thru */ 4409d30ea906Sjfb8856606 4410d30ea906Sjfb8856606 case 1: /* Parsing key */ 4411d30ea906Sjfb8856606 if (*letter == '=') { 4412d30ea906Sjfb8856606 *letter = '\0'; 4413d30ea906Sjfb8856606 pair->value = letter + 1; 4414d30ea906Sjfb8856606 state = 2; 4415d30ea906Sjfb8856606 } else if (*letter == ',' || *letter == '\0') 4416d30ea906Sjfb8856606 return -EINVAL; 4417d30ea906Sjfb8856606 break; 4418d30ea906Sjfb8856606 4419d30ea906Sjfb8856606 4420d30ea906Sjfb8856606 case 2: /* Parsing value */ 4421d30ea906Sjfb8856606 if (*letter == '[') 4422d30ea906Sjfb8856606 state = 3; 4423d30ea906Sjfb8856606 else if (*letter == ',') { 4424d30ea906Sjfb8856606 *letter = '\0'; 4425d30ea906Sjfb8856606 arglist->count++; 4426d30ea906Sjfb8856606 pair = &arglist->pairs[arglist->count]; 4427d30ea906Sjfb8856606 state = 0; 4428d30ea906Sjfb8856606 } else if (*letter == '\0') { 4429d30ea906Sjfb8856606 letter--; 4430d30ea906Sjfb8856606 arglist->count++; 4431d30ea906Sjfb8856606 pair = &arglist->pairs[arglist->count]; 4432d30ea906Sjfb8856606 state = 0; 4433d30ea906Sjfb8856606 } 4434d30ea906Sjfb8856606 break; 4435d30ea906Sjfb8856606 4436d30ea906Sjfb8856606 case 3: /* Parsing list */ 4437d30ea906Sjfb8856606 if (*letter == ']') 4438d30ea906Sjfb8856606 state = 2; 4439d30ea906Sjfb8856606 else if (*letter == '\0') 4440d30ea906Sjfb8856606 return -EINVAL; 4441d30ea906Sjfb8856606 break; 4442d30ea906Sjfb8856606 } 4443d30ea906Sjfb8856606 letter++; 4444d30ea906Sjfb8856606 } 4445d30ea906Sjfb8856606 } 4446d30ea906Sjfb8856606 4447d30ea906Sjfb8856606 int __rte_experimental 4448d30ea906Sjfb8856606 rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da) 4449d30ea906Sjfb8856606 { 4450d30ea906Sjfb8856606 struct rte_kvargs args; 4451d30ea906Sjfb8856606 struct rte_kvargs_pair *pair; 4452d30ea906Sjfb8856606 unsigned int i; 4453d30ea906Sjfb8856606 int result = 0; 4454d30ea906Sjfb8856606 4455d30ea906Sjfb8856606 memset(eth_da, 0, sizeof(*eth_da)); 4456d30ea906Sjfb8856606 4457d30ea906Sjfb8856606 result = rte_eth_devargs_tokenise(&args, dargs); 4458d30ea906Sjfb8856606 if (result < 0) 4459d30ea906Sjfb8856606 goto parse_cleanup; 4460d30ea906Sjfb8856606 4461d30ea906Sjfb8856606 for (i = 0; i < args.count; i++) { 4462d30ea906Sjfb8856606 pair = &args.pairs[i]; 4463d30ea906Sjfb8856606 if (strcmp("representor", pair->key) == 0) { 4464d30ea906Sjfb8856606 result = rte_eth_devargs_parse_list(pair->value, 4465d30ea906Sjfb8856606 rte_eth_devargs_parse_representor_ports, 4466d30ea906Sjfb8856606 eth_da); 4467d30ea906Sjfb8856606 if (result < 0) 4468d30ea906Sjfb8856606 goto parse_cleanup; 4469d30ea906Sjfb8856606 } 4470d30ea906Sjfb8856606 } 4471d30ea906Sjfb8856606 4472d30ea906Sjfb8856606 parse_cleanup: 4473d30ea906Sjfb8856606 if (args.str) 4474d30ea906Sjfb8856606 free(args.str); 4475d30ea906Sjfb8856606 4476d30ea906Sjfb8856606 return result; 4477d30ea906Sjfb8856606 } 4478d30ea906Sjfb8856606 4479d30ea906Sjfb8856606 RTE_INIT(ethdev_init_log) 4480d30ea906Sjfb8856606 { 4481d30ea906Sjfb8856606 rte_eth_dev_logtype = rte_log_register("lib.ethdev"); 4482d30ea906Sjfb8856606 if (rte_eth_dev_logtype >= 0) 4483d30ea906Sjfb8856606 rte_log_set_level(rte_eth_dev_logtype, RTE_LOG_INFO); 4484d30ea906Sjfb8856606 } 4485