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