xref: /f-stack/dpdk/lib/librte_ethdev/rte_ethdev.c (revision 2d9fd380)
1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606  * Copyright(c) 2010-2017 Intel Corporation
3d30ea906Sjfb8856606  */
4d30ea906Sjfb8856606 
5d30ea906Sjfb8856606 #include <sys/types.h>
6d30ea906Sjfb8856606 #include <sys/queue.h>
7d30ea906Sjfb8856606 #include <ctype.h>
8d30ea906Sjfb8856606 #include <stdio.h>
9d30ea906Sjfb8856606 #include <stdlib.h>
10d30ea906Sjfb8856606 #include <string.h>
11d30ea906Sjfb8856606 #include <stdarg.h>
12d30ea906Sjfb8856606 #include <errno.h>
13d30ea906Sjfb8856606 #include <stdbool.h>
14d30ea906Sjfb8856606 #include <stdint.h>
15d30ea906Sjfb8856606 #include <inttypes.h>
16d30ea906Sjfb8856606 #include <netinet/in.h>
17d30ea906Sjfb8856606 
18d30ea906Sjfb8856606 #include <rte_byteorder.h>
19d30ea906Sjfb8856606 #include <rte_log.h>
20d30ea906Sjfb8856606 #include <rte_debug.h>
21d30ea906Sjfb8856606 #include <rte_interrupts.h>
22d30ea906Sjfb8856606 #include <rte_memory.h>
23d30ea906Sjfb8856606 #include <rte_memcpy.h>
24d30ea906Sjfb8856606 #include <rte_memzone.h>
25d30ea906Sjfb8856606 #include <rte_launch.h>
26d30ea906Sjfb8856606 #include <rte_eal.h>
27d30ea906Sjfb8856606 #include <rte_per_lcore.h>
28d30ea906Sjfb8856606 #include <rte_lcore.h>
29d30ea906Sjfb8856606 #include <rte_branch_prediction.h>
30d30ea906Sjfb8856606 #include <rte_common.h>
31d30ea906Sjfb8856606 #include <rte_mempool.h>
32d30ea906Sjfb8856606 #include <rte_malloc.h>
33d30ea906Sjfb8856606 #include <rte_mbuf.h>
34d30ea906Sjfb8856606 #include <rte_errno.h>
35d30ea906Sjfb8856606 #include <rte_spinlock.h>
36d30ea906Sjfb8856606 #include <rte_string_fns.h>
37d30ea906Sjfb8856606 #include <rte_kvargs.h>
38d30ea906Sjfb8856606 #include <rte_class.h>
394418919fSjohnjiang #include <rte_ether.h>
40*2d9fd380Sjfb8856606 #include <rte_telemetry.h>
41d30ea906Sjfb8856606 
42*2d9fd380Sjfb8856606 #include "rte_ethdev_trace.h"
43d30ea906Sjfb8856606 #include "rte_ethdev.h"
44d30ea906Sjfb8856606 #include "rte_ethdev_driver.h"
45d30ea906Sjfb8856606 #include "ethdev_profile.h"
46d30ea906Sjfb8856606 #include "ethdev_private.h"
47d30ea906Sjfb8856606 
48d30ea906Sjfb8856606 static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";
49d30ea906Sjfb8856606 struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
50d30ea906Sjfb8856606 
51d30ea906Sjfb8856606 /* spinlock for eth device callbacks */
52*2d9fd380Sjfb8856606 static rte_spinlock_t eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
53d30ea906Sjfb8856606 
54d30ea906Sjfb8856606 /* spinlock for add/remove rx callbacks */
55*2d9fd380Sjfb8856606 static rte_spinlock_t eth_dev_rx_cb_lock = RTE_SPINLOCK_INITIALIZER;
56d30ea906Sjfb8856606 
57d30ea906Sjfb8856606 /* spinlock for add/remove tx callbacks */
58*2d9fd380Sjfb8856606 static rte_spinlock_t eth_dev_tx_cb_lock = RTE_SPINLOCK_INITIALIZER;
59d30ea906Sjfb8856606 
60d30ea906Sjfb8856606 /* spinlock for shared data allocation */
61*2d9fd380Sjfb8856606 static rte_spinlock_t eth_dev_shared_data_lock = RTE_SPINLOCK_INITIALIZER;
62d30ea906Sjfb8856606 
63d30ea906Sjfb8856606 /* store statistics names and its offset in stats structure  */
64d30ea906Sjfb8856606 struct rte_eth_xstats_name_off {
65d30ea906Sjfb8856606 	char name[RTE_ETH_XSTATS_NAME_SIZE];
66d30ea906Sjfb8856606 	unsigned offset;
67d30ea906Sjfb8856606 };
68d30ea906Sjfb8856606 
69d30ea906Sjfb8856606 /* Shared memory between primary and secondary processes. */
70d30ea906Sjfb8856606 static struct {
71d30ea906Sjfb8856606 	uint64_t next_owner_id;
72d30ea906Sjfb8856606 	rte_spinlock_t ownership_lock;
73d30ea906Sjfb8856606 	struct rte_eth_dev_data data[RTE_MAX_ETHPORTS];
74*2d9fd380Sjfb8856606 } *eth_dev_shared_data;
75d30ea906Sjfb8856606 
76*2d9fd380Sjfb8856606 static const struct rte_eth_xstats_name_off eth_dev_stats_strings[] = {
77d30ea906Sjfb8856606 	{"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)},
78d30ea906Sjfb8856606 	{"tx_good_packets", offsetof(struct rte_eth_stats, opackets)},
79d30ea906Sjfb8856606 	{"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)},
80d30ea906Sjfb8856606 	{"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)},
81d30ea906Sjfb8856606 	{"rx_missed_errors", offsetof(struct rte_eth_stats, imissed)},
82d30ea906Sjfb8856606 	{"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
83d30ea906Sjfb8856606 	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
84d30ea906Sjfb8856606 	{"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats,
85d30ea906Sjfb8856606 		rx_nombuf)},
86d30ea906Sjfb8856606 };
87d30ea906Sjfb8856606 
88*2d9fd380Sjfb8856606 #define RTE_NB_STATS RTE_DIM(eth_dev_stats_strings)
89d30ea906Sjfb8856606 
90*2d9fd380Sjfb8856606 static const struct rte_eth_xstats_name_off eth_dev_rxq_stats_strings[] = {
91d30ea906Sjfb8856606 	{"packets", offsetof(struct rte_eth_stats, q_ipackets)},
92d30ea906Sjfb8856606 	{"bytes", offsetof(struct rte_eth_stats, q_ibytes)},
93d30ea906Sjfb8856606 	{"errors", offsetof(struct rte_eth_stats, q_errors)},
94d30ea906Sjfb8856606 };
95d30ea906Sjfb8856606 
96*2d9fd380Sjfb8856606 #define RTE_NB_RXQ_STATS RTE_DIM(eth_dev_rxq_stats_strings)
97d30ea906Sjfb8856606 
98*2d9fd380Sjfb8856606 static const struct rte_eth_xstats_name_off eth_dev_txq_stats_strings[] = {
99d30ea906Sjfb8856606 	{"packets", offsetof(struct rte_eth_stats, q_opackets)},
100d30ea906Sjfb8856606 	{"bytes", offsetof(struct rte_eth_stats, q_obytes)},
101d30ea906Sjfb8856606 };
102*2d9fd380Sjfb8856606 #define RTE_NB_TXQ_STATS RTE_DIM(eth_dev_txq_stats_strings)
103d30ea906Sjfb8856606 
104d30ea906Sjfb8856606 #define RTE_RX_OFFLOAD_BIT2STR(_name)	\
105d30ea906Sjfb8856606 	{ DEV_RX_OFFLOAD_##_name, #_name }
106d30ea906Sjfb8856606 
107*2d9fd380Sjfb8856606 #define RTE_ETH_RX_OFFLOAD_BIT2STR(_name)	\
108*2d9fd380Sjfb8856606 	{ RTE_ETH_RX_OFFLOAD_##_name, #_name }
109*2d9fd380Sjfb8856606 
110d30ea906Sjfb8856606 static const struct {
111d30ea906Sjfb8856606 	uint64_t offload;
112d30ea906Sjfb8856606 	const char *name;
113*2d9fd380Sjfb8856606 } eth_dev_rx_offload_names[] = {
114d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(VLAN_STRIP),
115d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(IPV4_CKSUM),
116d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(UDP_CKSUM),
117d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(TCP_CKSUM),
118d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(TCP_LRO),
119d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(QINQ_STRIP),
120d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM),
121d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(MACSEC_STRIP),
122d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(HEADER_SPLIT),
123d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(VLAN_FILTER),
124d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(VLAN_EXTEND),
125d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(JUMBO_FRAME),
126d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(SCATTER),
127d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(TIMESTAMP),
128d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(SECURITY),
129d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(KEEP_CRC),
130d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(SCTP_CKSUM),
131d30ea906Sjfb8856606 	RTE_RX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM),
1324418919fSjohnjiang 	RTE_RX_OFFLOAD_BIT2STR(RSS_HASH),
133*2d9fd380Sjfb8856606 	RTE_ETH_RX_OFFLOAD_BIT2STR(BUFFER_SPLIT),
134d30ea906Sjfb8856606 };
135d30ea906Sjfb8856606 
136d30ea906Sjfb8856606 #undef RTE_RX_OFFLOAD_BIT2STR
137*2d9fd380Sjfb8856606 #undef RTE_ETH_RX_OFFLOAD_BIT2STR
138d30ea906Sjfb8856606 
139d30ea906Sjfb8856606 #define RTE_TX_OFFLOAD_BIT2STR(_name)	\
140d30ea906Sjfb8856606 	{ DEV_TX_OFFLOAD_##_name, #_name }
141d30ea906Sjfb8856606 
142d30ea906Sjfb8856606 static const struct {
143d30ea906Sjfb8856606 	uint64_t offload;
144d30ea906Sjfb8856606 	const char *name;
145*2d9fd380Sjfb8856606 } eth_dev_tx_offload_names[] = {
146d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(VLAN_INSERT),
147d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(IPV4_CKSUM),
148d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(UDP_CKSUM),
149d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(TCP_CKSUM),
150d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(SCTP_CKSUM),
151d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(TCP_TSO),
152d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(UDP_TSO),
153d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM),
154d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(QINQ_INSERT),
155d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(VXLAN_TNL_TSO),
156d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(GRE_TNL_TSO),
157d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(IPIP_TNL_TSO),
158d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(GENEVE_TNL_TSO),
159d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(MACSEC_INSERT),
160d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(MT_LOCKFREE),
161d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(MULTI_SEGS),
162d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(MBUF_FAST_FREE),
163d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(SECURITY),
164d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(UDP_TNL_TSO),
165d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(IP_TNL_TSO),
166d30ea906Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM),
167*2d9fd380Sjfb8856606 	RTE_TX_OFFLOAD_BIT2STR(SEND_ON_TIMESTAMP),
168d30ea906Sjfb8856606 };
169d30ea906Sjfb8856606 
170d30ea906Sjfb8856606 #undef RTE_TX_OFFLOAD_BIT2STR
171d30ea906Sjfb8856606 
172d30ea906Sjfb8856606 /**
173d30ea906Sjfb8856606  * The user application callback description.
174d30ea906Sjfb8856606  *
175d30ea906Sjfb8856606  * It contains callback address to be registered by user application,
176d30ea906Sjfb8856606  * the pointer to the parameters for callback, and the event type.
177d30ea906Sjfb8856606  */
178d30ea906Sjfb8856606 struct rte_eth_dev_callback {
179d30ea906Sjfb8856606 	TAILQ_ENTRY(rte_eth_dev_callback) next; /**< Callbacks list */
180d30ea906Sjfb8856606 	rte_eth_dev_cb_fn cb_fn;                /**< Callback address */
181d30ea906Sjfb8856606 	void *cb_arg;                           /**< Parameter for callback */
182d30ea906Sjfb8856606 	void *ret_param;                        /**< Return parameter */
183d30ea906Sjfb8856606 	enum rte_eth_event_type event;          /**< Interrupt event type */
184d30ea906Sjfb8856606 	uint32_t active;                        /**< Callback is executing */
185d30ea906Sjfb8856606 };
186d30ea906Sjfb8856606 
187d30ea906Sjfb8856606 enum {
188d30ea906Sjfb8856606 	STAT_QMAP_TX = 0,
189d30ea906Sjfb8856606 	STAT_QMAP_RX
190d30ea906Sjfb8856606 };
191d30ea906Sjfb8856606 
192d30ea906Sjfb8856606 int
rte_eth_iterator_init(struct rte_dev_iterator * iter,const char * devargs_str)193d30ea906Sjfb8856606 rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
194d30ea906Sjfb8856606 {
195d30ea906Sjfb8856606 	int ret;
196d30ea906Sjfb8856606 	struct rte_devargs devargs = {.args = NULL};
197d30ea906Sjfb8856606 	const char *bus_param_key;
198d30ea906Sjfb8856606 	char *bus_str = NULL;
199d30ea906Sjfb8856606 	char *cls_str = NULL;
200d30ea906Sjfb8856606 	int str_size;
201d30ea906Sjfb8856606 
202d30ea906Sjfb8856606 	memset(iter, 0, sizeof(*iter));
203d30ea906Sjfb8856606 
204d30ea906Sjfb8856606 	/*
205d30ea906Sjfb8856606 	 * The devargs string may use various syntaxes:
206d30ea906Sjfb8856606 	 *   - 0000:08:00.0,representor=[1-3]
207d30ea906Sjfb8856606 	 *   - pci:0000:06:00.0,representor=[0,5]
208d30ea906Sjfb8856606 	 *   - class=eth,mac=00:11:22:33:44:55
209d30ea906Sjfb8856606 	 * A new syntax is in development (not yet supported):
210d30ea906Sjfb8856606 	 *   - bus=X,paramX=x/class=Y,paramY=y/driver=Z,paramZ=z
211d30ea906Sjfb8856606 	 */
212d30ea906Sjfb8856606 
213d30ea906Sjfb8856606 	/*
214d30ea906Sjfb8856606 	 * Handle pure class filter (i.e. without any bus-level argument),
215d30ea906Sjfb8856606 	 * from future new syntax.
216d30ea906Sjfb8856606 	 * rte_devargs_parse() is not yet supporting the new syntax,
217d30ea906Sjfb8856606 	 * that's why this simple case is temporarily parsed here.
218d30ea906Sjfb8856606 	 */
219d30ea906Sjfb8856606 #define iter_anybus_str "class=eth,"
220d30ea906Sjfb8856606 	if (strncmp(devargs_str, iter_anybus_str,
221d30ea906Sjfb8856606 			strlen(iter_anybus_str)) == 0) {
222d30ea906Sjfb8856606 		iter->cls_str = devargs_str + strlen(iter_anybus_str);
223d30ea906Sjfb8856606 		goto end;
224d30ea906Sjfb8856606 	}
225d30ea906Sjfb8856606 
226d30ea906Sjfb8856606 	/* Split bus, device and parameters. */
227d30ea906Sjfb8856606 	ret = rte_devargs_parse(&devargs, devargs_str);
228d30ea906Sjfb8856606 	if (ret != 0)
229d30ea906Sjfb8856606 		goto error;
230d30ea906Sjfb8856606 
231d30ea906Sjfb8856606 	/*
232d30ea906Sjfb8856606 	 * Assume parameters of old syntax can match only at ethdev level.
233d30ea906Sjfb8856606 	 * Extra parameters will be ignored, thanks to "+" prefix.
234d30ea906Sjfb8856606 	 */
235d30ea906Sjfb8856606 	str_size = strlen(devargs.args) + 2;
236d30ea906Sjfb8856606 	cls_str = malloc(str_size);
237d30ea906Sjfb8856606 	if (cls_str == NULL) {
238d30ea906Sjfb8856606 		ret = -ENOMEM;
239d30ea906Sjfb8856606 		goto error;
240d30ea906Sjfb8856606 	}
241d30ea906Sjfb8856606 	ret = snprintf(cls_str, str_size, "+%s", devargs.args);
242d30ea906Sjfb8856606 	if (ret != str_size - 1) {
243d30ea906Sjfb8856606 		ret = -EINVAL;
244d30ea906Sjfb8856606 		goto error;
245d30ea906Sjfb8856606 	}
246d30ea906Sjfb8856606 	iter->cls_str = cls_str;
247d30ea906Sjfb8856606 	free(devargs.args); /* allocated by rte_devargs_parse() */
248d30ea906Sjfb8856606 	devargs.args = NULL;
249d30ea906Sjfb8856606 
250d30ea906Sjfb8856606 	iter->bus = devargs.bus;
251d30ea906Sjfb8856606 	if (iter->bus->dev_iterate == NULL) {
252d30ea906Sjfb8856606 		ret = -ENOTSUP;
253d30ea906Sjfb8856606 		goto error;
254d30ea906Sjfb8856606 	}
255d30ea906Sjfb8856606 
256d30ea906Sjfb8856606 	/* Convert bus args to new syntax for use with new API dev_iterate. */
257d30ea906Sjfb8856606 	if (strcmp(iter->bus->name, "vdev") == 0) {
258d30ea906Sjfb8856606 		bus_param_key = "name";
259d30ea906Sjfb8856606 	} else if (strcmp(iter->bus->name, "pci") == 0) {
260d30ea906Sjfb8856606 		bus_param_key = "addr";
261d30ea906Sjfb8856606 	} else {
262d30ea906Sjfb8856606 		ret = -ENOTSUP;
263d30ea906Sjfb8856606 		goto error;
264d30ea906Sjfb8856606 	}
265d30ea906Sjfb8856606 	str_size = strlen(bus_param_key) + strlen(devargs.name) + 2;
266d30ea906Sjfb8856606 	bus_str = malloc(str_size);
267d30ea906Sjfb8856606 	if (bus_str == NULL) {
268d30ea906Sjfb8856606 		ret = -ENOMEM;
269d30ea906Sjfb8856606 		goto error;
270d30ea906Sjfb8856606 	}
271d30ea906Sjfb8856606 	ret = snprintf(bus_str, str_size, "%s=%s",
272d30ea906Sjfb8856606 			bus_param_key, devargs.name);
273d30ea906Sjfb8856606 	if (ret != str_size - 1) {
274d30ea906Sjfb8856606 		ret = -EINVAL;
275d30ea906Sjfb8856606 		goto error;
276d30ea906Sjfb8856606 	}
277d30ea906Sjfb8856606 	iter->bus_str = bus_str;
278d30ea906Sjfb8856606 
279d30ea906Sjfb8856606 end:
280d30ea906Sjfb8856606 	iter->cls = rte_class_find_by_name("eth");
281d30ea906Sjfb8856606 	return 0;
282d30ea906Sjfb8856606 
283d30ea906Sjfb8856606 error:
284d30ea906Sjfb8856606 	if (ret == -ENOTSUP)
2850c6bd470Sfengbojiang 		RTE_ETHDEV_LOG(ERR, "Bus %s does not support iterating.\n",
286d30ea906Sjfb8856606 				iter->bus->name);
287d30ea906Sjfb8856606 	free(devargs.args);
288d30ea906Sjfb8856606 	free(bus_str);
289d30ea906Sjfb8856606 	free(cls_str);
290d30ea906Sjfb8856606 	return ret;
291d30ea906Sjfb8856606 }
292d30ea906Sjfb8856606 
293d30ea906Sjfb8856606 uint16_t
rte_eth_iterator_next(struct rte_dev_iterator * iter)294d30ea906Sjfb8856606 rte_eth_iterator_next(struct rte_dev_iterator *iter)
295d30ea906Sjfb8856606 {
296d30ea906Sjfb8856606 	if (iter->cls == NULL) /* invalid ethdev iterator */
297d30ea906Sjfb8856606 		return RTE_MAX_ETHPORTS;
298d30ea906Sjfb8856606 
299d30ea906Sjfb8856606 	do { /* loop to try all matching rte_device */
300d30ea906Sjfb8856606 		/* If not pure ethdev filter and */
301d30ea906Sjfb8856606 		if (iter->bus != NULL &&
302d30ea906Sjfb8856606 				/* not in middle of rte_eth_dev iteration, */
303d30ea906Sjfb8856606 				iter->class_device == NULL) {
304d30ea906Sjfb8856606 			/* get next rte_device to try. */
305d30ea906Sjfb8856606 			iter->device = iter->bus->dev_iterate(
306d30ea906Sjfb8856606 					iter->device, iter->bus_str, iter);
307d30ea906Sjfb8856606 			if (iter->device == NULL)
308d30ea906Sjfb8856606 				break; /* no more rte_device candidate */
309d30ea906Sjfb8856606 		}
310d30ea906Sjfb8856606 		/* A device is matching bus part, need to check ethdev part. */
311d30ea906Sjfb8856606 		iter->class_device = iter->cls->dev_iterate(
312d30ea906Sjfb8856606 				iter->class_device, iter->cls_str, iter);
313d30ea906Sjfb8856606 		if (iter->class_device != NULL)
314d30ea906Sjfb8856606 			return eth_dev_to_id(iter->class_device); /* match */
315d30ea906Sjfb8856606 	} while (iter->bus != NULL); /* need to try next rte_device */
316d30ea906Sjfb8856606 
317d30ea906Sjfb8856606 	/* No more ethdev port to iterate. */
318d30ea906Sjfb8856606 	rte_eth_iterator_cleanup(iter);
319d30ea906Sjfb8856606 	return RTE_MAX_ETHPORTS;
320d30ea906Sjfb8856606 }
321d30ea906Sjfb8856606 
322d30ea906Sjfb8856606 void
rte_eth_iterator_cleanup(struct rte_dev_iterator * iter)323d30ea906Sjfb8856606 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
324d30ea906Sjfb8856606 {
325d30ea906Sjfb8856606 	if (iter->bus_str == NULL)
326d30ea906Sjfb8856606 		return; /* nothing to free in pure class filter */
327d30ea906Sjfb8856606 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
328d30ea906Sjfb8856606 	free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */
329d30ea906Sjfb8856606 	memset(iter, 0, sizeof(*iter));
330d30ea906Sjfb8856606 }
331d30ea906Sjfb8856606 
332d30ea906Sjfb8856606 uint16_t
rte_eth_find_next(uint16_t port_id)333d30ea906Sjfb8856606 rte_eth_find_next(uint16_t port_id)
334d30ea906Sjfb8856606 {
335d30ea906Sjfb8856606 	while (port_id < RTE_MAX_ETHPORTS &&
3364418919fSjohnjiang 			rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED)
337d30ea906Sjfb8856606 		port_id++;
338d30ea906Sjfb8856606 
339d30ea906Sjfb8856606 	if (port_id >= RTE_MAX_ETHPORTS)
340d30ea906Sjfb8856606 		return RTE_MAX_ETHPORTS;
341d30ea906Sjfb8856606 
342d30ea906Sjfb8856606 	return port_id;
343d30ea906Sjfb8856606 }
344d30ea906Sjfb8856606 
3454418919fSjohnjiang /*
3464418919fSjohnjiang  * Macro to iterate over all valid ports for internal usage.
3474418919fSjohnjiang  * Note: RTE_ETH_FOREACH_DEV is different because filtering owned ports.
3484418919fSjohnjiang  */
3494418919fSjohnjiang #define RTE_ETH_FOREACH_VALID_DEV(port_id) \
3504418919fSjohnjiang 	for (port_id = rte_eth_find_next(0); \
3514418919fSjohnjiang 	     port_id < RTE_MAX_ETHPORTS; \
3524418919fSjohnjiang 	     port_id = rte_eth_find_next(port_id + 1))
3534418919fSjohnjiang 
3544418919fSjohnjiang uint16_t
rte_eth_find_next_of(uint16_t port_id,const struct rte_device * parent)3554418919fSjohnjiang rte_eth_find_next_of(uint16_t port_id, const struct rte_device *parent)
3564418919fSjohnjiang {
3574418919fSjohnjiang 	port_id = rte_eth_find_next(port_id);
3584418919fSjohnjiang 	while (port_id < RTE_MAX_ETHPORTS &&
3594418919fSjohnjiang 			rte_eth_devices[port_id].device != parent)
3604418919fSjohnjiang 		port_id = rte_eth_find_next(port_id + 1);
3614418919fSjohnjiang 
3624418919fSjohnjiang 	return port_id;
3634418919fSjohnjiang }
3644418919fSjohnjiang 
3654418919fSjohnjiang uint16_t
rte_eth_find_next_sibling(uint16_t port_id,uint16_t ref_port_id)3664418919fSjohnjiang rte_eth_find_next_sibling(uint16_t port_id, uint16_t ref_port_id)
3674418919fSjohnjiang {
3684418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(ref_port_id, RTE_MAX_ETHPORTS);
3694418919fSjohnjiang 	return rte_eth_find_next_of(port_id,
3704418919fSjohnjiang 			rte_eth_devices[ref_port_id].device);
3714418919fSjohnjiang }
3724418919fSjohnjiang 
373d30ea906Sjfb8856606 static void
eth_dev_shared_data_prepare(void)374*2d9fd380Sjfb8856606 eth_dev_shared_data_prepare(void)
375d30ea906Sjfb8856606 {
376d30ea906Sjfb8856606 	const unsigned flags = 0;
377d30ea906Sjfb8856606 	const struct rte_memzone *mz;
378d30ea906Sjfb8856606 
379*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_shared_data_lock);
380d30ea906Sjfb8856606 
381*2d9fd380Sjfb8856606 	if (eth_dev_shared_data == NULL) {
382d30ea906Sjfb8856606 		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
383d30ea906Sjfb8856606 			/* Allocate port data and ownership shared memory. */
384d30ea906Sjfb8856606 			mz = rte_memzone_reserve(MZ_RTE_ETH_DEV_DATA,
385*2d9fd380Sjfb8856606 					sizeof(*eth_dev_shared_data),
386d30ea906Sjfb8856606 					rte_socket_id(), flags);
387d30ea906Sjfb8856606 		} else
388d30ea906Sjfb8856606 			mz = rte_memzone_lookup(MZ_RTE_ETH_DEV_DATA);
389d30ea906Sjfb8856606 		if (mz == NULL)
390d30ea906Sjfb8856606 			rte_panic("Cannot allocate ethdev shared data\n");
391d30ea906Sjfb8856606 
392*2d9fd380Sjfb8856606 		eth_dev_shared_data = mz->addr;
393d30ea906Sjfb8856606 		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
394*2d9fd380Sjfb8856606 			eth_dev_shared_data->next_owner_id =
395d30ea906Sjfb8856606 					RTE_ETH_DEV_NO_OWNER + 1;
396*2d9fd380Sjfb8856606 			rte_spinlock_init(&eth_dev_shared_data->ownership_lock);
397*2d9fd380Sjfb8856606 			memset(eth_dev_shared_data->data, 0,
398*2d9fd380Sjfb8856606 			       sizeof(eth_dev_shared_data->data));
399d30ea906Sjfb8856606 		}
400d30ea906Sjfb8856606 	}
401d30ea906Sjfb8856606 
402*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_shared_data_lock);
403d30ea906Sjfb8856606 }
404d30ea906Sjfb8856606 
405d30ea906Sjfb8856606 static bool
eth_dev_is_allocated(const struct rte_eth_dev * ethdev)406*2d9fd380Sjfb8856606 eth_dev_is_allocated(const struct rte_eth_dev *ethdev)
407d30ea906Sjfb8856606 {
408d30ea906Sjfb8856606 	return ethdev->data->name[0] != '\0';
409d30ea906Sjfb8856606 }
410d30ea906Sjfb8856606 
411d30ea906Sjfb8856606 static struct rte_eth_dev *
eth_dev_allocated(const char * name)412*2d9fd380Sjfb8856606 eth_dev_allocated(const char *name)
413d30ea906Sjfb8856606 {
4140c6bd470Sfengbojiang 	uint16_t i;
4150c6bd470Sfengbojiang 
4160c6bd470Sfengbojiang 	RTE_BUILD_BUG_ON(RTE_MAX_ETHPORTS >= UINT16_MAX);
417d30ea906Sjfb8856606 
418d30ea906Sjfb8856606 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
419d30ea906Sjfb8856606 		if (rte_eth_devices[i].data != NULL &&
420d30ea906Sjfb8856606 		    strcmp(rte_eth_devices[i].data->name, name) == 0)
421d30ea906Sjfb8856606 			return &rte_eth_devices[i];
422d30ea906Sjfb8856606 	}
423d30ea906Sjfb8856606 	return NULL;
424d30ea906Sjfb8856606 }
425d30ea906Sjfb8856606 
426d30ea906Sjfb8856606 struct rte_eth_dev *
rte_eth_dev_allocated(const char * name)427d30ea906Sjfb8856606 rte_eth_dev_allocated(const char *name)
428d30ea906Sjfb8856606 {
429d30ea906Sjfb8856606 	struct rte_eth_dev *ethdev;
430d30ea906Sjfb8856606 
431*2d9fd380Sjfb8856606 	eth_dev_shared_data_prepare();
432d30ea906Sjfb8856606 
433*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
434d30ea906Sjfb8856606 
435*2d9fd380Sjfb8856606 	ethdev = eth_dev_allocated(name);
436d30ea906Sjfb8856606 
437*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
438d30ea906Sjfb8856606 
439d30ea906Sjfb8856606 	return ethdev;
440d30ea906Sjfb8856606 }
441d30ea906Sjfb8856606 
442d30ea906Sjfb8856606 static uint16_t
eth_dev_find_free_port(void)443*2d9fd380Sjfb8856606 eth_dev_find_free_port(void)
444d30ea906Sjfb8856606 {
4450c6bd470Sfengbojiang 	uint16_t i;
446d30ea906Sjfb8856606 
447d30ea906Sjfb8856606 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
448d30ea906Sjfb8856606 		/* Using shared name field to find a free port. */
449*2d9fd380Sjfb8856606 		if (eth_dev_shared_data->data[i].name[0] == '\0') {
450d30ea906Sjfb8856606 			RTE_ASSERT(rte_eth_devices[i].state ==
451d30ea906Sjfb8856606 				   RTE_ETH_DEV_UNUSED);
452d30ea906Sjfb8856606 			return i;
453d30ea906Sjfb8856606 		}
454d30ea906Sjfb8856606 	}
455d30ea906Sjfb8856606 	return RTE_MAX_ETHPORTS;
456d30ea906Sjfb8856606 }
457d30ea906Sjfb8856606 
458d30ea906Sjfb8856606 static struct rte_eth_dev *
eth_dev_get(uint16_t port_id)459d30ea906Sjfb8856606 eth_dev_get(uint16_t port_id)
460d30ea906Sjfb8856606 {
461d30ea906Sjfb8856606 	struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id];
462d30ea906Sjfb8856606 
463*2d9fd380Sjfb8856606 	eth_dev->data = &eth_dev_shared_data->data[port_id];
464d30ea906Sjfb8856606 
465d30ea906Sjfb8856606 	return eth_dev;
466d30ea906Sjfb8856606 }
467d30ea906Sjfb8856606 
468d30ea906Sjfb8856606 struct rte_eth_dev *
rte_eth_dev_allocate(const char * name)469d30ea906Sjfb8856606 rte_eth_dev_allocate(const char *name)
470d30ea906Sjfb8856606 {
471d30ea906Sjfb8856606 	uint16_t port_id;
472d30ea906Sjfb8856606 	struct rte_eth_dev *eth_dev = NULL;
4734418919fSjohnjiang 	size_t name_len;
4744418919fSjohnjiang 
4754418919fSjohnjiang 	name_len = strnlen(name, RTE_ETH_NAME_MAX_LEN);
4764418919fSjohnjiang 	if (name_len == 0) {
4774418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR, "Zero length Ethernet device name\n");
4784418919fSjohnjiang 		return NULL;
4794418919fSjohnjiang 	}
4804418919fSjohnjiang 
4814418919fSjohnjiang 	if (name_len >= RTE_ETH_NAME_MAX_LEN) {
4824418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR, "Ethernet device name is too long\n");
4834418919fSjohnjiang 		return NULL;
4844418919fSjohnjiang 	}
485d30ea906Sjfb8856606 
486*2d9fd380Sjfb8856606 	eth_dev_shared_data_prepare();
487d30ea906Sjfb8856606 
488d30ea906Sjfb8856606 	/* Synchronize port creation between primary and secondary threads. */
489*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
490d30ea906Sjfb8856606 
491*2d9fd380Sjfb8856606 	if (eth_dev_allocated(name) != NULL) {
492d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
493d30ea906Sjfb8856606 			"Ethernet device with name %s already allocated\n",
494d30ea906Sjfb8856606 			name);
495d30ea906Sjfb8856606 		goto unlock;
496d30ea906Sjfb8856606 	}
497d30ea906Sjfb8856606 
498*2d9fd380Sjfb8856606 	port_id = eth_dev_find_free_port();
499d30ea906Sjfb8856606 	if (port_id == RTE_MAX_ETHPORTS) {
500d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
501d30ea906Sjfb8856606 			"Reached maximum number of Ethernet ports\n");
502d30ea906Sjfb8856606 		goto unlock;
503d30ea906Sjfb8856606 	}
504d30ea906Sjfb8856606 
505d30ea906Sjfb8856606 	eth_dev = eth_dev_get(port_id);
5064418919fSjohnjiang 	strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name));
507d30ea906Sjfb8856606 	eth_dev->data->port_id = port_id;
5084418919fSjohnjiang 	eth_dev->data->mtu = RTE_ETHER_MTU;
509*2d9fd380Sjfb8856606 	pthread_mutex_init(&eth_dev->data->flow_ops_mutex, NULL);
510d30ea906Sjfb8856606 
511d30ea906Sjfb8856606 unlock:
512*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
513d30ea906Sjfb8856606 
514d30ea906Sjfb8856606 	return eth_dev;
515d30ea906Sjfb8856606 }
516d30ea906Sjfb8856606 
517d30ea906Sjfb8856606 /*
518d30ea906Sjfb8856606  * Attach to a port already registered by the primary process, which
519d30ea906Sjfb8856606  * makes sure that the same device would have the same port id both
520d30ea906Sjfb8856606  * in the primary and secondary process.
521d30ea906Sjfb8856606  */
522d30ea906Sjfb8856606 struct rte_eth_dev *
rte_eth_dev_attach_secondary(const char * name)523d30ea906Sjfb8856606 rte_eth_dev_attach_secondary(const char *name)
524d30ea906Sjfb8856606 {
525d30ea906Sjfb8856606 	uint16_t i;
526d30ea906Sjfb8856606 	struct rte_eth_dev *eth_dev = NULL;
527d30ea906Sjfb8856606 
528*2d9fd380Sjfb8856606 	eth_dev_shared_data_prepare();
529d30ea906Sjfb8856606 
530d30ea906Sjfb8856606 	/* Synchronize port attachment to primary port creation and release. */
531*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
532d30ea906Sjfb8856606 
533d30ea906Sjfb8856606 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
534*2d9fd380Sjfb8856606 		if (strcmp(eth_dev_shared_data->data[i].name, name) == 0)
535d30ea906Sjfb8856606 			break;
536d30ea906Sjfb8856606 	}
537d30ea906Sjfb8856606 	if (i == RTE_MAX_ETHPORTS) {
538d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
539d30ea906Sjfb8856606 			"Device %s is not driven by the primary process\n",
540d30ea906Sjfb8856606 			name);
541d30ea906Sjfb8856606 	} else {
542d30ea906Sjfb8856606 		eth_dev = eth_dev_get(i);
543d30ea906Sjfb8856606 		RTE_ASSERT(eth_dev->data->port_id == i);
544d30ea906Sjfb8856606 	}
545d30ea906Sjfb8856606 
546*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
547d30ea906Sjfb8856606 	return eth_dev;
548d30ea906Sjfb8856606 }
549d30ea906Sjfb8856606 
550d30ea906Sjfb8856606 int
rte_eth_dev_release_port(struct rte_eth_dev * eth_dev)551d30ea906Sjfb8856606 rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
552d30ea906Sjfb8856606 {
553d30ea906Sjfb8856606 	if (eth_dev == NULL)
554d30ea906Sjfb8856606 		return -EINVAL;
555d30ea906Sjfb8856606 
556*2d9fd380Sjfb8856606 	eth_dev_shared_data_prepare();
557d30ea906Sjfb8856606 
558d30ea906Sjfb8856606 	if (eth_dev->state != RTE_ETH_DEV_UNUSED)
559*2d9fd380Sjfb8856606 		rte_eth_dev_callback_process(eth_dev,
560d30ea906Sjfb8856606 				RTE_ETH_EVENT_DESTROY, NULL);
561d30ea906Sjfb8856606 
562*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
563d30ea906Sjfb8856606 
564d30ea906Sjfb8856606 	eth_dev->state = RTE_ETH_DEV_UNUSED;
565*2d9fd380Sjfb8856606 	eth_dev->device = NULL;
566*2d9fd380Sjfb8856606 	eth_dev->process_private = NULL;
567*2d9fd380Sjfb8856606 	eth_dev->intr_handle = NULL;
568*2d9fd380Sjfb8856606 	eth_dev->rx_pkt_burst = NULL;
569*2d9fd380Sjfb8856606 	eth_dev->tx_pkt_burst = NULL;
570*2d9fd380Sjfb8856606 	eth_dev->tx_pkt_prepare = NULL;
571*2d9fd380Sjfb8856606 	eth_dev->rx_queue_count = NULL;
572*2d9fd380Sjfb8856606 	eth_dev->rx_descriptor_done = NULL;
573*2d9fd380Sjfb8856606 	eth_dev->rx_descriptor_status = NULL;
574*2d9fd380Sjfb8856606 	eth_dev->tx_descriptor_status = NULL;
575*2d9fd380Sjfb8856606 	eth_dev->dev_ops = NULL;
576d30ea906Sjfb8856606 
577d30ea906Sjfb8856606 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
578d30ea906Sjfb8856606 		rte_free(eth_dev->data->rx_queues);
579d30ea906Sjfb8856606 		rte_free(eth_dev->data->tx_queues);
580d30ea906Sjfb8856606 		rte_free(eth_dev->data->mac_addrs);
581d30ea906Sjfb8856606 		rte_free(eth_dev->data->hash_mac_addrs);
582d30ea906Sjfb8856606 		rte_free(eth_dev->data->dev_private);
583*2d9fd380Sjfb8856606 		pthread_mutex_destroy(&eth_dev->data->flow_ops_mutex);
584d30ea906Sjfb8856606 		memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data));
585d30ea906Sjfb8856606 	}
586d30ea906Sjfb8856606 
587*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
588d30ea906Sjfb8856606 
589d30ea906Sjfb8856606 	return 0;
590d30ea906Sjfb8856606 }
591d30ea906Sjfb8856606 
592d30ea906Sjfb8856606 int
rte_eth_dev_is_valid_port(uint16_t port_id)593d30ea906Sjfb8856606 rte_eth_dev_is_valid_port(uint16_t port_id)
594d30ea906Sjfb8856606 {
595d30ea906Sjfb8856606 	if (port_id >= RTE_MAX_ETHPORTS ||
596d30ea906Sjfb8856606 	    (rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED))
597d30ea906Sjfb8856606 		return 0;
598d30ea906Sjfb8856606 	else
599d30ea906Sjfb8856606 		return 1;
600d30ea906Sjfb8856606 }
601d30ea906Sjfb8856606 
602d30ea906Sjfb8856606 static int
eth_is_valid_owner_id(uint64_t owner_id)603*2d9fd380Sjfb8856606 eth_is_valid_owner_id(uint64_t owner_id)
604d30ea906Sjfb8856606 {
605d30ea906Sjfb8856606 	if (owner_id == RTE_ETH_DEV_NO_OWNER ||
606*2d9fd380Sjfb8856606 	    eth_dev_shared_data->next_owner_id <= owner_id)
607d30ea906Sjfb8856606 		return 0;
608d30ea906Sjfb8856606 	return 1;
609d30ea906Sjfb8856606 }
610d30ea906Sjfb8856606 
611d30ea906Sjfb8856606 uint64_t
rte_eth_find_next_owned_by(uint16_t port_id,const uint64_t owner_id)612d30ea906Sjfb8856606 rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
613d30ea906Sjfb8856606 {
6144418919fSjohnjiang 	port_id = rte_eth_find_next(port_id);
615d30ea906Sjfb8856606 	while (port_id < RTE_MAX_ETHPORTS &&
6164418919fSjohnjiang 			rte_eth_devices[port_id].data->owner.id != owner_id)
6174418919fSjohnjiang 		port_id = rte_eth_find_next(port_id + 1);
618d30ea906Sjfb8856606 
619d30ea906Sjfb8856606 	return port_id;
620d30ea906Sjfb8856606 }
621d30ea906Sjfb8856606 
6224418919fSjohnjiang int
rte_eth_dev_owner_new(uint64_t * owner_id)623d30ea906Sjfb8856606 rte_eth_dev_owner_new(uint64_t *owner_id)
624d30ea906Sjfb8856606 {
625*2d9fd380Sjfb8856606 	eth_dev_shared_data_prepare();
626d30ea906Sjfb8856606 
627*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
628d30ea906Sjfb8856606 
629*2d9fd380Sjfb8856606 	*owner_id = eth_dev_shared_data->next_owner_id++;
630d30ea906Sjfb8856606 
631*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
632d30ea906Sjfb8856606 	return 0;
633d30ea906Sjfb8856606 }
634d30ea906Sjfb8856606 
635d30ea906Sjfb8856606 static int
eth_dev_owner_set(const uint16_t port_id,const uint64_t old_owner_id,const struct rte_eth_dev_owner * new_owner)636*2d9fd380Sjfb8856606 eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
637d30ea906Sjfb8856606 		       const struct rte_eth_dev_owner *new_owner)
638d30ea906Sjfb8856606 {
639d30ea906Sjfb8856606 	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
640d30ea906Sjfb8856606 	struct rte_eth_dev_owner *port_owner;
641d30ea906Sjfb8856606 
642*2d9fd380Sjfb8856606 	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
643d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
644d30ea906Sjfb8856606 			port_id);
645d30ea906Sjfb8856606 		return -ENODEV;
646d30ea906Sjfb8856606 	}
647d30ea906Sjfb8856606 
648*2d9fd380Sjfb8856606 	if (!eth_is_valid_owner_id(new_owner->id) &&
649*2d9fd380Sjfb8856606 	    !eth_is_valid_owner_id(old_owner_id)) {
650d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
651d30ea906Sjfb8856606 			"Invalid owner old_id=%016"PRIx64" new_id=%016"PRIx64"\n",
652d30ea906Sjfb8856606 		       old_owner_id, new_owner->id);
653d30ea906Sjfb8856606 		return -EINVAL;
654d30ea906Sjfb8856606 	}
655d30ea906Sjfb8856606 
656d30ea906Sjfb8856606 	port_owner = &rte_eth_devices[port_id].data->owner;
657d30ea906Sjfb8856606 	if (port_owner->id != old_owner_id) {
658d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
659d30ea906Sjfb8856606 			"Cannot set owner to port %u already owned by %s_%016"PRIX64"\n",
660d30ea906Sjfb8856606 			port_id, port_owner->name, port_owner->id);
661d30ea906Sjfb8856606 		return -EPERM;
662d30ea906Sjfb8856606 	}
663d30ea906Sjfb8856606 
6644418919fSjohnjiang 	/* can not truncate (same structure) */
6654418919fSjohnjiang 	strlcpy(port_owner->name, new_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN);
666d30ea906Sjfb8856606 
667d30ea906Sjfb8856606 	port_owner->id = new_owner->id;
668d30ea906Sjfb8856606 
669d30ea906Sjfb8856606 	RTE_ETHDEV_LOG(DEBUG, "Port %u owner is %s_%016"PRIx64"\n",
670d30ea906Sjfb8856606 		port_id, new_owner->name, new_owner->id);
671d30ea906Sjfb8856606 
672d30ea906Sjfb8856606 	return 0;
673d30ea906Sjfb8856606 }
674d30ea906Sjfb8856606 
6754418919fSjohnjiang int
rte_eth_dev_owner_set(const uint16_t port_id,const struct rte_eth_dev_owner * owner)676d30ea906Sjfb8856606 rte_eth_dev_owner_set(const uint16_t port_id,
677d30ea906Sjfb8856606 		      const struct rte_eth_dev_owner *owner)
678d30ea906Sjfb8856606 {
679d30ea906Sjfb8856606 	int ret;
680d30ea906Sjfb8856606 
681*2d9fd380Sjfb8856606 	eth_dev_shared_data_prepare();
682d30ea906Sjfb8856606 
683*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
684d30ea906Sjfb8856606 
685*2d9fd380Sjfb8856606 	ret = eth_dev_owner_set(port_id, RTE_ETH_DEV_NO_OWNER, owner);
686d30ea906Sjfb8856606 
687*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
688d30ea906Sjfb8856606 	return ret;
689d30ea906Sjfb8856606 }
690d30ea906Sjfb8856606 
6914418919fSjohnjiang int
rte_eth_dev_owner_unset(const uint16_t port_id,const uint64_t owner_id)692d30ea906Sjfb8856606 rte_eth_dev_owner_unset(const uint16_t port_id, const uint64_t owner_id)
693d30ea906Sjfb8856606 {
694d30ea906Sjfb8856606 	const struct rte_eth_dev_owner new_owner = (struct rte_eth_dev_owner)
695d30ea906Sjfb8856606 			{.id = RTE_ETH_DEV_NO_OWNER, .name = ""};
696d30ea906Sjfb8856606 	int ret;
697d30ea906Sjfb8856606 
698*2d9fd380Sjfb8856606 	eth_dev_shared_data_prepare();
699d30ea906Sjfb8856606 
700*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
701d30ea906Sjfb8856606 
702*2d9fd380Sjfb8856606 	ret = eth_dev_owner_set(port_id, owner_id, &new_owner);
703d30ea906Sjfb8856606 
704*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
705d30ea906Sjfb8856606 	return ret;
706d30ea906Sjfb8856606 }
707d30ea906Sjfb8856606 
7084418919fSjohnjiang int
rte_eth_dev_owner_delete(const uint64_t owner_id)709d30ea906Sjfb8856606 rte_eth_dev_owner_delete(const uint64_t owner_id)
710d30ea906Sjfb8856606 {
711d30ea906Sjfb8856606 	uint16_t port_id;
7124418919fSjohnjiang 	int ret = 0;
713d30ea906Sjfb8856606 
714*2d9fd380Sjfb8856606 	eth_dev_shared_data_prepare();
715d30ea906Sjfb8856606 
716*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
717d30ea906Sjfb8856606 
718*2d9fd380Sjfb8856606 	if (eth_is_valid_owner_id(owner_id)) {
719d30ea906Sjfb8856606 		for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
720d30ea906Sjfb8856606 			if (rte_eth_devices[port_id].data->owner.id == owner_id)
721d30ea906Sjfb8856606 				memset(&rte_eth_devices[port_id].data->owner, 0,
722d30ea906Sjfb8856606 				       sizeof(struct rte_eth_dev_owner));
723d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(NOTICE,
724d30ea906Sjfb8856606 			"All port owners owned by %016"PRIx64" identifier have removed\n",
725d30ea906Sjfb8856606 			owner_id);
726d30ea906Sjfb8856606 	} else {
727d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
728d30ea906Sjfb8856606 			       "Invalid owner id=%016"PRIx64"\n",
729d30ea906Sjfb8856606 			       owner_id);
7304418919fSjohnjiang 		ret = -EINVAL;
731d30ea906Sjfb8856606 	}
732d30ea906Sjfb8856606 
733*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
7344418919fSjohnjiang 
7354418919fSjohnjiang 	return ret;
736d30ea906Sjfb8856606 }
737d30ea906Sjfb8856606 
7384418919fSjohnjiang int
rte_eth_dev_owner_get(const uint16_t port_id,struct rte_eth_dev_owner * owner)739d30ea906Sjfb8856606 rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
740d30ea906Sjfb8856606 {
741d30ea906Sjfb8856606 	int ret = 0;
742d30ea906Sjfb8856606 	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
743d30ea906Sjfb8856606 
744*2d9fd380Sjfb8856606 	eth_dev_shared_data_prepare();
745d30ea906Sjfb8856606 
746*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
747d30ea906Sjfb8856606 
748*2d9fd380Sjfb8856606 	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
749d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
750d30ea906Sjfb8856606 			port_id);
751d30ea906Sjfb8856606 		ret = -ENODEV;
752d30ea906Sjfb8856606 	} else {
753d30ea906Sjfb8856606 		rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
754d30ea906Sjfb8856606 	}
755d30ea906Sjfb8856606 
756*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
757d30ea906Sjfb8856606 	return ret;
758d30ea906Sjfb8856606 }
759d30ea906Sjfb8856606 
760d30ea906Sjfb8856606 int
rte_eth_dev_socket_id(uint16_t port_id)761d30ea906Sjfb8856606 rte_eth_dev_socket_id(uint16_t port_id)
762d30ea906Sjfb8856606 {
763d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
764d30ea906Sjfb8856606 	return rte_eth_devices[port_id].data->numa_node;
765d30ea906Sjfb8856606 }
766d30ea906Sjfb8856606 
767d30ea906Sjfb8856606 void *
rte_eth_dev_get_sec_ctx(uint16_t port_id)768d30ea906Sjfb8856606 rte_eth_dev_get_sec_ctx(uint16_t port_id)
769d30ea906Sjfb8856606 {
770d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
771d30ea906Sjfb8856606 	return rte_eth_devices[port_id].security_ctx;
772d30ea906Sjfb8856606 }
773d30ea906Sjfb8856606 
774d30ea906Sjfb8856606 uint16_t
rte_eth_dev_count_avail(void)775d30ea906Sjfb8856606 rte_eth_dev_count_avail(void)
776d30ea906Sjfb8856606 {
777d30ea906Sjfb8856606 	uint16_t p;
778d30ea906Sjfb8856606 	uint16_t count;
779d30ea906Sjfb8856606 
780d30ea906Sjfb8856606 	count = 0;
781d30ea906Sjfb8856606 
782d30ea906Sjfb8856606 	RTE_ETH_FOREACH_DEV(p)
783d30ea906Sjfb8856606 		count++;
784d30ea906Sjfb8856606 
785d30ea906Sjfb8856606 	return count;
786d30ea906Sjfb8856606 }
787d30ea906Sjfb8856606 
7884418919fSjohnjiang uint16_t
rte_eth_dev_count_total(void)789d30ea906Sjfb8856606 rte_eth_dev_count_total(void)
790d30ea906Sjfb8856606 {
791d30ea906Sjfb8856606 	uint16_t port, count = 0;
792d30ea906Sjfb8856606 
7934418919fSjohnjiang 	RTE_ETH_FOREACH_VALID_DEV(port)
794d30ea906Sjfb8856606 		count++;
795d30ea906Sjfb8856606 
796d30ea906Sjfb8856606 	return count;
797d30ea906Sjfb8856606 }
798d30ea906Sjfb8856606 
799d30ea906Sjfb8856606 int
rte_eth_dev_get_name_by_port(uint16_t port_id,char * name)800d30ea906Sjfb8856606 rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
801d30ea906Sjfb8856606 {
802d30ea906Sjfb8856606 	char *tmp;
803d30ea906Sjfb8856606 
804*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
805d30ea906Sjfb8856606 
806d30ea906Sjfb8856606 	if (name == NULL) {
807d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
808d30ea906Sjfb8856606 		return -EINVAL;
809d30ea906Sjfb8856606 	}
810d30ea906Sjfb8856606 
811d30ea906Sjfb8856606 	/* shouldn't check 'rte_eth_devices[i].data',
812d30ea906Sjfb8856606 	 * because it might be overwritten by VDEV PMD */
813*2d9fd380Sjfb8856606 	tmp = eth_dev_shared_data->data[port_id].name;
814d30ea906Sjfb8856606 	strcpy(name, tmp);
815d30ea906Sjfb8856606 	return 0;
816d30ea906Sjfb8856606 }
817d30ea906Sjfb8856606 
818d30ea906Sjfb8856606 int
rte_eth_dev_get_port_by_name(const char * name,uint16_t * port_id)819d30ea906Sjfb8856606 rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
820d30ea906Sjfb8856606 {
8210c6bd470Sfengbojiang 	uint16_t pid;
822d30ea906Sjfb8856606 
823d30ea906Sjfb8856606 	if (name == NULL) {
824d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
825d30ea906Sjfb8856606 		return -EINVAL;
826d30ea906Sjfb8856606 	}
827d30ea906Sjfb8856606 
8284418919fSjohnjiang 	RTE_ETH_FOREACH_VALID_DEV(pid)
829*2d9fd380Sjfb8856606 		if (!strcmp(name, eth_dev_shared_data->data[pid].name)) {
830d30ea906Sjfb8856606 			*port_id = pid;
831d30ea906Sjfb8856606 			return 0;
832d30ea906Sjfb8856606 		}
833d30ea906Sjfb8856606 
834d30ea906Sjfb8856606 	return -ENODEV;
835d30ea906Sjfb8856606 }
836d30ea906Sjfb8856606 
837d30ea906Sjfb8856606 static int
eth_err(uint16_t port_id,int ret)838d30ea906Sjfb8856606 eth_err(uint16_t port_id, int ret)
839d30ea906Sjfb8856606 {
840d30ea906Sjfb8856606 	if (ret == 0)
841d30ea906Sjfb8856606 		return 0;
842d30ea906Sjfb8856606 	if (rte_eth_dev_is_removed(port_id))
843d30ea906Sjfb8856606 		return -EIO;
844d30ea906Sjfb8856606 	return ret;
845d30ea906Sjfb8856606 }
846d30ea906Sjfb8856606 
847d30ea906Sjfb8856606 static int
eth_dev_rx_queue_config(struct rte_eth_dev * dev,uint16_t nb_queues)848*2d9fd380Sjfb8856606 eth_dev_rx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
849d30ea906Sjfb8856606 {
850d30ea906Sjfb8856606 	uint16_t old_nb_queues = dev->data->nb_rx_queues;
851d30ea906Sjfb8856606 	void **rxq;
852d30ea906Sjfb8856606 	unsigned i;
853d30ea906Sjfb8856606 
854d30ea906Sjfb8856606 	if (dev->data->rx_queues == NULL && nb_queues != 0) { /* first time configuration */
855d30ea906Sjfb8856606 		dev->data->rx_queues = rte_zmalloc("ethdev->rx_queues",
856d30ea906Sjfb8856606 				sizeof(dev->data->rx_queues[0]) * nb_queues,
857d30ea906Sjfb8856606 				RTE_CACHE_LINE_SIZE);
858d30ea906Sjfb8856606 		if (dev->data->rx_queues == NULL) {
859d30ea906Sjfb8856606 			dev->data->nb_rx_queues = 0;
860d30ea906Sjfb8856606 			return -(ENOMEM);
861d30ea906Sjfb8856606 		}
862d30ea906Sjfb8856606 	} else if (dev->data->rx_queues != NULL && nb_queues != 0) { /* re-configure */
863d30ea906Sjfb8856606 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_release, -ENOTSUP);
864d30ea906Sjfb8856606 
865d30ea906Sjfb8856606 		rxq = dev->data->rx_queues;
866d30ea906Sjfb8856606 
867d30ea906Sjfb8856606 		for (i = nb_queues; i < old_nb_queues; i++)
868d30ea906Sjfb8856606 			(*dev->dev_ops->rx_queue_release)(rxq[i]);
869d30ea906Sjfb8856606 		rxq = rte_realloc(rxq, sizeof(rxq[0]) * nb_queues,
870d30ea906Sjfb8856606 				RTE_CACHE_LINE_SIZE);
871d30ea906Sjfb8856606 		if (rxq == NULL)
872d30ea906Sjfb8856606 			return -(ENOMEM);
873d30ea906Sjfb8856606 		if (nb_queues > old_nb_queues) {
874d30ea906Sjfb8856606 			uint16_t new_qs = nb_queues - old_nb_queues;
875d30ea906Sjfb8856606 
876d30ea906Sjfb8856606 			memset(rxq + old_nb_queues, 0,
877d30ea906Sjfb8856606 				sizeof(rxq[0]) * new_qs);
878d30ea906Sjfb8856606 		}
879d30ea906Sjfb8856606 
880d30ea906Sjfb8856606 		dev->data->rx_queues = rxq;
881d30ea906Sjfb8856606 
882d30ea906Sjfb8856606 	} else if (dev->data->rx_queues != NULL && nb_queues == 0) {
883d30ea906Sjfb8856606 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_release, -ENOTSUP);
884d30ea906Sjfb8856606 
885d30ea906Sjfb8856606 		rxq = dev->data->rx_queues;
886d30ea906Sjfb8856606 
887d30ea906Sjfb8856606 		for (i = nb_queues; i < old_nb_queues; i++)
888d30ea906Sjfb8856606 			(*dev->dev_ops->rx_queue_release)(rxq[i]);
889d30ea906Sjfb8856606 
890d30ea906Sjfb8856606 		rte_free(dev->data->rx_queues);
891d30ea906Sjfb8856606 		dev->data->rx_queues = NULL;
892d30ea906Sjfb8856606 	}
893d30ea906Sjfb8856606 	dev->data->nb_rx_queues = nb_queues;
894d30ea906Sjfb8856606 	return 0;
895d30ea906Sjfb8856606 }
896d30ea906Sjfb8856606 
897*2d9fd380Sjfb8856606 static int
eth_dev_validate_rx_queue(const struct rte_eth_dev * dev,uint16_t rx_queue_id)898*2d9fd380Sjfb8856606 eth_dev_validate_rx_queue(const struct rte_eth_dev *dev, uint16_t rx_queue_id)
899*2d9fd380Sjfb8856606 {
900*2d9fd380Sjfb8856606 	uint16_t port_id;
901*2d9fd380Sjfb8856606 
902*2d9fd380Sjfb8856606 	if (rx_queue_id >= dev->data->nb_rx_queues) {
903*2d9fd380Sjfb8856606 		port_id = dev->data->port_id;
904*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
905*2d9fd380Sjfb8856606 			       "Invalid Rx queue_id=%u of device with port_id=%u\n",
906*2d9fd380Sjfb8856606 			       rx_queue_id, port_id);
907*2d9fd380Sjfb8856606 		return -EINVAL;
908*2d9fd380Sjfb8856606 	}
909*2d9fd380Sjfb8856606 
910*2d9fd380Sjfb8856606 	if (dev->data->rx_queues[rx_queue_id] == NULL) {
911*2d9fd380Sjfb8856606 		port_id = dev->data->port_id;
912*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
913*2d9fd380Sjfb8856606 			       "Queue %u of device with port_id=%u has not been setup\n",
914*2d9fd380Sjfb8856606 			       rx_queue_id, port_id);
915*2d9fd380Sjfb8856606 		return -EINVAL;
916*2d9fd380Sjfb8856606 	}
917*2d9fd380Sjfb8856606 
918*2d9fd380Sjfb8856606 	return 0;
919*2d9fd380Sjfb8856606 }
920*2d9fd380Sjfb8856606 
921*2d9fd380Sjfb8856606 static int
eth_dev_validate_tx_queue(const struct rte_eth_dev * dev,uint16_t tx_queue_id)922*2d9fd380Sjfb8856606 eth_dev_validate_tx_queue(const struct rte_eth_dev *dev, uint16_t tx_queue_id)
923*2d9fd380Sjfb8856606 {
924*2d9fd380Sjfb8856606 	uint16_t port_id;
925*2d9fd380Sjfb8856606 
926*2d9fd380Sjfb8856606 	if (tx_queue_id >= dev->data->nb_tx_queues) {
927*2d9fd380Sjfb8856606 		port_id = dev->data->port_id;
928*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
929*2d9fd380Sjfb8856606 			       "Invalid Tx queue_id=%u of device with port_id=%u\n",
930*2d9fd380Sjfb8856606 			       tx_queue_id, port_id);
931*2d9fd380Sjfb8856606 		return -EINVAL;
932*2d9fd380Sjfb8856606 	}
933*2d9fd380Sjfb8856606 
934*2d9fd380Sjfb8856606 	if (dev->data->tx_queues[tx_queue_id] == NULL) {
935*2d9fd380Sjfb8856606 		port_id = dev->data->port_id;
936*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
937*2d9fd380Sjfb8856606 			       "Queue %u of device with port_id=%u has not been setup\n",
938*2d9fd380Sjfb8856606 			       tx_queue_id, port_id);
939*2d9fd380Sjfb8856606 		return -EINVAL;
940*2d9fd380Sjfb8856606 	}
941*2d9fd380Sjfb8856606 
942*2d9fd380Sjfb8856606 	return 0;
943*2d9fd380Sjfb8856606 }
944*2d9fd380Sjfb8856606 
945d30ea906Sjfb8856606 int
rte_eth_dev_rx_queue_start(uint16_t port_id,uint16_t rx_queue_id)946d30ea906Sjfb8856606 rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id)
947d30ea906Sjfb8856606 {
948d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
949*2d9fd380Sjfb8856606 	int ret;
950d30ea906Sjfb8856606 
951*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
952d30ea906Sjfb8856606 
953d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
954d30ea906Sjfb8856606 	if (!dev->data->dev_started) {
955d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
956d30ea906Sjfb8856606 			"Port %u must be started before start any queue\n",
957d30ea906Sjfb8856606 			port_id);
958d30ea906Sjfb8856606 		return -EINVAL;
959d30ea906Sjfb8856606 	}
960d30ea906Sjfb8856606 
961*2d9fd380Sjfb8856606 	ret = eth_dev_validate_rx_queue(dev, rx_queue_id);
962*2d9fd380Sjfb8856606 	if (ret != 0)
963*2d9fd380Sjfb8856606 		return ret;
964d30ea906Sjfb8856606 
965d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_start, -ENOTSUP);
966d30ea906Sjfb8856606 
9674418919fSjohnjiang 	if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) {
9684418919fSjohnjiang 		RTE_ETHDEV_LOG(INFO,
9694418919fSjohnjiang 			"Can't start Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
9704418919fSjohnjiang 			rx_queue_id, port_id);
9714418919fSjohnjiang 		return -EINVAL;
9724418919fSjohnjiang 	}
9734418919fSjohnjiang 
974d30ea906Sjfb8856606 	if (dev->data->rx_queue_state[rx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) {
975d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(INFO,
976d30ea906Sjfb8856606 			"Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n",
977d30ea906Sjfb8856606 			rx_queue_id, port_id);
978d30ea906Sjfb8856606 		return 0;
979d30ea906Sjfb8856606 	}
980d30ea906Sjfb8856606 
981d30ea906Sjfb8856606 	return eth_err(port_id, dev->dev_ops->rx_queue_start(dev,
982d30ea906Sjfb8856606 							     rx_queue_id));
983d30ea906Sjfb8856606 
984d30ea906Sjfb8856606 }
985d30ea906Sjfb8856606 
986d30ea906Sjfb8856606 int
rte_eth_dev_rx_queue_stop(uint16_t port_id,uint16_t rx_queue_id)987d30ea906Sjfb8856606 rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id)
988d30ea906Sjfb8856606 {
989d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
990*2d9fd380Sjfb8856606 	int ret;
991d30ea906Sjfb8856606 
992*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
993d30ea906Sjfb8856606 
994d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
995*2d9fd380Sjfb8856606 
996*2d9fd380Sjfb8856606 	ret = eth_dev_validate_rx_queue(dev, rx_queue_id);
997*2d9fd380Sjfb8856606 	if (ret != 0)
998*2d9fd380Sjfb8856606 		return ret;
999d30ea906Sjfb8856606 
1000d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_stop, -ENOTSUP);
1001d30ea906Sjfb8856606 
10024418919fSjohnjiang 	if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) {
10034418919fSjohnjiang 		RTE_ETHDEV_LOG(INFO,
10044418919fSjohnjiang 			"Can't stop Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
10054418919fSjohnjiang 			rx_queue_id, port_id);
10064418919fSjohnjiang 		return -EINVAL;
10074418919fSjohnjiang 	}
10084418919fSjohnjiang 
1009d30ea906Sjfb8856606 	if (dev->data->rx_queue_state[rx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) {
1010d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(INFO,
1011d30ea906Sjfb8856606 			"Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n",
1012d30ea906Sjfb8856606 			rx_queue_id, port_id);
1013d30ea906Sjfb8856606 		return 0;
1014d30ea906Sjfb8856606 	}
1015d30ea906Sjfb8856606 
1016d30ea906Sjfb8856606 	return eth_err(port_id, dev->dev_ops->rx_queue_stop(dev, rx_queue_id));
1017d30ea906Sjfb8856606 
1018d30ea906Sjfb8856606 }
1019d30ea906Sjfb8856606 
1020d30ea906Sjfb8856606 int
rte_eth_dev_tx_queue_start(uint16_t port_id,uint16_t tx_queue_id)1021d30ea906Sjfb8856606 rte_eth_dev_tx_queue_start(uint16_t port_id, uint16_t tx_queue_id)
1022d30ea906Sjfb8856606 {
1023d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
1024*2d9fd380Sjfb8856606 	int ret;
1025d30ea906Sjfb8856606 
1026*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1027d30ea906Sjfb8856606 
1028d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
1029d30ea906Sjfb8856606 	if (!dev->data->dev_started) {
1030d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
1031d30ea906Sjfb8856606 			"Port %u must be started before start any queue\n",
1032d30ea906Sjfb8856606 			port_id);
1033d30ea906Sjfb8856606 		return -EINVAL;
1034d30ea906Sjfb8856606 	}
1035d30ea906Sjfb8856606 
1036*2d9fd380Sjfb8856606 	ret = eth_dev_validate_tx_queue(dev, tx_queue_id);
1037*2d9fd380Sjfb8856606 	if (ret != 0)
1038*2d9fd380Sjfb8856606 		return ret;
1039d30ea906Sjfb8856606 
1040d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_start, -ENOTSUP);
1041d30ea906Sjfb8856606 
10424418919fSjohnjiang 	if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) {
10434418919fSjohnjiang 		RTE_ETHDEV_LOG(INFO,
10444418919fSjohnjiang 			"Can't start Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
10454418919fSjohnjiang 			tx_queue_id, port_id);
10464418919fSjohnjiang 		return -EINVAL;
10474418919fSjohnjiang 	}
10484418919fSjohnjiang 
1049d30ea906Sjfb8856606 	if (dev->data->tx_queue_state[tx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) {
1050d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(INFO,
1051d30ea906Sjfb8856606 			"Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n",
1052d30ea906Sjfb8856606 			tx_queue_id, port_id);
1053d30ea906Sjfb8856606 		return 0;
1054d30ea906Sjfb8856606 	}
1055d30ea906Sjfb8856606 
1056d30ea906Sjfb8856606 	return eth_err(port_id, dev->dev_ops->tx_queue_start(dev, tx_queue_id));
1057d30ea906Sjfb8856606 }
1058d30ea906Sjfb8856606 
1059d30ea906Sjfb8856606 int
rte_eth_dev_tx_queue_stop(uint16_t port_id,uint16_t tx_queue_id)1060d30ea906Sjfb8856606 rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id)
1061d30ea906Sjfb8856606 {
1062d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
1063*2d9fd380Sjfb8856606 	int ret;
1064d30ea906Sjfb8856606 
1065*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1066d30ea906Sjfb8856606 
1067d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
1068*2d9fd380Sjfb8856606 
1069*2d9fd380Sjfb8856606 	ret = eth_dev_validate_tx_queue(dev, tx_queue_id);
1070*2d9fd380Sjfb8856606 	if (ret != 0)
1071*2d9fd380Sjfb8856606 		return ret;
1072d30ea906Sjfb8856606 
1073d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_stop, -ENOTSUP);
1074d30ea906Sjfb8856606 
10754418919fSjohnjiang 	if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) {
10764418919fSjohnjiang 		RTE_ETHDEV_LOG(INFO,
10774418919fSjohnjiang 			"Can't stop Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
10784418919fSjohnjiang 			tx_queue_id, port_id);
10794418919fSjohnjiang 		return -EINVAL;
10804418919fSjohnjiang 	}
10814418919fSjohnjiang 
1082d30ea906Sjfb8856606 	if (dev->data->tx_queue_state[tx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) {
1083d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(INFO,
1084d30ea906Sjfb8856606 			"Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n",
1085d30ea906Sjfb8856606 			tx_queue_id, port_id);
1086d30ea906Sjfb8856606 		return 0;
1087d30ea906Sjfb8856606 	}
1088d30ea906Sjfb8856606 
1089d30ea906Sjfb8856606 	return eth_err(port_id, dev->dev_ops->tx_queue_stop(dev, tx_queue_id));
1090d30ea906Sjfb8856606 
1091d30ea906Sjfb8856606 }
1092d30ea906Sjfb8856606 
1093d30ea906Sjfb8856606 static int
eth_dev_tx_queue_config(struct rte_eth_dev * dev,uint16_t nb_queues)1094*2d9fd380Sjfb8856606 eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
1095d30ea906Sjfb8856606 {
1096d30ea906Sjfb8856606 	uint16_t old_nb_queues = dev->data->nb_tx_queues;
1097d30ea906Sjfb8856606 	void **txq;
1098d30ea906Sjfb8856606 	unsigned i;
1099d30ea906Sjfb8856606 
1100d30ea906Sjfb8856606 	if (dev->data->tx_queues == NULL && nb_queues != 0) { /* first time configuration */
1101d30ea906Sjfb8856606 		dev->data->tx_queues = rte_zmalloc("ethdev->tx_queues",
1102d30ea906Sjfb8856606 						   sizeof(dev->data->tx_queues[0]) * nb_queues,
1103d30ea906Sjfb8856606 						   RTE_CACHE_LINE_SIZE);
1104d30ea906Sjfb8856606 		if (dev->data->tx_queues == NULL) {
1105d30ea906Sjfb8856606 			dev->data->nb_tx_queues = 0;
1106d30ea906Sjfb8856606 			return -(ENOMEM);
1107d30ea906Sjfb8856606 		}
1108d30ea906Sjfb8856606 	} else if (dev->data->tx_queues != NULL && nb_queues != 0) { /* re-configure */
1109d30ea906Sjfb8856606 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_release, -ENOTSUP);
1110d30ea906Sjfb8856606 
1111d30ea906Sjfb8856606 		txq = dev->data->tx_queues;
1112d30ea906Sjfb8856606 
1113d30ea906Sjfb8856606 		for (i = nb_queues; i < old_nb_queues; i++)
1114d30ea906Sjfb8856606 			(*dev->dev_ops->tx_queue_release)(txq[i]);
1115d30ea906Sjfb8856606 		txq = rte_realloc(txq, sizeof(txq[0]) * nb_queues,
1116d30ea906Sjfb8856606 				  RTE_CACHE_LINE_SIZE);
1117d30ea906Sjfb8856606 		if (txq == NULL)
1118d30ea906Sjfb8856606 			return -ENOMEM;
1119d30ea906Sjfb8856606 		if (nb_queues > old_nb_queues) {
1120d30ea906Sjfb8856606 			uint16_t new_qs = nb_queues - old_nb_queues;
1121d30ea906Sjfb8856606 
1122d30ea906Sjfb8856606 			memset(txq + old_nb_queues, 0,
1123d30ea906Sjfb8856606 			       sizeof(txq[0]) * new_qs);
1124d30ea906Sjfb8856606 		}
1125d30ea906Sjfb8856606 
1126d30ea906Sjfb8856606 		dev->data->tx_queues = txq;
1127d30ea906Sjfb8856606 
1128d30ea906Sjfb8856606 	} else if (dev->data->tx_queues != NULL && nb_queues == 0) {
1129d30ea906Sjfb8856606 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_release, -ENOTSUP);
1130d30ea906Sjfb8856606 
1131d30ea906Sjfb8856606 		txq = dev->data->tx_queues;
1132d30ea906Sjfb8856606 
1133d30ea906Sjfb8856606 		for (i = nb_queues; i < old_nb_queues; i++)
1134d30ea906Sjfb8856606 			(*dev->dev_ops->tx_queue_release)(txq[i]);
1135d30ea906Sjfb8856606 
1136d30ea906Sjfb8856606 		rte_free(dev->data->tx_queues);
1137d30ea906Sjfb8856606 		dev->data->tx_queues = NULL;
1138d30ea906Sjfb8856606 	}
1139d30ea906Sjfb8856606 	dev->data->nb_tx_queues = nb_queues;
1140d30ea906Sjfb8856606 	return 0;
1141d30ea906Sjfb8856606 }
1142d30ea906Sjfb8856606 
1143d30ea906Sjfb8856606 uint32_t
rte_eth_speed_bitflag(uint32_t speed,int duplex)1144d30ea906Sjfb8856606 rte_eth_speed_bitflag(uint32_t speed, int duplex)
1145d30ea906Sjfb8856606 {
1146d30ea906Sjfb8856606 	switch (speed) {
1147d30ea906Sjfb8856606 	case ETH_SPEED_NUM_10M:
1148d30ea906Sjfb8856606 		return duplex ? ETH_LINK_SPEED_10M : ETH_LINK_SPEED_10M_HD;
1149d30ea906Sjfb8856606 	case ETH_SPEED_NUM_100M:
1150d30ea906Sjfb8856606 		return duplex ? ETH_LINK_SPEED_100M : ETH_LINK_SPEED_100M_HD;
1151d30ea906Sjfb8856606 	case ETH_SPEED_NUM_1G:
1152d30ea906Sjfb8856606 		return ETH_LINK_SPEED_1G;
1153d30ea906Sjfb8856606 	case ETH_SPEED_NUM_2_5G:
1154d30ea906Sjfb8856606 		return ETH_LINK_SPEED_2_5G;
1155d30ea906Sjfb8856606 	case ETH_SPEED_NUM_5G:
1156d30ea906Sjfb8856606 		return ETH_LINK_SPEED_5G;
1157d30ea906Sjfb8856606 	case ETH_SPEED_NUM_10G:
1158d30ea906Sjfb8856606 		return ETH_LINK_SPEED_10G;
1159d30ea906Sjfb8856606 	case ETH_SPEED_NUM_20G:
1160d30ea906Sjfb8856606 		return ETH_LINK_SPEED_20G;
1161d30ea906Sjfb8856606 	case ETH_SPEED_NUM_25G:
1162d30ea906Sjfb8856606 		return ETH_LINK_SPEED_25G;
1163d30ea906Sjfb8856606 	case ETH_SPEED_NUM_40G:
1164d30ea906Sjfb8856606 		return ETH_LINK_SPEED_40G;
1165d30ea906Sjfb8856606 	case ETH_SPEED_NUM_50G:
1166d30ea906Sjfb8856606 		return ETH_LINK_SPEED_50G;
1167d30ea906Sjfb8856606 	case ETH_SPEED_NUM_56G:
1168d30ea906Sjfb8856606 		return ETH_LINK_SPEED_56G;
1169d30ea906Sjfb8856606 	case ETH_SPEED_NUM_100G:
1170d30ea906Sjfb8856606 		return ETH_LINK_SPEED_100G;
1171*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_200G:
1172*2d9fd380Sjfb8856606 		return ETH_LINK_SPEED_200G;
1173d30ea906Sjfb8856606 	default:
1174d30ea906Sjfb8856606 		return 0;
1175d30ea906Sjfb8856606 	}
1176d30ea906Sjfb8856606 }
1177d30ea906Sjfb8856606 
1178d30ea906Sjfb8856606 const char *
rte_eth_dev_rx_offload_name(uint64_t offload)1179d30ea906Sjfb8856606 rte_eth_dev_rx_offload_name(uint64_t offload)
1180d30ea906Sjfb8856606 {
1181d30ea906Sjfb8856606 	const char *name = "UNKNOWN";
1182d30ea906Sjfb8856606 	unsigned int i;
1183d30ea906Sjfb8856606 
1184*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(eth_dev_rx_offload_names); ++i) {
1185*2d9fd380Sjfb8856606 		if (offload == eth_dev_rx_offload_names[i].offload) {
1186*2d9fd380Sjfb8856606 			name = eth_dev_rx_offload_names[i].name;
1187d30ea906Sjfb8856606 			break;
1188d30ea906Sjfb8856606 		}
1189d30ea906Sjfb8856606 	}
1190d30ea906Sjfb8856606 
1191d30ea906Sjfb8856606 	return name;
1192d30ea906Sjfb8856606 }
1193d30ea906Sjfb8856606 
1194d30ea906Sjfb8856606 const char *
rte_eth_dev_tx_offload_name(uint64_t offload)1195d30ea906Sjfb8856606 rte_eth_dev_tx_offload_name(uint64_t offload)
1196d30ea906Sjfb8856606 {
1197d30ea906Sjfb8856606 	const char *name = "UNKNOWN";
1198d30ea906Sjfb8856606 	unsigned int i;
1199d30ea906Sjfb8856606 
1200*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(eth_dev_tx_offload_names); ++i) {
1201*2d9fd380Sjfb8856606 		if (offload == eth_dev_tx_offload_names[i].offload) {
1202*2d9fd380Sjfb8856606 			name = eth_dev_tx_offload_names[i].name;
1203d30ea906Sjfb8856606 			break;
1204d30ea906Sjfb8856606 		}
1205d30ea906Sjfb8856606 	}
1206d30ea906Sjfb8856606 
1207d30ea906Sjfb8856606 	return name;
1208d30ea906Sjfb8856606 }
1209d30ea906Sjfb8856606 
12104418919fSjohnjiang static inline int
eth_dev_check_lro_pkt_size(uint16_t port_id,uint32_t config_size,uint32_t max_rx_pkt_len,uint32_t dev_info_size)1211*2d9fd380Sjfb8856606 eth_dev_check_lro_pkt_size(uint16_t port_id, uint32_t config_size,
12124418919fSjohnjiang 		   uint32_t max_rx_pkt_len, uint32_t dev_info_size)
12134418919fSjohnjiang {
12144418919fSjohnjiang 	int ret = 0;
12154418919fSjohnjiang 
12164418919fSjohnjiang 	if (dev_info_size == 0) {
12174418919fSjohnjiang 		if (config_size != max_rx_pkt_len) {
12184418919fSjohnjiang 			RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size"
12194418919fSjohnjiang 				       " %u != %u is not allowed\n",
12204418919fSjohnjiang 				       port_id, config_size, max_rx_pkt_len);
12214418919fSjohnjiang 			ret = -EINVAL;
12224418919fSjohnjiang 		}
12234418919fSjohnjiang 	} else if (config_size > dev_info_size) {
12244418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size %u "
12254418919fSjohnjiang 			       "> max allowed value %u\n", port_id, config_size,
12264418919fSjohnjiang 			       dev_info_size);
12274418919fSjohnjiang 		ret = -EINVAL;
12284418919fSjohnjiang 	} else if (config_size < RTE_ETHER_MIN_LEN) {
12294418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%d max_lro_pkt_size %u "
12304418919fSjohnjiang 			       "< min allowed value %u\n", port_id, config_size,
12314418919fSjohnjiang 			       (unsigned int)RTE_ETHER_MIN_LEN);
12324418919fSjohnjiang 		ret = -EINVAL;
12334418919fSjohnjiang 	}
12344418919fSjohnjiang 	return ret;
12354418919fSjohnjiang }
12364418919fSjohnjiang 
12374418919fSjohnjiang /*
12384418919fSjohnjiang  * Validate offloads that are requested through rte_eth_dev_configure against
12390c6bd470Sfengbojiang  * the offloads successfully set by the ethernet device.
12404418919fSjohnjiang  *
12414418919fSjohnjiang  * @param port_id
12424418919fSjohnjiang  *   The port identifier of the Ethernet device.
12434418919fSjohnjiang  * @param req_offloads
12444418919fSjohnjiang  *   The offloads that have been requested through `rte_eth_dev_configure`.
12454418919fSjohnjiang  * @param set_offloads
12460c6bd470Sfengbojiang  *   The offloads successfully set by the ethernet device.
12474418919fSjohnjiang  * @param offload_type
12484418919fSjohnjiang  *   The offload type i.e. Rx/Tx string.
12494418919fSjohnjiang  * @param offload_name
12504418919fSjohnjiang  *   The function that prints the offload name.
12514418919fSjohnjiang  * @return
12524418919fSjohnjiang  *   - (0) if validation successful.
12534418919fSjohnjiang  *   - (-EINVAL) if requested offload has been silently disabled.
12544418919fSjohnjiang  *
12554418919fSjohnjiang  */
12564418919fSjohnjiang static int
eth_dev_validate_offloads(uint16_t port_id,uint64_t req_offloads,uint64_t set_offloads,const char * offload_type,const char * (* offload_name)(uint64_t))1257*2d9fd380Sjfb8856606 eth_dev_validate_offloads(uint16_t port_id, uint64_t req_offloads,
12584418919fSjohnjiang 		  uint64_t set_offloads, const char *offload_type,
12594418919fSjohnjiang 		  const char *(*offload_name)(uint64_t))
12604418919fSjohnjiang {
12614418919fSjohnjiang 	uint64_t offloads_diff = req_offloads ^ set_offloads;
12624418919fSjohnjiang 	uint64_t offload;
12634418919fSjohnjiang 	int ret = 0;
12644418919fSjohnjiang 
12654418919fSjohnjiang 	while (offloads_diff != 0) {
12664418919fSjohnjiang 		/* Check if any offload is requested but not enabled. */
12674418919fSjohnjiang 		offload = 1ULL << __builtin_ctzll(offloads_diff);
12684418919fSjohnjiang 		if (offload & req_offloads) {
12694418919fSjohnjiang 			RTE_ETHDEV_LOG(ERR,
12704418919fSjohnjiang 				"Port %u failed to enable %s offload %s\n",
12714418919fSjohnjiang 				port_id, offload_type, offload_name(offload));
12724418919fSjohnjiang 			ret = -EINVAL;
12734418919fSjohnjiang 		}
12744418919fSjohnjiang 
12750c6bd470Sfengbojiang 		/* Check if offload couldn't be disabled. */
12764418919fSjohnjiang 		if (offload & set_offloads) {
12774418919fSjohnjiang 			RTE_ETHDEV_LOG(DEBUG,
12784418919fSjohnjiang 				"Port %u %s offload %s is not requested but enabled\n",
12794418919fSjohnjiang 				port_id, offload_type, offload_name(offload));
12804418919fSjohnjiang 		}
12814418919fSjohnjiang 
12824418919fSjohnjiang 		offloads_diff &= ~offload;
12834418919fSjohnjiang 	}
12844418919fSjohnjiang 
12854418919fSjohnjiang 	return ret;
12864418919fSjohnjiang }
12874418919fSjohnjiang 
1288d30ea906Sjfb8856606 int
rte_eth_dev_configure(uint16_t port_id,uint16_t nb_rx_q,uint16_t nb_tx_q,const struct rte_eth_conf * dev_conf)1289d30ea906Sjfb8856606 rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
1290d30ea906Sjfb8856606 		      const struct rte_eth_conf *dev_conf)
1291d30ea906Sjfb8856606 {
1292d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
1293d30ea906Sjfb8856606 	struct rte_eth_dev_info dev_info;
1294d30ea906Sjfb8856606 	struct rte_eth_conf orig_conf;
1295d30ea906Sjfb8856606 	int diag;
1296d30ea906Sjfb8856606 	int ret;
1297d30ea906Sjfb8856606 
1298*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1299d30ea906Sjfb8856606 
1300d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
1301d30ea906Sjfb8856606 
1302d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
1303d30ea906Sjfb8856606 
1304d30ea906Sjfb8856606 	if (dev->data->dev_started) {
1305d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
1306d30ea906Sjfb8856606 			"Port %u must be stopped to allow configuration\n",
1307d30ea906Sjfb8856606 			port_id);
1308d30ea906Sjfb8856606 		return -EBUSY;
1309d30ea906Sjfb8856606 	}
1310d30ea906Sjfb8856606 
1311d30ea906Sjfb8856606 	 /* Store original config, as rollback required on failure */
1312d30ea906Sjfb8856606 	memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf));
1313d30ea906Sjfb8856606 
1314d30ea906Sjfb8856606 	/*
1315d30ea906Sjfb8856606 	 * Copy the dev_conf parameter into the dev structure.
1316d30ea906Sjfb8856606 	 * rte_eth_dev_info_get() requires dev_conf, copy it before dev_info get
1317d30ea906Sjfb8856606 	 */
13184418919fSjohnjiang 	if (dev_conf != &dev->data->dev_conf)
13194418919fSjohnjiang 		memcpy(&dev->data->dev_conf, dev_conf,
13204418919fSjohnjiang 		       sizeof(dev->data->dev_conf));
1321d30ea906Sjfb8856606 
13224418919fSjohnjiang 	ret = rte_eth_dev_info_get(port_id, &dev_info);
13234418919fSjohnjiang 	if (ret != 0)
13244418919fSjohnjiang 		goto rollback;
1325d30ea906Sjfb8856606 
1326d30ea906Sjfb8856606 	/* If number of queues specified by application for both Rx and Tx is
1327d30ea906Sjfb8856606 	 * zero, use driver preferred values. This cannot be done individually
1328d30ea906Sjfb8856606 	 * as it is valid for either Tx or Rx (but not both) to be zero.
1329d30ea906Sjfb8856606 	 * If driver does not provide any preferred valued, fall back on
1330d30ea906Sjfb8856606 	 * EAL defaults.
1331d30ea906Sjfb8856606 	 */
1332d30ea906Sjfb8856606 	if (nb_rx_q == 0 && nb_tx_q == 0) {
1333d30ea906Sjfb8856606 		nb_rx_q = dev_info.default_rxportconf.nb_queues;
1334d30ea906Sjfb8856606 		if (nb_rx_q == 0)
1335d30ea906Sjfb8856606 			nb_rx_q = RTE_ETH_DEV_FALLBACK_RX_NBQUEUES;
1336d30ea906Sjfb8856606 		nb_tx_q = dev_info.default_txportconf.nb_queues;
1337d30ea906Sjfb8856606 		if (nb_tx_q == 0)
1338d30ea906Sjfb8856606 			nb_tx_q = RTE_ETH_DEV_FALLBACK_TX_NBQUEUES;
1339d30ea906Sjfb8856606 	}
1340d30ea906Sjfb8856606 
1341d30ea906Sjfb8856606 	if (nb_rx_q > RTE_MAX_QUEUES_PER_PORT) {
1342d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
1343d30ea906Sjfb8856606 			"Number of RX queues requested (%u) is greater than max supported(%d)\n",
1344d30ea906Sjfb8856606 			nb_rx_q, RTE_MAX_QUEUES_PER_PORT);
1345d30ea906Sjfb8856606 		ret = -EINVAL;
1346d30ea906Sjfb8856606 		goto rollback;
1347d30ea906Sjfb8856606 	}
1348d30ea906Sjfb8856606 
1349d30ea906Sjfb8856606 	if (nb_tx_q > RTE_MAX_QUEUES_PER_PORT) {
1350d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
1351d30ea906Sjfb8856606 			"Number of TX queues requested (%u) is greater than max supported(%d)\n",
1352d30ea906Sjfb8856606 			nb_tx_q, RTE_MAX_QUEUES_PER_PORT);
1353d30ea906Sjfb8856606 		ret = -EINVAL;
1354d30ea906Sjfb8856606 		goto rollback;
1355d30ea906Sjfb8856606 	}
1356d30ea906Sjfb8856606 
1357d30ea906Sjfb8856606 	/*
1358d30ea906Sjfb8856606 	 * Check that the numbers of RX and TX queues are not greater
1359d30ea906Sjfb8856606 	 * than the maximum number of RX and TX queues supported by the
1360d30ea906Sjfb8856606 	 * configured device.
1361d30ea906Sjfb8856606 	 */
1362d30ea906Sjfb8856606 	if (nb_rx_q > dev_info.max_rx_queues) {
1363d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_rx_queues=%u > %u\n",
1364d30ea906Sjfb8856606 			port_id, nb_rx_q, dev_info.max_rx_queues);
1365d30ea906Sjfb8856606 		ret = -EINVAL;
1366d30ea906Sjfb8856606 		goto rollback;
1367d30ea906Sjfb8856606 	}
1368d30ea906Sjfb8856606 
1369d30ea906Sjfb8856606 	if (nb_tx_q > dev_info.max_tx_queues) {
1370d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_tx_queues=%u > %u\n",
1371d30ea906Sjfb8856606 			port_id, nb_tx_q, dev_info.max_tx_queues);
1372d30ea906Sjfb8856606 		ret = -EINVAL;
1373d30ea906Sjfb8856606 		goto rollback;
1374d30ea906Sjfb8856606 	}
1375d30ea906Sjfb8856606 
1376d30ea906Sjfb8856606 	/* Check that the device supports requested interrupts */
1377d30ea906Sjfb8856606 	if ((dev_conf->intr_conf.lsc == 1) &&
1378d30ea906Sjfb8856606 			(!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) {
1379d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Driver %s does not support lsc\n",
1380d30ea906Sjfb8856606 			dev->device->driver->name);
1381d30ea906Sjfb8856606 		ret = -EINVAL;
1382d30ea906Sjfb8856606 		goto rollback;
1383d30ea906Sjfb8856606 	}
1384d30ea906Sjfb8856606 	if ((dev_conf->intr_conf.rmv == 1) &&
1385d30ea906Sjfb8856606 			(!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) {
1386d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Driver %s does not support rmv\n",
1387d30ea906Sjfb8856606 			dev->device->driver->name);
1388d30ea906Sjfb8856606 		ret = -EINVAL;
1389d30ea906Sjfb8856606 		goto rollback;
1390d30ea906Sjfb8856606 	}
1391d30ea906Sjfb8856606 
1392d30ea906Sjfb8856606 	/*
1393d30ea906Sjfb8856606 	 * If jumbo frames are enabled, check that the maximum RX packet
1394d30ea906Sjfb8856606 	 * length is supported by the configured device.
1395d30ea906Sjfb8856606 	 */
1396d30ea906Sjfb8856606 	if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
1397d30ea906Sjfb8856606 		if (dev_conf->rxmode.max_rx_pkt_len > dev_info.max_rx_pktlen) {
1398d30ea906Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
1399d30ea906Sjfb8856606 				"Ethdev port_id=%u max_rx_pkt_len %u > max valid value %u\n",
1400d30ea906Sjfb8856606 				port_id, dev_conf->rxmode.max_rx_pkt_len,
1401d30ea906Sjfb8856606 				dev_info.max_rx_pktlen);
1402d30ea906Sjfb8856606 			ret = -EINVAL;
1403d30ea906Sjfb8856606 			goto rollback;
14044418919fSjohnjiang 		} else if (dev_conf->rxmode.max_rx_pkt_len < RTE_ETHER_MIN_LEN) {
1405d30ea906Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
1406d30ea906Sjfb8856606 				"Ethdev port_id=%u max_rx_pkt_len %u < min valid value %u\n",
1407d30ea906Sjfb8856606 				port_id, dev_conf->rxmode.max_rx_pkt_len,
14084418919fSjohnjiang 				(unsigned int)RTE_ETHER_MIN_LEN);
1409d30ea906Sjfb8856606 			ret = -EINVAL;
1410d30ea906Sjfb8856606 			goto rollback;
1411d30ea906Sjfb8856606 		}
1412d30ea906Sjfb8856606 	} else {
14134418919fSjohnjiang 		if (dev_conf->rxmode.max_rx_pkt_len < RTE_ETHER_MIN_LEN ||
14144418919fSjohnjiang 			dev_conf->rxmode.max_rx_pkt_len > RTE_ETHER_MAX_LEN)
1415d30ea906Sjfb8856606 			/* Use default value */
1416d30ea906Sjfb8856606 			dev->data->dev_conf.rxmode.max_rx_pkt_len =
14174418919fSjohnjiang 							RTE_ETHER_MAX_LEN;
14184418919fSjohnjiang 	}
14194418919fSjohnjiang 
14204418919fSjohnjiang 	/*
14214418919fSjohnjiang 	 * If LRO is enabled, check that the maximum aggregated packet
14224418919fSjohnjiang 	 * size is supported by the configured device.
14234418919fSjohnjiang 	 */
14244418919fSjohnjiang 	if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO) {
14254418919fSjohnjiang 		if (dev_conf->rxmode.max_lro_pkt_size == 0)
14264418919fSjohnjiang 			dev->data->dev_conf.rxmode.max_lro_pkt_size =
14274418919fSjohnjiang 				dev->data->dev_conf.rxmode.max_rx_pkt_len;
1428*2d9fd380Sjfb8856606 		ret = eth_dev_check_lro_pkt_size(port_id,
14294418919fSjohnjiang 				dev->data->dev_conf.rxmode.max_lro_pkt_size,
14304418919fSjohnjiang 				dev->data->dev_conf.rxmode.max_rx_pkt_len,
14314418919fSjohnjiang 				dev_info.max_lro_pkt_size);
14324418919fSjohnjiang 		if (ret != 0)
14334418919fSjohnjiang 			goto rollback;
1434d30ea906Sjfb8856606 	}
1435d30ea906Sjfb8856606 
1436d30ea906Sjfb8856606 	/* Any requested offloading must be within its device capabilities */
1437d30ea906Sjfb8856606 	if ((dev_conf->rxmode.offloads & dev_info.rx_offload_capa) !=
1438d30ea906Sjfb8856606 	     dev_conf->rxmode.offloads) {
1439d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
1440d30ea906Sjfb8856606 			"Ethdev port_id=%u requested Rx offloads 0x%"PRIx64" doesn't match Rx offloads "
1441d30ea906Sjfb8856606 			"capabilities 0x%"PRIx64" in %s()\n",
1442d30ea906Sjfb8856606 			port_id, dev_conf->rxmode.offloads,
1443d30ea906Sjfb8856606 			dev_info.rx_offload_capa,
1444d30ea906Sjfb8856606 			__func__);
1445d30ea906Sjfb8856606 		ret = -EINVAL;
1446d30ea906Sjfb8856606 		goto rollback;
1447d30ea906Sjfb8856606 	}
1448d30ea906Sjfb8856606 	if ((dev_conf->txmode.offloads & dev_info.tx_offload_capa) !=
1449d30ea906Sjfb8856606 	     dev_conf->txmode.offloads) {
1450d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
1451d30ea906Sjfb8856606 			"Ethdev port_id=%u requested Tx offloads 0x%"PRIx64" doesn't match Tx offloads "
1452d30ea906Sjfb8856606 			"capabilities 0x%"PRIx64" in %s()\n",
1453d30ea906Sjfb8856606 			port_id, dev_conf->txmode.offloads,
1454d30ea906Sjfb8856606 			dev_info.tx_offload_capa,
1455d30ea906Sjfb8856606 			__func__);
1456d30ea906Sjfb8856606 		ret = -EINVAL;
1457d30ea906Sjfb8856606 		goto rollback;
1458d30ea906Sjfb8856606 	}
1459d30ea906Sjfb8856606 
14604418919fSjohnjiang 	dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf =
14614418919fSjohnjiang 		rte_eth_rss_hf_refine(dev_conf->rx_adv_conf.rss_conf.rss_hf);
14624418919fSjohnjiang 
1463d30ea906Sjfb8856606 	/* Check that device supports requested rss hash functions. */
1464d30ea906Sjfb8856606 	if ((dev_info.flow_type_rss_offloads |
1465d30ea906Sjfb8856606 	     dev_conf->rx_adv_conf.rss_conf.rss_hf) !=
1466d30ea906Sjfb8856606 	    dev_info.flow_type_rss_offloads) {
1467d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
1468d30ea906Sjfb8856606 			"Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n",
1469d30ea906Sjfb8856606 			port_id, dev_conf->rx_adv_conf.rss_conf.rss_hf,
1470d30ea906Sjfb8856606 			dev_info.flow_type_rss_offloads);
1471d30ea906Sjfb8856606 		ret = -EINVAL;
1472d30ea906Sjfb8856606 		goto rollback;
1473d30ea906Sjfb8856606 	}
1474d30ea906Sjfb8856606 
14754418919fSjohnjiang 	/* Check if Rx RSS distribution is disabled but RSS hash is enabled. */
14764418919fSjohnjiang 	if (((dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) == 0) &&
14774418919fSjohnjiang 	    (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_RSS_HASH)) {
14784418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR,
14794418919fSjohnjiang 			"Ethdev port_id=%u config invalid Rx mq_mode without RSS but %s offload is requested\n",
14804418919fSjohnjiang 			port_id,
14814418919fSjohnjiang 			rte_eth_dev_rx_offload_name(DEV_RX_OFFLOAD_RSS_HASH));
14824418919fSjohnjiang 		ret = -EINVAL;
14834418919fSjohnjiang 		goto rollback;
14844418919fSjohnjiang 	}
14854418919fSjohnjiang 
1486d30ea906Sjfb8856606 	/*
1487d30ea906Sjfb8856606 	 * Setup new number of RX/TX queues and reconfigure device.
1488d30ea906Sjfb8856606 	 */
1489*2d9fd380Sjfb8856606 	diag = eth_dev_rx_queue_config(dev, nb_rx_q);
1490d30ea906Sjfb8856606 	if (diag != 0) {
1491d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
1492*2d9fd380Sjfb8856606 			"Port%u eth_dev_rx_queue_config = %d\n",
1493d30ea906Sjfb8856606 			port_id, diag);
1494d30ea906Sjfb8856606 		ret = diag;
1495d30ea906Sjfb8856606 		goto rollback;
1496d30ea906Sjfb8856606 	}
1497d30ea906Sjfb8856606 
1498*2d9fd380Sjfb8856606 	diag = eth_dev_tx_queue_config(dev, nb_tx_q);
1499d30ea906Sjfb8856606 	if (diag != 0) {
1500d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
1501*2d9fd380Sjfb8856606 			"Port%u eth_dev_tx_queue_config = %d\n",
1502d30ea906Sjfb8856606 			port_id, diag);
1503*2d9fd380Sjfb8856606 		eth_dev_rx_queue_config(dev, 0);
1504d30ea906Sjfb8856606 		ret = diag;
1505d30ea906Sjfb8856606 		goto rollback;
1506d30ea906Sjfb8856606 	}
1507d30ea906Sjfb8856606 
1508d30ea906Sjfb8856606 	diag = (*dev->dev_ops->dev_configure)(dev);
1509d30ea906Sjfb8856606 	if (diag != 0) {
1510d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Port%u dev_configure = %d\n",
1511d30ea906Sjfb8856606 			port_id, diag);
1512d30ea906Sjfb8856606 		ret = eth_err(port_id, diag);
15134418919fSjohnjiang 		goto reset_queues;
1514d30ea906Sjfb8856606 	}
1515d30ea906Sjfb8856606 
1516d30ea906Sjfb8856606 	/* Initialize Rx profiling if enabled at compilation time. */
1517d30ea906Sjfb8856606 	diag = __rte_eth_dev_profile_init(port_id, dev);
1518d30ea906Sjfb8856606 	if (diag != 0) {
1519d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Port%u __rte_eth_dev_profile_init = %d\n",
1520d30ea906Sjfb8856606 			port_id, diag);
1521d30ea906Sjfb8856606 		ret = eth_err(port_id, diag);
15224418919fSjohnjiang 		goto reset_queues;
15234418919fSjohnjiang 	}
15244418919fSjohnjiang 
15254418919fSjohnjiang 	/* Validate Rx offloads. */
1526*2d9fd380Sjfb8856606 	diag = eth_dev_validate_offloads(port_id,
15274418919fSjohnjiang 			dev_conf->rxmode.offloads,
15284418919fSjohnjiang 			dev->data->dev_conf.rxmode.offloads, "Rx",
15294418919fSjohnjiang 			rte_eth_dev_rx_offload_name);
15304418919fSjohnjiang 	if (diag != 0) {
15314418919fSjohnjiang 		ret = diag;
15324418919fSjohnjiang 		goto reset_queues;
15334418919fSjohnjiang 	}
15344418919fSjohnjiang 
15354418919fSjohnjiang 	/* Validate Tx offloads. */
1536*2d9fd380Sjfb8856606 	diag = eth_dev_validate_offloads(port_id,
15374418919fSjohnjiang 			dev_conf->txmode.offloads,
15384418919fSjohnjiang 			dev->data->dev_conf.txmode.offloads, "Tx",
15394418919fSjohnjiang 			rte_eth_dev_tx_offload_name);
15404418919fSjohnjiang 	if (diag != 0) {
15414418919fSjohnjiang 		ret = diag;
15424418919fSjohnjiang 		goto reset_queues;
1543d30ea906Sjfb8856606 	}
1544d30ea906Sjfb8856606 
1545*2d9fd380Sjfb8856606 	rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, 0);
1546d30ea906Sjfb8856606 	return 0;
15474418919fSjohnjiang reset_queues:
1548*2d9fd380Sjfb8856606 	eth_dev_rx_queue_config(dev, 0);
1549*2d9fd380Sjfb8856606 	eth_dev_tx_queue_config(dev, 0);
1550d30ea906Sjfb8856606 rollback:
1551d30ea906Sjfb8856606 	memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf));
1552d30ea906Sjfb8856606 
1553*2d9fd380Sjfb8856606 	rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, ret);
1554d30ea906Sjfb8856606 	return ret;
1555d30ea906Sjfb8856606 }
1556d30ea906Sjfb8856606 
1557d30ea906Sjfb8856606 void
rte_eth_dev_internal_reset(struct rte_eth_dev * dev)1558*2d9fd380Sjfb8856606 rte_eth_dev_internal_reset(struct rte_eth_dev *dev)
1559d30ea906Sjfb8856606 {
1560d30ea906Sjfb8856606 	if (dev->data->dev_started) {
1561d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Port %u must be stopped to allow reset\n",
1562d30ea906Sjfb8856606 			dev->data->port_id);
1563d30ea906Sjfb8856606 		return;
1564d30ea906Sjfb8856606 	}
1565d30ea906Sjfb8856606 
1566*2d9fd380Sjfb8856606 	eth_dev_rx_queue_config(dev, 0);
1567*2d9fd380Sjfb8856606 	eth_dev_tx_queue_config(dev, 0);
1568d30ea906Sjfb8856606 
1569d30ea906Sjfb8856606 	memset(&dev->data->dev_conf, 0, sizeof(dev->data->dev_conf));
1570d30ea906Sjfb8856606 }
1571d30ea906Sjfb8856606 
1572d30ea906Sjfb8856606 static void
eth_dev_mac_restore(struct rte_eth_dev * dev,struct rte_eth_dev_info * dev_info)1573*2d9fd380Sjfb8856606 eth_dev_mac_restore(struct rte_eth_dev *dev,
1574d30ea906Sjfb8856606 			struct rte_eth_dev_info *dev_info)
1575d30ea906Sjfb8856606 {
15764418919fSjohnjiang 	struct rte_ether_addr *addr;
1577d30ea906Sjfb8856606 	uint16_t i;
1578d30ea906Sjfb8856606 	uint32_t pool = 0;
1579d30ea906Sjfb8856606 	uint64_t pool_mask;
1580d30ea906Sjfb8856606 
1581d30ea906Sjfb8856606 	/* replay MAC address configuration including default MAC */
1582d30ea906Sjfb8856606 	addr = &dev->data->mac_addrs[0];
1583d30ea906Sjfb8856606 	if (*dev->dev_ops->mac_addr_set != NULL)
1584d30ea906Sjfb8856606 		(*dev->dev_ops->mac_addr_set)(dev, addr);
1585d30ea906Sjfb8856606 	else if (*dev->dev_ops->mac_addr_add != NULL)
1586d30ea906Sjfb8856606 		(*dev->dev_ops->mac_addr_add)(dev, addr, 0, pool);
1587d30ea906Sjfb8856606 
1588d30ea906Sjfb8856606 	if (*dev->dev_ops->mac_addr_add != NULL) {
1589d30ea906Sjfb8856606 		for (i = 1; i < dev_info->max_mac_addrs; i++) {
1590d30ea906Sjfb8856606 			addr = &dev->data->mac_addrs[i];
1591d30ea906Sjfb8856606 
1592d30ea906Sjfb8856606 			/* skip zero address */
15934418919fSjohnjiang 			if (rte_is_zero_ether_addr(addr))
1594d30ea906Sjfb8856606 				continue;
1595d30ea906Sjfb8856606 
1596d30ea906Sjfb8856606 			pool = 0;
1597d30ea906Sjfb8856606 			pool_mask = dev->data->mac_pool_sel[i];
1598d30ea906Sjfb8856606 
1599d30ea906Sjfb8856606 			do {
1600d30ea906Sjfb8856606 				if (pool_mask & 1ULL)
1601d30ea906Sjfb8856606 					(*dev->dev_ops->mac_addr_add)(dev,
1602d30ea906Sjfb8856606 						addr, i, pool);
1603d30ea906Sjfb8856606 				pool_mask >>= 1;
1604d30ea906Sjfb8856606 				pool++;
1605d30ea906Sjfb8856606 			} while (pool_mask);
1606d30ea906Sjfb8856606 		}
1607d30ea906Sjfb8856606 	}
1608d30ea906Sjfb8856606 }
1609d30ea906Sjfb8856606 
16104418919fSjohnjiang static int
eth_dev_config_restore(struct rte_eth_dev * dev,struct rte_eth_dev_info * dev_info,uint16_t port_id)1611*2d9fd380Sjfb8856606 eth_dev_config_restore(struct rte_eth_dev *dev,
1612d30ea906Sjfb8856606 		struct rte_eth_dev_info *dev_info, uint16_t port_id)
1613d30ea906Sjfb8856606 {
16144418919fSjohnjiang 	int ret;
16154418919fSjohnjiang 
1616d30ea906Sjfb8856606 	if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR))
1617*2d9fd380Sjfb8856606 		eth_dev_mac_restore(dev, dev_info);
1618d30ea906Sjfb8856606 
1619d30ea906Sjfb8856606 	/* replay promiscuous configuration */
16204418919fSjohnjiang 	/*
16214418919fSjohnjiang 	 * use callbacks directly since we don't need port_id check and
16224418919fSjohnjiang 	 * would like to bypass the same value set
16234418919fSjohnjiang 	 */
16244418919fSjohnjiang 	if (rte_eth_promiscuous_get(port_id) == 1 &&
16254418919fSjohnjiang 	    *dev->dev_ops->promiscuous_enable != NULL) {
16264418919fSjohnjiang 		ret = eth_err(port_id,
16274418919fSjohnjiang 			      (*dev->dev_ops->promiscuous_enable)(dev));
16284418919fSjohnjiang 		if (ret != 0 && ret != -ENOTSUP) {
16294418919fSjohnjiang 			RTE_ETHDEV_LOG(ERR,
16304418919fSjohnjiang 				"Failed to enable promiscuous mode for device (port %u): %s\n",
16314418919fSjohnjiang 				port_id, rte_strerror(-ret));
16324418919fSjohnjiang 			return ret;
16334418919fSjohnjiang 		}
16344418919fSjohnjiang 	} else if (rte_eth_promiscuous_get(port_id) == 0 &&
16354418919fSjohnjiang 		   *dev->dev_ops->promiscuous_disable != NULL) {
16364418919fSjohnjiang 		ret = eth_err(port_id,
16374418919fSjohnjiang 			      (*dev->dev_ops->promiscuous_disable)(dev));
16384418919fSjohnjiang 		if (ret != 0 && ret != -ENOTSUP) {
16394418919fSjohnjiang 			RTE_ETHDEV_LOG(ERR,
16404418919fSjohnjiang 				"Failed to disable promiscuous mode for device (port %u): %s\n",
16414418919fSjohnjiang 				port_id, rte_strerror(-ret));
16424418919fSjohnjiang 			return ret;
16434418919fSjohnjiang 		}
16444418919fSjohnjiang 	}
1645d30ea906Sjfb8856606 
1646d30ea906Sjfb8856606 	/* replay all multicast configuration */
16474418919fSjohnjiang 	/*
16484418919fSjohnjiang 	 * use callbacks directly since we don't need port_id check and
16494418919fSjohnjiang 	 * would like to bypass the same value set
16504418919fSjohnjiang 	 */
16514418919fSjohnjiang 	if (rte_eth_allmulticast_get(port_id) == 1 &&
16524418919fSjohnjiang 	    *dev->dev_ops->allmulticast_enable != NULL) {
16534418919fSjohnjiang 		ret = eth_err(port_id,
16544418919fSjohnjiang 			      (*dev->dev_ops->allmulticast_enable)(dev));
16554418919fSjohnjiang 		if (ret != 0 && ret != -ENOTSUP) {
16564418919fSjohnjiang 			RTE_ETHDEV_LOG(ERR,
16574418919fSjohnjiang 				"Failed to enable allmulticast mode for device (port %u): %s\n",
16584418919fSjohnjiang 				port_id, rte_strerror(-ret));
16594418919fSjohnjiang 			return ret;
16604418919fSjohnjiang 		}
16614418919fSjohnjiang 	} else if (rte_eth_allmulticast_get(port_id) == 0 &&
16624418919fSjohnjiang 		   *dev->dev_ops->allmulticast_disable != NULL) {
16634418919fSjohnjiang 		ret = eth_err(port_id,
16644418919fSjohnjiang 			      (*dev->dev_ops->allmulticast_disable)(dev));
16654418919fSjohnjiang 		if (ret != 0 && ret != -ENOTSUP) {
16664418919fSjohnjiang 			RTE_ETHDEV_LOG(ERR,
16674418919fSjohnjiang 				"Failed to disable allmulticast mode for device (port %u): %s\n",
16684418919fSjohnjiang 				port_id, rte_strerror(-ret));
16694418919fSjohnjiang 			return ret;
16704418919fSjohnjiang 		}
16714418919fSjohnjiang 	}
16724418919fSjohnjiang 
16734418919fSjohnjiang 	return 0;
1674d30ea906Sjfb8856606 }
1675d30ea906Sjfb8856606 
1676d30ea906Sjfb8856606 int
rte_eth_dev_start(uint16_t port_id)1677d30ea906Sjfb8856606 rte_eth_dev_start(uint16_t port_id)
1678d30ea906Sjfb8856606 {
1679d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
1680d30ea906Sjfb8856606 	struct rte_eth_dev_info dev_info;
1681d30ea906Sjfb8856606 	int diag;
1682*2d9fd380Sjfb8856606 	int ret, ret_stop;
1683d30ea906Sjfb8856606 
1684*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1685d30ea906Sjfb8856606 
1686d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
1687d30ea906Sjfb8856606 
1688d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
1689d30ea906Sjfb8856606 
1690d30ea906Sjfb8856606 	if (dev->data->dev_started != 0) {
1691d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(INFO,
1692d30ea906Sjfb8856606 			"Device with port_id=%"PRIu16" already started\n",
1693d30ea906Sjfb8856606 			port_id);
1694d30ea906Sjfb8856606 		return 0;
1695d30ea906Sjfb8856606 	}
1696d30ea906Sjfb8856606 
16974418919fSjohnjiang 	ret = rte_eth_dev_info_get(port_id, &dev_info);
16984418919fSjohnjiang 	if (ret != 0)
16994418919fSjohnjiang 		return ret;
1700d30ea906Sjfb8856606 
1701d30ea906Sjfb8856606 	/* Lets restore MAC now if device does not support live change */
1702d30ea906Sjfb8856606 	if (*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR)
1703*2d9fd380Sjfb8856606 		eth_dev_mac_restore(dev, &dev_info);
1704d30ea906Sjfb8856606 
1705d30ea906Sjfb8856606 	diag = (*dev->dev_ops->dev_start)(dev);
1706d30ea906Sjfb8856606 	if (diag == 0)
1707d30ea906Sjfb8856606 		dev->data->dev_started = 1;
1708d30ea906Sjfb8856606 	else
1709d30ea906Sjfb8856606 		return eth_err(port_id, diag);
1710d30ea906Sjfb8856606 
1711*2d9fd380Sjfb8856606 	ret = eth_dev_config_restore(dev, &dev_info, port_id);
17124418919fSjohnjiang 	if (ret != 0) {
17134418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR,
17144418919fSjohnjiang 			"Error during restoring configuration for device (port %u): %s\n",
17154418919fSjohnjiang 			port_id, rte_strerror(-ret));
1716*2d9fd380Sjfb8856606 		ret_stop = rte_eth_dev_stop(port_id);
1717*2d9fd380Sjfb8856606 		if (ret_stop != 0) {
1718*2d9fd380Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
1719*2d9fd380Sjfb8856606 				"Failed to stop device (port %u): %s\n",
1720*2d9fd380Sjfb8856606 				port_id, rte_strerror(-ret_stop));
1721*2d9fd380Sjfb8856606 		}
1722*2d9fd380Sjfb8856606 
17234418919fSjohnjiang 		return ret;
17244418919fSjohnjiang 	}
1725d30ea906Sjfb8856606 
1726d30ea906Sjfb8856606 	if (dev->data->dev_conf.intr_conf.lsc == 0) {
1727d30ea906Sjfb8856606 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
1728d30ea906Sjfb8856606 		(*dev->dev_ops->link_update)(dev, 0);
1729d30ea906Sjfb8856606 	}
1730*2d9fd380Sjfb8856606 
1731*2d9fd380Sjfb8856606 	rte_ethdev_trace_start(port_id);
1732d30ea906Sjfb8856606 	return 0;
1733d30ea906Sjfb8856606 }
1734d30ea906Sjfb8856606 
1735*2d9fd380Sjfb8856606 int
rte_eth_dev_stop(uint16_t port_id)1736d30ea906Sjfb8856606 rte_eth_dev_stop(uint16_t port_id)
1737d30ea906Sjfb8856606 {
1738d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
1739*2d9fd380Sjfb8856606 	int ret;
1740d30ea906Sjfb8856606 
1741*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1742d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
1743d30ea906Sjfb8856606 
1744*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_stop, -ENOTSUP);
1745d30ea906Sjfb8856606 
1746d30ea906Sjfb8856606 	if (dev->data->dev_started == 0) {
1747d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(INFO,
1748d30ea906Sjfb8856606 			"Device with port_id=%"PRIu16" already stopped\n",
1749d30ea906Sjfb8856606 			port_id);
1750*2d9fd380Sjfb8856606 		return 0;
1751d30ea906Sjfb8856606 	}
1752d30ea906Sjfb8856606 
1753d30ea906Sjfb8856606 	dev->data->dev_started = 0;
1754*2d9fd380Sjfb8856606 	ret = (*dev->dev_ops->dev_stop)(dev);
1755*2d9fd380Sjfb8856606 	rte_ethdev_trace_stop(port_id, ret);
1756*2d9fd380Sjfb8856606 
1757*2d9fd380Sjfb8856606 	return ret;
1758d30ea906Sjfb8856606 }
1759d30ea906Sjfb8856606 
1760d30ea906Sjfb8856606 int
rte_eth_dev_set_link_up(uint16_t port_id)1761d30ea906Sjfb8856606 rte_eth_dev_set_link_up(uint16_t port_id)
1762d30ea906Sjfb8856606 {
1763d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
1764d30ea906Sjfb8856606 
1765*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1766d30ea906Sjfb8856606 
1767d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
1768d30ea906Sjfb8856606 
1769d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_up, -ENOTSUP);
1770d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->dev_set_link_up)(dev));
1771d30ea906Sjfb8856606 }
1772d30ea906Sjfb8856606 
1773d30ea906Sjfb8856606 int
rte_eth_dev_set_link_down(uint16_t port_id)1774d30ea906Sjfb8856606 rte_eth_dev_set_link_down(uint16_t port_id)
1775d30ea906Sjfb8856606 {
1776d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
1777d30ea906Sjfb8856606 
1778*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1779d30ea906Sjfb8856606 
1780d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
1781d30ea906Sjfb8856606 
1782d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_down, -ENOTSUP);
1783d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->dev_set_link_down)(dev));
1784d30ea906Sjfb8856606 }
1785d30ea906Sjfb8856606 
1786*2d9fd380Sjfb8856606 int
rte_eth_dev_close(uint16_t port_id)1787d30ea906Sjfb8856606 rte_eth_dev_close(uint16_t port_id)
1788d30ea906Sjfb8856606 {
1789d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
1790*2d9fd380Sjfb8856606 	int firsterr, binerr;
1791*2d9fd380Sjfb8856606 	int *lasterr = &firsterr;
1792d30ea906Sjfb8856606 
1793*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1794d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
1795d30ea906Sjfb8856606 
1796*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
1797*2d9fd380Sjfb8856606 	*lasterr = (*dev->dev_ops->dev_close)(dev);
1798*2d9fd380Sjfb8856606 	if (*lasterr != 0)
1799*2d9fd380Sjfb8856606 		lasterr = &binerr;
1800d30ea906Sjfb8856606 
1801*2d9fd380Sjfb8856606 	rte_ethdev_trace_close(port_id);
1802*2d9fd380Sjfb8856606 	*lasterr = rte_eth_dev_release_port(dev);
1803*2d9fd380Sjfb8856606 
1804*2d9fd380Sjfb8856606 	return eth_err(port_id, firsterr);
1805d30ea906Sjfb8856606 }
1806d30ea906Sjfb8856606 
1807d30ea906Sjfb8856606 int
rte_eth_dev_reset(uint16_t port_id)1808d30ea906Sjfb8856606 rte_eth_dev_reset(uint16_t port_id)
1809d30ea906Sjfb8856606 {
1810d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
1811d30ea906Sjfb8856606 	int ret;
1812d30ea906Sjfb8856606 
1813*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1814d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
1815d30ea906Sjfb8856606 
1816d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP);
1817d30ea906Sjfb8856606 
1818*2d9fd380Sjfb8856606 	ret = rte_eth_dev_stop(port_id);
1819*2d9fd380Sjfb8856606 	if (ret != 0) {
1820*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
1821*2d9fd380Sjfb8856606 			"Failed to stop device (port %u) before reset: %s - ignore\n",
1822*2d9fd380Sjfb8856606 			port_id, rte_strerror(-ret));
1823*2d9fd380Sjfb8856606 	}
1824d30ea906Sjfb8856606 	ret = dev->dev_ops->dev_reset(dev);
1825d30ea906Sjfb8856606 
1826d30ea906Sjfb8856606 	return eth_err(port_id, ret);
1827d30ea906Sjfb8856606 }
1828d30ea906Sjfb8856606 
18294418919fSjohnjiang int
rte_eth_dev_is_removed(uint16_t port_id)1830d30ea906Sjfb8856606 rte_eth_dev_is_removed(uint16_t port_id)
1831d30ea906Sjfb8856606 {
1832d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
1833d30ea906Sjfb8856606 	int ret;
1834d30ea906Sjfb8856606 
1835d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
1836d30ea906Sjfb8856606 
1837d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
1838d30ea906Sjfb8856606 
1839d30ea906Sjfb8856606 	if (dev->state == RTE_ETH_DEV_REMOVED)
1840d30ea906Sjfb8856606 		return 1;
1841d30ea906Sjfb8856606 
1842d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->is_removed, 0);
1843d30ea906Sjfb8856606 
1844d30ea906Sjfb8856606 	ret = dev->dev_ops->is_removed(dev);
1845d30ea906Sjfb8856606 	if (ret != 0)
1846d30ea906Sjfb8856606 		/* Device is physically removed. */
1847d30ea906Sjfb8856606 		dev->state = RTE_ETH_DEV_REMOVED;
1848d30ea906Sjfb8856606 
1849d30ea906Sjfb8856606 	return ret;
1850d30ea906Sjfb8856606 }
1851d30ea906Sjfb8856606 
1852*2d9fd380Sjfb8856606 static int
rte_eth_rx_queue_check_split(const struct rte_eth_rxseg_split * rx_seg,uint16_t n_seg,uint32_t * mbp_buf_size,const struct rte_eth_dev_info * dev_info)1853*2d9fd380Sjfb8856606 rte_eth_rx_queue_check_split(const struct rte_eth_rxseg_split *rx_seg,
1854*2d9fd380Sjfb8856606 			     uint16_t n_seg, uint32_t *mbp_buf_size,
1855*2d9fd380Sjfb8856606 			     const struct rte_eth_dev_info *dev_info)
1856*2d9fd380Sjfb8856606 {
1857*2d9fd380Sjfb8856606 	const struct rte_eth_rxseg_capa *seg_capa = &dev_info->rx_seg_capa;
1858*2d9fd380Sjfb8856606 	struct rte_mempool *mp_first;
1859*2d9fd380Sjfb8856606 	uint32_t offset_mask;
1860*2d9fd380Sjfb8856606 	uint16_t seg_idx;
1861*2d9fd380Sjfb8856606 
1862*2d9fd380Sjfb8856606 	if (n_seg > seg_capa->max_nseg) {
1863*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
1864*2d9fd380Sjfb8856606 			       "Requested Rx segments %u exceed supported %u\n",
1865*2d9fd380Sjfb8856606 			       n_seg, seg_capa->max_nseg);
1866*2d9fd380Sjfb8856606 		return -EINVAL;
1867*2d9fd380Sjfb8856606 	}
1868*2d9fd380Sjfb8856606 	/*
1869*2d9fd380Sjfb8856606 	 * Check the sizes and offsets against buffer sizes
1870*2d9fd380Sjfb8856606 	 * for each segment specified in extended configuration.
1871*2d9fd380Sjfb8856606 	 */
1872*2d9fd380Sjfb8856606 	mp_first = rx_seg[0].mp;
1873*2d9fd380Sjfb8856606 	offset_mask = (1u << seg_capa->offset_align_log2) - 1;
1874*2d9fd380Sjfb8856606 	for (seg_idx = 0; seg_idx < n_seg; seg_idx++) {
1875*2d9fd380Sjfb8856606 		struct rte_mempool *mpl = rx_seg[seg_idx].mp;
1876*2d9fd380Sjfb8856606 		uint32_t length = rx_seg[seg_idx].length;
1877*2d9fd380Sjfb8856606 		uint32_t offset = rx_seg[seg_idx].offset;
1878*2d9fd380Sjfb8856606 
1879*2d9fd380Sjfb8856606 		if (mpl == NULL) {
1880*2d9fd380Sjfb8856606 			RTE_ETHDEV_LOG(ERR, "null mempool pointer\n");
1881*2d9fd380Sjfb8856606 			return -EINVAL;
1882*2d9fd380Sjfb8856606 		}
1883*2d9fd380Sjfb8856606 		if (seg_idx != 0 && mp_first != mpl &&
1884*2d9fd380Sjfb8856606 		    seg_capa->multi_pools == 0) {
1885*2d9fd380Sjfb8856606 			RTE_ETHDEV_LOG(ERR, "Receiving to multiple pools is not supported\n");
1886*2d9fd380Sjfb8856606 			return -ENOTSUP;
1887*2d9fd380Sjfb8856606 		}
1888*2d9fd380Sjfb8856606 		if (offset != 0) {
1889*2d9fd380Sjfb8856606 			if (seg_capa->offset_allowed == 0) {
1890*2d9fd380Sjfb8856606 				RTE_ETHDEV_LOG(ERR, "Rx segmentation with offset is not supported\n");
1891*2d9fd380Sjfb8856606 				return -ENOTSUP;
1892*2d9fd380Sjfb8856606 			}
1893*2d9fd380Sjfb8856606 			if (offset & offset_mask) {
1894*2d9fd380Sjfb8856606 				RTE_ETHDEV_LOG(ERR, "Rx segmentation invalid offset alignment %u, %u\n",
1895*2d9fd380Sjfb8856606 					       offset,
1896*2d9fd380Sjfb8856606 					       seg_capa->offset_align_log2);
1897*2d9fd380Sjfb8856606 				return -EINVAL;
1898*2d9fd380Sjfb8856606 			}
1899*2d9fd380Sjfb8856606 		}
1900*2d9fd380Sjfb8856606 		if (mpl->private_data_size <
1901*2d9fd380Sjfb8856606 			sizeof(struct rte_pktmbuf_pool_private)) {
1902*2d9fd380Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
1903*2d9fd380Sjfb8856606 				       "%s private_data_size %u < %u\n",
1904*2d9fd380Sjfb8856606 				       mpl->name, mpl->private_data_size,
1905*2d9fd380Sjfb8856606 				       (unsigned int)sizeof
1906*2d9fd380Sjfb8856606 					(struct rte_pktmbuf_pool_private));
1907*2d9fd380Sjfb8856606 			return -ENOSPC;
1908*2d9fd380Sjfb8856606 		}
1909*2d9fd380Sjfb8856606 		offset += seg_idx != 0 ? 0 : RTE_PKTMBUF_HEADROOM;
1910*2d9fd380Sjfb8856606 		*mbp_buf_size = rte_pktmbuf_data_room_size(mpl);
1911*2d9fd380Sjfb8856606 		length = length != 0 ? length : *mbp_buf_size;
1912*2d9fd380Sjfb8856606 		if (*mbp_buf_size < length + offset) {
1913*2d9fd380Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
1914*2d9fd380Sjfb8856606 				       "%s mbuf_data_room_size %u < %u (segment length=%u + segment offset=%u)\n",
1915*2d9fd380Sjfb8856606 				       mpl->name, *mbp_buf_size,
1916*2d9fd380Sjfb8856606 				       length + offset, length, offset);
1917*2d9fd380Sjfb8856606 			return -EINVAL;
1918*2d9fd380Sjfb8856606 		}
1919*2d9fd380Sjfb8856606 	}
1920*2d9fd380Sjfb8856606 	return 0;
1921*2d9fd380Sjfb8856606 }
1922*2d9fd380Sjfb8856606 
1923d30ea906Sjfb8856606 int
rte_eth_rx_queue_setup(uint16_t port_id,uint16_t rx_queue_id,uint16_t nb_rx_desc,unsigned int socket_id,const struct rte_eth_rxconf * rx_conf,struct rte_mempool * mp)1924d30ea906Sjfb8856606 rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
1925d30ea906Sjfb8856606 		       uint16_t nb_rx_desc, unsigned int socket_id,
1926d30ea906Sjfb8856606 		       const struct rte_eth_rxconf *rx_conf,
1927d30ea906Sjfb8856606 		       struct rte_mempool *mp)
1928d30ea906Sjfb8856606 {
1929d30ea906Sjfb8856606 	int ret;
1930d30ea906Sjfb8856606 	uint32_t mbp_buf_size;
1931d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
1932d30ea906Sjfb8856606 	struct rte_eth_dev_info dev_info;
1933d30ea906Sjfb8856606 	struct rte_eth_rxconf local_conf;
1934d30ea906Sjfb8856606 	void **rxq;
1935d30ea906Sjfb8856606 
1936*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1937d30ea906Sjfb8856606 
1938d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
1939d30ea906Sjfb8856606 	if (rx_queue_id >= dev->data->nb_rx_queues) {
1940d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
1941d30ea906Sjfb8856606 		return -EINVAL;
1942d30ea906Sjfb8856606 	}
1943d30ea906Sjfb8856606 
1944d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP);
1945d30ea906Sjfb8856606 
19464418919fSjohnjiang 	ret = rte_eth_dev_info_get(port_id, &dev_info);
19474418919fSjohnjiang 	if (ret != 0)
19484418919fSjohnjiang 		return ret;
19494418919fSjohnjiang 
1950*2d9fd380Sjfb8856606 	if (mp != NULL) {
1951*2d9fd380Sjfb8856606 		/* Single pool configuration check. */
1952*2d9fd380Sjfb8856606 		if (rx_conf != NULL && rx_conf->rx_nseg != 0) {
1953*2d9fd380Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
1954*2d9fd380Sjfb8856606 				       "Ambiguous segment configuration\n");
1955*2d9fd380Sjfb8856606 			return -EINVAL;
1956*2d9fd380Sjfb8856606 		}
1957*2d9fd380Sjfb8856606 		/*
1958*2d9fd380Sjfb8856606 		 * Check the size of the mbuf data buffer, this value
1959*2d9fd380Sjfb8856606 		 * must be provided in the private data of the memory pool.
1960*2d9fd380Sjfb8856606 		 * First check that the memory pool(s) has a valid private data.
1961*2d9fd380Sjfb8856606 		 */
1962*2d9fd380Sjfb8856606 		if (mp->private_data_size <
1963*2d9fd380Sjfb8856606 				sizeof(struct rte_pktmbuf_pool_private)) {
1964*2d9fd380Sjfb8856606 			RTE_ETHDEV_LOG(ERR, "%s private_data_size %u < %u\n",
1965*2d9fd380Sjfb8856606 				mp->name, mp->private_data_size,
1966*2d9fd380Sjfb8856606 				(unsigned int)
1967*2d9fd380Sjfb8856606 				sizeof(struct rte_pktmbuf_pool_private));
1968d30ea906Sjfb8856606 			return -ENOSPC;
1969d30ea906Sjfb8856606 		}
1970d30ea906Sjfb8856606 		mbp_buf_size = rte_pktmbuf_data_room_size(mp);
1971*2d9fd380Sjfb8856606 		if (mbp_buf_size < dev_info.min_rx_bufsize +
1972*2d9fd380Sjfb8856606 				   RTE_PKTMBUF_HEADROOM) {
1973d30ea906Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
1974*2d9fd380Sjfb8856606 				       "%s mbuf_data_room_size %u < %u (RTE_PKTMBUF_HEADROOM=%u + min_rx_bufsize(dev)=%u)\n",
1975*2d9fd380Sjfb8856606 				       mp->name, mbp_buf_size,
1976*2d9fd380Sjfb8856606 				       RTE_PKTMBUF_HEADROOM +
1977*2d9fd380Sjfb8856606 				       dev_info.min_rx_bufsize,
1978*2d9fd380Sjfb8856606 				       RTE_PKTMBUF_HEADROOM,
1979*2d9fd380Sjfb8856606 				       dev_info.min_rx_bufsize);
1980d30ea906Sjfb8856606 			return -EINVAL;
1981d30ea906Sjfb8856606 		}
1982*2d9fd380Sjfb8856606 	} else {
1983*2d9fd380Sjfb8856606 		const struct rte_eth_rxseg_split *rx_seg;
1984*2d9fd380Sjfb8856606 		uint16_t n_seg;
1985*2d9fd380Sjfb8856606 
1986*2d9fd380Sjfb8856606 		/* Extended multi-segment configuration check. */
1987*2d9fd380Sjfb8856606 		if (rx_conf == NULL || rx_conf->rx_seg == NULL || rx_conf->rx_nseg == 0) {
1988*2d9fd380Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
1989*2d9fd380Sjfb8856606 				       "Memory pool is null and no extended configuration provided\n");
1990*2d9fd380Sjfb8856606 			return -EINVAL;
1991*2d9fd380Sjfb8856606 		}
1992*2d9fd380Sjfb8856606 
1993*2d9fd380Sjfb8856606 		rx_seg = (const struct rte_eth_rxseg_split *)rx_conf->rx_seg;
1994*2d9fd380Sjfb8856606 		n_seg = rx_conf->rx_nseg;
1995*2d9fd380Sjfb8856606 
1996*2d9fd380Sjfb8856606 		if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
1997*2d9fd380Sjfb8856606 			ret = rte_eth_rx_queue_check_split(rx_seg, n_seg,
1998*2d9fd380Sjfb8856606 							   &mbp_buf_size,
1999*2d9fd380Sjfb8856606 							   &dev_info);
2000*2d9fd380Sjfb8856606 			if (ret != 0)
2001*2d9fd380Sjfb8856606 				return ret;
2002*2d9fd380Sjfb8856606 		} else {
2003*2d9fd380Sjfb8856606 			RTE_ETHDEV_LOG(ERR, "No Rx segmentation offload configured\n");
2004*2d9fd380Sjfb8856606 			return -EINVAL;
2005*2d9fd380Sjfb8856606 		}
2006*2d9fd380Sjfb8856606 	}
2007d30ea906Sjfb8856606 
2008d30ea906Sjfb8856606 	/* Use default specified by driver, if nb_rx_desc is zero */
2009d30ea906Sjfb8856606 	if (nb_rx_desc == 0) {
2010d30ea906Sjfb8856606 		nb_rx_desc = dev_info.default_rxportconf.ring_size;
2011d30ea906Sjfb8856606 		/* If driver default is also zero, fall back on EAL default */
2012d30ea906Sjfb8856606 		if (nb_rx_desc == 0)
2013d30ea906Sjfb8856606 			nb_rx_desc = RTE_ETH_DEV_FALLBACK_RX_RINGSIZE;
2014d30ea906Sjfb8856606 	}
2015d30ea906Sjfb8856606 
2016d30ea906Sjfb8856606 	if (nb_rx_desc > dev_info.rx_desc_lim.nb_max ||
2017d30ea906Sjfb8856606 			nb_rx_desc < dev_info.rx_desc_lim.nb_min ||
2018d30ea906Sjfb8856606 			nb_rx_desc % dev_info.rx_desc_lim.nb_align != 0) {
2019d30ea906Sjfb8856606 
2020d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
20211646932aSjfb8856606 			"Invalid value for nb_rx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n",
2022d30ea906Sjfb8856606 			nb_rx_desc, dev_info.rx_desc_lim.nb_max,
2023d30ea906Sjfb8856606 			dev_info.rx_desc_lim.nb_min,
2024d30ea906Sjfb8856606 			dev_info.rx_desc_lim.nb_align);
2025d30ea906Sjfb8856606 		return -EINVAL;
2026d30ea906Sjfb8856606 	}
2027d30ea906Sjfb8856606 
2028d30ea906Sjfb8856606 	if (dev->data->dev_started &&
2029d30ea906Sjfb8856606 		!(dev_info.dev_capa &
2030d30ea906Sjfb8856606 			RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP))
2031d30ea906Sjfb8856606 		return -EBUSY;
2032d30ea906Sjfb8856606 
2033d30ea906Sjfb8856606 	if (dev->data->dev_started &&
2034d30ea906Sjfb8856606 		(dev->data->rx_queue_state[rx_queue_id] !=
2035d30ea906Sjfb8856606 			RTE_ETH_QUEUE_STATE_STOPPED))
2036d30ea906Sjfb8856606 		return -EBUSY;
2037d30ea906Sjfb8856606 
2038d30ea906Sjfb8856606 	rxq = dev->data->rx_queues;
2039d30ea906Sjfb8856606 	if (rxq[rx_queue_id]) {
2040d30ea906Sjfb8856606 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_release,
2041d30ea906Sjfb8856606 					-ENOTSUP);
2042d30ea906Sjfb8856606 		(*dev->dev_ops->rx_queue_release)(rxq[rx_queue_id]);
2043d30ea906Sjfb8856606 		rxq[rx_queue_id] = NULL;
2044d30ea906Sjfb8856606 	}
2045d30ea906Sjfb8856606 
2046d30ea906Sjfb8856606 	if (rx_conf == NULL)
2047d30ea906Sjfb8856606 		rx_conf = &dev_info.default_rxconf;
2048d30ea906Sjfb8856606 
2049d30ea906Sjfb8856606 	local_conf = *rx_conf;
2050d30ea906Sjfb8856606 
2051d30ea906Sjfb8856606 	/*
2052d30ea906Sjfb8856606 	 * If an offloading has already been enabled in
2053d30ea906Sjfb8856606 	 * rte_eth_dev_configure(), it has been enabled on all queues,
2054d30ea906Sjfb8856606 	 * so there is no need to enable it in this queue again.
2055d30ea906Sjfb8856606 	 * The local_conf.offloads input to underlying PMD only carries
2056d30ea906Sjfb8856606 	 * those offloadings which are only enabled on this queue and
2057d30ea906Sjfb8856606 	 * not enabled on all queues.
2058d30ea906Sjfb8856606 	 */
2059d30ea906Sjfb8856606 	local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads;
2060d30ea906Sjfb8856606 
2061d30ea906Sjfb8856606 	/*
2062d30ea906Sjfb8856606 	 * New added offloadings for this queue are those not enabled in
2063d30ea906Sjfb8856606 	 * rte_eth_dev_configure() and they must be per-queue type.
2064d30ea906Sjfb8856606 	 * A pure per-port offloading can't be enabled on a queue while
2065d30ea906Sjfb8856606 	 * disabled on another queue. A pure per-port offloading can't
2066d30ea906Sjfb8856606 	 * be enabled for any queue as new added one if it hasn't been
2067d30ea906Sjfb8856606 	 * enabled in rte_eth_dev_configure().
2068d30ea906Sjfb8856606 	 */
2069d30ea906Sjfb8856606 	if ((local_conf.offloads & dev_info.rx_queue_offload_capa) !=
2070d30ea906Sjfb8856606 	     local_conf.offloads) {
2071d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
2072d30ea906Sjfb8856606 			"Ethdev port_id=%d rx_queue_id=%d, new added offloads 0x%"PRIx64" must be "
20731646932aSjfb8856606 			"within per-queue offload capabilities 0x%"PRIx64" in %s()\n",
2074d30ea906Sjfb8856606 			port_id, rx_queue_id, local_conf.offloads,
2075d30ea906Sjfb8856606 			dev_info.rx_queue_offload_capa,
2076d30ea906Sjfb8856606 			__func__);
2077d30ea906Sjfb8856606 		return -EINVAL;
2078d30ea906Sjfb8856606 	}
2079d30ea906Sjfb8856606 
20804418919fSjohnjiang 	/*
20814418919fSjohnjiang 	 * If LRO is enabled, check that the maximum aggregated packet
20824418919fSjohnjiang 	 * size is supported by the configured device.
20834418919fSjohnjiang 	 */
20844418919fSjohnjiang 	if (local_conf.offloads & DEV_RX_OFFLOAD_TCP_LRO) {
20854418919fSjohnjiang 		if (dev->data->dev_conf.rxmode.max_lro_pkt_size == 0)
20864418919fSjohnjiang 			dev->data->dev_conf.rxmode.max_lro_pkt_size =
20874418919fSjohnjiang 				dev->data->dev_conf.rxmode.max_rx_pkt_len;
2088*2d9fd380Sjfb8856606 		int ret = eth_dev_check_lro_pkt_size(port_id,
20894418919fSjohnjiang 				dev->data->dev_conf.rxmode.max_lro_pkt_size,
20904418919fSjohnjiang 				dev->data->dev_conf.rxmode.max_rx_pkt_len,
20914418919fSjohnjiang 				dev_info.max_lro_pkt_size);
20924418919fSjohnjiang 		if (ret != 0)
20934418919fSjohnjiang 			return ret;
20944418919fSjohnjiang 	}
20954418919fSjohnjiang 
2096d30ea906Sjfb8856606 	ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
2097d30ea906Sjfb8856606 					      socket_id, &local_conf, mp);
2098d30ea906Sjfb8856606 	if (!ret) {
2099d30ea906Sjfb8856606 		if (!dev->data->min_rx_buf_size ||
2100d30ea906Sjfb8856606 		    dev->data->min_rx_buf_size > mbp_buf_size)
2101d30ea906Sjfb8856606 			dev->data->min_rx_buf_size = mbp_buf_size;
2102d30ea906Sjfb8856606 	}
2103d30ea906Sjfb8856606 
2104*2d9fd380Sjfb8856606 	rte_ethdev_trace_rxq_setup(port_id, rx_queue_id, nb_rx_desc, mp,
2105*2d9fd380Sjfb8856606 		rx_conf, ret);
2106d30ea906Sjfb8856606 	return eth_err(port_id, ret);
2107d30ea906Sjfb8856606 }
2108d30ea906Sjfb8856606 
2109d30ea906Sjfb8856606 int
rte_eth_rx_hairpin_queue_setup(uint16_t port_id,uint16_t rx_queue_id,uint16_t nb_rx_desc,const struct rte_eth_hairpin_conf * conf)21104418919fSjohnjiang rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
21114418919fSjohnjiang 			       uint16_t nb_rx_desc,
21124418919fSjohnjiang 			       const struct rte_eth_hairpin_conf *conf)
21134418919fSjohnjiang {
21144418919fSjohnjiang 	int ret;
21154418919fSjohnjiang 	struct rte_eth_dev *dev;
21164418919fSjohnjiang 	struct rte_eth_hairpin_cap cap;
21174418919fSjohnjiang 	void **rxq;
21184418919fSjohnjiang 	int i;
21194418919fSjohnjiang 	int count;
21204418919fSjohnjiang 
2121*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
21224418919fSjohnjiang 
21234418919fSjohnjiang 	dev = &rte_eth_devices[port_id];
21244418919fSjohnjiang 	if (rx_queue_id >= dev->data->nb_rx_queues) {
21254418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
21264418919fSjohnjiang 		return -EINVAL;
21274418919fSjohnjiang 	}
21284418919fSjohnjiang 	ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
21294418919fSjohnjiang 	if (ret != 0)
21304418919fSjohnjiang 		return ret;
21314418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_hairpin_queue_setup,
21324418919fSjohnjiang 				-ENOTSUP);
21334418919fSjohnjiang 	/* if nb_rx_desc is zero use max number of desc from the driver. */
21344418919fSjohnjiang 	if (nb_rx_desc == 0)
21354418919fSjohnjiang 		nb_rx_desc = cap.max_nb_desc;
21364418919fSjohnjiang 	if (nb_rx_desc > cap.max_nb_desc) {
21374418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR,
21384418919fSjohnjiang 			"Invalid value for nb_rx_desc(=%hu), should be: <= %hu",
21394418919fSjohnjiang 			nb_rx_desc, cap.max_nb_desc);
21404418919fSjohnjiang 		return -EINVAL;
21414418919fSjohnjiang 	}
21424418919fSjohnjiang 	if (conf->peer_count > cap.max_rx_2_tx) {
21434418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR,
2144*2d9fd380Sjfb8856606 			"Invalid value for number of peers for Rx queue(=%u), should be: <= %hu",
21454418919fSjohnjiang 			conf->peer_count, cap.max_rx_2_tx);
21464418919fSjohnjiang 		return -EINVAL;
21474418919fSjohnjiang 	}
21484418919fSjohnjiang 	if (conf->peer_count == 0) {
21494418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR,
2150*2d9fd380Sjfb8856606 			"Invalid value for number of peers for Rx queue(=%u), should be: > 0",
21514418919fSjohnjiang 			conf->peer_count);
21524418919fSjohnjiang 		return -EINVAL;
21534418919fSjohnjiang 	}
21544418919fSjohnjiang 	for (i = 0, count = 0; i < dev->data->nb_rx_queues &&
21554418919fSjohnjiang 	     cap.max_nb_queues != UINT16_MAX; i++) {
21564418919fSjohnjiang 		if (i == rx_queue_id || rte_eth_dev_is_rx_hairpin_queue(dev, i))
21574418919fSjohnjiang 			count++;
21584418919fSjohnjiang 	}
21594418919fSjohnjiang 	if (count > cap.max_nb_queues) {
21604418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR, "To many Rx hairpin queues max is %d",
21614418919fSjohnjiang 		cap.max_nb_queues);
21624418919fSjohnjiang 		return -EINVAL;
21634418919fSjohnjiang 	}
21644418919fSjohnjiang 	if (dev->data->dev_started)
21654418919fSjohnjiang 		return -EBUSY;
21664418919fSjohnjiang 	rxq = dev->data->rx_queues;
21674418919fSjohnjiang 	if (rxq[rx_queue_id] != NULL) {
21684418919fSjohnjiang 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_release,
21694418919fSjohnjiang 					-ENOTSUP);
21704418919fSjohnjiang 		(*dev->dev_ops->rx_queue_release)(rxq[rx_queue_id]);
21714418919fSjohnjiang 		rxq[rx_queue_id] = NULL;
21724418919fSjohnjiang 	}
21734418919fSjohnjiang 	ret = (*dev->dev_ops->rx_hairpin_queue_setup)(dev, rx_queue_id,
21744418919fSjohnjiang 						      nb_rx_desc, conf);
21754418919fSjohnjiang 	if (ret == 0)
21764418919fSjohnjiang 		dev->data->rx_queue_state[rx_queue_id] =
21774418919fSjohnjiang 			RTE_ETH_QUEUE_STATE_HAIRPIN;
21784418919fSjohnjiang 	return eth_err(port_id, ret);
21794418919fSjohnjiang }
21804418919fSjohnjiang 
21814418919fSjohnjiang int
rte_eth_tx_queue_setup(uint16_t port_id,uint16_t tx_queue_id,uint16_t nb_tx_desc,unsigned int socket_id,const struct rte_eth_txconf * tx_conf)2182d30ea906Sjfb8856606 rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
2183d30ea906Sjfb8856606 		       uint16_t nb_tx_desc, unsigned int socket_id,
2184d30ea906Sjfb8856606 		       const struct rte_eth_txconf *tx_conf)
2185d30ea906Sjfb8856606 {
2186d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
2187d30ea906Sjfb8856606 	struct rte_eth_dev_info dev_info;
2188d30ea906Sjfb8856606 	struct rte_eth_txconf local_conf;
2189d30ea906Sjfb8856606 	void **txq;
21904418919fSjohnjiang 	int ret;
2191d30ea906Sjfb8856606 
2192*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2193d30ea906Sjfb8856606 
2194d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2195d30ea906Sjfb8856606 	if (tx_queue_id >= dev->data->nb_tx_queues) {
2196d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
2197d30ea906Sjfb8856606 		return -EINVAL;
2198d30ea906Sjfb8856606 	}
2199d30ea906Sjfb8856606 
2200d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -ENOTSUP);
2201d30ea906Sjfb8856606 
22024418919fSjohnjiang 	ret = rte_eth_dev_info_get(port_id, &dev_info);
22034418919fSjohnjiang 	if (ret != 0)
22044418919fSjohnjiang 		return ret;
2205d30ea906Sjfb8856606 
2206d30ea906Sjfb8856606 	/* Use default specified by driver, if nb_tx_desc is zero */
2207d30ea906Sjfb8856606 	if (nb_tx_desc == 0) {
2208d30ea906Sjfb8856606 		nb_tx_desc = dev_info.default_txportconf.ring_size;
2209d30ea906Sjfb8856606 		/* If driver default is zero, fall back on EAL default */
2210d30ea906Sjfb8856606 		if (nb_tx_desc == 0)
2211d30ea906Sjfb8856606 			nb_tx_desc = RTE_ETH_DEV_FALLBACK_TX_RINGSIZE;
2212d30ea906Sjfb8856606 	}
2213d30ea906Sjfb8856606 	if (nb_tx_desc > dev_info.tx_desc_lim.nb_max ||
2214d30ea906Sjfb8856606 	    nb_tx_desc < dev_info.tx_desc_lim.nb_min ||
2215d30ea906Sjfb8856606 	    nb_tx_desc % dev_info.tx_desc_lim.nb_align != 0) {
2216d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
22171646932aSjfb8856606 			"Invalid value for nb_tx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n",
2218d30ea906Sjfb8856606 			nb_tx_desc, dev_info.tx_desc_lim.nb_max,
2219d30ea906Sjfb8856606 			dev_info.tx_desc_lim.nb_min,
2220d30ea906Sjfb8856606 			dev_info.tx_desc_lim.nb_align);
2221d30ea906Sjfb8856606 		return -EINVAL;
2222d30ea906Sjfb8856606 	}
2223d30ea906Sjfb8856606 
2224d30ea906Sjfb8856606 	if (dev->data->dev_started &&
2225d30ea906Sjfb8856606 		!(dev_info.dev_capa &
2226d30ea906Sjfb8856606 			RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP))
2227d30ea906Sjfb8856606 		return -EBUSY;
2228d30ea906Sjfb8856606 
2229d30ea906Sjfb8856606 	if (dev->data->dev_started &&
2230d30ea906Sjfb8856606 		(dev->data->tx_queue_state[tx_queue_id] !=
2231d30ea906Sjfb8856606 			RTE_ETH_QUEUE_STATE_STOPPED))
2232d30ea906Sjfb8856606 		return -EBUSY;
2233d30ea906Sjfb8856606 
2234d30ea906Sjfb8856606 	txq = dev->data->tx_queues;
2235d30ea906Sjfb8856606 	if (txq[tx_queue_id]) {
2236d30ea906Sjfb8856606 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_release,
2237d30ea906Sjfb8856606 					-ENOTSUP);
2238d30ea906Sjfb8856606 		(*dev->dev_ops->tx_queue_release)(txq[tx_queue_id]);
2239d30ea906Sjfb8856606 		txq[tx_queue_id] = NULL;
2240d30ea906Sjfb8856606 	}
2241d30ea906Sjfb8856606 
2242d30ea906Sjfb8856606 	if (tx_conf == NULL)
2243d30ea906Sjfb8856606 		tx_conf = &dev_info.default_txconf;
2244d30ea906Sjfb8856606 
2245d30ea906Sjfb8856606 	local_conf = *tx_conf;
2246d30ea906Sjfb8856606 
2247d30ea906Sjfb8856606 	/*
2248d30ea906Sjfb8856606 	 * If an offloading has already been enabled in
2249d30ea906Sjfb8856606 	 * rte_eth_dev_configure(), it has been enabled on all queues,
2250d30ea906Sjfb8856606 	 * so there is no need to enable it in this queue again.
2251d30ea906Sjfb8856606 	 * The local_conf.offloads input to underlying PMD only carries
2252d30ea906Sjfb8856606 	 * those offloadings which are only enabled on this queue and
2253d30ea906Sjfb8856606 	 * not enabled on all queues.
2254d30ea906Sjfb8856606 	 */
2255d30ea906Sjfb8856606 	local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads;
2256d30ea906Sjfb8856606 
2257d30ea906Sjfb8856606 	/*
2258d30ea906Sjfb8856606 	 * New added offloadings for this queue are those not enabled in
2259d30ea906Sjfb8856606 	 * rte_eth_dev_configure() and they must be per-queue type.
2260d30ea906Sjfb8856606 	 * A pure per-port offloading can't be enabled on a queue while
2261d30ea906Sjfb8856606 	 * disabled on another queue. A pure per-port offloading can't
2262d30ea906Sjfb8856606 	 * be enabled for any queue as new added one if it hasn't been
2263d30ea906Sjfb8856606 	 * enabled in rte_eth_dev_configure().
2264d30ea906Sjfb8856606 	 */
2265d30ea906Sjfb8856606 	if ((local_conf.offloads & dev_info.tx_queue_offload_capa) !=
2266d30ea906Sjfb8856606 	     local_conf.offloads) {
2267d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
2268d30ea906Sjfb8856606 			"Ethdev port_id=%d tx_queue_id=%d, new added offloads 0x%"PRIx64" must be "
22691646932aSjfb8856606 			"within per-queue offload capabilities 0x%"PRIx64" in %s()\n",
2270d30ea906Sjfb8856606 			port_id, tx_queue_id, local_conf.offloads,
2271d30ea906Sjfb8856606 			dev_info.tx_queue_offload_capa,
2272d30ea906Sjfb8856606 			__func__);
2273d30ea906Sjfb8856606 		return -EINVAL;
2274d30ea906Sjfb8856606 	}
2275d30ea906Sjfb8856606 
2276*2d9fd380Sjfb8856606 	rte_ethdev_trace_txq_setup(port_id, tx_queue_id, nb_tx_desc, tx_conf);
2277d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
2278d30ea906Sjfb8856606 		       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
2279d30ea906Sjfb8856606 }
2280d30ea906Sjfb8856606 
22814418919fSjohnjiang int
rte_eth_tx_hairpin_queue_setup(uint16_t port_id,uint16_t tx_queue_id,uint16_t nb_tx_desc,const struct rte_eth_hairpin_conf * conf)22824418919fSjohnjiang rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
22834418919fSjohnjiang 			       uint16_t nb_tx_desc,
22844418919fSjohnjiang 			       const struct rte_eth_hairpin_conf *conf)
22854418919fSjohnjiang {
22864418919fSjohnjiang 	struct rte_eth_dev *dev;
22874418919fSjohnjiang 	struct rte_eth_hairpin_cap cap;
22884418919fSjohnjiang 	void **txq;
22894418919fSjohnjiang 	int i;
22904418919fSjohnjiang 	int count;
22914418919fSjohnjiang 	int ret;
22924418919fSjohnjiang 
2293*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
22944418919fSjohnjiang 	dev = &rte_eth_devices[port_id];
22954418919fSjohnjiang 	if (tx_queue_id >= dev->data->nb_tx_queues) {
22964418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
22974418919fSjohnjiang 		return -EINVAL;
22984418919fSjohnjiang 	}
22994418919fSjohnjiang 	ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
23004418919fSjohnjiang 	if (ret != 0)
23014418919fSjohnjiang 		return ret;
23024418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_hairpin_queue_setup,
23034418919fSjohnjiang 				-ENOTSUP);
23044418919fSjohnjiang 	/* if nb_rx_desc is zero use max number of desc from the driver. */
23054418919fSjohnjiang 	if (nb_tx_desc == 0)
23064418919fSjohnjiang 		nb_tx_desc = cap.max_nb_desc;
23074418919fSjohnjiang 	if (nb_tx_desc > cap.max_nb_desc) {
23084418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR,
23094418919fSjohnjiang 			"Invalid value for nb_tx_desc(=%hu), should be: <= %hu",
23104418919fSjohnjiang 			nb_tx_desc, cap.max_nb_desc);
23114418919fSjohnjiang 		return -EINVAL;
23124418919fSjohnjiang 	}
23134418919fSjohnjiang 	if (conf->peer_count > cap.max_tx_2_rx) {
23144418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR,
2315*2d9fd380Sjfb8856606 			"Invalid value for number of peers for Tx queue(=%u), should be: <= %hu",
23164418919fSjohnjiang 			conf->peer_count, cap.max_tx_2_rx);
23174418919fSjohnjiang 		return -EINVAL;
23184418919fSjohnjiang 	}
23194418919fSjohnjiang 	if (conf->peer_count == 0) {
23204418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR,
2321*2d9fd380Sjfb8856606 			"Invalid value for number of peers for Tx queue(=%u), should be: > 0",
23224418919fSjohnjiang 			conf->peer_count);
23234418919fSjohnjiang 		return -EINVAL;
23244418919fSjohnjiang 	}
23254418919fSjohnjiang 	for (i = 0, count = 0; i < dev->data->nb_tx_queues &&
23264418919fSjohnjiang 	     cap.max_nb_queues != UINT16_MAX; i++) {
23274418919fSjohnjiang 		if (i == tx_queue_id || rte_eth_dev_is_tx_hairpin_queue(dev, i))
23284418919fSjohnjiang 			count++;
23294418919fSjohnjiang 	}
23304418919fSjohnjiang 	if (count > cap.max_nb_queues) {
23314418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR, "To many Tx hairpin queues max is %d",
23324418919fSjohnjiang 		cap.max_nb_queues);
23334418919fSjohnjiang 		return -EINVAL;
23344418919fSjohnjiang 	}
23354418919fSjohnjiang 	if (dev->data->dev_started)
23364418919fSjohnjiang 		return -EBUSY;
23374418919fSjohnjiang 	txq = dev->data->tx_queues;
23384418919fSjohnjiang 	if (txq[tx_queue_id] != NULL) {
23394418919fSjohnjiang 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_release,
23404418919fSjohnjiang 					-ENOTSUP);
23414418919fSjohnjiang 		(*dev->dev_ops->tx_queue_release)(txq[tx_queue_id]);
23424418919fSjohnjiang 		txq[tx_queue_id] = NULL;
23434418919fSjohnjiang 	}
23444418919fSjohnjiang 	ret = (*dev->dev_ops->tx_hairpin_queue_setup)
23454418919fSjohnjiang 		(dev, tx_queue_id, nb_tx_desc, conf);
23464418919fSjohnjiang 	if (ret == 0)
23474418919fSjohnjiang 		dev->data->tx_queue_state[tx_queue_id] =
23484418919fSjohnjiang 			RTE_ETH_QUEUE_STATE_HAIRPIN;
23494418919fSjohnjiang 	return eth_err(port_id, ret);
23504418919fSjohnjiang }
23514418919fSjohnjiang 
2352*2d9fd380Sjfb8856606 int
rte_eth_hairpin_bind(uint16_t tx_port,uint16_t rx_port)2353*2d9fd380Sjfb8856606 rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port)
2354*2d9fd380Sjfb8856606 {
2355*2d9fd380Sjfb8856606 	struct rte_eth_dev *dev;
2356*2d9fd380Sjfb8856606 	int ret;
2357*2d9fd380Sjfb8856606 
2358*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV);
2359*2d9fd380Sjfb8856606 	dev = &rte_eth_devices[tx_port];
2360*2d9fd380Sjfb8856606 	if (dev->data->dev_started == 0) {
2361*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Tx port %d is not started\n", tx_port);
2362*2d9fd380Sjfb8856606 		return -EBUSY;
2363*2d9fd380Sjfb8856606 	}
2364*2d9fd380Sjfb8856606 
2365*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_bind, -ENOTSUP);
2366*2d9fd380Sjfb8856606 	ret = (*dev->dev_ops->hairpin_bind)(dev, rx_port);
2367*2d9fd380Sjfb8856606 	if (ret != 0)
2368*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Failed to bind hairpin Tx %d"
2369*2d9fd380Sjfb8856606 			       " to Rx %d (%d - all ports)\n",
2370*2d9fd380Sjfb8856606 			       tx_port, rx_port, RTE_MAX_ETHPORTS);
2371*2d9fd380Sjfb8856606 
2372*2d9fd380Sjfb8856606 	return ret;
2373*2d9fd380Sjfb8856606 }
2374*2d9fd380Sjfb8856606 
2375*2d9fd380Sjfb8856606 int
rte_eth_hairpin_unbind(uint16_t tx_port,uint16_t rx_port)2376*2d9fd380Sjfb8856606 rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port)
2377*2d9fd380Sjfb8856606 {
2378*2d9fd380Sjfb8856606 	struct rte_eth_dev *dev;
2379*2d9fd380Sjfb8856606 	int ret;
2380*2d9fd380Sjfb8856606 
2381*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV);
2382*2d9fd380Sjfb8856606 	dev = &rte_eth_devices[tx_port];
2383*2d9fd380Sjfb8856606 	if (dev->data->dev_started == 0) {
2384*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Tx port %d is already stopped\n", tx_port);
2385*2d9fd380Sjfb8856606 		return -EBUSY;
2386*2d9fd380Sjfb8856606 	}
2387*2d9fd380Sjfb8856606 
2388*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_unbind, -ENOTSUP);
2389*2d9fd380Sjfb8856606 	ret = (*dev->dev_ops->hairpin_unbind)(dev, rx_port);
2390*2d9fd380Sjfb8856606 	if (ret != 0)
2391*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Failed to unbind hairpin Tx %d"
2392*2d9fd380Sjfb8856606 			       " from Rx %d (%d - all ports)\n",
2393*2d9fd380Sjfb8856606 			       tx_port, rx_port, RTE_MAX_ETHPORTS);
2394*2d9fd380Sjfb8856606 
2395*2d9fd380Sjfb8856606 	return ret;
2396*2d9fd380Sjfb8856606 }
2397*2d9fd380Sjfb8856606 
2398*2d9fd380Sjfb8856606 int
rte_eth_hairpin_get_peer_ports(uint16_t port_id,uint16_t * peer_ports,size_t len,uint32_t direction)2399*2d9fd380Sjfb8856606 rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports,
2400*2d9fd380Sjfb8856606 			       size_t len, uint32_t direction)
2401*2d9fd380Sjfb8856606 {
2402*2d9fd380Sjfb8856606 	struct rte_eth_dev *dev;
2403*2d9fd380Sjfb8856606 	int ret;
2404*2d9fd380Sjfb8856606 
2405*2d9fd380Sjfb8856606 	if (peer_ports == NULL || len == 0)
2406*2d9fd380Sjfb8856606 		return -EINVAL;
2407*2d9fd380Sjfb8856606 
2408*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2409*2d9fd380Sjfb8856606 	dev = &rte_eth_devices[port_id];
2410*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_get_peer_ports,
2411*2d9fd380Sjfb8856606 				-ENOTSUP);
2412*2d9fd380Sjfb8856606 
2413*2d9fd380Sjfb8856606 	ret = (*dev->dev_ops->hairpin_get_peer_ports)(dev, peer_ports,
2414*2d9fd380Sjfb8856606 						      len, direction);
2415*2d9fd380Sjfb8856606 	if (ret < 0)
2416*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Failed to get %d hairpin peer %s ports\n",
2417*2d9fd380Sjfb8856606 			       port_id, direction ? "Rx" : "Tx");
2418*2d9fd380Sjfb8856606 
2419*2d9fd380Sjfb8856606 	return ret;
2420*2d9fd380Sjfb8856606 }
2421*2d9fd380Sjfb8856606 
2422d30ea906Sjfb8856606 void
rte_eth_tx_buffer_drop_callback(struct rte_mbuf ** pkts,uint16_t unsent,void * userdata __rte_unused)2423d30ea906Sjfb8856606 rte_eth_tx_buffer_drop_callback(struct rte_mbuf **pkts, uint16_t unsent,
2424d30ea906Sjfb8856606 		void *userdata __rte_unused)
2425d30ea906Sjfb8856606 {
2426*2d9fd380Sjfb8856606 	rte_pktmbuf_free_bulk(pkts, unsent);
2427d30ea906Sjfb8856606 }
2428d30ea906Sjfb8856606 
2429d30ea906Sjfb8856606 void
rte_eth_tx_buffer_count_callback(struct rte_mbuf ** pkts,uint16_t unsent,void * userdata)2430d30ea906Sjfb8856606 rte_eth_tx_buffer_count_callback(struct rte_mbuf **pkts, uint16_t unsent,
2431d30ea906Sjfb8856606 		void *userdata)
2432d30ea906Sjfb8856606 {
2433d30ea906Sjfb8856606 	uint64_t *count = userdata;
2434d30ea906Sjfb8856606 
2435*2d9fd380Sjfb8856606 	rte_pktmbuf_free_bulk(pkts, unsent);
2436d30ea906Sjfb8856606 	*count += unsent;
2437d30ea906Sjfb8856606 }
2438d30ea906Sjfb8856606 
2439d30ea906Sjfb8856606 int
rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer * buffer,buffer_tx_error_fn cbfn,void * userdata)2440d30ea906Sjfb8856606 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
2441d30ea906Sjfb8856606 		buffer_tx_error_fn cbfn, void *userdata)
2442d30ea906Sjfb8856606 {
2443d30ea906Sjfb8856606 	buffer->error_callback = cbfn;
2444d30ea906Sjfb8856606 	buffer->error_userdata = userdata;
2445d30ea906Sjfb8856606 	return 0;
2446d30ea906Sjfb8856606 }
2447d30ea906Sjfb8856606 
2448d30ea906Sjfb8856606 int
rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer * buffer,uint16_t size)2449d30ea906Sjfb8856606 rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size)
2450d30ea906Sjfb8856606 {
2451d30ea906Sjfb8856606 	int ret = 0;
2452d30ea906Sjfb8856606 
2453d30ea906Sjfb8856606 	if (buffer == NULL)
2454d30ea906Sjfb8856606 		return -EINVAL;
2455d30ea906Sjfb8856606 
2456d30ea906Sjfb8856606 	buffer->size = size;
2457d30ea906Sjfb8856606 	if (buffer->error_callback == NULL) {
2458d30ea906Sjfb8856606 		ret = rte_eth_tx_buffer_set_err_callback(
2459d30ea906Sjfb8856606 			buffer, rte_eth_tx_buffer_drop_callback, NULL);
2460d30ea906Sjfb8856606 	}
2461d30ea906Sjfb8856606 
2462d30ea906Sjfb8856606 	return ret;
2463d30ea906Sjfb8856606 }
2464d30ea906Sjfb8856606 
2465d30ea906Sjfb8856606 int
rte_eth_tx_done_cleanup(uint16_t port_id,uint16_t queue_id,uint32_t free_cnt)2466d30ea906Sjfb8856606 rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
2467d30ea906Sjfb8856606 {
2468d30ea906Sjfb8856606 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2469d30ea906Sjfb8856606 	int ret;
2470d30ea906Sjfb8856606 
2471d30ea906Sjfb8856606 	/* Validate Input Data. Bail if not valid or not supported. */
2472d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2473d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
2474d30ea906Sjfb8856606 
2475d30ea906Sjfb8856606 	/* Call driver to free pending mbufs. */
2476d30ea906Sjfb8856606 	ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id],
2477d30ea906Sjfb8856606 					       free_cnt);
2478d30ea906Sjfb8856606 	return eth_err(port_id, ret);
2479d30ea906Sjfb8856606 }
2480d30ea906Sjfb8856606 
24814418919fSjohnjiang int
rte_eth_promiscuous_enable(uint16_t port_id)2482d30ea906Sjfb8856606 rte_eth_promiscuous_enable(uint16_t port_id)
2483d30ea906Sjfb8856606 {
2484d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
24854418919fSjohnjiang 	int diag = 0;
2486d30ea906Sjfb8856606 
24874418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2488d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2489d30ea906Sjfb8856606 
24904418919fSjohnjiang 	if (dev->data->promiscuous == 1)
24914418919fSjohnjiang 		return 0;
24924418919fSjohnjiang 
24934418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_enable, -ENOTSUP);
24944418919fSjohnjiang 
24954418919fSjohnjiang 	diag = (*dev->dev_ops->promiscuous_enable)(dev);
24964418919fSjohnjiang 	dev->data->promiscuous = (diag == 0) ? 1 : 0;
24974418919fSjohnjiang 
24984418919fSjohnjiang 	return eth_err(port_id, diag);
2499d30ea906Sjfb8856606 }
2500d30ea906Sjfb8856606 
25014418919fSjohnjiang int
rte_eth_promiscuous_disable(uint16_t port_id)2502d30ea906Sjfb8856606 rte_eth_promiscuous_disable(uint16_t port_id)
2503d30ea906Sjfb8856606 {
2504d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
25054418919fSjohnjiang 	int diag = 0;
2506d30ea906Sjfb8856606 
25074418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2508d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2509d30ea906Sjfb8856606 
25104418919fSjohnjiang 	if (dev->data->promiscuous == 0)
25114418919fSjohnjiang 		return 0;
25124418919fSjohnjiang 
25134418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_disable, -ENOTSUP);
25144418919fSjohnjiang 
2515d30ea906Sjfb8856606 	dev->data->promiscuous = 0;
25164418919fSjohnjiang 	diag = (*dev->dev_ops->promiscuous_disable)(dev);
25174418919fSjohnjiang 	if (diag != 0)
25184418919fSjohnjiang 		dev->data->promiscuous = 1;
25194418919fSjohnjiang 
25204418919fSjohnjiang 	return eth_err(port_id, diag);
2521d30ea906Sjfb8856606 }
2522d30ea906Sjfb8856606 
2523d30ea906Sjfb8856606 int
rte_eth_promiscuous_get(uint16_t port_id)2524d30ea906Sjfb8856606 rte_eth_promiscuous_get(uint16_t port_id)
2525d30ea906Sjfb8856606 {
2526d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
2527d30ea906Sjfb8856606 
2528*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2529d30ea906Sjfb8856606 
2530d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2531d30ea906Sjfb8856606 	return dev->data->promiscuous;
2532d30ea906Sjfb8856606 }
2533d30ea906Sjfb8856606 
25344418919fSjohnjiang int
rte_eth_allmulticast_enable(uint16_t port_id)2535d30ea906Sjfb8856606 rte_eth_allmulticast_enable(uint16_t port_id)
2536d30ea906Sjfb8856606 {
2537d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
25384418919fSjohnjiang 	int diag;
2539d30ea906Sjfb8856606 
25404418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2541d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2542d30ea906Sjfb8856606 
25434418919fSjohnjiang 	if (dev->data->all_multicast == 1)
25444418919fSjohnjiang 		return 0;
25454418919fSjohnjiang 
25464418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_enable, -ENOTSUP);
25474418919fSjohnjiang 	diag = (*dev->dev_ops->allmulticast_enable)(dev);
25484418919fSjohnjiang 	dev->data->all_multicast = (diag == 0) ? 1 : 0;
25494418919fSjohnjiang 
25504418919fSjohnjiang 	return eth_err(port_id, diag);
2551d30ea906Sjfb8856606 }
2552d30ea906Sjfb8856606 
25534418919fSjohnjiang int
rte_eth_allmulticast_disable(uint16_t port_id)2554d30ea906Sjfb8856606 rte_eth_allmulticast_disable(uint16_t port_id)
2555d30ea906Sjfb8856606 {
2556d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
25574418919fSjohnjiang 	int diag;
2558d30ea906Sjfb8856606 
25594418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2560d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2561d30ea906Sjfb8856606 
25624418919fSjohnjiang 	if (dev->data->all_multicast == 0)
25634418919fSjohnjiang 		return 0;
25644418919fSjohnjiang 
25654418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_disable, -ENOTSUP);
2566d30ea906Sjfb8856606 	dev->data->all_multicast = 0;
25674418919fSjohnjiang 	diag = (*dev->dev_ops->allmulticast_disable)(dev);
25684418919fSjohnjiang 	if (diag != 0)
25694418919fSjohnjiang 		dev->data->all_multicast = 1;
25704418919fSjohnjiang 
25714418919fSjohnjiang 	return eth_err(port_id, diag);
2572d30ea906Sjfb8856606 }
2573d30ea906Sjfb8856606 
2574d30ea906Sjfb8856606 int
rte_eth_allmulticast_get(uint16_t port_id)2575d30ea906Sjfb8856606 rte_eth_allmulticast_get(uint16_t port_id)
2576d30ea906Sjfb8856606 {
2577d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
2578d30ea906Sjfb8856606 
2579*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2580d30ea906Sjfb8856606 
2581d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2582d30ea906Sjfb8856606 	return dev->data->all_multicast;
2583d30ea906Sjfb8856606 }
2584d30ea906Sjfb8856606 
25854418919fSjohnjiang int
rte_eth_link_get(uint16_t port_id,struct rte_eth_link * eth_link)2586d30ea906Sjfb8856606 rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
2587d30ea906Sjfb8856606 {
2588d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
2589d30ea906Sjfb8856606 
25904418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2591d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2592d30ea906Sjfb8856606 
2593d30ea906Sjfb8856606 	if (dev->data->dev_conf.intr_conf.lsc &&
2594d30ea906Sjfb8856606 	    dev->data->dev_started)
2595d30ea906Sjfb8856606 		rte_eth_linkstatus_get(dev, eth_link);
2596d30ea906Sjfb8856606 	else {
25974418919fSjohnjiang 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
2598d30ea906Sjfb8856606 		(*dev->dev_ops->link_update)(dev, 1);
2599d30ea906Sjfb8856606 		*eth_link = dev->data->dev_link;
2600d30ea906Sjfb8856606 	}
26014418919fSjohnjiang 
26024418919fSjohnjiang 	return 0;
2603d30ea906Sjfb8856606 }
2604d30ea906Sjfb8856606 
26054418919fSjohnjiang int
rte_eth_link_get_nowait(uint16_t port_id,struct rte_eth_link * eth_link)2606d30ea906Sjfb8856606 rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
2607d30ea906Sjfb8856606 {
2608d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
2609d30ea906Sjfb8856606 
26104418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2611d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2612d30ea906Sjfb8856606 
2613d30ea906Sjfb8856606 	if (dev->data->dev_conf.intr_conf.lsc &&
2614d30ea906Sjfb8856606 	    dev->data->dev_started)
2615d30ea906Sjfb8856606 		rte_eth_linkstatus_get(dev, eth_link);
2616d30ea906Sjfb8856606 	else {
26174418919fSjohnjiang 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
2618d30ea906Sjfb8856606 		(*dev->dev_ops->link_update)(dev, 0);
2619d30ea906Sjfb8856606 		*eth_link = dev->data->dev_link;
2620d30ea906Sjfb8856606 	}
26214418919fSjohnjiang 
26224418919fSjohnjiang 	return 0;
2623d30ea906Sjfb8856606 }
2624d30ea906Sjfb8856606 
2625*2d9fd380Sjfb8856606 const char *
rte_eth_link_speed_to_str(uint32_t link_speed)2626*2d9fd380Sjfb8856606 rte_eth_link_speed_to_str(uint32_t link_speed)
2627*2d9fd380Sjfb8856606 {
2628*2d9fd380Sjfb8856606 	switch (link_speed) {
2629*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_NONE: return "None";
2630*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_10M:  return "10 Mbps";
2631*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_100M: return "100 Mbps";
2632*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_1G:   return "1 Gbps";
2633*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_2_5G: return "2.5 Gbps";
2634*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_5G:   return "5 Gbps";
2635*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_10G:  return "10 Gbps";
2636*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_20G:  return "20 Gbps";
2637*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_25G:  return "25 Gbps";
2638*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_40G:  return "40 Gbps";
2639*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_50G:  return "50 Gbps";
2640*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_56G:  return "56 Gbps";
2641*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_100G: return "100 Gbps";
2642*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_200G: return "200 Gbps";
2643*2d9fd380Sjfb8856606 	case ETH_SPEED_NUM_UNKNOWN: return "Unknown";
2644*2d9fd380Sjfb8856606 	default: return "Invalid";
2645*2d9fd380Sjfb8856606 	}
2646*2d9fd380Sjfb8856606 }
2647*2d9fd380Sjfb8856606 
2648*2d9fd380Sjfb8856606 int
rte_eth_link_to_str(char * str,size_t len,const struct rte_eth_link * eth_link)2649*2d9fd380Sjfb8856606 rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
2650*2d9fd380Sjfb8856606 {
2651*2d9fd380Sjfb8856606 	if (eth_link->link_status == ETH_LINK_DOWN)
2652*2d9fd380Sjfb8856606 		return snprintf(str, len, "Link down");
2653*2d9fd380Sjfb8856606 	else
2654*2d9fd380Sjfb8856606 		return snprintf(str, len, "Link up at %s %s %s",
2655*2d9fd380Sjfb8856606 			rte_eth_link_speed_to_str(eth_link->link_speed),
2656*2d9fd380Sjfb8856606 			(eth_link->link_duplex == ETH_LINK_FULL_DUPLEX) ?
2657*2d9fd380Sjfb8856606 			"FDX" : "HDX",
2658*2d9fd380Sjfb8856606 			(eth_link->link_autoneg == ETH_LINK_AUTONEG) ?
2659*2d9fd380Sjfb8856606 			"Autoneg" : "Fixed");
2660*2d9fd380Sjfb8856606 }
2661*2d9fd380Sjfb8856606 
2662d30ea906Sjfb8856606 int
rte_eth_stats_get(uint16_t port_id,struct rte_eth_stats * stats)2663d30ea906Sjfb8856606 rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
2664d30ea906Sjfb8856606 {
2665d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
2666d30ea906Sjfb8856606 
2667*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2668d30ea906Sjfb8856606 
2669d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2670d30ea906Sjfb8856606 	memset(stats, 0, sizeof(*stats));
2671d30ea906Sjfb8856606 
2672d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);
2673d30ea906Sjfb8856606 	stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
2674d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->stats_get)(dev, stats));
2675d30ea906Sjfb8856606 }
2676d30ea906Sjfb8856606 
2677d30ea906Sjfb8856606 int
rte_eth_stats_reset(uint16_t port_id)2678d30ea906Sjfb8856606 rte_eth_stats_reset(uint16_t port_id)
2679d30ea906Sjfb8856606 {
2680d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
26814418919fSjohnjiang 	int ret;
2682d30ea906Sjfb8856606 
2683d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2684d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2685d30ea906Sjfb8856606 
2686d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_reset, -ENOTSUP);
26874418919fSjohnjiang 	ret = (*dev->dev_ops->stats_reset)(dev);
26884418919fSjohnjiang 	if (ret != 0)
26894418919fSjohnjiang 		return eth_err(port_id, ret);
26904418919fSjohnjiang 
2691d30ea906Sjfb8856606 	dev->data->rx_mbuf_alloc_failed = 0;
2692d30ea906Sjfb8856606 
2693d30ea906Sjfb8856606 	return 0;
2694d30ea906Sjfb8856606 }
2695d30ea906Sjfb8856606 
2696d30ea906Sjfb8856606 static inline int
eth_dev_get_xstats_basic_count(struct rte_eth_dev * dev)2697*2d9fd380Sjfb8856606 eth_dev_get_xstats_basic_count(struct rte_eth_dev *dev)
2698d30ea906Sjfb8856606 {
2699d30ea906Sjfb8856606 	uint16_t nb_rxqs, nb_txqs;
2700d30ea906Sjfb8856606 	int count;
2701d30ea906Sjfb8856606 
2702d30ea906Sjfb8856606 	nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
2703d30ea906Sjfb8856606 	nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
2704d30ea906Sjfb8856606 
2705d30ea906Sjfb8856606 	count = RTE_NB_STATS;
2706*2d9fd380Sjfb8856606 	if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) {
2707d30ea906Sjfb8856606 		count += nb_rxqs * RTE_NB_RXQ_STATS;
2708d30ea906Sjfb8856606 		count += nb_txqs * RTE_NB_TXQ_STATS;
2709*2d9fd380Sjfb8856606 	}
2710d30ea906Sjfb8856606 
2711d30ea906Sjfb8856606 	return count;
2712d30ea906Sjfb8856606 }
2713d30ea906Sjfb8856606 
2714d30ea906Sjfb8856606 static int
eth_dev_get_xstats_count(uint16_t port_id)2715*2d9fd380Sjfb8856606 eth_dev_get_xstats_count(uint16_t port_id)
2716d30ea906Sjfb8856606 {
2717d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
2718d30ea906Sjfb8856606 	int count;
2719d30ea906Sjfb8856606 
2720*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2721d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2722d30ea906Sjfb8856606 	if (dev->dev_ops->xstats_get_names_by_id != NULL) {
2723d30ea906Sjfb8856606 		count = (*dev->dev_ops->xstats_get_names_by_id)(dev, NULL,
2724d30ea906Sjfb8856606 				NULL, 0);
2725d30ea906Sjfb8856606 		if (count < 0)
2726d30ea906Sjfb8856606 			return eth_err(port_id, count);
2727d30ea906Sjfb8856606 	}
2728d30ea906Sjfb8856606 	if (dev->dev_ops->xstats_get_names != NULL) {
2729d30ea906Sjfb8856606 		count = (*dev->dev_ops->xstats_get_names)(dev, NULL, 0);
2730d30ea906Sjfb8856606 		if (count < 0)
2731d30ea906Sjfb8856606 			return eth_err(port_id, count);
2732d30ea906Sjfb8856606 	} else
2733d30ea906Sjfb8856606 		count = 0;
2734d30ea906Sjfb8856606 
2735d30ea906Sjfb8856606 
2736*2d9fd380Sjfb8856606 	count += eth_dev_get_xstats_basic_count(dev);
2737d30ea906Sjfb8856606 
2738d30ea906Sjfb8856606 	return count;
2739d30ea906Sjfb8856606 }
2740d30ea906Sjfb8856606 
2741d30ea906Sjfb8856606 int
rte_eth_xstats_get_id_by_name(uint16_t port_id,const char * xstat_name,uint64_t * id)2742d30ea906Sjfb8856606 rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
2743d30ea906Sjfb8856606 		uint64_t *id)
2744d30ea906Sjfb8856606 {
2745d30ea906Sjfb8856606 	int cnt_xstats, idx_xstat;
2746d30ea906Sjfb8856606 
2747d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2748d30ea906Sjfb8856606 
2749d30ea906Sjfb8856606 	if (!id) {
2750d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Id pointer is NULL\n");
2751d30ea906Sjfb8856606 		return -ENOMEM;
2752d30ea906Sjfb8856606 	}
2753d30ea906Sjfb8856606 
2754d30ea906Sjfb8856606 	if (!xstat_name) {
2755d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "xstat_name pointer is NULL\n");
2756d30ea906Sjfb8856606 		return -ENOMEM;
2757d30ea906Sjfb8856606 	}
2758d30ea906Sjfb8856606 
2759d30ea906Sjfb8856606 	/* Get count */
2760d30ea906Sjfb8856606 	cnt_xstats = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
2761d30ea906Sjfb8856606 	if (cnt_xstats  < 0) {
2762d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Cannot get count of xstats\n");
2763d30ea906Sjfb8856606 		return -ENODEV;
2764d30ea906Sjfb8856606 	}
2765d30ea906Sjfb8856606 
2766d30ea906Sjfb8856606 	/* Get id-name lookup table */
2767d30ea906Sjfb8856606 	struct rte_eth_xstat_name xstats_names[cnt_xstats];
2768d30ea906Sjfb8856606 
2769d30ea906Sjfb8856606 	if (cnt_xstats != rte_eth_xstats_get_names_by_id(
2770d30ea906Sjfb8856606 			port_id, xstats_names, cnt_xstats, NULL)) {
2771d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Cannot get xstats lookup\n");
2772d30ea906Sjfb8856606 		return -1;
2773d30ea906Sjfb8856606 	}
2774d30ea906Sjfb8856606 
2775d30ea906Sjfb8856606 	for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) {
2776d30ea906Sjfb8856606 		if (!strcmp(xstats_names[idx_xstat].name, xstat_name)) {
2777d30ea906Sjfb8856606 			*id = idx_xstat;
2778d30ea906Sjfb8856606 			return 0;
2779d30ea906Sjfb8856606 		};
2780d30ea906Sjfb8856606 	}
2781d30ea906Sjfb8856606 
2782d30ea906Sjfb8856606 	return -EINVAL;
2783d30ea906Sjfb8856606 }
2784d30ea906Sjfb8856606 
2785d30ea906Sjfb8856606 /* retrieve basic stats names */
2786d30ea906Sjfb8856606 static int
eth_basic_stats_get_names(struct rte_eth_dev * dev,struct rte_eth_xstat_name * xstats_names)2787*2d9fd380Sjfb8856606 eth_basic_stats_get_names(struct rte_eth_dev *dev,
2788d30ea906Sjfb8856606 	struct rte_eth_xstat_name *xstats_names)
2789d30ea906Sjfb8856606 {
2790d30ea906Sjfb8856606 	int cnt_used_entries = 0;
2791d30ea906Sjfb8856606 	uint32_t idx, id_queue;
2792d30ea906Sjfb8856606 	uint16_t num_q;
2793d30ea906Sjfb8856606 
2794d30ea906Sjfb8856606 	for (idx = 0; idx < RTE_NB_STATS; idx++) {
27954418919fSjohnjiang 		strlcpy(xstats_names[cnt_used_entries].name,
2796*2d9fd380Sjfb8856606 			eth_dev_stats_strings[idx].name,
27974418919fSjohnjiang 			sizeof(xstats_names[0].name));
2798d30ea906Sjfb8856606 		cnt_used_entries++;
2799d30ea906Sjfb8856606 	}
2800*2d9fd380Sjfb8856606 
2801*2d9fd380Sjfb8856606 	if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0)
2802*2d9fd380Sjfb8856606 		return cnt_used_entries;
2803*2d9fd380Sjfb8856606 
2804d30ea906Sjfb8856606 	num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
2805d30ea906Sjfb8856606 	for (id_queue = 0; id_queue < num_q; id_queue++) {
2806d30ea906Sjfb8856606 		for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) {
2807d30ea906Sjfb8856606 			snprintf(xstats_names[cnt_used_entries].name,
2808d30ea906Sjfb8856606 				sizeof(xstats_names[0].name),
2809*2d9fd380Sjfb8856606 				"rx_q%u_%s",
2810*2d9fd380Sjfb8856606 				id_queue, eth_dev_rxq_stats_strings[idx].name);
2811d30ea906Sjfb8856606 			cnt_used_entries++;
2812d30ea906Sjfb8856606 		}
2813d30ea906Sjfb8856606 
2814d30ea906Sjfb8856606 	}
2815d30ea906Sjfb8856606 	num_q = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
2816d30ea906Sjfb8856606 	for (id_queue = 0; id_queue < num_q; id_queue++) {
2817d30ea906Sjfb8856606 		for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) {
2818d30ea906Sjfb8856606 			snprintf(xstats_names[cnt_used_entries].name,
2819d30ea906Sjfb8856606 				sizeof(xstats_names[0].name),
2820*2d9fd380Sjfb8856606 				"tx_q%u_%s",
2821*2d9fd380Sjfb8856606 				id_queue, eth_dev_txq_stats_strings[idx].name);
2822d30ea906Sjfb8856606 			cnt_used_entries++;
2823d30ea906Sjfb8856606 		}
2824d30ea906Sjfb8856606 	}
2825d30ea906Sjfb8856606 	return cnt_used_entries;
2826d30ea906Sjfb8856606 }
2827d30ea906Sjfb8856606 
2828d30ea906Sjfb8856606 /* retrieve ethdev extended statistics names */
2829d30ea906Sjfb8856606 int
rte_eth_xstats_get_names_by_id(uint16_t port_id,struct rte_eth_xstat_name * xstats_names,unsigned int size,uint64_t * ids)2830d30ea906Sjfb8856606 rte_eth_xstats_get_names_by_id(uint16_t port_id,
2831d30ea906Sjfb8856606 	struct rte_eth_xstat_name *xstats_names, unsigned int size,
2832d30ea906Sjfb8856606 	uint64_t *ids)
2833d30ea906Sjfb8856606 {
2834d30ea906Sjfb8856606 	struct rte_eth_xstat_name *xstats_names_copy;
2835d30ea906Sjfb8856606 	unsigned int no_basic_stat_requested = 1;
2836d30ea906Sjfb8856606 	unsigned int no_ext_stat_requested = 1;
2837d30ea906Sjfb8856606 	unsigned int expected_entries;
2838d30ea906Sjfb8856606 	unsigned int basic_count;
2839d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
2840d30ea906Sjfb8856606 	unsigned int i;
2841d30ea906Sjfb8856606 	int ret;
2842d30ea906Sjfb8856606 
2843d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2844d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2845d30ea906Sjfb8856606 
2846*2d9fd380Sjfb8856606 	basic_count = eth_dev_get_xstats_basic_count(dev);
2847*2d9fd380Sjfb8856606 	ret = eth_dev_get_xstats_count(port_id);
2848d30ea906Sjfb8856606 	if (ret < 0)
2849d30ea906Sjfb8856606 		return ret;
2850d30ea906Sjfb8856606 	expected_entries = (unsigned int)ret;
2851d30ea906Sjfb8856606 
2852d30ea906Sjfb8856606 	/* Return max number of stats if no ids given */
2853d30ea906Sjfb8856606 	if (!ids) {
2854d30ea906Sjfb8856606 		if (!xstats_names)
2855d30ea906Sjfb8856606 			return expected_entries;
2856d30ea906Sjfb8856606 		else if (xstats_names && size < expected_entries)
2857d30ea906Sjfb8856606 			return expected_entries;
2858d30ea906Sjfb8856606 	}
2859d30ea906Sjfb8856606 
2860d30ea906Sjfb8856606 	if (ids && !xstats_names)
2861d30ea906Sjfb8856606 		return -EINVAL;
2862d30ea906Sjfb8856606 
2863d30ea906Sjfb8856606 	if (ids && dev->dev_ops->xstats_get_names_by_id != NULL && size > 0) {
2864d30ea906Sjfb8856606 		uint64_t ids_copy[size];
2865d30ea906Sjfb8856606 
2866d30ea906Sjfb8856606 		for (i = 0; i < size; i++) {
2867d30ea906Sjfb8856606 			if (ids[i] < basic_count) {
2868d30ea906Sjfb8856606 				no_basic_stat_requested = 0;
2869d30ea906Sjfb8856606 				break;
2870d30ea906Sjfb8856606 			}
2871d30ea906Sjfb8856606 
2872d30ea906Sjfb8856606 			/*
2873d30ea906Sjfb8856606 			 * Convert ids to xstats ids that PMD knows.
2874d30ea906Sjfb8856606 			 * ids known by user are basic + extended stats.
2875d30ea906Sjfb8856606 			 */
2876d30ea906Sjfb8856606 			ids_copy[i] = ids[i] - basic_count;
2877d30ea906Sjfb8856606 		}
2878d30ea906Sjfb8856606 
2879d30ea906Sjfb8856606 		if (no_basic_stat_requested)
2880d30ea906Sjfb8856606 			return (*dev->dev_ops->xstats_get_names_by_id)(dev,
2881d30ea906Sjfb8856606 					xstats_names, ids_copy, size);
2882d30ea906Sjfb8856606 	}
2883d30ea906Sjfb8856606 
2884d30ea906Sjfb8856606 	/* Retrieve all stats */
2885d30ea906Sjfb8856606 	if (!ids) {
2886d30ea906Sjfb8856606 		int num_stats = rte_eth_xstats_get_names(port_id, xstats_names,
2887d30ea906Sjfb8856606 				expected_entries);
2888d30ea906Sjfb8856606 		if (num_stats < 0 || num_stats > (int)expected_entries)
2889d30ea906Sjfb8856606 			return num_stats;
2890d30ea906Sjfb8856606 		else
2891d30ea906Sjfb8856606 			return expected_entries;
2892d30ea906Sjfb8856606 	}
2893d30ea906Sjfb8856606 
2894d30ea906Sjfb8856606 	xstats_names_copy = calloc(expected_entries,
2895d30ea906Sjfb8856606 		sizeof(struct rte_eth_xstat_name));
2896d30ea906Sjfb8856606 
2897d30ea906Sjfb8856606 	if (!xstats_names_copy) {
2898d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Can't allocate memory\n");
2899d30ea906Sjfb8856606 		return -ENOMEM;
2900d30ea906Sjfb8856606 	}
2901d30ea906Sjfb8856606 
2902d30ea906Sjfb8856606 	if (ids) {
2903d30ea906Sjfb8856606 		for (i = 0; i < size; i++) {
2904d30ea906Sjfb8856606 			if (ids[i] >= basic_count) {
2905d30ea906Sjfb8856606 				no_ext_stat_requested = 0;
2906d30ea906Sjfb8856606 				break;
2907d30ea906Sjfb8856606 			}
2908d30ea906Sjfb8856606 		}
2909d30ea906Sjfb8856606 	}
2910d30ea906Sjfb8856606 
2911d30ea906Sjfb8856606 	/* Fill xstats_names_copy structure */
2912d30ea906Sjfb8856606 	if (ids && no_ext_stat_requested) {
2913*2d9fd380Sjfb8856606 		eth_basic_stats_get_names(dev, xstats_names_copy);
2914d30ea906Sjfb8856606 	} else {
2915d30ea906Sjfb8856606 		ret = rte_eth_xstats_get_names(port_id, xstats_names_copy,
2916d30ea906Sjfb8856606 			expected_entries);
2917d30ea906Sjfb8856606 		if (ret < 0) {
2918d30ea906Sjfb8856606 			free(xstats_names_copy);
2919d30ea906Sjfb8856606 			return ret;
2920d30ea906Sjfb8856606 		}
2921d30ea906Sjfb8856606 	}
2922d30ea906Sjfb8856606 
2923d30ea906Sjfb8856606 	/* Filter stats */
2924d30ea906Sjfb8856606 	for (i = 0; i < size; i++) {
2925d30ea906Sjfb8856606 		if (ids[i] >= expected_entries) {
2926d30ea906Sjfb8856606 			RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n");
2927d30ea906Sjfb8856606 			free(xstats_names_copy);
2928d30ea906Sjfb8856606 			return -1;
2929d30ea906Sjfb8856606 		}
2930d30ea906Sjfb8856606 		xstats_names[i] = xstats_names_copy[ids[i]];
2931d30ea906Sjfb8856606 	}
2932d30ea906Sjfb8856606 
2933d30ea906Sjfb8856606 	free(xstats_names_copy);
2934d30ea906Sjfb8856606 	return size;
2935d30ea906Sjfb8856606 }
2936d30ea906Sjfb8856606 
2937d30ea906Sjfb8856606 int
rte_eth_xstats_get_names(uint16_t port_id,struct rte_eth_xstat_name * xstats_names,unsigned int size)2938d30ea906Sjfb8856606 rte_eth_xstats_get_names(uint16_t port_id,
2939d30ea906Sjfb8856606 	struct rte_eth_xstat_name *xstats_names,
2940d30ea906Sjfb8856606 	unsigned int size)
2941d30ea906Sjfb8856606 {
2942d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
2943d30ea906Sjfb8856606 	int cnt_used_entries;
2944d30ea906Sjfb8856606 	int cnt_expected_entries;
2945d30ea906Sjfb8856606 	int cnt_driver_entries;
2946d30ea906Sjfb8856606 
2947*2d9fd380Sjfb8856606 	cnt_expected_entries = eth_dev_get_xstats_count(port_id);
2948d30ea906Sjfb8856606 	if (xstats_names == NULL || cnt_expected_entries < 0 ||
2949d30ea906Sjfb8856606 			(int)size < cnt_expected_entries)
2950d30ea906Sjfb8856606 		return cnt_expected_entries;
2951d30ea906Sjfb8856606 
2952*2d9fd380Sjfb8856606 	/* port_id checked in eth_dev_get_xstats_count() */
2953d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2954d30ea906Sjfb8856606 
2955*2d9fd380Sjfb8856606 	cnt_used_entries = eth_basic_stats_get_names(dev, xstats_names);
2956d30ea906Sjfb8856606 
2957d30ea906Sjfb8856606 	if (dev->dev_ops->xstats_get_names != NULL) {
2958d30ea906Sjfb8856606 		/* If there are any driver-specific xstats, append them
2959d30ea906Sjfb8856606 		 * to end of list.
2960d30ea906Sjfb8856606 		 */
2961d30ea906Sjfb8856606 		cnt_driver_entries = (*dev->dev_ops->xstats_get_names)(
2962d30ea906Sjfb8856606 			dev,
2963d30ea906Sjfb8856606 			xstats_names + cnt_used_entries,
2964d30ea906Sjfb8856606 			size - cnt_used_entries);
2965d30ea906Sjfb8856606 		if (cnt_driver_entries < 0)
2966d30ea906Sjfb8856606 			return eth_err(port_id, cnt_driver_entries);
2967d30ea906Sjfb8856606 		cnt_used_entries += cnt_driver_entries;
2968d30ea906Sjfb8856606 	}
2969d30ea906Sjfb8856606 
2970d30ea906Sjfb8856606 	return cnt_used_entries;
2971d30ea906Sjfb8856606 }
2972d30ea906Sjfb8856606 
2973d30ea906Sjfb8856606 
2974d30ea906Sjfb8856606 static int
eth_basic_stats_get(uint16_t port_id,struct rte_eth_xstat * xstats)2975*2d9fd380Sjfb8856606 eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats)
2976d30ea906Sjfb8856606 {
2977d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
2978d30ea906Sjfb8856606 	struct rte_eth_stats eth_stats;
2979d30ea906Sjfb8856606 	unsigned int count = 0, i, q;
2980d30ea906Sjfb8856606 	uint64_t val, *stats_ptr;
2981d30ea906Sjfb8856606 	uint16_t nb_rxqs, nb_txqs;
2982d30ea906Sjfb8856606 	int ret;
2983d30ea906Sjfb8856606 
2984d30ea906Sjfb8856606 	ret = rte_eth_stats_get(port_id, &eth_stats);
2985d30ea906Sjfb8856606 	if (ret < 0)
2986d30ea906Sjfb8856606 		return ret;
2987d30ea906Sjfb8856606 
2988d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
2989d30ea906Sjfb8856606 
2990d30ea906Sjfb8856606 	nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
2991d30ea906Sjfb8856606 	nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
2992d30ea906Sjfb8856606 
2993d30ea906Sjfb8856606 	/* global stats */
2994d30ea906Sjfb8856606 	for (i = 0; i < RTE_NB_STATS; i++) {
2995d30ea906Sjfb8856606 		stats_ptr = RTE_PTR_ADD(&eth_stats,
2996*2d9fd380Sjfb8856606 					eth_dev_stats_strings[i].offset);
2997d30ea906Sjfb8856606 		val = *stats_ptr;
2998d30ea906Sjfb8856606 		xstats[count++].value = val;
2999d30ea906Sjfb8856606 	}
3000d30ea906Sjfb8856606 
3001*2d9fd380Sjfb8856606 	if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0)
3002*2d9fd380Sjfb8856606 		return count;
3003*2d9fd380Sjfb8856606 
3004d30ea906Sjfb8856606 	/* per-rxq stats */
3005d30ea906Sjfb8856606 	for (q = 0; q < nb_rxqs; q++) {
3006d30ea906Sjfb8856606 		for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
3007d30ea906Sjfb8856606 			stats_ptr = RTE_PTR_ADD(&eth_stats,
3008*2d9fd380Sjfb8856606 					eth_dev_rxq_stats_strings[i].offset +
3009d30ea906Sjfb8856606 					q * sizeof(uint64_t));
3010d30ea906Sjfb8856606 			val = *stats_ptr;
3011d30ea906Sjfb8856606 			xstats[count++].value = val;
3012d30ea906Sjfb8856606 		}
3013d30ea906Sjfb8856606 	}
3014d30ea906Sjfb8856606 
3015d30ea906Sjfb8856606 	/* per-txq stats */
3016d30ea906Sjfb8856606 	for (q = 0; q < nb_txqs; q++) {
3017d30ea906Sjfb8856606 		for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
3018d30ea906Sjfb8856606 			stats_ptr = RTE_PTR_ADD(&eth_stats,
3019*2d9fd380Sjfb8856606 					eth_dev_txq_stats_strings[i].offset +
3020d30ea906Sjfb8856606 					q * sizeof(uint64_t));
3021d30ea906Sjfb8856606 			val = *stats_ptr;
3022d30ea906Sjfb8856606 			xstats[count++].value = val;
3023d30ea906Sjfb8856606 		}
3024d30ea906Sjfb8856606 	}
3025d30ea906Sjfb8856606 	return count;
3026d30ea906Sjfb8856606 }
3027d30ea906Sjfb8856606 
3028d30ea906Sjfb8856606 /* retrieve ethdev extended statistics */
3029d30ea906Sjfb8856606 int
rte_eth_xstats_get_by_id(uint16_t port_id,const uint64_t * ids,uint64_t * values,unsigned int size)3030d30ea906Sjfb8856606 rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
3031d30ea906Sjfb8856606 			 uint64_t *values, unsigned int size)
3032d30ea906Sjfb8856606 {
3033d30ea906Sjfb8856606 	unsigned int no_basic_stat_requested = 1;
3034d30ea906Sjfb8856606 	unsigned int no_ext_stat_requested = 1;
3035d30ea906Sjfb8856606 	unsigned int num_xstats_filled;
3036d30ea906Sjfb8856606 	unsigned int basic_count;
3037d30ea906Sjfb8856606 	uint16_t expected_entries;
3038d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3039d30ea906Sjfb8856606 	unsigned int i;
3040d30ea906Sjfb8856606 	int ret;
3041d30ea906Sjfb8856606 
3042d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3043*2d9fd380Sjfb8856606 	ret = eth_dev_get_xstats_count(port_id);
3044d30ea906Sjfb8856606 	if (ret < 0)
3045d30ea906Sjfb8856606 		return ret;
3046d30ea906Sjfb8856606 	expected_entries = (uint16_t)ret;
3047d30ea906Sjfb8856606 	struct rte_eth_xstat xstats[expected_entries];
3048d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3049*2d9fd380Sjfb8856606 	basic_count = eth_dev_get_xstats_basic_count(dev);
3050d30ea906Sjfb8856606 
3051d30ea906Sjfb8856606 	/* Return max number of stats if no ids given */
3052d30ea906Sjfb8856606 	if (!ids) {
3053d30ea906Sjfb8856606 		if (!values)
3054d30ea906Sjfb8856606 			return expected_entries;
3055d30ea906Sjfb8856606 		else if (values && size < expected_entries)
3056d30ea906Sjfb8856606 			return expected_entries;
3057d30ea906Sjfb8856606 	}
3058d30ea906Sjfb8856606 
3059d30ea906Sjfb8856606 	if (ids && !values)
3060d30ea906Sjfb8856606 		return -EINVAL;
3061d30ea906Sjfb8856606 
3062d30ea906Sjfb8856606 	if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) {
3063*2d9fd380Sjfb8856606 		unsigned int basic_count = eth_dev_get_xstats_basic_count(dev);
3064d30ea906Sjfb8856606 		uint64_t ids_copy[size];
3065d30ea906Sjfb8856606 
3066d30ea906Sjfb8856606 		for (i = 0; i < size; i++) {
3067d30ea906Sjfb8856606 			if (ids[i] < basic_count) {
3068d30ea906Sjfb8856606 				no_basic_stat_requested = 0;
3069d30ea906Sjfb8856606 				break;
3070d30ea906Sjfb8856606 			}
3071d30ea906Sjfb8856606 
3072d30ea906Sjfb8856606 			/*
3073d30ea906Sjfb8856606 			 * Convert ids to xstats ids that PMD knows.
3074d30ea906Sjfb8856606 			 * ids known by user are basic + extended stats.
3075d30ea906Sjfb8856606 			 */
3076d30ea906Sjfb8856606 			ids_copy[i] = ids[i] - basic_count;
3077d30ea906Sjfb8856606 		}
3078d30ea906Sjfb8856606 
3079d30ea906Sjfb8856606 		if (no_basic_stat_requested)
3080d30ea906Sjfb8856606 			return (*dev->dev_ops->xstats_get_by_id)(dev, ids_copy,
3081d30ea906Sjfb8856606 					values, size);
3082d30ea906Sjfb8856606 	}
3083d30ea906Sjfb8856606 
3084d30ea906Sjfb8856606 	if (ids) {
3085d30ea906Sjfb8856606 		for (i = 0; i < size; i++) {
3086d30ea906Sjfb8856606 			if (ids[i] >= basic_count) {
3087d30ea906Sjfb8856606 				no_ext_stat_requested = 0;
3088d30ea906Sjfb8856606 				break;
3089d30ea906Sjfb8856606 			}
3090d30ea906Sjfb8856606 		}
3091d30ea906Sjfb8856606 	}
3092d30ea906Sjfb8856606 
3093d30ea906Sjfb8856606 	/* Fill the xstats structure */
3094d30ea906Sjfb8856606 	if (ids && no_ext_stat_requested)
3095*2d9fd380Sjfb8856606 		ret = eth_basic_stats_get(port_id, xstats);
3096d30ea906Sjfb8856606 	else
3097d30ea906Sjfb8856606 		ret = rte_eth_xstats_get(port_id, xstats, expected_entries);
3098d30ea906Sjfb8856606 
3099d30ea906Sjfb8856606 	if (ret < 0)
3100d30ea906Sjfb8856606 		return ret;
3101d30ea906Sjfb8856606 	num_xstats_filled = (unsigned int)ret;
3102d30ea906Sjfb8856606 
3103d30ea906Sjfb8856606 	/* Return all stats */
3104d30ea906Sjfb8856606 	if (!ids) {
3105d30ea906Sjfb8856606 		for (i = 0; i < num_xstats_filled; i++)
3106d30ea906Sjfb8856606 			values[i] = xstats[i].value;
3107d30ea906Sjfb8856606 		return expected_entries;
3108d30ea906Sjfb8856606 	}
3109d30ea906Sjfb8856606 
3110d30ea906Sjfb8856606 	/* Filter stats */
3111d30ea906Sjfb8856606 	for (i = 0; i < size; i++) {
3112d30ea906Sjfb8856606 		if (ids[i] >= expected_entries) {
3113d30ea906Sjfb8856606 			RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n");
3114d30ea906Sjfb8856606 			return -1;
3115d30ea906Sjfb8856606 		}
3116d30ea906Sjfb8856606 		values[i] = xstats[ids[i]].value;
3117d30ea906Sjfb8856606 	}
3118d30ea906Sjfb8856606 	return size;
3119d30ea906Sjfb8856606 }
3120d30ea906Sjfb8856606 
3121d30ea906Sjfb8856606 int
rte_eth_xstats_get(uint16_t port_id,struct rte_eth_xstat * xstats,unsigned int n)3122d30ea906Sjfb8856606 rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats,
3123d30ea906Sjfb8856606 	unsigned int n)
3124d30ea906Sjfb8856606 {
3125d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3126d30ea906Sjfb8856606 	unsigned int count = 0, i;
3127d30ea906Sjfb8856606 	signed int xcount = 0;
3128d30ea906Sjfb8856606 	uint16_t nb_rxqs, nb_txqs;
3129d30ea906Sjfb8856606 	int ret;
3130d30ea906Sjfb8856606 
3131*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3132d30ea906Sjfb8856606 
3133d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3134d30ea906Sjfb8856606 
3135d30ea906Sjfb8856606 	nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
3136d30ea906Sjfb8856606 	nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
3137d30ea906Sjfb8856606 
3138d30ea906Sjfb8856606 	/* Return generic statistics */
3139*2d9fd380Sjfb8856606 	count = RTE_NB_STATS;
3140*2d9fd380Sjfb8856606 	if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS)
3141*2d9fd380Sjfb8856606 		count += (nb_rxqs * RTE_NB_RXQ_STATS) + (nb_txqs * RTE_NB_TXQ_STATS);
3142d30ea906Sjfb8856606 
3143d30ea906Sjfb8856606 	/* implemented by the driver */
3144d30ea906Sjfb8856606 	if (dev->dev_ops->xstats_get != NULL) {
3145d30ea906Sjfb8856606 		/* Retrieve the xstats from the driver at the end of the
3146d30ea906Sjfb8856606 		 * xstats struct.
3147d30ea906Sjfb8856606 		 */
3148d30ea906Sjfb8856606 		xcount = (*dev->dev_ops->xstats_get)(dev,
3149d30ea906Sjfb8856606 				     xstats ? xstats + count : NULL,
3150d30ea906Sjfb8856606 				     (n > count) ? n - count : 0);
3151d30ea906Sjfb8856606 
3152d30ea906Sjfb8856606 		if (xcount < 0)
3153d30ea906Sjfb8856606 			return eth_err(port_id, xcount);
3154d30ea906Sjfb8856606 	}
3155d30ea906Sjfb8856606 
3156d30ea906Sjfb8856606 	if (n < count + xcount || xstats == NULL)
3157d30ea906Sjfb8856606 		return count + xcount;
3158d30ea906Sjfb8856606 
3159d30ea906Sjfb8856606 	/* now fill the xstats structure */
3160*2d9fd380Sjfb8856606 	ret = eth_basic_stats_get(port_id, xstats);
3161d30ea906Sjfb8856606 	if (ret < 0)
3162d30ea906Sjfb8856606 		return ret;
3163d30ea906Sjfb8856606 	count = ret;
3164d30ea906Sjfb8856606 
3165d30ea906Sjfb8856606 	for (i = 0; i < count; i++)
3166d30ea906Sjfb8856606 		xstats[i].id = i;
3167d30ea906Sjfb8856606 	/* add an offset to driver-specific stats */
3168d30ea906Sjfb8856606 	for ( ; i < count + xcount; i++)
3169d30ea906Sjfb8856606 		xstats[i].id += count;
3170d30ea906Sjfb8856606 
3171d30ea906Sjfb8856606 	return count + xcount;
3172d30ea906Sjfb8856606 }
3173d30ea906Sjfb8856606 
3174d30ea906Sjfb8856606 /* reset ethdev extended statistics */
31754418919fSjohnjiang int
rte_eth_xstats_reset(uint16_t port_id)3176d30ea906Sjfb8856606 rte_eth_xstats_reset(uint16_t port_id)
3177d30ea906Sjfb8856606 {
3178d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3179d30ea906Sjfb8856606 
31804418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3181d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3182d30ea906Sjfb8856606 
3183d30ea906Sjfb8856606 	/* implemented by the driver */
31844418919fSjohnjiang 	if (dev->dev_ops->xstats_reset != NULL)
31854418919fSjohnjiang 		return eth_err(port_id, (*dev->dev_ops->xstats_reset)(dev));
3186d30ea906Sjfb8856606 
3187d30ea906Sjfb8856606 	/* fallback to default */
31884418919fSjohnjiang 	return rte_eth_stats_reset(port_id);
3189d30ea906Sjfb8856606 }
3190d30ea906Sjfb8856606 
3191d30ea906Sjfb8856606 static int
eth_dev_set_queue_stats_mapping(uint16_t port_id,uint16_t queue_id,uint8_t stat_idx,uint8_t is_rx)3192*2d9fd380Sjfb8856606 eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id,
3193*2d9fd380Sjfb8856606 		uint8_t stat_idx, uint8_t is_rx)
3194d30ea906Sjfb8856606 {
3195d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3196d30ea906Sjfb8856606 
3197d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3198d30ea906Sjfb8856606 
3199d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3200d30ea906Sjfb8856606 
3201d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set, -ENOTSUP);
3202d30ea906Sjfb8856606 
3203d30ea906Sjfb8856606 	if (is_rx && (queue_id >= dev->data->nb_rx_queues))
3204d30ea906Sjfb8856606 		return -EINVAL;
3205d30ea906Sjfb8856606 
3206d30ea906Sjfb8856606 	if (!is_rx && (queue_id >= dev->data->nb_tx_queues))
3207d30ea906Sjfb8856606 		return -EINVAL;
3208d30ea906Sjfb8856606 
3209d30ea906Sjfb8856606 	if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
3210d30ea906Sjfb8856606 		return -EINVAL;
3211d30ea906Sjfb8856606 
3212d30ea906Sjfb8856606 	return (*dev->dev_ops->queue_stats_mapping_set)
3213d30ea906Sjfb8856606 			(dev, queue_id, stat_idx, is_rx);
3214d30ea906Sjfb8856606 }
3215d30ea906Sjfb8856606 
3216d30ea906Sjfb8856606 
3217d30ea906Sjfb8856606 int
rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id,uint16_t tx_queue_id,uint8_t stat_idx)3218d30ea906Sjfb8856606 rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id,
3219d30ea906Sjfb8856606 		uint8_t stat_idx)
3220d30ea906Sjfb8856606 {
3221*2d9fd380Sjfb8856606 	return eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
3222*2d9fd380Sjfb8856606 						tx_queue_id,
3223d30ea906Sjfb8856606 						stat_idx, STAT_QMAP_TX));
3224d30ea906Sjfb8856606 }
3225d30ea906Sjfb8856606 
3226d30ea906Sjfb8856606 
3227d30ea906Sjfb8856606 int
rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,uint16_t rx_queue_id,uint8_t stat_idx)3228d30ea906Sjfb8856606 rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id,
3229d30ea906Sjfb8856606 		uint8_t stat_idx)
3230d30ea906Sjfb8856606 {
3231*2d9fd380Sjfb8856606 	return eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
3232*2d9fd380Sjfb8856606 						rx_queue_id,
3233d30ea906Sjfb8856606 						stat_idx, STAT_QMAP_RX));
3234d30ea906Sjfb8856606 }
3235d30ea906Sjfb8856606 
3236d30ea906Sjfb8856606 int
rte_eth_dev_fw_version_get(uint16_t port_id,char * fw_version,size_t fw_size)3237d30ea906Sjfb8856606 rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
3238d30ea906Sjfb8856606 {
3239d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3240d30ea906Sjfb8856606 
3241d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3242d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3243d30ea906Sjfb8856606 
3244d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
3245d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev,
3246d30ea906Sjfb8856606 							fw_version, fw_size));
3247d30ea906Sjfb8856606 }
3248d30ea906Sjfb8856606 
32494418919fSjohnjiang int
rte_eth_dev_info_get(uint16_t port_id,struct rte_eth_dev_info * dev_info)3250d30ea906Sjfb8856606 rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
3251d30ea906Sjfb8856606 {
3252d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3253d30ea906Sjfb8856606 	const struct rte_eth_desc_lim lim = {
3254d30ea906Sjfb8856606 		.nb_max = UINT16_MAX,
3255d30ea906Sjfb8856606 		.nb_min = 0,
3256d30ea906Sjfb8856606 		.nb_align = 1,
32574418919fSjohnjiang 		.nb_seg_max = UINT16_MAX,
32584418919fSjohnjiang 		.nb_mtu_seg_max = UINT16_MAX,
3259d30ea906Sjfb8856606 	};
32604418919fSjohnjiang 	int diag;
3261d30ea906Sjfb8856606 
32624b05018fSfengbojiang 	/*
32634b05018fSfengbojiang 	 * Init dev_info before port_id check since caller does not have
32644b05018fSfengbojiang 	 * return status and does not know if get is successful or not.
32654b05018fSfengbojiang 	 */
32664b05018fSfengbojiang 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
32674418919fSjohnjiang 	dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
32684b05018fSfengbojiang 
32694418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3270d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3271d30ea906Sjfb8856606 
3272d30ea906Sjfb8856606 	dev_info->rx_desc_lim = lim;
3273d30ea906Sjfb8856606 	dev_info->tx_desc_lim = lim;
3274d30ea906Sjfb8856606 	dev_info->device = dev->device;
32754418919fSjohnjiang 	dev_info->min_mtu = RTE_ETHER_MIN_MTU;
32764418919fSjohnjiang 	dev_info->max_mtu = UINT16_MAX;
3277d30ea906Sjfb8856606 
32784418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
32794418919fSjohnjiang 	diag = (*dev->dev_ops->dev_infos_get)(dev, dev_info);
32804418919fSjohnjiang 	if (diag != 0) {
32814418919fSjohnjiang 		/* Cleanup already filled in device information */
32824418919fSjohnjiang 		memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
32834418919fSjohnjiang 		return eth_err(port_id, diag);
32844418919fSjohnjiang 	}
32854418919fSjohnjiang 
32864418919fSjohnjiang 	/* Maximum number of queues should be <= RTE_MAX_QUEUES_PER_PORT */
32874418919fSjohnjiang 	dev_info->max_rx_queues = RTE_MIN(dev_info->max_rx_queues,
32884418919fSjohnjiang 			RTE_MAX_QUEUES_PER_PORT);
32894418919fSjohnjiang 	dev_info->max_tx_queues = RTE_MIN(dev_info->max_tx_queues,
32904418919fSjohnjiang 			RTE_MAX_QUEUES_PER_PORT);
32914418919fSjohnjiang 
3292d30ea906Sjfb8856606 	dev_info->driver_name = dev->device->driver->name;
3293d30ea906Sjfb8856606 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
3294d30ea906Sjfb8856606 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
3295d30ea906Sjfb8856606 
3296d30ea906Sjfb8856606 	dev_info->dev_flags = &dev->data->dev_flags;
32974418919fSjohnjiang 
32984418919fSjohnjiang 	return 0;
3299d30ea906Sjfb8856606 }
3300d30ea906Sjfb8856606 
3301d30ea906Sjfb8856606 int
rte_eth_dev_get_supported_ptypes(uint16_t port_id,uint32_t ptype_mask,uint32_t * ptypes,int num)3302d30ea906Sjfb8856606 rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
3303d30ea906Sjfb8856606 				 uint32_t *ptypes, int num)
3304d30ea906Sjfb8856606 {
3305d30ea906Sjfb8856606 	int i, j;
3306d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3307d30ea906Sjfb8856606 	const uint32_t *all_ptypes;
3308d30ea906Sjfb8856606 
3309d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3310d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3311d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
3312d30ea906Sjfb8856606 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
3313d30ea906Sjfb8856606 
3314d30ea906Sjfb8856606 	if (!all_ptypes)
3315d30ea906Sjfb8856606 		return 0;
3316d30ea906Sjfb8856606 
3317d30ea906Sjfb8856606 	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
3318d30ea906Sjfb8856606 		if (all_ptypes[i] & ptype_mask) {
3319d30ea906Sjfb8856606 			if (j < num)
3320d30ea906Sjfb8856606 				ptypes[j] = all_ptypes[i];
3321d30ea906Sjfb8856606 			j++;
3322d30ea906Sjfb8856606 		}
3323d30ea906Sjfb8856606 
3324d30ea906Sjfb8856606 	return j;
3325d30ea906Sjfb8856606 }
3326d30ea906Sjfb8856606 
33274418919fSjohnjiang int
rte_eth_dev_set_ptypes(uint16_t port_id,uint32_t ptype_mask,uint32_t * set_ptypes,unsigned int num)33284418919fSjohnjiang rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
33294418919fSjohnjiang 				 uint32_t *set_ptypes, unsigned int num)
33304418919fSjohnjiang {
33314418919fSjohnjiang 	const uint32_t valid_ptype_masks[] = {
33324418919fSjohnjiang 		RTE_PTYPE_L2_MASK,
33334418919fSjohnjiang 		RTE_PTYPE_L3_MASK,
33344418919fSjohnjiang 		RTE_PTYPE_L4_MASK,
33354418919fSjohnjiang 		RTE_PTYPE_TUNNEL_MASK,
33364418919fSjohnjiang 		RTE_PTYPE_INNER_L2_MASK,
33374418919fSjohnjiang 		RTE_PTYPE_INNER_L3_MASK,
33384418919fSjohnjiang 		RTE_PTYPE_INNER_L4_MASK,
33394418919fSjohnjiang 	};
33404418919fSjohnjiang 	const uint32_t *all_ptypes;
33414418919fSjohnjiang 	struct rte_eth_dev *dev;
33424418919fSjohnjiang 	uint32_t unused_mask;
33434418919fSjohnjiang 	unsigned int i, j;
33444418919fSjohnjiang 	int ret;
33454418919fSjohnjiang 
33464418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
33474418919fSjohnjiang 	dev = &rte_eth_devices[port_id];
33484418919fSjohnjiang 
33494418919fSjohnjiang 	if (num > 0 && set_ptypes == NULL)
33504418919fSjohnjiang 		return -EINVAL;
33514418919fSjohnjiang 
33524418919fSjohnjiang 	if (*dev->dev_ops->dev_supported_ptypes_get == NULL ||
33534418919fSjohnjiang 			*dev->dev_ops->dev_ptypes_set == NULL) {
33544418919fSjohnjiang 		ret = 0;
33554418919fSjohnjiang 		goto ptype_unknown;
33564418919fSjohnjiang 	}
33574418919fSjohnjiang 
33584418919fSjohnjiang 	if (ptype_mask == 0) {
33594418919fSjohnjiang 		ret = (*dev->dev_ops->dev_ptypes_set)(dev,
33604418919fSjohnjiang 				ptype_mask);
33614418919fSjohnjiang 		goto ptype_unknown;
33624418919fSjohnjiang 	}
33634418919fSjohnjiang 
33644418919fSjohnjiang 	unused_mask = ptype_mask;
33654418919fSjohnjiang 	for (i = 0; i < RTE_DIM(valid_ptype_masks); i++) {
33664418919fSjohnjiang 		uint32_t mask = ptype_mask & valid_ptype_masks[i];
33674418919fSjohnjiang 		if (mask && mask != valid_ptype_masks[i]) {
33684418919fSjohnjiang 			ret = -EINVAL;
33694418919fSjohnjiang 			goto ptype_unknown;
33704418919fSjohnjiang 		}
33714418919fSjohnjiang 		unused_mask &= ~valid_ptype_masks[i];
33724418919fSjohnjiang 	}
33734418919fSjohnjiang 
33744418919fSjohnjiang 	if (unused_mask) {
33754418919fSjohnjiang 		ret = -EINVAL;
33764418919fSjohnjiang 		goto ptype_unknown;
33774418919fSjohnjiang 	}
33784418919fSjohnjiang 
33794418919fSjohnjiang 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
33804418919fSjohnjiang 	if (all_ptypes == NULL) {
33814418919fSjohnjiang 		ret = 0;
33824418919fSjohnjiang 		goto ptype_unknown;
33834418919fSjohnjiang 	}
33844418919fSjohnjiang 
33854418919fSjohnjiang 	/*
33864418919fSjohnjiang 	 * Accommodate as many set_ptypes as possible. If the supplied
33874418919fSjohnjiang 	 * set_ptypes array is insufficient fill it partially.
33884418919fSjohnjiang 	 */
33894418919fSjohnjiang 	for (i = 0, j = 0; set_ptypes != NULL &&
33904418919fSjohnjiang 				(all_ptypes[i] != RTE_PTYPE_UNKNOWN); ++i) {
33914418919fSjohnjiang 		if (ptype_mask & all_ptypes[i]) {
33924418919fSjohnjiang 			if (j < num - 1) {
33934418919fSjohnjiang 				set_ptypes[j] = all_ptypes[i];
33944418919fSjohnjiang 				j++;
33954418919fSjohnjiang 				continue;
33964418919fSjohnjiang 			}
33974418919fSjohnjiang 			break;
33984418919fSjohnjiang 		}
33994418919fSjohnjiang 	}
34004418919fSjohnjiang 
34014418919fSjohnjiang 	if (set_ptypes != NULL && j < num)
34024418919fSjohnjiang 		set_ptypes[j] = RTE_PTYPE_UNKNOWN;
34034418919fSjohnjiang 
34044418919fSjohnjiang 	return (*dev->dev_ops->dev_ptypes_set)(dev, ptype_mask);
34054418919fSjohnjiang 
34064418919fSjohnjiang ptype_unknown:
34074418919fSjohnjiang 	if (num > 0)
34084418919fSjohnjiang 		set_ptypes[0] = RTE_PTYPE_UNKNOWN;
34094418919fSjohnjiang 
34104418919fSjohnjiang 	return ret;
34114418919fSjohnjiang }
34124418919fSjohnjiang 
34134418919fSjohnjiang int
rte_eth_macaddr_get(uint16_t port_id,struct rte_ether_addr * mac_addr)34144418919fSjohnjiang rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
3415d30ea906Sjfb8856606 {
3416d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3417d30ea906Sjfb8856606 
34184418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3419d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
34204418919fSjohnjiang 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
3421d30ea906Sjfb8856606 
34224418919fSjohnjiang 	return 0;
34234418919fSjohnjiang }
3424d30ea906Sjfb8856606 
3425d30ea906Sjfb8856606 int
rte_eth_dev_get_mtu(uint16_t port_id,uint16_t * mtu)3426d30ea906Sjfb8856606 rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
3427d30ea906Sjfb8856606 {
3428d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3429d30ea906Sjfb8856606 
3430d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3431d30ea906Sjfb8856606 
3432d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3433d30ea906Sjfb8856606 	*mtu = dev->data->mtu;
3434d30ea906Sjfb8856606 	return 0;
3435d30ea906Sjfb8856606 }
3436d30ea906Sjfb8856606 
3437d30ea906Sjfb8856606 int
rte_eth_dev_set_mtu(uint16_t port_id,uint16_t mtu)3438d30ea906Sjfb8856606 rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu)
3439d30ea906Sjfb8856606 {
3440d30ea906Sjfb8856606 	int ret;
34414418919fSjohnjiang 	struct rte_eth_dev_info dev_info;
3442d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3443d30ea906Sjfb8856606 
3444d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3445d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3446d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mtu_set, -ENOTSUP);
3447d30ea906Sjfb8856606 
34484418919fSjohnjiang 	/*
34494418919fSjohnjiang 	 * Check if the device supports dev_infos_get, if it does not
34504418919fSjohnjiang 	 * skip min_mtu/max_mtu validation here as this requires values
34514418919fSjohnjiang 	 * that are populated within the call to rte_eth_dev_info_get()
34524418919fSjohnjiang 	 * which relies on dev->dev_ops->dev_infos_get.
34534418919fSjohnjiang 	 */
34544418919fSjohnjiang 	if (*dev->dev_ops->dev_infos_get != NULL) {
34554418919fSjohnjiang 		ret = rte_eth_dev_info_get(port_id, &dev_info);
34564418919fSjohnjiang 		if (ret != 0)
34574418919fSjohnjiang 			return ret;
34584418919fSjohnjiang 
34594418919fSjohnjiang 		if (mtu < dev_info.min_mtu || mtu > dev_info.max_mtu)
34604418919fSjohnjiang 			return -EINVAL;
34614418919fSjohnjiang 	}
34624418919fSjohnjiang 
3463d30ea906Sjfb8856606 	ret = (*dev->dev_ops->mtu_set)(dev, mtu);
3464d30ea906Sjfb8856606 	if (!ret)
3465d30ea906Sjfb8856606 		dev->data->mtu = mtu;
3466d30ea906Sjfb8856606 
3467d30ea906Sjfb8856606 	return eth_err(port_id, ret);
3468d30ea906Sjfb8856606 }
3469d30ea906Sjfb8856606 
3470d30ea906Sjfb8856606 int
rte_eth_dev_vlan_filter(uint16_t port_id,uint16_t vlan_id,int on)3471d30ea906Sjfb8856606 rte_eth_dev_vlan_filter(uint16_t port_id, uint16_t vlan_id, int on)
3472d30ea906Sjfb8856606 {
3473d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3474d30ea906Sjfb8856606 	int ret;
3475d30ea906Sjfb8856606 
3476d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3477d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3478d30ea906Sjfb8856606 	if (!(dev->data->dev_conf.rxmode.offloads &
3479d30ea906Sjfb8856606 	      DEV_RX_OFFLOAD_VLAN_FILTER)) {
3480d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Port %u: vlan-filtering disabled\n",
3481d30ea906Sjfb8856606 			port_id);
3482d30ea906Sjfb8856606 		return -ENOSYS;
3483d30ea906Sjfb8856606 	}
3484d30ea906Sjfb8856606 
3485d30ea906Sjfb8856606 	if (vlan_id > 4095) {
3486d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Port_id=%u invalid vlan_id=%u > 4095\n",
3487d30ea906Sjfb8856606 			port_id, vlan_id);
3488d30ea906Sjfb8856606 		return -EINVAL;
3489d30ea906Sjfb8856606 	}
3490d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_filter_set, -ENOTSUP);
3491d30ea906Sjfb8856606 
3492d30ea906Sjfb8856606 	ret = (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on);
3493d30ea906Sjfb8856606 	if (ret == 0) {
3494d30ea906Sjfb8856606 		struct rte_vlan_filter_conf *vfc;
3495d30ea906Sjfb8856606 		int vidx;
3496d30ea906Sjfb8856606 		int vbit;
3497d30ea906Sjfb8856606 
3498d30ea906Sjfb8856606 		vfc = &dev->data->vlan_filter_conf;
3499d30ea906Sjfb8856606 		vidx = vlan_id / 64;
3500d30ea906Sjfb8856606 		vbit = vlan_id % 64;
3501d30ea906Sjfb8856606 
3502d30ea906Sjfb8856606 		if (on)
3503d30ea906Sjfb8856606 			vfc->ids[vidx] |= UINT64_C(1) << vbit;
3504d30ea906Sjfb8856606 		else
3505d30ea906Sjfb8856606 			vfc->ids[vidx] &= ~(UINT64_C(1) << vbit);
3506d30ea906Sjfb8856606 	}
3507d30ea906Sjfb8856606 
3508d30ea906Sjfb8856606 	return eth_err(port_id, ret);
3509d30ea906Sjfb8856606 }
3510d30ea906Sjfb8856606 
3511d30ea906Sjfb8856606 int
rte_eth_dev_set_vlan_strip_on_queue(uint16_t port_id,uint16_t rx_queue_id,int on)3512d30ea906Sjfb8856606 rte_eth_dev_set_vlan_strip_on_queue(uint16_t port_id, uint16_t rx_queue_id,
3513d30ea906Sjfb8856606 				    int on)
3514d30ea906Sjfb8856606 {
3515d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3516d30ea906Sjfb8856606 
3517d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3518d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3519d30ea906Sjfb8856606 	if (rx_queue_id >= dev->data->nb_rx_queues) {
3520d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid rx_queue_id=%u\n", rx_queue_id);
3521d30ea906Sjfb8856606 		return -EINVAL;
3522d30ea906Sjfb8856606 	}
3523d30ea906Sjfb8856606 
3524d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP);
3525d30ea906Sjfb8856606 	(*dev->dev_ops->vlan_strip_queue_set)(dev, rx_queue_id, on);
3526d30ea906Sjfb8856606 
3527d30ea906Sjfb8856606 	return 0;
3528d30ea906Sjfb8856606 }
3529d30ea906Sjfb8856606 
3530d30ea906Sjfb8856606 int
rte_eth_dev_set_vlan_ether_type(uint16_t port_id,enum rte_vlan_type vlan_type,uint16_t tpid)3531d30ea906Sjfb8856606 rte_eth_dev_set_vlan_ether_type(uint16_t port_id,
3532d30ea906Sjfb8856606 				enum rte_vlan_type vlan_type,
3533d30ea906Sjfb8856606 				uint16_t tpid)
3534d30ea906Sjfb8856606 {
3535d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3536d30ea906Sjfb8856606 
3537d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3538d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3539d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
3540d30ea906Sjfb8856606 
3541d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->vlan_tpid_set)(dev, vlan_type,
3542d30ea906Sjfb8856606 							       tpid));
3543d30ea906Sjfb8856606 }
3544d30ea906Sjfb8856606 
3545d30ea906Sjfb8856606 int
rte_eth_dev_set_vlan_offload(uint16_t port_id,int offload_mask)3546d30ea906Sjfb8856606 rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask)
3547d30ea906Sjfb8856606 {
35480c6bd470Sfengbojiang 	struct rte_eth_dev_info dev_info;
3549d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3550d30ea906Sjfb8856606 	int ret = 0;
3551d30ea906Sjfb8856606 	int mask = 0;
3552d30ea906Sjfb8856606 	int cur, org = 0;
3553d30ea906Sjfb8856606 	uint64_t orig_offloads;
35544418919fSjohnjiang 	uint64_t dev_offloads;
35550c6bd470Sfengbojiang 	uint64_t new_offloads;
3556d30ea906Sjfb8856606 
3557d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3558d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3559d30ea906Sjfb8856606 
3560d30ea906Sjfb8856606 	/* save original values in case of failure */
3561d30ea906Sjfb8856606 	orig_offloads = dev->data->dev_conf.rxmode.offloads;
35624418919fSjohnjiang 	dev_offloads = orig_offloads;
3563d30ea906Sjfb8856606 
3564d30ea906Sjfb8856606 	/* check which option changed by application */
3565d30ea906Sjfb8856606 	cur = !!(offload_mask & ETH_VLAN_STRIP_OFFLOAD);
35664418919fSjohnjiang 	org = !!(dev_offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
3567d30ea906Sjfb8856606 	if (cur != org) {
3568d30ea906Sjfb8856606 		if (cur)
35694418919fSjohnjiang 			dev_offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
3570d30ea906Sjfb8856606 		else
35714418919fSjohnjiang 			dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
3572d30ea906Sjfb8856606 		mask |= ETH_VLAN_STRIP_MASK;
3573d30ea906Sjfb8856606 	}
3574d30ea906Sjfb8856606 
3575d30ea906Sjfb8856606 	cur = !!(offload_mask & ETH_VLAN_FILTER_OFFLOAD);
35764418919fSjohnjiang 	org = !!(dev_offloads & DEV_RX_OFFLOAD_VLAN_FILTER);
3577d30ea906Sjfb8856606 	if (cur != org) {
3578d30ea906Sjfb8856606 		if (cur)
35794418919fSjohnjiang 			dev_offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
3580d30ea906Sjfb8856606 		else
35814418919fSjohnjiang 			dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
3582d30ea906Sjfb8856606 		mask |= ETH_VLAN_FILTER_MASK;
3583d30ea906Sjfb8856606 	}
3584d30ea906Sjfb8856606 
3585d30ea906Sjfb8856606 	cur = !!(offload_mask & ETH_VLAN_EXTEND_OFFLOAD);
35864418919fSjohnjiang 	org = !!(dev_offloads & DEV_RX_OFFLOAD_VLAN_EXTEND);
3587d30ea906Sjfb8856606 	if (cur != org) {
3588d30ea906Sjfb8856606 		if (cur)
35894418919fSjohnjiang 			dev_offloads |= DEV_RX_OFFLOAD_VLAN_EXTEND;
3590d30ea906Sjfb8856606 		else
35914418919fSjohnjiang 			dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_EXTEND;
3592d30ea906Sjfb8856606 		mask |= ETH_VLAN_EXTEND_MASK;
3593d30ea906Sjfb8856606 	}
3594d30ea906Sjfb8856606 
35954418919fSjohnjiang 	cur = !!(offload_mask & ETH_QINQ_STRIP_OFFLOAD);
35964418919fSjohnjiang 	org = !!(dev_offloads & DEV_RX_OFFLOAD_QINQ_STRIP);
35974418919fSjohnjiang 	if (cur != org) {
35984418919fSjohnjiang 		if (cur)
35994418919fSjohnjiang 			dev_offloads |= DEV_RX_OFFLOAD_QINQ_STRIP;
36004418919fSjohnjiang 		else
36014418919fSjohnjiang 			dev_offloads &= ~DEV_RX_OFFLOAD_QINQ_STRIP;
36024418919fSjohnjiang 		mask |= ETH_QINQ_STRIP_MASK;
36034418919fSjohnjiang 	}
36044418919fSjohnjiang 
3605d30ea906Sjfb8856606 	/*no change*/
3606d30ea906Sjfb8856606 	if (mask == 0)
3607d30ea906Sjfb8856606 		return ret;
3608d30ea906Sjfb8856606 
36090c6bd470Sfengbojiang 	ret = rte_eth_dev_info_get(port_id, &dev_info);
36100c6bd470Sfengbojiang 	if (ret != 0)
36110c6bd470Sfengbojiang 		return ret;
36120c6bd470Sfengbojiang 
36130c6bd470Sfengbojiang 	/* Rx VLAN offloading must be within its device capabilities */
36140c6bd470Sfengbojiang 	if ((dev_offloads & dev_info.rx_offload_capa) != dev_offloads) {
36150c6bd470Sfengbojiang 		new_offloads = dev_offloads & ~orig_offloads;
36160c6bd470Sfengbojiang 		RTE_ETHDEV_LOG(ERR,
36170c6bd470Sfengbojiang 			"Ethdev port_id=%u requested new added VLAN offloads "
36180c6bd470Sfengbojiang 			"0x%" PRIx64 " must be within Rx offloads capabilities "
36190c6bd470Sfengbojiang 			"0x%" PRIx64 " in %s()\n",
36200c6bd470Sfengbojiang 			port_id, new_offloads, dev_info.rx_offload_capa,
36210c6bd470Sfengbojiang 			__func__);
36220c6bd470Sfengbojiang 		return -EINVAL;
36230c6bd470Sfengbojiang 	}
36240c6bd470Sfengbojiang 
3625d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_offload_set, -ENOTSUP);
36264418919fSjohnjiang 	dev->data->dev_conf.rxmode.offloads = dev_offloads;
3627d30ea906Sjfb8856606 	ret = (*dev->dev_ops->vlan_offload_set)(dev, mask);
3628d30ea906Sjfb8856606 	if (ret) {
3629d30ea906Sjfb8856606 		/* hit an error restore  original values */
3630d30ea906Sjfb8856606 		dev->data->dev_conf.rxmode.offloads = orig_offloads;
3631d30ea906Sjfb8856606 	}
3632d30ea906Sjfb8856606 
3633d30ea906Sjfb8856606 	return eth_err(port_id, ret);
3634d30ea906Sjfb8856606 }
3635d30ea906Sjfb8856606 
3636d30ea906Sjfb8856606 int
rte_eth_dev_get_vlan_offload(uint16_t port_id)3637d30ea906Sjfb8856606 rte_eth_dev_get_vlan_offload(uint16_t port_id)
3638d30ea906Sjfb8856606 {
3639d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
36404418919fSjohnjiang 	uint64_t *dev_offloads;
3641d30ea906Sjfb8856606 	int ret = 0;
3642d30ea906Sjfb8856606 
3643d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3644d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
36454418919fSjohnjiang 	dev_offloads = &dev->data->dev_conf.rxmode.offloads;
3646d30ea906Sjfb8856606 
36474418919fSjohnjiang 	if (*dev_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
3648d30ea906Sjfb8856606 		ret |= ETH_VLAN_STRIP_OFFLOAD;
3649d30ea906Sjfb8856606 
36504418919fSjohnjiang 	if (*dev_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
3651d30ea906Sjfb8856606 		ret |= ETH_VLAN_FILTER_OFFLOAD;
3652d30ea906Sjfb8856606 
36534418919fSjohnjiang 	if (*dev_offloads & DEV_RX_OFFLOAD_VLAN_EXTEND)
3654d30ea906Sjfb8856606 		ret |= ETH_VLAN_EXTEND_OFFLOAD;
3655d30ea906Sjfb8856606 
36564418919fSjohnjiang 	if (*dev_offloads & DEV_RX_OFFLOAD_QINQ_STRIP)
36574418919fSjohnjiang 		ret |= ETH_QINQ_STRIP_OFFLOAD;
36584418919fSjohnjiang 
3659d30ea906Sjfb8856606 	return ret;
3660d30ea906Sjfb8856606 }
3661d30ea906Sjfb8856606 
3662d30ea906Sjfb8856606 int
rte_eth_dev_set_vlan_pvid(uint16_t port_id,uint16_t pvid,int on)3663d30ea906Sjfb8856606 rte_eth_dev_set_vlan_pvid(uint16_t port_id, uint16_t pvid, int on)
3664d30ea906Sjfb8856606 {
3665d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3666d30ea906Sjfb8856606 
3667d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3668d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3669d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_pvid_set, -ENOTSUP);
3670d30ea906Sjfb8856606 
3671d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->vlan_pvid_set)(dev, pvid, on));
3672d30ea906Sjfb8856606 }
3673d30ea906Sjfb8856606 
3674d30ea906Sjfb8856606 int
rte_eth_dev_flow_ctrl_get(uint16_t port_id,struct rte_eth_fc_conf * fc_conf)3675d30ea906Sjfb8856606 rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
3676d30ea906Sjfb8856606 {
3677d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3678d30ea906Sjfb8856606 
3679d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3680d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3681d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
3682d30ea906Sjfb8856606 	memset(fc_conf, 0, sizeof(*fc_conf));
3683d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf));
3684d30ea906Sjfb8856606 }
3685d30ea906Sjfb8856606 
3686d30ea906Sjfb8856606 int
rte_eth_dev_flow_ctrl_set(uint16_t port_id,struct rte_eth_fc_conf * fc_conf)3687d30ea906Sjfb8856606 rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
3688d30ea906Sjfb8856606 {
3689d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3690d30ea906Sjfb8856606 
3691d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3692d30ea906Sjfb8856606 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
3693d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
3694d30ea906Sjfb8856606 		return -EINVAL;
3695d30ea906Sjfb8856606 	}
3696d30ea906Sjfb8856606 
3697d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3698d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP);
3699d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf));
3700d30ea906Sjfb8856606 }
3701d30ea906Sjfb8856606 
3702d30ea906Sjfb8856606 int
rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,struct rte_eth_pfc_conf * pfc_conf)3703d30ea906Sjfb8856606 rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
3704d30ea906Sjfb8856606 				   struct rte_eth_pfc_conf *pfc_conf)
3705d30ea906Sjfb8856606 {
3706d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3707d30ea906Sjfb8856606 
3708d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3709d30ea906Sjfb8856606 	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
3710d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
3711d30ea906Sjfb8856606 		return -EINVAL;
3712d30ea906Sjfb8856606 	}
3713d30ea906Sjfb8856606 
3714d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3715d30ea906Sjfb8856606 	/* High water, low water validation are device specific */
3716d30ea906Sjfb8856606 	if  (*dev->dev_ops->priority_flow_ctrl_set)
3717d30ea906Sjfb8856606 		return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set)
3718d30ea906Sjfb8856606 					(dev, pfc_conf));
3719d30ea906Sjfb8856606 	return -ENOTSUP;
3720d30ea906Sjfb8856606 }
3721d30ea906Sjfb8856606 
3722d30ea906Sjfb8856606 static int
eth_check_reta_mask(struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size)3723*2d9fd380Sjfb8856606 eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
3724d30ea906Sjfb8856606 			uint16_t reta_size)
3725d30ea906Sjfb8856606 {
3726d30ea906Sjfb8856606 	uint16_t i, num;
3727d30ea906Sjfb8856606 
3728d30ea906Sjfb8856606 	if (!reta_conf)
3729d30ea906Sjfb8856606 		return -EINVAL;
3730d30ea906Sjfb8856606 
3731d30ea906Sjfb8856606 	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
3732d30ea906Sjfb8856606 	for (i = 0; i < num; i++) {
3733d30ea906Sjfb8856606 		if (reta_conf[i].mask)
3734d30ea906Sjfb8856606 			return 0;
3735d30ea906Sjfb8856606 	}
3736d30ea906Sjfb8856606 
3737d30ea906Sjfb8856606 	return -EINVAL;
3738d30ea906Sjfb8856606 }
3739d30ea906Sjfb8856606 
3740d30ea906Sjfb8856606 static int
eth_check_reta_entry(struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size,uint16_t max_rxq)3741*2d9fd380Sjfb8856606 eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
3742d30ea906Sjfb8856606 			 uint16_t reta_size,
3743d30ea906Sjfb8856606 			 uint16_t max_rxq)
3744d30ea906Sjfb8856606 {
3745d30ea906Sjfb8856606 	uint16_t i, idx, shift;
3746d30ea906Sjfb8856606 
3747d30ea906Sjfb8856606 	if (!reta_conf)
3748d30ea906Sjfb8856606 		return -EINVAL;
3749d30ea906Sjfb8856606 
3750d30ea906Sjfb8856606 	if (max_rxq == 0) {
3751d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
3752d30ea906Sjfb8856606 		return -EINVAL;
3753d30ea906Sjfb8856606 	}
3754d30ea906Sjfb8856606 
3755d30ea906Sjfb8856606 	for (i = 0; i < reta_size; i++) {
3756d30ea906Sjfb8856606 		idx = i / RTE_RETA_GROUP_SIZE;
3757d30ea906Sjfb8856606 		shift = i % RTE_RETA_GROUP_SIZE;
3758d30ea906Sjfb8856606 		if ((reta_conf[idx].mask & (1ULL << shift)) &&
3759d30ea906Sjfb8856606 			(reta_conf[idx].reta[shift] >= max_rxq)) {
3760d30ea906Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
3761d30ea906Sjfb8856606 				"reta_conf[%u]->reta[%u]: %u exceeds the maximum rxq index: %u\n",
3762d30ea906Sjfb8856606 				idx, shift,
3763d30ea906Sjfb8856606 				reta_conf[idx].reta[shift], max_rxq);
3764d30ea906Sjfb8856606 			return -EINVAL;
3765d30ea906Sjfb8856606 		}
3766d30ea906Sjfb8856606 	}
3767d30ea906Sjfb8856606 
3768d30ea906Sjfb8856606 	return 0;
3769d30ea906Sjfb8856606 }
3770d30ea906Sjfb8856606 
3771d30ea906Sjfb8856606 int
rte_eth_dev_rss_reta_update(uint16_t port_id,struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size)3772d30ea906Sjfb8856606 rte_eth_dev_rss_reta_update(uint16_t port_id,
3773d30ea906Sjfb8856606 			    struct rte_eth_rss_reta_entry64 *reta_conf,
3774d30ea906Sjfb8856606 			    uint16_t reta_size)
3775d30ea906Sjfb8856606 {
3776d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3777d30ea906Sjfb8856606 	int ret;
3778d30ea906Sjfb8856606 
3779d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3780d30ea906Sjfb8856606 	/* Check mask bits */
3781*2d9fd380Sjfb8856606 	ret = eth_check_reta_mask(reta_conf, reta_size);
3782d30ea906Sjfb8856606 	if (ret < 0)
3783d30ea906Sjfb8856606 		return ret;
3784d30ea906Sjfb8856606 
3785d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3786d30ea906Sjfb8856606 
3787d30ea906Sjfb8856606 	/* Check entry value */
3788*2d9fd380Sjfb8856606 	ret = eth_check_reta_entry(reta_conf, reta_size,
3789d30ea906Sjfb8856606 				dev->data->nb_rx_queues);
3790d30ea906Sjfb8856606 	if (ret < 0)
3791d30ea906Sjfb8856606 		return ret;
3792d30ea906Sjfb8856606 
3793d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_update, -ENOTSUP);
3794d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->reta_update)(dev, reta_conf,
3795d30ea906Sjfb8856606 							     reta_size));
3796d30ea906Sjfb8856606 }
3797d30ea906Sjfb8856606 
3798d30ea906Sjfb8856606 int
rte_eth_dev_rss_reta_query(uint16_t port_id,struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size)3799d30ea906Sjfb8856606 rte_eth_dev_rss_reta_query(uint16_t port_id,
3800d30ea906Sjfb8856606 			   struct rte_eth_rss_reta_entry64 *reta_conf,
3801d30ea906Sjfb8856606 			   uint16_t reta_size)
3802d30ea906Sjfb8856606 {
3803d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3804d30ea906Sjfb8856606 	int ret;
3805d30ea906Sjfb8856606 
3806d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3807d30ea906Sjfb8856606 
3808d30ea906Sjfb8856606 	/* Check mask bits */
3809*2d9fd380Sjfb8856606 	ret = eth_check_reta_mask(reta_conf, reta_size);
3810d30ea906Sjfb8856606 	if (ret < 0)
3811d30ea906Sjfb8856606 		return ret;
3812d30ea906Sjfb8856606 
3813d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3814d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP);
3815d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf,
3816d30ea906Sjfb8856606 							    reta_size));
3817d30ea906Sjfb8856606 }
3818d30ea906Sjfb8856606 
3819d30ea906Sjfb8856606 int
rte_eth_dev_rss_hash_update(uint16_t port_id,struct rte_eth_rss_conf * rss_conf)3820d30ea906Sjfb8856606 rte_eth_dev_rss_hash_update(uint16_t port_id,
3821d30ea906Sjfb8856606 			    struct rte_eth_rss_conf *rss_conf)
3822d30ea906Sjfb8856606 {
3823d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3824d30ea906Sjfb8856606 	struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
38254418919fSjohnjiang 	int ret;
3826d30ea906Sjfb8856606 
3827d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
38284418919fSjohnjiang 
38294418919fSjohnjiang 	ret = rte_eth_dev_info_get(port_id, &dev_info);
38304418919fSjohnjiang 	if (ret != 0)
38314418919fSjohnjiang 		return ret;
38324418919fSjohnjiang 
38334418919fSjohnjiang 	rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf);
38344418919fSjohnjiang 
3835d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3836d30ea906Sjfb8856606 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
3837d30ea906Sjfb8856606 	    dev_info.flow_type_rss_offloads) {
3838d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
3839d30ea906Sjfb8856606 			"Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n",
3840d30ea906Sjfb8856606 			port_id, rss_conf->rss_hf,
3841d30ea906Sjfb8856606 			dev_info.flow_type_rss_offloads);
3842d30ea906Sjfb8856606 		return -EINVAL;
3843d30ea906Sjfb8856606 	}
3844d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP);
3845d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->rss_hash_update)(dev,
3846d30ea906Sjfb8856606 								 rss_conf));
3847d30ea906Sjfb8856606 }
3848d30ea906Sjfb8856606 
3849d30ea906Sjfb8856606 int
rte_eth_dev_rss_hash_conf_get(uint16_t port_id,struct rte_eth_rss_conf * rss_conf)3850d30ea906Sjfb8856606 rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
3851d30ea906Sjfb8856606 			      struct rte_eth_rss_conf *rss_conf)
3852d30ea906Sjfb8856606 {
3853d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3854d30ea906Sjfb8856606 
3855d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3856d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3857d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
3858d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
3859d30ea906Sjfb8856606 								   rss_conf));
3860d30ea906Sjfb8856606 }
3861d30ea906Sjfb8856606 
3862d30ea906Sjfb8856606 int
rte_eth_dev_udp_tunnel_port_add(uint16_t port_id,struct rte_eth_udp_tunnel * udp_tunnel)3863d30ea906Sjfb8856606 rte_eth_dev_udp_tunnel_port_add(uint16_t port_id,
3864d30ea906Sjfb8856606 				struct rte_eth_udp_tunnel *udp_tunnel)
3865d30ea906Sjfb8856606 {
3866d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3867d30ea906Sjfb8856606 
3868d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3869d30ea906Sjfb8856606 	if (udp_tunnel == NULL) {
3870d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid udp_tunnel parameter\n");
3871d30ea906Sjfb8856606 		return -EINVAL;
3872d30ea906Sjfb8856606 	}
3873d30ea906Sjfb8856606 
3874d30ea906Sjfb8856606 	if (udp_tunnel->prot_type >= RTE_TUNNEL_TYPE_MAX) {
3875d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n");
3876d30ea906Sjfb8856606 		return -EINVAL;
3877d30ea906Sjfb8856606 	}
3878d30ea906Sjfb8856606 
3879d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3880d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_add, -ENOTSUP);
3881d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_add)(dev,
3882d30ea906Sjfb8856606 								udp_tunnel));
3883d30ea906Sjfb8856606 }
3884d30ea906Sjfb8856606 
3885d30ea906Sjfb8856606 int
rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,struct rte_eth_udp_tunnel * udp_tunnel)3886d30ea906Sjfb8856606 rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
3887d30ea906Sjfb8856606 				   struct rte_eth_udp_tunnel *udp_tunnel)
3888d30ea906Sjfb8856606 {
3889d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3890d30ea906Sjfb8856606 
3891d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3892d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3893d30ea906Sjfb8856606 
3894d30ea906Sjfb8856606 	if (udp_tunnel == NULL) {
3895d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid udp_tunnel parameter\n");
3896d30ea906Sjfb8856606 		return -EINVAL;
3897d30ea906Sjfb8856606 	}
3898d30ea906Sjfb8856606 
3899d30ea906Sjfb8856606 	if (udp_tunnel->prot_type >= RTE_TUNNEL_TYPE_MAX) {
3900d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n");
3901d30ea906Sjfb8856606 		return -EINVAL;
3902d30ea906Sjfb8856606 	}
3903d30ea906Sjfb8856606 
3904d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_del, -ENOTSUP);
3905d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_del)(dev,
3906d30ea906Sjfb8856606 								udp_tunnel));
3907d30ea906Sjfb8856606 }
3908d30ea906Sjfb8856606 
3909d30ea906Sjfb8856606 int
rte_eth_led_on(uint16_t port_id)3910d30ea906Sjfb8856606 rte_eth_led_on(uint16_t port_id)
3911d30ea906Sjfb8856606 {
3912d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3913d30ea906Sjfb8856606 
3914d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3915d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3916d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_on, -ENOTSUP);
3917d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->dev_led_on)(dev));
3918d30ea906Sjfb8856606 }
3919d30ea906Sjfb8856606 
3920d30ea906Sjfb8856606 int
rte_eth_led_off(uint16_t port_id)3921d30ea906Sjfb8856606 rte_eth_led_off(uint16_t port_id)
3922d30ea906Sjfb8856606 {
3923d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
3924d30ea906Sjfb8856606 
3925d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3926d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
3927d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_off, -ENOTSUP);
3928d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->dev_led_off)(dev));
3929d30ea906Sjfb8856606 }
3930d30ea906Sjfb8856606 
3931*2d9fd380Sjfb8856606 int
rte_eth_fec_get_capability(uint16_t port_id,struct rte_eth_fec_capa * speed_fec_capa,unsigned int num)3932*2d9fd380Sjfb8856606 rte_eth_fec_get_capability(uint16_t port_id,
3933*2d9fd380Sjfb8856606 			   struct rte_eth_fec_capa *speed_fec_capa,
3934*2d9fd380Sjfb8856606 			   unsigned int num)
3935*2d9fd380Sjfb8856606 {
3936*2d9fd380Sjfb8856606 	struct rte_eth_dev *dev;
3937*2d9fd380Sjfb8856606 	int ret;
3938*2d9fd380Sjfb8856606 
3939*2d9fd380Sjfb8856606 	if (speed_fec_capa == NULL && num > 0)
3940*2d9fd380Sjfb8856606 		return -EINVAL;
3941*2d9fd380Sjfb8856606 
3942*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3943*2d9fd380Sjfb8856606 	dev = &rte_eth_devices[port_id];
3944*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get_capability, -ENOTSUP);
3945*2d9fd380Sjfb8856606 	ret = (*dev->dev_ops->fec_get_capability)(dev, speed_fec_capa, num);
3946*2d9fd380Sjfb8856606 
3947*2d9fd380Sjfb8856606 	return ret;
3948*2d9fd380Sjfb8856606 }
3949*2d9fd380Sjfb8856606 
3950*2d9fd380Sjfb8856606 int
rte_eth_fec_get(uint16_t port_id,uint32_t * fec_capa)3951*2d9fd380Sjfb8856606 rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa)
3952*2d9fd380Sjfb8856606 {
3953*2d9fd380Sjfb8856606 	struct rte_eth_dev *dev;
3954*2d9fd380Sjfb8856606 
3955*2d9fd380Sjfb8856606 	if (fec_capa == NULL)
3956*2d9fd380Sjfb8856606 		return -EINVAL;
3957*2d9fd380Sjfb8856606 
3958*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3959*2d9fd380Sjfb8856606 	dev = &rte_eth_devices[port_id];
3960*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get, -ENOTSUP);
3961*2d9fd380Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->fec_get)(dev, fec_capa));
3962*2d9fd380Sjfb8856606 }
3963*2d9fd380Sjfb8856606 
3964*2d9fd380Sjfb8856606 int
rte_eth_fec_set(uint16_t port_id,uint32_t fec_capa)3965*2d9fd380Sjfb8856606 rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa)
3966*2d9fd380Sjfb8856606 {
3967*2d9fd380Sjfb8856606 	struct rte_eth_dev *dev;
3968*2d9fd380Sjfb8856606 
3969*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3970*2d9fd380Sjfb8856606 	dev = &rte_eth_devices[port_id];
3971*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_set, -ENOTSUP);
3972*2d9fd380Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->fec_set)(dev, fec_capa));
3973*2d9fd380Sjfb8856606 }
3974*2d9fd380Sjfb8856606 
3975d30ea906Sjfb8856606 /*
3976d30ea906Sjfb8856606  * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
3977d30ea906Sjfb8856606  * an empty spot.
3978d30ea906Sjfb8856606  */
3979d30ea906Sjfb8856606 static int
eth_dev_get_mac_addr_index(uint16_t port_id,const struct rte_ether_addr * addr)3980*2d9fd380Sjfb8856606 eth_dev_get_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr)
3981d30ea906Sjfb8856606 {
3982d30ea906Sjfb8856606 	struct rte_eth_dev_info dev_info;
3983d30ea906Sjfb8856606 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
3984d30ea906Sjfb8856606 	unsigned i;
39854418919fSjohnjiang 	int ret;
3986d30ea906Sjfb8856606 
39874418919fSjohnjiang 	ret = rte_eth_dev_info_get(port_id, &dev_info);
39884418919fSjohnjiang 	if (ret != 0)
39894418919fSjohnjiang 		return -1;
3990d30ea906Sjfb8856606 
3991d30ea906Sjfb8856606 	for (i = 0; i < dev_info.max_mac_addrs; i++)
39924418919fSjohnjiang 		if (memcmp(addr, &dev->data->mac_addrs[i],
39934418919fSjohnjiang 				RTE_ETHER_ADDR_LEN) == 0)
3994d30ea906Sjfb8856606 			return i;
3995d30ea906Sjfb8856606 
3996d30ea906Sjfb8856606 	return -1;
3997d30ea906Sjfb8856606 }
3998d30ea906Sjfb8856606 
39994418919fSjohnjiang static const struct rte_ether_addr null_mac_addr;
4000d30ea906Sjfb8856606 
4001d30ea906Sjfb8856606 int
rte_eth_dev_mac_addr_add(uint16_t port_id,struct rte_ether_addr * addr,uint32_t pool)40024418919fSjohnjiang rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
4003d30ea906Sjfb8856606 			uint32_t pool)
4004d30ea906Sjfb8856606 {
4005d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4006d30ea906Sjfb8856606 	int index;
4007d30ea906Sjfb8856606 	uint64_t pool_mask;
4008d30ea906Sjfb8856606 	int ret;
4009d30ea906Sjfb8856606 
4010d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4011d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4012d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
4013d30ea906Sjfb8856606 
40144418919fSjohnjiang 	if (rte_is_zero_ether_addr(addr)) {
4015d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
4016d30ea906Sjfb8856606 			port_id);
4017d30ea906Sjfb8856606 		return -EINVAL;
4018d30ea906Sjfb8856606 	}
4019d30ea906Sjfb8856606 	if (pool >= ETH_64_POOLS) {
4020d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Pool id must be 0-%d\n", ETH_64_POOLS - 1);
4021d30ea906Sjfb8856606 		return -EINVAL;
4022d30ea906Sjfb8856606 	}
4023d30ea906Sjfb8856606 
4024*2d9fd380Sjfb8856606 	index = eth_dev_get_mac_addr_index(port_id, addr);
4025d30ea906Sjfb8856606 	if (index < 0) {
4026*2d9fd380Sjfb8856606 		index = eth_dev_get_mac_addr_index(port_id, &null_mac_addr);
4027d30ea906Sjfb8856606 		if (index < 0) {
4028d30ea906Sjfb8856606 			RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n",
4029d30ea906Sjfb8856606 				port_id);
4030d30ea906Sjfb8856606 			return -ENOSPC;
4031d30ea906Sjfb8856606 		}
4032d30ea906Sjfb8856606 	} else {
4033d30ea906Sjfb8856606 		pool_mask = dev->data->mac_pool_sel[index];
4034d30ea906Sjfb8856606 
4035d30ea906Sjfb8856606 		/* Check if both MAC address and pool is already there, and do nothing */
4036d30ea906Sjfb8856606 		if (pool_mask & (1ULL << pool))
4037d30ea906Sjfb8856606 			return 0;
4038d30ea906Sjfb8856606 	}
4039d30ea906Sjfb8856606 
4040d30ea906Sjfb8856606 	/* Update NIC */
4041d30ea906Sjfb8856606 	ret = (*dev->dev_ops->mac_addr_add)(dev, addr, index, pool);
4042d30ea906Sjfb8856606 
4043d30ea906Sjfb8856606 	if (ret == 0) {
4044d30ea906Sjfb8856606 		/* Update address in NIC data structure */
40454418919fSjohnjiang 		rte_ether_addr_copy(addr, &dev->data->mac_addrs[index]);
4046d30ea906Sjfb8856606 
4047d30ea906Sjfb8856606 		/* Update pool bitmap in NIC data structure */
4048d30ea906Sjfb8856606 		dev->data->mac_pool_sel[index] |= (1ULL << pool);
4049d30ea906Sjfb8856606 	}
4050d30ea906Sjfb8856606 
4051d30ea906Sjfb8856606 	return eth_err(port_id, ret);
4052d30ea906Sjfb8856606 }
4053d30ea906Sjfb8856606 
4054d30ea906Sjfb8856606 int
rte_eth_dev_mac_addr_remove(uint16_t port_id,struct rte_ether_addr * addr)40554418919fSjohnjiang rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
4056d30ea906Sjfb8856606 {
4057d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4058d30ea906Sjfb8856606 	int index;
4059d30ea906Sjfb8856606 
4060d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4061d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4062d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
4063d30ea906Sjfb8856606 
4064*2d9fd380Sjfb8856606 	index = eth_dev_get_mac_addr_index(port_id, addr);
4065d30ea906Sjfb8856606 	if (index == 0) {
4066d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
4067d30ea906Sjfb8856606 			"Port %u: Cannot remove default MAC address\n",
4068d30ea906Sjfb8856606 			port_id);
4069d30ea906Sjfb8856606 		return -EADDRINUSE;
4070d30ea906Sjfb8856606 	} else if (index < 0)
4071d30ea906Sjfb8856606 		return 0;  /* Do nothing if address wasn't found */
4072d30ea906Sjfb8856606 
4073d30ea906Sjfb8856606 	/* Update NIC */
4074d30ea906Sjfb8856606 	(*dev->dev_ops->mac_addr_remove)(dev, index);
4075d30ea906Sjfb8856606 
4076d30ea906Sjfb8856606 	/* Update address in NIC data structure */
40774418919fSjohnjiang 	rte_ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]);
4078d30ea906Sjfb8856606 
4079d30ea906Sjfb8856606 	/* reset pool bitmap */
4080d30ea906Sjfb8856606 	dev->data->mac_pool_sel[index] = 0;
4081d30ea906Sjfb8856606 
4082d30ea906Sjfb8856606 	return 0;
4083d30ea906Sjfb8856606 }
4084d30ea906Sjfb8856606 
4085d30ea906Sjfb8856606 int
rte_eth_dev_default_mac_addr_set(uint16_t port_id,struct rte_ether_addr * addr)40864418919fSjohnjiang rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
4087d30ea906Sjfb8856606 {
4088d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4089d30ea906Sjfb8856606 	int ret;
4090d30ea906Sjfb8856606 
4091d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4092d30ea906Sjfb8856606 
40934418919fSjohnjiang 	if (!rte_is_valid_assigned_ether_addr(addr))
4094d30ea906Sjfb8856606 		return -EINVAL;
4095d30ea906Sjfb8856606 
4096d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4097d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
4098d30ea906Sjfb8856606 
4099d30ea906Sjfb8856606 	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
4100d30ea906Sjfb8856606 	if (ret < 0)
4101d30ea906Sjfb8856606 		return ret;
4102d30ea906Sjfb8856606 
4103d30ea906Sjfb8856606 	/* Update default address in NIC data structure */
41044418919fSjohnjiang 	rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
4105d30ea906Sjfb8856606 
4106d30ea906Sjfb8856606 	return 0;
4107d30ea906Sjfb8856606 }
4108d30ea906Sjfb8856606 
4109d30ea906Sjfb8856606 
4110d30ea906Sjfb8856606 /*
4111d30ea906Sjfb8856606  * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
4112d30ea906Sjfb8856606  * an empty spot.
4113d30ea906Sjfb8856606  */
4114d30ea906Sjfb8856606 static int
eth_dev_get_hash_mac_addr_index(uint16_t port_id,const struct rte_ether_addr * addr)4115*2d9fd380Sjfb8856606 eth_dev_get_hash_mac_addr_index(uint16_t port_id,
4116*2d9fd380Sjfb8856606 		const struct rte_ether_addr *addr)
4117d30ea906Sjfb8856606 {
4118d30ea906Sjfb8856606 	struct rte_eth_dev_info dev_info;
4119d30ea906Sjfb8856606 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
4120d30ea906Sjfb8856606 	unsigned i;
41214418919fSjohnjiang 	int ret;
4122d30ea906Sjfb8856606 
41234418919fSjohnjiang 	ret = rte_eth_dev_info_get(port_id, &dev_info);
41244418919fSjohnjiang 	if (ret != 0)
41254418919fSjohnjiang 		return -1;
41264418919fSjohnjiang 
4127d30ea906Sjfb8856606 	if (!dev->data->hash_mac_addrs)
4128d30ea906Sjfb8856606 		return -1;
4129d30ea906Sjfb8856606 
4130d30ea906Sjfb8856606 	for (i = 0; i < dev_info.max_hash_mac_addrs; i++)
4131d30ea906Sjfb8856606 		if (memcmp(addr, &dev->data->hash_mac_addrs[i],
41324418919fSjohnjiang 			RTE_ETHER_ADDR_LEN) == 0)
4133d30ea906Sjfb8856606 			return i;
4134d30ea906Sjfb8856606 
4135d30ea906Sjfb8856606 	return -1;
4136d30ea906Sjfb8856606 }
4137d30ea906Sjfb8856606 
4138d30ea906Sjfb8856606 int
rte_eth_dev_uc_hash_table_set(uint16_t port_id,struct rte_ether_addr * addr,uint8_t on)41394418919fSjohnjiang rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
4140d30ea906Sjfb8856606 				uint8_t on)
4141d30ea906Sjfb8856606 {
4142d30ea906Sjfb8856606 	int index;
4143d30ea906Sjfb8856606 	int ret;
4144d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4145d30ea906Sjfb8856606 
4146d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4147d30ea906Sjfb8856606 
4148d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
41494418919fSjohnjiang 	if (rte_is_zero_ether_addr(addr)) {
4150d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
4151d30ea906Sjfb8856606 			port_id);
4152d30ea906Sjfb8856606 		return -EINVAL;
4153d30ea906Sjfb8856606 	}
4154d30ea906Sjfb8856606 
4155*2d9fd380Sjfb8856606 	index = eth_dev_get_hash_mac_addr_index(port_id, addr);
4156d30ea906Sjfb8856606 	/* Check if it's already there, and do nothing */
4157d30ea906Sjfb8856606 	if ((index >= 0) && on)
4158d30ea906Sjfb8856606 		return 0;
4159d30ea906Sjfb8856606 
4160d30ea906Sjfb8856606 	if (index < 0) {
4161d30ea906Sjfb8856606 		if (!on) {
4162d30ea906Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
4163d30ea906Sjfb8856606 				"Port %u: the MAC address was not set in UTA\n",
4164d30ea906Sjfb8856606 				port_id);
4165d30ea906Sjfb8856606 			return -EINVAL;
4166d30ea906Sjfb8856606 		}
4167d30ea906Sjfb8856606 
4168*2d9fd380Sjfb8856606 		index = eth_dev_get_hash_mac_addr_index(port_id, &null_mac_addr);
4169d30ea906Sjfb8856606 		if (index < 0) {
4170d30ea906Sjfb8856606 			RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n",
4171d30ea906Sjfb8856606 				port_id);
4172d30ea906Sjfb8856606 			return -ENOSPC;
4173d30ea906Sjfb8856606 		}
4174d30ea906Sjfb8856606 	}
4175d30ea906Sjfb8856606 
4176d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_hash_table_set, -ENOTSUP);
4177d30ea906Sjfb8856606 	ret = (*dev->dev_ops->uc_hash_table_set)(dev, addr, on);
4178d30ea906Sjfb8856606 	if (ret == 0) {
4179d30ea906Sjfb8856606 		/* Update address in NIC data structure */
4180d30ea906Sjfb8856606 		if (on)
41814418919fSjohnjiang 			rte_ether_addr_copy(addr,
4182d30ea906Sjfb8856606 					&dev->data->hash_mac_addrs[index]);
4183d30ea906Sjfb8856606 		else
41844418919fSjohnjiang 			rte_ether_addr_copy(&null_mac_addr,
4185d30ea906Sjfb8856606 					&dev->data->hash_mac_addrs[index]);
4186d30ea906Sjfb8856606 	}
4187d30ea906Sjfb8856606 
4188d30ea906Sjfb8856606 	return eth_err(port_id, ret);
4189d30ea906Sjfb8856606 }
4190d30ea906Sjfb8856606 
4191d30ea906Sjfb8856606 int
rte_eth_dev_uc_all_hash_table_set(uint16_t port_id,uint8_t on)4192d30ea906Sjfb8856606 rte_eth_dev_uc_all_hash_table_set(uint16_t port_id, uint8_t on)
4193d30ea906Sjfb8856606 {
4194d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4195d30ea906Sjfb8856606 
4196d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4197d30ea906Sjfb8856606 
4198d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4199d30ea906Sjfb8856606 
4200d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_all_hash_table_set, -ENOTSUP);
4201d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->uc_all_hash_table_set)(dev,
4202d30ea906Sjfb8856606 								       on));
4203d30ea906Sjfb8856606 }
4204d30ea906Sjfb8856606 
rte_eth_set_queue_rate_limit(uint16_t port_id,uint16_t queue_idx,uint16_t tx_rate)4205d30ea906Sjfb8856606 int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
4206d30ea906Sjfb8856606 					uint16_t tx_rate)
4207d30ea906Sjfb8856606 {
4208d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4209d30ea906Sjfb8856606 	struct rte_eth_dev_info dev_info;
4210d30ea906Sjfb8856606 	struct rte_eth_link link;
42114418919fSjohnjiang 	int ret;
4212d30ea906Sjfb8856606 
4213d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4214d30ea906Sjfb8856606 
42154418919fSjohnjiang 	ret = rte_eth_dev_info_get(port_id, &dev_info);
42164418919fSjohnjiang 	if (ret != 0)
42174418919fSjohnjiang 		return ret;
42184418919fSjohnjiang 
4219d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4220d30ea906Sjfb8856606 	link = dev->data->dev_link;
4221d30ea906Sjfb8856606 
4222d30ea906Sjfb8856606 	if (queue_idx > dev_info.max_tx_queues) {
4223d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
4224d30ea906Sjfb8856606 			"Set queue rate limit:port %u: invalid queue id=%u\n",
4225d30ea906Sjfb8856606 			port_id, queue_idx);
4226d30ea906Sjfb8856606 		return -EINVAL;
4227d30ea906Sjfb8856606 	}
4228d30ea906Sjfb8856606 
4229d30ea906Sjfb8856606 	if (tx_rate > link.link_speed) {
4230d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
4231d30ea906Sjfb8856606 			"Set queue rate limit:invalid tx_rate=%u, bigger than link speed= %d\n",
4232d30ea906Sjfb8856606 			tx_rate, link.link_speed);
4233d30ea906Sjfb8856606 		return -EINVAL;
4234d30ea906Sjfb8856606 	}
4235d30ea906Sjfb8856606 
4236d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_queue_rate_limit, -ENOTSUP);
4237d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->set_queue_rate_limit)(dev,
4238d30ea906Sjfb8856606 							queue_idx, tx_rate));
4239d30ea906Sjfb8856606 }
4240d30ea906Sjfb8856606 
4241d30ea906Sjfb8856606 int
rte_eth_mirror_rule_set(uint16_t port_id,struct rte_eth_mirror_conf * mirror_conf,uint8_t rule_id,uint8_t on)4242d30ea906Sjfb8856606 rte_eth_mirror_rule_set(uint16_t port_id,
4243d30ea906Sjfb8856606 			struct rte_eth_mirror_conf *mirror_conf,
4244d30ea906Sjfb8856606 			uint8_t rule_id, uint8_t on)
4245d30ea906Sjfb8856606 {
4246d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4247d30ea906Sjfb8856606 
4248d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4249d30ea906Sjfb8856606 	if (mirror_conf->rule_type == 0) {
4250d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
4251d30ea906Sjfb8856606 		return -EINVAL;
4252d30ea906Sjfb8856606 	}
4253d30ea906Sjfb8856606 
4254d30ea906Sjfb8856606 	if (mirror_conf->dst_pool >= ETH_64_POOLS) {
4255d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid dst pool, pool id must be 0-%d\n",
4256d30ea906Sjfb8856606 			ETH_64_POOLS - 1);
4257d30ea906Sjfb8856606 		return -EINVAL;
4258d30ea906Sjfb8856606 	}
4259d30ea906Sjfb8856606 
4260d30ea906Sjfb8856606 	if ((mirror_conf->rule_type & (ETH_MIRROR_VIRTUAL_POOL_UP |
4261d30ea906Sjfb8856606 	     ETH_MIRROR_VIRTUAL_POOL_DOWN)) &&
4262d30ea906Sjfb8856606 	    (mirror_conf->pool_mask == 0)) {
4263d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
4264d30ea906Sjfb8856606 			"Invalid mirror pool, pool mask can not be 0\n");
4265d30ea906Sjfb8856606 		return -EINVAL;
4266d30ea906Sjfb8856606 	}
4267d30ea906Sjfb8856606 
4268d30ea906Sjfb8856606 	if ((mirror_conf->rule_type & ETH_MIRROR_VLAN) &&
4269d30ea906Sjfb8856606 	    mirror_conf->vlan.vlan_mask == 0) {
4270d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
4271d30ea906Sjfb8856606 			"Invalid vlan mask, vlan mask can not be 0\n");
4272d30ea906Sjfb8856606 		return -EINVAL;
4273d30ea906Sjfb8856606 	}
4274d30ea906Sjfb8856606 
4275d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4276d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_set, -ENOTSUP);
4277d30ea906Sjfb8856606 
4278d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->mirror_rule_set)(dev,
4279d30ea906Sjfb8856606 						mirror_conf, rule_id, on));
4280d30ea906Sjfb8856606 }
4281d30ea906Sjfb8856606 
4282d30ea906Sjfb8856606 int
rte_eth_mirror_rule_reset(uint16_t port_id,uint8_t rule_id)4283d30ea906Sjfb8856606 rte_eth_mirror_rule_reset(uint16_t port_id, uint8_t rule_id)
4284d30ea906Sjfb8856606 {
4285d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4286d30ea906Sjfb8856606 
4287d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4288d30ea906Sjfb8856606 
4289d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4290d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_reset, -ENOTSUP);
4291d30ea906Sjfb8856606 
4292d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->mirror_rule_reset)(dev,
4293d30ea906Sjfb8856606 								   rule_id));
4294d30ea906Sjfb8856606 }
4295d30ea906Sjfb8856606 
RTE_INIT(eth_dev_init_cb_lists)4296d30ea906Sjfb8856606 RTE_INIT(eth_dev_init_cb_lists)
4297d30ea906Sjfb8856606 {
42980c6bd470Sfengbojiang 	uint16_t i;
4299d30ea906Sjfb8856606 
4300d30ea906Sjfb8856606 	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
4301d30ea906Sjfb8856606 		TAILQ_INIT(&rte_eth_devices[i].link_intr_cbs);
4302d30ea906Sjfb8856606 }
4303d30ea906Sjfb8856606 
4304d30ea906Sjfb8856606 int
rte_eth_dev_callback_register(uint16_t port_id,enum rte_eth_event_type event,rte_eth_dev_cb_fn cb_fn,void * cb_arg)4305d30ea906Sjfb8856606 rte_eth_dev_callback_register(uint16_t port_id,
4306d30ea906Sjfb8856606 			enum rte_eth_event_type event,
4307d30ea906Sjfb8856606 			rte_eth_dev_cb_fn cb_fn, void *cb_arg)
4308d30ea906Sjfb8856606 {
4309d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4310d30ea906Sjfb8856606 	struct rte_eth_dev_callback *user_cb;
43110c6bd470Sfengbojiang 	uint16_t next_port;
4312d30ea906Sjfb8856606 	uint16_t last_port;
4313d30ea906Sjfb8856606 
4314d30ea906Sjfb8856606 	if (!cb_fn)
4315d30ea906Sjfb8856606 		return -EINVAL;
4316d30ea906Sjfb8856606 
4317d30ea906Sjfb8856606 	if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
4318d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id);
4319d30ea906Sjfb8856606 		return -EINVAL;
4320d30ea906Sjfb8856606 	}
4321d30ea906Sjfb8856606 
4322d30ea906Sjfb8856606 	if (port_id == RTE_ETH_ALL) {
4323d30ea906Sjfb8856606 		next_port = 0;
4324d30ea906Sjfb8856606 		last_port = RTE_MAX_ETHPORTS - 1;
4325d30ea906Sjfb8856606 	} else {
4326d30ea906Sjfb8856606 		next_port = last_port = port_id;
4327d30ea906Sjfb8856606 	}
4328d30ea906Sjfb8856606 
4329*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_cb_lock);
4330d30ea906Sjfb8856606 
4331d30ea906Sjfb8856606 	do {
4332d30ea906Sjfb8856606 		dev = &rte_eth_devices[next_port];
4333d30ea906Sjfb8856606 
4334d30ea906Sjfb8856606 		TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) {
4335d30ea906Sjfb8856606 			if (user_cb->cb_fn == cb_fn &&
4336d30ea906Sjfb8856606 				user_cb->cb_arg == cb_arg &&
4337d30ea906Sjfb8856606 				user_cb->event == event) {
4338d30ea906Sjfb8856606 				break;
4339d30ea906Sjfb8856606 			}
4340d30ea906Sjfb8856606 		}
4341d30ea906Sjfb8856606 
4342d30ea906Sjfb8856606 		/* create a new callback. */
4343d30ea906Sjfb8856606 		if (user_cb == NULL) {
4344d30ea906Sjfb8856606 			user_cb = rte_zmalloc("INTR_USER_CALLBACK",
4345d30ea906Sjfb8856606 				sizeof(struct rte_eth_dev_callback), 0);
4346d30ea906Sjfb8856606 			if (user_cb != NULL) {
4347d30ea906Sjfb8856606 				user_cb->cb_fn = cb_fn;
4348d30ea906Sjfb8856606 				user_cb->cb_arg = cb_arg;
4349d30ea906Sjfb8856606 				user_cb->event = event;
4350d30ea906Sjfb8856606 				TAILQ_INSERT_TAIL(&(dev->link_intr_cbs),
4351d30ea906Sjfb8856606 						  user_cb, next);
4352d30ea906Sjfb8856606 			} else {
4353*2d9fd380Sjfb8856606 				rte_spinlock_unlock(&eth_dev_cb_lock);
4354d30ea906Sjfb8856606 				rte_eth_dev_callback_unregister(port_id, event,
4355d30ea906Sjfb8856606 								cb_fn, cb_arg);
4356d30ea906Sjfb8856606 				return -ENOMEM;
4357d30ea906Sjfb8856606 			}
4358d30ea906Sjfb8856606 
4359d30ea906Sjfb8856606 		}
4360d30ea906Sjfb8856606 	} while (++next_port <= last_port);
4361d30ea906Sjfb8856606 
4362*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_cb_lock);
4363d30ea906Sjfb8856606 	return 0;
4364d30ea906Sjfb8856606 }
4365d30ea906Sjfb8856606 
4366d30ea906Sjfb8856606 int
rte_eth_dev_callback_unregister(uint16_t port_id,enum rte_eth_event_type event,rte_eth_dev_cb_fn cb_fn,void * cb_arg)4367d30ea906Sjfb8856606 rte_eth_dev_callback_unregister(uint16_t port_id,
4368d30ea906Sjfb8856606 			enum rte_eth_event_type event,
4369d30ea906Sjfb8856606 			rte_eth_dev_cb_fn cb_fn, void *cb_arg)
4370d30ea906Sjfb8856606 {
4371d30ea906Sjfb8856606 	int ret;
4372d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4373d30ea906Sjfb8856606 	struct rte_eth_dev_callback *cb, *next;
43740c6bd470Sfengbojiang 	uint16_t next_port;
4375d30ea906Sjfb8856606 	uint16_t last_port;
4376d30ea906Sjfb8856606 
4377d30ea906Sjfb8856606 	if (!cb_fn)
4378d30ea906Sjfb8856606 		return -EINVAL;
4379d30ea906Sjfb8856606 
4380d30ea906Sjfb8856606 	if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
4381d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id);
4382d30ea906Sjfb8856606 		return -EINVAL;
4383d30ea906Sjfb8856606 	}
4384d30ea906Sjfb8856606 
4385d30ea906Sjfb8856606 	if (port_id == RTE_ETH_ALL) {
4386d30ea906Sjfb8856606 		next_port = 0;
4387d30ea906Sjfb8856606 		last_port = RTE_MAX_ETHPORTS - 1;
4388d30ea906Sjfb8856606 	} else {
4389d30ea906Sjfb8856606 		next_port = last_port = port_id;
4390d30ea906Sjfb8856606 	}
4391d30ea906Sjfb8856606 
4392*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_cb_lock);
4393d30ea906Sjfb8856606 
4394d30ea906Sjfb8856606 	do {
4395d30ea906Sjfb8856606 		dev = &rte_eth_devices[next_port];
4396d30ea906Sjfb8856606 		ret = 0;
4397d30ea906Sjfb8856606 		for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL;
4398d30ea906Sjfb8856606 		     cb = next) {
4399d30ea906Sjfb8856606 
4400d30ea906Sjfb8856606 			next = TAILQ_NEXT(cb, next);
4401d30ea906Sjfb8856606 
4402d30ea906Sjfb8856606 			if (cb->cb_fn != cb_fn || cb->event != event ||
44034418919fSjohnjiang 			    (cb_arg != (void *)-1 && cb->cb_arg != cb_arg))
4404d30ea906Sjfb8856606 				continue;
4405d30ea906Sjfb8856606 
4406d30ea906Sjfb8856606 			/*
4407d30ea906Sjfb8856606 			 * if this callback is not executing right now,
4408d30ea906Sjfb8856606 			 * then remove it.
4409d30ea906Sjfb8856606 			 */
4410d30ea906Sjfb8856606 			if (cb->active == 0) {
4411d30ea906Sjfb8856606 				TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next);
4412d30ea906Sjfb8856606 				rte_free(cb);
4413d30ea906Sjfb8856606 			} else {
4414d30ea906Sjfb8856606 				ret = -EAGAIN;
4415d30ea906Sjfb8856606 			}
4416d30ea906Sjfb8856606 		}
4417d30ea906Sjfb8856606 	} while (++next_port <= last_port);
4418d30ea906Sjfb8856606 
4419*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_cb_lock);
4420d30ea906Sjfb8856606 	return ret;
4421d30ea906Sjfb8856606 }
4422d30ea906Sjfb8856606 
4423d30ea906Sjfb8856606 int
rte_eth_dev_callback_process(struct rte_eth_dev * dev,enum rte_eth_event_type event,void * ret_param)4424*2d9fd380Sjfb8856606 rte_eth_dev_callback_process(struct rte_eth_dev *dev,
4425d30ea906Sjfb8856606 	enum rte_eth_event_type event, void *ret_param)
4426d30ea906Sjfb8856606 {
4427d30ea906Sjfb8856606 	struct rte_eth_dev_callback *cb_lst;
4428d30ea906Sjfb8856606 	struct rte_eth_dev_callback dev_cb;
4429d30ea906Sjfb8856606 	int rc = 0;
4430d30ea906Sjfb8856606 
4431*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_cb_lock);
4432d30ea906Sjfb8856606 	TAILQ_FOREACH(cb_lst, &(dev->link_intr_cbs), next) {
4433d30ea906Sjfb8856606 		if (cb_lst->cb_fn == NULL || cb_lst->event != event)
4434d30ea906Sjfb8856606 			continue;
4435d30ea906Sjfb8856606 		dev_cb = *cb_lst;
4436d30ea906Sjfb8856606 		cb_lst->active = 1;
4437d30ea906Sjfb8856606 		if (ret_param != NULL)
4438d30ea906Sjfb8856606 			dev_cb.ret_param = ret_param;
4439d30ea906Sjfb8856606 
4440*2d9fd380Sjfb8856606 		rte_spinlock_unlock(&eth_dev_cb_lock);
4441d30ea906Sjfb8856606 		rc = dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
4442d30ea906Sjfb8856606 				dev_cb.cb_arg, dev_cb.ret_param);
4443*2d9fd380Sjfb8856606 		rte_spinlock_lock(&eth_dev_cb_lock);
4444d30ea906Sjfb8856606 		cb_lst->active = 0;
4445d30ea906Sjfb8856606 	}
4446*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_cb_lock);
4447d30ea906Sjfb8856606 	return rc;
4448d30ea906Sjfb8856606 }
4449d30ea906Sjfb8856606 
4450d30ea906Sjfb8856606 void
rte_eth_dev_probing_finish(struct rte_eth_dev * dev)4451d30ea906Sjfb8856606 rte_eth_dev_probing_finish(struct rte_eth_dev *dev)
4452d30ea906Sjfb8856606 {
4453d30ea906Sjfb8856606 	if (dev == NULL)
4454d30ea906Sjfb8856606 		return;
4455d30ea906Sjfb8856606 
4456*2d9fd380Sjfb8856606 	rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_NEW, NULL);
4457d30ea906Sjfb8856606 
4458d30ea906Sjfb8856606 	dev->state = RTE_ETH_DEV_ATTACHED;
4459d30ea906Sjfb8856606 }
4460d30ea906Sjfb8856606 
4461d30ea906Sjfb8856606 int
rte_eth_dev_rx_intr_ctl(uint16_t port_id,int epfd,int op,void * data)4462d30ea906Sjfb8856606 rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data)
4463d30ea906Sjfb8856606 {
4464d30ea906Sjfb8856606 	uint32_t vec;
4465d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4466d30ea906Sjfb8856606 	struct rte_intr_handle *intr_handle;
4467d30ea906Sjfb8856606 	uint16_t qid;
4468d30ea906Sjfb8856606 	int rc;
4469d30ea906Sjfb8856606 
4470d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4471d30ea906Sjfb8856606 
4472d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4473d30ea906Sjfb8856606 
4474d30ea906Sjfb8856606 	if (!dev->intr_handle) {
4475d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "RX Intr handle unset\n");
4476d30ea906Sjfb8856606 		return -ENOTSUP;
4477d30ea906Sjfb8856606 	}
4478d30ea906Sjfb8856606 
4479d30ea906Sjfb8856606 	intr_handle = dev->intr_handle;
4480d30ea906Sjfb8856606 	if (!intr_handle->intr_vec) {
4481d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "RX Intr vector unset\n");
4482d30ea906Sjfb8856606 		return -EPERM;
4483d30ea906Sjfb8856606 	}
4484d30ea906Sjfb8856606 
4485d30ea906Sjfb8856606 	for (qid = 0; qid < dev->data->nb_rx_queues; qid++) {
4486d30ea906Sjfb8856606 		vec = intr_handle->intr_vec[qid];
4487d30ea906Sjfb8856606 		rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data);
4488d30ea906Sjfb8856606 		if (rc && rc != -EEXIST) {
4489d30ea906Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
4490d30ea906Sjfb8856606 				"p %u q %u rx ctl error op %d epfd %d vec %u\n",
4491d30ea906Sjfb8856606 				port_id, qid, op, epfd, vec);
4492d30ea906Sjfb8856606 		}
4493d30ea906Sjfb8856606 	}
4494d30ea906Sjfb8856606 
4495d30ea906Sjfb8856606 	return 0;
4496d30ea906Sjfb8856606 }
4497d30ea906Sjfb8856606 
44984418919fSjohnjiang int
rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id,uint16_t queue_id)4499d30ea906Sjfb8856606 rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id, uint16_t queue_id)
4500d30ea906Sjfb8856606 {
4501d30ea906Sjfb8856606 	struct rte_intr_handle *intr_handle;
4502d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4503d30ea906Sjfb8856606 	unsigned int efd_idx;
4504d30ea906Sjfb8856606 	uint32_t vec;
4505d30ea906Sjfb8856606 	int fd;
4506d30ea906Sjfb8856606 
4507d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
4508d30ea906Sjfb8856606 
4509d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4510d30ea906Sjfb8856606 
4511d30ea906Sjfb8856606 	if (queue_id >= dev->data->nb_rx_queues) {
4512d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
4513d30ea906Sjfb8856606 		return -1;
4514d30ea906Sjfb8856606 	}
4515d30ea906Sjfb8856606 
4516d30ea906Sjfb8856606 	if (!dev->intr_handle) {
4517d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "RX Intr handle unset\n");
4518d30ea906Sjfb8856606 		return -1;
4519d30ea906Sjfb8856606 	}
4520d30ea906Sjfb8856606 
4521d30ea906Sjfb8856606 	intr_handle = dev->intr_handle;
4522d30ea906Sjfb8856606 	if (!intr_handle->intr_vec) {
4523d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "RX Intr vector unset\n");
4524d30ea906Sjfb8856606 		return -1;
4525d30ea906Sjfb8856606 	}
4526d30ea906Sjfb8856606 
4527d30ea906Sjfb8856606 	vec = intr_handle->intr_vec[queue_id];
4528d30ea906Sjfb8856606 	efd_idx = (vec >= RTE_INTR_VEC_RXTX_OFFSET) ?
4529d30ea906Sjfb8856606 		(vec - RTE_INTR_VEC_RXTX_OFFSET) : vec;
4530d30ea906Sjfb8856606 	fd = intr_handle->efds[efd_idx];
4531d30ea906Sjfb8856606 
4532d30ea906Sjfb8856606 	return fd;
4533d30ea906Sjfb8856606 }
4534d30ea906Sjfb8856606 
4535*2d9fd380Sjfb8856606 static inline int
eth_dev_dma_mzone_name(char * name,size_t len,uint16_t port_id,uint16_t queue_id,const char * ring_name)4536*2d9fd380Sjfb8856606 eth_dev_dma_mzone_name(char *name, size_t len, uint16_t port_id, uint16_t queue_id,
4537*2d9fd380Sjfb8856606 		const char *ring_name)
4538*2d9fd380Sjfb8856606 {
4539*2d9fd380Sjfb8856606 	return snprintf(name, len, "eth_p%d_q%d_%s",
4540*2d9fd380Sjfb8856606 			port_id, queue_id, ring_name);
4541*2d9fd380Sjfb8856606 }
4542*2d9fd380Sjfb8856606 
4543d30ea906Sjfb8856606 const struct rte_memzone *
rte_eth_dma_zone_reserve(const struct rte_eth_dev * dev,const char * ring_name,uint16_t queue_id,size_t size,unsigned align,int socket_id)4544d30ea906Sjfb8856606 rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
4545d30ea906Sjfb8856606 			 uint16_t queue_id, size_t size, unsigned align,
4546d30ea906Sjfb8856606 			 int socket_id)
4547d30ea906Sjfb8856606 {
4548d30ea906Sjfb8856606 	char z_name[RTE_MEMZONE_NAMESIZE];
4549d30ea906Sjfb8856606 	const struct rte_memzone *mz;
45504418919fSjohnjiang 	int rc;
4551d30ea906Sjfb8856606 
4552*2d9fd380Sjfb8856606 	rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id,
4553*2d9fd380Sjfb8856606 			queue_id, ring_name);
45544418919fSjohnjiang 	if (rc >= RTE_MEMZONE_NAMESIZE) {
45554418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR, "ring name too long\n");
45564418919fSjohnjiang 		rte_errno = ENAMETOOLONG;
45574418919fSjohnjiang 		return NULL;
45584418919fSjohnjiang 	}
4559d30ea906Sjfb8856606 
4560d30ea906Sjfb8856606 	mz = rte_memzone_lookup(z_name);
4561*2d9fd380Sjfb8856606 	if (mz) {
4562*2d9fd380Sjfb8856606 		if ((socket_id != SOCKET_ID_ANY && socket_id != mz->socket_id) ||
4563*2d9fd380Sjfb8856606 				size > mz->len ||
4564*2d9fd380Sjfb8856606 				((uintptr_t)mz->addr & (align - 1)) != 0) {
4565*2d9fd380Sjfb8856606 			RTE_ETHDEV_LOG(ERR,
4566*2d9fd380Sjfb8856606 				"memzone %s does not justify the requested attributes\n",
4567*2d9fd380Sjfb8856606 				mz->name);
4568*2d9fd380Sjfb8856606 			return NULL;
4569*2d9fd380Sjfb8856606 		}
4570*2d9fd380Sjfb8856606 
4571d30ea906Sjfb8856606 		return mz;
4572*2d9fd380Sjfb8856606 	}
4573d30ea906Sjfb8856606 
4574d30ea906Sjfb8856606 	return rte_memzone_reserve_aligned(z_name, size, socket_id,
4575d30ea906Sjfb8856606 			RTE_MEMZONE_IOVA_CONTIG, align);
4576d30ea906Sjfb8856606 }
4577d30ea906Sjfb8856606 
45784418919fSjohnjiang int
rte_eth_dma_zone_free(const struct rte_eth_dev * dev,const char * ring_name,uint16_t queue_id)4579*2d9fd380Sjfb8856606 rte_eth_dma_zone_free(const struct rte_eth_dev *dev, const char *ring_name,
4580*2d9fd380Sjfb8856606 		uint16_t queue_id)
4581*2d9fd380Sjfb8856606 {
4582*2d9fd380Sjfb8856606 	char z_name[RTE_MEMZONE_NAMESIZE];
4583*2d9fd380Sjfb8856606 	const struct rte_memzone *mz;
4584*2d9fd380Sjfb8856606 	int rc = 0;
4585*2d9fd380Sjfb8856606 
4586*2d9fd380Sjfb8856606 	rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id,
4587*2d9fd380Sjfb8856606 			queue_id, ring_name);
4588*2d9fd380Sjfb8856606 	if (rc >= RTE_MEMZONE_NAMESIZE) {
4589*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "ring name too long\n");
4590*2d9fd380Sjfb8856606 		return -ENAMETOOLONG;
4591*2d9fd380Sjfb8856606 	}
4592*2d9fd380Sjfb8856606 
4593*2d9fd380Sjfb8856606 	mz = rte_memzone_lookup(z_name);
4594*2d9fd380Sjfb8856606 	if (mz)
4595*2d9fd380Sjfb8856606 		rc = rte_memzone_free(mz);
4596*2d9fd380Sjfb8856606 	else
4597*2d9fd380Sjfb8856606 		rc = -ENOENT;
4598*2d9fd380Sjfb8856606 
4599*2d9fd380Sjfb8856606 	return rc;
4600*2d9fd380Sjfb8856606 }
4601*2d9fd380Sjfb8856606 
4602*2d9fd380Sjfb8856606 int
rte_eth_dev_create(struct rte_device * device,const char * name,size_t priv_data_size,ethdev_bus_specific_init ethdev_bus_specific_init,void * bus_init_params,ethdev_init_t ethdev_init,void * init_params)4603d30ea906Sjfb8856606 rte_eth_dev_create(struct rte_device *device, const char *name,
4604d30ea906Sjfb8856606 	size_t priv_data_size,
4605d30ea906Sjfb8856606 	ethdev_bus_specific_init ethdev_bus_specific_init,
4606d30ea906Sjfb8856606 	void *bus_init_params,
4607d30ea906Sjfb8856606 	ethdev_init_t ethdev_init, void *init_params)
4608d30ea906Sjfb8856606 {
4609d30ea906Sjfb8856606 	struct rte_eth_dev *ethdev;
4610d30ea906Sjfb8856606 	int retval;
4611d30ea906Sjfb8856606 
4612d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL);
4613d30ea906Sjfb8856606 
4614d30ea906Sjfb8856606 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
4615d30ea906Sjfb8856606 		ethdev = rte_eth_dev_allocate(name);
4616d30ea906Sjfb8856606 		if (!ethdev)
4617d30ea906Sjfb8856606 			return -ENODEV;
4618d30ea906Sjfb8856606 
4619d30ea906Sjfb8856606 		if (priv_data_size) {
4620d30ea906Sjfb8856606 			ethdev->data->dev_private = rte_zmalloc_socket(
4621d30ea906Sjfb8856606 				name, priv_data_size, RTE_CACHE_LINE_SIZE,
4622d30ea906Sjfb8856606 				device->numa_node);
4623d30ea906Sjfb8856606 
4624d30ea906Sjfb8856606 			if (!ethdev->data->dev_private) {
46250c6bd470Sfengbojiang 				RTE_ETHDEV_LOG(ERR,
46260c6bd470Sfengbojiang 					"failed to allocate private data\n");
4627d30ea906Sjfb8856606 				retval = -ENOMEM;
4628d30ea906Sjfb8856606 				goto probe_failed;
4629d30ea906Sjfb8856606 			}
4630d30ea906Sjfb8856606 		}
4631d30ea906Sjfb8856606 	} else {
4632d30ea906Sjfb8856606 		ethdev = rte_eth_dev_attach_secondary(name);
4633d30ea906Sjfb8856606 		if (!ethdev) {
46340c6bd470Sfengbojiang 			RTE_ETHDEV_LOG(ERR,
46350c6bd470Sfengbojiang 				"secondary process attach failed, ethdev doesn't exist\n");
4636d30ea906Sjfb8856606 			return  -ENODEV;
4637d30ea906Sjfb8856606 		}
4638d30ea906Sjfb8856606 	}
4639d30ea906Sjfb8856606 
4640d30ea906Sjfb8856606 	ethdev->device = device;
4641d30ea906Sjfb8856606 
4642d30ea906Sjfb8856606 	if (ethdev_bus_specific_init) {
4643d30ea906Sjfb8856606 		retval = ethdev_bus_specific_init(ethdev, bus_init_params);
4644d30ea906Sjfb8856606 		if (retval) {
46450c6bd470Sfengbojiang 			RTE_ETHDEV_LOG(ERR,
46460c6bd470Sfengbojiang 				"ethdev bus specific initialisation failed\n");
4647d30ea906Sjfb8856606 			goto probe_failed;
4648d30ea906Sjfb8856606 		}
4649d30ea906Sjfb8856606 	}
4650d30ea906Sjfb8856606 
4651d30ea906Sjfb8856606 	retval = ethdev_init(ethdev, init_params);
4652d30ea906Sjfb8856606 	if (retval) {
46530c6bd470Sfengbojiang 		RTE_ETHDEV_LOG(ERR, "ethdev initialisation failed\n");
4654d30ea906Sjfb8856606 		goto probe_failed;
4655d30ea906Sjfb8856606 	}
4656d30ea906Sjfb8856606 
4657d30ea906Sjfb8856606 	rte_eth_dev_probing_finish(ethdev);
4658d30ea906Sjfb8856606 
4659d30ea906Sjfb8856606 	return retval;
4660d30ea906Sjfb8856606 
4661d30ea906Sjfb8856606 probe_failed:
4662d30ea906Sjfb8856606 	rte_eth_dev_release_port(ethdev);
4663d30ea906Sjfb8856606 	return retval;
4664d30ea906Sjfb8856606 }
4665d30ea906Sjfb8856606 
46664418919fSjohnjiang int
rte_eth_dev_destroy(struct rte_eth_dev * ethdev,ethdev_uninit_t ethdev_uninit)4667d30ea906Sjfb8856606 rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
4668d30ea906Sjfb8856606 	ethdev_uninit_t ethdev_uninit)
4669d30ea906Sjfb8856606 {
4670d30ea906Sjfb8856606 	int ret;
4671d30ea906Sjfb8856606 
4672d30ea906Sjfb8856606 	ethdev = rte_eth_dev_allocated(ethdev->data->name);
4673d30ea906Sjfb8856606 	if (!ethdev)
4674d30ea906Sjfb8856606 		return -ENODEV;
4675d30ea906Sjfb8856606 
4676d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL);
4677d30ea906Sjfb8856606 
4678d30ea906Sjfb8856606 	ret = ethdev_uninit(ethdev);
4679d30ea906Sjfb8856606 	if (ret)
4680d30ea906Sjfb8856606 		return ret;
4681d30ea906Sjfb8856606 
4682d30ea906Sjfb8856606 	return rte_eth_dev_release_port(ethdev);
4683d30ea906Sjfb8856606 }
4684d30ea906Sjfb8856606 
4685d30ea906Sjfb8856606 int
rte_eth_dev_rx_intr_ctl_q(uint16_t port_id,uint16_t queue_id,int epfd,int op,void * data)4686d30ea906Sjfb8856606 rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
4687d30ea906Sjfb8856606 			  int epfd, int op, void *data)
4688d30ea906Sjfb8856606 {
4689d30ea906Sjfb8856606 	uint32_t vec;
4690d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4691d30ea906Sjfb8856606 	struct rte_intr_handle *intr_handle;
4692d30ea906Sjfb8856606 	int rc;
4693d30ea906Sjfb8856606 
4694d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4695d30ea906Sjfb8856606 
4696d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4697d30ea906Sjfb8856606 	if (queue_id >= dev->data->nb_rx_queues) {
4698d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
4699d30ea906Sjfb8856606 		return -EINVAL;
4700d30ea906Sjfb8856606 	}
4701d30ea906Sjfb8856606 
4702d30ea906Sjfb8856606 	if (!dev->intr_handle) {
4703d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "RX Intr handle unset\n");
4704d30ea906Sjfb8856606 		return -ENOTSUP;
4705d30ea906Sjfb8856606 	}
4706d30ea906Sjfb8856606 
4707d30ea906Sjfb8856606 	intr_handle = dev->intr_handle;
4708d30ea906Sjfb8856606 	if (!intr_handle->intr_vec) {
4709d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "RX Intr vector unset\n");
4710d30ea906Sjfb8856606 		return -EPERM;
4711d30ea906Sjfb8856606 	}
4712d30ea906Sjfb8856606 
4713d30ea906Sjfb8856606 	vec = intr_handle->intr_vec[queue_id];
4714d30ea906Sjfb8856606 	rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data);
4715d30ea906Sjfb8856606 	if (rc && rc != -EEXIST) {
4716d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
4717d30ea906Sjfb8856606 			"p %u q %u rx ctl error op %d epfd %d vec %u\n",
4718d30ea906Sjfb8856606 			port_id, queue_id, op, epfd, vec);
4719d30ea906Sjfb8856606 		return rc;
4720d30ea906Sjfb8856606 	}
4721d30ea906Sjfb8856606 
4722d30ea906Sjfb8856606 	return 0;
4723d30ea906Sjfb8856606 }
4724d30ea906Sjfb8856606 
4725d30ea906Sjfb8856606 int
rte_eth_dev_rx_intr_enable(uint16_t port_id,uint16_t queue_id)4726d30ea906Sjfb8856606 rte_eth_dev_rx_intr_enable(uint16_t port_id,
4727d30ea906Sjfb8856606 			   uint16_t queue_id)
4728d30ea906Sjfb8856606 {
4729d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4730*2d9fd380Sjfb8856606 	int ret;
4731d30ea906Sjfb8856606 
4732d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4733d30ea906Sjfb8856606 
4734d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4735d30ea906Sjfb8856606 
4736*2d9fd380Sjfb8856606 	ret = eth_dev_validate_rx_queue(dev, queue_id);
4737*2d9fd380Sjfb8856606 	if (ret != 0)
4738*2d9fd380Sjfb8856606 		return ret;
4739*2d9fd380Sjfb8856606 
4740d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_enable, -ENOTSUP);
4741d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_enable)(dev,
4742d30ea906Sjfb8856606 								queue_id));
4743d30ea906Sjfb8856606 }
4744d30ea906Sjfb8856606 
4745d30ea906Sjfb8856606 int
rte_eth_dev_rx_intr_disable(uint16_t port_id,uint16_t queue_id)4746d30ea906Sjfb8856606 rte_eth_dev_rx_intr_disable(uint16_t port_id,
4747d30ea906Sjfb8856606 			    uint16_t queue_id)
4748d30ea906Sjfb8856606 {
4749d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4750*2d9fd380Sjfb8856606 	int ret;
4751d30ea906Sjfb8856606 
4752d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4753d30ea906Sjfb8856606 
4754d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
4755d30ea906Sjfb8856606 
4756*2d9fd380Sjfb8856606 	ret = eth_dev_validate_rx_queue(dev, queue_id);
4757*2d9fd380Sjfb8856606 	if (ret != 0)
4758*2d9fd380Sjfb8856606 		return ret;
4759*2d9fd380Sjfb8856606 
4760d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_disable, -ENOTSUP);
4761d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_disable)(dev,
4762d30ea906Sjfb8856606 								queue_id));
4763d30ea906Sjfb8856606 }
4764d30ea906Sjfb8856606 
4765d30ea906Sjfb8856606 
4766d30ea906Sjfb8856606 const struct rte_eth_rxtx_callback *
rte_eth_add_rx_callback(uint16_t port_id,uint16_t queue_id,rte_rx_callback_fn fn,void * user_param)4767d30ea906Sjfb8856606 rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id,
4768d30ea906Sjfb8856606 		rte_rx_callback_fn fn, void *user_param)
4769d30ea906Sjfb8856606 {
4770d30ea906Sjfb8856606 #ifndef RTE_ETHDEV_RXTX_CALLBACKS
4771d30ea906Sjfb8856606 	rte_errno = ENOTSUP;
4772d30ea906Sjfb8856606 	return NULL;
4773d30ea906Sjfb8856606 #endif
47744418919fSjohnjiang 	struct rte_eth_dev *dev;
47754418919fSjohnjiang 
4776d30ea906Sjfb8856606 	/* check input parameters */
4777d30ea906Sjfb8856606 	if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
4778d30ea906Sjfb8856606 		    queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) {
4779d30ea906Sjfb8856606 		rte_errno = EINVAL;
4780d30ea906Sjfb8856606 		return NULL;
4781d30ea906Sjfb8856606 	}
47824418919fSjohnjiang 	dev = &rte_eth_devices[port_id];
47834418919fSjohnjiang 	if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) {
47844418919fSjohnjiang 		rte_errno = EINVAL;
47854418919fSjohnjiang 		return NULL;
47864418919fSjohnjiang 	}
4787d30ea906Sjfb8856606 	struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
4788d30ea906Sjfb8856606 
4789d30ea906Sjfb8856606 	if (cb == NULL) {
4790d30ea906Sjfb8856606 		rte_errno = ENOMEM;
4791d30ea906Sjfb8856606 		return NULL;
4792d30ea906Sjfb8856606 	}
4793d30ea906Sjfb8856606 
4794d30ea906Sjfb8856606 	cb->fn.rx = fn;
4795d30ea906Sjfb8856606 	cb->param = user_param;
4796d30ea906Sjfb8856606 
4797*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_rx_cb_lock);
4798d30ea906Sjfb8856606 	/* Add the callbacks in fifo order. */
4799d30ea906Sjfb8856606 	struct rte_eth_rxtx_callback *tail =
4800d30ea906Sjfb8856606 		rte_eth_devices[port_id].post_rx_burst_cbs[queue_id];
4801d30ea906Sjfb8856606 
4802d30ea906Sjfb8856606 	if (!tail) {
48030c6bd470Sfengbojiang 		/* Stores to cb->fn and cb->param should complete before
48040c6bd470Sfengbojiang 		 * cb is visible to data plane.
48050c6bd470Sfengbojiang 		 */
48060c6bd470Sfengbojiang 		__atomic_store_n(
48070c6bd470Sfengbojiang 			&rte_eth_devices[port_id].post_rx_burst_cbs[queue_id],
48080c6bd470Sfengbojiang 			cb, __ATOMIC_RELEASE);
4809d30ea906Sjfb8856606 
4810d30ea906Sjfb8856606 	} else {
4811d30ea906Sjfb8856606 		while (tail->next)
4812d30ea906Sjfb8856606 			tail = tail->next;
48130c6bd470Sfengbojiang 		/* Stores to cb->fn and cb->param should complete before
48140c6bd470Sfengbojiang 		 * cb is visible to data plane.
48150c6bd470Sfengbojiang 		 */
48160c6bd470Sfengbojiang 		__atomic_store_n(&tail->next, cb, __ATOMIC_RELEASE);
4817d30ea906Sjfb8856606 	}
4818*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_rx_cb_lock);
4819d30ea906Sjfb8856606 
4820d30ea906Sjfb8856606 	return cb;
4821d30ea906Sjfb8856606 }
4822d30ea906Sjfb8856606 
4823d30ea906Sjfb8856606 const struct rte_eth_rxtx_callback *
rte_eth_add_first_rx_callback(uint16_t port_id,uint16_t queue_id,rte_rx_callback_fn fn,void * user_param)4824d30ea906Sjfb8856606 rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id,
4825d30ea906Sjfb8856606 		rte_rx_callback_fn fn, void *user_param)
4826d30ea906Sjfb8856606 {
4827d30ea906Sjfb8856606 #ifndef RTE_ETHDEV_RXTX_CALLBACKS
4828d30ea906Sjfb8856606 	rte_errno = ENOTSUP;
4829d30ea906Sjfb8856606 	return NULL;
4830d30ea906Sjfb8856606 #endif
4831d30ea906Sjfb8856606 	/* check input parameters */
4832d30ea906Sjfb8856606 	if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
4833d30ea906Sjfb8856606 		queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) {
4834d30ea906Sjfb8856606 		rte_errno = EINVAL;
4835d30ea906Sjfb8856606 		return NULL;
4836d30ea906Sjfb8856606 	}
4837d30ea906Sjfb8856606 
4838d30ea906Sjfb8856606 	struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
4839d30ea906Sjfb8856606 
4840d30ea906Sjfb8856606 	if (cb == NULL) {
4841d30ea906Sjfb8856606 		rte_errno = ENOMEM;
4842d30ea906Sjfb8856606 		return NULL;
4843d30ea906Sjfb8856606 	}
4844d30ea906Sjfb8856606 
4845d30ea906Sjfb8856606 	cb->fn.rx = fn;
4846d30ea906Sjfb8856606 	cb->param = user_param;
4847d30ea906Sjfb8856606 
4848*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_rx_cb_lock);
48490c6bd470Sfengbojiang 	/* Add the callbacks at first position */
4850d30ea906Sjfb8856606 	cb->next = rte_eth_devices[port_id].post_rx_burst_cbs[queue_id];
4851*2d9fd380Sjfb8856606 	/* Stores to cb->fn, cb->param and cb->next should complete before
4852*2d9fd380Sjfb8856606 	 * cb is visible to data plane threads.
4853*2d9fd380Sjfb8856606 	 */
4854*2d9fd380Sjfb8856606 	__atomic_store_n(
4855*2d9fd380Sjfb8856606 		&rte_eth_devices[port_id].post_rx_burst_cbs[queue_id],
4856*2d9fd380Sjfb8856606 		cb, __ATOMIC_RELEASE);
4857*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_rx_cb_lock);
4858d30ea906Sjfb8856606 
4859d30ea906Sjfb8856606 	return cb;
4860d30ea906Sjfb8856606 }
4861d30ea906Sjfb8856606 
4862d30ea906Sjfb8856606 const struct rte_eth_rxtx_callback *
rte_eth_add_tx_callback(uint16_t port_id,uint16_t queue_id,rte_tx_callback_fn fn,void * user_param)4863d30ea906Sjfb8856606 rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id,
4864d30ea906Sjfb8856606 		rte_tx_callback_fn fn, void *user_param)
4865d30ea906Sjfb8856606 {
4866d30ea906Sjfb8856606 #ifndef RTE_ETHDEV_RXTX_CALLBACKS
4867d30ea906Sjfb8856606 	rte_errno = ENOTSUP;
4868d30ea906Sjfb8856606 	return NULL;
4869d30ea906Sjfb8856606 #endif
48704418919fSjohnjiang 	struct rte_eth_dev *dev;
48714418919fSjohnjiang 
4872d30ea906Sjfb8856606 	/* check input parameters */
4873d30ea906Sjfb8856606 	if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
4874d30ea906Sjfb8856606 		    queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) {
4875d30ea906Sjfb8856606 		rte_errno = EINVAL;
4876d30ea906Sjfb8856606 		return NULL;
4877d30ea906Sjfb8856606 	}
4878d30ea906Sjfb8856606 
48794418919fSjohnjiang 	dev = &rte_eth_devices[port_id];
48804418919fSjohnjiang 	if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) {
48814418919fSjohnjiang 		rte_errno = EINVAL;
48824418919fSjohnjiang 		return NULL;
48834418919fSjohnjiang 	}
48844418919fSjohnjiang 
4885d30ea906Sjfb8856606 	struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
4886d30ea906Sjfb8856606 
4887d30ea906Sjfb8856606 	if (cb == NULL) {
4888d30ea906Sjfb8856606 		rte_errno = ENOMEM;
4889d30ea906Sjfb8856606 		return NULL;
4890d30ea906Sjfb8856606 	}
4891d30ea906Sjfb8856606 
4892d30ea906Sjfb8856606 	cb->fn.tx = fn;
4893d30ea906Sjfb8856606 	cb->param = user_param;
4894d30ea906Sjfb8856606 
4895*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_tx_cb_lock);
4896d30ea906Sjfb8856606 	/* Add the callbacks in fifo order. */
4897d30ea906Sjfb8856606 	struct rte_eth_rxtx_callback *tail =
4898d30ea906Sjfb8856606 		rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id];
4899d30ea906Sjfb8856606 
4900d30ea906Sjfb8856606 	if (!tail) {
49010c6bd470Sfengbojiang 		/* Stores to cb->fn and cb->param should complete before
49020c6bd470Sfengbojiang 		 * cb is visible to data plane.
49030c6bd470Sfengbojiang 		 */
49040c6bd470Sfengbojiang 		__atomic_store_n(
49050c6bd470Sfengbojiang 			&rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id],
49060c6bd470Sfengbojiang 			cb, __ATOMIC_RELEASE);
4907d30ea906Sjfb8856606 
4908d30ea906Sjfb8856606 	} else {
4909d30ea906Sjfb8856606 		while (tail->next)
4910d30ea906Sjfb8856606 			tail = tail->next;
49110c6bd470Sfengbojiang 		/* Stores to cb->fn and cb->param should complete before
49120c6bd470Sfengbojiang 		 * cb is visible to data plane.
49130c6bd470Sfengbojiang 		 */
49140c6bd470Sfengbojiang 		__atomic_store_n(&tail->next, cb, __ATOMIC_RELEASE);
4915d30ea906Sjfb8856606 	}
4916*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_tx_cb_lock);
4917d30ea906Sjfb8856606 
4918d30ea906Sjfb8856606 	return cb;
4919d30ea906Sjfb8856606 }
4920d30ea906Sjfb8856606 
4921d30ea906Sjfb8856606 int
rte_eth_remove_rx_callback(uint16_t port_id,uint16_t queue_id,const struct rte_eth_rxtx_callback * user_cb)4922d30ea906Sjfb8856606 rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id,
4923d30ea906Sjfb8856606 		const struct rte_eth_rxtx_callback *user_cb)
4924d30ea906Sjfb8856606 {
4925d30ea906Sjfb8856606 #ifndef RTE_ETHDEV_RXTX_CALLBACKS
4926d30ea906Sjfb8856606 	return -ENOTSUP;
4927d30ea906Sjfb8856606 #endif
4928d30ea906Sjfb8856606 	/* Check input parameters. */
4929*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4930d30ea906Sjfb8856606 	if (user_cb == NULL ||
4931d30ea906Sjfb8856606 			queue_id >= rte_eth_devices[port_id].data->nb_rx_queues)
4932d30ea906Sjfb8856606 		return -EINVAL;
4933d30ea906Sjfb8856606 
4934d30ea906Sjfb8856606 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
4935d30ea906Sjfb8856606 	struct rte_eth_rxtx_callback *cb;
4936d30ea906Sjfb8856606 	struct rte_eth_rxtx_callback **prev_cb;
4937d30ea906Sjfb8856606 	int ret = -EINVAL;
4938d30ea906Sjfb8856606 
4939*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_rx_cb_lock);
4940d30ea906Sjfb8856606 	prev_cb = &dev->post_rx_burst_cbs[queue_id];
4941d30ea906Sjfb8856606 	for (; *prev_cb != NULL; prev_cb = &cb->next) {
4942d30ea906Sjfb8856606 		cb = *prev_cb;
4943d30ea906Sjfb8856606 		if (cb == user_cb) {
4944d30ea906Sjfb8856606 			/* Remove the user cb from the callback list. */
49450c6bd470Sfengbojiang 			__atomic_store_n(prev_cb, cb->next, __ATOMIC_RELAXED);
4946d30ea906Sjfb8856606 			ret = 0;
4947d30ea906Sjfb8856606 			break;
4948d30ea906Sjfb8856606 		}
4949d30ea906Sjfb8856606 	}
4950*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_rx_cb_lock);
4951d30ea906Sjfb8856606 
4952d30ea906Sjfb8856606 	return ret;
4953d30ea906Sjfb8856606 }
4954d30ea906Sjfb8856606 
4955d30ea906Sjfb8856606 int
rte_eth_remove_tx_callback(uint16_t port_id,uint16_t queue_id,const struct rte_eth_rxtx_callback * user_cb)4956d30ea906Sjfb8856606 rte_eth_remove_tx_callback(uint16_t port_id, uint16_t queue_id,
4957d30ea906Sjfb8856606 		const struct rte_eth_rxtx_callback *user_cb)
4958d30ea906Sjfb8856606 {
4959d30ea906Sjfb8856606 #ifndef RTE_ETHDEV_RXTX_CALLBACKS
4960d30ea906Sjfb8856606 	return -ENOTSUP;
4961d30ea906Sjfb8856606 #endif
4962d30ea906Sjfb8856606 	/* Check input parameters. */
4963*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4964d30ea906Sjfb8856606 	if (user_cb == NULL ||
4965d30ea906Sjfb8856606 			queue_id >= rte_eth_devices[port_id].data->nb_tx_queues)
4966d30ea906Sjfb8856606 		return -EINVAL;
4967d30ea906Sjfb8856606 
4968d30ea906Sjfb8856606 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
4969d30ea906Sjfb8856606 	int ret = -EINVAL;
4970d30ea906Sjfb8856606 	struct rte_eth_rxtx_callback *cb;
4971d30ea906Sjfb8856606 	struct rte_eth_rxtx_callback **prev_cb;
4972d30ea906Sjfb8856606 
4973*2d9fd380Sjfb8856606 	rte_spinlock_lock(&eth_dev_tx_cb_lock);
4974d30ea906Sjfb8856606 	prev_cb = &dev->pre_tx_burst_cbs[queue_id];
4975d30ea906Sjfb8856606 	for (; *prev_cb != NULL; prev_cb = &cb->next) {
4976d30ea906Sjfb8856606 		cb = *prev_cb;
4977d30ea906Sjfb8856606 		if (cb == user_cb) {
4978d30ea906Sjfb8856606 			/* Remove the user cb from the callback list. */
49790c6bd470Sfengbojiang 			__atomic_store_n(prev_cb, cb->next, __ATOMIC_RELAXED);
4980d30ea906Sjfb8856606 			ret = 0;
4981d30ea906Sjfb8856606 			break;
4982d30ea906Sjfb8856606 		}
4983d30ea906Sjfb8856606 	}
4984*2d9fd380Sjfb8856606 	rte_spinlock_unlock(&eth_dev_tx_cb_lock);
4985d30ea906Sjfb8856606 
4986d30ea906Sjfb8856606 	return ret;
4987d30ea906Sjfb8856606 }
4988d30ea906Sjfb8856606 
4989d30ea906Sjfb8856606 int
rte_eth_rx_queue_info_get(uint16_t port_id,uint16_t queue_id,struct rte_eth_rxq_info * qinfo)4990d30ea906Sjfb8856606 rte_eth_rx_queue_info_get(uint16_t port_id, uint16_t queue_id,
4991d30ea906Sjfb8856606 	struct rte_eth_rxq_info *qinfo)
4992d30ea906Sjfb8856606 {
4993d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
4994d30ea906Sjfb8856606 
4995d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4996d30ea906Sjfb8856606 
4997d30ea906Sjfb8856606 	if (qinfo == NULL)
4998d30ea906Sjfb8856606 		return -EINVAL;
4999d30ea906Sjfb8856606 
5000d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5001d30ea906Sjfb8856606 	if (queue_id >= dev->data->nb_rx_queues) {
5002d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
5003d30ea906Sjfb8856606 		return -EINVAL;
5004d30ea906Sjfb8856606 	}
5005d30ea906Sjfb8856606 
5006*2d9fd380Sjfb8856606 	if (dev->data->rx_queues == NULL ||
5007*2d9fd380Sjfb8856606 			dev->data->rx_queues[queue_id] == NULL) {
5008*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
5009*2d9fd380Sjfb8856606 			       "Rx queue %"PRIu16" of device with port_id=%"
5010*2d9fd380Sjfb8856606 			       PRIu16" has not been setup\n",
5011*2d9fd380Sjfb8856606 			       queue_id, port_id);
5012*2d9fd380Sjfb8856606 		return -EINVAL;
5013*2d9fd380Sjfb8856606 	}
5014*2d9fd380Sjfb8856606 
50154418919fSjohnjiang 	if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) {
50164418919fSjohnjiang 		RTE_ETHDEV_LOG(INFO,
50174418919fSjohnjiang 			"Can't get hairpin Rx queue %"PRIu16" info of device with port_id=%"PRIu16"\n",
50184418919fSjohnjiang 			queue_id, port_id);
50194418919fSjohnjiang 		return -EINVAL;
50204418919fSjohnjiang 	}
50214418919fSjohnjiang 
5022d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rxq_info_get, -ENOTSUP);
5023d30ea906Sjfb8856606 
5024d30ea906Sjfb8856606 	memset(qinfo, 0, sizeof(*qinfo));
5025d30ea906Sjfb8856606 	dev->dev_ops->rxq_info_get(dev, queue_id, qinfo);
5026d30ea906Sjfb8856606 	return 0;
5027d30ea906Sjfb8856606 }
5028d30ea906Sjfb8856606 
5029d30ea906Sjfb8856606 int
rte_eth_tx_queue_info_get(uint16_t port_id,uint16_t queue_id,struct rte_eth_txq_info * qinfo)5030d30ea906Sjfb8856606 rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id,
5031d30ea906Sjfb8856606 	struct rte_eth_txq_info *qinfo)
5032d30ea906Sjfb8856606 {
5033d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5034d30ea906Sjfb8856606 
5035d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5036d30ea906Sjfb8856606 
5037d30ea906Sjfb8856606 	if (qinfo == NULL)
5038d30ea906Sjfb8856606 		return -EINVAL;
5039d30ea906Sjfb8856606 
5040d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5041d30ea906Sjfb8856606 	if (queue_id >= dev->data->nb_tx_queues) {
5042d30ea906Sjfb8856606 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
5043d30ea906Sjfb8856606 		return -EINVAL;
5044d30ea906Sjfb8856606 	}
5045d30ea906Sjfb8856606 
5046*2d9fd380Sjfb8856606 	if (dev->data->tx_queues == NULL ||
5047*2d9fd380Sjfb8856606 			dev->data->tx_queues[queue_id] == NULL) {
5048*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(ERR,
5049*2d9fd380Sjfb8856606 			       "Tx queue %"PRIu16" of device with port_id=%"
5050*2d9fd380Sjfb8856606 			       PRIu16" has not been setup\n",
5051*2d9fd380Sjfb8856606 			       queue_id, port_id);
5052*2d9fd380Sjfb8856606 		return -EINVAL;
5053*2d9fd380Sjfb8856606 	}
5054*2d9fd380Sjfb8856606 
50554418919fSjohnjiang 	if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) {
50564418919fSjohnjiang 		RTE_ETHDEV_LOG(INFO,
50574418919fSjohnjiang 			"Can't get hairpin Tx queue %"PRIu16" info of device with port_id=%"PRIu16"\n",
50584418919fSjohnjiang 			queue_id, port_id);
50594418919fSjohnjiang 		return -EINVAL;
50604418919fSjohnjiang 	}
50614418919fSjohnjiang 
5062d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->txq_info_get, -ENOTSUP);
5063d30ea906Sjfb8856606 
5064d30ea906Sjfb8856606 	memset(qinfo, 0, sizeof(*qinfo));
5065d30ea906Sjfb8856606 	dev->dev_ops->txq_info_get(dev, queue_id, qinfo);
5066d30ea906Sjfb8856606 
5067d30ea906Sjfb8856606 	return 0;
5068d30ea906Sjfb8856606 }
5069d30ea906Sjfb8856606 
5070d30ea906Sjfb8856606 int
rte_eth_rx_burst_mode_get(uint16_t port_id,uint16_t queue_id,struct rte_eth_burst_mode * mode)50714418919fSjohnjiang rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
50724418919fSjohnjiang 			  struct rte_eth_burst_mode *mode)
50734418919fSjohnjiang {
50744418919fSjohnjiang 	struct rte_eth_dev *dev;
50754418919fSjohnjiang 
50764418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
50774418919fSjohnjiang 
50784418919fSjohnjiang 	if (mode == NULL)
50794418919fSjohnjiang 		return -EINVAL;
50804418919fSjohnjiang 
50814418919fSjohnjiang 	dev = &rte_eth_devices[port_id];
50824418919fSjohnjiang 
50834418919fSjohnjiang 	if (queue_id >= dev->data->nb_rx_queues) {
50844418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
50854418919fSjohnjiang 		return -EINVAL;
50864418919fSjohnjiang 	}
50874418919fSjohnjiang 
50884418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_burst_mode_get, -ENOTSUP);
50894418919fSjohnjiang 	memset(mode, 0, sizeof(*mode));
50904418919fSjohnjiang 	return eth_err(port_id,
50914418919fSjohnjiang 		       dev->dev_ops->rx_burst_mode_get(dev, queue_id, mode));
50924418919fSjohnjiang }
50934418919fSjohnjiang 
50944418919fSjohnjiang int
rte_eth_tx_burst_mode_get(uint16_t port_id,uint16_t queue_id,struct rte_eth_burst_mode * mode)50954418919fSjohnjiang rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
50964418919fSjohnjiang 			  struct rte_eth_burst_mode *mode)
50974418919fSjohnjiang {
50984418919fSjohnjiang 	struct rte_eth_dev *dev;
50994418919fSjohnjiang 
51004418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
51014418919fSjohnjiang 
51024418919fSjohnjiang 	if (mode == NULL)
51034418919fSjohnjiang 		return -EINVAL;
51044418919fSjohnjiang 
51054418919fSjohnjiang 	dev = &rte_eth_devices[port_id];
51064418919fSjohnjiang 
51074418919fSjohnjiang 	if (queue_id >= dev->data->nb_tx_queues) {
51084418919fSjohnjiang 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
51094418919fSjohnjiang 		return -EINVAL;
51104418919fSjohnjiang 	}
51114418919fSjohnjiang 
51124418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_burst_mode_get, -ENOTSUP);
51134418919fSjohnjiang 	memset(mode, 0, sizeof(*mode));
51144418919fSjohnjiang 	return eth_err(port_id,
51154418919fSjohnjiang 		       dev->dev_ops->tx_burst_mode_get(dev, queue_id, mode));
51164418919fSjohnjiang }
51174418919fSjohnjiang 
51184418919fSjohnjiang int
rte_eth_dev_set_mc_addr_list(uint16_t port_id,struct rte_ether_addr * mc_addr_set,uint32_t nb_mc_addr)5119d30ea906Sjfb8856606 rte_eth_dev_set_mc_addr_list(uint16_t port_id,
51204418919fSjohnjiang 			     struct rte_ether_addr *mc_addr_set,
5121d30ea906Sjfb8856606 			     uint32_t nb_mc_addr)
5122d30ea906Sjfb8856606 {
5123d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5124d30ea906Sjfb8856606 
5125d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5126d30ea906Sjfb8856606 
5127d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5128d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_mc_addr_list, -ENOTSUP);
5129d30ea906Sjfb8856606 	return eth_err(port_id, dev->dev_ops->set_mc_addr_list(dev,
5130d30ea906Sjfb8856606 						mc_addr_set, nb_mc_addr));
5131d30ea906Sjfb8856606 }
5132d30ea906Sjfb8856606 
5133d30ea906Sjfb8856606 int
rte_eth_timesync_enable(uint16_t port_id)5134d30ea906Sjfb8856606 rte_eth_timesync_enable(uint16_t port_id)
5135d30ea906Sjfb8856606 {
5136d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5137d30ea906Sjfb8856606 
5138d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5139d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5140d30ea906Sjfb8856606 
5141d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_enable, -ENOTSUP);
5142d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->timesync_enable)(dev));
5143d30ea906Sjfb8856606 }
5144d30ea906Sjfb8856606 
5145d30ea906Sjfb8856606 int
rte_eth_timesync_disable(uint16_t port_id)5146d30ea906Sjfb8856606 rte_eth_timesync_disable(uint16_t port_id)
5147d30ea906Sjfb8856606 {
5148d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5149d30ea906Sjfb8856606 
5150d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5151d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5152d30ea906Sjfb8856606 
5153d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_disable, -ENOTSUP);
5154d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->timesync_disable)(dev));
5155d30ea906Sjfb8856606 }
5156d30ea906Sjfb8856606 
5157d30ea906Sjfb8856606 int
rte_eth_timesync_read_rx_timestamp(uint16_t port_id,struct timespec * timestamp,uint32_t flags)5158d30ea906Sjfb8856606 rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
5159d30ea906Sjfb8856606 				   uint32_t flags)
5160d30ea906Sjfb8856606 {
5161d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5162d30ea906Sjfb8856606 
5163d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5164d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5165d30ea906Sjfb8856606 
5166d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
5167d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp)
5168d30ea906Sjfb8856606 				(dev, timestamp, flags));
5169d30ea906Sjfb8856606 }
5170d30ea906Sjfb8856606 
5171d30ea906Sjfb8856606 int
rte_eth_timesync_read_tx_timestamp(uint16_t port_id,struct timespec * timestamp)5172d30ea906Sjfb8856606 rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
5173d30ea906Sjfb8856606 				   struct timespec *timestamp)
5174d30ea906Sjfb8856606 {
5175d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5176d30ea906Sjfb8856606 
5177d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5178d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5179d30ea906Sjfb8856606 
5180d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
5181d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp)
5182d30ea906Sjfb8856606 				(dev, timestamp));
5183d30ea906Sjfb8856606 }
5184d30ea906Sjfb8856606 
5185d30ea906Sjfb8856606 int
rte_eth_timesync_adjust_time(uint16_t port_id,int64_t delta)5186d30ea906Sjfb8856606 rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta)
5187d30ea906Sjfb8856606 {
5188d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5189d30ea906Sjfb8856606 
5190d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5191d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5192d30ea906Sjfb8856606 
5193d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_adjust_time, -ENOTSUP);
5194d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->timesync_adjust_time)(dev,
5195d30ea906Sjfb8856606 								      delta));
5196d30ea906Sjfb8856606 }
5197d30ea906Sjfb8856606 
5198d30ea906Sjfb8856606 int
rte_eth_timesync_read_time(uint16_t port_id,struct timespec * timestamp)5199d30ea906Sjfb8856606 rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
5200d30ea906Sjfb8856606 {
5201d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5202d30ea906Sjfb8856606 
5203d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5204d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5205d30ea906Sjfb8856606 
5206d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
5207d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev,
5208d30ea906Sjfb8856606 								timestamp));
5209d30ea906Sjfb8856606 }
5210d30ea906Sjfb8856606 
5211d30ea906Sjfb8856606 int
rte_eth_timesync_write_time(uint16_t port_id,const struct timespec * timestamp)5212d30ea906Sjfb8856606 rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
5213d30ea906Sjfb8856606 {
5214d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5215d30ea906Sjfb8856606 
5216d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5217d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5218d30ea906Sjfb8856606 
5219d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
5220d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev,
5221d30ea906Sjfb8856606 								timestamp));
5222d30ea906Sjfb8856606 }
5223d30ea906Sjfb8856606 
5224d30ea906Sjfb8856606 int
rte_eth_read_clock(uint16_t port_id,uint64_t * clock)52254418919fSjohnjiang rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
52264418919fSjohnjiang {
52274418919fSjohnjiang 	struct rte_eth_dev *dev;
52284418919fSjohnjiang 
52294418919fSjohnjiang 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
52304418919fSjohnjiang 	dev = &rte_eth_devices[port_id];
52314418919fSjohnjiang 
52324418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
52334418919fSjohnjiang 	return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock));
52344418919fSjohnjiang }
52354418919fSjohnjiang 
52364418919fSjohnjiang int
rte_eth_dev_get_reg_info(uint16_t port_id,struct rte_dev_reg_info * info)5237d30ea906Sjfb8856606 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
5238d30ea906Sjfb8856606 {
5239d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5240d30ea906Sjfb8856606 
5241d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5242d30ea906Sjfb8856606 
5243d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5244d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_reg, -ENOTSUP);
5245d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info));
5246d30ea906Sjfb8856606 }
5247d30ea906Sjfb8856606 
5248d30ea906Sjfb8856606 int
rte_eth_dev_get_eeprom_length(uint16_t port_id)5249d30ea906Sjfb8856606 rte_eth_dev_get_eeprom_length(uint16_t port_id)
5250d30ea906Sjfb8856606 {
5251d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5252d30ea906Sjfb8856606 
5253d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5254d30ea906Sjfb8856606 
5255d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5256d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom_length, -ENOTSUP);
5257d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->get_eeprom_length)(dev));
5258d30ea906Sjfb8856606 }
5259d30ea906Sjfb8856606 
5260d30ea906Sjfb8856606 int
rte_eth_dev_get_eeprom(uint16_t port_id,struct rte_dev_eeprom_info * info)5261d30ea906Sjfb8856606 rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
5262d30ea906Sjfb8856606 {
5263d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5264d30ea906Sjfb8856606 
5265d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5266d30ea906Sjfb8856606 
5267d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5268d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom, -ENOTSUP);
5269d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->get_eeprom)(dev, info));
5270d30ea906Sjfb8856606 }
5271d30ea906Sjfb8856606 
5272d30ea906Sjfb8856606 int
rte_eth_dev_set_eeprom(uint16_t port_id,struct rte_dev_eeprom_info * info)5273d30ea906Sjfb8856606 rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
5274d30ea906Sjfb8856606 {
5275d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5276d30ea906Sjfb8856606 
5277d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5278d30ea906Sjfb8856606 
5279d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5280d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_eeprom, -ENOTSUP);
5281d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->set_eeprom)(dev, info));
5282d30ea906Sjfb8856606 }
5283d30ea906Sjfb8856606 
52844418919fSjohnjiang int
rte_eth_dev_get_module_info(uint16_t port_id,struct rte_eth_dev_module_info * modinfo)5285d30ea906Sjfb8856606 rte_eth_dev_get_module_info(uint16_t port_id,
5286d30ea906Sjfb8856606 			    struct rte_eth_dev_module_info *modinfo)
5287d30ea906Sjfb8856606 {
5288d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5289d30ea906Sjfb8856606 
5290d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5291d30ea906Sjfb8856606 
5292d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5293d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_info, -ENOTSUP);
5294d30ea906Sjfb8856606 	return (*dev->dev_ops->get_module_info)(dev, modinfo);
5295d30ea906Sjfb8856606 }
5296d30ea906Sjfb8856606 
52974418919fSjohnjiang int
rte_eth_dev_get_module_eeprom(uint16_t port_id,struct rte_dev_eeprom_info * info)5298d30ea906Sjfb8856606 rte_eth_dev_get_module_eeprom(uint16_t port_id,
5299d30ea906Sjfb8856606 			      struct rte_dev_eeprom_info *info)
5300d30ea906Sjfb8856606 {
5301d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5302d30ea906Sjfb8856606 
5303d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5304d30ea906Sjfb8856606 
5305d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5306d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_eeprom, -ENOTSUP);
5307d30ea906Sjfb8856606 	return (*dev->dev_ops->get_module_eeprom)(dev, info);
5308d30ea906Sjfb8856606 }
5309d30ea906Sjfb8856606 
5310d30ea906Sjfb8856606 int
rte_eth_dev_get_dcb_info(uint16_t port_id,struct rte_eth_dcb_info * dcb_info)5311d30ea906Sjfb8856606 rte_eth_dev_get_dcb_info(uint16_t port_id,
5312d30ea906Sjfb8856606 			     struct rte_eth_dcb_info *dcb_info)
5313d30ea906Sjfb8856606 {
5314d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5315d30ea906Sjfb8856606 
5316d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5317d30ea906Sjfb8856606 
5318d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5319d30ea906Sjfb8856606 	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
5320d30ea906Sjfb8856606 
5321d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_dcb_info, -ENOTSUP);
5322d30ea906Sjfb8856606 	return eth_err(port_id, (*dev->dev_ops->get_dcb_info)(dev, dcb_info));
5323d30ea906Sjfb8856606 }
5324d30ea906Sjfb8856606 
5325d30ea906Sjfb8856606 static void
eth_dev_adjust_nb_desc(uint16_t * nb_desc,const struct rte_eth_desc_lim * desc_lim)5326*2d9fd380Sjfb8856606 eth_dev_adjust_nb_desc(uint16_t *nb_desc,
5327d30ea906Sjfb8856606 		const struct rte_eth_desc_lim *desc_lim)
5328d30ea906Sjfb8856606 {
5329d30ea906Sjfb8856606 	if (desc_lim->nb_align != 0)
5330d30ea906Sjfb8856606 		*nb_desc = RTE_ALIGN_CEIL(*nb_desc, desc_lim->nb_align);
5331d30ea906Sjfb8856606 
5332d30ea906Sjfb8856606 	if (desc_lim->nb_max != 0)
5333d30ea906Sjfb8856606 		*nb_desc = RTE_MIN(*nb_desc, desc_lim->nb_max);
5334d30ea906Sjfb8856606 
5335d30ea906Sjfb8856606 	*nb_desc = RTE_MAX(*nb_desc, desc_lim->nb_min);
5336d30ea906Sjfb8856606 }
5337d30ea906Sjfb8856606 
5338d30ea906Sjfb8856606 int
rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id,uint16_t * nb_rx_desc,uint16_t * nb_tx_desc)5339d30ea906Sjfb8856606 rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id,
5340d30ea906Sjfb8856606 				 uint16_t *nb_rx_desc,
5341d30ea906Sjfb8856606 				 uint16_t *nb_tx_desc)
5342d30ea906Sjfb8856606 {
5343d30ea906Sjfb8856606 	struct rte_eth_dev_info dev_info;
53444418919fSjohnjiang 	int ret;
5345d30ea906Sjfb8856606 
5346d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5347d30ea906Sjfb8856606 
53484418919fSjohnjiang 	ret = rte_eth_dev_info_get(port_id, &dev_info);
53494418919fSjohnjiang 	if (ret != 0)
53504418919fSjohnjiang 		return ret;
5351d30ea906Sjfb8856606 
5352d30ea906Sjfb8856606 	if (nb_rx_desc != NULL)
5353*2d9fd380Sjfb8856606 		eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim);
5354d30ea906Sjfb8856606 
5355d30ea906Sjfb8856606 	if (nb_tx_desc != NULL)
5356*2d9fd380Sjfb8856606 		eth_dev_adjust_nb_desc(nb_tx_desc, &dev_info.tx_desc_lim);
5357d30ea906Sjfb8856606 
5358d30ea906Sjfb8856606 	return 0;
5359d30ea906Sjfb8856606 }
5360d30ea906Sjfb8856606 
5361d30ea906Sjfb8856606 int
rte_eth_dev_hairpin_capability_get(uint16_t port_id,struct rte_eth_hairpin_cap * cap)53624418919fSjohnjiang rte_eth_dev_hairpin_capability_get(uint16_t port_id,
53634418919fSjohnjiang 				   struct rte_eth_hairpin_cap *cap)
53644418919fSjohnjiang {
53654418919fSjohnjiang 	struct rte_eth_dev *dev;
53664418919fSjohnjiang 
5367*2d9fd380Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
53684418919fSjohnjiang 
53694418919fSjohnjiang 	dev = &rte_eth_devices[port_id];
53704418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
53714418919fSjohnjiang 	memset(cap, 0, sizeof(*cap));
53724418919fSjohnjiang 	return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap));
53734418919fSjohnjiang }
53744418919fSjohnjiang 
53754418919fSjohnjiang int
rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev * dev,uint16_t queue_id)53764418919fSjohnjiang rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
53774418919fSjohnjiang {
53784418919fSjohnjiang 	if (dev->data->rx_queue_state[queue_id] ==
53794418919fSjohnjiang 	    RTE_ETH_QUEUE_STATE_HAIRPIN)
53804418919fSjohnjiang 		return 1;
53814418919fSjohnjiang 	return 0;
53824418919fSjohnjiang }
53834418919fSjohnjiang 
53844418919fSjohnjiang int
rte_eth_dev_is_tx_hairpin_queue(struct rte_eth_dev * dev,uint16_t queue_id)53854418919fSjohnjiang rte_eth_dev_is_tx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
53864418919fSjohnjiang {
53874418919fSjohnjiang 	if (dev->data->tx_queue_state[queue_id] ==
53884418919fSjohnjiang 	    RTE_ETH_QUEUE_STATE_HAIRPIN)
53894418919fSjohnjiang 		return 1;
53904418919fSjohnjiang 	return 0;
53914418919fSjohnjiang }
53924418919fSjohnjiang 
53934418919fSjohnjiang int
rte_eth_dev_pool_ops_supported(uint16_t port_id,const char * pool)5394d30ea906Sjfb8856606 rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
5395d30ea906Sjfb8856606 {
5396d30ea906Sjfb8856606 	struct rte_eth_dev *dev;
5397d30ea906Sjfb8856606 
5398d30ea906Sjfb8856606 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5399d30ea906Sjfb8856606 
5400d30ea906Sjfb8856606 	if (pool == NULL)
5401d30ea906Sjfb8856606 		return -EINVAL;
5402d30ea906Sjfb8856606 
5403d30ea906Sjfb8856606 	dev = &rte_eth_devices[port_id];
5404d30ea906Sjfb8856606 
5405d30ea906Sjfb8856606 	if (*dev->dev_ops->pool_ops_supported == NULL)
5406d30ea906Sjfb8856606 		return 1; /* all pools are supported */
5407d30ea906Sjfb8856606 
5408d30ea906Sjfb8856606 	return (*dev->dev_ops->pool_ops_supported)(dev, pool);
5409d30ea906Sjfb8856606 }
5410d30ea906Sjfb8856606 
5411d30ea906Sjfb8856606 /**
5412d30ea906Sjfb8856606  * A set of values to describe the possible states of a switch domain.
5413d30ea906Sjfb8856606  */
5414d30ea906Sjfb8856606 enum rte_eth_switch_domain_state {
5415d30ea906Sjfb8856606 	RTE_ETH_SWITCH_DOMAIN_UNUSED = 0,
5416d30ea906Sjfb8856606 	RTE_ETH_SWITCH_DOMAIN_ALLOCATED
5417d30ea906Sjfb8856606 };
5418d30ea906Sjfb8856606 
5419d30ea906Sjfb8856606 /**
5420d30ea906Sjfb8856606  * Array of switch domains available for allocation. Array is sized to
5421d30ea906Sjfb8856606  * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than
5422d30ea906Sjfb8856606  * ethdev ports in a single process.
5423d30ea906Sjfb8856606  */
5424d30ea906Sjfb8856606 static struct rte_eth_dev_switch {
5425d30ea906Sjfb8856606 	enum rte_eth_switch_domain_state state;
5426*2d9fd380Sjfb8856606 } eth_dev_switch_domains[RTE_MAX_ETHPORTS];
5427d30ea906Sjfb8856606 
54284418919fSjohnjiang int
rte_eth_switch_domain_alloc(uint16_t * domain_id)5429d30ea906Sjfb8856606 rte_eth_switch_domain_alloc(uint16_t *domain_id)
5430d30ea906Sjfb8856606 {
54310c6bd470Sfengbojiang 	uint16_t i;
5432d30ea906Sjfb8856606 
5433d30ea906Sjfb8856606 	*domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
5434d30ea906Sjfb8856606 
54354418919fSjohnjiang 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
5436*2d9fd380Sjfb8856606 		if (eth_dev_switch_domains[i].state ==
5437d30ea906Sjfb8856606 			RTE_ETH_SWITCH_DOMAIN_UNUSED) {
5438*2d9fd380Sjfb8856606 			eth_dev_switch_domains[i].state =
5439d30ea906Sjfb8856606 				RTE_ETH_SWITCH_DOMAIN_ALLOCATED;
5440d30ea906Sjfb8856606 			*domain_id = i;
5441d30ea906Sjfb8856606 			return 0;
5442d30ea906Sjfb8856606 		}
5443d30ea906Sjfb8856606 	}
5444d30ea906Sjfb8856606 
5445d30ea906Sjfb8856606 	return -ENOSPC;
5446d30ea906Sjfb8856606 }
5447d30ea906Sjfb8856606 
54484418919fSjohnjiang int
rte_eth_switch_domain_free(uint16_t domain_id)5449d30ea906Sjfb8856606 rte_eth_switch_domain_free(uint16_t domain_id)
5450d30ea906Sjfb8856606 {
5451d30ea906Sjfb8856606 	if (domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID ||
5452d30ea906Sjfb8856606 		domain_id >= RTE_MAX_ETHPORTS)
5453d30ea906Sjfb8856606 		return -EINVAL;
5454d30ea906Sjfb8856606 
5455*2d9fd380Sjfb8856606 	if (eth_dev_switch_domains[domain_id].state !=
5456d30ea906Sjfb8856606 		RTE_ETH_SWITCH_DOMAIN_ALLOCATED)
5457d30ea906Sjfb8856606 		return -EINVAL;
5458d30ea906Sjfb8856606 
5459*2d9fd380Sjfb8856606 	eth_dev_switch_domains[domain_id].state = RTE_ETH_SWITCH_DOMAIN_UNUSED;
5460d30ea906Sjfb8856606 
5461d30ea906Sjfb8856606 	return 0;
5462d30ea906Sjfb8856606 }
5463d30ea906Sjfb8856606 
5464d30ea906Sjfb8856606 static int
eth_dev_devargs_tokenise(struct rte_kvargs * arglist,const char * str_in)5465*2d9fd380Sjfb8856606 eth_dev_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in)
5466d30ea906Sjfb8856606 {
5467d30ea906Sjfb8856606 	int state;
5468d30ea906Sjfb8856606 	struct rte_kvargs_pair *pair;
5469d30ea906Sjfb8856606 	char *letter;
5470d30ea906Sjfb8856606 
5471d30ea906Sjfb8856606 	arglist->str = strdup(str_in);
5472d30ea906Sjfb8856606 	if (arglist->str == NULL)
5473d30ea906Sjfb8856606 		return -ENOMEM;
5474d30ea906Sjfb8856606 
5475d30ea906Sjfb8856606 	letter = arglist->str;
5476d30ea906Sjfb8856606 	state = 0;
5477d30ea906Sjfb8856606 	arglist->count = 0;
5478d30ea906Sjfb8856606 	pair = &arglist->pairs[0];
5479d30ea906Sjfb8856606 	while (1) {
5480d30ea906Sjfb8856606 		switch (state) {
5481d30ea906Sjfb8856606 		case 0: /* Initial */
5482d30ea906Sjfb8856606 			if (*letter == '=')
5483d30ea906Sjfb8856606 				return -EINVAL;
5484d30ea906Sjfb8856606 			else if (*letter == '\0')
5485d30ea906Sjfb8856606 				return 0;
5486d30ea906Sjfb8856606 
5487d30ea906Sjfb8856606 			state = 1;
5488d30ea906Sjfb8856606 			pair->key = letter;
5489d30ea906Sjfb8856606 			/* fall-thru */
5490d30ea906Sjfb8856606 
5491d30ea906Sjfb8856606 		case 1: /* Parsing key */
5492d30ea906Sjfb8856606 			if (*letter == '=') {
5493d30ea906Sjfb8856606 				*letter = '\0';
5494d30ea906Sjfb8856606 				pair->value = letter + 1;
5495d30ea906Sjfb8856606 				state = 2;
5496d30ea906Sjfb8856606 			} else if (*letter == ',' || *letter == '\0')
5497d30ea906Sjfb8856606 				return -EINVAL;
5498d30ea906Sjfb8856606 			break;
5499d30ea906Sjfb8856606 
5500d30ea906Sjfb8856606 
5501d30ea906Sjfb8856606 		case 2: /* Parsing value */
5502d30ea906Sjfb8856606 			if (*letter == '[')
5503d30ea906Sjfb8856606 				state = 3;
5504d30ea906Sjfb8856606 			else if (*letter == ',') {
5505d30ea906Sjfb8856606 				*letter = '\0';
5506d30ea906Sjfb8856606 				arglist->count++;
5507d30ea906Sjfb8856606 				pair = &arglist->pairs[arglist->count];
5508d30ea906Sjfb8856606 				state = 0;
5509d30ea906Sjfb8856606 			} else if (*letter == '\0') {
5510d30ea906Sjfb8856606 				letter--;
5511d30ea906Sjfb8856606 				arglist->count++;
5512d30ea906Sjfb8856606 				pair = &arglist->pairs[arglist->count];
5513d30ea906Sjfb8856606 				state = 0;
5514d30ea906Sjfb8856606 			}
5515d30ea906Sjfb8856606 			break;
5516d30ea906Sjfb8856606 
5517d30ea906Sjfb8856606 		case 3: /* Parsing list */
5518d30ea906Sjfb8856606 			if (*letter == ']')
5519d30ea906Sjfb8856606 				state = 2;
5520d30ea906Sjfb8856606 			else if (*letter == '\0')
5521d30ea906Sjfb8856606 				return -EINVAL;
5522d30ea906Sjfb8856606 			break;
5523d30ea906Sjfb8856606 		}
5524d30ea906Sjfb8856606 		letter++;
5525d30ea906Sjfb8856606 	}
5526d30ea906Sjfb8856606 }
5527d30ea906Sjfb8856606 
55284418919fSjohnjiang int
rte_eth_devargs_parse(const char * dargs,struct rte_eth_devargs * eth_da)5529d30ea906Sjfb8856606 rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da)
5530d30ea906Sjfb8856606 {
5531d30ea906Sjfb8856606 	struct rte_kvargs args;
5532d30ea906Sjfb8856606 	struct rte_kvargs_pair *pair;
5533d30ea906Sjfb8856606 	unsigned int i;
5534d30ea906Sjfb8856606 	int result = 0;
5535d30ea906Sjfb8856606 
5536d30ea906Sjfb8856606 	memset(eth_da, 0, sizeof(*eth_da));
5537d30ea906Sjfb8856606 
5538*2d9fd380Sjfb8856606 	result = eth_dev_devargs_tokenise(&args, dargs);
5539d30ea906Sjfb8856606 	if (result < 0)
5540d30ea906Sjfb8856606 		goto parse_cleanup;
5541d30ea906Sjfb8856606 
5542d30ea906Sjfb8856606 	for (i = 0; i < args.count; i++) {
5543d30ea906Sjfb8856606 		pair = &args.pairs[i];
5544d30ea906Sjfb8856606 		if (strcmp("representor", pair->key) == 0) {
5545d30ea906Sjfb8856606 			result = rte_eth_devargs_parse_list(pair->value,
5546d30ea906Sjfb8856606 				rte_eth_devargs_parse_representor_ports,
5547d30ea906Sjfb8856606 				eth_da);
5548d30ea906Sjfb8856606 			if (result < 0)
5549d30ea906Sjfb8856606 				goto parse_cleanup;
5550d30ea906Sjfb8856606 		}
5551d30ea906Sjfb8856606 	}
5552d30ea906Sjfb8856606 
5553d30ea906Sjfb8856606 parse_cleanup:
5554d30ea906Sjfb8856606 	if (args.str)
5555d30ea906Sjfb8856606 		free(args.str);
5556d30ea906Sjfb8856606 
5557d30ea906Sjfb8856606 	return result;
5558d30ea906Sjfb8856606 }
5559d30ea906Sjfb8856606 
5560*2d9fd380Sjfb8856606 static int
eth_dev_handle_port_list(const char * cmd __rte_unused,const char * params __rte_unused,struct rte_tel_data * d)5561*2d9fd380Sjfb8856606 eth_dev_handle_port_list(const char *cmd __rte_unused,
5562*2d9fd380Sjfb8856606 		const char *params __rte_unused,
5563*2d9fd380Sjfb8856606 		struct rte_tel_data *d)
5564d30ea906Sjfb8856606 {
5565*2d9fd380Sjfb8856606 	int port_id;
5566*2d9fd380Sjfb8856606 
5567*2d9fd380Sjfb8856606 	rte_tel_data_start_array(d, RTE_TEL_INT_VAL);
5568*2d9fd380Sjfb8856606 	RTE_ETH_FOREACH_DEV(port_id)
5569*2d9fd380Sjfb8856606 		rte_tel_data_add_array_int(d, port_id);
5570*2d9fd380Sjfb8856606 	return 0;
5571*2d9fd380Sjfb8856606 }
5572*2d9fd380Sjfb8856606 
5573*2d9fd380Sjfb8856606 static void
eth_dev_add_port_queue_stats(struct rte_tel_data * d,uint64_t * q_stats,const char * stat_name)5574*2d9fd380Sjfb8856606 eth_dev_add_port_queue_stats(struct rte_tel_data *d, uint64_t *q_stats,
5575*2d9fd380Sjfb8856606 		const char *stat_name)
5576*2d9fd380Sjfb8856606 {
5577*2d9fd380Sjfb8856606 	int q;
5578*2d9fd380Sjfb8856606 	struct rte_tel_data *q_data = rte_tel_data_alloc();
5579*2d9fd380Sjfb8856606 	rte_tel_data_start_array(q_data, RTE_TEL_U64_VAL);
5580*2d9fd380Sjfb8856606 	for (q = 0; q < RTE_ETHDEV_QUEUE_STAT_CNTRS; q++)
5581*2d9fd380Sjfb8856606 		rte_tel_data_add_array_u64(q_data, q_stats[q]);
5582*2d9fd380Sjfb8856606 	rte_tel_data_add_dict_container(d, stat_name, q_data, 0);
5583*2d9fd380Sjfb8856606 }
5584*2d9fd380Sjfb8856606 
5585*2d9fd380Sjfb8856606 #define ADD_DICT_STAT(stats, s) rte_tel_data_add_dict_u64(d, #s, stats.s)
5586*2d9fd380Sjfb8856606 
5587*2d9fd380Sjfb8856606 static int
eth_dev_handle_port_stats(const char * cmd __rte_unused,const char * params,struct rte_tel_data * d)5588*2d9fd380Sjfb8856606 eth_dev_handle_port_stats(const char *cmd __rte_unused,
5589*2d9fd380Sjfb8856606 		const char *params,
5590*2d9fd380Sjfb8856606 		struct rte_tel_data *d)
5591*2d9fd380Sjfb8856606 {
5592*2d9fd380Sjfb8856606 	struct rte_eth_stats stats;
5593*2d9fd380Sjfb8856606 	int port_id, ret;
5594*2d9fd380Sjfb8856606 
5595*2d9fd380Sjfb8856606 	if (params == NULL || strlen(params) == 0 || !isdigit(*params))
5596*2d9fd380Sjfb8856606 		return -1;
5597*2d9fd380Sjfb8856606 
5598*2d9fd380Sjfb8856606 	port_id = atoi(params);
5599*2d9fd380Sjfb8856606 	if (!rte_eth_dev_is_valid_port(port_id))
5600*2d9fd380Sjfb8856606 		return -1;
5601*2d9fd380Sjfb8856606 
5602*2d9fd380Sjfb8856606 	ret = rte_eth_stats_get(port_id, &stats);
5603*2d9fd380Sjfb8856606 	if (ret < 0)
5604*2d9fd380Sjfb8856606 		return -1;
5605*2d9fd380Sjfb8856606 
5606*2d9fd380Sjfb8856606 	rte_tel_data_start_dict(d);
5607*2d9fd380Sjfb8856606 	ADD_DICT_STAT(stats, ipackets);
5608*2d9fd380Sjfb8856606 	ADD_DICT_STAT(stats, opackets);
5609*2d9fd380Sjfb8856606 	ADD_DICT_STAT(stats, ibytes);
5610*2d9fd380Sjfb8856606 	ADD_DICT_STAT(stats, obytes);
5611*2d9fd380Sjfb8856606 	ADD_DICT_STAT(stats, imissed);
5612*2d9fd380Sjfb8856606 	ADD_DICT_STAT(stats, ierrors);
5613*2d9fd380Sjfb8856606 	ADD_DICT_STAT(stats, oerrors);
5614*2d9fd380Sjfb8856606 	ADD_DICT_STAT(stats, rx_nombuf);
5615*2d9fd380Sjfb8856606 	eth_dev_add_port_queue_stats(d, stats.q_ipackets, "q_ipackets");
5616*2d9fd380Sjfb8856606 	eth_dev_add_port_queue_stats(d, stats.q_opackets, "q_opackets");
5617*2d9fd380Sjfb8856606 	eth_dev_add_port_queue_stats(d, stats.q_ibytes, "q_ibytes");
5618*2d9fd380Sjfb8856606 	eth_dev_add_port_queue_stats(d, stats.q_obytes, "q_obytes");
5619*2d9fd380Sjfb8856606 	eth_dev_add_port_queue_stats(d, stats.q_errors, "q_errors");
5620*2d9fd380Sjfb8856606 
5621*2d9fd380Sjfb8856606 	return 0;
5622*2d9fd380Sjfb8856606 }
5623*2d9fd380Sjfb8856606 
5624*2d9fd380Sjfb8856606 static int
eth_dev_handle_port_xstats(const char * cmd __rte_unused,const char * params,struct rte_tel_data * d)5625*2d9fd380Sjfb8856606 eth_dev_handle_port_xstats(const char *cmd __rte_unused,
5626*2d9fd380Sjfb8856606 		const char *params,
5627*2d9fd380Sjfb8856606 		struct rte_tel_data *d)
5628*2d9fd380Sjfb8856606 {
5629*2d9fd380Sjfb8856606 	struct rte_eth_xstat *eth_xstats;
5630*2d9fd380Sjfb8856606 	struct rte_eth_xstat_name *xstat_names;
5631*2d9fd380Sjfb8856606 	int port_id, num_xstats;
5632*2d9fd380Sjfb8856606 	int i, ret;
5633*2d9fd380Sjfb8856606 	char *end_param;
5634*2d9fd380Sjfb8856606 
5635*2d9fd380Sjfb8856606 	if (params == NULL || strlen(params) == 0 || !isdigit(*params))
5636*2d9fd380Sjfb8856606 		return -1;
5637*2d9fd380Sjfb8856606 
5638*2d9fd380Sjfb8856606 	port_id = strtoul(params, &end_param, 0);
5639*2d9fd380Sjfb8856606 	if (*end_param != '\0')
5640*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(NOTICE,
5641*2d9fd380Sjfb8856606 			"Extra parameters passed to ethdev telemetry command, ignoring");
5642*2d9fd380Sjfb8856606 	if (!rte_eth_dev_is_valid_port(port_id))
5643*2d9fd380Sjfb8856606 		return -1;
5644*2d9fd380Sjfb8856606 
5645*2d9fd380Sjfb8856606 	num_xstats = rte_eth_xstats_get(port_id, NULL, 0);
5646*2d9fd380Sjfb8856606 	if (num_xstats < 0)
5647*2d9fd380Sjfb8856606 		return -1;
5648*2d9fd380Sjfb8856606 
5649*2d9fd380Sjfb8856606 	/* use one malloc for both names and stats */
5650*2d9fd380Sjfb8856606 	eth_xstats = malloc((sizeof(struct rte_eth_xstat) +
5651*2d9fd380Sjfb8856606 			sizeof(struct rte_eth_xstat_name)) * num_xstats);
5652*2d9fd380Sjfb8856606 	if (eth_xstats == NULL)
5653*2d9fd380Sjfb8856606 		return -1;
5654*2d9fd380Sjfb8856606 	xstat_names = (void *)&eth_xstats[num_xstats];
5655*2d9fd380Sjfb8856606 
5656*2d9fd380Sjfb8856606 	ret = rte_eth_xstats_get_names(port_id, xstat_names, num_xstats);
5657*2d9fd380Sjfb8856606 	if (ret < 0 || ret > num_xstats) {
5658*2d9fd380Sjfb8856606 		free(eth_xstats);
5659*2d9fd380Sjfb8856606 		return -1;
5660*2d9fd380Sjfb8856606 	}
5661*2d9fd380Sjfb8856606 
5662*2d9fd380Sjfb8856606 	ret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats);
5663*2d9fd380Sjfb8856606 	if (ret < 0 || ret > num_xstats) {
5664*2d9fd380Sjfb8856606 		free(eth_xstats);
5665*2d9fd380Sjfb8856606 		return -1;
5666*2d9fd380Sjfb8856606 	}
5667*2d9fd380Sjfb8856606 
5668*2d9fd380Sjfb8856606 	rte_tel_data_start_dict(d);
5669*2d9fd380Sjfb8856606 	for (i = 0; i < num_xstats; i++)
5670*2d9fd380Sjfb8856606 		rte_tel_data_add_dict_u64(d, xstat_names[i].name,
5671*2d9fd380Sjfb8856606 				eth_xstats[i].value);
5672*2d9fd380Sjfb8856606 	return 0;
5673*2d9fd380Sjfb8856606 }
5674*2d9fd380Sjfb8856606 
5675*2d9fd380Sjfb8856606 static int
eth_dev_handle_port_link_status(const char * cmd __rte_unused,const char * params,struct rte_tel_data * d)5676*2d9fd380Sjfb8856606 eth_dev_handle_port_link_status(const char *cmd __rte_unused,
5677*2d9fd380Sjfb8856606 		const char *params,
5678*2d9fd380Sjfb8856606 		struct rte_tel_data *d)
5679*2d9fd380Sjfb8856606 {
5680*2d9fd380Sjfb8856606 	static const char *status_str = "status";
5681*2d9fd380Sjfb8856606 	int ret, port_id;
5682*2d9fd380Sjfb8856606 	struct rte_eth_link link;
5683*2d9fd380Sjfb8856606 	char *end_param;
5684*2d9fd380Sjfb8856606 
5685*2d9fd380Sjfb8856606 	if (params == NULL || strlen(params) == 0 || !isdigit(*params))
5686*2d9fd380Sjfb8856606 		return -1;
5687*2d9fd380Sjfb8856606 
5688*2d9fd380Sjfb8856606 	port_id = strtoul(params, &end_param, 0);
5689*2d9fd380Sjfb8856606 	if (*end_param != '\0')
5690*2d9fd380Sjfb8856606 		RTE_ETHDEV_LOG(NOTICE,
5691*2d9fd380Sjfb8856606 			"Extra parameters passed to ethdev telemetry command, ignoring");
5692*2d9fd380Sjfb8856606 	if (!rte_eth_dev_is_valid_port(port_id))
5693*2d9fd380Sjfb8856606 		return -1;
5694*2d9fd380Sjfb8856606 
5695*2d9fd380Sjfb8856606 	ret = rte_eth_link_get(port_id, &link);
5696*2d9fd380Sjfb8856606 	if (ret < 0)
5697*2d9fd380Sjfb8856606 		return -1;
5698*2d9fd380Sjfb8856606 
5699*2d9fd380Sjfb8856606 	rte_tel_data_start_dict(d);
5700*2d9fd380Sjfb8856606 	if (!link.link_status) {
5701*2d9fd380Sjfb8856606 		rte_tel_data_add_dict_string(d, status_str, "DOWN");
5702*2d9fd380Sjfb8856606 		return 0;
5703*2d9fd380Sjfb8856606 	}
5704*2d9fd380Sjfb8856606 	rte_tel_data_add_dict_string(d, status_str, "UP");
5705*2d9fd380Sjfb8856606 	rte_tel_data_add_dict_u64(d, "speed", link.link_speed);
5706*2d9fd380Sjfb8856606 	rte_tel_data_add_dict_string(d, "duplex",
5707*2d9fd380Sjfb8856606 			(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
5708*2d9fd380Sjfb8856606 				"full-duplex" : "half-duplex");
5709*2d9fd380Sjfb8856606 	return 0;
5710*2d9fd380Sjfb8856606 }
5711*2d9fd380Sjfb8856606 
5712*2d9fd380Sjfb8856606 int
rte_eth_hairpin_queue_peer_update(uint16_t peer_port,uint16_t peer_queue,struct rte_hairpin_peer_info * cur_info,struct rte_hairpin_peer_info * peer_info,uint32_t direction)5713*2d9fd380Sjfb8856606 rte_eth_hairpin_queue_peer_update(uint16_t peer_port, uint16_t peer_queue,
5714*2d9fd380Sjfb8856606 				  struct rte_hairpin_peer_info *cur_info,
5715*2d9fd380Sjfb8856606 				  struct rte_hairpin_peer_info *peer_info,
5716*2d9fd380Sjfb8856606 				  uint32_t direction)
5717*2d9fd380Sjfb8856606 {
5718*2d9fd380Sjfb8856606 	struct rte_eth_dev *dev;
5719*2d9fd380Sjfb8856606 
5720*2d9fd380Sjfb8856606 	/* Current queue information is not mandatory. */
5721*2d9fd380Sjfb8856606 	if (peer_info == NULL)
5722*2d9fd380Sjfb8856606 		return -EINVAL;
5723*2d9fd380Sjfb8856606 
5724*2d9fd380Sjfb8856606 	/* No need to check the validity again. */
5725*2d9fd380Sjfb8856606 	dev = &rte_eth_devices[peer_port];
5726*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_update,
5727*2d9fd380Sjfb8856606 				-ENOTSUP);
5728*2d9fd380Sjfb8856606 
5729*2d9fd380Sjfb8856606 	return (*dev->dev_ops->hairpin_queue_peer_update)(dev, peer_queue,
5730*2d9fd380Sjfb8856606 					cur_info, peer_info, direction);
5731*2d9fd380Sjfb8856606 }
5732*2d9fd380Sjfb8856606 
5733*2d9fd380Sjfb8856606 int
rte_eth_hairpin_queue_peer_bind(uint16_t cur_port,uint16_t cur_queue,struct rte_hairpin_peer_info * peer_info,uint32_t direction)5734*2d9fd380Sjfb8856606 rte_eth_hairpin_queue_peer_bind(uint16_t cur_port, uint16_t cur_queue,
5735*2d9fd380Sjfb8856606 				struct rte_hairpin_peer_info *peer_info,
5736*2d9fd380Sjfb8856606 				uint32_t direction)
5737*2d9fd380Sjfb8856606 {
5738*2d9fd380Sjfb8856606 	struct rte_eth_dev *dev;
5739*2d9fd380Sjfb8856606 
5740*2d9fd380Sjfb8856606 	if (peer_info == NULL)
5741*2d9fd380Sjfb8856606 		return -EINVAL;
5742*2d9fd380Sjfb8856606 
5743*2d9fd380Sjfb8856606 	/* No need to check the validity again. */
5744*2d9fd380Sjfb8856606 	dev = &rte_eth_devices[cur_port];
5745*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_bind,
5746*2d9fd380Sjfb8856606 				-ENOTSUP);
5747*2d9fd380Sjfb8856606 
5748*2d9fd380Sjfb8856606 	return (*dev->dev_ops->hairpin_queue_peer_bind)(dev, cur_queue,
5749*2d9fd380Sjfb8856606 							peer_info, direction);
5750*2d9fd380Sjfb8856606 }
5751*2d9fd380Sjfb8856606 
5752*2d9fd380Sjfb8856606 int
rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port,uint16_t cur_queue,uint32_t direction)5753*2d9fd380Sjfb8856606 rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue,
5754*2d9fd380Sjfb8856606 				  uint32_t direction)
5755*2d9fd380Sjfb8856606 {
5756*2d9fd380Sjfb8856606 	struct rte_eth_dev *dev;
5757*2d9fd380Sjfb8856606 
5758*2d9fd380Sjfb8856606 	/* No need to check the validity again. */
5759*2d9fd380Sjfb8856606 	dev = &rte_eth_devices[cur_port];
5760*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_unbind,
5761*2d9fd380Sjfb8856606 				-ENOTSUP);
5762*2d9fd380Sjfb8856606 
5763*2d9fd380Sjfb8856606 	return (*dev->dev_ops->hairpin_queue_peer_unbind)(dev, cur_queue,
5764*2d9fd380Sjfb8856606 							  direction);
5765*2d9fd380Sjfb8856606 }
5766*2d9fd380Sjfb8856606 
5767*2d9fd380Sjfb8856606 RTE_LOG_REGISTER(rte_eth_dev_logtype, lib.ethdev, INFO);
5768*2d9fd380Sjfb8856606 
RTE_INIT(ethdev_init_telemetry)5769*2d9fd380Sjfb8856606 RTE_INIT(ethdev_init_telemetry)
5770*2d9fd380Sjfb8856606 {
5771*2d9fd380Sjfb8856606 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
5772*2d9fd380Sjfb8856606 			"Returns list of available ethdev ports. Takes no parameters");
5773*2d9fd380Sjfb8856606 	rte_telemetry_register_cmd("/ethdev/stats", eth_dev_handle_port_stats,
5774*2d9fd380Sjfb8856606 			"Returns the common stats for a port. Parameters: int port_id");
5775*2d9fd380Sjfb8856606 	rte_telemetry_register_cmd("/ethdev/xstats", eth_dev_handle_port_xstats,
5776*2d9fd380Sjfb8856606 			"Returns the extended stats for a port. Parameters: int port_id");
5777*2d9fd380Sjfb8856606 	rte_telemetry_register_cmd("/ethdev/link_status",
5778*2d9fd380Sjfb8856606 			eth_dev_handle_port_link_status,
5779*2d9fd380Sjfb8856606 			"Returns the link status for a port. Parameters: int port_id");
5780d30ea906Sjfb8856606 }
5781