1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020 Broadcom
6 #include <rte_common.h>
9 #include <rte_malloc.h>
10 #include <rte_cryptodev_pmd.h>
12 #include "bcmfs_device.h"
13 #include "bcmfs_logs.h"
15 #include "bcmfs_sym_pmd.h"
16 #include "bcmfs_sym_req.h"
17 #include "bcmfs_sym_session.h"
18 #include "bcmfs_sym_capabilities.h"
20 uint8_t cryptodev_bcmfs_driver_id;
22 static int bcmfs_sym_qp_release(struct rte_cryptodev *dev,
23 uint16_t queue_pair_id);
26 bcmfs_sym_dev_config(__rte_unused struct rte_cryptodev *dev,
27 __rte_unused struct rte_cryptodev_config *config)
33 bcmfs_sym_dev_start(__rte_unused struct rte_cryptodev *dev)
39 bcmfs_sym_dev_stop(__rte_unused struct rte_cryptodev *dev)
44 bcmfs_sym_dev_close(struct rte_cryptodev *dev)
48 for (i = 0; i < dev->data->nb_queue_pairs; i++) {
49 ret = bcmfs_sym_qp_release(dev, i);
58 bcmfs_sym_dev_info_get(struct rte_cryptodev *dev,
59 struct rte_cryptodev_info *dev_info)
61 struct bcmfs_sym_dev_private *internals = dev->data->dev_private;
62 struct bcmfs_device *fsdev = internals->fsdev;
64 if (dev_info != NULL) {
65 dev_info->driver_id = cryptodev_bcmfs_driver_id;
66 dev_info->feature_flags = dev->feature_flags;
67 dev_info->max_nb_queue_pairs = fsdev->max_hw_qps;
68 /* No limit of number of sessions */
69 dev_info->sym.max_nb_sessions = 0;
70 dev_info->capabilities = bcmfs_sym_get_capabilities();
75 bcmfs_sym_stats_get(struct rte_cryptodev *dev,
76 struct rte_cryptodev_stats *stats)
78 struct bcmfs_qp_stats bcmfs_stats = {0};
79 struct bcmfs_sym_dev_private *bcmfs_priv;
80 struct bcmfs_device *fsdev;
82 if (stats == NULL || dev == NULL) {
83 BCMFS_LOG(ERR, "invalid ptr: stats %p, dev %p", stats, dev);
86 bcmfs_priv = dev->data->dev_private;
87 fsdev = bcmfs_priv->fsdev;
89 bcmfs_qp_stats_get(fsdev->qps_in_use, fsdev->max_hw_qps, &bcmfs_stats);
91 stats->enqueued_count = bcmfs_stats.enqueued_count;
92 stats->dequeued_count = bcmfs_stats.dequeued_count;
93 stats->enqueue_err_count = bcmfs_stats.enqueue_err_count;
94 stats->dequeue_err_count = bcmfs_stats.dequeue_err_count;
98 bcmfs_sym_stats_reset(struct rte_cryptodev *dev)
100 struct bcmfs_sym_dev_private *bcmfs_priv;
101 struct bcmfs_device *fsdev;
104 BCMFS_LOG(ERR, "invalid cryptodev ptr %p", dev);
107 bcmfs_priv = dev->data->dev_private;
108 fsdev = bcmfs_priv->fsdev;
110 bcmfs_qp_stats_reset(fsdev->qps_in_use, fsdev->max_hw_qps);
114 bcmfs_sym_qp_release(struct rte_cryptodev *dev, uint16_t queue_pair_id)
116 struct bcmfs_sym_dev_private *bcmfs_private = dev->data->dev_private;
117 struct bcmfs_qp *qp = (struct bcmfs_qp *)
118 (dev->data->queue_pairs[queue_pair_id]);
120 BCMFS_LOG(DEBUG, "Release sym qp %u on device %d",
121 queue_pair_id, dev->data->dev_id);
123 rte_mempool_free(qp->sr_mp);
125 bcmfs_private->fsdev->qps_in_use[queue_pair_id] = NULL;
127 return bcmfs_qp_release((struct bcmfs_qp **)
128 &dev->data->queue_pairs[queue_pair_id]);
132 spu_req_init(struct bcmfs_sym_request *sr, rte_iova_t iova __rte_unused)
134 memset(sr, 0, sizeof(*sr));
136 sr->cptr = iova + offsetof(struct bcmfs_sym_request, cipher_key);
137 sr->aptr = iova + offsetof(struct bcmfs_sym_request, auth_key);
138 sr->iptr = iova + offsetof(struct bcmfs_sym_request, iv);
139 sr->dptr = iova + offsetof(struct bcmfs_sym_request, digest);
140 sr->rptr = iova + offsetof(struct bcmfs_sym_request, resp);
144 req_pool_obj_init(__rte_unused struct rte_mempool *mp,
145 __rte_unused void *opaque, void *obj,
146 __rte_unused unsigned int obj_idx)
148 spu_req_init(obj, rte_mempool_virt2iova(obj));
151 static struct rte_mempool *
152 bcmfs_sym_req_pool_create(struct rte_cryptodev *cdev __rte_unused,
153 uint32_t nobjs, uint16_t qp_id,
156 char softreq_pool_name[RTE_RING_NAMESIZE];
157 struct rte_mempool *mp;
159 snprintf(softreq_pool_name, RTE_RING_NAMESIZE, "%s_%d",
162 mp = rte_mempool_create(softreq_pool_name,
163 RTE_ALIGN_MUL_CEIL(nobjs, 64),
164 sizeof(struct bcmfs_sym_request),
165 64, 0, NULL, NULL, req_pool_obj_init, NULL,
168 BCMFS_LOG(ERR, "Failed to create req pool, qid %d, err %d",
175 bcmfs_sym_qp_setup(struct rte_cryptodev *cdev, uint16_t qp_id,
176 const struct rte_cryptodev_qp_conf *qp_conf,
180 struct bcmfs_qp *qp = NULL;
181 struct bcmfs_qp_config bcmfs_qp_conf;
183 struct bcmfs_qp **qp_addr =
184 (struct bcmfs_qp **)&cdev->data->queue_pairs[qp_id];
185 struct bcmfs_sym_dev_private *bcmfs_private = cdev->data->dev_private;
186 struct bcmfs_device *fsdev = bcmfs_private->fsdev;
189 /* If qp is already in use free ring memory and qp metadata. */
190 if (*qp_addr != NULL) {
191 ret = bcmfs_sym_qp_release(cdev, qp_id);
196 if (qp_id >= fsdev->max_hw_qps) {
197 BCMFS_LOG(ERR, "qp_id %u invalid for this device", qp_id);
201 bcmfs_qp_conf.nb_descriptors = qp_conf->nb_descriptors;
202 bcmfs_qp_conf.socket_id = socket_id;
203 bcmfs_qp_conf.max_descs_req = BCMFS_CRYPTO_MAX_HW_DESCS_PER_REQ;
204 bcmfs_qp_conf.iobase = BCMFS_QP_IOBASE_XLATE(fsdev->mmap_addr, qp_id);
205 bcmfs_qp_conf.ops = fsdev->sym_hw_qp_ops;
207 ret = bcmfs_qp_setup(qp_addr, qp_id, &bcmfs_qp_conf);
211 qp = (struct bcmfs_qp *)*qp_addr;
213 qp->sr_mp = bcmfs_sym_req_pool_create(cdev, qp_conf->nb_descriptors,
215 if (qp->sr_mp == NULL)
218 /* store a link to the qp in the bcmfs_device */
219 bcmfs_private->fsdev->qps_in_use[qp_id] = *qp_addr;
221 cdev->data->queue_pairs[qp_id] = qp;
222 BCMFS_LOG(NOTICE, "queue %d setup done\n", qp_id);
227 static struct rte_cryptodev_ops crypto_bcmfs_ops = {
228 /* Device related operations */
229 .dev_configure = bcmfs_sym_dev_config,
230 .dev_start = bcmfs_sym_dev_start,
231 .dev_stop = bcmfs_sym_dev_stop,
232 .dev_close = bcmfs_sym_dev_close,
233 .dev_infos_get = bcmfs_sym_dev_info_get,
234 /* Stats Collection */
235 .stats_get = bcmfs_sym_stats_get,
236 .stats_reset = bcmfs_sym_stats_reset,
237 /* Queue-Pair management */
238 .queue_pair_setup = bcmfs_sym_qp_setup,
239 .queue_pair_release = bcmfs_sym_qp_release,
240 /* Crypto session related operations */
241 .sym_session_get_size = bcmfs_sym_session_get_private_size,
242 .sym_session_configure = bcmfs_sym_session_configure,
243 .sym_session_clear = bcmfs_sym_session_clear
248 bcmfs_sym_pmd_enqueue_op_burst(void *queue_pair,
249 struct rte_crypto_op **ops,
255 struct bcmfs_sym_request *sreq;
256 struct bcmfs_sym_session *sess;
257 struct bcmfs_qp *qp = (struct bcmfs_qp *)queue_pair;
262 if (nb_ops > BCMFS_MAX_REQS_BUFF)
263 nb_ops = BCMFS_MAX_REQS_BUFF;
265 /* We do not process more than available space */
266 if (nb_ops > (qp->nb_descriptors - qp->nb_pending_requests))
267 nb_ops = qp->nb_descriptors - qp->nb_pending_requests;
269 for (i = 0; i < nb_ops; i++) {
270 sess = bcmfs_sym_get_session(ops[i]);
271 if (unlikely(sess == NULL))
274 if (rte_mempool_get(qp->sr_mp, (void **)&sreq))
277 /* save rte_crypto_op */
281 qp->infl_msgs[i] = &sreq->msgs;
282 qp->infl_msgs[i]->ctx = (void *)sreq;
284 /* pre process the request crypto h/w acceleration */
285 retval = bcmfs_process_sym_crypto_op(ops[i], sess, sreq);
286 if (unlikely(retval < 0))
289 /* Send burst request to hw QP */
290 enq = bcmfs_enqueue_op_burst(qp, (void **)qp->infl_msgs, i);
292 for (j = enq; j < i; j++)
293 rte_mempool_put(qp->sr_mp, qp->infl_msgs[j]->ctx);
298 for (j = 0; j < i; j++)
299 rte_mempool_put(qp->sr_mp, qp->infl_msgs[j]->ctx);
304 static void bcmfs_sym_set_request_status(struct rte_crypto_op *op,
305 struct bcmfs_sym_request *out)
307 if (*out->resp == BCMFS_SYM_RESPONSE_SUCCESS)
308 op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
309 else if (*out->resp == BCMFS_SYM_RESPONSE_HASH_TAG_ERROR)
310 op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
312 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
316 bcmfs_sym_pmd_dequeue_op_burst(void *queue_pair,
317 struct rte_crypto_op **ops,
322 unsigned int pkts = 0;
323 struct bcmfs_sym_request *sreq;
324 struct bcmfs_qp *qp = queue_pair;
326 if (nb_ops > BCMFS_MAX_REQS_BUFF)
327 nb_ops = BCMFS_MAX_REQS_BUFF;
329 deq = bcmfs_dequeue_op_burst(qp, (void **)qp->infl_msgs, nb_ops);
330 /* get rte_crypto_ops */
331 for (i = 0; i < deq; i++) {
332 sreq = (struct bcmfs_sym_request *)qp->infl_msgs[i]->ctx;
334 /* set the status based on the response from the crypto h/w */
335 bcmfs_sym_set_request_status(sreq->op, sreq);
337 ops[pkts++] = sreq->op;
339 rte_mempool_put(qp->sr_mp, sreq);
346 * An rte_driver is needed in the registration of both the
347 * device and the driver with cryptodev.
349 static const char bcmfs_sym_drv_name[] = RTE_STR(CRYPTODEV_NAME_BCMFS_SYM_PMD);
350 static const struct rte_driver cryptodev_bcmfs_sym_driver = {
351 .name = bcmfs_sym_drv_name,
352 .alias = bcmfs_sym_drv_name
356 bcmfs_sym_dev_create(struct bcmfs_device *fsdev)
358 struct rte_cryptodev_pmd_init_params init_params = {
360 .socket_id = rte_socket_id(),
361 .private_data_size = sizeof(struct bcmfs_sym_dev_private)
363 char name[RTE_CRYPTODEV_NAME_MAX_LEN];
364 struct rte_cryptodev *cryptodev;
365 struct bcmfs_sym_dev_private *internals;
367 snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s",
370 /* Populate subset device to use in cryptodev device creation */
371 fsdev->sym_rte_dev.driver = &cryptodev_bcmfs_sym_driver;
372 fsdev->sym_rte_dev.numa_node = 0;
373 fsdev->sym_rte_dev.devargs = NULL;
375 cryptodev = rte_cryptodev_pmd_create(name,
378 if (cryptodev == NULL)
381 fsdev->sym_rte_dev.name = cryptodev->data->name;
382 cryptodev->driver_id = cryptodev_bcmfs_driver_id;
383 cryptodev->dev_ops = &crypto_bcmfs_ops;
385 cryptodev->enqueue_burst = bcmfs_sym_pmd_enqueue_op_burst;
386 cryptodev->dequeue_burst = bcmfs_sym_pmd_dequeue_op_burst;
388 cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
389 RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
390 RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT;
392 internals = cryptodev->data->dev_private;
393 internals->fsdev = fsdev;
394 fsdev->sym_dev = internals;
396 internals->sym_dev_id = cryptodev->data->dev_id;
397 internals->fsdev_capabilities = bcmfs_sym_get_capabilities();
399 BCMFS_LOG(DEBUG, "Created bcmfs-sym device %s as cryptodev instance %d",
400 cryptodev->data->name, internals->sym_dev_id);
405 bcmfs_sym_dev_destroy(struct bcmfs_device *fsdev)
407 struct rte_cryptodev *cryptodev;
411 if (fsdev->sym_dev == NULL)
414 /* free crypto device */
415 cryptodev = rte_cryptodev_pmd_get_dev(fsdev->sym_dev->sym_dev_id);
416 rte_cryptodev_pmd_destroy(cryptodev);
417 fsdev->sym_rte_dev.name = NULL;
418 fsdev->sym_dev = NULL;
423 static struct cryptodev_driver bcmfs_crypto_drv;
424 RTE_PMD_REGISTER_CRYPTO_DRIVER(bcmfs_crypto_drv,
425 cryptodev_bcmfs_sym_driver,
426 cryptodev_bcmfs_driver_id);