New upstream version 18.11-rc1
[deb_dpdk.git] / doc / guides / prog_guide / event_ethernet_tx_adapter.rst
1 ..  SPDX-License-Identifier: BSD-3-Clause
2     Copyright(c) 2017 Intel Corporation.
3
4 Event Ethernet Tx Adapter Library
5 =================================
6
7 The DPDK Eventdev API allows the application to use an event driven programming
8 model for packet processing in which the event device distributes events
9 referencing packets to the application cores in a dynamic load balanced fashion
10 while handling atomicity and packet ordering. Event adapters provide the interface
11 between the ethernet, crypto and timer devices and the event device. Event adapter
12 APIs enable common application code by abstracting PMD specific capabilities.
13 The Event ethernet Tx adapter provides configuration and data path APIs for the
14 transmit stage of the application allowing the same application code to use eventdev
15 PMD support or in its absence, a common implementation.
16
17 In the common implementation, the application enqueues mbufs to the adapter
18 which runs as a rte_service function. The service function dequeues events
19 from its event port and transmits the mbufs referenced by these events.
20
21
22 API Walk-through
23 ----------------
24
25 This section will introduce the reader to the adapter API. The
26 application has to first instantiate an adapter which is associated with
27 a single eventdev, next the adapter instance is configured with Tx queues,
28 finally the adapter is started and the application can start enqueuing mbufs
29 to it.
30
31 Creating an Adapter Instance
32 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33
34 An adapter instance is created using ``rte_event_eth_tx_adapter_create()``. This
35 function is passed the event device to be associated with the adapter and port
36 configuration for the adapter to setup an event port if the adapter needs to use
37 a service function.
38
39 If the application desires to have finer control of eventdev port configuration,
40 it can use the ``rte_event_eth_tx_adapter_create_ext()`` function. The
41 ``rte_event_eth_tx_adapter_create_ext()`` function is passed a callback function.
42 The callback function is invoked if the adapter needs to use a service function
43 and needs to create an event port for it. The callback is expected to fill the
44 ``struct rte_event_eth_tx_adapter_conf`` structure passed to it.
45
46 .. code-block:: c
47
48         struct rte_event_dev_info dev_info;
49         struct rte_event_port_conf tx_p_conf = {0};
50
51         err = rte_event_dev_info_get(id, &dev_info);
52
53         tx_p_conf.new_event_threshold = dev_info.max_num_events;
54         tx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth;
55         tx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth;
56
57         err = rte_event_eth_tx_adapter_create(id, dev_id, &tx_p_conf);
58
59 Adding Tx Queues to the Adapter Instance
60 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
61
62 Ethdev Tx queues are added to the instance using the
63 ``rte_event_eth_tx_adapter_queue_add()`` function. A queue value
64 of -1 is used to indicate all queues within a device.
65
66 .. code-block:: c
67
68         int err = rte_event_eth_tx_adapter_queue_add(id,
69                                                      eth_dev_id,
70                                                      q);
71
72 Querying Adapter Capabilities
73 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
74
75 The ``rte_event_eth_tx_adapter_caps_get()`` function allows
76 the application to query the adapter capabilities for an eventdev and ethdev
77 combination. Currently, the only capability flag defined is
78 ``RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT``, the application can
79 query this flag to determine if a service function is associated with the
80 adapter and retrieve its service identifier using the
81 ``rte_event_eth_tx_adapter_service_id_get()`` API.
82
83
84 .. code-block:: c
85
86         int err = rte_event_eth_tx_adapter_caps_get(dev_id, eth_dev_id, &cap);
87
88         if (!(cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT))
89                 err = rte_event_eth_tx_adapter_service_id_get(id, &service_id);
90
91 Linking a Queue to the Adapter's Event Port
92 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
93
94 If the adapter uses a service function as described in the previous section, the
95 application is required to link a queue to the adapter's event port. The adapter's
96 event port can be obtained using the ``rte_event_eth_tx_adapter_event_port_get()``
97 function. The queue can be configured with the ``RTE_EVENT_QUEUE_CFG_SINGLE_LINK``
98 since it is linked to a single event port.
99
100 Configuring the Service Function
101 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102
103 If the adapter uses a service function, the application can assign
104 a service core to the service function as shown below.
105
106 .. code-block:: c
107
108         if (rte_event_eth_tx_adapter_service_id_get(id, &service_id) == 0)
109                 rte_service_map_lcore_set(service_id, TX_CORE_ID);
110
111 Starting the Adapter Instance
112 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
113
114 The application calls ``rte_event_eth_tx_adapter_start()`` to start the adapter.
115 This function calls the start callback of the eventdev PMD if supported,
116 and the ``rte_service_run_state_set()`` to enable the service function if one exists.
117
118 Enqueuing Packets to the Adapter
119 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120
121 The application needs to notify the adapter about the transmit port and queue used
122 to send the packet. The transmit port is set in the ``struct rte mbuf::port`` field
123 and the transmit queue is set using the ``rte_event_eth_tx_adapter_txq_set()``
124 function.
125
126 If the eventdev PMD supports the ``RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT``
127 capability for a given ethernet device, the application should use the
128 ``rte_event_eth_tx_adapter_enqueue()`` function to enqueue packets to the adapter.
129
130 If the adapter uses a service function for the ethernet device then the application
131 should use the ``rte_event_enqueue_burst()`` function.
132
133 .. code-block:: c
134
135         struct rte_event event;
136
137         if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
138
139                 event.mbuf = m;
140
141                 m->port = tx_port;
142                 rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
143
144                 rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1);
145         } else {
146
147                 event.queue_id = qid; /* event queue linked to adapter port */
148                 event.op = RTE_EVENT_OP_NEW;
149                 event.event_type = RTE_EVENT_TYPE_CPU;
150                 event.sched_type = RTE_SCHED_TYPE_ATOMIC;
151                 event.mbuf = m;
152
153                 m->port = tx_port;
154                 rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
155
156                 rte_event_enqueue_burst(dev_id, ev_port, &event, 1);
157         }
158
159 Getting Adapter Statistics
160 ~~~~~~~~~~~~~~~~~~~~~~~~~~
161
162 The  ``rte_event_eth_tx_adapter_stats_get()`` function reports counters defined
163 in struct ``rte_event_eth_tx_adapter_stats``. The counter values are the sum of
164 the counts from the eventdev PMD callback if the callback is supported, and
165 the counts maintained by the service function, if one exists.