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