/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright(c) 2007-2022 Intel Corporation */ /** ***************************************************************************** * @file sal_get_instances.c * * @defgroup SalCtrl Service Access Layer Controller * * @ingroup SalCtrl * * @description * This file contains the main function to get SAL instances. * *****************************************************************************/ /* ******************************************************************************* * Include public/global header files ******************************************************************************* */ /* QAT-API includes */ #include "cpa.h" #include "cpa_cy_common.h" #include "cpa_cy_im.h" #include "cpa_dc.h" /* ADF includes */ #include "icp_accel_devices.h" #include "icp_adf_accel_mgr.h" /* SAL includes */ #include "lac_mem.h" #include "lac_list.h" #include "lac_sal_types.h" /** ****************************************************************************** * @ingroup SalCtrl * @description * Get either sym or asym instance number *****************************************************************************/ static CpaStatus Lac_GetSingleCyNumInstances( const CpaAccelerationServiceType accelerationServiceType, Cpa16U *pNumInstances) { CpaStatus status = CPA_STATUS_SUCCESS; icp_accel_dev_t **pAdfInsts = NULL; icp_accel_dev_t *dev_addr = NULL; sal_t *base_addr = NULL; sal_list_t *list_temp = NULL; Cpa16U num_accel_dev = 0; Cpa16U num_inst = 0; Cpa16U i = 0; Cpa32U accel_capability = 0; char *service = NULL; LAC_CHECK_NULL_PARAM(pNumInstances); *pNumInstances = 0; switch (accelerationServiceType) { case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; service = "asym"; break; case CPA_ACC_SVC_TYPE_CRYPTO_SYM: accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; service = "sym"; break; default: QAT_UTILS_LOG("Invalid service type\n"); return CPA_STATUS_INVALID_PARAM; } /* Get the number of accel_dev in the system */ status = icp_amgr_getNumInstances(&num_accel_dev); LAC_CHECK_STATUS(status); /* Allocate memory to store addr of accel_devs */ pAdfInsts = malloc(num_accel_dev * sizeof(icp_accel_dev_t *), M_QAT, M_WAITOK | M_ZERO); if (NULL == pAdfInsts) { QAT_UTILS_LOG("Failed to allocate dev instance memory\n"); return CPA_STATUS_RESOURCE; } num_accel_dev = 0; status = icp_amgr_getAllAccelDevByCapabilities(accel_capability, pAdfInsts, &num_accel_dev); if (CPA_STATUS_SUCCESS != status) { QAT_UTILS_LOG("No support for service %s\n", service); free(pAdfInsts, M_QAT); return status; } for (i = 0; i < num_accel_dev; i++) { dev_addr = pAdfInsts[i]; if (NULL == dev_addr || NULL == dev_addr->pSalHandle) { continue; } base_addr = dev_addr->pSalHandle; if (CPA_ACC_SVC_TYPE_CRYPTO_ASYM == accelerationServiceType) { list_temp = base_addr->asym_services; } else { list_temp = base_addr->sym_services; } while (NULL != list_temp) { num_inst++; list_temp = SalList_next(list_temp); } } *pNumInstances = num_inst; free(pAdfInsts, M_QAT); return status; } /** ****************************************************************************** * @ingroup SalCtrl * @description * Get either sym or asym instance *****************************************************************************/ static CpaStatus Lac_GetSingleCyInstances( const CpaAccelerationServiceType accelerationServiceType, Cpa16U numInstances, CpaInstanceHandle *pInstances) { CpaStatus status = CPA_STATUS_SUCCESS; icp_accel_dev_t **pAdfInsts = NULL; icp_accel_dev_t *dev_addr = NULL; sal_t *base_addr = NULL; sal_list_t *list_temp = NULL; Cpa16U num_accel_dev = 0; Cpa16U num_allocated_instances = 0; Cpa16U index = 0; Cpa16U i = 0; Cpa32U accel_capability = 0; char *service = NULL; LAC_CHECK_NULL_PARAM(pInstances); if (0 == numInstances) { QAT_UTILS_LOG("NumInstances is 0\n"); return CPA_STATUS_INVALID_PARAM; } switch (accelerationServiceType) { case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; service = "asym"; break; case CPA_ACC_SVC_TYPE_CRYPTO_SYM: accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; service = "sym"; break; default: QAT_UTILS_LOG("Invalid service type\n"); return CPA_STATUS_INVALID_PARAM; } /* Get the number of instances */ status = cpaGetNumInstances(accelerationServiceType, &num_allocated_instances); if (CPA_STATUS_SUCCESS != status) { return status; } if (numInstances > num_allocated_instances) { QAT_UTILS_LOG("Only %d instances available\n", num_allocated_instances); return CPA_STATUS_RESOURCE; } /* Get the number of accel devices in the system */ status = icp_amgr_getNumInstances(&num_accel_dev); LAC_CHECK_STATUS(status); /* Allocate memory to store addr of accel_devs */ pAdfInsts = malloc(num_accel_dev * sizeof(icp_accel_dev_t *), M_QAT, M_WAITOK | M_ZERO); if (NULL == pAdfInsts) { QAT_UTILS_LOG("Failed to allocate dev instance memory\n"); return CPA_STATUS_RESOURCE; } num_accel_dev = 0; status = icp_amgr_getAllAccelDevByCapabilities(accel_capability, pAdfInsts, &num_accel_dev); if (CPA_STATUS_SUCCESS != status) { QAT_UTILS_LOG("No support for service %s\n", service); free(pAdfInsts, M_QAT); return status; } for (i = 0; i < num_accel_dev; i++) { dev_addr = pAdfInsts[i]; /* Note dev_addr cannot be NULL here as numInstances = 0 * is not valid and if dev_addr = NULL then index = 0 (which * is less than numInstances and status is set to _RESOURCE * above) */ base_addr = dev_addr->pSalHandle; if (NULL == base_addr) { continue; } if (CPA_ACC_SVC_TYPE_CRYPTO_ASYM == accelerationServiceType) list_temp = base_addr->asym_services; else list_temp = base_addr->sym_services; while (NULL != list_temp) { if (index > (numInstances - 1)) break; pInstances[index] = SalList_getObject(list_temp); list_temp = SalList_next(list_temp); index++; } } free(pAdfInsts, M_QAT); return status; } /** ****************************************************************************** * @ingroup SalCtrl *****************************************************************************/ CpaStatus cpaGetNumInstances(const CpaAccelerationServiceType accelerationServiceType, Cpa16U *pNumInstances) { switch (accelerationServiceType) { case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: case CPA_ACC_SVC_TYPE_CRYPTO_SYM: return Lac_GetSingleCyNumInstances(accelerationServiceType, pNumInstances); case CPA_ACC_SVC_TYPE_CRYPTO: return cpaCyGetNumInstances(pNumInstances); case CPA_ACC_SVC_TYPE_DATA_COMPRESSION: return cpaDcGetNumInstances(pNumInstances); default: QAT_UTILS_LOG("Invalid service type\n"); *pNumInstances = 0; return CPA_STATUS_INVALID_PARAM; } } /** ****************************************************************************** * @ingroup SalCtrl *****************************************************************************/ CpaStatus cpaGetInstances(const CpaAccelerationServiceType accelerationServiceType, Cpa16U numInstances, CpaInstanceHandle *pInstances) { switch (accelerationServiceType) { case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: case CPA_ACC_SVC_TYPE_CRYPTO_SYM: return Lac_GetSingleCyInstances(accelerationServiceType, numInstances, pInstances); case CPA_ACC_SVC_TYPE_CRYPTO: return cpaCyGetInstances(numInstances, pInstances); case CPA_ACC_SVC_TYPE_DATA_COMPRESSION: return cpaDcGetInstances(numInstances, pInstances); default: QAT_UTILS_LOG("Invalid service type\n"); return CPA_STATUS_INVALID_PARAM; } }