1*41dd9a6bSDavid Young.. SPDX-License-Identifier: BSD-3-Clause 2*41dd9a6bSDavid Young Copyright(c) 2017 Intel Corporation. 3*41dd9a6bSDavid Young 4*41dd9a6bSDavid YoungEvent Ethernet Rx Adapter Library 5*41dd9a6bSDavid Young================================= 6*41dd9a6bSDavid Young 7*41dd9a6bSDavid YoungThe DPDK Eventdev API allows the application to use an event driven programming 8*41dd9a6bSDavid Youngmodel for packet processing. In this model, the application polls an event 9*41dd9a6bSDavid Youngdevice port for receiving events that reference packets instead of polling Rx 10*41dd9a6bSDavid Youngqueues of ethdev ports. Packet transfer between ethdev and the event device can 11*41dd9a6bSDavid Youngbe supported in hardware or require a software thread to receive packets from 12*41dd9a6bSDavid Youngthe ethdev port using ethdev poll mode APIs and enqueue these as events to the 13*41dd9a6bSDavid Youngevent device using the eventdev API. Both transfer mechanisms may be present on 14*41dd9a6bSDavid Youngthe same platform depending on the particular combination of the ethdev and 15*41dd9a6bSDavid Youngthe event device. 16*41dd9a6bSDavid Young 17*41dd9a6bSDavid YoungThe Event Ethernet Rx Adapter library is intended for the application code to 18*41dd9a6bSDavid Youngconfigure both transfer mechanisms using a common API. A capability API allows 19*41dd9a6bSDavid Youngthe eventdev PMD to advertise features supported for a given ethdev and allows 20*41dd9a6bSDavid Youngthe application to perform configuration as per supported features. 21*41dd9a6bSDavid Young 22*41dd9a6bSDavid YoungAPI Walk-through 23*41dd9a6bSDavid Young---------------- 24*41dd9a6bSDavid Young 25*41dd9a6bSDavid YoungThis section will introduce the reader to the adapter API. The 26*41dd9a6bSDavid Youngapplication has to first instantiate an adapter which is associated with 27*41dd9a6bSDavid Younga single eventdev, next the adapter instance is configured with Rx queues 28*41dd9a6bSDavid Youngthat are either polled by a SW thread or linked using hardware support. Finally 29*41dd9a6bSDavid Youngthe adapter is started. 30*41dd9a6bSDavid Young 31*41dd9a6bSDavid YoungFor SW based packet transfers from ethdev to eventdev, the adapter uses a 32*41dd9a6bSDavid YoungDPDK service function and the application is also required to assign a core to 33*41dd9a6bSDavid Youngthe service function. 34*41dd9a6bSDavid Young 35*41dd9a6bSDavid YoungCreating an Adapter Instance 36*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37*41dd9a6bSDavid Young 38*41dd9a6bSDavid YoungAn adapter instance is created using ``rte_event_eth_rx_adapter_create()``. This 39*41dd9a6bSDavid Youngfunction is passed the event device to be associated with the adapter and port 40*41dd9a6bSDavid Youngconfiguration for the adapter to setup an event port if the adapter needs to use 41*41dd9a6bSDavid Younga service function. 42*41dd9a6bSDavid Young 43*41dd9a6bSDavid Young.. code-block:: c 44*41dd9a6bSDavid Young 45*41dd9a6bSDavid Young int err; 46*41dd9a6bSDavid Young uint8_t dev_id; 47*41dd9a6bSDavid Young struct rte_event_dev_info dev_info; 48*41dd9a6bSDavid Young struct rte_event_port_conf rx_p_conf; 49*41dd9a6bSDavid Young 50*41dd9a6bSDavid Young err = rte_event_dev_info_get(id, &dev_info); 51*41dd9a6bSDavid Young 52*41dd9a6bSDavid Young rx_p_conf.new_event_threshold = dev_info.max_num_events; 53*41dd9a6bSDavid Young rx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth; 54*41dd9a6bSDavid Young rx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth; 55*41dd9a6bSDavid Young err = rte_event_eth_rx_adapter_create(id, dev_id, &rx_p_conf); 56*41dd9a6bSDavid Young 57*41dd9a6bSDavid YoungIf the application desires to have finer control of eventdev port allocation 58*41dd9a6bSDavid Youngand setup, it can use the ``rte_event_eth_rx_adapter_create_ext()`` function. 59*41dd9a6bSDavid YoungThe ``rte_event_eth_rx_adapter_create_ext()`` function is passed a callback 60*41dd9a6bSDavid Youngfunction. The callback function is invoked if the adapter needs to use a 61*41dd9a6bSDavid Youngservice function and needs to create an event port for it. The callback is 62*41dd9a6bSDavid Youngexpected to fill the ``struct rte_event_eth_rx_adapter_conf structure`` 63*41dd9a6bSDavid Youngpassed to it. 64*41dd9a6bSDavid Young 65*41dd9a6bSDavid YoungIf the application desires to control the event buffer size at adapter level, 66*41dd9a6bSDavid Youngit can use the ``rte_event_eth_rx_adapter_create_with_params()`` api. The event 67*41dd9a6bSDavid Youngbuffer size is specified using ``struct rte_event_eth_rx_adapter_params:: 68*41dd9a6bSDavid Youngevent_buf_size``. To configure the event buffer size at queue level, the boolean 69*41dd9a6bSDavid Youngflag ``struct rte_event_eth_rx_adapter_params::use_queue_event_buf`` need to be 70*41dd9a6bSDavid Youngset to true. The function is passed the event device to be associated with 71*41dd9a6bSDavid Youngthe adapter and port configuration for the adapter to setup an event port 72*41dd9a6bSDavid Youngif the adapter needs to use a service function. 73*41dd9a6bSDavid Young 74*41dd9a6bSDavid YoungIf the application desires to control both the event port allocation and event 75*41dd9a6bSDavid Youngbuffer size, ``rte_event_eth_rx_adapter_create_ext_with_params()`` can be used. 76*41dd9a6bSDavid Young 77*41dd9a6bSDavid YoungEvent device configuration for service based adapter 78*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 79*41dd9a6bSDavid Young 80*41dd9a6bSDavid YoungWhen ``rte_event_eth_rx_adapter_create()`` or 81*41dd9a6bSDavid Young``rte_event_eth_rx_adapter_create_with_params()`` is used for creating 82*41dd9a6bSDavid Youngadapter instance, ``rte_event_dev_config::nb_event_ports`` is 83*41dd9a6bSDavid Youngautomatically incremented and the event device is reconfigured 84*41dd9a6bSDavid Youngwith the additional event port during service initialization. 85*41dd9a6bSDavid YoungThis event device reconfigure logic also increments the 86*41dd9a6bSDavid Young``rte_event_dev_config::nb_single_link_event_port_queues`` 87*41dd9a6bSDavid Youngparameter if the adapter event port config is of type 88*41dd9a6bSDavid Young``RTE_EVENT_PORT_CFG_SINGLE_LINK``. 89*41dd9a6bSDavid Young 90*41dd9a6bSDavid YoungApplication no longer needs to account for the 91*41dd9a6bSDavid Young``rte_event_dev_config::nb_event_ports`` and 92*41dd9a6bSDavid Young``rte_event_dev_config::nb_single_link_event_port_queues`` 93*41dd9a6bSDavid Youngparameters required for eth Rx adapter in the event device configuration, 94*41dd9a6bSDavid Youngwhen the adapter is created using the above-mentioned APIs. 95*41dd9a6bSDavid Young 96*41dd9a6bSDavid YoungAdding Rx Queues to the Adapter Instance 97*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 98*41dd9a6bSDavid Young 99*41dd9a6bSDavid YoungEthdev Rx queues are added to the instance using the 100*41dd9a6bSDavid Young``rte_event_eth_rx_adapter_queue_add()`` function. Configuration for the Rx 101*41dd9a6bSDavid Youngqueue is passed in using a ``struct rte_event_eth_rx_adapter_queue_conf`` 102*41dd9a6bSDavid Youngparameter. Event information for packets from this Rx queue is encoded in the 103*41dd9a6bSDavid Young``ev`` field of ``struct rte_event_eth_rx_adapter_queue_conf``. The 104*41dd9a6bSDavid Youngservicing_weight member of the struct rte_event_eth_rx_adapter_queue_conf 105*41dd9a6bSDavid Youngis the relative polling frequency of the Rx queue and is applicable when the 106*41dd9a6bSDavid Youngadapter uses a service core function. The applications can configure queue 107*41dd9a6bSDavid Youngevent buffer size in ``struct rte_event_eth_rx_adapter_queue_conf::event_buf_size`` 108*41dd9a6bSDavid Youngparameter. 109*41dd9a6bSDavid Young 110*41dd9a6bSDavid Young.. code-block:: c 111*41dd9a6bSDavid Young 112*41dd9a6bSDavid Young ev.queue_id = 0; 113*41dd9a6bSDavid Young ev.sched_type = RTE_SCHED_TYPE_ATOMIC; 114*41dd9a6bSDavid Young ev.priority = 0; 115*41dd9a6bSDavid Young 116*41dd9a6bSDavid Young queue_config.rx_queue_flags = 0; 117*41dd9a6bSDavid Young queue_config.ev = ev; 118*41dd9a6bSDavid Young queue_config.servicing_weight = 1; 119*41dd9a6bSDavid Young queue_config.event_buf_size = 1024; 120*41dd9a6bSDavid Young 121*41dd9a6bSDavid Young err = rte_event_eth_rx_adapter_queue_add(id, 122*41dd9a6bSDavid Young eth_dev_id, 123*41dd9a6bSDavid Young 0, &queue_config); 124*41dd9a6bSDavid Young 125*41dd9a6bSDavid YoungQuerying Adapter Capabilities 126*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 127*41dd9a6bSDavid Young 128*41dd9a6bSDavid YoungThe ``rte_event_eth_rx_adapter_caps_get()`` function allows 129*41dd9a6bSDavid Youngthe application to query the adapter capabilities for an eventdev and ethdev 130*41dd9a6bSDavid Youngcombination. For e.g, if the ``RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID`` 131*41dd9a6bSDavid Youngis set, the application can override the adapter generated flow ID in the event 132*41dd9a6bSDavid Youngusing ``rx_queue_flags`` field in ``struct rte_event_eth_rx_adapter_queue_conf`` 133*41dd9a6bSDavid Youngwhich is passed as a parameter to the ``rte_event_eth_rx_adapter_queue_add()`` 134*41dd9a6bSDavid Youngfunction. 135*41dd9a6bSDavid Young 136*41dd9a6bSDavid Young.. code-block:: c 137*41dd9a6bSDavid Young 138*41dd9a6bSDavid Young err = rte_event_eth_rx_adapter_caps_get(dev_id, eth_dev_id, &cap); 139*41dd9a6bSDavid Young 140*41dd9a6bSDavid Young queue_config.rx_queue_flags = 0; 141*41dd9a6bSDavid Young if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) { 142*41dd9a6bSDavid Young ev.flow_id = 1; 143*41dd9a6bSDavid Young queue_config.rx_queue_flags = 144*41dd9a6bSDavid Young RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID; 145*41dd9a6bSDavid Young } 146*41dd9a6bSDavid Young 147*41dd9a6bSDavid YoungConfiguring the Service Function 148*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 149*41dd9a6bSDavid Young 150*41dd9a6bSDavid YoungIf the adapter uses a service function, the application is required to assign 151*41dd9a6bSDavid Younga service core to the service function as show below. 152*41dd9a6bSDavid Young 153*41dd9a6bSDavid Young.. code-block:: c 154*41dd9a6bSDavid Young 155*41dd9a6bSDavid Young uint32_t service_id; 156*41dd9a6bSDavid Young 157*41dd9a6bSDavid Young if (rte_event_eth_rx_adapter_service_id_get(0, &service_id) == 0) 158*41dd9a6bSDavid Young rte_service_map_lcore_set(service_id, RX_CORE_ID); 159*41dd9a6bSDavid Young 160*41dd9a6bSDavid YoungStarting the Adapter Instance 161*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 162*41dd9a6bSDavid Young 163*41dd9a6bSDavid YoungThe application calls ``rte_event_eth_rx_adapter_start()`` to start the adapter. 164*41dd9a6bSDavid YoungThis function calls the start callbacks of the eventdev PMDs for hardware based 165*41dd9a6bSDavid Youngeventdev-ethdev connections and ``rte_service_run_state_set()`` to enable the 166*41dd9a6bSDavid Youngservice function if one exists. 167*41dd9a6bSDavid Young 168*41dd9a6bSDavid Young.. Note:: 169*41dd9a6bSDavid Young 170*41dd9a6bSDavid Young The eventdev to which the event_eth_rx_adapter is connected needs to 171*41dd9a6bSDavid Young be started before calling rte_event_eth_rx_adapter_start(). 172*41dd9a6bSDavid Young 173*41dd9a6bSDavid YoungGetting Adapter Statistics 174*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~ 175*41dd9a6bSDavid Young 176*41dd9a6bSDavid YoungThe ``rte_event_eth_rx_adapter_stats_get()`` function reports counters defined 177*41dd9a6bSDavid Youngin struct ``rte_event_eth_rx_adapter_stats``. The received packet and 178*41dd9a6bSDavid Youngenqueued event counts are a sum of the counts from the eventdev PMD callbacks 179*41dd9a6bSDavid Youngif the callback is supported, and the counts maintained by the service function, 180*41dd9a6bSDavid Youngif one exists. The service function also maintains a count of cycles for which 181*41dd9a6bSDavid Youngit was not able to enqueue to the event device. 182*41dd9a6bSDavid Young 183*41dd9a6bSDavid YoungGetting Adapter queue config 184*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185*41dd9a6bSDavid Young 186*41dd9a6bSDavid YoungThe ``rte_event_eth_rx_adapter_queue_conf_get()`` function reports 187*41dd9a6bSDavid Youngflags for handling received packets, event queue identifier, scheduler type, 188*41dd9a6bSDavid Youngevent priority, polling frequency of the receive queue and flow identifier 189*41dd9a6bSDavid Youngin struct ``rte_event_eth_rx_adapter_queue_conf``. 190*41dd9a6bSDavid Young 191*41dd9a6bSDavid YoungSet/Get adapter runtime configuration parameters 192*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 193*41dd9a6bSDavid Young 194*41dd9a6bSDavid YoungThe runtime configuration parameters of adapter can be set/get using 195*41dd9a6bSDavid Young``rte_event_eth_rx_adapter_runtime_params_set()`` and 196*41dd9a6bSDavid Young``rte_event_eth_rx_adapter_runtime_params_get()`` respectively. 197*41dd9a6bSDavid YoungThe parameters that can be set/get are defined in 198*41dd9a6bSDavid Young``struct rte_event_eth_rx_adapter_runtime_params``. 199*41dd9a6bSDavid Young 200*41dd9a6bSDavid YoungGetting and resetting Adapter queue stats 201*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 202*41dd9a6bSDavid Young 203*41dd9a6bSDavid YoungThe ``rte_event_eth_rx_adapter_queue_stats_get()`` function reports 204*41dd9a6bSDavid Youngadapter queue counters defined in struct ``rte_event_eth_rx_adapter_queue_stats``. 205*41dd9a6bSDavid YoungThis function reports queue level stats only when queue level event buffer is 206*41dd9a6bSDavid Youngused otherwise it returns -EINVAL. 207*41dd9a6bSDavid Young 208*41dd9a6bSDavid YoungThe ``rte_event_eth_rx_adapter_queue_stats_reset`` function can be used to 209*41dd9a6bSDavid Youngreset queue level stats when queue level event buffer is in use. 210*41dd9a6bSDavid Young 211*41dd9a6bSDavid YoungGetting Adapter Instance ID 212*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~ 213*41dd9a6bSDavid Young 214*41dd9a6bSDavid YoungThe ``rte_event_eth_rx_adapter_instance_get()`` function reports 215*41dd9a6bSDavid YoungRx adapter instance ID for a specified ethernet device ID and Rx queue index. 216*41dd9a6bSDavid Young 217*41dd9a6bSDavid YoungInterrupt Based Rx Queues 218*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~ 219*41dd9a6bSDavid Young 220*41dd9a6bSDavid YoungThe service core function is typically set up to poll ethernet Rx queues for 221*41dd9a6bSDavid Youngpackets. Certain queues may have low packet rates and it would be more 222*41dd9a6bSDavid Youngefficient to enable the Rx queue interrupt and read packets after receiving 223*41dd9a6bSDavid Youngthe interrupt. 224*41dd9a6bSDavid Young 225*41dd9a6bSDavid YoungThe servicing_weight member of struct rte_event_eth_rx_adapter_queue_conf 226*41dd9a6bSDavid Youngis applicable when the adapter uses a service core function. The application 227*41dd9a6bSDavid Younghas to enable Rx queue interrupts when configuring the ethernet device 228*41dd9a6bSDavid Youngusing the ``rte_eth_dev_configure()`` function and then use a servicing_weight 229*41dd9a6bSDavid Youngof zero when adding the Rx queue to the adapter. 230*41dd9a6bSDavid Young 231*41dd9a6bSDavid YoungThe adapter creates a thread blocked on the interrupt, on an interrupt this 232*41dd9a6bSDavid Youngthread enqueues the port id and the queue id to a ring buffer. The adapter 233*41dd9a6bSDavid Youngservice function dequeues the port id and queue id from the ring buffer, 234*41dd9a6bSDavid Younginvokes the ``rte_eth_rx_burst()`` to receive packets on the queue and 235*41dd9a6bSDavid Youngconverts the received packets to events in the same manner as packets 236*41dd9a6bSDavid Youngreceived on a polled Rx queue. The interrupt thread is affinitized to the same 237*41dd9a6bSDavid YoungCPUs as the lcores of the Rx adapter service function, if the Rx adapter 238*41dd9a6bSDavid Youngservice function has not been mapped to any lcores, the interrupt thread 239*41dd9a6bSDavid Youngis mapped to the main lcore. 240*41dd9a6bSDavid Young 241*41dd9a6bSDavid YoungRx Callback for SW Rx Adapter 242*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 243*41dd9a6bSDavid Young 244*41dd9a6bSDavid YoungFor SW based packet transfers, i.e., when the 245*41dd9a6bSDavid Young``RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT`` is not set in the adapter's 246*41dd9a6bSDavid Youngcapabilities flags for a particular ethernet device, the service function 247*41dd9a6bSDavid Youngtemporarily enqueues mbufs to an event buffer before batch enqueuing these 248*41dd9a6bSDavid Youngto the event device. If the buffer fills up, the service function stops 249*41dd9a6bSDavid Youngdequeuing packets from the ethernet device. The application may want to 250*41dd9a6bSDavid Youngmonitor the buffer fill level and instruct the service function to selectively 251*41dd9a6bSDavid Youngenqueue packets to the event device. The application may also use some other 252*41dd9a6bSDavid Youngcriteria to decide which packets should enter the event device even when 253*41dd9a6bSDavid Youngthe event buffer fill level is low. The 254*41dd9a6bSDavid Young``rte_event_eth_rx_adapter_cb_register()`` function allow the application 255*41dd9a6bSDavid Youngto register a callback that selects which packets to enqueue to the event 256*41dd9a6bSDavid Youngdevice. 257*41dd9a6bSDavid Young 258*41dd9a6bSDavid YoungRx event vectorization 259*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~ 260*41dd9a6bSDavid Young 261*41dd9a6bSDavid YoungThe event devices, ethernet device pairs which support the capability 262*41dd9a6bSDavid Young``RTE_EVENT_ETH_RX_ADAPTER_CAP_EVENT_VECTOR`` can aggregate packets based on 263*41dd9a6bSDavid Youngflow characteristics and generate a ``rte_event`` containing ``rte_event_vector`` 264*41dd9a6bSDavid Youngwhose event type is either ``RTE_EVENT_TYPE_ETHDEV_VECTOR`` or 265*41dd9a6bSDavid Young``RTE_EVENT_TYPE_ETH_RX_ADAPTER_VECTOR``. 266*41dd9a6bSDavid YoungThe maximum, minimum vector sizes and timeouts vary based on the device 267*41dd9a6bSDavid Youngcapability and can be queried using 268*41dd9a6bSDavid Young``rte_event_eth_rx_adapter_vector_limits_get``. 269*41dd9a6bSDavid YoungThe Rx adapter additionally might include useful data such as ethernet device 270*41dd9a6bSDavid Youngport and queue identifier in the ``rte_event_vector::port`` and 271*41dd9a6bSDavid Young``rte_event_vector::queue`` and mark ``rte_event_vector::attr_valid`` as true. 272*41dd9a6bSDavid YoungThe aggregation size and timeout are configurable at a queue level by setting 273*41dd9a6bSDavid Young``rte_event_eth_rx_adapter_queue_conf::vector_sz``, 274*41dd9a6bSDavid Young``rte_event_eth_rx_adapter_queue_conf::vector_timeout_ns`` and 275*41dd9a6bSDavid Young``rte_event_eth_rx_adapter_queue_conf::vector_mp`` when adding queues using 276*41dd9a6bSDavid Young``rte_event_eth_rx_adapter_queue_add``. 277*41dd9a6bSDavid Young 278*41dd9a6bSDavid YoungA loop processing ``rte_event_vector`` containing mbufs is shown below. 279*41dd9a6bSDavid Young 280*41dd9a6bSDavid Young.. code-block:: c 281*41dd9a6bSDavid Young 282*41dd9a6bSDavid Young event = rte_event_dequeue_burst(event_dev, event_port, &event, 283*41dd9a6bSDavid Young 1, 0); 284*41dd9a6bSDavid Young if (!event) 285*41dd9a6bSDavid Young continue; 286*41dd9a6bSDavid Young 287*41dd9a6bSDavid Young switch (ev.event_type) { 288*41dd9a6bSDavid Young case RTE_EVENT_TYPE_ETH_RX_ADAPTER_VECTOR: 289*41dd9a6bSDavid Young case RTE_EVENT_TYPE_ETHDEV_VECTOR: 290*41dd9a6bSDavid Young struct rte_mbufs **mbufs; 291*41dd9a6bSDavid Young 292*41dd9a6bSDavid Young mbufs = (struct rte_mbufs **)ev[i].vec->mbufs; 293*41dd9a6bSDavid Young for (i = 0; i < ev.vec->nb_elem; i++) { 294*41dd9a6bSDavid Young /* Process each mbuf. */ 295*41dd9a6bSDavid Young } 296*41dd9a6bSDavid Young break; 297*41dd9a6bSDavid Young case default: 298*41dd9a6bSDavid Young /* Handle other event_types. */ 299*41dd9a6bSDavid Young } 300*41dd9a6bSDavid Young 301*41dd9a6bSDavid YoungRx event vectorization for SW Rx adapter 302*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 303*41dd9a6bSDavid Young 304*41dd9a6bSDavid YoungFor SW based event vectorization, i.e., when the 305*41dd9a6bSDavid Young``RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT`` is not set in the adapter's 306*41dd9a6bSDavid Youngcapabilities flags for a particular ethernet device, the service function 307*41dd9a6bSDavid Youngcreates a single event vector flow for all the mbufs arriving on the given 308*41dd9a6bSDavid YoungRx queue. 309*41dd9a6bSDavid YoungThe 20-bit event flow identifier is set to 12-bits of Rx queue identifier 310*41dd9a6bSDavid Youngand 8-bits of ethernet device identifier. 311*41dd9a6bSDavid YoungFlow identifier is formatted as follows: 312*41dd9a6bSDavid Young 313*41dd9a6bSDavid Young.. code-block:: console 314*41dd9a6bSDavid Young 315*41dd9a6bSDavid Young 19 12,11 0 316*41dd9a6bSDavid Young +---------+--------------+ 317*41dd9a6bSDavid Young | port_id | queue_id | 318*41dd9a6bSDavid Young +---------+--------------+ 319