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