Skip to content

Commit

Permalink
crypto/ipsec_mb: introduce IPsec_mb framework
Browse files Browse the repository at this point in the history
This patch introduces the new framework to share common code between
the SW crypto PMDs that depend on the intel-ipsec-mb library.
This change helps to reduce future effort on the code maintenance and
feature updates.

The PMDs that will be added to this framework in subsequent patches are:
  - AESNI MB
  - AESNI GCM
  - CHACHA20_POLY1305
  - KASUMI
  - SNOW3G
  - ZUC

The use of these PMDs will not change, they will still be supported for
x86, and will use the same EAL args as before.

The minimum required version for the intel-ipsec-mb library is now v1.0.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Signed-off-by: Ciara Power <ciara.power@intel.com>
Acked-by: Ray Kinsella <mdr@ashroe.eu>
Acked-by: Akhil Goyal <gakhil@marvell.com>
  • Loading branch information
Fan Zhang authored and Akhil Goyal committed Oct 20, 2021
1 parent 68e8ca7 commit c75542a
Show file tree
Hide file tree
Showing 8 changed files with 780 additions and 0 deletions.
4 changes: 4 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,10 @@ F: drivers/common/qat/
F: doc/guides/cryptodevs/qat.rst
F: doc/guides/cryptodevs/features/qat.ini

IPsec MB
M: Fan Zhang <roy.fan.zhang@intel.com>
F: drivers/crypto/ipsec_mb/

KASUMI
M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
F: drivers/crypto/kasumi/
Expand Down
5 changes: 5 additions & 0 deletions doc/guides/rel_notes/release_21_11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,11 @@ New Features
* Added PDCP short MAC-I support.
* Added raw vector datapath API support.

* **Added framework for consolidation of IPsec_MB dependent SW Crypto PMDs.**

* The IPsec_MB framework was added to share common code between Intel
SW Crypto PMDs that depend on the intel-ipsec-mb library.

* **Updated the ACC100 bbdev PMD.**

Added support for more comprehensive CRC options.
Expand Down
293 changes: 293 additions & 0 deletions drivers/crypto/ipsec_mb/ipsec_mb_ops.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2021 Intel Corporation
*/

#include <string.h>

#include <rte_common.h>
#include <rte_malloc.h>

#include "ipsec_mb_private.h"

/** Configure device */
int
ipsec_mb_config(__rte_unused struct rte_cryptodev *dev,
__rte_unused struct rte_cryptodev_config *config)
{
return 0;
}

/** Start device */
int
ipsec_mb_start(__rte_unused struct rte_cryptodev *dev)
{
return 0;
}

/** Stop device */
void
ipsec_mb_stop(__rte_unused struct rte_cryptodev *dev)
{
}

/** Close device */
int
ipsec_mb_close(__rte_unused struct rte_cryptodev *dev)
{
return 0;
}

/** Get device statistics */
void
ipsec_mb_stats_get(struct rte_cryptodev *dev,
struct rte_cryptodev_stats *stats)
{
int qp_id;

for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
struct ipsec_mb_qp *qp = dev->data->queue_pairs[qp_id];
if (qp == NULL) {
IPSEC_MB_LOG(DEBUG, "Uninitialised qp %d", qp_id);
continue;
}

stats->enqueued_count += qp->stats.enqueued_count;
stats->dequeued_count += qp->stats.dequeued_count;

stats->enqueue_err_count += qp->stats.enqueue_err_count;
stats->dequeue_err_count += qp->stats.dequeue_err_count;
}
}

/** Reset device statistics */
void
ipsec_mb_stats_reset(struct rte_cryptodev *dev)
{
int qp_id;

for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
struct ipsec_mb_qp *qp = dev->data->queue_pairs[qp_id];

memset(&qp->stats, 0, sizeof(qp->stats));
}
}

/** Get device info */
void
ipsec_mb_info_get(struct rte_cryptodev *dev,
struct rte_cryptodev_info *dev_info)
{
struct ipsec_mb_dev_private *internals = dev->data->dev_private;
struct ipsec_mb_internals *pmd_info =
&ipsec_mb_pmds[internals->pmd_type];

if (dev_info != NULL) {
dev_info->driver_id = dev->driver_id;
dev_info->feature_flags = dev->feature_flags;
dev_info->capabilities = pmd_info->caps;
dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
/* No limit of number of sessions */
dev_info->sym.max_nb_sessions = 0;
}
}

/** Release queue pair */
int
ipsec_mb_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
{
struct ipsec_mb_qp *qp = dev->data->queue_pairs[qp_id];
struct rte_ring *r = NULL;

if (qp != NULL) {
r = rte_ring_lookup(qp->name);
if (r)
rte_ring_free(r);
rte_free(qp);
dev->data->queue_pairs[qp_id] = NULL;
}
return 0;
}

/** Set a unique name for the queue pair */
int
ipsec_mb_qp_set_unique_name(struct rte_cryptodev *dev,
struct ipsec_mb_qp *qp)
{
uint32_t n =
snprintf(qp->name, sizeof(qp->name), "ipsec_mb_pmd_%u_qp_%u",
dev->data->dev_id, qp->id);

if (n >= sizeof(qp->name))
return -1;

return 0;
}

