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 /************************************************************************* 462 * @ingroup SalCtrl 463 * @description 464 * This function is used to initialise the service instances. 465 * It allocates memory for service instances and invokes the 466 * Init function on them. 467 * 468 * @context 469 * This function is called from the SalCtrl_ServiceEventInit function. 470 * 471 * @assumptions 472 * None 473 * @sideEffects 474 * None 475 * @reentrant 476 * No 477 * @threadSafe 478 * Yes 479 * 480 * @param[in] device An icp_accel_dev_t* type 481 * @param[in] services A pointer to the container of services 482 * @param[in] dbg_dir A pointer to the debug directory 483 * @param[in] dbg_dir_name Name of the debug directory 484 * @param[in] tail_list SAL's list of services 485 * @param[in] instance_count Number of instances 486 * @param[in] svc_type The type of the service instance 487 * 488 *************************************************************************/ 489 static CpaStatus 490 SalCtrl_ServiceInit(icp_accel_dev_t *device, 491 sal_list_t **services, 492 debug_dir_info_t **dbg_dir, 493 char *dbg_dir_name, 494 sal_list_t *tail_list, 495 Cpa32U instance_count, 496 sal_service_type_t svc_type) 497 { 498 CpaStatus status = CPA_STATUS_SUCCESS; 499 sal_service_t *pInst = NULL; 500 Cpa32U i = 0; 501 debug_dir_info_t *debug_dir = NULL; 502 503 debug_dir = LAC_OS_MALLOC(sizeof(debug_dir_info_t)); 504 if (NULL == debug_dir) { 505 QAT_UTILS_LOG("Failed to allocate memory for debug dir.\n"); 506 return CPA_STATUS_RESOURCE; 507 } 508 debug_dir->name = dbg_dir_name; 509 debug_dir->parent = NULL; 510 status = icp_adf_debugAddDir(device, debug_dir); 511 if (CPA_STATUS_SUCCESS != status) { 512 QAT_UTILS_LOG("Failed to add debug dir.\n"); 513 LAC_OS_FREE(debug_dir); 514 debug_dir = NULL; 515 return status; 516 } 517 518 if (!icp_adf_is_dev_in_reset(device)) { 519 for (i = 0; i < instance_count; i++) { 520 status = SalCtrl_ServiceCreate(svc_type, i, &pInst); 521 if (CPA_STATUS_SUCCESS != status) { 522 break; 523 } 524 pInst->debug_parent_dir = debug_dir; 525 pInst->capabilitiesMask = device->accelCapabilitiesMask; 526 status = SalList_add(services, &tail_list, pInst); 527 if (CPA_STATUS_SUCCESS != status) { 528 free(pInst, M_QAT); 529 } 530 } 531 } else { 532 sal_list_t *curr_element = *services; 533 sal_service_t *service = NULL; 534 while (NULL != curr_element) { 535 service = 536 (sal_service_t *)SalList_getObject(curr_element); 537 service->debug_parent_dir = debug_dir; 538 539 if (CPA_TRUE == service->isInstanceStarted) { 540 icp_qa_dev_get(device); 541 } 542 543 curr_element = SalList_next(curr_element); 544 } 545 } 546 547 if (CPA_STATUS_SUCCESS != status) { 548 QAT_UTILS_LOG("Failed to allocate all instances.\n"); 549 icp_adf_debugRemoveDir(debug_dir); 550 LAC_OS_FREE(debug_dir); 551 debug_dir = NULL; 552 SalList_free(services); 553 return status; 554 } 555 556 /* Call init function for each service instance */ 557 SAL_FOR_EACH(*services, sal_service_t, device, init, status); 558 if (CPA_STATUS_SUCCESS != status) { 559 QAT_UTILS_LOG("Failed to initialise all service instances.\n"); 560 /* shutdown all instances initialised before error */ 561 SAL_FOR_EACH_STATE(*services, 562 sal_service_t, 563 device, 564 shutdown, 565 SAL_SERVICE_STATE_INITIALIZED); 566 icp_adf_debugRemoveDir(debug_dir); 567 LAC_OS_FREE(debug_dir); 568 debug_dir = NULL; 569 SalList_free(services); 570 return status; 571 } 572 /* initialize the debug directory for relevant service */ 573 *dbg_dir = debug_dir; 574 575 return status; 576 } 577 578 /************************************************************************** 579 * @ingroup SalCtrl 580 * @description 581 * This function calls the start function on all the service instances. 582 * 583 * @context 584 * This function is called from the SalCtrl_ServiceEventStart function. 585 * 586 * @assumptions 587 * None 588 * @sideEffects 589 * None 590 * @reentrant 591 * No 592 * @threadSafe 593 * Yes 594 * 595 * @param[in] device An icp_accel_dev_t* type 596 * @param[in] services A pointer to the container of services 597 * 598 **************************************************************************/ 599 static CpaStatus 600 SalCtrl_ServiceStart(icp_accel_dev_t *device, sal_list_t *services) 601 { 602 CpaStatus status = CPA_STATUS_SUCCESS; 603 604 /* Call Start function for each service instance */ 605 SAL_FOR_EACH(services, sal_service_t, device, start, status); 606 if (CPA_STATUS_SUCCESS != status) { 607 QAT_UTILS_LOG("Failed to start all instances.\n"); 608 /* stop all instances started before error */ 609 SAL_FOR_EACH_STATE(services, 610 sal_service_t, 611 device, 612 stop, 613 SAL_SERVICE_STATE_RUNNING); 614 return status; 615 } 616 617 if (icp_adf_is_dev_in_reset(device)) { 618 sal_list_t *curr_element = services; 619 sal_service_t *service = NULL; 620 while (NULL != curr_element) { 621 service = 622 (sal_service_t *)SalList_getObject(curr_element); 623 if (service->notification_cb) { 624 service->notification_cb( 625 service, 626 service->cb_tag, 627 CPA_INSTANCE_EVENT_RESTARTED); 628 } 629 curr_element = SalList_next(curr_element); 630 } 631 } 632 633 return status; 634 } 635 636 /**************************************************************************** 637 * @ingroup SalCtrl 638 * @description 639 * This function calls the stop function on all the 640 * service instances. 641 * 642 * @context 643 * This function is called from the SalCtrl_ServiceEventStop function. 644 * 645 * @assumptions 646 * None 647 * @sideEffects 648 * None 649 * @reentrant 650 * No 651 * @threadSafe 652 * Yes 653 * 654 * @param[in] device An icp_accel_dev_t* type 655 * @param[in] services A pointer to the container of services 656 * 657 *************************************************************************/ 658 static CpaStatus 659 SalCtrl_ServiceStop(icp_accel_dev_t *device, sal_list_t *services) 660 { 661 CpaStatus status = CPA_STATUS_SUCCESS; 662 663 /* Calling restarting functions */ 664 if (icp_adf_is_dev_in_reset(device)) { 665 sal_list_t *curr_element = services; 666 sal_service_t *service = NULL; 667 while (NULL != curr_element) { 668 service = 669 (sal_service_t *)SalList_getObject(curr_element); 670 if (service->notification_cb) { 671 service->notification_cb( 672 service, 673 service->cb_tag, 674 CPA_INSTANCE_EVENT_RESTARTING); 675 } 676 curr_element = SalList_next(curr_element); 677 } 678 } 679 680 /* Call Stop function for each service instance */ 681 SAL_FOR_EACH(services, sal_service_t, device, stop, status); 682 683 return status; 684 } 685 686 /* 687 * @ingroup SalCtrl 688 * @description 689 * This function is used to print hardware and software versions in proc 690 * filesystem entry via ADF Debug interface 691 * 692 * @context 693 * This functions is called from proc filesystem interface 694 * 695 * @assumptions 696 * None 697 * @sideEffects 698 * None 699 * @reentrant 700 * No 701 * @threadSafe 702 * Yes 703 * 704 * @param[in] private_data A pointer to a private data passed to the 705 * function while adding a debug file. 706 * @param[out] data Pointer to a buffer where version information 707 * needs to be printed to. 708 * @param[in] size Size of a buffer pointed by data. 709 * @param[in] offset Offset in a debug file 710 * 711 * @retval 0 This function always returns 0 712 */ 713 static int 714 SalCtrl_VersionDebug(void *private_data, char *data, int size, int offset) 715 { 716 CpaStatus status = CPA_STATUS_SUCCESS; 717 Cpa32U len = 0; 718 icp_accel_dev_t *device = (icp_accel_dev_t *)private_data; 719 char param_value[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 }; 720 721 len += snprintf( 722 data + len, 723 size - len, 724 SEPARATOR BORDER 725 " Hardware and Software versions for device %d " BORDER 726 "\n" SEPARATOR, 727 device->accelId); 728 729 memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES); 730 status = icp_adf_cfgGetParamValue(device, 731 LAC_CFG_SECTION_GENERAL, 732 ICP_CFG_HW_REV_ID_KEY, 733 param_value); 734 LAC_CHECK_STATUS(status); 735 736 len += snprintf(data + len, 737 size - len, 738 " Hardware Version: %s %s \n", 739 param_value, 740 get_sku_info(device->sku)); 741 742 memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES); 743 status = icp_adf_cfgGetParamValue(device, 744 LAC_CFG_SECTION_GENERAL, 745 ICP_CFG_UOF_VER_KEY, 746 param_value); 747 LAC_CHECK_STATUS(status); 748 749 len += snprintf(data + len, 750 size - len, 751 " Firmware Version: %s \n", 752 param_value); 753 memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES); 754 status = icp_adf_cfgGetParamValue(device, 755 LAC_CFG_SECTION_GENERAL, 756 ICP_CFG_MMP_VER_KEY, 757 param_value); 758 LAC_CHECK_STATUS(status); 759 760 len += snprintf(data + len, 761 size - len, 762 " MMP Version: %s \n", 763 param_value); 764 len += snprintf(data + len, 765 size - len, 766 " Driver Version: %d.%d.%d \n", 767 SAL_INFO2_DRIVER_SW_VERSION_MAJ_NUMBER, 768 SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER, 769 SAL_INFO2_DRIVER_SW_VERSION_PATCH_NUMBER); 770 771 memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES); 772 status = icp_adf_cfgGetParamValue(device, 773 LAC_CFG_SECTION_GENERAL, 774 ICP_CFG_LO_COMPATIBLE_DRV_KEY, 775 param_value); 776 LAC_CHECK_STATUS(status); 777 778 len += snprintf(data + len, 779 size - len, 780 " Lowest Compatible Driver: %s \n", 781 param_value); 782 783 len += snprintf(data + len, 784 size - len, 785 " QuickAssist API CY Version: %d.%d \n", 786 CPA_CY_API_VERSION_NUM_MAJOR, 787 CPA_CY_API_VERSION_NUM_MINOR); 788 len += snprintf(data + len, 789 size - len, 790 " QuickAssist API DC Version: %d.%d \n", 791 CPA_DC_API_VERSION_NUM_MAJOR, 792 CPA_DC_API_VERSION_NUM_MINOR); 793 794 len += snprintf(data + len, size - len, SEPARATOR); 795 return 0; 796 } 797 798 /************************************************************************** 799 * @ingroup SalCtrl 800 * @description 801 * This function calls the shutdown function on all the service 802 * instances. It also frees all service instance memory 803 * allocated at Init. 804 * 805 * @context 806 * This function is called from the SalCtrl_ServiceEventHandler function. 807 * 808 * @assumptions 809 * None 810 * @sideEffects 811 * None 812 * @reentrant 813 * No 814 * @threadSafe 815 * Yes 816 * 817 * @param[in] device An icp_accel_dev_t* type 818 * @param[in] enabled_services Services enabled by user 819 * 820 ****************************************************************************/ 821 static CpaStatus 822 SalCtrl_ServiceEventShutdown(icp_accel_dev_t *device, Cpa32U enabled_services) 823 { 824 CpaStatus status = CPA_STATUS_SUCCESS; 825 CpaStatus ret_status = CPA_STATUS_SUCCESS; 826 sal_t *service_container = (sal_t *)device->pSalHandle; 827 828 if (NULL == service_container) { 829 QAT_UTILS_LOG("Private data is NULL\n"); 830 return CPA_STATUS_FATAL; 831 } 832 833 if (SalCtrl_IsServiceEnabled(enabled_services, 834 SAL_SERVICE_TYPE_CRYPTO)) { 835 status = 836 SalCtrl_ServiceShutdown(device, 837 &service_container->crypto_services, 838 &service_container->cy_dir, 839 SAL_SERVICE_TYPE_CRYPTO); 840 if (CPA_STATUS_SUCCESS != status) { 841 ret_status = status; 842 } 843 } 844 845 if (SalCtrl_IsServiceEnabled(enabled_services, 846 SAL_SERVICE_TYPE_CRYPTO_ASYM)) { 847 status = 848 SalCtrl_ServiceShutdown(device, 849 &service_container->asym_services, 850 &service_container->asym_dir, 851 SAL_SERVICE_TYPE_CRYPTO_ASYM); 852 if (CPA_STATUS_SUCCESS != status) { 853 ret_status = status; 854 } 855 } 856 857 if (SalCtrl_IsServiceEnabled(enabled_services, 858 SAL_SERVICE_TYPE_CRYPTO_SYM)) { 859 status = 860 SalCtrl_ServiceShutdown(device, 861 &service_container->sym_services, 862 &service_container->sym_dir, 863 SAL_SERVICE_TYPE_CRYPTO_SYM); 864 if (CPA_STATUS_SUCCESS != status) { 865 ret_status = status; 866 } 867 } 868 869 if (SalCtrl_IsServiceEnabled(enabled_services, 870 SAL_SERVICE_TYPE_COMPRESSION)) { 871 status = SalCtrl_ServiceShutdown( 872 device, 873 &service_container->compression_services, 874 &service_container->dc_dir, 875 SAL_SERVICE_TYPE_COMPRESSION); 876 if (CPA_STATUS_SUCCESS != status) { 877 ret_status = status; 878 } 879 } 880 881 if (service_container->ver_file) { 882 icp_adf_debugRemoveFile(service_container->ver_file); 883 LAC_OS_FREE(service_container->ver_file); 884 service_container->ver_file = NULL; 885 } 886 887 if (!icp_adf_is_dev_in_reset(device)) { 888 /* Free container also */ 889 free(service_container, M_QAT); 890 device->pSalHandle = NULL; 891 } 892 893 return ret_status; 894 } 895 896 /************************************************************************* 897 * @ingroup SalCtrl 898 * @description 899 * This function is used to initialize the service instances. 900 * It first checks (via ADF query) which services are enabled in the 901 * system and the number of each services. 902 * It then invokes the init function on them which creates the 903 * instances and allocates memory for them. 904 * 905 * @context 906 * This function is called from the SalCtrl_ServiceEventHandler function. 907 * 908 * @assumptions 909 * None 910 * @sideEffects 911 * None 912 * @reentrant 913 * No 914 * @threadSafe 915 * Yes 916 * 917 * @param[in] device An icp_accel_dev_t* type 918 * @param[in] enabled_services Services enabled by user 919 * 920 *************************************************************************/ 921 static CpaStatus 922 SalCtrl_ServiceEventInit(icp_accel_dev_t *device, Cpa32U enabled_services) 923 { 924 sal_t *service_container = NULL; 925 CpaStatus status = CPA_STATUS_SUCCESS; 926 sal_list_t *tail_list = NULL; 927 Cpa32U instance_count = 0; 928 929 status = SalCtrl_GetSupportedServices(device, enabled_services); 930 if (CPA_STATUS_SUCCESS != status) { 931 QAT_UTILS_LOG("Failed to get supported services.\n"); 932 return status; 933 } 934 935 if (!icp_adf_is_dev_in_reset(device)) { 936 service_container = malloc(sizeof(sal_t), M_QAT, M_WAITOK); 937 device->pSalHandle = service_container; 938 service_container->asym_services = NULL; 939 service_container->sym_services = NULL; 940 service_container->crypto_services = NULL; 941 service_container->compression_services = NULL; 942 } else { 943 service_container = device->pSalHandle; 944 } 945 service_container->asym_dir = NULL; 946 service_container->sym_dir = NULL; 947 service_container->cy_dir = NULL; 948 service_container->dc_dir = NULL; 949 service_container->ver_file = NULL; 950 951 service_container->ver_file = LAC_OS_MALLOC(sizeof(debug_file_info_t)); 952 if (NULL == service_container->ver_file) { 953 free(service_container, M_QAT); 954 return CPA_STATUS_RESOURCE; 955 } 956 957 memset(service_container->ver_file, 0, sizeof(debug_file_info_t)); 958 service_container->ver_file->name = ver_file_name; 959 service_container->ver_file->seq_read = SalCtrl_VersionDebug; 960 service_container->ver_file->private_data = device; 961 service_container->ver_file->parent = NULL; 962 963 status = icp_adf_debugAddFile(device, service_container->ver_file); 964 if (CPA_STATUS_SUCCESS != status) { 965 LAC_OS_FREE(service_container->ver_file); 966 free(service_container, M_QAT); 967 return status; 968 } 969 970 if (SalCtrl_IsServiceEnabled(enabled_services, 971 SAL_SERVICE_TYPE_CRYPTO_ASYM)) { 972 status = SalCtrl_GetInstanceCount(device, 973 "NumberCyInstances", 974 &instance_count); 975 if (CPA_STATUS_SUCCESS != status) { 976 instance_count = 0; 977 } 978 status = SalCtrl_ServiceInit(device, 979 &service_container->asym_services, 980 &service_container->asym_dir, 981 asym_dir_name, 982 tail_list, 983 instance_count, 984 SAL_SERVICE_TYPE_CRYPTO_ASYM); 985 if (CPA_STATUS_SUCCESS != status) { 986 goto err_init; 987 } 988 } 989 990 if (SalCtrl_IsServiceEnabled(enabled_services, 991 SAL_SERVICE_TYPE_CRYPTO_SYM)) { 992 status = SalCtrl_GetInstanceCount(device, 993 "NumberCyInstances", 994 &instance_count); 995 if (CPA_STATUS_SUCCESS != status) { 996 instance_count = 0; 997 } 998 status = SalCtrl_ServiceInit(device, 999 &service_container->sym_services, 1000 &service_container->sym_dir, 1001 sym_dir_name, 1002 tail_list, 1003 instance_count, 1004 SAL_SERVICE_TYPE_CRYPTO_SYM); 1005 if (CPA_STATUS_SUCCESS != status) { 1006 goto err_init; 1007 } 1008 } 1009 1010 if (SalCtrl_IsServiceEnabled(enabled_services, 1011 SAL_SERVICE_TYPE_CRYPTO)) { 1012 status = SalCtrl_GetInstanceCount(device, 1013 "NumberCyInstances", 1014 &instance_count); 1015 if (CPA_STATUS_SUCCESS != status) { 1016 instance_count = 0; 1017 } 1018 status = 1019 SalCtrl_ServiceInit(device, 1020 &service_container->crypto_services, 1021 &service_container->cy_dir, 1022 cy_dir_name, 1023 tail_list, 1024 instance_count, 1025 SAL_SERVICE_TYPE_CRYPTO); 1026 if (CPA_STATUS_SUCCESS != status) { 1027 goto err_init; 1028 } 1029 } 1030 if (SalCtrl_IsServiceEnabled(enabled_services, 1031 SAL_SERVICE_TYPE_COMPRESSION)) { 1032 status = SalCtrl_GetInstanceCount(device, 1033 "NumberDcInstances", 1034 &instance_count); 1035 if (CPA_STATUS_SUCCESS != status) { 1036 instance_count = 0; 1037 } 1038 status = SalCtrl_ServiceInit( 1039 device, 1040 &service_container->compression_services, 1041 &service_container->dc_dir, 1042 dc_dir_name, 1043 tail_list, 1044 instance_count, 1045 SAL_SERVICE_TYPE_COMPRESSION); 1046 if (CPA_STATUS_SUCCESS != status) { 1047 goto err_init; 1048 } 1049 } 1050 1051 return status; 1052 1053 err_init: 1054 SalCtrl_ServiceEventShutdown(device, enabled_services); 1055 return status; 1056 } 1057 1058 /**************************************************************************** 1059 * @ingroup SalCtrl 1060 * @description 1061 * This function calls the stop function on all the service instances. 1062 * 1063 * @context 1064 * This function is called from the SalCtrl_ServiceEventHandler function. 1065 * 1066 * @assumptions 1067 * None 1068 * @sideEffects 1069 * None 1070 * @reentrant 1071 * No 1072 * @threadSafe 1073 * Yes 1074 * 1075 * @param[in] device An icp_accel_dev_t* type 1076 * @param[in] enabled_services Enabled services by user 1077 * 1078 *************************************************************************/ 1079 static CpaStatus 1080 SalCtrl_ServiceEventStop(icp_accel_dev_t *device, Cpa32U enabled_services) 1081 { 1082 CpaStatus status = CPA_STATUS_SUCCESS; 1083 CpaStatus ret_status = CPA_STATUS_SUCCESS; 1084 sal_t *service_container = device->pSalHandle; 1085 1086 if (service_container == NULL) { 1087 QAT_UTILS_LOG("Private data is NULL.\n"); 1088 return CPA_STATUS_FATAL; 1089 } 1090 1091 if (SalCtrl_IsServiceEnabled(enabled_services, 1092 SAL_SERVICE_TYPE_CRYPTO_ASYM)) { 1093 status = SalCtrl_ServiceStop(device, 1094 service_container->asym_services); 1095 if (CPA_STATUS_SUCCESS != status) { 1096 ret_status = status; 1097 } 1098 } 1099 1100 if (SalCtrl_IsServiceEnabled(enabled_services, 1101 SAL_SERVICE_TYPE_CRYPTO_SYM)) { 1102 status = SalCtrl_ServiceStop(device, 1103 service_container->sym_services); 1104 if (CPA_STATUS_SUCCESS != status) { 1105 ret_status = status; 1106 } 1107 } 1108 1109 if (SalCtrl_IsServiceEnabled(enabled_services, 1110 SAL_SERVICE_TYPE_CRYPTO)) { 1111 status = 1112 SalCtrl_ServiceStop(device, 1113 service_container->crypto_services); 1114 if (CPA_STATUS_SUCCESS != status) { 1115 ret_status = status; 1116 } 1117 } 1118 1119 if (SalCtrl_IsServiceEnabled(enabled_services, 1120 SAL_SERVICE_TYPE_COMPRESSION)) { 1121 status = SalCtrl_ServiceStop( 1122 device, service_container->compression_services); 1123 if (CPA_STATUS_SUCCESS != status) { 1124 ret_status = status; 1125 } 1126 } 1127 1128 return ret_status; 1129 } 1130 1131 /************************************************************************** 1132 * @ingroup SalCtrl 1133 * @description 1134 * This function calls the start function on all the service instances. 1135 * 1136 * @context 1137 * This function is called from the SalCtrl_ServiceEventHandler function. 1138 * 1139 * @assumptions 1140 * None 1141 * @sideEffects 1142 * None 1143 * @reentrant 1144 * No 1145 * @threadSafe 1146 * Yes 1147 * 1148 * @param[in] device An icp_accel_dev_t* type 1149 * @param[in] enabled_services Enabled services by user 1150 * 1151 **************************************************************************/ 1152 static CpaStatus 1153 SalCtrl_ServiceEventStart(icp_accel_dev_t *device, Cpa32U enabled_services) 1154 { 1155 CpaStatus status = CPA_STATUS_SUCCESS; 1156 sal_t *service_container = device->pSalHandle; 1157 1158 if (service_container == NULL) { 1159 QAT_UTILS_LOG("Private data is NULL.\n"); 1160 return CPA_STATUS_FATAL; 1161 } 1162 1163 if (SalCtrl_IsServiceEnabled(enabled_services, 1164 SAL_SERVICE_TYPE_CRYPTO_ASYM)) { 1165 status = SalCtrl_ServiceStart(device, 1166 service_container->asym_services); 1167 if (CPA_STATUS_SUCCESS != status) { 1168 goto err_start; 1169 } 1170 } 1171 1172 if (SalCtrl_IsServiceEnabled(enabled_services, 1173 SAL_SERVICE_TYPE_CRYPTO_SYM)) { 1174 status = SalCtrl_ServiceStart(device, 1175 service_container->sym_services); 1176 if (CPA_STATUS_SUCCESS != status) { 1177 goto err_start; 1178 } 1179 } 1180 1181 if (SalCtrl_IsServiceEnabled(enabled_services, 1182 SAL_SERVICE_TYPE_CRYPTO)) { 1183 status = 1184 SalCtrl_ServiceStart(device, 1185 service_container->crypto_services); 1186 if (CPA_STATUS_SUCCESS != status) { 1187 goto err_start; 1188 } 1189 } 1190 1191 if (SalCtrl_IsServiceEnabled(enabled_services, 1192 SAL_SERVICE_TYPE_COMPRESSION)) { 1193 status = SalCtrl_ServiceStart( 1194 device, service_container->compression_services); 1195 if (CPA_STATUS_SUCCESS != status) { 1196 goto err_start; 1197 } 1198 } 1199 1200 return status; 1201 err_start: 1202 SalCtrl_ServiceEventStop(device, enabled_services); 1203 return status; 1204 } 1205 1206 /************************************************************************* 1207 * @ingroup SalCtrl 1208 * @description 1209 * This function is the events handler registered with ADF 1210 * for the QA API services (cy, dc) - kernel and user 1211 * 1212 * @context 1213 * This function is called from an ADF context. 1214 * 1215 * @assumptions 1216 * None 1217 * @sideEffects 1218 * None 1219 * @reentrant 1220 * No 1221 * @threadSafe 1222 * Yes 1223 * 1224 * @param[in] device An icp_accel_dev_t* type 1225 * @param[in] event Event from ADF 1226 * @param[in] param Parameter used for back compatibility 1227 * 1228 ***********************************************************************/ 1229 static CpaStatus 1230 SalCtrl_ServiceEventHandler(icp_accel_dev_t *device, 1231 icp_adf_subsystemEvent_t event, 1232 void *param) 1233 { 1234 CpaStatus status = CPA_STATUS_SUCCESS; 1235 CpaStatus stats_status = CPA_STATUS_SUCCESS; 1236 Cpa32U enabled_services = 0; 1237 1238 status = SalCtrl_GetEnabledServices(device, &enabled_services); 1239 if (CPA_STATUS_SUCCESS != status) { 1240 QAT_UTILS_LOG("Failed to get enabled services.\n"); 1241 return status; 1242 } 1243 1244 switch (event) { 1245 case ICP_ADF_EVENT_INIT: { 1246 /* In case there is no QAT SAL needs to call InitStats */ 1247 if (NULL == device->pQatStats) { 1248 status = SalStatistics_InitStatisticsCollection(device); 1249 } 1250 if (CPA_STATUS_SUCCESS != status) { 1251 return status; 1252 } 1253 1254 status = SalCtrl_ServiceEventInit(device, enabled_services); 1255 break; 1256 } 1257 case ICP_ADF_EVENT_START: { 1258 status = SalCtrl_ServiceEventStart(device, enabled_services); 1259 break; 1260 } 1261 case ICP_ADF_EVENT_STOP: { 1262 status = SalCtrl_ServiceEventStop(device, enabled_services); 1263 break; 1264 } 1265 case ICP_ADF_EVENT_SHUTDOWN: { 1266 status = SalCtrl_ServiceEventShutdown(device, enabled_services); 1267 stats_status = SalStatistics_CleanStatisticsCollection(device); 1268 if (CPA_STATUS_SUCCESS != status || 1269 CPA_STATUS_SUCCESS != stats_status) { 1270 return CPA_STATUS_FAIL; 1271 } 1272 break; 1273 } 1274 default: 1275 status = CPA_STATUS_SUCCESS; 1276 break; 1277 } 1278 return status; 1279 } 1280 1281 CpaStatus 1282 SalCtrl_AdfServicesRegister(void) 1283 { 1284 /* Fill out the global sal_service_reg_handle structure */ 1285 sal_service_reg_handle.subserviceEventHandler = 1286 SalCtrl_ServiceEventHandler; 1287 /* Set subsystem name to globally defined name */ 1288 sal_service_reg_handle.subsystem_name = subsystem_name; 1289 1290 return icp_adf_subsystemRegister(&sal_service_reg_handle); 1291 } 1292 1293 CpaStatus 1294 SalCtrl_AdfServicesUnregister(void) 1295 { 1296 return icp_adf_subsystemUnregister(&sal_service_reg_handle); 1297 } 1298 1299 CpaStatus 1300 SalCtrl_AdfServicesStartedCheck(void) 1301 { 1302 CpaStatus status = CPA_STATUS_SUCCESS; 1303 Cpa32U retry_num = 0; 1304 CpaBoolean state = CPA_FALSE; 1305 1306 do { 1307 state = icp_adf_isSubsystemStarted(&sal_service_reg_handle); 1308 retry_num++; 1309 } while ((CPA_FALSE == state) && (retry_num < MAX_SUBSYSTEM_RETRY)); 1310 1311 if (CPA_FALSE == state) { 1312 QAT_UTILS_LOG("Sal Ctrl failed to start in given time.\n"); 1313 status = CPA_STATUS_FAIL; 1314 } 1315 1316 return status; 1317 } 1318 1319 CpaStatus 1320 validateConcurrRequest(Cpa32U numConcurrRequests) 1321 { 1322 Cpa32U baseReq = SAL_64_CONCURR_REQUESTS; 1323 1324 if (SAL_64_CONCURR_REQUESTS > numConcurrRequests) { 1325 QAT_UTILS_LOG( 1326 "Invalid numConcurrRequests, it is less than min value.\n"); 1327 return CPA_STATUS_FAIL; 1328 } 1329 1330 while (SAL_MAX_CONCURR_REQUESTS >= baseReq) { 1331 if (baseReq != numConcurrRequests) { 1332 baseReq = baseReq << 1; 1333 } else { 1334 break; 1335 } 1336 } 1337 if (SAL_MAX_CONCURR_REQUESTS < baseReq) { 1338 QAT_UTILS_LOG( 1339 "Invalid baseReg, it is greater than max value.\n"); 1340 return CPA_STATUS_FAIL; 1341 } 1342 1343 return CPA_STATUS_SUCCESS; 1344 } 1345