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