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 *****************************************************************************/
44static CpaStatus
45Lac_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 *****************************************************************************/
132static CpaStatus
133Lac_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 *****************************************************************************/
241CpaStatus
242cpaGetNumInstances(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 *****************************************************************************/
266CpaStatus
267cpaGetInstances(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