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