288 lines · c
1// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)2/* Copyright(c) 2014 - 2020 Intel Corporation */3#include <linux/module.h>4#include <linux/slab.h>5#include "adf_accel_devices.h"6#include "adf_common_drv.h"7#include "adf_transport.h"8#include "adf_cfg.h"9#include "adf_cfg_strings.h"10#include "adf_gen2_hw_data.h"11#include "qat_crypto.h"12#include "icp_qat_fw.h"13 14#define SEC ADF_KERNEL_SEC15 16static struct service_hndl qat_crypto;17 18void qat_crypto_put_instance(struct qat_crypto_instance *inst)19{20 atomic_dec(&inst->refctr);21 adf_dev_put(inst->accel_dev);22}23 24static int qat_crypto_free_instances(struct adf_accel_dev *accel_dev)25{26 struct qat_crypto_instance *inst, *tmp;27 int i;28 29 list_for_each_entry_safe(inst, tmp, &accel_dev->crypto_list, list) {30 for (i = 0; i < atomic_read(&inst->refctr); i++)31 qat_crypto_put_instance(inst);32 33 if (inst->sym_tx)34 adf_remove_ring(inst->sym_tx);35 36 if (inst->sym_rx)37 adf_remove_ring(inst->sym_rx);38 39 if (inst->pke_tx)40 adf_remove_ring(inst->pke_tx);41 42 if (inst->pke_rx)43 adf_remove_ring(inst->pke_rx);44 45 list_del(&inst->list);46 kfree(inst);47 }48 return 0;49}50 51struct qat_crypto_instance *qat_crypto_get_instance_node(int node)52{53 struct adf_accel_dev *accel_dev = NULL, *tmp_dev;54 struct qat_crypto_instance *inst = NULL, *tmp_inst;55 unsigned long best = ~0;56 57 list_for_each_entry(tmp_dev, adf_devmgr_get_head(), list) {58 unsigned long ctr;59 60 if ((node == dev_to_node(&GET_DEV(tmp_dev)) ||61 dev_to_node(&GET_DEV(tmp_dev)) < 0) &&62 adf_dev_started(tmp_dev) &&63 !list_empty(&tmp_dev->crypto_list)) {64 ctr = atomic_read(&tmp_dev->ref_count);65 if (best > ctr) {66 accel_dev = tmp_dev;67 best = ctr;68 }69 }70 }71 72 if (!accel_dev) {73 pr_debug_ratelimited("QAT: Could not find a device on node %d\n", node);74 /* Get any started device */75 list_for_each_entry(tmp_dev, adf_devmgr_get_head(), list) {76 if (adf_dev_started(tmp_dev) &&77 !list_empty(&tmp_dev->crypto_list)) {78 accel_dev = tmp_dev;79 break;80 }81 }82 }83 84 if (!accel_dev)85 return NULL;86 87 best = ~0;88 list_for_each_entry(tmp_inst, &accel_dev->crypto_list, list) {89 unsigned long ctr;90 91 ctr = atomic_read(&tmp_inst->refctr);92 if (best > ctr) {93 inst = tmp_inst;94 best = ctr;95 }96 }97 if (inst) {98 if (adf_dev_get(accel_dev)) {99 dev_err(&GET_DEV(accel_dev), "Could not increment dev refctr\n");100 return NULL;101 }102 atomic_inc(&inst->refctr);103 }104 return inst;105}106 107/**108 * qat_crypto_vf_dev_config() - create dev config required to create109 * crypto inst.110 *111 * @accel_dev: Pointer to acceleration device.112 *113 * Function creates device configuration required to create114 * asym, sym or, crypto instances115 *116 * Return: 0 on success, error code otherwise.117 */118int qat_crypto_vf_dev_config(struct adf_accel_dev *accel_dev)119{120 u16 ring_to_svc_map = GET_HW_DATA(accel_dev)->ring_to_svc_map;121 122 if (ring_to_svc_map != ADF_GEN2_DEFAULT_RING_TO_SRV_MAP) {123 dev_err(&GET_DEV(accel_dev),124 "Unsupported ring/service mapping present on PF");125 return -EFAULT;126 }127 128 return GET_HW_DATA(accel_dev)->dev_config(accel_dev);129}130 131static int qat_crypto_create_instances(struct adf_accel_dev *accel_dev)132{133 unsigned long num_inst, num_msg_sym, num_msg_asym;134 char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];135 char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];136 unsigned long sym_bank, asym_bank;137 struct qat_crypto_instance *inst;138 int msg_size;139 int ret;140 int i;141 142 INIT_LIST_HEAD(&accel_dev->crypto_list);143 ret = adf_cfg_get_param_value(accel_dev, SEC, ADF_NUM_CY, val);144 if (ret)145 return ret;146 147 ret = kstrtoul(val, 0, &num_inst);148 if (ret)149 return ret;150 151 for (i = 0; i < num_inst; i++) {152 inst = kzalloc_node(sizeof(*inst), GFP_KERNEL,153 dev_to_node(&GET_DEV(accel_dev)));154 if (!inst) {155 ret = -ENOMEM;156 goto err;157 }158 159 list_add_tail(&inst->list, &accel_dev->crypto_list);160 inst->id = i;161 atomic_set(&inst->refctr, 0);162 inst->accel_dev = accel_dev;163 164 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_BANK_NUM, i);165 ret = adf_cfg_get_param_value(accel_dev, SEC, key, val);166 if (ret)167 goto err;168 169 ret = kstrtoul(val, 10, &sym_bank);170 if (ret)171 goto err;172 173 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_BANK_NUM, i);174 ret = adf_cfg_get_param_value(accel_dev, SEC, key, val);175 if (ret)176 goto err;177 178 ret = kstrtoul(val, 10, &asym_bank);179 if (ret)180 goto err;181 182 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_SIZE, i);183 ret = adf_cfg_get_param_value(accel_dev, SEC, key, val);184 if (ret)185 goto err;186 187 ret = kstrtoul(val, 10, &num_msg_sym);188 if (ret)189 goto err;190 191 num_msg_sym = num_msg_sym >> 1;192 193 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_SIZE, i);194 ret = adf_cfg_get_param_value(accel_dev, SEC, key, val);195 if (ret)196 goto err;197 198 ret = kstrtoul(val, 10, &num_msg_asym);199 if (ret)200 goto err;201 num_msg_asym = num_msg_asym >> 1;202 203 msg_size = ICP_QAT_FW_REQ_DEFAULT_SZ;204 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_TX, i);205 ret = adf_create_ring(accel_dev, SEC, sym_bank, num_msg_sym,206 msg_size, key, NULL, 0, &inst->sym_tx);207 if (ret)208 goto err;209 210 msg_size = msg_size >> 1;211 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_TX, i);212 ret = adf_create_ring(accel_dev, SEC, asym_bank, num_msg_asym,213 msg_size, key, NULL, 0, &inst->pke_tx);214 if (ret)215 goto err;216 217 msg_size = ICP_QAT_FW_RESP_DEFAULT_SZ;218 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_RX, i);219 ret = adf_create_ring(accel_dev, SEC, sym_bank, num_msg_sym,220 msg_size, key, qat_alg_callback, 0,221 &inst->sym_rx);222 if (ret)223 goto err;224 225 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_RX, i);226 ret = adf_create_ring(accel_dev, SEC, asym_bank, num_msg_asym,227 msg_size, key, qat_alg_asym_callback, 0,228 &inst->pke_rx);229 if (ret)230 goto err;231 232 INIT_LIST_HEAD(&inst->backlog.list);233 spin_lock_init(&inst->backlog.lock);234 }235 return 0;236err:237 qat_crypto_free_instances(accel_dev);238 return ret;239}240 241static int qat_crypto_init(struct adf_accel_dev *accel_dev)242{243 if (qat_crypto_create_instances(accel_dev))244 return -EFAULT;245 246 return 0;247}248 249static int qat_crypto_shutdown(struct adf_accel_dev *accel_dev)250{251 return qat_crypto_free_instances(accel_dev);252}253 254static int qat_crypto_event_handler(struct adf_accel_dev *accel_dev,255 enum adf_event event)256{257 int ret;258 259 switch (event) {260 case ADF_EVENT_INIT:261 ret = qat_crypto_init(accel_dev);262 break;263 case ADF_EVENT_SHUTDOWN:264 ret = qat_crypto_shutdown(accel_dev);265 break;266 case ADF_EVENT_RESTARTING:267 case ADF_EVENT_RESTARTED:268 case ADF_EVENT_START:269 case ADF_EVENT_STOP:270 default:271 ret = 0;272 }273 return ret;274}275 276int qat_crypto_register(void)277{278 memset(&qat_crypto, 0, sizeof(qat_crypto));279 qat_crypto.event_hld = qat_crypto_event_handler;280 qat_crypto.name = "qat_crypto";281 return adf_service_register(&qat_crypto);282}283 284int qat_crypto_unregister(void)285{286 return adf_service_unregister(&qat_crypto);287}288