1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 
4 /**
5  *****************************************************************************
6  * @file sal_get_instances.c
7  *
8  * @defgroup SalCtrl Service Access Layer Controller
9  *
10  * @ingroup SalCtrl
11  *
12  * @description
13  *      This file contains the main function to get SAL instances.
14  *
15  *****************************************************************************/
16 
17 /*
18 *******************************************************************************
19 * Include public/global header files
20 *******************************************************************************
21 */
22 
23 /* QAT-API includes */
24 #include "cpa.h"
25 #include "cpa_cy_common.h"
26 #include "cpa_cy_im.h"
27 #include "cpa_dc.h"
28 
29 /* ADF includes */
30 #include "icp_accel_devices.h"
31 #include "icp_adf_accel_mgr.h"
32 
33 /* SAL includes */
34 #include "lac_mem.h"
35 #include "lac_list.h"
36 #include "lac_sal_types.h"
37 
38 /**
39  ******************************************************************************
40  * @ingroup SalCtrl
41  * @description
42  *   Get either sym or asym instance number
43  *****************************************************************************/
44 static CpaStatus
45 Lac_GetSingleCyNumInstances(
46     const CpaAccelerationServiceType accelerationServiceType,
47     Cpa16U *pNumInstances)
48 {
49 	CpaStatus status = CPA_STATUS_SUCCESS;
50 	icp_accel_dev_t **pAdfInsts = NULL;
51 	icp_accel_dev_t *dev_addr = NULL;
52 	sal_t *base_addr = NULL;
53 	sal_list_t *list_temp = NULL;
54 	Cpa16U num_accel_dev = 0;
55 	Cpa16U num_inst = 0;
56 	Cpa16U i = 0;
57 	Cpa32U accel_capability = 0;
58 	char *service = NULL;
59 
60 	LAC_CHECK_NULL_PARAM(pNumInstances);
61 	*pNumInstances = 0;
62 
63 	switch (accelerationServiceType) {
64 	case CPA_ACC_SVC_TYPE_CRYPTO_ASYM:
65 		accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
66 		service = "asym";
67 		break;
68 
69 	case CPA_ACC_SVC_TYPE_CRYPTO_SYM:
70 		accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC;
71 		service = "sym";
72 		break;
73 
74 	default:
75 		QAT_UTILS_LOG("Invalid service type\n");
76 		return CPA_STATUS_INVALID_PARAM;
77 	}
78 
79 	/* Get the number of accel_dev in the system */
80 	status = icp_amgr_getNumInstances(&num_accel_dev);
81 	LAC_CHECK_STATUS(status);
82 
83 	/* Allocate memory to store addr of accel_devs */
84 	pAdfInsts = malloc(num_accel_dev * sizeof(icp_accel_dev_t *),
85 			   M_QAT,
86 			   M_WAITOK | M_ZERO);
87 	if (NULL == pAdfInsts) {
88 		QAT_UTILS_LOG("Failed to allocate dev instance memory\n");
89 		return CPA_STATUS_RESOURCE;
90 	}
91 
92 	num_accel_dev = 0;
93 	status = icp_amgr_getAllAccelDevByCapabilities(accel_capability,
94 						       pAdfInsts,
95 						       &num_accel_dev);
96 	if (CPA_STATUS_SUCCESS != status) {
97 		QAT_UTILS_LOG("No support for service %s\n", service);
98 		free(pAdfInsts, M_QAT);
99 		return status;
100 	}
101 
102 	for (i = 0; i < num_accel_dev; i++) {
103 		dev_addr = pAdfInsts[i];
104 		if (NULL == dev_addr || NULL == dev_addr->pSalHandle) {
105 			continue;
106 		}
107 		base_addr = dev_addr->pSalHandle;
108 
109 		if (CPA_ACC_SVC_TYPE_CRYPTO_ASYM == accelerationServiceType) {
110 			list_temp = base_addr->asym_services;
111 		} else {
112 			list_temp = base_addr->sym_services;
113 		}
114 		while (NULL != list_temp) {
115 			num_inst++;
116 			list_temp = SalList_next(list_temp);
117 		}
118 	}
119 
120 	*pNumInstances = num_inst;
121 	free(pAdfInsts, M_QAT);
122 
123 	return status;
124 }
125 
126 /**
127  ******************************************************************************
128  * @ingroup SalCtrl
129  * @description
130  *   Get either sym or asym instance
131  *****************************************************************************/
132 static CpaStatus
133 Lac_GetSingleCyInstances(
134     const CpaAccelerationServiceType accelerationServiceType,
135     Cpa16U numInstances,
136     CpaInstanceHandle *pInstances)
137 {
138 	CpaStatus status = CPA_STATUS_SUCCESS;
139 	icp_accel_dev_t **pAdfInsts = NULL;
140 	icp_accel_dev_t *dev_addr = NULL;
141 	sal_t *base_addr = NULL;
142 	sal_list_t *list_temp = NULL;
143 	Cpa16U num_accel_dev = 0;
144 	Cpa16U num_allocated_instances = 0;
145 	Cpa16U index = 0;
146 	Cpa16U i = 0;
147 	Cpa32U accel_capability = 0;
148 	char *service = NULL;
149 
150 	LAC_CHECK_NULL_PARAM(pInstances);
151 	if (0 == numInstances) {
152 		QAT_UTILS_LOG("NumInstances is 0\n");
153 		return CPA_STATUS_INVALID_PARAM;
154 	}
155 
156 	switch (accelerationServiceType) {
157 	case CPA_ACC_SVC_TYPE_CRYPTO_ASYM:
158 		accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
159 		service = "asym";
160 		break;
161 
162 	case CPA_ACC_SVC_TYPE_CRYPTO_SYM:
163 		accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC;
164 		service = "sym";
165 		break;
166 	default:
167 		QAT_UTILS_LOG("Invalid service type\n");
168 		return CPA_STATUS_INVALID_PARAM;
169 	}
170 
171 	/* Get the number of instances */
172 	status = cpaGetNumInstances(accelerationServiceType,
173 				    &num_allocated_instances);
174 	if (CPA_STATUS_SUCCESS != status) {
175 		return status;
176 	}
177 
178 	if (numInstances > num_allocated_instances) {
179 		QAT_UTILS_LOG("Only %d instances available\n",
180 			      num_allocated_instances);
181 		return CPA_STATUS_RESOURCE;
182 	}
183 
184 	/* Get the number of accel devices in the system */
185 	status = icp_amgr_getNumInstances(&num_accel_dev);
186 	LAC_CHECK_STATUS(status);
187 
188 	/* Allocate memory to store addr of accel_devs */
189 	pAdfInsts = malloc(num_accel_dev * sizeof(icp_accel_dev_t *),
190 			   M_QAT,
191 			   M_WAITOK | M_ZERO);
192 	if (NULL == pAdfInsts) {
193 		QAT_UTILS_LOG("Failed to allocate dev instance memory\n");
194 		return CPA_STATUS_RESOURCE;
195 	}
196 
197 	num_accel_dev = 0;
198 	status = icp_amgr_getAllAccelDevByCapabilities(accel_capability,
199 						       pAdfInsts,
200 						       &num_accel_dev);
201 	if (CPA_STATUS_SUCCESS != status) {
202 		QAT_UTILS_LOG("No support for service %s\n", service);
203 		free(pAdfInsts, M_QAT);
204 		return status;
205 	}
206 
207 	for (i = 0; i < num_accel_dev; i++) {
208 		dev_addr = pAdfInsts[i];
209 		/* Note dev_addr cannot be NULL here as numInstances = 0
210 		 * is not valid and if dev_addr = NULL then index = 0 (which
211 		 * is less than numInstances and status is set to _RESOURCE
212 		 * above)
213 		 */
214 		base_addr = dev_addr->pSalHandle;
215 		if (NULL == base_addr) {
216 			continue;
217 		}
218 
219 		if (CPA_ACC_SVC_TYPE_CRYPTO_ASYM == accelerationServiceType)
220 			list_temp = base_addr->asym_services;
221 		else
222 			list_temp = base_addr->sym_services;
223 		while (NULL != list_temp) {
224 			if (index > (numInstances - 1))
225 				break;
226 
227 			pInstances[index] = SalList_getObject(list_temp);
228 			list_temp = SalList_next(list_temp);
229 			index++;
230 		}
231 	}
232 	free(pAdfInsts, M_QAT);
233 
234 	return status;
235 }
236 
237 /**
238  ******************************************************************************
239  * @ingroup SalCtrl
240  *****************************************************************************/
241 CpaStatus
242 cpaGetNumInstances(const CpaAccelerationServiceType accelerationServiceType,
243 		   Cpa16U *pNumInstances)
244 {
245 	switch (accelerationServiceType) {
246 	case CPA_ACC_SVC_TYPE_CRYPTO_ASYM:
247 	case CPA_ACC_SVC_TYPE_CRYPTO_SYM:
248 		return Lac_GetSingleCyNumInstances(accelerationServiceType,
249 						   pNumInstances);
250 	case CPA_ACC_SVC_TYPE_CRYPTO:
251 		return cpaCyGetNumInstances(pNumInstances);
252 	case CPA_ACC_SVC_TYPE_DATA_COMPRESSION:
253 		return cpaDcGetNumInstances(pNumInstances);
254 
255 	default:
256 		QAT_UTILS_LOG("Invalid service type\n");
257 		*pNumInstances = 0;
258 		return CPA_STATUS_INVALID_PARAM;
259 	}
260 }
261 
262 /**
263  ******************************************************************************
264  * @ingroup SalCtrl
265  *****************************************************************************/
266 CpaStatus
267 cpaGetInstances(const CpaAccelerationServiceType accelerationServiceType,
268 		Cpa16U numInstances,
269 		CpaInstanceHandle *pInstances)
270 {
271 	switch (accelerationServiceType) {
272 	case CPA_ACC_SVC_TYPE_CRYPTO_ASYM:
273 	case CPA_ACC_SVC_TYPE_CRYPTO_SYM:
274 		return Lac_GetSingleCyInstances(accelerationServiceType,
275 						numInstances,
276 						pInstances);
277 
278 	case CPA_ACC_SVC_TYPE_CRYPTO:
279 		return cpaCyGetInstances(numInstances, pInstances);
280 	case CPA_ACC_SVC_TYPE_DATA_COMPRESSION:
281 		return cpaDcGetInstances(numInstances, pInstances);
282 
283 	default:
284 		QAT_UTILS_LOG("Invalid service type\n");
285 		return CPA_STATUS_INVALID_PARAM;
286 	}
287 }
288