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 }
Cache object: f90a1e935158285c7874e98606a529db
|