/** Create a ring to place processed operations on */
static struct rte_ring
*ipsec_mb_qp_create_processed_ops_ring(
struct ipsec_mb_qp *qp, unsigned int ring_size, int socket_id)
{
struct rte_ring *r;
char ring_name[RTE_CRYPTODEV_NAME_MAX_LEN];

unsigned int n = rte_strlcpy(ring_name, qp->name, sizeof(ring_name));

if (n >= sizeof(ring_name))
return NULL;

r = rte_ring_lookup(ring_name);
if (r) {
if (rte_ring_get_size(r) >= ring_size) {
IPSEC_MB_LOG(
INFO, "Reusing existing ring %s for processed ops",
ring_name);
return r;
}
IPSEC_MB_LOG(
ERR, "Unable to reuse existing ring %s for processed ops",
ring_name);
return NULL;
}

return rte_ring_create(ring_name, ring_size, socket_id,
RING_F_SP_ENQ | RING_F_SC_DEQ);
}

/** Setup a queue pair */
int
ipsec_mb_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
int socket_id)
{
struct ipsec_mb_qp *qp = NULL;
struct ipsec_mb_dev_private *internals = dev->data->dev_private;
struct ipsec_mb_internals *pmd_data =
&ipsec_mb_pmds[internals->pmd_type];
uint32_t qp_size;
int ret;

/* Free memory prior to re-allocation if needed. */
if (dev->data->queue_pairs[qp_id] != NULL)
ipsec_mb_qp_release(dev, qp_id);

qp_size = sizeof(*qp) + pmd_data->qp_priv_size;
/* Allocate the queue pair data structure. */
qp = rte_zmalloc_socket("IPSEC PMD Queue Pair", qp_size,
RTE_CACHE_LINE_SIZE, socket_id);
if (qp == NULL)
return -ENOMEM;

qp->id = qp_id;
dev->data->queue_pairs[qp_id] = qp;
if (ipsec_mb_qp_set_unique_name(dev, qp)) {
ret = -EINVAL;
goto qp_setup_cleanup;
}

qp->pmd_type = internals->pmd_type;
qp->sess_mp = qp_conf->mp_session;
qp->sess_mp_priv = qp_conf->mp_session_private;

qp->ingress_queue = ipsec_mb_qp_create_processed_ops_ring(qp,
qp_conf->nb_descriptors, socket_id);
if (qp->ingress_queue == NULL) {
ret = -EINVAL;
goto qp_setup_cleanup;
}

qp->mb_mgr = alloc_init_mb_mgr();
if (!qp->mb_mgr) {
ret = -ENOMEM;
goto qp_setup_cleanup;
}

memset(&qp->stats, 0, sizeof(qp->stats));

if (pmd_data->queue_pair_configure) {
ret = pmd_data->queue_pair_configure(qp);
if (ret < 0)
goto qp_setup_cleanup;
}

return 0;

qp_setup_cleanup:
if (qp->mb_mgr)
free_mb_mgr(qp->mb_mgr);
if (qp)
rte_free(qp);
return ret;
}

/** Return the size of the specific pmd session structure */
unsigned
ipsec_mb_sym_session_get_size(struct rte_cryptodev *dev)
{
struct ipsec_mb_dev_private *internals = dev->data->dev_private;
struct ipsec_mb_internals *pmd_data =
&ipsec_mb_pmds[internals->pmd_type];

return pmd_data->session_priv_size;
}

/** Configure pmd specific multi-buffer session from a crypto xform chain */
int
ipsec_mb_sym_session_configure(
struct rte_cryptodev *dev, struct rte_crypto_sym_xform *xform,
struct rte_cryptodev_sym_session *sess, struct rte_mempool *mempool)
{
void *sess_private_data;
struct ipsec_mb_dev_private *internals = dev->data->dev_private;
struct ipsec_mb_internals *pmd_data =
&ipsec_mb_pmds[internals->pmd_type];
IMB_MGR *mb_mgr = alloc_init_mb_mgr();
int ret = 0;

if (!mb_mgr)
return -ENOMEM;

if (unlikely(sess == NULL)) {
IPSEC_MB_LOG(ERR, "invalid session struct");
free_mb_mgr(mb_mgr);
return -EINVAL;
}

if (rte_mempool_get(mempool, &sess_private_data)) {
IPSEC_MB_LOG(ERR, "Couldn't get object from session mempool");
free_mb_mgr(mb_mgr);
return -ENOMEM;
}

ret = (*pmd_data->session_configure)(mb_mgr, sess_private_data, xform);
if (ret != 0) {
IPSEC_MB_LOG(ERR, "failed configure session parameters");

/* Return session to mempool */
rte_mempool_put(mempool, sess_private_data);
free_mb_mgr(mb_mgr);
return ret;
}

set_sym_session_private_data(sess, dev->driver_id, sess_private_data);

return 0;
}

/** Clear the session memory */
void
ipsec_mb_sym_session_clear(struct rte_cryptodev *dev,
struct rte_cryptodev_sym_session *sess)
{
uint8_t index = dev->driver_id;
void *sess_priv = get_sym_session_private_data(sess, index);

/* Zero out the whole structure */
if (sess_priv) {
memset(sess_priv, 0, ipsec_mb_sym_session_get_size(dev));
struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);

set_sym_session_private_data(sess, index, NULL);
rte_mempool_put(sess_mp, sess_priv);
}
}
Loading

0 comments on commit c75542a

Please sign in to comment.