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 * 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 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 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 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 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 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 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 211 icp_adf_debugRemoveDir(debug_dir_info_t *dir_info) 212 { 213 } 214 215 CpaStatus 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 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 * 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 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 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 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 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 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 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 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 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 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 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