New upstream version 18.08
[deb_dpdk.git] / doc / guides / prog_guide / event_crypto_adapter.rst
1 ..  SPDX-License-Identifier: BSD-3-Clause
2     Copyright(c) 2018 Intel Corporation. All rights reserved.
3
4 Event Crypto Adapter Library
5 ============================
6
7 The DPDK :doc:`Eventdev library <eventdev>` provides event driven
8 programming model with features to schedule events.
9 The :doc:`Cryptodev library <cryptodev_lib>` provides an interface to
10 the crypto poll mode drivers which supports different crypto operations.
11 The Event Crypto Adapter is one of the adapter which is intended to
12 bridge between the event device and the crypto device.
13
14 The packet flow from crypto device to the event device can be accomplished
15 using SW and HW based transfer mechanism.
16 The Adapter queries an eventdev PMD to determine which mechanism to be used.
17 The adapter uses an EAL service core function for SW based packet transfer
18 and uses the eventdev PMD functions to configure HW based packet transfer
19 between the crypto device and the event device. The crypto adapter uses a new
20 event type called ``RTE_EVENT_TYPE_CRYPTODEV`` to indicate the event source.
21
22 The application can choose to submit a crypto operation directly to
23 crypto device or send it to the crypto adapter via eventdev based on
24 RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD capability.
25 The first mode is known as the event new(RTE_EVENT_CRYPTO_ADAPTER_OP_NEW)
26 mode and the second as the event forward(RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD)
27 mode. The choice of mode can be specified while creating the adapter.
28 In the former mode, it is an application responsibility to enable ingress
29 packet ordering. In the latter mode, it is the adapter responsibility to
30 enable the ingress packet ordering.
31
32
33 Adapter Mode
34 ------------
35
36 RTE_EVENT_CRYPTO_ADAPTER_OP_NEW mode
37 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38
39 In the RTE_EVENT_CRYPTO_ADAPTER_OP_NEW mode, application submits crypto
40 operations directly to crypto device. The adapter then dequeues crypto
41 completions from crypto device and enqueues them as events to the event device.
42 This mode does not ensure ingress ordering, if the application directly
43 enqueues to the cryptodev without going through crypto/atomic stage.
44 In this mode, events dequeued from the adapter will be treated as new events.
45 The application needs to specify event information (response information)
46 which 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
55 RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD mode
56 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57
58 In the RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD mode, if HW supports
59 RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD capability the application
60 can directly submit the crypto operations to the cryptodev.
61 If not, application retrieves crypto adapter's event port using
62 rte_event_crypto_adapter_event_port_get() API. Then, links its event
63 queue to this port and starts enqueuing crypto operations as events
64 to the eventdev. The adapter then dequeues the events and submits the
65 crypto operations to the cryptodev. After the crypto completions, the
66 adapter enqueues events to the event device.
67 Application can use this mode, when ingress packet ordering is needed.
68 In this mode, events dequeued from the adapter will be treated as
69 forwarded events. The application needs to specify the cryptodev ID
70 and queue pair ID (request information) needed to enqueue a crypto
71 operation in addition to the event information (response information)
72 needed 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
81 API Overview
82 ------------
83
84 This section has a brief introduction to the event crypto adapter APIs.
85 The application is expected to create an adapter which is associated with
86 a single eventdev, then add cryptodev and queue pair to the adapter instance.
87
88 Create an adapter instance
89 ~~~~~~~~~~~~~~~~~~~~~~~~~~
90
91 An adapter instance is created using ``rte_event_crypto_adapter_create()``. This
92 function is called with event device to be associated with the adapter and port
93 configuration for the adapter to setup an event port(if the adapter needs to use
94 a service function).
95
96 Adapter 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
115 If the application desires to have finer control of eventdev port allocation
116 and setup, it can use the ``rte_event_crypto_adapter_create_ext()`` function.
117 The ``rte_event_crypto_adapter_create_ext()`` function is passed as a callback
118 function. The callback function is invoked if the adapter needs to use a
119 service function and needs to create an event port for it. The callback is
120 expected to fill the ``struct rte_event_crypto_adapter_conf`` structure
121 passed to it.
122
123 For RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD mode, the event port created by adapter
124 can be retrieved using ``rte_event_crypto_adapter_event_port_get()`` API.
125 Application can use this event port to link with event queue on which it
126 enqueues 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
146 Querying adapter capabilities
147 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
148
149 The ``rte_event_crypto_adapter_caps_get()`` function allows
150 the application to query the adapter capabilities for an eventdev and cryptodev
151 combination. This API provides whether cryptodev and eventdev are connected using
152 internal HW port or not.
153
154 .. code-block:: c
155
156         rte_event_crypto_adapter_caps_get(dev_id, cdev_id, &cap);
157
158 Adding queue pair to the adapter instance
159 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
160
161 Cryptodev device id and queue pair are created using cryptodev APIs.
162 For 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
174 These cryptodev id and queue pair are added to the instance using the
175 ``rte_event_crypto_adapter_queue_pair_add()`` API.
176 The same is removed using ``rte_event_crypto_adapter_queue_pair_del()`` API.
177 If HW supports RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_QP_EV_BIND
178 capability, 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
194 Configure the service function
195 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
196
197 If the adapter uses a service function, the application is required to assign
198 a 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
207 Set event request/response information
208 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
209
210 In the RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD mode, the application needs
211 to specify the cryptodev ID and queue pair ID (request information) in
212 addition to the event information (response information) needed to enqueue
213 an event after the crypto operation has completed. The request and response
214 information are specified in the ``struct rte_crypto_op`` private data or
215 session's private data.
216
217 In the RTE_EVENT_CRYPTO_ADAPTER_OP_NEW mode, the application is required
218 to provide only the response information.
219
220 The SW adapter or HW PMD uses ``rte_crypto_op::sess_type`` to
221 decide whether request/response data is located in the crypto session/
222 crypto security session or at an offset in the ``struct rte_crypto_op``.
223 The ``rte_crypto_op::private_data_offset`` is used to locate the request/
224 response in the ``rte_crypto_op``.
225
226 For crypto session, ``rte_cryptodev_sym_session_set_user_data()`` API
227 will be used to set request/response data. The same data will be obtained
228 by ``rte_cryptodev_sym_session_get_user_data()`` API.  The
229 RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA capability indicates
230 whether HW or SW supports this feature.
231
232 For security session, ``rte_security_session_set_private_data()`` API
233 will be used to set request/response data. The same data will be obtained
234 by ``rte_security_session_get_private_data()`` API.
235
236 For session-less it is mandatory to place the request/response data with
237 the ``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
277 Start the adapter instance
278 ~~~~~~~~~~~~~~~~~~~~~~~~~~
279
280 The application calls ``rte_event_crypto_adapter_start()`` to start the adapter.
281 This function calls the start callbacks of the eventdev PMDs for hardware based
282 eventdev-cryptodev connections and ``rte_service_run_state_set()`` to enable the
283 service function if one exists.
284
285 .. code-block:: c
286
287         rte_event_crypto_adapter_start(id, mode);
288
289 Get adapter statistics
290 ~~~~~~~~~~~~~~~~~~~~~~
291
292 The  ``rte_event_crypto_adapter_stats_get()`` function reports counters defined
293 in struct ``rte_event_crypto_adapter_stats``. The received packet and
294 enqueued event counts are a sum of the counts from the eventdev PMD callbacks
295 if the callback is supported, and the counts maintained by the service function,
296 if one exists.