1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 /* $FreeBSD$ */ 4 /** 5 ***************************************************************************** 6 * @file sal_ctrl_services.c 7 * 8 * @ingroup SalCtrl 9 * 10 * @description 11 * This file contains the core of the service controller implementation. 12 * 13 *****************************************************************************/ 14 15 /* QAT-API includes */ 16 #include "cpa.h" 17 #include "cpa_cy_key.h" 18 #include "cpa_cy_ln.h" 19 #include "cpa_cy_dh.h" 20 #include "cpa_cy_dsa.h" 21 #include "cpa_cy_rsa.h" 22 #include "cpa_cy_ec.h" 23 #include "cpa_cy_prime.h" 24 #include "cpa_cy_sym.h" 25 #include "cpa_dc.h" 26 27 /* QAT utils includes */ 28 #include "qat_utils.h" 29 30 /* ADF includes */ 31 #include "icp_adf_init.h" 32 #include "icp_adf_transport.h" 33 #include "icp_accel_devices.h" 34 #include "icp_adf_cfg.h" 35 #include "icp_adf_init.h" 36 #include "icp_adf_accel_mgr.h" 37 #include "icp_adf_debug.h" 38 39 /* FW includes */ 40 #include "icp_qat_fw_la.h" 41 42 /* SAL includes */ 43 #include "lac_mem.h" 44 #include "lac_mem_pools.h" 45 #include "lac_list.h" 46 #include "lac_hooks.h" 47 #include "sal_string_parse.h" 48 #include "lac_common.h" 49 #include "lac_sal_types.h" 50 #include "lac_sal.h" 51 #include "lac_sal_ctrl.h" 52 #include "icp_sal_versions.h" 53 54 #define MAX_SUBSYSTEM_RETRY 64 55 56 static char *subsystem_name = "SAL"; 57 /**< Name used by ADF to identify this component. */ 58 static char *cy_dir_name = "cy"; 59 static char *asym_dir_name = "asym"; 60 static char *sym_dir_name = "sym"; 61 static char *dc_dir_name = "dc"; 62 /**< Stats dir names. */ 63 static char *ver_file_name = "version"; 64 65 static subservice_registation_handle_t sal_service_reg_handle; 66 /**< Data structure used by ADF to keep a reference to this component. */ 67 68 /* 69 * @ingroup SalCtrl 70 * @description 71 * This function is used to parse the results from ADF 72 * in response to ServiceEnabled query.The results are 73 * semi-colon separated. Internally, the bitmask represented 74 * by the enabled_service is used to track which features are enabled. 75 * 76 * @context 77 * This functions is called from the SalCtrl_ServiceEventInit function. 78 * 79 * @assumptions 80 * None 81 * @sideEffects 82 * None 83 * @reentrant 84 * No 85 * @threadSafe 86 * Yes 87 * 88 * @param[in] device pointer to icp_accel_dev_t structure 89 * @param[in] pEnabledServices pointer to memory where enabled services will 90 * be written. 91 * @retval Status 92 */ 93 CpaStatus 94 SalCtrl_GetEnabledServices(icp_accel_dev_t *device, Cpa32U *pEnabledServices) 95 { 96 CpaStatus status = CPA_STATUS_SUCCESS; 97 char param_value[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 }; 98 char *token = NULL; 99 char *running = NULL; 100 101 *pEnabledServices = 0; 102 103 memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES); 104 status = icp_adf_cfgGetParamValue(device, 105 LAC_CFG_SECTION_GENERAL, 106 "ServicesEnabled", 107 param_value); 108 109 if (CPA_STATUS_SUCCESS == status) { 110 running = param_value; 111 112 token = strsep(&running, ";"); 113 114 while (NULL != token) { 115 do { 116 if (strncmp(token, "asym", strlen("asym")) == 117 0) { 118 *pEnabledServices |= 119 SAL_SERVICE_TYPE_CRYPTO_ASYM; 120 break; 121 } 122 if (strncmp(token, "sym", strlen("sym")) == 0) { 123 *pEnabledServices |= 124 SAL_SERVICE_TYPE_CRYPTO_SYM; 125 break; 126 } 127 if (strncmp(token, "cy", strlen("cy")) == 0) { 128 *pEnabledServices |= 129 SAL_SERVICE_TYPE_CRYPTO; 130 break; 131 } 132 if (strncmp(token, "dc", strlen("dc")) == 0) { 133 *pEnabledServices |= 134 SAL_SERVICE_TYPE_COMPRESSION; 135 break; 136 } 137 138 QAT_UTILS_LOG( 139 "Error parsing enabled services from ADF.\n"); 140 return CPA_STATUS_FAIL; 141 142 } while (0); 143 token = strsep(&running, ";"); 144 } 145 } else { 146 QAT_UTILS_LOG("Failed to get enabled services from ADF.\n"); 147 } 148 return status; 149 } 150 151 /* 152 * @ingroup SalCtrl 153 * @description 154 * This function is used to check whether a service is enabled 155 * 156 * @context 157 * This functions is called from the SalCtrl_ServiceEventInit function. 158 * 159 * @assumptions 160 * None 161 * @sideEffects 162 * None 163 * @reentrant 164 * No 165 * @threadSafe 166 * Yes 167 * 168 * param[in] enabled_services It is the bitmask for the enabled services 169 * param[in] service It is the service we want to check for 170 */ 171 CpaBoolean 172 SalCtrl_IsServiceEnabled(Cpa32U enabled_services, sal_service_type_t service) 173 { 174 return (CpaBoolean)((enabled_services & (Cpa32U)(service)) != 0); 175 } 176 177 /* 178 * @ingroup SalCtrl 179 * @description 180 * This function is used to check whether enabled services has associated 181 * hardware capability support 182 * 183 * @context 184 * This functions is called from the SalCtrl_ServiceEventInit function. 185 * 186 * @assumptions 187 * None 188 * @sideEffects 189 * None 190 * @reentrant 191 * No 192 * @threadSafe 193 * Yes 194 * 195 * param[in] device A pointer to an icp_accel_dev_t 196 * param[in] enabled_services It is the bitmask for the enabled services 197 */ 198 199 CpaStatus 200 SalCtrl_GetSupportedServices(icp_accel_dev_t *device, Cpa32U enabled_services) 201 { 202 CpaStatus status = CPA_STATUS_SUCCESS; 203 Cpa32U capabilitiesMask = 0; 204 205 status = icp_amgr_getAccelDevCapabilities(device, &capabilitiesMask); 206 207 if (CPA_STATUS_SUCCESS == status) { 208 if (SalCtrl_IsServiceEnabled(enabled_services, 209 SAL_SERVICE_TYPE_CRYPTO)) { 210 if (!(capabilitiesMask & 211 ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC) || 212 !(capabilitiesMask & 213 ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC)) { 214 QAT_UTILS_LOG( 215 "Device does not support Crypto service\n"); 216 status = CPA_STATUS_FAIL; 217 } 218 } 219 if (SalCtrl_IsServiceEnabled(enabled_services, 220 SAL_SERVICE_TYPE_CRYPTO_ASYM)) { 221 if (!(capabilitiesMask & 222 ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC)) { 223 QAT_UTILS_LOG( 224 "Device does not support Asym service\n"); 225 status = CPA_STATUS_FAIL; 226 } 227 } 228 if (SalCtrl_IsServiceEnabled(enabled_services, 229 SAL_SERVICE_TYPE_CRYPTO_SYM)) { 230 if (!(capabilitiesMask & 231 ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC)) { 232 QAT_UTILS_LOG( 233 "Device does not support Sym service\n"); 234 status = CPA_STATUS_FAIL; 235 } 236 } 237 if (SalCtrl_IsServiceEnabled(enabled_services, 238 SAL_SERVICE_TYPE_COMPRESSION)) { 239 if (!(capabilitiesMask & 240 ICP_ACCEL_CAPABILITIES_COMPRESSION)) { 241 QAT_UTILS_LOG( 242 "Device does not support Compression service.\n"); 243 status = CPA_STATUS_FAIL; 244 } 245 } 246 } 247 248 return status; 249 } 250 251 /************************************************************************* 252 * @ingroup SalCtrl 253 * @description 254 * This function is used to check if a service is supported 255 * on the device. The key difference between this and 256 * SalCtrl_GetSupportedServices() is that the latter treats it as 257 * an error if the service is unsupported. 258 * 259 * @context 260 * This can be called anywhere. 261 * 262 * @assumptions 263 * None 264 * @sideEffects 265 * None 266 * @reentrant 267 * No 268 * @threadSafe 269 * Yes 270 * 271 * param[in] device 272 * param[in] service service or services to check 273 * 274 *************************************************************************/ 275 CpaBoolean 276 SalCtrl_IsServiceSupported(icp_accel_dev_t *device, 277 sal_service_type_t service_to_check) 278 { 279 CpaStatus status = CPA_STATUS_SUCCESS; 280 Cpa32U capabilitiesMask = 0; 281 CpaBoolean service_supported = CPA_TRUE; 282 283 if (!(SalCtrl_IsServiceEnabled((Cpa32U)service_to_check, 284 SAL_SERVICE_TYPE_CRYPTO)) && 285 !(SalCtrl_IsServiceEnabled((Cpa32U)service_to_check, 286 SAL_SERVICE_TYPE_CRYPTO_ASYM)) && 287 !(SalCtrl_IsServiceEnabled((Cpa32U)service_to_check, 288 SAL_SERVICE_TYPE_CRYPTO_SYM)) && 289 !(SalCtrl_IsServiceEnabled((Cpa32U)service_to_check, 290 SAL_SERVICE_TYPE_COMPRESSION))) { 291 QAT_UTILS_LOG("Invalid service type\n"); 292 service_supported = CPA_FALSE; 293 } 294 295 status = icp_amgr_getAccelDevCapabilities(device, &capabilitiesMask); 296 297 if (CPA_STATUS_SUCCESS != status) { 298 QAT_UTILS_LOG("Can not get device capabilities.\n"); 299 return CPA_FALSE; 300 } 301 302 if (SalCtrl_IsServiceEnabled((Cpa32U)service_to_check, 303 SAL_SERVICE_TYPE_CRYPTO)) { 304 if (!(capabilitiesMask & 305 ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC) || 306 !(capabilitiesMask & 307 ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC)) { 308 QAT_UTILS_LOG( 309 "Device does not support Crypto service\n"); 310 service_supported = CPA_FALSE; 311 } 312 } 313 if (SalCtrl_IsServiceEnabled((Cpa32U)service_to_check, 314 SAL_SERVICE_TYPE_CRYPTO_ASYM)) { 315 if (!(capabilitiesMask & 316 ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC)) { 317 QAT_UTILS_LOG("Device does not support Asym service\n"); 318 service_supported = CPA_FALSE; 319 } 320 } 321 if (SalCtrl_IsServiceEnabled((Cpa32U)service_to_check, 322 SAL_SERVICE_TYPE_CRYPTO_SYM)) { 323 if (!(capabilitiesMask & 324 ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC)) { 325 QAT_UTILS_LOG("Device does not support Sym service\n"); 326 service_supported = CPA_FALSE; 327 } 328 } 329 if (SalCtrl_IsServiceEnabled((Cpa32U)service_to_check, 330 SAL_SERVICE_TYPE_COMPRESSION)) { 331 if (!(capabilitiesMask & ICP_ACCEL_CAPABILITIES_COMPRESSION)) { 332 QAT_UTILS_LOG( 333 "Device does not support Compression service.\n"); 334 service_supported = CPA_FALSE; 335 } 336 } 337 338 return service_supported; 339 } 340 341 /* 342 * @ingroup SalCtrl 343 * @description 344 * This function is used to retrieve how many instances are 345 * to be configured for process specific service. 346 * 347 * @context 348 * This functions is called from the SalCtrl_ServiceEventInit function. 349 * 350 * @assumptions 351 * None 352 * @sideEffects 353 * None 354 * @reentrant 355 * No 356 * @threadSafe 357 * Yes 358 * 359 * @param[in] device A pointer to an icp_accel_dev_t 360 * @param[in] key Represents the parameter's name we want to query 361 * @param[out] pCount Pointer to memory where num instances will be stored 362 * @retval status returned status from ADF or _FAIL if number of instances 363 * is out of range for the device. 364 */ 365 static CpaStatus 366 SalCtrl_GetInstanceCount(icp_accel_dev_t *device, char *key, Cpa32U *pCount) 367 { 368 CpaStatus status = CPA_STATUS_FAIL; 369 char param_value[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; 370 371 memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES); 372 status = icp_adf_cfgGetParamValue(device, 373 icpGetProcessName(), 374 key, 375 param_value); 376 if (CPA_STATUS_SUCCESS == status) { 377 *pCount = 378 (Cpa32U)(Sal_Strtoul(param_value, NULL, SAL_CFG_BASE_DEC)); 379 if (*pCount > SAL_MAX_NUM_INSTANCES_PER_DEV) { 380 QAT_UTILS_LOG("Number of instances is out of range.\n"); 381 status = CPA_STATUS_FAIL; 382 } 383 } 384 return status; 385 } 386 387 /************************************************************************** 388 * @ingroup SalCtrl 389 * @description 390 * This function calls the shutdown function on all the 391 * service instances. 392 * It also frees all service instance memory allocated at Init. 393 * 394 * @context 395 * This function is called from the SalCtrl_ServiceEventShutdown 396 * function. 397 * 398 * @assumptions 399 * params[in] should not be NULL 400 * @sideEffects 401 * None 402 * @reentrant 403 * No 404 * @threadSafe 405 * Yes 406 * 407 * @param[in] device An icp_accel_dev_t* type 408 * @param[in] services A pointer to the container of services 409 * @param[in] dbg_dir A pointer to the debug directory 410 * @param[in] svc_type The type of the service instance 411 * 412 ****************************************************************************/ 413 static CpaStatus 414 SalCtrl_ServiceShutdown(icp_accel_dev_t *device, 415 sal_list_t **services, 416 debug_dir_info_t **debug_dir, 417 sal_service_type_t svc_type) 418 { 419 CpaStatus status = CPA_STATUS_SUCCESS; 420 sal_list_t *dyn_service = NULL; 421 sal_service_t *inst = NULL; 422 423 /* Call Shutdown function for each service instance */ 424 SAL_FOR_EACH(*services, sal_service_t, device, shutdown, status); 425 426 if (*debug_dir) { 427 icp_adf_debugRemoveDir(*debug_dir); 428 LAC_OS_FREE(*debug_dir); 429 *debug_dir = NULL; 430 } 431 432 if (!icp_adf_is_dev_in_reset(device)) { 433 dyn_service = *services; 434 while (dyn_service) { 435 inst = (sal_service_t *)SalList_getObject(dyn_service); 436 if (CPA_TRUE == inst->is_dyn) { 437 icp_adf_putDynInstance(device, 438 (adf_service_type_t) 439 svc_type, 440 inst->instance); 441 } 442 dyn_service = SalList_next(dyn_service); 443 } 444 /* Free Sal services controller memory */ 445 SalList_free(services); 446 } else { 447 sal_list_t *curr_element = NULL; 448 sal_service_t *service = NULL; 449 curr_element = *services; 450 while (NULL != curr_element) { 451 service = 452 (sal_service_t *)SalList_getObject(curr_element); 453 service->state = SAL_SERVICE_STATE_RESTARTING; 454 curr_element = SalList_next(curr_element); 455 } 456 } 457 458 return status; 459 } 460 461 static CpaStatus 462 selectGeneration(device_type_t deviceType, sal_service_t *pInst) 463 { 464 switch (deviceType) { 465 case DEVICE_C62X: 466 case DEVICE_C62XVF: 467 case DEVICE_DH895XCC: 468 case DEVICE_DH895XCCVF: 469 case DEVICE_C3XXX: 470 case DEVICE_C3XXXVF: 471 case DEVICE_200XX: 472 case DEVICE_200XXVF: 473 pInst->gen = GEN2; 474 break; 475 476 case DEVICE_C4XXX: 477 case DEVICE_C4XXXVF: 478 pInst->gen = GEN3; 479 break; 480 481 case DEVICE_GEN4: 482 pInst->gen = GEN4; 483 break; 484 485 default: 486 QAT_UTILS_LOG("deviceType not initialised\n"); 487 return CPA_STATUS_FAIL; 488 } 489 return CPA_STATUS_SUCCESS; 490 } 491 492 /************************************************************************* 493 * @ingroup SalCtrl 494 * @description 495 * This function is used to initialise the service instances. 496 * It allocates memory for service instances and invokes the 497 * Init function on them. 498 * 499 * @context 500 * This function is called from the SalCtrl_ServiceEventInit function. 501 * 502 * @assumptions 503 * None 504 * @sideEffects 505 * None 506 * @reentrant 507 * No 508 * @threadSafe 509 * Yes 510 * 511 * @param[in] device An icp_accel_dev_t* type 512 * @param[in] services A pointer to the container of services 513 * @param[in] dbg_dir A pointer to the debug directory 514 * @param[in] dbg_dir_name Name of the debug directory 515 * @param[in] tail_list SAL's list of services 516 * @param[in] instance_count Number of instances 517 * @param[in] svc_type The type of the service instance 518 * 519 *************************************************************************/ 520 static CpaStatus 521 SalCtrl_ServiceInit(icp_accel_dev_t *device, 522 sal_list_t **services, 523 debug_dir_info_t **dbg_dir, 524 char *dbg_dir_name, 525 sal_list_t *tail_list, 526 Cpa32U instance_count, 527 sal_service_type_t svc_type) 528 { 529 CpaStatus status = CPA_STATUS_SUCCESS; 530 sal_service_t *pInst = NULL; 531 Cpa32U i = 0; 532 debug_dir_info_t *debug_dir = NULL; 533 534 debug_dir = LAC_OS_MALLOC(sizeof(debug_dir_info_t)); 535 if (NULL == debug_dir) { 536 QAT_UTILS_LOG("Failed to allocate memory for debug dir.\n"); 537 return CPA_STATUS_RESOURCE; 538 } 539 debug_dir->name = dbg_dir_name; 540 debug_dir->parent = NULL; 541 status = icp_adf_debugAddDir(device, debug_dir); 542 if (CPA_STATUS_SUCCESS != status) { 543 QAT_UTILS_LOG("Failed to add debug dir.\n"); 544 LAC_OS_FREE(debug_dir); 545 debug_dir = NULL; 546 return status; 547 } 548 549 if (!icp_adf_is_dev_in_reset(device)) { 550 for (i = 0; i < instance_count; i++) { 551 status = SalCtrl_ServiceCreate(svc_type, i, &pInst); 552 if (CPA_STATUS_SUCCESS != status) { 553 break; 554 } 555 pInst->debug_parent_dir = debug_dir; 556 pInst->capabilitiesMask = device->accelCapabilitiesMask; 557 558 status = selectGeneration(device->deviceType, pInst); 559 if (CPA_STATUS_SUCCESS == status) { 560 status = 561 SalList_add(services, &tail_list, pInst); 562 } 563 if (CPA_STATUS_SUCCESS != status) { 564 free(pInst, M_QAT); 565 } 566 } 567 } else { 568 sal_list_t *curr_element = *services; 569 sal_service_t *service = NULL; 570 while (NULL != curr_element) { 571 service = 572 (sal_service_t *)SalList_getObject(curr_element); 573 service->debug_parent_dir = debug_dir; 574 575 if (CPA_TRUE == service->isInstanceStarted) { 576 icp_qa_dev_get(device); 577 } 578 579 curr_element = SalList_next(curr_element); 580 } 581 } 582 583 if (CPA_STATUS_SUCCESS != status) { 584 QAT_UTILS_LOG("Failed to allocate all instances.\n"); 585 icp_adf_debugRemoveDir(debug_dir); 586 LAC_OS_FREE(debug_dir); 587 debug_dir = NULL; 588 SalList_free(services); 589 return status; 590 } 591 592 /* Call init function for each service instance */ 593 SAL_FOR_EACH(*services, sal_service_t, device, init, status); 594 if (CPA_STATUS_SUCCESS != status) { 595 QAT_UTILS_LOG("Failed to initialise all service instances.\n"); 596 /* shutdown all instances initialised before error */ 597 SAL_FOR_EACH_STATE(*services, 598 sal_service_t, 599 device, 600 shutdown, 601 SAL_SERVICE_STATE_INITIALIZED); 602 icp_adf_debugRemoveDir(debug_dir); 603 LAC_OS_FREE(debug_dir); 604 debug_dir = NULL; 605 SalList_free(services); 606 return status; 607 } 608 /* initialize the debug directory for relevant service */ 609 *dbg_dir = debug_dir; 610 611 return status; 612 } 613 614 /************************************************************************** 615 * @ingroup SalCtrl 616 * @description 617 * This function calls the start function on all the service instances. 618 * 619 * @context 620 * This function is called from the SalCtrl_ServiceEventStart function. 621 * 622 * @assumptions 623 * None 624 * @sideEffects 625 * None 626 * @reentrant 627 * No 628 * @threadSafe 629 * Yes 630 * 631 * @param[in] device An icp_accel_dev_t* type 632 * @param[in] services A pointer to the container of services 633 * 634 **************************************************************************/ 635 static CpaStatus 636 SalCtrl_ServiceStart(icp_accel_dev_t *device, sal_list_t *services) 637 { 638 CpaStatus status = CPA_STATUS_SUCCESS; 639 640 /* Call Start function for each service instance */ 641 SAL_FOR_EACH(services, sal_service_t, device, start, status); 642 if (CPA_STATUS_SUCCESS != status) { 643 QAT_UTILS_LOG("Failed to start all instances.\n"); 644 /* stop all instances started before error */ 645 SAL_FOR_EACH_STATE(services, 646 sal_service_t, 647 device, 648 stop, 649 SAL_SERVICE_STATE_RUNNING); 650 return status; 651 } 652 653 if (icp_adf_is_dev_in_reset(device)) { 654 sal_list_t *curr_element = services; 655 sal_service_t *service = NULL; 656 while (NULL != curr_element) { 657 service = 658 (sal_service_t *)SalList_getObject(curr_element); 659 if (service->notification_cb) { 660 service->notification_cb( 661 service, 662 service->cb_tag, 663 CPA_INSTANCE_EVENT_RESTARTED); 664 } 665 curr_element = SalList_next(curr_element); 666 } 667 } 668 669 return status; 670 } 671 672 /**************************************************************************** 673 * @ingroup SalCtrl 674 * @description 675 * This function calls the stop function on all the 676 * service instances. 677 * 678 * @context 679 * This function is called from the SalCtrl_ServiceEventStop function. 680 * 681 * @assumptions 682 * None 683 * @sideEffects 684 * None 685 * @reentrant 686 * No 687 * @threadSafe 688 * Yes 689 * 690 * @param[in] device An icp_accel_dev_t* type 691 * @param[in] services A pointer to the container of services 692 * 693 *************************************************************************/ 694 static CpaStatus 695 SalCtrl_ServiceStop(icp_accel_dev_t *device, sal_list_t *services) 696 { 697 CpaStatus status = CPA_STATUS_SUCCESS; 698 699 /* Calling restarting functions */ 700 if (icp_adf_is_dev_in_reset(device)) { 701 sal_list_t *curr_element = services; 702 sal_service_t *service = NULL; 703 while (NULL != curr_element) { 704 service = 705 (sal_service_t *)SalList_getObject(curr_element); 706 if (service->notification_cb) { 707 service->notification_cb( 708 service, 709 service->cb_tag, 710 CPA_INSTANCE_EVENT_RESTARTING); 711 } 712 curr_element = SalList_next(curr_element); 713 } 714 } 715 716 /* Call Stop function for each service instance */ 717 SAL_FOR_EACH(services, sal_service_t, device, stop, status); 718 719 return status; 720 } 721 722 /* 723 * @ingroup SalCtrl 724 * @description 725 * This function is used to print hardware and software versions in proc 726 * filesystem entry via ADF Debug interface 727 * 728 * @context 729 * This functions is called from proc filesystem interface 730 * 731 * @assumptions 732 * None 733 * @sideEffects 734 * None 735 * @reentrant 736 * No 737 * @threadSafe 738 * Yes 739 * 740 * @param[in] private_data A pointer to a private data passed to the 741 * function while adding a debug file. 742 * @param[out] data Pointer to a buffer where version information 743 * needs to be printed to. 744 * @param[in] size Size of a buffer pointed by data. 745 * @param[in] offset Offset in a debug file 746 * 747 * @retval 0 This function always returns 0 748 */ 749 static int 750 SalCtrl_VersionDebug(void *private_data, char *data, int size, int offset) 751 { 752 CpaStatus status = CPA_STATUS_SUCCESS; 753 Cpa32U len = 0; 754 icp_accel_dev_t *device = (icp_accel_dev_t *)private_data; 755 char param_value[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 }; 756 757 len += snprintf( 758 data + len, 759 size - len, 760 SEPARATOR BORDER 761 " Hardware and Software versions for device %d " BORDER 762 "\n" SEPARATOR, 763 device->accelId); 764 765 memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES); 766 status = icp_adf_cfgGetParamValue(device, 767 LAC_CFG_SECTION_GENERAL, 768 ICP_CFG_HW_REV_ID_KEY, 769 param_value); 770 LAC_CHECK_STATUS(status); 771 772 len += snprintf(data + len, 773 size - len, 774 " Hardware Version: %s %s \n", 775 param_value, 776 get_sku_info(device->sku)); 777 778 memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES); 779 status = icp_adf_cfgGetParamValue(device, 780 LAC_CFG_SECTION_GENERAL, 781 ICP_CFG_UOF_VER_KEY, 782 param_value); 783 LAC_CHECK_STATUS(status); 784 785 len += snprintf(data + len, 786 size - len, 787 " Firmware Version: %s \n", 788 param_value); 789 memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES); 790 status = icp_adf_cfgGetParamValue(device, 791 LAC_CFG_SECTION_GENERAL, 792 ICP_CFG_MMP_VER_KEY, 793 param_value); 794 LAC_CHECK_STATUS(status); 795 796 len += snprintf(data + len, 797 size - len, 798 " MMP Version: %s \n", 799 param_value); 800 len += snprintf(data + len, 801 size - len, 802 " Driver Version: %d.%d.%d \n", 803 SAL_INFO2_DRIVER_SW_VERSION_MAJ_NUMBER, 804 SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER, 805 SAL_INFO2_DRIVER_SW_VERSION_PATCH_NUMBER); 806 807 memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES); 808 status = icp_adf_cfgGetParamValue(device, 809 LAC_CFG_SECTION_GENERAL, 810 ICP_CFG_LO_COMPATIBLE_DRV_KEY, 811 param_value); 812 LAC_CHECK_STATUS(status); 813 814 len += snprintf(data + len, 815 size - len, 816 " Lowest Compatible Driver: %s \n", 817 param_value); 818 819 len += snprintf(data + len, 820 size - len, 821 " QuickAssist API CY Version: %d.%d \n", 822 CPA_CY_API_VERSION_NUM_MAJOR, 823 CPA_CY_API_VERSION_NUM_MINOR); 824 len += snprintf(data + len, 825 size - len, 826 " QuickAssist API DC Version: %d.%d \n", 827 CPA_DC_API_VERSION_NUM_MAJOR, 828 CPA_DC_API_VERSION_NUM_MINOR); 829 830 len += snprintf(data + len, size - len, SEPARATOR); 831 return 0; 832 } 833 834 /************************************************************************** 835 * @ingroup SalCtrl 836 * @description 837 * This function calls the shutdown function on all the service 838 * instances. It also frees all service instance memory 839 * allocated at Init. 840 * 841 * @context 842 * This function is called from the SalCtrl_ServiceEventHandler function. 843 * 844 * @assumptions 845 * None 846 * @sideEffects 847 * None 848 * @reentrant 849 * No 850 * @threadSafe 851 * Yes 852 * 853 * @param[in] device An icp_accel_dev_t* type 854 * @param[in] enabled_services Services enabled by user 855 * 856 ****************************************************************************/ 857 static CpaStatus 858 SalCtrl_ServiceEventShutdown(icp_accel_dev_t *device, Cpa32U enabled_services) 859 { 860 CpaStatus status = CPA_STATUS_SUCCESS; 861 CpaStatus ret_status = CPA_STATUS_SUCCESS; 862 sal_t *service_container = (sal_t *)device->pSalHandle; 863 864 if (NULL == service_container) { 865 QAT_UTILS_LOG("Private data is NULL\n"); 866 return CPA_STATUS_FATAL; 867 } 868 869 if (SalCtrl_IsServiceEnabled(enabled_services, 870 SAL_SERVICE_TYPE_CRYPTO)) { 871 status = 872 SalCtrl_ServiceShutdown(device, 873 &service_container->crypto_services, 874 &service_container->cy_dir, 875 SAL_SERVICE_TYPE_CRYPTO); 876 if (CPA_STATUS_SUCCESS != status) { 877 ret_status = status; 878 } 879 } 880 881 if (SalCtrl_IsServiceEnabled(enabled_services, 882 SAL_SERVICE_TYPE_CRYPTO_ASYM)) { 883 status = 884 SalCtrl_ServiceShutdown(device, 885 &service_container->asym_services, 886 &service_container->asym_dir, 887 SAL_SERVICE_TYPE_CRYPTO_ASYM); 888 if (CPA_STATUS_SUCCESS != status) { 889 ret_status = status; 890 } 891 } 892 893 if (SalCtrl_IsServiceEnabled(enabled_services, 894 SAL_SERVICE_TYPE_CRYPTO_SYM)) { 895 status = 896 SalCtrl_ServiceShutdown(device, 897 &service_container->sym_services, 898 &service_container->sym_dir, 899 SAL_SERVICE_TYPE_CRYPTO_SYM); 900 if (CPA_STATUS_SUCCESS != status) { 901 ret_status = status; 902 } 903 } 904 905 if (SalCtrl_IsServiceEnabled(enabled_services, 906 SAL_SERVICE_TYPE_COMPRESSION)) { 907 status = SalCtrl_ServiceShutdown( 908 device, 909 &service_container->compression_services, 910 &service_container->dc_dir, 911 SAL_SERVICE_TYPE_COMPRESSION); 912 if (CPA_STATUS_SUCCESS != status) { 913 ret_status = status; 914 } 915 } 916 917 if (service_container->ver_file) { 918 icp_adf_debugRemoveFile(service_container->ver_file); 919 LAC_OS_FREE(service_container->ver_file); 920 service_container->ver_file = NULL; 921 } 922 923 if (!icp_adf_is_dev_in_reset(device)) { 924 /* Free container also */ 925 free(service_container, M_QAT); 926 device->pSalHandle = NULL; 927 } 928 929 return ret_status; 930 } 931 932 /************************************************************************* 933 * @ingroup SalCtrl 934 * @description 935 * This function is used to initialize the service instances. 936 * It first checks (via ADF query) which services are enabled in the 937 * system and the number of each services. 938 * It then invokes the init function on them which creates the 939 * instances and allocates memory for them. 940 * 941 * @context 942 * This function is called from the SalCtrl_ServiceEventHandler function. 943 * 944 * @assumptions 945 * None 946 * @sideEffects 947 * None 948 * @reentrant 949 * No 950 * @threadSafe 951 * Yes 952 * 953 * @param[in] device An icp_accel_dev_t* type 954 * @param[in] enabled_services Services enabled by user 955 * 956 *************************************************************************/ 957 static CpaStatus 958 SalCtrl_ServiceEventInit(icp_accel_dev_t *device, Cpa32U enabled_services) 959 { 960 sal_t *service_container = NULL; 961 CpaStatus status = CPA_STATUS_SUCCESS; 962 sal_list_t *tail_list = NULL; 963 Cpa32U instance_count = 0; 964 965 status = SalCtrl_GetSupportedServices(device, enabled_services); 966 if (CPA_STATUS_SUCCESS != status) { 967 QAT_UTILS_LOG("Failed to get supported services.\n"); 968 return status; 969 } 970 971 if (!icp_adf_is_dev_in_reset(device)) { 972 service_container = malloc(sizeof(sal_t), M_QAT, M_WAITOK); 973 device->pSalHandle = service_container; 974 service_container->asym_services = NULL; 975 service_container->sym_services = NULL; 976 service_container->crypto_services = NULL; 977 service_container->compression_services = NULL; 978 } else { 979 service_container = device->pSalHandle; 980 } 981 service_container->asym_dir = NULL; 982 service_container->sym_dir = NULL; 983 service_container->cy_dir = NULL; 984 service_container->dc_dir = NULL; 985 service_container->ver_file = NULL; 986 987 service_container->ver_file = LAC_OS_MALLOC(sizeof(debug_file_info_t)); 988 if (NULL == service_container->ver_file) { 989 free(service_container, M_QAT); 990 return CPA_STATUS_RESOURCE; 991 } 992 993 memset(service_container->ver_file, 0, sizeof(debug_file_info_t)); 994 service_container->ver_file->name = ver_file_name; 995 service_container->ver_file->seq_read = SalCtrl_VersionDebug; 996 service_container->ver_file->private_data = device; 997 service_container->ver_file->parent = NULL; 998 999 status = icp_adf_debugAddFile(device, service_container->ver_file); 1000 if (CPA_STATUS_SUCCESS != status) { 1001 LAC_OS_FREE(service_container->ver_file); 1002 free(service_container, M_QAT); 1003 return status; 1004 } 1005 1006 if (SalCtrl_IsServiceEnabled(enabled_services, 1007 SAL_SERVICE_TYPE_CRYPTO_ASYM)) { 1008 status = SalCtrl_GetInstanceCount(device, 1009 "NumberCyInstances", 1010 &instance_count); 1011 if (CPA_STATUS_SUCCESS != status) { 1012 instance_count = 0; 1013 } 1014 status = SalCtrl_ServiceInit(device, 1015 &service_container->asym_services, 1016 &service_container->asym_dir, 1017 asym_dir_name, 1018 tail_list, 1019 instance_count, 1020 SAL_SERVICE_TYPE_CRYPTO_ASYM); 1021 if (CPA_STATUS_SUCCESS != status) { 1022 goto err_init; 1023 } 1024 } 1025 1026 if (SalCtrl_IsServiceEnabled(enabled_services, 1027 SAL_SERVICE_TYPE_CRYPTO_SYM)) { 1028 status = SalCtrl_GetInstanceCount(device, 1029 "NumberCyInstances", 1030 &instance_count); 1031 if (CPA_STATUS_SUCCESS != status) { 1032 instance_count = 0; 1033 } 1034 status = SalCtrl_ServiceInit(device, 1035 &service_container->sym_services, 1036 &service_container->sym_dir, 1037 sym_dir_name, 1038 tail_list, 1039 instance_count, 1040 SAL_SERVICE_TYPE_CRYPTO_SYM); 1041 if (CPA_STATUS_SUCCESS != status) { 1042 goto err_init; 1043 } 1044 } 1045 1046 if (SalCtrl_IsServiceEnabled(enabled_services, 1047 SAL_SERVICE_TYPE_CRYPTO)) { 1048 status = SalCtrl_GetInstanceCount(device, 1049 "NumberCyInstances", 1050 &instance_count); 1051 if (CPA_STATUS_SUCCESS != status) { 1052 instance_count = 0; 1053 } 1054 status = 1055 SalCtrl_ServiceInit(device, 1056 &service_container->crypto_services, 1057 &service_container->cy_dir, 1058 cy_dir_name, 1059 tail_list, 1060 instance_count, 1061 SAL_SERVICE_TYPE_CRYPTO); 1062 if (CPA_STATUS_SUCCESS != status) { 1063 goto err_init; 1064 } 1065 } 1066 if (SalCtrl_IsServiceEnabled(enabled_services, 1067 SAL_SERVICE_TYPE_COMPRESSION)) { 1068 status = SalCtrl_GetInstanceCount(device, 1069 "NumberDcInstances", 1070 &instance_count); 1071 if (CPA_STATUS_SUCCESS != status) { 1072 instance_count = 0; 1073 } 1074 status = SalCtrl_ServiceInit( 1075 device, 1076 &service_container->compression_services, 1077 &service_container->dc_dir, 1078 dc_dir_name, 1079 tail_list, 1080 instance_count, 1081 SAL_SERVICE_TYPE_COMPRESSION); 1082 if (CPA_STATUS_SUCCESS != status) { 1083 goto err_init; 1084 } 1085 } 1086 1087 return status; 1088 1089 err_init: 1090 SalCtrl_ServiceEventShutdown(device, enabled_services); 1091 return status; 1092 } 1093 1094 /**************************************************************************** 1095 * @ingroup SalCtrl 1096 * @description 1097 * This function calls the stop function on all the service instances. 1098 * 1099 * @context 1100 * This function is called from the SalCtrl_ServiceEventHandler function. 1101 * 1102 * @assumptions 1103 * None 1104 * @sideEffects 1105 * None 1106 * @reentrant 1107 * No 1108 * @threadSafe 1109 * Yes 1110 * 1111 * @param[in] device An icp_accel_dev_t* type 1112 * @param[in] enabled_services Enabled services by user 1113 * 1114 *************************************************************************/ 1115 static CpaStatus 1116 SalCtrl_ServiceEventStop(icp_accel_dev_t *device, Cpa32U enabled_services) 1117 { 1118 CpaStatus status = CPA_STATUS_SUCCESS; 1119 CpaStatus ret_status = CPA_STATUS_SUCCESS; 1120 sal_t *service_container = device->pSalHandle; 1121 1122 if (service_container == NULL) { 1123 QAT_UTILS_LOG("Private data is NULL.\n"); 1124 return CPA_STATUS_FATAL; 1125 } 1126 1127 if (SalCtrl_IsServiceEnabled(enabled_services, 1128 SAL_SERVICE_TYPE_CRYPTO_ASYM)) { 1129 status = SalCtrl_ServiceStop(device, 1130 service_container->asym_services); 1131 if (CPA_STATUS_SUCCESS != status) { 1132 ret_status = status; 1133 } 1134 } 1135 1136 if (SalCtrl_IsServiceEnabled(enabled_services, 1137 SAL_SERVICE_TYPE_CRYPTO_SYM)) { 1138 status = SalCtrl_ServiceStop(device, 1139 service_container->sym_services); 1140 if (CPA_STATUS_SUCCESS != status) { 1141 ret_status = status; 1142 } 1143 } 1144 1145 if (SalCtrl_IsServiceEnabled(enabled_services, 1146 SAL_SERVICE_TYPE_CRYPTO)) { 1147 status = 1148 SalCtrl_ServiceStop(device, 1149 service_container->crypto_services); 1150 if (CPA_STATUS_SUCCESS != status) { 1151 ret_status = status; 1152 } 1153 } 1154 1155 if (SalCtrl_IsServiceEnabled(enabled_services, 1156 SAL_SERVICE_TYPE_COMPRESSION)) { 1157 status = SalCtrl_ServiceStop( 1158 device, service_container->compression_services); 1159 if (CPA_STATUS_SUCCESS != status) { 1160 ret_status = status; 1161 } 1162 } 1163 1164 return ret_status; 1165 } 1166 1167 /************************************************************************** 1168 * @ingroup SalCtrl 1169 * @description 1170 * This function calls the start function on all the service instances. 1171 * 1172 * @context 1173 * This function is called from the SalCtrl_ServiceEventHandler function. 1174 * 1175 * @assumptions 1176 * None 1177 * @sideEffects 1178 * None 1179 * @reentrant 1180 * No 1181 * @threadSafe 1182 * Yes 1183 * 1184 * @param[in] device An icp_accel_dev_t* type 1185 * @param[in] enabled_services Enabled services by user 1186 * 1187 **************************************************************************/ 1188 static CpaStatus 1189 SalCtrl_ServiceEventStart(icp_accel_dev_t *device, Cpa32U enabled_services) 1190 { 1191 CpaStatus status = CPA_STATUS_SUCCESS; 1192 sal_t *service_container = device->pSalHandle; 1193 1194 if (service_container == NULL) { 1195 QAT_UTILS_LOG("Private data is NULL.\n"); 1196 return CPA_STATUS_FATAL; 1197 } 1198 1199 if (SalCtrl_IsServiceEnabled(enabled_services, 1200 SAL_SERVICE_TYPE_CRYPTO_ASYM)) { 1201 status = SalCtrl_ServiceStart(device, 1202 service_container->asym_services); 1203 if (CPA_STATUS_SUCCESS != status) { 1204 goto err_start; 1205 } 1206 } 1207 1208 if (SalCtrl_IsServiceEnabled(enabled_services, 1209 SAL_SERVICE_TYPE_CRYPTO_SYM)) { 1210 status = SalCtrl_ServiceStart(device, 1211 service_container->sym_services); 1212 if (CPA_STATUS_SUCCESS != status) { 1213 goto err_start; 1214 } 1215 } 1216 1217 if (SalCtrl_IsServiceEnabled(enabled_services, 1218 SAL_SERVICE_TYPE_CRYPTO)) { 1219 status = 1220 SalCtrl_ServiceStart(device, 1221 service_container->crypto_services); 1222 if (CPA_STATUS_SUCCESS != status) { 1223 goto err_start; 1224 } 1225 } 1226 1227 if (SalCtrl_IsServiceEnabled(enabled_services, 1228 SAL_SERVICE_TYPE_COMPRESSION)) { 1229 status = SalCtrl_ServiceStart( 1230 device, service_container->compression_services); 1231 if (CPA_STATUS_SUCCESS != status) { 1232 goto err_start; 1233 } 1234 } 1235 1236 return status; 1237 err_start: 1238 SalCtrl_ServiceEventStop(device, enabled_services); 1239 return status; 1240 } 1241 1242 /************************************************************************* 1243 * @ingroup SalCtrl 1244 * @description 1245 * This function is the events handler registered with ADF 1246 * for the QA API services (cy, dc) - kernel and user 1247 * 1248 * @context 1249 * This function is called from an ADF context. 1250 * 1251 * @assumptions 1252 * None 1253 * @sideEffects 1254 * None 1255 * @reentrant 1256 * No 1257 * @threadSafe 1258 * Yes 1259 * 1260 * @param[in] device An icp_accel_dev_t* type 1261 * @param[in] event Event from ADF 1262 * @param[in] param Parameter used for back compatibility 1263 * 1264 ***********************************************************************/ 1265 static CpaStatus 1266 SalCtrl_ServiceEventHandler(icp_accel_dev_t *device, 1267 icp_adf_subsystemEvent_t event, 1268 void *param) 1269 { 1270 CpaStatus status = CPA_STATUS_SUCCESS; 1271 CpaStatus stats_status = CPA_STATUS_SUCCESS; 1272 Cpa32U enabled_services = 0; 1273 1274 status = SalCtrl_GetEnabledServices(device, &enabled_services); 1275 if (CPA_STATUS_SUCCESS != status) { 1276 QAT_UTILS_LOG("Failed to get enabled services.\n"); 1277 return status; 1278 } 1279 1280 switch (event) { 1281 case ICP_ADF_EVENT_INIT: { 1282 /* In case there is no QAT SAL needs to call InitStats */ 1283 if (NULL == device->pQatStats) { 1284 status = SalStatistics_InitStatisticsCollection(device); 1285 } 1286 if (CPA_STATUS_SUCCESS != status) { 1287 return status; 1288 } 1289 1290 status = SalCtrl_ServiceEventInit(device, enabled_services); 1291 break; 1292 } 1293 case ICP_ADF_EVENT_START: { 1294 status = SalCtrl_ServiceEventStart(device, enabled_services); 1295 break; 1296 } 1297 case ICP_ADF_EVENT_STOP: { 1298 status = SalCtrl_ServiceEventStop(device, enabled_services); 1299 break; 1300 } 1301 case ICP_ADF_EVENT_SHUTDOWN: { 1302 status = SalCtrl_ServiceEventShutdown(device, enabled_services); 1303 stats_status = SalStatistics_CleanStatisticsCollection(device); 1304 if (CPA_STATUS_SUCCESS != status || 1305 CPA_STATUS_SUCCESS != stats_status) { 1306 return CPA_STATUS_FAIL; 1307 } 1308 break; 1309 } 1310 default: 1311 status = CPA_STATUS_SUCCESS; 1312 break; 1313 } 1314 return status; 1315 } 1316 1317 CpaStatus 1318 SalCtrl_AdfServicesRegister(void) 1319 { 1320 /* Fill out the global sal_service_reg_handle structure */ 1321 sal_service_reg_handle.subserviceEventHandler = 1322 SalCtrl_ServiceEventHandler; 1323 /* Set subsystem name to globally defined name */ 1324 sal_service_reg_handle.subsystem_name = subsystem_name; 1325 1326 return icp_adf_subsystemRegister(&sal_service_reg_handle); 1327 } 1328 1329 CpaStatus 1330 SalCtrl_AdfServicesUnregister(void) 1331 { 1332 return icp_adf_subsystemUnregister(&sal_service_reg_handle); 1333 } 1334 1335 CpaStatus 1336 SalCtrl_AdfServicesStartedCheck(void) 1337 { 1338 CpaStatus status = CPA_STATUS_SUCCESS; 1339 Cpa32U retry_num = 0; 1340 CpaBoolean state = CPA_FALSE; 1341 1342 do { 1343 state = icp_adf_isSubsystemStarted(&sal_service_reg_handle); 1344 retry_num++; 1345 } while ((CPA_FALSE == state) && (retry_num < MAX_SUBSYSTEM_RETRY)); 1346 1347 if (CPA_FALSE == state) { 1348 QAT_UTILS_LOG("Sal Ctrl failed to start in given time.\n"); 1349 status = CPA_STATUS_FAIL; 1350 } 1351 1352 return status; 1353 } 1354 1355 CpaStatus 1356 validateConcurrRequest(Cpa32U numConcurrRequests) 1357 { 1358 Cpa32U baseReq = SAL_64_CONCURR_REQUESTS; 1359 1360 if (SAL_64_CONCURR_REQUESTS > numConcurrRequests) { 1361 QAT_UTILS_LOG( 1362 "Invalid numConcurrRequests, it is less than min value.\n"); 1363 return CPA_STATUS_FAIL; 1364 } 1365 1366 while (SAL_MAX_CONCURR_REQUESTS >= baseReq) { 1367 if (baseReq != numConcurrRequests) { 1368 baseReq = baseReq << 1; 1369 } else { 1370 break; 1371 } 1372 } 1373 if (SAL_MAX_CONCURR_REQUESTS < baseReq) { 1374 QAT_UTILS_LOG( 1375 "Invalid baseReg, it is greater than max value.\n"); 1376 return CPA_STATUS_FAIL; 1377 } 1378 1379 return CPA_STATUS_SUCCESS; 1380 } 1381