1..  SPDX-License-Identifier: BSD-3-Clause
2    Copyright(c) 2017 Intel Corporation.
3
4Event Ethernet Rx Adapter Library
5=================================
6
7The DPDK Eventdev API allows the application to use an event driven programming
8model for packet processing. In this model, the application polls an event
9device port for receiving events that reference packets instead of polling Rx
10queues of ethdev ports. Packet transfer between ethdev and the event device can
11be supported in hardware or require a software thread to receive packets from
12the ethdev port using ethdev poll mode APIs and enqueue these as events to the
13event device using the eventdev API. Both transfer mechanisms may be present on
14the same platform depending on the particular combination of the ethdev and
15the event device.
16
17The Event Ethernet Rx Adapter library is intended for the application code to
18configure both transfer mechanisms using a common API. A capability API allows
19the eventdev PMD to advertise features supported for a given ethdev and allows
20the application to perform configuration as per supported features.
21
22API Walk-through
23----------------
24
25This section will introduce the reader to the adapter API. The
26application has to first instantiate an adapter which is associated with
27a single eventdev, next the adapter instance is configured with Rx queues
28that are either polled by a SW thread or linked using hardware support. Finally
29the adapter is started.
30
31For SW based packet transfers from ethdev to eventdev, the adapter uses a
32DPDK service function and the application is also required to assign a core to
33the service function.
34
35Creating an Adapter Instance
36~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37
38An adapter instance is created using ``rte_event_eth_rx_adapter_create()``. This
39function is passed the event device to be associated with the adapter and port
40configuration for the adapter to setup an event port if the adapter needs to use
41a service function.
42
43.. code-block:: c
44
45        int err;
46        uint8_t dev_id;
47        struct rte_event_dev_info dev_info;
48        struct rte_event_port_conf rx_p_conf;
49
50        err = rte_event_dev_info_get(id, &dev_info);
51
52        rx_p_conf.new_event_threshold = dev_info.max_num_events;
53        rx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth;
54        rx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth;
55        err = rte_event_eth_rx_adapter_create(id, dev_id, &rx_p_conf);
56
57If the application desires to have finer control of eventdev port allocation
58and setup, it can use the ``rte_event_eth_rx_adapter_create_ext()`` function.
59The ``rte_event_eth_rx_adapter_create_ext()`` function is passed a callback
60function. The callback function is invoked if the adapter needs to use a
61service function and needs to create an event port for it. The callback is
62expected to fill the ``struct rte_event_eth_rx_adapter_conf structure``
63passed to it.
64
65Adding Rx Queues to the Adapter Instance
66~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
67
68Ethdev Rx queues are added to the instance using the
69``rte_event_eth_rx_adapter_queue_add()`` function. Configuration for the Rx
70queue is passed in using a ``struct rte_event_eth_rx_adapter_queue_conf``
71parameter. Event information for packets from this Rx queue is encoded in the
72``ev`` field of ``struct rte_event_eth_rx_adapter_queue_conf``. The
73servicing_weight member of the struct  rte_event_eth_rx_adapter_queue_conf
74is the relative polling frequency of the Rx queue and is applicable when the
75adapter uses a service core function.
76
77.. code-block:: c
78
79        ev.queue_id = 0;
80        ev.sched_type = RTE_SCHED_TYPE_ATOMIC;
81        ev.priority = 0;
82
83        queue_config.rx_queue_flags = 0;
84        queue_config.ev = ev;
85        queue_config.servicing_weight = 1;
86
87        err = rte_event_eth_rx_adapter_queue_add(id,
88                                                eth_dev_id,
89                                                0, &queue_config);
90
91Querying Adapter Capabilities
92~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
93
94The ``rte_event_eth_rx_adapter_caps_get()`` function allows
95the application to query the adapter capabilities for an eventdev and ethdev
96combination. For e.g, if the ``RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID``
97is set, the application can override the adapter generated flow ID in the event
98using ``rx_queue_flags`` field in ``struct rte_event_eth_rx_adapter_queue_conf``
99which is passed as a parameter to the ``rte_event_eth_rx_adapter_queue_add()``
100function.
101
102.. code-block:: c
103
104        err = rte_event_eth_rx_adapter_caps_get(dev_id, eth_dev_id, &cap);
105
106        queue_config.rx_queue_flags = 0;
107        if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) {
108                ev.flow_id = 1;
109                queue_config.rx_queue_flags =
110                        RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID;
111        }
112
113Configuring the Service Function
114~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115
116If the adapter uses a service function, the application is required to assign
117a service core to the service function as show below.
118
119.. code-block:: c
120
121        uint32_t service_id;
122
123        if (rte_event_eth_rx_adapter_service_id_get(0, &service_id) == 0)
124                rte_service_map_lcore_set(service_id, RX_CORE_ID);
125
126Starting the Adapter Instance
127~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
128
129The application calls ``rte_event_eth_rx_adapter_start()`` to start the adapter.
130This function calls the start callbacks of the eventdev PMDs for hardware based
131eventdev-ethdev connections and ``rte_service_run_state_set()`` to enable the
132service function if one exists.
133
134.. Note::
135
136         The eventdev to which the event_eth_rx_adapter is connected needs to
137         be started before calling rte_event_eth_rx_adapter_start().
138
139Getting Adapter Statistics
140~~~~~~~~~~~~~~~~~~~~~~~~~~
141
142The  ``rte_event_eth_rx_adapter_stats_get()`` function reports counters defined
143in struct ``rte_event_eth_rx_adapter_stats``. The received packet and
144enqueued event counts are a sum of the counts from the eventdev PMD callbacks
145if the callback is supported, and the counts maintained by the service function,
146if one exists. The service function also maintains a count of cycles for which
147it was not able to enqueue to the event device.
148
149Interrupt Based Rx Queues
150~~~~~~~~~~~~~~~~~~~~~~~~~~
151
152The service core function is typically set up to poll ethernet Rx queues for
153packets. Certain queues may have low packet rates and it would be more
154efficient to enable the Rx queue interrupt and read packets after receiving
155the interrupt.
156
157The servicing_weight member of struct rte_event_eth_rx_adapter_queue_conf
158is applicable when the adapter uses a service core function. The application
159has to enable Rx queue interrupts when configuring the ethernet device
160using the ``rte_eth_dev_configure()`` function and then use a servicing_weight
161of zero when adding the Rx queue to the adapter.
162
163The adapter creates a thread blocked on the interrupt, on an interrupt this
164thread enqueues the port id and the queue id to a ring buffer. The adapter
165service function dequeues the port id and queue id from the ring buffer,
166invokes the ``rte_eth_rx_burst()`` to receive packets on the queue and
167converts the received packets to events in the same manner as packets
168received on a polled Rx queue. The interrupt thread is affinitized to the same
169CPUs as the lcores of the Rx adapter service function, if the Rx adapter
170service function has not been mapped to any lcores, the interrupt thread
171is mapped to the main lcore.
172
173Rx Callback for SW Rx Adapter
174~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
175
176For SW based packet transfers, i.e., when the
177``RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT`` is not set in the adapter's
178capabilities flags for a particular ethernet device, the service function
179temporarily enqueues mbufs to an event buffer before batch enqueuing these
180to the event device. If the buffer fills up, the service function stops
181dequeuing packets from the ethernet device. The application may want to
182monitor the buffer fill level and instruct the service function to selectively
183enqueue packets to the event device. The application may also use some other
184criteria to decide which packets should enter the event device even when
185the event buffer fill level is low. The
186``rte_event_eth_rx_adapter_cb_register()`` function allow the application
187to register a callback that selects which packets to enqueue to the event
188device.
189