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