1.. SPDX-License-Identifier: BSD-3-Clause 2 Copyright(c) 2018 Intel Corporation. All rights reserved. 3 4Event Crypto Adapter Library 5============================ 6 7The DPDK :doc:`Eventdev library <eventdev>` provides event driven 8programming model with features to schedule events. 9The :doc:`Cryptodev library <cryptodev_lib>` provides an interface to 10the crypto poll mode drivers which supports different crypto operations. 11The Event Crypto Adapter is one of the adapter which is intended to 12bridge between the event device and the crypto device. 13 14The packet flow from crypto device to the event device can be accomplished 15using SW and HW based transfer mechanism. 16The Adapter queries an eventdev PMD to determine which mechanism to be used. 17The adapter uses an EAL service core function for SW based packet transfer 18and uses the eventdev PMD functions to configure HW based packet transfer 19between the crypto device and the event device. The crypto adapter uses a new 20event type called ``RTE_EVENT_TYPE_CRYPTODEV`` to indicate the event source. 21 22The application can choose to submit a crypto operation directly to 23crypto device or send it to the crypto adapter via eventdev based on 24RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD capability. 25The first mode is known as the event new(RTE_EVENT_CRYPTO_ADAPTER_OP_NEW) 26mode and the second as the event forward(RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD) 27mode. The choice of mode can be specified while creating the adapter. 28In the former mode, it is an application responsibility to enable ingress 29packet ordering. In the latter mode, it is the adapter responsibility to 30enable the ingress packet ordering. 31 32 33Adapter Mode 34------------ 35 36RTE_EVENT_CRYPTO_ADAPTER_OP_NEW mode 37~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 38 39In the RTE_EVENT_CRYPTO_ADAPTER_OP_NEW mode, application submits crypto 40operations directly to crypto device. The adapter then dequeues crypto 41completions from crypto device and enqueues them as events to the event device. 42This mode does not ensure ingress ordering, if the application directly 43enqueues to the cryptodev without going through crypto/atomic stage. 44In this mode, events dequeued from the adapter will be treated as new events. 45The application needs to specify event information (response information) 46which is needed to enqueue an event after the crypto operation is completed. 47 48.. _figure_event_crypto_adapter_op_new: 49 50.. figure:: img/event_crypto_adapter_op_new.* 51 52 Working model of ``RTE_EVENT_CRYPTO_ADAPTER_OP_NEW`` mode 53 54 55RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD mode 56~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 58In the RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD mode, if HW supports 59RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD capability the application 60can directly submit the crypto operations to the cryptodev. 61If not, application retrieves crypto adapter's event port using 62rte_event_crypto_adapter_event_port_get() API. Then, links its event 63queue to this port and starts enqueuing crypto operations as events 64to the eventdev. The adapter then dequeues the events and submits the 65crypto operations to the cryptodev. After the crypto completions, the 66adapter enqueues events to the event device. 67Application can use this mode, when ingress packet ordering is needed. 68In this mode, events dequeued from the adapter will be treated as 69forwarded events. The application needs to specify the cryptodev ID 70and queue pair ID (request information) needed to enqueue a crypto 71operation in addition to the event information (response information) 72needed to enqueue an event after the crypto operation has completed. 73 74.. _figure_event_crypto_adapter_op_forward: 75 76.. figure:: img/event_crypto_adapter_op_forward.* 77 78 Working model of ``RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD`` mode 79 80 81API Overview 82------------ 83 84This section has a brief introduction to the event crypto adapter APIs. 85The application is expected to create an adapter which is associated with 86a single eventdev, then add cryptodev and queue pair to the adapter instance. 87 88Create an adapter instance 89~~~~~~~~~~~~~~~~~~~~~~~~~~ 90 91An adapter instance is created using ``rte_event_crypto_adapter_create()``. This 92function is called with event device to be associated with the adapter and port 93configuration for the adapter to setup an event port(if the adapter needs to use 94a service function). 95 96Adapter can be started in ``RTE_EVENT_CRYPTO_ADAPTER_OP_NEW`` or 97``RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD`` mode. 98 99.. code-block:: c 100 101 int err; 102 uint8_t dev_id, id; 103 struct rte_event_dev_info dev_info; 104 struct rte_event_port_conf conf; 105 enum rte_event_crypto_adapter_mode mode; 106 107 err = rte_event_dev_info_get(id, &dev_info); 108 109 conf.new_event_threshold = dev_info.max_num_events; 110 conf.dequeue_depth = dev_info.max_event_port_dequeue_depth; 111 conf.enqueue_depth = dev_info.max_event_port_enqueue_depth; 112 mode = RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD; 113 err = rte_event_crypto_adapter_create(id, dev_id, &conf, mode); 114 115If the application desires to have finer control of eventdev port allocation 116and setup, it can use the ``rte_event_crypto_adapter_create_ext()`` function. 117The ``rte_event_crypto_adapter_create_ext()`` function is passed as a callback 118function. The callback function is invoked if the adapter needs to use a 119service function and needs to create an event port for it. The callback is 120expected to fill the ``struct rte_event_crypto_adapter_conf`` structure 121passed to it. 122 123For RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD mode, the event port created by adapter 124can be retrieved using ``rte_event_crypto_adapter_event_port_get()`` API. 125Application can use this event port to link with event queue on which it 126enqueues events towards the crypto adapter. 127 128.. code-block:: c 129 130 uint8_t id, evdev, crypto_ev_port_id, app_qid; 131 struct rte_event ev; 132 int ret; 133 134 ret = rte_event_crypto_adapter_event_port_get(id, &crypto_ev_port_id); 135 ret = rte_event_queue_setup(evdev, app_qid, NULL); 136 ret = rte_event_port_link(evdev, crypto_ev_port_id, &app_qid, NULL, 1); 137 138 // Fill in event info and update event_ptr with rte_crypto_op 139 memset(&ev, 0, sizeof(ev)); 140 ev.queue_id = app_qid; 141 . 142 . 143 ev.event_ptr = op; 144 ret = rte_event_enqueue_burst(evdev, app_ev_port_id, ev, nb_events); 145 146Querying adapter capabilities 147~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 148 149The ``rte_event_crypto_adapter_caps_get()`` function allows 150the application to query the adapter capabilities for an eventdev and cryptodev 151combination. This API provides whether cryptodev and eventdev are connected using 152internal HW port or not. 153 154.. code-block:: c 155 156 rte_event_crypto_adapter_caps_get(dev_id, cdev_id, &cap); 157 158Adding queue pair to the adapter instance 159~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 160 161Cryptodev device id and queue pair are created using cryptodev APIs. 162For more information see :doc:`here <cryptodev_lib>`. 163 164.. code-block:: c 165 166 struct rte_cryptodev_config conf; 167 struct rte_cryptodev_qp_conf qp_conf; 168 uint8_t cdev_id = 0; 169 uint16_t qp_id = 0; 170 171 rte_cryptodev_configure(cdev_id, &conf); 172 rte_cryptodev_queue_pair_setup(cdev_id, qp_id, &qp_conf); 173 174These cryptodev id and queue pair are added to the instance using the 175``rte_event_crypto_adapter_queue_pair_add()`` API. 176The same is removed using ``rte_event_crypto_adapter_queue_pair_del()`` API. 177If HW supports RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_QP_EV_BIND 178capability, event information must be passed to the add API. 179 180.. code-block:: c 181 182 uint32_t cap; 183 int ret; 184 185 ret = rte_event_crypto_adapter_caps_get(id, evdev, &cap); 186 if (cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_QP_EV_BIND) { 187 struct rte_event event; 188 189 // Fill in event information & pass it to add API 190 rte_event_crypto_adapter_queue_pair_add(id, cdev_id, qp_id, &event); 191 } else 192 rte_event_crypto_adapter_queue_pair_add(id, cdev_id, qp_id, NULL); 193 194Configure the service function 195~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 196 197If the adapter uses a service function, the application is required to assign 198a service core to the service function as show below. 199 200.. code-block:: c 201 202 uint32_t service_id; 203 204 if (rte_event_crypto_adapter_service_id_get(id, &service_id) == 0) 205 rte_service_map_lcore_set(service_id, CORE_ID); 206 207Set event request/response information 208~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 209 210In the RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD mode, the application needs 211to specify the cryptodev ID and queue pair ID (request information) in 212addition to the event information (response information) needed to enqueue 213an event after the crypto operation has completed. The request and response 214information are specified in the ``struct rte_crypto_op`` private data or 215session's private data. 216 217In the RTE_EVENT_CRYPTO_ADAPTER_OP_NEW mode, the application is required 218to provide only the response information. 219 220The SW adapter or HW PMD uses ``rte_crypto_op::sess_type`` to 221decide whether request/response data is located in the crypto session/ 222crypto security session or at an offset in the ``struct rte_crypto_op``. 223The ``rte_crypto_op::private_data_offset`` is used to locate the request/ 224response in the ``rte_crypto_op``. 225 226For crypto session, ``rte_cryptodev_sym_session_set_user_data()`` API 227will be used to set request/response data. The same data will be obtained 228by ``rte_cryptodev_sym_session_get_user_data()`` API. The 229RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA capability indicates 230whether HW or SW supports this feature. 231 232For security session, ``rte_security_session_set_private_data()`` API 233will be used to set request/response data. The same data will be obtained 234by ``rte_security_session_get_private_data()`` API. 235 236For session-less it is mandatory to place the request/response data with 237the ``rte_crypto_op``. 238 239.. code-block:: c 240 241 union rte_event_crypto_metadata m_data; 242 struct rte_event ev; 243 struct rte_crypto_op *op; 244 245 /* Allocate & fill op structure */ 246 op = rte_crypto_op_alloc(); 247 248 memset(&m_data, 0, sizeof(m_data)); 249 memset(&ev, 0, sizeof(ev)); 250 /* Fill event information and update event_ptr to rte_crypto_op */ 251 ev.event_ptr = op; 252 253 if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { 254 /* Copy response information */ 255 rte_memcpy(&m_data.response_info, &ev, sizeof(ev)); 256 /* Copy request information */ 257 m_data.request_info.cdev_id = cdev_id; 258 m_data.request_info.queue_pair_id = qp_id; 259 /* Call set API to store private data information */ 260 rte_cryptodev_sym_session_set_user_data( 261 op->sym->session, 262 &m_data, 263 sizeof(m_data)); 264 } if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) { 265 uint32_t len = IV_OFFSET + MAXIMUM_IV_LENGTH + 266 (sizeof(struct rte_crypto_sym_xform) * 2); 267 op->private_data_offset = len; 268 /* Copy response information */ 269 rte_memcpy(&m_data.response_info, &ev, sizeof(ev)); 270 /* Copy request information */ 271 m_data.request_info.cdev_id = cdev_id; 272 m_data.request_info.queue_pair_id = qp_id; 273 /* Store private data information along with rte_crypto_op */ 274 rte_memcpy(op + len, &m_data, sizeof(m_data)); 275 } 276 277Start the adapter instance 278~~~~~~~~~~~~~~~~~~~~~~~~~~ 279 280The application calls ``rte_event_crypto_adapter_start()`` to start the adapter. 281This function calls the start callbacks of the eventdev PMDs for hardware based 282eventdev-cryptodev connections and ``rte_service_run_state_set()`` to enable the 283service function if one exists. 284 285.. code-block:: c 286 287 rte_event_crypto_adapter_start(id, mode); 288 289.. Note:: 290 291 The eventdev to which the event_crypto_adapter is connected needs to 292 be started before calling rte_event_crypto_adapter_start(). 293 294Get adapter statistics 295~~~~~~~~~~~~~~~~~~~~~~ 296 297The ``rte_event_crypto_adapter_stats_get()`` function reports counters defined 298in struct ``rte_event_crypto_adapter_stats``. The received packet and 299enqueued event counts are a sum of the counts from the eventdev PMD callbacks 300if the callback is supported, and the counts maintained by the service function, 301if one exists. 302