1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 #include "adf_cfg.h"
4 #include "cpa.h"
5 #include "icp_accel_devices.h"
6 #include "adf_common_drv.h"
7 #include "icp_adf_accel_mgr.h"
8 #include "icp_adf_cfg.h"
9 #include "icp_adf_debug.h"
10 #include "icp_adf_init.h"
11 #include "lac_sal_ctrl.h"
12
13 static subservice_registation_handle_t *salService = NULL;
14 static struct service_hndl adfService = { 0 };
15 static icp_accel_dev_t *adfDevices = NULL;
16 static icp_accel_dev_t *adfDevicesHead = NULL;
17 struct mtx *adfDevicesLock;
18
19 /*
20 * Need to keep track of what device is currently in reset state
21 */
22 static char accel_dev_reset_stat[ADF_MAX_DEVICES] = { 0 };
23
24 /*
25 * Need to keep track of what device is currently in error state
26 */
27 static char accel_dev_error_stat[ADF_MAX_DEVICES] = { 0 };
28
29 /*
30 * Need to preserve sal handle during restart
31 */
32 static void *accel_dev_sal_hdl_ptr[ADF_MAX_DEVICES] = { 0 };
33
34 static icp_accel_dev_t *
create_adf_dev_structure(struct adf_accel_dev * accel_dev)35 create_adf_dev_structure(struct adf_accel_dev *accel_dev)
36 {
37 icp_accel_dev_t *adf = NULL;
38
39 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
40
41 adf = malloc(sizeof(*adf), M_QAT, M_WAITOK);
42 memset(adf, 0, sizeof(*adf));
43 adf->accelId = accel_dev->accel_id;
44 adf->pAccelName = (char *)hw_data->dev_class->name;
45 adf->deviceType = (device_type_t)hw_data->dev_class->type;
46 strlcpy(adf->deviceName,
47 hw_data->dev_class->name,
48 sizeof(adf->deviceName));
49 adf->accelCapabilitiesMask = hw_data->accel_capabilities_mask;
50 adf->sku = hw_data->get_sku(hw_data);
51 adf->accel_dev = accel_dev;
52 accel_dev->lac_dev = adf;
53
54 return adf;
55 }
56
57 /*
58 * adf_event_handler
59 * Handle device init/uninit/start/stop event
60 */
61 static CpaStatus
adf_event_handler(struct adf_accel_dev * accel_dev,enum adf_event event)62 adf_event_handler(struct adf_accel_dev *accel_dev, enum adf_event event)
63 {
64 CpaStatus status = CPA_STATUS_FAIL;
65 icp_accel_dev_t *adf = NULL;
66
67 if (!adf_cfg_sec_find(accel_dev, ADF_KERNEL_SAL_SEC)) {
68 return CPA_STATUS_SUCCESS;
69 }
70
71 if (event == ADF_EVENT_INIT) {
72 adf = create_adf_dev_structure(accel_dev);
73 if (NULL == adf) {
74 return CPA_STATUS_FAIL;
75 }
76 if (accel_dev_sal_hdl_ptr[accel_dev->accel_id]) {
77 adf->pSalHandle =
78 accel_dev_sal_hdl_ptr[accel_dev->accel_id];
79 accel_dev_sal_hdl_ptr[accel_dev->accel_id] = NULL;
80 }
81
82 qatUtilsMutexLock(&adfDevicesLock, QAT_UTILS_WAIT_FOREVER);
83 ICP_ADD_ELEMENT_TO_END_OF_LIST(adf, adfDevices, adfDevicesHead);
84 qatUtilsMutexUnlock(&adfDevicesLock);
85 } else {
86 adf = accel_dev->lac_dev;
87 }
88
89 if (event == ADF_EVENT_START) {
90 adf->dcExtendedFeatures =
91 accel_dev->hw_device->extended_dc_capabilities;
92 }
93
94 if (event == ADF_EVENT_RESTARTING) {
95 accel_dev_reset_stat[accel_dev->accel_id] = 1;
96 accel_dev_sal_hdl_ptr[accel_dev->accel_id] = adf->pSalHandle;
97 }
98
99 if (event == ADF_EVENT_RESTARTED) {
100 accel_dev_reset_stat[accel_dev->accel_id] = 0;
101 accel_dev_error_stat[accel_dev->accel_id] = 0;
102 }
103
104 status =
105 salService->subserviceEventHandler(adf,
106 (icp_adf_subsystemEvent_t)event,
107 NULL);
108
109 if (event == ADF_EVENT_ERROR) {
110 accel_dev_error_stat[accel_dev->accel_id] = 1;
111 }
112
113 if ((status == CPA_STATUS_SUCCESS && event == ADF_EVENT_SHUTDOWN) ||
114 (status != CPA_STATUS_SUCCESS && event == ADF_EVENT_INIT)) {
115 qatUtilsMutexLock(&adfDevicesLock, QAT_UTILS_WAIT_FOREVER);
116 ICP_REMOVE_ELEMENT_FROM_LIST(adf, adfDevices, adfDevicesHead);
117 qatUtilsMutexUnlock(&adfDevicesLock);
118 accel_dev->lac_dev = NULL;
119 free(adf, M_QAT);
120 }
121
122 if (status == CPA_STATUS_SUCCESS && event == ADF_EVENT_START) {
123 qatUtilsMutexLock(&adfDevicesLock, QAT_UTILS_WAIT_FOREVER);
124 adf->adfSubsystemStatus = 1;
125 qatUtilsMutexUnlock(&adfDevicesLock);
126 }
127
128 if ((status == CPA_STATUS_SUCCESS && event == ADF_EVENT_STOP) ||
129 (status == CPA_STATUS_RETRY && event == ADF_EVENT_STOP)) {
130 qatUtilsMutexLock(&adfDevicesLock, QAT_UTILS_WAIT_FOREVER);
131 adf->adfSubsystemStatus = 0;
132 qatUtilsMutexUnlock(&adfDevicesLock);
133 status = CPA_STATUS_SUCCESS;
134 }
135
136 return status;
137 }
138
139 /*
140 * icp_adf_subsystemRegister
141 * adapter function from SAL to adf driver
142 * call adf_service_register from adf driver directly with same
143 * parameters
144 */
145 CpaStatus
icp_adf_subsystemRegister(subservice_registation_handle_t * sal_service_reg_handle)146 icp_adf_subsystemRegister(
147 subservice_registation_handle_t *sal_service_reg_handle)
148 {
149 if (salService != NULL)
150 return CPA_STATUS_FAIL;
151
152 salService = sal_service_reg_handle;
153 adfService.name = sal_service_reg_handle->subsystem_name;
154 adfService.event_hld = adf_event_handler;
155
156 if (adf_service_register(&adfService) == 0) {
157 return CPA_STATUS_SUCCESS;
158 } else {
159 salService = NULL;
160 return CPA_STATUS_FAIL;
161 }
162 }
163
164 /*
165 * icp_adf_subsystemUnegister
166 * adapter function from SAL to adf driver
167 */
168 CpaStatus
icp_adf_subsystemUnregister(subservice_registation_handle_t * sal_service_reg_handle)169 icp_adf_subsystemUnregister(
170 subservice_registation_handle_t *sal_service_reg_handle)
171 {
172 if (adf_service_unregister(&adfService) == 0) {
173 salService = NULL;
174 return CPA_STATUS_SUCCESS;
175 } else {
176 return CPA_STATUS_FAIL;
177 }
178 }
179
180 /*
181 * icp_adf_cfgGetParamValue
182 * get parameter value from section @section with key @param
183 */
184 CpaStatus
icp_adf_cfgGetParamValue(icp_accel_dev_t * adf,const char * section,const char * param,char * value)185 icp_adf_cfgGetParamValue(icp_accel_dev_t *adf,
186 const char *section,
187 const char *param,
188 char *value)
189 {
190 if (adf_cfg_get_param_value(adf->accel_dev, section, param, value) ==
191 0) {
192 return CPA_STATUS_SUCCESS;
193 } else {
194 return CPA_STATUS_FAIL;
195 }
196 }
197
198 CpaBoolean
icp_adf_is_dev_in_reset(icp_accel_dev_t * accel_dev)199 icp_adf_is_dev_in_reset(icp_accel_dev_t *accel_dev)
200 {
201 return (CpaBoolean)accel_dev_reset_stat[accel_dev->accelId];
202 }
203
204 CpaStatus
icp_adf_debugAddDir(icp_accel_dev_t * adf,debug_dir_info_t * dir_info)205 icp_adf_debugAddDir(icp_accel_dev_t *adf, debug_dir_info_t *dir_info)
206 {
207 return CPA_STATUS_SUCCESS;
208 }
209
210 void
icp_adf_debugRemoveDir(debug_dir_info_t * dir_info)211 icp_adf_debugRemoveDir(debug_dir_info_t *dir_info)
212 {
213 }
214
215 CpaStatus
icp_adf_debugAddFile(icp_accel_dev_t * adf,debug_file_info_t * file_info)216 icp_adf_debugAddFile(icp_accel_dev_t *adf, debug_file_info_t *file_info)
217 {
218 return CPA_STATUS_SUCCESS;
219 }
220
221 void
icp_adf_debugRemoveFile(debug_file_info_t * file_info)222 icp_adf_debugRemoveFile(debug_file_info_t *file_info)
223 {
224 }
225
226 /*
227 * icp_adf_getAccelDevByAccelId
228 * return acceleration device with id @accelId
229 */
230 icp_accel_dev_t *
icp_adf_getAccelDevByAccelId(Cpa32U accelId)231 icp_adf_getAccelDevByAccelId(Cpa32U accelId)
232 {
233 icp_accel_dev_t *adf = NULL;
234
235 qatUtilsMutexLock(&adfDevicesLock, QAT_UTILS_WAIT_FOREVER);
236 adf = adfDevicesHead;
237 while (adf != NULL && adf->accelId != accelId)
238 adf = adf->pNext;
239 qatUtilsMutexUnlock(&adfDevicesLock);
240 return adf;
241 }
242
243 /*
244 * icp_amgr_getNumInstances
245 * Return the number of acceleration devices it the system.
246 */
247 CpaStatus
icp_amgr_getNumInstances(Cpa16U * pNumInstances)248 icp_amgr_getNumInstances(Cpa16U *pNumInstances)
249 {
250 icp_accel_dev_t *adf = NULL;
251 Cpa16U count = 0;
252
253 qatUtilsMutexLock(&adfDevicesLock, QAT_UTILS_WAIT_FOREVER);
254 for (adf = adfDevicesHead; adf != NULL; adf = adf->pNext)
255 count++;
256 qatUtilsMutexUnlock(&adfDevicesLock);
257 *pNumInstances = count;
258 return CPA_STATUS_SUCCESS;
259 }
260
261 /*
262 * icp_amgr_getAccelDevByCapabilities
263 * Returns a started accel device that implements
264 * the capabilities specified in capabilitiesMask.
265 */
266 CpaStatus
icp_amgr_getAccelDevByCapabilities(Cpa32U capabilitiesMask,icp_accel_dev_t ** pAccel_devs,Cpa16U * pNumInstances)267 icp_amgr_getAccelDevByCapabilities(Cpa32U capabilitiesMask,
268 icp_accel_dev_t **pAccel_devs,
269 Cpa16U *pNumInstances)
270 {
271 icp_accel_dev_t *adf = NULL;
272 *pNumInstances = 0;
273
274 qatUtilsMutexLock(&adfDevicesLock, QAT_UTILS_WAIT_FOREVER);
275 for (adf = adfDevicesHead; adf != NULL; adf = adf->pNext) {
276 if (adf->accelCapabilitiesMask & capabilitiesMask) {
277 if (adf->adfSubsystemStatus) {
278 pAccel_devs[0] = adf;
279 *pNumInstances = 1;
280 qatUtilsMutexUnlock(&adfDevicesLock);
281 return CPA_STATUS_SUCCESS;
282 }
283 }
284 }
285 qatUtilsMutexUnlock(&adfDevicesLock);
286 return CPA_STATUS_FAIL;
287 }
288
289 /*
290 * icp_amgr_getAllAccelDevByEachCapabilities
291 * Returns table of accel devices that are started and implement
292 * each of the capabilities specified in capabilitiesMask.
293 */
294 CpaStatus
icp_amgr_getAllAccelDevByEachCapability(Cpa32U capabilitiesMask,icp_accel_dev_t ** pAccel_devs,Cpa16U * pNumInstances)295 icp_amgr_getAllAccelDevByEachCapability(Cpa32U capabilitiesMask,
296 icp_accel_dev_t **pAccel_devs,
297 Cpa16U *pNumInstances)
298 {
299 icp_accel_dev_t *adf = NULL;
300 *pNumInstances = 0;
301 qatUtilsMutexLock(&adfDevicesLock, QAT_UTILS_WAIT_FOREVER);
302 for (adf = adfDevicesHead; adf != NULL; adf = adf->pNext) {
303 Cpa32U enabled_caps =
304 adf->accelCapabilitiesMask & capabilitiesMask;
305 if (enabled_caps == capabilitiesMask) {
306 if (adf->adfSubsystemStatus) {
307 pAccel_devs[(*pNumInstances)++] =
308 (icp_accel_dev_t *)adf;
309 }
310 }
311 }
312 qatUtilsMutexUnlock(&adfDevicesLock);
313 return CPA_STATUS_SUCCESS;
314 }
315
316 /*
317 * icp_amgr_getAllAccelDevByCapabilities
318 * Fetches accel devices based on the capability
319 * and returns the count of the device
320 */
321 CpaStatus
icp_amgr_getAllAccelDevByCapabilities(Cpa32U capabilitiesMask,icp_accel_dev_t ** pAccel_devs,Cpa16U * pNumInstances)322 icp_amgr_getAllAccelDevByCapabilities(Cpa32U capabilitiesMask,
323 icp_accel_dev_t **pAccel_devs,
324 Cpa16U *pNumInstances)
325 {
326 icp_accel_dev_t *adf = NULL;
327 Cpa16U i = 0;
328
329 qatUtilsMutexLock(&adfDevicesLock, QAT_UTILS_WAIT_FOREVER);
330 for (adf = adfDevicesHead; adf != NULL; adf = adf->pNext) {
331 if (adf->accelCapabilitiesMask & capabilitiesMask) {
332 if (adf->adfSubsystemStatus) {
333 pAccel_devs[i++] = adf;
334 }
335 }
336 }
337 qatUtilsMutexUnlock(&adfDevicesLock);
338 *pNumInstances = i;
339 return CPA_STATUS_SUCCESS;
340 }
341
342 /*
343 * icp_amgr_getAccelDevCapabilities
344 * Returns accel devices capabilities specified in capabilitiesMask.
345 *
346 * Returns:
347 * CPA_STATUS_SUCCESS on success
348 * CPA_STATUS_FAIL on failure
349 */
350 CpaStatus
icp_amgr_getAccelDevCapabilities(icp_accel_dev_t * accel_dev,Cpa32U * pCapabilitiesMask)351 icp_amgr_getAccelDevCapabilities(icp_accel_dev_t *accel_dev,
352 Cpa32U *pCapabilitiesMask)
353 {
354 ICP_CHECK_FOR_NULL_PARAM(accel_dev);
355 ICP_CHECK_FOR_NULL_PARAM(pCapabilitiesMask);
356
357 *pCapabilitiesMask = accel_dev->accelCapabilitiesMask;
358 return CPA_STATUS_SUCCESS;
359 }
360
361 /*
362 * icp_qa_dev_get
363 *
364 * Description:
365 * Function increments the device usage counter.
366 *
367 * Returns: void
368 */
369 void
icp_qa_dev_get(icp_accel_dev_t * pDev)370 icp_qa_dev_get(icp_accel_dev_t *pDev)
371 {
372 ICP_CHECK_FOR_NULL_PARAM_VOID(pDev);
373 adf_dev_get(pDev->accel_dev);
374 }
375
376 /*
377 * icp_qa_dev_put
378 *
379 * Description:
380 * Function decrements the device usage counter.
381 *
382 * Returns: void
383 */
384 void
icp_qa_dev_put(icp_accel_dev_t * pDev)385 icp_qa_dev_put(icp_accel_dev_t *pDev)
386 {
387 ICP_CHECK_FOR_NULL_PARAM_VOID(pDev);
388 adf_dev_put(pDev->accel_dev);
389 }
390
391 Cpa16U
icp_adf_get_busAddress(Cpa16U packageId)392 icp_adf_get_busAddress(Cpa16U packageId)
393 {
394 Cpa16U busAddr = 0xFFFF;
395 icp_accel_dev_t *adf = NULL;
396
397 qatUtilsMutexLock(&adfDevicesLock, QAT_UTILS_WAIT_FOREVER);
398 for (adf = adfDevicesHead; adf != NULL; adf = adf->pNext) {
399 if (adf->accelId == packageId) {
400 busAddr = pci_get_bus(accel_to_pci_dev(adf->accel_dev))
401 << 8 |
402 pci_get_slot(accel_to_pci_dev(adf->accel_dev))
403 << 3 |
404 pci_get_function(accel_to_pci_dev(adf->accel_dev));
405 break;
406 }
407 }
408 qatUtilsMutexUnlock(&adfDevicesLock);
409 return busAddr;
410 }
411
412 CpaBoolean
icp_adf_isSubsystemStarted(subservice_registation_handle_t * subsystem_hdl)413 icp_adf_isSubsystemStarted(subservice_registation_handle_t *subsystem_hdl)
414 {
415 if (subsystem_hdl == salService)
416 return CPA_TRUE;
417 else
418 return CPA_FALSE;
419 }
420
421 CpaBoolean
icp_adf_is_dev_in_error(icp_accel_dev_t * accel_dev)422 icp_adf_is_dev_in_error(icp_accel_dev_t *accel_dev)
423 {
424 return (CpaBoolean)accel_dev_error_stat[accel_dev->accelId];
425 }
426