xref: /dpdk/lib/eventdev/rte_event_eth_tx_adapter.h (revision 3a80d7fb2ecdd6e8e48e56e3726b26980fa2a089)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation.
3  */
4 
5 #ifndef _RTE_EVENT_ETH_TX_ADAPTER_
6 #define _RTE_EVENT_ETH_TX_ADAPTER_
7 
8 /**
9  * @file
10  *
11  * RTE Event Ethernet Tx Adapter
12  *
13  * The event ethernet Tx adapter provides configuration and data path APIs
14  * for the ethernet transmit stage of an event driven packet processing
15  * application. These APIs abstract the implementation of the transmit stage
16  * and allow the application to use eventdev PMD support or a common
17  * implementation.
18  *
19  * In the common implementation, the application enqueues mbufs to the adapter
20  * which runs as a rte_service function. The service function dequeues events
21  * from its event port and transmits the mbufs referenced by these events.
22  *
23  * The ethernet Tx event adapter APIs are:
24  *
25  *  - rte_event_eth_tx_adapter_create()
26  *  - rte_event_eth_tx_adapter_create_ext()
27  *  - rte_event_eth_tx_adapter_free()
28  *  - rte_event_eth_tx_adapter_start()
29  *  - rte_event_eth_tx_adapter_stop()
30  *  - rte_event_eth_tx_adapter_queue_add()
31  *  - rte_event_eth_tx_adapter_queue_del()
32  *  - rte_event_eth_tx_adapter_stats_get()
33  *  - rte_event_eth_tx_adapter_stats_reset()
34  *  - rte_event_eth_tx_adapter_enqueue()
35  *  - rte_event_eth_tx_adapter_event_port_get()
36  *  - rte_event_eth_tx_adapter_service_id_get()
37  *  - rte_event_eth_tx_adapter_instance_get()
38  *  - rte_event_eth_tx_adapter_queue_start()
39  *  - rte_event_eth_tx_adapter_queue_stop()
40  *
41  * The application creates the adapter using
42  * rte_event_eth_tx_adapter_create() or rte_event_eth_tx_adapter_create_ext().
43  *
44  * The adapter will use the common implementation when the eventdev PMD
45  * does not have the #RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT capability.
46  * The common implementation uses an event port that is created using the port
47  * configuration parameter passed to rte_event_eth_tx_adapter_create(). The
48  * application can get the port identifier using
49  * rte_event_eth_tx_adapter_event_port_get() and must link an event queue to
50  * this port.
51  *
52  * If the eventdev PMD has the #RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT
53  * flags set, Tx adapter events should be enqueued using the
54  * rte_event_eth_tx_adapter_enqueue() function, else the application should
55  * use rte_event_enqueue_burst().
56  *
57  * Transmit queues can be added and deleted from the adapter using
58  * rte_event_eth_tx_adapter_queue_add()/del() APIs respectively.
59  *
60  * The application can start and stop the adapter using the
61  * rte_event_eth_tx_adapter_start/stop() calls.
62  *
63  * The common adapter implementation uses an EAL service function as described
64  * before and its execution is controlled using the rte_service APIs. The
65  * rte_event_eth_tx_adapter_service_id_get()
66  * function can be used to retrieve the adapter's service function ID.
67  *
68  * The ethernet port and transmit queue index to transmit the mbuf on are
69  * specified using the mbuf port struct rte_mbuf::hash::txadapter:txq.
70  * The application should use the rte_event_eth_tx_adapter_txq_set()
71  * and rte_event_eth_tx_adapter_txq_get() functions to access the transmit
72  * queue index, using these macros will help with minimizing application
73  * impact due to a change in how the transmit queue index is specified.
74  */
75 
76 #ifdef __cplusplus
77 extern "C" {
78 #endif
79 
80 #include <stdint.h>
81 
82 #include <rte_compat.h>
83 #include <rte_mbuf.h>
84 
85 #include "rte_eventdev.h"
86 
87 /**
88  * Adapter configuration structure
89  *
90  * @see rte_event_eth_tx_adapter_create_ext
91  * @see rte_event_eth_tx_adapter_conf_cb
92  */
93 struct rte_event_eth_tx_adapter_conf {
94 	uint8_t event_port_id;
95 	/**< Event port identifier, the adapter service function dequeues mbuf
96 	 * events from this port.
97 	 * @see RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT
98 	 */
99 	uint32_t max_nb_tx;
100 	/**< The adapter can return early if it has processed at least
101 	 * max_nb_tx mbufs. This isn't treated as a requirement; batching may
102 	 * cause the adapter to process more than max_nb_tx mbufs.
103 	 */
104 };
105 
106 /**
107  * Function type used for adapter configuration callback. The callback is
108  * used to fill in members of the struct rte_event_eth_tx_adapter_conf, this
109  * callback is invoked when creating a RTE service function based
110  * adapter implementation.
111  *
112  * @param id
113  *  Adapter identifier.
114  * @param dev_id
115  *  Event device identifier.
116  * @param [out] conf
117  *  Structure that needs to be populated by this callback.
118  * @param arg
119  *  Argument to the callback. This is the same as the conf_arg passed to the
120  *  rte_event_eth_tx_adapter_create_ext().
121  *
122  * @return
123  *   - 0: Success
124  *   - <0: Error code on failure
125  */
126 typedef int (*rte_event_eth_tx_adapter_conf_cb) (uint8_t id, uint8_t dev_id,
127 				struct rte_event_eth_tx_adapter_conf *conf,
128 				void *arg);
129 
130 /**
131  * A structure used to retrieve statistics for an ethernet Tx adapter instance.
132  */
133 struct rte_event_eth_tx_adapter_stats {
134 	uint64_t tx_retry;
135 	/**< Number of transmit retries */
136 	uint64_t tx_packets;
137 	/**< Number of packets transmitted */
138 	uint64_t tx_dropped;
139 	/**< Number of packets dropped */
140 };
141 
142 /**
143  * Create a new ethernet Tx adapter with the specified identifier.
144  *
145  * When this API is used for creating adapter instance,
146  * ``rte_event_dev_config::nb_event_ports`` is automatically incremented,
147  * and event device is reconfigured with additional event port during service
148  * initialization. This event device reconfigure logic also increments the
149  * ``rte_event_dev_config::nb_single_link_event_port_queues``
150  * parameter if the adapter event port config is of type
151  * ``RTE_EVENT_PORT_CFG_SINGLE_LINK``.
152  *
153  * Application no longer needs to account for the
154  * ``rte_event_dev_config::nb_event_ports`` and
155  * ``rte_event_dev_config::nb_single_link_event_port_queues``
156  * parameters required for eth Tx adapter in event device configure when
157  * the adapter is created with this API.
158  *
159  * @param id
160  *  The identifier of the ethernet Tx adapter.
161  * @param dev_id
162  *  The event device identifier.
163  * @param port_config
164  *  Event port configuration, the adapter uses this configuration to
165  *  create an event port if needed.
166  * @return
167  *   - 0: Success
168  *   - <0: Error code on failure
169  */
170 int
171 rte_event_eth_tx_adapter_create(uint8_t id, uint8_t dev_id,
172 				struct rte_event_port_conf *port_config);
173 
174 /**
175  * Create a new ethernet Tx adapter with the specified identifier.
176  *
177  * @param id
178  *  The identifier of the ethernet Tx adapter.
179  * @param dev_id
180  *  The event device identifier.
181  * @param conf_cb
182  *  Callback function that initializes members of the
183  *  struct rte_event_eth_tx_adapter_conf struct passed into
184  *  it.
185  * @param conf_arg
186  *  Argument that is passed to the conf_cb function.
187  * @return
188  *   - 0: Success
189  *   - <0: Error code on failure
190  */
191 int
192 rte_event_eth_tx_adapter_create_ext(uint8_t id, uint8_t dev_id,
193 				rte_event_eth_tx_adapter_conf_cb conf_cb,
194 				void *conf_arg);
195 
196 /**
197  * Free an ethernet Tx adapter
198  *
199  * @param id
200  *  Adapter identifier.
201  * @return
202  *   - 0: Success
203  *   - <0: Error code on failure, If the adapter still has Tx queues
204  *      added to it, the function returns -EBUSY.
205  */
206 int
207 rte_event_eth_tx_adapter_free(uint8_t id);
208 
209 /**
210  * Start ethernet Tx adapter
211  *
212  * @param id
213  *  Adapter identifier.
214  * @return
215  *  - 0: Success, Adapter started correctly.
216  *  - <0: Error code on failure.
217  */
218 int
219 rte_event_eth_tx_adapter_start(uint8_t id);
220 
221 /**
222  * Stop ethernet Tx adapter
223  *
224  * @param id
225  *  Adapter identifier.
226  * @return
227  *  - 0: Success.
228  *  - <0: Error code on failure.
229  */
230 int
231 rte_event_eth_tx_adapter_stop(uint8_t id);
232 
233 /**
234  * Add a Tx queue to the adapter.
235  * A queue value of -1 is used to indicate all
236  * queues within the device.
237  *
238  * @param id
239  *  Adapter identifier.
240  * @param eth_dev_id
241  *  Ethernet Port Identifier.
242  * @param queue
243  *  Tx queue index.
244  * @return
245  *  - 0: Success, Queues added successfully.
246  *  - <0: Error code on failure.
247  */
248 int
249 rte_event_eth_tx_adapter_queue_add(uint8_t id,
250 				uint16_t eth_dev_id,
251 				int32_t queue);
252 
253 /**
254  * Delete a Tx queue from the adapter.
255  * A queue value of -1 is used to indicate all
256  * queues within the device, that have been added to this
257  * adapter.
258  *
259  * @param id
260  *  Adapter identifier.
261  * @param eth_dev_id
262  *  Ethernet Port Identifier.
263  * @param queue
264  *  Tx queue index.
265  * @return
266  *  - 0: Success, Queues deleted successfully.
267  *  - <0: Error code on failure.
268  */
269 int
270 rte_event_eth_tx_adapter_queue_del(uint8_t id,
271 				uint16_t eth_dev_id,
272 				int32_t queue);
273 
274 /**
275  * Set Tx queue in the mbuf. This queue is used by the adapter
276  * to transmit the mbuf.
277  *
278  * @param pkt
279  *  Pointer to the mbuf.
280  * @param queue
281  *  Tx queue index.
282  */
283 static __rte_always_inline void
284 rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
285 {
286 	pkt->hash.txadapter.txq = queue;
287 }
288 
289 /**
290  * Retrieve Tx queue from the mbuf.
291  *
292  * @param pkt
293  *  Pointer to the mbuf.
294  * @return
295  *  Tx queue identifier.
296  *
297  * @see rte_event_eth_tx_adapter_txq_set()
298  */
299 static __rte_always_inline uint16_t
300 rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
301 {
302 	return pkt->hash.txadapter.txq;
303 }
304 
305 /**
306  * Retrieve the adapter event port. The adapter creates an event port if
307  * the #RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT is not set in the
308  * ethernet Tx capabilities of the event device.
309  *
310  * @param id
311  *  Adapter Identifier.
312  * @param[out] event_port_id
313  *  Event port pointer.
314  * @return
315  *   - 0: Success.
316  *   - <0: Error code on failure.
317  */
318 int
319 rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
320 
321 #define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST	0x1
322 /**< This flag is used when all the packets enqueued in the tx adapter are
323  * destined for the same Ethernet port & Tx queue.
324  */
325 
326 /**
327  * Enqueue a burst of events objects or an event object supplied in *rte_event*
328  * structure on an  event device designated by its *dev_id* through the event
329  * port specified by *port_id*. This function is supported if the eventdev PMD
330  * has the #RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT capability flag set.
331  *
332  * The *nb_events* parameter is the number of event objects to enqueue which are
333  * supplied in the *ev* array of *rte_event* structure.
334  *
335  * The rte_event_eth_tx_adapter_enqueue() function returns the number of
336  * events objects it actually enqueued. A return value equal to *nb_events*
337  * means that all event objects have been enqueued.
338  *
339  * @param dev_id
340  *  The identifier of the device.
341  * @param port_id
342  *  The identifier of the event port.
343  * @param ev
344  *  Points to an array of *nb_events* objects of type *rte_event* structure
345  *  which contain the event object enqueue operations to be processed.
346  * @param nb_events
347  *  The number of event objects to enqueue, typically number of
348  *  rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
349  *  available for this port.
350  * @param flags
351  *  RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
352  *  #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies that all the packets
353  *  which are enqueued are destined for the same Ethernet port & Tx queue.
354  *
355  * @return
356  *   The number of event objects actually enqueued on the event device. The
357  *   return value can be less than the value of the *nb_events* parameter when
358  *   the event devices queue is full or if invalid parameters are specified in a
359  *   *rte_event*. If the return value is less than *nb_events*, the remaining
360  *   events at the end of ev[] are not consumed and the caller has to take care
361  *   of them, and rte_errno is set accordingly. Possible errno values include:
362  *   - EINVAL   The port ID is invalid, device ID is invalid, an event's queue
363  *              ID is invalid, or an event's sched type doesn't match the
364  *              capabilities of the destination queue.
365  *   - ENOSPC   The event port was backpressured and unable to enqueue
366  *              one or more events. This error code is only applicable to
367  *              closed systems.
368  */
369 static inline uint16_t
370 rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
371 				uint8_t port_id,
372 				struct rte_event ev[],
373 				uint16_t nb_events,
374 				const uint8_t flags)
375 {
376 	const struct rte_event_fp_ops *fp_ops;
377 	void *port;
378 
379 	fp_ops = &rte_event_fp_ops[dev_id];
380 	port = fp_ops->data[port_id];
381 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG
382 	if (dev_id >= RTE_EVENT_MAX_DEVS ||
383 	    port_id >= RTE_EVENT_MAX_PORTS_PER_DEV) {
384 		rte_errno = EINVAL;
385 		return 0;
386 	}
387 
388 	if (port == NULL) {
389 		rte_errno = EINVAL;
390 		return 0;
391 	}
392 #endif
393 	rte_eventdev_trace_eth_tx_adapter_enqueue(dev_id, port_id, ev,
394 		nb_events, flags);
395 	if (flags)
396 		return fp_ops->txa_enqueue_same_dest(port, ev, nb_events);
397 	else
398 		return fp_ops->txa_enqueue(port, ev, nb_events);
399 }
400 
401 /**
402  * Retrieve statistics for an adapter
403  *
404  * @param id
405  *  Adapter identifier.
406  * @param [out] stats
407  *  A pointer to structure used to retrieve statistics for an adapter.
408  * @return
409  *  - 0: Success, statistics retrieved successfully.
410  *  - <0: Error code on failure.
411  */
412 int
413 rte_event_eth_tx_adapter_stats_get(uint8_t id,
414 				struct rte_event_eth_tx_adapter_stats *stats);
415 
416 /**
417  * Reset statistics for an adapter.
418  *
419  * @param id
420  *  Adapter identifier.
421  * @return
422  *  - 0: Success, statistics reset successfully.
423  *  - <0: Error code on failure.
424  */
425 int
426 rte_event_eth_tx_adapter_stats_reset(uint8_t id);
427 
428 /**
429  * Retrieve the service ID of an adapter. If the adapter doesn't use
430  * a rte_service function, this function returns -ESRCH.
431  *
432  * @param id
433  *  Adapter identifier.
434  * @param [out] service_id
435  *  A pointer to a uint32_t, to be filled in with the service id.
436  * @return
437  *  - 0: Success
438  *  - <0: Error code on failure, if the adapter doesn't use a rte_service
439  * function, this function returns -ESRCH.
440  */
441 int
442 rte_event_eth_tx_adapter_service_id_get(uint8_t id, uint32_t *service_id);
443 
444 /**
445  * Get TX adapter instance id for TX queue
446  *
447  * @param eth_dev_id
448  *  Port identifier of Ethernet device
449  *
450  * @param tx_queue_id
451  *  Etherdev device TX queue index
452  *
453  * @param[out] txa_inst_id
454  *  Pointer to TX adapter instance identifier
455  *  Contains valid Tx adapter instance id when return value is 0
456  *
457  * @return
458  *  -  0: Success
459  *  - <0: Error code on failure
460  */
461 __rte_experimental
462 int
463 rte_event_eth_tx_adapter_instance_get(uint16_t eth_dev_id,
464 				      uint16_t tx_queue_id,
465 				      uint8_t *txa_inst_id);
466 /**
467  * Enables the adapter to start enqueueing of packets to the
468  * Tx queue.
469  *
470  * This function is provided so that the application can
471  * resume enqueueing packets that reference packets for
472  * <eth_dev_id, tx_queue_id> after calling
473  * rte_event_eth_tx_adapter_queue_stop().
474  * @see rte_event_eth_tx_adapter_queue_stop
475  *
476  * Use case:
477  * --------
478  * The queue start/stop APIs help avoid some unexpected behavior with
479  * application stopping ethdev Tx queues and adapter being unaware of it.
480  * With these APIs, the application can call stop API to notify adapter
481  * that corresponding ethdev Tx queue is stopped and any in-flight
482  * packets are freed by adapter dataplane code. Adapter queue stop API
483  * is called before stopping the ethdev Tx queue. When ethdev Tx queue
484  * is enabled, application can notify adapter to resume processing of
485  * the packets for that queue by calling the start API. The ethdev Tx
486  * queue is started before calling adapter start API.
487  *
488  * @param eth_dev_id
489  *  Port identifier of Ethernet device.
490  * @param tx_queue_id
491  *  Ethernet device transmit queue index.
492  * @return
493  *   - 0: Success
494  *   - <0: Error code on failure
495  */
496 __rte_experimental
497 int
498 rte_event_eth_tx_adapter_queue_start(uint16_t eth_dev_id, uint16_t tx_queue_id);
499 
500 /**
501  * Stops the adapter runtime function from enqueueing any packets
502  * to the associated Tx queue. This API also frees any packets that may
503  * have been buffered for this queue. All inflight packets destined to the
504  * queue are freed by the adapter runtime until the queue is started again.
505  * @see rte_event_eth_tx_adapter_queue_start
506  *
507  * @param eth_dev_id
508  *  Port identifier of Ethernet device.
509  * @param tx_queue_id
510  *  Ethernet device transmit queue index.
511  * @return
512  *   - 0: Success
513  *   - <0: Error code on failure
514  */
515 __rte_experimental
516 int
517 rte_event_eth_tx_adapter_queue_stop(uint16_t eth_dev_id, uint16_t tx_queue_id);
518 
519 #ifdef __cplusplus
520 }
521 #endif
522 #endif	/* _RTE_EVENT_ETH_TX_ADAPTER_ */
523