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 13static subservice_registation_handle_t *salService = NULL; 14static struct service_hndl adfService = { 0 }; 15static icp_accel_dev_t *adfDevices = NULL; 16static icp_accel_dev_t *adfDevicesHead = NULL; 17struct mtx *adfDevicesLock; 18 19/* 20 * Need to keep track of what device is currently in reset state 21 */ 22static 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 */ 27static char accel_dev_error_stat[ADF_MAX_DEVICES] = { 0 }; 28 29/* 30 * Need to preserve sal handle during restart 31 */ 32static void *accel_dev_sal_hdl_ptr[ADF_MAX_DEVICES] = { 0 }; 33 34static icp_accel_dev_t * 35create_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 */ 61static CpaStatus 62adf_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 */ 145CpaStatus 146icp_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 */ 168CpaStatus 169icp_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 */ 184CpaStatus 185icp_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 198CpaBoolean 199icp_adf_is_dev_in_reset(icp_accel_dev_t *accel_dev) 200{ 201 return (CpaBoolean)accel_dev_reset_stat[accel_dev->accelId]; 202} 203 204CpaStatus 205icp_adf_debugAddDir(icp_accel_dev_t *adf, debug_dir_info_t *dir_info) 206{ 207 return CPA_STATUS_SUCCESS; 208} 209 210void 211icp_adf_debugRemoveDir(debug_dir_info_t *dir_info) 212{ 213} 214 215CpaStatus 216icp_adf_debugAddFile(icp_accel_dev_t *adf, debug_file_info_t *file_info) 217{ 218 return CPA_STATUS_SUCCESS; 219} 220 221void 222icp_adf_debugRemoveFile(debug_file_info_t *file_info) 223{ 224} 225 226/* 227 * icp_adf_getAccelDevByAccelId 228 * return acceleration device with id @accelId 229 */ 230icp_accel_dev_t * 231icp_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 */ 247CpaStatus 248icp_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 */ 266CpaStatus 267icp_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 */ 294CpaStatus 295icp_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 */ 321CpaStatus 322icp_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 */ 350CpaStatus 351icp_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 */ 369void 370icp_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 */ 384void 385icp_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 391Cpa16U 392icp_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 412CpaBoolean 413icp_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 421CpaBoolean 422icp_adf_is_dev_in_error(icp_accel_dev_t *accel_dev) 423{ 424 return (CpaBoolean)accel_dev_error_stat[accel_dev->accelId]; 425} 426