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