Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2017 Intel Corporation
3 : : */
4 : :
5 : : #include <errno.h>
6 : : #include <inttypes.h>
7 : : #include <stdbool.h>
8 : : #include <stdint.h>
9 : : #include <stdio.h>
10 : : #include <stdlib.h>
11 : : #include <string.h>
12 : : #include <sys/queue.h>
13 : :
14 : : #include <bus_driver.h>
15 : : #include <rte_log.h>
16 : : #include <rte_interrupts.h>
17 : : #include <rte_kvargs.h>
18 : : #include <rte_memcpy.h>
19 : : #include <rte_common.h>
20 : : #include <rte_mempool.h>
21 : : #include <rte_malloc.h>
22 : : #include <rte_mbuf.h>
23 : : #include <rte_errno.h>
24 : : #include <rte_spinlock.h>
25 : : #include <rte_string_fns.h>
26 : : #include <rte_class.h>
27 : : #include <rte_ether.h>
28 : : #include <rte_telemetry.h>
29 : :
30 : : #include "rte_ethdev.h"
31 : : #include "rte_ethdev_trace_fp.h"
32 : : #include "ethdev_driver.h"
33 : : #include "rte_flow_driver.h"
34 : : #include "ethdev_profile.h"
35 : : #include "ethdev_private.h"
36 : : #include "ethdev_trace.h"
37 : : #include "sff_telemetry.h"
38 : :
39 : : #define ETH_XSTATS_ITER_NUM 0x100
40 : :
41 : : struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
42 : :
43 : : /* public fast-path API */
44 : : struct rte_eth_fp_ops rte_eth_fp_ops[RTE_MAX_ETHPORTS];
45 : :
46 : : /* spinlock for add/remove Rx callbacks */
47 : : static rte_spinlock_t eth_dev_rx_cb_lock = RTE_SPINLOCK_INITIALIZER;
48 : :
49 : : /* spinlock for add/remove Tx callbacks */
50 : : static rte_spinlock_t eth_dev_tx_cb_lock = RTE_SPINLOCK_INITIALIZER;
51 : :
52 : : /* store statistics names and its offset in stats structure */
53 : : struct rte_eth_xstats_name_off {
54 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
55 : : unsigned offset;
56 : : };
57 : :
58 : : static const struct rte_eth_xstats_name_off eth_dev_stats_strings[] = {
59 : : {"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)},
60 : : {"tx_good_packets", offsetof(struct rte_eth_stats, opackets)},
61 : : {"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)},
62 : : {"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)},
63 : : {"rx_missed_errors", offsetof(struct rte_eth_stats, imissed)},
64 : : {"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
65 : : {"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
66 : : {"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats,
67 : : rx_nombuf)},
68 : : };
69 : :
70 : : #define RTE_NB_STATS RTE_DIM(eth_dev_stats_strings)
71 : :
72 : : static const struct rte_eth_xstats_name_off eth_dev_rxq_stats_strings[] = {
73 : : {"packets", offsetof(struct rte_eth_stats, q_ipackets)},
74 : : {"bytes", offsetof(struct rte_eth_stats, q_ibytes)},
75 : : {"errors", offsetof(struct rte_eth_stats, q_errors)},
76 : : };
77 : :
78 : : #define RTE_NB_RXQ_STATS RTE_DIM(eth_dev_rxq_stats_strings)
79 : :
80 : : static const struct rte_eth_xstats_name_off eth_dev_txq_stats_strings[] = {
81 : : {"packets", offsetof(struct rte_eth_stats, q_opackets)},
82 : : {"bytes", offsetof(struct rte_eth_stats, q_obytes)},
83 : : };
84 : : #define RTE_NB_TXQ_STATS RTE_DIM(eth_dev_txq_stats_strings)
85 : :
86 : : #define RTE_RX_OFFLOAD_BIT2STR(_name) \
87 : : { RTE_ETH_RX_OFFLOAD_##_name, #_name }
88 : :
89 : : static const struct {
90 : : uint64_t offload;
91 : : const char *name;
92 : : } eth_dev_rx_offload_names[] = {
93 : : RTE_RX_OFFLOAD_BIT2STR(VLAN_STRIP),
94 : : RTE_RX_OFFLOAD_BIT2STR(IPV4_CKSUM),
95 : : RTE_RX_OFFLOAD_BIT2STR(UDP_CKSUM),
96 : : RTE_RX_OFFLOAD_BIT2STR(TCP_CKSUM),
97 : : RTE_RX_OFFLOAD_BIT2STR(TCP_LRO),
98 : : RTE_RX_OFFLOAD_BIT2STR(QINQ_STRIP),
99 : : RTE_RX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM),
100 : : RTE_RX_OFFLOAD_BIT2STR(MACSEC_STRIP),
101 : : RTE_RX_OFFLOAD_BIT2STR(VLAN_FILTER),
102 : : RTE_RX_OFFLOAD_BIT2STR(VLAN_EXTEND),
103 : : RTE_RX_OFFLOAD_BIT2STR(SCATTER),
104 : : RTE_RX_OFFLOAD_BIT2STR(TIMESTAMP),
105 : : RTE_RX_OFFLOAD_BIT2STR(SECURITY),
106 : : RTE_RX_OFFLOAD_BIT2STR(KEEP_CRC),
107 : : RTE_RX_OFFLOAD_BIT2STR(SCTP_CKSUM),
108 : : RTE_RX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM),
109 : : RTE_RX_OFFLOAD_BIT2STR(RSS_HASH),
110 : : RTE_RX_OFFLOAD_BIT2STR(BUFFER_SPLIT),
111 : : };
112 : :
113 : : #undef RTE_RX_OFFLOAD_BIT2STR
114 : : #undef RTE_ETH_RX_OFFLOAD_BIT2STR
115 : :
116 : : #define RTE_TX_OFFLOAD_BIT2STR(_name) \
117 : : { RTE_ETH_TX_OFFLOAD_##_name, #_name }
118 : :
119 : : static const struct {
120 : : uint64_t offload;
121 : : const char *name;
122 : : } eth_dev_tx_offload_names[] = {
123 : : RTE_TX_OFFLOAD_BIT2STR(VLAN_INSERT),
124 : : RTE_TX_OFFLOAD_BIT2STR(IPV4_CKSUM),
125 : : RTE_TX_OFFLOAD_BIT2STR(UDP_CKSUM),
126 : : RTE_TX_OFFLOAD_BIT2STR(TCP_CKSUM),
127 : : RTE_TX_OFFLOAD_BIT2STR(SCTP_CKSUM),
128 : : RTE_TX_OFFLOAD_BIT2STR(TCP_TSO),
129 : : RTE_TX_OFFLOAD_BIT2STR(UDP_TSO),
130 : : RTE_TX_OFFLOAD_BIT2STR(OUTER_IPV4_CKSUM),
131 : : RTE_TX_OFFLOAD_BIT2STR(QINQ_INSERT),
132 : : RTE_TX_OFFLOAD_BIT2STR(VXLAN_TNL_TSO),
133 : : RTE_TX_OFFLOAD_BIT2STR(GRE_TNL_TSO),
134 : : RTE_TX_OFFLOAD_BIT2STR(IPIP_TNL_TSO),
135 : : RTE_TX_OFFLOAD_BIT2STR(GENEVE_TNL_TSO),
136 : : RTE_TX_OFFLOAD_BIT2STR(MACSEC_INSERT),
137 : : RTE_TX_OFFLOAD_BIT2STR(MT_LOCKFREE),
138 : : RTE_TX_OFFLOAD_BIT2STR(MULTI_SEGS),
139 : : RTE_TX_OFFLOAD_BIT2STR(MBUF_FAST_FREE),
140 : : RTE_TX_OFFLOAD_BIT2STR(SECURITY),
141 : : RTE_TX_OFFLOAD_BIT2STR(UDP_TNL_TSO),
142 : : RTE_TX_OFFLOAD_BIT2STR(IP_TNL_TSO),
143 : : RTE_TX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM),
144 : : RTE_TX_OFFLOAD_BIT2STR(SEND_ON_TIMESTAMP),
145 : : };
146 : :
147 : : #undef RTE_TX_OFFLOAD_BIT2STR
148 : :
149 : : static const struct {
150 : : uint64_t offload;
151 : : const char *name;
152 : : } rte_eth_dev_capa_names[] = {
153 : : {RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP, "RUNTIME_RX_QUEUE_SETUP"},
154 : : {RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP, "RUNTIME_TX_QUEUE_SETUP"},
155 : : {RTE_ETH_DEV_CAPA_RXQ_SHARE, "RXQ_SHARE"},
156 : : {RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP, "FLOW_RULE_KEEP"},
157 : : {RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"},
158 : : };
159 : :
160 : : enum {
161 : : STAT_QMAP_TX = 0,
162 : : STAT_QMAP_RX
163 : : };
164 : :
165 : : static const struct {
166 : : enum rte_eth_hash_function algo;
167 : : const char *name;
168 : : } rte_eth_dev_rss_algo_names[] = {
169 : : {RTE_ETH_HASH_FUNCTION_DEFAULT, "default"},
170 : : {RTE_ETH_HASH_FUNCTION_SIMPLE_XOR, "simple_xor"},
171 : : {RTE_ETH_HASH_FUNCTION_TOEPLITZ, "toeplitz"},
172 : : {RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ, "symmetric_toeplitz"},
173 : : {RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ_SORT, "symmetric_toeplitz_sort"},
174 : : };
175 : :
176 : : int
177 : 0 : rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
178 : : {
179 : : int ret;
180 : : struct rte_devargs devargs;
181 : : const char *bus_param_key;
182 : : char *bus_str = NULL;
183 : : char *cls_str = NULL;
184 : : int str_size;
185 : :
186 [ # # ]: 0 : if (iter == NULL) {
187 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot initialize NULL iterator");
188 : 0 : return -EINVAL;
189 : : }
190 : :
191 [ # # ]: 0 : if (devargs_str == NULL) {
192 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
193 : : "Cannot initialize iterator from NULL device description string");
194 : 0 : return -EINVAL;
195 : : }
196 : :
197 : : memset(iter, 0, sizeof(*iter));
198 : : memset(&devargs, 0, sizeof(devargs));
199 : :
200 : : /*
201 : : * The devargs string may use various syntaxes:
202 : : * - 0000:08:00.0,representor=[1-3]
203 : : * - pci:0000:06:00.0,representor=[0,5]
204 : : * - class=eth,mac=00:11:22:33:44:55
205 : : * - bus=X,paramX=x/class=Y,paramY=y/driver=Z,paramZ=z
206 : : */
207 : :
208 : : /*
209 : : * Handle pure class filter (i.e. without any bus-level argument),
210 : : * from future new syntax.
211 : : * rte_devargs_parse() is not yet supporting the new syntax,
212 : : * that's why this simple case is temporarily parsed here.
213 : : */
214 : : #define iter_anybus_str "class=eth,"
215 [ # # ]: 0 : if (strncmp(devargs_str, iter_anybus_str,
216 : : strlen(iter_anybus_str)) == 0) {
217 : 0 : iter->cls_str = devargs_str + strlen(iter_anybus_str);
218 : 0 : goto end;
219 : : }
220 : :
221 : : /* Split bus, device and parameters. */
222 : 0 : ret = rte_devargs_parse(&devargs, devargs_str);
223 [ # # ]: 0 : if (ret != 0)
224 : 0 : goto error;
225 : :
226 : : /*
227 : : * Assume parameters of old syntax can match only at ethdev level.
228 : : * Extra parameters will be ignored, thanks to "+" prefix.
229 : : */
230 : 0 : str_size = strlen(devargs.args) + 2;
231 : 0 : cls_str = malloc(str_size);
232 [ # # ]: 0 : if (cls_str == NULL) {
233 : : ret = -ENOMEM;
234 : 0 : goto error;
235 : : }
236 : : ret = snprintf(cls_str, str_size, "+%s", devargs.args);
237 [ # # ]: 0 : if (ret != str_size - 1) {
238 : : ret = -EINVAL;
239 : 0 : goto error;
240 : : }
241 : 0 : iter->cls_str = cls_str;
242 : :
243 : 0 : iter->bus = devargs.bus;
244 [ # # ]: 0 : if (iter->bus->dev_iterate == NULL) {
245 : : ret = -ENOTSUP;
246 : 0 : goto error;
247 : : }
248 : :
249 : : /* Convert bus args to new syntax for use with new API dev_iterate. */
250 [ # # ]: 0 : if ((strcmp(iter->bus->name, "vdev") == 0) ||
251 [ # # ]: 0 : (strcmp(iter->bus->name, "fslmc") == 0) ||
252 [ # # ]: 0 : (strcmp(iter->bus->name, "dpaa_bus") == 0)) {
253 : : bus_param_key = "name";
254 [ # # ]: 0 : } else if (strcmp(iter->bus->name, "pci") == 0) {
255 : : bus_param_key = "addr";
256 : : } else {
257 : : ret = -ENOTSUP;
258 : 0 : goto error;
259 : : }
260 : 0 : str_size = strlen(bus_param_key) + strlen(devargs.name) + 2;
261 : 0 : bus_str = malloc(str_size);
262 [ # # ]: 0 : if (bus_str == NULL) {
263 : : ret = -ENOMEM;
264 : 0 : goto error;
265 : : }
266 : : ret = snprintf(bus_str, str_size, "%s=%s",
267 : : bus_param_key, devargs.name);
268 [ # # ]: 0 : if (ret != str_size - 1) {
269 : : ret = -EINVAL;
270 : 0 : goto error;
271 : : }
272 : 0 : iter->bus_str = bus_str;
273 : :
274 : 0 : end:
275 : 0 : iter->cls = rte_class_find_by_name("eth");
276 : 0 : rte_devargs_reset(&devargs);
277 : :
278 : : rte_eth_trace_iterator_init(devargs_str);
279 : :
280 : : return 0;
281 : :
282 : 0 : error:
283 [ # # ]: 0 : if (ret == -ENOTSUP)
284 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Bus %s does not support iterating.",
285 : : iter->bus->name);
286 : 0 : rte_devargs_reset(&devargs);
287 : 0 : free(bus_str);
288 : 0 : free(cls_str);
289 : 0 : return ret;
290 : : }
291 : :
292 : : uint16_t
293 : 0 : rte_eth_iterator_next(struct rte_dev_iterator *iter)
294 : : {
295 [ # # ]: 0 : if (iter == NULL) {
296 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
297 : : "Cannot get next device from NULL iterator");
298 : 0 : return RTE_MAX_ETHPORTS;
299 : : }
300 : :
301 [ # # ]: 0 : if (iter->cls == NULL) /* invalid ethdev iterator */
302 : : return RTE_MAX_ETHPORTS;
303 : :
304 : : do { /* loop to try all matching rte_device */
305 : : /* If not pure ethdev filter and */
306 [ # # ]: 0 : if (iter->bus != NULL &&
307 : : /* not in middle of rte_eth_dev iteration, */
308 [ # # ]: 0 : iter->class_device == NULL) {
309 : : /* get next rte_device to try. */
310 : 0 : iter->device = iter->bus->dev_iterate(
311 : 0 : iter->device, iter->bus_str, iter);
312 [ # # ]: 0 : if (iter->device == NULL)
313 : : break; /* no more rte_device candidate */
314 : : }
315 : : /* A device is matching bus part, need to check ethdev part. */
316 : 0 : iter->class_device = iter->cls->dev_iterate(
317 : 0 : iter->class_device, iter->cls_str, iter);
318 [ # # ]: 0 : if (iter->class_device != NULL) {
319 : 0 : uint16_t id = eth_dev_to_id(iter->class_device);
320 : :
321 : 0 : rte_eth_trace_iterator_next(iter, id);
322 : :
323 : 0 : return id; /* match */
324 : : }
325 [ # # ]: 0 : } while (iter->bus != NULL); /* need to try next rte_device */
326 : :
327 : : /* No more ethdev port to iterate. */
328 : 0 : rte_eth_iterator_cleanup(iter);
329 : 0 : return RTE_MAX_ETHPORTS;
330 : : }
331 : :
332 : : void
333 : 0 : rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
334 : : {
335 [ # # ]: 0 : if (iter == NULL) {
336 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot do clean up from NULL iterator");
337 : 0 : return;
338 : : }
339 : :
340 [ # # ]: 0 : if (iter->bus_str == NULL)
341 : : return; /* nothing to free in pure class filter */
342 : :
343 : 0 : rte_eth_trace_iterator_cleanup(iter);
344 : :
345 : 0 : free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
346 : 0 : free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */
347 : : memset(iter, 0, sizeof(*iter));
348 : : }
349 : :
350 : : uint16_t
351 : 12579 : rte_eth_find_next(uint16_t port_id)
352 : : {
353 [ + + ]: 138126 : while (port_id < RTE_MAX_ETHPORTS &&
354 [ + + ]: 133941 : rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED)
355 : 125547 : port_id++;
356 : :
357 [ + + ]: 12579 : if (port_id >= RTE_MAX_ETHPORTS)
358 : : return RTE_MAX_ETHPORTS;
359 : :
360 : 8394 : rte_eth_trace_find_next(port_id);
361 : :
362 : 8394 : return port_id;
363 : : }
364 : :
365 : : /*
366 : : * Macro to iterate over all valid ports for internal usage.
367 : : * Note: RTE_ETH_FOREACH_DEV is different because filtering owned ports.
368 : : */
369 : : #define RTE_ETH_FOREACH_VALID_DEV(port_id) \
370 : : for (port_id = rte_eth_find_next(0); \
371 : : port_id < RTE_MAX_ETHPORTS; \
372 : : port_id = rte_eth_find_next(port_id + 1))
373 : :
374 : : uint16_t
375 : 0 : rte_eth_find_next_of(uint16_t port_id, const struct rte_device *parent)
376 : : {
377 : 0 : port_id = rte_eth_find_next(port_id);
378 [ # # ]: 0 : while (port_id < RTE_MAX_ETHPORTS &&
379 [ # # ]: 0 : rte_eth_devices[port_id].device != parent)
380 : 0 : port_id = rte_eth_find_next(port_id + 1);
381 : :
382 : 0 : rte_eth_trace_find_next_of(port_id, parent);
383 : :
384 : 0 : return port_id;
385 : : }
386 : :
387 : : uint16_t
388 : 0 : rte_eth_find_next_sibling(uint16_t port_id, uint16_t ref_port_id)
389 : : {
390 : : uint16_t ret;
391 : :
392 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(ref_port_id, RTE_MAX_ETHPORTS);
393 : 0 : ret = rte_eth_find_next_of(port_id,
394 : 0 : rte_eth_devices[ref_port_id].device);
395 : :
396 : 0 : rte_eth_trace_find_next_sibling(port_id, ref_port_id, ret);
397 : :
398 : 0 : return ret;
399 : : }
400 : :
401 : : static bool
402 : : eth_dev_is_allocated(const struct rte_eth_dev *ethdev)
403 : : {
404 [ - + - - : 118 : return ethdev->data != NULL && ethdev->data->name[0] != '\0';
- - - - ]
405 : : }
406 : :
407 : : int
408 : 342 : rte_eth_dev_is_valid_port(uint16_t port_id)
409 : : {
410 : : int is_valid;
411 : :
412 [ + + ]: 342 : if (port_id >= RTE_MAX_ETHPORTS ||
413 [ + + ]: 340 : (rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED))
414 : : is_valid = 0;
415 : : else
416 : : is_valid = 1;
417 : :
418 : 342 : rte_ethdev_trace_is_valid_port(port_id, is_valid);
419 : :
420 : 342 : return is_valid;
421 : : }
422 : :
423 : : static int
424 : : eth_is_valid_owner_id(uint64_t owner_id)
425 : : __rte_requires_capability(rte_mcfg_ethdev_get_lock())
426 : : {
427 [ # # # # ]: 0 : if (owner_id == RTE_ETH_DEV_NO_OWNER ||
428 [ # # # # : 0 : eth_dev_shared_data->next_owner_id <= owner_id)
# # ]
429 : : return 0;
430 : : return 1;
431 : : }
432 : :
433 : : uint64_t
434 : 12549 : rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
435 : : {
436 : 12549 : port_id = rte_eth_find_next(port_id);
437 [ + + ]: 12549 : while (port_id < RTE_MAX_ETHPORTS &&
438 [ - + ]: 8367 : rte_eth_devices[port_id].data->owner.id != owner_id)
439 : 0 : port_id = rte_eth_find_next(port_id + 1);
440 : :
441 : 12549 : rte_eth_trace_find_next_owned_by(port_id, owner_id);
442 : :
443 : 12549 : return port_id;
444 : : }
445 : :
446 : : int
447 : 0 : rte_eth_dev_owner_new(uint64_t *owner_id)
448 : : {
449 : : int ret;
450 : :
451 [ # # ]: 0 : if (owner_id == NULL) {
452 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get new owner ID to NULL");
453 : 0 : return -EINVAL;
454 : : }
455 : :
456 : 0 : rte_spinlock_lock(rte_mcfg_ethdev_get_lock());
457 : :
458 [ # # ]: 0 : if (eth_dev_shared_data_prepare() != NULL) {
459 : 0 : *owner_id = eth_dev_shared_data->next_owner_id++;
460 : 0 : eth_dev_shared_data->allocated_owners++;
461 : : ret = 0;
462 : : } else {
463 : : ret = -ENOMEM;
464 : : }
465 : :
466 : 0 : rte_spinlock_unlock(rte_mcfg_ethdev_get_lock());
467 : :
468 [ # # ]: 0 : rte_ethdev_trace_owner_new(*owner_id, ret);
469 : :
470 : 0 : return ret;
471 : : }
472 : :
473 : : static int
474 : 0 : eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
475 : : const struct rte_eth_dev_owner *new_owner)
476 : : __rte_requires_capability(rte_mcfg_ethdev_get_lock())
477 : : {
478 : 0 : struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
479 : : struct rte_eth_dev_owner *port_owner;
480 : :
481 [ # # # # ]: 0 : if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
482 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Port ID %"PRIu16" is not allocated",
483 : : port_id);
484 : 0 : return -ENODEV;
485 : : }
486 : :
487 [ # # ]: 0 : if (new_owner == NULL) {
488 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
489 : : "Cannot set ethdev port %u owner from NULL owner",
490 : : port_id);
491 : 0 : return -EINVAL;
492 : : }
493 : :
494 [ # # ]: 0 : if (!eth_is_valid_owner_id(new_owner->id) &&
495 : : !eth_is_valid_owner_id(old_owner_id)) {
496 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
497 : : "Invalid owner old_id=%016"PRIx64" new_id=%016"PRIx64,
498 : : old_owner_id, new_owner->id);
499 : 0 : return -EINVAL;
500 : : }
501 : :
502 : : port_owner = &rte_eth_devices[port_id].data->owner;
503 [ # # ]: 0 : if (port_owner->id != old_owner_id) {
504 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
505 : : "Cannot set owner to port %u already owned by %s_%016"PRIX64,
506 : : port_id, port_owner->name, port_owner->id);
507 : 0 : return -EPERM;
508 : : }
509 : :
510 : : /* can not truncate (same structure) */
511 : 0 : strlcpy(port_owner->name, new_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN);
512 : :
513 : 0 : port_owner->id = new_owner->id;
514 : :
515 : 0 : RTE_ETHDEV_LOG_LINE(DEBUG, "Port %u owner is %s_%016"PRIx64,
516 : : port_id, new_owner->name, new_owner->id);
517 : :
518 : 0 : return 0;
519 : : }
520 : :
521 : : int
522 : 0 : rte_eth_dev_owner_set(const uint16_t port_id,
523 : : const struct rte_eth_dev_owner *owner)
524 : : {
525 : : int ret;
526 : :
527 : 0 : rte_spinlock_lock(rte_mcfg_ethdev_get_lock());
528 : :
529 [ # # ]: 0 : if (eth_dev_shared_data_prepare() != NULL)
530 : 0 : ret = eth_dev_owner_set(port_id, RTE_ETH_DEV_NO_OWNER, owner);
531 : : else
532 : : ret = -ENOMEM;
533 : :
534 : 0 : rte_spinlock_unlock(rte_mcfg_ethdev_get_lock());
535 : :
536 : 0 : rte_ethdev_trace_owner_set(port_id, owner, ret);
537 : :
538 : 0 : return ret;
539 : : }
540 : :
541 : : int
542 : 0 : rte_eth_dev_owner_unset(const uint16_t port_id, const uint64_t owner_id)
543 : : {
544 : 0 : const struct rte_eth_dev_owner new_owner = (struct rte_eth_dev_owner)
545 : : {.id = RTE_ETH_DEV_NO_OWNER, .name = ""};
546 : : int ret;
547 : :
548 : 0 : rte_spinlock_lock(rte_mcfg_ethdev_get_lock());
549 : :
550 [ # # ]: 0 : if (eth_dev_shared_data_prepare() != NULL)
551 : 0 : ret = eth_dev_owner_set(port_id, owner_id, &new_owner);
552 : : else
553 : : ret = -ENOMEM;
554 : :
555 : 0 : rte_spinlock_unlock(rte_mcfg_ethdev_get_lock());
556 : :
557 : 0 : rte_ethdev_trace_owner_unset(port_id, owner_id, ret);
558 : :
559 : 0 : return ret;
560 : : }
561 : :
562 : : int
563 : 0 : rte_eth_dev_owner_delete(const uint64_t owner_id)
564 : : {
565 : : uint16_t port_id;
566 : : int ret = 0;
567 : :
568 : 0 : rte_spinlock_lock(rte_mcfg_ethdev_get_lock());
569 : :
570 [ # # ]: 0 : if (eth_dev_shared_data_prepare() == NULL) {
571 : : ret = -ENOMEM;
572 : : } else if (eth_is_valid_owner_id(owner_id)) {
573 [ # # ]: 0 : for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
574 : 0 : struct rte_eth_dev_data *data =
575 : 0 : rte_eth_devices[port_id].data;
576 [ # # # # ]: 0 : if (data != NULL && data->owner.id == owner_id)
577 : 0 : memset(&data->owner, 0,
578 : : sizeof(struct rte_eth_dev_owner));
579 : : }
580 : 0 : RTE_ETHDEV_LOG_LINE(NOTICE,
581 : : "All port owners owned by %016"PRIx64" identifier have removed",
582 : : owner_id);
583 : 0 : eth_dev_shared_data->allocated_owners--;
584 : 0 : eth_dev_shared_data_release();
585 : : } else {
586 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
587 : : "Invalid owner ID=%016"PRIx64,
588 : : owner_id);
589 : : ret = -EINVAL;
590 : : }
591 : :
592 : 0 : rte_spinlock_unlock(rte_mcfg_ethdev_get_lock());
593 : :
594 : 0 : rte_ethdev_trace_owner_delete(owner_id, ret);
595 : :
596 : 0 : return ret;
597 : : }
598 : :
599 : : int
600 : 0 : rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
601 : : {
602 : : struct rte_eth_dev *ethdev;
603 : : int ret;
604 : :
605 [ # # ]: 0 : if (port_id >= RTE_MAX_ETHPORTS)
606 : : return -ENODEV;
607 : :
608 [ # # ]: 0 : ethdev = &rte_eth_devices[port_id];
609 [ # # ]: 0 : if (!eth_dev_is_allocated(ethdev)) {
610 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Port ID %"PRIu16" is not allocated",
611 : : port_id);
612 : 0 : return -ENODEV;
613 : : }
614 : :
615 [ # # ]: 0 : if (owner == NULL) {
616 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u owner to NULL",
617 : : port_id);
618 : 0 : return -EINVAL;
619 : : }
620 : :
621 : 0 : rte_spinlock_lock(rte_mcfg_ethdev_get_lock());
622 : :
623 [ # # ]: 0 : if (eth_dev_shared_data_prepare() != NULL) {
624 [ # # ]: 0 : rte_memcpy(owner, ðdev->data->owner, sizeof(*owner));
625 : : ret = 0;
626 : : } else {
627 : : ret = -ENOMEM;
628 : : }
629 : :
630 : 0 : rte_spinlock_unlock(rte_mcfg_ethdev_get_lock());
631 : :
632 : 0 : rte_ethdev_trace_owner_get(port_id, owner, ret);
633 : :
634 : 0 : return ret;
635 : : }
636 : :
637 : : int
638 : 118 : rte_eth_dev_socket_id(uint16_t port_id)
639 : : {
640 : : int socket_id = SOCKET_ID_ANY;
641 : : struct rte_eth_dev *ethdev;
642 : :
643 [ - + ]: 118 : if (port_id >= RTE_MAX_ETHPORTS) {
644 : 0 : rte_errno = EINVAL;
645 : 0 : return socket_id;
646 : : }
647 : :
648 [ + - ]: 118 : ethdev = &rte_eth_devices[port_id];
649 [ - + ]: 118 : if (!eth_dev_is_allocated(ethdev)) {
650 : 0 : rte_errno = EINVAL;
651 : : } else {
652 : 118 : socket_id = rte_eth_devices[port_id].data->numa_node;
653 [ - + ]: 118 : if (socket_id == SOCKET_ID_ANY)
654 : 0 : rte_errno = 0;
655 : : }
656 : :
657 : 118 : rte_ethdev_trace_socket_id(port_id, socket_id);
658 : :
659 : 118 : return socket_id;
660 : : }
661 : :
662 : : void *
663 : 0 : rte_eth_dev_get_sec_ctx(uint16_t port_id)
664 : : {
665 : : void *ctx;
666 : :
667 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
668 [ # # ]: 0 : ctx = rte_eth_devices[port_id].security_ctx;
669 : :
670 : 0 : rte_ethdev_trace_get_sec_ctx(port_id, ctx);
671 : :
672 : 0 : return ctx;
673 : : }
674 : :
675 : : uint16_t
676 : 75 : rte_eth_dev_count_avail(void)
677 : : {
678 : : uint16_t p;
679 : : uint16_t count;
680 : :
681 : : count = 0;
682 : :
683 [ + + ]: 224 : RTE_ETH_FOREACH_DEV(p)
684 : 149 : count++;
685 : :
686 : 75 : rte_ethdev_trace_count_avail(count);
687 : :
688 : 75 : return count;
689 : : }
690 : :
691 : : uint16_t
692 : 3 : rte_eth_dev_count_total(void)
693 : : {
694 : : uint16_t port, count = 0;
695 : :
696 [ + + ]: 9 : RTE_ETH_FOREACH_VALID_DEV(port)
697 : 6 : count++;
698 : :
699 : 3 : rte_ethdev_trace_count_total(count);
700 : :
701 : 3 : return count;
702 : : }
703 : :
704 : : int
705 : 2 : rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
706 : : {
707 : : char *tmp;
708 : :
709 [ - + ]: 2 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
710 : :
711 [ - + ]: 2 : if (name == NULL) {
712 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u name to NULL",
713 : : port_id);
714 : 0 : return -EINVAL;
715 : : }
716 : :
717 : 2 : rte_spinlock_lock(rte_mcfg_ethdev_get_lock());
718 : : /* shouldn't check 'rte_eth_devices[i].data',
719 : : * because it might be overwritten by VDEV PMD */
720 : 2 : tmp = eth_dev_shared_data->data[port_id].name;
721 : 2 : rte_spinlock_unlock(rte_mcfg_ethdev_get_lock());
722 : :
723 : : strcpy(name, tmp);
724 : :
725 : 2 : rte_ethdev_trace_get_name_by_port(port_id, name);
726 : :
727 : 2 : return 0;
728 : : }
729 : :
730 : : int
731 : 10 : rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
732 : : {
733 : : int ret = -ENODEV;
734 : : uint16_t pid;
735 : :
736 [ - + ]: 10 : if (name == NULL) {
737 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get port ID from NULL name");
738 : 0 : return -EINVAL;
739 : : }
740 : :
741 [ - + ]: 10 : if (port_id == NULL) {
742 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
743 : : "Cannot get port ID to NULL for %s", name);
744 : 0 : return -EINVAL;
745 : : }
746 : :
747 : 10 : rte_spinlock_lock(rte_mcfg_ethdev_get_lock());
748 [ + - ]: 21 : RTE_ETH_FOREACH_VALID_DEV(pid) {
749 [ + + ]: 21 : if (strcmp(name, eth_dev_shared_data->data[pid].name) != 0)
750 : : continue;
751 : :
752 [ - + ]: 10 : *port_id = pid;
753 : 10 : rte_ethdev_trace_get_port_by_name(name, *port_id);
754 : : ret = 0;
755 : 10 : break;
756 : : }
757 : 10 : rte_spinlock_unlock(rte_mcfg_ethdev_get_lock());
758 : :
759 : 10 : return ret;
760 : : }
761 : :
762 : : int
763 : 116 : eth_err(uint16_t port_id, int ret)
764 : : {
765 [ - + ]: 116 : if (ret == 0)
766 : : return 0;
767 [ # # ]: 0 : if (rte_eth_dev_is_removed(port_id))
768 : 0 : return -EIO;
769 : : return ret;
770 : : }
771 : :
772 : : static int
773 : 0 : eth_dev_validate_rx_queue(const struct rte_eth_dev *dev, uint16_t rx_queue_id)
774 : : {
775 : : uint16_t port_id;
776 : :
777 [ # # ]: 0 : if (rx_queue_id >= dev->data->nb_rx_queues) {
778 : 0 : port_id = dev->data->port_id;
779 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
780 : : "Invalid Rx queue_id=%u of device with port_id=%u",
781 : : rx_queue_id, port_id);
782 : 0 : return -EINVAL;
783 : : }
784 : :
785 [ # # ]: 0 : if (dev->data->rx_queues[rx_queue_id] == NULL) {
786 : 0 : port_id = dev->data->port_id;
787 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
788 : : "Queue %u of device with port_id=%u has not been setup",
789 : : rx_queue_id, port_id);
790 : 0 : return -EINVAL;
791 : : }
792 : :
793 : : return 0;
794 : : }
795 : :
796 : : static int
797 : 0 : eth_dev_validate_tx_queue(const struct rte_eth_dev *dev, uint16_t tx_queue_id)
798 : : {
799 : : uint16_t port_id;
800 : :
801 [ # # ]: 0 : if (tx_queue_id >= dev->data->nb_tx_queues) {
802 : 0 : port_id = dev->data->port_id;
803 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
804 : : "Invalid Tx queue_id=%u of device with port_id=%u",
805 : : tx_queue_id, port_id);
806 : 0 : return -EINVAL;
807 : : }
808 : :
809 [ # # ]: 0 : if (dev->data->tx_queues[tx_queue_id] == NULL) {
810 : 0 : port_id = dev->data->port_id;
811 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
812 : : "Queue %u of device with port_id=%u has not been setup",
813 : : tx_queue_id, port_id);
814 : 0 : return -EINVAL;
815 : : }
816 : :
817 : : return 0;
818 : : }
819 : :
820 : : int
821 : 0 : rte_eth_rx_queue_is_valid(uint16_t port_id, uint16_t queue_id)
822 : : {
823 : : struct rte_eth_dev *dev;
824 : :
825 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
826 : 0 : dev = &rte_eth_devices[port_id];
827 : :
828 : 0 : return eth_dev_validate_rx_queue(dev, queue_id);
829 : : }
830 : :
831 : : int
832 : 0 : rte_eth_tx_queue_is_valid(uint16_t port_id, uint16_t queue_id)
833 : : {
834 : : struct rte_eth_dev *dev;
835 : :
836 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
837 : 0 : dev = &rte_eth_devices[port_id];
838 : :
839 : 0 : return eth_dev_validate_tx_queue(dev, queue_id);
840 : : }
841 : :
842 : : int
843 : 0 : rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id)
844 : : {
845 : : struct rte_eth_dev *dev;
846 : : int ret;
847 : :
848 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
849 : 0 : dev = &rte_eth_devices[port_id];
850 : :
851 [ # # ]: 0 : if (!dev->data->dev_started) {
852 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
853 : : "Port %u must be started before start any queue",
854 : : port_id);
855 : 0 : return -EINVAL;
856 : : }
857 : :
858 : 0 : ret = eth_dev_validate_rx_queue(dev, rx_queue_id);
859 [ # # ]: 0 : if (ret != 0)
860 : : return ret;
861 : :
862 [ # # ]: 0 : if (dev->dev_ops->rx_queue_start == NULL)
863 : : return -ENOTSUP;
864 : :
865 [ # # ]: 0 : if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) {
866 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
867 : : "Can't start Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16,
868 : : rx_queue_id, port_id);
869 : 0 : return -EINVAL;
870 : : }
871 : :
872 [ # # ]: 0 : if (dev->data->rx_queue_state[rx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) {
873 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
874 : : "Queue %"PRIu16" of device with port_id=%"PRIu16" already started",
875 : : rx_queue_id, port_id);
876 : 0 : return 0;
877 : : }
878 : :
879 : 0 : ret = eth_err(port_id, dev->dev_ops->rx_queue_start(dev, rx_queue_id));
880 : :
881 : 0 : rte_ethdev_trace_rx_queue_start(port_id, rx_queue_id, ret);
882 : :
883 : 0 : return ret;
884 : : }
885 : :
886 : : int
887 : 0 : rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id)
888 : : {
889 : : struct rte_eth_dev *dev;
890 : : int ret;
891 : :
892 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
893 : 0 : dev = &rte_eth_devices[port_id];
894 : :
895 : 0 : ret = eth_dev_validate_rx_queue(dev, rx_queue_id);
896 [ # # ]: 0 : if (ret != 0)
897 : : return ret;
898 : :
899 [ # # ]: 0 : if (dev->dev_ops->rx_queue_stop == NULL)
900 : : return -ENOTSUP;
901 : :
902 [ # # ]: 0 : if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) {
903 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
904 : : "Can't stop Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16,
905 : : rx_queue_id, port_id);
906 : 0 : return -EINVAL;
907 : : }
908 : :
909 [ # # ]: 0 : if (dev->data->rx_queue_state[rx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) {
910 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
911 : : "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped",
912 : : rx_queue_id, port_id);
913 : 0 : return 0;
914 : : }
915 : :
916 : 0 : ret = eth_err(port_id, dev->dev_ops->rx_queue_stop(dev, rx_queue_id));
917 : :
918 : 0 : rte_ethdev_trace_rx_queue_stop(port_id, rx_queue_id, ret);
919 : :
920 : 0 : return ret;
921 : : }
922 : :
923 : : int
924 : 0 : rte_eth_dev_tx_queue_start(uint16_t port_id, uint16_t tx_queue_id)
925 : : {
926 : : struct rte_eth_dev *dev;
927 : : int ret;
928 : :
929 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
930 : 0 : dev = &rte_eth_devices[port_id];
931 : :
932 [ # # ]: 0 : if (!dev->data->dev_started) {
933 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
934 : : "Port %u must be started before start any queue",
935 : : port_id);
936 : 0 : return -EINVAL;
937 : : }
938 : :
939 : 0 : ret = eth_dev_validate_tx_queue(dev, tx_queue_id);
940 [ # # ]: 0 : if (ret != 0)
941 : : return ret;
942 : :
943 [ # # ]: 0 : if (dev->dev_ops->tx_queue_start == NULL)
944 : : return -ENOTSUP;
945 : :
946 [ # # ]: 0 : if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) {
947 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
948 : : "Can't start Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16,
949 : : tx_queue_id, port_id);
950 : 0 : return -EINVAL;
951 : : }
952 : :
953 [ # # ]: 0 : if (dev->data->tx_queue_state[tx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) {
954 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
955 : : "Queue %"PRIu16" of device with port_id=%"PRIu16" already started",
956 : : tx_queue_id, port_id);
957 : 0 : return 0;
958 : : }
959 : :
960 : 0 : ret = eth_err(port_id, dev->dev_ops->tx_queue_start(dev, tx_queue_id));
961 : :
962 : 0 : rte_ethdev_trace_tx_queue_start(port_id, tx_queue_id, ret);
963 : :
964 : 0 : return ret;
965 : : }
966 : :
967 : : int
968 : 0 : rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id)
969 : : {
970 : : struct rte_eth_dev *dev;
971 : : int ret;
972 : :
973 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
974 : 0 : dev = &rte_eth_devices[port_id];
975 : :
976 : 0 : ret = eth_dev_validate_tx_queue(dev, tx_queue_id);
977 [ # # ]: 0 : if (ret != 0)
978 : : return ret;
979 : :
980 [ # # ]: 0 : if (dev->dev_ops->tx_queue_stop == NULL)
981 : : return -ENOTSUP;
982 : :
983 [ # # ]: 0 : if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) {
984 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
985 : : "Can't stop Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16,
986 : : tx_queue_id, port_id);
987 : 0 : return -EINVAL;
988 : : }
989 : :
990 [ # # ]: 0 : if (dev->data->tx_queue_state[tx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) {
991 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
992 : : "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped",
993 : : tx_queue_id, port_id);
994 : 0 : return 0;
995 : : }
996 : :
997 : 0 : ret = eth_err(port_id, dev->dev_ops->tx_queue_stop(dev, tx_queue_id));
998 : :
999 : 0 : rte_ethdev_trace_tx_queue_stop(port_id, tx_queue_id, ret);
1000 : :
1001 : 0 : return ret;
1002 : : }
1003 : :
1004 : : uint32_t
1005 : 0 : rte_eth_speed_bitflag(uint32_t speed, int duplex)
1006 : : {
1007 : : uint32_t ret;
1008 : :
1009 [ # # # # : 0 : switch (speed) {
# # # # #
# # # # #
# ]
1010 : 0 : case RTE_ETH_SPEED_NUM_10M:
1011 [ # # ]: 0 : ret = duplex ? RTE_ETH_LINK_SPEED_10M : RTE_ETH_LINK_SPEED_10M_HD;
1012 : : break;
1013 : 0 : case RTE_ETH_SPEED_NUM_100M:
1014 [ # # ]: 0 : ret = duplex ? RTE_ETH_LINK_SPEED_100M : RTE_ETH_LINK_SPEED_100M_HD;
1015 : : break;
1016 : : case RTE_ETH_SPEED_NUM_1G:
1017 : : ret = RTE_ETH_LINK_SPEED_1G;
1018 : : break;
1019 : 0 : case RTE_ETH_SPEED_NUM_2_5G:
1020 : : ret = RTE_ETH_LINK_SPEED_2_5G;
1021 : 0 : break;
1022 : 0 : case RTE_ETH_SPEED_NUM_5G:
1023 : : ret = RTE_ETH_LINK_SPEED_5G;
1024 : 0 : break;
1025 : 0 : case RTE_ETH_SPEED_NUM_10G:
1026 : : ret = RTE_ETH_LINK_SPEED_10G;
1027 : 0 : break;
1028 : 0 : case RTE_ETH_SPEED_NUM_20G:
1029 : : ret = RTE_ETH_LINK_SPEED_20G;
1030 : 0 : break;
1031 : 0 : case RTE_ETH_SPEED_NUM_25G:
1032 : : ret = RTE_ETH_LINK_SPEED_25G;
1033 : 0 : break;
1034 : 0 : case RTE_ETH_SPEED_NUM_40G:
1035 : : ret = RTE_ETH_LINK_SPEED_40G;
1036 : 0 : break;
1037 : 0 : case RTE_ETH_SPEED_NUM_50G:
1038 : : ret = RTE_ETH_LINK_SPEED_50G;
1039 : 0 : break;
1040 : 0 : case RTE_ETH_SPEED_NUM_56G:
1041 : : ret = RTE_ETH_LINK_SPEED_56G;
1042 : 0 : break;
1043 : 0 : case RTE_ETH_SPEED_NUM_100G:
1044 : : ret = RTE_ETH_LINK_SPEED_100G;
1045 : 0 : break;
1046 : 0 : case RTE_ETH_SPEED_NUM_200G:
1047 : : ret = RTE_ETH_LINK_SPEED_200G;
1048 : 0 : break;
1049 : 0 : case RTE_ETH_SPEED_NUM_400G:
1050 : : ret = RTE_ETH_LINK_SPEED_400G;
1051 : 0 : break;
1052 : 0 : default:
1053 : : ret = 0;
1054 : : }
1055 : :
1056 : 0 : rte_eth_trace_speed_bitflag(speed, duplex, ret);
1057 : :
1058 : 0 : return ret;
1059 : : }
1060 : :
1061 : : const char *
1062 : 0 : rte_eth_dev_rx_offload_name(uint64_t offload)
1063 : : {
1064 : : const char *name = "UNKNOWN";
1065 : : unsigned int i;
1066 : :
1067 [ # # ]: 0 : for (i = 0; i < RTE_DIM(eth_dev_rx_offload_names); ++i) {
1068 [ # # ]: 0 : if (offload == eth_dev_rx_offload_names[i].offload) {
1069 : 0 : name = eth_dev_rx_offload_names[i].name;
1070 : 0 : break;
1071 : : }
1072 : : }
1073 : :
1074 : 0 : rte_ethdev_trace_rx_offload_name(offload, name);
1075 : :
1076 : 0 : return name;
1077 : : }
1078 : :
1079 : : const char *
1080 : 0 : rte_eth_dev_tx_offload_name(uint64_t offload)
1081 : : {
1082 : : const char *name = "UNKNOWN";
1083 : : unsigned int i;
1084 : :
1085 [ # # ]: 0 : for (i = 0; i < RTE_DIM(eth_dev_tx_offload_names); ++i) {
1086 [ # # ]: 0 : if (offload == eth_dev_tx_offload_names[i].offload) {
1087 : 0 : name = eth_dev_tx_offload_names[i].name;
1088 : 0 : break;
1089 : : }
1090 : : }
1091 : :
1092 : 0 : rte_ethdev_trace_tx_offload_name(offload, name);
1093 : :
1094 : 0 : return name;
1095 : : }
1096 : :
1097 : : static char *
1098 : 0 : eth_dev_offload_names(uint64_t bitmask, char *buf, size_t size,
1099 : : const char *(*offload_name)(uint64_t))
1100 : : {
1101 : : unsigned int pos = 0;
1102 : : int ret;
1103 : :
1104 : : /* There should be at least enough space to handle those cases */
1105 : : RTE_ASSERT(size >= sizeof("none") && size >= sizeof("..."));
1106 : :
1107 [ # # ]: 0 : if (bitmask == 0) {
1108 : : ret = snprintf(&buf[pos], size - pos, "none");
1109 [ # # # # ]: 0 : if (ret < 0 || pos + ret >= size)
1110 : : ret = 0;
1111 : 0 : pos += ret;
1112 : 0 : goto out;
1113 : : }
1114 : :
1115 [ # # ]: 0 : while (bitmask != 0) {
1116 : 0 : uint64_t offload = RTE_BIT64(rte_ctz64(bitmask));
1117 : 0 : const char *name = offload_name(offload);
1118 : :
1119 [ # # ]: 0 : ret = snprintf(&buf[pos], size - pos, "%s,", name);
1120 [ # # # # ]: 0 : if (ret < 0 || pos + ret >= size) {
1121 [ # # ]: 0 : if (pos + sizeof("...") >= size)
1122 : 0 : pos = size - sizeof("...");
1123 [ # # ]: 0 : ret = snprintf(&buf[pos], size - pos, "...");
1124 [ # # # # ]: 0 : if (ret > 0 && pos + ret < size)
1125 : : pos += ret;
1126 : 0 : goto out;
1127 : : }
1128 : :
1129 : : pos += ret;
1130 : 0 : bitmask &= ~offload;
1131 : : }
1132 : :
1133 : : /* Eliminate trailing comma */
1134 : 0 : pos--;
1135 : 0 : out:
1136 : 0 : buf[pos] = '\0';
1137 : 0 : return buf;
1138 : : }
1139 : :
1140 : : const char *
1141 : 0 : rte_eth_dev_capability_name(uint64_t capability)
1142 : : {
1143 : : const char *name = "UNKNOWN";
1144 : : unsigned int i;
1145 : :
1146 [ # # ]: 0 : for (i = 0; i < RTE_DIM(rte_eth_dev_capa_names); ++i) {
1147 [ # # ]: 0 : if (capability == rte_eth_dev_capa_names[i].offload) {
1148 : 0 : name = rte_eth_dev_capa_names[i].name;
1149 : 0 : break;
1150 : : }
1151 : : }
1152 : :
1153 : 0 : rte_ethdev_trace_capability_name(capability, name);
1154 : :
1155 : 0 : return name;
1156 : : }
1157 : :
1158 : : static inline int
1159 : 0 : eth_dev_check_lro_pkt_size(uint16_t port_id, uint32_t config_size,
1160 : : uint32_t max_rx_pkt_len, uint32_t dev_info_size)
1161 : : {
1162 : : int ret = 0;
1163 : :
1164 [ # # ]: 0 : if (dev_info_size == 0) {
1165 [ # # ]: 0 : if (config_size != max_rx_pkt_len) {
1166 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%d max_lro_pkt_size"
1167 : : " %u != %u is not allowed",
1168 : : port_id, config_size, max_rx_pkt_len);
1169 : : ret = -EINVAL;
1170 : : }
1171 [ # # ]: 0 : } else if (config_size > dev_info_size) {
1172 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%d max_lro_pkt_size %u "
1173 : : "> max allowed value %u", port_id, config_size,
1174 : : dev_info_size);
1175 : : ret = -EINVAL;
1176 [ # # ]: 0 : } else if (config_size < RTE_ETHER_MIN_LEN) {
1177 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%d max_lro_pkt_size %u "
1178 : : "< min allowed value %u", port_id, config_size,
1179 : : (unsigned int)RTE_ETHER_MIN_LEN);
1180 : : ret = -EINVAL;
1181 : : }
1182 : 0 : return ret;
1183 : : }
1184 : :
1185 : : /*
1186 : : * Validate offloads that are requested through rte_eth_dev_configure against
1187 : : * the offloads successfully set by the Ethernet device.
1188 : : *
1189 : : * @param port_id
1190 : : * The port identifier of the Ethernet device.
1191 : : * @param req_offloads
1192 : : * The offloads that have been requested through `rte_eth_dev_configure`.
1193 : : * @param set_offloads
1194 : : * The offloads successfully set by the Ethernet device.
1195 : : * @param offload_type
1196 : : * The offload type i.e. Rx/Tx string.
1197 : : * @param offload_name
1198 : : * The function that prints the offload name.
1199 : : * @return
1200 : : * - (0) if validation successful.
1201 : : * - (-EINVAL) if requested offload has been silently disabled.
1202 : : */
1203 : : static int
1204 : 30 : eth_dev_validate_offloads(uint16_t port_id, uint64_t req_offloads,
1205 : : uint64_t set_offloads, const char *offload_type,
1206 : : const char *(*offload_name)(uint64_t))
1207 : : {
1208 : 30 : uint64_t offloads_diff = req_offloads ^ set_offloads;
1209 : : uint64_t offload;
1210 : : int ret = 0;
1211 : :
1212 [ - + ]: 30 : while (offloads_diff != 0) {
1213 : : /* Check if any offload is requested but not enabled. */
1214 : 0 : offload = RTE_BIT64(rte_ctz64(offloads_diff));
1215 [ # # ]: 0 : if (offload & req_offloads) {
1216 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1217 : : "Port %u failed to enable %s offload %s",
1218 : : port_id, offload_type, offload_name(offload));
1219 : : ret = -EINVAL;
1220 : : }
1221 : :
1222 : : /* Check if offload couldn't be disabled. */
1223 [ # # ]: 0 : if (offload & set_offloads) {
1224 : 0 : RTE_ETHDEV_LOG_LINE(DEBUG,
1225 : : "Port %u %s offload %s is not requested but enabled",
1226 : : port_id, offload_type, offload_name(offload));
1227 : : }
1228 : :
1229 : 0 : offloads_diff &= ~offload;
1230 : : }
1231 : :
1232 : 30 : return ret;
1233 : : }
1234 : :
1235 : : static uint32_t
1236 : : eth_dev_get_overhead_len(uint32_t max_rx_pktlen, uint16_t max_mtu)
1237 : : {
1238 : : uint32_t overhead_len;
1239 : :
1240 [ # # # # : 0 : if (max_mtu != UINT16_MAX && max_rx_pktlen > max_mtu)
# # ]
1241 : 0 : overhead_len = max_rx_pktlen - max_mtu;
1242 : : else
1243 : : overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
1244 : :
1245 : : return overhead_len;
1246 : : }
1247 : :
1248 : : /* rte_eth_dev_info_get() should be called prior to this function */
1249 : : static int
1250 : 15 : eth_dev_validate_mtu(uint16_t port_id, struct rte_eth_dev_info *dev_info,
1251 : : uint16_t mtu)
1252 : : {
1253 : : uint32_t overhead_len;
1254 : : uint32_t frame_size;
1255 : :
1256 [ - + ]: 15 : if (mtu < dev_info->min_mtu) {
1257 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1258 : : "MTU (%u) < device min MTU (%u) for port_id %u",
1259 : : mtu, dev_info->min_mtu, port_id);
1260 : 0 : return -EINVAL;
1261 : : }
1262 [ - + ]: 15 : if (mtu > dev_info->max_mtu) {
1263 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1264 : : "MTU (%u) > device max MTU (%u) for port_id %u",
1265 : : mtu, dev_info->max_mtu, port_id);
1266 : 0 : return -EINVAL;
1267 : : }
1268 : :
1269 [ - + ]: 15 : overhead_len = eth_dev_get_overhead_len(dev_info->max_rx_pktlen,
1270 : : dev_info->max_mtu);
1271 : 15 : frame_size = mtu + overhead_len;
1272 [ - + ]: 15 : if (frame_size < RTE_ETHER_MIN_LEN) {
1273 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1274 : : "Frame size (%u) < min frame size (%u) for port_id %u",
1275 : : frame_size, RTE_ETHER_MIN_LEN, port_id);
1276 : 0 : return -EINVAL;
1277 : : }
1278 : :
1279 [ - + ]: 15 : if (frame_size > dev_info->max_rx_pktlen) {
1280 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1281 : : "Frame size (%u) > device max frame size (%u) for port_id %u",
1282 : : frame_size, dev_info->max_rx_pktlen, port_id);
1283 : 0 : return -EINVAL;
1284 : : }
1285 : :
1286 : : return 0;
1287 : : }
1288 : :
1289 : : int
1290 : 15 : rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
1291 : : const struct rte_eth_conf *dev_conf)
1292 : : {
1293 : : enum rte_eth_hash_function algorithm;
1294 : : struct rte_eth_dev *dev;
1295 : : struct rte_eth_dev_info dev_info;
1296 : : struct rte_eth_conf orig_conf;
1297 : : int diag;
1298 : : int ret;
1299 : : uint16_t old_mtu;
1300 : :
1301 [ - + ]: 15 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1302 : 15 : dev = &rte_eth_devices[port_id];
1303 : :
1304 [ - + ]: 15 : if (dev_conf == NULL) {
1305 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1306 : : "Cannot configure ethdev port %u from NULL config",
1307 : : port_id);
1308 : 0 : return -EINVAL;
1309 : : }
1310 : :
1311 [ + - ]: 15 : if (dev->dev_ops->dev_configure == NULL)
1312 : : return -ENOTSUP;
1313 : :
1314 [ - + ]: 15 : if (dev->data->dev_started) {
1315 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1316 : : "Port %u must be stopped to allow configuration",
1317 : : port_id);
1318 : 0 : return -EBUSY;
1319 : : }
1320 : :
1321 : : /*
1322 : : * Ensure that "dev_configured" is always 0 each time prepare to do
1323 : : * dev_configure() to avoid any non-anticipated behaviour.
1324 : : * And set to 1 when dev_configure() is executed successfully.
1325 : : */
1326 : 15 : dev->data->dev_configured = 0;
1327 : :
1328 : : /* Store original config, as rollback required on failure */
1329 [ + - ]: 15 : memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf));
1330 : :
1331 : : /*
1332 : : * Copy the dev_conf parameter into the dev structure.
1333 : : * rte_eth_dev_info_get() requires dev_conf, copy it before dev_info get
1334 : : */
1335 [ + - ]: 15 : if (dev_conf != &dev->data->dev_conf)
1336 : : memcpy(&dev->data->dev_conf, dev_conf,
1337 : : sizeof(dev->data->dev_conf));
1338 : :
1339 : : /* Backup mtu for rollback */
1340 : 15 : old_mtu = dev->data->mtu;
1341 : :
1342 : : /* fields must be zero to reserve them for future ABI changes */
1343 [ + - ]: 15 : if (dev_conf->rxmode.reserved_64s[0] != 0 ||
1344 [ + - ]: 15 : dev_conf->rxmode.reserved_64s[1] != 0 ||
1345 [ + - ]: 15 : dev_conf->rxmode.reserved_ptrs[0] != NULL ||
1346 [ - + ]: 15 : dev_conf->rxmode.reserved_ptrs[1] != NULL) {
1347 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Rxmode reserved fields not zero");
1348 : : ret = -EINVAL;
1349 : 0 : goto rollback;
1350 : : }
1351 : :
1352 [ + - ]: 15 : if (dev_conf->txmode.reserved_64s[0] != 0 ||
1353 [ + - ]: 15 : dev_conf->txmode.reserved_64s[1] != 0 ||
1354 [ + - ]: 15 : dev_conf->txmode.reserved_ptrs[0] != NULL ||
1355 [ - + ]: 15 : dev_conf->txmode.reserved_ptrs[1] != NULL) {
1356 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "txmode reserved fields not zero");
1357 : : ret = -EINVAL;
1358 : 0 : goto rollback;
1359 : : }
1360 : :
1361 : 15 : ret = rte_eth_dev_info_get(port_id, &dev_info);
1362 [ - + ]: 15 : if (ret != 0)
1363 : 0 : goto rollback;
1364 : :
1365 : : /* If number of queues specified by application for both Rx and Tx is
1366 : : * zero, use driver preferred values. This cannot be done individually
1367 : : * as it is valid for either Tx or Rx (but not both) to be zero.
1368 : : * If driver does not provide any preferred valued, fall back on
1369 : : * EAL defaults.
1370 : : */
1371 [ - + ]: 15 : if (nb_rx_q == 0 && nb_tx_q == 0) {
1372 : 0 : nb_rx_q = dev_info.default_rxportconf.nb_queues;
1373 : : if (nb_rx_q == 0)
1374 : : nb_rx_q = RTE_ETH_DEV_FALLBACK_RX_NBQUEUES;
1375 : 0 : nb_tx_q = dev_info.default_txportconf.nb_queues;
1376 : : if (nb_tx_q == 0)
1377 : : nb_tx_q = RTE_ETH_DEV_FALLBACK_TX_NBQUEUES;
1378 : : }
1379 : :
1380 [ - + ]: 15 : if (nb_rx_q > RTE_MAX_QUEUES_PER_PORT) {
1381 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1382 : : "Number of Rx queues requested (%u) is greater than max supported(%d)",
1383 : : nb_rx_q, RTE_MAX_QUEUES_PER_PORT);
1384 : : ret = -EINVAL;
1385 : 0 : goto rollback;
1386 : : }
1387 : :
1388 [ - + ]: 15 : if (nb_tx_q > RTE_MAX_QUEUES_PER_PORT) {
1389 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1390 : : "Number of Tx queues requested (%u) is greater than max supported(%d)",
1391 : : nb_tx_q, RTE_MAX_QUEUES_PER_PORT);
1392 : : ret = -EINVAL;
1393 : 0 : goto rollback;
1394 : : }
1395 : :
1396 : : /*
1397 : : * Check that the numbers of Rx and Tx queues are not greater
1398 : : * than the maximum number of Rx and Tx queues supported by the
1399 : : * configured device.
1400 : : */
1401 [ - + ]: 15 : if (nb_rx_q > dev_info.max_rx_queues) {
1402 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u nb_rx_queues=%u > %u",
1403 : : port_id, nb_rx_q, dev_info.max_rx_queues);
1404 : : ret = -EINVAL;
1405 : 0 : goto rollback;
1406 : : }
1407 : :
1408 [ - + ]: 15 : if (nb_tx_q > dev_info.max_tx_queues) {
1409 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u nb_tx_queues=%u > %u",
1410 : : port_id, nb_tx_q, dev_info.max_tx_queues);
1411 : : ret = -EINVAL;
1412 : 0 : goto rollback;
1413 : : }
1414 : :
1415 : : /* Check that the device supports requested interrupts */
1416 [ - + ]: 15 : if ((dev_conf->intr_conf.lsc == 1) &&
1417 [ # # ]: 0 : (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) {
1418 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Driver %s does not support lsc",
1419 : : dev->device->driver->name);
1420 : : ret = -EINVAL;
1421 : 0 : goto rollback;
1422 : : }
1423 [ - + ]: 15 : if ((dev_conf->intr_conf.rmv == 1) &&
1424 [ # # ]: 0 : (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) {
1425 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Driver %s does not support rmv",
1426 : : dev->device->driver->name);
1427 : : ret = -EINVAL;
1428 : 0 : goto rollback;
1429 : : }
1430 : :
1431 [ + - ]: 15 : if (dev_conf->rxmode.mtu == 0)
1432 : 15 : dev->data->dev_conf.rxmode.mtu =
1433 [ + - ]: 15 : (dev_info.max_mtu == 0) ? RTE_ETHER_MTU :
1434 : 15 : RTE_MIN(dev_info.max_mtu, RTE_ETHER_MTU);
1435 : :
1436 : 15 : ret = eth_dev_validate_mtu(port_id, &dev_info,
1437 : 15 : dev->data->dev_conf.rxmode.mtu);
1438 [ - + ]: 15 : if (ret != 0)
1439 : 0 : goto rollback;
1440 : :
1441 : 15 : dev->data->mtu = dev->data->dev_conf.rxmode.mtu;
1442 : :
1443 : : /*
1444 : : * If LRO is enabled, check that the maximum aggregated packet
1445 : : * size is supported by the configured device.
1446 : : */
1447 [ - + ]: 15 : if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) {
1448 : : uint32_t max_rx_pktlen;
1449 : : uint32_t overhead_len;
1450 : :
1451 : 0 : overhead_len = eth_dev_get_overhead_len(dev_info.max_rx_pktlen,
1452 [ # # ]: 0 : dev_info.max_mtu);
1453 : 0 : max_rx_pktlen = dev->data->dev_conf.rxmode.mtu + overhead_len;
1454 [ # # ]: 0 : if (dev_conf->rxmode.max_lro_pkt_size == 0)
1455 : 0 : dev->data->dev_conf.rxmode.max_lro_pkt_size = max_rx_pktlen;
1456 : 0 : ret = eth_dev_check_lro_pkt_size(port_id,
1457 : : dev->data->dev_conf.rxmode.max_lro_pkt_size,
1458 : : max_rx_pktlen,
1459 : : dev_info.max_lro_pkt_size);
1460 [ # # ]: 0 : if (ret != 0)
1461 : 0 : goto rollback;
1462 : : }
1463 : :
1464 : : /* Any requested offloading must be within its device capabilities */
1465 [ - + ]: 15 : if ((dev_conf->rxmode.offloads & dev_info.rx_offload_capa) !=
1466 : : dev_conf->rxmode.offloads) {
1467 : : char buffer[512];
1468 : :
1469 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does not support Rx offloads %s",
1470 : : port_id, eth_dev_offload_names(
1471 : : dev_conf->rxmode.offloads & ~dev_info.rx_offload_capa,
1472 : : buffer, sizeof(buffer), rte_eth_dev_rx_offload_name));
1473 : 0 : RTE_ETHDEV_LOG_LINE(DEBUG, "Ethdev port_id=%u was requested Rx offloads %s",
1474 : : port_id, eth_dev_offload_names(dev_conf->rxmode.offloads,
1475 : : buffer, sizeof(buffer), rte_eth_dev_rx_offload_name));
1476 : 0 : RTE_ETHDEV_LOG_LINE(DEBUG, "Ethdev port_id=%u supports Rx offloads %s",
1477 : : port_id, eth_dev_offload_names(dev_info.rx_offload_capa,
1478 : : buffer, sizeof(buffer), rte_eth_dev_rx_offload_name));
1479 : :
1480 : : ret = -EINVAL;
1481 : 0 : goto rollback;
1482 : : }
1483 [ - + ]: 15 : if ((dev_conf->txmode.offloads & dev_info.tx_offload_capa) !=
1484 : : dev_conf->txmode.offloads) {
1485 : : char buffer[512];
1486 : :
1487 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port_id=%u does not support Tx offloads %s",
1488 : : port_id, eth_dev_offload_names(
1489 : : dev_conf->txmode.offloads & ~dev_info.tx_offload_capa,
1490 : : buffer, sizeof(buffer), rte_eth_dev_tx_offload_name));
1491 : 0 : RTE_ETHDEV_LOG_LINE(DEBUG, "Ethdev port_id=%u was requested Tx offloads %s",
1492 : : port_id, eth_dev_offload_names(dev_conf->txmode.offloads,
1493 : : buffer, sizeof(buffer), rte_eth_dev_tx_offload_name));
1494 : 0 : RTE_ETHDEV_LOG_LINE(DEBUG, "Ethdev port_id=%u supports Tx offloads %s",
1495 : : port_id, eth_dev_offload_names(dev_info.tx_offload_capa,
1496 : : buffer, sizeof(buffer), rte_eth_dev_tx_offload_name));
1497 : : ret = -EINVAL;
1498 : 0 : goto rollback;
1499 : : }
1500 : :
1501 : 30 : dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf =
1502 [ - + ]: 15 : rte_eth_rss_hf_refine(dev_conf->rx_adv_conf.rss_conf.rss_hf);
1503 : :
1504 : : /* Check that device supports requested rss hash functions. */
1505 : 15 : if ((dev_info.flow_type_rss_offloads |
1506 [ - + ]: 15 : dev_conf->rx_adv_conf.rss_conf.rss_hf) !=
1507 : : dev_info.flow_type_rss_offloads) {
1508 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1509 : : "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64,
1510 : : port_id, dev_conf->rx_adv_conf.rss_conf.rss_hf,
1511 : : dev_info.flow_type_rss_offloads);
1512 : : ret = -EINVAL;
1513 : 0 : goto rollback;
1514 : : }
1515 : :
1516 : : /* Check if Rx RSS distribution is disabled but RSS hash is enabled. */
1517 [ + - ]: 15 : if (((dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) == 0) &&
1518 [ - + ]: 15 : (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)) {
1519 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1520 : : "Ethdev port_id=%u config invalid Rx mq_mode without RSS but %s offload is requested",
1521 : : port_id,
1522 : : rte_eth_dev_rx_offload_name(RTE_ETH_RX_OFFLOAD_RSS_HASH));
1523 : : ret = -EINVAL;
1524 : 0 : goto rollback;
1525 : : }
1526 : :
1527 [ - + ]: 15 : if (dev_conf->rx_adv_conf.rss_conf.rss_key != NULL &&
1528 [ # # ]: 0 : dev_conf->rx_adv_conf.rss_conf.rss_key_len != dev_info.hash_key_size) {
1529 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1530 : : "Ethdev port_id=%u invalid RSS key len: %u, valid value: %u",
1531 : : port_id, dev_conf->rx_adv_conf.rss_conf.rss_key_len,
1532 : : dev_info.hash_key_size);
1533 : : ret = -EINVAL;
1534 : 0 : goto rollback;
1535 : : }
1536 : :
1537 : 15 : algorithm = dev_conf->rx_adv_conf.rss_conf.algorithm;
1538 [ + - ]: 15 : if ((size_t)algorithm >= CHAR_BIT * sizeof(dev_info.rss_algo_capa) ||
1539 [ - + ]: 15 : (dev_info.rss_algo_capa & RTE_ETH_HASH_ALGO_TO_CAPA(algorithm)) == 0) {
1540 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1541 : : "Ethdev port_id=%u configured RSS hash algorithm (%u)"
1542 : : "is not in the algorithm capability (0x%" PRIx32 ")",
1543 : : port_id, algorithm, dev_info.rss_algo_capa);
1544 : : ret = -EINVAL;
1545 : 0 : goto rollback;
1546 : : }
1547 : :
1548 : : /*
1549 : : * Setup new number of Rx/Tx queues and reconfigure device.
1550 : : */
1551 : 15 : diag = eth_dev_rx_queue_config(dev, nb_rx_q);
1552 [ - + ]: 15 : if (diag != 0) {
1553 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1554 : : "Port%u eth_dev_rx_queue_config = %d",
1555 : : port_id, diag);
1556 : : ret = diag;
1557 : 0 : goto rollback;
1558 : : }
1559 : :
1560 : 15 : diag = eth_dev_tx_queue_config(dev, nb_tx_q);
1561 [ - + ]: 15 : if (diag != 0) {
1562 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1563 : : "Port%u eth_dev_tx_queue_config = %d",
1564 : : port_id, diag);
1565 : 0 : eth_dev_rx_queue_config(dev, 0);
1566 : : ret = diag;
1567 : 0 : goto rollback;
1568 : : }
1569 : :
1570 : 15 : diag = dev->dev_ops->dev_configure(dev);
1571 [ - + ]: 15 : if (diag != 0) {
1572 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Port%u dev_configure = %d",
1573 : : port_id, diag);
1574 : 0 : ret = eth_err(port_id, diag);
1575 : 0 : goto reset_queues;
1576 : : }
1577 : :
1578 : : /* Initialize Rx profiling if enabled at compilation time. */
1579 : 15 : diag = __rte_eth_dev_profile_init(port_id, dev);
1580 [ - + ]: 15 : if (diag != 0) {
1581 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Port%u __rte_eth_dev_profile_init = %d",
1582 : : port_id, diag);
1583 : 0 : ret = eth_err(port_id, diag);
1584 : 0 : goto reset_queues;
1585 : : }
1586 : :
1587 : : /* Validate Rx offloads. */
1588 : 15 : diag = eth_dev_validate_offloads(port_id,
1589 : 15 : dev_conf->rxmode.offloads,
1590 : 15 : dev->data->dev_conf.rxmode.offloads, "Rx",
1591 : : rte_eth_dev_rx_offload_name);
1592 [ - + ]: 15 : if (diag != 0) {
1593 : : ret = diag;
1594 : 0 : goto reset_queues;
1595 : : }
1596 : :
1597 : : /* Validate Tx offloads. */
1598 : 15 : diag = eth_dev_validate_offloads(port_id,
1599 : 15 : dev_conf->txmode.offloads,
1600 : 15 : dev->data->dev_conf.txmode.offloads, "Tx",
1601 : : rte_eth_dev_tx_offload_name);
1602 [ - + ]: 15 : if (diag != 0) {
1603 : : ret = diag;
1604 : 0 : goto reset_queues;
1605 : : }
1606 : :
1607 [ - + ]: 15 : dev->data->dev_configured = 1;
1608 : 15 : rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, 0);
1609 : 15 : return 0;
1610 : 0 : reset_queues:
1611 : 0 : eth_dev_rx_queue_config(dev, 0);
1612 : 0 : eth_dev_tx_queue_config(dev, 0);
1613 : 0 : rollback:
1614 [ # # ]: 0 : memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf));
1615 [ # # ]: 0 : if (old_mtu != dev->data->mtu)
1616 : 0 : dev->data->mtu = old_mtu;
1617 : :
1618 : 0 : rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, ret);
1619 : 0 : return ret;
1620 : : }
1621 : :
1622 : : static void
1623 : 10 : eth_dev_mac_restore(struct rte_eth_dev *dev,
1624 : : struct rte_eth_dev_info *dev_info)
1625 : : {
1626 : : struct rte_ether_addr *addr;
1627 : : uint16_t i;
1628 : : uint32_t pool = 0;
1629 : : uint64_t pool_mask;
1630 : :
1631 : : /* replay MAC address configuration including default MAC */
1632 : 10 : addr = &dev->data->mac_addrs[0];
1633 [ - + ]: 10 : if (dev->dev_ops->mac_addr_set != NULL)
1634 : 0 : dev->dev_ops->mac_addr_set(dev, addr);
1635 [ + - ]: 10 : else if (dev->dev_ops->mac_addr_add != NULL)
1636 : 10 : dev->dev_ops->mac_addr_add(dev, addr, 0, pool);
1637 : :
1638 [ + - ]: 10 : if (dev->dev_ops->mac_addr_add != NULL) {
1639 [ - + ]: 10 : for (i = 1; i < dev_info->max_mac_addrs; i++) {
1640 [ # # ]: 0 : addr = &dev->data->mac_addrs[i];
1641 : :
1642 : : /* skip zero address */
1643 [ # # ]: 0 : if (rte_is_zero_ether_addr(addr))
1644 : 0 : continue;
1645 : :
1646 : : pool = 0;
1647 : 0 : pool_mask = dev->data->mac_pool_sel[i];
1648 : :
1649 : : do {
1650 [ # # ]: 0 : if (pool_mask & UINT64_C(1))
1651 : 0 : dev->dev_ops->mac_addr_add(dev, addr, i, pool);
1652 : 0 : pool_mask >>= 1;
1653 : 0 : pool++;
1654 [ # # ]: 0 : } while (pool_mask);
1655 : : }
1656 : : }
1657 : 10 : }
1658 : :
1659 : : static int
1660 : 10 : eth_dev_promiscuous_restore(struct rte_eth_dev *dev, uint16_t port_id)
1661 : : {
1662 : : int ret;
1663 : :
1664 : : /* replay promiscuous configuration */
1665 : : /*
1666 : : * use callbacks directly since we don't need port_id check and
1667 : : * would like to bypass the same value set
1668 : : */
1669 [ + - ]: 10 : if (rte_eth_promiscuous_get(port_id) == 1 &&
1670 [ + - ]: 10 : dev->dev_ops->promiscuous_enable != NULL) {
1671 : 10 : ret = eth_err(port_id, dev->dev_ops->promiscuous_enable(dev));
1672 [ - + ]: 10 : if (ret != 0 && ret != -ENOTSUP) {
1673 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1674 : : "Failed to enable promiscuous mode for device (port %u): %s",
1675 : : port_id, rte_strerror(-ret));
1676 : 0 : return ret;
1677 : : }
1678 [ # # ]: 0 : } else if (rte_eth_promiscuous_get(port_id) == 0 &&
1679 [ # # ]: 0 : dev->dev_ops->promiscuous_disable != NULL) {
1680 : 0 : ret = eth_err(port_id, dev->dev_ops->promiscuous_disable(dev));
1681 [ # # ]: 0 : if (ret != 0 && ret != -ENOTSUP) {
1682 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1683 : : "Failed to disable promiscuous mode for device (port %u): %s",
1684 : : port_id, rte_strerror(-ret));
1685 : 0 : return ret;
1686 : : }
1687 : : }
1688 : :
1689 : : return 0;
1690 : : }
1691 : :
1692 : : static int
1693 : 10 : eth_dev_allmulticast_restore(struct rte_eth_dev *dev, uint16_t port_id)
1694 : : {
1695 : : int ret;
1696 : :
1697 : : /* replay all multicast configuration */
1698 : : /*
1699 : : * use callbacks directly since we don't need port_id check and
1700 : : * would like to bypass the same value set
1701 : : */
1702 [ + - ]: 10 : if (rte_eth_allmulticast_get(port_id) == 1 &&
1703 [ + - ]: 10 : dev->dev_ops->allmulticast_enable != NULL) {
1704 : 10 : ret = eth_err(port_id, dev->dev_ops->allmulticast_enable(dev));
1705 [ - + ]: 10 : if (ret != 0 && ret != -ENOTSUP) {
1706 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1707 : : "Failed to enable allmulticast mode for device (port %u): %s",
1708 : : port_id, rte_strerror(-ret));
1709 : 0 : return ret;
1710 : : }
1711 [ # # ]: 0 : } else if (rte_eth_allmulticast_get(port_id) == 0 &&
1712 [ # # ]: 0 : dev->dev_ops->allmulticast_disable != NULL) {
1713 : 0 : ret = eth_err(port_id, dev->dev_ops->allmulticast_disable(dev));
1714 [ # # ]: 0 : if (ret != 0 && ret != -ENOTSUP) {
1715 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1716 : : "Failed to disable allmulticast mode for device (port %u): %s",
1717 : : port_id, rte_strerror(-ret));
1718 : 0 : return ret;
1719 : : }
1720 : : }
1721 : :
1722 : : return 0;
1723 : : }
1724 : :
1725 : : static int
1726 : 10 : eth_dev_config_restore(struct rte_eth_dev *dev,
1727 : : struct rte_eth_dev_info *dev_info,
1728 : : uint64_t restore_flags,
1729 : : uint16_t port_id)
1730 : : {
1731 : : int ret;
1732 : :
1733 [ + - ]: 10 : if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR) &&
1734 [ + - ]: 10 : (restore_flags & RTE_ETH_RESTORE_MAC_ADDR))
1735 : 10 : eth_dev_mac_restore(dev, dev_info);
1736 : :
1737 [ + - ]: 10 : if (restore_flags & RTE_ETH_RESTORE_PROMISC) {
1738 : 10 : ret = eth_dev_promiscuous_restore(dev, port_id);
1739 [ + - ]: 10 : if (ret != 0)
1740 : : return ret;
1741 : : }
1742 : :
1743 [ + - ]: 10 : if (restore_flags & RTE_ETH_RESTORE_ALLMULTI) {
1744 : 10 : ret = eth_dev_allmulticast_restore(dev, port_id);
1745 [ - + ]: 10 : if (ret != 0)
1746 : 0 : return ret;
1747 : : }
1748 : :
1749 : : return 0;
1750 : : }
1751 : :
1752 : : int
1753 : 10 : rte_eth_dev_start(uint16_t port_id)
1754 : : {
1755 : : struct rte_eth_dev *dev;
1756 : : struct rte_eth_dev_info dev_info;
1757 : : uint64_t restore_flags;
1758 : : int diag;
1759 : : int ret, ret_stop;
1760 : :
1761 [ - + ]: 10 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1762 : 10 : dev = &rte_eth_devices[port_id];
1763 : :
1764 [ + - ]: 10 : if (dev->dev_ops->dev_start == NULL)
1765 : : return -ENOTSUP;
1766 : :
1767 [ - + ]: 10 : if (dev->data->dev_configured == 0) {
1768 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
1769 : : "Device with port_id=%"PRIu16" is not configured.",
1770 : : port_id);
1771 : 0 : return -EINVAL;
1772 : : }
1773 : :
1774 [ - + ]: 10 : if (dev->data->dev_started != 0) {
1775 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
1776 : : "Device with port_id=%"PRIu16" already started",
1777 : : port_id);
1778 : 0 : return 0;
1779 : : }
1780 : :
1781 : 10 : ret = rte_eth_dev_info_get(port_id, &dev_info);
1782 [ + - ]: 10 : if (ret != 0)
1783 : : return ret;
1784 : :
1785 : 10 : restore_flags = rte_eth_get_restore_flags(dev, RTE_ETH_START);
1786 : :
1787 : : /* Lets restore MAC now if device does not support live change */
1788 [ - + ]: 10 : if ((*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR) &&
1789 [ # # ]: 0 : (restore_flags & RTE_ETH_RESTORE_MAC_ADDR))
1790 : 0 : eth_dev_mac_restore(dev, &dev_info);
1791 : :
1792 : 10 : diag = dev->dev_ops->dev_start(dev);
1793 [ + - ]: 10 : if (diag == 0)
1794 : 10 : dev->data->dev_started = 1;
1795 : : else
1796 : 0 : return eth_err(port_id, diag);
1797 : :
1798 : 10 : ret = eth_dev_config_restore(dev, &dev_info, restore_flags, port_id);
1799 [ - + ]: 10 : if (ret != 0) {
1800 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1801 : : "Error during restoring configuration for device (port %u): %s",
1802 : : port_id, rte_strerror(-ret));
1803 : 0 : ret_stop = rte_eth_dev_stop(port_id);
1804 [ # # ]: 0 : if (ret_stop != 0) {
1805 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1806 : : "Failed to stop device (port %u): %s",
1807 : : port_id, rte_strerror(-ret_stop));
1808 : : }
1809 : :
1810 : 0 : return ret;
1811 : : }
1812 : :
1813 [ + - ]: 10 : if (dev->data->dev_conf.intr_conf.lsc == 0) {
1814 [ + - ]: 10 : if (dev->dev_ops->link_update == NULL)
1815 : : return -ENOTSUP;
1816 : 10 : dev->dev_ops->link_update(dev, 0);
1817 : : }
1818 : :
1819 : : /* expose selection of PMD fast-path functions */
1820 : 10 : eth_dev_fp_ops_setup(rte_eth_fp_ops + port_id, dev);
1821 : :
1822 : 10 : rte_ethdev_trace_start(port_id);
1823 : 10 : return 0;
1824 : : }
1825 : :
1826 : : int
1827 : 10 : rte_eth_dev_stop(uint16_t port_id)
1828 : : {
1829 : : struct rte_eth_dev *dev;
1830 : : int ret;
1831 : :
1832 [ - + ]: 10 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1833 : 10 : dev = &rte_eth_devices[port_id];
1834 : :
1835 [ + - ]: 10 : if (dev->dev_ops->dev_stop == NULL)
1836 : : return -ENOTSUP;
1837 : :
1838 [ - + ]: 10 : if (dev->data->dev_started == 0) {
1839 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
1840 : : "Device with port_id=%"PRIu16" already stopped",
1841 : : port_id);
1842 : 0 : return 0;
1843 : : }
1844 : :
1845 : : /* point fast-path functions to dummy ones */
1846 : 10 : eth_dev_fp_ops_reset(rte_eth_fp_ops + port_id);
1847 : :
1848 : 10 : ret = dev->dev_ops->dev_stop(dev);
1849 [ + - ]: 10 : if (ret == 0)
1850 : 10 : dev->data->dev_started = 0;
1851 : 10 : rte_ethdev_trace_stop(port_id, ret);
1852 : :
1853 : 10 : return ret;
1854 : : }
1855 : :
1856 : : int
1857 : 0 : rte_eth_dev_set_link_up(uint16_t port_id)
1858 : : {
1859 : : struct rte_eth_dev *dev;
1860 : : int ret;
1861 : :
1862 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1863 : 0 : dev = &rte_eth_devices[port_id];
1864 : :
1865 [ # # ]: 0 : if (dev->dev_ops->dev_set_link_up == NULL)
1866 : : return -ENOTSUP;
1867 : 0 : ret = eth_err(port_id, dev->dev_ops->dev_set_link_up(dev));
1868 : :
1869 : 0 : rte_ethdev_trace_set_link_up(port_id, ret);
1870 : :
1871 : 0 : return ret;
1872 : : }
1873 : :
1874 : : int
1875 : 0 : rte_eth_dev_set_link_down(uint16_t port_id)
1876 : : {
1877 : : struct rte_eth_dev *dev;
1878 : : int ret;
1879 : :
1880 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1881 : 0 : dev = &rte_eth_devices[port_id];
1882 : :
1883 [ # # ]: 0 : if (dev->dev_ops->dev_set_link_down == NULL)
1884 : : return -ENOTSUP;
1885 : 0 : ret = eth_err(port_id, dev->dev_ops->dev_set_link_down(dev));
1886 : :
1887 : 0 : rte_ethdev_trace_set_link_down(port_id, ret);
1888 : :
1889 : 0 : return ret;
1890 : : }
1891 : :
1892 : : int
1893 : 0 : rte_eth_speed_lanes_get(uint16_t port_id, uint32_t *lane)
1894 : : {
1895 : : struct rte_eth_dev *dev;
1896 : :
1897 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1898 : 0 : dev = &rte_eth_devices[port_id];
1899 : :
1900 [ # # ]: 0 : if (dev->dev_ops->speed_lanes_get == NULL)
1901 : : return -ENOTSUP;
1902 : 0 : return eth_err(port_id, dev->dev_ops->speed_lanes_get(dev, lane));
1903 : : }
1904 : :
1905 : : int
1906 : 0 : rte_eth_speed_lanes_get_capability(uint16_t port_id,
1907 : : struct rte_eth_speed_lanes_capa *speed_lanes_capa,
1908 : : unsigned int num)
1909 : : {
1910 : : struct rte_eth_dev *dev;
1911 : : int ret;
1912 : :
1913 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1914 : 0 : dev = &rte_eth_devices[port_id];
1915 : :
1916 [ # # ]: 0 : if (dev->dev_ops->speed_lanes_get_capa == NULL)
1917 : : return -ENOTSUP;
1918 : :
1919 [ # # ]: 0 : if (speed_lanes_capa == NULL && num > 0) {
1920 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1921 : : "Cannot get ethdev port %u speed lanes capability to NULL when array size is non zero",
1922 : : port_id);
1923 : 0 : return -EINVAL;
1924 : : }
1925 : :
1926 : 0 : ret = dev->dev_ops->speed_lanes_get_capa(dev, speed_lanes_capa, num);
1927 : :
1928 : 0 : return ret;
1929 : : }
1930 : :
1931 : : int
1932 : 0 : rte_eth_speed_lanes_set(uint16_t port_id, uint32_t speed_lanes_capa)
1933 : : {
1934 : : struct rte_eth_dev *dev;
1935 : :
1936 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1937 : 0 : dev = &rte_eth_devices[port_id];
1938 : :
1939 [ # # ]: 0 : if (dev->dev_ops->speed_lanes_set == NULL)
1940 : : return -ENOTSUP;
1941 : 0 : return eth_err(port_id, dev->dev_ops->speed_lanes_set(dev, speed_lanes_capa));
1942 : : }
1943 : :
1944 : : int
1945 : 0 : rte_eth_dev_close(uint16_t port_id)
1946 : : {
1947 : : struct rte_eth_dev *dev;
1948 : : int firsterr, binerr;
1949 : : int *lasterr = &firsterr;
1950 : :
1951 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1952 : 0 : dev = &rte_eth_devices[port_id];
1953 : :
1954 : : /*
1955 : : * Secondary process needs to close device to release process private
1956 : : * resources. But secondary process should not be obliged to wait
1957 : : * for device stop before closing ethdev.
1958 : : */
1959 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
1960 [ # # ]: 0 : dev->data->dev_started) {
1961 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot close started device (port %u)",
1962 : : port_id);
1963 : 0 : return -EINVAL;
1964 : : }
1965 : :
1966 [ # # ]: 0 : if (dev->dev_ops->dev_close == NULL)
1967 : : return -ENOTSUP;
1968 : 0 : *lasterr = dev->dev_ops->dev_close(dev);
1969 [ # # ]: 0 : if (*lasterr != 0)
1970 : : lasterr = &binerr;
1971 : :
1972 : 0 : rte_ethdev_trace_close(port_id);
1973 : 0 : *lasterr = rte_eth_dev_release_port(dev);
1974 : :
1975 : 0 : return firsterr;
1976 : : }
1977 : :
1978 : : int
1979 : 0 : rte_eth_dev_reset(uint16_t port_id)
1980 : : {
1981 : : struct rte_eth_dev *dev;
1982 : : int ret;
1983 : :
1984 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
1985 : 0 : dev = &rte_eth_devices[port_id];
1986 : :
1987 [ # # ]: 0 : if (dev->dev_ops->dev_reset == NULL)
1988 : : return -ENOTSUP;
1989 : :
1990 : 0 : ret = rte_eth_dev_stop(port_id);
1991 [ # # ]: 0 : if (ret != 0) {
1992 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
1993 : : "Failed to stop device (port %u) before reset: %s - ignore",
1994 : : port_id, rte_strerror(-ret));
1995 : : }
1996 : 0 : ret = eth_err(port_id, dev->dev_ops->dev_reset(dev));
1997 : :
1998 : 0 : rte_ethdev_trace_reset(port_id, ret);
1999 : :
2000 : 0 : return ret;
2001 : : }
2002 : :
2003 : : int
2004 : 0 : rte_eth_dev_is_removed(uint16_t port_id)
2005 : : {
2006 : : struct rte_eth_dev *dev;
2007 : : int ret;
2008 : :
2009 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
2010 : 0 : dev = &rte_eth_devices[port_id];
2011 : :
2012 [ # # ]: 0 : if (dev->state == RTE_ETH_DEV_REMOVED)
2013 : : return 1;
2014 : :
2015 [ # # ]: 0 : if (dev->dev_ops->is_removed == NULL)
2016 : : return 0;
2017 : :
2018 : 0 : ret = dev->dev_ops->is_removed(dev);
2019 [ # # ]: 0 : if (ret != 0)
2020 : : /* Device is physically removed. */
2021 : 0 : dev->state = RTE_ETH_DEV_REMOVED;
2022 : :
2023 : 0 : rte_ethdev_trace_is_removed(port_id, ret);
2024 : :
2025 : 0 : return ret;
2026 : : }
2027 : :
2028 : : static int
2029 : 40 : rte_eth_check_rx_mempool(struct rte_mempool *mp, uint16_t offset,
2030 : : uint16_t min_length)
2031 : : {
2032 : : uint16_t data_room_size;
2033 : :
2034 : : /*
2035 : : * Check the size of the mbuf data buffer, this value
2036 : : * must be provided in the private data of the memory pool.
2037 : : * First check that the memory pool(s) has a valid private data.
2038 : : */
2039 [ - + ]: 40 : if (mp->private_data_size <
2040 : : sizeof(struct rte_pktmbuf_pool_private)) {
2041 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "%s private_data_size %u < %u",
2042 : : mp->name, mp->private_data_size,
2043 : : (unsigned int)
2044 : : sizeof(struct rte_pktmbuf_pool_private));
2045 : 0 : return -ENOSPC;
2046 : : }
2047 : : data_room_size = rte_pktmbuf_data_room_size(mp);
2048 [ - + ]: 40 : if (data_room_size < offset + min_length) {
2049 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2050 : : "%s mbuf_data_room_size %u < %u (%u + %u)",
2051 : : mp->name, data_room_size,
2052 : : offset + min_length, offset, min_length);
2053 : 0 : return -EINVAL;
2054 : : }
2055 : : return 0;
2056 : : }
2057 : :
2058 : : static int
2059 : 0 : eth_dev_buffer_split_get_supported_hdrs_helper(uint16_t port_id, uint32_t **ptypes)
2060 : : {
2061 : : int cnt;
2062 : :
2063 : 0 : cnt = rte_eth_buffer_split_get_supported_hdr_ptypes(port_id, NULL, 0);
2064 [ # # ]: 0 : if (cnt <= 0)
2065 : : return cnt;
2066 : :
2067 : 0 : *ptypes = malloc(sizeof(uint32_t) * cnt);
2068 [ # # ]: 0 : if (*ptypes == NULL)
2069 : : return -ENOMEM;
2070 : :
2071 : 0 : cnt = rte_eth_buffer_split_get_supported_hdr_ptypes(port_id, *ptypes, cnt);
2072 [ # # ]: 0 : if (cnt <= 0) {
2073 : 0 : free(*ptypes);
2074 : 0 : *ptypes = NULL;
2075 : : }
2076 : : return cnt;
2077 : : }
2078 : :
2079 : : static int
2080 : 0 : rte_eth_rx_queue_check_split(uint16_t port_id,
2081 : : const struct rte_eth_rxseg_split *rx_seg,
2082 : : uint16_t n_seg, uint32_t *mbp_buf_size,
2083 : : const struct rte_eth_dev_info *dev_info)
2084 : : {
2085 : : const struct rte_eth_rxseg_capa *seg_capa = &dev_info->rx_seg_capa;
2086 : : struct rte_mempool *mp_first;
2087 : : uint32_t offset_mask;
2088 : : uint16_t seg_idx;
2089 : : int ret = 0;
2090 : : int ptype_cnt;
2091 : : uint32_t *ptypes;
2092 : : uint32_t prev_proto_hdrs = RTE_PTYPE_UNKNOWN;
2093 : : int i;
2094 : :
2095 [ # # ]: 0 : if (n_seg > seg_capa->max_nseg) {
2096 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2097 : : "Requested Rx segments %u exceed supported %u",
2098 : : n_seg, seg_capa->max_nseg);
2099 : 0 : return -EINVAL;
2100 : : }
2101 : : /*
2102 : : * Check the sizes and offsets against buffer sizes
2103 : : * for each segment specified in extended configuration.
2104 : : */
2105 : 0 : mp_first = rx_seg[0].mp;
2106 : 0 : offset_mask = RTE_BIT32(seg_capa->offset_align_log2) - 1;
2107 : :
2108 : 0 : ptypes = NULL;
2109 : 0 : ptype_cnt = eth_dev_buffer_split_get_supported_hdrs_helper(port_id, &ptypes);
2110 : :
2111 [ # # ]: 0 : for (seg_idx = 0; seg_idx < n_seg; seg_idx++) {
2112 : 0 : struct rte_mempool *mpl = rx_seg[seg_idx].mp;
2113 : 0 : uint32_t length = rx_seg[seg_idx].length;
2114 : 0 : uint32_t offset = rx_seg[seg_idx].offset;
2115 : 0 : uint32_t proto_hdr = rx_seg[seg_idx].proto_hdr;
2116 : :
2117 [ # # ]: 0 : if (mpl == NULL) {
2118 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "null mempool pointer");
2119 : : ret = -EINVAL;
2120 : 0 : goto out;
2121 : : }
2122 [ # # ]: 0 : if (seg_idx != 0 && mp_first != mpl &&
2123 [ # # ]: 0 : seg_capa->multi_pools == 0) {
2124 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Receiving to multiple pools is not supported");
2125 : : ret = -ENOTSUP;
2126 : 0 : goto out;
2127 : : }
2128 [ # # ]: 0 : if (offset != 0) {
2129 [ # # ]: 0 : if (seg_capa->offset_allowed == 0) {
2130 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Rx segmentation with offset is not supported");
2131 : : ret = -ENOTSUP;
2132 : 0 : goto out;
2133 : : }
2134 [ # # ]: 0 : if (offset & offset_mask) {
2135 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Rx segmentation invalid offset alignment %u, %u",
2136 : : offset,
2137 : : seg_capa->offset_align_log2);
2138 : : ret = -EINVAL;
2139 : 0 : goto out;
2140 : : }
2141 : : }
2142 : :
2143 [ # # # # ]: 0 : offset += seg_idx != 0 ? 0 : RTE_PKTMBUF_HEADROOM;
2144 : 0 : *mbp_buf_size = rte_pktmbuf_data_room_size(mpl);
2145 [ # # ]: 0 : if (proto_hdr != 0) {
2146 : : /* Split based on protocol headers. */
2147 [ # # ]: 0 : if (length != 0) {
2148 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2149 : : "Do not set length split and protocol split within a segment"
2150 : : );
2151 : : ret = -EINVAL;
2152 : 0 : goto out;
2153 : : }
2154 [ # # ]: 0 : if ((proto_hdr & prev_proto_hdrs) != 0) {
2155 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2156 : : "Repeat with previous protocol headers or proto-split after length-based split"
2157 : : );
2158 : : ret = -EINVAL;
2159 : 0 : goto out;
2160 : : }
2161 [ # # ]: 0 : if (ptype_cnt <= 0) {
2162 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2163 : : "Port %u failed to get supported buffer split header protocols",
2164 : : port_id);
2165 : : ret = -ENOTSUP;
2166 : 0 : goto out;
2167 : : }
2168 [ # # ]: 0 : for (i = 0; i < ptype_cnt; i++) {
2169 [ # # ]: 0 : if ((prev_proto_hdrs | proto_hdr) == ptypes[i])
2170 : : break;
2171 : : }
2172 [ # # ]: 0 : if (i == ptype_cnt) {
2173 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2174 : : "Requested Rx split header protocols 0x%x is not supported.",
2175 : : proto_hdr);
2176 : : ret = -EINVAL;
2177 : 0 : goto out;
2178 : : }
2179 : 0 : prev_proto_hdrs |= proto_hdr;
2180 : : } else {
2181 : : /* Split at fixed length. */
2182 [ # # ]: 0 : length = length != 0 ? length : *mbp_buf_size;
2183 : : prev_proto_hdrs = RTE_PTYPE_ALL_MASK;
2184 : : }
2185 : :
2186 : 0 : ret = rte_eth_check_rx_mempool(mpl, offset, length);
2187 [ # # ]: 0 : if (ret != 0)
2188 : 0 : goto out;
2189 : : }
2190 : 0 : out:
2191 : 0 : free(ptypes);
2192 : 0 : return ret;
2193 : : }
2194 : :
2195 : : static int
2196 : 0 : rte_eth_rx_queue_check_mempools(struct rte_mempool **rx_mempools,
2197 : : uint16_t n_mempools, uint32_t *min_buf_size,
2198 : : const struct rte_eth_dev_info *dev_info)
2199 : : {
2200 : : uint16_t pool_idx;
2201 : : int ret;
2202 : :
2203 [ # # ]: 0 : if (n_mempools > dev_info->max_rx_mempools) {
2204 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2205 : : "Too many Rx mempools %u vs maximum %u",
2206 : : n_mempools, dev_info->max_rx_mempools);
2207 : 0 : return -EINVAL;
2208 : : }
2209 : :
2210 [ # # ]: 0 : for (pool_idx = 0; pool_idx < n_mempools; pool_idx++) {
2211 : 0 : struct rte_mempool *mp = rx_mempools[pool_idx];
2212 : :
2213 [ # # ]: 0 : if (mp == NULL) {
2214 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "null Rx mempool pointer");
2215 : 0 : return -EINVAL;
2216 : : }
2217 : :
2218 : 0 : ret = rte_eth_check_rx_mempool(mp, RTE_PKTMBUF_HEADROOM,
2219 : 0 : dev_info->min_rx_bufsize);
2220 [ # # ]: 0 : if (ret != 0)
2221 : 0 : return ret;
2222 : :
2223 [ # # ]: 0 : *min_buf_size = RTE_MIN(*min_buf_size,
2224 : : rte_pktmbuf_data_room_size(mp));
2225 : : }
2226 : :
2227 : : return 0;
2228 : : }
2229 : :
2230 : : int
2231 : 40 : rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
2232 : : uint16_t nb_rx_desc, unsigned int socket_id,
2233 : : const struct rte_eth_rxconf *rx_conf,
2234 : : struct rte_mempool *mp)
2235 : : {
2236 : : int ret;
2237 : : uint64_t rx_offloads;
2238 : 40 : uint32_t mbp_buf_size = UINT32_MAX;
2239 : : struct rte_eth_dev *dev;
2240 : : struct rte_eth_dev_info dev_info;
2241 : : struct rte_eth_rxconf local_conf;
2242 : : uint32_t buf_data_size;
2243 : :
2244 [ - + ]: 40 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2245 : 40 : dev = &rte_eth_devices[port_id];
2246 : :
2247 [ - + ]: 40 : if (rx_queue_id >= dev->data->nb_rx_queues) {
2248 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", rx_queue_id);
2249 : 0 : return -EINVAL;
2250 : : }
2251 : :
2252 [ + - ]: 40 : if (dev->dev_ops->rx_queue_setup == NULL)
2253 : : return -ENOTSUP;
2254 : :
2255 [ - + ]: 40 : if (rx_conf != NULL &&
2256 [ # # ]: 0 : (rx_conf->reserved_64s[0] != 0 ||
2257 [ # # ]: 0 : rx_conf->reserved_64s[1] != 0 ||
2258 [ # # ]: 0 : rx_conf->reserved_ptrs[0] != NULL ||
2259 [ # # ]: 0 : rx_conf->reserved_ptrs[1] != NULL)) {
2260 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Rx conf reserved fields not zero");
2261 : 0 : return -EINVAL;
2262 : : }
2263 : :
2264 : 40 : ret = rte_eth_dev_info_get(port_id, &dev_info);
2265 [ + - ]: 40 : if (ret != 0)
2266 : : return ret;
2267 : :
2268 : 40 : rx_offloads = dev->data->dev_conf.rxmode.offloads;
2269 [ - + ]: 40 : if (rx_conf != NULL)
2270 : 0 : rx_offloads |= rx_conf->offloads;
2271 : :
2272 : : /* Deferred start requires that device supports queue start */
2273 [ - + - - ]: 40 : if (rx_conf != NULL && rx_conf->rx_deferred_start &&
2274 [ # # ]: 0 : dev->dev_ops->rx_queue_start == NULL) {
2275 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2276 : : "Deferred start requested, but driver does not support Rx queue start");
2277 : 0 : return -ENOTSUP;
2278 : : }
2279 : :
2280 : : /* Ensure that we have one and only one source of Rx buffers */
2281 : 120 : if ((mp != NULL) +
2282 [ - + - - : 80 : (rx_conf != NULL && rx_conf->rx_nseg > 0) +
- + ]
2283 [ - + - - ]: 40 : (rx_conf != NULL && rx_conf->rx_nmempool > 0) != 1) {
2284 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2285 : : "Ambiguous Rx mempools configuration");
2286 : 0 : return -EINVAL;
2287 : : }
2288 : :
2289 [ + - ]: 40 : if (mp != NULL) {
2290 : : /* Single pool configuration check. */
2291 : 40 : ret = rte_eth_check_rx_mempool(mp, RTE_PKTMBUF_HEADROOM,
2292 : 40 : dev_info.min_rx_bufsize);
2293 [ + - ]: 40 : if (ret != 0)
2294 : : return ret;
2295 : :
2296 : 40 : mbp_buf_size = rte_pktmbuf_data_room_size(mp);
2297 : 40 : buf_data_size = mbp_buf_size - RTE_PKTMBUF_HEADROOM;
2298 [ - + ]: 40 : if (buf_data_size > dev_info.max_rx_bufsize)
2299 : 0 : RTE_ETHDEV_LOG_LINE(DEBUG,
2300 : : "For port_id=%u, the mbuf data buffer size (%u) is bigger than "
2301 : : "max buffer size (%u) device can utilize, so mbuf size can be reduced.",
2302 : : port_id, buf_data_size, dev_info.max_rx_bufsize);
2303 [ # # # # ]: 0 : } else if (rx_conf != NULL && rx_conf->rx_nseg > 0) {
2304 : : const struct rte_eth_rxseg_split *rx_seg;
2305 : : uint16_t n_seg;
2306 : :
2307 : : /* Extended multi-segment configuration check. */
2308 [ # # ]: 0 : if (rx_conf->rx_seg == NULL) {
2309 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2310 : : "Memory pool is null and no multi-segment configuration provided");
2311 : 0 : return -EINVAL;
2312 : : }
2313 : :
2314 : : rx_seg = (const struct rte_eth_rxseg_split *)rx_conf->rx_seg;
2315 : : n_seg = rx_conf->rx_nseg;
2316 : :
2317 [ # # ]: 0 : if (rx_offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
2318 : 0 : ret = rte_eth_rx_queue_check_split(port_id, rx_seg, n_seg,
2319 : : &mbp_buf_size,
2320 : : &dev_info);
2321 [ # # ]: 0 : if (ret != 0)
2322 : : return ret;
2323 : : } else {
2324 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "No Rx segmentation offload configured");
2325 : 0 : return -EINVAL;
2326 : : }
2327 [ # # # # ]: 0 : } else if (rx_conf != NULL && rx_conf->rx_nmempool > 0) {
2328 : : /* Extended multi-pool configuration check. */
2329 [ # # ]: 0 : if (rx_conf->rx_mempools == NULL) {
2330 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Memory pools array is null");
2331 : 0 : return -EINVAL;
2332 : : }
2333 : :
2334 : 0 : ret = rte_eth_rx_queue_check_mempools(rx_conf->rx_mempools,
2335 : : rx_conf->rx_nmempool,
2336 : : &mbp_buf_size,
2337 : : &dev_info);
2338 [ # # ]: 0 : if (ret != 0)
2339 : : return ret;
2340 : : } else {
2341 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Missing Rx mempool configuration");
2342 : 0 : return -EINVAL;
2343 : : }
2344 : :
2345 : : /* Use default specified by driver, if nb_rx_desc is zero */
2346 [ - + ]: 40 : if (nb_rx_desc == 0) {
2347 : 0 : nb_rx_desc = dev_info.default_rxportconf.ring_size;
2348 : : /* If driver default is also zero, fall back on EAL default */
2349 [ # # ]: 0 : if (nb_rx_desc == 0)
2350 : : nb_rx_desc = RTE_ETH_DEV_FALLBACK_RX_RINGSIZE;
2351 : : }
2352 : :
2353 [ + - ]: 40 : if (nb_rx_desc > dev_info.rx_desc_lim.nb_max ||
2354 [ + - ]: 40 : nb_rx_desc < dev_info.rx_desc_lim.nb_min ||
2355 [ - + ]: 40 : nb_rx_desc % dev_info.rx_desc_lim.nb_align != 0) {
2356 : :
2357 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2358 : : "Invalid value for nb_rx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu",
2359 : : nb_rx_desc, dev_info.rx_desc_lim.nb_max,
2360 : : dev_info.rx_desc_lim.nb_min,
2361 : : dev_info.rx_desc_lim.nb_align);
2362 : 0 : return -EINVAL;
2363 : : }
2364 : :
2365 [ - + ]: 40 : if (dev->data->dev_started &&
2366 [ # # ]: 0 : !(dev_info.dev_capa &
2367 : : RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP))
2368 : : return -EBUSY;
2369 : :
2370 [ - + ]: 40 : if (dev->data->dev_started &&
2371 [ # # ]: 0 : (dev->data->rx_queue_state[rx_queue_id] !=
2372 : : RTE_ETH_QUEUE_STATE_STOPPED))
2373 : : return -EBUSY;
2374 : :
2375 : 40 : eth_dev_rxq_release(dev, rx_queue_id);
2376 : :
2377 [ + - ]: 40 : if (rx_conf == NULL)
2378 : : rx_conf = &dev_info.default_rxconf;
2379 : :
2380 : 40 : local_conf = *rx_conf;
2381 : :
2382 : : /*
2383 : : * If an offloading has already been enabled in
2384 : : * rte_eth_dev_configure(), it has been enabled on all queues,
2385 : : * so there is no need to enable it in this queue again.
2386 : : * The local_conf.offloads input to underlying PMD only carries
2387 : : * those offloadings which are only enabled on this queue and
2388 : : * not enabled on all queues.
2389 : : */
2390 : 40 : local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads;
2391 : :
2392 : : /*
2393 : : * New added offloadings for this queue are those not enabled in
2394 : : * rte_eth_dev_configure() and they must be per-queue type.
2395 : : * A pure per-port offloading can't be enabled on a queue while
2396 : : * disabled on another queue. A pure per-port offloading can't
2397 : : * be enabled for any queue as new added one if it hasn't been
2398 : : * enabled in rte_eth_dev_configure().
2399 : : */
2400 [ - + ]: 40 : if ((local_conf.offloads & dev_info.rx_queue_offload_capa) !=
2401 : : local_conf.offloads) {
2402 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2403 : : "Ethdev port_id=%d rx_queue_id=%d, new added offloads 0x%"PRIx64" must be "
2404 : : "within per-queue offload capabilities 0x%"PRIx64" in %s()",
2405 : : port_id, rx_queue_id, local_conf.offloads,
2406 : : dev_info.rx_queue_offload_capa,
2407 : : __func__);
2408 : 0 : return -EINVAL;
2409 : : }
2410 : :
2411 [ - + ]: 40 : if (local_conf.share_group > 0 &&
2412 [ # # ]: 0 : (dev_info.dev_capa & RTE_ETH_DEV_CAPA_RXQ_SHARE) == 0) {
2413 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2414 : : "Ethdev port_id=%d rx_queue_id=%d, enabled share_group=%hu while device doesn't support Rx queue share",
2415 : : port_id, rx_queue_id, local_conf.share_group);
2416 : 0 : return -EINVAL;
2417 : : }
2418 : :
2419 : : /*
2420 : : * If LRO is enabled, check that the maximum aggregated packet
2421 : : * size is supported by the configured device.
2422 : : */
2423 : : /* Get the real Ethernet overhead length */
2424 [ - + ]: 40 : if (local_conf.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) {
2425 : : uint32_t overhead_len;
2426 : : uint32_t max_rx_pktlen;
2427 : : int ret;
2428 : :
2429 : 0 : overhead_len = eth_dev_get_overhead_len(dev_info.max_rx_pktlen,
2430 [ # # ]: 0 : dev_info.max_mtu);
2431 : 0 : max_rx_pktlen = dev->data->mtu + overhead_len;
2432 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.max_lro_pkt_size == 0)
2433 : 0 : dev->data->dev_conf.rxmode.max_lro_pkt_size = max_rx_pktlen;
2434 : 0 : ret = eth_dev_check_lro_pkt_size(port_id,
2435 : : dev->data->dev_conf.rxmode.max_lro_pkt_size,
2436 : : max_rx_pktlen,
2437 : : dev_info.max_lro_pkt_size);
2438 [ # # ]: 0 : if (ret != 0)
2439 : : return ret;
2440 : : }
2441 : :
2442 : 40 : ret = dev->dev_ops->rx_queue_setup(dev, rx_queue_id, nb_rx_desc,
2443 : : socket_id, &local_conf, mp);
2444 [ + - ]: 40 : if (!ret) {
2445 [ + + ]: 40 : if (!dev->data->min_rx_buf_size ||
2446 [ - + ]: 30 : dev->data->min_rx_buf_size > mbp_buf_size)
2447 : 10 : dev->data->min_rx_buf_size = mbp_buf_size;
2448 : : }
2449 : :
2450 : 40 : rte_ethdev_trace_rxq_setup(port_id, rx_queue_id, nb_rx_desc, mp,
2451 : : rx_conf, ret);
2452 : 40 : return eth_err(port_id, ret);
2453 : : }
2454 : :
2455 : : int
2456 : 0 : rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
2457 : : uint16_t nb_rx_desc,
2458 : : const struct rte_eth_hairpin_conf *conf)
2459 : : {
2460 : : int ret;
2461 : : struct rte_eth_dev *dev;
2462 : : struct rte_eth_hairpin_cap cap;
2463 : : int i;
2464 : : int count;
2465 : :
2466 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2467 : 0 : dev = &rte_eth_devices[port_id];
2468 : :
2469 [ # # ]: 0 : if (rx_queue_id >= dev->data->nb_rx_queues) {
2470 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", rx_queue_id);
2471 : 0 : return -EINVAL;
2472 : : }
2473 : :
2474 [ # # ]: 0 : if (conf == NULL) {
2475 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2476 : : "Cannot setup ethdev port %u Rx hairpin queue from NULL config",
2477 : : port_id);
2478 : 0 : return -EINVAL;
2479 : : }
2480 : :
2481 [ # # ]: 0 : if (conf->reserved != 0) {
2482 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2483 : : "Rx hairpin reserved field not zero");
2484 : 0 : return -EINVAL;
2485 : : }
2486 : :
2487 : 0 : ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
2488 [ # # ]: 0 : if (ret != 0)
2489 : : return ret;
2490 [ # # ]: 0 : if (dev->dev_ops->rx_hairpin_queue_setup == NULL)
2491 : : return -ENOTSUP;
2492 : : /* if nb_rx_desc is zero use max number of desc from the driver. */
2493 [ # # ]: 0 : if (nb_rx_desc == 0)
2494 : 0 : nb_rx_desc = cap.max_nb_desc;
2495 [ # # ]: 0 : if (nb_rx_desc > cap.max_nb_desc) {
2496 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2497 : : "Invalid value for nb_rx_desc(=%hu), should be: <= %hu",
2498 : : nb_rx_desc, cap.max_nb_desc);
2499 : 0 : return -EINVAL;
2500 : : }
2501 [ # # ]: 0 : if (conf->peer_count > cap.max_rx_2_tx) {
2502 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2503 : : "Invalid value for number of peers for Rx queue(=%u), should be: <= %hu",
2504 : : conf->peer_count, cap.max_rx_2_tx);
2505 : 0 : return -EINVAL;
2506 : : }
2507 [ # # # # ]: 0 : if (conf->use_locked_device_memory && !cap.rx_cap.locked_device_memory) {
2508 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2509 : : "Attempt to use locked device memory for Rx queue, which is not supported");
2510 : 0 : return -EINVAL;
2511 : : }
2512 [ # # # # ]: 0 : if (conf->use_rte_memory && !cap.rx_cap.rte_memory) {
2513 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2514 : : "Attempt to use DPDK memory for Rx queue, which is not supported");
2515 : 0 : return -EINVAL;
2516 : : }
2517 [ # # ]: 0 : if (conf->use_locked_device_memory && conf->use_rte_memory) {
2518 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2519 : : "Attempt to use mutually exclusive memory settings for Rx queue");
2520 : 0 : return -EINVAL;
2521 : : }
2522 : 0 : if (conf->force_memory &&
2523 [ # # ]: 0 : !conf->use_locked_device_memory &&
2524 : : !conf->use_rte_memory) {
2525 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2526 : : "Attempt to force Rx queue memory settings, but none is set");
2527 : 0 : return -EINVAL;
2528 : : }
2529 [ # # ]: 0 : if (conf->peer_count == 0) {
2530 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2531 : : "Invalid value for number of peers for Rx queue(=%u), should be: > 0",
2532 : : conf->peer_count);
2533 : 0 : return -EINVAL;
2534 : : }
2535 [ # # ]: 0 : for (i = 0, count = 0; i < dev->data->nb_rx_queues &&
2536 [ # # ]: 0 : cap.max_nb_queues != UINT16_MAX; i++) {
2537 [ # # # # ]: 0 : if (i == rx_queue_id || rte_eth_dev_is_rx_hairpin_queue(dev, i))
2538 : 0 : count++;
2539 : : }
2540 [ # # ]: 0 : if (count > cap.max_nb_queues) {
2541 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "To many Rx hairpin queues max is %d",
2542 : : cap.max_nb_queues);
2543 : 0 : return -EINVAL;
2544 : : }
2545 [ # # ]: 0 : if (dev->data->dev_started)
2546 : : return -EBUSY;
2547 : 0 : eth_dev_rxq_release(dev, rx_queue_id);
2548 : 0 : ret = dev->dev_ops->rx_hairpin_queue_setup(dev, rx_queue_id, nb_rx_desc, conf);
2549 [ # # ]: 0 : if (ret == 0)
2550 : 0 : dev->data->rx_queue_state[rx_queue_id] =
2551 : : RTE_ETH_QUEUE_STATE_HAIRPIN;
2552 : 0 : ret = eth_err(port_id, ret);
2553 : :
2554 : 0 : rte_eth_trace_rx_hairpin_queue_setup(port_id, rx_queue_id, nb_rx_desc,
2555 : : conf, ret);
2556 : :
2557 : 0 : return ret;
2558 : : }
2559 : :
2560 : : int
2561 : 40 : rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
2562 : : uint16_t nb_tx_desc, unsigned int socket_id,
2563 : : const struct rte_eth_txconf *tx_conf)
2564 : : {
2565 : : struct rte_eth_dev *dev;
2566 : : struct rte_eth_dev_info dev_info;
2567 : : struct rte_eth_txconf local_conf;
2568 : : int ret;
2569 : :
2570 [ - + ]: 40 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2571 : 40 : dev = &rte_eth_devices[port_id];
2572 : :
2573 [ - + ]: 40 : if (tx_queue_id >= dev->data->nb_tx_queues) {
2574 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", tx_queue_id);
2575 : 0 : return -EINVAL;
2576 : : }
2577 : :
2578 [ + - ]: 40 : if (dev->dev_ops->tx_queue_setup == NULL)
2579 : : return -ENOTSUP;
2580 : :
2581 [ - + ]: 40 : if (tx_conf != NULL &&
2582 [ # # ]: 0 : (tx_conf->reserved_64s[0] != 0 ||
2583 [ # # ]: 0 : tx_conf->reserved_64s[1] != 0 ||
2584 [ # # ]: 0 : tx_conf->reserved_ptrs[0] != NULL ||
2585 [ # # ]: 0 : tx_conf->reserved_ptrs[1] != NULL)) {
2586 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Tx conf reserved fields not zero");
2587 : 0 : return -EINVAL;
2588 : : }
2589 : :
2590 : : /* Deferred start requires that device supports queue start */
2591 [ - + - - ]: 40 : if (tx_conf != NULL && tx_conf->tx_deferred_start &&
2592 [ # # ]: 0 : dev->dev_ops->tx_queue_start == NULL) {
2593 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2594 : : "Deferred start requested, but driver does not support Tx queue start");
2595 : 0 : return -ENOTSUP;
2596 : : }
2597 : :
2598 : 40 : ret = rte_eth_dev_info_get(port_id, &dev_info);
2599 [ + - ]: 40 : if (ret != 0)
2600 : : return ret;
2601 : :
2602 : : /* Use default specified by driver, if nb_tx_desc is zero */
2603 [ - + ]: 40 : if (nb_tx_desc == 0) {
2604 : 0 : nb_tx_desc = dev_info.default_txportconf.ring_size;
2605 : : /* If driver default is zero, fall back on EAL default */
2606 [ # # ]: 0 : if (nb_tx_desc == 0)
2607 : : nb_tx_desc = RTE_ETH_DEV_FALLBACK_TX_RINGSIZE;
2608 : : }
2609 [ + - ]: 40 : if (nb_tx_desc > dev_info.tx_desc_lim.nb_max ||
2610 [ + - ]: 40 : nb_tx_desc < dev_info.tx_desc_lim.nb_min ||
2611 [ - + ]: 40 : nb_tx_desc % dev_info.tx_desc_lim.nb_align != 0) {
2612 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2613 : : "Invalid value for nb_tx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu",
2614 : : nb_tx_desc, dev_info.tx_desc_lim.nb_max,
2615 : : dev_info.tx_desc_lim.nb_min,
2616 : : dev_info.tx_desc_lim.nb_align);
2617 : 0 : return -EINVAL;
2618 : : }
2619 : :
2620 [ - + ]: 40 : if (dev->data->dev_started &&
2621 [ # # ]: 0 : !(dev_info.dev_capa &
2622 : : RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP))
2623 : : return -EBUSY;
2624 : :
2625 [ - + ]: 40 : if (dev->data->dev_started &&
2626 [ # # ]: 0 : (dev->data->tx_queue_state[tx_queue_id] !=
2627 : : RTE_ETH_QUEUE_STATE_STOPPED))
2628 : : return -EBUSY;
2629 : :
2630 : 40 : eth_dev_txq_release(dev, tx_queue_id);
2631 : :
2632 [ + - ]: 40 : if (tx_conf == NULL)
2633 : : tx_conf = &dev_info.default_txconf;
2634 : :
2635 : 40 : local_conf = *tx_conf;
2636 : :
2637 : : /*
2638 : : * If an offloading has already been enabled in
2639 : : * rte_eth_dev_configure(), it has been enabled on all queues,
2640 : : * so there is no need to enable it in this queue again.
2641 : : * The local_conf.offloads input to underlying PMD only carries
2642 : : * those offloadings which are only enabled on this queue and
2643 : : * not enabled on all queues.
2644 : : */
2645 : 40 : local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads;
2646 : :
2647 : : /*
2648 : : * New added offloadings for this queue are those not enabled in
2649 : : * rte_eth_dev_configure() and they must be per-queue type.
2650 : : * A pure per-port offloading can't be enabled on a queue while
2651 : : * disabled on another queue. A pure per-port offloading can't
2652 : : * be enabled for any queue as new added one if it hasn't been
2653 : : * enabled in rte_eth_dev_configure().
2654 : : */
2655 [ - + ]: 40 : if ((local_conf.offloads & dev_info.tx_queue_offload_capa) !=
2656 : : local_conf.offloads) {
2657 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2658 : : "Ethdev port_id=%d tx_queue_id=%d, new added offloads 0x%"PRIx64" must be "
2659 : : "within per-queue offload capabilities 0x%"PRIx64" in %s()",
2660 : : port_id, tx_queue_id, local_conf.offloads,
2661 : : dev_info.tx_queue_offload_capa,
2662 : : __func__);
2663 : 0 : return -EINVAL;
2664 : : }
2665 : :
2666 [ - + ]: 40 : rte_ethdev_trace_txq_setup(port_id, tx_queue_id, nb_tx_desc, tx_conf);
2667 : 40 : return eth_err(port_id, dev->dev_ops->tx_queue_setup(dev,
2668 : : tx_queue_id, nb_tx_desc, socket_id, &local_conf));
2669 : : }
2670 : :
2671 : : int
2672 : 0 : rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
2673 : : uint16_t nb_tx_desc,
2674 : : const struct rte_eth_hairpin_conf *conf)
2675 : : {
2676 : : struct rte_eth_dev *dev;
2677 : : struct rte_eth_hairpin_cap cap;
2678 : : int i;
2679 : : int count;
2680 : : int ret;
2681 : :
2682 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2683 : 0 : dev = &rte_eth_devices[port_id];
2684 : :
2685 [ # # ]: 0 : if (tx_queue_id >= dev->data->nb_tx_queues) {
2686 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", tx_queue_id);
2687 : 0 : return -EINVAL;
2688 : : }
2689 : :
2690 [ # # ]: 0 : if (conf == NULL) {
2691 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2692 : : "Cannot setup ethdev port %u Tx hairpin queue from NULL config",
2693 : : port_id);
2694 : 0 : return -EINVAL;
2695 : : }
2696 : :
2697 : 0 : ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
2698 [ # # ]: 0 : if (ret != 0)
2699 : : return ret;
2700 [ # # ]: 0 : if (dev->dev_ops->tx_hairpin_queue_setup == NULL)
2701 : : return -ENOTSUP;
2702 : : /* if nb_rx_desc is zero use max number of desc from the driver. */
2703 [ # # ]: 0 : if (nb_tx_desc == 0)
2704 : 0 : nb_tx_desc = cap.max_nb_desc;
2705 [ # # ]: 0 : if (nb_tx_desc > cap.max_nb_desc) {
2706 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2707 : : "Invalid value for nb_tx_desc(=%hu), should be: <= %hu",
2708 : : nb_tx_desc, cap.max_nb_desc);
2709 : 0 : return -EINVAL;
2710 : : }
2711 [ # # ]: 0 : if (conf->peer_count > cap.max_tx_2_rx) {
2712 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2713 : : "Invalid value for number of peers for Tx queue(=%u), should be: <= %hu",
2714 : : conf->peer_count, cap.max_tx_2_rx);
2715 : 0 : return -EINVAL;
2716 : : }
2717 [ # # # # ]: 0 : if (conf->use_locked_device_memory && !cap.tx_cap.locked_device_memory) {
2718 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2719 : : "Attempt to use locked device memory for Tx queue, which is not supported");
2720 : 0 : return -EINVAL;
2721 : : }
2722 [ # # # # ]: 0 : if (conf->use_rte_memory && !cap.tx_cap.rte_memory) {
2723 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2724 : : "Attempt to use DPDK memory for Tx queue, which is not supported");
2725 : 0 : return -EINVAL;
2726 : : }
2727 [ # # ]: 0 : if (conf->use_locked_device_memory && conf->use_rte_memory) {
2728 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2729 : : "Attempt to use mutually exclusive memory settings for Tx queue");
2730 : 0 : return -EINVAL;
2731 : : }
2732 : 0 : if (conf->force_memory &&
2733 [ # # ]: 0 : !conf->use_locked_device_memory &&
2734 : : !conf->use_rte_memory) {
2735 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2736 : : "Attempt to force Tx queue memory settings, but none is set");
2737 : 0 : return -EINVAL;
2738 : : }
2739 [ # # ]: 0 : if (conf->peer_count == 0) {
2740 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2741 : : "Invalid value for number of peers for Tx queue(=%u), should be: > 0",
2742 : : conf->peer_count);
2743 : 0 : return -EINVAL;
2744 : : }
2745 [ # # ]: 0 : for (i = 0, count = 0; i < dev->data->nb_tx_queues &&
2746 [ # # ]: 0 : cap.max_nb_queues != UINT16_MAX; i++) {
2747 [ # # # # ]: 0 : if (i == tx_queue_id || rte_eth_dev_is_tx_hairpin_queue(dev, i))
2748 : 0 : count++;
2749 : : }
2750 [ # # ]: 0 : if (count > cap.max_nb_queues) {
2751 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "To many Tx hairpin queues max is %d",
2752 : : cap.max_nb_queues);
2753 : 0 : return -EINVAL;
2754 : : }
2755 [ # # ]: 0 : if (dev->data->dev_started)
2756 : : return -EBUSY;
2757 : 0 : eth_dev_txq_release(dev, tx_queue_id);
2758 : 0 : ret = dev->dev_ops->tx_hairpin_queue_setup(dev, tx_queue_id, nb_tx_desc, conf);
2759 [ # # ]: 0 : if (ret == 0)
2760 : 0 : dev->data->tx_queue_state[tx_queue_id] =
2761 : : RTE_ETH_QUEUE_STATE_HAIRPIN;
2762 : 0 : ret = eth_err(port_id, ret);
2763 : :
2764 : 0 : rte_eth_trace_tx_hairpin_queue_setup(port_id, tx_queue_id, nb_tx_desc,
2765 : : conf, ret);
2766 : :
2767 : 0 : return ret;
2768 : : }
2769 : :
2770 : : int
2771 : 0 : rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port)
2772 : : {
2773 : : struct rte_eth_dev *dev;
2774 : : int ret;
2775 : :
2776 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV);
2777 : 0 : dev = &rte_eth_devices[tx_port];
2778 : :
2779 [ # # ]: 0 : if (dev->data->dev_started == 0) {
2780 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Tx port %d is not started", tx_port);
2781 : 0 : return -EBUSY;
2782 : : }
2783 : :
2784 [ # # ]: 0 : if (dev->dev_ops->hairpin_bind == NULL)
2785 : : return -ENOTSUP;
2786 : 0 : ret = dev->dev_ops->hairpin_bind(dev, rx_port);
2787 [ # # ]: 0 : if (ret != 0)
2788 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Failed to bind hairpin Tx %d"
2789 : : " to Rx %d (%d - all ports)",
2790 : : tx_port, rx_port, RTE_MAX_ETHPORTS);
2791 : :
2792 : 0 : rte_eth_trace_hairpin_bind(tx_port, rx_port, ret);
2793 : :
2794 : 0 : return ret;
2795 : : }
2796 : :
2797 : : int
2798 : 0 : rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port)
2799 : : {
2800 : : struct rte_eth_dev *dev;
2801 : : int ret;
2802 : :
2803 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV);
2804 : 0 : dev = &rte_eth_devices[tx_port];
2805 : :
2806 [ # # ]: 0 : if (dev->data->dev_started == 0) {
2807 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Tx port %d is already stopped", tx_port);
2808 : 0 : return -EBUSY;
2809 : : }
2810 : :
2811 [ # # ]: 0 : if (dev->dev_ops->hairpin_unbind == NULL)
2812 : : return -ENOTSUP;
2813 : 0 : ret = dev->dev_ops->hairpin_unbind(dev, rx_port);
2814 [ # # ]: 0 : if (ret != 0)
2815 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Failed to unbind hairpin Tx %d"
2816 : : " from Rx %d (%d - all ports)",
2817 : : tx_port, rx_port, RTE_MAX_ETHPORTS);
2818 : :
2819 : 0 : rte_eth_trace_hairpin_unbind(tx_port, rx_port, ret);
2820 : :
2821 : 0 : return ret;
2822 : : }
2823 : :
2824 : : int
2825 : 0 : rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports,
2826 : : size_t len, uint32_t direction)
2827 : : {
2828 : : struct rte_eth_dev *dev;
2829 : : int ret;
2830 : :
2831 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2832 : 0 : dev = &rte_eth_devices[port_id];
2833 : :
2834 [ # # ]: 0 : if (peer_ports == NULL) {
2835 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2836 : : "Cannot get ethdev port %u hairpin peer ports to NULL",
2837 : : port_id);
2838 : 0 : return -EINVAL;
2839 : : }
2840 : :
2841 [ # # ]: 0 : if (len == 0) {
2842 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2843 : : "Cannot get ethdev port %u hairpin peer ports to array with zero size",
2844 : : port_id);
2845 : 0 : return -EINVAL;
2846 : : }
2847 : :
2848 [ # # ]: 0 : if (dev->dev_ops->hairpin_get_peer_ports == NULL)
2849 : : return -ENOTSUP;
2850 : :
2851 : 0 : ret = dev->dev_ops->hairpin_get_peer_ports(dev, peer_ports, len, direction);
2852 [ # # ]: 0 : if (ret < 0)
2853 [ # # ]: 0 : RTE_ETHDEV_LOG_LINE(ERR, "Failed to get %d hairpin peer %s ports",
2854 : : port_id, direction ? "Rx" : "Tx");
2855 : :
2856 : 0 : rte_eth_trace_hairpin_get_peer_ports(port_id, peer_ports, len,
2857 : : direction, ret);
2858 : :
2859 : 0 : return ret;
2860 : : }
2861 : :
2862 : : void
2863 : 0 : rte_eth_tx_buffer_drop_callback(struct rte_mbuf **pkts, uint16_t unsent,
2864 : : void *userdata __rte_unused)
2865 : : {
2866 : 0 : rte_pktmbuf_free_bulk(pkts, unsent);
2867 : :
2868 : : rte_eth_trace_tx_buffer_drop_callback((void **)pkts, unsent);
2869 : 0 : }
2870 : :
2871 : : void
2872 : 0 : rte_eth_tx_buffer_count_callback(struct rte_mbuf **pkts, uint16_t unsent,
2873 : : void *userdata)
2874 : : {
2875 : : uint64_t *count = userdata;
2876 : :
2877 : 0 : rte_pktmbuf_free_bulk(pkts, unsent);
2878 : 0 : *count += unsent;
2879 : :
2880 : : rte_eth_trace_tx_buffer_count_callback((void **)pkts, unsent, *count);
2881 : 0 : }
2882 : :
2883 : : int
2884 : 108 : rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
2885 : : buffer_tx_error_fn cbfn, void *userdata)
2886 : : {
2887 [ - + ]: 108 : if (buffer == NULL) {
2888 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
2889 : : "Cannot set Tx buffer error callback to NULL buffer");
2890 : 0 : return -EINVAL;
2891 : : }
2892 : :
2893 : 108 : buffer->error_callback = cbfn;
2894 [ - + ]: 108 : buffer->error_userdata = userdata;
2895 : :
2896 : : rte_eth_trace_tx_buffer_set_err_callback(buffer);
2897 : :
2898 : : return 0;
2899 : : }
2900 : :
2901 : : int
2902 : 54 : rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size)
2903 : : {
2904 : : int ret = 0;
2905 : :
2906 [ - + ]: 54 : if (buffer == NULL) {
2907 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot initialize NULL buffer");
2908 : 0 : return -EINVAL;
2909 : : }
2910 : :
2911 : 54 : buffer->size = size;
2912 [ + - ]: 54 : if (buffer->error_callback == NULL) {
2913 : 54 : ret = rte_eth_tx_buffer_set_err_callback(
2914 : : buffer, rte_eth_tx_buffer_drop_callback, NULL);
2915 : : }
2916 : :
2917 : 54 : rte_eth_trace_tx_buffer_init(buffer, size, ret);
2918 : :
2919 : 54 : return ret;
2920 : : }
2921 : :
2922 : : int
2923 : 0 : rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
2924 : : {
2925 : : struct rte_eth_dev *dev;
2926 : : int ret;
2927 : :
2928 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2929 : : dev = &rte_eth_devices[port_id];
2930 : :
2931 : : #ifdef RTE_ETHDEV_DEBUG_TX
2932 : : ret = eth_dev_validate_tx_queue(dev, queue_id);
2933 : : if (ret != 0)
2934 : : return ret;
2935 : : #endif
2936 : :
2937 [ # # ]: 0 : if (dev->dev_ops->tx_done_cleanup == NULL)
2938 : : return -ENOTSUP;
2939 : :
2940 : : /* Call driver to free pending mbufs. */
2941 : 0 : ret = dev->dev_ops->tx_done_cleanup(dev->data->tx_queues[queue_id], free_cnt);
2942 : 0 : ret = eth_err(port_id, ret);
2943 : :
2944 : 0 : rte_eth_trace_tx_done_cleanup(port_id, queue_id, free_cnt, ret);
2945 : :
2946 : 0 : return ret;
2947 : : }
2948 : :
2949 : : int
2950 : 2 : rte_eth_promiscuous_enable(uint16_t port_id)
2951 : : {
2952 : : struct rte_eth_dev *dev;
2953 : : int diag = 0;
2954 : :
2955 [ - + ]: 2 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2956 : 2 : dev = &rte_eth_devices[port_id];
2957 : :
2958 [ - + ]: 2 : if (dev->data->promiscuous == 1)
2959 : : return 0;
2960 : :
2961 [ # # ]: 0 : if (dev->dev_ops->promiscuous_enable == NULL)
2962 : : return -ENOTSUP;
2963 : :
2964 : 0 : diag = dev->dev_ops->promiscuous_enable(dev);
2965 : 0 : dev->data->promiscuous = (diag == 0) ? 1 : 0;
2966 : :
2967 : 0 : diag = eth_err(port_id, diag);
2968 : :
2969 [ # # ]: 0 : rte_eth_trace_promiscuous_enable(port_id, dev->data->promiscuous,
2970 : : diag);
2971 : :
2972 : 0 : return diag;
2973 : : }
2974 : :
2975 : : int
2976 : 0 : rte_eth_promiscuous_disable(uint16_t port_id)
2977 : : {
2978 : : struct rte_eth_dev *dev;
2979 : : int diag = 0;
2980 : :
2981 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2982 : 0 : dev = &rte_eth_devices[port_id];
2983 : :
2984 [ # # ]: 0 : if (dev->data->promiscuous == 0)
2985 : : return 0;
2986 : :
2987 [ # # ]: 0 : if (dev->dev_ops->promiscuous_disable == NULL)
2988 : : return -ENOTSUP;
2989 : :
2990 : 0 : dev->data->promiscuous = 0;
2991 : 0 : diag = dev->dev_ops->promiscuous_disable(dev);
2992 [ # # ]: 0 : if (diag != 0)
2993 : 0 : dev->data->promiscuous = 1;
2994 : :
2995 : 0 : diag = eth_err(port_id, diag);
2996 : :
2997 [ # # ]: 0 : rte_eth_trace_promiscuous_disable(port_id, dev->data->promiscuous,
2998 : : diag);
2999 : :
3000 : 0 : return diag;
3001 : : }
3002 : :
3003 : : int
3004 : 10 : rte_eth_promiscuous_get(uint16_t port_id)
3005 : : {
3006 : : struct rte_eth_dev *dev;
3007 : :
3008 [ - + ]: 10 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3009 : : dev = &rte_eth_devices[port_id];
3010 : :
3011 [ - + ]: 10 : rte_eth_trace_promiscuous_get(port_id, dev->data->promiscuous);
3012 : :
3013 : 10 : return dev->data->promiscuous;
3014 : : }
3015 : :
3016 : : int
3017 : 0 : rte_eth_allmulticast_enable(uint16_t port_id)
3018 : : {
3019 : : struct rte_eth_dev *dev;
3020 : : int diag;
3021 : :
3022 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3023 : 0 : dev = &rte_eth_devices[port_id];
3024 : :
3025 [ # # ]: 0 : if (dev->data->all_multicast == 1)
3026 : : return 0;
3027 : :
3028 [ # # ]: 0 : if (dev->dev_ops->allmulticast_enable == NULL)
3029 : : return -ENOTSUP;
3030 : 0 : diag = dev->dev_ops->allmulticast_enable(dev);
3031 : 0 : dev->data->all_multicast = (diag == 0) ? 1 : 0;
3032 : :
3033 : 0 : diag = eth_err(port_id, diag);
3034 : :
3035 [ # # ]: 0 : rte_eth_trace_allmulticast_enable(port_id, dev->data->all_multicast,
3036 : : diag);
3037 : :
3038 : 0 : return diag;
3039 : : }
3040 : :
3041 : : int
3042 : 0 : rte_eth_allmulticast_disable(uint16_t port_id)
3043 : : {
3044 : : struct rte_eth_dev *dev;
3045 : : int diag;
3046 : :
3047 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3048 : 0 : dev = &rte_eth_devices[port_id];
3049 : :
3050 [ # # ]: 0 : if (dev->data->all_multicast == 0)
3051 : : return 0;
3052 : :
3053 [ # # ]: 0 : if (dev->dev_ops->allmulticast_disable == NULL)
3054 : : return -ENOTSUP;
3055 : 0 : dev->data->all_multicast = 0;
3056 : 0 : diag = dev->dev_ops->allmulticast_disable(dev);
3057 [ # # ]: 0 : if (diag != 0)
3058 : 0 : dev->data->all_multicast = 1;
3059 : :
3060 : 0 : diag = eth_err(port_id, diag);
3061 : :
3062 [ # # ]: 0 : rte_eth_trace_allmulticast_disable(port_id, dev->data->all_multicast,
3063 : : diag);
3064 : :
3065 : 0 : return diag;
3066 : : }
3067 : :
3068 : : int
3069 : 10 : rte_eth_allmulticast_get(uint16_t port_id)
3070 : : {
3071 : : struct rte_eth_dev *dev;
3072 : :
3073 [ - + ]: 10 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3074 : : dev = &rte_eth_devices[port_id];
3075 : :
3076 [ - + ]: 10 : rte_eth_trace_allmulticast_get(port_id, dev->data->all_multicast);
3077 : :
3078 : 10 : return dev->data->all_multicast;
3079 : : }
3080 : :
3081 : : int
3082 : 7 : rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
3083 : : {
3084 : : struct rte_eth_dev *dev;
3085 : :
3086 [ - + ]: 7 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3087 : 7 : dev = &rte_eth_devices[port_id];
3088 : :
3089 [ - + ]: 7 : if (eth_link == NULL) {
3090 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u link to NULL",
3091 : : port_id);
3092 : 0 : return -EINVAL;
3093 : : }
3094 : :
3095 [ - + - - ]: 7 : if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started)
3096 : 0 : rte_eth_linkstatus_get(dev, eth_link);
3097 : : else {
3098 [ + - ]: 7 : if (dev->dev_ops->link_update == NULL)
3099 : : return -ENOTSUP;
3100 : 7 : dev->dev_ops->link_update(dev, 1);
3101 : 7 : *eth_link = dev->data->dev_link;
3102 : : }
3103 : :
3104 : : rte_eth_trace_link_get(port_id, eth_link);
3105 : :
3106 : : return 0;
3107 : : }
3108 : :
3109 : : int
3110 : 0 : rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
3111 : : {
3112 : : struct rte_eth_dev *dev;
3113 : :
3114 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3115 : 0 : dev = &rte_eth_devices[port_id];
3116 : :
3117 [ # # ]: 0 : if (eth_link == NULL) {
3118 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u link to NULL",
3119 : : port_id);
3120 : 0 : return -EINVAL;
3121 : : }
3122 : :
3123 [ # # # # ]: 0 : if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started)
3124 : 0 : rte_eth_linkstatus_get(dev, eth_link);
3125 : : else {
3126 [ # # ]: 0 : if (dev->dev_ops->link_update == NULL)
3127 : : return -ENOTSUP;
3128 : 0 : dev->dev_ops->link_update(dev, 0);
3129 : 0 : *eth_link = dev->data->dev_link;
3130 : : }
3131 : :
3132 : 0 : rte_eth_trace_link_get_nowait(port_id, eth_link);
3133 : :
3134 : 0 : return 0;
3135 : : }
3136 : :
3137 : : const char *
3138 : 23 : rte_eth_link_speed_to_str(uint32_t link_speed)
3139 : : {
3140 : : const char *ret;
3141 : :
3142 [ + + + + : 23 : switch (link_speed) {
+ + + + +
+ + + + +
+ + + ]
3143 : : case RTE_ETH_SPEED_NUM_NONE:
3144 : : ret = "None";
3145 : : break;
3146 : 2 : case RTE_ETH_SPEED_NUM_10M:
3147 : : ret = "10 Mbps";
3148 : 2 : break;
3149 : 1 : case RTE_ETH_SPEED_NUM_100M:
3150 : : ret = "100 Mbps";
3151 : 1 : break;
3152 : 1 : case RTE_ETH_SPEED_NUM_1G:
3153 : : ret = "1 Gbps";
3154 : 1 : break;
3155 : 2 : case RTE_ETH_SPEED_NUM_2_5G:
3156 : : ret = "2.5 Gbps";
3157 : 2 : break;
3158 : 1 : case RTE_ETH_SPEED_NUM_5G:
3159 : : ret = "5 Gbps";
3160 : 1 : break;
3161 : 1 : case RTE_ETH_SPEED_NUM_10G:
3162 : : ret = "10 Gbps";
3163 : 1 : break;
3164 : 1 : case RTE_ETH_SPEED_NUM_20G:
3165 : : ret = "20 Gbps";
3166 : 1 : break;
3167 : 1 : case RTE_ETH_SPEED_NUM_25G:
3168 : : ret = "25 Gbps";
3169 : 1 : break;
3170 : 1 : case RTE_ETH_SPEED_NUM_40G:
3171 : : ret = "40 Gbps";
3172 : 1 : break;
3173 : 1 : case RTE_ETH_SPEED_NUM_50G:
3174 : : ret = "50 Gbps";
3175 : 1 : break;
3176 : 1 : case RTE_ETH_SPEED_NUM_56G:
3177 : : ret = "56 Gbps";
3178 : 1 : break;
3179 : 1 : case RTE_ETH_SPEED_NUM_100G:
3180 : : ret = "100 Gbps";
3181 : 1 : break;
3182 : 1 : case RTE_ETH_SPEED_NUM_200G:
3183 : : ret = "200 Gbps";
3184 : 1 : break;
3185 : 2 : case RTE_ETH_SPEED_NUM_400G:
3186 : : ret = "400 Gbps";
3187 : 2 : break;
3188 : 2 : case RTE_ETH_SPEED_NUM_UNKNOWN:
3189 : : ret = "Unknown";
3190 : 2 : break;
3191 : 2 : default:
3192 : : ret = "Invalid";
3193 : : }
3194 : :
3195 : : rte_eth_trace_link_speed_to_str(link_speed, ret);
3196 : :
3197 : 23 : return ret;
3198 : : }
3199 : :
3200 : : int
3201 : 7 : rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
3202 : : {
3203 : : int ret;
3204 : :
3205 [ - + ]: 7 : if (str == NULL) {
3206 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot convert link to NULL string");
3207 : 0 : return -EINVAL;
3208 : : }
3209 : :
3210 [ - + ]: 7 : if (len == 0) {
3211 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
3212 : : "Cannot convert link to string with zero size");
3213 : 0 : return -EINVAL;
3214 : : }
3215 : :
3216 [ - + ]: 7 : if (eth_link == NULL) {
3217 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot convert to string from NULL link");
3218 : 0 : return -EINVAL;
3219 : : }
3220 : :
3221 [ + + ]: 7 : if (eth_link->link_status == RTE_ETH_LINK_DOWN)
3222 : : ret = snprintf(str, len, "Link down");
3223 : : else
3224 : 18 : ret = snprintf(str, len, "Link up at %s %s %s",
3225 : 6 : rte_eth_link_speed_to_str(eth_link->link_speed),
3226 [ + + ]: 6 : (eth_link->link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ?
3227 : : "FDX" : "HDX",
3228 [ + + ]: 6 : (eth_link->link_autoneg == RTE_ETH_LINK_AUTONEG) ?
3229 : : "Autoneg" : "Fixed");
3230 : :
3231 : 7 : rte_eth_trace_link_to_str(len, eth_link, str, ret);
3232 : :
3233 : 7 : return ret;
3234 : : }
3235 : :
3236 : : int
3237 : 19 : rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
3238 : : {
3239 : : struct rte_eth_dev *dev;
3240 : : int ret;
3241 : :
3242 [ + + ]: 19 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3243 : 16 : dev = &rte_eth_devices[port_id];
3244 : :
3245 [ - + ]: 16 : if (stats == NULL) {
3246 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u stats to NULL",
3247 : : port_id);
3248 : 0 : return -EINVAL;
3249 : : }
3250 : :
3251 : : memset(stats, 0, sizeof(*stats));
3252 : :
3253 [ + - ]: 16 : if (dev->dev_ops->stats_get == NULL)
3254 : : return -ENOTSUP;
3255 : 16 : stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
3256 : 16 : ret = eth_err(port_id, dev->dev_ops->stats_get(dev, stats));
3257 : :
3258 : : rte_eth_trace_stats_get(port_id, stats, ret);
3259 : :
3260 : 16 : return ret;
3261 : : }
3262 : :
3263 : : int
3264 : 4 : rte_eth_stats_reset(uint16_t port_id)
3265 : : {
3266 : : struct rte_eth_dev *dev;
3267 : : int ret;
3268 : :
3269 [ - + ]: 4 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3270 : 4 : dev = &rte_eth_devices[port_id];
3271 : :
3272 [ + - ]: 4 : if (dev->dev_ops->stats_reset == NULL)
3273 : : return -ENOTSUP;
3274 : 4 : ret = dev->dev_ops->stats_reset(dev);
3275 [ - + ]: 4 : if (ret != 0)
3276 : 0 : return eth_err(port_id, ret);
3277 : :
3278 [ - + ]: 4 : dev->data->rx_mbuf_alloc_failed = 0;
3279 : :
3280 : 4 : rte_eth_trace_stats_reset(port_id);
3281 : :
3282 : 4 : return 0;
3283 : : }
3284 : :
3285 : : static inline int
3286 : : eth_dev_get_xstats_basic_count(struct rte_eth_dev *dev)
3287 : : {
3288 : : uint16_t nb_rxqs, nb_txqs;
3289 : : int count;
3290 : :
3291 : 0 : nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
3292 : 0 : nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
3293 : :
3294 : : count = RTE_NB_STATS;
3295 [ # # ]: 0 : if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) {
3296 : 0 : count += nb_rxqs * RTE_NB_RXQ_STATS;
3297 : 0 : count += nb_txqs * RTE_NB_TXQ_STATS;
3298 : : }
3299 : :
3300 : : return count;
3301 : : }
3302 : :
3303 : : static int
3304 : 0 : eth_dev_get_xstats_count(uint16_t port_id)
3305 : : {
3306 : : struct rte_eth_dev *dev;
3307 : : int count;
3308 : :
3309 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3310 : 0 : dev = &rte_eth_devices[port_id];
3311 [ # # ]: 0 : if (dev->dev_ops->xstats_get_names != NULL) {
3312 : 0 : count = dev->dev_ops->xstats_get_names(dev, NULL, 0);
3313 [ # # ]: 0 : if (count < 0)
3314 : 0 : return eth_err(port_id, count);
3315 : : } else
3316 : : count = 0;
3317 : :
3318 : :
3319 : 0 : count += eth_dev_get_xstats_basic_count(dev);
3320 : :
3321 : 0 : return count;
3322 : : }
3323 : :
3324 : : int
3325 : 0 : rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
3326 : : uint64_t *id)
3327 : : {
3328 : : int cnt_xstats, idx_xstat, rc;
3329 : : struct rte_eth_xstat_name *xstats_names;
3330 : :
3331 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3332 : :
3333 [ # # ]: 0 : if (xstat_name == NULL) {
3334 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
3335 : : "Cannot get ethdev port %u xstats ID from NULL xstat name",
3336 : : port_id);
3337 : 0 : return -ENOMEM;
3338 : : }
3339 : :
3340 [ # # ]: 0 : if (id == NULL) {
3341 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
3342 : : "Cannot get ethdev port %u xstats ID to NULL",
3343 : : port_id);
3344 : 0 : return -ENOMEM;
3345 : : }
3346 : :
3347 : : /* Get count */
3348 : 0 : cnt_xstats = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
3349 [ # # ]: 0 : if (cnt_xstats < 0) {
3350 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get count of xstats");
3351 : 0 : return -ENODEV;
3352 : : }
3353 : :
3354 : : /* Get id-name lookup table */
3355 : 0 : xstats_names = calloc(cnt_xstats, sizeof(xstats_names[0]));
3356 [ # # ]: 0 : if (xstats_names == NULL) {
3357 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Can't allocate memory");
3358 : 0 : return -ENOMEM;
3359 : : }
3360 : :
3361 [ # # ]: 0 : if (cnt_xstats != rte_eth_xstats_get_names_by_id(
3362 : : port_id, xstats_names, cnt_xstats, NULL)) {
3363 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get xstats lookup");
3364 : 0 : free(xstats_names);
3365 : 0 : return -1;
3366 : : }
3367 : :
3368 : : rc = -EINVAL;
3369 [ # # ]: 0 : for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) {
3370 [ # # ]: 0 : if (!strcmp(xstats_names[idx_xstat].name, xstat_name)) {
3371 [ # # ]: 0 : *id = idx_xstat;
3372 : :
3373 : 0 : rte_eth_trace_xstats_get_id_by_name(port_id,
3374 : : xstat_name, *id);
3375 : : rc = 0;
3376 : 0 : break;
3377 : : };
3378 : : }
3379 : :
3380 : 0 : free(xstats_names);
3381 : 0 : return rc;
3382 : : }
3383 : :
3384 : : /* retrieve basic stats names */
3385 : : static int
3386 : 0 : eth_basic_stats_get_names(struct rte_eth_dev *dev,
3387 : : struct rte_eth_xstat_name *xstats_names)
3388 : : {
3389 : : int cnt_used_entries = 0;
3390 : : uint32_t idx, id_queue;
3391 : : uint16_t num_q;
3392 : :
3393 [ # # ]: 0 : for (idx = 0; idx < RTE_NB_STATS; idx++) {
3394 : 0 : strlcpy(xstats_names[cnt_used_entries].name,
3395 : : eth_dev_stats_strings[idx].name,
3396 : : sizeof(xstats_names[0].name));
3397 : 0 : cnt_used_entries++;
3398 : : }
3399 : :
3400 [ # # ]: 0 : if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0)
3401 : : return cnt_used_entries;
3402 : :
3403 : 0 : num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
3404 [ # # ]: 0 : for (id_queue = 0; id_queue < num_q; id_queue++) {
3405 [ # # ]: 0 : for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) {
3406 : 0 : snprintf(xstats_names[cnt_used_entries].name,
3407 : : sizeof(xstats_names[0].name),
3408 : : "rx_q%u_%s",
3409 : 0 : id_queue, eth_dev_rxq_stats_strings[idx].name);
3410 : 0 : cnt_used_entries++;
3411 : : }
3412 : :
3413 : : }
3414 : 0 : num_q = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
3415 [ # # ]: 0 : for (id_queue = 0; id_queue < num_q; id_queue++) {
3416 [ # # ]: 0 : for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) {
3417 : 0 : snprintf(xstats_names[cnt_used_entries].name,
3418 : : sizeof(xstats_names[0].name),
3419 : : "tx_q%u_%s",
3420 : 0 : id_queue, eth_dev_txq_stats_strings[idx].name);
3421 : 0 : cnt_used_entries++;
3422 : : }
3423 : : }
3424 : : return cnt_used_entries;
3425 : : }
3426 : :
3427 : : static int
3428 : 0 : eth_xstats_get_by_name_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
3429 : : struct rte_eth_xstat_name *xstats_names, uint32_t size,
3430 : : uint32_t basic_count)
3431 : : {
3432 : : int32_t rc;
3433 : : uint32_t i, k, m, n;
3434 : : uint64_t ids_copy[ETH_XSTATS_ITER_NUM];
3435 : :
3436 : : m = 0;
3437 [ # # ]: 0 : for (n = 0; n != size; n += k) {
3438 : :
3439 : 0 : k = RTE_MIN(size - n, RTE_DIM(ids_copy));
3440 : :
3441 : : /*
3442 : : * Convert ids to xstats ids that PMD knows.
3443 : : * ids known by user are basic + extended stats.
3444 : : */
3445 [ # # ]: 0 : for (i = 0; i < k; i++)
3446 : 0 : ids_copy[i] = ids[n + i] - basic_count;
3447 : :
3448 : 0 : rc = dev->dev_ops->xstats_get_names_by_id(dev, ids_copy, xstats_names + m, k);
3449 [ # # ]: 0 : if (rc < 0)
3450 : 0 : return rc;
3451 : 0 : m += rc;
3452 : : }
3453 : :
3454 : 0 : return m;
3455 : : }
3456 : :
3457 : :
3458 : : /* retrieve ethdev extended statistics names */
3459 : : int
3460 : 0 : rte_eth_xstats_get_names_by_id(uint16_t port_id,
3461 : : struct rte_eth_xstat_name *xstats_names, unsigned int size,
3462 : : uint64_t *ids)
3463 : : {
3464 : : struct rte_eth_xstat_name *xstats_names_copy;
3465 : : unsigned int expected_entries;
3466 : : unsigned int nb_basic_stats;
3467 : : unsigned int basic_count;
3468 : : struct rte_eth_dev *dev;
3469 : : unsigned int i;
3470 : : int ret;
3471 : :
3472 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3473 [ # # ]: 0 : dev = &rte_eth_devices[port_id];
3474 : :
3475 : 0 : basic_count = eth_dev_get_xstats_basic_count(dev);
3476 : 0 : ret = eth_dev_get_xstats_count(port_id);
3477 [ # # ]: 0 : if (ret < 0)
3478 : : return ret;
3479 : 0 : expected_entries = (unsigned int)ret;
3480 : :
3481 : : /* Return max number of stats if no ids given */
3482 [ # # ]: 0 : if (!ids) {
3483 [ # # ]: 0 : if (!xstats_names)
3484 : : return expected_entries;
3485 [ # # ]: 0 : else if (xstats_names && size < expected_entries)
3486 : : return expected_entries;
3487 : : }
3488 : :
3489 [ # # ]: 0 : if (ids && !xstats_names)
3490 : : return -EINVAL;
3491 : :
3492 : : nb_basic_stats = 0;
3493 [ # # ]: 0 : if (ids != NULL) {
3494 [ # # ]: 0 : for (i = 0; i < size; i++)
3495 : 0 : nb_basic_stats += (ids[i] < basic_count);
3496 : : }
3497 : :
3498 : : /* no basic stats requested, devops function provided */
3499 [ # # # # ]: 0 : if (nb_basic_stats == 0 && ids != NULL && size != 0 &&
3500 [ # # ]: 0 : dev->dev_ops->xstats_get_names_by_id != NULL)
3501 : 0 : return eth_xstats_get_by_name_by_id(dev, ids, xstats_names,
3502 : : size, basic_count);
3503 : :
3504 : : /* Retrieve all stats */
3505 [ # # ]: 0 : if (!ids) {
3506 : 0 : int num_stats = rte_eth_xstats_get_names(port_id, xstats_names,
3507 : : expected_entries);
3508 [ # # ]: 0 : if (num_stats < 0 || num_stats > (int)expected_entries)
3509 : : return num_stats;
3510 : : else
3511 : 0 : return expected_entries;
3512 : : }
3513 : :
3514 : 0 : xstats_names_copy = calloc(expected_entries,
3515 : : sizeof(struct rte_eth_xstat_name));
3516 : :
3517 [ # # ]: 0 : if (!xstats_names_copy) {
3518 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Can't allocate memory");
3519 : 0 : return -ENOMEM;
3520 : : }
3521 : :
3522 : : /* Fill xstats_names_copy structure */
3523 [ # # ]: 0 : if (ids && nb_basic_stats == size) {
3524 : 0 : eth_basic_stats_get_names(dev, xstats_names_copy);
3525 : : } else {
3526 : 0 : ret = rte_eth_xstats_get_names(port_id, xstats_names_copy,
3527 : : expected_entries);
3528 [ # # ]: 0 : if (ret < 0) {
3529 : 0 : free(xstats_names_copy);
3530 : 0 : return ret;
3531 : : }
3532 : : }
3533 : :
3534 : : /* Filter stats */
3535 [ # # ]: 0 : for (i = 0; i < size; i++) {
3536 [ # # ]: 0 : if (ids[i] >= expected_entries) {
3537 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Id value isn't valid");
3538 : 0 : free(xstats_names_copy);
3539 : 0 : return -1;
3540 : : }
3541 [ # # ]: 0 : xstats_names[i] = xstats_names_copy[ids[i]];
3542 : :
3543 : 0 : rte_eth_trace_xstats_get_names_by_id(port_id, &xstats_names[i],
3544 : : ids[i]);
3545 : : }
3546 : :
3547 : 0 : free(xstats_names_copy);
3548 : 0 : return size;
3549 : : }
3550 : :
3551 : : int
3552 : 0 : rte_eth_xstats_get_names(uint16_t port_id,
3553 : : struct rte_eth_xstat_name *xstats_names,
3554 : : unsigned int size)
3555 : : {
3556 : : struct rte_eth_dev *dev;
3557 : : int cnt_used_entries;
3558 : : int cnt_expected_entries;
3559 : : int cnt_driver_entries;
3560 : : int i;
3561 : :
3562 : 0 : cnt_expected_entries = eth_dev_get_xstats_count(port_id);
3563 [ # # ]: 0 : if (xstats_names == NULL || cnt_expected_entries < 0 ||
3564 [ # # ]: 0 : (int)size < cnt_expected_entries)
3565 : : return cnt_expected_entries;
3566 : :
3567 : : /* port_id checked in eth_dev_get_xstats_count() */
3568 : 0 : dev = &rte_eth_devices[port_id];
3569 : :
3570 : 0 : cnt_used_entries = eth_basic_stats_get_names(dev, xstats_names);
3571 : :
3572 [ # # ]: 0 : if (dev->dev_ops->xstats_get_names != NULL) {
3573 : : /* If there are any driver-specific xstats, append them
3574 : : * to end of list.
3575 : : */
3576 : 0 : cnt_driver_entries = dev->dev_ops->xstats_get_names(
3577 : : dev,
3578 : 0 : xstats_names + cnt_used_entries,
3579 : : size - cnt_used_entries);
3580 [ # # ]: 0 : if (cnt_driver_entries < 0)
3581 : 0 : return eth_err(port_id, cnt_driver_entries);
3582 : 0 : cnt_used_entries += cnt_driver_entries;
3583 : : }
3584 : :
3585 [ # # ]: 0 : for (i = 0; i < cnt_used_entries; i++)
3586 [ # # ]: 0 : rte_eth_trace_xstats_get_names(port_id, i, &xstats_names[i],
3587 : : size, cnt_used_entries);
3588 : :
3589 : : return cnt_used_entries;
3590 : : }
3591 : :
3592 : :
3593 : : static int
3594 : 0 : eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats)
3595 : : {
3596 : : struct rte_eth_dev *dev;
3597 : : struct rte_eth_stats eth_stats;
3598 : : unsigned int count = 0, i, q;
3599 : : uint64_t val, *stats_ptr;
3600 : : uint16_t nb_rxqs, nb_txqs;
3601 : : int ret;
3602 : :
3603 : 0 : ret = rte_eth_stats_get(port_id, ð_stats);
3604 [ # # ]: 0 : if (ret < 0)
3605 : : return ret;
3606 : :
3607 : : dev = &rte_eth_devices[port_id];
3608 : :
3609 : 0 : nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
3610 : 0 : nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
3611 : :
3612 : : /* global stats */
3613 [ # # ]: 0 : for (i = 0; i < RTE_NB_STATS; i++) {
3614 : 0 : stats_ptr = RTE_PTR_ADD(ð_stats,
3615 : : eth_dev_stats_strings[i].offset);
3616 : 0 : val = *stats_ptr;
3617 : 0 : xstats[count++].value = val;
3618 : : }
3619 : :
3620 [ # # ]: 0 : if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0)
3621 : : return count;
3622 : :
3623 : : /* per-rxq stats */
3624 [ # # ]: 0 : for (q = 0; q < nb_rxqs; q++) {
3625 [ # # ]: 0 : for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
3626 : 0 : stats_ptr = RTE_PTR_ADD(ð_stats,
3627 : : eth_dev_rxq_stats_strings[i].offset +
3628 : : q * sizeof(uint64_t));
3629 : 0 : val = *stats_ptr;
3630 : 0 : xstats[count++].value = val;
3631 : : }
3632 : : }
3633 : :
3634 : : /* per-txq stats */
3635 [ # # ]: 0 : for (q = 0; q < nb_txqs; q++) {
3636 [ # # ]: 0 : for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
3637 : 0 : stats_ptr = RTE_PTR_ADD(ð_stats,
3638 : : eth_dev_txq_stats_strings[i].offset +
3639 : : q * sizeof(uint64_t));
3640 : 0 : val = *stats_ptr;
3641 : 0 : xstats[count++].value = val;
3642 : : }
3643 : : }
3644 : 0 : return count;
3645 : : }
3646 : :
3647 : : static int
3648 : 0 : eth_xtats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
3649 : : uint64_t *values, uint32_t size, uint32_t basic_count)
3650 : : {
3651 : : int32_t rc;
3652 : : uint32_t i, k, m, n;
3653 : : uint64_t ids_copy[ETH_XSTATS_ITER_NUM];
3654 : :
3655 : : m = 0;
3656 [ # # ]: 0 : for (n = 0; n != size; n += k) {
3657 : :
3658 : 0 : k = RTE_MIN(size - n, RTE_DIM(ids_copy));
3659 : :
3660 : : /*
3661 : : * Convert ids to xstats ids that PMD knows.
3662 : : * ids known by user are basic + extended stats.
3663 : : */
3664 [ # # ]: 0 : for (i = 0; i < k; i++)
3665 : 0 : ids_copy[i] = ids[n + i] - basic_count;
3666 : :
3667 : 0 : rc = dev->dev_ops->xstats_get_by_id(dev, ids_copy, values + m, k);
3668 [ # # ]: 0 : if (rc < 0)
3669 : 0 : return rc;
3670 : 0 : m += rc;
3671 : : }
3672 : :
3673 : 0 : return m;
3674 : : }
3675 : :
3676 : : /* retrieve ethdev extended statistics */
3677 : : int
3678 : 0 : rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
3679 : : uint64_t *values, unsigned int size)
3680 : : {
3681 : : unsigned int nb_basic_stats;
3682 : : unsigned int num_xstats_filled;
3683 : : unsigned int basic_count;
3684 : : uint16_t expected_entries;
3685 : : struct rte_eth_dev *dev;
3686 : : struct rte_eth_xstat *xstats;
3687 : : unsigned int i;
3688 : : int ret;
3689 : :
3690 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3691 : 0 : dev = &rte_eth_devices[port_id];
3692 : :
3693 : 0 : ret = eth_dev_get_xstats_count(port_id);
3694 [ # # ]: 0 : if (ret < 0)
3695 : : return ret;
3696 [ # # ]: 0 : expected_entries = (uint16_t)ret;
3697 : 0 : basic_count = eth_dev_get_xstats_basic_count(dev);
3698 : :
3699 : : /* Return max number of stats if no ids given */
3700 [ # # ]: 0 : if (!ids) {
3701 [ # # ]: 0 : if (!values)
3702 : 0 : return expected_entries;
3703 [ # # ]: 0 : else if (values && size < expected_entries)
3704 : : return expected_entries;
3705 : : }
3706 : :
3707 [ # # ]: 0 : if (ids && !values)
3708 : : return -EINVAL;
3709 : :
3710 : : nb_basic_stats = 0;
3711 [ # # ]: 0 : if (ids != NULL) {
3712 [ # # ]: 0 : for (i = 0; i < size; i++)
3713 : 0 : nb_basic_stats += (ids[i] < basic_count);
3714 : : }
3715 : :
3716 : : /* no basic stats requested, devops function provided */
3717 [ # # # # ]: 0 : if (nb_basic_stats == 0 && ids != NULL && size != 0 &&
3718 [ # # ]: 0 : dev->dev_ops->xstats_get_by_id != NULL)
3719 : 0 : return eth_xtats_get_by_id(dev, ids, values, size, basic_count);
3720 : :
3721 : 0 : xstats = calloc(expected_entries, sizeof(xstats[0]));
3722 [ # # ]: 0 : if (xstats == NULL) {
3723 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Can't allocate memory");
3724 : 0 : return -ENOMEM;
3725 : : }
3726 : :
3727 : : /* Fill the xstats structure */
3728 [ # # ]: 0 : if (ids && nb_basic_stats == size)
3729 : 0 : ret = eth_basic_stats_get(port_id, xstats);
3730 : : else
3731 : 0 : ret = rte_eth_xstats_get(port_id, xstats, expected_entries);
3732 : :
3733 [ # # ]: 0 : if (ret < 0) {
3734 : 0 : free(xstats);
3735 : 0 : return ret;
3736 : : }
3737 : 0 : num_xstats_filled = (unsigned int)ret;
3738 : :
3739 : : /* Return all stats */
3740 [ # # ]: 0 : if (!ids) {
3741 [ # # ]: 0 : for (i = 0; i < num_xstats_filled; i++)
3742 : 0 : values[i] = xstats[i].value;
3743 : :
3744 : 0 : free(xstats);
3745 : 0 : return expected_entries;
3746 : : }
3747 : :
3748 : : /* Filter stats */
3749 [ # # ]: 0 : for (i = 0; i < size; i++) {
3750 [ # # ]: 0 : if (ids[i] >= expected_entries) {
3751 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Id value isn't valid");
3752 : 0 : break;
3753 : : }
3754 : 0 : values[i] = xstats[ids[i]].value;
3755 : : }
3756 : :
3757 : 0 : rte_eth_trace_xstats_get_by_id(port_id, ids, values, size);
3758 : :
3759 : 0 : free(xstats);
3760 [ # # ]: 0 : return (i == size) ? (int32_t)size : -1;
3761 : : }
3762 : :
3763 : : int
3764 : 0 : rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats,
3765 : : unsigned int n)
3766 : : {
3767 : : struct rte_eth_dev *dev;
3768 : : unsigned int count, i;
3769 : : signed int xcount = 0;
3770 : : int ret;
3771 : :
3772 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3773 [ # # ]: 0 : if (xstats == NULL && n > 0)
3774 : : return -EINVAL;
3775 [ # # ]: 0 : dev = &rte_eth_devices[port_id];
3776 : :
3777 : 0 : count = eth_dev_get_xstats_basic_count(dev);
3778 : :
3779 : : /* implemented by the driver */
3780 [ # # ]: 0 : if (dev->dev_ops->xstats_get != NULL) {
3781 : : /* Retrieve the xstats from the driver at the end of the
3782 : : * xstats struct.
3783 : : */
3784 [ # # # # ]: 0 : xcount = dev->dev_ops->xstats_get(dev,
3785 : 0 : (n > count) ? xstats + count : NULL,
3786 : : (n > count) ? n - count : 0);
3787 : :
3788 [ # # ]: 0 : if (xcount < 0)
3789 : 0 : return eth_err(port_id, xcount);
3790 : : }
3791 : :
3792 [ # # # # ]: 0 : if (n < count + xcount || xstats == NULL)
3793 : 0 : return count + xcount;
3794 : :
3795 : : /* now fill the xstats structure */
3796 : 0 : ret = eth_basic_stats_get(port_id, xstats);
3797 [ # # ]: 0 : if (ret < 0)
3798 : : return ret;
3799 : 0 : count = ret;
3800 : :
3801 [ # # ]: 0 : for (i = 0; i < count; i++)
3802 : 0 : xstats[i].id = i;
3803 : : /* add an offset to driver-specific stats */
3804 [ # # ]: 0 : for ( ; i < count + xcount; i++)
3805 : 0 : xstats[i].id += count;
3806 : :
3807 [ # # ]: 0 : for (i = 0; i < n; i++)
3808 [ # # ]: 0 : rte_eth_trace_xstats_get(port_id, xstats[i]);
3809 : :
3810 : 0 : return count + xcount;
3811 : : }
3812 : :
3813 : : /* reset ethdev extended statistics */
3814 : : int
3815 : 0 : rte_eth_xstats_reset(uint16_t port_id)
3816 : : {
3817 : : struct rte_eth_dev *dev;
3818 : :
3819 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3820 : 0 : dev = &rte_eth_devices[port_id];
3821 : :
3822 : : /* implemented by the driver */
3823 [ # # ]: 0 : if (dev->dev_ops->xstats_reset != NULL) {
3824 : 0 : int ret = eth_err(port_id, dev->dev_ops->xstats_reset(dev));
3825 : :
3826 : 0 : rte_eth_trace_xstats_reset(port_id, ret);
3827 : :
3828 : 0 : return ret;
3829 : : }
3830 : :
3831 : : /* fallback to default */
3832 : 0 : return rte_eth_stats_reset(port_id);
3833 : : }
3834 : :
3835 : : int
3836 : 0 : rte_eth_xstats_set_counter(uint16_t port_id, uint64_t id, int on_off)
3837 : : {
3838 : : struct rte_eth_dev *dev;
3839 : : unsigned int basic_count;
3840 : :
3841 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3842 : :
3843 [ # # ]: 0 : dev = &rte_eth_devices[port_id];
3844 : : basic_count = eth_dev_get_xstats_basic_count(dev);
3845 [ # # ]: 0 : if (id < basic_count)
3846 : : return -EINVAL;
3847 : :
3848 [ # # ]: 0 : if (on_off == 1) {
3849 [ # # ]: 0 : if (rte_eth_xstats_query_state(port_id, id) == 1)
3850 : : return -EEXIST;
3851 [ # # ]: 0 : if (dev->dev_ops->xstats_enable != NULL)
3852 : 0 : return dev->dev_ops->xstats_enable(dev, id - basic_count);
3853 : : } else {
3854 [ # # ]: 0 : if (rte_eth_xstats_query_state(port_id, id) == 0)
3855 : : return 0;
3856 [ # # ]: 0 : if (dev->dev_ops->xstats_disable != NULL)
3857 : 0 : return dev->dev_ops->xstats_disable(dev, id - basic_count);
3858 : : }
3859 : :
3860 : : return -ENOTSUP;
3861 : : }
3862 : :
3863 : :
3864 : : int
3865 : 0 : rte_eth_xstats_query_state(uint16_t port_id, uint64_t id)
3866 : : {
3867 : : struct rte_eth_dev *dev;
3868 : : unsigned int basic_count;
3869 : :
3870 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3871 : :
3872 [ # # ]: 0 : dev = &rte_eth_devices[port_id];
3873 : : basic_count = eth_dev_get_xstats_basic_count(dev);
3874 [ # # ]: 0 : if (id < basic_count)
3875 : : return -ENOTSUP;
3876 : :
3877 : : /* implemented by the driver */
3878 [ # # ]: 0 : if (dev->dev_ops->xstats_query_state != NULL)
3879 : 0 : return dev->dev_ops->xstats_query_state(dev, id - basic_count);
3880 : :
3881 : : return -ENOTSUP;
3882 : : }
3883 : :
3884 : : static int
3885 : 0 : eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id,
3886 : : uint8_t stat_idx, uint8_t is_rx)
3887 : : {
3888 : : struct rte_eth_dev *dev;
3889 : :
3890 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3891 : 0 : dev = &rte_eth_devices[port_id];
3892 : :
3893 [ # # # # ]: 0 : if (is_rx && (queue_id >= dev->data->nb_rx_queues))
3894 : : return -EINVAL;
3895 : :
3896 [ # # # # ]: 0 : if (!is_rx && (queue_id >= dev->data->nb_tx_queues))
3897 : : return -EINVAL;
3898 : :
3899 [ # # ]: 0 : if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
3900 : : return -EINVAL;
3901 : :
3902 [ # # ]: 0 : if (dev->dev_ops->queue_stats_mapping_set == NULL)
3903 : : return -ENOTSUP;
3904 : 0 : return dev->dev_ops->queue_stats_mapping_set(dev, queue_id, stat_idx, is_rx);
3905 : : }
3906 : :
3907 : : int
3908 : 0 : rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id,
3909 : : uint8_t stat_idx)
3910 : : {
3911 : : int ret;
3912 : :
3913 : 0 : ret = eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
3914 : : tx_queue_id,
3915 : : stat_idx, STAT_QMAP_TX));
3916 : :
3917 : 0 : rte_ethdev_trace_set_tx_queue_stats_mapping(port_id, tx_queue_id,
3918 : : stat_idx, ret);
3919 : :
3920 : 0 : return ret;
3921 : : }
3922 : :
3923 : : int
3924 : 0 : rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id,
3925 : : uint8_t stat_idx)
3926 : : {
3927 : : int ret;
3928 : :
3929 : 0 : ret = eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
3930 : : rx_queue_id,
3931 : : stat_idx, STAT_QMAP_RX));
3932 : :
3933 : 0 : rte_ethdev_trace_set_rx_queue_stats_mapping(port_id, rx_queue_id,
3934 : : stat_idx, ret);
3935 : :
3936 : 0 : return ret;
3937 : : }
3938 : :
3939 : : int
3940 : 0 : rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
3941 : : {
3942 : : struct rte_eth_dev *dev;
3943 : : int ret;
3944 : :
3945 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3946 : 0 : dev = &rte_eth_devices[port_id];
3947 : :
3948 [ # # ]: 0 : if (fw_version == NULL && fw_size > 0) {
3949 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
3950 : : "Cannot get ethdev port %u FW version to NULL when string size is non zero",
3951 : : port_id);
3952 : 0 : return -EINVAL;
3953 : : }
3954 : :
3955 [ # # ]: 0 : if (dev->dev_ops->fw_version_get == NULL)
3956 : : return -ENOTSUP;
3957 : 0 : ret = eth_err(port_id, dev->dev_ops->fw_version_get(dev, fw_version, fw_size));
3958 : :
3959 : 0 : rte_ethdev_trace_fw_version_get(port_id, fw_version, fw_size, ret);
3960 : :
3961 : 0 : return ret;
3962 : : }
3963 : :
3964 : : int
3965 : 118 : rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
3966 : : {
3967 : : struct rte_eth_dev *dev;
3968 : : const struct rte_eth_desc_lim lim = {
3969 : : .nb_max = UINT16_MAX,
3970 : : .nb_min = 0,
3971 : : .nb_align = 1,
3972 : : .nb_seg_max = UINT16_MAX,
3973 : : .nb_mtu_seg_max = UINT16_MAX,
3974 : : };
3975 : : int diag;
3976 : :
3977 [ - + ]: 118 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
3978 : 118 : dev = &rte_eth_devices[port_id];
3979 : :
3980 [ - + ]: 118 : if (dev_info == NULL) {
3981 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u info to NULL",
3982 : : port_id);
3983 : 0 : return -EINVAL;
3984 : : }
3985 : :
3986 : : /*
3987 : : * Init dev_info before port_id check since caller does not have
3988 : : * return status and does not know if get is successful or not.
3989 : : */
3990 : : memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
3991 : 118 : dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
3992 : :
3993 : 118 : dev_info->rx_desc_lim = lim;
3994 : 118 : dev_info->tx_desc_lim = lim;
3995 : 118 : dev_info->device = dev->device;
3996 : 118 : dev_info->min_mtu = RTE_ETHER_MIN_LEN - RTE_ETHER_HDR_LEN -
3997 : : RTE_ETHER_CRC_LEN;
3998 : 118 : dev_info->max_mtu = UINT16_MAX;
3999 : 118 : dev_info->rss_algo_capa = RTE_ETH_HASH_ALGO_CAPA_MASK(DEFAULT);
4000 : 118 : dev_info->max_rx_bufsize = UINT32_MAX;
4001 : :
4002 [ + - ]: 118 : if (dev->dev_ops->dev_infos_get == NULL)
4003 : : return -ENOTSUP;
4004 : 118 : diag = dev->dev_ops->dev_infos_get(dev, dev_info);
4005 [ - + ]: 118 : if (diag != 0) {
4006 : : /* Cleanup already filled in device information */
4007 : : memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
4008 : 0 : return eth_err(port_id, diag);
4009 : : }
4010 : :
4011 : : /* Maximum number of queues should be <= RTE_MAX_QUEUES_PER_PORT */
4012 : 118 : dev_info->max_rx_queues = RTE_MIN(dev_info->max_rx_queues,
4013 : : RTE_MAX_QUEUES_PER_PORT);
4014 : 118 : dev_info->max_tx_queues = RTE_MIN(dev_info->max_tx_queues,
4015 : : RTE_MAX_QUEUES_PER_PORT);
4016 : :
4017 : 118 : dev_info->driver_name = dev->device->driver->name;
4018 : 118 : dev_info->nb_rx_queues = dev->data->nb_rx_queues;
4019 : 118 : dev_info->nb_tx_queues = dev->data->nb_tx_queues;
4020 : :
4021 [ - + ]: 118 : dev_info->dev_flags = &dev->data->dev_flags;
4022 : :
4023 : 118 : rte_ethdev_trace_info_get(port_id, dev_info);
4024 : :
4025 : 118 : return 0;
4026 : : }
4027 : :
4028 : : int
4029 : 0 : rte_eth_dev_conf_get(uint16_t port_id, struct rte_eth_conf *dev_conf)
4030 : : {
4031 : : struct rte_eth_dev *dev;
4032 : :
4033 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4034 : : dev = &rte_eth_devices[port_id];
4035 : :
4036 [ # # ]: 0 : if (dev_conf == NULL) {
4037 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4038 : : "Cannot get ethdev port %u configuration to NULL",
4039 : : port_id);
4040 : 0 : return -EINVAL;
4041 : : }
4042 : :
4043 [ # # ]: 0 : memcpy(dev_conf, &dev->data->dev_conf, sizeof(struct rte_eth_conf));
4044 : :
4045 : 0 : rte_ethdev_trace_conf_get(port_id, dev_conf);
4046 : :
4047 : 0 : return 0;
4048 : : }
4049 : :
4050 : : int
4051 : 0 : rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
4052 : : uint32_t *ptypes, int num)
4053 : : {
4054 : : size_t i;
4055 : : int j;
4056 : : struct rte_eth_dev *dev;
4057 : : const uint32_t *all_ptypes;
4058 : 0 : size_t no_of_elements = 0;
4059 : :
4060 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4061 : 0 : dev = &rte_eth_devices[port_id];
4062 : :
4063 [ # # ]: 0 : if (ptypes == NULL && num > 0) {
4064 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4065 : : "Cannot get ethdev port %u supported packet types to NULL when array size is non zero",
4066 : : port_id);
4067 : 0 : return -EINVAL;
4068 : : }
4069 : :
4070 [ # # ]: 0 : if (dev->dev_ops->dev_supported_ptypes_get == NULL)
4071 : : return 0;
4072 : 0 : all_ptypes = dev->dev_ops->dev_supported_ptypes_get(dev, &no_of_elements);
4073 : :
4074 [ # # ]: 0 : if (!all_ptypes)
4075 : : return 0;
4076 : :
4077 [ # # ]: 0 : for (i = 0, j = 0; i < no_of_elements; ++i)
4078 [ # # ]: 0 : if (all_ptypes[i] & ptype_mask) {
4079 [ # # ]: 0 : if (j < num) {
4080 [ # # ]: 0 : ptypes[j] = all_ptypes[i];
4081 : :
4082 : 0 : rte_ethdev_trace_get_supported_ptypes(port_id,
4083 : : j, num, ptypes[j]);
4084 : : }
4085 : 0 : j++;
4086 : : }
4087 : :
4088 : : return j;
4089 : : }
4090 : :
4091 : : int
4092 : 0 : rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
4093 : : uint32_t *set_ptypes, unsigned int num)
4094 : : {
4095 : 0 : const uint32_t valid_ptype_masks[] = {
4096 : : RTE_PTYPE_L2_MASK,
4097 : : RTE_PTYPE_L3_MASK,
4098 : : RTE_PTYPE_L4_MASK,
4099 : : RTE_PTYPE_TUNNEL_MASK,
4100 : : RTE_PTYPE_INNER_L2_MASK,
4101 : : RTE_PTYPE_INNER_L3_MASK,
4102 : : RTE_PTYPE_INNER_L4_MASK,
4103 : : };
4104 : : const uint32_t *all_ptypes;
4105 : : struct rte_eth_dev *dev;
4106 : : uint32_t unused_mask;
4107 : : size_t i;
4108 : : unsigned int j;
4109 : : int ret;
4110 : 0 : size_t no_of_elements = 0;
4111 : :
4112 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4113 : 0 : dev = &rte_eth_devices[port_id];
4114 : :
4115 [ # # ]: 0 : if (num > 0 && set_ptypes == NULL) {
4116 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4117 : : "Cannot get ethdev port %u set packet types to NULL when array size is non zero",
4118 : : port_id);
4119 : 0 : return -EINVAL;
4120 : : }
4121 : :
4122 [ # # ]: 0 : if (dev->dev_ops->dev_supported_ptypes_get == NULL ||
4123 [ # # ]: 0 : dev->dev_ops->dev_ptypes_set == NULL) {
4124 : : ret = 0;
4125 : 0 : goto ptype_unknown;
4126 : : }
4127 : :
4128 [ # # ]: 0 : if (ptype_mask == 0) {
4129 : 0 : ret = dev->dev_ops->dev_ptypes_set(dev, ptype_mask);
4130 : 0 : goto ptype_unknown;
4131 : : }
4132 : :
4133 : : unused_mask = ptype_mask;
4134 [ # # ]: 0 : for (i = 0; i < RTE_DIM(valid_ptype_masks); i++) {
4135 : 0 : uint32_t mask = ptype_mask & valid_ptype_masks[i];
4136 [ # # # # ]: 0 : if (mask && mask != valid_ptype_masks[i]) {
4137 : : ret = -EINVAL;
4138 : 0 : goto ptype_unknown;
4139 : : }
4140 : 0 : unused_mask &= ~valid_ptype_masks[i];
4141 : : }
4142 : :
4143 [ # # ]: 0 : if (unused_mask) {
4144 : : ret = -EINVAL;
4145 : 0 : goto ptype_unknown;
4146 : : }
4147 : :
4148 : 0 : all_ptypes = dev->dev_ops->dev_supported_ptypes_get(dev, &no_of_elements);
4149 [ # # ]: 0 : if (all_ptypes == NULL) {
4150 : : ret = 0;
4151 : 0 : goto ptype_unknown;
4152 : : }
4153 : :
4154 : : /*
4155 : : * Accommodate as many set_ptypes as possible. If the supplied
4156 : : * set_ptypes array is insufficient fill it partially.
4157 : : */
4158 [ # # ]: 0 : for (i = 0, j = 0; set_ptypes != NULL &&
4159 [ # # ]: 0 : (i < no_of_elements); ++i) {
4160 [ # # ]: 0 : if (ptype_mask & all_ptypes[i]) {
4161 [ # # ]: 0 : if (j < num - 1) {
4162 : 0 : set_ptypes[j] = all_ptypes[i];
4163 : :
4164 [ # # ]: 0 : rte_ethdev_trace_set_ptypes(port_id, j, num,
4165 : : set_ptypes[j]);
4166 : :
4167 : 0 : j++;
4168 : 0 : continue;
4169 : : }
4170 : : break;
4171 : : }
4172 : : }
4173 : :
4174 [ # # ]: 0 : if (set_ptypes != NULL && j < num)
4175 : 0 : set_ptypes[j] = RTE_PTYPE_UNKNOWN;
4176 : :
4177 : 0 : return dev->dev_ops->dev_ptypes_set(dev, ptype_mask);
4178 : :
4179 : 0 : ptype_unknown:
4180 [ # # ]: 0 : if (num > 0)
4181 : 0 : set_ptypes[0] = RTE_PTYPE_UNKNOWN;
4182 : :
4183 : : return ret;
4184 : : }
4185 : :
4186 : : int
4187 : 0 : rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr *ma,
4188 : : unsigned int num)
4189 : : {
4190 : : int32_t ret;
4191 : : struct rte_eth_dev *dev;
4192 : : struct rte_eth_dev_info dev_info;
4193 : :
4194 [ # # ]: 0 : if (ma == NULL) {
4195 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "%s: invalid parameters", __func__);
4196 : 0 : return -EINVAL;
4197 : : }
4198 : :
4199 : : /* will check for us that port_id is a valid one */
4200 : 0 : ret = rte_eth_dev_info_get(port_id, &dev_info);
4201 [ # # ]: 0 : if (ret != 0)
4202 : : return ret;
4203 : :
4204 : : dev = &rte_eth_devices[port_id];
4205 : 0 : num = RTE_MIN(dev_info.max_mac_addrs, num);
4206 [ # # ]: 0 : memcpy(ma, dev->data->mac_addrs, num * sizeof(ma[0]));
4207 : :
4208 : 0 : rte_eth_trace_macaddrs_get(port_id, num);
4209 : :
4210 : 0 : return num;
4211 : : }
4212 : :
4213 : : int
4214 : 6 : rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
4215 : : {
4216 : : struct rte_eth_dev *dev;
4217 : :
4218 [ - + ]: 6 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4219 : : dev = &rte_eth_devices[port_id];
4220 : :
4221 [ - + ]: 6 : if (mac_addr == NULL) {
4222 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4223 : : "Cannot get ethdev port %u MAC address to NULL",
4224 : : port_id);
4225 : 0 : return -EINVAL;
4226 : : }
4227 : :
4228 : 6 : rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
4229 : :
4230 : : rte_eth_trace_macaddr_get(port_id, mac_addr);
4231 : :
4232 : 6 : return 0;
4233 : : }
4234 : :
4235 : : int
4236 : 0 : rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
4237 : : {
4238 : : struct rte_eth_dev *dev;
4239 : :
4240 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4241 : : dev = &rte_eth_devices[port_id];
4242 : :
4243 [ # # ]: 0 : if (mtu == NULL) {
4244 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u MTU to NULL",
4245 : : port_id);
4246 : 0 : return -EINVAL;
4247 : : }
4248 : :
4249 : 0 : *mtu = dev->data->mtu;
4250 : :
4251 : : rte_ethdev_trace_get_mtu(port_id, *mtu);
4252 : :
4253 : 0 : return 0;
4254 : : }
4255 : :
4256 : : int
4257 : 0 : rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu)
4258 : : {
4259 : : int ret;
4260 : : struct rte_eth_dev_info dev_info;
4261 : : struct rte_eth_dev *dev;
4262 : :
4263 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4264 : 0 : dev = &rte_eth_devices[port_id];
4265 [ # # ]: 0 : if (dev->dev_ops->mtu_set == NULL)
4266 : : return -ENOTSUP;
4267 : :
4268 : : /*
4269 : : * Check if the device supports dev_infos_get, if it does not
4270 : : * skip min_mtu/max_mtu validation here as this requires values
4271 : : * that are populated within the call to rte_eth_dev_info_get()
4272 : : * which relies on dev->dev_ops->dev_infos_get.
4273 : : */
4274 [ # # ]: 0 : if (dev->dev_ops->dev_infos_get != NULL) {
4275 : 0 : ret = rte_eth_dev_info_get(port_id, &dev_info);
4276 [ # # ]: 0 : if (ret != 0)
4277 : : return ret;
4278 : :
4279 : 0 : ret = eth_dev_validate_mtu(port_id, &dev_info, mtu);
4280 [ # # ]: 0 : if (ret != 0)
4281 : : return ret;
4282 : : }
4283 : :
4284 [ # # ]: 0 : if (dev->data->dev_configured == 0) {
4285 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4286 : : "Port %u must be configured before MTU set",
4287 : : port_id);
4288 : 0 : return -EINVAL;
4289 : : }
4290 : :
4291 : 0 : ret = dev->dev_ops->mtu_set(dev, mtu);
4292 [ # # ]: 0 : if (ret == 0)
4293 : 0 : dev->data->mtu = mtu;
4294 : :
4295 : 0 : ret = eth_err(port_id, ret);
4296 : :
4297 : 0 : rte_ethdev_trace_set_mtu(port_id, mtu, ret);
4298 : :
4299 : 0 : return ret;
4300 : : }
4301 : :
4302 : : int
4303 : 0 : rte_eth_dev_vlan_filter(uint16_t port_id, uint16_t vlan_id, int on)
4304 : : {
4305 : : struct rte_eth_dev *dev;
4306 : : int ret;
4307 : :
4308 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4309 : 0 : dev = &rte_eth_devices[port_id];
4310 : :
4311 [ # # ]: 0 : if (!(dev->data->dev_conf.rxmode.offloads &
4312 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER)) {
4313 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Port %u: VLAN-filtering disabled",
4314 : : port_id);
4315 : 0 : return -ENOSYS;
4316 : : }
4317 : :
4318 [ # # ]: 0 : if (vlan_id > 4095) {
4319 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Port_id=%u invalid vlan_id=%u > 4095",
4320 : : port_id, vlan_id);
4321 : 0 : return -EINVAL;
4322 : : }
4323 [ # # ]: 0 : if (dev->dev_ops->vlan_filter_set == NULL)
4324 : : return -ENOTSUP;
4325 : :
4326 : 0 : ret = dev->dev_ops->vlan_filter_set(dev, vlan_id, on);
4327 [ # # ]: 0 : if (ret == 0) {
4328 : : struct rte_vlan_filter_conf *vfc;
4329 : : int vidx;
4330 : : int vbit;
4331 : :
4332 : 0 : vfc = &dev->data->vlan_filter_conf;
4333 : 0 : vidx = vlan_id / 64;
4334 : 0 : vbit = vlan_id % 64;
4335 : :
4336 [ # # ]: 0 : if (on)
4337 : 0 : vfc->ids[vidx] |= RTE_BIT64(vbit);
4338 : : else
4339 : 0 : vfc->ids[vidx] &= ~RTE_BIT64(vbit);
4340 : : }
4341 : :
4342 : 0 : ret = eth_err(port_id, ret);
4343 : :
4344 : 0 : rte_ethdev_trace_vlan_filter(port_id, vlan_id, on, ret);
4345 : :
4346 : 0 : return ret;
4347 : : }
4348 : :
4349 : : int
4350 : 0 : rte_eth_dev_set_vlan_strip_on_queue(uint16_t port_id, uint16_t rx_queue_id,
4351 : : int on)
4352 : : {
4353 : : struct rte_eth_dev *dev;
4354 : :
4355 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4356 : 0 : dev = &rte_eth_devices[port_id];
4357 : :
4358 [ # # ]: 0 : if (rx_queue_id >= dev->data->nb_rx_queues) {
4359 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid rx_queue_id=%u", rx_queue_id);
4360 : 0 : return -EINVAL;
4361 : : }
4362 : :
4363 [ # # ]: 0 : if (dev->dev_ops->vlan_strip_queue_set == NULL)
4364 : : return -ENOTSUP;
4365 : 0 : dev->dev_ops->vlan_strip_queue_set(dev, rx_queue_id, on);
4366 : :
4367 : 0 : rte_ethdev_trace_set_vlan_strip_on_queue(port_id, rx_queue_id, on);
4368 : :
4369 : 0 : return 0;
4370 : : }
4371 : :
4372 : : int
4373 : 0 : rte_eth_dev_set_vlan_ether_type(uint16_t port_id,
4374 : : enum rte_vlan_type vlan_type,
4375 : : uint16_t tpid)
4376 : : {
4377 : : struct rte_eth_dev *dev;
4378 : : int ret;
4379 : :
4380 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4381 : 0 : dev = &rte_eth_devices[port_id];
4382 : :
4383 [ # # ]: 0 : if (dev->dev_ops->vlan_tpid_set == NULL)
4384 : : return -ENOTSUP;
4385 : 0 : ret = eth_err(port_id, dev->dev_ops->vlan_tpid_set(dev, vlan_type, tpid));
4386 : :
4387 : 0 : rte_ethdev_trace_set_vlan_ether_type(port_id, vlan_type, tpid, ret);
4388 : :
4389 : 0 : return ret;
4390 : : }
4391 : :
4392 : : int
4393 : 0 : rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask)
4394 : : {
4395 : : struct rte_eth_dev_info dev_info;
4396 : : struct rte_eth_dev *dev;
4397 : : int ret = 0;
4398 : : int mask = 0;
4399 : : int cur, org = 0;
4400 : : uint64_t orig_offloads;
4401 : : uint64_t dev_offloads;
4402 : : uint64_t new_offloads;
4403 : :
4404 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4405 : 0 : dev = &rte_eth_devices[port_id];
4406 : :
4407 : : /* save original values in case of failure */
4408 : 0 : orig_offloads = dev->data->dev_conf.rxmode.offloads;
4409 : : dev_offloads = orig_offloads;
4410 : :
4411 : : /* check which option changed by application */
4412 : 0 : cur = !!(offload_mask & RTE_ETH_VLAN_STRIP_OFFLOAD);
4413 : 0 : org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP);
4414 [ # # ]: 0 : if (cur != org) {
4415 [ # # ]: 0 : if (cur)
4416 : 0 : dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
4417 : : else
4418 : 0 : dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
4419 : : mask |= RTE_ETH_VLAN_STRIP_MASK;
4420 : : }
4421 : :
4422 : 0 : cur = !!(offload_mask & RTE_ETH_VLAN_FILTER_OFFLOAD);
4423 : 0 : org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER);
4424 [ # # ]: 0 : if (cur != org) {
4425 [ # # ]: 0 : if (cur)
4426 : 0 : dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
4427 : : else
4428 : 0 : dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
4429 : 0 : mask |= RTE_ETH_VLAN_FILTER_MASK;
4430 : : }
4431 : :
4432 : 0 : cur = !!(offload_mask & RTE_ETH_VLAN_EXTEND_OFFLOAD);
4433 : 0 : org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND);
4434 [ # # ]: 0 : if (cur != org) {
4435 [ # # ]: 0 : if (cur)
4436 : 0 : dev_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
4437 : : else
4438 : 0 : dev_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
4439 : 0 : mask |= RTE_ETH_VLAN_EXTEND_MASK;
4440 : : }
4441 : :
4442 : 0 : cur = !!(offload_mask & RTE_ETH_QINQ_STRIP_OFFLOAD);
4443 : 0 : org = !!(dev_offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP);
4444 [ # # ]: 0 : if (cur != org) {
4445 [ # # ]: 0 : if (cur)
4446 : 0 : dev_offloads |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
4447 : : else
4448 : 0 : dev_offloads &= ~RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
4449 : 0 : mask |= RTE_ETH_QINQ_STRIP_MASK;
4450 : : }
4451 : :
4452 : : /*no change*/
4453 [ # # ]: 0 : if (mask == 0)
4454 : : return ret;
4455 : :
4456 : 0 : ret = rte_eth_dev_info_get(port_id, &dev_info);
4457 [ # # ]: 0 : if (ret != 0)
4458 : : return ret;
4459 : :
4460 : : /* Rx VLAN offloading must be within its device capabilities */
4461 [ # # ]: 0 : if ((dev_offloads & dev_info.rx_offload_capa) != dev_offloads) {
4462 : 0 : new_offloads = dev_offloads & ~orig_offloads;
4463 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4464 : : "Ethdev port_id=%u requested new added VLAN offloads "
4465 : : "0x%" PRIx64 " must be within Rx offloads capabilities "
4466 : : "0x%" PRIx64 " in %s()",
4467 : : port_id, new_offloads, dev_info.rx_offload_capa,
4468 : : __func__);
4469 : 0 : return -EINVAL;
4470 : : }
4471 : :
4472 [ # # ]: 0 : if (dev->dev_ops->vlan_offload_set == NULL)
4473 : : return -ENOTSUP;
4474 : 0 : dev->data->dev_conf.rxmode.offloads = dev_offloads;
4475 : 0 : ret = dev->dev_ops->vlan_offload_set(dev, mask);
4476 [ # # ]: 0 : if (ret) {
4477 : : /* hit an error restore original values */
4478 : 0 : dev->data->dev_conf.rxmode.offloads = orig_offloads;
4479 : : }
4480 : :
4481 : 0 : ret = eth_err(port_id, ret);
4482 : :
4483 : 0 : rte_ethdev_trace_set_vlan_offload(port_id, offload_mask, ret);
4484 : :
4485 : 0 : return ret;
4486 : : }
4487 : :
4488 : : int
4489 : 0 : rte_eth_dev_get_vlan_offload(uint16_t port_id)
4490 : : {
4491 : : struct rte_eth_dev *dev;
4492 : : uint64_t *dev_offloads;
4493 : : int ret = 0;
4494 : :
4495 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4496 : : dev = &rte_eth_devices[port_id];
4497 : 0 : dev_offloads = &dev->data->dev_conf.rxmode.offloads;
4498 : :
4499 [ # # ]: 0 : if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
4500 : : ret |= RTE_ETH_VLAN_STRIP_OFFLOAD;
4501 : :
4502 [ # # ]: 0 : if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER)
4503 : 0 : ret |= RTE_ETH_VLAN_FILTER_OFFLOAD;
4504 : :
4505 [ # # ]: 0 : if (*dev_offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)
4506 : 0 : ret |= RTE_ETH_VLAN_EXTEND_OFFLOAD;
4507 : :
4508 [ # # ]: 0 : if (*dev_offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP)
4509 : 0 : ret |= RTE_ETH_QINQ_STRIP_OFFLOAD;
4510 : :
4511 : 0 : rte_ethdev_trace_get_vlan_offload(port_id, ret);
4512 : :
4513 : 0 : return ret;
4514 : : }
4515 : :
4516 : : int
4517 : 0 : rte_eth_dev_set_vlan_pvid(uint16_t port_id, uint16_t pvid, int on)
4518 : : {
4519 : : struct rte_eth_dev *dev;
4520 : : int ret;
4521 : :
4522 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4523 : 0 : dev = &rte_eth_devices[port_id];
4524 : :
4525 [ # # ]: 0 : if (dev->dev_ops->vlan_pvid_set == NULL)
4526 : : return -ENOTSUP;
4527 : 0 : ret = eth_err(port_id, dev->dev_ops->vlan_pvid_set(dev, pvid, on));
4528 : :
4529 : 0 : rte_ethdev_trace_set_vlan_pvid(port_id, pvid, on, ret);
4530 : :
4531 : 0 : return ret;
4532 : : }
4533 : :
4534 : : int
4535 : 0 : rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
4536 : : {
4537 : : struct rte_eth_dev *dev;
4538 : : int ret;
4539 : :
4540 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4541 : 0 : dev = &rte_eth_devices[port_id];
4542 : :
4543 [ # # ]: 0 : if (fc_conf == NULL) {
4544 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4545 : : "Cannot get ethdev port %u flow control config to NULL",
4546 : : port_id);
4547 : 0 : return -EINVAL;
4548 : : }
4549 : :
4550 [ # # ]: 0 : if (dev->dev_ops->flow_ctrl_get == NULL)
4551 : : return -ENOTSUP;
4552 : : memset(fc_conf, 0, sizeof(*fc_conf));
4553 : 0 : ret = eth_err(port_id, dev->dev_ops->flow_ctrl_get(dev, fc_conf));
4554 : :
4555 : 0 : rte_ethdev_trace_flow_ctrl_get(port_id, fc_conf, ret);
4556 : :
4557 : 0 : return ret;
4558 : : }
4559 : :
4560 : : int
4561 : 0 : rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
4562 : : {
4563 : : struct rte_eth_dev *dev;
4564 : : int ret;
4565 : :
4566 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4567 : 0 : dev = &rte_eth_devices[port_id];
4568 : :
4569 [ # # ]: 0 : if (fc_conf == NULL) {
4570 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4571 : : "Cannot set ethdev port %u flow control from NULL config",
4572 : : port_id);
4573 : 0 : return -EINVAL;
4574 : : }
4575 : :
4576 [ # # ]: 0 : if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
4577 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid send_xon, only 0/1 allowed");
4578 : 0 : return -EINVAL;
4579 : : }
4580 : :
4581 [ # # ]: 0 : if (dev->dev_ops->flow_ctrl_set == NULL)
4582 : : return -ENOTSUP;
4583 : 0 : ret = eth_err(port_id, dev->dev_ops->flow_ctrl_set(dev, fc_conf));
4584 : :
4585 : 0 : rte_ethdev_trace_flow_ctrl_set(port_id, fc_conf, ret);
4586 : :
4587 : 0 : return ret;
4588 : : }
4589 : :
4590 : : int
4591 : 0 : rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
4592 : : struct rte_eth_pfc_conf *pfc_conf)
4593 : : {
4594 : : struct rte_eth_dev *dev;
4595 : : int ret;
4596 : :
4597 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4598 : 0 : dev = &rte_eth_devices[port_id];
4599 : :
4600 [ # # ]: 0 : if (pfc_conf == NULL) {
4601 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4602 : : "Cannot set ethdev port %u priority flow control from NULL config",
4603 : : port_id);
4604 : 0 : return -EINVAL;
4605 : : }
4606 : :
4607 [ # # ]: 0 : if (pfc_conf->priority > (RTE_ETH_DCB_NUM_USER_PRIORITIES - 1)) {
4608 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid priority, only 0-7 allowed");
4609 : 0 : return -EINVAL;
4610 : : }
4611 : :
4612 : : /* High water, low water validation are device specific */
4613 [ # # ]: 0 : if (dev->dev_ops->priority_flow_ctrl_set == NULL)
4614 : : return -ENOTSUP;
4615 : 0 : ret = eth_err(port_id, dev->dev_ops->priority_flow_ctrl_set(dev, pfc_conf));
4616 : :
4617 : 0 : rte_ethdev_trace_priority_flow_ctrl_set(port_id, pfc_conf, ret);
4618 : :
4619 : 0 : return ret;
4620 : : }
4621 : :
4622 : : static int
4623 : 0 : validate_rx_pause_config(struct rte_eth_dev_info *dev_info, uint8_t tc_max,
4624 : : struct rte_eth_pfc_queue_conf *pfc_queue_conf)
4625 : : {
4626 [ # # ]: 0 : if ((pfc_queue_conf->mode == RTE_ETH_FC_RX_PAUSE) ||
4627 : : (pfc_queue_conf->mode == RTE_ETH_FC_FULL)) {
4628 [ # # ]: 0 : if (pfc_queue_conf->rx_pause.tx_qid >= dev_info->nb_tx_queues) {
4629 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4630 : : "PFC Tx queue not in range for Rx pause requested:%d configured:%d",
4631 : : pfc_queue_conf->rx_pause.tx_qid,
4632 : : dev_info->nb_tx_queues);
4633 : 0 : return -EINVAL;
4634 : : }
4635 : :
4636 [ # # ]: 0 : if (pfc_queue_conf->rx_pause.tc >= tc_max) {
4637 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4638 : : "PFC TC not in range for Rx pause requested:%d max:%d",
4639 : : pfc_queue_conf->rx_pause.tc, tc_max);
4640 : 0 : return -EINVAL;
4641 : : }
4642 : : }
4643 : :
4644 : : return 0;
4645 : : }
4646 : :
4647 : : static int
4648 : 0 : validate_tx_pause_config(struct rte_eth_dev_info *dev_info, uint8_t tc_max,
4649 : : struct rte_eth_pfc_queue_conf *pfc_queue_conf)
4650 : : {
4651 [ # # ]: 0 : if ((pfc_queue_conf->mode == RTE_ETH_FC_TX_PAUSE) ||
4652 : : (pfc_queue_conf->mode == RTE_ETH_FC_FULL)) {
4653 [ # # ]: 0 : if (pfc_queue_conf->tx_pause.rx_qid >= dev_info->nb_rx_queues) {
4654 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4655 : : "PFC Rx queue not in range for Tx pause requested:%d configured:%d",
4656 : : pfc_queue_conf->tx_pause.rx_qid,
4657 : : dev_info->nb_rx_queues);
4658 : 0 : return -EINVAL;
4659 : : }
4660 : :
4661 [ # # ]: 0 : if (pfc_queue_conf->tx_pause.tc >= tc_max) {
4662 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4663 : : "PFC TC not in range for Tx pause requested:%d max:%d",
4664 : : pfc_queue_conf->tx_pause.tc, tc_max);
4665 : 0 : return -EINVAL;
4666 : : }
4667 : : }
4668 : :
4669 : : return 0;
4670 : : }
4671 : :
4672 : : int
4673 : 0 : rte_eth_dev_priority_flow_ctrl_queue_info_get(uint16_t port_id,
4674 : : struct rte_eth_pfc_queue_info *pfc_queue_info)
4675 : : {
4676 : : struct rte_eth_dev *dev;
4677 : : int ret;
4678 : :
4679 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4680 : 0 : dev = &rte_eth_devices[port_id];
4681 : :
4682 [ # # ]: 0 : if (pfc_queue_info == NULL) {
4683 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "PFC info param is NULL for port (%u)",
4684 : : port_id);
4685 : 0 : return -EINVAL;
4686 : : }
4687 : :
4688 [ # # ]: 0 : if (dev->dev_ops->priority_flow_ctrl_queue_info_get == NULL)
4689 : : return -ENOTSUP;
4690 : 0 : ret = eth_err(port_id,
4691 : : dev->dev_ops->priority_flow_ctrl_queue_info_get(dev, pfc_queue_info));
4692 : :
4693 : 0 : rte_ethdev_trace_priority_flow_ctrl_queue_info_get(port_id,
4694 : : pfc_queue_info, ret);
4695 : :
4696 : 0 : return ret;
4697 : : }
4698 : :
4699 : : int
4700 : 0 : rte_eth_dev_priority_flow_ctrl_queue_configure(uint16_t port_id,
4701 : : struct rte_eth_pfc_queue_conf *pfc_queue_conf)
4702 : : {
4703 : : struct rte_eth_pfc_queue_info pfc_info;
4704 : : struct rte_eth_dev_info dev_info;
4705 : : struct rte_eth_dev *dev;
4706 : : int ret;
4707 : :
4708 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4709 : 0 : dev = &rte_eth_devices[port_id];
4710 : :
4711 [ # # ]: 0 : if (pfc_queue_conf == NULL) {
4712 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "PFC parameters are NULL for port (%u)",
4713 : : port_id);
4714 : 0 : return -EINVAL;
4715 : : }
4716 : :
4717 : 0 : ret = rte_eth_dev_info_get(port_id, &dev_info);
4718 [ # # ]: 0 : if (ret != 0)
4719 : : return ret;
4720 : :
4721 : 0 : ret = rte_eth_dev_priority_flow_ctrl_queue_info_get(port_id, &pfc_info);
4722 [ # # ]: 0 : if (ret != 0)
4723 : : return ret;
4724 : :
4725 [ # # ]: 0 : if (pfc_info.tc_max == 0) {
4726 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Ethdev port %u does not support PFC TC values",
4727 : : port_id);
4728 : 0 : return -ENOTSUP;
4729 : : }
4730 : :
4731 : : /* Check requested mode supported or not */
4732 [ # # ]: 0 : if (pfc_info.mode_capa == RTE_ETH_FC_RX_PAUSE &&
4733 [ # # ]: 0 : pfc_queue_conf->mode == RTE_ETH_FC_TX_PAUSE) {
4734 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "PFC Tx pause unsupported for port (%d)",
4735 : : port_id);
4736 : 0 : return -EINVAL;
4737 : : }
4738 : :
4739 [ # # ]: 0 : if (pfc_info.mode_capa == RTE_ETH_FC_TX_PAUSE &&
4740 [ # # ]: 0 : pfc_queue_conf->mode == RTE_ETH_FC_RX_PAUSE) {
4741 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "PFC Rx pause unsupported for port (%d)",
4742 : : port_id);
4743 : 0 : return -EINVAL;
4744 : : }
4745 : :
4746 : : /* Validate Rx pause parameters */
4747 [ # # ]: 0 : if (pfc_info.mode_capa == RTE_ETH_FC_FULL ||
4748 : : pfc_info.mode_capa == RTE_ETH_FC_RX_PAUSE) {
4749 : 0 : ret = validate_rx_pause_config(&dev_info, pfc_info.tc_max,
4750 : : pfc_queue_conf);
4751 [ # # ]: 0 : if (ret != 0)
4752 : : return ret;
4753 : : }
4754 : :
4755 : : /* Validate Tx pause parameters */
4756 [ # # ]: 0 : if (pfc_info.mode_capa == RTE_ETH_FC_FULL ||
4757 : : pfc_info.mode_capa == RTE_ETH_FC_TX_PAUSE) {
4758 : 0 : ret = validate_tx_pause_config(&dev_info, pfc_info.tc_max,
4759 : : pfc_queue_conf);
4760 [ # # ]: 0 : if (ret != 0)
4761 : : return ret;
4762 : : }
4763 : :
4764 [ # # ]: 0 : if (dev->dev_ops->priority_flow_ctrl_queue_config == NULL)
4765 : : return -ENOTSUP;
4766 : 0 : ret = eth_err(port_id, dev->dev_ops->priority_flow_ctrl_queue_config(dev, pfc_queue_conf));
4767 : :
4768 : 0 : rte_ethdev_trace_priority_flow_ctrl_queue_configure(port_id,
4769 : : pfc_queue_conf, ret);
4770 : :
4771 : 0 : return ret;
4772 : : }
4773 : :
4774 : : static int
4775 : : eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
4776 : : uint16_t reta_size)
4777 : : {
4778 : : uint16_t i, num;
4779 : :
4780 : 0 : num = (reta_size + RTE_ETH_RETA_GROUP_SIZE - 1) / RTE_ETH_RETA_GROUP_SIZE;
4781 [ # # # # ]: 0 : for (i = 0; i < num; i++) {
4782 [ # # # # ]: 0 : if (reta_conf[i].mask)
4783 : : return 0;
4784 : : }
4785 : :
4786 : : return -EINVAL;
4787 : : }
4788 : :
4789 : : static int
4790 : 0 : eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
4791 : : uint16_t reta_size,
4792 : : uint16_t max_rxq)
4793 : : {
4794 : : uint16_t i, idx, shift;
4795 : :
4796 [ # # ]: 0 : if (max_rxq == 0) {
4797 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "No receive queue is available");
4798 : 0 : return -EINVAL;
4799 : : }
4800 : :
4801 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
4802 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
4803 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
4804 [ # # ]: 0 : if ((reta_conf[idx].mask & RTE_BIT64(shift)) &&
4805 [ # # ]: 0 : (reta_conf[idx].reta[shift] >= max_rxq)) {
4806 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4807 : : "reta_conf[%u]->reta[%u]: %u exceeds the maximum rxq index: %u",
4808 : : idx, shift,
4809 : : reta_conf[idx].reta[shift], max_rxq);
4810 : 0 : return -EINVAL;
4811 : : }
4812 : : }
4813 : :
4814 : : return 0;
4815 : : }
4816 : :
4817 : : int
4818 : 0 : rte_eth_dev_rss_reta_update(uint16_t port_id,
4819 : : struct rte_eth_rss_reta_entry64 *reta_conf,
4820 : : uint16_t reta_size)
4821 : : {
4822 : : enum rte_eth_rx_mq_mode mq_mode;
4823 : : struct rte_eth_dev *dev;
4824 : : int ret;
4825 : :
4826 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4827 : 0 : dev = &rte_eth_devices[port_id];
4828 : :
4829 [ # # ]: 0 : if (reta_conf == NULL) {
4830 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4831 : : "Cannot update ethdev port %u RSS RETA to NULL",
4832 : : port_id);
4833 : 0 : return -EINVAL;
4834 : : }
4835 : :
4836 [ # # ]: 0 : if (reta_size == 0) {
4837 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4838 : : "Cannot update ethdev port %u RSS RETA with zero size",
4839 : : port_id);
4840 : 0 : return -EINVAL;
4841 : : }
4842 : :
4843 : : /* Check mask bits */
4844 : 0 : ret = eth_check_reta_mask(reta_conf, reta_size);
4845 [ # # ]: 0 : if (ret < 0)
4846 : : return ret;
4847 : :
4848 : : /* Check entry value */
4849 : 0 : ret = eth_check_reta_entry(reta_conf, reta_size,
4850 : 0 : dev->data->nb_rx_queues);
4851 [ # # ]: 0 : if (ret < 0)
4852 : : return ret;
4853 : :
4854 : 0 : mq_mode = dev->data->dev_conf.rxmode.mq_mode;
4855 [ # # ]: 0 : if (!(mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)) {
4856 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Multi-queue RSS mode isn't enabled.");
4857 : 0 : return -ENOTSUP;
4858 : : }
4859 : :
4860 [ # # ]: 0 : if (dev->dev_ops->reta_update == NULL)
4861 : : return -ENOTSUP;
4862 : 0 : ret = eth_err(port_id, dev->dev_ops->reta_update(dev, reta_conf, reta_size));
4863 : :
4864 : 0 : rte_ethdev_trace_rss_reta_update(port_id, reta_conf, reta_size, ret);
4865 : :
4866 : 0 : return ret;
4867 : : }
4868 : :
4869 : : int
4870 : 0 : rte_eth_dev_rss_reta_query(uint16_t port_id,
4871 : : struct rte_eth_rss_reta_entry64 *reta_conf,
4872 : : uint16_t reta_size)
4873 : : {
4874 : : struct rte_eth_dev *dev;
4875 : : int ret;
4876 : :
4877 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4878 : 0 : dev = &rte_eth_devices[port_id];
4879 : :
4880 [ # # ]: 0 : if (reta_conf == NULL) {
4881 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4882 : : "Cannot query ethdev port %u RSS RETA from NULL config",
4883 : : port_id);
4884 : 0 : return -EINVAL;
4885 : : }
4886 : :
4887 : : /* Check mask bits */
4888 : 0 : ret = eth_check_reta_mask(reta_conf, reta_size);
4889 [ # # ]: 0 : if (ret < 0)
4890 : : return ret;
4891 : :
4892 [ # # ]: 0 : if (dev->dev_ops->reta_query == NULL)
4893 : : return -ENOTSUP;
4894 : 0 : ret = eth_err(port_id, dev->dev_ops->reta_query(dev, reta_conf, reta_size));
4895 : :
4896 : 0 : rte_ethdev_trace_rss_reta_query(port_id, reta_conf, reta_size, ret);
4897 : :
4898 : 0 : return ret;
4899 : : }
4900 : :
4901 : : int
4902 : 0 : rte_eth_dev_rss_hash_update(uint16_t port_id,
4903 : : struct rte_eth_rss_conf *rss_conf)
4904 : : {
4905 : : struct rte_eth_dev *dev;
4906 : 0 : struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
4907 : : enum rte_eth_rx_mq_mode mq_mode;
4908 : : int ret;
4909 : :
4910 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4911 : 0 : dev = &rte_eth_devices[port_id];
4912 : :
4913 [ # # ]: 0 : if (rss_conf == NULL) {
4914 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4915 : : "Cannot update ethdev port %u RSS hash from NULL config",
4916 : : port_id);
4917 : 0 : return -EINVAL;
4918 : : }
4919 : :
4920 : 0 : ret = rte_eth_dev_info_get(port_id, &dev_info);
4921 [ # # ]: 0 : if (ret != 0)
4922 : : return ret;
4923 : :
4924 [ # # ]: 0 : rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf);
4925 [ # # ]: 0 : if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
4926 : : dev_info.flow_type_rss_offloads) {
4927 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4928 : : "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64,
4929 : : port_id, rss_conf->rss_hf,
4930 : : dev_info.flow_type_rss_offloads);
4931 : 0 : return -EINVAL;
4932 : : }
4933 : :
4934 : 0 : mq_mode = dev->data->dev_conf.rxmode.mq_mode;
4935 [ # # ]: 0 : if (!(mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)) {
4936 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Multi-queue RSS mode isn't enabled.");
4937 : 0 : return -ENOTSUP;
4938 : : }
4939 : :
4940 [ # # ]: 0 : if (rss_conf->rss_key != NULL &&
4941 [ # # ]: 0 : rss_conf->rss_key_len != dev_info.hash_key_size) {
4942 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4943 : : "Ethdev port_id=%u invalid RSS key len: %u, valid value: %u",
4944 : : port_id, rss_conf->rss_key_len, dev_info.hash_key_size);
4945 : 0 : return -EINVAL;
4946 : : }
4947 : :
4948 [ # # ]: 0 : if ((size_t)rss_conf->algorithm >= CHAR_BIT * sizeof(dev_info.rss_algo_capa) ||
4949 : 0 : (dev_info.rss_algo_capa &
4950 [ # # ]: 0 : RTE_ETH_HASH_ALGO_TO_CAPA(rss_conf->algorithm)) == 0) {
4951 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4952 : : "Ethdev port_id=%u configured RSS hash algorithm (%u)"
4953 : : "is not in the algorithm capability (0x%" PRIx32 ")",
4954 : : port_id, rss_conf->algorithm, dev_info.rss_algo_capa);
4955 : 0 : return -EINVAL;
4956 : : }
4957 : :
4958 [ # # ]: 0 : if (dev->dev_ops->rss_hash_update == NULL)
4959 : : return -ENOTSUP;
4960 : 0 : ret = eth_err(port_id, dev->dev_ops->rss_hash_update(dev, rss_conf));
4961 : :
4962 : 0 : rte_ethdev_trace_rss_hash_update(port_id, rss_conf, ret);
4963 : :
4964 : 0 : return ret;
4965 : : }
4966 : :
4967 : : int
4968 : 0 : rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
4969 : : struct rte_eth_rss_conf *rss_conf)
4970 : : {
4971 : 0 : struct rte_eth_dev_info dev_info = { 0 };
4972 : : struct rte_eth_dev *dev;
4973 : : int ret;
4974 : :
4975 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
4976 : 0 : dev = &rte_eth_devices[port_id];
4977 : :
4978 [ # # ]: 0 : if (rss_conf == NULL) {
4979 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4980 : : "Cannot get ethdev port %u RSS hash config to NULL",
4981 : : port_id);
4982 : 0 : return -EINVAL;
4983 : : }
4984 : :
4985 : 0 : ret = rte_eth_dev_info_get(port_id, &dev_info);
4986 [ # # ]: 0 : if (ret != 0)
4987 : : return ret;
4988 : :
4989 [ # # ]: 0 : if (rss_conf->rss_key != NULL &&
4990 [ # # ]: 0 : rss_conf->rss_key_len < dev_info.hash_key_size) {
4991 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
4992 : : "Ethdev port_id=%u invalid RSS key len: %u, should not be less than: %u",
4993 : : port_id, rss_conf->rss_key_len, dev_info.hash_key_size);
4994 : 0 : return -EINVAL;
4995 : : }
4996 : :
4997 : 0 : rss_conf->algorithm = RTE_ETH_HASH_FUNCTION_DEFAULT;
4998 : :
4999 [ # # ]: 0 : if (dev->dev_ops->rss_hash_conf_get == NULL)
5000 : : return -ENOTSUP;
5001 : 0 : ret = eth_err(port_id, dev->dev_ops->rss_hash_conf_get(dev, rss_conf));
5002 : :
5003 : 0 : rte_ethdev_trace_rss_hash_conf_get(port_id, rss_conf, ret);
5004 : :
5005 : 0 : return ret;
5006 : : }
5007 : :
5008 : : const char *
5009 : 0 : rte_eth_dev_rss_algo_name(enum rte_eth_hash_function rss_algo)
5010 : : {
5011 : : const char *name = "Unknown function";
5012 : : unsigned int i;
5013 : :
5014 [ # # ]: 0 : for (i = 0; i < RTE_DIM(rte_eth_dev_rss_algo_names); i++) {
5015 [ # # ]: 0 : if (rss_algo == rte_eth_dev_rss_algo_names[i].algo)
5016 : 0 : return rte_eth_dev_rss_algo_names[i].name;
5017 : : }
5018 : :
5019 : : return name;
5020 : : }
5021 : :
5022 : : int
5023 : 0 : rte_eth_find_rss_algo(const char *name, uint32_t *algo)
5024 : : {
5025 : : unsigned int i;
5026 : :
5027 [ # # ]: 0 : for (i = 0; i < RTE_DIM(rte_eth_dev_rss_algo_names); i++) {
5028 [ # # ]: 0 : if (strcmp(name, rte_eth_dev_rss_algo_names[i].name) == 0) {
5029 : 0 : *algo = rte_eth_dev_rss_algo_names[i].algo;
5030 : 0 : return 0;
5031 : : }
5032 : : }
5033 : :
5034 : : return -EINVAL;
5035 : : }
5036 : :
5037 : : int
5038 : 0 : rte_eth_dev_udp_tunnel_port_add(uint16_t port_id,
5039 : : struct rte_eth_udp_tunnel *udp_tunnel)
5040 : : {
5041 : : struct rte_eth_dev *dev;
5042 : : int ret;
5043 : :
5044 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5045 : 0 : dev = &rte_eth_devices[port_id];
5046 : :
5047 [ # # ]: 0 : if (udp_tunnel == NULL) {
5048 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5049 : : "Cannot add ethdev port %u UDP tunnel port from NULL UDP tunnel",
5050 : : port_id);
5051 : 0 : return -EINVAL;
5052 : : }
5053 : :
5054 [ # # ]: 0 : if (udp_tunnel->prot_type >= RTE_ETH_TUNNEL_TYPE_MAX) {
5055 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid tunnel type");
5056 : 0 : return -EINVAL;
5057 : : }
5058 : :
5059 [ # # ]: 0 : if (dev->dev_ops->udp_tunnel_port_add == NULL)
5060 : : return -ENOTSUP;
5061 : 0 : ret = eth_err(port_id, dev->dev_ops->udp_tunnel_port_add(dev, udp_tunnel));
5062 : :
5063 : 0 : rte_ethdev_trace_udp_tunnel_port_add(port_id, udp_tunnel, ret);
5064 : :
5065 : 0 : return ret;
5066 : : }
5067 : :
5068 : : int
5069 : 0 : rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
5070 : : struct rte_eth_udp_tunnel *udp_tunnel)
5071 : : {
5072 : : struct rte_eth_dev *dev;
5073 : : int ret;
5074 : :
5075 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5076 : 0 : dev = &rte_eth_devices[port_id];
5077 : :
5078 [ # # ]: 0 : if (udp_tunnel == NULL) {
5079 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5080 : : "Cannot delete ethdev port %u UDP tunnel port from NULL UDP tunnel",
5081 : : port_id);
5082 : 0 : return -EINVAL;
5083 : : }
5084 : :
5085 [ # # ]: 0 : if (udp_tunnel->prot_type >= RTE_ETH_TUNNEL_TYPE_MAX) {
5086 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid tunnel type");
5087 : 0 : return -EINVAL;
5088 : : }
5089 : :
5090 [ # # ]: 0 : if (dev->dev_ops->udp_tunnel_port_del == NULL)
5091 : : return -ENOTSUP;
5092 : 0 : ret = eth_err(port_id, dev->dev_ops->udp_tunnel_port_del(dev, udp_tunnel));
5093 : :
5094 : 0 : rte_ethdev_trace_udp_tunnel_port_delete(port_id, udp_tunnel, ret);
5095 : :
5096 : 0 : return ret;
5097 : : }
5098 : :
5099 : : int
5100 : 0 : rte_eth_led_on(uint16_t port_id)
5101 : : {
5102 : : struct rte_eth_dev *dev;
5103 : : int ret;
5104 : :
5105 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5106 : 0 : dev = &rte_eth_devices[port_id];
5107 : :
5108 [ # # ]: 0 : if (dev->dev_ops->dev_led_on == NULL)
5109 : : return -ENOTSUP;
5110 : 0 : ret = eth_err(port_id, dev->dev_ops->dev_led_on(dev));
5111 : :
5112 : 0 : rte_eth_trace_led_on(port_id, ret);
5113 : :
5114 : 0 : return ret;
5115 : : }
5116 : :
5117 : : int
5118 : 0 : rte_eth_led_off(uint16_t port_id)
5119 : : {
5120 : : struct rte_eth_dev *dev;
5121 : : int ret;
5122 : :
5123 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5124 : 0 : dev = &rte_eth_devices[port_id];
5125 : :
5126 [ # # ]: 0 : if (dev->dev_ops->dev_led_off == NULL)
5127 : : return -ENOTSUP;
5128 : 0 : ret = eth_err(port_id, dev->dev_ops->dev_led_off(dev));
5129 : :
5130 : 0 : rte_eth_trace_led_off(port_id, ret);
5131 : :
5132 : 0 : return ret;
5133 : : }
5134 : :
5135 : : int
5136 : 0 : rte_eth_fec_get_capability(uint16_t port_id,
5137 : : struct rte_eth_fec_capa *speed_fec_capa,
5138 : : unsigned int num)
5139 : : {
5140 : : struct rte_eth_dev *dev;
5141 : : int ret;
5142 : :
5143 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5144 : 0 : dev = &rte_eth_devices[port_id];
5145 : :
5146 [ # # ]: 0 : if (speed_fec_capa == NULL && num > 0) {
5147 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5148 : : "Cannot get ethdev port %u FEC capability to NULL when array size is non zero",
5149 : : port_id);
5150 : 0 : return -EINVAL;
5151 : : }
5152 : :
5153 [ # # ]: 0 : if (dev->dev_ops->fec_get_capability == NULL)
5154 : : return -ENOTSUP;
5155 : 0 : ret = dev->dev_ops->fec_get_capability(dev, speed_fec_capa, num);
5156 : :
5157 : 0 : rte_eth_trace_fec_get_capability(port_id, speed_fec_capa, num, ret);
5158 : :
5159 : 0 : return ret;
5160 : : }
5161 : :
5162 : : int
5163 : 0 : rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa)
5164 : : {
5165 : : struct rte_eth_dev *dev;
5166 : : int ret;
5167 : :
5168 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5169 : 0 : dev = &rte_eth_devices[port_id];
5170 : :
5171 [ # # ]: 0 : if (fec_capa == NULL) {
5172 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5173 : : "Cannot get ethdev port %u current FEC mode to NULL",
5174 : : port_id);
5175 : 0 : return -EINVAL;
5176 : : }
5177 : :
5178 [ # # ]: 0 : if (dev->dev_ops->fec_get == NULL)
5179 : : return -ENOTSUP;
5180 : 0 : ret = eth_err(port_id, dev->dev_ops->fec_get(dev, fec_capa));
5181 : :
5182 : 0 : rte_eth_trace_fec_get(port_id, fec_capa, ret);
5183 : :
5184 : 0 : return ret;
5185 : : }
5186 : :
5187 : : int
5188 : 0 : rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa)
5189 : : {
5190 : : struct rte_eth_dev *dev;
5191 : : int ret;
5192 : :
5193 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5194 : 0 : dev = &rte_eth_devices[port_id];
5195 : :
5196 [ # # ]: 0 : if (fec_capa == 0) {
5197 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "At least one FEC mode should be specified");
5198 : 0 : return -EINVAL;
5199 : : }
5200 : :
5201 [ # # ]: 0 : if (dev->dev_ops->fec_set == NULL)
5202 : : return -ENOTSUP;
5203 : 0 : ret = eth_err(port_id, dev->dev_ops->fec_set(dev, fec_capa));
5204 : :
5205 : 0 : rte_eth_trace_fec_set(port_id, fec_capa, ret);
5206 : :
5207 : 0 : return ret;
5208 : : }
5209 : :
5210 : : /*
5211 : : * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
5212 : : * an empty spot.
5213 : : */
5214 : : static int
5215 : 0 : eth_dev_get_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr)
5216 : : {
5217 : : struct rte_eth_dev_info dev_info;
5218 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
5219 : : unsigned i;
5220 : : int ret;
5221 : :
5222 : 0 : ret = rte_eth_dev_info_get(port_id, &dev_info);
5223 [ # # ]: 0 : if (ret != 0)
5224 : : return -1;
5225 : :
5226 [ # # ]: 0 : for (i = 0; i < dev_info.max_mac_addrs; i++)
5227 [ # # ]: 0 : if (memcmp(addr, &dev->data->mac_addrs[i],
5228 : : RTE_ETHER_ADDR_LEN) == 0)
5229 : 0 : return i;
5230 : :
5231 : : return -1;
5232 : : }
5233 : :
5234 : : static const struct rte_ether_addr null_mac_addr;
5235 : :
5236 : : int
5237 : 0 : rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
5238 : : uint32_t pool)
5239 : : {
5240 : : struct rte_eth_dev *dev;
5241 : : int index;
5242 : : uint64_t pool_mask;
5243 : : int ret;
5244 : :
5245 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5246 : 0 : dev = &rte_eth_devices[port_id];
5247 : :
5248 [ # # ]: 0 : if (addr == NULL) {
5249 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5250 : : "Cannot add ethdev port %u MAC address from NULL address",
5251 : : port_id);
5252 : 0 : return -EINVAL;
5253 : : }
5254 : :
5255 [ # # ]: 0 : if (dev->dev_ops->mac_addr_add == NULL)
5256 : : return -ENOTSUP;
5257 : :
5258 [ # # ]: 0 : if (rte_is_zero_ether_addr(addr)) {
5259 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Port %u: Cannot add NULL MAC address",
5260 : : port_id);
5261 : 0 : return -EINVAL;
5262 : : }
5263 [ # # ]: 0 : if (pool >= RTE_ETH_64_POOLS) {
5264 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Pool ID must be 0-%d", RTE_ETH_64_POOLS - 1);
5265 : 0 : return -EINVAL;
5266 : : }
5267 : :
5268 : 0 : index = eth_dev_get_mac_addr_index(port_id, addr);
5269 [ # # ]: 0 : if (index < 0) {
5270 : 0 : index = eth_dev_get_mac_addr_index(port_id, &null_mac_addr);
5271 [ # # ]: 0 : if (index < 0) {
5272 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Port %u: MAC address array full",
5273 : : port_id);
5274 : 0 : return -ENOSPC;
5275 : : }
5276 : : } else {
5277 : 0 : pool_mask = dev->data->mac_pool_sel[index];
5278 : :
5279 : : /* Check if both MAC address and pool is already there, and do nothing */
5280 [ # # ]: 0 : if (pool_mask & RTE_BIT64(pool))
5281 : : return 0;
5282 : : }
5283 : :
5284 : : /* Update NIC */
5285 : 0 : ret = dev->dev_ops->mac_addr_add(dev, addr, index, pool);
5286 : :
5287 [ # # ]: 0 : if (ret == 0) {
5288 : : /* Update address in NIC data structure */
5289 : 0 : rte_ether_addr_copy(addr, &dev->data->mac_addrs[index]);
5290 : :
5291 : : /* Update pool bitmap in NIC data structure */
5292 : 0 : dev->data->mac_pool_sel[index] |= RTE_BIT64(pool);
5293 : : }
5294 : :
5295 : 0 : ret = eth_err(port_id, ret);
5296 : :
5297 : 0 : rte_ethdev_trace_mac_addr_add(port_id, addr, pool, ret);
5298 : :
5299 : 0 : return ret;
5300 : : }
5301 : :
5302 : : int
5303 : 0 : rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
5304 : : {
5305 : : struct rte_eth_dev *dev;
5306 : : int index;
5307 : :
5308 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5309 : 0 : dev = &rte_eth_devices[port_id];
5310 : :
5311 [ # # ]: 0 : if (addr == NULL) {
5312 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5313 : : "Cannot remove ethdev port %u MAC address from NULL address",
5314 : : port_id);
5315 : 0 : return -EINVAL;
5316 : : }
5317 : :
5318 [ # # ]: 0 : if (dev->dev_ops->mac_addr_remove == NULL)
5319 : : return -ENOTSUP;
5320 : :
5321 : 0 : index = eth_dev_get_mac_addr_index(port_id, addr);
5322 [ # # ]: 0 : if (index == 0) {
5323 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5324 : : "Port %u: Cannot remove default MAC address",
5325 : : port_id);
5326 : 0 : return -EADDRINUSE;
5327 [ # # ]: 0 : } else if (index < 0)
5328 : : return 0; /* Do nothing if address wasn't found */
5329 : :
5330 : : /* Update NIC */
5331 : 0 : dev->dev_ops->mac_addr_remove(dev, index);
5332 : :
5333 : : /* Update address in NIC data structure */
5334 [ # # ]: 0 : rte_ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]);
5335 : :
5336 : : /* reset pool bitmap */
5337 [ # # ]: 0 : dev->data->mac_pool_sel[index] = 0;
5338 : :
5339 : 0 : rte_ethdev_trace_mac_addr_remove(port_id, addr);
5340 : :
5341 : 0 : return 0;
5342 : : }
5343 : :
5344 : : int
5345 : 0 : rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
5346 : : {
5347 : : struct rte_eth_dev *dev;
5348 : : int index;
5349 : : int ret;
5350 : :
5351 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5352 : 0 : dev = &rte_eth_devices[port_id];
5353 : :
5354 [ # # ]: 0 : if (addr == NULL) {
5355 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5356 : : "Cannot set ethdev port %u default MAC address from NULL address",
5357 : : port_id);
5358 : 0 : return -EINVAL;
5359 : : }
5360 : :
5361 : : if (!rte_is_valid_assigned_ether_addr(addr))
5362 : : return -EINVAL;
5363 : :
5364 [ # # ]: 0 : if (dev->dev_ops->mac_addr_set == NULL)
5365 : : return -ENOTSUP;
5366 : :
5367 : : /* Keep address unique in dev->data->mac_addrs[]. */
5368 : 0 : index = eth_dev_get_mac_addr_index(port_id, addr);
5369 [ # # ]: 0 : if (index > 0) {
5370 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5371 : : "New default address for port %u was already in the address list. Please remove it first.",
5372 : : port_id);
5373 : 0 : return -EEXIST;
5374 : : }
5375 : :
5376 : 0 : ret = dev->dev_ops->mac_addr_set(dev, addr);
5377 [ # # ]: 0 : if (ret < 0)
5378 : : return ret;
5379 : :
5380 : : /* Update default address in NIC data structure */
5381 [ # # ]: 0 : rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
5382 : :
5383 : 0 : rte_ethdev_trace_default_mac_addr_set(port_id, addr);
5384 : :
5385 : 0 : return 0;
5386 : : }
5387 : :
5388 : :
5389 : : /*
5390 : : * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
5391 : : * an empty spot.
5392 : : */
5393 : : static int
5394 : 0 : eth_dev_get_hash_mac_addr_index(uint16_t port_id,
5395 : : const struct rte_ether_addr *addr)
5396 : : {
5397 : : struct rte_eth_dev_info dev_info;
5398 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
5399 : : unsigned i;
5400 : : int ret;
5401 : :
5402 : 0 : ret = rte_eth_dev_info_get(port_id, &dev_info);
5403 [ # # ]: 0 : if (ret != 0)
5404 : : return -1;
5405 : :
5406 [ # # ]: 0 : if (!dev->data->hash_mac_addrs)
5407 : : return -1;
5408 : :
5409 [ # # ]: 0 : for (i = 0; i < dev_info.max_hash_mac_addrs; i++)
5410 [ # # ]: 0 : if (memcmp(addr, &dev->data->hash_mac_addrs[i],
5411 : : RTE_ETHER_ADDR_LEN) == 0)
5412 : 0 : return i;
5413 : :
5414 : : return -1;
5415 : : }
5416 : :
5417 : : int
5418 : 0 : rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
5419 : : uint8_t on)
5420 : : {
5421 : : int index;
5422 : : int ret;
5423 : : struct rte_eth_dev *dev;
5424 : :
5425 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5426 : 0 : dev = &rte_eth_devices[port_id];
5427 : :
5428 [ # # ]: 0 : if (addr == NULL) {
5429 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5430 : : "Cannot set ethdev port %u unicast hash table from NULL address",
5431 : : port_id);
5432 : 0 : return -EINVAL;
5433 : : }
5434 : :
5435 [ # # ]: 0 : if (rte_is_zero_ether_addr(addr)) {
5436 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Port %u: Cannot add NULL MAC address",
5437 : : port_id);
5438 : 0 : return -EINVAL;
5439 : : }
5440 : :
5441 : 0 : index = eth_dev_get_hash_mac_addr_index(port_id, addr);
5442 : : /* Check if it's already there, and do nothing */
5443 [ # # ]: 0 : if ((index >= 0) && on)
5444 : : return 0;
5445 : :
5446 [ # # ]: 0 : if (index < 0) {
5447 [ # # ]: 0 : if (!on) {
5448 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5449 : : "Port %u: the MAC address was not set in UTA",
5450 : : port_id);
5451 : 0 : return -EINVAL;
5452 : : }
5453 : :
5454 : 0 : index = eth_dev_get_hash_mac_addr_index(port_id, &null_mac_addr);
5455 [ # # ]: 0 : if (index < 0) {
5456 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Port %u: MAC address array full",
5457 : : port_id);
5458 : 0 : return -ENOSPC;
5459 : : }
5460 : : }
5461 : :
5462 [ # # ]: 0 : if (dev->dev_ops->uc_hash_table_set == NULL)
5463 : : return -ENOTSUP;
5464 : 0 : ret = dev->dev_ops->uc_hash_table_set(dev, addr, on);
5465 [ # # ]: 0 : if (ret == 0) {
5466 : : /* Update address in NIC data structure */
5467 [ # # ]: 0 : if (on)
5468 : 0 : rte_ether_addr_copy(addr,
5469 : 0 : &dev->data->hash_mac_addrs[index]);
5470 : : else
5471 : 0 : rte_ether_addr_copy(&null_mac_addr,
5472 : 0 : &dev->data->hash_mac_addrs[index]);
5473 : : }
5474 : :
5475 : 0 : ret = eth_err(port_id, ret);
5476 : :
5477 : 0 : rte_ethdev_trace_uc_hash_table_set(port_id, on, ret);
5478 : :
5479 : 0 : return ret;
5480 : : }
5481 : :
5482 : : int
5483 : 0 : rte_eth_dev_uc_all_hash_table_set(uint16_t port_id, uint8_t on)
5484 : : {
5485 : : struct rte_eth_dev *dev;
5486 : : int ret;
5487 : :
5488 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5489 : 0 : dev = &rte_eth_devices[port_id];
5490 : :
5491 [ # # ]: 0 : if (dev->dev_ops->uc_all_hash_table_set == NULL)
5492 : : return -ENOTSUP;
5493 : 0 : ret = eth_err(port_id, dev->dev_ops->uc_all_hash_table_set(dev, on));
5494 : :
5495 : 0 : rte_ethdev_trace_uc_all_hash_table_set(port_id, on, ret);
5496 : :
5497 : 0 : return ret;
5498 : : }
5499 : :
5500 : 0 : int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
5501 : : uint32_t tx_rate)
5502 : : {
5503 : : struct rte_eth_dev *dev;
5504 : : struct rte_eth_dev_info dev_info;
5505 : : struct rte_eth_link link;
5506 : : int ret;
5507 : :
5508 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5509 : 0 : dev = &rte_eth_devices[port_id];
5510 : :
5511 : 0 : ret = rte_eth_dev_info_get(port_id, &dev_info);
5512 [ # # ]: 0 : if (ret != 0)
5513 : : return ret;
5514 : :
5515 : 0 : link = dev->data->dev_link;
5516 : :
5517 [ # # ]: 0 : if (queue_idx > dev_info.max_tx_queues) {
5518 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5519 : : "Set queue rate limit:port %u: invalid queue ID=%u",
5520 : : port_id, queue_idx);
5521 : 0 : return -EINVAL;
5522 : : }
5523 : :
5524 [ # # ]: 0 : if (tx_rate > link.link_speed) {
5525 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5526 : : "Set queue rate limit:invalid tx_rate=%u, bigger than link speed= %d",
5527 : : tx_rate, link.link_speed);
5528 : 0 : return -EINVAL;
5529 : : }
5530 : :
5531 [ # # ]: 0 : if (dev->dev_ops->set_queue_rate_limit == NULL)
5532 : : return -ENOTSUP;
5533 : 0 : ret = eth_err(port_id, dev->dev_ops->set_queue_rate_limit(dev, queue_idx, tx_rate));
5534 : :
5535 [ # # ]: 0 : rte_eth_trace_set_queue_rate_limit(port_id, queue_idx, tx_rate, ret);
5536 : :
5537 : 0 : return ret;
5538 : : }
5539 : :
5540 : 0 : int rte_eth_rx_avail_thresh_set(uint16_t port_id, uint16_t queue_id,
5541 : : uint8_t avail_thresh)
5542 : : {
5543 : : struct rte_eth_dev *dev;
5544 : : int ret;
5545 : :
5546 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5547 : 0 : dev = &rte_eth_devices[port_id];
5548 : :
5549 [ # # ]: 0 : if (queue_id > dev->data->nb_rx_queues) {
5550 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5551 : : "Set queue avail thresh: port %u: invalid queue ID=%u.",
5552 : : port_id, queue_id);
5553 : 0 : return -EINVAL;
5554 : : }
5555 : :
5556 [ # # ]: 0 : if (avail_thresh > 99) {
5557 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5558 : : "Set queue avail thresh: port %u: threshold should be <= 99.",
5559 : : port_id);
5560 : 0 : return -EINVAL;
5561 : : }
5562 [ # # ]: 0 : if (dev->dev_ops->rx_queue_avail_thresh_set == NULL)
5563 : : return -ENOTSUP;
5564 : 0 : ret = eth_err(port_id,
5565 : : dev->dev_ops->rx_queue_avail_thresh_set(dev, queue_id, avail_thresh));
5566 : :
5567 : 0 : rte_eth_trace_rx_avail_thresh_set(port_id, queue_id, avail_thresh, ret);
5568 : :
5569 : 0 : return ret;
5570 : : }
5571 : :
5572 : 0 : int rte_eth_rx_avail_thresh_query(uint16_t port_id, uint16_t *queue_id,
5573 : : uint8_t *avail_thresh)
5574 : : {
5575 : : struct rte_eth_dev *dev;
5576 : : int ret;
5577 : :
5578 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5579 : 0 : dev = &rte_eth_devices[port_id];
5580 : :
5581 [ # # ]: 0 : if (queue_id == NULL)
5582 : : return -EINVAL;
5583 [ # # ]: 0 : if (*queue_id >= dev->data->nb_rx_queues)
5584 : 0 : *queue_id = 0;
5585 : :
5586 [ # # ]: 0 : if (dev->dev_ops->rx_queue_avail_thresh_query == NULL)
5587 : : return -ENOTSUP;
5588 : 0 : ret = eth_err(port_id,
5589 : : dev->dev_ops->rx_queue_avail_thresh_query(dev, queue_id, avail_thresh));
5590 : :
5591 [ # # ]: 0 : rte_eth_trace_rx_avail_thresh_query(port_id, *queue_id, ret);
5592 : :
5593 : 0 : return ret;
5594 : : }
5595 : :
5596 : 252 : RTE_INIT(eth_dev_init_fp_ops)
5597 : : {
5598 : : uint32_t i;
5599 : :
5600 [ + + ]: 8316 : for (i = 0; i != RTE_DIM(rte_eth_fp_ops); i++)
5601 : 8064 : eth_dev_fp_ops_reset(rte_eth_fp_ops + i);
5602 : 252 : }
5603 : :
5604 : 252 : RTE_INIT(eth_dev_init_cb_lists)
5605 : : {
5606 : : uint16_t i;
5607 : :
5608 [ + + ]: 8316 : for (i = 0; i < RTE_MAX_ETHPORTS; i++)
5609 : 8064 : TAILQ_INIT(&rte_eth_devices[i].link_intr_cbs);
5610 : 252 : }
5611 : :
5612 : : int
5613 : 0 : rte_eth_dev_callback_register(uint16_t port_id,
5614 : : enum rte_eth_event_type event,
5615 : : rte_eth_dev_cb_fn cb_fn, void *cb_arg)
5616 : : {
5617 : : struct rte_eth_dev *dev;
5618 : : struct rte_eth_dev_callback *user_cb;
5619 : : uint16_t next_port;
5620 : : uint16_t last_port;
5621 : :
5622 [ # # ]: 0 : if (cb_fn == NULL) {
5623 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5624 : : "Cannot register ethdev port %u callback from NULL",
5625 : : port_id);
5626 : 0 : return -EINVAL;
5627 : : }
5628 : :
5629 [ # # # # ]: 0 : if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
5630 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid port_id=%d", port_id);
5631 : 0 : return -EINVAL;
5632 : : }
5633 : :
5634 [ # # ]: 0 : if (port_id == RTE_ETH_ALL) {
5635 : : next_port = 0;
5636 : : last_port = RTE_MAX_ETHPORTS - 1;
5637 : : } else {
5638 : : next_port = last_port = port_id;
5639 : : }
5640 : :
5641 : : rte_spinlock_lock(ð_dev_cb_lock);
5642 : :
5643 : : do {
5644 : 0 : dev = &rte_eth_devices[next_port];
5645 : :
5646 [ # # ]: 0 : TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) {
5647 [ # # ]: 0 : if (user_cb->cb_fn == cb_fn &&
5648 [ # # ]: 0 : user_cb->cb_arg == cb_arg &&
5649 [ # # ]: 0 : user_cb->event == event) {
5650 : : break;
5651 : : }
5652 : : }
5653 : :
5654 : : /* create a new callback. */
5655 [ # # ]: 0 : if (user_cb == NULL) {
5656 : 0 : user_cb = rte_zmalloc("INTR_USER_CALLBACK",
5657 : : sizeof(struct rte_eth_dev_callback), 0);
5658 [ # # ]: 0 : if (user_cb != NULL) {
5659 : 0 : user_cb->cb_fn = cb_fn;
5660 : 0 : user_cb->cb_arg = cb_arg;
5661 : 0 : user_cb->event = event;
5662 : 0 : TAILQ_INSERT_TAIL(&(dev->link_intr_cbs),
5663 : : user_cb, next);
5664 : : } else {
5665 : : rte_spinlock_unlock(ð_dev_cb_lock);
5666 : 0 : rte_eth_dev_callback_unregister(port_id, event,
5667 : : cb_fn, cb_arg);
5668 : 0 : return -ENOMEM;
5669 : : }
5670 : :
5671 : : }
5672 [ # # ]: 0 : } while (++next_port <= last_port);
5673 : :
5674 : : rte_spinlock_unlock(ð_dev_cb_lock);
5675 : :
5676 : 0 : rte_ethdev_trace_callback_register(port_id, event, cb_fn, cb_arg);
5677 : :
5678 : 0 : return 0;
5679 : : }
5680 : :
5681 : : int
5682 : 0 : rte_eth_dev_callback_unregister(uint16_t port_id,
5683 : : enum rte_eth_event_type event,
5684 : : rte_eth_dev_cb_fn cb_fn, void *cb_arg)
5685 : : {
5686 : : int ret;
5687 : : struct rte_eth_dev *dev;
5688 : : struct rte_eth_dev_callback *cb, *next;
5689 : : uint16_t next_port;
5690 : : uint16_t last_port;
5691 : :
5692 [ # # ]: 0 : if (cb_fn == NULL) {
5693 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5694 : : "Cannot unregister ethdev port %u callback from NULL",
5695 : : port_id);
5696 : 0 : return -EINVAL;
5697 : : }
5698 : :
5699 [ # # # # ]: 0 : if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
5700 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid port_id=%d", port_id);
5701 : 0 : return -EINVAL;
5702 : : }
5703 : :
5704 [ # # ]: 0 : if (port_id == RTE_ETH_ALL) {
5705 : : next_port = 0;
5706 : : last_port = RTE_MAX_ETHPORTS - 1;
5707 : : } else {
5708 : : next_port = last_port = port_id;
5709 : : }
5710 : :
5711 : : rte_spinlock_lock(ð_dev_cb_lock);
5712 : :
5713 : : do {
5714 : 0 : dev = &rte_eth_devices[next_port];
5715 : : ret = 0;
5716 [ # # ]: 0 : for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL;
5717 : : cb = next) {
5718 : :
5719 : 0 : next = TAILQ_NEXT(cb, next);
5720 : :
5721 [ # # # # : 0 : if (cb->cb_fn != cb_fn || cb->event != event ||
# # ]
5722 [ # # ]: 0 : (cb_arg != (void *)-1 && cb->cb_arg != cb_arg))
5723 : 0 : continue;
5724 : :
5725 : : /*
5726 : : * if this callback is not executing right now,
5727 : : * then remove it.
5728 : : */
5729 [ # # ]: 0 : if (cb->active == 0) {
5730 [ # # ]: 0 : TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next);
5731 : 0 : rte_free(cb);
5732 : : } else {
5733 : : ret = -EAGAIN;
5734 : : }
5735 : : }
5736 [ # # ]: 0 : } while (++next_port <= last_port);
5737 : :
5738 : : rte_spinlock_unlock(ð_dev_cb_lock);
5739 : :
5740 : 0 : rte_ethdev_trace_callback_unregister(port_id, event, cb_fn, cb_arg,
5741 : : ret);
5742 : :
5743 : 0 : return ret;
5744 : : }
5745 : :
5746 : : int
5747 : 0 : rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data)
5748 : : {
5749 : : uint32_t vec;
5750 : : struct rte_eth_dev *dev;
5751 : : struct rte_intr_handle *intr_handle;
5752 : : uint16_t qid;
5753 : : int rc;
5754 : :
5755 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5756 : : dev = &rte_eth_devices[port_id];
5757 : :
5758 [ # # ]: 0 : if (!dev->intr_handle) {
5759 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr handle unset");
5760 : 0 : return -ENOTSUP;
5761 : : }
5762 : :
5763 : : intr_handle = dev->intr_handle;
5764 [ # # ]: 0 : if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) {
5765 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr vector unset");
5766 : 0 : return -EPERM;
5767 : : }
5768 : :
5769 [ # # ]: 0 : for (qid = 0; qid < dev->data->nb_rx_queues; qid++) {
5770 : 0 : vec = rte_intr_vec_list_index_get(intr_handle, qid);
5771 : 0 : rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data);
5772 : :
5773 : 0 : rte_ethdev_trace_rx_intr_ctl(port_id, qid, epfd, op, data, rc);
5774 : :
5775 [ # # ]: 0 : if (rc && rc != -EEXIST) {
5776 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5777 : : "p %u q %u Rx ctl error op %d epfd %d vec %u",
5778 : : port_id, qid, op, epfd, vec);
5779 : : }
5780 : : }
5781 : :
5782 : : return 0;
5783 : : }
5784 : :
5785 : : int
5786 : 0 : rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id, uint16_t queue_id)
5787 : : {
5788 : : struct rte_intr_handle *intr_handle;
5789 : : struct rte_eth_dev *dev;
5790 : : unsigned int efd_idx;
5791 : : uint32_t vec;
5792 : : int fd;
5793 : :
5794 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
5795 : : dev = &rte_eth_devices[port_id];
5796 : :
5797 [ # # ]: 0 : if (queue_id >= dev->data->nb_rx_queues) {
5798 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id);
5799 : 0 : return -1;
5800 : : }
5801 : :
5802 [ # # ]: 0 : if (!dev->intr_handle) {
5803 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr handle unset");
5804 : 0 : return -1;
5805 : : }
5806 : :
5807 : : intr_handle = dev->intr_handle;
5808 [ # # ]: 0 : if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) {
5809 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr vector unset");
5810 : 0 : return -1;
5811 : : }
5812 : :
5813 : 0 : vec = rte_intr_vec_list_index_get(intr_handle, queue_id);
5814 : : efd_idx = (vec >= RTE_INTR_VEC_RXTX_OFFSET) ?
5815 [ # # ]: 0 : (vec - RTE_INTR_VEC_RXTX_OFFSET) : vec;
5816 : 0 : fd = rte_intr_efds_index_get(intr_handle, efd_idx);
5817 : :
5818 : 0 : rte_ethdev_trace_rx_intr_ctl_q_get_fd(port_id, queue_id, fd);
5819 : :
5820 : 0 : return fd;
5821 : : }
5822 : :
5823 : : int
5824 : 0 : rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
5825 : : int epfd, int op, void *data)
5826 : : {
5827 : : uint32_t vec;
5828 : : struct rte_eth_dev *dev;
5829 : : struct rte_intr_handle *intr_handle;
5830 : : int rc;
5831 : :
5832 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5833 : : dev = &rte_eth_devices[port_id];
5834 : :
5835 [ # # ]: 0 : if (queue_id >= dev->data->nb_rx_queues) {
5836 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id);
5837 : 0 : return -EINVAL;
5838 : : }
5839 : :
5840 [ # # ]: 0 : if (!dev->intr_handle) {
5841 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr handle unset");
5842 : 0 : return -ENOTSUP;
5843 : : }
5844 : :
5845 : : intr_handle = dev->intr_handle;
5846 [ # # ]: 0 : if (rte_intr_vec_list_index_get(intr_handle, 0) < 0) {
5847 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Rx Intr vector unset");
5848 : 0 : return -EPERM;
5849 : : }
5850 : :
5851 : 0 : vec = rte_intr_vec_list_index_get(intr_handle, queue_id);
5852 : 0 : rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data);
5853 : :
5854 : 0 : rte_ethdev_trace_rx_intr_ctl_q(port_id, queue_id, epfd, op, data, rc);
5855 : :
5856 [ # # ]: 0 : if (rc && rc != -EEXIST) {
5857 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
5858 : : "p %u q %u Rx ctl error op %d epfd %d vec %u",
5859 : : port_id, queue_id, op, epfd, vec);
5860 : 0 : return rc;
5861 : : }
5862 : :
5863 : : return 0;
5864 : : }
5865 : :
5866 : : int
5867 : 0 : rte_eth_dev_rx_intr_enable(uint16_t port_id,
5868 : : uint16_t queue_id)
5869 : : {
5870 : : struct rte_eth_dev *dev;
5871 : : int ret;
5872 : :
5873 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5874 : 0 : dev = &rte_eth_devices[port_id];
5875 : :
5876 : 0 : ret = eth_dev_validate_rx_queue(dev, queue_id);
5877 [ # # ]: 0 : if (ret != 0)
5878 : : return ret;
5879 : :
5880 [ # # ]: 0 : if (dev->dev_ops->rx_queue_intr_enable == NULL)
5881 : : return -ENOTSUP;
5882 : 0 : ret = eth_err(port_id, dev->dev_ops->rx_queue_intr_enable(dev, queue_id));
5883 : :
5884 : : rte_ethdev_trace_rx_intr_enable(port_id, queue_id, ret);
5885 : :
5886 : 0 : return ret;
5887 : : }
5888 : :
5889 : : int
5890 : 0 : rte_eth_dev_rx_intr_disable(uint16_t port_id,
5891 : : uint16_t queue_id)
5892 : : {
5893 : : struct rte_eth_dev *dev;
5894 : : int ret;
5895 : :
5896 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
5897 : 0 : dev = &rte_eth_devices[port_id];
5898 : :
5899 : 0 : ret = eth_dev_validate_rx_queue(dev, queue_id);
5900 [ # # ]: 0 : if (ret != 0)
5901 : : return ret;
5902 : :
5903 [ # # ]: 0 : if (dev->dev_ops->rx_queue_intr_disable == NULL)
5904 : : return -ENOTSUP;
5905 : 0 : ret = eth_err(port_id, dev->dev_ops->rx_queue_intr_disable(dev, queue_id));
5906 : :
5907 : : rte_ethdev_trace_rx_intr_disable(port_id, queue_id, ret);
5908 : :
5909 : 0 : return ret;
5910 : : }
5911 : :
5912 : :
5913 : : const struct rte_eth_rxtx_callback *
5914 : 0 : rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id,
5915 : : rte_rx_callback_fn fn, void *user_param)
5916 : : {
5917 : : #ifndef RTE_ETHDEV_RXTX_CALLBACKS
5918 : : rte_errno = ENOTSUP;
5919 : : return NULL;
5920 : : #endif
5921 : : struct rte_eth_dev *dev;
5922 : :
5923 : : /* check input parameters */
5924 [ # # # # ]: 0 : if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
5925 [ # # ]: 0 : queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) {
5926 : 0 : rte_errno = EINVAL;
5927 : 0 : return NULL;
5928 : : }
5929 : 0 : dev = &rte_eth_devices[port_id];
5930 [ # # ]: 0 : if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) {
5931 : 0 : rte_errno = EINVAL;
5932 : 0 : return NULL;
5933 : : }
5934 : 0 : struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
5935 : :
5936 [ # # ]: 0 : if (cb == NULL) {
5937 : 0 : rte_errno = ENOMEM;
5938 : 0 : return NULL;
5939 : : }
5940 : :
5941 : 0 : cb->fn.rx = fn;
5942 : 0 : cb->param = user_param;
5943 : :
5944 : : rte_spinlock_lock(ð_dev_rx_cb_lock);
5945 : : /* Add the callbacks in fifo order. */
5946 : 0 : struct rte_eth_rxtx_callback *tail =
5947 : : rte_eth_devices[port_id].post_rx_burst_cbs[queue_id];
5948 : :
5949 [ # # ]: 0 : if (!tail) {
5950 : : /* Stores to cb->fn and cb->param should complete before
5951 : : * cb is visible to data plane.
5952 : : */
5953 : 0 : rte_atomic_store_explicit(
5954 : : &rte_eth_devices[port_id].post_rx_burst_cbs[queue_id],
5955 : : cb, rte_memory_order_release);
5956 : :
5957 : : } else {
5958 [ # # ]: 0 : while (tail->next)
5959 : : tail = tail->next;
5960 : : /* Stores to cb->fn and cb->param should complete before
5961 : : * cb is visible to data plane.
5962 : : */
5963 : 0 : rte_atomic_store_explicit(&tail->next, cb, rte_memory_order_release);
5964 : : }
5965 : : rte_spinlock_unlock(ð_dev_rx_cb_lock);
5966 : :
5967 : 0 : rte_eth_trace_add_rx_callback(port_id, queue_id, fn, user_param, cb);
5968 : :
5969 : 0 : return cb;
5970 : : }
5971 : :
5972 : : const struct rte_eth_rxtx_callback *
5973 : 1 : rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id,
5974 : : rte_rx_callback_fn fn, void *user_param)
5975 : : {
5976 : : #ifndef RTE_ETHDEV_RXTX_CALLBACKS
5977 : : rte_errno = ENOTSUP;
5978 : : return NULL;
5979 : : #endif
5980 : : /* check input parameters */
5981 [ + - + - ]: 1 : if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
5982 [ - + ]: 1 : queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) {
5983 : 0 : rte_errno = EINVAL;
5984 : 0 : return NULL;
5985 : : }
5986 : :
5987 : 1 : struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
5988 : :
5989 [ - + ]: 1 : if (cb == NULL) {
5990 : 0 : rte_errno = ENOMEM;
5991 : 0 : return NULL;
5992 : : }
5993 : :
5994 : 1 : cb->fn.rx = fn;
5995 : 1 : cb->param = user_param;
5996 : :
5997 : : rte_spinlock_lock(ð_dev_rx_cb_lock);
5998 : : /* Add the callbacks at first position */
5999 : 1 : cb->next = rte_eth_devices[port_id].post_rx_burst_cbs[queue_id];
6000 : : /* Stores to cb->fn, cb->param and cb->next should complete before
6001 : : * cb is visible to data plane threads.
6002 : : */
6003 : 1 : rte_atomic_store_explicit(
6004 : : &rte_eth_devices[port_id].post_rx_burst_cbs[queue_id],
6005 : : cb, rte_memory_order_release);
6006 : : rte_spinlock_unlock(ð_dev_rx_cb_lock);
6007 : :
6008 : 1 : rte_eth_trace_add_first_rx_callback(port_id, queue_id, fn, user_param,
6009 : : cb);
6010 : :
6011 : 1 : return cb;
6012 : : }
6013 : :
6014 : : const struct rte_eth_rxtx_callback *
6015 : 1 : rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id,
6016 : : rte_tx_callback_fn fn, void *user_param)
6017 : : {
6018 : : #ifndef RTE_ETHDEV_RXTX_CALLBACKS
6019 : : rte_errno = ENOTSUP;
6020 : : return NULL;
6021 : : #endif
6022 : : struct rte_eth_dev *dev;
6023 : :
6024 : : /* check input parameters */
6025 [ + - + - ]: 1 : if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
6026 [ - + ]: 1 : queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) {
6027 : 0 : rte_errno = EINVAL;
6028 : 0 : return NULL;
6029 : : }
6030 : :
6031 : 1 : dev = &rte_eth_devices[port_id];
6032 [ - + ]: 1 : if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) {
6033 : 0 : rte_errno = EINVAL;
6034 : 0 : return NULL;
6035 : : }
6036 : :
6037 : 1 : struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
6038 : :
6039 [ - + ]: 1 : if (cb == NULL) {
6040 : 0 : rte_errno = ENOMEM;
6041 : 0 : return NULL;
6042 : : }
6043 : :
6044 : 1 : cb->fn.tx = fn;
6045 : 1 : cb->param = user_param;
6046 : :
6047 : : rte_spinlock_lock(ð_dev_tx_cb_lock);
6048 : : /* Add the callbacks in fifo order. */
6049 : 1 : struct rte_eth_rxtx_callback *tail =
6050 : : rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id];
6051 : :
6052 [ + - ]: 1 : if (!tail) {
6053 : : /* Stores to cb->fn and cb->param should complete before
6054 : : * cb is visible to data plane.
6055 : : */
6056 : 1 : rte_atomic_store_explicit(
6057 : : &rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id],
6058 : : cb, rte_memory_order_release);
6059 : :
6060 : : } else {
6061 [ # # ]: 0 : while (tail->next)
6062 : : tail = tail->next;
6063 : : /* Stores to cb->fn and cb->param should complete before
6064 : : * cb is visible to data plane.
6065 : : */
6066 : 0 : rte_atomic_store_explicit(&tail->next, cb, rte_memory_order_release);
6067 : : }
6068 : : rte_spinlock_unlock(ð_dev_tx_cb_lock);
6069 : :
6070 : 1 : rte_eth_trace_add_tx_callback(port_id, queue_id, fn, user_param, cb);
6071 : :
6072 : 1 : return cb;
6073 : : }
6074 : :
6075 : : int
6076 : 1 : rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id,
6077 : : const struct rte_eth_rxtx_callback *user_cb)
6078 : : {
6079 : : #ifndef RTE_ETHDEV_RXTX_CALLBACKS
6080 : : return -ENOTSUP;
6081 : : #endif
6082 : : /* Check input parameters. */
6083 [ - + ]: 1 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6084 [ + - ]: 1 : if (user_cb == NULL ||
6085 [ + - ]: 1 : queue_id >= rte_eth_devices[port_id].data->nb_rx_queues)
6086 : : return -EINVAL;
6087 : :
6088 : : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
6089 : : struct rte_eth_rxtx_callback *cb;
6090 : : RTE_ATOMIC(struct rte_eth_rxtx_callback *) *prev_cb;
6091 : : int ret = -EINVAL;
6092 : :
6093 : : rte_spinlock_lock(ð_dev_rx_cb_lock);
6094 : 1 : prev_cb = &dev->post_rx_burst_cbs[queue_id];
6095 [ + - ]: 1 : for (; *prev_cb != NULL; prev_cb = &cb->next) {
6096 : : cb = *prev_cb;
6097 [ + - ]: 1 : if (cb == user_cb) {
6098 : : /* Remove the user cb from the callback list. */
6099 : 1 : rte_atomic_store_explicit(prev_cb, cb->next, rte_memory_order_relaxed);
6100 : : ret = 0;
6101 : 1 : break;
6102 : : }
6103 : : }
6104 : : rte_spinlock_unlock(ð_dev_rx_cb_lock);
6105 : :
6106 : 1 : rte_eth_trace_remove_rx_callback(port_id, queue_id, user_cb, ret);
6107 : :
6108 : 1 : return ret;
6109 : : }
6110 : :
6111 : : int
6112 : 1 : rte_eth_remove_tx_callback(uint16_t port_id, uint16_t queue_id,
6113 : : const struct rte_eth_rxtx_callback *user_cb)
6114 : : {
6115 : : #ifndef RTE_ETHDEV_RXTX_CALLBACKS
6116 : : return -ENOTSUP;
6117 : : #endif
6118 : : /* Check input parameters. */
6119 [ - + ]: 1 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6120 [ + - ]: 1 : if (user_cb == NULL ||
6121 [ + - ]: 1 : queue_id >= rte_eth_devices[port_id].data->nb_tx_queues)
6122 : : return -EINVAL;
6123 : :
6124 : : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
6125 : : int ret = -EINVAL;
6126 : : struct rte_eth_rxtx_callback *cb;
6127 : : RTE_ATOMIC(struct rte_eth_rxtx_callback *) *prev_cb;
6128 : :
6129 : : rte_spinlock_lock(ð_dev_tx_cb_lock);
6130 : 1 : prev_cb = &dev->pre_tx_burst_cbs[queue_id];
6131 [ + - ]: 1 : for (; *prev_cb != NULL; prev_cb = &cb->next) {
6132 : : cb = *prev_cb;
6133 [ + - ]: 1 : if (cb == user_cb) {
6134 : : /* Remove the user cb from the callback list. */
6135 : 1 : rte_atomic_store_explicit(prev_cb, cb->next, rte_memory_order_relaxed);
6136 : : ret = 0;
6137 : 1 : break;
6138 : : }
6139 : : }
6140 : : rte_spinlock_unlock(ð_dev_tx_cb_lock);
6141 : :
6142 : 1 : rte_eth_trace_remove_tx_callback(port_id, queue_id, user_cb, ret);
6143 : :
6144 : 1 : return ret;
6145 : : }
6146 : :
6147 : : int
6148 : 0 : rte_eth_rx_queue_info_get(uint16_t port_id, uint16_t queue_id,
6149 : : struct rte_eth_rxq_info *qinfo)
6150 : : {
6151 : : struct rte_eth_dev *dev;
6152 : :
6153 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6154 : 0 : dev = &rte_eth_devices[port_id];
6155 : :
6156 [ # # ]: 0 : if (queue_id >= dev->data->nb_rx_queues) {
6157 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id);
6158 : 0 : return -EINVAL;
6159 : : }
6160 : :
6161 [ # # ]: 0 : if (qinfo == NULL) {
6162 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u Rx queue %u info to NULL",
6163 : : port_id, queue_id);
6164 : 0 : return -EINVAL;
6165 : : }
6166 : :
6167 [ # # ]: 0 : if (dev->data->rx_queues == NULL ||
6168 [ # # ]: 0 : dev->data->rx_queues[queue_id] == NULL) {
6169 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6170 : : "Rx queue %"PRIu16" of device with port_id=%"
6171 : : PRIu16" has not been setup",
6172 : : queue_id, port_id);
6173 : 0 : return -EINVAL;
6174 : : }
6175 : :
6176 [ # # ]: 0 : if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) {
6177 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
6178 : : "Can't get hairpin Rx queue %"PRIu16" info of device with port_id=%"PRIu16,
6179 : : queue_id, port_id);
6180 : 0 : return -EINVAL;
6181 : : }
6182 : :
6183 [ # # ]: 0 : if (dev->dev_ops->rxq_info_get == NULL)
6184 : : return -ENOTSUP;
6185 : :
6186 : : memset(qinfo, 0, sizeof(*qinfo));
6187 : 0 : dev->dev_ops->rxq_info_get(dev, queue_id, qinfo);
6188 [ # # ]: 0 : qinfo->queue_state = dev->data->rx_queue_state[queue_id];
6189 : :
6190 : 0 : rte_eth_trace_rx_queue_info_get(port_id, queue_id, qinfo);
6191 : :
6192 : 0 : return 0;
6193 : : }
6194 : :
6195 : : int
6196 : 0 : rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id,
6197 : : struct rte_eth_txq_info *qinfo)
6198 : : {
6199 : : struct rte_eth_dev *dev;
6200 : :
6201 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6202 : 0 : dev = &rte_eth_devices[port_id];
6203 : :
6204 [ # # ]: 0 : if (queue_id >= dev->data->nb_tx_queues) {
6205 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", queue_id);
6206 : 0 : return -EINVAL;
6207 : : }
6208 : :
6209 [ # # ]: 0 : if (qinfo == NULL) {
6210 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get ethdev port %u Tx queue %u info to NULL",
6211 : : port_id, queue_id);
6212 : 0 : return -EINVAL;
6213 : : }
6214 : :
6215 [ # # ]: 0 : if (dev->data->tx_queues == NULL ||
6216 [ # # ]: 0 : dev->data->tx_queues[queue_id] == NULL) {
6217 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6218 : : "Tx queue %"PRIu16" of device with port_id=%"
6219 : : PRIu16" has not been setup",
6220 : : queue_id, port_id);
6221 : 0 : return -EINVAL;
6222 : : }
6223 : :
6224 [ # # ]: 0 : if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) {
6225 : 0 : RTE_ETHDEV_LOG_LINE(INFO,
6226 : : "Can't get hairpin Tx queue %"PRIu16" info of device with port_id=%"PRIu16,
6227 : : queue_id, port_id);
6228 : 0 : return -EINVAL;
6229 : : }
6230 : :
6231 [ # # ]: 0 : if (dev->dev_ops->txq_info_get == NULL)
6232 : : return -ENOTSUP;
6233 : :
6234 : : memset(qinfo, 0, sizeof(*qinfo));
6235 : 0 : dev->dev_ops->txq_info_get(dev, queue_id, qinfo);
6236 [ # # ]: 0 : qinfo->queue_state = dev->data->tx_queue_state[queue_id];
6237 : :
6238 : 0 : rte_eth_trace_tx_queue_info_get(port_id, queue_id, qinfo);
6239 : :
6240 : 0 : return 0;
6241 : : }
6242 : :
6243 : : int
6244 : 0 : rte_eth_recycle_rx_queue_info_get(uint16_t port_id, uint16_t queue_id,
6245 : : struct rte_eth_recycle_rxq_info *recycle_rxq_info)
6246 : : {
6247 : : struct rte_eth_dev *dev;
6248 : : int ret;
6249 : :
6250 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6251 : 0 : dev = &rte_eth_devices[port_id];
6252 : :
6253 : 0 : ret = eth_dev_validate_rx_queue(dev, queue_id);
6254 [ # # ]: 0 : if (unlikely(ret != 0))
6255 : : return ret;
6256 : :
6257 [ # # ]: 0 : if (dev->dev_ops->recycle_rxq_info_get == NULL)
6258 : : return -ENOTSUP;
6259 : :
6260 : 0 : dev->dev_ops->recycle_rxq_info_get(dev, queue_id, recycle_rxq_info);
6261 : :
6262 : 0 : return 0;
6263 : : }
6264 : :
6265 : : int
6266 : 0 : rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
6267 : : struct rte_eth_burst_mode *mode)
6268 : : {
6269 : : struct rte_eth_dev *dev;
6270 : : int ret;
6271 : :
6272 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6273 : 0 : dev = &rte_eth_devices[port_id];
6274 : :
6275 [ # # ]: 0 : if (queue_id >= dev->data->nb_rx_queues) {
6276 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id);
6277 : 0 : return -EINVAL;
6278 : : }
6279 : :
6280 [ # # ]: 0 : if (mode == NULL) {
6281 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6282 : : "Cannot get ethdev port %u Rx queue %u burst mode to NULL",
6283 : : port_id, queue_id);
6284 : 0 : return -EINVAL;
6285 : : }
6286 : :
6287 [ # # ]: 0 : if (dev->dev_ops->rx_burst_mode_get == NULL)
6288 : : return -ENOTSUP;
6289 : : memset(mode, 0, sizeof(*mode));
6290 : 0 : ret = eth_err(port_id,
6291 : 0 : dev->dev_ops->rx_burst_mode_get(dev, queue_id, mode));
6292 : :
6293 : 0 : rte_eth_trace_rx_burst_mode_get(port_id, queue_id, mode, ret);
6294 : :
6295 : 0 : return ret;
6296 : : }
6297 : :
6298 : : int
6299 : 0 : rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
6300 : : struct rte_eth_burst_mode *mode)
6301 : : {
6302 : : struct rte_eth_dev *dev;
6303 : : int ret;
6304 : :
6305 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6306 : 0 : dev = &rte_eth_devices[port_id];
6307 : :
6308 [ # # ]: 0 : if (queue_id >= dev->data->nb_tx_queues) {
6309 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", queue_id);
6310 : 0 : return -EINVAL;
6311 : : }
6312 : :
6313 [ # # ]: 0 : if (mode == NULL) {
6314 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6315 : : "Cannot get ethdev port %u Tx queue %u burst mode to NULL",
6316 : : port_id, queue_id);
6317 : 0 : return -EINVAL;
6318 : : }
6319 : :
6320 [ # # ]: 0 : if (dev->dev_ops->tx_burst_mode_get == NULL)
6321 : : return -ENOTSUP;
6322 : : memset(mode, 0, sizeof(*mode));
6323 : 0 : ret = eth_err(port_id,
6324 : 0 : dev->dev_ops->tx_burst_mode_get(dev, queue_id, mode));
6325 : :
6326 : 0 : rte_eth_trace_tx_burst_mode_get(port_id, queue_id, mode, ret);
6327 : :
6328 : 0 : return ret;
6329 : : }
6330 : :
6331 : : int
6332 : 0 : rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
6333 : : struct rte_power_monitor_cond *pmc)
6334 : : {
6335 : : struct rte_eth_dev *dev;
6336 : : int ret;
6337 : :
6338 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6339 : : dev = &rte_eth_devices[port_id];
6340 : :
6341 [ # # ]: 0 : if (queue_id >= dev->data->nb_rx_queues) {
6342 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id);
6343 : 0 : return -EINVAL;
6344 : : }
6345 : :
6346 [ # # ]: 0 : if (pmc == NULL) {
6347 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6348 : : "Cannot get ethdev port %u Rx queue %u power monitor condition to NULL",
6349 : : port_id, queue_id);
6350 : 0 : return -EINVAL;
6351 : : }
6352 : :
6353 [ # # ]: 0 : if (dev->dev_ops->get_monitor_addr == NULL)
6354 : : return -ENOTSUP;
6355 : 0 : ret = eth_err(port_id,
6356 : 0 : dev->dev_ops->get_monitor_addr(dev->data->rx_queues[queue_id], pmc));
6357 : :
6358 : 0 : rte_eth_trace_get_monitor_addr(port_id, queue_id, pmc, ret);
6359 : :
6360 : 0 : return ret;
6361 : : }
6362 : :
6363 : : int
6364 : 0 : rte_eth_dev_set_mc_addr_list(uint16_t port_id,
6365 : : struct rte_ether_addr *mc_addr_set,
6366 : : uint32_t nb_mc_addr)
6367 : : {
6368 : : struct rte_eth_dev *dev;
6369 : : int ret;
6370 : :
6371 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6372 : 0 : dev = &rte_eth_devices[port_id];
6373 : :
6374 [ # # ]: 0 : if (dev->dev_ops->set_mc_addr_list == NULL)
6375 : : return -ENOTSUP;
6376 : 0 : ret = eth_err(port_id, dev->dev_ops->set_mc_addr_list(dev,
6377 : : mc_addr_set, nb_mc_addr));
6378 : :
6379 : 0 : rte_ethdev_trace_set_mc_addr_list(port_id, mc_addr_set, nb_mc_addr,
6380 : : ret);
6381 : :
6382 : 0 : return ret;
6383 : : }
6384 : :
6385 : : int
6386 : 0 : rte_eth_timesync_enable(uint16_t port_id)
6387 : : {
6388 : : struct rte_eth_dev *dev;
6389 : : int ret;
6390 : :
6391 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6392 : 0 : dev = &rte_eth_devices[port_id];
6393 : :
6394 [ # # ]: 0 : if (dev->dev_ops->timesync_enable == NULL)
6395 : : return -ENOTSUP;
6396 : 0 : ret = eth_err(port_id, dev->dev_ops->timesync_enable(dev));
6397 : :
6398 : 0 : rte_eth_trace_timesync_enable(port_id, ret);
6399 : :
6400 : 0 : return ret;
6401 : : }
6402 : :
6403 : : int
6404 : 0 : rte_eth_timesync_disable(uint16_t port_id)
6405 : : {
6406 : : struct rte_eth_dev *dev;
6407 : : int ret;
6408 : :
6409 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6410 : 0 : dev = &rte_eth_devices[port_id];
6411 : :
6412 [ # # ]: 0 : if (dev->dev_ops->timesync_disable == NULL)
6413 : : return -ENOTSUP;
6414 : 0 : ret = eth_err(port_id, dev->dev_ops->timesync_disable(dev));
6415 : :
6416 : 0 : rte_eth_trace_timesync_disable(port_id, ret);
6417 : :
6418 : 0 : return ret;
6419 : : }
6420 : :
6421 : : int
6422 : 0 : rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
6423 : : uint32_t flags)
6424 : : {
6425 : : struct rte_eth_dev *dev;
6426 : : int ret;
6427 : :
6428 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6429 : 0 : dev = &rte_eth_devices[port_id];
6430 : :
6431 [ # # ]: 0 : if (timestamp == NULL) {
6432 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6433 : : "Cannot read ethdev port %u Rx timestamp to NULL",
6434 : : port_id);
6435 : 0 : return -EINVAL;
6436 : : }
6437 : :
6438 [ # # ]: 0 : if (dev->dev_ops->timesync_read_rx_timestamp == NULL)
6439 : : return -ENOTSUP;
6440 : :
6441 : 0 : ret = eth_err(port_id, dev->dev_ops->timesync_read_rx_timestamp(dev, timestamp, flags));
6442 : :
6443 : : rte_eth_trace_timesync_read_rx_timestamp(port_id, timestamp, flags,
6444 : : ret);
6445 : :
6446 : 0 : return ret;
6447 : : }
6448 : :
6449 : : int
6450 : 0 : rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
6451 : : struct timespec *timestamp)
6452 : : {
6453 : : struct rte_eth_dev *dev;
6454 : : int ret;
6455 : :
6456 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6457 : 0 : dev = &rte_eth_devices[port_id];
6458 : :
6459 [ # # ]: 0 : if (timestamp == NULL) {
6460 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6461 : : "Cannot read ethdev port %u Tx timestamp to NULL",
6462 : : port_id);
6463 : 0 : return -EINVAL;
6464 : : }
6465 : :
6466 [ # # ]: 0 : if (dev->dev_ops->timesync_read_tx_timestamp == NULL)
6467 : : return -ENOTSUP;
6468 : :
6469 : 0 : ret = eth_err(port_id, dev->dev_ops->timesync_read_tx_timestamp(dev, timestamp));
6470 : :
6471 : : rte_eth_trace_timesync_read_tx_timestamp(port_id, timestamp, ret);
6472 : :
6473 : 0 : return ret;
6474 : :
6475 : : }
6476 : :
6477 : : int
6478 : 0 : rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta)
6479 : : {
6480 : : struct rte_eth_dev *dev;
6481 : : int ret;
6482 : :
6483 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6484 : 0 : dev = &rte_eth_devices[port_id];
6485 : :
6486 [ # # ]: 0 : if (dev->dev_ops->timesync_adjust_time == NULL)
6487 : : return -ENOTSUP;
6488 : 0 : ret = eth_err(port_id, dev->dev_ops->timesync_adjust_time(dev, delta));
6489 : :
6490 : : rte_eth_trace_timesync_adjust_time(port_id, delta, ret);
6491 : :
6492 : 0 : return ret;
6493 : : }
6494 : :
6495 : : int
6496 : 0 : rte_eth_timesync_adjust_freq(uint16_t port_id, int64_t ppm)
6497 : : {
6498 : : struct rte_eth_dev *dev;
6499 : : int ret;
6500 : :
6501 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6502 : 0 : dev = &rte_eth_devices[port_id];
6503 : :
6504 [ # # ]: 0 : if (dev->dev_ops->timesync_adjust_freq == NULL)
6505 : : return -ENOTSUP;
6506 : 0 : ret = eth_err(port_id, dev->dev_ops->timesync_adjust_freq(dev, ppm));
6507 : :
6508 : : rte_eth_trace_timesync_adjust_freq(port_id, ppm, ret);
6509 : :
6510 : 0 : return ret;
6511 : : }
6512 : :
6513 : : int
6514 : 0 : rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
6515 : : {
6516 : : struct rte_eth_dev *dev;
6517 : : int ret;
6518 : :
6519 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6520 : 0 : dev = &rte_eth_devices[port_id];
6521 : :
6522 [ # # ]: 0 : if (timestamp == NULL) {
6523 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6524 : : "Cannot read ethdev port %u timesync time to NULL",
6525 : : port_id);
6526 : 0 : return -EINVAL;
6527 : : }
6528 : :
6529 [ # # ]: 0 : if (dev->dev_ops->timesync_read_time == NULL)
6530 : : return -ENOTSUP;
6531 : 0 : ret = eth_err(port_id, dev->dev_ops->timesync_read_time(dev, timestamp));
6532 : :
6533 : : rte_eth_trace_timesync_read_time(port_id, timestamp, ret);
6534 : :
6535 : 0 : return ret;
6536 : : }
6537 : :
6538 : : int
6539 : 0 : rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
6540 : : {
6541 : : struct rte_eth_dev *dev;
6542 : : int ret;
6543 : :
6544 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6545 : 0 : dev = &rte_eth_devices[port_id];
6546 : :
6547 [ # # ]: 0 : if (timestamp == NULL) {
6548 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6549 : : "Cannot write ethdev port %u timesync from NULL time",
6550 : : port_id);
6551 : 0 : return -EINVAL;
6552 : : }
6553 : :
6554 [ # # ]: 0 : if (dev->dev_ops->timesync_write_time == NULL)
6555 : : return -ENOTSUP;
6556 : 0 : ret = eth_err(port_id, dev->dev_ops->timesync_write_time(dev, timestamp));
6557 : :
6558 : 0 : rte_eth_trace_timesync_write_time(port_id, timestamp, ret);
6559 : :
6560 : 0 : return ret;
6561 : : }
6562 : :
6563 : : int
6564 : 0 : rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
6565 : : {
6566 : : struct rte_eth_dev *dev;
6567 : : int ret;
6568 : :
6569 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6570 : 0 : dev = &rte_eth_devices[port_id];
6571 : :
6572 [ # # ]: 0 : if (clock == NULL) {
6573 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot read ethdev port %u clock to NULL",
6574 : : port_id);
6575 : 0 : return -EINVAL;
6576 : : }
6577 : :
6578 [ # # ]: 0 : if (dev->dev_ops->read_clock == NULL)
6579 : : return -ENOTSUP;
6580 : 0 : ret = eth_err(port_id, dev->dev_ops->read_clock(dev, clock));
6581 : :
6582 : 0 : rte_eth_trace_read_clock(port_id, clock, ret);
6583 : :
6584 : 0 : return ret;
6585 : : }
6586 : :
6587 : : int
6588 : 0 : rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
6589 : : {
6590 : 0 : struct rte_dev_reg_info reg_info = { 0 };
6591 : : int ret;
6592 : :
6593 [ # # ]: 0 : if (info == NULL) {
6594 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6595 : : "Cannot get ethdev port %u register info to NULL",
6596 : : port_id);
6597 : 0 : return -EINVAL;
6598 : : }
6599 : :
6600 : 0 : reg_info.length = info->length;
6601 : 0 : reg_info.width = info->width;
6602 : 0 : reg_info.offset = info->offset;
6603 : 0 : reg_info.data = info->data;
6604 : :
6605 : 0 : ret = rte_eth_dev_get_reg_info_ext(port_id, ®_info);
6606 [ # # ]: 0 : if (ret != 0)
6607 : : return ret;
6608 : :
6609 : 0 : info->length = reg_info.length;
6610 : 0 : info->width = reg_info.width;
6611 : 0 : info->version = reg_info.version;
6612 : 0 : info->offset = reg_info.offset;
6613 : :
6614 : 0 : return 0;
6615 : : }
6616 : :
6617 : : int
6618 : 0 : rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
6619 : : {
6620 : : struct rte_eth_dev *dev;
6621 : : uint32_t i;
6622 : : int ret;
6623 : :
6624 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6625 : 0 : dev = &rte_eth_devices[port_id];
6626 : :
6627 [ # # ]: 0 : if (info == NULL) {
6628 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6629 : : "Cannot get ethdev port %u register info to NULL",
6630 : : port_id);
6631 : 0 : return -EINVAL;
6632 : : }
6633 : :
6634 [ # # # # ]: 0 : if (info->names != NULL && info->length != 0)
6635 : 0 : memset(info->names, 0, sizeof(struct rte_eth_reg_name) * info->length);
6636 : :
6637 [ # # ]: 0 : if (dev->dev_ops->get_reg == NULL)
6638 : : return -ENOTSUP;
6639 : 0 : ret = eth_err(port_id, dev->dev_ops->get_reg(dev, info));
6640 : :
6641 : 0 : rte_ethdev_trace_get_reg_info(port_id, info, ret);
6642 : :
6643 : : /* Report the default names if drivers not report. */
6644 [ # # # # : 0 : if (ret == 0 && info->names != NULL && strlen(info->names[0].name) == 0) {
# # ]
6645 [ # # ]: 0 : for (i = 0; i < info->length; i++)
6646 : 0 : snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
6647 : 0 : "index_%u", info->offset + i);
6648 : : }
6649 : : return ret;
6650 : : }
6651 : :
6652 : : int
6653 : 0 : rte_eth_dev_get_eeprom_length(uint16_t port_id)
6654 : : {
6655 : : struct rte_eth_dev *dev;
6656 : : int ret;
6657 : :
6658 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6659 : 0 : dev = &rte_eth_devices[port_id];
6660 : :
6661 [ # # ]: 0 : if (dev->dev_ops->get_eeprom_length == NULL)
6662 : : return -ENOTSUP;
6663 : 0 : ret = eth_err(port_id, dev->dev_ops->get_eeprom_length(dev));
6664 : :
6665 : 0 : rte_ethdev_trace_get_eeprom_length(port_id, ret);
6666 : :
6667 : 0 : return ret;
6668 : : }
6669 : :
6670 : : int
6671 : 0 : rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
6672 : : {
6673 : : struct rte_eth_dev *dev;
6674 : : int ret;
6675 : :
6676 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6677 : 0 : dev = &rte_eth_devices[port_id];
6678 : :
6679 [ # # ]: 0 : if (info == NULL) {
6680 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6681 : : "Cannot get ethdev port %u EEPROM info to NULL",
6682 : : port_id);
6683 : 0 : return -EINVAL;
6684 : : }
6685 : :
6686 [ # # ]: 0 : if (dev->dev_ops->get_eeprom == NULL)
6687 : : return -ENOTSUP;
6688 : 0 : ret = eth_err(port_id, dev->dev_ops->get_eeprom(dev, info));
6689 : :
6690 : 0 : rte_ethdev_trace_get_eeprom(port_id, info, ret);
6691 : :
6692 : 0 : return ret;
6693 : : }
6694 : :
6695 : : int
6696 : 0 : rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
6697 : : {
6698 : : struct rte_eth_dev *dev;
6699 : : int ret;
6700 : :
6701 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6702 : 0 : dev = &rte_eth_devices[port_id];
6703 : :
6704 [ # # ]: 0 : if (info == NULL) {
6705 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6706 : : "Cannot set ethdev port %u EEPROM from NULL info",
6707 : : port_id);
6708 : 0 : return -EINVAL;
6709 : : }
6710 : :
6711 [ # # ]: 0 : if (dev->dev_ops->set_eeprom == NULL)
6712 : : return -ENOTSUP;
6713 : 0 : ret = eth_err(port_id, dev->dev_ops->set_eeprom(dev, info));
6714 : :
6715 : 0 : rte_ethdev_trace_set_eeprom(port_id, info, ret);
6716 : :
6717 : 0 : return ret;
6718 : : }
6719 : :
6720 : : int
6721 : 0 : rte_eth_dev_get_module_info(uint16_t port_id,
6722 : : struct rte_eth_dev_module_info *modinfo)
6723 : : {
6724 : : struct rte_eth_dev *dev;
6725 : : int ret;
6726 : :
6727 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6728 : 0 : dev = &rte_eth_devices[port_id];
6729 : :
6730 [ # # ]: 0 : if (modinfo == NULL) {
6731 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6732 : : "Cannot get ethdev port %u EEPROM module info to NULL",
6733 : : port_id);
6734 : 0 : return -EINVAL;
6735 : : }
6736 : :
6737 [ # # ]: 0 : if (dev->dev_ops->get_module_info == NULL)
6738 : : return -ENOTSUP;
6739 : 0 : ret = dev->dev_ops->get_module_info(dev, modinfo);
6740 : :
6741 : 0 : rte_ethdev_trace_get_module_info(port_id, modinfo, ret);
6742 : :
6743 : 0 : return ret;
6744 : : }
6745 : :
6746 : : int
6747 : 0 : rte_eth_dev_get_module_eeprom(uint16_t port_id,
6748 : : struct rte_dev_eeprom_info *info)
6749 : : {
6750 : : struct rte_eth_dev *dev;
6751 : : int ret;
6752 : :
6753 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6754 : 0 : dev = &rte_eth_devices[port_id];
6755 : :
6756 [ # # ]: 0 : if (info == NULL) {
6757 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6758 : : "Cannot get ethdev port %u module EEPROM info to NULL",
6759 : : port_id);
6760 : 0 : return -EINVAL;
6761 : : }
6762 : :
6763 [ # # ]: 0 : if (info->data == NULL) {
6764 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6765 : : "Cannot get ethdev port %u module EEPROM data to NULL",
6766 : : port_id);
6767 : 0 : return -EINVAL;
6768 : : }
6769 : :
6770 [ # # ]: 0 : if (info->length == 0) {
6771 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6772 : : "Cannot get ethdev port %u module EEPROM to data with zero size",
6773 : : port_id);
6774 : 0 : return -EINVAL;
6775 : : }
6776 : :
6777 [ # # ]: 0 : if (dev->dev_ops->get_module_eeprom == NULL)
6778 : : return -ENOTSUP;
6779 : 0 : ret = dev->dev_ops->get_module_eeprom(dev, info);
6780 : :
6781 : 0 : rte_ethdev_trace_get_module_eeprom(port_id, info, ret);
6782 : :
6783 : 0 : return ret;
6784 : : }
6785 : :
6786 : : int
6787 : 0 : rte_eth_dev_get_dcb_info(uint16_t port_id,
6788 : : struct rte_eth_dcb_info *dcb_info)
6789 : : {
6790 : : struct rte_eth_dev *dev;
6791 : : int ret;
6792 : :
6793 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6794 : 0 : dev = &rte_eth_devices[port_id];
6795 : :
6796 [ # # ]: 0 : if (dcb_info == NULL) {
6797 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6798 : : "Cannot get ethdev port %u DCB info to NULL",
6799 : : port_id);
6800 : 0 : return -EINVAL;
6801 : : }
6802 : :
6803 : : memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
6804 : :
6805 [ # # ]: 0 : if (dev->dev_ops->get_dcb_info == NULL)
6806 : : return -ENOTSUP;
6807 : 0 : ret = eth_err(port_id, dev->dev_ops->get_dcb_info(dev, dcb_info));
6808 : :
6809 : 0 : rte_ethdev_trace_get_dcb_info(port_id, dcb_info, ret);
6810 : :
6811 : 0 : return ret;
6812 : : }
6813 : :
6814 : : static void
6815 : : eth_dev_adjust_nb_desc(uint16_t *nb_desc,
6816 : : const struct rte_eth_desc_lim *desc_lim)
6817 : : {
6818 : : /* Upcast to uint32 to avoid potential overflow with RTE_ALIGN_CEIL(). */
6819 : 0 : uint32_t nb_desc_32 = (uint32_t)*nb_desc;
6820 : :
6821 [ # # # # ]: 0 : if (desc_lim->nb_align != 0)
6822 : 0 : nb_desc_32 = RTE_ALIGN_CEIL(nb_desc_32, desc_lim->nb_align);
6823 : :
6824 [ # # # # ]: 0 : if (desc_lim->nb_max != 0)
6825 : 0 : nb_desc_32 = RTE_MIN(nb_desc_32, desc_lim->nb_max);
6826 : :
6827 : 0 : nb_desc_32 = RTE_MAX(nb_desc_32, desc_lim->nb_min);
6828 : :
6829 : : /* Assign clipped u32 back to u16. */
6830 : 0 : *nb_desc = (uint16_t)nb_desc_32;
6831 : 0 : }
6832 : :
6833 : : int
6834 : 0 : rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id,
6835 : : uint16_t *nb_rx_desc,
6836 : : uint16_t *nb_tx_desc)
6837 : : {
6838 : : struct rte_eth_dev_info dev_info;
6839 : : int ret;
6840 : :
6841 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6842 : :
6843 : 0 : ret = rte_eth_dev_info_get(port_id, &dev_info);
6844 [ # # ]: 0 : if (ret != 0)
6845 : : return ret;
6846 : :
6847 [ # # ]: 0 : if (nb_rx_desc != NULL)
6848 : : eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim);
6849 : :
6850 [ # # ]: 0 : if (nb_tx_desc != NULL)
6851 : : eth_dev_adjust_nb_desc(nb_tx_desc, &dev_info.tx_desc_lim);
6852 : :
6853 : 0 : rte_ethdev_trace_adjust_nb_rx_tx_desc(port_id);
6854 : :
6855 : 0 : return 0;
6856 : : }
6857 : :
6858 : : int
6859 : 0 : rte_eth_dev_hairpin_capability_get(uint16_t port_id,
6860 : : struct rte_eth_hairpin_cap *cap)
6861 : : {
6862 : : struct rte_eth_dev *dev;
6863 : : int ret;
6864 : :
6865 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6866 : 0 : dev = &rte_eth_devices[port_id];
6867 : :
6868 [ # # ]: 0 : if (cap == NULL) {
6869 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6870 : : "Cannot get ethdev port %u hairpin capability to NULL",
6871 : : port_id);
6872 : 0 : return -EINVAL;
6873 : : }
6874 : :
6875 [ # # ]: 0 : if (dev->dev_ops->hairpin_cap_get == NULL)
6876 : : return -ENOTSUP;
6877 : : memset(cap, 0, sizeof(*cap));
6878 : 0 : ret = eth_err(port_id, dev->dev_ops->hairpin_cap_get(dev, cap));
6879 : :
6880 : 0 : rte_ethdev_trace_hairpin_capability_get(port_id, cap, ret);
6881 : :
6882 : 0 : return ret;
6883 : : }
6884 : :
6885 : : int
6886 : 0 : rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
6887 : : {
6888 : : struct rte_eth_dev *dev;
6889 : : int ret;
6890 : :
6891 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6892 : 0 : dev = &rte_eth_devices[port_id];
6893 : :
6894 [ # # ]: 0 : if (pool == NULL) {
6895 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6896 : : "Cannot test ethdev port %u mempool operation from NULL pool",
6897 : : port_id);
6898 : 0 : return -EINVAL;
6899 : : }
6900 : :
6901 [ # # ]: 0 : if (dev->dev_ops->pool_ops_supported == NULL)
6902 : : return 1; /* all pools are supported */
6903 : :
6904 : 0 : ret = dev->dev_ops->pool_ops_supported(dev, pool);
6905 : :
6906 : 0 : rte_ethdev_trace_pool_ops_supported(port_id, pool, ret);
6907 : :
6908 : 0 : return ret;
6909 : : }
6910 : :
6911 : : int
6912 : 0 : rte_eth_representor_info_get(uint16_t port_id,
6913 : : struct rte_eth_representor_info *info)
6914 : : {
6915 : : struct rte_eth_dev *dev;
6916 : : int ret;
6917 : :
6918 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6919 : 0 : dev = &rte_eth_devices[port_id];
6920 : :
6921 [ # # ]: 0 : if (dev->dev_ops->representor_info_get == NULL)
6922 : : return -ENOTSUP;
6923 : 0 : ret = eth_err(port_id, dev->dev_ops->representor_info_get(dev, info));
6924 : :
6925 : 0 : rte_eth_trace_representor_info_get(port_id, info, ret);
6926 : :
6927 : 0 : return ret;
6928 : : }
6929 : :
6930 : : int
6931 : 0 : rte_eth_rx_metadata_negotiate(uint16_t port_id, uint64_t *features)
6932 : : {
6933 : : struct rte_eth_dev *dev;
6934 : : int ret;
6935 : :
6936 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6937 : 0 : dev = &rte_eth_devices[port_id];
6938 : :
6939 [ # # ]: 0 : if (dev->data->dev_configured != 0) {
6940 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6941 : : "The port (ID=%"PRIu16") is already configured",
6942 : : port_id);
6943 : 0 : return -EBUSY;
6944 : : }
6945 : :
6946 [ # # ]: 0 : if (features == NULL) {
6947 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid features (NULL)");
6948 : 0 : return -EINVAL;
6949 : : }
6950 : :
6951 [ # # # # ]: 0 : if ((*features & RTE_ETH_RX_METADATA_TUNNEL_ID) != 0 &&
6952 : 0 : rte_flow_restore_info_dynflag_register() < 0)
6953 : 0 : *features &= ~RTE_ETH_RX_METADATA_TUNNEL_ID;
6954 : :
6955 [ # # ]: 0 : if (dev->dev_ops->rx_metadata_negotiate == NULL)
6956 : : return -ENOTSUP;
6957 : 0 : ret = eth_err(port_id,
6958 : : dev->dev_ops->rx_metadata_negotiate(dev, features));
6959 : :
6960 [ # # ]: 0 : rte_eth_trace_rx_metadata_negotiate(port_id, *features, ret);
6961 : :
6962 : 0 : return ret;
6963 : : }
6964 : :
6965 : : int
6966 : 0 : rte_eth_ip_reassembly_capability_get(uint16_t port_id,
6967 : : struct rte_eth_ip_reassembly_params *reassembly_capa)
6968 : : {
6969 : : struct rte_eth_dev *dev;
6970 : : int ret;
6971 : :
6972 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
6973 : 0 : dev = &rte_eth_devices[port_id];
6974 : :
6975 [ # # ]: 0 : if (dev->data->dev_configured == 0) {
6976 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
6977 : : "port_id=%u is not configured, cannot get IP reassembly capability",
6978 : : port_id);
6979 : 0 : return -EINVAL;
6980 : : }
6981 : :
6982 [ # # ]: 0 : if (reassembly_capa == NULL) {
6983 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get reassembly capability to NULL");
6984 : 0 : return -EINVAL;
6985 : : }
6986 : :
6987 [ # # ]: 0 : if (dev->dev_ops->ip_reassembly_capability_get == NULL)
6988 : : return -ENOTSUP;
6989 : : memset(reassembly_capa, 0, sizeof(struct rte_eth_ip_reassembly_params));
6990 : :
6991 : 0 : ret = eth_err(port_id,
6992 : 0 : dev->dev_ops->ip_reassembly_capability_get(dev, reassembly_capa));
6993 : :
6994 : 0 : rte_eth_trace_ip_reassembly_capability_get(port_id, reassembly_capa,
6995 : : ret);
6996 : :
6997 : 0 : return ret;
6998 : : }
6999 : :
7000 : : int
7001 : 0 : rte_eth_ip_reassembly_conf_get(uint16_t port_id,
7002 : : struct rte_eth_ip_reassembly_params *conf)
7003 : : {
7004 : : struct rte_eth_dev *dev;
7005 : : int ret;
7006 : :
7007 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
7008 : 0 : dev = &rte_eth_devices[port_id];
7009 : :
7010 [ # # ]: 0 : if (dev->data->dev_configured == 0) {
7011 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
7012 : : "port_id=%u is not configured, cannot get IP reassembly configuration",
7013 : : port_id);
7014 : 0 : return -EINVAL;
7015 : : }
7016 : :
7017 [ # # ]: 0 : if (conf == NULL) {
7018 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Cannot get reassembly info to NULL");
7019 : 0 : return -EINVAL;
7020 : : }
7021 : :
7022 [ # # ]: 0 : if (dev->dev_ops->ip_reassembly_conf_get == NULL)
7023 : : return -ENOTSUP;
7024 : : memset(conf, 0, sizeof(struct rte_eth_ip_reassembly_params));
7025 : 0 : ret = eth_err(port_id,
7026 : 0 : dev->dev_ops->ip_reassembly_conf_get(dev, conf));
7027 : :
7028 : 0 : rte_eth_trace_ip_reassembly_conf_get(port_id, conf, ret);
7029 : :
7030 : 0 : return ret;
7031 : : }
7032 : :
7033 : : int
7034 : 0 : rte_eth_ip_reassembly_conf_set(uint16_t port_id,
7035 : : const struct rte_eth_ip_reassembly_params *conf)
7036 : : {
7037 : : struct rte_eth_dev *dev;
7038 : : int ret;
7039 : :
7040 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
7041 : 0 : dev = &rte_eth_devices[port_id];
7042 : :
7043 [ # # ]: 0 : if (dev->data->dev_configured == 0) {
7044 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
7045 : : "port_id=%u is not configured, cannot set IP reassembly configuration",
7046 : : port_id);
7047 : 0 : return -EINVAL;
7048 : : }
7049 : :
7050 [ # # ]: 0 : if (dev->data->dev_started != 0) {
7051 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
7052 : : "port_id=%u is started, cannot configure IP reassembly params.",
7053 : : port_id);
7054 : 0 : return -EINVAL;
7055 : : }
7056 : :
7057 [ # # ]: 0 : if (conf == NULL) {
7058 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
7059 : : "Invalid IP reassembly configuration (NULL)");
7060 : 0 : return -EINVAL;
7061 : : }
7062 : :
7063 [ # # ]: 0 : if (dev->dev_ops->ip_reassembly_conf_set == NULL)
7064 : : return -ENOTSUP;
7065 : 0 : ret = eth_err(port_id,
7066 : : dev->dev_ops->ip_reassembly_conf_set(dev, conf));
7067 : :
7068 : 0 : rte_eth_trace_ip_reassembly_conf_set(port_id, conf, ret);
7069 : :
7070 : 0 : return ret;
7071 : : }
7072 : :
7073 : : int
7074 : 0 : rte_eth_dev_priv_dump(uint16_t port_id, FILE *file)
7075 : : {
7076 : : struct rte_eth_dev *dev;
7077 : :
7078 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
7079 : 0 : dev = &rte_eth_devices[port_id];
7080 : :
7081 [ # # ]: 0 : if (file == NULL) {
7082 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid file (NULL)");
7083 : 0 : return -EINVAL;
7084 : : }
7085 : :
7086 [ # # ]: 0 : if (dev->dev_ops->eth_dev_priv_dump == NULL)
7087 : : return -ENOTSUP;
7088 : 0 : return eth_err(port_id, dev->dev_ops->eth_dev_priv_dump(dev, file));
7089 : : }
7090 : :
7091 : : int
7092 : 0 : rte_eth_rx_descriptor_dump(uint16_t port_id, uint16_t queue_id,
7093 : : uint16_t offset, uint16_t num, FILE *file)
7094 : : {
7095 : : struct rte_eth_dev *dev;
7096 : :
7097 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
7098 : 0 : dev = &rte_eth_devices[port_id];
7099 : :
7100 [ # # ]: 0 : if (queue_id >= dev->data->nb_rx_queues) {
7101 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Rx queue_id=%u", queue_id);
7102 : 0 : return -EINVAL;
7103 : : }
7104 : :
7105 [ # # ]: 0 : if (file == NULL) {
7106 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid file (NULL)");
7107 : 0 : return -EINVAL;
7108 : : }
7109 : :
7110 [ # # ]: 0 : if (dev->dev_ops->eth_rx_descriptor_dump == NULL)
7111 : : return -ENOTSUP;
7112 : :
7113 : 0 : return eth_err(port_id,
7114 : : dev->dev_ops->eth_rx_descriptor_dump(dev, queue_id, offset, num, file));
7115 : : }
7116 : :
7117 : : int
7118 : 0 : rte_eth_tx_descriptor_dump(uint16_t port_id, uint16_t queue_id,
7119 : : uint16_t offset, uint16_t num, FILE *file)
7120 : : {
7121 : : struct rte_eth_dev *dev;
7122 : :
7123 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
7124 : 0 : dev = &rte_eth_devices[port_id];
7125 : :
7126 [ # # ]: 0 : if (queue_id >= dev->data->nb_tx_queues) {
7127 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", queue_id);
7128 : 0 : return -EINVAL;
7129 : : }
7130 : :
7131 [ # # ]: 0 : if (file == NULL) {
7132 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid file (NULL)");
7133 : 0 : return -EINVAL;
7134 : : }
7135 : :
7136 [ # # ]: 0 : if (dev->dev_ops->eth_tx_descriptor_dump == NULL)
7137 : : return -ENOTSUP;
7138 : :
7139 : 0 : return eth_err(port_id,
7140 : : dev->dev_ops->eth_tx_descriptor_dump(dev, queue_id, offset, num, file));
7141 : : }
7142 : :
7143 : : int
7144 : 0 : rte_eth_buffer_split_get_supported_hdr_ptypes(uint16_t port_id, uint32_t *ptypes, int num)
7145 : : {
7146 : : size_t i;
7147 : : int j;
7148 : : struct rte_eth_dev *dev;
7149 : : const uint32_t *all_types;
7150 : 0 : size_t no_of_elements = 0;
7151 : :
7152 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
7153 : 0 : dev = &rte_eth_devices[port_id];
7154 : :
7155 [ # # ]: 0 : if (ptypes == NULL && num > 0) {
7156 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
7157 : : "Cannot get ethdev port %u supported header protocol types to NULL when array size is non zero",
7158 : : port_id);
7159 : 0 : return -EINVAL;
7160 : : }
7161 : :
7162 [ # # ]: 0 : if (dev->dev_ops->buffer_split_supported_hdr_ptypes_get == NULL)
7163 : : return -ENOTSUP;
7164 : 0 : all_types = dev->dev_ops->buffer_split_supported_hdr_ptypes_get(dev, &no_of_elements);
7165 : :
7166 [ # # ]: 0 : if (all_types == NULL)
7167 : : return 0;
7168 : :
7169 [ # # ]: 0 : for (i = 0, j = 0; i < no_of_elements; ++i) {
7170 [ # # ]: 0 : if (j < num) {
7171 [ # # ]: 0 : ptypes[j] = all_types[i];
7172 : :
7173 : 0 : rte_eth_trace_buffer_split_get_supported_hdr_ptypes(
7174 : : port_id, j, ptypes[j]);
7175 : : }
7176 : 0 : j++;
7177 : : }
7178 : :
7179 : : return j;
7180 : : }
7181 : :
7182 : 0 : int rte_eth_dev_count_aggr_ports(uint16_t port_id)
7183 : : {
7184 : : struct rte_eth_dev *dev;
7185 : : int ret;
7186 : :
7187 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
7188 : 0 : dev = &rte_eth_devices[port_id];
7189 : :
7190 [ # # ]: 0 : if (dev->dev_ops->count_aggr_ports == NULL)
7191 : : return 0;
7192 : 0 : ret = eth_err(port_id, dev->dev_ops->count_aggr_ports(dev));
7193 : :
7194 : 0 : rte_eth_trace_count_aggr_ports(port_id, ret);
7195 : :
7196 : 0 : return ret;
7197 : : }
7198 : :
7199 : 0 : int rte_eth_dev_map_aggr_tx_affinity(uint16_t port_id, uint16_t tx_queue_id,
7200 : : uint8_t affinity)
7201 : : {
7202 : : struct rte_eth_dev *dev;
7203 : : int aggr_ports;
7204 : : int ret;
7205 : :
7206 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
7207 : 0 : dev = &rte_eth_devices[port_id];
7208 : :
7209 [ # # ]: 0 : if (tx_queue_id >= dev->data->nb_tx_queues) {
7210 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "Invalid Tx queue_id=%u", tx_queue_id);
7211 : 0 : return -EINVAL;
7212 : : }
7213 : :
7214 [ # # ]: 0 : if (dev->dev_ops->map_aggr_tx_affinity == NULL)
7215 : : return -ENOTSUP;
7216 : :
7217 [ # # ]: 0 : if (dev->data->dev_configured == 0) {
7218 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
7219 : : "Port %u must be configured before Tx affinity mapping",
7220 : : port_id);
7221 : 0 : return -EINVAL;
7222 : : }
7223 : :
7224 [ # # ]: 0 : if (dev->data->dev_started) {
7225 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
7226 : : "Port %u must be stopped to allow configuration",
7227 : : port_id);
7228 : 0 : return -EBUSY;
7229 : : }
7230 : :
7231 : 0 : aggr_ports = rte_eth_dev_count_aggr_ports(port_id);
7232 [ # # ]: 0 : if (aggr_ports == 0) {
7233 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
7234 : : "Port %u has no aggregated port",
7235 : : port_id);
7236 : 0 : return -ENOTSUP;
7237 : : }
7238 : :
7239 [ # # ]: 0 : if (affinity > aggr_ports) {
7240 : 0 : RTE_ETHDEV_LOG_LINE(ERR,
7241 : : "Port %u map invalid affinity %u exceeds the maximum number %u",
7242 : : port_id, affinity, aggr_ports);
7243 : 0 : return -EINVAL;
7244 : : }
7245 : :
7246 : 0 : ret = eth_err(port_id,
7247 : 0 : dev->dev_ops->map_aggr_tx_affinity(dev, tx_queue_id, affinity));
7248 : :
7249 : 0 : rte_eth_trace_map_aggr_tx_affinity(port_id, tx_queue_id, affinity, ret);
7250 : :
7251 : 0 : return ret;
7252 : : }
7253 : :
7254 [ - + ]: 252 : RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO);
|