Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Intel Corporation
3 : : */
4 : : #include <eal_export.h>
5 : : #include <rte_string_fns.h>
6 : : #include <rte_reorder.h>
7 : : #include <rte_cryptodev.h>
8 : : #include <cryptodev_pmd.h>
9 : : #include <rte_security_driver.h>
10 : : #include <rte_malloc.h>
11 : :
12 : : #include "rte_cryptodev_scheduler.h"
13 : : #include "scheduler_pmd_private.h"
14 : :
15 : : #define MAX_CAPS 256
16 : :
17 : : /** update the scheduler pmd's capability with attaching device's
18 : : * capability.
19 : : * For each device to be attached, the scheduler's capability should be
20 : : * the common capability set of all workers
21 : : **/
22 : : static uint32_t
23 : 0 : sync_caps(struct rte_cryptodev_capabilities *caps,
24 : : uint32_t nb_caps,
25 : : const struct rte_cryptodev_capabilities *worker_caps)
26 : : {
27 : : uint32_t sync_nb_caps = nb_caps, nb_worker_caps = 0;
28 : : uint32_t i;
29 : :
30 [ # # ]: 0 : while (worker_caps[nb_worker_caps].op != RTE_CRYPTO_OP_TYPE_UNDEFINED)
31 : 0 : nb_worker_caps++;
32 : :
33 [ # # ]: 0 : if (nb_caps == 0) {
34 : : rte_memcpy(caps, worker_caps, sizeof(*caps) * nb_worker_caps);
35 : 0 : return nb_worker_caps;
36 : : }
37 : :
38 [ # # ]: 0 : for (i = 0; i < sync_nb_caps; i++) {
39 : 0 : struct rte_cryptodev_capabilities *cap = &caps[i];
40 : : uint32_t j;
41 : :
42 [ # # ]: 0 : for (j = 0; j < nb_worker_caps; j++) {
43 : 0 : const struct rte_cryptodev_capabilities *s_cap =
44 : 0 : &worker_caps[j];
45 : :
46 [ # # ]: 0 : if (s_cap->op != cap->op || s_cap->sym.xform_type !=
47 [ # # ]: 0 : cap->sym.xform_type)
48 : 0 : continue;
49 : :
50 [ # # ]: 0 : if (s_cap->sym.xform_type ==
51 : : RTE_CRYPTO_SYM_XFORM_AUTH) {
52 : 0 : if (s_cap->sym.auth.algo !=
53 [ # # ]: 0 : cap->sym.auth.algo)
54 : 0 : continue;
55 : :
56 : 0 : cap->sym.auth.digest_size.min =
57 : 0 : s_cap->sym.auth.digest_size.min <
58 : 0 : cap->sym.auth.digest_size.min ?
59 : 0 : s_cap->sym.auth.digest_size.min :
60 : : cap->sym.auth.digest_size.min;
61 : 0 : cap->sym.auth.digest_size.max =
62 : 0 : s_cap->sym.auth.digest_size.max <
63 : 0 : cap->sym.auth.digest_size.max ?
64 : 0 : s_cap->sym.auth.digest_size.max :
65 : : cap->sym.auth.digest_size.max;
66 : : }
67 : :
68 [ # # ]: 0 : if (s_cap->sym.xform_type ==
69 : : RTE_CRYPTO_SYM_XFORM_CIPHER)
70 : 0 : if (s_cap->sym.cipher.algo !=
71 [ # # ]: 0 : cap->sym.cipher.algo)
72 : 0 : continue;
73 : :
74 : : /* no common cap found */
75 : : break;
76 : : }
77 : :
78 [ # # ]: 0 : if (j < nb_worker_caps)
79 : 0 : continue;
80 : :
81 : : /* remove a uncommon cap from the array */
82 [ # # ]: 0 : for (j = i; j < sync_nb_caps - 1; j++)
83 [ # # ]: 0 : rte_memcpy(&caps[j], &caps[j+1], sizeof(*cap));
84 : :
85 : 0 : memset(&caps[sync_nb_caps - 1], 0, sizeof(*cap));
86 : : sync_nb_caps--;
87 : 0 : i--;
88 : : }
89 : :
90 : : return sync_nb_caps;
91 : : }
92 : :
93 : : static int
94 : 0 : check_sec_cap_equal(const struct rte_security_capability *sec_cap1,
95 : : struct rte_security_capability *sec_cap2)
96 : : {
97 [ # # ]: 0 : if (sec_cap1->action != sec_cap2->action ||
98 : 0 : sec_cap1->protocol != sec_cap2->protocol ||
99 [ # # ]: 0 : sec_cap1->ol_flags != sec_cap2->ol_flags)
100 : : return 0;
101 : :
102 [ # # ]: 0 : if (sec_cap1->protocol == RTE_SECURITY_PROTOCOL_DOCSIS)
103 : 0 : return !memcmp(&sec_cap1->docsis, &sec_cap2->docsis,
104 : : sizeof(sec_cap1->docsis));
105 : : else
106 : : return 0;
107 : : }
108 : :
109 : : static void
110 : : copy_sec_cap(struct rte_security_capability *dst_sec_cap,
111 : : struct rte_security_capability *src_sec_cap)
112 : : {
113 : 0 : dst_sec_cap->action = src_sec_cap->action;
114 : 0 : dst_sec_cap->protocol = src_sec_cap->protocol;
115 : 0 : if (src_sec_cap->protocol == RTE_SECURITY_PROTOCOL_DOCSIS)
116 : 0 : dst_sec_cap->docsis = src_sec_cap->docsis;
117 : 0 : dst_sec_cap->ol_flags = src_sec_cap->ol_flags;
118 : 0 : }
119 : :
120 : : static uint32_t
121 : 0 : sync_sec_crypto_caps(struct rte_cryptodev_capabilities *tmp_sec_crypto_caps,
122 : : const struct rte_cryptodev_capabilities *sec_crypto_caps,
123 : : const struct rte_cryptodev_capabilities *worker_sec_crypto_caps)
124 : : {
125 : : uint8_t nb_caps = 0;
126 : :
127 : 0 : nb_caps = sync_caps(tmp_sec_crypto_caps, nb_caps, sec_crypto_caps);
128 : 0 : sync_caps(tmp_sec_crypto_caps, nb_caps, worker_sec_crypto_caps);
129 : :
130 : 0 : return nb_caps;
131 : : }
132 : :
133 : : /** update the scheduler pmd's security capability with attaching device's
134 : : * security capability.
135 : : * For each device to be attached, the scheduler's security capability should
136 : : * be the common capability set of all workers
137 : : **/
138 : : static uint32_t
139 : 0 : sync_sec_caps(uint32_t worker_idx,
140 : : struct rte_security_capability *sec_caps,
141 : : struct rte_cryptodev_capabilities sec_crypto_caps[][MAX_CAPS],
142 : : uint32_t nb_sec_caps,
143 : : const struct rte_security_capability *worker_sec_caps)
144 : : {
145 : : uint32_t nb_worker_sec_caps = 0, i;
146 : :
147 [ # # ]: 0 : if (worker_sec_caps == NULL)
148 : : return 0;
149 : :
150 [ # # ]: 0 : while (worker_sec_caps[nb_worker_sec_caps].action !=
151 : : RTE_SECURITY_ACTION_TYPE_NONE)
152 : 0 : nb_worker_sec_caps++;
153 : :
154 : : /* Handle first worker */
155 [ # # ]: 0 : if (worker_idx == 0) {
156 : : uint32_t nb_worker_sec_crypto_caps = 0;
157 : : uint32_t nb_worker_supp_sec_caps = 0;
158 : :
159 [ # # ]: 0 : for (i = 0; i < nb_worker_sec_caps; i++) {
160 : : /* Check for supported security protocols */
161 : 0 : if (!scheduler_check_sec_proto_supp(worker_sec_caps[i].action,
162 [ # # ]: 0 : worker_sec_caps[i].protocol))
163 : 0 : continue;
164 : :
165 : 0 : sec_caps[nb_worker_supp_sec_caps] = worker_sec_caps[i];
166 : :
167 : 0 : while (worker_sec_caps[i].crypto_capabilities[
168 [ # # ]: 0 : nb_worker_sec_crypto_caps].op !=
169 : : RTE_CRYPTO_OP_TYPE_UNDEFINED)
170 : 0 : nb_worker_sec_crypto_caps++;
171 : :
172 [ # # ]: 0 : rte_memcpy(&sec_crypto_caps[nb_worker_supp_sec_caps][0],
173 : : &worker_sec_caps[i].crypto_capabilities[0],
174 : : sizeof(sec_crypto_caps[nb_worker_supp_sec_caps][0]) *
175 : : nb_worker_sec_crypto_caps);
176 : :
177 : 0 : nb_worker_supp_sec_caps++;
178 : : }
179 : 0 : return nb_worker_supp_sec_caps;
180 : : }
181 : :
182 [ # # ]: 0 : for (i = 0; i < nb_sec_caps; i++) {
183 : 0 : struct rte_security_capability *sec_cap = &sec_caps[i];
184 : : uint32_t j;
185 : :
186 [ # # ]: 0 : for (j = 0; j < nb_worker_sec_caps; j++) {
187 : : struct rte_cryptodev_capabilities
188 : 0 : tmp_sec_crypto_caps[MAX_CAPS] = { {0} };
189 : : uint32_t nb_sec_crypto_caps = 0;
190 : 0 : const struct rte_security_capability *worker_sec_cap =
191 : 0 : &worker_sec_caps[j];
192 : :
193 [ # # ]: 0 : if (!check_sec_cap_equal(worker_sec_cap, sec_cap))
194 : 0 : continue;
195 : :
196 : : /* Sync the crypto caps of the common security cap */
197 : 0 : nb_sec_crypto_caps = sync_sec_crypto_caps(
198 : : tmp_sec_crypto_caps,
199 : 0 : &sec_crypto_caps[i][0],
200 : 0 : &worker_sec_cap->crypto_capabilities[0]);
201 : :
202 : : memset(&sec_crypto_caps[i][0], 0,
203 : : sizeof(sec_crypto_caps[i][0]) * MAX_CAPS);
204 : :
205 [ # # ]: 0 : rte_memcpy(&sec_crypto_caps[i][0],
206 : : &tmp_sec_crypto_caps[0],
207 : : sizeof(sec_crypto_caps[i][0]) * nb_sec_crypto_caps);
208 : :
209 : 0 : break;
210 : : }
211 : :
212 [ # # ]: 0 : if (j < nb_worker_sec_caps)
213 : 0 : continue;
214 : :
215 : : /*
216 : : * Remove an uncommon security cap, and it's associated crypto
217 : : * caps, from the arrays
218 : : */
219 [ # # ]: 0 : for (j = i; j < nb_sec_caps - 1; j++) {
220 [ # # ]: 0 : rte_memcpy(&sec_caps[j], &sec_caps[j+1],
221 : : sizeof(*sec_cap));
222 : :
223 : 0 : rte_memcpy(&sec_crypto_caps[j][0],
224 [ # # ]: 0 : &sec_crypto_caps[j+1][0],
225 : : sizeof(*&sec_crypto_caps[j][0]) *
226 : : MAX_CAPS);
227 : : }
228 : 0 : memset(&sec_caps[nb_sec_caps - 1], 0, sizeof(*sec_cap));
229 : 0 : memset(&sec_crypto_caps[nb_sec_caps - 1][0], 0,
230 : : sizeof(*&sec_crypto_caps[nb_sec_caps - 1][0]) *
231 : : MAX_CAPS);
232 : : nb_sec_caps--;
233 : 0 : i--;
234 : : }
235 : :
236 : : return nb_sec_caps;
237 : : }
238 : :
239 : : static int
240 : 0 : update_scheduler_capability(struct scheduler_ctx *sched_ctx)
241 : : {
242 : 0 : struct rte_cryptodev_capabilities tmp_caps[MAX_CAPS] = { {0} };
243 : 0 : struct rte_security_capability tmp_sec_caps[MAX_CAPS] = { {0} };
244 : : struct rte_cryptodev_capabilities
245 : 0 : tmp_sec_crypto_caps[MAX_CAPS][MAX_CAPS] = { {{0}} };
246 : : uint32_t nb_caps = 0, nb_sec_caps = 0, i;
247 : : struct rte_cryptodev_info dev_info;
248 : :
249 : : /* Free any previously allocated capability memory */
250 : : scheduler_free_capabilities(sched_ctx);
251 : :
252 : : /* Determine the new cryptodev capabilities for the scheduler */
253 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
254 : 0 : rte_cryptodev_info_get(sched_ctx->workers[i].dev_id, &dev_info);
255 : :
256 : 0 : nb_caps = sync_caps(tmp_caps, nb_caps, dev_info.capabilities);
257 [ # # ]: 0 : if (nb_caps == 0)
258 : : return -1;
259 : : }
260 : :
261 : 0 : sched_ctx->capabilities = rte_zmalloc_socket(NULL,
262 : : sizeof(struct rte_cryptodev_capabilities) *
263 : 0 : (nb_caps + 1), 0, SOCKET_ID_ANY);
264 [ # # ]: 0 : if (!sched_ctx->capabilities)
265 : : return -ENOMEM;
266 : :
267 [ # # ]: 0 : rte_memcpy(sched_ctx->capabilities, tmp_caps,
268 : : sizeof(struct rte_cryptodev_capabilities) * nb_caps);
269 : :
270 : : /* Determine the new security capabilities for the scheduler */
271 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
272 : 0 : struct rte_cryptodev *dev =
273 : 0 : &rte_cryptodevs[sched_ctx->workers[i].dev_id];
274 : 0 : struct rte_security_ctx *sec_ctx = dev->security_ctx;
275 : :
276 : 0 : nb_sec_caps = sync_sec_caps(i, tmp_sec_caps, tmp_sec_crypto_caps,
277 : : nb_sec_caps, rte_security_capabilities_get(sec_ctx));
278 : : }
279 : :
280 : 0 : sched_ctx->sec_capabilities = rte_zmalloc_socket(NULL,
281 : : sizeof(struct rte_security_capability) *
282 : 0 : (nb_sec_caps + 1), 0, SOCKET_ID_ANY);
283 [ # # ]: 0 : if (!sched_ctx->sec_capabilities)
284 : : return -ENOMEM;
285 : :
286 : 0 : sched_ctx->sec_crypto_capabilities = rte_zmalloc_socket(NULL,
287 : : sizeof(struct rte_cryptodev_capabilities *) *
288 : : (nb_sec_caps + 1),
289 : : 0, SOCKET_ID_ANY);
290 [ # # ]: 0 : if (!sched_ctx->sec_crypto_capabilities)
291 : : return -ENOMEM;
292 : :
293 [ # # ]: 0 : for (i = 0; i < nb_sec_caps; i++) {
294 : : uint16_t nb_sec_crypto_caps = 0;
295 : :
296 [ # # ]: 0 : copy_sec_cap(&sched_ctx->sec_capabilities[i], &tmp_sec_caps[i]);
297 : :
298 [ # # ]: 0 : while (tmp_sec_crypto_caps[i][nb_sec_crypto_caps].op !=
299 : : RTE_CRYPTO_OP_TYPE_UNDEFINED)
300 : 0 : nb_sec_crypto_caps++;
301 : :
302 : 0 : sched_ctx->sec_crypto_capabilities[i] =
303 : 0 : rte_zmalloc_socket(NULL,
304 : : sizeof(struct rte_cryptodev_capabilities) *
305 : 0 : (nb_sec_crypto_caps + 1), 0, SOCKET_ID_ANY);
306 [ # # ]: 0 : if (!sched_ctx->sec_crypto_capabilities[i])
307 : : return -ENOMEM;
308 : :
309 : 0 : rte_memcpy(sched_ctx->sec_crypto_capabilities[i],
310 [ # # ]: 0 : &tmp_sec_crypto_caps[i][0],
311 : : sizeof(struct rte_cryptodev_capabilities)
312 : : * nb_sec_crypto_caps);
313 : :
314 : 0 : sched_ctx->sec_capabilities[i].crypto_capabilities =
315 : 0 : sched_ctx->sec_crypto_capabilities[i];
316 : : }
317 : :
318 : : return 0;
319 : : }
320 : :
321 : : static void
322 : 0 : update_scheduler_feature_flag(struct rte_cryptodev *dev)
323 : : {
324 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
325 : : uint32_t i;
326 : :
327 : 0 : dev->feature_flags = 0;
328 : :
329 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
330 : : struct rte_cryptodev_info dev_info;
331 : :
332 : 0 : rte_cryptodev_info_get(sched_ctx->workers[i].dev_id, &dev_info);
333 : :
334 : 0 : dev->feature_flags |= dev_info.feature_flags;
335 : : }
336 : 0 : }
337 : :
338 : : static void
339 : 0 : update_max_nb_qp(struct scheduler_ctx *sched_ctx)
340 : : {
341 : : uint32_t i;
342 : : uint32_t max_nb_qp;
343 : :
344 [ # # ]: 0 : if (!sched_ctx->nb_workers)
345 : : return;
346 : :
347 : : max_nb_qp = sched_ctx->nb_workers ? UINT32_MAX : 0;
348 : :
349 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
350 : : struct rte_cryptodev_info dev_info;
351 : :
352 : 0 : rte_cryptodev_info_get(sched_ctx->workers[i].dev_id, &dev_info);
353 : 0 : max_nb_qp = dev_info.max_nb_queue_pairs < max_nb_qp ?
354 : : dev_info.max_nb_queue_pairs : max_nb_qp;
355 : : }
356 : :
357 : 0 : sched_ctx->max_nb_queue_pairs = max_nb_qp;
358 : : }
359 : :
360 : : /** Attach a device to the scheduler. */
361 : : RTE_EXPORT_SYMBOL(rte_cryptodev_scheduler_worker_attach)
362 : : int
363 : 0 : rte_cryptodev_scheduler_worker_attach(uint8_t scheduler_id, uint8_t worker_id)
364 : : {
365 : 0 : struct rte_cryptodev *dev = rte_cryptodev_pmd_get_dev(scheduler_id);
366 : : struct scheduler_ctx *sched_ctx;
367 : : struct scheduler_worker *worker;
368 : : struct rte_cryptodev_info dev_info;
369 : : uint32_t i;
370 : :
371 [ # # ]: 0 : if (!dev) {
372 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
373 : 0 : return -ENOTSUP;
374 : : }
375 : :
376 [ # # ]: 0 : if (dev->driver_id != cryptodev_scheduler_driver_id) {
377 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
378 : 0 : return -ENOTSUP;
379 : : }
380 : :
381 [ # # ]: 0 : if (dev->data->dev_started) {
382 : 0 : CR_SCHED_LOG(ERR, "Illegal operation");
383 : 0 : return -EBUSY;
384 : : }
385 : :
386 : 0 : sched_ctx = dev->data->dev_private;
387 [ # # ]: 0 : if (sched_ctx->nb_workers >=
388 : : RTE_CRYPTODEV_SCHEDULER_MAX_NB_WORKERS) {
389 : 0 : CR_SCHED_LOG(ERR, "Too many workers attached");
390 : 0 : return -ENOMEM;
391 : : }
392 : :
393 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++)
394 [ # # ]: 0 : if (sched_ctx->workers[i].dev_id == worker_id) {
395 : 0 : CR_SCHED_LOG(ERR, "Worker already added");
396 : 0 : return -ENOTSUP;
397 : : }
398 : :
399 : : worker = &sched_ctx->workers[sched_ctx->nb_workers];
400 : :
401 : 0 : rte_cryptodev_info_get(worker_id, &dev_info);
402 : :
403 : 0 : worker->dev_id = worker_id;
404 : 0 : worker->driver_id = dev_info.driver_id;
405 : 0 : sched_ctx->nb_workers++;
406 : :
407 [ # # ]: 0 : if (update_scheduler_capability(sched_ctx) < 0) {
408 : : scheduler_free_capabilities(sched_ctx);
409 : 0 : worker->dev_id = 0;
410 : 0 : worker->driver_id = 0;
411 : 0 : sched_ctx->nb_workers--;
412 : :
413 : 0 : CR_SCHED_LOG(ERR, "capabilities update failed");
414 : 0 : return -ENOTSUP;
415 : : }
416 : :
417 : 0 : update_scheduler_feature_flag(dev);
418 : :
419 : 0 : update_max_nb_qp(sched_ctx);
420 : :
421 : 0 : return 0;
422 : : }
423 : :
424 : : RTE_EXPORT_SYMBOL(rte_cryptodev_scheduler_worker_detach)
425 : : int
426 : 0 : rte_cryptodev_scheduler_worker_detach(uint8_t scheduler_id, uint8_t worker_id)
427 : : {
428 : 0 : struct rte_cryptodev *dev = rte_cryptodev_pmd_get_dev(scheduler_id);
429 : : struct scheduler_ctx *sched_ctx;
430 : : uint32_t i, worker_pos;
431 : :
432 [ # # ]: 0 : if (!dev) {
433 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
434 : 0 : return -ENOTSUP;
435 : : }
436 : :
437 [ # # ]: 0 : if (dev->driver_id != cryptodev_scheduler_driver_id) {
438 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
439 : 0 : return -ENOTSUP;
440 : : }
441 : :
442 [ # # ]: 0 : if (dev->data->dev_started) {
443 : 0 : CR_SCHED_LOG(ERR, "Illegal operation");
444 : 0 : return -EBUSY;
445 : : }
446 : :
447 : 0 : sched_ctx = dev->data->dev_private;
448 : :
449 [ # # ]: 0 : for (worker_pos = 0; worker_pos < sched_ctx->nb_workers; worker_pos++)
450 [ # # ]: 0 : if (sched_ctx->workers[worker_pos].dev_id == worker_id)
451 : : break;
452 [ # # ]: 0 : if (worker_pos == sched_ctx->nb_workers) {
453 : 0 : CR_SCHED_LOG(ERR, "Cannot find worker");
454 : 0 : return -ENOTSUP;
455 : : }
456 : :
457 [ # # ]: 0 : if (sched_ctx->ops.worker_detach(dev, worker_id) < 0) {
458 : 0 : CR_SCHED_LOG(ERR, "Failed to detach worker");
459 : 0 : return -ENOTSUP;
460 : : }
461 : :
462 [ # # ]: 0 : for (i = worker_pos; i < sched_ctx->nb_workers - 1; i++) {
463 : 0 : memcpy(&sched_ctx->workers[i], &sched_ctx->workers[i+1],
464 : : sizeof(struct scheduler_worker));
465 : : }
466 : 0 : memset(&sched_ctx->workers[sched_ctx->nb_workers - 1], 0,
467 : : sizeof(struct scheduler_worker));
468 : 0 : sched_ctx->nb_workers--;
469 : :
470 [ # # ]: 0 : if (update_scheduler_capability(sched_ctx) < 0) {
471 : : scheduler_free_capabilities(sched_ctx);
472 : 0 : CR_SCHED_LOG(ERR, "capabilities update failed");
473 : 0 : return -ENOTSUP;
474 : : }
475 : :
476 : 0 : update_scheduler_feature_flag(dev);
477 : :
478 : 0 : update_max_nb_qp(sched_ctx);
479 : :
480 : 0 : return 0;
481 : : }
482 : :
483 : : RTE_EXPORT_SYMBOL(rte_cryptodev_scheduler_mode_set)
484 : : int
485 : 0 : rte_cryptodev_scheduler_mode_set(uint8_t scheduler_id,
486 : : enum rte_cryptodev_scheduler_mode mode)
487 : : {
488 : 0 : struct rte_cryptodev *dev = rte_cryptodev_pmd_get_dev(scheduler_id);
489 : : struct scheduler_ctx *sched_ctx;
490 : :
491 [ # # ]: 0 : if (!dev) {
492 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
493 : 0 : return -ENOTSUP;
494 : : }
495 : :
496 [ # # ]: 0 : if (dev->driver_id != cryptodev_scheduler_driver_id) {
497 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
498 : 0 : return -ENOTSUP;
499 : : }
500 : :
501 [ # # ]: 0 : if (dev->data->dev_started) {
502 : 0 : CR_SCHED_LOG(ERR, "Illegal operation");
503 : 0 : return -EBUSY;
504 : : }
505 : :
506 : 0 : sched_ctx = dev->data->dev_private;
507 : :
508 [ # # ]: 0 : if (mode == sched_ctx->mode)
509 : : return 0;
510 : :
511 [ # # # # : 0 : switch (mode) {
# ]
512 : 0 : case CDEV_SCHED_MODE_ROUNDROBIN:
513 [ # # ]: 0 : if (rte_cryptodev_scheduler_load_user_scheduler(scheduler_id,
514 : : crypto_scheduler_roundrobin) < 0) {
515 : 0 : CR_SCHED_LOG(ERR, "Failed to load scheduler");
516 : 0 : return -1;
517 : : }
518 : : break;
519 : 0 : case CDEV_SCHED_MODE_PKT_SIZE_DISTR:
520 [ # # ]: 0 : if (rte_cryptodev_scheduler_load_user_scheduler(scheduler_id,
521 : : crypto_scheduler_pkt_size_based_distr) < 0) {
522 : 0 : CR_SCHED_LOG(ERR, "Failed to load scheduler");
523 : 0 : return -1;
524 : : }
525 : : break;
526 : 0 : case CDEV_SCHED_MODE_FAILOVER:
527 [ # # ]: 0 : if (rte_cryptodev_scheduler_load_user_scheduler(scheduler_id,
528 : : crypto_scheduler_failover) < 0) {
529 : 0 : CR_SCHED_LOG(ERR, "Failed to load scheduler");
530 : 0 : return -1;
531 : : }
532 : : break;
533 : 0 : case CDEV_SCHED_MODE_MULTICORE:
534 [ # # ]: 0 : if (rte_cryptodev_scheduler_load_user_scheduler(scheduler_id,
535 : : crypto_scheduler_multicore) < 0) {
536 : 0 : CR_SCHED_LOG(ERR, "Failed to load scheduler");
537 : 0 : return -1;
538 : : }
539 : : break;
540 : 0 : default:
541 : 0 : CR_SCHED_LOG(ERR, "Not yet supported");
542 : 0 : return -ENOTSUP;
543 : : }
544 : :
545 : : return 0;
546 : : }
547 : :
548 : : RTE_EXPORT_SYMBOL(rte_cryptodev_scheduler_mode_get)
549 : : enum rte_cryptodev_scheduler_mode
550 : 0 : rte_cryptodev_scheduler_mode_get(uint8_t scheduler_id)
551 : : {
552 : 0 : struct rte_cryptodev *dev = rte_cryptodev_pmd_get_dev(scheduler_id);
553 : : struct scheduler_ctx *sched_ctx;
554 : :
555 [ # # ]: 0 : if (!dev) {
556 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
557 : 0 : return -ENOTSUP;
558 : : }
559 : :
560 [ # # ]: 0 : if (dev->driver_id != cryptodev_scheduler_driver_id) {
561 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
562 : 0 : return -ENOTSUP;
563 : : }
564 : :
565 : 0 : sched_ctx = dev->data->dev_private;
566 : :
567 : 0 : return sched_ctx->mode;
568 : : }
569 : :
570 : : RTE_EXPORT_SYMBOL(rte_cryptodev_scheduler_ordering_set)
571 : : int
572 : 0 : rte_cryptodev_scheduler_ordering_set(uint8_t scheduler_id,
573 : : uint32_t enable_reorder)
574 : : {
575 : 0 : struct rte_cryptodev *dev = rte_cryptodev_pmd_get_dev(scheduler_id);
576 : : struct scheduler_ctx *sched_ctx;
577 : :
578 [ # # ]: 0 : if (!dev) {
579 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
580 : 0 : return -ENOTSUP;
581 : : }
582 : :
583 [ # # ]: 0 : if (dev->driver_id != cryptodev_scheduler_driver_id) {
584 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
585 : 0 : return -ENOTSUP;
586 : : }
587 : :
588 [ # # ]: 0 : if (dev->data->dev_started) {
589 : 0 : CR_SCHED_LOG(ERR, "Illegal operation");
590 : 0 : return -EBUSY;
591 : : }
592 : :
593 : 0 : sched_ctx = dev->data->dev_private;
594 : :
595 : 0 : sched_ctx->reordering_enabled = enable_reorder;
596 : :
597 : 0 : return 0;
598 : : }
599 : :
600 : : RTE_EXPORT_SYMBOL(rte_cryptodev_scheduler_ordering_get)
601 : : int
602 : 0 : rte_cryptodev_scheduler_ordering_get(uint8_t scheduler_id)
603 : : {
604 : 0 : struct rte_cryptodev *dev = rte_cryptodev_pmd_get_dev(scheduler_id);
605 : : struct scheduler_ctx *sched_ctx;
606 : :
607 [ # # ]: 0 : if (!dev) {
608 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
609 : 0 : return -ENOTSUP;
610 : : }
611 : :
612 [ # # ]: 0 : if (dev->driver_id != cryptodev_scheduler_driver_id) {
613 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
614 : 0 : return -ENOTSUP;
615 : : }
616 : :
617 : 0 : sched_ctx = dev->data->dev_private;
618 : :
619 : 0 : return (int)sched_ctx->reordering_enabled;
620 : : }
621 : :
622 : : RTE_EXPORT_SYMBOL(rte_cryptodev_scheduler_load_user_scheduler)
623 : : int
624 : 0 : rte_cryptodev_scheduler_load_user_scheduler(uint8_t scheduler_id,
625 : : struct rte_cryptodev_scheduler *scheduler) {
626 : :
627 : 0 : struct rte_cryptodev *dev = rte_cryptodev_pmd_get_dev(scheduler_id);
628 : : struct scheduler_ctx *sched_ctx;
629 : :
630 [ # # ]: 0 : if (!dev) {
631 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
632 : 0 : return -ENOTSUP;
633 : : }
634 : :
635 [ # # ]: 0 : if (dev->driver_id != cryptodev_scheduler_driver_id) {
636 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
637 : 0 : return -ENOTSUP;
638 : : }
639 : :
640 [ # # ]: 0 : if (dev->data->dev_started) {
641 : 0 : CR_SCHED_LOG(ERR, "Illegal operation");
642 : 0 : return -EBUSY;
643 : : }
644 : :
645 : 0 : sched_ctx = dev->data->dev_private;
646 : :
647 [ # # ]: 0 : if (strlen(scheduler->name) > RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
648 : 0 : CR_SCHED_LOG(ERR, "Invalid name %s, should be less than "
649 : : "%u bytes.", scheduler->name,
650 : : RTE_CRYPTODEV_NAME_MAX_LEN);
651 : 0 : return -EINVAL;
652 : : }
653 [ # # ]: 0 : strlcpy(sched_ctx->name, scheduler->name, sizeof(sched_ctx->name));
654 : :
655 [ # # ]: 0 : if (strlen(scheduler->description) >
656 : : RTE_CRYPTODEV_SCHEDULER_DESC_MAX_LEN - 1) {
657 : 0 : CR_SCHED_LOG(ERR, "Invalid description %s, should be less than "
658 : : "%u bytes.", scheduler->description,
659 : : RTE_CRYPTODEV_SCHEDULER_DESC_MAX_LEN - 1);
660 : 0 : return -EINVAL;
661 : : }
662 [ # # ]: 0 : strlcpy(sched_ctx->description, scheduler->description,
663 : : sizeof(sched_ctx->description));
664 : :
665 : : /* load scheduler instance operations functions */
666 : 0 : sched_ctx->ops.config_queue_pair = scheduler->ops->config_queue_pair;
667 : 0 : sched_ctx->ops.create_private_ctx = scheduler->ops->create_private_ctx;
668 : 0 : sched_ctx->ops.scheduler_start = scheduler->ops->scheduler_start;
669 : 0 : sched_ctx->ops.scheduler_stop = scheduler->ops->scheduler_stop;
670 : 0 : sched_ctx->ops.worker_attach = scheduler->ops->worker_attach;
671 : 0 : sched_ctx->ops.worker_detach = scheduler->ops->worker_detach;
672 : 0 : sched_ctx->ops.option_set = scheduler->ops->option_set;
673 : 0 : sched_ctx->ops.option_get = scheduler->ops->option_get;
674 : :
675 [ # # ]: 0 : if (sched_ctx->private_ctx) {
676 : 0 : rte_free(sched_ctx->private_ctx);
677 : 0 : sched_ctx->private_ctx = NULL;
678 : : }
679 : :
680 [ # # ]: 0 : if (sched_ctx->ops.create_private_ctx) {
681 : 0 : int ret = (*sched_ctx->ops.create_private_ctx)(dev);
682 : :
683 [ # # ]: 0 : if (ret < 0) {
684 : 0 : CR_SCHED_LOG(ERR, "Unable to create scheduler private "
685 : : "context");
686 : 0 : return ret;
687 : : }
688 : : }
689 : :
690 : 0 : sched_ctx->mode = scheduler->mode;
691 : :
692 : 0 : return 0;
693 : : }
694 : :
695 : : RTE_EXPORT_SYMBOL(rte_cryptodev_scheduler_workers_get)
696 : : int
697 : 0 : rte_cryptodev_scheduler_workers_get(uint8_t scheduler_id, uint8_t *workers)
698 : : {
699 : 0 : struct rte_cryptodev *dev = rte_cryptodev_pmd_get_dev(scheduler_id);
700 : : struct scheduler_ctx *sched_ctx;
701 : : uint32_t nb_workers = 0;
702 : :
703 [ # # ]: 0 : if (!dev) {
704 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
705 : 0 : return -ENOTSUP;
706 : : }
707 : :
708 [ # # ]: 0 : if (dev->driver_id != cryptodev_scheduler_driver_id) {
709 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
710 : 0 : return -ENOTSUP;
711 : : }
712 : :
713 : 0 : sched_ctx = dev->data->dev_private;
714 : :
715 : 0 : nb_workers = sched_ctx->nb_workers;
716 : :
717 [ # # ]: 0 : if (workers && nb_workers) {
718 : : uint32_t i;
719 : :
720 [ # # ]: 0 : for (i = 0; i < nb_workers; i++)
721 : 0 : workers[i] = sched_ctx->workers[i].dev_id;
722 : : }
723 : :
724 : 0 : return (int)nb_workers;
725 : : }
726 : :
727 : : RTE_EXPORT_SYMBOL(rte_cryptodev_scheduler_option_set)
728 : : int
729 : 0 : rte_cryptodev_scheduler_option_set(uint8_t scheduler_id,
730 : : enum rte_cryptodev_schedule_option_type option_type,
731 : : void *option)
732 : : {
733 : 0 : struct rte_cryptodev *dev = rte_cryptodev_pmd_get_dev(scheduler_id);
734 : : struct scheduler_ctx *sched_ctx;
735 : :
736 [ # # ]: 0 : if (option_type == CDEV_SCHED_OPTION_NOT_SET ||
737 : : option_type >= CDEV_SCHED_OPTION_COUNT) {
738 : 0 : CR_SCHED_LOG(ERR, "Invalid option parameter");
739 : 0 : return -EINVAL;
740 : : }
741 : :
742 [ # # ]: 0 : if (!option) {
743 : 0 : CR_SCHED_LOG(ERR, "Invalid option parameter");
744 : 0 : return -EINVAL;
745 : : }
746 : :
747 [ # # ]: 0 : if (dev->data->dev_started) {
748 : 0 : CR_SCHED_LOG(ERR, "Illegal operation");
749 : 0 : return -EBUSY;
750 : : }
751 : :
752 : 0 : sched_ctx = dev->data->dev_private;
753 : :
754 [ # # ]: 0 : if (sched_ctx->ops.option_set == NULL)
755 : : return -ENOTSUP;
756 : :
757 : 0 : return sched_ctx->ops.option_set(dev, option_type, option);
758 : : }
759 : :
760 : : RTE_EXPORT_SYMBOL(rte_cryptodev_scheduler_option_get)
761 : : int
762 : 0 : rte_cryptodev_scheduler_option_get(uint8_t scheduler_id,
763 : : enum rte_cryptodev_schedule_option_type option_type,
764 : : void *option)
765 : : {
766 : 0 : struct rte_cryptodev *dev = rte_cryptodev_pmd_get_dev(scheduler_id);
767 : : struct scheduler_ctx *sched_ctx;
768 : :
769 [ # # ]: 0 : if (!dev) {
770 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
771 : 0 : return -ENOTSUP;
772 : : }
773 : :
774 [ # # ]: 0 : if (!option) {
775 : 0 : CR_SCHED_LOG(ERR, "Invalid option parameter");
776 : 0 : return -EINVAL;
777 : : }
778 : :
779 [ # # ]: 0 : if (dev->driver_id != cryptodev_scheduler_driver_id) {
780 : 0 : CR_SCHED_LOG(ERR, "Operation not supported");
781 : 0 : return -ENOTSUP;
782 : : }
783 : :
784 : 0 : sched_ctx = dev->data->dev_private;
785 : :
786 [ # # ]: 0 : if (sched_ctx->ops.option_get == NULL)
787 : : return -ENOTSUP;
788 : :
789 : 0 : return sched_ctx->ops.option_get(dev, option_type, option);
790 : : }
791 : :
792 : :
793 [ - + ]: 252 : RTE_LOG_REGISTER_DEFAULT(scheduler_logtype_driver, INFO);
|