xref: /dpdk/lib/ethdev/rte_ethdev.c (revision 52b49ea0)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2010-2017 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #include <ctype.h>
699a2dd95SBruce Richardson #include <errno.h>
799a2dd95SBruce Richardson #include <inttypes.h>
899a2dd95SBruce Richardson #include <stdbool.h>
999a2dd95SBruce Richardson #include <stdint.h>
1099a2dd95SBruce Richardson #include <stdlib.h>
1199a2dd95SBruce Richardson #include <string.h>
1299a2dd95SBruce Richardson #include <sys/queue.h>
1399a2dd95SBruce Richardson 
1499a2dd95SBruce Richardson #include <rte_byteorder.h>
1599a2dd95SBruce Richardson #include <rte_log.h>
1699a2dd95SBruce Richardson #include <rte_debug.h>
1799a2dd95SBruce Richardson #include <rte_interrupts.h>
1899a2dd95SBruce Richardson #include <rte_memory.h>
1999a2dd95SBruce Richardson #include <rte_memcpy.h>
2099a2dd95SBruce Richardson #include <rte_memzone.h>
2199a2dd95SBruce Richardson #include <rte_launch.h>
2299a2dd95SBruce Richardson #include <rte_eal.h>
2399a2dd95SBruce Richardson #include <rte_per_lcore.h>
2499a2dd95SBruce Richardson #include <rte_lcore.h>
2599a2dd95SBruce Richardson #include <rte_branch_prediction.h>
2699a2dd95SBruce Richardson #include <rte_common.h>
2799a2dd95SBruce Richardson #include <rte_mempool.h>
2899a2dd95SBruce Richardson #include <rte_malloc.h>
2999a2dd95SBruce Richardson #include <rte_mbuf.h>
3099a2dd95SBruce Richardson #include <rte_errno.h>
3199a2dd95SBruce Richardson #include <rte_spinlock.h>
3299a2dd95SBruce Richardson #include <rte_string_fns.h>
3399a2dd95SBruce Richardson #include <rte_kvargs.h>
3499a2dd95SBruce Richardson #include <rte_class.h>
3599a2dd95SBruce Richardson #include <rte_ether.h>
3699a2dd95SBruce Richardson #include <rte_telemetry.h>
3799a2dd95SBruce Richardson 
3899a2dd95SBruce Richardson #include "rte_ethdev_trace.h"
3999a2dd95SBruce Richardson #include "rte_ethdev.h"
4099a2dd95SBruce Richardson #include "ethdev_driver.h"
4199a2dd95SBruce Richardson #include "ethdev_profile.h"
4299a2dd95SBruce Richardson #include "ethdev_private.h"
4399a2dd95SBruce Richardson 
4499a2dd95SBruce Richardson static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";
4599a2dd95SBruce Richardson struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
4699a2dd95SBruce Richardson 
47c87d435aSKonstantin Ananyev /* public fast-path API */
48c87d435aSKonstantin Ananyev struct rte_eth_fp_ops rte_eth_fp_ops[RTE_MAX_ETHPORTS];
49c87d435aSKonstantin Ananyev 
5099a2dd95SBruce Richardson /* spinlock for eth device callbacks */
5199a2dd95SBruce Richardson static rte_spinlock_t eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
5299a2dd95SBruce Richardson 
5309fd4227SAndrew Rybchenko /* spinlock for add/remove Rx callbacks */
5499a2dd95SBruce Richardson static rte_spinlock_t eth_dev_rx_cb_lock = RTE_SPINLOCK_INITIALIZER;
5599a2dd95SBruce Richardson 
5609fd4227SAndrew Rybchenko /* spinlock for add/remove Tx callbacks */
5799a2dd95SBruce Richardson static rte_spinlock_t eth_dev_tx_cb_lock = RTE_SPINLOCK_INITIALIZER;
5899a2dd95SBruce Richardson 
5999a2dd95SBruce Richardson /* spinlock for shared data allocation */
6099a2dd95SBruce Richardson static rte_spinlock_t eth_dev_shared_data_lock = RTE_SPINLOCK_INITIALIZER;
6199a2dd95SBruce Richardson 
6299a2dd95SBruce Richardson /* store statistics names and its offset in stats structure  */
6399a2dd95SBruce Richardson struct rte_eth_xstats_name_off {
6499a2dd95SBruce Richardson 	char name[RTE_ETH_XSTATS_NAME_SIZE];
6599a2dd95SBruce Richardson 	unsigned offset;
6699a2dd95SBruce Richardson };
6799a2dd95SBruce Richardson 
6899a2dd95SBruce Richardson /* Shared memory between primary and secondary processes. */
6999a2dd95SBruce Richardson static struct {
7099a2dd95SBruce Richardson 	uint64_t next_owner_id;
7199a2dd95SBruce Richardson 	rte_spinlock_t ownership_lock;
7299a2dd95SBruce Richardson 	struct rte_eth_dev_data data[RTE_MAX_ETHPORTS];
7399a2dd95SBruce Richardson } *eth_dev_shared_data;
7499a2dd95SBruce Richardson 
7599a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_stats_strings[] = {
7699a2dd95SBruce Richardson 	{"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)},
7799a2dd95SBruce Richardson 	{"tx_good_packets", offsetof(struct rte_eth_stats, opackets)},
7899a2dd95SBruce Richardson 	{"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)},
7999a2dd95SBruce Richardson 	{"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)},
8099a2dd95SBruce Richardson 	{"rx_missed_errors", offsetof(struct rte_eth_stats, imissed)},
8199a2dd95SBruce Richardson 	{"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
8299a2dd95SBruce Richardson 	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
8399a2dd95SBruce Richardson 	{"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats,
8499a2dd95SBruce Richardson 		rx_nombuf)},
8599a2dd95SBruce Richardson };
8699a2dd95SBruce Richardson 
8799a2dd95SBruce Richardson #define RTE_NB_STATS RTE_DIM(eth_dev_stats_strings)
8899a2dd95SBruce Richardson 
8999a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_rxq_stats_strings[] = {
9099a2dd95SBruce Richardson 	{"packets", offsetof(struct rte_eth_stats, q_ipackets)},
9199a2dd95SBruce Richardson 	{"bytes", offsetof(struct rte_eth_stats, q_ibytes)},
9299a2dd95SBruce Richardson 	{"errors", offsetof(struct rte_eth_stats, q_errors)},
9399a2dd95SBruce Richardson };
9499a2dd95SBruce Richardson 
9599a2dd95SBruce Richardson #define RTE_NB_RXQ_STATS RTE_DIM(eth_dev_rxq_stats_strings)
9699a2dd95SBruce Richardson 
9799a2dd95SBruce Richardson static const struct rte_eth_xstats_name_off eth_dev_txq_stats_strings[] = {
9899a2dd95SBruce Richardson 	{"packets", offsetof(struct rte_eth_stats, q_opackets)},
9999a2dd95SBruce Richardson 	{"bytes", offsetof(struct rte_eth_stats, q_obytes)},
10099a2dd95SBruce Richardson };
10199a2dd95SBruce Richardson #define RTE_NB_TXQ_STATS RTE_DIM(eth_dev_txq_stats_strings)
10299a2dd95SBruce Richardson 
10399a2dd95SBruce Richardson #define RTE_RX_OFFLOAD_BIT2STR(_name)	\
10499a2dd95SBruce Richardson 	{ RTE_ETH_RX_OFFLOAD_##_name, #_name }
10599a2dd95SBruce Richardson 
10699a2dd95SBruce Richardson static const struct {
10799a2dd95SBruce Richardson 	uint64_t offload;
10899a2dd95SBruce Richardson 	const char *name;
10999a2dd95SBruce Richardson } eth_dev_rx_offload_names[] = {
11099a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(VLAN_STRIP),
11199a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(IPV4_CKSUM),
11299a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(UDP_CKSUM),
11399a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(TCP_CKSUM),
11499a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(TCP_LRO),
11599a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(QINQ_STRIP),
11699a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM),
11799a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(MACSEC_STRIP),
11899a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(HEADER_SPLIT),
11999a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(VLAN_FILTER),
12099a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(VLAN_EXTEND),
12199a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(SCATTER),
12299a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(TIMESTAMP),
12399a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(SECURITY),
12499a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(KEEP_CRC),
12599a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(SCTP_CKSUM),
12699a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM),
12799a2dd95SBruce Richardson 	RTE_RX_OFFLOAD_BIT2STR(RSS_HASH),
128295968d1SFerruh Yigit 	RTE_RX_OFFLOAD_BIT2STR(BUFFER_SPLIT),
12999a2dd95SBruce Richardson };
13099a2dd95SBruce Richardson 
13199a2dd95SBruce Richardson #undef RTE_RX_OFFLOAD_BIT2STR
13299a2dd95SBruce Richardson #undef RTE_ETH_RX_OFFLOAD_BIT2STR
13399a2dd95SBruce Richardson 
13499a2dd95SBruce Richardson #define RTE_TX_OFFLOAD_BIT2STR(_name)	\
135295968d1SFerruh Yigit 	{ RTE_ETH_TX_OFFLOAD_##_name, #_name }
13699a2dd95SBruce Richardson 
13799a2dd95SBruce Richardson static const struct {
13899a2dd95SBruce Richardson 	uint64_t offload;
13999a2dd95SBruce Richardson 	const char *name;
14099a2dd95SBruce Richardson } eth_dev_tx_offload_names[] = {
14199a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(VLAN_INSERT),
14299a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(IPV4_CKSUM),
14399a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(UDP_CKSUM),
14499a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(TCP_CKSUM),
14599a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(SCTP_CKSUM),
14699a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(TCP_TSO),
14799a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(UDP_TSO),
14899a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM),
14999a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(QINQ_INSERT),
15099a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(VXLAN_TNL_TSO),
15199a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(GRE_TNL_TSO),
15299a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(IPIP_TNL_TSO),
15399a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(GENEVE_TNL_TSO),
15499a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(MACSEC_INSERT),
15599a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(MT_LOCKFREE),
15699a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(MULTI_SEGS),
15799a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(MBUF_FAST_FREE),
15899a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(SECURITY),
15999a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(UDP_TNL_TSO),
16099a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(IP_TNL_TSO),
16199a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM),
16299a2dd95SBruce Richardson 	RTE_TX_OFFLOAD_BIT2STR(SEND_ON_TIMESTAMP),
16399a2dd95SBruce Richardson };
16499a2dd95SBruce Richardson 
16599a2dd95SBruce Richardson #undef RTE_TX_OFFLOAD_BIT2STR
16699a2dd95SBruce Richardson 
16793e441c9SXueming Li static const struct {
16893e441c9SXueming Li 	uint64_t offload;
16993e441c9SXueming Li 	const char *name;
17093e441c9SXueming Li } rte_eth_dev_capa_names[] = {
17193e441c9SXueming Li 	{RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP, "RUNTIME_RX_QUEUE_SETUP"},
17293e441c9SXueming Li 	{RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP, "RUNTIME_TX_QUEUE_SETUP"},
17393e441c9SXueming Li 	{RTE_ETH_DEV_CAPA_RXQ_SHARE, "RXQ_SHARE"},
17464be0e77SDmitry Kozlyuk 	{RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP, "FLOW_RULE_KEEP"},
17564be0e77SDmitry Kozlyuk 	{RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"},
17693e441c9SXueming Li };
17793e441c9SXueming Li 
17899a2dd95SBruce Richardson /**
17999a2dd95SBruce Richardson  * The user application callback description.
18099a2dd95SBruce Richardson  *
18199a2dd95SBruce Richardson  * It contains callback address to be registered by user application,
18299a2dd95SBruce Richardson  * the pointer to the parameters for callback, and the event type.
18399a2dd95SBruce Richardson  */
18499a2dd95SBruce Richardson struct rte_eth_dev_callback {
18599a2dd95SBruce Richardson 	TAILQ_ENTRY(rte_eth_dev_callback) next; /**< Callbacks list */
18699a2dd95SBruce Richardson 	rte_eth_dev_cb_fn cb_fn;                /**< Callback address */
18799a2dd95SBruce Richardson 	void *cb_arg;                           /**< Parameter for callback */
18899a2dd95SBruce Richardson 	void *ret_param;                        /**< Return parameter */
18999a2dd95SBruce Richardson 	enum rte_eth_event_type event;          /**< Interrupt event type */
19099a2dd95SBruce Richardson 	uint32_t active;                        /**< Callback is executing */
19199a2dd95SBruce Richardson };
19299a2dd95SBruce Richardson 
19399a2dd95SBruce Richardson enum {
19499a2dd95SBruce Richardson 	STAT_QMAP_TX = 0,
19599a2dd95SBruce Richardson 	STAT_QMAP_RX
19699a2dd95SBruce Richardson };
19799a2dd95SBruce Richardson 
19899a2dd95SBruce Richardson int
19999a2dd95SBruce Richardson rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
20099a2dd95SBruce Richardson {
20199a2dd95SBruce Richardson 	int ret;
20299a2dd95SBruce Richardson 	struct rte_devargs devargs;
20399a2dd95SBruce Richardson 	const char *bus_param_key;
20499a2dd95SBruce Richardson 	char *bus_str = NULL;
20599a2dd95SBruce Richardson 	char *cls_str = NULL;
20699a2dd95SBruce Richardson 	int str_size;
20799a2dd95SBruce Richardson 
20853ef1b34SMin Hu (Connor) 	if (iter == NULL) {
20953ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot initialize NULL iterator\n");
21053ef1b34SMin Hu (Connor) 		return -EINVAL;
21153ef1b34SMin Hu (Connor) 	}
21253ef1b34SMin Hu (Connor) 
21353ef1b34SMin Hu (Connor) 	if (devargs_str == NULL) {
21453ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
21553ef1b34SMin Hu (Connor) 			"Cannot initialize iterator from NULL device description string\n");
21653ef1b34SMin Hu (Connor) 		return -EINVAL;
21753ef1b34SMin Hu (Connor) 	}
21853ef1b34SMin Hu (Connor) 
21999a2dd95SBruce Richardson 	memset(iter, 0, sizeof(*iter));
22099a2dd95SBruce Richardson 	memset(&devargs, 0, sizeof(devargs));
22199a2dd95SBruce Richardson 
22299a2dd95SBruce Richardson 	/*
22399a2dd95SBruce Richardson 	 * The devargs string may use various syntaxes:
22499a2dd95SBruce Richardson 	 *   - 0000:08:00.0,representor=[1-3]
22599a2dd95SBruce Richardson 	 *   - pci:0000:06:00.0,representor=[0,5]
22699a2dd95SBruce Richardson 	 *   - class=eth,mac=00:11:22:33:44:55
22799a2dd95SBruce Richardson 	 *   - bus=X,paramX=x/class=Y,paramY=y/driver=Z,paramZ=z
22899a2dd95SBruce Richardson 	 */
22999a2dd95SBruce Richardson 
23099a2dd95SBruce Richardson 	/*
23199a2dd95SBruce Richardson 	 * Handle pure class filter (i.e. without any bus-level argument),
23299a2dd95SBruce Richardson 	 * from future new syntax.
23399a2dd95SBruce Richardson 	 * rte_devargs_parse() is not yet supporting the new syntax,
23499a2dd95SBruce Richardson 	 * that's why this simple case is temporarily parsed here.
23599a2dd95SBruce Richardson 	 */
23699a2dd95SBruce Richardson #define iter_anybus_str "class=eth,"
23799a2dd95SBruce Richardson 	if (strncmp(devargs_str, iter_anybus_str,
23899a2dd95SBruce Richardson 			strlen(iter_anybus_str)) == 0) {
23999a2dd95SBruce Richardson 		iter->cls_str = devargs_str + strlen(iter_anybus_str);
24099a2dd95SBruce Richardson 		goto end;
24199a2dd95SBruce Richardson 	}
24299a2dd95SBruce Richardson 
24399a2dd95SBruce Richardson 	/* Split bus, device and parameters. */
24499a2dd95SBruce Richardson 	ret = rte_devargs_parse(&devargs, devargs_str);
24599a2dd95SBruce Richardson 	if (ret != 0)
24699a2dd95SBruce Richardson 		goto error;
24799a2dd95SBruce Richardson 
24899a2dd95SBruce Richardson 	/*
24999a2dd95SBruce Richardson 	 * Assume parameters of old syntax can match only at ethdev level.
25099a2dd95SBruce Richardson 	 * Extra parameters will be ignored, thanks to "+" prefix.
25199a2dd95SBruce Richardson 	 */
25299a2dd95SBruce Richardson 	str_size = strlen(devargs.args) + 2;
25399a2dd95SBruce Richardson 	cls_str = malloc(str_size);
25499a2dd95SBruce Richardson 	if (cls_str == NULL) {
25599a2dd95SBruce Richardson 		ret = -ENOMEM;
25699a2dd95SBruce Richardson 		goto error;
25799a2dd95SBruce Richardson 	}
25899a2dd95SBruce Richardson 	ret = snprintf(cls_str, str_size, "+%s", devargs.args);
25999a2dd95SBruce Richardson 	if (ret != str_size - 1) {
26099a2dd95SBruce Richardson 		ret = -EINVAL;
26199a2dd95SBruce Richardson 		goto error;
26299a2dd95SBruce Richardson 	}
26399a2dd95SBruce Richardson 	iter->cls_str = cls_str;
26499a2dd95SBruce Richardson 
26599a2dd95SBruce Richardson 	iter->bus = devargs.bus;
26699a2dd95SBruce Richardson 	if (iter->bus->dev_iterate == NULL) {
26799a2dd95SBruce Richardson 		ret = -ENOTSUP;
26899a2dd95SBruce Richardson 		goto error;
26999a2dd95SBruce Richardson 	}
27099a2dd95SBruce Richardson 
27199a2dd95SBruce Richardson 	/* Convert bus args to new syntax for use with new API dev_iterate. */
272a956adb2SHemant Agrawal 	if ((strcmp(iter->bus->name, "vdev") == 0) ||
273a956adb2SHemant Agrawal 		(strcmp(iter->bus->name, "fslmc") == 0) ||
274a956adb2SHemant Agrawal 		(strcmp(iter->bus->name, "dpaa_bus") == 0)) {
27599a2dd95SBruce Richardson 		bus_param_key = "name";
27699a2dd95SBruce Richardson 	} else if (strcmp(iter->bus->name, "pci") == 0) {
27799a2dd95SBruce Richardson 		bus_param_key = "addr";
27899a2dd95SBruce Richardson 	} else {
27999a2dd95SBruce Richardson 		ret = -ENOTSUP;
28099a2dd95SBruce Richardson 		goto error;
28199a2dd95SBruce Richardson 	}
28299a2dd95SBruce Richardson 	str_size = strlen(bus_param_key) + strlen(devargs.name) + 2;
28399a2dd95SBruce Richardson 	bus_str = malloc(str_size);
28499a2dd95SBruce Richardson 	if (bus_str == NULL) {
28599a2dd95SBruce Richardson 		ret = -ENOMEM;
28699a2dd95SBruce Richardson 		goto error;
28799a2dd95SBruce Richardson 	}
28899a2dd95SBruce Richardson 	ret = snprintf(bus_str, str_size, "%s=%s",
28999a2dd95SBruce Richardson 			bus_param_key, devargs.name);
29099a2dd95SBruce Richardson 	if (ret != str_size - 1) {
29199a2dd95SBruce Richardson 		ret = -EINVAL;
29299a2dd95SBruce Richardson 		goto error;
29399a2dd95SBruce Richardson 	}
29499a2dd95SBruce Richardson 	iter->bus_str = bus_str;
29599a2dd95SBruce Richardson 
29699a2dd95SBruce Richardson end:
29799a2dd95SBruce Richardson 	iter->cls = rte_class_find_by_name("eth");
29899a2dd95SBruce Richardson 	rte_devargs_reset(&devargs);
29999a2dd95SBruce Richardson 	return 0;
30099a2dd95SBruce Richardson 
30199a2dd95SBruce Richardson error:
30299a2dd95SBruce Richardson 	if (ret == -ENOTSUP)
30399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Bus %s does not support iterating.\n",
30499a2dd95SBruce Richardson 				iter->bus->name);
30599a2dd95SBruce Richardson 	rte_devargs_reset(&devargs);
30699a2dd95SBruce Richardson 	free(bus_str);
30799a2dd95SBruce Richardson 	free(cls_str);
30899a2dd95SBruce Richardson 	return ret;
30999a2dd95SBruce Richardson }
31099a2dd95SBruce Richardson 
31199a2dd95SBruce Richardson uint16_t
31299a2dd95SBruce Richardson rte_eth_iterator_next(struct rte_dev_iterator *iter)
31399a2dd95SBruce Richardson {
31453ef1b34SMin Hu (Connor) 	if (iter == NULL) {
31553ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
31653ef1b34SMin Hu (Connor) 			"Cannot get next device from NULL iterator\n");
31753ef1b34SMin Hu (Connor) 		return RTE_MAX_ETHPORTS;
31853ef1b34SMin Hu (Connor) 	}
31953ef1b34SMin Hu (Connor) 
32099a2dd95SBruce Richardson 	if (iter->cls == NULL) /* invalid ethdev iterator */
32199a2dd95SBruce Richardson 		return RTE_MAX_ETHPORTS;
32299a2dd95SBruce Richardson 
32399a2dd95SBruce Richardson 	do { /* loop to try all matching rte_device */
32499a2dd95SBruce Richardson 		/* If not pure ethdev filter and */
32599a2dd95SBruce Richardson 		if (iter->bus != NULL &&
32699a2dd95SBruce Richardson 				/* not in middle of rte_eth_dev iteration, */
32799a2dd95SBruce Richardson 				iter->class_device == NULL) {
32899a2dd95SBruce Richardson 			/* get next rte_device to try. */
32999a2dd95SBruce Richardson 			iter->device = iter->bus->dev_iterate(
33099a2dd95SBruce Richardson 					iter->device, iter->bus_str, iter);
33199a2dd95SBruce Richardson 			if (iter->device == NULL)
33299a2dd95SBruce Richardson 				break; /* no more rte_device candidate */
33399a2dd95SBruce Richardson 		}
33499a2dd95SBruce Richardson 		/* A device is matching bus part, need to check ethdev part. */
33599a2dd95SBruce Richardson 		iter->class_device = iter->cls->dev_iterate(
33699a2dd95SBruce Richardson 				iter->class_device, iter->cls_str, iter);
33799a2dd95SBruce Richardson 		if (iter->class_device != NULL)
33899a2dd95SBruce Richardson 			return eth_dev_to_id(iter->class_device); /* match */
33999a2dd95SBruce Richardson 	} while (iter->bus != NULL); /* need to try next rte_device */
34099a2dd95SBruce Richardson 
34199a2dd95SBruce Richardson 	/* No more ethdev port to iterate. */
34299a2dd95SBruce Richardson 	rte_eth_iterator_cleanup(iter);
34399a2dd95SBruce Richardson 	return RTE_MAX_ETHPORTS;
34499a2dd95SBruce Richardson }
34599a2dd95SBruce Richardson 
34699a2dd95SBruce Richardson void
34799a2dd95SBruce Richardson rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
34899a2dd95SBruce Richardson {
34953ef1b34SMin Hu (Connor) 	if (iter == NULL) {
35053ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot do clean up from NULL iterator\n");
35153ef1b34SMin Hu (Connor) 		return;
35253ef1b34SMin Hu (Connor) 	}
35353ef1b34SMin Hu (Connor) 
35499a2dd95SBruce Richardson 	if (iter->bus_str == NULL)
35599a2dd95SBruce Richardson 		return; /* nothing to free in pure class filter */
35699a2dd95SBruce Richardson 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
35799a2dd95SBruce Richardson 	free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */
35899a2dd95SBruce Richardson 	memset(iter, 0, sizeof(*iter));
35999a2dd95SBruce Richardson }
36099a2dd95SBruce Richardson 
36199a2dd95SBruce Richardson uint16_t
36299a2dd95SBruce Richardson rte_eth_find_next(uint16_t port_id)
36399a2dd95SBruce Richardson {
36499a2dd95SBruce Richardson 	while (port_id < RTE_MAX_ETHPORTS &&
36599a2dd95SBruce Richardson 			rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED)
36699a2dd95SBruce Richardson 		port_id++;
36799a2dd95SBruce Richardson 
36899a2dd95SBruce Richardson 	if (port_id >= RTE_MAX_ETHPORTS)
36999a2dd95SBruce Richardson 		return RTE_MAX_ETHPORTS;
37099a2dd95SBruce Richardson 
37199a2dd95SBruce Richardson 	return port_id;
37299a2dd95SBruce Richardson }
37399a2dd95SBruce Richardson 
37499a2dd95SBruce Richardson /*
37599a2dd95SBruce Richardson  * Macro to iterate over all valid ports for internal usage.
37699a2dd95SBruce Richardson  * Note: RTE_ETH_FOREACH_DEV is different because filtering owned ports.
37799a2dd95SBruce Richardson  */
37899a2dd95SBruce Richardson #define RTE_ETH_FOREACH_VALID_DEV(port_id) \
37999a2dd95SBruce Richardson 	for (port_id = rte_eth_find_next(0); \
38099a2dd95SBruce Richardson 	     port_id < RTE_MAX_ETHPORTS; \
38199a2dd95SBruce Richardson 	     port_id = rte_eth_find_next(port_id + 1))
38299a2dd95SBruce Richardson 
38399a2dd95SBruce Richardson uint16_t
38499a2dd95SBruce Richardson rte_eth_find_next_of(uint16_t port_id, const struct rte_device *parent)
38599a2dd95SBruce Richardson {
38699a2dd95SBruce Richardson 	port_id = rte_eth_find_next(port_id);
38799a2dd95SBruce Richardson 	while (port_id < RTE_MAX_ETHPORTS &&
38899a2dd95SBruce Richardson 			rte_eth_devices[port_id].device != parent)
38999a2dd95SBruce Richardson 		port_id = rte_eth_find_next(port_id + 1);
39099a2dd95SBruce Richardson 
39199a2dd95SBruce Richardson 	return port_id;
39299a2dd95SBruce Richardson }
39399a2dd95SBruce Richardson 
39499a2dd95SBruce Richardson uint16_t
39599a2dd95SBruce Richardson rte_eth_find_next_sibling(uint16_t port_id, uint16_t ref_port_id)
39699a2dd95SBruce Richardson {
39799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(ref_port_id, RTE_MAX_ETHPORTS);
39899a2dd95SBruce Richardson 	return rte_eth_find_next_of(port_id,
39999a2dd95SBruce Richardson 			rte_eth_devices[ref_port_id].device);
40099a2dd95SBruce Richardson }
40199a2dd95SBruce Richardson 
40299a2dd95SBruce Richardson static void
40399a2dd95SBruce Richardson eth_dev_shared_data_prepare(void)
40499a2dd95SBruce Richardson {
40599a2dd95SBruce Richardson 	const unsigned flags = 0;
40699a2dd95SBruce Richardson 	const struct rte_memzone *mz;
40799a2dd95SBruce Richardson 
40899a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_shared_data_lock);
40999a2dd95SBruce Richardson 
41099a2dd95SBruce Richardson 	if (eth_dev_shared_data == NULL) {
41199a2dd95SBruce Richardson 		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
41299a2dd95SBruce Richardson 			/* Allocate port data and ownership shared memory. */
41399a2dd95SBruce Richardson 			mz = rte_memzone_reserve(MZ_RTE_ETH_DEV_DATA,
41499a2dd95SBruce Richardson 					sizeof(*eth_dev_shared_data),
41599a2dd95SBruce Richardson 					rte_socket_id(), flags);
41699a2dd95SBruce Richardson 		} else
41799a2dd95SBruce Richardson 			mz = rte_memzone_lookup(MZ_RTE_ETH_DEV_DATA);
41899a2dd95SBruce Richardson 		if (mz == NULL)
41999a2dd95SBruce Richardson 			rte_panic("Cannot allocate ethdev shared data\n");
42099a2dd95SBruce Richardson 
42199a2dd95SBruce Richardson 		eth_dev_shared_data = mz->addr;
42299a2dd95SBruce Richardson 		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
42399a2dd95SBruce Richardson 			eth_dev_shared_data->next_owner_id =
42499a2dd95SBruce Richardson 					RTE_ETH_DEV_NO_OWNER + 1;
42599a2dd95SBruce Richardson 			rte_spinlock_init(&eth_dev_shared_data->ownership_lock);
42699a2dd95SBruce Richardson 			memset(eth_dev_shared_data->data, 0,
42799a2dd95SBruce Richardson 			       sizeof(eth_dev_shared_data->data));
42899a2dd95SBruce Richardson 		}
42999a2dd95SBruce Richardson 	}
43099a2dd95SBruce Richardson 
43199a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_shared_data_lock);
43299a2dd95SBruce Richardson }
43399a2dd95SBruce Richardson 
43499a2dd95SBruce Richardson static bool
43599a2dd95SBruce Richardson eth_dev_is_allocated(const struct rte_eth_dev *ethdev)
43699a2dd95SBruce Richardson {
43799a2dd95SBruce Richardson 	return ethdev->data->name[0] != '\0';
43899a2dd95SBruce Richardson }
43999a2dd95SBruce Richardson 
44099a2dd95SBruce Richardson static struct rte_eth_dev *
44199a2dd95SBruce Richardson eth_dev_allocated(const char *name)
44299a2dd95SBruce Richardson {
44399a2dd95SBruce Richardson 	uint16_t i;
44499a2dd95SBruce Richardson 
44599a2dd95SBruce Richardson 	RTE_BUILD_BUG_ON(RTE_MAX_ETHPORTS >= UINT16_MAX);
44699a2dd95SBruce Richardson 
44799a2dd95SBruce Richardson 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
44899a2dd95SBruce Richardson 		if (rte_eth_devices[i].data != NULL &&
44999a2dd95SBruce Richardson 		    strcmp(rte_eth_devices[i].data->name, name) == 0)
45099a2dd95SBruce Richardson 			return &rte_eth_devices[i];
45199a2dd95SBruce Richardson 	}
45299a2dd95SBruce Richardson 	return NULL;
45399a2dd95SBruce Richardson }
45499a2dd95SBruce Richardson 
45599a2dd95SBruce Richardson struct rte_eth_dev *
45699a2dd95SBruce Richardson rte_eth_dev_allocated(const char *name)
45799a2dd95SBruce Richardson {
45899a2dd95SBruce Richardson 	struct rte_eth_dev *ethdev;
45999a2dd95SBruce Richardson 
46099a2dd95SBruce Richardson 	eth_dev_shared_data_prepare();
46199a2dd95SBruce Richardson 
46299a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
46399a2dd95SBruce Richardson 
46499a2dd95SBruce Richardson 	ethdev = eth_dev_allocated(name);
46599a2dd95SBruce Richardson 
46699a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
46799a2dd95SBruce Richardson 
46899a2dd95SBruce Richardson 	return ethdev;
46999a2dd95SBruce Richardson }
47099a2dd95SBruce Richardson 
47199a2dd95SBruce Richardson static uint16_t
47299a2dd95SBruce Richardson eth_dev_find_free_port(void)
47399a2dd95SBruce Richardson {
47499a2dd95SBruce Richardson 	uint16_t i;
47599a2dd95SBruce Richardson 
47699a2dd95SBruce Richardson 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
47799a2dd95SBruce Richardson 		/* Using shared name field to find a free port. */
47899a2dd95SBruce Richardson 		if (eth_dev_shared_data->data[i].name[0] == '\0') {
47999a2dd95SBruce Richardson 			RTE_ASSERT(rte_eth_devices[i].state ==
48099a2dd95SBruce Richardson 				   RTE_ETH_DEV_UNUSED);
48199a2dd95SBruce Richardson 			return i;
48299a2dd95SBruce Richardson 		}
48399a2dd95SBruce Richardson 	}
48499a2dd95SBruce Richardson 	return RTE_MAX_ETHPORTS;
48599a2dd95SBruce Richardson }
48699a2dd95SBruce Richardson 
48799a2dd95SBruce Richardson static struct rte_eth_dev *
48899a2dd95SBruce Richardson eth_dev_get(uint16_t port_id)
48999a2dd95SBruce Richardson {
49099a2dd95SBruce Richardson 	struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id];
49199a2dd95SBruce Richardson 
49299a2dd95SBruce Richardson 	eth_dev->data = &eth_dev_shared_data->data[port_id];
49399a2dd95SBruce Richardson 
49499a2dd95SBruce Richardson 	return eth_dev;
49599a2dd95SBruce Richardson }
49699a2dd95SBruce Richardson 
49799a2dd95SBruce Richardson struct rte_eth_dev *
49899a2dd95SBruce Richardson rte_eth_dev_allocate(const char *name)
49999a2dd95SBruce Richardson {
50099a2dd95SBruce Richardson 	uint16_t port_id;
50199a2dd95SBruce Richardson 	struct rte_eth_dev *eth_dev = NULL;
50299a2dd95SBruce Richardson 	size_t name_len;
50399a2dd95SBruce Richardson 
50499a2dd95SBruce Richardson 	name_len = strnlen(name, RTE_ETH_NAME_MAX_LEN);
50599a2dd95SBruce Richardson 	if (name_len == 0) {
50699a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Zero length Ethernet device name\n");
50799a2dd95SBruce Richardson 		return NULL;
50899a2dd95SBruce Richardson 	}
50999a2dd95SBruce Richardson 
51099a2dd95SBruce Richardson 	if (name_len >= RTE_ETH_NAME_MAX_LEN) {
51199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Ethernet device name is too long\n");
51299a2dd95SBruce Richardson 		return NULL;
51399a2dd95SBruce Richardson 	}
51499a2dd95SBruce Richardson 
51599a2dd95SBruce Richardson 	eth_dev_shared_data_prepare();
51699a2dd95SBruce Richardson 
51799a2dd95SBruce Richardson 	/* Synchronize port creation between primary and secondary threads. */
51899a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
51999a2dd95SBruce Richardson 
52099a2dd95SBruce Richardson 	if (eth_dev_allocated(name) != NULL) {
52199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
52299a2dd95SBruce Richardson 			"Ethernet device with name %s already allocated\n",
52399a2dd95SBruce Richardson 			name);
52499a2dd95SBruce Richardson 		goto unlock;
52599a2dd95SBruce Richardson 	}
52699a2dd95SBruce Richardson 
52799a2dd95SBruce Richardson 	port_id = eth_dev_find_free_port();
52899a2dd95SBruce Richardson 	if (port_id == RTE_MAX_ETHPORTS) {
52999a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
53099a2dd95SBruce Richardson 			"Reached maximum number of Ethernet ports\n");
53199a2dd95SBruce Richardson 		goto unlock;
53299a2dd95SBruce Richardson 	}
53399a2dd95SBruce Richardson 
53499a2dd95SBruce Richardson 	eth_dev = eth_dev_get(port_id);
53599a2dd95SBruce Richardson 	strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name));
53699a2dd95SBruce Richardson 	eth_dev->data->port_id = port_id;
537ff4e52efSViacheslav Galaktionov 	eth_dev->data->backer_port_id = RTE_MAX_ETHPORTS;
53899a2dd95SBruce Richardson 	eth_dev->data->mtu = RTE_ETHER_MTU;
53999a2dd95SBruce Richardson 	pthread_mutex_init(&eth_dev->data->flow_ops_mutex, NULL);
54099a2dd95SBruce Richardson 
54199a2dd95SBruce Richardson unlock:
54299a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
54399a2dd95SBruce Richardson 
54499a2dd95SBruce Richardson 	return eth_dev;
54599a2dd95SBruce Richardson }
54699a2dd95SBruce Richardson 
54799a2dd95SBruce Richardson /*
54899a2dd95SBruce Richardson  * Attach to a port already registered by the primary process, which
5495906be5aSAndrew Rybchenko  * makes sure that the same device would have the same port ID both
55099a2dd95SBruce Richardson  * in the primary and secondary process.
55199a2dd95SBruce Richardson  */
55299a2dd95SBruce Richardson struct rte_eth_dev *
55399a2dd95SBruce Richardson rte_eth_dev_attach_secondary(const char *name)
55499a2dd95SBruce Richardson {
55599a2dd95SBruce Richardson 	uint16_t i;
55699a2dd95SBruce Richardson 	struct rte_eth_dev *eth_dev = NULL;
55799a2dd95SBruce Richardson 
55899a2dd95SBruce Richardson 	eth_dev_shared_data_prepare();
55999a2dd95SBruce Richardson 
56099a2dd95SBruce Richardson 	/* Synchronize port attachment to primary port creation and release. */
56199a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
56299a2dd95SBruce Richardson 
56399a2dd95SBruce Richardson 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
56499a2dd95SBruce Richardson 		if (strcmp(eth_dev_shared_data->data[i].name, name) == 0)
56599a2dd95SBruce Richardson 			break;
56699a2dd95SBruce Richardson 	}
56799a2dd95SBruce Richardson 	if (i == RTE_MAX_ETHPORTS) {
56899a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
56999a2dd95SBruce Richardson 			"Device %s is not driven by the primary process\n",
57099a2dd95SBruce Richardson 			name);
57199a2dd95SBruce Richardson 	} else {
57299a2dd95SBruce Richardson 		eth_dev = eth_dev_get(i);
57399a2dd95SBruce Richardson 		RTE_ASSERT(eth_dev->data->port_id == i);
57499a2dd95SBruce Richardson 	}
57599a2dd95SBruce Richardson 
57699a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
57799a2dd95SBruce Richardson 	return eth_dev;
57899a2dd95SBruce Richardson }
57999a2dd95SBruce Richardson 
58099a2dd95SBruce Richardson int
58199a2dd95SBruce Richardson rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
58299a2dd95SBruce Richardson {
58399a2dd95SBruce Richardson 	if (eth_dev == NULL)
58499a2dd95SBruce Richardson 		return -EINVAL;
58599a2dd95SBruce Richardson 
58699a2dd95SBruce Richardson 	eth_dev_shared_data_prepare();
58799a2dd95SBruce Richardson 
58899a2dd95SBruce Richardson 	if (eth_dev->state != RTE_ETH_DEV_UNUSED)
58999a2dd95SBruce Richardson 		rte_eth_dev_callback_process(eth_dev,
59099a2dd95SBruce Richardson 				RTE_ETH_EVENT_DESTROY, NULL);
59199a2dd95SBruce Richardson 
592c87d435aSKonstantin Ananyev 	eth_dev_fp_ops_reset(rte_eth_fp_ops + eth_dev->data->port_id);
593c87d435aSKonstantin Ananyev 
59499a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
59599a2dd95SBruce Richardson 
59699a2dd95SBruce Richardson 	eth_dev->state = RTE_ETH_DEV_UNUSED;
59799a2dd95SBruce Richardson 	eth_dev->device = NULL;
59899a2dd95SBruce Richardson 	eth_dev->process_private = NULL;
59999a2dd95SBruce Richardson 	eth_dev->intr_handle = NULL;
60099a2dd95SBruce Richardson 	eth_dev->rx_pkt_burst = NULL;
60199a2dd95SBruce Richardson 	eth_dev->tx_pkt_burst = NULL;
60299a2dd95SBruce Richardson 	eth_dev->tx_pkt_prepare = NULL;
60399a2dd95SBruce Richardson 	eth_dev->rx_queue_count = NULL;
60499a2dd95SBruce Richardson 	eth_dev->rx_descriptor_status = NULL;
60599a2dd95SBruce Richardson 	eth_dev->tx_descriptor_status = NULL;
60699a2dd95SBruce Richardson 	eth_dev->dev_ops = NULL;
60799a2dd95SBruce Richardson 
60899a2dd95SBruce Richardson 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
60999a2dd95SBruce Richardson 		rte_free(eth_dev->data->rx_queues);
61099a2dd95SBruce Richardson 		rte_free(eth_dev->data->tx_queues);
61199a2dd95SBruce Richardson 		rte_free(eth_dev->data->mac_addrs);
61299a2dd95SBruce Richardson 		rte_free(eth_dev->data->hash_mac_addrs);
61399a2dd95SBruce Richardson 		rte_free(eth_dev->data->dev_private);
61499a2dd95SBruce Richardson 		pthread_mutex_destroy(&eth_dev->data->flow_ops_mutex);
61599a2dd95SBruce Richardson 		memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data));
61699a2dd95SBruce Richardson 	}
61799a2dd95SBruce Richardson 
61899a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
61999a2dd95SBruce Richardson 
62099a2dd95SBruce Richardson 	return 0;
62199a2dd95SBruce Richardson }
62299a2dd95SBruce Richardson 
62399a2dd95SBruce Richardson int
62499a2dd95SBruce Richardson rte_eth_dev_is_valid_port(uint16_t port_id)
62599a2dd95SBruce Richardson {
62699a2dd95SBruce Richardson 	if (port_id >= RTE_MAX_ETHPORTS ||
62799a2dd95SBruce Richardson 	    (rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED))
62899a2dd95SBruce Richardson 		return 0;
62999a2dd95SBruce Richardson 	else
63099a2dd95SBruce Richardson 		return 1;
63199a2dd95SBruce Richardson }
63299a2dd95SBruce Richardson 
63399a2dd95SBruce Richardson static int
63499a2dd95SBruce Richardson eth_is_valid_owner_id(uint64_t owner_id)
63599a2dd95SBruce Richardson {
63699a2dd95SBruce Richardson 	if (owner_id == RTE_ETH_DEV_NO_OWNER ||
63799a2dd95SBruce Richardson 	    eth_dev_shared_data->next_owner_id <= owner_id)
63899a2dd95SBruce Richardson 		return 0;
63999a2dd95SBruce Richardson 	return 1;
64099a2dd95SBruce Richardson }
64199a2dd95SBruce Richardson 
64299a2dd95SBruce Richardson uint64_t
64399a2dd95SBruce Richardson rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
64499a2dd95SBruce Richardson {
64599a2dd95SBruce Richardson 	port_id = rte_eth_find_next(port_id);
64699a2dd95SBruce Richardson 	while (port_id < RTE_MAX_ETHPORTS &&
64799a2dd95SBruce Richardson 			rte_eth_devices[port_id].data->owner.id != owner_id)
64899a2dd95SBruce Richardson 		port_id = rte_eth_find_next(port_id + 1);
64999a2dd95SBruce Richardson 
65099a2dd95SBruce Richardson 	return port_id;
65199a2dd95SBruce Richardson }
65299a2dd95SBruce Richardson 
65399a2dd95SBruce Richardson int
65499a2dd95SBruce Richardson rte_eth_dev_owner_new(uint64_t *owner_id)
65599a2dd95SBruce Richardson {
65653ef1b34SMin Hu (Connor) 	if (owner_id == NULL) {
65753ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot get new owner ID to NULL\n");
65853ef1b34SMin Hu (Connor) 		return -EINVAL;
65953ef1b34SMin Hu (Connor) 	}
66053ef1b34SMin Hu (Connor) 
66199a2dd95SBruce Richardson 	eth_dev_shared_data_prepare();
66299a2dd95SBruce Richardson 
66399a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
66499a2dd95SBruce Richardson 
66599a2dd95SBruce Richardson 	*owner_id = eth_dev_shared_data->next_owner_id++;
66699a2dd95SBruce Richardson 
66799a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
66899a2dd95SBruce Richardson 	return 0;
66999a2dd95SBruce Richardson }
67099a2dd95SBruce Richardson 
67199a2dd95SBruce Richardson static int
67299a2dd95SBruce Richardson eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
67399a2dd95SBruce Richardson 		       const struct rte_eth_dev_owner *new_owner)
67499a2dd95SBruce Richardson {
67599a2dd95SBruce Richardson 	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
67699a2dd95SBruce Richardson 	struct rte_eth_dev_owner *port_owner;
67799a2dd95SBruce Richardson 
67899a2dd95SBruce Richardson 	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
6795906be5aSAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Port ID %"PRIu16" is not allocated\n",
68099a2dd95SBruce Richardson 			port_id);
68199a2dd95SBruce Richardson 		return -ENODEV;
68299a2dd95SBruce Richardson 	}
68399a2dd95SBruce Richardson 
68453ef1b34SMin Hu (Connor) 	if (new_owner == NULL) {
68553ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
68653ef1b34SMin Hu (Connor) 			"Cannot set ethdev port %u owner from NULL owner\n",
68753ef1b34SMin Hu (Connor) 			port_id);
68853ef1b34SMin Hu (Connor) 		return -EINVAL;
68953ef1b34SMin Hu (Connor) 	}
69053ef1b34SMin Hu (Connor) 
69199a2dd95SBruce Richardson 	if (!eth_is_valid_owner_id(new_owner->id) &&
69299a2dd95SBruce Richardson 	    !eth_is_valid_owner_id(old_owner_id)) {
69399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
69499a2dd95SBruce Richardson 			"Invalid owner old_id=%016"PRIx64" new_id=%016"PRIx64"\n",
69599a2dd95SBruce Richardson 		       old_owner_id, new_owner->id);
69699a2dd95SBruce Richardson 		return -EINVAL;
69799a2dd95SBruce Richardson 	}
69899a2dd95SBruce Richardson 
69999a2dd95SBruce Richardson 	port_owner = &rte_eth_devices[port_id].data->owner;
70099a2dd95SBruce Richardson 	if (port_owner->id != old_owner_id) {
70199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
70299a2dd95SBruce Richardson 			"Cannot set owner to port %u already owned by %s_%016"PRIX64"\n",
70399a2dd95SBruce Richardson 			port_id, port_owner->name, port_owner->id);
70499a2dd95SBruce Richardson 		return -EPERM;
70599a2dd95SBruce Richardson 	}
70699a2dd95SBruce Richardson 
70799a2dd95SBruce Richardson 	/* can not truncate (same structure) */
70899a2dd95SBruce Richardson 	strlcpy(port_owner->name, new_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN);
70999a2dd95SBruce Richardson 
71099a2dd95SBruce Richardson 	port_owner->id = new_owner->id;
71199a2dd95SBruce Richardson 
71299a2dd95SBruce Richardson 	RTE_ETHDEV_LOG(DEBUG, "Port %u owner is %s_%016"PRIx64"\n",
71399a2dd95SBruce Richardson 		port_id, new_owner->name, new_owner->id);
71499a2dd95SBruce Richardson 
71599a2dd95SBruce Richardson 	return 0;
71699a2dd95SBruce Richardson }
71799a2dd95SBruce Richardson 
71899a2dd95SBruce Richardson int
71999a2dd95SBruce Richardson rte_eth_dev_owner_set(const uint16_t port_id,
72099a2dd95SBruce Richardson 		      const struct rte_eth_dev_owner *owner)
72199a2dd95SBruce Richardson {
72299a2dd95SBruce Richardson 	int ret;
72399a2dd95SBruce Richardson 
72499a2dd95SBruce Richardson 	eth_dev_shared_data_prepare();
72599a2dd95SBruce Richardson 
72699a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
72799a2dd95SBruce Richardson 
72899a2dd95SBruce Richardson 	ret = eth_dev_owner_set(port_id, RTE_ETH_DEV_NO_OWNER, owner);
72999a2dd95SBruce Richardson 
73099a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
73199a2dd95SBruce Richardson 	return ret;
73299a2dd95SBruce Richardson }
73399a2dd95SBruce Richardson 
73499a2dd95SBruce Richardson int
73599a2dd95SBruce Richardson rte_eth_dev_owner_unset(const uint16_t port_id, const uint64_t owner_id)
73699a2dd95SBruce Richardson {
73799a2dd95SBruce Richardson 	const struct rte_eth_dev_owner new_owner = (struct rte_eth_dev_owner)
73899a2dd95SBruce Richardson 			{.id = RTE_ETH_DEV_NO_OWNER, .name = ""};
73999a2dd95SBruce Richardson 	int ret;
74099a2dd95SBruce Richardson 
74199a2dd95SBruce Richardson 	eth_dev_shared_data_prepare();
74299a2dd95SBruce Richardson 
74399a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
74499a2dd95SBruce Richardson 
74599a2dd95SBruce Richardson 	ret = eth_dev_owner_set(port_id, owner_id, &new_owner);
74699a2dd95SBruce Richardson 
74799a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
74899a2dd95SBruce Richardson 	return ret;
74999a2dd95SBruce Richardson }
75099a2dd95SBruce Richardson 
75199a2dd95SBruce Richardson int
75299a2dd95SBruce Richardson rte_eth_dev_owner_delete(const uint64_t owner_id)
75399a2dd95SBruce Richardson {
75499a2dd95SBruce Richardson 	uint16_t port_id;
75599a2dd95SBruce Richardson 	int ret = 0;
75699a2dd95SBruce Richardson 
75799a2dd95SBruce Richardson 	eth_dev_shared_data_prepare();
75899a2dd95SBruce Richardson 
75999a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
76099a2dd95SBruce Richardson 
76199a2dd95SBruce Richardson 	if (eth_is_valid_owner_id(owner_id)) {
762b7ade5d3SFerruh Yigit 		for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
763b7ade5d3SFerruh Yigit 			struct rte_eth_dev_data *data =
764b7ade5d3SFerruh Yigit 				rte_eth_devices[port_id].data;
765b7ade5d3SFerruh Yigit 			if (data != NULL && data->owner.id == owner_id)
766b7ade5d3SFerruh Yigit 				memset(&data->owner, 0,
76799a2dd95SBruce Richardson 				       sizeof(struct rte_eth_dev_owner));
768b7ade5d3SFerruh Yigit 		}
76999a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(NOTICE,
77099a2dd95SBruce Richardson 			"All port owners owned by %016"PRIx64" identifier have removed\n",
77199a2dd95SBruce Richardson 			owner_id);
77299a2dd95SBruce Richardson 	} else {
77399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
7745906be5aSAndrew Rybchenko 			       "Invalid owner ID=%016"PRIx64"\n",
77599a2dd95SBruce Richardson 			       owner_id);
77699a2dd95SBruce Richardson 		ret = -EINVAL;
77799a2dd95SBruce Richardson 	}
77899a2dd95SBruce Richardson 
77999a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
78099a2dd95SBruce Richardson 
78199a2dd95SBruce Richardson 	return ret;
78299a2dd95SBruce Richardson }
78399a2dd95SBruce Richardson 
78499a2dd95SBruce Richardson int
78599a2dd95SBruce Richardson rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
78699a2dd95SBruce Richardson {
78753ef1b34SMin Hu (Connor) 	struct rte_eth_dev *ethdev;
78853ef1b34SMin Hu (Connor) 
78953ef1b34SMin Hu (Connor) 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
79053ef1b34SMin Hu (Connor) 	ethdev = &rte_eth_devices[port_id];
79153ef1b34SMin Hu (Connor) 
79253ef1b34SMin Hu (Connor) 	if (!eth_dev_is_allocated(ethdev)) {
7935906be5aSAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Port ID %"PRIu16" is not allocated\n",
79453ef1b34SMin Hu (Connor) 			port_id);
79553ef1b34SMin Hu (Connor) 		return -ENODEV;
79653ef1b34SMin Hu (Connor) 	}
79753ef1b34SMin Hu (Connor) 
79853ef1b34SMin Hu (Connor) 	if (owner == NULL) {
79953ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u owner to NULL\n",
80053ef1b34SMin Hu (Connor) 			port_id);
80153ef1b34SMin Hu (Connor) 		return -EINVAL;
80253ef1b34SMin Hu (Connor) 	}
80399a2dd95SBruce Richardson 
80499a2dd95SBruce Richardson 	eth_dev_shared_data_prepare();
80599a2dd95SBruce Richardson 
80699a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
80799a2dd95SBruce Richardson 	rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
80899a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
80953ef1b34SMin Hu (Connor) 
81053ef1b34SMin Hu (Connor) 	return 0;
81199a2dd95SBruce Richardson }
81299a2dd95SBruce Richardson 
81399a2dd95SBruce Richardson int
81499a2dd95SBruce Richardson rte_eth_dev_socket_id(uint16_t port_id)
81599a2dd95SBruce Richardson {
81699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
81799a2dd95SBruce Richardson 	return rte_eth_devices[port_id].data->numa_node;
81899a2dd95SBruce Richardson }
81999a2dd95SBruce Richardson 
82099a2dd95SBruce Richardson void *
82199a2dd95SBruce Richardson rte_eth_dev_get_sec_ctx(uint16_t port_id)
82299a2dd95SBruce Richardson {
82399a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
82499a2dd95SBruce Richardson 	return rte_eth_devices[port_id].security_ctx;
82599a2dd95SBruce Richardson }
82699a2dd95SBruce Richardson 
82799a2dd95SBruce Richardson uint16_t
82899a2dd95SBruce Richardson rte_eth_dev_count_avail(void)
82999a2dd95SBruce Richardson {
83099a2dd95SBruce Richardson 	uint16_t p;
83199a2dd95SBruce Richardson 	uint16_t count;
83299a2dd95SBruce Richardson 
83399a2dd95SBruce Richardson 	count = 0;
83499a2dd95SBruce Richardson 
83599a2dd95SBruce Richardson 	RTE_ETH_FOREACH_DEV(p)
83699a2dd95SBruce Richardson 		count++;
83799a2dd95SBruce Richardson 
83899a2dd95SBruce Richardson 	return count;
83999a2dd95SBruce Richardson }
84099a2dd95SBruce Richardson 
84199a2dd95SBruce Richardson uint16_t
84299a2dd95SBruce Richardson rte_eth_dev_count_total(void)
84399a2dd95SBruce Richardson {
84499a2dd95SBruce Richardson 	uint16_t port, count = 0;
84599a2dd95SBruce Richardson 
84699a2dd95SBruce Richardson 	RTE_ETH_FOREACH_VALID_DEV(port)
84799a2dd95SBruce Richardson 		count++;
84899a2dd95SBruce Richardson 
84999a2dd95SBruce Richardson 	return count;
85099a2dd95SBruce Richardson }
85199a2dd95SBruce Richardson 
85299a2dd95SBruce Richardson int
85399a2dd95SBruce Richardson rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
85499a2dd95SBruce Richardson {
85599a2dd95SBruce Richardson 	char *tmp;
85699a2dd95SBruce Richardson 
85799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
85899a2dd95SBruce Richardson 
85999a2dd95SBruce Richardson 	if (name == NULL) {
86053ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u name to NULL\n",
86153ef1b34SMin Hu (Connor) 			port_id);
86299a2dd95SBruce Richardson 		return -EINVAL;
86399a2dd95SBruce Richardson 	}
86499a2dd95SBruce Richardson 
86599a2dd95SBruce Richardson 	/* shouldn't check 'rte_eth_devices[i].data',
86699a2dd95SBruce Richardson 	 * because it might be overwritten by VDEV PMD */
86799a2dd95SBruce Richardson 	tmp = eth_dev_shared_data->data[port_id].name;
86899a2dd95SBruce Richardson 	strcpy(name, tmp);
86999a2dd95SBruce Richardson 	return 0;
87099a2dd95SBruce Richardson }
87199a2dd95SBruce Richardson 
87299a2dd95SBruce Richardson int
87399a2dd95SBruce Richardson rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
87499a2dd95SBruce Richardson {
87599a2dd95SBruce Richardson 	uint16_t pid;
87699a2dd95SBruce Richardson 
87799a2dd95SBruce Richardson 	if (name == NULL) {
87853ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name");
87953ef1b34SMin Hu (Connor) 		return -EINVAL;
88053ef1b34SMin Hu (Connor) 	}
88153ef1b34SMin Hu (Connor) 
88253ef1b34SMin Hu (Connor) 	if (port_id == NULL) {
88353ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
88453ef1b34SMin Hu (Connor) 			"Cannot get port ID to NULL for %s\n", name);
88599a2dd95SBruce Richardson 		return -EINVAL;
88699a2dd95SBruce Richardson 	}
88799a2dd95SBruce Richardson 
88899a2dd95SBruce Richardson 	RTE_ETH_FOREACH_VALID_DEV(pid)
88999a2dd95SBruce Richardson 		if (!strcmp(name, eth_dev_shared_data->data[pid].name)) {
89099a2dd95SBruce Richardson 			*port_id = pid;
89199a2dd95SBruce Richardson 			return 0;
89299a2dd95SBruce Richardson 		}
89399a2dd95SBruce Richardson 
89499a2dd95SBruce Richardson 	return -ENODEV;
89599a2dd95SBruce Richardson }
89699a2dd95SBruce Richardson 
89799a2dd95SBruce Richardson static int
89899a2dd95SBruce Richardson eth_err(uint16_t port_id, int ret)
89999a2dd95SBruce Richardson {
90099a2dd95SBruce Richardson 	if (ret == 0)
90199a2dd95SBruce Richardson 		return 0;
90299a2dd95SBruce Richardson 	if (rte_eth_dev_is_removed(port_id))
90399a2dd95SBruce Richardson 		return -EIO;
90499a2dd95SBruce Richardson 	return ret;
90599a2dd95SBruce Richardson }
90699a2dd95SBruce Richardson 
90749ed3224SXueming Li static void
90849ed3224SXueming Li eth_dev_rxq_release(struct rte_eth_dev *dev, uint16_t qid)
90949ed3224SXueming Li {
91049ed3224SXueming Li 	void **rxq = dev->data->rx_queues;
91149ed3224SXueming Li 
91249ed3224SXueming Li 	if (rxq[qid] == NULL)
91349ed3224SXueming Li 		return;
91449ed3224SXueming Li 
91549ed3224SXueming Li 	if (dev->dev_ops->rx_queue_release != NULL)
9167483341aSXueming Li 		(*dev->dev_ops->rx_queue_release)(dev, qid);
91749ed3224SXueming Li 	rxq[qid] = NULL;
91849ed3224SXueming Li }
91949ed3224SXueming Li 
92049ed3224SXueming Li static void
92149ed3224SXueming Li eth_dev_txq_release(struct rte_eth_dev *dev, uint16_t qid)
92249ed3224SXueming Li {
92349ed3224SXueming Li 	void **txq = dev->data->tx_queues;
92449ed3224SXueming Li 
92549ed3224SXueming Li 	if (txq[qid] == NULL)
92649ed3224SXueming Li 		return;
92749ed3224SXueming Li 
92849ed3224SXueming Li 	if (dev->dev_ops->tx_queue_release != NULL)
9297483341aSXueming Li 		(*dev->dev_ops->tx_queue_release)(dev, qid);
93049ed3224SXueming Li 	txq[qid] = NULL;
93149ed3224SXueming Li }
93249ed3224SXueming Li 
93399a2dd95SBruce Richardson static int
93499a2dd95SBruce Richardson eth_dev_rx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
93599a2dd95SBruce Richardson {
93699a2dd95SBruce Richardson 	uint16_t old_nb_queues = dev->data->nb_rx_queues;
93799a2dd95SBruce Richardson 	unsigned i;
93899a2dd95SBruce Richardson 
93999a2dd95SBruce Richardson 	if (dev->data->rx_queues == NULL && nb_queues != 0) { /* first time configuration */
94099a2dd95SBruce Richardson 		dev->data->rx_queues = rte_zmalloc("ethdev->rx_queues",
941c024496aSKonstantin Ananyev 				sizeof(dev->data->rx_queues[0]) *
942c024496aSKonstantin Ananyev 				RTE_MAX_QUEUES_PER_PORT,
94399a2dd95SBruce Richardson 				RTE_CACHE_LINE_SIZE);
94499a2dd95SBruce Richardson 		if (dev->data->rx_queues == NULL) {
94599a2dd95SBruce Richardson 			dev->data->nb_rx_queues = 0;
94699a2dd95SBruce Richardson 			return -(ENOMEM);
94799a2dd95SBruce Richardson 		}
94899a2dd95SBruce Richardson 	} else if (dev->data->rx_queues != NULL && nb_queues != 0) { /* re-configure */
94949ed3224SXueming Li 		for (i = nb_queues; i < old_nb_queues; i++)
95049ed3224SXueming Li 			eth_dev_rxq_release(dev, i);
95199a2dd95SBruce Richardson 
95299a2dd95SBruce Richardson 	} else if (dev->data->rx_queues != NULL && nb_queues == 0) {
95399a2dd95SBruce Richardson 		for (i = nb_queues; i < old_nb_queues; i++)
95449ed3224SXueming Li 			eth_dev_rxq_release(dev, i);
95599a2dd95SBruce Richardson 
95699a2dd95SBruce Richardson 		rte_free(dev->data->rx_queues);
95799a2dd95SBruce Richardson 		dev->data->rx_queues = NULL;
95899a2dd95SBruce Richardson 	}
95999a2dd95SBruce Richardson 	dev->data->nb_rx_queues = nb_queues;
96099a2dd95SBruce Richardson 	return 0;
96199a2dd95SBruce Richardson }
96299a2dd95SBruce Richardson 
96399a2dd95SBruce Richardson static int
96499a2dd95SBruce Richardson eth_dev_validate_rx_queue(const struct rte_eth_dev *dev, uint16_t rx_queue_id)
96599a2dd95SBruce Richardson {
96699a2dd95SBruce Richardson 	uint16_t port_id;
96799a2dd95SBruce Richardson 
96899a2dd95SBruce Richardson 	if (rx_queue_id >= dev->data->nb_rx_queues) {
96999a2dd95SBruce Richardson 		port_id = dev->data->port_id;
97099a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
97199a2dd95SBruce Richardson 			       "Invalid Rx queue_id=%u of device with port_id=%u\n",
97299a2dd95SBruce Richardson 			       rx_queue_id, port_id);
97399a2dd95SBruce Richardson 		return -EINVAL;
97499a2dd95SBruce Richardson 	}
97599a2dd95SBruce Richardson 
97699a2dd95SBruce Richardson 	if (dev->data->rx_queues[rx_queue_id] == NULL) {
97799a2dd95SBruce Richardson 		port_id = dev->data->port_id;
97899a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
97999a2dd95SBruce Richardson 			       "Queue %u of device with port_id=%u has not been setup\n",
98099a2dd95SBruce Richardson 			       rx_queue_id, port_id);
98199a2dd95SBruce Richardson 		return -EINVAL;
98299a2dd95SBruce Richardson 	}
98399a2dd95SBruce Richardson 
98499a2dd95SBruce Richardson 	return 0;
98599a2dd95SBruce Richardson }
98699a2dd95SBruce Richardson 
98799a2dd95SBruce Richardson static int
98899a2dd95SBruce Richardson eth_dev_validate_tx_queue(const struct rte_eth_dev *dev, uint16_t tx_queue_id)
98999a2dd95SBruce Richardson {
99099a2dd95SBruce Richardson 	uint16_t port_id;
99199a2dd95SBruce Richardson 
99299a2dd95SBruce Richardson 	if (tx_queue_id >= dev->data->nb_tx_queues) {
99399a2dd95SBruce Richardson 		port_id = dev->data->port_id;
99499a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
99599a2dd95SBruce Richardson 			       "Invalid Tx queue_id=%u of device with port_id=%u\n",
99699a2dd95SBruce Richardson 			       tx_queue_id, port_id);
99799a2dd95SBruce Richardson 		return -EINVAL;
99899a2dd95SBruce Richardson 	}
99999a2dd95SBruce Richardson 
100099a2dd95SBruce Richardson 	if (dev->data->tx_queues[tx_queue_id] == NULL) {
100199a2dd95SBruce Richardson 		port_id = dev->data->port_id;
100299a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
100399a2dd95SBruce Richardson 			       "Queue %u of device with port_id=%u has not been setup\n",
100499a2dd95SBruce Richardson 			       tx_queue_id, port_id);
100599a2dd95SBruce Richardson 		return -EINVAL;
100699a2dd95SBruce Richardson 	}
100799a2dd95SBruce Richardson 
100899a2dd95SBruce Richardson 	return 0;
100999a2dd95SBruce Richardson }
101099a2dd95SBruce Richardson 
101199a2dd95SBruce Richardson int
101299a2dd95SBruce Richardson rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id)
101399a2dd95SBruce Richardson {
101499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
101599a2dd95SBruce Richardson 	int ret;
101699a2dd95SBruce Richardson 
101799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
101899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
101953ef1b34SMin Hu (Connor) 
102099a2dd95SBruce Richardson 	if (!dev->data->dev_started) {
102199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
102299a2dd95SBruce Richardson 			"Port %u must be started before start any queue\n",
102399a2dd95SBruce Richardson 			port_id);
102499a2dd95SBruce Richardson 		return -EINVAL;
102599a2dd95SBruce Richardson 	}
102699a2dd95SBruce Richardson 
102799a2dd95SBruce Richardson 	ret = eth_dev_validate_rx_queue(dev, rx_queue_id);
102899a2dd95SBruce Richardson 	if (ret != 0)
102999a2dd95SBruce Richardson 		return ret;
103099a2dd95SBruce Richardson 
103199a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_start, -ENOTSUP);
103299a2dd95SBruce Richardson 
103399a2dd95SBruce Richardson 	if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) {
103499a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
103599a2dd95SBruce Richardson 			"Can't start Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
103699a2dd95SBruce Richardson 			rx_queue_id, port_id);
103799a2dd95SBruce Richardson 		return -EINVAL;
103899a2dd95SBruce Richardson 	}
103999a2dd95SBruce Richardson 
104099a2dd95SBruce Richardson 	if (dev->data->rx_queue_state[rx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) {
104199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
104299a2dd95SBruce Richardson 			"Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n",
104399a2dd95SBruce Richardson 			rx_queue_id, port_id);
104499a2dd95SBruce Richardson 		return 0;
104599a2dd95SBruce Richardson 	}
104699a2dd95SBruce Richardson 
104753ef1b34SMin Hu (Connor) 	return eth_err(port_id, dev->dev_ops->rx_queue_start(dev, rx_queue_id));
104899a2dd95SBruce Richardson }
104999a2dd95SBruce Richardson 
105099a2dd95SBruce Richardson int
105199a2dd95SBruce Richardson rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id)
105299a2dd95SBruce Richardson {
105399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
105499a2dd95SBruce Richardson 	int ret;
105599a2dd95SBruce Richardson 
105699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
105799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
105899a2dd95SBruce Richardson 
105999a2dd95SBruce Richardson 	ret = eth_dev_validate_rx_queue(dev, rx_queue_id);
106099a2dd95SBruce Richardson 	if (ret != 0)
106199a2dd95SBruce Richardson 		return ret;
106299a2dd95SBruce Richardson 
106399a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_stop, -ENOTSUP);
106499a2dd95SBruce Richardson 
106599a2dd95SBruce Richardson 	if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) {
106699a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
106799a2dd95SBruce Richardson 			"Can't stop Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
106899a2dd95SBruce Richardson 			rx_queue_id, port_id);
106999a2dd95SBruce Richardson 		return -EINVAL;
107099a2dd95SBruce Richardson 	}
107199a2dd95SBruce Richardson 
107299a2dd95SBruce Richardson 	if (dev->data->rx_queue_state[rx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) {
107399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
107499a2dd95SBruce Richardson 			"Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n",
107599a2dd95SBruce Richardson 			rx_queue_id, port_id);
107699a2dd95SBruce Richardson 		return 0;
107799a2dd95SBruce Richardson 	}
107899a2dd95SBruce Richardson 
107999a2dd95SBruce Richardson 	return eth_err(port_id, dev->dev_ops->rx_queue_stop(dev, rx_queue_id));
108099a2dd95SBruce Richardson }
108199a2dd95SBruce Richardson 
108299a2dd95SBruce Richardson int
108399a2dd95SBruce Richardson rte_eth_dev_tx_queue_start(uint16_t port_id, uint16_t tx_queue_id)
108499a2dd95SBruce Richardson {
108599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
108699a2dd95SBruce Richardson 	int ret;
108799a2dd95SBruce Richardson 
108899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
108999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
109053ef1b34SMin Hu (Connor) 
109199a2dd95SBruce Richardson 	if (!dev->data->dev_started) {
109299a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
109399a2dd95SBruce Richardson 			"Port %u must be started before start any queue\n",
109499a2dd95SBruce Richardson 			port_id);
109599a2dd95SBruce Richardson 		return -EINVAL;
109699a2dd95SBruce Richardson 	}
109799a2dd95SBruce Richardson 
109899a2dd95SBruce Richardson 	ret = eth_dev_validate_tx_queue(dev, tx_queue_id);
109999a2dd95SBruce Richardson 	if (ret != 0)
110099a2dd95SBruce Richardson 		return ret;
110199a2dd95SBruce Richardson 
110299a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_start, -ENOTSUP);
110399a2dd95SBruce Richardson 
110499a2dd95SBruce Richardson 	if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) {
110599a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
110699a2dd95SBruce Richardson 			"Can't start Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
110799a2dd95SBruce Richardson 			tx_queue_id, port_id);
110899a2dd95SBruce Richardson 		return -EINVAL;
110999a2dd95SBruce Richardson 	}
111099a2dd95SBruce Richardson 
111199a2dd95SBruce Richardson 	if (dev->data->tx_queue_state[tx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) {
111299a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
111399a2dd95SBruce Richardson 			"Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n",
111499a2dd95SBruce Richardson 			tx_queue_id, port_id);
111599a2dd95SBruce Richardson 		return 0;
111699a2dd95SBruce Richardson 	}
111799a2dd95SBruce Richardson 
111899a2dd95SBruce Richardson 	return eth_err(port_id, dev->dev_ops->tx_queue_start(dev, tx_queue_id));
111999a2dd95SBruce Richardson }
112099a2dd95SBruce Richardson 
112199a2dd95SBruce Richardson int
112299a2dd95SBruce Richardson rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id)
112399a2dd95SBruce Richardson {
112499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
112599a2dd95SBruce Richardson 	int ret;
112699a2dd95SBruce Richardson 
112799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
112899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
112999a2dd95SBruce Richardson 
113099a2dd95SBruce Richardson 	ret = eth_dev_validate_tx_queue(dev, tx_queue_id);
113199a2dd95SBruce Richardson 	if (ret != 0)
113299a2dd95SBruce Richardson 		return ret;
113399a2dd95SBruce Richardson 
113499a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_stop, -ENOTSUP);
113599a2dd95SBruce Richardson 
113699a2dd95SBruce Richardson 	if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) {
113799a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
113899a2dd95SBruce Richardson 			"Can't stop Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
113999a2dd95SBruce Richardson 			tx_queue_id, port_id);
114099a2dd95SBruce Richardson 		return -EINVAL;
114199a2dd95SBruce Richardson 	}
114299a2dd95SBruce Richardson 
114399a2dd95SBruce Richardson 	if (dev->data->tx_queue_state[tx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) {
114499a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
114599a2dd95SBruce Richardson 			"Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n",
114699a2dd95SBruce Richardson 			tx_queue_id, port_id);
114799a2dd95SBruce Richardson 		return 0;
114899a2dd95SBruce Richardson 	}
114999a2dd95SBruce Richardson 
115099a2dd95SBruce Richardson 	return eth_err(port_id, dev->dev_ops->tx_queue_stop(dev, tx_queue_id));
115199a2dd95SBruce Richardson }
115299a2dd95SBruce Richardson 
115399a2dd95SBruce Richardson static int
115499a2dd95SBruce Richardson eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
115599a2dd95SBruce Richardson {
115699a2dd95SBruce Richardson 	uint16_t old_nb_queues = dev->data->nb_tx_queues;
115799a2dd95SBruce Richardson 	unsigned i;
115899a2dd95SBruce Richardson 
115999a2dd95SBruce Richardson 	if (dev->data->tx_queues == NULL && nb_queues != 0) { /* first time configuration */
116099a2dd95SBruce Richardson 		dev->data->tx_queues = rte_zmalloc("ethdev->tx_queues",
1161c024496aSKonstantin Ananyev 				sizeof(dev->data->tx_queues[0]) *
1162c024496aSKonstantin Ananyev 				RTE_MAX_QUEUES_PER_PORT,
116399a2dd95SBruce Richardson 				RTE_CACHE_LINE_SIZE);
116499a2dd95SBruce Richardson 		if (dev->data->tx_queues == NULL) {
116599a2dd95SBruce Richardson 			dev->data->nb_tx_queues = 0;
116699a2dd95SBruce Richardson 			return -(ENOMEM);
116799a2dd95SBruce Richardson 		}
116899a2dd95SBruce Richardson 	} else if (dev->data->tx_queues != NULL && nb_queues != 0) { /* re-configure */
116949ed3224SXueming Li 		for (i = nb_queues; i < old_nb_queues; i++)
117049ed3224SXueming Li 			eth_dev_txq_release(dev, i);
117199a2dd95SBruce Richardson 
117299a2dd95SBruce Richardson 	} else if (dev->data->tx_queues != NULL && nb_queues == 0) {
117399a2dd95SBruce Richardson 		for (i = nb_queues; i < old_nb_queues; i++)
117449ed3224SXueming Li 			eth_dev_txq_release(dev, i);
117599a2dd95SBruce Richardson 
117699a2dd95SBruce Richardson 		rte_free(dev->data->tx_queues);
117799a2dd95SBruce Richardson 		dev->data->tx_queues = NULL;
117899a2dd95SBruce Richardson 	}
117999a2dd95SBruce Richardson 	dev->data->nb_tx_queues = nb_queues;
118099a2dd95SBruce Richardson 	return 0;
118199a2dd95SBruce Richardson }
118299a2dd95SBruce Richardson 
118399a2dd95SBruce Richardson uint32_t
118499a2dd95SBruce Richardson rte_eth_speed_bitflag(uint32_t speed, int duplex)
118599a2dd95SBruce Richardson {
118699a2dd95SBruce Richardson 	switch (speed) {
1187295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_10M:
1188295968d1SFerruh Yigit 		return duplex ? RTE_ETH_LINK_SPEED_10M : RTE_ETH_LINK_SPEED_10M_HD;
1189295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_100M:
1190295968d1SFerruh Yigit 		return duplex ? RTE_ETH_LINK_SPEED_100M : RTE_ETH_LINK_SPEED_100M_HD;
1191295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_1G:
1192295968d1SFerruh Yigit 		return RTE_ETH_LINK_SPEED_1G;
1193295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_2_5G:
1194295968d1SFerruh Yigit 		return RTE_ETH_LINK_SPEED_2_5G;
1195295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_5G:
1196295968d1SFerruh Yigit 		return RTE_ETH_LINK_SPEED_5G;
1197295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_10G:
1198295968d1SFerruh Yigit 		return RTE_ETH_LINK_SPEED_10G;
1199295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_20G:
1200295968d1SFerruh Yigit 		return RTE_ETH_LINK_SPEED_20G;
1201295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_25G:
1202295968d1SFerruh Yigit 		return RTE_ETH_LINK_SPEED_25G;
1203295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_40G:
1204295968d1SFerruh Yigit 		return RTE_ETH_LINK_SPEED_40G;
1205295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_50G:
1206295968d1SFerruh Yigit 		return RTE_ETH_LINK_SPEED_50G;
1207295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_56G:
1208295968d1SFerruh Yigit 		return RTE_ETH_LINK_SPEED_56G;
1209295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_100G:
1210295968d1SFerruh Yigit 		return RTE_ETH_LINK_SPEED_100G;
1211295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_200G:
1212295968d1SFerruh Yigit 		return RTE_ETH_LINK_SPEED_200G;
121399a2dd95SBruce Richardson 	default:
121499a2dd95SBruce Richardson 		return 0;
121599a2dd95SBruce Richardson 	}
121699a2dd95SBruce Richardson }
121799a2dd95SBruce Richardson 
121899a2dd95SBruce Richardson const char *
121999a2dd95SBruce Richardson rte_eth_dev_rx_offload_name(uint64_t offload)
122099a2dd95SBruce Richardson {
122199a2dd95SBruce Richardson 	const char *name = "UNKNOWN";
122299a2dd95SBruce Richardson 	unsigned int i;
122399a2dd95SBruce Richardson 
122499a2dd95SBruce Richardson 	for (i = 0; i < RTE_DIM(eth_dev_rx_offload_names); ++i) {
122599a2dd95SBruce Richardson 		if (offload == eth_dev_rx_offload_names[i].offload) {
122699a2dd95SBruce Richardson 			name = eth_dev_rx_offload_names[i].name;
122799a2dd95SBruce Richardson 			break;
122899a2dd95SBruce Richardson 		}
122999a2dd95SBruce Richardson 	}
123099a2dd95SBruce Richardson 
123199a2dd95SBruce Richardson 	return name;
123299a2dd95SBruce Richardson }
123399a2dd95SBruce Richardson 
123499a2dd95SBruce Richardson const char *
123599a2dd95SBruce Richardson rte_eth_dev_tx_offload_name(uint64_t offload)
123699a2dd95SBruce Richardson {
123799a2dd95SBruce Richardson 	const char *name = "UNKNOWN";
123899a2dd95SBruce Richardson 	unsigned int i;
123999a2dd95SBruce Richardson 
124099a2dd95SBruce Richardson 	for (i = 0; i < RTE_DIM(eth_dev_tx_offload_names); ++i) {
124199a2dd95SBruce Richardson 		if (offload == eth_dev_tx_offload_names[i].offload) {
124299a2dd95SBruce Richardson 			name = eth_dev_tx_offload_names[i].name;
124399a2dd95SBruce Richardson 			break;
124499a2dd95SBruce Richardson 		}
124599a2dd95SBruce Richardson 	}
124699a2dd95SBruce Richardson 
124799a2dd95SBruce Richardson 	return name;
124899a2dd95SBruce Richardson }
124999a2dd95SBruce Richardson 
125093e441c9SXueming Li const char *
125193e441c9SXueming Li rte_eth_dev_capability_name(uint64_t capability)
125293e441c9SXueming Li {
125393e441c9SXueming Li 	const char *name = "UNKNOWN";
125493e441c9SXueming Li 	unsigned int i;
125593e441c9SXueming Li 
125693e441c9SXueming Li 	for (i = 0; i < RTE_DIM(rte_eth_dev_capa_names); ++i) {
125793e441c9SXueming Li 		if (capability == rte_eth_dev_capa_names[i].offload) {
125893e441c9SXueming Li 			name = rte_eth_dev_capa_names[i].name;
125993e441c9SXueming Li 			break;
126093e441c9SXueming Li 		}
126193e441c9SXueming Li 	}
126293e441c9SXueming Li 
126393e441c9SXueming Li 	return name;
126493e441c9SXueming Li }
126593e441c9SXueming Li 
126699a2dd95SBruce Richardson static inline int
126799a2dd95SBruce Richardson eth_dev_check_lro_pkt_size(uint16_t port_id, uint32_t config_size,
126899a2dd95SBruce Richardson 		   uint32_t max_rx_pkt_len, uint32_t dev_info_size)
126999a2dd95SBruce Richardson {
127099a2dd95SBruce Richardson 	int ret = 0;
127199a2dd95SBruce Richardson 
127299a2dd95SBruce Richardson 	if (dev_info_size == 0) {
127399a2dd95SBruce Richardson 		if (config_size != max_rx_pkt_len) {
127499a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size"
127599a2dd95SBruce Richardson 				       " %u != %u is not allowed\n",
127699a2dd95SBruce Richardson 				       port_id, config_size, max_rx_pkt_len);
127799a2dd95SBruce Richardson 			ret = -EINVAL;
127899a2dd95SBruce Richardson 		}
127999a2dd95SBruce Richardson 	} else if (config_size > dev_info_size) {
128099a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size %u "
128199a2dd95SBruce Richardson 			       "> max allowed value %u\n", port_id, config_size,
128299a2dd95SBruce Richardson 			       dev_info_size);
128399a2dd95SBruce Richardson 		ret = -EINVAL;
128499a2dd95SBruce Richardson 	} else if (config_size < RTE_ETHER_MIN_LEN) {
128599a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size %u "
128699a2dd95SBruce Richardson 			       "< min allowed value %u\n", port_id, config_size,
128799a2dd95SBruce Richardson 			       (unsigned int)RTE_ETHER_MIN_LEN);
128899a2dd95SBruce Richardson 		ret = -EINVAL;
128999a2dd95SBruce Richardson 	}
129099a2dd95SBruce Richardson 	return ret;
129199a2dd95SBruce Richardson }
129299a2dd95SBruce Richardson 
129399a2dd95SBruce Richardson /*
129499a2dd95SBruce Richardson  * Validate offloads that are requested through rte_eth_dev_configure against
12950d9f56a8SAndrew Rybchenko  * the offloads successfully set by the Ethernet device.
129699a2dd95SBruce Richardson  *
129799a2dd95SBruce Richardson  * @param port_id
129899a2dd95SBruce Richardson  *   The port identifier of the Ethernet device.
129999a2dd95SBruce Richardson  * @param req_offloads
130099a2dd95SBruce Richardson  *   The offloads that have been requested through `rte_eth_dev_configure`.
130199a2dd95SBruce Richardson  * @param set_offloads
13020d9f56a8SAndrew Rybchenko  *   The offloads successfully set by the Ethernet device.
130399a2dd95SBruce Richardson  * @param offload_type
130499a2dd95SBruce Richardson  *   The offload type i.e. Rx/Tx string.
130599a2dd95SBruce Richardson  * @param offload_name
130699a2dd95SBruce Richardson  *   The function that prints the offload name.
130799a2dd95SBruce Richardson  * @return
130899a2dd95SBruce Richardson  *   - (0) if validation successful.
130999a2dd95SBruce Richardson  *   - (-EINVAL) if requested offload has been silently disabled.
131099a2dd95SBruce Richardson  *
131199a2dd95SBruce Richardson  */
131299a2dd95SBruce Richardson static int
131399a2dd95SBruce Richardson eth_dev_validate_offloads(uint16_t port_id, uint64_t req_offloads,
131499a2dd95SBruce Richardson 		  uint64_t set_offloads, const char *offload_type,
131599a2dd95SBruce Richardson 		  const char *(*offload_name)(uint64_t))
131699a2dd95SBruce Richardson {
131799a2dd95SBruce Richardson 	uint64_t offloads_diff = req_offloads ^ set_offloads;
131899a2dd95SBruce Richardson 	uint64_t offload;
131999a2dd95SBruce Richardson 	int ret = 0;
132099a2dd95SBruce Richardson 
132199a2dd95SBruce Richardson 	while (offloads_diff != 0) {
132299a2dd95SBruce Richardson 		/* Check if any offload is requested but not enabled. */
1323e1823e08SThomas Monjalon 		offload = RTE_BIT64(__builtin_ctzll(offloads_diff));
132499a2dd95SBruce Richardson 		if (offload & req_offloads) {
132599a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
132699a2dd95SBruce Richardson 				"Port %u failed to enable %s offload %s\n",
132799a2dd95SBruce Richardson 				port_id, offload_type, offload_name(offload));
132899a2dd95SBruce Richardson 			ret = -EINVAL;
132999a2dd95SBruce Richardson 		}
133099a2dd95SBruce Richardson 
133199a2dd95SBruce Richardson 		/* Check if offload couldn't be disabled. */
133299a2dd95SBruce Richardson 		if (offload & set_offloads) {
133399a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(DEBUG,
133499a2dd95SBruce Richardson 				"Port %u %s offload %s is not requested but enabled\n",
133599a2dd95SBruce Richardson 				port_id, offload_type, offload_name(offload));
133699a2dd95SBruce Richardson 		}
133799a2dd95SBruce Richardson 
133899a2dd95SBruce Richardson 		offloads_diff &= ~offload;
133999a2dd95SBruce Richardson 	}
134099a2dd95SBruce Richardson 
134199a2dd95SBruce Richardson 	return ret;
134299a2dd95SBruce Richardson }
134399a2dd95SBruce Richardson 
13441bb4a528SFerruh Yigit static uint32_t
13451bb4a528SFerruh Yigit eth_dev_get_overhead_len(uint32_t max_rx_pktlen, uint16_t max_mtu)
13461bb4a528SFerruh Yigit {
13471bb4a528SFerruh Yigit 	uint32_t overhead_len;
13481bb4a528SFerruh Yigit 
13491bb4a528SFerruh Yigit 	if (max_mtu != UINT16_MAX && max_rx_pktlen > max_mtu)
13501bb4a528SFerruh Yigit 		overhead_len = max_rx_pktlen - max_mtu;
13511bb4a528SFerruh Yigit 	else
13521bb4a528SFerruh Yigit 		overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
13531bb4a528SFerruh Yigit 
13541bb4a528SFerruh Yigit 	return overhead_len;
13551bb4a528SFerruh Yigit }
13561bb4a528SFerruh Yigit 
1357990912e6SFerruh Yigit /* rte_eth_dev_info_get() should be called prior to this function */
1358990912e6SFerruh Yigit static int
1359990912e6SFerruh Yigit eth_dev_validate_mtu(uint16_t port_id, struct rte_eth_dev_info *dev_info,
1360990912e6SFerruh Yigit 		uint16_t mtu)
1361990912e6SFerruh Yigit {
1362990912e6SFerruh Yigit 	uint32_t overhead_len;
1363990912e6SFerruh Yigit 	uint32_t frame_size;
1364990912e6SFerruh Yigit 
1365990912e6SFerruh Yigit 	if (mtu < dev_info->min_mtu) {
1366990912e6SFerruh Yigit 		RTE_ETHDEV_LOG(ERR,
1367990912e6SFerruh Yigit 			"MTU (%u) < device min MTU (%u) for port_id %u\n",
1368990912e6SFerruh Yigit 			mtu, dev_info->min_mtu, port_id);
1369990912e6SFerruh Yigit 		return -EINVAL;
1370990912e6SFerruh Yigit 	}
1371990912e6SFerruh Yigit 	if (mtu > dev_info->max_mtu) {
1372990912e6SFerruh Yigit 		RTE_ETHDEV_LOG(ERR,
1373990912e6SFerruh Yigit 			"MTU (%u) > device max MTU (%u) for port_id %u\n",
1374990912e6SFerruh Yigit 			mtu, dev_info->max_mtu, port_id);
1375990912e6SFerruh Yigit 		return -EINVAL;
1376990912e6SFerruh Yigit 	}
1377990912e6SFerruh Yigit 
1378990912e6SFerruh Yigit 	overhead_len = eth_dev_get_overhead_len(dev_info->max_rx_pktlen,
1379990912e6SFerruh Yigit 			dev_info->max_mtu);
1380990912e6SFerruh Yigit 	frame_size = mtu + overhead_len;
1381990912e6SFerruh Yigit 	if (frame_size < RTE_ETHER_MIN_LEN) {
1382990912e6SFerruh Yigit 		RTE_ETHDEV_LOG(ERR,
1383990912e6SFerruh Yigit 			"Frame size (%u) < min frame size (%u) for port_id %u\n",
1384990912e6SFerruh Yigit 			frame_size, RTE_ETHER_MIN_LEN, port_id);
1385990912e6SFerruh Yigit 		return -EINVAL;
1386990912e6SFerruh Yigit 	}
1387990912e6SFerruh Yigit 
1388990912e6SFerruh Yigit 	if (frame_size > dev_info->max_rx_pktlen) {
1389990912e6SFerruh Yigit 		RTE_ETHDEV_LOG(ERR,
1390990912e6SFerruh Yigit 			"Frame size (%u) > device max frame size (%u) for port_id %u\n",
1391990912e6SFerruh Yigit 			frame_size, dev_info->max_rx_pktlen, port_id);
1392990912e6SFerruh Yigit 		return -EINVAL;
1393990912e6SFerruh Yigit 	}
1394990912e6SFerruh Yigit 
1395990912e6SFerruh Yigit 	return 0;
1396990912e6SFerruh Yigit }
1397990912e6SFerruh Yigit 
139899a2dd95SBruce Richardson int
139999a2dd95SBruce Richardson rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
140099a2dd95SBruce Richardson 		      const struct rte_eth_conf *dev_conf)
140199a2dd95SBruce Richardson {
140299a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
140399a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info;
140499a2dd95SBruce Richardson 	struct rte_eth_conf orig_conf;
140599a2dd95SBruce Richardson 	int diag;
140699a2dd95SBruce Richardson 	int ret;
140799a2dd95SBruce Richardson 	uint16_t old_mtu;
140899a2dd95SBruce Richardson 
140999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
141099a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
141199a2dd95SBruce Richardson 
141253ef1b34SMin Hu (Connor) 	if (dev_conf == NULL) {
141353ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
141453ef1b34SMin Hu (Connor) 			"Cannot configure ethdev port %u from NULL config\n",
141553ef1b34SMin Hu (Connor) 			port_id);
141653ef1b34SMin Hu (Connor) 		return -EINVAL;
141753ef1b34SMin Hu (Connor) 	}
141853ef1b34SMin Hu (Connor) 
141999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
142099a2dd95SBruce Richardson 
142199a2dd95SBruce Richardson 	if (dev->data->dev_started) {
142299a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
142399a2dd95SBruce Richardson 			"Port %u must be stopped to allow configuration\n",
142499a2dd95SBruce Richardson 			port_id);
142599a2dd95SBruce Richardson 		return -EBUSY;
142699a2dd95SBruce Richardson 	}
142799a2dd95SBruce Richardson 
142802edbfabSHuisong Li 	/*
142902edbfabSHuisong Li 	 * Ensure that "dev_configured" is always 0 each time prepare to do
143002edbfabSHuisong Li 	 * dev_configure() to avoid any non-anticipated behaviour.
143102edbfabSHuisong Li 	 * And set to 1 when dev_configure() is executed successfully.
143202edbfabSHuisong Li 	 */
143302edbfabSHuisong Li 	dev->data->dev_configured = 0;
143402edbfabSHuisong Li 
143599a2dd95SBruce Richardson 	 /* Store original config, as rollback required on failure */
143699a2dd95SBruce Richardson 	memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf));
143799a2dd95SBruce Richardson 
143899a2dd95SBruce Richardson 	/*
143999a2dd95SBruce Richardson 	 * Copy the dev_conf parameter into the dev structure.
144099a2dd95SBruce Richardson 	 * rte_eth_dev_info_get() requires dev_conf, copy it before dev_info get
144199a2dd95SBruce Richardson 	 */
144299a2dd95SBruce Richardson 	if (dev_conf != &dev->data->dev_conf)
144399a2dd95SBruce Richardson 		memcpy(&dev->data->dev_conf, dev_conf,
144499a2dd95SBruce Richardson 		       sizeof(dev->data->dev_conf));
144599a2dd95SBruce Richardson 
144699a2dd95SBruce Richardson 	/* Backup mtu for rollback */
144799a2dd95SBruce Richardson 	old_mtu = dev->data->mtu;
144899a2dd95SBruce Richardson 
144999a2dd95SBruce Richardson 	ret = rte_eth_dev_info_get(port_id, &dev_info);
145099a2dd95SBruce Richardson 	if (ret != 0)
145199a2dd95SBruce Richardson 		goto rollback;
145299a2dd95SBruce Richardson 
145399a2dd95SBruce Richardson 	/* If number of queues specified by application for both Rx and Tx is
145499a2dd95SBruce Richardson 	 * zero, use driver preferred values. This cannot be done individually
145599a2dd95SBruce Richardson 	 * as it is valid for either Tx or Rx (but not both) to be zero.
145699a2dd95SBruce Richardson 	 * If driver does not provide any preferred valued, fall back on
145799a2dd95SBruce Richardson 	 * EAL defaults.
145899a2dd95SBruce Richardson 	 */
145999a2dd95SBruce Richardson 	if (nb_rx_q == 0 && nb_tx_q == 0) {
146099a2dd95SBruce Richardson 		nb_rx_q = dev_info.default_rxportconf.nb_queues;
146199a2dd95SBruce Richardson 		if (nb_rx_q == 0)
146299a2dd95SBruce Richardson 			nb_rx_q = RTE_ETH_DEV_FALLBACK_RX_NBQUEUES;
146399a2dd95SBruce Richardson 		nb_tx_q = dev_info.default_txportconf.nb_queues;
146499a2dd95SBruce Richardson 		if (nb_tx_q == 0)
146599a2dd95SBruce Richardson 			nb_tx_q = RTE_ETH_DEV_FALLBACK_TX_NBQUEUES;
146699a2dd95SBruce Richardson 	}
146799a2dd95SBruce Richardson 
146899a2dd95SBruce Richardson 	if (nb_rx_q > RTE_MAX_QUEUES_PER_PORT) {
146999a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
147009fd4227SAndrew Rybchenko 			"Number of Rx queues requested (%u) is greater than max supported(%d)\n",
147199a2dd95SBruce Richardson 			nb_rx_q, RTE_MAX_QUEUES_PER_PORT);
147299a2dd95SBruce Richardson 		ret = -EINVAL;
147399a2dd95SBruce Richardson 		goto rollback;
147499a2dd95SBruce Richardson 	}
147599a2dd95SBruce Richardson 
147699a2dd95SBruce Richardson 	if (nb_tx_q > RTE_MAX_QUEUES_PER_PORT) {
147799a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
147809fd4227SAndrew Rybchenko 			"Number of Tx queues requested (%u) is greater than max supported(%d)\n",
147999a2dd95SBruce Richardson 			nb_tx_q, RTE_MAX_QUEUES_PER_PORT);
148099a2dd95SBruce Richardson 		ret = -EINVAL;
148199a2dd95SBruce Richardson 		goto rollback;
148299a2dd95SBruce Richardson 	}
148399a2dd95SBruce Richardson 
148499a2dd95SBruce Richardson 	/*
148509fd4227SAndrew Rybchenko 	 * Check that the numbers of Rx and Tx queues are not greater
148609fd4227SAndrew Rybchenko 	 * than the maximum number of Rx and Tx queues supported by the
148799a2dd95SBruce Richardson 	 * configured device.
148899a2dd95SBruce Richardson 	 */
148999a2dd95SBruce Richardson 	if (nb_rx_q > dev_info.max_rx_queues) {
149099a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_rx_queues=%u > %u\n",
149199a2dd95SBruce Richardson 			port_id, nb_rx_q, dev_info.max_rx_queues);
149299a2dd95SBruce Richardson 		ret = -EINVAL;
149399a2dd95SBruce Richardson 		goto rollback;
149499a2dd95SBruce Richardson 	}
149599a2dd95SBruce Richardson 
149699a2dd95SBruce Richardson 	if (nb_tx_q > dev_info.max_tx_queues) {
149799a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_tx_queues=%u > %u\n",
149899a2dd95SBruce Richardson 			port_id, nb_tx_q, dev_info.max_tx_queues);
149999a2dd95SBruce Richardson 		ret = -EINVAL;
150099a2dd95SBruce Richardson 		goto rollback;
150199a2dd95SBruce Richardson 	}
150299a2dd95SBruce Richardson 
150399a2dd95SBruce Richardson 	/* Check that the device supports requested interrupts */
150499a2dd95SBruce Richardson 	if ((dev_conf->intr_conf.lsc == 1) &&
150599a2dd95SBruce Richardson 			(!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) {
150699a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Driver %s does not support lsc\n",
150799a2dd95SBruce Richardson 			dev->device->driver->name);
150899a2dd95SBruce Richardson 		ret = -EINVAL;
150999a2dd95SBruce Richardson 		goto rollback;
151099a2dd95SBruce Richardson 	}
151199a2dd95SBruce Richardson 	if ((dev_conf->intr_conf.rmv == 1) &&
151299a2dd95SBruce Richardson 			(!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) {
151399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Driver %s does not support rmv\n",
151499a2dd95SBruce Richardson 			dev->device->driver->name);
151599a2dd95SBruce Richardson 		ret = -EINVAL;
151699a2dd95SBruce Richardson 		goto rollback;
151799a2dd95SBruce Richardson 	}
151899a2dd95SBruce Richardson 
15191bb4a528SFerruh Yigit 	if (dev_conf->rxmode.mtu == 0)
15201bb4a528SFerruh Yigit 		dev->data->dev_conf.rxmode.mtu = RTE_ETHER_MTU;
1521990912e6SFerruh Yigit 
1522990912e6SFerruh Yigit 	ret = eth_dev_validate_mtu(port_id, &dev_info,
1523990912e6SFerruh Yigit 			dev->data->dev_conf.rxmode.mtu);
1524990912e6SFerruh Yigit 	if (ret != 0)
152599a2dd95SBruce Richardson 		goto rollback;
152699a2dd95SBruce Richardson 
15271bb4a528SFerruh Yigit 	dev->data->mtu = dev->data->dev_conf.rxmode.mtu;
15281bb4a528SFerruh Yigit 
152999a2dd95SBruce Richardson 	/*
153099a2dd95SBruce Richardson 	 * If LRO is enabled, check that the maximum aggregated packet
153199a2dd95SBruce Richardson 	 * size is supported by the configured device.
153299a2dd95SBruce Richardson 	 */
1533295968d1SFerruh Yigit 	if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) {
1534990912e6SFerruh Yigit 		uint32_t max_rx_pktlen;
1535990912e6SFerruh Yigit 		uint32_t overhead_len;
1536990912e6SFerruh Yigit 
1537990912e6SFerruh Yigit 		overhead_len = eth_dev_get_overhead_len(dev_info.max_rx_pktlen,
1538990912e6SFerruh Yigit 				dev_info.max_mtu);
1539990912e6SFerruh Yigit 		max_rx_pktlen = dev->data->dev_conf.rxmode.mtu + overhead_len;
154099a2dd95SBruce Richardson 		if (dev_conf->rxmode.max_lro_pkt_size == 0)
15411bb4a528SFerruh Yigit 			dev->data->dev_conf.rxmode.max_lro_pkt_size = max_rx_pktlen;
154299a2dd95SBruce Richardson 		ret = eth_dev_check_lro_pkt_size(port_id,
154399a2dd95SBruce Richardson 				dev->data->dev_conf.rxmode.max_lro_pkt_size,
15441bb4a528SFerruh Yigit 				max_rx_pktlen,
154599a2dd95SBruce Richardson 				dev_info.max_lro_pkt_size);
154699a2dd95SBruce Richardson 		if (ret != 0)
154799a2dd95SBruce Richardson 			goto rollback;
154899a2dd95SBruce Richardson 	}
154999a2dd95SBruce Richardson 
155099a2dd95SBruce Richardson 	/* Any requested offloading must be within its device capabilities */
155199a2dd95SBruce Richardson 	if ((dev_conf->rxmode.offloads & dev_info.rx_offload_capa) !=
155299a2dd95SBruce Richardson 	     dev_conf->rxmode.offloads) {
155399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
155499a2dd95SBruce Richardson 			"Ethdev port_id=%u requested Rx offloads 0x%"PRIx64" doesn't match Rx offloads "
155599a2dd95SBruce Richardson 			"capabilities 0x%"PRIx64" in %s()\n",
155699a2dd95SBruce Richardson 			port_id, dev_conf->rxmode.offloads,
155799a2dd95SBruce Richardson 			dev_info.rx_offload_capa,
155899a2dd95SBruce Richardson 			__func__);
155999a2dd95SBruce Richardson 		ret = -EINVAL;
156099a2dd95SBruce Richardson 		goto rollback;
156199a2dd95SBruce Richardson 	}
156299a2dd95SBruce Richardson 	if ((dev_conf->txmode.offloads & dev_info.tx_offload_capa) !=
156399a2dd95SBruce Richardson 	     dev_conf->txmode.offloads) {
156499a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
156599a2dd95SBruce Richardson 			"Ethdev port_id=%u requested Tx offloads 0x%"PRIx64" doesn't match Tx offloads "
156699a2dd95SBruce Richardson 			"capabilities 0x%"PRIx64" in %s()\n",
156799a2dd95SBruce Richardson 			port_id, dev_conf->txmode.offloads,
156899a2dd95SBruce Richardson 			dev_info.tx_offload_capa,
156999a2dd95SBruce Richardson 			__func__);
157099a2dd95SBruce Richardson 		ret = -EINVAL;
157199a2dd95SBruce Richardson 		goto rollback;
157299a2dd95SBruce Richardson 	}
157399a2dd95SBruce Richardson 
157499a2dd95SBruce Richardson 	dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf =
157599a2dd95SBruce Richardson 		rte_eth_rss_hf_refine(dev_conf->rx_adv_conf.rss_conf.rss_hf);
157699a2dd95SBruce Richardson 
157799a2dd95SBruce Richardson 	/* Check that device supports requested rss hash functions. */
157899a2dd95SBruce Richardson 	if ((dev_info.flow_type_rss_offloads |
157999a2dd95SBruce Richardson 	     dev_conf->rx_adv_conf.rss_conf.rss_hf) !=
158099a2dd95SBruce Richardson 	    dev_info.flow_type_rss_offloads) {
158199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
158299a2dd95SBruce Richardson 			"Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n",
158399a2dd95SBruce Richardson 			port_id, dev_conf->rx_adv_conf.rss_conf.rss_hf,
158499a2dd95SBruce Richardson 			dev_info.flow_type_rss_offloads);
158599a2dd95SBruce Richardson 		ret = -EINVAL;
158699a2dd95SBruce Richardson 		goto rollback;
158799a2dd95SBruce Richardson 	}
158899a2dd95SBruce Richardson 
158999a2dd95SBruce Richardson 	/* Check if Rx RSS distribution is disabled but RSS hash is enabled. */
1590295968d1SFerruh Yigit 	if (((dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) == 0) &&
1591295968d1SFerruh Yigit 	    (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)) {
159299a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
159399a2dd95SBruce Richardson 			"Ethdev port_id=%u config invalid Rx mq_mode without RSS but %s offload is requested\n",
159499a2dd95SBruce Richardson 			port_id,
1595295968d1SFerruh Yigit 			rte_eth_dev_rx_offload_name(RTE_ETH_RX_OFFLOAD_RSS_HASH));
159699a2dd95SBruce Richardson 		ret = -EINVAL;
159799a2dd95SBruce Richardson 		goto rollback;
159899a2dd95SBruce Richardson 	}
159999a2dd95SBruce Richardson 
160099a2dd95SBruce Richardson 	/*
160109fd4227SAndrew Rybchenko 	 * Setup new number of Rx/Tx queues and reconfigure device.
160299a2dd95SBruce Richardson 	 */
160399a2dd95SBruce Richardson 	diag = eth_dev_rx_queue_config(dev, nb_rx_q);
160499a2dd95SBruce Richardson 	if (diag != 0) {
160599a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
160699a2dd95SBruce Richardson 			"Port%u eth_dev_rx_queue_config = %d\n",
160799a2dd95SBruce Richardson 			port_id, diag);
160899a2dd95SBruce Richardson 		ret = diag;
160999a2dd95SBruce Richardson 		goto rollback;
161099a2dd95SBruce Richardson 	}
161199a2dd95SBruce Richardson 
161299a2dd95SBruce Richardson 	diag = eth_dev_tx_queue_config(dev, nb_tx_q);
161399a2dd95SBruce Richardson 	if (diag != 0) {
161499a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
161599a2dd95SBruce Richardson 			"Port%u eth_dev_tx_queue_config = %d\n",
161699a2dd95SBruce Richardson 			port_id, diag);
161799a2dd95SBruce Richardson 		eth_dev_rx_queue_config(dev, 0);
161899a2dd95SBruce Richardson 		ret = diag;
161999a2dd95SBruce Richardson 		goto rollback;
162099a2dd95SBruce Richardson 	}
162199a2dd95SBruce Richardson 
162299a2dd95SBruce Richardson 	diag = (*dev->dev_ops->dev_configure)(dev);
162399a2dd95SBruce Richardson 	if (diag != 0) {
162499a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Port%u dev_configure = %d\n",
162599a2dd95SBruce Richardson 			port_id, diag);
162699a2dd95SBruce Richardson 		ret = eth_err(port_id, diag);
162799a2dd95SBruce Richardson 		goto reset_queues;
162899a2dd95SBruce Richardson 	}
162999a2dd95SBruce Richardson 
163099a2dd95SBruce Richardson 	/* Initialize Rx profiling if enabled at compilation time. */
163199a2dd95SBruce Richardson 	diag = __rte_eth_dev_profile_init(port_id, dev);
163299a2dd95SBruce Richardson 	if (diag != 0) {
163399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Port%u __rte_eth_dev_profile_init = %d\n",
163499a2dd95SBruce Richardson 			port_id, diag);
163599a2dd95SBruce Richardson 		ret = eth_err(port_id, diag);
163699a2dd95SBruce Richardson 		goto reset_queues;
163799a2dd95SBruce Richardson 	}
163899a2dd95SBruce Richardson 
163999a2dd95SBruce Richardson 	/* Validate Rx offloads. */
164099a2dd95SBruce Richardson 	diag = eth_dev_validate_offloads(port_id,
164199a2dd95SBruce Richardson 			dev_conf->rxmode.offloads,
164299a2dd95SBruce Richardson 			dev->data->dev_conf.rxmode.offloads, "Rx",
164399a2dd95SBruce Richardson 			rte_eth_dev_rx_offload_name);
164499a2dd95SBruce Richardson 	if (diag != 0) {
164599a2dd95SBruce Richardson 		ret = diag;
164699a2dd95SBruce Richardson 		goto reset_queues;
164799a2dd95SBruce Richardson 	}
164899a2dd95SBruce Richardson 
164999a2dd95SBruce Richardson 	/* Validate Tx offloads. */
165099a2dd95SBruce Richardson 	diag = eth_dev_validate_offloads(port_id,
165199a2dd95SBruce Richardson 			dev_conf->txmode.offloads,
165299a2dd95SBruce Richardson 			dev->data->dev_conf.txmode.offloads, "Tx",
165399a2dd95SBruce Richardson 			rte_eth_dev_tx_offload_name);
165499a2dd95SBruce Richardson 	if (diag != 0) {
165599a2dd95SBruce Richardson 		ret = diag;
165699a2dd95SBruce Richardson 		goto reset_queues;
165799a2dd95SBruce Richardson 	}
165899a2dd95SBruce Richardson 
165902edbfabSHuisong Li 	dev->data->dev_configured = 1;
166099a2dd95SBruce Richardson 	rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, 0);
166199a2dd95SBruce Richardson 	return 0;
166299a2dd95SBruce Richardson reset_queues:
166399a2dd95SBruce Richardson 	eth_dev_rx_queue_config(dev, 0);
166499a2dd95SBruce Richardson 	eth_dev_tx_queue_config(dev, 0);
166599a2dd95SBruce Richardson rollback:
166699a2dd95SBruce Richardson 	memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf));
166799a2dd95SBruce Richardson 	if (old_mtu != dev->data->mtu)
166899a2dd95SBruce Richardson 		dev->data->mtu = old_mtu;
166999a2dd95SBruce Richardson 
167099a2dd95SBruce Richardson 	rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, ret);
167199a2dd95SBruce Richardson 	return ret;
167299a2dd95SBruce Richardson }
167399a2dd95SBruce Richardson 
167499a2dd95SBruce Richardson void
167599a2dd95SBruce Richardson rte_eth_dev_internal_reset(struct rte_eth_dev *dev)
167699a2dd95SBruce Richardson {
167799a2dd95SBruce Richardson 	if (dev->data->dev_started) {
167899a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Port %u must be stopped to allow reset\n",
167999a2dd95SBruce Richardson 			dev->data->port_id);
168099a2dd95SBruce Richardson 		return;
168199a2dd95SBruce Richardson 	}
168299a2dd95SBruce Richardson 
168399a2dd95SBruce Richardson 	eth_dev_rx_queue_config(dev, 0);
168499a2dd95SBruce Richardson 	eth_dev_tx_queue_config(dev, 0);
168599a2dd95SBruce Richardson 
168699a2dd95SBruce Richardson 	memset(&dev->data->dev_conf, 0, sizeof(dev->data->dev_conf));
168799a2dd95SBruce Richardson }
168899a2dd95SBruce Richardson 
168999a2dd95SBruce Richardson static void
169099a2dd95SBruce Richardson eth_dev_mac_restore(struct rte_eth_dev *dev,
169199a2dd95SBruce Richardson 			struct rte_eth_dev_info *dev_info)
169299a2dd95SBruce Richardson {
169399a2dd95SBruce Richardson 	struct rte_ether_addr *addr;
169499a2dd95SBruce Richardson 	uint16_t i;
169599a2dd95SBruce Richardson 	uint32_t pool = 0;
169699a2dd95SBruce Richardson 	uint64_t pool_mask;
169799a2dd95SBruce Richardson 
169899a2dd95SBruce Richardson 	/* replay MAC address configuration including default MAC */
169999a2dd95SBruce Richardson 	addr = &dev->data->mac_addrs[0];
170099a2dd95SBruce Richardson 	if (*dev->dev_ops->mac_addr_set != NULL)
170199a2dd95SBruce Richardson 		(*dev->dev_ops->mac_addr_set)(dev, addr);
170299a2dd95SBruce Richardson 	else if (*dev->dev_ops->mac_addr_add != NULL)
170399a2dd95SBruce Richardson 		(*dev->dev_ops->mac_addr_add)(dev, addr, 0, pool);
170499a2dd95SBruce Richardson 
170599a2dd95SBruce Richardson 	if (*dev->dev_ops->mac_addr_add != NULL) {
170699a2dd95SBruce Richardson 		for (i = 1; i < dev_info->max_mac_addrs; i++) {
170799a2dd95SBruce Richardson 			addr = &dev->data->mac_addrs[i];
170899a2dd95SBruce Richardson 
170999a2dd95SBruce Richardson 			/* skip zero address */
171099a2dd95SBruce Richardson 			if (rte_is_zero_ether_addr(addr))
171199a2dd95SBruce Richardson 				continue;
171299a2dd95SBruce Richardson 
171399a2dd95SBruce Richardson 			pool = 0;
171499a2dd95SBruce Richardson 			pool_mask = dev->data->mac_pool_sel[i];
171599a2dd95SBruce Richardson 
171699a2dd95SBruce Richardson 			do {
1717e1823e08SThomas Monjalon 				if (pool_mask & UINT64_C(1))
171899a2dd95SBruce Richardson 					(*dev->dev_ops->mac_addr_add)(dev,
171999a2dd95SBruce Richardson 						addr, i, pool);
172099a2dd95SBruce Richardson 				pool_mask >>= 1;
172199a2dd95SBruce Richardson 				pool++;
172299a2dd95SBruce Richardson 			} while (pool_mask);
172399a2dd95SBruce Richardson 		}
172499a2dd95SBruce Richardson 	}
172599a2dd95SBruce Richardson }
172699a2dd95SBruce Richardson 
172799a2dd95SBruce Richardson static int
172899a2dd95SBruce Richardson eth_dev_config_restore(struct rte_eth_dev *dev,
172999a2dd95SBruce Richardson 		struct rte_eth_dev_info *dev_info, uint16_t port_id)
173099a2dd95SBruce Richardson {
173199a2dd95SBruce Richardson 	int ret;
173299a2dd95SBruce Richardson 
173399a2dd95SBruce Richardson 	if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR))
173499a2dd95SBruce Richardson 		eth_dev_mac_restore(dev, dev_info);
173599a2dd95SBruce Richardson 
173699a2dd95SBruce Richardson 	/* replay promiscuous configuration */
173799a2dd95SBruce Richardson 	/*
173899a2dd95SBruce Richardson 	 * use callbacks directly since we don't need port_id check and
173999a2dd95SBruce Richardson 	 * would like to bypass the same value set
174099a2dd95SBruce Richardson 	 */
174199a2dd95SBruce Richardson 	if (rte_eth_promiscuous_get(port_id) == 1 &&
174299a2dd95SBruce Richardson 	    *dev->dev_ops->promiscuous_enable != NULL) {
174399a2dd95SBruce Richardson 		ret = eth_err(port_id,
174499a2dd95SBruce Richardson 			      (*dev->dev_ops->promiscuous_enable)(dev));
174599a2dd95SBruce Richardson 		if (ret != 0 && ret != -ENOTSUP) {
174699a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
174799a2dd95SBruce Richardson 				"Failed to enable promiscuous mode for device (port %u): %s\n",
174899a2dd95SBruce Richardson 				port_id, rte_strerror(-ret));
174999a2dd95SBruce Richardson 			return ret;
175099a2dd95SBruce Richardson 		}
175199a2dd95SBruce Richardson 	} else if (rte_eth_promiscuous_get(port_id) == 0 &&
175299a2dd95SBruce Richardson 		   *dev->dev_ops->promiscuous_disable != NULL) {
175399a2dd95SBruce Richardson 		ret = eth_err(port_id,
175499a2dd95SBruce Richardson 			      (*dev->dev_ops->promiscuous_disable)(dev));
175599a2dd95SBruce Richardson 		if (ret != 0 && ret != -ENOTSUP) {
175699a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
175799a2dd95SBruce Richardson 				"Failed to disable promiscuous mode for device (port %u): %s\n",
175899a2dd95SBruce Richardson 				port_id, rte_strerror(-ret));
175999a2dd95SBruce Richardson 			return ret;
176099a2dd95SBruce Richardson 		}
176199a2dd95SBruce Richardson 	}
176299a2dd95SBruce Richardson 
176399a2dd95SBruce Richardson 	/* replay all multicast configuration */
176499a2dd95SBruce Richardson 	/*
176599a2dd95SBruce Richardson 	 * use callbacks directly since we don't need port_id check and
176699a2dd95SBruce Richardson 	 * would like to bypass the same value set
176799a2dd95SBruce Richardson 	 */
176899a2dd95SBruce Richardson 	if (rte_eth_allmulticast_get(port_id) == 1 &&
176999a2dd95SBruce Richardson 	    *dev->dev_ops->allmulticast_enable != NULL) {
177099a2dd95SBruce Richardson 		ret = eth_err(port_id,
177199a2dd95SBruce Richardson 			      (*dev->dev_ops->allmulticast_enable)(dev));
177299a2dd95SBruce Richardson 		if (ret != 0 && ret != -ENOTSUP) {
177399a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
177499a2dd95SBruce Richardson 				"Failed to enable allmulticast mode for device (port %u): %s\n",
177599a2dd95SBruce Richardson 				port_id, rte_strerror(-ret));
177699a2dd95SBruce Richardson 			return ret;
177799a2dd95SBruce Richardson 		}
177899a2dd95SBruce Richardson 	} else if (rte_eth_allmulticast_get(port_id) == 0 &&
177999a2dd95SBruce Richardson 		   *dev->dev_ops->allmulticast_disable != NULL) {
178099a2dd95SBruce Richardson 		ret = eth_err(port_id,
178199a2dd95SBruce Richardson 			      (*dev->dev_ops->allmulticast_disable)(dev));
178299a2dd95SBruce Richardson 		if (ret != 0 && ret != -ENOTSUP) {
178399a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
178499a2dd95SBruce Richardson 				"Failed to disable allmulticast mode for device (port %u): %s\n",
178599a2dd95SBruce Richardson 				port_id, rte_strerror(-ret));
178699a2dd95SBruce Richardson 			return ret;
178799a2dd95SBruce Richardson 		}
178899a2dd95SBruce Richardson 	}
178999a2dd95SBruce Richardson 
179099a2dd95SBruce Richardson 	return 0;
179199a2dd95SBruce Richardson }
179299a2dd95SBruce Richardson 
179399a2dd95SBruce Richardson int
179499a2dd95SBruce Richardson rte_eth_dev_start(uint16_t port_id)
179599a2dd95SBruce Richardson {
179699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
179799a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info;
179899a2dd95SBruce Richardson 	int diag;
179999a2dd95SBruce Richardson 	int ret, ret_stop;
180099a2dd95SBruce Richardson 
180199a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
180299a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
180399a2dd95SBruce Richardson 
180499a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
180599a2dd95SBruce Richardson 
180602edbfabSHuisong Li 	if (dev->data->dev_configured == 0) {
180702edbfabSHuisong Li 		RTE_ETHDEV_LOG(INFO,
180802edbfabSHuisong Li 			"Device with port_id=%"PRIu16" is not configured.\n",
180902edbfabSHuisong Li 			port_id);
181002edbfabSHuisong Li 		return -EINVAL;
181102edbfabSHuisong Li 	}
181202edbfabSHuisong Li 
181399a2dd95SBruce Richardson 	if (dev->data->dev_started != 0) {
181499a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
181599a2dd95SBruce Richardson 			"Device with port_id=%"PRIu16" already started\n",
181699a2dd95SBruce Richardson 			port_id);
181799a2dd95SBruce Richardson 		return 0;
181899a2dd95SBruce Richardson 	}
181999a2dd95SBruce Richardson 
182099a2dd95SBruce Richardson 	ret = rte_eth_dev_info_get(port_id, &dev_info);
182199a2dd95SBruce Richardson 	if (ret != 0)
182299a2dd95SBruce Richardson 		return ret;
182399a2dd95SBruce Richardson 
182499a2dd95SBruce Richardson 	/* Lets restore MAC now if device does not support live change */
182599a2dd95SBruce Richardson 	if (*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR)
182699a2dd95SBruce Richardson 		eth_dev_mac_restore(dev, &dev_info);
182799a2dd95SBruce Richardson 
182899a2dd95SBruce Richardson 	diag = (*dev->dev_ops->dev_start)(dev);
182999a2dd95SBruce Richardson 	if (diag == 0)
183099a2dd95SBruce Richardson 		dev->data->dev_started = 1;
183199a2dd95SBruce Richardson 	else
183299a2dd95SBruce Richardson 		return eth_err(port_id, diag);
183399a2dd95SBruce Richardson 
183499a2dd95SBruce Richardson 	ret = eth_dev_config_restore(dev, &dev_info, port_id);
183599a2dd95SBruce Richardson 	if (ret != 0) {
183699a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
183799a2dd95SBruce Richardson 			"Error during restoring configuration for device (port %u): %s\n",
183899a2dd95SBruce Richardson 			port_id, rte_strerror(-ret));
183999a2dd95SBruce Richardson 		ret_stop = rte_eth_dev_stop(port_id);
184099a2dd95SBruce Richardson 		if (ret_stop != 0) {
184199a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
184299a2dd95SBruce Richardson 				"Failed to stop device (port %u): %s\n",
184399a2dd95SBruce Richardson 				port_id, rte_strerror(-ret_stop));
184499a2dd95SBruce Richardson 		}
184599a2dd95SBruce Richardson 
184699a2dd95SBruce Richardson 		return ret;
184799a2dd95SBruce Richardson 	}
184899a2dd95SBruce Richardson 
184999a2dd95SBruce Richardson 	if (dev->data->dev_conf.intr_conf.lsc == 0) {
185099a2dd95SBruce Richardson 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
185199a2dd95SBruce Richardson 		(*dev->dev_ops->link_update)(dev, 0);
185299a2dd95SBruce Richardson 	}
185399a2dd95SBruce Richardson 
1854c87d435aSKonstantin Ananyev 	/* expose selection of PMD fast-path functions */
1855c87d435aSKonstantin Ananyev 	eth_dev_fp_ops_setup(rte_eth_fp_ops + port_id, dev);
1856c87d435aSKonstantin Ananyev 
185799a2dd95SBruce Richardson 	rte_ethdev_trace_start(port_id);
185899a2dd95SBruce Richardson 	return 0;
185999a2dd95SBruce Richardson }
186099a2dd95SBruce Richardson 
186199a2dd95SBruce Richardson int
186299a2dd95SBruce Richardson rte_eth_dev_stop(uint16_t port_id)
186399a2dd95SBruce Richardson {
186499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
186599a2dd95SBruce Richardson 	int ret;
186699a2dd95SBruce Richardson 
186799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
186899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
186999a2dd95SBruce Richardson 
187099a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_stop, -ENOTSUP);
187199a2dd95SBruce Richardson 
187299a2dd95SBruce Richardson 	if (dev->data->dev_started == 0) {
187399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
187499a2dd95SBruce Richardson 			"Device with port_id=%"PRIu16" already stopped\n",
187599a2dd95SBruce Richardson 			port_id);
187699a2dd95SBruce Richardson 		return 0;
187799a2dd95SBruce Richardson 	}
187899a2dd95SBruce Richardson 
1879c87d435aSKonstantin Ananyev 	/* point fast-path functions to dummy ones */
1880c87d435aSKonstantin Ananyev 	eth_dev_fp_ops_reset(rte_eth_fp_ops + port_id);
1881c87d435aSKonstantin Ananyev 
188299a2dd95SBruce Richardson 	dev->data->dev_started = 0;
188399a2dd95SBruce Richardson 	ret = (*dev->dev_ops->dev_stop)(dev);
188499a2dd95SBruce Richardson 	rte_ethdev_trace_stop(port_id, ret);
188599a2dd95SBruce Richardson 
188699a2dd95SBruce Richardson 	return ret;
188799a2dd95SBruce Richardson }
188899a2dd95SBruce Richardson 
188999a2dd95SBruce Richardson int
189099a2dd95SBruce Richardson rte_eth_dev_set_link_up(uint16_t port_id)
189199a2dd95SBruce Richardson {
189299a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
189399a2dd95SBruce Richardson 
189499a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
189599a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
189699a2dd95SBruce Richardson 
189799a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_up, -ENOTSUP);
189899a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->dev_set_link_up)(dev));
189999a2dd95SBruce Richardson }
190099a2dd95SBruce Richardson 
190199a2dd95SBruce Richardson int
190299a2dd95SBruce Richardson rte_eth_dev_set_link_down(uint16_t port_id)
190399a2dd95SBruce Richardson {
190499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
190599a2dd95SBruce Richardson 
190699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
190799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
190899a2dd95SBruce Richardson 
190999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_down, -ENOTSUP);
191099a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->dev_set_link_down)(dev));
191199a2dd95SBruce Richardson }
191299a2dd95SBruce Richardson 
191399a2dd95SBruce Richardson int
191499a2dd95SBruce Richardson rte_eth_dev_close(uint16_t port_id)
191599a2dd95SBruce Richardson {
191699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
191799a2dd95SBruce Richardson 	int firsterr, binerr;
191899a2dd95SBruce Richardson 	int *lasterr = &firsterr;
191999a2dd95SBruce Richardson 
192099a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
192199a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
192299a2dd95SBruce Richardson 
1923febc855bSAndrew Rybchenko 	if (dev->data->dev_started) {
1924febc855bSAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Cannot close started device (port %u)\n",
1925febc855bSAndrew Rybchenko 			       port_id);
1926febc855bSAndrew Rybchenko 		return -EINVAL;
1927febc855bSAndrew Rybchenko 	}
1928febc855bSAndrew Rybchenko 
192999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
193099a2dd95SBruce Richardson 	*lasterr = (*dev->dev_ops->dev_close)(dev);
193199a2dd95SBruce Richardson 	if (*lasterr != 0)
193299a2dd95SBruce Richardson 		lasterr = &binerr;
193399a2dd95SBruce Richardson 
193499a2dd95SBruce Richardson 	rte_ethdev_trace_close(port_id);
193599a2dd95SBruce Richardson 	*lasterr = rte_eth_dev_release_port(dev);
193699a2dd95SBruce Richardson 
193799a2dd95SBruce Richardson 	return firsterr;
193899a2dd95SBruce Richardson }
193999a2dd95SBruce Richardson 
194099a2dd95SBruce Richardson int
194199a2dd95SBruce Richardson rte_eth_dev_reset(uint16_t port_id)
194299a2dd95SBruce Richardson {
194399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
194499a2dd95SBruce Richardson 	int ret;
194599a2dd95SBruce Richardson 
194699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
194799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
194899a2dd95SBruce Richardson 
194999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP);
195099a2dd95SBruce Richardson 
195199a2dd95SBruce Richardson 	ret = rte_eth_dev_stop(port_id);
195299a2dd95SBruce Richardson 	if (ret != 0) {
195399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
195499a2dd95SBruce Richardson 			"Failed to stop device (port %u) before reset: %s - ignore\n",
195599a2dd95SBruce Richardson 			port_id, rte_strerror(-ret));
195699a2dd95SBruce Richardson 	}
195799a2dd95SBruce Richardson 	ret = dev->dev_ops->dev_reset(dev);
195899a2dd95SBruce Richardson 
195999a2dd95SBruce Richardson 	return eth_err(port_id, ret);
196099a2dd95SBruce Richardson }
196199a2dd95SBruce Richardson 
196299a2dd95SBruce Richardson int
196399a2dd95SBruce Richardson rte_eth_dev_is_removed(uint16_t port_id)
196499a2dd95SBruce Richardson {
196599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
196699a2dd95SBruce Richardson 	int ret;
196799a2dd95SBruce Richardson 
196899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
196999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
197099a2dd95SBruce Richardson 
197199a2dd95SBruce Richardson 	if (dev->state == RTE_ETH_DEV_REMOVED)
197299a2dd95SBruce Richardson 		return 1;
197399a2dd95SBruce Richardson 
197499a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->is_removed, 0);
197599a2dd95SBruce Richardson 
197699a2dd95SBruce Richardson 	ret = dev->dev_ops->is_removed(dev);
197799a2dd95SBruce Richardson 	if (ret != 0)
197899a2dd95SBruce Richardson 		/* Device is physically removed. */
197999a2dd95SBruce Richardson 		dev->state = RTE_ETH_DEV_REMOVED;
198099a2dd95SBruce Richardson 
198199a2dd95SBruce Richardson 	return ret;
198299a2dd95SBruce Richardson }
198399a2dd95SBruce Richardson 
198499a2dd95SBruce Richardson static int
198599a2dd95SBruce Richardson rte_eth_rx_queue_check_split(const struct rte_eth_rxseg_split *rx_seg,
198699a2dd95SBruce Richardson 			     uint16_t n_seg, uint32_t *mbp_buf_size,
198799a2dd95SBruce Richardson 			     const struct rte_eth_dev_info *dev_info)
198899a2dd95SBruce Richardson {
198999a2dd95SBruce Richardson 	const struct rte_eth_rxseg_capa *seg_capa = &dev_info->rx_seg_capa;
199099a2dd95SBruce Richardson 	struct rte_mempool *mp_first;
199199a2dd95SBruce Richardson 	uint32_t offset_mask;
199299a2dd95SBruce Richardson 	uint16_t seg_idx;
199399a2dd95SBruce Richardson 
199499a2dd95SBruce Richardson 	if (n_seg > seg_capa->max_nseg) {
199599a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
199699a2dd95SBruce Richardson 			       "Requested Rx segments %u exceed supported %u\n",
199799a2dd95SBruce Richardson 			       n_seg, seg_capa->max_nseg);
199899a2dd95SBruce Richardson 		return -EINVAL;
199999a2dd95SBruce Richardson 	}
200099a2dd95SBruce Richardson 	/*
200199a2dd95SBruce Richardson 	 * Check the sizes and offsets against buffer sizes
200299a2dd95SBruce Richardson 	 * for each segment specified in extended configuration.
200399a2dd95SBruce Richardson 	 */
200499a2dd95SBruce Richardson 	mp_first = rx_seg[0].mp;
2005e1823e08SThomas Monjalon 	offset_mask = RTE_BIT32(seg_capa->offset_align_log2) - 1;
200699a2dd95SBruce Richardson 	for (seg_idx = 0; seg_idx < n_seg; seg_idx++) {
200799a2dd95SBruce Richardson 		struct rte_mempool *mpl = rx_seg[seg_idx].mp;
200899a2dd95SBruce Richardson 		uint32_t length = rx_seg[seg_idx].length;
200999a2dd95SBruce Richardson 		uint32_t offset = rx_seg[seg_idx].offset;
201099a2dd95SBruce Richardson 
201199a2dd95SBruce Richardson 		if (mpl == NULL) {
201299a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR, "null mempool pointer\n");
201399a2dd95SBruce Richardson 			return -EINVAL;
201499a2dd95SBruce Richardson 		}
201599a2dd95SBruce Richardson 		if (seg_idx != 0 && mp_first != mpl &&
201699a2dd95SBruce Richardson 		    seg_capa->multi_pools == 0) {
201799a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR, "Receiving to multiple pools is not supported\n");
201899a2dd95SBruce Richardson 			return -ENOTSUP;
201999a2dd95SBruce Richardson 		}
202099a2dd95SBruce Richardson 		if (offset != 0) {
202199a2dd95SBruce Richardson 			if (seg_capa->offset_allowed == 0) {
202299a2dd95SBruce Richardson 				RTE_ETHDEV_LOG(ERR, "Rx segmentation with offset is not supported\n");
202399a2dd95SBruce Richardson 				return -ENOTSUP;
202499a2dd95SBruce Richardson 			}
202599a2dd95SBruce Richardson 			if (offset & offset_mask) {
202699a2dd95SBruce Richardson 				RTE_ETHDEV_LOG(ERR, "Rx segmentation invalid offset alignment %u, %u\n",
202799a2dd95SBruce Richardson 					       offset,
202899a2dd95SBruce Richardson 					       seg_capa->offset_align_log2);
202999a2dd95SBruce Richardson 				return -EINVAL;
203099a2dd95SBruce Richardson 			}
203199a2dd95SBruce Richardson 		}
203299a2dd95SBruce Richardson 		if (mpl->private_data_size <
203399a2dd95SBruce Richardson 			sizeof(struct rte_pktmbuf_pool_private)) {
203499a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
203599a2dd95SBruce Richardson 				       "%s private_data_size %u < %u\n",
203699a2dd95SBruce Richardson 				       mpl->name, mpl->private_data_size,
203799a2dd95SBruce Richardson 				       (unsigned int)sizeof
203899a2dd95SBruce Richardson 					(struct rte_pktmbuf_pool_private));
203999a2dd95SBruce Richardson 			return -ENOSPC;
204099a2dd95SBruce Richardson 		}
204199a2dd95SBruce Richardson 		offset += seg_idx != 0 ? 0 : RTE_PKTMBUF_HEADROOM;
204299a2dd95SBruce Richardson 		*mbp_buf_size = rte_pktmbuf_data_room_size(mpl);
204399a2dd95SBruce Richardson 		length = length != 0 ? length : *mbp_buf_size;
204499a2dd95SBruce Richardson 		if (*mbp_buf_size < length + offset) {
204599a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
204699a2dd95SBruce Richardson 				       "%s mbuf_data_room_size %u < %u (segment length=%u + segment offset=%u)\n",
204799a2dd95SBruce Richardson 				       mpl->name, *mbp_buf_size,
204899a2dd95SBruce Richardson 				       length + offset, length, offset);
204999a2dd95SBruce Richardson 			return -EINVAL;
205099a2dd95SBruce Richardson 		}
205199a2dd95SBruce Richardson 	}
205299a2dd95SBruce Richardson 	return 0;
205399a2dd95SBruce Richardson }
205499a2dd95SBruce Richardson 
205599a2dd95SBruce Richardson int
205699a2dd95SBruce Richardson rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
205799a2dd95SBruce Richardson 		       uint16_t nb_rx_desc, unsigned int socket_id,
205899a2dd95SBruce Richardson 		       const struct rte_eth_rxconf *rx_conf,
205999a2dd95SBruce Richardson 		       struct rte_mempool *mp)
206099a2dd95SBruce Richardson {
206199a2dd95SBruce Richardson 	int ret;
206299a2dd95SBruce Richardson 	uint32_t mbp_buf_size;
206399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
206499a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info;
206599a2dd95SBruce Richardson 	struct rte_eth_rxconf local_conf;
206699a2dd95SBruce Richardson 
206799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
206899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
206953ef1b34SMin Hu (Connor) 
207099a2dd95SBruce Richardson 	if (rx_queue_id >= dev->data->nb_rx_queues) {
207109fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", rx_queue_id);
207299a2dd95SBruce Richardson 		return -EINVAL;
207399a2dd95SBruce Richardson 	}
207499a2dd95SBruce Richardson 
207599a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP);
207699a2dd95SBruce Richardson 
207799a2dd95SBruce Richardson 	ret = rte_eth_dev_info_get(port_id, &dev_info);
207899a2dd95SBruce Richardson 	if (ret != 0)
207999a2dd95SBruce Richardson 		return ret;
208099a2dd95SBruce Richardson 
208199a2dd95SBruce Richardson 	if (mp != NULL) {
208299a2dd95SBruce Richardson 		/* Single pool configuration check. */
208399a2dd95SBruce Richardson 		if (rx_conf != NULL && rx_conf->rx_nseg != 0) {
208499a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
208599a2dd95SBruce Richardson 				       "Ambiguous segment configuration\n");
208699a2dd95SBruce Richardson 			return -EINVAL;
208799a2dd95SBruce Richardson 		}
208899a2dd95SBruce Richardson 		/*
208999a2dd95SBruce Richardson 		 * Check the size of the mbuf data buffer, this value
209099a2dd95SBruce Richardson 		 * must be provided in the private data of the memory pool.
209199a2dd95SBruce Richardson 		 * First check that the memory pool(s) has a valid private data.
209299a2dd95SBruce Richardson 		 */
209399a2dd95SBruce Richardson 		if (mp->private_data_size <
209499a2dd95SBruce Richardson 				sizeof(struct rte_pktmbuf_pool_private)) {
209599a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR, "%s private_data_size %u < %u\n",
209699a2dd95SBruce Richardson 				mp->name, mp->private_data_size,
209799a2dd95SBruce Richardson 				(unsigned int)
209899a2dd95SBruce Richardson 				sizeof(struct rte_pktmbuf_pool_private));
209999a2dd95SBruce Richardson 			return -ENOSPC;
210099a2dd95SBruce Richardson 		}
210199a2dd95SBruce Richardson 		mbp_buf_size = rte_pktmbuf_data_room_size(mp);
210299a2dd95SBruce Richardson 		if (mbp_buf_size < dev_info.min_rx_bufsize +
210399a2dd95SBruce Richardson 				   RTE_PKTMBUF_HEADROOM) {
210499a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
210599a2dd95SBruce Richardson 				       "%s mbuf_data_room_size %u < %u (RTE_PKTMBUF_HEADROOM=%u + min_rx_bufsize(dev)=%u)\n",
210699a2dd95SBruce Richardson 				       mp->name, mbp_buf_size,
210799a2dd95SBruce Richardson 				       RTE_PKTMBUF_HEADROOM +
210899a2dd95SBruce Richardson 				       dev_info.min_rx_bufsize,
210999a2dd95SBruce Richardson 				       RTE_PKTMBUF_HEADROOM,
211099a2dd95SBruce Richardson 				       dev_info.min_rx_bufsize);
211199a2dd95SBruce Richardson 			return -EINVAL;
211299a2dd95SBruce Richardson 		}
211399a2dd95SBruce Richardson 	} else {
211499a2dd95SBruce Richardson 		const struct rte_eth_rxseg_split *rx_seg;
211599a2dd95SBruce Richardson 		uint16_t n_seg;
211699a2dd95SBruce Richardson 
211799a2dd95SBruce Richardson 		/* Extended multi-segment configuration check. */
211899a2dd95SBruce Richardson 		if (rx_conf == NULL || rx_conf->rx_seg == NULL || rx_conf->rx_nseg == 0) {
211999a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
212099a2dd95SBruce Richardson 				       "Memory pool is null and no extended configuration provided\n");
212199a2dd95SBruce Richardson 			return -EINVAL;
212299a2dd95SBruce Richardson 		}
212399a2dd95SBruce Richardson 
212499a2dd95SBruce Richardson 		rx_seg = (const struct rte_eth_rxseg_split *)rx_conf->rx_seg;
212599a2dd95SBruce Richardson 		n_seg = rx_conf->rx_nseg;
212699a2dd95SBruce Richardson 
212799a2dd95SBruce Richardson 		if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
212899a2dd95SBruce Richardson 			ret = rte_eth_rx_queue_check_split(rx_seg, n_seg,
212999a2dd95SBruce Richardson 							   &mbp_buf_size,
213099a2dd95SBruce Richardson 							   &dev_info);
213199a2dd95SBruce Richardson 			if (ret != 0)
213299a2dd95SBruce Richardson 				return ret;
213399a2dd95SBruce Richardson 		} else {
213499a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR, "No Rx segmentation offload configured\n");
213599a2dd95SBruce Richardson 			return -EINVAL;
213699a2dd95SBruce Richardson 		}
213799a2dd95SBruce Richardson 	}
213899a2dd95SBruce Richardson 
213999a2dd95SBruce Richardson 	/* Use default specified by driver, if nb_rx_desc is zero */
214099a2dd95SBruce Richardson 	if (nb_rx_desc == 0) {
214199a2dd95SBruce Richardson 		nb_rx_desc = dev_info.default_rxportconf.ring_size;
214299a2dd95SBruce Richardson 		/* If driver default is also zero, fall back on EAL default */
214399a2dd95SBruce Richardson 		if (nb_rx_desc == 0)
214499a2dd95SBruce Richardson 			nb_rx_desc = RTE_ETH_DEV_FALLBACK_RX_RINGSIZE;
214599a2dd95SBruce Richardson 	}
214699a2dd95SBruce Richardson 
214799a2dd95SBruce Richardson 	if (nb_rx_desc > dev_info.rx_desc_lim.nb_max ||
214899a2dd95SBruce Richardson 			nb_rx_desc < dev_info.rx_desc_lim.nb_min ||
214999a2dd95SBruce Richardson 			nb_rx_desc % dev_info.rx_desc_lim.nb_align != 0) {
215099a2dd95SBruce Richardson 
215199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
215299a2dd95SBruce Richardson 			"Invalid value for nb_rx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n",
215399a2dd95SBruce Richardson 			nb_rx_desc, dev_info.rx_desc_lim.nb_max,
215499a2dd95SBruce Richardson 			dev_info.rx_desc_lim.nb_min,
215599a2dd95SBruce Richardson 			dev_info.rx_desc_lim.nb_align);
215699a2dd95SBruce Richardson 		return -EINVAL;
215799a2dd95SBruce Richardson 	}
215899a2dd95SBruce Richardson 
215999a2dd95SBruce Richardson 	if (dev->data->dev_started &&
216099a2dd95SBruce Richardson 		!(dev_info.dev_capa &
216199a2dd95SBruce Richardson 			RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP))
216299a2dd95SBruce Richardson 		return -EBUSY;
216399a2dd95SBruce Richardson 
216499a2dd95SBruce Richardson 	if (dev->data->dev_started &&
216599a2dd95SBruce Richardson 		(dev->data->rx_queue_state[rx_queue_id] !=
216699a2dd95SBruce Richardson 			RTE_ETH_QUEUE_STATE_STOPPED))
216799a2dd95SBruce Richardson 		return -EBUSY;
216899a2dd95SBruce Richardson 
216949ed3224SXueming Li 	eth_dev_rxq_release(dev, rx_queue_id);
217099a2dd95SBruce Richardson 
217199a2dd95SBruce Richardson 	if (rx_conf == NULL)
217299a2dd95SBruce Richardson 		rx_conf = &dev_info.default_rxconf;
217399a2dd95SBruce Richardson 
217499a2dd95SBruce Richardson 	local_conf = *rx_conf;
217599a2dd95SBruce Richardson 
217699a2dd95SBruce Richardson 	/*
217799a2dd95SBruce Richardson 	 * If an offloading has already been enabled in
217899a2dd95SBruce Richardson 	 * rte_eth_dev_configure(), it has been enabled on all queues,
217999a2dd95SBruce Richardson 	 * so there is no need to enable it in this queue again.
218099a2dd95SBruce Richardson 	 * The local_conf.offloads input to underlying PMD only carries
218199a2dd95SBruce Richardson 	 * those offloadings which are only enabled on this queue and
218299a2dd95SBruce Richardson 	 * not enabled on all queues.
218399a2dd95SBruce Richardson 	 */
218499a2dd95SBruce Richardson 	local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads;
218599a2dd95SBruce Richardson 
218699a2dd95SBruce Richardson 	/*
218799a2dd95SBruce Richardson 	 * New added offloadings for this queue are those not enabled in
218899a2dd95SBruce Richardson 	 * rte_eth_dev_configure() and they must be per-queue type.
218999a2dd95SBruce Richardson 	 * A pure per-port offloading can't be enabled on a queue while
219099a2dd95SBruce Richardson 	 * disabled on another queue. A pure per-port offloading can't
219199a2dd95SBruce Richardson 	 * be enabled for any queue as new added one if it hasn't been
219299a2dd95SBruce Richardson 	 * enabled in rte_eth_dev_configure().
219399a2dd95SBruce Richardson 	 */
219499a2dd95SBruce Richardson 	if ((local_conf.offloads & dev_info.rx_queue_offload_capa) !=
219599a2dd95SBruce Richardson 	     local_conf.offloads) {
219699a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
219799a2dd95SBruce Richardson 			"Ethdev port_id=%d rx_queue_id=%d, new added offloads 0x%"PRIx64" must be "
219899a2dd95SBruce Richardson 			"within per-queue offload capabilities 0x%"PRIx64" in %s()\n",
219999a2dd95SBruce Richardson 			port_id, rx_queue_id, local_conf.offloads,
220099a2dd95SBruce Richardson 			dev_info.rx_queue_offload_capa,
220199a2dd95SBruce Richardson 			__func__);
220299a2dd95SBruce Richardson 		return -EINVAL;
220399a2dd95SBruce Richardson 	}
220499a2dd95SBruce Richardson 
2205dd22740cSXueming Li 	if (local_conf.share_group > 0 &&
2206dd22740cSXueming Li 	    (dev_info.dev_capa & RTE_ETH_DEV_CAPA_RXQ_SHARE) == 0) {
2207dd22740cSXueming Li 		RTE_ETHDEV_LOG(ERR,
2208dd22740cSXueming Li 			"Ethdev port_id=%d rx_queue_id=%d, enabled share_group=%hu while device doesn't support Rx queue share\n",
2209dd22740cSXueming Li 			port_id, rx_queue_id, local_conf.share_group);
2210dd22740cSXueming Li 		return -EINVAL;
2211dd22740cSXueming Li 	}
2212dd22740cSXueming Li 
221399a2dd95SBruce Richardson 	/*
221499a2dd95SBruce Richardson 	 * If LRO is enabled, check that the maximum aggregated packet
221599a2dd95SBruce Richardson 	 * size is supported by the configured device.
221699a2dd95SBruce Richardson 	 */
22171bb4a528SFerruh Yigit 	/* Get the real Ethernet overhead length */
2218295968d1SFerruh Yigit 	if (local_conf.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) {
22191bb4a528SFerruh Yigit 		uint32_t overhead_len;
22201bb4a528SFerruh Yigit 		uint32_t max_rx_pktlen;
22211bb4a528SFerruh Yigit 		int ret;
22221bb4a528SFerruh Yigit 
22231bb4a528SFerruh Yigit 		overhead_len = eth_dev_get_overhead_len(dev_info.max_rx_pktlen,
22241bb4a528SFerruh Yigit 				dev_info.max_mtu);
22251bb4a528SFerruh Yigit 		max_rx_pktlen = dev->data->mtu + overhead_len;
222699a2dd95SBruce Richardson 		if (dev->data->dev_conf.rxmode.max_lro_pkt_size == 0)
22271bb4a528SFerruh Yigit 			dev->data->dev_conf.rxmode.max_lro_pkt_size = max_rx_pktlen;
22281bb4a528SFerruh Yigit 		ret = eth_dev_check_lro_pkt_size(port_id,
222999a2dd95SBruce Richardson 				dev->data->dev_conf.rxmode.max_lro_pkt_size,
22301bb4a528SFerruh Yigit 				max_rx_pktlen,
223199a2dd95SBruce Richardson 				dev_info.max_lro_pkt_size);
223299a2dd95SBruce Richardson 		if (ret != 0)
223399a2dd95SBruce Richardson 			return ret;
223499a2dd95SBruce Richardson 	}
223599a2dd95SBruce Richardson 
223699a2dd95SBruce Richardson 	ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
223799a2dd95SBruce Richardson 					      socket_id, &local_conf, mp);
223899a2dd95SBruce Richardson 	if (!ret) {
223999a2dd95SBruce Richardson 		if (!dev->data->min_rx_buf_size ||
224099a2dd95SBruce Richardson 		    dev->data->min_rx_buf_size > mbp_buf_size)
224199a2dd95SBruce Richardson 			dev->data->min_rx_buf_size = mbp_buf_size;
224299a2dd95SBruce Richardson 	}
224399a2dd95SBruce Richardson 
224499a2dd95SBruce Richardson 	rte_ethdev_trace_rxq_setup(port_id, rx_queue_id, nb_rx_desc, mp,
224599a2dd95SBruce Richardson 		rx_conf, ret);
224699a2dd95SBruce Richardson 	return eth_err(port_id, ret);
224799a2dd95SBruce Richardson }
224899a2dd95SBruce Richardson 
224999a2dd95SBruce Richardson int
225099a2dd95SBruce Richardson rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
225199a2dd95SBruce Richardson 			       uint16_t nb_rx_desc,
225299a2dd95SBruce Richardson 			       const struct rte_eth_hairpin_conf *conf)
225399a2dd95SBruce Richardson {
225499a2dd95SBruce Richardson 	int ret;
225599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
225699a2dd95SBruce Richardson 	struct rte_eth_hairpin_cap cap;
225799a2dd95SBruce Richardson 	int i;
225899a2dd95SBruce Richardson 	int count;
225999a2dd95SBruce Richardson 
226099a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
226199a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
226253ef1b34SMin Hu (Connor) 
226399a2dd95SBruce Richardson 	if (rx_queue_id >= dev->data->nb_rx_queues) {
226409fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", rx_queue_id);
226599a2dd95SBruce Richardson 		return -EINVAL;
226699a2dd95SBruce Richardson 	}
226753ef1b34SMin Hu (Connor) 
226853ef1b34SMin Hu (Connor) 	if (conf == NULL) {
226953ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
227053ef1b34SMin Hu (Connor) 			"Cannot setup ethdev port %u Rx hairpin queue from NULL config\n",
227153ef1b34SMin Hu (Connor) 			port_id);
227253ef1b34SMin Hu (Connor) 		return -EINVAL;
227353ef1b34SMin Hu (Connor) 	}
227453ef1b34SMin Hu (Connor) 
227599a2dd95SBruce Richardson 	ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
227699a2dd95SBruce Richardson 	if (ret != 0)
227799a2dd95SBruce Richardson 		return ret;
227899a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_hairpin_queue_setup,
227999a2dd95SBruce Richardson 				-ENOTSUP);
228099a2dd95SBruce Richardson 	/* if nb_rx_desc is zero use max number of desc from the driver. */
228199a2dd95SBruce Richardson 	if (nb_rx_desc == 0)
228299a2dd95SBruce Richardson 		nb_rx_desc = cap.max_nb_desc;
228399a2dd95SBruce Richardson 	if (nb_rx_desc > cap.max_nb_desc) {
228499a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
228599a2dd95SBruce Richardson 			"Invalid value for nb_rx_desc(=%hu), should be: <= %hu",
228699a2dd95SBruce Richardson 			nb_rx_desc, cap.max_nb_desc);
228799a2dd95SBruce Richardson 		return -EINVAL;
228899a2dd95SBruce Richardson 	}
228999a2dd95SBruce Richardson 	if (conf->peer_count > cap.max_rx_2_tx) {
229099a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
229199a2dd95SBruce Richardson 			"Invalid value for number of peers for Rx queue(=%u), should be: <= %hu",
229299a2dd95SBruce Richardson 			conf->peer_count, cap.max_rx_2_tx);
229399a2dd95SBruce Richardson 		return -EINVAL;
229499a2dd95SBruce Richardson 	}
229599a2dd95SBruce Richardson 	if (conf->peer_count == 0) {
229699a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
229799a2dd95SBruce Richardson 			"Invalid value for number of peers for Rx queue(=%u), should be: > 0",
229899a2dd95SBruce Richardson 			conf->peer_count);
229999a2dd95SBruce Richardson 		return -EINVAL;
230099a2dd95SBruce Richardson 	}
230199a2dd95SBruce Richardson 	for (i = 0, count = 0; i < dev->data->nb_rx_queues &&
230299a2dd95SBruce Richardson 	     cap.max_nb_queues != UINT16_MAX; i++) {
230399a2dd95SBruce Richardson 		if (i == rx_queue_id || rte_eth_dev_is_rx_hairpin_queue(dev, i))
230499a2dd95SBruce Richardson 			count++;
230599a2dd95SBruce Richardson 	}
230699a2dd95SBruce Richardson 	if (count > cap.max_nb_queues) {
230799a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "To many Rx hairpin queues max is %d",
230899a2dd95SBruce Richardson 		cap.max_nb_queues);
230999a2dd95SBruce Richardson 		return -EINVAL;
231099a2dd95SBruce Richardson 	}
231199a2dd95SBruce Richardson 	if (dev->data->dev_started)
231299a2dd95SBruce Richardson 		return -EBUSY;
231349ed3224SXueming Li 	eth_dev_rxq_release(dev, rx_queue_id);
231499a2dd95SBruce Richardson 	ret = (*dev->dev_ops->rx_hairpin_queue_setup)(dev, rx_queue_id,
231599a2dd95SBruce Richardson 						      nb_rx_desc, conf);
231699a2dd95SBruce Richardson 	if (ret == 0)
231799a2dd95SBruce Richardson 		dev->data->rx_queue_state[rx_queue_id] =
231899a2dd95SBruce Richardson 			RTE_ETH_QUEUE_STATE_HAIRPIN;
231999a2dd95SBruce Richardson 	return eth_err(port_id, ret);
232099a2dd95SBruce Richardson }
232199a2dd95SBruce Richardson 
232299a2dd95SBruce Richardson int
232399a2dd95SBruce Richardson rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
232499a2dd95SBruce Richardson 		       uint16_t nb_tx_desc, unsigned int socket_id,
232599a2dd95SBruce Richardson 		       const struct rte_eth_txconf *tx_conf)
232699a2dd95SBruce Richardson {
232799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
232899a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info;
232999a2dd95SBruce Richardson 	struct rte_eth_txconf local_conf;
233099a2dd95SBruce Richardson 	int ret;
233199a2dd95SBruce Richardson 
233299a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
233399a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
233453ef1b34SMin Hu (Connor) 
233599a2dd95SBruce Richardson 	if (tx_queue_id >= dev->data->nb_tx_queues) {
233609fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", tx_queue_id);
233799a2dd95SBruce Richardson 		return -EINVAL;
233899a2dd95SBruce Richardson 	}
233999a2dd95SBruce Richardson 
234099a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -ENOTSUP);
234199a2dd95SBruce Richardson 
234299a2dd95SBruce Richardson 	ret = rte_eth_dev_info_get(port_id, &dev_info);
234399a2dd95SBruce Richardson 	if (ret != 0)
234499a2dd95SBruce Richardson 		return ret;
234599a2dd95SBruce Richardson 
234699a2dd95SBruce Richardson 	/* Use default specified by driver, if nb_tx_desc is zero */
234799a2dd95SBruce Richardson 	if (nb_tx_desc == 0) {
234899a2dd95SBruce Richardson 		nb_tx_desc = dev_info.default_txportconf.ring_size;
234999a2dd95SBruce Richardson 		/* If driver default is zero, fall back on EAL default */
235099a2dd95SBruce Richardson 		if (nb_tx_desc == 0)
235199a2dd95SBruce Richardson 			nb_tx_desc = RTE_ETH_DEV_FALLBACK_TX_RINGSIZE;
235299a2dd95SBruce Richardson 	}
235399a2dd95SBruce Richardson 	if (nb_tx_desc > dev_info.tx_desc_lim.nb_max ||
235499a2dd95SBruce Richardson 	    nb_tx_desc < dev_info.tx_desc_lim.nb_min ||
235599a2dd95SBruce Richardson 	    nb_tx_desc % dev_info.tx_desc_lim.nb_align != 0) {
235699a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
235799a2dd95SBruce Richardson 			"Invalid value for nb_tx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n",
235899a2dd95SBruce Richardson 			nb_tx_desc, dev_info.tx_desc_lim.nb_max,
235999a2dd95SBruce Richardson 			dev_info.tx_desc_lim.nb_min,
236099a2dd95SBruce Richardson 			dev_info.tx_desc_lim.nb_align);
236199a2dd95SBruce Richardson 		return -EINVAL;
236299a2dd95SBruce Richardson 	}
236399a2dd95SBruce Richardson 
236499a2dd95SBruce Richardson 	if (dev->data->dev_started &&
236599a2dd95SBruce Richardson 		!(dev_info.dev_capa &
236699a2dd95SBruce Richardson 			RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP))
236799a2dd95SBruce Richardson 		return -EBUSY;
236899a2dd95SBruce Richardson 
236999a2dd95SBruce Richardson 	if (dev->data->dev_started &&
237099a2dd95SBruce Richardson 		(dev->data->tx_queue_state[tx_queue_id] !=
237199a2dd95SBruce Richardson 			RTE_ETH_QUEUE_STATE_STOPPED))
237299a2dd95SBruce Richardson 		return -EBUSY;
237399a2dd95SBruce Richardson 
237449ed3224SXueming Li 	eth_dev_txq_release(dev, tx_queue_id);
237599a2dd95SBruce Richardson 
237699a2dd95SBruce Richardson 	if (tx_conf == NULL)
237799a2dd95SBruce Richardson 		tx_conf = &dev_info.default_txconf;
237899a2dd95SBruce Richardson 
237999a2dd95SBruce Richardson 	local_conf = *tx_conf;
238099a2dd95SBruce Richardson 
238199a2dd95SBruce Richardson 	/*
238299a2dd95SBruce Richardson 	 * If an offloading has already been enabled in
238399a2dd95SBruce Richardson 	 * rte_eth_dev_configure(), it has been enabled on all queues,
238499a2dd95SBruce Richardson 	 * so there is no need to enable it in this queue again.
238599a2dd95SBruce Richardson 	 * The local_conf.offloads input to underlying PMD only carries
238699a2dd95SBruce Richardson 	 * those offloadings which are only enabled on this queue and
238799a2dd95SBruce Richardson 	 * not enabled on all queues.
238899a2dd95SBruce Richardson 	 */
238999a2dd95SBruce Richardson 	local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads;
239099a2dd95SBruce Richardson 
239199a2dd95SBruce Richardson 	/*
239299a2dd95SBruce Richardson 	 * New added offloadings for this queue are those not enabled in
239399a2dd95SBruce Richardson 	 * rte_eth_dev_configure() and they must be per-queue type.
239499a2dd95SBruce Richardson 	 * A pure per-port offloading can't be enabled on a queue while
239599a2dd95SBruce Richardson 	 * disabled on another queue. A pure per-port offloading can't
239699a2dd95SBruce Richardson 	 * be enabled for any queue as new added one if it hasn't been
239799a2dd95SBruce Richardson 	 * enabled in rte_eth_dev_configure().
239899a2dd95SBruce Richardson 	 */
239999a2dd95SBruce Richardson 	if ((local_conf.offloads & dev_info.tx_queue_offload_capa) !=
240099a2dd95SBruce Richardson 	     local_conf.offloads) {
240199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
240299a2dd95SBruce Richardson 			"Ethdev port_id=%d tx_queue_id=%d, new added offloads 0x%"PRIx64" must be "
240399a2dd95SBruce Richardson 			"within per-queue offload capabilities 0x%"PRIx64" in %s()\n",
240499a2dd95SBruce Richardson 			port_id, tx_queue_id, local_conf.offloads,
240599a2dd95SBruce Richardson 			dev_info.tx_queue_offload_capa,
240699a2dd95SBruce Richardson 			__func__);
240799a2dd95SBruce Richardson 		return -EINVAL;
240899a2dd95SBruce Richardson 	}
240999a2dd95SBruce Richardson 
241099a2dd95SBruce Richardson 	rte_ethdev_trace_txq_setup(port_id, tx_queue_id, nb_tx_desc, tx_conf);
241199a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
241299a2dd95SBruce Richardson 		       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
241399a2dd95SBruce Richardson }
241499a2dd95SBruce Richardson 
241599a2dd95SBruce Richardson int
241699a2dd95SBruce Richardson rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
241799a2dd95SBruce Richardson 			       uint16_t nb_tx_desc,
241899a2dd95SBruce Richardson 			       const struct rte_eth_hairpin_conf *conf)
241999a2dd95SBruce Richardson {
242099a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
242199a2dd95SBruce Richardson 	struct rte_eth_hairpin_cap cap;
242299a2dd95SBruce Richardson 	int i;
242399a2dd95SBruce Richardson 	int count;
242499a2dd95SBruce Richardson 	int ret;
242599a2dd95SBruce Richardson 
242699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
242799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
242853ef1b34SMin Hu (Connor) 
242999a2dd95SBruce Richardson 	if (tx_queue_id >= dev->data->nb_tx_queues) {
243009fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", tx_queue_id);
243199a2dd95SBruce Richardson 		return -EINVAL;
243299a2dd95SBruce Richardson 	}
243353ef1b34SMin Hu (Connor) 
243453ef1b34SMin Hu (Connor) 	if (conf == NULL) {
243553ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
243653ef1b34SMin Hu (Connor) 			"Cannot setup ethdev port %u Tx hairpin queue from NULL config\n",
243753ef1b34SMin Hu (Connor) 			port_id);
243853ef1b34SMin Hu (Connor) 		return -EINVAL;
243953ef1b34SMin Hu (Connor) 	}
244053ef1b34SMin Hu (Connor) 
244199a2dd95SBruce Richardson 	ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
244299a2dd95SBruce Richardson 	if (ret != 0)
244399a2dd95SBruce Richardson 		return ret;
244499a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_hairpin_queue_setup,
244599a2dd95SBruce Richardson 				-ENOTSUP);
244699a2dd95SBruce Richardson 	/* if nb_rx_desc is zero use max number of desc from the driver. */
244799a2dd95SBruce Richardson 	if (nb_tx_desc == 0)
244899a2dd95SBruce Richardson 		nb_tx_desc = cap.max_nb_desc;
244999a2dd95SBruce Richardson 	if (nb_tx_desc > cap.max_nb_desc) {
245099a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
245199a2dd95SBruce Richardson 			"Invalid value for nb_tx_desc(=%hu), should be: <= %hu",
245299a2dd95SBruce Richardson 			nb_tx_desc, cap.max_nb_desc);
245399a2dd95SBruce Richardson 		return -EINVAL;
245499a2dd95SBruce Richardson 	}
245599a2dd95SBruce Richardson 	if (conf->peer_count > cap.max_tx_2_rx) {
245699a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
245799a2dd95SBruce Richardson 			"Invalid value for number of peers for Tx queue(=%u), should be: <= %hu",
245899a2dd95SBruce Richardson 			conf->peer_count, cap.max_tx_2_rx);
245999a2dd95SBruce Richardson 		return -EINVAL;
246099a2dd95SBruce Richardson 	}
246199a2dd95SBruce Richardson 	if (conf->peer_count == 0) {
246299a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
246399a2dd95SBruce Richardson 			"Invalid value for number of peers for Tx queue(=%u), should be: > 0",
246499a2dd95SBruce Richardson 			conf->peer_count);
246599a2dd95SBruce Richardson 		return -EINVAL;
246699a2dd95SBruce Richardson 	}
246799a2dd95SBruce Richardson 	for (i = 0, count = 0; i < dev->data->nb_tx_queues &&
246899a2dd95SBruce Richardson 	     cap.max_nb_queues != UINT16_MAX; i++) {
246999a2dd95SBruce Richardson 		if (i == tx_queue_id || rte_eth_dev_is_tx_hairpin_queue(dev, i))
247099a2dd95SBruce Richardson 			count++;
247199a2dd95SBruce Richardson 	}
247299a2dd95SBruce Richardson 	if (count > cap.max_nb_queues) {
247399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "To many Tx hairpin queues max is %d",
247499a2dd95SBruce Richardson 		cap.max_nb_queues);
247599a2dd95SBruce Richardson 		return -EINVAL;
247699a2dd95SBruce Richardson 	}
247799a2dd95SBruce Richardson 	if (dev->data->dev_started)
247899a2dd95SBruce Richardson 		return -EBUSY;
247949ed3224SXueming Li 	eth_dev_txq_release(dev, tx_queue_id);
248099a2dd95SBruce Richardson 	ret = (*dev->dev_ops->tx_hairpin_queue_setup)
248199a2dd95SBruce Richardson 		(dev, tx_queue_id, nb_tx_desc, conf);
248299a2dd95SBruce Richardson 	if (ret == 0)
248399a2dd95SBruce Richardson 		dev->data->tx_queue_state[tx_queue_id] =
248499a2dd95SBruce Richardson 			RTE_ETH_QUEUE_STATE_HAIRPIN;
248599a2dd95SBruce Richardson 	return eth_err(port_id, ret);
248699a2dd95SBruce Richardson }
248799a2dd95SBruce Richardson 
248899a2dd95SBruce Richardson int
248999a2dd95SBruce Richardson rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port)
249099a2dd95SBruce Richardson {
249199a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
249299a2dd95SBruce Richardson 	int ret;
249399a2dd95SBruce Richardson 
249499a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV);
249599a2dd95SBruce Richardson 	dev = &rte_eth_devices[tx_port];
249653ef1b34SMin Hu (Connor) 
249799a2dd95SBruce Richardson 	if (dev->data->dev_started == 0) {
249899a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Tx port %d is not started\n", tx_port);
249999a2dd95SBruce Richardson 		return -EBUSY;
250099a2dd95SBruce Richardson 	}
250199a2dd95SBruce Richardson 
250299a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_bind, -ENOTSUP);
250399a2dd95SBruce Richardson 	ret = (*dev->dev_ops->hairpin_bind)(dev, rx_port);
250499a2dd95SBruce Richardson 	if (ret != 0)
250599a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Failed to bind hairpin Tx %d"
250699a2dd95SBruce Richardson 			       " to Rx %d (%d - all ports)\n",
250799a2dd95SBruce Richardson 			       tx_port, rx_port, RTE_MAX_ETHPORTS);
250899a2dd95SBruce Richardson 
250999a2dd95SBruce Richardson 	return ret;
251099a2dd95SBruce Richardson }
251199a2dd95SBruce Richardson 
251299a2dd95SBruce Richardson int
251399a2dd95SBruce Richardson rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port)
251499a2dd95SBruce Richardson {
251599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
251699a2dd95SBruce Richardson 	int ret;
251799a2dd95SBruce Richardson 
251899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV);
251999a2dd95SBruce Richardson 	dev = &rte_eth_devices[tx_port];
252053ef1b34SMin Hu (Connor) 
252199a2dd95SBruce Richardson 	if (dev->data->dev_started == 0) {
252299a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Tx port %d is already stopped\n", tx_port);
252399a2dd95SBruce Richardson 		return -EBUSY;
252499a2dd95SBruce Richardson 	}
252599a2dd95SBruce Richardson 
252699a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_unbind, -ENOTSUP);
252799a2dd95SBruce Richardson 	ret = (*dev->dev_ops->hairpin_unbind)(dev, rx_port);
252899a2dd95SBruce Richardson 	if (ret != 0)
252999a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Failed to unbind hairpin Tx %d"
253099a2dd95SBruce Richardson 			       " from Rx %d (%d - all ports)\n",
253199a2dd95SBruce Richardson 			       tx_port, rx_port, RTE_MAX_ETHPORTS);
253299a2dd95SBruce Richardson 
253399a2dd95SBruce Richardson 	return ret;
253499a2dd95SBruce Richardson }
253599a2dd95SBruce Richardson 
253699a2dd95SBruce Richardson int
253799a2dd95SBruce Richardson rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports,
253899a2dd95SBruce Richardson 			       size_t len, uint32_t direction)
253999a2dd95SBruce Richardson {
254099a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
254199a2dd95SBruce Richardson 	int ret;
254299a2dd95SBruce Richardson 
254399a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
254499a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
254553ef1b34SMin Hu (Connor) 
254653ef1b34SMin Hu (Connor) 	if (peer_ports == NULL) {
254753ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
254853ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u hairpin peer ports to NULL\n",
254953ef1b34SMin Hu (Connor) 			port_id);
255053ef1b34SMin Hu (Connor) 		return -EINVAL;
255153ef1b34SMin Hu (Connor) 	}
255253ef1b34SMin Hu (Connor) 
255353ef1b34SMin Hu (Connor) 	if (len == 0) {
255453ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
255553ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u hairpin peer ports to array with zero size\n",
255653ef1b34SMin Hu (Connor) 			port_id);
255753ef1b34SMin Hu (Connor) 		return -EINVAL;
255853ef1b34SMin Hu (Connor) 	}
255953ef1b34SMin Hu (Connor) 
256099a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_get_peer_ports,
256199a2dd95SBruce Richardson 				-ENOTSUP);
256299a2dd95SBruce Richardson 
256399a2dd95SBruce Richardson 	ret = (*dev->dev_ops->hairpin_get_peer_ports)(dev, peer_ports,
256499a2dd95SBruce Richardson 						      len, direction);
256599a2dd95SBruce Richardson 	if (ret < 0)
256699a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Failed to get %d hairpin peer %s ports\n",
256799a2dd95SBruce Richardson 			       port_id, direction ? "Rx" : "Tx");
256899a2dd95SBruce Richardson 
256999a2dd95SBruce Richardson 	return ret;
257099a2dd95SBruce Richardson }
257199a2dd95SBruce Richardson 
257299a2dd95SBruce Richardson void
257399a2dd95SBruce Richardson rte_eth_tx_buffer_drop_callback(struct rte_mbuf **pkts, uint16_t unsent,
257499a2dd95SBruce Richardson 		void *userdata __rte_unused)
257599a2dd95SBruce Richardson {
257699a2dd95SBruce Richardson 	rte_pktmbuf_free_bulk(pkts, unsent);
257799a2dd95SBruce Richardson }
257899a2dd95SBruce Richardson 
257999a2dd95SBruce Richardson void
258099a2dd95SBruce Richardson rte_eth_tx_buffer_count_callback(struct rte_mbuf **pkts, uint16_t unsent,
258199a2dd95SBruce Richardson 		void *userdata)
258299a2dd95SBruce Richardson {
258399a2dd95SBruce Richardson 	uint64_t *count = userdata;
258499a2dd95SBruce Richardson 
258599a2dd95SBruce Richardson 	rte_pktmbuf_free_bulk(pkts, unsent);
258699a2dd95SBruce Richardson 	*count += unsent;
258799a2dd95SBruce Richardson }
258899a2dd95SBruce Richardson 
258999a2dd95SBruce Richardson int
259099a2dd95SBruce Richardson rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
259199a2dd95SBruce Richardson 		buffer_tx_error_fn cbfn, void *userdata)
259299a2dd95SBruce Richardson {
259353ef1b34SMin Hu (Connor) 	if (buffer == NULL) {
259453ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
259553ef1b34SMin Hu (Connor) 			"Cannot set Tx buffer error callback to NULL buffer\n");
259653ef1b34SMin Hu (Connor) 		return -EINVAL;
259753ef1b34SMin Hu (Connor) 	}
259853ef1b34SMin Hu (Connor) 
259999a2dd95SBruce Richardson 	buffer->error_callback = cbfn;
260099a2dd95SBruce Richardson 	buffer->error_userdata = userdata;
260199a2dd95SBruce Richardson 	return 0;
260299a2dd95SBruce Richardson }
260399a2dd95SBruce Richardson 
260499a2dd95SBruce Richardson int
260599a2dd95SBruce Richardson rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size)
260699a2dd95SBruce Richardson {
260799a2dd95SBruce Richardson 	int ret = 0;
260899a2dd95SBruce Richardson 
260953ef1b34SMin Hu (Connor) 	if (buffer == NULL) {
261053ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot initialize NULL buffer\n");
261199a2dd95SBruce Richardson 		return -EINVAL;
261253ef1b34SMin Hu (Connor) 	}
261399a2dd95SBruce Richardson 
261499a2dd95SBruce Richardson 	buffer->size = size;
261599a2dd95SBruce Richardson 	if (buffer->error_callback == NULL) {
261699a2dd95SBruce Richardson 		ret = rte_eth_tx_buffer_set_err_callback(
261799a2dd95SBruce Richardson 			buffer, rte_eth_tx_buffer_drop_callback, NULL);
261899a2dd95SBruce Richardson 	}
261999a2dd95SBruce Richardson 
262099a2dd95SBruce Richardson 	return ret;
262199a2dd95SBruce Richardson }
262299a2dd95SBruce Richardson 
262399a2dd95SBruce Richardson int
262499a2dd95SBruce Richardson rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
262599a2dd95SBruce Richardson {
262653ef1b34SMin Hu (Connor) 	struct rte_eth_dev *dev;
262799a2dd95SBruce Richardson 	int ret;
262899a2dd95SBruce Richardson 
262999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
263053ef1b34SMin Hu (Connor) 	dev = &rte_eth_devices[port_id];
263153ef1b34SMin Hu (Connor) 
263299a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
263399a2dd95SBruce Richardson 
263499a2dd95SBruce Richardson 	/* Call driver to free pending mbufs. */
263599a2dd95SBruce Richardson 	ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id],
263699a2dd95SBruce Richardson 					       free_cnt);
263799a2dd95SBruce Richardson 	return eth_err(port_id, ret);
263899a2dd95SBruce Richardson }
263999a2dd95SBruce Richardson 
264099a2dd95SBruce Richardson int
264199a2dd95SBruce Richardson rte_eth_promiscuous_enable(uint16_t port_id)
264299a2dd95SBruce Richardson {
264399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
264499a2dd95SBruce Richardson 	int diag = 0;
264599a2dd95SBruce Richardson 
264699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
264799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
264899a2dd95SBruce Richardson 
264999a2dd95SBruce Richardson 	if (dev->data->promiscuous == 1)
265099a2dd95SBruce Richardson 		return 0;
265199a2dd95SBruce Richardson 
265299a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_enable, -ENOTSUP);
265399a2dd95SBruce Richardson 
265499a2dd95SBruce Richardson 	diag = (*dev->dev_ops->promiscuous_enable)(dev);
265599a2dd95SBruce Richardson 	dev->data->promiscuous = (diag == 0) ? 1 : 0;
265699a2dd95SBruce Richardson 
265799a2dd95SBruce Richardson 	return eth_err(port_id, diag);
265899a2dd95SBruce Richardson }
265999a2dd95SBruce Richardson 
266099a2dd95SBruce Richardson int
266199a2dd95SBruce Richardson rte_eth_promiscuous_disable(uint16_t port_id)
266299a2dd95SBruce Richardson {
266399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
266499a2dd95SBruce Richardson 	int diag = 0;
266599a2dd95SBruce Richardson 
266699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
266799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
266899a2dd95SBruce Richardson 
266999a2dd95SBruce Richardson 	if (dev->data->promiscuous == 0)
267099a2dd95SBruce Richardson 		return 0;
267199a2dd95SBruce Richardson 
267299a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_disable, -ENOTSUP);
267399a2dd95SBruce Richardson 
267499a2dd95SBruce Richardson 	dev->data->promiscuous = 0;
267599a2dd95SBruce Richardson 	diag = (*dev->dev_ops->promiscuous_disable)(dev);
267699a2dd95SBruce Richardson 	if (diag != 0)
267799a2dd95SBruce Richardson 		dev->data->promiscuous = 1;
267899a2dd95SBruce Richardson 
267999a2dd95SBruce Richardson 	return eth_err(port_id, diag);
268099a2dd95SBruce Richardson }
268199a2dd95SBruce Richardson 
268299a2dd95SBruce Richardson int
268399a2dd95SBruce Richardson rte_eth_promiscuous_get(uint16_t port_id)
268499a2dd95SBruce Richardson {
268599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
268699a2dd95SBruce Richardson 
268799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
268899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
268953ef1b34SMin Hu (Connor) 
269099a2dd95SBruce Richardson 	return dev->data->promiscuous;
269199a2dd95SBruce Richardson }
269299a2dd95SBruce Richardson 
269399a2dd95SBruce Richardson int
269499a2dd95SBruce Richardson rte_eth_allmulticast_enable(uint16_t port_id)
269599a2dd95SBruce Richardson {
269699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
269799a2dd95SBruce Richardson 	int diag;
269899a2dd95SBruce Richardson 
269999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
270099a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
270199a2dd95SBruce Richardson 
270299a2dd95SBruce Richardson 	if (dev->data->all_multicast == 1)
270399a2dd95SBruce Richardson 		return 0;
270499a2dd95SBruce Richardson 
270599a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_enable, -ENOTSUP);
270699a2dd95SBruce Richardson 	diag = (*dev->dev_ops->allmulticast_enable)(dev);
270799a2dd95SBruce Richardson 	dev->data->all_multicast = (diag == 0) ? 1 : 0;
270899a2dd95SBruce Richardson 
270999a2dd95SBruce Richardson 	return eth_err(port_id, diag);
271099a2dd95SBruce Richardson }
271199a2dd95SBruce Richardson 
271299a2dd95SBruce Richardson int
271399a2dd95SBruce Richardson rte_eth_allmulticast_disable(uint16_t port_id)
271499a2dd95SBruce Richardson {
271599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
271699a2dd95SBruce Richardson 	int diag;
271799a2dd95SBruce Richardson 
271899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
271999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
272099a2dd95SBruce Richardson 
272199a2dd95SBruce Richardson 	if (dev->data->all_multicast == 0)
272299a2dd95SBruce Richardson 		return 0;
272399a2dd95SBruce Richardson 
272499a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_disable, -ENOTSUP);
272599a2dd95SBruce Richardson 	dev->data->all_multicast = 0;
272699a2dd95SBruce Richardson 	diag = (*dev->dev_ops->allmulticast_disable)(dev);
272799a2dd95SBruce Richardson 	if (diag != 0)
272899a2dd95SBruce Richardson 		dev->data->all_multicast = 1;
272999a2dd95SBruce Richardson 
273099a2dd95SBruce Richardson 	return eth_err(port_id, diag);
273199a2dd95SBruce Richardson }
273299a2dd95SBruce Richardson 
273399a2dd95SBruce Richardson int
273499a2dd95SBruce Richardson rte_eth_allmulticast_get(uint16_t port_id)
273599a2dd95SBruce Richardson {
273699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
273799a2dd95SBruce Richardson 
273899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
273999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
274053ef1b34SMin Hu (Connor) 
274199a2dd95SBruce Richardson 	return dev->data->all_multicast;
274299a2dd95SBruce Richardson }
274399a2dd95SBruce Richardson 
274499a2dd95SBruce Richardson int
274599a2dd95SBruce Richardson rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
274699a2dd95SBruce Richardson {
274799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
274899a2dd95SBruce Richardson 
274999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
275099a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
275199a2dd95SBruce Richardson 
275253ef1b34SMin Hu (Connor) 	if (eth_link == NULL) {
275353ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u link to NULL\n",
275453ef1b34SMin Hu (Connor) 			port_id);
275553ef1b34SMin Hu (Connor) 		return -EINVAL;
275653ef1b34SMin Hu (Connor) 	}
275753ef1b34SMin Hu (Connor) 
275853ef1b34SMin Hu (Connor) 	if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started)
275999a2dd95SBruce Richardson 		rte_eth_linkstatus_get(dev, eth_link);
276099a2dd95SBruce Richardson 	else {
276199a2dd95SBruce Richardson 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
276299a2dd95SBruce Richardson 		(*dev->dev_ops->link_update)(dev, 1);
276399a2dd95SBruce Richardson 		*eth_link = dev->data->dev_link;
276499a2dd95SBruce Richardson 	}
276599a2dd95SBruce Richardson 
276699a2dd95SBruce Richardson 	return 0;
276799a2dd95SBruce Richardson }
276899a2dd95SBruce Richardson 
276999a2dd95SBruce Richardson int
277099a2dd95SBruce Richardson rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
277199a2dd95SBruce Richardson {
277299a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
277399a2dd95SBruce Richardson 
277499a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
277599a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
277699a2dd95SBruce Richardson 
277753ef1b34SMin Hu (Connor) 	if (eth_link == NULL) {
277853ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u link to NULL\n",
277953ef1b34SMin Hu (Connor) 			port_id);
278053ef1b34SMin Hu (Connor) 		return -EINVAL;
278153ef1b34SMin Hu (Connor) 	}
278253ef1b34SMin Hu (Connor) 
278353ef1b34SMin Hu (Connor) 	if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started)
278499a2dd95SBruce Richardson 		rte_eth_linkstatus_get(dev, eth_link);
278599a2dd95SBruce Richardson 	else {
278699a2dd95SBruce Richardson 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
278799a2dd95SBruce Richardson 		(*dev->dev_ops->link_update)(dev, 0);
278899a2dd95SBruce Richardson 		*eth_link = dev->data->dev_link;
278999a2dd95SBruce Richardson 	}
279099a2dd95SBruce Richardson 
279199a2dd95SBruce Richardson 	return 0;
279299a2dd95SBruce Richardson }
279399a2dd95SBruce Richardson 
279499a2dd95SBruce Richardson const char *
279599a2dd95SBruce Richardson rte_eth_link_speed_to_str(uint32_t link_speed)
279699a2dd95SBruce Richardson {
279799a2dd95SBruce Richardson 	switch (link_speed) {
2798295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_NONE: return "None";
2799295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_10M:  return "10 Mbps";
2800295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_100M: return "100 Mbps";
2801295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_1G:   return "1 Gbps";
2802295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_2_5G: return "2.5 Gbps";
2803295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_5G:   return "5 Gbps";
2804295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_10G:  return "10 Gbps";
2805295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_20G:  return "20 Gbps";
2806295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_25G:  return "25 Gbps";
2807295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_40G:  return "40 Gbps";
2808295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_50G:  return "50 Gbps";
2809295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_56G:  return "56 Gbps";
2810295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_100G: return "100 Gbps";
2811295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_200G: return "200 Gbps";
2812295968d1SFerruh Yigit 	case RTE_ETH_SPEED_NUM_UNKNOWN: return "Unknown";
281399a2dd95SBruce Richardson 	default: return "Invalid";
281499a2dd95SBruce Richardson 	}
281599a2dd95SBruce Richardson }
281699a2dd95SBruce Richardson 
281799a2dd95SBruce Richardson int
281899a2dd95SBruce Richardson rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
281999a2dd95SBruce Richardson {
282053ef1b34SMin Hu (Connor) 	if (str == NULL) {
282153ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot convert link to NULL string\n");
282253ef1b34SMin Hu (Connor) 		return -EINVAL;
282353ef1b34SMin Hu (Connor) 	}
282453ef1b34SMin Hu (Connor) 
282553ef1b34SMin Hu (Connor) 	if (len == 0) {
282653ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
282753ef1b34SMin Hu (Connor) 			"Cannot convert link to string with zero size\n");
282853ef1b34SMin Hu (Connor) 		return -EINVAL;
282953ef1b34SMin Hu (Connor) 	}
283053ef1b34SMin Hu (Connor) 
283153ef1b34SMin Hu (Connor) 	if (eth_link == NULL) {
283253ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot convert to string from NULL link\n");
283353ef1b34SMin Hu (Connor) 		return -EINVAL;
283453ef1b34SMin Hu (Connor) 	}
283553ef1b34SMin Hu (Connor) 
2836295968d1SFerruh Yigit 	if (eth_link->link_status == RTE_ETH_LINK_DOWN)
283799a2dd95SBruce Richardson 		return snprintf(str, len, "Link down");
283899a2dd95SBruce Richardson 	else
283999a2dd95SBruce Richardson 		return snprintf(str, len, "Link up at %s %s %s",
284099a2dd95SBruce Richardson 			rte_eth_link_speed_to_str(eth_link->link_speed),
2841295968d1SFerruh Yigit 			(eth_link->link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ?
284299a2dd95SBruce Richardson 			"FDX" : "HDX",
2843295968d1SFerruh Yigit 			(eth_link->link_autoneg == RTE_ETH_LINK_AUTONEG) ?
284499a2dd95SBruce Richardson 			"Autoneg" : "Fixed");
284599a2dd95SBruce Richardson }
284699a2dd95SBruce Richardson 
284799a2dd95SBruce Richardson int
284899a2dd95SBruce Richardson rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
284999a2dd95SBruce Richardson {
285099a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
285199a2dd95SBruce Richardson 
285299a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
285399a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
285453ef1b34SMin Hu (Connor) 
285553ef1b34SMin Hu (Connor) 	if (stats == NULL) {
285653ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u stats to NULL\n",
285753ef1b34SMin Hu (Connor) 			port_id);
285853ef1b34SMin Hu (Connor) 		return -EINVAL;
285953ef1b34SMin Hu (Connor) 	}
286053ef1b34SMin Hu (Connor) 
286199a2dd95SBruce Richardson 	memset(stats, 0, sizeof(*stats));
286299a2dd95SBruce Richardson 
286399a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);
286499a2dd95SBruce Richardson 	stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
286599a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->stats_get)(dev, stats));
286699a2dd95SBruce Richardson }
286799a2dd95SBruce Richardson 
286899a2dd95SBruce Richardson int
286999a2dd95SBruce Richardson rte_eth_stats_reset(uint16_t port_id)
287099a2dd95SBruce Richardson {
287199a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
287299a2dd95SBruce Richardson 	int ret;
287399a2dd95SBruce Richardson 
287499a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
287599a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
287699a2dd95SBruce Richardson 
287799a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_reset, -ENOTSUP);
287899a2dd95SBruce Richardson 	ret = (*dev->dev_ops->stats_reset)(dev);
287999a2dd95SBruce Richardson 	if (ret != 0)
288099a2dd95SBruce Richardson 		return eth_err(port_id, ret);
288199a2dd95SBruce Richardson 
288299a2dd95SBruce Richardson 	dev->data->rx_mbuf_alloc_failed = 0;
288399a2dd95SBruce Richardson 
288499a2dd95SBruce Richardson 	return 0;
288599a2dd95SBruce Richardson }
288699a2dd95SBruce Richardson 
288799a2dd95SBruce Richardson static inline int
288899a2dd95SBruce Richardson eth_dev_get_xstats_basic_count(struct rte_eth_dev *dev)
288999a2dd95SBruce Richardson {
289099a2dd95SBruce Richardson 	uint16_t nb_rxqs, nb_txqs;
289199a2dd95SBruce Richardson 	int count;
289299a2dd95SBruce Richardson 
289399a2dd95SBruce Richardson 	nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
289499a2dd95SBruce Richardson 	nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
289599a2dd95SBruce Richardson 
289699a2dd95SBruce Richardson 	count = RTE_NB_STATS;
289799a2dd95SBruce Richardson 	if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) {
289899a2dd95SBruce Richardson 		count += nb_rxqs * RTE_NB_RXQ_STATS;
289999a2dd95SBruce Richardson 		count += nb_txqs * RTE_NB_TXQ_STATS;
290099a2dd95SBruce Richardson 	}
290199a2dd95SBruce Richardson 
290299a2dd95SBruce Richardson 	return count;
290399a2dd95SBruce Richardson }
290499a2dd95SBruce Richardson 
290599a2dd95SBruce Richardson static int
290699a2dd95SBruce Richardson eth_dev_get_xstats_count(uint16_t port_id)
290799a2dd95SBruce Richardson {
290899a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
290999a2dd95SBruce Richardson 	int count;
291099a2dd95SBruce Richardson 
291199a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
291299a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
291399a2dd95SBruce Richardson 	if (dev->dev_ops->xstats_get_names != NULL) {
291499a2dd95SBruce Richardson 		count = (*dev->dev_ops->xstats_get_names)(dev, NULL, 0);
291599a2dd95SBruce Richardson 		if (count < 0)
291699a2dd95SBruce Richardson 			return eth_err(port_id, count);
291799a2dd95SBruce Richardson 	} else
291899a2dd95SBruce Richardson 		count = 0;
291999a2dd95SBruce Richardson 
292099a2dd95SBruce Richardson 
292199a2dd95SBruce Richardson 	count += eth_dev_get_xstats_basic_count(dev);
292299a2dd95SBruce Richardson 
292399a2dd95SBruce Richardson 	return count;
292499a2dd95SBruce Richardson }
292599a2dd95SBruce Richardson 
292699a2dd95SBruce Richardson int
292799a2dd95SBruce Richardson rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
292899a2dd95SBruce Richardson 		uint64_t *id)
292999a2dd95SBruce Richardson {
293099a2dd95SBruce Richardson 	int cnt_xstats, idx_xstat;
293199a2dd95SBruce Richardson 
293299a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
293399a2dd95SBruce Richardson 
293453ef1b34SMin Hu (Connor) 	if (xstat_name == NULL) {
293553ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
293653ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u xstats ID from NULL xstat name\n",
293753ef1b34SMin Hu (Connor) 			port_id);
293899a2dd95SBruce Richardson 		return -ENOMEM;
293999a2dd95SBruce Richardson 	}
294099a2dd95SBruce Richardson 
294153ef1b34SMin Hu (Connor) 	if (id == NULL) {
294253ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
294353ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u xstats ID to NULL\n",
294453ef1b34SMin Hu (Connor) 			port_id);
294599a2dd95SBruce Richardson 		return -ENOMEM;
294699a2dd95SBruce Richardson 	}
294799a2dd95SBruce Richardson 
294899a2dd95SBruce Richardson 	/* Get count */
294999a2dd95SBruce Richardson 	cnt_xstats = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
295099a2dd95SBruce Richardson 	if (cnt_xstats  < 0) {
295199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Cannot get count of xstats\n");
295299a2dd95SBruce Richardson 		return -ENODEV;
295399a2dd95SBruce Richardson 	}
295499a2dd95SBruce Richardson 
295599a2dd95SBruce Richardson 	/* Get id-name lookup table */
295699a2dd95SBruce Richardson 	struct rte_eth_xstat_name xstats_names[cnt_xstats];
295799a2dd95SBruce Richardson 
295899a2dd95SBruce Richardson 	if (cnt_xstats != rte_eth_xstats_get_names_by_id(
295999a2dd95SBruce Richardson 			port_id, xstats_names, cnt_xstats, NULL)) {
296099a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Cannot get xstats lookup\n");
296199a2dd95SBruce Richardson 		return -1;
296299a2dd95SBruce Richardson 	}
296399a2dd95SBruce Richardson 
296499a2dd95SBruce Richardson 	for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) {
296599a2dd95SBruce Richardson 		if (!strcmp(xstats_names[idx_xstat].name, xstat_name)) {
296699a2dd95SBruce Richardson 			*id = idx_xstat;
296799a2dd95SBruce Richardson 			return 0;
296899a2dd95SBruce Richardson 		};
296999a2dd95SBruce Richardson 	}
297099a2dd95SBruce Richardson 
297199a2dd95SBruce Richardson 	return -EINVAL;
297299a2dd95SBruce Richardson }
297399a2dd95SBruce Richardson 
297499a2dd95SBruce Richardson /* retrieve basic stats names */
297599a2dd95SBruce Richardson static int
297699a2dd95SBruce Richardson eth_basic_stats_get_names(struct rte_eth_dev *dev,
297799a2dd95SBruce Richardson 	struct rte_eth_xstat_name *xstats_names)
297899a2dd95SBruce Richardson {
297999a2dd95SBruce Richardson 	int cnt_used_entries = 0;
298099a2dd95SBruce Richardson 	uint32_t idx, id_queue;
298199a2dd95SBruce Richardson 	uint16_t num_q;
298299a2dd95SBruce Richardson 
298399a2dd95SBruce Richardson 	for (idx = 0; idx < RTE_NB_STATS; idx++) {
298499a2dd95SBruce Richardson 		strlcpy(xstats_names[cnt_used_entries].name,
298599a2dd95SBruce Richardson 			eth_dev_stats_strings[idx].name,
298699a2dd95SBruce Richardson 			sizeof(xstats_names[0].name));
298799a2dd95SBruce Richardson 		cnt_used_entries++;
298899a2dd95SBruce Richardson 	}
298999a2dd95SBruce Richardson 
299099a2dd95SBruce Richardson 	if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0)
299199a2dd95SBruce Richardson 		return cnt_used_entries;
299299a2dd95SBruce Richardson 
299399a2dd95SBruce Richardson 	num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
299499a2dd95SBruce Richardson 	for (id_queue = 0; id_queue < num_q; id_queue++) {
299599a2dd95SBruce Richardson 		for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) {
299699a2dd95SBruce Richardson 			snprintf(xstats_names[cnt_used_entries].name,
299799a2dd95SBruce Richardson 				sizeof(xstats_names[0].name),
299899a2dd95SBruce Richardson 				"rx_q%u_%s",
299999a2dd95SBruce Richardson 				id_queue, eth_dev_rxq_stats_strings[idx].name);
300099a2dd95SBruce Richardson 			cnt_used_entries++;
300199a2dd95SBruce Richardson 		}
300299a2dd95SBruce Richardson 
300399a2dd95SBruce Richardson 	}
300499a2dd95SBruce Richardson 	num_q = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
300599a2dd95SBruce Richardson 	for (id_queue = 0; id_queue < num_q; id_queue++) {
300699a2dd95SBruce Richardson 		for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) {
300799a2dd95SBruce Richardson 			snprintf(xstats_names[cnt_used_entries].name,
300899a2dd95SBruce Richardson 				sizeof(xstats_names[0].name),
300999a2dd95SBruce Richardson 				"tx_q%u_%s",
301099a2dd95SBruce Richardson 				id_queue, eth_dev_txq_stats_strings[idx].name);
301199a2dd95SBruce Richardson 			cnt_used_entries++;
301299a2dd95SBruce Richardson 		}
301399a2dd95SBruce Richardson 	}
301499a2dd95SBruce Richardson 	return cnt_used_entries;
301599a2dd95SBruce Richardson }
301699a2dd95SBruce Richardson 
301799a2dd95SBruce Richardson /* retrieve ethdev extended statistics names */
301899a2dd95SBruce Richardson int
301999a2dd95SBruce Richardson rte_eth_xstats_get_names_by_id(uint16_t port_id,
302099a2dd95SBruce Richardson 	struct rte_eth_xstat_name *xstats_names, unsigned int size,
302199a2dd95SBruce Richardson 	uint64_t *ids)
302299a2dd95SBruce Richardson {
302399a2dd95SBruce Richardson 	struct rte_eth_xstat_name *xstats_names_copy;
302499a2dd95SBruce Richardson 	unsigned int no_basic_stat_requested = 1;
302599a2dd95SBruce Richardson 	unsigned int no_ext_stat_requested = 1;
302699a2dd95SBruce Richardson 	unsigned int expected_entries;
302799a2dd95SBruce Richardson 	unsigned int basic_count;
302899a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
302999a2dd95SBruce Richardson 	unsigned int i;
303099a2dd95SBruce Richardson 	int ret;
303199a2dd95SBruce Richardson 
303299a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
303399a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
303499a2dd95SBruce Richardson 
303599a2dd95SBruce Richardson 	basic_count = eth_dev_get_xstats_basic_count(dev);
303699a2dd95SBruce Richardson 	ret = eth_dev_get_xstats_count(port_id);
303799a2dd95SBruce Richardson 	if (ret < 0)
303899a2dd95SBruce Richardson 		return ret;
303999a2dd95SBruce Richardson 	expected_entries = (unsigned int)ret;
304099a2dd95SBruce Richardson 
304199a2dd95SBruce Richardson 	/* Return max number of stats if no ids given */
304299a2dd95SBruce Richardson 	if (!ids) {
304399a2dd95SBruce Richardson 		if (!xstats_names)
304499a2dd95SBruce Richardson 			return expected_entries;
304599a2dd95SBruce Richardson 		else if (xstats_names && size < expected_entries)
304699a2dd95SBruce Richardson 			return expected_entries;
304799a2dd95SBruce Richardson 	}
304899a2dd95SBruce Richardson 
304999a2dd95SBruce Richardson 	if (ids && !xstats_names)
305099a2dd95SBruce Richardson 		return -EINVAL;
305199a2dd95SBruce Richardson 
305299a2dd95SBruce Richardson 	if (ids && dev->dev_ops->xstats_get_names_by_id != NULL && size > 0) {
305399a2dd95SBruce Richardson 		uint64_t ids_copy[size];
305499a2dd95SBruce Richardson 
305599a2dd95SBruce Richardson 		for (i = 0; i < size; i++) {
305699a2dd95SBruce Richardson 			if (ids[i] < basic_count) {
305799a2dd95SBruce Richardson 				no_basic_stat_requested = 0;
305899a2dd95SBruce Richardson 				break;
305999a2dd95SBruce Richardson 			}
306099a2dd95SBruce Richardson 
306199a2dd95SBruce Richardson 			/*
306299a2dd95SBruce Richardson 			 * Convert ids to xstats ids that PMD knows.
306399a2dd95SBruce Richardson 			 * ids known by user are basic + extended stats.
306499a2dd95SBruce Richardson 			 */
306599a2dd95SBruce Richardson 			ids_copy[i] = ids[i] - basic_count;
306699a2dd95SBruce Richardson 		}
306799a2dd95SBruce Richardson 
306899a2dd95SBruce Richardson 		if (no_basic_stat_requested)
306999a2dd95SBruce Richardson 			return (*dev->dev_ops->xstats_get_names_by_id)(dev,
30708c9f976fSAndrew Rybchenko 					ids_copy, xstats_names, size);
307199a2dd95SBruce Richardson 	}
307299a2dd95SBruce Richardson 
307399a2dd95SBruce Richardson 	/* Retrieve all stats */
307499a2dd95SBruce Richardson 	if (!ids) {
307599a2dd95SBruce Richardson 		int num_stats = rte_eth_xstats_get_names(port_id, xstats_names,
307699a2dd95SBruce Richardson 				expected_entries);
307799a2dd95SBruce Richardson 		if (num_stats < 0 || num_stats > (int)expected_entries)
307899a2dd95SBruce Richardson 			return num_stats;
307999a2dd95SBruce Richardson 		else
308099a2dd95SBruce Richardson 			return expected_entries;
308199a2dd95SBruce Richardson 	}
308299a2dd95SBruce Richardson 
308399a2dd95SBruce Richardson 	xstats_names_copy = calloc(expected_entries,
308499a2dd95SBruce Richardson 		sizeof(struct rte_eth_xstat_name));
308599a2dd95SBruce Richardson 
308699a2dd95SBruce Richardson 	if (!xstats_names_copy) {
308799a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Can't allocate memory\n");
308899a2dd95SBruce Richardson 		return -ENOMEM;
308999a2dd95SBruce Richardson 	}
309099a2dd95SBruce Richardson 
309199a2dd95SBruce Richardson 	if (ids) {
309299a2dd95SBruce Richardson 		for (i = 0; i < size; i++) {
309399a2dd95SBruce Richardson 			if (ids[i] >= basic_count) {
309499a2dd95SBruce Richardson 				no_ext_stat_requested = 0;
309599a2dd95SBruce Richardson 				break;
309699a2dd95SBruce Richardson 			}
309799a2dd95SBruce Richardson 		}
309899a2dd95SBruce Richardson 	}
309999a2dd95SBruce Richardson 
310099a2dd95SBruce Richardson 	/* Fill xstats_names_copy structure */
310199a2dd95SBruce Richardson 	if (ids && no_ext_stat_requested) {
310299a2dd95SBruce Richardson 		eth_basic_stats_get_names(dev, xstats_names_copy);
310399a2dd95SBruce Richardson 	} else {
310499a2dd95SBruce Richardson 		ret = rte_eth_xstats_get_names(port_id, xstats_names_copy,
310599a2dd95SBruce Richardson 			expected_entries);
310699a2dd95SBruce Richardson 		if (ret < 0) {
310799a2dd95SBruce Richardson 			free(xstats_names_copy);
310899a2dd95SBruce Richardson 			return ret;
310999a2dd95SBruce Richardson 		}
311099a2dd95SBruce Richardson 	}
311199a2dd95SBruce Richardson 
311299a2dd95SBruce Richardson 	/* Filter stats */
311399a2dd95SBruce Richardson 	for (i = 0; i < size; i++) {
311499a2dd95SBruce Richardson 		if (ids[i] >= expected_entries) {
311599a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n");
311699a2dd95SBruce Richardson 			free(xstats_names_copy);
311799a2dd95SBruce Richardson 			return -1;
311899a2dd95SBruce Richardson 		}
311999a2dd95SBruce Richardson 		xstats_names[i] = xstats_names_copy[ids[i]];
312099a2dd95SBruce Richardson 	}
312199a2dd95SBruce Richardson 
312299a2dd95SBruce Richardson 	free(xstats_names_copy);
312399a2dd95SBruce Richardson 	return size;
312499a2dd95SBruce Richardson }
312599a2dd95SBruce Richardson 
312699a2dd95SBruce Richardson int
312799a2dd95SBruce Richardson rte_eth_xstats_get_names(uint16_t port_id,
312899a2dd95SBruce Richardson 	struct rte_eth_xstat_name *xstats_names,
312999a2dd95SBruce Richardson 	unsigned int size)
313099a2dd95SBruce Richardson {
313199a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
313299a2dd95SBruce Richardson 	int cnt_used_entries;
313399a2dd95SBruce Richardson 	int cnt_expected_entries;
313499a2dd95SBruce Richardson 	int cnt_driver_entries;
313599a2dd95SBruce Richardson 
313699a2dd95SBruce Richardson 	cnt_expected_entries = eth_dev_get_xstats_count(port_id);
313799a2dd95SBruce Richardson 	if (xstats_names == NULL || cnt_expected_entries < 0 ||
313899a2dd95SBruce Richardson 			(int)size < cnt_expected_entries)
313999a2dd95SBruce Richardson 		return cnt_expected_entries;
314099a2dd95SBruce Richardson 
314199a2dd95SBruce Richardson 	/* port_id checked in eth_dev_get_xstats_count() */
314299a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
314399a2dd95SBruce Richardson 
314499a2dd95SBruce Richardson 	cnt_used_entries = eth_basic_stats_get_names(dev, xstats_names);
314599a2dd95SBruce Richardson 
314699a2dd95SBruce Richardson 	if (dev->dev_ops->xstats_get_names != NULL) {
314799a2dd95SBruce Richardson 		/* If there are any driver-specific xstats, append them
314899a2dd95SBruce Richardson 		 * to end of list.
314999a2dd95SBruce Richardson 		 */
315099a2dd95SBruce Richardson 		cnt_driver_entries = (*dev->dev_ops->xstats_get_names)(
315199a2dd95SBruce Richardson 			dev,
315299a2dd95SBruce Richardson 			xstats_names + cnt_used_entries,
315399a2dd95SBruce Richardson 			size - cnt_used_entries);
315499a2dd95SBruce Richardson 		if (cnt_driver_entries < 0)
315599a2dd95SBruce Richardson 			return eth_err(port_id, cnt_driver_entries);
315699a2dd95SBruce Richardson 		cnt_used_entries += cnt_driver_entries;
315799a2dd95SBruce Richardson 	}
315899a2dd95SBruce Richardson 
315999a2dd95SBruce Richardson 	return cnt_used_entries;
316099a2dd95SBruce Richardson }
316199a2dd95SBruce Richardson 
316299a2dd95SBruce Richardson 
316399a2dd95SBruce Richardson static int
316499a2dd95SBruce Richardson eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats)
316599a2dd95SBruce Richardson {
316699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
316799a2dd95SBruce Richardson 	struct rte_eth_stats eth_stats;
316899a2dd95SBruce Richardson 	unsigned int count = 0, i, q;
316999a2dd95SBruce Richardson 	uint64_t val, *stats_ptr;
317099a2dd95SBruce Richardson 	uint16_t nb_rxqs, nb_txqs;
317199a2dd95SBruce Richardson 	int ret;
317299a2dd95SBruce Richardson 
317399a2dd95SBruce Richardson 	ret = rte_eth_stats_get(port_id, &eth_stats);
317499a2dd95SBruce Richardson 	if (ret < 0)
317599a2dd95SBruce Richardson 		return ret;
317699a2dd95SBruce Richardson 
317799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
317899a2dd95SBruce Richardson 
317999a2dd95SBruce Richardson 	nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
318099a2dd95SBruce Richardson 	nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
318199a2dd95SBruce Richardson 
318299a2dd95SBruce Richardson 	/* global stats */
318399a2dd95SBruce Richardson 	for (i = 0; i < RTE_NB_STATS; i++) {
318499a2dd95SBruce Richardson 		stats_ptr = RTE_PTR_ADD(&eth_stats,
318599a2dd95SBruce Richardson 					eth_dev_stats_strings[i].offset);
318699a2dd95SBruce Richardson 		val = *stats_ptr;
318799a2dd95SBruce Richardson 		xstats[count++].value = val;
318899a2dd95SBruce Richardson 	}
318999a2dd95SBruce Richardson 
319099a2dd95SBruce Richardson 	if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0)
319199a2dd95SBruce Richardson 		return count;
319299a2dd95SBruce Richardson 
319399a2dd95SBruce Richardson 	/* per-rxq stats */
319499a2dd95SBruce Richardson 	for (q = 0; q < nb_rxqs; q++) {
319599a2dd95SBruce Richardson 		for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
319699a2dd95SBruce Richardson 			stats_ptr = RTE_PTR_ADD(&eth_stats,
319799a2dd95SBruce Richardson 					eth_dev_rxq_stats_strings[i].offset +
319899a2dd95SBruce Richardson 					q * sizeof(uint64_t));
319999a2dd95SBruce Richardson 			val = *stats_ptr;
320099a2dd95SBruce Richardson 			xstats[count++].value = val;
320199a2dd95SBruce Richardson 		}
320299a2dd95SBruce Richardson 	}
320399a2dd95SBruce Richardson 
320499a2dd95SBruce Richardson 	/* per-txq stats */
320599a2dd95SBruce Richardson 	for (q = 0; q < nb_txqs; q++) {
320699a2dd95SBruce Richardson 		for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
320799a2dd95SBruce Richardson 			stats_ptr = RTE_PTR_ADD(&eth_stats,
320899a2dd95SBruce Richardson 					eth_dev_txq_stats_strings[i].offset +
320999a2dd95SBruce Richardson 					q * sizeof(uint64_t));
321099a2dd95SBruce Richardson 			val = *stats_ptr;
321199a2dd95SBruce Richardson 			xstats[count++].value = val;
321299a2dd95SBruce Richardson 		}
321399a2dd95SBruce Richardson 	}
321499a2dd95SBruce Richardson 	return count;
321599a2dd95SBruce Richardson }
321699a2dd95SBruce Richardson 
321799a2dd95SBruce Richardson /* retrieve ethdev extended statistics */
321899a2dd95SBruce Richardson int
321999a2dd95SBruce Richardson rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
322099a2dd95SBruce Richardson 			 uint64_t *values, unsigned int size)
322199a2dd95SBruce Richardson {
322299a2dd95SBruce Richardson 	unsigned int no_basic_stat_requested = 1;
322399a2dd95SBruce Richardson 	unsigned int no_ext_stat_requested = 1;
322499a2dd95SBruce Richardson 	unsigned int num_xstats_filled;
322599a2dd95SBruce Richardson 	unsigned int basic_count;
322699a2dd95SBruce Richardson 	uint16_t expected_entries;
322799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
322899a2dd95SBruce Richardson 	unsigned int i;
322999a2dd95SBruce Richardson 	int ret;
323099a2dd95SBruce Richardson 
323199a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
323253ef1b34SMin Hu (Connor) 	dev = &rte_eth_devices[port_id];
323353ef1b34SMin Hu (Connor) 
323499a2dd95SBruce Richardson 	ret = eth_dev_get_xstats_count(port_id);
323599a2dd95SBruce Richardson 	if (ret < 0)
323699a2dd95SBruce Richardson 		return ret;
323799a2dd95SBruce Richardson 	expected_entries = (uint16_t)ret;
323899a2dd95SBruce Richardson 	struct rte_eth_xstat xstats[expected_entries];
323999a2dd95SBruce Richardson 	basic_count = eth_dev_get_xstats_basic_count(dev);
324099a2dd95SBruce Richardson 
324199a2dd95SBruce Richardson 	/* Return max number of stats if no ids given */
324299a2dd95SBruce Richardson 	if (!ids) {
324399a2dd95SBruce Richardson 		if (!values)
324499a2dd95SBruce Richardson 			return expected_entries;
324599a2dd95SBruce Richardson 		else if (values && size < expected_entries)
324699a2dd95SBruce Richardson 			return expected_entries;
324799a2dd95SBruce Richardson 	}
324899a2dd95SBruce Richardson 
324999a2dd95SBruce Richardson 	if (ids && !values)
325099a2dd95SBruce Richardson 		return -EINVAL;
325199a2dd95SBruce Richardson 
325299a2dd95SBruce Richardson 	if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) {
325399a2dd95SBruce Richardson 		unsigned int basic_count = eth_dev_get_xstats_basic_count(dev);
325499a2dd95SBruce Richardson 		uint64_t ids_copy[size];
325599a2dd95SBruce Richardson 
325699a2dd95SBruce Richardson 		for (i = 0; i < size; i++) {
325799a2dd95SBruce Richardson 			if (ids[i] < basic_count) {
325899a2dd95SBruce Richardson 				no_basic_stat_requested = 0;
325999a2dd95SBruce Richardson 				break;
326099a2dd95SBruce Richardson 			}
326199a2dd95SBruce Richardson 
326299a2dd95SBruce Richardson 			/*
326399a2dd95SBruce Richardson 			 * Convert ids to xstats ids that PMD knows.
326499a2dd95SBruce Richardson 			 * ids known by user are basic + extended stats.
326599a2dd95SBruce Richardson 			 */
326699a2dd95SBruce Richardson 			ids_copy[i] = ids[i] - basic_count;
326799a2dd95SBruce Richardson 		}
326899a2dd95SBruce Richardson 
326999a2dd95SBruce Richardson 		if (no_basic_stat_requested)
327099a2dd95SBruce Richardson 			return (*dev->dev_ops->xstats_get_by_id)(dev, ids_copy,
327199a2dd95SBruce Richardson 					values, size);
327299a2dd95SBruce Richardson 	}
327399a2dd95SBruce Richardson 
327499a2dd95SBruce Richardson 	if (ids) {
327599a2dd95SBruce Richardson 		for (i = 0; i < size; i++) {
327699a2dd95SBruce Richardson 			if (ids[i] >= basic_count) {
327799a2dd95SBruce Richardson 				no_ext_stat_requested = 0;
327899a2dd95SBruce Richardson 				break;
327999a2dd95SBruce Richardson 			}
328099a2dd95SBruce Richardson 		}
328199a2dd95SBruce Richardson 	}
328299a2dd95SBruce Richardson 
328399a2dd95SBruce Richardson 	/* Fill the xstats structure */
328499a2dd95SBruce Richardson 	if (ids && no_ext_stat_requested)
328599a2dd95SBruce Richardson 		ret = eth_basic_stats_get(port_id, xstats);
328699a2dd95SBruce Richardson 	else
328799a2dd95SBruce Richardson 		ret = rte_eth_xstats_get(port_id, xstats, expected_entries);
328899a2dd95SBruce Richardson 
328999a2dd95SBruce Richardson 	if (ret < 0)
329099a2dd95SBruce Richardson 		return ret;
329199a2dd95SBruce Richardson 	num_xstats_filled = (unsigned int)ret;
329299a2dd95SBruce Richardson 
329399a2dd95SBruce Richardson 	/* Return all stats */
329499a2dd95SBruce Richardson 	if (!ids) {
329599a2dd95SBruce Richardson 		for (i = 0; i < num_xstats_filled; i++)
329699a2dd95SBruce Richardson 			values[i] = xstats[i].value;
329799a2dd95SBruce Richardson 		return expected_entries;
329899a2dd95SBruce Richardson 	}
329999a2dd95SBruce Richardson 
330099a2dd95SBruce Richardson 	/* Filter stats */
330199a2dd95SBruce Richardson 	for (i = 0; i < size; i++) {
330299a2dd95SBruce Richardson 		if (ids[i] >= expected_entries) {
330399a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n");
330499a2dd95SBruce Richardson 			return -1;
330599a2dd95SBruce Richardson 		}
330699a2dd95SBruce Richardson 		values[i] = xstats[ids[i]].value;
330799a2dd95SBruce Richardson 	}
330899a2dd95SBruce Richardson 	return size;
330999a2dd95SBruce Richardson }
331099a2dd95SBruce Richardson 
331199a2dd95SBruce Richardson int
331299a2dd95SBruce Richardson rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats,
331399a2dd95SBruce Richardson 	unsigned int n)
331499a2dd95SBruce Richardson {
331599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
331699a2dd95SBruce Richardson 	unsigned int count = 0, i;
331799a2dd95SBruce Richardson 	signed int xcount = 0;
331899a2dd95SBruce Richardson 	uint16_t nb_rxqs, nb_txqs;
331999a2dd95SBruce Richardson 	int ret;
332099a2dd95SBruce Richardson 
332199a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
332299a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
332399a2dd95SBruce Richardson 
332499a2dd95SBruce Richardson 	nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
332599a2dd95SBruce Richardson 	nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
332699a2dd95SBruce Richardson 
332799a2dd95SBruce Richardson 	/* Return generic statistics */
332899a2dd95SBruce Richardson 	count = RTE_NB_STATS;
332999a2dd95SBruce Richardson 	if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS)
333099a2dd95SBruce Richardson 		count += (nb_rxqs * RTE_NB_RXQ_STATS) + (nb_txqs * RTE_NB_TXQ_STATS);
333199a2dd95SBruce Richardson 
333299a2dd95SBruce Richardson 	/* implemented by the driver */
333399a2dd95SBruce Richardson 	if (dev->dev_ops->xstats_get != NULL) {
333499a2dd95SBruce Richardson 		/* Retrieve the xstats from the driver at the end of the
333599a2dd95SBruce Richardson 		 * xstats struct.
333699a2dd95SBruce Richardson 		 */
333799a2dd95SBruce Richardson 		xcount = (*dev->dev_ops->xstats_get)(dev,
333899a2dd95SBruce Richardson 				     xstats ? xstats + count : NULL,
333999a2dd95SBruce Richardson 				     (n > count) ? n - count : 0);
334099a2dd95SBruce Richardson 
334199a2dd95SBruce Richardson 		if (xcount < 0)
334299a2dd95SBruce Richardson 			return eth_err(port_id, xcount);
334399a2dd95SBruce Richardson 	}
334499a2dd95SBruce Richardson 
334599a2dd95SBruce Richardson 	if (n < count + xcount || xstats == NULL)
334699a2dd95SBruce Richardson 		return count + xcount;
334799a2dd95SBruce Richardson 
334899a2dd95SBruce Richardson 	/* now fill the xstats structure */
334999a2dd95SBruce Richardson 	ret = eth_basic_stats_get(port_id, xstats);
335099a2dd95SBruce Richardson 	if (ret < 0)
335199a2dd95SBruce Richardson 		return ret;
335299a2dd95SBruce Richardson 	count = ret;
335399a2dd95SBruce Richardson 
335499a2dd95SBruce Richardson 	for (i = 0; i < count; i++)
335599a2dd95SBruce Richardson 		xstats[i].id = i;
335699a2dd95SBruce Richardson 	/* add an offset to driver-specific stats */
335799a2dd95SBruce Richardson 	for ( ; i < count + xcount; i++)
335899a2dd95SBruce Richardson 		xstats[i].id += count;
335999a2dd95SBruce Richardson 
336099a2dd95SBruce Richardson 	return count + xcount;
336199a2dd95SBruce Richardson }
336299a2dd95SBruce Richardson 
336399a2dd95SBruce Richardson /* reset ethdev extended statistics */
336499a2dd95SBruce Richardson int
336599a2dd95SBruce Richardson rte_eth_xstats_reset(uint16_t port_id)
336699a2dd95SBruce Richardson {
336799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
336899a2dd95SBruce Richardson 
336999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
337099a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
337199a2dd95SBruce Richardson 
337299a2dd95SBruce Richardson 	/* implemented by the driver */
337399a2dd95SBruce Richardson 	if (dev->dev_ops->xstats_reset != NULL)
337499a2dd95SBruce Richardson 		return eth_err(port_id, (*dev->dev_ops->xstats_reset)(dev));
337599a2dd95SBruce Richardson 
337699a2dd95SBruce Richardson 	/* fallback to default */
337799a2dd95SBruce Richardson 	return rte_eth_stats_reset(port_id);
337899a2dd95SBruce Richardson }
337999a2dd95SBruce Richardson 
338099a2dd95SBruce Richardson static int
338199a2dd95SBruce Richardson eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id,
338299a2dd95SBruce Richardson 		uint8_t stat_idx, uint8_t is_rx)
338399a2dd95SBruce Richardson {
338499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
338599a2dd95SBruce Richardson 
338699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
338799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
338899a2dd95SBruce Richardson 
338999a2dd95SBruce Richardson 	if (is_rx && (queue_id >= dev->data->nb_rx_queues))
339099a2dd95SBruce Richardson 		return -EINVAL;
339199a2dd95SBruce Richardson 
339299a2dd95SBruce Richardson 	if (!is_rx && (queue_id >= dev->data->nb_tx_queues))
339399a2dd95SBruce Richardson 		return -EINVAL;
339499a2dd95SBruce Richardson 
339599a2dd95SBruce Richardson 	if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
339699a2dd95SBruce Richardson 		return -EINVAL;
339799a2dd95SBruce Richardson 
339853ef1b34SMin Hu (Connor) 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set, -ENOTSUP);
339953ef1b34SMin Hu (Connor) 	return (*dev->dev_ops->queue_stats_mapping_set) (dev, queue_id, stat_idx, is_rx);
340099a2dd95SBruce Richardson }
340199a2dd95SBruce Richardson 
340299a2dd95SBruce Richardson int
340399a2dd95SBruce Richardson rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id,
340499a2dd95SBruce Richardson 		uint8_t stat_idx)
340599a2dd95SBruce Richardson {
340699a2dd95SBruce Richardson 	return eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
340799a2dd95SBruce Richardson 						tx_queue_id,
340899a2dd95SBruce Richardson 						stat_idx, STAT_QMAP_TX));
340999a2dd95SBruce Richardson }
341099a2dd95SBruce Richardson 
341199a2dd95SBruce Richardson int
341299a2dd95SBruce Richardson rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id,
341399a2dd95SBruce Richardson 		uint8_t stat_idx)
341499a2dd95SBruce Richardson {
341599a2dd95SBruce Richardson 	return eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
341699a2dd95SBruce Richardson 						rx_queue_id,
341799a2dd95SBruce Richardson 						stat_idx, STAT_QMAP_RX));
341899a2dd95SBruce Richardson }
341999a2dd95SBruce Richardson 
342099a2dd95SBruce Richardson int
342199a2dd95SBruce Richardson rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
342299a2dd95SBruce Richardson {
342399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
342499a2dd95SBruce Richardson 
342599a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
342699a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
342799a2dd95SBruce Richardson 
342853ef1b34SMin Hu (Connor) 	if (fw_version == NULL && fw_size > 0) {
342953ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
343053ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u FW version to NULL when string size is non zero\n",
343153ef1b34SMin Hu (Connor) 			port_id);
343253ef1b34SMin Hu (Connor) 		return -EINVAL;
343353ef1b34SMin Hu (Connor) 	}
343453ef1b34SMin Hu (Connor) 
343599a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
343699a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev,
343799a2dd95SBruce Richardson 							fw_version, fw_size));
343899a2dd95SBruce Richardson }
343999a2dd95SBruce Richardson 
344099a2dd95SBruce Richardson int
344199a2dd95SBruce Richardson rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
344299a2dd95SBruce Richardson {
344399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
344499a2dd95SBruce Richardson 	const struct rte_eth_desc_lim lim = {
344599a2dd95SBruce Richardson 		.nb_max = UINT16_MAX,
344699a2dd95SBruce Richardson 		.nb_min = 0,
344799a2dd95SBruce Richardson 		.nb_align = 1,
344899a2dd95SBruce Richardson 		.nb_seg_max = UINT16_MAX,
344999a2dd95SBruce Richardson 		.nb_mtu_seg_max = UINT16_MAX,
345099a2dd95SBruce Richardson 	};
345199a2dd95SBruce Richardson 	int diag;
345299a2dd95SBruce Richardson 
345353ef1b34SMin Hu (Connor) 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
345453ef1b34SMin Hu (Connor) 	dev = &rte_eth_devices[port_id];
345553ef1b34SMin Hu (Connor) 
345653ef1b34SMin Hu (Connor) 	if (dev_info == NULL) {
345753ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u info to NULL\n",
345853ef1b34SMin Hu (Connor) 			port_id);
345953ef1b34SMin Hu (Connor) 		return -EINVAL;
346053ef1b34SMin Hu (Connor) 	}
346153ef1b34SMin Hu (Connor) 
346299a2dd95SBruce Richardson 	/*
346399a2dd95SBruce Richardson 	 * Init dev_info before port_id check since caller does not have
346499a2dd95SBruce Richardson 	 * return status and does not know if get is successful or not.
346599a2dd95SBruce Richardson 	 */
346699a2dd95SBruce Richardson 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
346799a2dd95SBruce Richardson 	dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
346899a2dd95SBruce Richardson 
346999a2dd95SBruce Richardson 	dev_info->rx_desc_lim = lim;
347099a2dd95SBruce Richardson 	dev_info->tx_desc_lim = lim;
347199a2dd95SBruce Richardson 	dev_info->device = dev->device;
3472990912e6SFerruh Yigit 	dev_info->min_mtu = RTE_ETHER_MIN_LEN - RTE_ETHER_HDR_LEN -
3473990912e6SFerruh Yigit 		RTE_ETHER_CRC_LEN;
347499a2dd95SBruce Richardson 	dev_info->max_mtu = UINT16_MAX;
347599a2dd95SBruce Richardson 
347699a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
347799a2dd95SBruce Richardson 	diag = (*dev->dev_ops->dev_infos_get)(dev, dev_info);
347899a2dd95SBruce Richardson 	if (diag != 0) {
347999a2dd95SBruce Richardson 		/* Cleanup already filled in device information */
348099a2dd95SBruce Richardson 		memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
348199a2dd95SBruce Richardson 		return eth_err(port_id, diag);
348299a2dd95SBruce Richardson 	}
348399a2dd95SBruce Richardson 
348499a2dd95SBruce Richardson 	/* Maximum number of queues should be <= RTE_MAX_QUEUES_PER_PORT */
348599a2dd95SBruce Richardson 	dev_info->max_rx_queues = RTE_MIN(dev_info->max_rx_queues,
348699a2dd95SBruce Richardson 			RTE_MAX_QUEUES_PER_PORT);
348799a2dd95SBruce Richardson 	dev_info->max_tx_queues = RTE_MIN(dev_info->max_tx_queues,
348899a2dd95SBruce Richardson 			RTE_MAX_QUEUES_PER_PORT);
348999a2dd95SBruce Richardson 
349099a2dd95SBruce Richardson 	dev_info->driver_name = dev->device->driver->name;
349199a2dd95SBruce Richardson 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
349299a2dd95SBruce Richardson 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
349399a2dd95SBruce Richardson 
349499a2dd95SBruce Richardson 	dev_info->dev_flags = &dev->data->dev_flags;
349599a2dd95SBruce Richardson 
349699a2dd95SBruce Richardson 	return 0;
349799a2dd95SBruce Richardson }
349899a2dd95SBruce Richardson 
349999a2dd95SBruce Richardson int
3500632be327SJie Wang rte_eth_dev_conf_get(uint16_t port_id, struct rte_eth_conf *dev_conf)
3501632be327SJie Wang {
3502632be327SJie Wang 	struct rte_eth_dev *dev;
3503632be327SJie Wang 
3504632be327SJie Wang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3505632be327SJie Wang 	dev = &rte_eth_devices[port_id];
3506632be327SJie Wang 
3507632be327SJie Wang 	if (dev_conf == NULL) {
3508632be327SJie Wang 		RTE_ETHDEV_LOG(ERR,
3509632be327SJie Wang 			"Cannot get ethdev port %u configuration to NULL\n",
3510632be327SJie Wang 			port_id);
3511632be327SJie Wang 		return -EINVAL;
3512632be327SJie Wang 	}
3513632be327SJie Wang 
3514632be327SJie Wang 	memcpy(dev_conf, &dev->data->dev_conf, sizeof(struct rte_eth_conf));
3515632be327SJie Wang 
3516632be327SJie Wang 	return 0;
3517632be327SJie Wang }
3518632be327SJie Wang 
3519632be327SJie Wang int
352099a2dd95SBruce Richardson rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
352199a2dd95SBruce Richardson 				 uint32_t *ptypes, int num)
352299a2dd95SBruce Richardson {
352399a2dd95SBruce Richardson 	int i, j;
352499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
352599a2dd95SBruce Richardson 	const uint32_t *all_ptypes;
352699a2dd95SBruce Richardson 
352799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
352899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
352953ef1b34SMin Hu (Connor) 
353053ef1b34SMin Hu (Connor) 	if (ptypes == NULL && num > 0) {
353153ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
353253ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u supported packet types to NULL when array size is non zero\n",
353353ef1b34SMin Hu (Connor) 			port_id);
353453ef1b34SMin Hu (Connor) 		return -EINVAL;
353553ef1b34SMin Hu (Connor) 	}
353653ef1b34SMin Hu (Connor) 
353799a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
353899a2dd95SBruce Richardson 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
353999a2dd95SBruce Richardson 
354099a2dd95SBruce Richardson 	if (!all_ptypes)
354199a2dd95SBruce Richardson 		return 0;
354299a2dd95SBruce Richardson 
354399a2dd95SBruce Richardson 	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
354499a2dd95SBruce Richardson 		if (all_ptypes[i] & ptype_mask) {
354599a2dd95SBruce Richardson 			if (j < num)
354699a2dd95SBruce Richardson 				ptypes[j] = all_ptypes[i];
354799a2dd95SBruce Richardson 			j++;
354899a2dd95SBruce Richardson 		}
354999a2dd95SBruce Richardson 
355099a2dd95SBruce Richardson 	return j;
355199a2dd95SBruce Richardson }
355299a2dd95SBruce Richardson 
355399a2dd95SBruce Richardson int
355499a2dd95SBruce Richardson rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
355599a2dd95SBruce Richardson 				 uint32_t *set_ptypes, unsigned int num)
355699a2dd95SBruce Richardson {
355799a2dd95SBruce Richardson 	const uint32_t valid_ptype_masks[] = {
355899a2dd95SBruce Richardson 		RTE_PTYPE_L2_MASK,
355999a2dd95SBruce Richardson 		RTE_PTYPE_L3_MASK,
356099a2dd95SBruce Richardson 		RTE_PTYPE_L4_MASK,
356199a2dd95SBruce Richardson 		RTE_PTYPE_TUNNEL_MASK,
356299a2dd95SBruce Richardson 		RTE_PTYPE_INNER_L2_MASK,
356399a2dd95SBruce Richardson 		RTE_PTYPE_INNER_L3_MASK,
356499a2dd95SBruce Richardson 		RTE_PTYPE_INNER_L4_MASK,
356599a2dd95SBruce Richardson 	};
356699a2dd95SBruce Richardson 	const uint32_t *all_ptypes;
356799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
356899a2dd95SBruce Richardson 	uint32_t unused_mask;
356999a2dd95SBruce Richardson 	unsigned int i, j;
357099a2dd95SBruce Richardson 	int ret;
357199a2dd95SBruce Richardson 
357299a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
357399a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
357499a2dd95SBruce Richardson 
357553ef1b34SMin Hu (Connor) 	if (num > 0 && set_ptypes == NULL) {
357653ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
357753ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u set packet types to NULL when array size is non zero\n",
357853ef1b34SMin Hu (Connor) 			port_id);
357999a2dd95SBruce Richardson 		return -EINVAL;
358053ef1b34SMin Hu (Connor) 	}
358199a2dd95SBruce Richardson 
358299a2dd95SBruce Richardson 	if (*dev->dev_ops->dev_supported_ptypes_get == NULL ||
358399a2dd95SBruce Richardson 			*dev->dev_ops->dev_ptypes_set == NULL) {
358499a2dd95SBruce Richardson 		ret = 0;
358599a2dd95SBruce Richardson 		goto ptype_unknown;
358699a2dd95SBruce Richardson 	}
358799a2dd95SBruce Richardson 
358899a2dd95SBruce Richardson 	if (ptype_mask == 0) {
358999a2dd95SBruce Richardson 		ret = (*dev->dev_ops->dev_ptypes_set)(dev,
359099a2dd95SBruce Richardson 				ptype_mask);
359199a2dd95SBruce Richardson 		goto ptype_unknown;
359299a2dd95SBruce Richardson 	}
359399a2dd95SBruce Richardson 
359499a2dd95SBruce Richardson 	unused_mask = ptype_mask;
359599a2dd95SBruce Richardson 	for (i = 0; i < RTE_DIM(valid_ptype_masks); i++) {
359699a2dd95SBruce Richardson 		uint32_t mask = ptype_mask & valid_ptype_masks[i];
359799a2dd95SBruce Richardson 		if (mask && mask != valid_ptype_masks[i]) {
359899a2dd95SBruce Richardson 			ret = -EINVAL;
359999a2dd95SBruce Richardson 			goto ptype_unknown;
360099a2dd95SBruce Richardson 		}
360199a2dd95SBruce Richardson 		unused_mask &= ~valid_ptype_masks[i];
360299a2dd95SBruce Richardson 	}
360399a2dd95SBruce Richardson 
360499a2dd95SBruce Richardson 	if (unused_mask) {
360599a2dd95SBruce Richardson 		ret = -EINVAL;
360699a2dd95SBruce Richardson 		goto ptype_unknown;
360799a2dd95SBruce Richardson 	}
360899a2dd95SBruce Richardson 
360999a2dd95SBruce Richardson 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
361099a2dd95SBruce Richardson 	if (all_ptypes == NULL) {
361199a2dd95SBruce Richardson 		ret = 0;
361299a2dd95SBruce Richardson 		goto ptype_unknown;
361399a2dd95SBruce Richardson 	}
361499a2dd95SBruce Richardson 
361599a2dd95SBruce Richardson 	/*
361699a2dd95SBruce Richardson 	 * Accommodate as many set_ptypes as possible. If the supplied
361799a2dd95SBruce Richardson 	 * set_ptypes array is insufficient fill it partially.
361899a2dd95SBruce Richardson 	 */
361999a2dd95SBruce Richardson 	for (i = 0, j = 0; set_ptypes != NULL &&
362099a2dd95SBruce Richardson 				(all_ptypes[i] != RTE_PTYPE_UNKNOWN); ++i) {
362199a2dd95SBruce Richardson 		if (ptype_mask & all_ptypes[i]) {
362299a2dd95SBruce Richardson 			if (j < num - 1) {
362399a2dd95SBruce Richardson 				set_ptypes[j] = all_ptypes[i];
362499a2dd95SBruce Richardson 				j++;
362599a2dd95SBruce Richardson 				continue;
362699a2dd95SBruce Richardson 			}
362799a2dd95SBruce Richardson 			break;
362899a2dd95SBruce Richardson 		}
362999a2dd95SBruce Richardson 	}
363099a2dd95SBruce Richardson 
363199a2dd95SBruce Richardson 	if (set_ptypes != NULL && j < num)
363299a2dd95SBruce Richardson 		set_ptypes[j] = RTE_PTYPE_UNKNOWN;
363399a2dd95SBruce Richardson 
363499a2dd95SBruce Richardson 	return (*dev->dev_ops->dev_ptypes_set)(dev, ptype_mask);
363599a2dd95SBruce Richardson 
363699a2dd95SBruce Richardson ptype_unknown:
363799a2dd95SBruce Richardson 	if (num > 0)
363899a2dd95SBruce Richardson 		set_ptypes[0] = RTE_PTYPE_UNKNOWN;
363999a2dd95SBruce Richardson 
364099a2dd95SBruce Richardson 	return ret;
364199a2dd95SBruce Richardson }
364299a2dd95SBruce Richardson 
364399a2dd95SBruce Richardson int
364427a300e6SKonstantin Ananyev rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr *ma,
364527a300e6SKonstantin Ananyev 	unsigned int num)
364627a300e6SKonstantin Ananyev {
364727a300e6SKonstantin Ananyev 	int32_t ret;
364827a300e6SKonstantin Ananyev 	struct rte_eth_dev *dev;
364927a300e6SKonstantin Ananyev 	struct rte_eth_dev_info dev_info;
365027a300e6SKonstantin Ananyev 
365127a300e6SKonstantin Ananyev 	if (ma == NULL) {
365227a300e6SKonstantin Ananyev 		RTE_ETHDEV_LOG(ERR, "%s: invalid parameters\n", __func__);
365327a300e6SKonstantin Ananyev 		return -EINVAL;
365427a300e6SKonstantin Ananyev 	}
365527a300e6SKonstantin Ananyev 
365627a300e6SKonstantin Ananyev 	/* will check for us that port_id is a valid one */
365727a300e6SKonstantin Ananyev 	ret = rte_eth_dev_info_get(port_id, &dev_info);
365827a300e6SKonstantin Ananyev 	if (ret != 0)
365927a300e6SKonstantin Ananyev 		return ret;
366027a300e6SKonstantin Ananyev 
366127a300e6SKonstantin Ananyev 	dev = &rte_eth_devices[port_id];
366227a300e6SKonstantin Ananyev 	num = RTE_MIN(dev_info.max_mac_addrs, num);
366327a300e6SKonstantin Ananyev 	memcpy(ma, dev->data->mac_addrs, num * sizeof(ma[0]));
366427a300e6SKonstantin Ananyev 
366527a300e6SKonstantin Ananyev 	return num;
366627a300e6SKonstantin Ananyev }
366727a300e6SKonstantin Ananyev 
366827a300e6SKonstantin Ananyev int
366999a2dd95SBruce Richardson rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
367099a2dd95SBruce Richardson {
367199a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
367299a2dd95SBruce Richardson 
367399a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
367499a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
367553ef1b34SMin Hu (Connor) 
367653ef1b34SMin Hu (Connor) 	if (mac_addr == NULL) {
367753ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
367853ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u MAC address to NULL\n",
367953ef1b34SMin Hu (Connor) 			port_id);
368053ef1b34SMin Hu (Connor) 		return -EINVAL;
368153ef1b34SMin Hu (Connor) 	}
368253ef1b34SMin Hu (Connor) 
368399a2dd95SBruce Richardson 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
368499a2dd95SBruce Richardson 
368599a2dd95SBruce Richardson 	return 0;
368699a2dd95SBruce Richardson }
368799a2dd95SBruce Richardson 
368899a2dd95SBruce Richardson int
368999a2dd95SBruce Richardson rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
369099a2dd95SBruce Richardson {
369199a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
369299a2dd95SBruce Richardson 
369399a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
369499a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
369553ef1b34SMin Hu (Connor) 
369653ef1b34SMin Hu (Connor) 	if (mtu == NULL) {
369753ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u MTU to NULL\n",
369853ef1b34SMin Hu (Connor) 			port_id);
369953ef1b34SMin Hu (Connor) 		return -EINVAL;
370053ef1b34SMin Hu (Connor) 	}
370153ef1b34SMin Hu (Connor) 
370299a2dd95SBruce Richardson 	*mtu = dev->data->mtu;
370399a2dd95SBruce Richardson 	return 0;
370499a2dd95SBruce Richardson }
370599a2dd95SBruce Richardson 
370699a2dd95SBruce Richardson int
370799a2dd95SBruce Richardson rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu)
370899a2dd95SBruce Richardson {
370999a2dd95SBruce Richardson 	int ret;
371099a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info;
371199a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
371299a2dd95SBruce Richardson 
371399a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
371499a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
371599a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mtu_set, -ENOTSUP);
371699a2dd95SBruce Richardson 
371799a2dd95SBruce Richardson 	/*
371899a2dd95SBruce Richardson 	 * Check if the device supports dev_infos_get, if it does not
371999a2dd95SBruce Richardson 	 * skip min_mtu/max_mtu validation here as this requires values
372099a2dd95SBruce Richardson 	 * that are populated within the call to rte_eth_dev_info_get()
372199a2dd95SBruce Richardson 	 * which relies on dev->dev_ops->dev_infos_get.
372299a2dd95SBruce Richardson 	 */
372399a2dd95SBruce Richardson 	if (*dev->dev_ops->dev_infos_get != NULL) {
372499a2dd95SBruce Richardson 		ret = rte_eth_dev_info_get(port_id, &dev_info);
372599a2dd95SBruce Richardson 		if (ret != 0)
372699a2dd95SBruce Richardson 			return ret;
372799a2dd95SBruce Richardson 
3728990912e6SFerruh Yigit 		ret = eth_dev_validate_mtu(port_id, &dev_info, mtu);
3729990912e6SFerruh Yigit 		if (ret != 0)
3730990912e6SFerruh Yigit 			return ret;
373199a2dd95SBruce Richardson 	}
373299a2dd95SBruce Richardson 
3733b26bee10SIvan Ilchenko 	if (dev->data->dev_configured == 0) {
3734b26bee10SIvan Ilchenko 		RTE_ETHDEV_LOG(ERR,
3735b26bee10SIvan Ilchenko 			"Port %u must be configured before MTU set\n",
3736b26bee10SIvan Ilchenko 			port_id);
3737b26bee10SIvan Ilchenko 		return -EINVAL;
3738b26bee10SIvan Ilchenko 	}
3739b26bee10SIvan Ilchenko 
374099a2dd95SBruce Richardson 	ret = (*dev->dev_ops->mtu_set)(dev, mtu);
3741b563c142SFerruh Yigit 	if (ret == 0)
374299a2dd95SBruce Richardson 		dev->data->mtu = mtu;
374399a2dd95SBruce Richardson 
374499a2dd95SBruce Richardson 	return eth_err(port_id, ret);
374599a2dd95SBruce Richardson }
374699a2dd95SBruce Richardson 
374799a2dd95SBruce Richardson int
374899a2dd95SBruce Richardson rte_eth_dev_vlan_filter(uint16_t port_id, uint16_t vlan_id, int on)
374999a2dd95SBruce Richardson {
375099a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
375199a2dd95SBruce Richardson 	int ret;
375299a2dd95SBruce Richardson 
375399a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
375499a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
375553ef1b34SMin Hu (Connor) 
375699a2dd95SBruce Richardson 	if (!(dev->data->dev_conf.rxmode.offloads &
3757295968d1SFerruh Yigit 	      RTE_ETH_RX_OFFLOAD_VLAN_FILTER)) {
37585b49ba65SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Port %u: VLAN-filtering disabled\n",
375999a2dd95SBruce Richardson 			port_id);
376099a2dd95SBruce Richardson 		return -ENOSYS;
376199a2dd95SBruce Richardson 	}
376299a2dd95SBruce Richardson 
376399a2dd95SBruce Richardson 	if (vlan_id > 4095) {
376499a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Port_id=%u invalid vlan_id=%u > 4095\n",
376599a2dd95SBruce Richardson 			port_id, vlan_id);
376699a2dd95SBruce Richardson 		return -EINVAL;
376799a2dd95SBruce Richardson 	}
376899a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_filter_set, -ENOTSUP);
376999a2dd95SBruce Richardson 
377099a2dd95SBruce Richardson 	ret = (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on);
377199a2dd95SBruce Richardson 	if (ret == 0) {
377299a2dd95SBruce Richardson 		struct rte_vlan_filter_conf *vfc;
377399a2dd95SBruce Richardson 		int vidx;
377499a2dd95SBruce Richardson 		int vbit;
377599a2dd95SBruce Richardson 
377699a2dd95SBruce Richardson 		vfc = &dev->data->vlan_filter_conf;
377799a2dd95SBruce Richardson 		vidx = vlan_id / 64;
377899a2dd95SBruce Richardson 		vbit = vlan_id % 64;
377999a2dd95SBruce Richardson 
378099a2dd95SBruce Richardson 		if (on)
3781e1823e08SThomas Monjalon 			vfc->ids[vidx] |= RTE_BIT64(vbit);
378299a2dd95SBruce Richardson 		else
3783e1823e08SThomas Monjalon 			vfc->ids[vidx] &= ~RTE_BIT64(vbit);
378499a2dd95SBruce Richardson 	}
378599a2dd95SBruce Richardson 
378699a2dd95SBruce Richardson 	return eth_err(port_id, ret);
378799a2dd95SBruce Richardson }
378899a2dd95SBruce Richardson 
378999a2dd95SBruce Richardson int
379099a2dd95SBruce Richardson rte_eth_dev_set_vlan_strip_on_queue(uint16_t port_id, uint16_t rx_queue_id,
379199a2dd95SBruce Richardson 				    int on)
379299a2dd95SBruce Richardson {
379399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
379499a2dd95SBruce Richardson 
379599a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
379699a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
379753ef1b34SMin Hu (Connor) 
379899a2dd95SBruce Richardson 	if (rx_queue_id >= dev->data->nb_rx_queues) {
379999a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Invalid rx_queue_id=%u\n", rx_queue_id);
380099a2dd95SBruce Richardson 		return -EINVAL;
380199a2dd95SBruce Richardson 	}
380299a2dd95SBruce Richardson 
380399a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP);
380499a2dd95SBruce Richardson 	(*dev->dev_ops->vlan_strip_queue_set)(dev, rx_queue_id, on);
380599a2dd95SBruce Richardson 
380699a2dd95SBruce Richardson 	return 0;
380799a2dd95SBruce Richardson }
380899a2dd95SBruce Richardson 
380999a2dd95SBruce Richardson int
381099a2dd95SBruce Richardson rte_eth_dev_set_vlan_ether_type(uint16_t port_id,
381199a2dd95SBruce Richardson 				enum rte_vlan_type vlan_type,
381299a2dd95SBruce Richardson 				uint16_t tpid)
381399a2dd95SBruce Richardson {
381499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
381599a2dd95SBruce Richardson 
381699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
381799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
381899a2dd95SBruce Richardson 
381953ef1b34SMin Hu (Connor) 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
382099a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->vlan_tpid_set)(dev, vlan_type,
382199a2dd95SBruce Richardson 							       tpid));
382299a2dd95SBruce Richardson }
382399a2dd95SBruce Richardson 
382499a2dd95SBruce Richardson int
382599a2dd95SBruce Richardson rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask)
382699a2dd95SBruce Richardson {
382799a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info;
382899a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
382999a2dd95SBruce Richardson 	int ret = 0;
383099a2dd95SBruce Richardson 	int mask = 0;
383199a2dd95SBruce Richardson 	int cur, org = 0;
383299a2dd95SBruce Richardson 	uint64_t orig_offloads;
383399a2dd95SBruce Richardson 	uint64_t dev_offloads;
383499a2dd95SBruce Richardson 	uint64_t new_offloads;
383599a2dd95SBruce Richardson 
383699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
383799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
383899a2dd95SBruce Richardson 
383999a2dd95SBruce Richardson 	/* save original values in case of failure */
384099a2dd95SBruce Richardson 	orig_offloads = dev->data->dev_conf.rxmode.offloads;
384199a2dd95SBruce Richardson 	dev_offloads = orig_offloads;
384299a2dd95SBruce Richardson 
384399a2dd95SBruce Richardson 	/* check which option changed by application */
3844295968d1SFerruh Yigit 	cur = !!(offload_mask & RTE_ETH_VLAN_STRIP_OFFLOAD);
3845295968d1SFerruh Yigit 	org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP);
384699a2dd95SBruce Richardson 	if (cur != org) {
384799a2dd95SBruce Richardson 		if (cur)
3848295968d1SFerruh Yigit 			dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
384999a2dd95SBruce Richardson 		else
3850295968d1SFerruh Yigit 			dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
3851295968d1SFerruh Yigit 		mask |= RTE_ETH_VLAN_STRIP_MASK;
385299a2dd95SBruce Richardson 	}
385399a2dd95SBruce Richardson 
3854295968d1SFerruh Yigit 	cur = !!(offload_mask & RTE_ETH_VLAN_FILTER_OFFLOAD);
3855295968d1SFerruh Yigit 	org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER);
385699a2dd95SBruce Richardson 	if (cur != org) {
385799a2dd95SBruce Richardson 		if (cur)
3858295968d1SFerruh Yigit 			dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
385999a2dd95SBruce Richardson 		else
3860295968d1SFerruh Yigit 			dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
3861295968d1SFerruh Yigit 		mask |= RTE_ETH_VLAN_FILTER_MASK;
386299a2dd95SBruce Richardson 	}
386399a2dd95SBruce Richardson 
3864295968d1SFerruh Yigit 	cur = !!(offload_mask & RTE_ETH_VLAN_EXTEND_OFFLOAD);
3865295968d1SFerruh Yigit 	org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND);
386699a2dd95SBruce Richardson 	if (cur != org) {
386799a2dd95SBruce Richardson 		if (cur)
3868295968d1SFerruh Yigit 			dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
386999a2dd95SBruce Richardson 		else
3870295968d1SFerruh Yigit 			dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
3871295968d1SFerruh Yigit 		mask |= RTE_ETH_VLAN_EXTEND_MASK;
387299a2dd95SBruce Richardson 	}
387399a2dd95SBruce Richardson 
3874295968d1SFerruh Yigit 	cur = !!(offload_mask & RTE_ETH_QINQ_STRIP_OFFLOAD);
3875295968d1SFerruh Yigit 	org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP);
387699a2dd95SBruce Richardson 	if (cur != org) {
387799a2dd95SBruce Richardson 		if (cur)
3878295968d1SFerruh Yigit 			dev_offloads |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
387999a2dd95SBruce Richardson 		else
3880295968d1SFerruh Yigit 			dev_offloads &= ~RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
3881295968d1SFerruh Yigit 		mask |= RTE_ETH_QINQ_STRIP_MASK;
388299a2dd95SBruce Richardson 	}
388399a2dd95SBruce Richardson 
388499a2dd95SBruce Richardson 	/*no change*/
388599a2dd95SBruce Richardson 	if (mask == 0)
388699a2dd95SBruce Richardson 		return ret;
388799a2dd95SBruce Richardson 
388899a2dd95SBruce Richardson 	ret = rte_eth_dev_info_get(port_id, &dev_info);
388999a2dd95SBruce Richardson 	if (ret != 0)
389099a2dd95SBruce Richardson 		return ret;
389199a2dd95SBruce Richardson 
389299a2dd95SBruce Richardson 	/* Rx VLAN offloading must be within its device capabilities */
389399a2dd95SBruce Richardson 	if ((dev_offloads & dev_info.rx_offload_capa) != dev_offloads) {
389499a2dd95SBruce Richardson 		new_offloads = dev_offloads & ~orig_offloads;
389599a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
389699a2dd95SBruce Richardson 			"Ethdev port_id=%u requested new added VLAN offloads "
389799a2dd95SBruce Richardson 			"0x%" PRIx64 " must be within Rx offloads capabilities "
389899a2dd95SBruce Richardson 			"0x%" PRIx64 " in %s()\n",
389999a2dd95SBruce Richardson 			port_id, new_offloads, dev_info.rx_offload_capa,
390099a2dd95SBruce Richardson 			__func__);
390199a2dd95SBruce Richardson 		return -EINVAL;
390299a2dd95SBruce Richardson 	}
390399a2dd95SBruce Richardson 
390499a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_offload_set, -ENOTSUP);
390599a2dd95SBruce Richardson 	dev->data->dev_conf.rxmode.offloads = dev_offloads;
390699a2dd95SBruce Richardson 	ret = (*dev->dev_ops->vlan_offload_set)(dev, mask);
390799a2dd95SBruce Richardson 	if (ret) {
390899a2dd95SBruce Richardson 		/* hit an error restore  original values */
390999a2dd95SBruce Richardson 		dev->data->dev_conf.rxmode.offloads = orig_offloads;
391099a2dd95SBruce Richardson 	}
391199a2dd95SBruce Richardson 
391299a2dd95SBruce Richardson 	return eth_err(port_id, ret);
391399a2dd95SBruce Richardson }
391499a2dd95SBruce Richardson 
391599a2dd95SBruce Richardson int
391699a2dd95SBruce Richardson rte_eth_dev_get_vlan_offload(uint16_t port_id)
391799a2dd95SBruce Richardson {
391899a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
391999a2dd95SBruce Richardson 	uint64_t *dev_offloads;
392099a2dd95SBruce Richardson 	int ret = 0;
392199a2dd95SBruce Richardson 
392299a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
392399a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
392499a2dd95SBruce Richardson 	dev_offloads = &dev->data->dev_conf.rxmode.offloads;
392599a2dd95SBruce Richardson 
3926295968d1SFerruh Yigit 	if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
3927295968d1SFerruh Yigit 		ret |= RTE_ETH_VLAN_STRIP_OFFLOAD;
392899a2dd95SBruce Richardson 
3929295968d1SFerruh Yigit 	if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER)
3930295968d1SFerruh Yigit 		ret |= RTE_ETH_VLAN_FILTER_OFFLOAD;
393199a2dd95SBruce Richardson 
3932295968d1SFerruh Yigit 	if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)
3933295968d1SFerruh Yigit 		ret |= RTE_ETH_VLAN_EXTEND_OFFLOAD;
393499a2dd95SBruce Richardson 
3935295968d1SFerruh Yigit 	if (*dev_offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP)
3936295968d1SFerruh Yigit 		ret |= RTE_ETH_QINQ_STRIP_OFFLOAD;
393799a2dd95SBruce Richardson 
393899a2dd95SBruce Richardson 	return ret;
393999a2dd95SBruce Richardson }
394099a2dd95SBruce Richardson 
394199a2dd95SBruce Richardson int
394299a2dd95SBruce Richardson rte_eth_dev_set_vlan_pvid(uint16_t port_id, uint16_t pvid, int on)
394399a2dd95SBruce Richardson {
394499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
394599a2dd95SBruce Richardson 
394699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
394799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
394899a2dd95SBruce Richardson 
394953ef1b34SMin Hu (Connor) 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_pvid_set, -ENOTSUP);
395099a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->vlan_pvid_set)(dev, pvid, on));
395199a2dd95SBruce Richardson }
395299a2dd95SBruce Richardson 
395399a2dd95SBruce Richardson int
395499a2dd95SBruce Richardson rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
395599a2dd95SBruce Richardson {
395699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
395799a2dd95SBruce Richardson 
395899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
395999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
396053ef1b34SMin Hu (Connor) 
396153ef1b34SMin Hu (Connor) 	if (fc_conf == NULL) {
396253ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
396353ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u flow control config to NULL\n",
396453ef1b34SMin Hu (Connor) 			port_id);
396553ef1b34SMin Hu (Connor) 		return -EINVAL;
396653ef1b34SMin Hu (Connor) 	}
396753ef1b34SMin Hu (Connor) 
396899a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
396999a2dd95SBruce Richardson 	memset(fc_conf, 0, sizeof(*fc_conf));
397099a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf));
397199a2dd95SBruce Richardson }
397299a2dd95SBruce Richardson 
397399a2dd95SBruce Richardson int
397499a2dd95SBruce Richardson rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
397599a2dd95SBruce Richardson {
397699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
397799a2dd95SBruce Richardson 
397899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
397953ef1b34SMin Hu (Connor) 	dev = &rte_eth_devices[port_id];
398053ef1b34SMin Hu (Connor) 
398153ef1b34SMin Hu (Connor) 	if (fc_conf == NULL) {
398253ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
398353ef1b34SMin Hu (Connor) 			"Cannot set ethdev port %u flow control from NULL config\n",
398453ef1b34SMin Hu (Connor) 			port_id);
398553ef1b34SMin Hu (Connor) 		return -EINVAL;
398653ef1b34SMin Hu (Connor) 	}
398753ef1b34SMin Hu (Connor) 
398899a2dd95SBruce Richardson 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
398999a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
399099a2dd95SBruce Richardson 		return -EINVAL;
399199a2dd95SBruce Richardson 	}
399299a2dd95SBruce Richardson 
399399a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP);
399499a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf));
399599a2dd95SBruce Richardson }
399699a2dd95SBruce Richardson 
399799a2dd95SBruce Richardson int
399899a2dd95SBruce Richardson rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
399999a2dd95SBruce Richardson 				   struct rte_eth_pfc_conf *pfc_conf)
400099a2dd95SBruce Richardson {
400199a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
400299a2dd95SBruce Richardson 
400399a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
400453ef1b34SMin Hu (Connor) 	dev = &rte_eth_devices[port_id];
400553ef1b34SMin Hu (Connor) 
400653ef1b34SMin Hu (Connor) 	if (pfc_conf == NULL) {
400753ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
400853ef1b34SMin Hu (Connor) 			"Cannot set ethdev port %u priority flow control from NULL config\n",
400953ef1b34SMin Hu (Connor) 			port_id);
401053ef1b34SMin Hu (Connor) 		return -EINVAL;
401153ef1b34SMin Hu (Connor) 	}
401253ef1b34SMin Hu (Connor) 
4013295968d1SFerruh Yigit 	if (pfc_conf->priority > (RTE_ETH_DCB_NUM_USER_PRIORITIES - 1)) {
401499a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
401599a2dd95SBruce Richardson 		return -EINVAL;
401699a2dd95SBruce Richardson 	}
401799a2dd95SBruce Richardson 
401899a2dd95SBruce Richardson 	/* High water, low water validation are device specific */
401999a2dd95SBruce Richardson 	if  (*dev->dev_ops->priority_flow_ctrl_set)
402099a2dd95SBruce Richardson 		return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set)
402199a2dd95SBruce Richardson 					(dev, pfc_conf));
402299a2dd95SBruce Richardson 	return -ENOTSUP;
402399a2dd95SBruce Richardson }
402499a2dd95SBruce Richardson 
402599a2dd95SBruce Richardson static int
402699a2dd95SBruce Richardson eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
402799a2dd95SBruce Richardson 			uint16_t reta_size)
402899a2dd95SBruce Richardson {
402999a2dd95SBruce Richardson 	uint16_t i, num;
403099a2dd95SBruce Richardson 
4031295968d1SFerruh Yigit 	num = (reta_size + RTE_ETH_RETA_GROUP_SIZE - 1) / RTE_ETH_RETA_GROUP_SIZE;
403299a2dd95SBruce Richardson 	for (i = 0; i < num; i++) {
403399a2dd95SBruce Richardson 		if (reta_conf[i].mask)
403499a2dd95SBruce Richardson 			return 0;
403599a2dd95SBruce Richardson 	}
403699a2dd95SBruce Richardson 
403799a2dd95SBruce Richardson 	return -EINVAL;
403899a2dd95SBruce Richardson }
403999a2dd95SBruce Richardson 
404099a2dd95SBruce Richardson static int
404199a2dd95SBruce Richardson eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
404299a2dd95SBruce Richardson 			 uint16_t reta_size,
404399a2dd95SBruce Richardson 			 uint16_t max_rxq)
404499a2dd95SBruce Richardson {
404599a2dd95SBruce Richardson 	uint16_t i, idx, shift;
404699a2dd95SBruce Richardson 
404799a2dd95SBruce Richardson 	if (max_rxq == 0) {
404899a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
404999a2dd95SBruce Richardson 		return -EINVAL;
405099a2dd95SBruce Richardson 	}
405199a2dd95SBruce Richardson 
405299a2dd95SBruce Richardson 	for (i = 0; i < reta_size; i++) {
4053295968d1SFerruh Yigit 		idx = i / RTE_ETH_RETA_GROUP_SIZE;
4054295968d1SFerruh Yigit 		shift = i % RTE_ETH_RETA_GROUP_SIZE;
4055e1823e08SThomas Monjalon 		if ((reta_conf[idx].mask & RTE_BIT64(shift)) &&
405699a2dd95SBruce Richardson 			(reta_conf[idx].reta[shift] >= max_rxq)) {
405799a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
405899a2dd95SBruce Richardson 				"reta_conf[%u]->reta[%u]: %u exceeds the maximum rxq index: %u\n",
405999a2dd95SBruce Richardson 				idx, shift,
406099a2dd95SBruce Richardson 				reta_conf[idx].reta[shift], max_rxq);
406199a2dd95SBruce Richardson 			return -EINVAL;
406299a2dd95SBruce Richardson 		}
406399a2dd95SBruce Richardson 	}
406499a2dd95SBruce Richardson 
406599a2dd95SBruce Richardson 	return 0;
406699a2dd95SBruce Richardson }
406799a2dd95SBruce Richardson 
406899a2dd95SBruce Richardson int
406999a2dd95SBruce Richardson rte_eth_dev_rss_reta_update(uint16_t port_id,
407099a2dd95SBruce Richardson 			    struct rte_eth_rss_reta_entry64 *reta_conf,
407199a2dd95SBruce Richardson 			    uint16_t reta_size)
407299a2dd95SBruce Richardson {
407399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
407499a2dd95SBruce Richardson 	int ret;
407599a2dd95SBruce Richardson 
407699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
407753ef1b34SMin Hu (Connor) 	dev = &rte_eth_devices[port_id];
407853ef1b34SMin Hu (Connor) 
407953ef1b34SMin Hu (Connor) 	if (reta_conf == NULL) {
408053ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
408153ef1b34SMin Hu (Connor) 			"Cannot update ethdev port %u RSS RETA to NULL\n",
408253ef1b34SMin Hu (Connor) 			port_id);
408353ef1b34SMin Hu (Connor) 		return -EINVAL;
408453ef1b34SMin Hu (Connor) 	}
408553ef1b34SMin Hu (Connor) 
408653ef1b34SMin Hu (Connor) 	if (reta_size == 0) {
408753ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
408853ef1b34SMin Hu (Connor) 			"Cannot update ethdev port %u RSS RETA with zero size\n",
408953ef1b34SMin Hu (Connor) 			port_id);
409053ef1b34SMin Hu (Connor) 		return -EINVAL;
409153ef1b34SMin Hu (Connor) 	}
409253ef1b34SMin Hu (Connor) 
409399a2dd95SBruce Richardson 	/* Check mask bits */
409499a2dd95SBruce Richardson 	ret = eth_check_reta_mask(reta_conf, reta_size);
409599a2dd95SBruce Richardson 	if (ret < 0)
409699a2dd95SBruce Richardson 		return ret;
409799a2dd95SBruce Richardson 
409899a2dd95SBruce Richardson 	/* Check entry value */
409999a2dd95SBruce Richardson 	ret = eth_check_reta_entry(reta_conf, reta_size,
410099a2dd95SBruce Richardson 				dev->data->nb_rx_queues);
410199a2dd95SBruce Richardson 	if (ret < 0)
410299a2dd95SBruce Richardson 		return ret;
410399a2dd95SBruce Richardson 
410499a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_update, -ENOTSUP);
410599a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->reta_update)(dev, reta_conf,
410699a2dd95SBruce Richardson 							     reta_size));
410799a2dd95SBruce Richardson }
410899a2dd95SBruce Richardson 
410999a2dd95SBruce Richardson int
411099a2dd95SBruce Richardson rte_eth_dev_rss_reta_query(uint16_t port_id,
411199a2dd95SBruce Richardson 			   struct rte_eth_rss_reta_entry64 *reta_conf,
411299a2dd95SBruce Richardson 			   uint16_t reta_size)
411399a2dd95SBruce Richardson {
411499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
411599a2dd95SBruce Richardson 	int ret;
411699a2dd95SBruce Richardson 
411799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
411853ef1b34SMin Hu (Connor) 	dev = &rte_eth_devices[port_id];
411953ef1b34SMin Hu (Connor) 
412053ef1b34SMin Hu (Connor) 	if (reta_conf == NULL) {
412153ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
412253ef1b34SMin Hu (Connor) 			"Cannot query ethdev port %u RSS RETA from NULL config\n",
412353ef1b34SMin Hu (Connor) 			port_id);
412453ef1b34SMin Hu (Connor) 		return -EINVAL;
412553ef1b34SMin Hu (Connor) 	}
412699a2dd95SBruce Richardson 
412799a2dd95SBruce Richardson 	/* Check mask bits */
412899a2dd95SBruce Richardson 	ret = eth_check_reta_mask(reta_conf, reta_size);
412999a2dd95SBruce Richardson 	if (ret < 0)
413099a2dd95SBruce Richardson 		return ret;
413199a2dd95SBruce Richardson 
413299a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP);
413399a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf,
413499a2dd95SBruce Richardson 							    reta_size));
413599a2dd95SBruce Richardson }
413699a2dd95SBruce Richardson 
413799a2dd95SBruce Richardson int
413899a2dd95SBruce Richardson rte_eth_dev_rss_hash_update(uint16_t port_id,
413999a2dd95SBruce Richardson 			    struct rte_eth_rss_conf *rss_conf)
414099a2dd95SBruce Richardson {
414199a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
414299a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
414399a2dd95SBruce Richardson 	int ret;
414499a2dd95SBruce Richardson 
414599a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
414653ef1b34SMin Hu (Connor) 	dev = &rte_eth_devices[port_id];
414753ef1b34SMin Hu (Connor) 
414853ef1b34SMin Hu (Connor) 	if (rss_conf == NULL) {
414953ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
415053ef1b34SMin Hu (Connor) 			"Cannot update ethdev port %u RSS hash from NULL config\n",
415153ef1b34SMin Hu (Connor) 			port_id);
415253ef1b34SMin Hu (Connor) 		return -EINVAL;
415353ef1b34SMin Hu (Connor) 	}
415499a2dd95SBruce Richardson 
415599a2dd95SBruce Richardson 	ret = rte_eth_dev_info_get(port_id, &dev_info);
415699a2dd95SBruce Richardson 	if (ret != 0)
415799a2dd95SBruce Richardson 		return ret;
415899a2dd95SBruce Richardson 
415999a2dd95SBruce Richardson 	rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf);
416099a2dd95SBruce Richardson 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
416199a2dd95SBruce Richardson 	    dev_info.flow_type_rss_offloads) {
416299a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
416399a2dd95SBruce Richardson 			"Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n",
416499a2dd95SBruce Richardson 			port_id, rss_conf->rss_hf,
416599a2dd95SBruce Richardson 			dev_info.flow_type_rss_offloads);
416699a2dd95SBruce Richardson 		return -EINVAL;
416799a2dd95SBruce Richardson 	}
416899a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP);
416999a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->rss_hash_update)(dev,
417099a2dd95SBruce Richardson 								 rss_conf));
417199a2dd95SBruce Richardson }
417299a2dd95SBruce Richardson 
417399a2dd95SBruce Richardson int
417499a2dd95SBruce Richardson rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
417599a2dd95SBruce Richardson 			      struct rte_eth_rss_conf *rss_conf)
417699a2dd95SBruce Richardson {
417799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
417899a2dd95SBruce Richardson 
417999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
418099a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
418153ef1b34SMin Hu (Connor) 
418253ef1b34SMin Hu (Connor) 	if (rss_conf == NULL) {
418353ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
418453ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u RSS hash config to NULL\n",
418553ef1b34SMin Hu (Connor) 			port_id);
418653ef1b34SMin Hu (Connor) 		return -EINVAL;
418753ef1b34SMin Hu (Connor) 	}
418853ef1b34SMin Hu (Connor) 
418999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
419099a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
419199a2dd95SBruce Richardson 								   rss_conf));
419299a2dd95SBruce Richardson }
419399a2dd95SBruce Richardson 
419499a2dd95SBruce Richardson int
419599a2dd95SBruce Richardson rte_eth_dev_udp_tunnel_port_add(uint16_t port_id,
419699a2dd95SBruce Richardson 				struct rte_eth_udp_tunnel *udp_tunnel)
419799a2dd95SBruce Richardson {
419899a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
419999a2dd95SBruce Richardson 
420099a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
420153ef1b34SMin Hu (Connor) 	dev = &rte_eth_devices[port_id];
420253ef1b34SMin Hu (Connor) 
420399a2dd95SBruce Richardson 	if (udp_tunnel == NULL) {
420453ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
420553ef1b34SMin Hu (Connor) 			"Cannot add ethdev port %u UDP tunnel port from NULL UDP tunnel\n",
420653ef1b34SMin Hu (Connor) 			port_id);
420799a2dd95SBruce Richardson 		return -EINVAL;
420899a2dd95SBruce Richardson 	}
420999a2dd95SBruce Richardson 
4210295968d1SFerruh Yigit 	if (udp_tunnel->prot_type >= RTE_ETH_TUNNEL_TYPE_MAX) {
421199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n");
421299a2dd95SBruce Richardson 		return -EINVAL;
421399a2dd95SBruce Richardson 	}
421499a2dd95SBruce Richardson 
421599a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_add, -ENOTSUP);
421699a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_add)(dev,
421799a2dd95SBruce Richardson 								udp_tunnel));
421899a2dd95SBruce Richardson }
421999a2dd95SBruce Richardson 
422099a2dd95SBruce Richardson int
422199a2dd95SBruce Richardson rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
422299a2dd95SBruce Richardson 				   struct rte_eth_udp_tunnel *udp_tunnel)
422399a2dd95SBruce Richardson {
422499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
422599a2dd95SBruce Richardson 
422699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
422799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
422899a2dd95SBruce Richardson 
422999a2dd95SBruce Richardson 	if (udp_tunnel == NULL) {
423053ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
423153ef1b34SMin Hu (Connor) 			"Cannot delete ethdev port %u UDP tunnel port from NULL UDP tunnel\n",
423253ef1b34SMin Hu (Connor) 			port_id);
423399a2dd95SBruce Richardson 		return -EINVAL;
423499a2dd95SBruce Richardson 	}
423599a2dd95SBruce Richardson 
4236295968d1SFerruh Yigit 	if (udp_tunnel->prot_type >= RTE_ETH_TUNNEL_TYPE_MAX) {
423799a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n");
423899a2dd95SBruce Richardson 		return -EINVAL;
423999a2dd95SBruce Richardson 	}
424099a2dd95SBruce Richardson 
424199a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_del, -ENOTSUP);
424299a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_del)(dev,
424399a2dd95SBruce Richardson 								udp_tunnel));
424499a2dd95SBruce Richardson }
424599a2dd95SBruce Richardson 
424699a2dd95SBruce Richardson int
424799a2dd95SBruce Richardson rte_eth_led_on(uint16_t port_id)
424899a2dd95SBruce Richardson {
424999a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
425099a2dd95SBruce Richardson 
425199a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
425299a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
425353ef1b34SMin Hu (Connor) 
425499a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_on, -ENOTSUP);
425599a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->dev_led_on)(dev));
425699a2dd95SBruce Richardson }
425799a2dd95SBruce Richardson 
425899a2dd95SBruce Richardson int
425999a2dd95SBruce Richardson rte_eth_led_off(uint16_t port_id)
426099a2dd95SBruce Richardson {
426199a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
426299a2dd95SBruce Richardson 
426399a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
426499a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
426553ef1b34SMin Hu (Connor) 
426699a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_off, -ENOTSUP);
426799a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->dev_led_off)(dev));
426899a2dd95SBruce Richardson }
426999a2dd95SBruce Richardson 
427099a2dd95SBruce Richardson int
427199a2dd95SBruce Richardson rte_eth_fec_get_capability(uint16_t port_id,
427299a2dd95SBruce Richardson 			   struct rte_eth_fec_capa *speed_fec_capa,
427399a2dd95SBruce Richardson 			   unsigned int num)
427499a2dd95SBruce Richardson {
427599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
427699a2dd95SBruce Richardson 	int ret;
427799a2dd95SBruce Richardson 
427899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
427999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
428053ef1b34SMin Hu (Connor) 
428153ef1b34SMin Hu (Connor) 	if (speed_fec_capa == NULL && num > 0) {
428253ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
428353ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u FEC capability to NULL when array size is non zero\n",
428453ef1b34SMin Hu (Connor) 			port_id);
428553ef1b34SMin Hu (Connor) 		return -EINVAL;
428653ef1b34SMin Hu (Connor) 	}
428753ef1b34SMin Hu (Connor) 
428899a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get_capability, -ENOTSUP);
428999a2dd95SBruce Richardson 	ret = (*dev->dev_ops->fec_get_capability)(dev, speed_fec_capa, num);
429099a2dd95SBruce Richardson 
429199a2dd95SBruce Richardson 	return ret;
429299a2dd95SBruce Richardson }
429399a2dd95SBruce Richardson 
429499a2dd95SBruce Richardson int
429599a2dd95SBruce Richardson rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa)
429699a2dd95SBruce Richardson {
429799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
429899a2dd95SBruce Richardson 
429999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
430099a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
430153ef1b34SMin Hu (Connor) 
430253ef1b34SMin Hu (Connor) 	if (fec_capa == NULL) {
430353ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
430453ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u current FEC mode to NULL\n",
430553ef1b34SMin Hu (Connor) 			port_id);
430653ef1b34SMin Hu (Connor) 		return -EINVAL;
430753ef1b34SMin Hu (Connor) 	}
430853ef1b34SMin Hu (Connor) 
430999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get, -ENOTSUP);
431099a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->fec_get)(dev, fec_capa));
431199a2dd95SBruce Richardson }
431299a2dd95SBruce Richardson 
431399a2dd95SBruce Richardson int
431499a2dd95SBruce Richardson rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa)
431599a2dd95SBruce Richardson {
431699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
431799a2dd95SBruce Richardson 
431899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
431999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
432053ef1b34SMin Hu (Connor) 
432199a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_set, -ENOTSUP);
432299a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->fec_set)(dev, fec_capa));
432399a2dd95SBruce Richardson }
432499a2dd95SBruce Richardson 
432599a2dd95SBruce Richardson /*
432699a2dd95SBruce Richardson  * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
432799a2dd95SBruce Richardson  * an empty spot.
432899a2dd95SBruce Richardson  */
432999a2dd95SBruce Richardson static int
433099a2dd95SBruce Richardson eth_dev_get_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr)
433199a2dd95SBruce Richardson {
433299a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info;
433399a2dd95SBruce Richardson 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
433499a2dd95SBruce Richardson 	unsigned i;
433599a2dd95SBruce Richardson 	int ret;
433699a2dd95SBruce Richardson 
433799a2dd95SBruce Richardson 	ret = rte_eth_dev_info_get(port_id, &dev_info);
433899a2dd95SBruce Richardson 	if (ret != 0)
433999a2dd95SBruce Richardson 		return -1;
434099a2dd95SBruce Richardson 
434199a2dd95SBruce Richardson 	for (i = 0; i < dev_info.max_mac_addrs; i++)
434299a2dd95SBruce Richardson 		if (memcmp(addr, &dev->data->mac_addrs[i],
434399a2dd95SBruce Richardson 				RTE_ETHER_ADDR_LEN) == 0)
434499a2dd95SBruce Richardson 			return i;
434599a2dd95SBruce Richardson 
434699a2dd95SBruce Richardson 	return -1;
434799a2dd95SBruce Richardson }
434899a2dd95SBruce Richardson 
434999a2dd95SBruce Richardson static const struct rte_ether_addr null_mac_addr;
435099a2dd95SBruce Richardson 
435199a2dd95SBruce Richardson int
435299a2dd95SBruce Richardson rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
435399a2dd95SBruce Richardson 			uint32_t pool)
435499a2dd95SBruce Richardson {
435599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
435699a2dd95SBruce Richardson 	int index;
435799a2dd95SBruce Richardson 	uint64_t pool_mask;
435899a2dd95SBruce Richardson 	int ret;
435999a2dd95SBruce Richardson 
436099a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
436199a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
436253ef1b34SMin Hu (Connor) 
436353ef1b34SMin Hu (Connor) 	if (addr == NULL) {
436453ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
436553ef1b34SMin Hu (Connor) 			"Cannot add ethdev port %u MAC address from NULL address\n",
436653ef1b34SMin Hu (Connor) 			port_id);
436753ef1b34SMin Hu (Connor) 		return -EINVAL;
436853ef1b34SMin Hu (Connor) 	}
436953ef1b34SMin Hu (Connor) 
437099a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
437199a2dd95SBruce Richardson 
437299a2dd95SBruce Richardson 	if (rte_is_zero_ether_addr(addr)) {
437399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
437499a2dd95SBruce Richardson 			port_id);
437599a2dd95SBruce Richardson 		return -EINVAL;
437699a2dd95SBruce Richardson 	}
4377295968d1SFerruh Yigit 	if (pool >= RTE_ETH_64_POOLS) {
4378295968d1SFerruh Yigit 		RTE_ETHDEV_LOG(ERR, "Pool ID must be 0-%d\n", RTE_ETH_64_POOLS - 1);
437999a2dd95SBruce Richardson 		return -EINVAL;
438099a2dd95SBruce Richardson 	}
438199a2dd95SBruce Richardson 
438299a2dd95SBruce Richardson 	index = eth_dev_get_mac_addr_index(port_id, addr);
438399a2dd95SBruce Richardson 	if (index < 0) {
438499a2dd95SBruce Richardson 		index = eth_dev_get_mac_addr_index(port_id, &null_mac_addr);
438599a2dd95SBruce Richardson 		if (index < 0) {
438699a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n",
438799a2dd95SBruce Richardson 				port_id);
438899a2dd95SBruce Richardson 			return -ENOSPC;
438999a2dd95SBruce Richardson 		}
439099a2dd95SBruce Richardson 	} else {
439199a2dd95SBruce Richardson 		pool_mask = dev->data->mac_pool_sel[index];
439299a2dd95SBruce Richardson 
439399a2dd95SBruce Richardson 		/* Check if both MAC address and pool is already there, and do nothing */
4394e1823e08SThomas Monjalon 		if (pool_mask & RTE_BIT64(pool))
439599a2dd95SBruce Richardson 			return 0;
439699a2dd95SBruce Richardson 	}
439799a2dd95SBruce Richardson 
439899a2dd95SBruce Richardson 	/* Update NIC */
439999a2dd95SBruce Richardson 	ret = (*dev->dev_ops->mac_addr_add)(dev, addr, index, pool);
440099a2dd95SBruce Richardson 
440199a2dd95SBruce Richardson 	if (ret == 0) {
440299a2dd95SBruce Richardson 		/* Update address in NIC data structure */
440399a2dd95SBruce Richardson 		rte_ether_addr_copy(addr, &dev->data->mac_addrs[index]);
440499a2dd95SBruce Richardson 
440599a2dd95SBruce Richardson 		/* Update pool bitmap in NIC data structure */
4406e1823e08SThomas Monjalon 		dev->data->mac_pool_sel[index] |= RTE_BIT64(pool);
440799a2dd95SBruce Richardson 	}
440899a2dd95SBruce Richardson 
440999a2dd95SBruce Richardson 	return eth_err(port_id, ret);
441099a2dd95SBruce Richardson }
441199a2dd95SBruce Richardson 
441299a2dd95SBruce Richardson int
441399a2dd95SBruce Richardson rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
441499a2dd95SBruce Richardson {
441599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
441699a2dd95SBruce Richardson 	int index;
441799a2dd95SBruce Richardson 
441899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
441999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
442053ef1b34SMin Hu (Connor) 
442153ef1b34SMin Hu (Connor) 	if (addr == NULL) {
442253ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
442353ef1b34SMin Hu (Connor) 			"Cannot remove ethdev port %u MAC address from NULL address\n",
442453ef1b34SMin Hu (Connor) 			port_id);
442553ef1b34SMin Hu (Connor) 		return -EINVAL;
442653ef1b34SMin Hu (Connor) 	}
442753ef1b34SMin Hu (Connor) 
442899a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
442999a2dd95SBruce Richardson 
443099a2dd95SBruce Richardson 	index = eth_dev_get_mac_addr_index(port_id, addr);
443199a2dd95SBruce Richardson 	if (index == 0) {
443299a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
443399a2dd95SBruce Richardson 			"Port %u: Cannot remove default MAC address\n",
443499a2dd95SBruce Richardson 			port_id);
443599a2dd95SBruce Richardson 		return -EADDRINUSE;
443699a2dd95SBruce Richardson 	} else if (index < 0)
443799a2dd95SBruce Richardson 		return 0;  /* Do nothing if address wasn't found */
443899a2dd95SBruce Richardson 
443999a2dd95SBruce Richardson 	/* Update NIC */
444099a2dd95SBruce Richardson 	(*dev->dev_ops->mac_addr_remove)(dev, index);
444199a2dd95SBruce Richardson 
444299a2dd95SBruce Richardson 	/* Update address in NIC data structure */
444399a2dd95SBruce Richardson 	rte_ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]);
444499a2dd95SBruce Richardson 
444599a2dd95SBruce Richardson 	/* reset pool bitmap */
444699a2dd95SBruce Richardson 	dev->data->mac_pool_sel[index] = 0;
444799a2dd95SBruce Richardson 
444899a2dd95SBruce Richardson 	return 0;
444999a2dd95SBruce Richardson }
445099a2dd95SBruce Richardson 
445199a2dd95SBruce Richardson int
445299a2dd95SBruce Richardson rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
445399a2dd95SBruce Richardson {
445499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
445599a2dd95SBruce Richardson 	int ret;
445699a2dd95SBruce Richardson 
445799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
445853ef1b34SMin Hu (Connor) 	dev = &rte_eth_devices[port_id];
445953ef1b34SMin Hu (Connor) 
446053ef1b34SMin Hu (Connor) 	if (addr == NULL) {
446153ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
446253ef1b34SMin Hu (Connor) 			"Cannot set ethdev port %u default MAC address from NULL address\n",
446353ef1b34SMin Hu (Connor) 			port_id);
446453ef1b34SMin Hu (Connor) 		return -EINVAL;
446553ef1b34SMin Hu (Connor) 	}
446699a2dd95SBruce Richardson 
446799a2dd95SBruce Richardson 	if (!rte_is_valid_assigned_ether_addr(addr))
446899a2dd95SBruce Richardson 		return -EINVAL;
446999a2dd95SBruce Richardson 
447099a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
447199a2dd95SBruce Richardson 
447299a2dd95SBruce Richardson 	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
447399a2dd95SBruce Richardson 	if (ret < 0)
447499a2dd95SBruce Richardson 		return ret;
447599a2dd95SBruce Richardson 
447699a2dd95SBruce Richardson 	/* Update default address in NIC data structure */
447799a2dd95SBruce Richardson 	rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
447899a2dd95SBruce Richardson 
447999a2dd95SBruce Richardson 	return 0;
448099a2dd95SBruce Richardson }
448199a2dd95SBruce Richardson 
448299a2dd95SBruce Richardson 
448399a2dd95SBruce Richardson /*
448499a2dd95SBruce Richardson  * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
448599a2dd95SBruce Richardson  * an empty spot.
448699a2dd95SBruce Richardson  */
448799a2dd95SBruce Richardson static int
448899a2dd95SBruce Richardson eth_dev_get_hash_mac_addr_index(uint16_t port_id,
448999a2dd95SBruce Richardson 		const struct rte_ether_addr *addr)
449099a2dd95SBruce Richardson {
449199a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info;
449299a2dd95SBruce Richardson 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
449399a2dd95SBruce Richardson 	unsigned i;
449499a2dd95SBruce Richardson 	int ret;
449599a2dd95SBruce Richardson 
449699a2dd95SBruce Richardson 	ret = rte_eth_dev_info_get(port_id, &dev_info);
449799a2dd95SBruce Richardson 	if (ret != 0)
449899a2dd95SBruce Richardson 		return -1;
449999a2dd95SBruce Richardson 
450099a2dd95SBruce Richardson 	if (!dev->data->hash_mac_addrs)
450199a2dd95SBruce Richardson 		return -1;
450299a2dd95SBruce Richardson 
450399a2dd95SBruce Richardson 	for (i = 0; i < dev_info.max_hash_mac_addrs; i++)
450499a2dd95SBruce Richardson 		if (memcmp(addr, &dev->data->hash_mac_addrs[i],
450599a2dd95SBruce Richardson 			RTE_ETHER_ADDR_LEN) == 0)
450699a2dd95SBruce Richardson 			return i;
450799a2dd95SBruce Richardson 
450899a2dd95SBruce Richardson 	return -1;
450999a2dd95SBruce Richardson }
451099a2dd95SBruce Richardson 
451199a2dd95SBruce Richardson int
451299a2dd95SBruce Richardson rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
451399a2dd95SBruce Richardson 				uint8_t on)
451499a2dd95SBruce Richardson {
451599a2dd95SBruce Richardson 	int index;
451699a2dd95SBruce Richardson 	int ret;
451799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
451899a2dd95SBruce Richardson 
451999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
452099a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
452153ef1b34SMin Hu (Connor) 
452253ef1b34SMin Hu (Connor) 	if (addr == NULL) {
452353ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
452453ef1b34SMin Hu (Connor) 			"Cannot set ethdev port %u unicast hash table from NULL address\n",
452553ef1b34SMin Hu (Connor) 			port_id);
452653ef1b34SMin Hu (Connor) 		return -EINVAL;
452753ef1b34SMin Hu (Connor) 	}
452853ef1b34SMin Hu (Connor) 
452999a2dd95SBruce Richardson 	if (rte_is_zero_ether_addr(addr)) {
453099a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
453199a2dd95SBruce Richardson 			port_id);
453299a2dd95SBruce Richardson 		return -EINVAL;
453399a2dd95SBruce Richardson 	}
453499a2dd95SBruce Richardson 
453599a2dd95SBruce Richardson 	index = eth_dev_get_hash_mac_addr_index(port_id, addr);
453699a2dd95SBruce Richardson 	/* Check if it's already there, and do nothing */
453799a2dd95SBruce Richardson 	if ((index >= 0) && on)
453899a2dd95SBruce Richardson 		return 0;
453999a2dd95SBruce Richardson 
454099a2dd95SBruce Richardson 	if (index < 0) {
454199a2dd95SBruce Richardson 		if (!on) {
454299a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
454399a2dd95SBruce Richardson 				"Port %u: the MAC address was not set in UTA\n",
454499a2dd95SBruce Richardson 				port_id);
454599a2dd95SBruce Richardson 			return -EINVAL;
454699a2dd95SBruce Richardson 		}
454799a2dd95SBruce Richardson 
454899a2dd95SBruce Richardson 		index = eth_dev_get_hash_mac_addr_index(port_id, &null_mac_addr);
454999a2dd95SBruce Richardson 		if (index < 0) {
455099a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n",
455199a2dd95SBruce Richardson 				port_id);
455299a2dd95SBruce Richardson 			return -ENOSPC;
455399a2dd95SBruce Richardson 		}
455499a2dd95SBruce Richardson 	}
455599a2dd95SBruce Richardson 
455699a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_hash_table_set, -ENOTSUP);
455799a2dd95SBruce Richardson 	ret = (*dev->dev_ops->uc_hash_table_set)(dev, addr, on);
455899a2dd95SBruce Richardson 	if (ret == 0) {
455999a2dd95SBruce Richardson 		/* Update address in NIC data structure */
456099a2dd95SBruce Richardson 		if (on)
456199a2dd95SBruce Richardson 			rte_ether_addr_copy(addr,
456299a2dd95SBruce Richardson 					&dev->data->hash_mac_addrs[index]);
456399a2dd95SBruce Richardson 		else
456499a2dd95SBruce Richardson 			rte_ether_addr_copy(&null_mac_addr,
456599a2dd95SBruce Richardson 					&dev->data->hash_mac_addrs[index]);
456699a2dd95SBruce Richardson 	}
456799a2dd95SBruce Richardson 
456899a2dd95SBruce Richardson 	return eth_err(port_id, ret);
456999a2dd95SBruce Richardson }
457099a2dd95SBruce Richardson 
457199a2dd95SBruce Richardson int
457299a2dd95SBruce Richardson rte_eth_dev_uc_all_hash_table_set(uint16_t port_id, uint8_t on)
457399a2dd95SBruce Richardson {
457499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
457599a2dd95SBruce Richardson 
457699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
457799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
457899a2dd95SBruce Richardson 
457999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_all_hash_table_set, -ENOTSUP);
458099a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->uc_all_hash_table_set)(dev,
458199a2dd95SBruce Richardson 								       on));
458299a2dd95SBruce Richardson }
458399a2dd95SBruce Richardson 
458499a2dd95SBruce Richardson int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
458599a2dd95SBruce Richardson 					uint16_t tx_rate)
458699a2dd95SBruce Richardson {
458799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
458899a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info;
458999a2dd95SBruce Richardson 	struct rte_eth_link link;
459099a2dd95SBruce Richardson 	int ret;
459199a2dd95SBruce Richardson 
459299a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
459353ef1b34SMin Hu (Connor) 	dev = &rte_eth_devices[port_id];
459499a2dd95SBruce Richardson 
459599a2dd95SBruce Richardson 	ret = rte_eth_dev_info_get(port_id, &dev_info);
459699a2dd95SBruce Richardson 	if (ret != 0)
459799a2dd95SBruce Richardson 		return ret;
459899a2dd95SBruce Richardson 
459999a2dd95SBruce Richardson 	link = dev->data->dev_link;
460099a2dd95SBruce Richardson 
460199a2dd95SBruce Richardson 	if (queue_idx > dev_info.max_tx_queues) {
460299a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
46035906be5aSAndrew Rybchenko 			"Set queue rate limit:port %u: invalid queue ID=%u\n",
460499a2dd95SBruce Richardson 			port_id, queue_idx);
460599a2dd95SBruce Richardson 		return -EINVAL;
460699a2dd95SBruce Richardson 	}
460799a2dd95SBruce Richardson 
460899a2dd95SBruce Richardson 	if (tx_rate > link.link_speed) {
460999a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
461099a2dd95SBruce Richardson 			"Set queue rate limit:invalid tx_rate=%u, bigger than link speed= %d\n",
461199a2dd95SBruce Richardson 			tx_rate, link.link_speed);
461299a2dd95SBruce Richardson 		return -EINVAL;
461399a2dd95SBruce Richardson 	}
461499a2dd95SBruce Richardson 
461599a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_queue_rate_limit, -ENOTSUP);
461699a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->set_queue_rate_limit)(dev,
461799a2dd95SBruce Richardson 							queue_idx, tx_rate));
461899a2dd95SBruce Richardson }
461999a2dd95SBruce Richardson 
4620c87d435aSKonstantin Ananyev RTE_INIT(eth_dev_init_fp_ops)
4621c87d435aSKonstantin Ananyev {
4622c87d435aSKonstantin Ananyev 	uint32_t i;
4623c87d435aSKonstantin Ananyev 
4624c87d435aSKonstantin Ananyev 	for (i = 0; i != RTE_DIM(rte_eth_fp_ops); i++)
4625c87d435aSKonstantin Ananyev 		eth_dev_fp_ops_reset(rte_eth_fp_ops + i);
4626c87d435aSKonstantin Ananyev }
4627c87d435aSKonstantin Ananyev 
462899a2dd95SBruce Richardson RTE_INIT(eth_dev_init_cb_lists)
462999a2dd95SBruce Richardson {
463099a2dd95SBruce Richardson 	uint16_t i;
463199a2dd95SBruce Richardson 
463299a2dd95SBruce Richardson 	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
463399a2dd95SBruce Richardson 		TAILQ_INIT(&rte_eth_devices[i].link_intr_cbs);
463499a2dd95SBruce Richardson }
463599a2dd95SBruce Richardson 
463699a2dd95SBruce Richardson int
463799a2dd95SBruce Richardson rte_eth_dev_callback_register(uint16_t port_id,
463899a2dd95SBruce Richardson 			enum rte_eth_event_type event,
463999a2dd95SBruce Richardson 			rte_eth_dev_cb_fn cb_fn, void *cb_arg)
464099a2dd95SBruce Richardson {
464199a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
464299a2dd95SBruce Richardson 	struct rte_eth_dev_callback *user_cb;
464399a2dd95SBruce Richardson 	uint16_t next_port;
464499a2dd95SBruce Richardson 	uint16_t last_port;
464599a2dd95SBruce Richardson 
464653ef1b34SMin Hu (Connor) 	if (cb_fn == NULL) {
464753ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
464853ef1b34SMin Hu (Connor) 			"Cannot register ethdev port %u callback from NULL\n",
464953ef1b34SMin Hu (Connor) 			port_id);
465099a2dd95SBruce Richardson 		return -EINVAL;
465153ef1b34SMin Hu (Connor) 	}
465299a2dd95SBruce Richardson 
465399a2dd95SBruce Richardson 	if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
465499a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id);
465599a2dd95SBruce Richardson 		return -EINVAL;
465699a2dd95SBruce Richardson 	}
465799a2dd95SBruce Richardson 
465899a2dd95SBruce Richardson 	if (port_id == RTE_ETH_ALL) {
465999a2dd95SBruce Richardson 		next_port = 0;
466099a2dd95SBruce Richardson 		last_port = RTE_MAX_ETHPORTS - 1;
466199a2dd95SBruce Richardson 	} else {
466299a2dd95SBruce Richardson 		next_port = last_port = port_id;
466399a2dd95SBruce Richardson 	}
466499a2dd95SBruce Richardson 
466599a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_cb_lock);
466699a2dd95SBruce Richardson 
466799a2dd95SBruce Richardson 	do {
466899a2dd95SBruce Richardson 		dev = &rte_eth_devices[next_port];
466999a2dd95SBruce Richardson 
467099a2dd95SBruce Richardson 		TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) {
467199a2dd95SBruce Richardson 			if (user_cb->cb_fn == cb_fn &&
467299a2dd95SBruce Richardson 				user_cb->cb_arg == cb_arg &&
467399a2dd95SBruce Richardson 				user_cb->event == event) {
467499a2dd95SBruce Richardson 				break;
467599a2dd95SBruce Richardson 			}
467699a2dd95SBruce Richardson 		}
467799a2dd95SBruce Richardson 
467899a2dd95SBruce Richardson 		/* create a new callback. */
467999a2dd95SBruce Richardson 		if (user_cb == NULL) {
468099a2dd95SBruce Richardson 			user_cb = rte_zmalloc("INTR_USER_CALLBACK",
468199a2dd95SBruce Richardson 				sizeof(struct rte_eth_dev_callback), 0);
468299a2dd95SBruce Richardson 			if (user_cb != NULL) {
468399a2dd95SBruce Richardson 				user_cb->cb_fn = cb_fn;
468499a2dd95SBruce Richardson 				user_cb->cb_arg = cb_arg;
468599a2dd95SBruce Richardson 				user_cb->event = event;
468699a2dd95SBruce Richardson 				TAILQ_INSERT_TAIL(&(dev->link_intr_cbs),
468799a2dd95SBruce Richardson 						  user_cb, next);
468899a2dd95SBruce Richardson 			} else {
468999a2dd95SBruce Richardson 				rte_spinlock_unlock(&eth_dev_cb_lock);
469099a2dd95SBruce Richardson 				rte_eth_dev_callback_unregister(port_id, event,
469199a2dd95SBruce Richardson 								cb_fn, cb_arg);
469299a2dd95SBruce Richardson 				return -ENOMEM;
469399a2dd95SBruce Richardson 			}
469499a2dd95SBruce Richardson 
469599a2dd95SBruce Richardson 		}
469699a2dd95SBruce Richardson 	} while (++next_port <= last_port);
469799a2dd95SBruce Richardson 
469899a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_cb_lock);
469999a2dd95SBruce Richardson 	return 0;
470099a2dd95SBruce Richardson }
470199a2dd95SBruce Richardson 
470299a2dd95SBruce Richardson int
470399a2dd95SBruce Richardson rte_eth_dev_callback_unregister(uint16_t port_id,
470499a2dd95SBruce Richardson 			enum rte_eth_event_type event,
470599a2dd95SBruce Richardson 			rte_eth_dev_cb_fn cb_fn, void *cb_arg)
470699a2dd95SBruce Richardson {
470799a2dd95SBruce Richardson 	int ret;
470899a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
470999a2dd95SBruce Richardson 	struct rte_eth_dev_callback *cb, *next;
471099a2dd95SBruce Richardson 	uint16_t next_port;
471199a2dd95SBruce Richardson 	uint16_t last_port;
471299a2dd95SBruce Richardson 
471353ef1b34SMin Hu (Connor) 	if (cb_fn == NULL) {
471453ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
471553ef1b34SMin Hu (Connor) 			"Cannot unregister ethdev port %u callback from NULL\n",
471653ef1b34SMin Hu (Connor) 			port_id);
471799a2dd95SBruce Richardson 		return -EINVAL;
471853ef1b34SMin Hu (Connor) 	}
471999a2dd95SBruce Richardson 
472099a2dd95SBruce Richardson 	if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
472199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id);
472299a2dd95SBruce Richardson 		return -EINVAL;
472399a2dd95SBruce Richardson 	}
472499a2dd95SBruce Richardson 
472599a2dd95SBruce Richardson 	if (port_id == RTE_ETH_ALL) {
472699a2dd95SBruce Richardson 		next_port = 0;
472799a2dd95SBruce Richardson 		last_port = RTE_MAX_ETHPORTS - 1;
472899a2dd95SBruce Richardson 	} else {
472999a2dd95SBruce Richardson 		next_port = last_port = port_id;
473099a2dd95SBruce Richardson 	}
473199a2dd95SBruce Richardson 
473299a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_cb_lock);
473399a2dd95SBruce Richardson 
473499a2dd95SBruce Richardson 	do {
473599a2dd95SBruce Richardson 		dev = &rte_eth_devices[next_port];
473699a2dd95SBruce Richardson 		ret = 0;
473799a2dd95SBruce Richardson 		for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL;
473899a2dd95SBruce Richardson 		     cb = next) {
473999a2dd95SBruce Richardson 
474099a2dd95SBruce Richardson 			next = TAILQ_NEXT(cb, next);
474199a2dd95SBruce Richardson 
474299a2dd95SBruce Richardson 			if (cb->cb_fn != cb_fn || cb->event != event ||
474399a2dd95SBruce Richardson 			    (cb_arg != (void *)-1 && cb->cb_arg != cb_arg))
474499a2dd95SBruce Richardson 				continue;
474599a2dd95SBruce Richardson 
474699a2dd95SBruce Richardson 			/*
474799a2dd95SBruce Richardson 			 * if this callback is not executing right now,
474899a2dd95SBruce Richardson 			 * then remove it.
474999a2dd95SBruce Richardson 			 */
475099a2dd95SBruce Richardson 			if (cb->active == 0) {
475199a2dd95SBruce Richardson 				TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next);
475299a2dd95SBruce Richardson 				rte_free(cb);
475399a2dd95SBruce Richardson 			} else {
475499a2dd95SBruce Richardson 				ret = -EAGAIN;
475599a2dd95SBruce Richardson 			}
475699a2dd95SBruce Richardson 		}
475799a2dd95SBruce Richardson 	} while (++next_port <= last_port);
475899a2dd95SBruce Richardson 
475999a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_cb_lock);
476099a2dd95SBruce Richardson 	return ret;
476199a2dd95SBruce Richardson }
476299a2dd95SBruce Richardson 
476399a2dd95SBruce Richardson int
476499a2dd95SBruce Richardson rte_eth_dev_callback_process(struct rte_eth_dev *dev,
476599a2dd95SBruce Richardson 	enum rte_eth_event_type event, void *ret_param)
476699a2dd95SBruce Richardson {
476799a2dd95SBruce Richardson 	struct rte_eth_dev_callback *cb_lst;
476899a2dd95SBruce Richardson 	struct rte_eth_dev_callback dev_cb;
476999a2dd95SBruce Richardson 	int rc = 0;
477099a2dd95SBruce Richardson 
477199a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_cb_lock);
477299a2dd95SBruce Richardson 	TAILQ_FOREACH(cb_lst, &(dev->link_intr_cbs), next) {
477399a2dd95SBruce Richardson 		if (cb_lst->cb_fn == NULL || cb_lst->event != event)
477499a2dd95SBruce Richardson 			continue;
477599a2dd95SBruce Richardson 		dev_cb = *cb_lst;
477699a2dd95SBruce Richardson 		cb_lst->active = 1;
477799a2dd95SBruce Richardson 		if (ret_param != NULL)
477899a2dd95SBruce Richardson 			dev_cb.ret_param = ret_param;
477999a2dd95SBruce Richardson 
478099a2dd95SBruce Richardson 		rte_spinlock_unlock(&eth_dev_cb_lock);
478199a2dd95SBruce Richardson 		rc = dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
478299a2dd95SBruce Richardson 				dev_cb.cb_arg, dev_cb.ret_param);
478399a2dd95SBruce Richardson 		rte_spinlock_lock(&eth_dev_cb_lock);
478499a2dd95SBruce Richardson 		cb_lst->active = 0;
478599a2dd95SBruce Richardson 	}
478699a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_cb_lock);
478799a2dd95SBruce Richardson 	return rc;
478899a2dd95SBruce Richardson }
478999a2dd95SBruce Richardson 
479099a2dd95SBruce Richardson void
479199a2dd95SBruce Richardson rte_eth_dev_probing_finish(struct rte_eth_dev *dev)
479299a2dd95SBruce Richardson {
479399a2dd95SBruce Richardson 	if (dev == NULL)
479499a2dd95SBruce Richardson 		return;
479599a2dd95SBruce Richardson 
4796c87d435aSKonstantin Ananyev 	/*
4797c87d435aSKonstantin Ananyev 	 * for secondary process, at that point we expect device
4798c87d435aSKonstantin Ananyev 	 * to be already 'usable', so shared data and all function pointers
4799c87d435aSKonstantin Ananyev 	 * for fast-path devops have to be setup properly inside rte_eth_dev.
4800c87d435aSKonstantin Ananyev 	 */
4801c87d435aSKonstantin Ananyev 	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
4802c87d435aSKonstantin Ananyev 		eth_dev_fp_ops_setup(rte_eth_fp_ops + dev->data->port_id, dev);
4803c87d435aSKonstantin Ananyev 
480499a2dd95SBruce Richardson 	rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_NEW, NULL);
480599a2dd95SBruce Richardson 
480699a2dd95SBruce Richardson 	dev->state = RTE_ETH_DEV_ATTACHED;
480799a2dd95SBruce Richardson }
480899a2dd95SBruce Richardson 
480999a2dd95SBruce Richardson int
481099a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data)
481199a2dd95SBruce Richardson {
481299a2dd95SBruce Richardson 	uint32_t vec;
481399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
481499a2dd95SBruce Richardson 	struct rte_intr_handle *intr_handle;
481599a2dd95SBruce Richardson 	uint16_t qid;
481699a2dd95SBruce Richardson 	int rc;
481799a2dd95SBruce Richardson 
481899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
481999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
482099a2dd95SBruce Richardson 
482199a2dd95SBruce Richardson 	if (!dev->intr_handle) {
482209fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Rx Intr handle unset\n");
482399a2dd95SBruce Richardson 		return -ENOTSUP;
482499a2dd95SBruce Richardson 	}
482599a2dd95SBruce Richardson 
482699a2dd95SBruce Richardson 	intr_handle = dev->intr_handle;
4827c2bd9367SHarman Kalra 	if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) {
482809fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n");
482999a2dd95SBruce Richardson 		return -EPERM;
483099a2dd95SBruce Richardson 	}
483199a2dd95SBruce Richardson 
483299a2dd95SBruce Richardson 	for (qid = 0; qid < dev->data->nb_rx_queues; qid++) {
4833c2bd9367SHarman Kalra 		vec = rte_intr_vec_list_index_get(intr_handle, qid);
483499a2dd95SBruce Richardson 		rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data);
483599a2dd95SBruce Richardson 		if (rc && rc != -EEXIST) {
483699a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
483709fd4227SAndrew Rybchenko 				"p %u q %u Rx ctl error op %d epfd %d vec %u\n",
483899a2dd95SBruce Richardson 				port_id, qid, op, epfd, vec);
483999a2dd95SBruce Richardson 		}
484099a2dd95SBruce Richardson 	}
484199a2dd95SBruce Richardson 
484299a2dd95SBruce Richardson 	return 0;
484399a2dd95SBruce Richardson }
484499a2dd95SBruce Richardson 
484599a2dd95SBruce Richardson int
484699a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id, uint16_t queue_id)
484799a2dd95SBruce Richardson {
484899a2dd95SBruce Richardson 	struct rte_intr_handle *intr_handle;
484999a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
485099a2dd95SBruce Richardson 	unsigned int efd_idx;
485199a2dd95SBruce Richardson 	uint32_t vec;
485299a2dd95SBruce Richardson 	int fd;
485399a2dd95SBruce Richardson 
485499a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
485599a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
485699a2dd95SBruce Richardson 
485799a2dd95SBruce Richardson 	if (queue_id >= dev->data->nb_rx_queues) {
485809fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id);
485999a2dd95SBruce Richardson 		return -1;
486099a2dd95SBruce Richardson 	}
486199a2dd95SBruce Richardson 
486299a2dd95SBruce Richardson 	if (!dev->intr_handle) {
486309fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Rx Intr handle unset\n");
486499a2dd95SBruce Richardson 		return -1;
486599a2dd95SBruce Richardson 	}
486699a2dd95SBruce Richardson 
486799a2dd95SBruce Richardson 	intr_handle = dev->intr_handle;
4868c2bd9367SHarman Kalra 	if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) {
486909fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n");
487099a2dd95SBruce Richardson 		return -1;
487199a2dd95SBruce Richardson 	}
487299a2dd95SBruce Richardson 
4873c2bd9367SHarman Kalra 	vec = rte_intr_vec_list_index_get(intr_handle, queue_id);
487499a2dd95SBruce Richardson 	efd_idx = (vec >= RTE_INTR_VEC_RXTX_OFFSET) ?
487599a2dd95SBruce Richardson 		(vec - RTE_INTR_VEC_RXTX_OFFSET) : vec;
4876c2bd9367SHarman Kalra 	fd = rte_intr_efds_index_get(intr_handle, efd_idx);
487799a2dd95SBruce Richardson 
487899a2dd95SBruce Richardson 	return fd;
487999a2dd95SBruce Richardson }
488099a2dd95SBruce Richardson 
488199a2dd95SBruce Richardson static inline int
488299a2dd95SBruce Richardson eth_dev_dma_mzone_name(char *name, size_t len, uint16_t port_id, uint16_t queue_id,
488399a2dd95SBruce Richardson 		const char *ring_name)
488499a2dd95SBruce Richardson {
488599a2dd95SBruce Richardson 	return snprintf(name, len, "eth_p%d_q%d_%s",
488699a2dd95SBruce Richardson 			port_id, queue_id, ring_name);
488799a2dd95SBruce Richardson }
488899a2dd95SBruce Richardson 
488999a2dd95SBruce Richardson const struct rte_memzone *
489099a2dd95SBruce Richardson rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
489199a2dd95SBruce Richardson 			 uint16_t queue_id, size_t size, unsigned align,
489299a2dd95SBruce Richardson 			 int socket_id)
489399a2dd95SBruce Richardson {
489499a2dd95SBruce Richardson 	char z_name[RTE_MEMZONE_NAMESIZE];
489599a2dd95SBruce Richardson 	const struct rte_memzone *mz;
489699a2dd95SBruce Richardson 	int rc;
489799a2dd95SBruce Richardson 
489899a2dd95SBruce Richardson 	rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id,
489999a2dd95SBruce Richardson 			queue_id, ring_name);
490099a2dd95SBruce Richardson 	if (rc >= RTE_MEMZONE_NAMESIZE) {
490199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "ring name too long\n");
490299a2dd95SBruce Richardson 		rte_errno = ENAMETOOLONG;
490399a2dd95SBruce Richardson 		return NULL;
490499a2dd95SBruce Richardson 	}
490599a2dd95SBruce Richardson 
490699a2dd95SBruce Richardson 	mz = rte_memzone_lookup(z_name);
490799a2dd95SBruce Richardson 	if (mz) {
490899a2dd95SBruce Richardson 		if ((socket_id != SOCKET_ID_ANY && socket_id != mz->socket_id) ||
490999a2dd95SBruce Richardson 				size > mz->len ||
491099a2dd95SBruce Richardson 				((uintptr_t)mz->addr & (align - 1)) != 0) {
491199a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
491299a2dd95SBruce Richardson 				"memzone %s does not justify the requested attributes\n",
491399a2dd95SBruce Richardson 				mz->name);
491499a2dd95SBruce Richardson 			return NULL;
491599a2dd95SBruce Richardson 		}
491699a2dd95SBruce Richardson 
491799a2dd95SBruce Richardson 		return mz;
491899a2dd95SBruce Richardson 	}
491999a2dd95SBruce Richardson 
492099a2dd95SBruce Richardson 	return rte_memzone_reserve_aligned(z_name, size, socket_id,
492199a2dd95SBruce Richardson 			RTE_MEMZONE_IOVA_CONTIG, align);
492299a2dd95SBruce Richardson }
492399a2dd95SBruce Richardson 
492499a2dd95SBruce Richardson int
492599a2dd95SBruce Richardson rte_eth_dma_zone_free(const struct rte_eth_dev *dev, const char *ring_name,
492699a2dd95SBruce Richardson 		uint16_t queue_id)
492799a2dd95SBruce Richardson {
492899a2dd95SBruce Richardson 	char z_name[RTE_MEMZONE_NAMESIZE];
492999a2dd95SBruce Richardson 	const struct rte_memzone *mz;
493099a2dd95SBruce Richardson 	int rc = 0;
493199a2dd95SBruce Richardson 
493299a2dd95SBruce Richardson 	rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id,
493399a2dd95SBruce Richardson 			queue_id, ring_name);
493499a2dd95SBruce Richardson 	if (rc >= RTE_MEMZONE_NAMESIZE) {
493599a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "ring name too long\n");
493699a2dd95SBruce Richardson 		return -ENAMETOOLONG;
493799a2dd95SBruce Richardson 	}
493899a2dd95SBruce Richardson 
493999a2dd95SBruce Richardson 	mz = rte_memzone_lookup(z_name);
494099a2dd95SBruce Richardson 	if (mz)
494199a2dd95SBruce Richardson 		rc = rte_memzone_free(mz);
494299a2dd95SBruce Richardson 	else
494399a2dd95SBruce Richardson 		rc = -ENOENT;
494499a2dd95SBruce Richardson 
494599a2dd95SBruce Richardson 	return rc;
494699a2dd95SBruce Richardson }
494799a2dd95SBruce Richardson 
494899a2dd95SBruce Richardson int
494999a2dd95SBruce Richardson rte_eth_dev_create(struct rte_device *device, const char *name,
495099a2dd95SBruce Richardson 	size_t priv_data_size,
495199a2dd95SBruce Richardson 	ethdev_bus_specific_init ethdev_bus_specific_init,
495299a2dd95SBruce Richardson 	void *bus_init_params,
495399a2dd95SBruce Richardson 	ethdev_init_t ethdev_init, void *init_params)
495499a2dd95SBruce Richardson {
495599a2dd95SBruce Richardson 	struct rte_eth_dev *ethdev;
495699a2dd95SBruce Richardson 	int retval;
495799a2dd95SBruce Richardson 
495899a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL);
495999a2dd95SBruce Richardson 
496099a2dd95SBruce Richardson 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
496199a2dd95SBruce Richardson 		ethdev = rte_eth_dev_allocate(name);
496299a2dd95SBruce Richardson 		if (!ethdev)
496399a2dd95SBruce Richardson 			return -ENODEV;
496499a2dd95SBruce Richardson 
496599a2dd95SBruce Richardson 		if (priv_data_size) {
496699a2dd95SBruce Richardson 			ethdev->data->dev_private = rte_zmalloc_socket(
496799a2dd95SBruce Richardson 				name, priv_data_size, RTE_CACHE_LINE_SIZE,
496899a2dd95SBruce Richardson 				device->numa_node);
496999a2dd95SBruce Richardson 
497099a2dd95SBruce Richardson 			if (!ethdev->data->dev_private) {
497199a2dd95SBruce Richardson 				RTE_ETHDEV_LOG(ERR,
497299a2dd95SBruce Richardson 					"failed to allocate private data\n");
497399a2dd95SBruce Richardson 				retval = -ENOMEM;
497499a2dd95SBruce Richardson 				goto probe_failed;
497599a2dd95SBruce Richardson 			}
497699a2dd95SBruce Richardson 		}
497799a2dd95SBruce Richardson 	} else {
497899a2dd95SBruce Richardson 		ethdev = rte_eth_dev_attach_secondary(name);
497999a2dd95SBruce Richardson 		if (!ethdev) {
498099a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
498199a2dd95SBruce Richardson 				"secondary process attach failed, ethdev doesn't exist\n");
498299a2dd95SBruce Richardson 			return  -ENODEV;
498399a2dd95SBruce Richardson 		}
498499a2dd95SBruce Richardson 	}
498599a2dd95SBruce Richardson 
498699a2dd95SBruce Richardson 	ethdev->device = device;
498799a2dd95SBruce Richardson 
498899a2dd95SBruce Richardson 	if (ethdev_bus_specific_init) {
498999a2dd95SBruce Richardson 		retval = ethdev_bus_specific_init(ethdev, bus_init_params);
499099a2dd95SBruce Richardson 		if (retval) {
499199a2dd95SBruce Richardson 			RTE_ETHDEV_LOG(ERR,
499299a2dd95SBruce Richardson 				"ethdev bus specific initialisation failed\n");
499399a2dd95SBruce Richardson 			goto probe_failed;
499499a2dd95SBruce Richardson 		}
499599a2dd95SBruce Richardson 	}
499699a2dd95SBruce Richardson 
499799a2dd95SBruce Richardson 	retval = ethdev_init(ethdev, init_params);
499899a2dd95SBruce Richardson 	if (retval) {
499999a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "ethdev initialisation failed\n");
500099a2dd95SBruce Richardson 		goto probe_failed;
500199a2dd95SBruce Richardson 	}
500299a2dd95SBruce Richardson 
500399a2dd95SBruce Richardson 	rte_eth_dev_probing_finish(ethdev);
500499a2dd95SBruce Richardson 
500599a2dd95SBruce Richardson 	return retval;
500699a2dd95SBruce Richardson 
500799a2dd95SBruce Richardson probe_failed:
500899a2dd95SBruce Richardson 	rte_eth_dev_release_port(ethdev);
500999a2dd95SBruce Richardson 	return retval;
501099a2dd95SBruce Richardson }
501199a2dd95SBruce Richardson 
501299a2dd95SBruce Richardson int
501399a2dd95SBruce Richardson rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
501499a2dd95SBruce Richardson 	ethdev_uninit_t ethdev_uninit)
501599a2dd95SBruce Richardson {
501699a2dd95SBruce Richardson 	int ret;
501799a2dd95SBruce Richardson 
501899a2dd95SBruce Richardson 	ethdev = rte_eth_dev_allocated(ethdev->data->name);
501999a2dd95SBruce Richardson 	if (!ethdev)
502099a2dd95SBruce Richardson 		return -ENODEV;
502199a2dd95SBruce Richardson 
502299a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL);
502399a2dd95SBruce Richardson 
502499a2dd95SBruce Richardson 	ret = ethdev_uninit(ethdev);
502599a2dd95SBruce Richardson 	if (ret)
502699a2dd95SBruce Richardson 		return ret;
502799a2dd95SBruce Richardson 
502899a2dd95SBruce Richardson 	return rte_eth_dev_release_port(ethdev);
502999a2dd95SBruce Richardson }
503099a2dd95SBruce Richardson 
503199a2dd95SBruce Richardson int
503299a2dd95SBruce Richardson rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
503399a2dd95SBruce Richardson 			  int epfd, int op, void *data)
503499a2dd95SBruce Richardson {
503599a2dd95SBruce Richardson 	uint32_t vec;
503699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
503799a2dd95SBruce Richardson 	struct rte_intr_handle *intr_handle;
503899a2dd95SBruce Richardson 	int rc;
503999a2dd95SBruce Richardson 
504099a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
504199a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
504253ef1b34SMin Hu (Connor) 
504399a2dd95SBruce Richardson 	if (queue_id >= dev->data->nb_rx_queues) {
504409fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id);
504599a2dd95SBruce Richardson 		return -EINVAL;
504699a2dd95SBruce Richardson 	}
504799a2dd95SBruce Richardson 
504899a2dd95SBruce Richardson 	if (!dev->intr_handle) {
504909fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Rx Intr handle unset\n");
505099a2dd95SBruce Richardson 		return -ENOTSUP;
505199a2dd95SBruce Richardson 	}
505299a2dd95SBruce Richardson 
505399a2dd95SBruce Richardson 	intr_handle = dev->intr_handle;
5054c2bd9367SHarman Kalra 	if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) {
505509fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Rx Intr vector unset\n");
505699a2dd95SBruce Richardson 		return -EPERM;
505799a2dd95SBruce Richardson 	}
505899a2dd95SBruce Richardson 
5059c2bd9367SHarman Kalra 	vec = rte_intr_vec_list_index_get(intr_handle, queue_id);
506099a2dd95SBruce Richardson 	rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data);
506199a2dd95SBruce Richardson 	if (rc && rc != -EEXIST) {
506299a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
506309fd4227SAndrew Rybchenko 			"p %u q %u Rx ctl error op %d epfd %d vec %u\n",
506499a2dd95SBruce Richardson 			port_id, queue_id, op, epfd, vec);
506599a2dd95SBruce Richardson 		return rc;
506699a2dd95SBruce Richardson 	}
506799a2dd95SBruce Richardson 
506899a2dd95SBruce Richardson 	return 0;
506999a2dd95SBruce Richardson }
507099a2dd95SBruce Richardson 
507199a2dd95SBruce Richardson int
507299a2dd95SBruce Richardson rte_eth_dev_rx_intr_enable(uint16_t port_id,
507399a2dd95SBruce Richardson 			   uint16_t queue_id)
507499a2dd95SBruce Richardson {
507599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
507699a2dd95SBruce Richardson 	int ret;
507799a2dd95SBruce Richardson 
507899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
507999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
508099a2dd95SBruce Richardson 
508199a2dd95SBruce Richardson 	ret = eth_dev_validate_rx_queue(dev, queue_id);
508299a2dd95SBruce Richardson 	if (ret != 0)
508399a2dd95SBruce Richardson 		return ret;
508499a2dd95SBruce Richardson 
508599a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_enable, -ENOTSUP);
508653ef1b34SMin Hu (Connor) 	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_enable)(dev, queue_id));
508799a2dd95SBruce Richardson }
508899a2dd95SBruce Richardson 
508999a2dd95SBruce Richardson int
509099a2dd95SBruce Richardson rte_eth_dev_rx_intr_disable(uint16_t port_id,
509199a2dd95SBruce Richardson 			    uint16_t queue_id)
509299a2dd95SBruce Richardson {
509399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
509499a2dd95SBruce Richardson 	int ret;
509599a2dd95SBruce Richardson 
509699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
509799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
509899a2dd95SBruce Richardson 
509999a2dd95SBruce Richardson 	ret = eth_dev_validate_rx_queue(dev, queue_id);
510099a2dd95SBruce Richardson 	if (ret != 0)
510199a2dd95SBruce Richardson 		return ret;
510299a2dd95SBruce Richardson 
510399a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_disable, -ENOTSUP);
510453ef1b34SMin Hu (Connor) 	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_disable)(dev, queue_id));
510599a2dd95SBruce Richardson }
510699a2dd95SBruce Richardson 
510799a2dd95SBruce Richardson 
510899a2dd95SBruce Richardson const struct rte_eth_rxtx_callback *
510999a2dd95SBruce Richardson rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id,
511099a2dd95SBruce Richardson 		rte_rx_callback_fn fn, void *user_param)
511199a2dd95SBruce Richardson {
511299a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS
511399a2dd95SBruce Richardson 	rte_errno = ENOTSUP;
511499a2dd95SBruce Richardson 	return NULL;
511599a2dd95SBruce Richardson #endif
511699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
511799a2dd95SBruce Richardson 
511899a2dd95SBruce Richardson 	/* check input parameters */
511999a2dd95SBruce Richardson 	if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
512099a2dd95SBruce Richardson 		    queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) {
512199a2dd95SBruce Richardson 		rte_errno = EINVAL;
512299a2dd95SBruce Richardson 		return NULL;
512399a2dd95SBruce Richardson 	}
512499a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
512599a2dd95SBruce Richardson 	if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) {
512699a2dd95SBruce Richardson 		rte_errno = EINVAL;
512799a2dd95SBruce Richardson 		return NULL;
512899a2dd95SBruce Richardson 	}
512999a2dd95SBruce Richardson 	struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
513099a2dd95SBruce Richardson 
513199a2dd95SBruce Richardson 	if (cb == NULL) {
513299a2dd95SBruce Richardson 		rte_errno = ENOMEM;
513399a2dd95SBruce Richardson 		return NULL;
513499a2dd95SBruce Richardson 	}
513599a2dd95SBruce Richardson 
513699a2dd95SBruce Richardson 	cb->fn.rx = fn;
513799a2dd95SBruce Richardson 	cb->param = user_param;
513899a2dd95SBruce Richardson 
513999a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_rx_cb_lock);
514099a2dd95SBruce Richardson 	/* Add the callbacks in fifo order. */
514199a2dd95SBruce Richardson 	struct rte_eth_rxtx_callback *tail =
514299a2dd95SBruce Richardson 		rte_eth_devices[port_id].post_rx_burst_cbs[queue_id];
514399a2dd95SBruce Richardson 
514499a2dd95SBruce Richardson 	if (!tail) {
514599a2dd95SBruce Richardson 		/* Stores to cb->fn and cb->param should complete before
514699a2dd95SBruce Richardson 		 * cb is visible to data plane.
514799a2dd95SBruce Richardson 		 */
514899a2dd95SBruce Richardson 		__atomic_store_n(
514999a2dd95SBruce Richardson 			&rte_eth_devices[port_id].post_rx_burst_cbs[queue_id],
515099a2dd95SBruce Richardson 			cb, __ATOMIC_RELEASE);
515199a2dd95SBruce Richardson 
515299a2dd95SBruce Richardson 	} else {
515399a2dd95SBruce Richardson 		while (tail->next)
515499a2dd95SBruce Richardson 			tail = tail->next;
515599a2dd95SBruce Richardson 		/* Stores to cb->fn and cb->param should complete before
515699a2dd95SBruce Richardson 		 * cb is visible to data plane.
515799a2dd95SBruce Richardson 		 */
515899a2dd95SBruce Richardson 		__atomic_store_n(&tail->next, cb, __ATOMIC_RELEASE);
515999a2dd95SBruce Richardson 	}
516099a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_rx_cb_lock);
516199a2dd95SBruce Richardson 
516299a2dd95SBruce Richardson 	return cb;
516399a2dd95SBruce Richardson }
516499a2dd95SBruce Richardson 
516599a2dd95SBruce Richardson const struct rte_eth_rxtx_callback *
516699a2dd95SBruce Richardson rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id,
516799a2dd95SBruce Richardson 		rte_rx_callback_fn fn, void *user_param)
516899a2dd95SBruce Richardson {
516999a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS
517099a2dd95SBruce Richardson 	rte_errno = ENOTSUP;
517199a2dd95SBruce Richardson 	return NULL;
517299a2dd95SBruce Richardson #endif
517399a2dd95SBruce Richardson 	/* check input parameters */
517499a2dd95SBruce Richardson 	if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
517599a2dd95SBruce Richardson 		queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) {
517699a2dd95SBruce Richardson 		rte_errno = EINVAL;
517799a2dd95SBruce Richardson 		return NULL;
517899a2dd95SBruce Richardson 	}
517999a2dd95SBruce Richardson 
518099a2dd95SBruce Richardson 	struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
518199a2dd95SBruce Richardson 
518299a2dd95SBruce Richardson 	if (cb == NULL) {
518399a2dd95SBruce Richardson 		rte_errno = ENOMEM;
518499a2dd95SBruce Richardson 		return NULL;
518599a2dd95SBruce Richardson 	}
518699a2dd95SBruce Richardson 
518799a2dd95SBruce Richardson 	cb->fn.rx = fn;
518899a2dd95SBruce Richardson 	cb->param = user_param;
518999a2dd95SBruce Richardson 
519099a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_rx_cb_lock);
519199a2dd95SBruce Richardson 	/* Add the callbacks at first position */
519299a2dd95SBruce Richardson 	cb->next = rte_eth_devices[port_id].post_rx_burst_cbs[queue_id];
519399a2dd95SBruce Richardson 	/* Stores to cb->fn, cb->param and cb->next should complete before
519499a2dd95SBruce Richardson 	 * cb is visible to data plane threads.
519599a2dd95SBruce Richardson 	 */
519699a2dd95SBruce Richardson 	__atomic_store_n(
519799a2dd95SBruce Richardson 		&rte_eth_devices[port_id].post_rx_burst_cbs[queue_id],
519899a2dd95SBruce Richardson 		cb, __ATOMIC_RELEASE);
519999a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_rx_cb_lock);
520099a2dd95SBruce Richardson 
520199a2dd95SBruce Richardson 	return cb;
520299a2dd95SBruce Richardson }
520399a2dd95SBruce Richardson 
520499a2dd95SBruce Richardson const struct rte_eth_rxtx_callback *
520599a2dd95SBruce Richardson rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id,
520699a2dd95SBruce Richardson 		rte_tx_callback_fn fn, void *user_param)
520799a2dd95SBruce Richardson {
520899a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS
520999a2dd95SBruce Richardson 	rte_errno = ENOTSUP;
521099a2dd95SBruce Richardson 	return NULL;
521199a2dd95SBruce Richardson #endif
521299a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
521399a2dd95SBruce Richardson 
521499a2dd95SBruce Richardson 	/* check input parameters */
521599a2dd95SBruce Richardson 	if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
521699a2dd95SBruce Richardson 		    queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) {
521799a2dd95SBruce Richardson 		rte_errno = EINVAL;
521899a2dd95SBruce Richardson 		return NULL;
521999a2dd95SBruce Richardson 	}
522099a2dd95SBruce Richardson 
522199a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
522299a2dd95SBruce Richardson 	if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) {
522399a2dd95SBruce Richardson 		rte_errno = EINVAL;
522499a2dd95SBruce Richardson 		return NULL;
522599a2dd95SBruce Richardson 	}
522699a2dd95SBruce Richardson 
522799a2dd95SBruce Richardson 	struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
522899a2dd95SBruce Richardson 
522999a2dd95SBruce Richardson 	if (cb == NULL) {
523099a2dd95SBruce Richardson 		rte_errno = ENOMEM;
523199a2dd95SBruce Richardson 		return NULL;
523299a2dd95SBruce Richardson 	}
523399a2dd95SBruce Richardson 
523499a2dd95SBruce Richardson 	cb->fn.tx = fn;
523599a2dd95SBruce Richardson 	cb->param = user_param;
523699a2dd95SBruce Richardson 
523799a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_tx_cb_lock);
523899a2dd95SBruce Richardson 	/* Add the callbacks in fifo order. */
523999a2dd95SBruce Richardson 	struct rte_eth_rxtx_callback *tail =
524099a2dd95SBruce Richardson 		rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id];
524199a2dd95SBruce Richardson 
524299a2dd95SBruce Richardson 	if (!tail) {
524399a2dd95SBruce Richardson 		/* Stores to cb->fn and cb->param should complete before
524499a2dd95SBruce Richardson 		 * cb is visible to data plane.
524599a2dd95SBruce Richardson 		 */
524699a2dd95SBruce Richardson 		__atomic_store_n(
524799a2dd95SBruce Richardson 			&rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id],
524899a2dd95SBruce Richardson 			cb, __ATOMIC_RELEASE);
524999a2dd95SBruce Richardson 
525099a2dd95SBruce Richardson 	} else {
525199a2dd95SBruce Richardson 		while (tail->next)
525299a2dd95SBruce Richardson 			tail = tail->next;
525399a2dd95SBruce Richardson 		/* Stores to cb->fn and cb->param should complete before
525499a2dd95SBruce Richardson 		 * cb is visible to data plane.
525599a2dd95SBruce Richardson 		 */
525699a2dd95SBruce Richardson 		__atomic_store_n(&tail->next, cb, __ATOMIC_RELEASE);
525799a2dd95SBruce Richardson 	}
525899a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_tx_cb_lock);
525999a2dd95SBruce Richardson 
526099a2dd95SBruce Richardson 	return cb;
526199a2dd95SBruce Richardson }
526299a2dd95SBruce Richardson 
526399a2dd95SBruce Richardson int
526499a2dd95SBruce Richardson rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id,
526599a2dd95SBruce Richardson 		const struct rte_eth_rxtx_callback *user_cb)
526699a2dd95SBruce Richardson {
526799a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS
526899a2dd95SBruce Richardson 	return -ENOTSUP;
526999a2dd95SBruce Richardson #endif
527099a2dd95SBruce Richardson 	/* Check input parameters. */
527199a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
527299a2dd95SBruce Richardson 	if (user_cb == NULL ||
527399a2dd95SBruce Richardson 			queue_id >= rte_eth_devices[port_id].data->nb_rx_queues)
527499a2dd95SBruce Richardson 		return -EINVAL;
527599a2dd95SBruce Richardson 
527699a2dd95SBruce Richardson 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
527799a2dd95SBruce Richardson 	struct rte_eth_rxtx_callback *cb;
527899a2dd95SBruce Richardson 	struct rte_eth_rxtx_callback **prev_cb;
527999a2dd95SBruce Richardson 	int ret = -EINVAL;
528099a2dd95SBruce Richardson 
528199a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_rx_cb_lock);
528299a2dd95SBruce Richardson 	prev_cb = &dev->post_rx_burst_cbs[queue_id];
528399a2dd95SBruce Richardson 	for (; *prev_cb != NULL; prev_cb = &cb->next) {
528499a2dd95SBruce Richardson 		cb = *prev_cb;
528599a2dd95SBruce Richardson 		if (cb == user_cb) {
528699a2dd95SBruce Richardson 			/* Remove the user cb from the callback list. */
528799a2dd95SBruce Richardson 			__atomic_store_n(prev_cb, cb->next, __ATOMIC_RELAXED);
528899a2dd95SBruce Richardson 			ret = 0;
528999a2dd95SBruce Richardson 			break;
529099a2dd95SBruce Richardson 		}
529199a2dd95SBruce Richardson 	}
529299a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_rx_cb_lock);
529399a2dd95SBruce Richardson 
529499a2dd95SBruce Richardson 	return ret;
529599a2dd95SBruce Richardson }
529699a2dd95SBruce Richardson 
529799a2dd95SBruce Richardson int
529899a2dd95SBruce Richardson rte_eth_remove_tx_callback(uint16_t port_id, uint16_t queue_id,
529999a2dd95SBruce Richardson 		const struct rte_eth_rxtx_callback *user_cb)
530099a2dd95SBruce Richardson {
530199a2dd95SBruce Richardson #ifndef RTE_ETHDEV_RXTX_CALLBACKS
530299a2dd95SBruce Richardson 	return -ENOTSUP;
530399a2dd95SBruce Richardson #endif
530499a2dd95SBruce Richardson 	/* Check input parameters. */
530599a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
530699a2dd95SBruce Richardson 	if (user_cb == NULL ||
530799a2dd95SBruce Richardson 			queue_id >= rte_eth_devices[port_id].data->nb_tx_queues)
530899a2dd95SBruce Richardson 		return -EINVAL;
530999a2dd95SBruce Richardson 
531099a2dd95SBruce Richardson 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
531199a2dd95SBruce Richardson 	int ret = -EINVAL;
531299a2dd95SBruce Richardson 	struct rte_eth_rxtx_callback *cb;
531399a2dd95SBruce Richardson 	struct rte_eth_rxtx_callback **prev_cb;
531499a2dd95SBruce Richardson 
531599a2dd95SBruce Richardson 	rte_spinlock_lock(&eth_dev_tx_cb_lock);
531699a2dd95SBruce Richardson 	prev_cb = &dev->pre_tx_burst_cbs[queue_id];
531799a2dd95SBruce Richardson 	for (; *prev_cb != NULL; prev_cb = &cb->next) {
531899a2dd95SBruce Richardson 		cb = *prev_cb;
531999a2dd95SBruce Richardson 		if (cb == user_cb) {
532099a2dd95SBruce Richardson 			/* Remove the user cb from the callback list. */
532199a2dd95SBruce Richardson 			__atomic_store_n(prev_cb, cb->next, __ATOMIC_RELAXED);
532299a2dd95SBruce Richardson 			ret = 0;
532399a2dd95SBruce Richardson 			break;
532499a2dd95SBruce Richardson 		}
532599a2dd95SBruce Richardson 	}
532699a2dd95SBruce Richardson 	rte_spinlock_unlock(&eth_dev_tx_cb_lock);
532799a2dd95SBruce Richardson 
532899a2dd95SBruce Richardson 	return ret;
532999a2dd95SBruce Richardson }
533099a2dd95SBruce Richardson 
533199a2dd95SBruce Richardson int
533299a2dd95SBruce Richardson rte_eth_rx_queue_info_get(uint16_t port_id, uint16_t queue_id,
533399a2dd95SBruce Richardson 	struct rte_eth_rxq_info *qinfo)
533499a2dd95SBruce Richardson {
533599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
533699a2dd95SBruce Richardson 
533799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
533899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
533953ef1b34SMin Hu (Connor) 
534099a2dd95SBruce Richardson 	if (queue_id >= dev->data->nb_rx_queues) {
534109fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id);
534299a2dd95SBruce Richardson 		return -EINVAL;
534399a2dd95SBruce Richardson 	}
534499a2dd95SBruce Richardson 
534553ef1b34SMin Hu (Connor) 	if (qinfo == NULL) {
534653ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u Rx queue %u info to NULL\n",
534753ef1b34SMin Hu (Connor) 			port_id, queue_id);
534853ef1b34SMin Hu (Connor) 		return -EINVAL;
534953ef1b34SMin Hu (Connor) 	}
535053ef1b34SMin Hu (Connor) 
535199a2dd95SBruce Richardson 	if (dev->data->rx_queues == NULL ||
535299a2dd95SBruce Richardson 			dev->data->rx_queues[queue_id] == NULL) {
535399a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
535499a2dd95SBruce Richardson 			       "Rx queue %"PRIu16" of device with port_id=%"
535599a2dd95SBruce Richardson 			       PRIu16" has not been setup\n",
535699a2dd95SBruce Richardson 			       queue_id, port_id);
535799a2dd95SBruce Richardson 		return -EINVAL;
535899a2dd95SBruce Richardson 	}
535999a2dd95SBruce Richardson 
536099a2dd95SBruce Richardson 	if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) {
536199a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
536299a2dd95SBruce Richardson 			"Can't get hairpin Rx queue %"PRIu16" info of device with port_id=%"PRIu16"\n",
536399a2dd95SBruce Richardson 			queue_id, port_id);
536499a2dd95SBruce Richardson 		return -EINVAL;
536599a2dd95SBruce Richardson 	}
536699a2dd95SBruce Richardson 
536799a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rxq_info_get, -ENOTSUP);
536899a2dd95SBruce Richardson 
536999a2dd95SBruce Richardson 	memset(qinfo, 0, sizeof(*qinfo));
537099a2dd95SBruce Richardson 	dev->dev_ops->rxq_info_get(dev, queue_id, qinfo);
53719ad9ff47SLijun Ou 	qinfo->queue_state = dev->data->rx_queue_state[queue_id];
53729ad9ff47SLijun Ou 
537399a2dd95SBruce Richardson 	return 0;
537499a2dd95SBruce Richardson }
537599a2dd95SBruce Richardson 
537699a2dd95SBruce Richardson int
537799a2dd95SBruce Richardson rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id,
537899a2dd95SBruce Richardson 	struct rte_eth_txq_info *qinfo)
537999a2dd95SBruce Richardson {
538099a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
538199a2dd95SBruce Richardson 
538299a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
538399a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
538453ef1b34SMin Hu (Connor) 
538599a2dd95SBruce Richardson 	if (queue_id >= dev->data->nb_tx_queues) {
538609fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", queue_id);
538799a2dd95SBruce Richardson 		return -EINVAL;
538899a2dd95SBruce Richardson 	}
538999a2dd95SBruce Richardson 
539053ef1b34SMin Hu (Connor) 	if (qinfo == NULL) {
539153ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u Tx queue %u info to NULL\n",
539253ef1b34SMin Hu (Connor) 			port_id, queue_id);
539353ef1b34SMin Hu (Connor) 		return -EINVAL;
539453ef1b34SMin Hu (Connor) 	}
539553ef1b34SMin Hu (Connor) 
539699a2dd95SBruce Richardson 	if (dev->data->tx_queues == NULL ||
539799a2dd95SBruce Richardson 			dev->data->tx_queues[queue_id] == NULL) {
539899a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR,
539999a2dd95SBruce Richardson 			       "Tx queue %"PRIu16" of device with port_id=%"
540099a2dd95SBruce Richardson 			       PRIu16" has not been setup\n",
540199a2dd95SBruce Richardson 			       queue_id, port_id);
540299a2dd95SBruce Richardson 		return -EINVAL;
540399a2dd95SBruce Richardson 	}
540499a2dd95SBruce Richardson 
540599a2dd95SBruce Richardson 	if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) {
540699a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(INFO,
540799a2dd95SBruce Richardson 			"Can't get hairpin Tx queue %"PRIu16" info of device with port_id=%"PRIu16"\n",
540899a2dd95SBruce Richardson 			queue_id, port_id);
540999a2dd95SBruce Richardson 		return -EINVAL;
541099a2dd95SBruce Richardson 	}
541199a2dd95SBruce Richardson 
541299a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->txq_info_get, -ENOTSUP);
541399a2dd95SBruce Richardson 
541499a2dd95SBruce Richardson 	memset(qinfo, 0, sizeof(*qinfo));
541599a2dd95SBruce Richardson 	dev->dev_ops->txq_info_get(dev, queue_id, qinfo);
54169ad9ff47SLijun Ou 	qinfo->queue_state = dev->data->tx_queue_state[queue_id];
541799a2dd95SBruce Richardson 
541899a2dd95SBruce Richardson 	return 0;
541999a2dd95SBruce Richardson }
542099a2dd95SBruce Richardson 
542199a2dd95SBruce Richardson int
542299a2dd95SBruce Richardson rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
542399a2dd95SBruce Richardson 			  struct rte_eth_burst_mode *mode)
542499a2dd95SBruce Richardson {
542599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
542699a2dd95SBruce Richardson 
542799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
542899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
542999a2dd95SBruce Richardson 
543099a2dd95SBruce Richardson 	if (queue_id >= dev->data->nb_rx_queues) {
543109fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id);
543299a2dd95SBruce Richardson 		return -EINVAL;
543399a2dd95SBruce Richardson 	}
543499a2dd95SBruce Richardson 
543553ef1b34SMin Hu (Connor) 	if (mode == NULL) {
543653ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
543753ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u Rx queue %u burst mode to NULL\n",
543853ef1b34SMin Hu (Connor) 			port_id, queue_id);
543953ef1b34SMin Hu (Connor) 		return -EINVAL;
544053ef1b34SMin Hu (Connor) 	}
544153ef1b34SMin Hu (Connor) 
544299a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_burst_mode_get, -ENOTSUP);
544399a2dd95SBruce Richardson 	memset(mode, 0, sizeof(*mode));
544499a2dd95SBruce Richardson 	return eth_err(port_id,
544599a2dd95SBruce Richardson 		       dev->dev_ops->rx_burst_mode_get(dev, queue_id, mode));
544699a2dd95SBruce Richardson }
544799a2dd95SBruce Richardson 
544899a2dd95SBruce Richardson int
544999a2dd95SBruce Richardson rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
545099a2dd95SBruce Richardson 			  struct rte_eth_burst_mode *mode)
545199a2dd95SBruce Richardson {
545299a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
545399a2dd95SBruce Richardson 
545499a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
545599a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
545699a2dd95SBruce Richardson 
545799a2dd95SBruce Richardson 	if (queue_id >= dev->data->nb_tx_queues) {
545809fd4227SAndrew Rybchenko 		RTE_ETHDEV_LOG(ERR, "Invalid Tx queue_id=%u\n", queue_id);
545999a2dd95SBruce Richardson 		return -EINVAL;
546099a2dd95SBruce Richardson 	}
546199a2dd95SBruce Richardson 
546253ef1b34SMin Hu (Connor) 	if (mode == NULL) {
546353ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
546453ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u Tx queue %u burst mode to NULL\n",
546553ef1b34SMin Hu (Connor) 			port_id, queue_id);
546653ef1b34SMin Hu (Connor) 		return -EINVAL;
546753ef1b34SMin Hu (Connor) 	}
546853ef1b34SMin Hu (Connor) 
546999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_burst_mode_get, -ENOTSUP);
547099a2dd95SBruce Richardson 	memset(mode, 0, sizeof(*mode));
547199a2dd95SBruce Richardson 	return eth_err(port_id,
547299a2dd95SBruce Richardson 		       dev->dev_ops->tx_burst_mode_get(dev, queue_id, mode));
547399a2dd95SBruce Richardson }
547499a2dd95SBruce Richardson 
547599a2dd95SBruce Richardson int
547699a2dd95SBruce Richardson rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
547799a2dd95SBruce Richardson 		struct rte_power_monitor_cond *pmc)
547899a2dd95SBruce Richardson {
547999a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
548099a2dd95SBruce Richardson 
548199a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
548299a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
548399a2dd95SBruce Richardson 
548499a2dd95SBruce Richardson 	if (queue_id >= dev->data->nb_rx_queues) {
548599a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id);
548699a2dd95SBruce Richardson 		return -EINVAL;
548799a2dd95SBruce Richardson 	}
548899a2dd95SBruce Richardson 
548999a2dd95SBruce Richardson 	if (pmc == NULL) {
549053ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
549153ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u Rx queue %u power monitor condition to NULL\n",
549253ef1b34SMin Hu (Connor) 			port_id, queue_id);
549399a2dd95SBruce Richardson 		return -EINVAL;
549499a2dd95SBruce Richardson 	}
549599a2dd95SBruce Richardson 
549653ef1b34SMin Hu (Connor) 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_monitor_addr, -ENOTSUP);
549799a2dd95SBruce Richardson 	return eth_err(port_id,
549853ef1b34SMin Hu (Connor) 		dev->dev_ops->get_monitor_addr(dev->data->rx_queues[queue_id], pmc));
549999a2dd95SBruce Richardson }
550099a2dd95SBruce Richardson 
550199a2dd95SBruce Richardson int
550299a2dd95SBruce Richardson rte_eth_dev_set_mc_addr_list(uint16_t port_id,
550399a2dd95SBruce Richardson 			     struct rte_ether_addr *mc_addr_set,
550499a2dd95SBruce Richardson 			     uint32_t nb_mc_addr)
550599a2dd95SBruce Richardson {
550699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
550799a2dd95SBruce Richardson 
550899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
550999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
551053ef1b34SMin Hu (Connor) 
551199a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_mc_addr_list, -ENOTSUP);
551299a2dd95SBruce Richardson 	return eth_err(port_id, dev->dev_ops->set_mc_addr_list(dev,
551399a2dd95SBruce Richardson 						mc_addr_set, nb_mc_addr));
551499a2dd95SBruce Richardson }
551599a2dd95SBruce Richardson 
551699a2dd95SBruce Richardson int
551799a2dd95SBruce Richardson rte_eth_timesync_enable(uint16_t port_id)
551899a2dd95SBruce Richardson {
551999a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
552099a2dd95SBruce Richardson 
552199a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
552299a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
552399a2dd95SBruce Richardson 
552499a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_enable, -ENOTSUP);
552599a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->timesync_enable)(dev));
552699a2dd95SBruce Richardson }
552799a2dd95SBruce Richardson 
552899a2dd95SBruce Richardson int
552999a2dd95SBruce Richardson rte_eth_timesync_disable(uint16_t port_id)
553099a2dd95SBruce Richardson {
553199a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
553299a2dd95SBruce Richardson 
553399a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
553499a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
553599a2dd95SBruce Richardson 
553699a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_disable, -ENOTSUP);
553799a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->timesync_disable)(dev));
553899a2dd95SBruce Richardson }
553999a2dd95SBruce Richardson 
554099a2dd95SBruce Richardson int
554199a2dd95SBruce Richardson rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
554299a2dd95SBruce Richardson 				   uint32_t flags)
554399a2dd95SBruce Richardson {
554499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
554599a2dd95SBruce Richardson 
554699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
554799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
554899a2dd95SBruce Richardson 
554953ef1b34SMin Hu (Connor) 	if (timestamp == NULL) {
555053ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
555153ef1b34SMin Hu (Connor) 			"Cannot read ethdev port %u Rx timestamp to NULL\n",
555253ef1b34SMin Hu (Connor) 			port_id);
555353ef1b34SMin Hu (Connor) 		return -EINVAL;
555453ef1b34SMin Hu (Connor) 	}
555553ef1b34SMin Hu (Connor) 
555699a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
555799a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp)
555899a2dd95SBruce Richardson 				(dev, timestamp, flags));
555999a2dd95SBruce Richardson }
556099a2dd95SBruce Richardson 
556199a2dd95SBruce Richardson int
556299a2dd95SBruce Richardson rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
556399a2dd95SBruce Richardson 				   struct timespec *timestamp)
556499a2dd95SBruce Richardson {
556599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
556699a2dd95SBruce Richardson 
556799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
556899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
556999a2dd95SBruce Richardson 
557053ef1b34SMin Hu (Connor) 	if (timestamp == NULL) {
557153ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
557253ef1b34SMin Hu (Connor) 			"Cannot read ethdev port %u Tx timestamp to NULL\n",
557353ef1b34SMin Hu (Connor) 			port_id);
557453ef1b34SMin Hu (Connor) 		return -EINVAL;
557553ef1b34SMin Hu (Connor) 	}
557653ef1b34SMin Hu (Connor) 
557799a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
557899a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp)
557999a2dd95SBruce Richardson 				(dev, timestamp));
558099a2dd95SBruce Richardson }
558199a2dd95SBruce Richardson 
558299a2dd95SBruce Richardson int
558399a2dd95SBruce Richardson rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta)
558499a2dd95SBruce Richardson {
558599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
558699a2dd95SBruce Richardson 
558799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
558899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
558999a2dd95SBruce Richardson 
559099a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_adjust_time, -ENOTSUP);
559153ef1b34SMin Hu (Connor) 	return eth_err(port_id, (*dev->dev_ops->timesync_adjust_time)(dev, delta));
559299a2dd95SBruce Richardson }
559399a2dd95SBruce Richardson 
559499a2dd95SBruce Richardson int
559599a2dd95SBruce Richardson rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
559699a2dd95SBruce Richardson {
559799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
559899a2dd95SBruce Richardson 
559999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
560099a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
560199a2dd95SBruce Richardson 
560253ef1b34SMin Hu (Connor) 	if (timestamp == NULL) {
560353ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
560453ef1b34SMin Hu (Connor) 			"Cannot read ethdev port %u timesync time to NULL\n",
560553ef1b34SMin Hu (Connor) 			port_id);
560653ef1b34SMin Hu (Connor) 		return -EINVAL;
560753ef1b34SMin Hu (Connor) 	}
560853ef1b34SMin Hu (Connor) 
560999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
561099a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev,
561199a2dd95SBruce Richardson 								timestamp));
561299a2dd95SBruce Richardson }
561399a2dd95SBruce Richardson 
561499a2dd95SBruce Richardson int
561599a2dd95SBruce Richardson rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
561699a2dd95SBruce Richardson {
561799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
561899a2dd95SBruce Richardson 
561999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
562099a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
562199a2dd95SBruce Richardson 
562253ef1b34SMin Hu (Connor) 	if (timestamp == NULL) {
562353ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
562453ef1b34SMin Hu (Connor) 			"Cannot write ethdev port %u timesync from NULL time\n",
562553ef1b34SMin Hu (Connor) 			port_id);
562653ef1b34SMin Hu (Connor) 		return -EINVAL;
562753ef1b34SMin Hu (Connor) 	}
562853ef1b34SMin Hu (Connor) 
562999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
563099a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev,
563199a2dd95SBruce Richardson 								timestamp));
563299a2dd95SBruce Richardson }
563399a2dd95SBruce Richardson 
563499a2dd95SBruce Richardson int
563599a2dd95SBruce Richardson rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
563699a2dd95SBruce Richardson {
563799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
563899a2dd95SBruce Richardson 
563999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
564099a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
564199a2dd95SBruce Richardson 
564253ef1b34SMin Hu (Connor) 	if (clock == NULL) {
564353ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR, "Cannot read ethdev port %u clock to NULL\n",
564453ef1b34SMin Hu (Connor) 			port_id);
564553ef1b34SMin Hu (Connor) 		return -EINVAL;
564653ef1b34SMin Hu (Connor) 	}
564753ef1b34SMin Hu (Connor) 
564899a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
564999a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock));
565099a2dd95SBruce Richardson }
565199a2dd95SBruce Richardson 
565299a2dd95SBruce Richardson int
565399a2dd95SBruce Richardson rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
565499a2dd95SBruce Richardson {
565599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
565699a2dd95SBruce Richardson 
565799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
565899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
565953ef1b34SMin Hu (Connor) 
566053ef1b34SMin Hu (Connor) 	if (info == NULL) {
566153ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
566253ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u register info to NULL\n",
566353ef1b34SMin Hu (Connor) 			port_id);
566453ef1b34SMin Hu (Connor) 		return -EINVAL;
566553ef1b34SMin Hu (Connor) 	}
566653ef1b34SMin Hu (Connor) 
566799a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_reg, -ENOTSUP);
566899a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info));
566999a2dd95SBruce Richardson }
567099a2dd95SBruce Richardson 
567199a2dd95SBruce Richardson int
567299a2dd95SBruce Richardson rte_eth_dev_get_eeprom_length(uint16_t port_id)
567399a2dd95SBruce Richardson {
567499a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
567599a2dd95SBruce Richardson 
567699a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
567799a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
567853ef1b34SMin Hu (Connor) 
567999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom_length, -ENOTSUP);
568099a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->get_eeprom_length)(dev));
568199a2dd95SBruce Richardson }
568299a2dd95SBruce Richardson 
568399a2dd95SBruce Richardson int
568499a2dd95SBruce Richardson rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
568599a2dd95SBruce Richardson {
568699a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
568799a2dd95SBruce Richardson 
568899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
568999a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
569053ef1b34SMin Hu (Connor) 
569153ef1b34SMin Hu (Connor) 	if (info == NULL) {
569253ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
569353ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u EEPROM info to NULL\n",
569453ef1b34SMin Hu (Connor) 			port_id);
569553ef1b34SMin Hu (Connor) 		return -EINVAL;
569653ef1b34SMin Hu (Connor) 	}
569753ef1b34SMin Hu (Connor) 
569899a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom, -ENOTSUP);
569999a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->get_eeprom)(dev, info));
570099a2dd95SBruce Richardson }
570199a2dd95SBruce Richardson 
570299a2dd95SBruce Richardson int
570399a2dd95SBruce Richardson rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
570499a2dd95SBruce Richardson {
570599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
570699a2dd95SBruce Richardson 
570799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
570899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
570953ef1b34SMin Hu (Connor) 
571053ef1b34SMin Hu (Connor) 	if (info == NULL) {
571153ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
571253ef1b34SMin Hu (Connor) 			"Cannot set ethdev port %u EEPROM from NULL info\n",
571353ef1b34SMin Hu (Connor) 			port_id);
571453ef1b34SMin Hu (Connor) 		return -EINVAL;
571553ef1b34SMin Hu (Connor) 	}
571653ef1b34SMin Hu (Connor) 
571799a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_eeprom, -ENOTSUP);
571899a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->set_eeprom)(dev, info));
571999a2dd95SBruce Richardson }
572099a2dd95SBruce Richardson 
572199a2dd95SBruce Richardson int
572299a2dd95SBruce Richardson rte_eth_dev_get_module_info(uint16_t port_id,
572399a2dd95SBruce Richardson 			    struct rte_eth_dev_module_info *modinfo)
572499a2dd95SBruce Richardson {
572599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
572699a2dd95SBruce Richardson 
572799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
572899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
572953ef1b34SMin Hu (Connor) 
573053ef1b34SMin Hu (Connor) 	if (modinfo == NULL) {
573153ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
573253ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u EEPROM module info to NULL\n",
573353ef1b34SMin Hu (Connor) 			port_id);
573453ef1b34SMin Hu (Connor) 		return -EINVAL;
573553ef1b34SMin Hu (Connor) 	}
573653ef1b34SMin Hu (Connor) 
573799a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_info, -ENOTSUP);
573899a2dd95SBruce Richardson 	return (*dev->dev_ops->get_module_info)(dev, modinfo);
573999a2dd95SBruce Richardson }
574099a2dd95SBruce Richardson 
574199a2dd95SBruce Richardson int
574299a2dd95SBruce Richardson rte_eth_dev_get_module_eeprom(uint16_t port_id,
574399a2dd95SBruce Richardson 			      struct rte_dev_eeprom_info *info)
574499a2dd95SBruce Richardson {
574599a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
574699a2dd95SBruce Richardson 
574799a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
574899a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
574953ef1b34SMin Hu (Connor) 
575053ef1b34SMin Hu (Connor) 	if (info == NULL) {
575153ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
575253ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u module EEPROM info to NULL\n",
575353ef1b34SMin Hu (Connor) 			port_id);
575453ef1b34SMin Hu (Connor) 		return -EINVAL;
575553ef1b34SMin Hu (Connor) 	}
575653ef1b34SMin Hu (Connor) 
575753ef1b34SMin Hu (Connor) 	if (info->data == NULL) {
575853ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
575953ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u module EEPROM data to NULL\n",
576053ef1b34SMin Hu (Connor) 			port_id);
576153ef1b34SMin Hu (Connor) 		return -EINVAL;
576253ef1b34SMin Hu (Connor) 	}
576353ef1b34SMin Hu (Connor) 
576453ef1b34SMin Hu (Connor) 	if (info->length == 0) {
576553ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
576653ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u module EEPROM to data with zero size\n",
576753ef1b34SMin Hu (Connor) 			port_id);
576853ef1b34SMin Hu (Connor) 		return -EINVAL;
576953ef1b34SMin Hu (Connor) 	}
577053ef1b34SMin Hu (Connor) 
577199a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_eeprom, -ENOTSUP);
577299a2dd95SBruce Richardson 	return (*dev->dev_ops->get_module_eeprom)(dev, info);
577399a2dd95SBruce Richardson }
577499a2dd95SBruce Richardson 
577599a2dd95SBruce Richardson int
577699a2dd95SBruce Richardson rte_eth_dev_get_dcb_info(uint16_t port_id,
577799a2dd95SBruce Richardson 			     struct rte_eth_dcb_info *dcb_info)
577899a2dd95SBruce Richardson {
577999a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
578099a2dd95SBruce Richardson 
578199a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
578299a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
578353ef1b34SMin Hu (Connor) 
578453ef1b34SMin Hu (Connor) 	if (dcb_info == NULL) {
578553ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
578653ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u DCB info to NULL\n",
578753ef1b34SMin Hu (Connor) 			port_id);
578853ef1b34SMin Hu (Connor) 		return -EINVAL;
578953ef1b34SMin Hu (Connor) 	}
579053ef1b34SMin Hu (Connor) 
579199a2dd95SBruce Richardson 	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
579299a2dd95SBruce Richardson 
579399a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_dcb_info, -ENOTSUP);
579499a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->get_dcb_info)(dev, dcb_info));
579599a2dd95SBruce Richardson }
579699a2dd95SBruce Richardson 
579799a2dd95SBruce Richardson static void
579899a2dd95SBruce Richardson eth_dev_adjust_nb_desc(uint16_t *nb_desc,
579999a2dd95SBruce Richardson 		const struct rte_eth_desc_lim *desc_lim)
580099a2dd95SBruce Richardson {
580199a2dd95SBruce Richardson 	if (desc_lim->nb_align != 0)
580299a2dd95SBruce Richardson 		*nb_desc = RTE_ALIGN_CEIL(*nb_desc, desc_lim->nb_align);
580399a2dd95SBruce Richardson 
580499a2dd95SBruce Richardson 	if (desc_lim->nb_max != 0)
580599a2dd95SBruce Richardson 		*nb_desc = RTE_MIN(*nb_desc, desc_lim->nb_max);
580699a2dd95SBruce Richardson 
580799a2dd95SBruce Richardson 	*nb_desc = RTE_MAX(*nb_desc, desc_lim->nb_min);
580899a2dd95SBruce Richardson }
580999a2dd95SBruce Richardson 
581099a2dd95SBruce Richardson int
581199a2dd95SBruce Richardson rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id,
581299a2dd95SBruce Richardson 				 uint16_t *nb_rx_desc,
581399a2dd95SBruce Richardson 				 uint16_t *nb_tx_desc)
581499a2dd95SBruce Richardson {
581599a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info;
581699a2dd95SBruce Richardson 	int ret;
581799a2dd95SBruce Richardson 
581899a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
581999a2dd95SBruce Richardson 
582099a2dd95SBruce Richardson 	ret = rte_eth_dev_info_get(port_id, &dev_info);
582199a2dd95SBruce Richardson 	if (ret != 0)
582299a2dd95SBruce Richardson 		return ret;
582399a2dd95SBruce Richardson 
582499a2dd95SBruce Richardson 	if (nb_rx_desc != NULL)
582599a2dd95SBruce Richardson 		eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim);
582699a2dd95SBruce Richardson 
582799a2dd95SBruce Richardson 	if (nb_tx_desc != NULL)
582899a2dd95SBruce Richardson 		eth_dev_adjust_nb_desc(nb_tx_desc, &dev_info.tx_desc_lim);
582999a2dd95SBruce Richardson 
583099a2dd95SBruce Richardson 	return 0;
583199a2dd95SBruce Richardson }
583299a2dd95SBruce Richardson 
583399a2dd95SBruce Richardson int
583499a2dd95SBruce Richardson rte_eth_dev_hairpin_capability_get(uint16_t port_id,
583599a2dd95SBruce Richardson 				   struct rte_eth_hairpin_cap *cap)
583699a2dd95SBruce Richardson {
583799a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
583899a2dd95SBruce Richardson 
583999a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
584099a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
584153ef1b34SMin Hu (Connor) 
584253ef1b34SMin Hu (Connor) 	if (cap == NULL) {
584353ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
584453ef1b34SMin Hu (Connor) 			"Cannot get ethdev port %u hairpin capability to NULL\n",
584553ef1b34SMin Hu (Connor) 			port_id);
584653ef1b34SMin Hu (Connor) 		return -EINVAL;
584753ef1b34SMin Hu (Connor) 	}
584853ef1b34SMin Hu (Connor) 
584999a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
585099a2dd95SBruce Richardson 	memset(cap, 0, sizeof(*cap));
585199a2dd95SBruce Richardson 	return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap));
585299a2dd95SBruce Richardson }
585399a2dd95SBruce Richardson 
585499a2dd95SBruce Richardson int
585599a2dd95SBruce Richardson rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
585699a2dd95SBruce Richardson {
585753ef1b34SMin Hu (Connor) 	if (dev->data->rx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN)
585899a2dd95SBruce Richardson 		return 1;
585999a2dd95SBruce Richardson 	return 0;
586099a2dd95SBruce Richardson }
586199a2dd95SBruce Richardson 
586299a2dd95SBruce Richardson int
586399a2dd95SBruce Richardson rte_eth_dev_is_tx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
586499a2dd95SBruce Richardson {
586553ef1b34SMin Hu (Connor) 	if (dev->data->tx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN)
586699a2dd95SBruce Richardson 		return 1;
586799a2dd95SBruce Richardson 	return 0;
586899a2dd95SBruce Richardson }
586999a2dd95SBruce Richardson 
587099a2dd95SBruce Richardson int
587199a2dd95SBruce Richardson rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
587299a2dd95SBruce Richardson {
587399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
587499a2dd95SBruce Richardson 
587599a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
587699a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
587799a2dd95SBruce Richardson 
587853ef1b34SMin Hu (Connor) 	if (pool == NULL) {
587953ef1b34SMin Hu (Connor) 		RTE_ETHDEV_LOG(ERR,
588053ef1b34SMin Hu (Connor) 			"Cannot test ethdev port %u mempool operation from NULL pool\n",
588153ef1b34SMin Hu (Connor) 			port_id);
588253ef1b34SMin Hu (Connor) 		return -EINVAL;
588353ef1b34SMin Hu (Connor) 	}
588453ef1b34SMin Hu (Connor) 
588599a2dd95SBruce Richardson 	if (*dev->dev_ops->pool_ops_supported == NULL)
588699a2dd95SBruce Richardson 		return 1; /* all pools are supported */
588799a2dd95SBruce Richardson 
588899a2dd95SBruce Richardson 	return (*dev->dev_ops->pool_ops_supported)(dev, pool);
588999a2dd95SBruce Richardson }
589099a2dd95SBruce Richardson 
589199a2dd95SBruce Richardson /**
589299a2dd95SBruce Richardson  * A set of values to describe the possible states of a switch domain.
589399a2dd95SBruce Richardson  */
589499a2dd95SBruce Richardson enum rte_eth_switch_domain_state {
589599a2dd95SBruce Richardson 	RTE_ETH_SWITCH_DOMAIN_UNUSED = 0,
589699a2dd95SBruce Richardson 	RTE_ETH_SWITCH_DOMAIN_ALLOCATED
589799a2dd95SBruce Richardson };
589899a2dd95SBruce Richardson 
589999a2dd95SBruce Richardson /**
590099a2dd95SBruce Richardson  * Array of switch domains available for allocation. Array is sized to
590199a2dd95SBruce Richardson  * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than
590299a2dd95SBruce Richardson  * ethdev ports in a single process.
590399a2dd95SBruce Richardson  */
590499a2dd95SBruce Richardson static struct rte_eth_dev_switch {
590599a2dd95SBruce Richardson 	enum rte_eth_switch_domain_state state;
590699a2dd95SBruce Richardson } eth_dev_switch_domains[RTE_MAX_ETHPORTS];
590799a2dd95SBruce Richardson 
590899a2dd95SBruce Richardson int
590999a2dd95SBruce Richardson rte_eth_switch_domain_alloc(uint16_t *domain_id)
591099a2dd95SBruce Richardson {
591199a2dd95SBruce Richardson 	uint16_t i;
591299a2dd95SBruce Richardson 
591399a2dd95SBruce Richardson 	*domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
591499a2dd95SBruce Richardson 
591599a2dd95SBruce Richardson 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
591699a2dd95SBruce Richardson 		if (eth_dev_switch_domains[i].state ==
591799a2dd95SBruce Richardson 			RTE_ETH_SWITCH_DOMAIN_UNUSED) {
591899a2dd95SBruce Richardson 			eth_dev_switch_domains[i].state =
591999a2dd95SBruce Richardson 				RTE_ETH_SWITCH_DOMAIN_ALLOCATED;
592099a2dd95SBruce Richardson 			*domain_id = i;
592199a2dd95SBruce Richardson 			return 0;
592299a2dd95SBruce Richardson 		}
592399a2dd95SBruce Richardson 	}
592499a2dd95SBruce Richardson 
592599a2dd95SBruce Richardson 	return -ENOSPC;
592699a2dd95SBruce Richardson }
592799a2dd95SBruce Richardson 
592899a2dd95SBruce Richardson int
592999a2dd95SBruce Richardson rte_eth_switch_domain_free(uint16_t domain_id)
593099a2dd95SBruce Richardson {
593199a2dd95SBruce Richardson 	if (domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID ||
593299a2dd95SBruce Richardson 		domain_id >= RTE_MAX_ETHPORTS)
593399a2dd95SBruce Richardson 		return -EINVAL;
593499a2dd95SBruce Richardson 
593599a2dd95SBruce Richardson 	if (eth_dev_switch_domains[domain_id].state !=
593699a2dd95SBruce Richardson 		RTE_ETH_SWITCH_DOMAIN_ALLOCATED)
593799a2dd95SBruce Richardson 		return -EINVAL;
593899a2dd95SBruce Richardson 
593999a2dd95SBruce Richardson 	eth_dev_switch_domains[domain_id].state = RTE_ETH_SWITCH_DOMAIN_UNUSED;
594099a2dd95SBruce Richardson 
594199a2dd95SBruce Richardson 	return 0;
594299a2dd95SBruce Richardson }
594399a2dd95SBruce Richardson 
594499a2dd95SBruce Richardson static int
594599a2dd95SBruce Richardson eth_dev_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in)
594699a2dd95SBruce Richardson {
594799a2dd95SBruce Richardson 	int state;
594899a2dd95SBruce Richardson 	struct rte_kvargs_pair *pair;
594999a2dd95SBruce Richardson 	char *letter;
595099a2dd95SBruce Richardson 
595199a2dd95SBruce Richardson 	arglist->str = strdup(str_in);
595299a2dd95SBruce Richardson 	if (arglist->str == NULL)
595399a2dd95SBruce Richardson 		return -ENOMEM;
595499a2dd95SBruce Richardson 
595599a2dd95SBruce Richardson 	letter = arglist->str;
595699a2dd95SBruce Richardson 	state = 0;
595799a2dd95SBruce Richardson 	arglist->count = 0;
595899a2dd95SBruce Richardson 	pair = &arglist->pairs[0];
595999a2dd95SBruce Richardson 	while (1) {
596099a2dd95SBruce Richardson 		switch (state) {
596199a2dd95SBruce Richardson 		case 0: /* Initial */
596299a2dd95SBruce Richardson 			if (*letter == '=')
596399a2dd95SBruce Richardson 				return -EINVAL;
596499a2dd95SBruce Richardson 			else if (*letter == '\0')
596599a2dd95SBruce Richardson 				return 0;
596699a2dd95SBruce Richardson 
596799a2dd95SBruce Richardson 			state = 1;
596899a2dd95SBruce Richardson 			pair->key = letter;
596999a2dd95SBruce Richardson 			/* fall-thru */
597099a2dd95SBruce Richardson 
597199a2dd95SBruce Richardson 		case 1: /* Parsing key */
597299a2dd95SBruce Richardson 			if (*letter == '=') {
597399a2dd95SBruce Richardson 				*letter = '\0';
597499a2dd95SBruce Richardson 				pair->value = letter + 1;
597599a2dd95SBruce Richardson 				state = 2;
597699a2dd95SBruce Richardson 			} else if (*letter == ',' || *letter == '\0')
597799a2dd95SBruce Richardson 				return -EINVAL;
597899a2dd95SBruce Richardson 			break;
597999a2dd95SBruce Richardson 
598099a2dd95SBruce Richardson 
598199a2dd95SBruce Richardson 		case 2: /* Parsing value */
598299a2dd95SBruce Richardson 			if (*letter == '[')
598399a2dd95SBruce Richardson 				state = 3;
598499a2dd95SBruce Richardson 			else if (*letter == ',') {
598599a2dd95SBruce Richardson 				*letter = '\0';
598699a2dd95SBruce Richardson 				arglist->count++;
598799a2dd95SBruce Richardson 				pair = &arglist->pairs[arglist->count];
598899a2dd95SBruce Richardson 				state = 0;
598999a2dd95SBruce Richardson 			} else if (*letter == '\0') {
599099a2dd95SBruce Richardson 				letter--;
599199a2dd95SBruce Richardson 				arglist->count++;
599299a2dd95SBruce Richardson 				pair = &arglist->pairs[arglist->count];
599399a2dd95SBruce Richardson 				state = 0;
599499a2dd95SBruce Richardson 			}
599599a2dd95SBruce Richardson 			break;
599699a2dd95SBruce Richardson 
599799a2dd95SBruce Richardson 		case 3: /* Parsing list */
599899a2dd95SBruce Richardson 			if (*letter == ']')
599999a2dd95SBruce Richardson 				state = 2;
600099a2dd95SBruce Richardson 			else if (*letter == '\0')
600199a2dd95SBruce Richardson 				return -EINVAL;
600299a2dd95SBruce Richardson 			break;
600399a2dd95SBruce Richardson 		}
600499a2dd95SBruce Richardson 		letter++;
600599a2dd95SBruce Richardson 	}
600699a2dd95SBruce Richardson }
600799a2dd95SBruce Richardson 
600899a2dd95SBruce Richardson int
600999a2dd95SBruce Richardson rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da)
601099a2dd95SBruce Richardson {
601199a2dd95SBruce Richardson 	struct rte_kvargs args;
601299a2dd95SBruce Richardson 	struct rte_kvargs_pair *pair;
601399a2dd95SBruce Richardson 	unsigned int i;
601499a2dd95SBruce Richardson 	int result = 0;
601599a2dd95SBruce Richardson 
601699a2dd95SBruce Richardson 	memset(eth_da, 0, sizeof(*eth_da));
601799a2dd95SBruce Richardson 
601899a2dd95SBruce Richardson 	result = eth_dev_devargs_tokenise(&args, dargs);
601999a2dd95SBruce Richardson 	if (result < 0)
602099a2dd95SBruce Richardson 		goto parse_cleanup;
602199a2dd95SBruce Richardson 
602299a2dd95SBruce Richardson 	for (i = 0; i < args.count; i++) {
602399a2dd95SBruce Richardson 		pair = &args.pairs[i];
602499a2dd95SBruce Richardson 		if (strcmp("representor", pair->key) == 0) {
602599a2dd95SBruce Richardson 			if (eth_da->type != RTE_ETH_REPRESENTOR_NONE) {
602699a2dd95SBruce Richardson 				RTE_LOG(ERR, EAL, "duplicated representor key: %s\n",
602799a2dd95SBruce Richardson 					dargs);
602899a2dd95SBruce Richardson 				result = -1;
602999a2dd95SBruce Richardson 				goto parse_cleanup;
603099a2dd95SBruce Richardson 			}
603199a2dd95SBruce Richardson 			result = rte_eth_devargs_parse_representor_ports(
603299a2dd95SBruce Richardson 					pair->value, eth_da);
603399a2dd95SBruce Richardson 			if (result < 0)
603499a2dd95SBruce Richardson 				goto parse_cleanup;
603599a2dd95SBruce Richardson 		}
603699a2dd95SBruce Richardson 	}
603799a2dd95SBruce Richardson 
603899a2dd95SBruce Richardson parse_cleanup:
603999a2dd95SBruce Richardson 	if (args.str)
604099a2dd95SBruce Richardson 		free(args.str);
604199a2dd95SBruce Richardson 
604299a2dd95SBruce Richardson 	return result;
604399a2dd95SBruce Richardson }
604499a2dd95SBruce Richardson 
604599a2dd95SBruce Richardson int
6046ff4e52efSViacheslav Galaktionov rte_eth_representor_id_get(uint16_t port_id,
604799a2dd95SBruce Richardson 			   enum rte_eth_representor_type type,
604899a2dd95SBruce Richardson 			   int controller, int pf, int representor_port,
604999a2dd95SBruce Richardson 			   uint16_t *repr_id)
605099a2dd95SBruce Richardson {
605110eaf41dSViacheslav Galaktionov 	int ret, n, count;
605210eaf41dSViacheslav Galaktionov 	uint32_t i;
605399a2dd95SBruce Richardson 	struct rte_eth_representor_info *info = NULL;
605499a2dd95SBruce Richardson 	size_t size;
605599a2dd95SBruce Richardson 
605699a2dd95SBruce Richardson 	if (type == RTE_ETH_REPRESENTOR_NONE)
605799a2dd95SBruce Richardson 		return 0;
605899a2dd95SBruce Richardson 	if (repr_id == NULL)
605999a2dd95SBruce Richardson 		return -EINVAL;
606099a2dd95SBruce Richardson 
606199a2dd95SBruce Richardson 	/* Get PMD representor range info. */
6062ff4e52efSViacheslav Galaktionov 	ret = rte_eth_representor_info_get(port_id, NULL);
606399a2dd95SBruce Richardson 	if (ret == -ENOTSUP && type == RTE_ETH_REPRESENTOR_VF &&
606499a2dd95SBruce Richardson 	    controller == -1 && pf == -1) {
606599a2dd95SBruce Richardson 		/* Direct mapping for legacy VF representor. */
606699a2dd95SBruce Richardson 		*repr_id = representor_port;
606799a2dd95SBruce Richardson 		return 0;
606899a2dd95SBruce Richardson 	} else if (ret < 0) {
606999a2dd95SBruce Richardson 		return ret;
607099a2dd95SBruce Richardson 	}
607199a2dd95SBruce Richardson 	n = ret;
607299a2dd95SBruce Richardson 	size = sizeof(*info) + n * sizeof(info->ranges[0]);
607399a2dd95SBruce Richardson 	info = calloc(1, size);
607499a2dd95SBruce Richardson 	if (info == NULL)
607599a2dd95SBruce Richardson 		return -ENOMEM;
607610eaf41dSViacheslav Galaktionov 	info->nb_ranges_alloc = n;
6077ff4e52efSViacheslav Galaktionov 	ret = rte_eth_representor_info_get(port_id, info);
607899a2dd95SBruce Richardson 	if (ret < 0)
607999a2dd95SBruce Richardson 		goto out;
608099a2dd95SBruce Richardson 
608199a2dd95SBruce Richardson 	/* Default controller and pf to caller. */
608299a2dd95SBruce Richardson 	if (controller == -1)
608399a2dd95SBruce Richardson 		controller = info->controller;
608499a2dd95SBruce Richardson 	if (pf == -1)
608599a2dd95SBruce Richardson 		pf = info->pf;
608699a2dd95SBruce Richardson 
608799a2dd95SBruce Richardson 	/* Locate representor ID. */
608899a2dd95SBruce Richardson 	ret = -ENOENT;
608910eaf41dSViacheslav Galaktionov 	for (i = 0; i < info->nb_ranges; ++i) {
609099a2dd95SBruce Richardson 		if (info->ranges[i].type != type)
609199a2dd95SBruce Richardson 			continue;
609299a2dd95SBruce Richardson 		if (info->ranges[i].controller != controller)
609399a2dd95SBruce Richardson 			continue;
609499a2dd95SBruce Richardson 		if (info->ranges[i].id_end < info->ranges[i].id_base) {
609599a2dd95SBruce Richardson 			RTE_LOG(WARNING, EAL, "Port %hu invalid representor ID Range %u - %u, entry %d\n",
6096ff4e52efSViacheslav Galaktionov 				port_id, info->ranges[i].id_base,
609799a2dd95SBruce Richardson 				info->ranges[i].id_end, i);
609899a2dd95SBruce Richardson 			continue;
609999a2dd95SBruce Richardson 
610099a2dd95SBruce Richardson 		}
610199a2dd95SBruce Richardson 		count = info->ranges[i].id_end - info->ranges[i].id_base + 1;
610299a2dd95SBruce Richardson 		switch (info->ranges[i].type) {
610399a2dd95SBruce Richardson 		case RTE_ETH_REPRESENTOR_PF:
610499a2dd95SBruce Richardson 			if (pf < info->ranges[i].pf ||
610599a2dd95SBruce Richardson 			    pf >= info->ranges[i].pf + count)
610699a2dd95SBruce Richardson 				continue;
610799a2dd95SBruce Richardson 			*repr_id = info->ranges[i].id_base +
610899a2dd95SBruce Richardson 				   (pf - info->ranges[i].pf);
610999a2dd95SBruce Richardson 			ret = 0;
611099a2dd95SBruce Richardson 			goto out;
611199a2dd95SBruce Richardson 		case RTE_ETH_REPRESENTOR_VF:
611299a2dd95SBruce Richardson 			if (info->ranges[i].pf != pf)
611399a2dd95SBruce Richardson 				continue;
611499a2dd95SBruce Richardson 			if (representor_port < info->ranges[i].vf ||
611599a2dd95SBruce Richardson 			    representor_port >= info->ranges[i].vf + count)
611699a2dd95SBruce Richardson 				continue;
611799a2dd95SBruce Richardson 			*repr_id = info->ranges[i].id_base +
611899a2dd95SBruce Richardson 				   (representor_port - info->ranges[i].vf);
611999a2dd95SBruce Richardson 			ret = 0;
612099a2dd95SBruce Richardson 			goto out;
612199a2dd95SBruce Richardson 		case RTE_ETH_REPRESENTOR_SF:
612299a2dd95SBruce Richardson 			if (info->ranges[i].pf != pf)
612399a2dd95SBruce Richardson 				continue;
612499a2dd95SBruce Richardson 			if (representor_port < info->ranges[i].sf ||
612599a2dd95SBruce Richardson 			    representor_port >= info->ranges[i].sf + count)
612699a2dd95SBruce Richardson 				continue;
612799a2dd95SBruce Richardson 			*repr_id = info->ranges[i].id_base +
612899a2dd95SBruce Richardson 			      (representor_port - info->ranges[i].sf);
612999a2dd95SBruce Richardson 			ret = 0;
613099a2dd95SBruce Richardson 			goto out;
613199a2dd95SBruce Richardson 		default:
613299a2dd95SBruce Richardson 			break;
613399a2dd95SBruce Richardson 		}
613499a2dd95SBruce Richardson 	}
613599a2dd95SBruce Richardson out:
613699a2dd95SBruce Richardson 	free(info);
613799a2dd95SBruce Richardson 	return ret;
613899a2dd95SBruce Richardson }
613999a2dd95SBruce Richardson 
614099a2dd95SBruce Richardson static int
614199a2dd95SBruce Richardson eth_dev_handle_port_list(const char *cmd __rte_unused,
614299a2dd95SBruce Richardson 		const char *params __rte_unused,
614399a2dd95SBruce Richardson 		struct rte_tel_data *d)
614499a2dd95SBruce Richardson {
614599a2dd95SBruce Richardson 	int port_id;
614699a2dd95SBruce Richardson 
614799a2dd95SBruce Richardson 	rte_tel_data_start_array(d, RTE_TEL_INT_VAL);
614899a2dd95SBruce Richardson 	RTE_ETH_FOREACH_DEV(port_id)
614999a2dd95SBruce Richardson 		rte_tel_data_add_array_int(d, port_id);
615099a2dd95SBruce Richardson 	return 0;
615199a2dd95SBruce Richardson }
615299a2dd95SBruce Richardson 
615399a2dd95SBruce Richardson static void
615499a2dd95SBruce Richardson eth_dev_add_port_queue_stats(struct rte_tel_data *d, uint64_t *q_stats,
615599a2dd95SBruce Richardson 		const char *stat_name)
615699a2dd95SBruce Richardson {
615799a2dd95SBruce Richardson 	int q;
615899a2dd95SBruce Richardson 	struct rte_tel_data *q_data = rte_tel_data_alloc();
615999a2dd95SBruce Richardson 	rte_tel_data_start_array(q_data, RTE_TEL_U64_VAL);
616099a2dd95SBruce Richardson 	for (q = 0; q < RTE_ETHDEV_QUEUE_STAT_CNTRS; q++)
616199a2dd95SBruce Richardson 		rte_tel_data_add_array_u64(q_data, q_stats[q]);
616299a2dd95SBruce Richardson 	rte_tel_data_add_dict_container(d, stat_name, q_data, 0);
616399a2dd95SBruce Richardson }
616499a2dd95SBruce Richardson 
616599a2dd95SBruce Richardson #define ADD_DICT_STAT(stats, s) rte_tel_data_add_dict_u64(d, #s, stats.s)
616699a2dd95SBruce Richardson 
616799a2dd95SBruce Richardson static int
616899a2dd95SBruce Richardson eth_dev_handle_port_stats(const char *cmd __rte_unused,
616999a2dd95SBruce Richardson 		const char *params,
617099a2dd95SBruce Richardson 		struct rte_tel_data *d)
617199a2dd95SBruce Richardson {
617299a2dd95SBruce Richardson 	struct rte_eth_stats stats;
617399a2dd95SBruce Richardson 	int port_id, ret;
617499a2dd95SBruce Richardson 
617599a2dd95SBruce Richardson 	if (params == NULL || strlen(params) == 0 || !isdigit(*params))
617699a2dd95SBruce Richardson 		return -1;
617799a2dd95SBruce Richardson 
617899a2dd95SBruce Richardson 	port_id = atoi(params);
617999a2dd95SBruce Richardson 	if (!rte_eth_dev_is_valid_port(port_id))
618099a2dd95SBruce Richardson 		return -1;
618199a2dd95SBruce Richardson 
618299a2dd95SBruce Richardson 	ret = rte_eth_stats_get(port_id, &stats);
618399a2dd95SBruce Richardson 	if (ret < 0)
618499a2dd95SBruce Richardson 		return -1;
618599a2dd95SBruce Richardson 
618699a2dd95SBruce Richardson 	rte_tel_data_start_dict(d);
618799a2dd95SBruce Richardson 	ADD_DICT_STAT(stats, ipackets);
618899a2dd95SBruce Richardson 	ADD_DICT_STAT(stats, opackets);
618999a2dd95SBruce Richardson 	ADD_DICT_STAT(stats, ibytes);
619099a2dd95SBruce Richardson 	ADD_DICT_STAT(stats, obytes);
619199a2dd95SBruce Richardson 	ADD_DICT_STAT(stats, imissed);
619299a2dd95SBruce Richardson 	ADD_DICT_STAT(stats, ierrors);
619399a2dd95SBruce Richardson 	ADD_DICT_STAT(stats, oerrors);
619499a2dd95SBruce Richardson 	ADD_DICT_STAT(stats, rx_nombuf);
619599a2dd95SBruce Richardson 	eth_dev_add_port_queue_stats(d, stats.q_ipackets, "q_ipackets");
619699a2dd95SBruce Richardson 	eth_dev_add_port_queue_stats(d, stats.q_opackets, "q_opackets");
619799a2dd95SBruce Richardson 	eth_dev_add_port_queue_stats(d, stats.q_ibytes, "q_ibytes");
619899a2dd95SBruce Richardson 	eth_dev_add_port_queue_stats(d, stats.q_obytes, "q_obytes");
619999a2dd95SBruce Richardson 	eth_dev_add_port_queue_stats(d, stats.q_errors, "q_errors");
620099a2dd95SBruce Richardson 
620199a2dd95SBruce Richardson 	return 0;
620299a2dd95SBruce Richardson }
620399a2dd95SBruce Richardson 
620499a2dd95SBruce Richardson static int
620599a2dd95SBruce Richardson eth_dev_handle_port_xstats(const char *cmd __rte_unused,
620699a2dd95SBruce Richardson 		const char *params,
620799a2dd95SBruce Richardson 		struct rte_tel_data *d)
620899a2dd95SBruce Richardson {
620999a2dd95SBruce Richardson 	struct rte_eth_xstat *eth_xstats;
621099a2dd95SBruce Richardson 	struct rte_eth_xstat_name *xstat_names;
621199a2dd95SBruce Richardson 	int port_id, num_xstats;
621299a2dd95SBruce Richardson 	int i, ret;
621399a2dd95SBruce Richardson 	char *end_param;
621499a2dd95SBruce Richardson 
621599a2dd95SBruce Richardson 	if (params == NULL || strlen(params) == 0 || !isdigit(*params))
621699a2dd95SBruce Richardson 		return -1;
621799a2dd95SBruce Richardson 
621899a2dd95SBruce Richardson 	port_id = strtoul(params, &end_param, 0);
621999a2dd95SBruce Richardson 	if (*end_param != '\0')
622099a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(NOTICE,
622199a2dd95SBruce Richardson 			"Extra parameters passed to ethdev telemetry command, ignoring");
622299a2dd95SBruce Richardson 	if (!rte_eth_dev_is_valid_port(port_id))
622399a2dd95SBruce Richardson 		return -1;
622499a2dd95SBruce Richardson 
622599a2dd95SBruce Richardson 	num_xstats = rte_eth_xstats_get(port_id, NULL, 0);
622699a2dd95SBruce Richardson 	if (num_xstats < 0)
622799a2dd95SBruce Richardson 		return -1;
622899a2dd95SBruce Richardson 
622999a2dd95SBruce Richardson 	/* use one malloc for both names and stats */
623099a2dd95SBruce Richardson 	eth_xstats = malloc((sizeof(struct rte_eth_xstat) +
623199a2dd95SBruce Richardson 			sizeof(struct rte_eth_xstat_name)) * num_xstats);
623299a2dd95SBruce Richardson 	if (eth_xstats == NULL)
623399a2dd95SBruce Richardson 		return -1;
623499a2dd95SBruce Richardson 	xstat_names = (void *)&eth_xstats[num_xstats];
623599a2dd95SBruce Richardson 
623699a2dd95SBruce Richardson 	ret = rte_eth_xstats_get_names(port_id, xstat_names, num_xstats);
623799a2dd95SBruce Richardson 	if (ret < 0 || ret > num_xstats) {
623899a2dd95SBruce Richardson 		free(eth_xstats);
623999a2dd95SBruce Richardson 		return -1;
624099a2dd95SBruce Richardson 	}
624199a2dd95SBruce Richardson 
624299a2dd95SBruce Richardson 	ret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats);
624399a2dd95SBruce Richardson 	if (ret < 0 || ret > num_xstats) {
624499a2dd95SBruce Richardson 		free(eth_xstats);
624599a2dd95SBruce Richardson 		return -1;
624699a2dd95SBruce Richardson 	}
624799a2dd95SBruce Richardson 
624899a2dd95SBruce Richardson 	rte_tel_data_start_dict(d);
624999a2dd95SBruce Richardson 	for (i = 0; i < num_xstats; i++)
625099a2dd95SBruce Richardson 		rte_tel_data_add_dict_u64(d, xstat_names[i].name,
625199a2dd95SBruce Richardson 				eth_xstats[i].value);
625299a2dd95SBruce Richardson 	return 0;
625399a2dd95SBruce Richardson }
625499a2dd95SBruce Richardson 
625599a2dd95SBruce Richardson static int
625699a2dd95SBruce Richardson eth_dev_handle_port_link_status(const char *cmd __rte_unused,
625799a2dd95SBruce Richardson 		const char *params,
625899a2dd95SBruce Richardson 		struct rte_tel_data *d)
625999a2dd95SBruce Richardson {
626099a2dd95SBruce Richardson 	static const char *status_str = "status";
626199a2dd95SBruce Richardson 	int ret, port_id;
626299a2dd95SBruce Richardson 	struct rte_eth_link link;
626399a2dd95SBruce Richardson 	char *end_param;
626499a2dd95SBruce Richardson 
626599a2dd95SBruce Richardson 	if (params == NULL || strlen(params) == 0 || !isdigit(*params))
626699a2dd95SBruce Richardson 		return -1;
626799a2dd95SBruce Richardson 
626899a2dd95SBruce Richardson 	port_id = strtoul(params, &end_param, 0);
626999a2dd95SBruce Richardson 	if (*end_param != '\0')
627099a2dd95SBruce Richardson 		RTE_ETHDEV_LOG(NOTICE,
627199a2dd95SBruce Richardson 			"Extra parameters passed to ethdev telemetry command, ignoring");
627299a2dd95SBruce Richardson 	if (!rte_eth_dev_is_valid_port(port_id))
627399a2dd95SBruce Richardson 		return -1;
627499a2dd95SBruce Richardson 
627599a2dd95SBruce Richardson 	ret = rte_eth_link_get_nowait(port_id, &link);
627699a2dd95SBruce Richardson 	if (ret < 0)
627799a2dd95SBruce Richardson 		return -1;
627899a2dd95SBruce Richardson 
627999a2dd95SBruce Richardson 	rte_tel_data_start_dict(d);
628099a2dd95SBruce Richardson 	if (!link.link_status) {
628199a2dd95SBruce Richardson 		rte_tel_data_add_dict_string(d, status_str, "DOWN");
628299a2dd95SBruce Richardson 		return 0;
628399a2dd95SBruce Richardson 	}
628499a2dd95SBruce Richardson 	rte_tel_data_add_dict_string(d, status_str, "UP");
628599a2dd95SBruce Richardson 	rte_tel_data_add_dict_u64(d, "speed", link.link_speed);
628699a2dd95SBruce Richardson 	rte_tel_data_add_dict_string(d, "duplex",
6287295968d1SFerruh Yigit 			(link.link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ?
628899a2dd95SBruce Richardson 				"full-duplex" : "half-duplex");
628999a2dd95SBruce Richardson 	return 0;
629099a2dd95SBruce Richardson }
629199a2dd95SBruce Richardson 
629258b43c1dSGowrishankar Muthukrishnan static int
629358b43c1dSGowrishankar Muthukrishnan eth_dev_handle_port_info(const char *cmd __rte_unused,
629458b43c1dSGowrishankar Muthukrishnan 		const char *params,
629558b43c1dSGowrishankar Muthukrishnan 		struct rte_tel_data *d)
629658b43c1dSGowrishankar Muthukrishnan {
629758b43c1dSGowrishankar Muthukrishnan 	struct rte_tel_data *rxq_state, *txq_state;
629858b43c1dSGowrishankar Muthukrishnan 	char mac_addr[RTE_ETHER_ADDR_LEN];
629958b43c1dSGowrishankar Muthukrishnan 	struct rte_eth_dev *eth_dev;
630058b43c1dSGowrishankar Muthukrishnan 	char *end_param;
630158b43c1dSGowrishankar Muthukrishnan 	int port_id, i;
630258b43c1dSGowrishankar Muthukrishnan 
630358b43c1dSGowrishankar Muthukrishnan 	if (params == NULL || strlen(params) == 0 || !isdigit(*params))
630458b43c1dSGowrishankar Muthukrishnan 		return -1;
630558b43c1dSGowrishankar Muthukrishnan 
630658b43c1dSGowrishankar Muthukrishnan 	port_id = strtoul(params, &end_param, 0);
630758b43c1dSGowrishankar Muthukrishnan 	if (*end_param != '\0')
630858b43c1dSGowrishankar Muthukrishnan 		RTE_ETHDEV_LOG(NOTICE,
630958b43c1dSGowrishankar Muthukrishnan 			"Extra parameters passed to ethdev telemetry command, ignoring");
631058b43c1dSGowrishankar Muthukrishnan 
631158b43c1dSGowrishankar Muthukrishnan 	if (!rte_eth_dev_is_valid_port(port_id))
631258b43c1dSGowrishankar Muthukrishnan 		return -EINVAL;
631358b43c1dSGowrishankar Muthukrishnan 
631458b43c1dSGowrishankar Muthukrishnan 	eth_dev = &rte_eth_devices[port_id];
631558b43c1dSGowrishankar Muthukrishnan 	if (!eth_dev)
631658b43c1dSGowrishankar Muthukrishnan 		return -EINVAL;
631758b43c1dSGowrishankar Muthukrishnan 
631858b43c1dSGowrishankar Muthukrishnan 	rxq_state = rte_tel_data_alloc();
631958b43c1dSGowrishankar Muthukrishnan 	if (!rxq_state)
632058b43c1dSGowrishankar Muthukrishnan 		return -ENOMEM;
632158b43c1dSGowrishankar Muthukrishnan 
632258b43c1dSGowrishankar Muthukrishnan 	txq_state = rte_tel_data_alloc();
6323*52b49ea0SYunjian Wang 	if (!txq_state) {
6324*52b49ea0SYunjian Wang 		rte_tel_data_free(rxq_state);
632558b43c1dSGowrishankar Muthukrishnan 		return -ENOMEM;
6326*52b49ea0SYunjian Wang 	}
632758b43c1dSGowrishankar Muthukrishnan 
632858b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_start_dict(d);
632958b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_string(d, "name", eth_dev->data->name);
633058b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "state", eth_dev->state);
633158b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "nb_rx_queues",
633258b43c1dSGowrishankar Muthukrishnan 			eth_dev->data->nb_rx_queues);
633358b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "nb_tx_queues",
633458b43c1dSGowrishankar Muthukrishnan 			eth_dev->data->nb_tx_queues);
633558b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "port_id", eth_dev->data->port_id);
633658b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "mtu", eth_dev->data->mtu);
633758b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "rx_mbuf_size_min",
633858b43c1dSGowrishankar Muthukrishnan 			eth_dev->data->min_rx_buf_size);
633958b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "rx_mbuf_alloc_fail",
634058b43c1dSGowrishankar Muthukrishnan 			eth_dev->data->rx_mbuf_alloc_failed);
634158b43c1dSGowrishankar Muthukrishnan 	snprintf(mac_addr, RTE_ETHER_ADDR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
634258b43c1dSGowrishankar Muthukrishnan 			 eth_dev->data->mac_addrs->addr_bytes[0],
634358b43c1dSGowrishankar Muthukrishnan 			 eth_dev->data->mac_addrs->addr_bytes[1],
634458b43c1dSGowrishankar Muthukrishnan 			 eth_dev->data->mac_addrs->addr_bytes[2],
634558b43c1dSGowrishankar Muthukrishnan 			 eth_dev->data->mac_addrs->addr_bytes[3],
634658b43c1dSGowrishankar Muthukrishnan 			 eth_dev->data->mac_addrs->addr_bytes[4],
634758b43c1dSGowrishankar Muthukrishnan 			 eth_dev->data->mac_addrs->addr_bytes[5]);
634858b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_string(d, "mac_addr", mac_addr);
634958b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "promiscuous",
635058b43c1dSGowrishankar Muthukrishnan 			eth_dev->data->promiscuous);
635158b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "scattered_rx",
635258b43c1dSGowrishankar Muthukrishnan 			eth_dev->data->scattered_rx);
635358b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "all_multicast",
635458b43c1dSGowrishankar Muthukrishnan 			eth_dev->data->all_multicast);
635558b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "dev_started", eth_dev->data->dev_started);
635658b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "lro", eth_dev->data->lro);
635758b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "dev_configured",
635858b43c1dSGowrishankar Muthukrishnan 			eth_dev->data->dev_configured);
635958b43c1dSGowrishankar Muthukrishnan 
636058b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_start_array(rxq_state, RTE_TEL_INT_VAL);
636158b43c1dSGowrishankar Muthukrishnan 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++)
636258b43c1dSGowrishankar Muthukrishnan 		rte_tel_data_add_array_int(rxq_state,
636358b43c1dSGowrishankar Muthukrishnan 				eth_dev->data->rx_queue_state[i]);
636458b43c1dSGowrishankar Muthukrishnan 
636558b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_start_array(txq_state, RTE_TEL_INT_VAL);
636658b43c1dSGowrishankar Muthukrishnan 	for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
636758b43c1dSGowrishankar Muthukrishnan 		rte_tel_data_add_array_int(txq_state,
636858b43c1dSGowrishankar Muthukrishnan 				eth_dev->data->tx_queue_state[i]);
636958b43c1dSGowrishankar Muthukrishnan 
637058b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_container(d, "rxq_state", rxq_state, 0);
637158b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_container(d, "txq_state", txq_state, 0);
637258b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "numa_node", eth_dev->data->numa_node);
637358b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "dev_flags", eth_dev->data->dev_flags);
637458b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "rx_offloads",
637558b43c1dSGowrishankar Muthukrishnan 			eth_dev->data->dev_conf.rxmode.offloads);
637658b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "tx_offloads",
637758b43c1dSGowrishankar Muthukrishnan 			eth_dev->data->dev_conf.txmode.offloads);
637858b43c1dSGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "ethdev_rss_hf",
637958b43c1dSGowrishankar Muthukrishnan 			eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf);
638058b43c1dSGowrishankar Muthukrishnan 
638158b43c1dSGowrishankar Muthukrishnan 	return 0;
638258b43c1dSGowrishankar Muthukrishnan }
638358b43c1dSGowrishankar Muthukrishnan 
638499a2dd95SBruce Richardson int
638599a2dd95SBruce Richardson rte_eth_hairpin_queue_peer_update(uint16_t peer_port, uint16_t peer_queue,
638699a2dd95SBruce Richardson 				  struct rte_hairpin_peer_info *cur_info,
638799a2dd95SBruce Richardson 				  struct rte_hairpin_peer_info *peer_info,
638899a2dd95SBruce Richardson 				  uint32_t direction)
638999a2dd95SBruce Richardson {
639099a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
639199a2dd95SBruce Richardson 
639299a2dd95SBruce Richardson 	/* Current queue information is not mandatory. */
639399a2dd95SBruce Richardson 	if (peer_info == NULL)
639499a2dd95SBruce Richardson 		return -EINVAL;
639599a2dd95SBruce Richardson 
639699a2dd95SBruce Richardson 	/* No need to check the validity again. */
639799a2dd95SBruce Richardson 	dev = &rte_eth_devices[peer_port];
639899a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_update,
639999a2dd95SBruce Richardson 				-ENOTSUP);
640099a2dd95SBruce Richardson 
640199a2dd95SBruce Richardson 	return (*dev->dev_ops->hairpin_queue_peer_update)(dev, peer_queue,
640299a2dd95SBruce Richardson 					cur_info, peer_info, direction);
640399a2dd95SBruce Richardson }
640499a2dd95SBruce Richardson 
640599a2dd95SBruce Richardson int
640699a2dd95SBruce Richardson rte_eth_hairpin_queue_peer_bind(uint16_t cur_port, uint16_t cur_queue,
640799a2dd95SBruce Richardson 				struct rte_hairpin_peer_info *peer_info,
640899a2dd95SBruce Richardson 				uint32_t direction)
640999a2dd95SBruce Richardson {
641099a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
641199a2dd95SBruce Richardson 
641299a2dd95SBruce Richardson 	if (peer_info == NULL)
641399a2dd95SBruce Richardson 		return -EINVAL;
641499a2dd95SBruce Richardson 
641599a2dd95SBruce Richardson 	/* No need to check the validity again. */
641699a2dd95SBruce Richardson 	dev = &rte_eth_devices[cur_port];
641799a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_bind,
641899a2dd95SBruce Richardson 				-ENOTSUP);
641999a2dd95SBruce Richardson 
642099a2dd95SBruce Richardson 	return (*dev->dev_ops->hairpin_queue_peer_bind)(dev, cur_queue,
642199a2dd95SBruce Richardson 							peer_info, direction);
642299a2dd95SBruce Richardson }
642399a2dd95SBruce Richardson 
642499a2dd95SBruce Richardson int
642599a2dd95SBruce Richardson rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue,
642699a2dd95SBruce Richardson 				  uint32_t direction)
642799a2dd95SBruce Richardson {
642899a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
642999a2dd95SBruce Richardson 
643099a2dd95SBruce Richardson 	/* No need to check the validity again. */
643199a2dd95SBruce Richardson 	dev = &rte_eth_devices[cur_port];
643299a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_unbind,
643399a2dd95SBruce Richardson 				-ENOTSUP);
643499a2dd95SBruce Richardson 
643599a2dd95SBruce Richardson 	return (*dev->dev_ops->hairpin_queue_peer_unbind)(dev, cur_queue,
643699a2dd95SBruce Richardson 							  direction);
643799a2dd95SBruce Richardson }
643899a2dd95SBruce Richardson 
643999a2dd95SBruce Richardson int
644099a2dd95SBruce Richardson rte_eth_representor_info_get(uint16_t port_id,
644199a2dd95SBruce Richardson 			     struct rte_eth_representor_info *info)
644299a2dd95SBruce Richardson {
644399a2dd95SBruce Richardson 	struct rte_eth_dev *dev;
644499a2dd95SBruce Richardson 
644599a2dd95SBruce Richardson 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
644699a2dd95SBruce Richardson 	dev = &rte_eth_devices[port_id];
644799a2dd95SBruce Richardson 
644899a2dd95SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->representor_info_get, -ENOTSUP);
644953ef1b34SMin Hu (Connor) 	return eth_err(port_id, (*dev->dev_ops->representor_info_get)(dev, info));
645099a2dd95SBruce Richardson }
645199a2dd95SBruce Richardson 
6452f6d8a6d3SIvan Malov int
6453f6d8a6d3SIvan Malov rte_eth_rx_metadata_negotiate(uint16_t port_id, uint64_t *features)
6454f6d8a6d3SIvan Malov {
6455f6d8a6d3SIvan Malov 	struct rte_eth_dev *dev;
6456f6d8a6d3SIvan Malov 
6457f6d8a6d3SIvan Malov 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6458f6d8a6d3SIvan Malov 	dev = &rte_eth_devices[port_id];
6459f6d8a6d3SIvan Malov 
6460f6d8a6d3SIvan Malov 	if (dev->data->dev_configured != 0) {
6461f6d8a6d3SIvan Malov 		RTE_ETHDEV_LOG(ERR,
64625906be5aSAndrew Rybchenko 			"The port (ID=%"PRIu16") is already configured\n",
6463f6d8a6d3SIvan Malov 			port_id);
6464f6d8a6d3SIvan Malov 		return -EBUSY;
6465f6d8a6d3SIvan Malov 	}
6466f6d8a6d3SIvan Malov 
6467f6d8a6d3SIvan Malov 	if (features == NULL) {
6468f6d8a6d3SIvan Malov 		RTE_ETHDEV_LOG(ERR, "Invalid features (NULL)\n");
6469f6d8a6d3SIvan Malov 		return -EINVAL;
6470f6d8a6d3SIvan Malov 	}
6471f6d8a6d3SIvan Malov 
6472f6d8a6d3SIvan Malov 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_metadata_negotiate, -ENOTSUP);
6473f6d8a6d3SIvan Malov 	return eth_err(port_id,
6474f6d8a6d3SIvan Malov 		       (*dev->dev_ops->rx_metadata_negotiate)(dev, features));
6475f6d8a6d3SIvan Malov }
6476f6d8a6d3SIvan Malov 
6477eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO);
647899a2dd95SBruce Richardson 
647999a2dd95SBruce Richardson RTE_INIT(ethdev_init_telemetry)
648099a2dd95SBruce Richardson {
648199a2dd95SBruce Richardson 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
648299a2dd95SBruce Richardson 			"Returns list of available ethdev ports. Takes no parameters");
648399a2dd95SBruce Richardson 	rte_telemetry_register_cmd("/ethdev/stats", eth_dev_handle_port_stats,
648499a2dd95SBruce Richardson 			"Returns the common stats for a port. Parameters: int port_id");
648599a2dd95SBruce Richardson 	rte_telemetry_register_cmd("/ethdev/xstats", eth_dev_handle_port_xstats,
648699a2dd95SBruce Richardson 			"Returns the extended stats for a port. Parameters: int port_id");
648799a2dd95SBruce Richardson 	rte_telemetry_register_cmd("/ethdev/link_status",
648899a2dd95SBruce Richardson 			eth_dev_handle_port_link_status,
648999a2dd95SBruce Richardson 			"Returns the link status for a port. Parameters: int port_id");
649058b43c1dSGowrishankar Muthukrishnan 	rte_telemetry_register_cmd("/ethdev/info", eth_dev_handle_port_info,
649158b43c1dSGowrishankar Muthukrishnan 			"Returns the device info for a port. Parameters: int port_id");
649299a2dd95SBruce Richardson }
6493