mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
1156 lines
29 KiB
C
1156 lines
29 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause */
|
|
/* Copyright(c) 2007-2022 Intel Corporation */
|
|
#include "adf_cfg_instance.h"
|
|
#include "adf_cfg_device.h"
|
|
#include "adf_cfg_section.h"
|
|
|
|
static bool
|
|
adf_cfg_is_svc_enabled(struct adf_accel_dev *accel_dev, const u8 svc)
|
|
{
|
|
int ring_pair_index = 0;
|
|
u8 serv_type = NA;
|
|
struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
|
|
|
|
for (ring_pair_index = 0; ring_pair_index < ADF_CFG_NUM_SERVICES;
|
|
ring_pair_index++) {
|
|
serv_type =
|
|
GET_SRV_TYPE(hw_data->ring_to_svc_map, ring_pair_index);
|
|
if (serv_type == svc)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_set_core_number_for_instance(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name,
|
|
const char *inst_name,
|
|
int process_num,
|
|
unsigned long *core_number)
|
|
{
|
|
char *core_val = NULL;
|
|
char *pos = NULL;
|
|
char **tokens = NULL;
|
|
int token_index = 0;
|
|
int core_arr_index = 0;
|
|
int i = 0;
|
|
int ret = EFAULT;
|
|
unsigned long *core_num_arr = NULL;
|
|
unsigned long core_num;
|
|
unsigned long start, end;
|
|
|
|
/* do memory allocation */
|
|
core_val =
|
|
malloc(ADF_CFG_MAX_VAL_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
tokens = malloc(sizeof(char *) * ADF_CFG_MAX_TOKENS,
|
|
M_QAT,
|
|
M_WAITOK | M_ZERO);
|
|
|
|
for (i = 0; i < ADF_CFG_MAX_TOKENS; i++) {
|
|
tokens[i] =
|
|
malloc(ADF_CFG_MAX_TOKEN_LEN, M_QAT, M_WAITOK | M_ZERO);
|
|
}
|
|
|
|
core_num_arr = malloc(sizeof(unsigned long) * ADF_CFG_MAX_CORE_NUM,
|
|
M_QAT,
|
|
M_WAITOK | M_ZERO);
|
|
|
|
/* parse the core_val */
|
|
ret = EFAULT;
|
|
if (adf_cfg_get_param_value(accel_dev, sec_name, inst_name, core_val))
|
|
goto failed;
|
|
|
|
pos = strchr(core_val, ',');
|
|
while (pos) {
|
|
pos[0] = '\0';
|
|
strlcpy(tokens[token_index++], core_val, ADF_CFG_MAX_TOKEN_LEN);
|
|
strlcpy(core_val, pos + 1, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
|
|
pos = strchr(core_val, ',');
|
|
if (!pos)
|
|
strlcpy(tokens[token_index++],
|
|
core_val,
|
|
ADF_CFG_MAX_VAL_LEN_IN_BYTES);
|
|
}
|
|
|
|
/* in case there is only N-M */
|
|
if (token_index == 0)
|
|
strlcpy(tokens[token_index++],
|
|
core_val,
|
|
ADF_CFG_MAX_VAL_LEN_IN_BYTES);
|
|
|
|
/* parse the tokens such as N-M */
|
|
for (i = 0; i < token_index; i++) {
|
|
pos = strchr(tokens[i], '-');
|
|
if (pos) {
|
|
pos[0] = '\0';
|
|
ret = compat_strtoul(tokens[i], 10, &start);
|
|
if (ret)
|
|
goto failed;
|
|
ret = compat_strtoul(pos + 1, 10, &end);
|
|
if (ret)
|
|
goto failed;
|
|
if (start > end) {
|
|
ret = EFAULT;
|
|
goto failed;
|
|
}
|
|
for (core_num = start; core_num < end + 1; core_num++)
|
|
core_num_arr[core_arr_index++] = core_num;
|
|
} else {
|
|
ret = compat_strtoul(tokens[i], 10, &core_num);
|
|
if (ret)
|
|
goto failed;
|
|
core_num_arr[core_arr_index++] = core_num;
|
|
}
|
|
}
|
|
|
|
if (core_arr_index == 0) {
|
|
ret = compat_strtoul(core_val, 10, &core_num);
|
|
if (ret)
|
|
goto failed;
|
|
else
|
|
core_num_arr[core_arr_index++] = core_num;
|
|
}
|
|
|
|
*core_number = core_num_arr[process_num % core_arr_index];
|
|
ret = 0;
|
|
failed:
|
|
free(core_val, M_QAT);
|
|
if (tokens) {
|
|
for (i = 0; i < ADF_CFG_MAX_TOKENS; i++)
|
|
free(tokens[i], M_QAT);
|
|
free(tokens, M_QAT);
|
|
}
|
|
free(core_num_arr, M_QAT);
|
|
|
|
if (ret)
|
|
device_printf(GET_DEV(accel_dev),
|
|
"Get core number failed with error %d\n",
|
|
ret);
|
|
return ret;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_set_value(struct adf_accel_dev *accel_dev,
|
|
const char *sec,
|
|
const char *key,
|
|
unsigned long *value)
|
|
{
|
|
char *val = NULL;
|
|
int ret = EFAULT;
|
|
|
|
val = malloc(ADF_CFG_MAX_VAL_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
if (adf_cfg_get_param_value(accel_dev, sec, key, val))
|
|
goto out;
|
|
|
|
/* as the key type can be either ADF_DEC or ADF_HEX */
|
|
if (compat_strtoul(val, 10, value) && compat_strtoul(val, 16, value))
|
|
goto out;
|
|
|
|
ret = 0;
|
|
out:
|
|
free(val, M_QAT);
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
adf_cfg_add_cy_inst_info(struct adf_accel_dev *accel_dev,
|
|
struct adf_cfg_instance *crypto_inst,
|
|
const char *derived_sec,
|
|
int inst_index)
|
|
{
|
|
char *key = NULL;
|
|
unsigned long bank_number = 0;
|
|
unsigned long ring_number = 0;
|
|
unsigned long asym_req = 0;
|
|
unsigned long sym_req = 0;
|
|
|
|
key = malloc(ADF_CFG_MAX_KEY_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_BANK_NUM_FORMAT,
|
|
inst_index);
|
|
bank_number = crypto_inst->bundle;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&bank_number, ADF_DEC);
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_ASYM_TX_FORMAT,
|
|
inst_index);
|
|
ring_number = crypto_inst->asym_tx;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&ring_number, ADF_DEC);
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_SYM_TX_FORMAT,
|
|
inst_index);
|
|
ring_number = crypto_inst->sym_tx;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&ring_number, ADF_DEC);
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_ASYM_RX_FORMAT,
|
|
inst_index);
|
|
ring_number = crypto_inst->asym_rx;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&ring_number, ADF_DEC);
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_SYM_RX_FORMAT,
|
|
inst_index);
|
|
ring_number = crypto_inst->sym_rx;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&ring_number, ADF_DEC);
|
|
|
|
strlcpy(key, ADF_CY_RING_ASYM_SIZE, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(accel_dev, ADF_GENERAL_SEC, key, &asym_req))
|
|
asym_req = ADF_CFG_DEF_CY_RING_ASYM_SIZE;
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_RING_ASYM_SIZE_FORMAT,
|
|
inst_index);
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&asym_req, ADF_DEC);
|
|
|
|
strlcpy(key, ADF_CY_RING_SYM_SIZE, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(accel_dev, ADF_GENERAL_SEC, key, &sym_req))
|
|
sym_req = ADF_CFG_DEF_CY_RING_SYM_SIZE;
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_RING_SYM_SIZE_FORMAT,
|
|
inst_index);
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&sym_req, ADF_DEC);
|
|
|
|
free(key, M_QAT);
|
|
}
|
|
|
|
static void
|
|
adf_cfg_add_dc_inst_info(struct adf_accel_dev *accel_dev,
|
|
struct adf_cfg_instance *dc_inst,
|
|
const char *derived_sec,
|
|
int inst_index)
|
|
{
|
|
char *key = NULL;
|
|
unsigned long bank_number = 0;
|
|
unsigned long ring_number = 0;
|
|
unsigned long dc_req = 0;
|
|
|
|
key = malloc(ADF_CFG_MAX_KEY_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
snprintf(key, ADF_CFG_MAX_STR_LEN, ADF_DC_BANK_NUM_FORMAT, inst_index);
|
|
bank_number = dc_inst->bundle;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&bank_number, ADF_DEC);
|
|
|
|
snprintf(key, ADF_CFG_MAX_STR_LEN, ADF_DC_TX_FORMAT, inst_index);
|
|
ring_number = dc_inst->dc_tx;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&ring_number, ADF_DEC);
|
|
|
|
snprintf(key, ADF_CFG_MAX_STR_LEN, ADF_DC_RX_FORMAT, inst_index);
|
|
ring_number = dc_inst->dc_rx;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&ring_number, ADF_DEC);
|
|
|
|
strlcpy(key, ADF_DC_RING_SIZE, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(accel_dev, ADF_GENERAL_SEC, key, &dc_req))
|
|
dc_req = ADF_CFG_DEF_DC_RING_SIZE;
|
|
|
|
snprintf(key, ADF_CFG_MAX_STR_LEN, ADF_DC_RING_SIZE_FORMAT, inst_index);
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&dc_req, ADF_DEC);
|
|
|
|
free(key, M_QAT);
|
|
}
|
|
|
|
static void
|
|
adf_cfg_add_asym_inst_info(struct adf_accel_dev *accel_dev,
|
|
struct adf_cfg_instance *asym_inst,
|
|
const char *derived_sec,
|
|
int inst_index)
|
|
{
|
|
char *key = NULL;
|
|
unsigned long bank_number = 0;
|
|
unsigned long ring_number = 0;
|
|
unsigned long asym_req = 0;
|
|
|
|
key = malloc(ADF_CFG_MAX_KEY_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
if (adf_cy_inst_cross_banks(accel_dev))
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_ASYM_BANK_NUM_FORMAT,
|
|
inst_index);
|
|
else
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_BANK_NUM_FORMAT,
|
|
inst_index);
|
|
bank_number = asym_inst->bundle;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&bank_number, ADF_DEC);
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_ASYM_TX_FORMAT,
|
|
inst_index);
|
|
ring_number = asym_inst->asym_tx;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&ring_number, ADF_DEC);
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_ASYM_RX_FORMAT,
|
|
inst_index);
|
|
ring_number = asym_inst->asym_rx;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&ring_number, ADF_DEC);
|
|
|
|
strlcpy(key, ADF_CY_RING_ASYM_SIZE, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(accel_dev, ADF_GENERAL_SEC, key, &asym_req))
|
|
asym_req = ADF_CFG_DEF_CY_RING_ASYM_SIZE;
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_RING_ASYM_SIZE_FORMAT,
|
|
inst_index);
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&asym_req, ADF_DEC);
|
|
|
|
free(key, M_QAT);
|
|
}
|
|
|
|
static void
|
|
adf_cfg_add_sym_inst_info(struct adf_accel_dev *accel_dev,
|
|
struct adf_cfg_instance *sym_inst,
|
|
const char *derived_sec,
|
|
int inst_index)
|
|
{
|
|
char *key = NULL;
|
|
unsigned long bank_number = 0;
|
|
unsigned long ring_number = 0;
|
|
unsigned long sym_req = 0;
|
|
|
|
key = malloc(ADF_CFG_MAX_KEY_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
if (adf_cy_inst_cross_banks(accel_dev))
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_SYM_BANK_NUM_FORMAT,
|
|
inst_index);
|
|
else
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_BANK_NUM_FORMAT,
|
|
inst_index);
|
|
|
|
bank_number = sym_inst->bundle;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&bank_number, ADF_DEC);
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_SYM_TX_FORMAT,
|
|
inst_index);
|
|
ring_number = sym_inst->sym_tx;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&ring_number, ADF_DEC);
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_SYM_RX_FORMAT,
|
|
inst_index);
|
|
ring_number = sym_inst->sym_rx;
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&ring_number, ADF_DEC);
|
|
|
|
strlcpy(key, ADF_CY_RING_SYM_SIZE, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(accel_dev, ADF_GENERAL_SEC, key, &sym_req))
|
|
sym_req = ADF_CFG_DEF_CY_RING_SYM_SIZE;
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_RING_SYM_SIZE_FORMAT,
|
|
inst_index);
|
|
adf_cfg_add_key_value_param(
|
|
accel_dev, derived_sec, key, (void *)&sym_req, ADF_DEC);
|
|
|
|
free(key, M_QAT);
|
|
}
|
|
|
|
static int
|
|
adf_cfg_section_copy(struct adf_accel_dev *accel_dev,
|
|
const char *processed_sec,
|
|
const char *derived_sec)
|
|
{
|
|
unsigned long val = 0;
|
|
struct list_head *list;
|
|
struct adf_cfg_section *sec_process =
|
|
adf_cfg_sec_find(accel_dev, processed_sec);
|
|
if (!sec_process)
|
|
return EFAULT;
|
|
|
|
list_for_each(list, &sec_process->param_head)
|
|
{
|
|
struct adf_cfg_key_val *ptr =
|
|
list_entry(list, struct adf_cfg_key_val, list);
|
|
|
|
/*
|
|
* ignore CoreAffinity since it will be generated later, and
|
|
* there is no need to keep NumProcesses and LimitDevAccess.
|
|
*/
|
|
if (strstr(ptr->key, ADF_ETRMGR_CORE_AFFINITY) ||
|
|
strstr(ptr->key, ADF_NUM_PROCESSES) ||
|
|
strstr(ptr->key, ADF_LIMIT_DEV_ACCESS))
|
|
continue;
|
|
|
|
if (ptr->type == ADF_DEC) {
|
|
if (!compat_strtoul(ptr->val, 10, &val))
|
|
adf_cfg_add_key_value_param(accel_dev,
|
|
derived_sec,
|
|
ptr->key,
|
|
(void *)&val,
|
|
ptr->type);
|
|
} else if (ptr->type == ADF_STR) {
|
|
adf_cfg_add_key_value_param(accel_dev,
|
|
derived_sec,
|
|
ptr->key,
|
|
(void *)ptr->val,
|
|
ptr->type);
|
|
} else if (ptr->type == ADF_HEX) {
|
|
if (!compat_strtoul(ptr->val, 16, &val))
|
|
adf_cfg_add_key_value_param(accel_dev,
|
|
derived_sec,
|
|
ptr->key,
|
|
(void *)val,
|
|
ptr->type);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_create_rings_entries_for_cy_inst(struct adf_accel_dev *accel_dev,
|
|
const char *processed_sec,
|
|
const char *derived_sec,
|
|
int process_num,
|
|
enum adf_cfg_service_type serv_type)
|
|
{
|
|
int i = 0;
|
|
int ret = EFAULT;
|
|
unsigned long num_inst = 0, num_dc_inst = 0;
|
|
unsigned long core_number = 0;
|
|
unsigned long polling_mode = 0;
|
|
struct adf_cfg_instance *crypto_inst = NULL;
|
|
|
|
char *key = NULL;
|
|
char *val = NULL;
|
|
|
|
key = malloc(ADF_CFG_MAX_KEY_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
val = malloc(ADF_CFG_MAX_VAL_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_SERVICES_ENABLED);
|
|
if (adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val))
|
|
goto failed;
|
|
if ((!strncmp(val, ADF_CFG_CY, ADF_CFG_MAX_VAL_LEN_IN_BYTES)) ||
|
|
(!strncmp(val, ADF_CFG_ASYM, ADF_CFG_MAX_VAL_LEN_IN_BYTES)) ||
|
|
(!strncmp(val, ADF_CFG_SYM, ADF_CFG_MAX_VAL_LEN_IN_BYTES))) {
|
|
strlcpy(key, ADF_NUM_DC, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(
|
|
accel_dev, processed_sec, key, &num_dc_inst))
|
|
goto failed;
|
|
if (num_dc_inst > 0) {
|
|
device_printf(
|
|
GET_DEV(accel_dev),
|
|
"NumDcInstances > 0,when CY only is enabled\n");
|
|
goto failed;
|
|
}
|
|
}
|
|
ret = EFAULT;
|
|
|
|
strlcpy(key, ADF_NUM_CY, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(accel_dev, processed_sec, key, &num_inst))
|
|
goto failed;
|
|
|
|
crypto_inst = malloc(sizeof(*crypto_inst), M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
for (i = 0; i < num_inst; i++) {
|
|
memset(crypto_inst, 0, sizeof(*crypto_inst));
|
|
crypto_inst->stype = serv_type;
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_CORE_AFFINITY_FORMAT,
|
|
i);
|
|
if (adf_cfg_set_core_number_for_instance(accel_dev,
|
|
processed_sec,
|
|
key,
|
|
process_num,
|
|
&core_number))
|
|
goto failed;
|
|
|
|
if (strcmp(processed_sec, ADF_KERNEL_SEC) &&
|
|
strcmp(processed_sec, ADF_KERNEL_SAL_SEC))
|
|
adf_cfg_add_key_value_param(accel_dev,
|
|
derived_sec,
|
|
key,
|
|
(void *)&core_number,
|
|
ADF_DEC);
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_NAME_FORMAT,
|
|
i);
|
|
if (adf_cfg_get_param_value(accel_dev, processed_sec, key, val))
|
|
goto failed;
|
|
|
|
strlcpy(crypto_inst->name, val, sizeof(crypto_inst->name));
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_CY_POLL_MODE_FORMAT,
|
|
i);
|
|
if (adf_cfg_set_value(
|
|
accel_dev, processed_sec, key, &polling_mode))
|
|
goto failed;
|
|
|
|
crypto_inst->polling_mode = polling_mode;
|
|
CPU_ZERO(&crypto_inst->affinity_mask);
|
|
CPU_SET(core_number, &crypto_inst->affinity_mask);
|
|
|
|
if (adf_cfg_get_ring_pairs(accel_dev->cfg->dev,
|
|
crypto_inst,
|
|
derived_sec,
|
|
accel_dev))
|
|
goto failed;
|
|
|
|
switch (serv_type) {
|
|
case CRYPTO:
|
|
adf_cfg_add_cy_inst_info(accel_dev,
|
|
crypto_inst,
|
|
derived_sec,
|
|
i);
|
|
break;
|
|
case ASYM:
|
|
adf_cfg_add_asym_inst_info(accel_dev,
|
|
crypto_inst,
|
|
derived_sec,
|
|
i);
|
|
break;
|
|
case SYM:
|
|
adf_cfg_add_sym_inst_info(accel_dev,
|
|
crypto_inst,
|
|
derived_sec,
|
|
i);
|
|
break;
|
|
default:
|
|
pr_err("unknown crypto instance type %d.\n", serv_type);
|
|
goto failed;
|
|
}
|
|
}
|
|
|
|
ret = 0;
|
|
failed:
|
|
free(crypto_inst, M_QAT);
|
|
free(val, M_QAT);
|
|
free(key, M_QAT);
|
|
|
|
if (ret)
|
|
device_printf(GET_DEV(accel_dev),
|
|
"Failed to create rings for cy\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_create_rings_entries_for_dc_inst(struct adf_accel_dev *accel_dev,
|
|
const char *processed_sec,
|
|
const char *derived_sec,
|
|
int process_num)
|
|
{
|
|
int i = 0;
|
|
int ret = EFAULT;
|
|
unsigned long num_inst = 0, num_cy_inst = 0;
|
|
unsigned long core_number = 0;
|
|
unsigned long polling_mode = 0;
|
|
struct adf_cfg_instance *dc_inst = NULL;
|
|
|
|
char *key = NULL;
|
|
char *val = NULL;
|
|
|
|
key = malloc(ADF_CFG_MAX_KEY_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
val = malloc(ADF_CFG_MAX_VAL_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
ret = EFAULT;
|
|
|
|
snprintf(key, ADF_CFG_MAX_STR_LEN, ADF_SERVICES_ENABLED);
|
|
if (adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val))
|
|
goto failed;
|
|
|
|
if (!strncmp(val, ADF_CFG_DC, ADF_CFG_MAX_VAL_LEN_IN_BYTES)) {
|
|
strlcpy(key, ADF_NUM_CY, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(
|
|
accel_dev, processed_sec, key, &num_cy_inst))
|
|
goto failed;
|
|
if (num_cy_inst > 0) {
|
|
device_printf(
|
|
GET_DEV(accel_dev),
|
|
"NumCyInstances > 0,when DC only is enabled\n");
|
|
goto failed;
|
|
}
|
|
}
|
|
|
|
strlcpy(key, ADF_NUM_DC, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(accel_dev, processed_sec, key, &num_inst))
|
|
goto failed;
|
|
|
|
dc_inst = malloc(sizeof(*dc_inst), M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
for (i = 0; i < num_inst; i++) {
|
|
memset(dc_inst, 0, sizeof(*dc_inst));
|
|
dc_inst->stype = COMP;
|
|
snprintf(key,
|
|
ADF_CFG_MAX_STR_LEN,
|
|
ADF_DC_CORE_AFFINITY_FORMAT,
|
|
i);
|
|
|
|
if (adf_cfg_set_core_number_for_instance(accel_dev,
|
|
processed_sec,
|
|
key,
|
|
process_num,
|
|
&core_number))
|
|
goto failed;
|
|
|
|
if (strcmp(processed_sec, ADF_KERNEL_SEC) &&
|
|
strcmp(processed_sec, ADF_KERNEL_SAL_SEC)) {
|
|
adf_cfg_add_key_value_param(accel_dev,
|
|
derived_sec,
|
|
key,
|
|
(void *)&core_number,
|
|
ADF_DEC);
|
|
}
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_DC_NAME_FORMAT,
|
|
i);
|
|
if (adf_cfg_get_param_value(accel_dev, processed_sec, key, val))
|
|
goto failed;
|
|
|
|
strlcpy(dc_inst->name, val, sizeof(dc_inst->name));
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_DC_POLL_MODE_FORMAT,
|
|
i);
|
|
if (adf_cfg_set_value(
|
|
accel_dev, processed_sec, key, &polling_mode))
|
|
goto failed;
|
|
|
|
dc_inst->polling_mode = polling_mode;
|
|
CPU_ZERO(&dc_inst->affinity_mask);
|
|
CPU_SET(core_number, &dc_inst->affinity_mask);
|
|
|
|
if (adf_cfg_get_ring_pairs(
|
|
accel_dev->cfg->dev, dc_inst, derived_sec, accel_dev))
|
|
goto failed;
|
|
|
|
adf_cfg_add_dc_inst_info(accel_dev, dc_inst, derived_sec, i);
|
|
}
|
|
|
|
ret = 0;
|
|
failed:
|
|
free(dc_inst, M_QAT);
|
|
free(val, M_QAT);
|
|
free(key, M_QAT);
|
|
|
|
if (ret)
|
|
device_printf(GET_DEV(accel_dev),
|
|
"Failed to create rings for dc\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_process_user_section(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name,
|
|
int dev)
|
|
{
|
|
int i = 0;
|
|
int ret = EFAULT;
|
|
unsigned long num_processes = 0;
|
|
unsigned long limit_dev_acc = 0;
|
|
u8 serv_type = 0;
|
|
|
|
char *key = NULL;
|
|
char *val = NULL;
|
|
char *derived_sec_name = NULL;
|
|
|
|
key = malloc(ADF_CFG_MAX_KEY_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
val = malloc(ADF_CFG_MAX_VAL_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
derived_sec_name =
|
|
malloc(ADF_CFG_MAX_STR_LEN, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
strlcpy(key, ADF_NUM_PROCESSES, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(accel_dev, sec_name, key, &num_processes))
|
|
num_processes = 0;
|
|
|
|
strlcpy(key, ADF_LIMIT_DEV_ACCESS, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(accel_dev, sec_name, key, &limit_dev_acc))
|
|
limit_dev_acc = 0;
|
|
|
|
for (i = 0; i < num_processes; i++) {
|
|
if (limit_dev_acc)
|
|
snprintf(derived_sec_name,
|
|
ADF_CFG_MAX_STR_LEN,
|
|
ADF_LIMITED_USER_SECTION_NAME_FORMAT,
|
|
sec_name,
|
|
dev,
|
|
i);
|
|
else
|
|
snprintf(derived_sec_name,
|
|
ADF_CFG_MAX_STR_LEN,
|
|
ADF_USER_SECTION_NAME_FORMAT,
|
|
sec_name,
|
|
i);
|
|
|
|
if (adf_cfg_derived_section_add(accel_dev, derived_sec_name))
|
|
goto failed;
|
|
|
|
/* copy items to the derived section */
|
|
adf_cfg_section_copy(accel_dev, sec_name, derived_sec_name);
|
|
|
|
for (serv_type = NA; serv_type <= USED; serv_type++) {
|
|
switch (serv_type) {
|
|
case NA:
|
|
break;
|
|
case CRYPTO:
|
|
case ASYM:
|
|
case SYM:
|
|
if (adf_cfg_is_svc_enabled(accel_dev,
|
|
serv_type))
|
|
if (adf_cfg_create_rings_entries_for_cy_inst(
|
|
accel_dev,
|
|
sec_name,
|
|
derived_sec_name,
|
|
i,
|
|
(enum adf_cfg_service_type)
|
|
serv_type))
|
|
goto failed;
|
|
break;
|
|
case COMP:
|
|
if (adf_cfg_is_svc_enabled(accel_dev,
|
|
serv_type))
|
|
if (adf_cfg_create_rings_entries_for_dc_inst(
|
|
accel_dev,
|
|
sec_name,
|
|
derived_sec_name,
|
|
i))
|
|
goto failed;
|
|
break;
|
|
case USED:
|
|
break;
|
|
default:
|
|
pr_err("Unknown service type %d.\n", serv_type);
|
|
}
|
|
}
|
|
}
|
|
|
|
ret = 0;
|
|
failed:
|
|
|
|
free(val, M_QAT);
|
|
free(key, M_QAT);
|
|
free(derived_sec_name, M_QAT);
|
|
|
|
if (ret)
|
|
device_printf(GET_DEV(accel_dev),
|
|
"Failed to process user section %s\n",
|
|
sec_name);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_cleanup_user_section(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name)
|
|
{
|
|
struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, sec_name);
|
|
struct list_head *head;
|
|
struct list_head *list_ptr, *tmp;
|
|
|
|
if (!sec)
|
|
return EFAULT;
|
|
|
|
if (sec->is_derived)
|
|
return 0;
|
|
|
|
head = &sec->param_head;
|
|
list_for_each_prev_safe(list_ptr, tmp, head)
|
|
{
|
|
struct adf_cfg_key_val *ptr =
|
|
list_entry(list_ptr, struct adf_cfg_key_val, list);
|
|
|
|
if (!strcmp(ptr->key, ADF_LIMIT_DEV_ACCESS))
|
|
continue;
|
|
|
|
list_del(list_ptr);
|
|
free(ptr, M_QAT);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_process_section_no_op(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_cleanup_general_section(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name)
|
|
{
|
|
unsigned long first_used_bundle = 0;
|
|
int ret = EFAULT;
|
|
char *key = NULL;
|
|
char *val = NULL;
|
|
|
|
key = malloc(ADF_CFG_MAX_KEY_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
val = malloc(ADF_CFG_MAX_VAL_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
/* Remove sections that not needed after processing */
|
|
strlcpy(key, ADF_CONFIG_VERSION, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_remove_key_param(accel_dev, sec_name, key))
|
|
goto failed;
|
|
|
|
strlcpy(key, ADF_CY ADF_RING_ASYM_SIZE, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_remove_key_param(accel_dev, sec_name, key))
|
|
goto failed;
|
|
|
|
strlcpy(key, ADF_CY ADF_RING_SYM_SIZE, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_remove_key_param(accel_dev, sec_name, key))
|
|
goto failed;
|
|
|
|
strlcpy(key, ADF_DC ADF_RING_DC_SIZE, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_remove_key_param(accel_dev, sec_name, key))
|
|
goto failed;
|
|
|
|
/* After all processing done, set the "FirstUserBundle" value */
|
|
first_used_bundle = accel_dev->cfg->dev->max_kernel_bundle_nr + 1;
|
|
strlcpy(key, ADF_FIRST_USER_BUNDLE, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_add_key_value_param(
|
|
accel_dev, sec_name, key, (void *)&first_used_bundle, ADF_DEC))
|
|
goto failed;
|
|
|
|
ret = 0;
|
|
failed:
|
|
free(key, M_QAT);
|
|
free(val, M_QAT);
|
|
|
|
if (ret)
|
|
device_printf(GET_DEV(accel_dev),
|
|
"Failed to clean up general section\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_process_kernel_section(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name)
|
|
{
|
|
u8 serv_type = 0;
|
|
|
|
for (serv_type = NA; serv_type <= USED; serv_type++) {
|
|
switch (serv_type) {
|
|
case NA:
|
|
break;
|
|
case CRYPTO:
|
|
case ASYM:
|
|
case SYM:
|
|
if (adf_cfg_is_svc_enabled(accel_dev, serv_type))
|
|
if (adf_cfg_create_rings_entries_for_cy_inst(
|
|
accel_dev,
|
|
sec_name,
|
|
sec_name,
|
|
0,
|
|
(enum adf_cfg_service_type)serv_type))
|
|
goto failed;
|
|
break;
|
|
case COMP:
|
|
if (adf_cfg_is_svc_enabled(accel_dev, serv_type))
|
|
if (adf_cfg_create_rings_entries_for_dc_inst(
|
|
accel_dev, sec_name, sec_name, 0))
|
|
goto failed;
|
|
break;
|
|
case USED:
|
|
break;
|
|
default:
|
|
pr_err("Unknown service type of instance %d.\n",
|
|
serv_type);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
|
|
failed:
|
|
return EFAULT;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_cleanup_kernel_section(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_create_accel_section(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name)
|
|
{
|
|
/* Find global settings for coalescing. Use defaults if not found */
|
|
unsigned long accel_coales = 0;
|
|
unsigned long accel_coales_timer = 0;
|
|
unsigned long accel_coales_num_msg = 0;
|
|
unsigned long cpu;
|
|
char *key = NULL;
|
|
char *val = NULL;
|
|
int ret = EFAULT;
|
|
int index = 0;
|
|
struct adf_hw_device_data *hw_device = accel_dev->hw_device;
|
|
|
|
if (!hw_device)
|
|
goto failed;
|
|
|
|
key = malloc(ADF_CFG_MAX_KEY_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
val = malloc(ADF_CFG_MAX_VAL_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
strlcpy(key,
|
|
ADF_ETRMGR_COALESCING_ENABLED,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(accel_dev, ADF_GENERAL_SEC, key, &accel_coales))
|
|
accel_coales = ADF_CFG_ACCEL_DEF_COALES;
|
|
|
|
strlcpy(key, ADF_ETRMGR_COALESCE_TIMER, ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(
|
|
accel_dev, ADF_GENERAL_SEC, key, &accel_coales_timer))
|
|
accel_coales_timer = ADF_CFG_ACCEL_DEF_COALES_TIMER;
|
|
|
|
strlcpy(key,
|
|
ADF_ETRMGR_COALESCING_MSG_ENABLED,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES);
|
|
if (adf_cfg_set_value(
|
|
accel_dev, ADF_GENERAL_SEC, key, &accel_coales_num_msg))
|
|
accel_coales_num_msg = ADF_CFG_ACCEL_DEF_COALES_NUM_MSG;
|
|
|
|
for (index = 0; index < hw_device->num_banks; index++) {
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_ETRMGR_COALESCING_ENABLED_FORMAT,
|
|
index);
|
|
ret = adf_cfg_add_key_value_param(
|
|
accel_dev, sec_name, key, &accel_coales, ADF_DEC);
|
|
if (ret != 0)
|
|
goto failed;
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_ETRMGR_COALESCE_TIMER_FORMAT,
|
|
index);
|
|
ret = adf_cfg_add_key_value_param(
|
|
accel_dev, sec_name, key, &accel_coales_timer, ADF_DEC);
|
|
if (ret != 0)
|
|
goto failed;
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_ETRMGR_COALESCING_MSG_ENABLED_FORMAT,
|
|
index);
|
|
ret = adf_cfg_add_key_value_param(
|
|
accel_dev, sec_name, key, &accel_coales_num_msg, ADF_DEC);
|
|
if (ret != 0)
|
|
goto failed;
|
|
|
|
cpu = ADF_CFG_AFFINITY_WHATEVER;
|
|
|
|
snprintf(key,
|
|
ADF_CFG_MAX_KEY_LEN_IN_BYTES,
|
|
ADF_ETRMGR_CORE_AFFINITY_FORMAT,
|
|
index);
|
|
ret = adf_cfg_add_key_value_param(
|
|
accel_dev, sec_name, key, &cpu, ADF_DEC);
|
|
if (ret != 0)
|
|
goto failed;
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
failed:
|
|
free(key, M_QAT);
|
|
free(val, M_QAT);
|
|
|
|
if (ret)
|
|
device_printf(GET_DEV(accel_dev),
|
|
"Failed to create accel section\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_cleanup_accel_section(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
adf_cfg_process_accel_section(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name)
|
|
{
|
|
int accel_num = 0;
|
|
struct adf_hw_device_data *hw_device = accel_dev->hw_device;
|
|
char *derived_name = NULL;
|
|
int ret = EFAULT;
|
|
|
|
if (!hw_device)
|
|
goto failed;
|
|
|
|
if (hw_device->num_logical_accel == 0)
|
|
goto failed;
|
|
|
|
derived_name =
|
|
malloc(ADF_CFG_MAX_SECTION_LEN_IN_BYTES, M_QAT, M_WAITOK | M_ZERO);
|
|
|
|
for (accel_num = 0; accel_num < hw_device->num_logical_accel;
|
|
accel_num++) {
|
|
snprintf(derived_name,
|
|
ADF_CFG_MAX_SECTION_LEN_IN_BYTES,
|
|
ADF_ACCEL_STR,
|
|
accel_num);
|
|
ret = adf_cfg_section_add(accel_dev, derived_name);
|
|
if (ret != 0)
|
|
goto failed;
|
|
|
|
ret = adf_cfg_create_accel_section(accel_dev, derived_name);
|
|
if (ret != 0)
|
|
goto failed;
|
|
}
|
|
|
|
ret = 0;
|
|
failed:
|
|
free(derived_name, M_QAT);
|
|
|
|
if (ret)
|
|
device_printf(GET_DEV(accel_dev),
|
|
"Failed to process accel section\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
int
|
|
adf_cfg_process_section(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name,
|
|
int dev)
|
|
{
|
|
if (!strcmp(sec_name, ADF_GENERAL_SEC) ||
|
|
!strcmp(sec_name, ADF_INLINE_SEC))
|
|
return adf_cfg_process_section_no_op(accel_dev, sec_name);
|
|
else if (!strcmp(sec_name, ADF_KERNEL_SEC) ||
|
|
!strcmp(sec_name, ADF_KERNEL_SAL_SEC))
|
|
return adf_cfg_process_kernel_section(accel_dev, sec_name);
|
|
else if (!strcmp(sec_name, ADF_ACCEL_SEC))
|
|
return adf_cfg_process_accel_section(accel_dev, sec_name);
|
|
else
|
|
return adf_cfg_process_user_section(accel_dev, sec_name, dev);
|
|
}
|
|
|
|
int
|
|
adf_cfg_cleanup_section(struct adf_accel_dev *accel_dev,
|
|
const char *sec_name,
|
|
int dev)
|
|
{
|
|
if (!strcmp(sec_name, ADF_GENERAL_SEC))
|
|
return adf_cfg_cleanup_general_section(accel_dev, sec_name);
|
|
else if (!strcmp(sec_name, ADF_INLINE_SEC))
|
|
return adf_cfg_process_section_no_op(accel_dev, sec_name);
|
|
else if (!strcmp(sec_name, ADF_KERNEL_SEC) ||
|
|
!strcmp(sec_name, ADF_KERNEL_SAL_SEC))
|
|
return adf_cfg_cleanup_kernel_section(accel_dev, sec_name);
|
|
else if (strstr(sec_name, ADF_ACCEL_SEC))
|
|
return adf_cfg_cleanup_accel_section(accel_dev, sec_name);
|
|
else
|
|
return adf_cfg_cleanup_user_section(accel_dev, sec_name);
|
|
}
|
|
|
|
int
|
|
adf_cfg_setup_irq(struct adf_accel_dev *accel_dev)
|
|
{
|
|
int ret = EFAULT;
|
|
struct adf_accel_pci *info_pci_dev = &accel_dev->accel_pci_dev;
|
|
struct adf_cfg_device *cfg_dev = NULL;
|
|
struct msix_entry *msixe = NULL;
|
|
u32 num_msix = 0;
|
|
int index = 0;
|
|
int computed_core = 0;
|
|
|
|
if (!accel_dev || !accel_dev->cfg || !accel_dev->hw_device)
|
|
goto failed;
|
|
|
|
cfg_dev = accel_dev->cfg->dev;
|
|
if (!cfg_dev)
|
|
goto failed;
|
|
|
|
msixe =
|
|
(struct msix_entry *)accel_dev->accel_pci_dev.msix_entries.entries;
|
|
num_msix = accel_dev->accel_pci_dev.msix_entries.num_entries;
|
|
if (!msixe)
|
|
goto cleanup_and_fail;
|
|
|
|
/*
|
|
* Here we want to set the affinity of kernel and epoll mode
|
|
* bundle into user defined value.
|
|
* Because in adf_isr.c we setup core affinity by round-robin
|
|
* we need to reset it after device up done.
|
|
*/
|
|
for (index = 0; index < accel_dev->hw_device->num_banks; index++) {
|
|
struct adf_cfg_bundle *bundle = cfg_dev->bundles[index];
|
|
|
|
if (!bundle)
|
|
continue;
|
|
|
|
if (bundle->type != KERNEL &&
|
|
bundle->polling_mode != ADF_CFG_RESP_EPOLL)
|
|
continue;
|
|
|
|
if (bundle->number >= num_msix)
|
|
goto cleanup_and_fail;
|
|
|
|
computed_core = CPU_FFS(&bundle->affinity_mask) - 1;
|
|
bus_bind_intr(info_pci_dev->pci_dev,
|
|
msixe[index].irq,
|
|
computed_core);
|
|
}
|
|
ret = 0;
|
|
|
|
cleanup_and_fail:
|
|
adf_cfg_device_clear(cfg_dev, accel_dev);
|
|
free(cfg_dev, M_QAT);
|
|
accel_dev->cfg->dev = NULL;
|
|
|
|
failed:
|
|
return ret;
|
|
}
|