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