1.. SPDX-License-Identifier: BSD-3-Clause 2 Copyright(c) 2017 Intel Corporation. 3 4Event Ethernet Tx Adapter Library 5================================= 6 7The DPDK Eventdev API allows the application to use an event driven programming 8model for packet processing in which the event device distributes events 9referencing packets to the application cores in a dynamic load balanced fashion 10while handling atomicity and packet ordering. Event adapters provide the interface 11between the ethernet, crypto and timer devices and the event device. Event adapter 12APIs enable common application code by abstracting PMD specific capabilities. 13The Event ethernet Tx adapter provides configuration and data path APIs for the 14transmit stage of the application allowing the same application code to use eventdev 15PMD support or in its absence, a common implementation. 16 17In the common implementation, the application enqueues mbufs to the adapter 18which runs as a rte_service function. The service function dequeues events 19from its event port and transmits the mbufs referenced by these events. 20 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 Tx queues, 28finally the adapter is started and the application can start enqueuing mbufs 29to it. 30 31Creating an Adapter Instance 32~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33 34An adapter instance is created using ``rte_event_eth_tx_adapter_create()``. This 35function is passed the event device to be associated with the adapter and port 36configuration for the adapter to setup an event port if the adapter needs to use 37a service function. 38 39If the application desires to have finer control of eventdev port configuration, 40it 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. 42The callback function is invoked if the adapter needs to use a service function 43and 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 59Adding Tx Queues to the Adapter Instance 60~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 61 62Ethdev Tx queues are added to the instance using the 63``rte_event_eth_tx_adapter_queue_add()`` function. A queue value 64of -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 72Querying Adapter Capabilities 73~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 74 75The ``rte_event_eth_tx_adapter_caps_get()`` function allows 76the application to query the adapter capabilities for an eventdev and ethdev 77combination. Currently, the only capability flag defined is 78``RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT``, the application can 79query this flag to determine if a service function is associated with the 80adapter 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 91Linking a Queue to the Adapter's Event Port 92~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 93 94If the adapter uses a service function as described in the previous section, the 95application is required to link a queue to the adapter's event port. The adapter's 96event port can be obtained using the ``rte_event_eth_tx_adapter_event_port_get()`` 97function. The queue can be configured with the ``RTE_EVENT_QUEUE_CFG_SINGLE_LINK`` 98since it is linked to a single event port. 99 100Configuring the Service Function 101~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 102 103If the adapter uses a service function, the application can assign 104a 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 111Starting the Adapter Instance 112~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 113 114The application calls ``rte_event_eth_tx_adapter_start()`` to start the adapter. 115This function calls the start callback of the eventdev PMD if supported, 116and the ``rte_service_run_state_set()`` to enable the service function if one exists. 117 118Enqueuing Packets to the Adapter 119~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 120 121The application needs to notify the adapter about the transmit port and queue used 122to send the packet. The transmit port is set in the ``struct rte mbuf::port`` field 123and the transmit queue is set using the ``rte_event_eth_tx_adapter_txq_set()`` 124function. 125 126If the eventdev PMD supports the ``RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT`` 127capability 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 130If the adapter uses a service function for the ethernet device then the application 131should 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 eq_flags = 0; 141 142 m->port = tx_port; 143 rte_event_eth_tx_adapter_txq_set(m, tx_queue_id); 144 145 rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1, eq_flags); 146 } else { 147 148 event.queue_id = qid; /* event queue linked to adapter port */ 149 event.op = RTE_EVENT_OP_NEW; 150 event.event_type = RTE_EVENT_TYPE_CPU; 151 event.sched_type = RTE_SCHED_TYPE_ATOMIC; 152 event.mbuf = m; 153 154 m->port = tx_port; 155 rte_event_eth_tx_adapter_txq_set(m, tx_queue_id); 156 157 rte_event_enqueue_burst(dev_id, ev_port, &event, 1); 158 } 159 160Getting Adapter Statistics 161~~~~~~~~~~~~~~~~~~~~~~~~~~ 162 163The ``rte_event_eth_tx_adapter_stats_get()`` function reports counters defined 164in struct ``rte_event_eth_tx_adapter_stats``. The counter values are the sum of 165the counts from the eventdev PMD callback if the callback is supported, and 166the counts maintained by the service function, if one exists. 167