dpdk/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2016-2018 Intel Corporation
   3 */
   4
   5#include <string.h>
   6
   7#include <rte_common.h>
   8#include <rte_malloc.h>
   9#include <rte_cryptodev_pmd.h>
  10
  11#include "kasumi_pmd_private.h"
  12
  13static const struct rte_cryptodev_capabilities kasumi_pmd_capabilities[] = {
  14        {       /* KASUMI (F9) */
  15                .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
  16                {.sym = {
  17                        .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
  18                        {.auth = {
  19                                .algo = RTE_CRYPTO_AUTH_KASUMI_F9,
  20                                .block_size = 8,
  21                                .key_size = {
  22                                        .min = 16,
  23                                        .max = 16,
  24                                        .increment = 0
  25                                },
  26                                .digest_size = {
  27                                        .min = 4,
  28                                        .max = 4,
  29                                        .increment = 0
  30                                },
  31                                .iv_size = { 0 }
  32                        }, }
  33                }, }
  34        },
  35        {       /* KASUMI (F8) */
  36                .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
  37                {.sym = {
  38                        .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
  39                        {.cipher = {
  40                                .algo = RTE_CRYPTO_CIPHER_KASUMI_F8,
  41                                .block_size = 8,
  42                                .key_size = {
  43                                        .min = 16,
  44                                        .max = 16,
  45                                        .increment = 0
  46                                },
  47                                .iv_size = {
  48                                        .min = 8,
  49                                        .max = 8,
  50                                        .increment = 0
  51                                }
  52                        }, }
  53                }, }
  54        },
  55        RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
  56};
  57
  58/** Configure device */
  59static int
  60kasumi_pmd_config(__rte_unused struct rte_cryptodev *dev,
  61                __rte_unused struct rte_cryptodev_config *config)
  62{
  63        return 0;
  64}
  65
  66/** Start device */
  67static int
  68kasumi_pmd_start(__rte_unused struct rte_cryptodev *dev)
  69{
  70        return 0;
  71}
  72
  73/** Stop device */
  74static void
  75kasumi_pmd_stop(__rte_unused struct rte_cryptodev *dev)
  76{
  77}
  78
  79/** Close device */
  80static int
  81kasumi_pmd_close(__rte_unused struct rte_cryptodev *dev)
  82{
  83        return 0;
  84}
  85
  86
  87/** Get device statistics */
  88static void
  89kasumi_pmd_stats_get(struct rte_cryptodev *dev,
  90                struct rte_cryptodev_stats *stats)
  91{
  92        int qp_id;
  93
  94        for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
  95                struct kasumi_qp *qp = dev->data->queue_pairs[qp_id];
  96
  97                stats->enqueued_count += qp->qp_stats.enqueued_count;
  98                stats->dequeued_count += qp->qp_stats.dequeued_count;
  99
 100                stats->enqueue_err_count += qp->qp_stats.enqueue_err_count;
 101                stats->dequeue_err_count += qp->qp_stats.dequeue_err_count;
 102        }
 103}
 104
 105/** Reset device statistics */
 106static void
 107kasumi_pmd_stats_reset(struct rte_cryptodev *dev)
 108{
 109        int qp_id;
 110
 111        for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
 112                struct kasumi_qp *qp = dev->data->queue_pairs[qp_id];
 113
 114                memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
 115        }
 116}
 117
 118
 119/** Get device info */
 120static void
 121kasumi_pmd_info_get(struct rte_cryptodev *dev,
 122                struct rte_cryptodev_info *dev_info)
 123{
 124        struct kasumi_private *internals = dev->data->dev_private;
 125
 126        if (dev_info != NULL) {
 127                dev_info->driver_id = dev->driver_id;
 128                dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
 129                /* No limit of number of sessions */
 130                dev_info->sym.max_nb_sessions = 0;
 131                dev_info->feature_flags = dev->feature_flags;
 132                dev_info->capabilities = kasumi_pmd_capabilities;
 133        }
 134}
 135
 136/** Release queue pair */
 137static int
 138kasumi_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
 139{
 140        struct kasumi_qp *qp = dev->data->queue_pairs[qp_id];
 141
 142        if (qp != NULL) {
 143                rte_ring_free(qp->processed_ops);
 144                rte_free(qp);
 145                dev->data->queue_pairs[qp_id] = NULL;
 146        }
 147        return 0;
 148}
 149
 150/** set a unique name for the queue pair based on its name, dev_id and qp_id */
 151static int
 152kasumi_pmd_qp_set_unique_name(struct rte_cryptodev *dev,
 153                struct kasumi_qp *qp)
 154{
 155        unsigned n = snprintf(qp->name, sizeof(qp->name),
 156                        "kasumi_pmd_%u_qp_%u",
 157                        dev->data->dev_id, qp->id);
 158
 159        if (n >= sizeof(qp->name))
 160                return -1;
 161
 162        return 0;
 163}
 164
 165/** Create a ring to place processed ops on */
 166static struct rte_ring *
 167kasumi_pmd_qp_create_processed_ops_ring(struct kasumi_qp *qp,
 168                unsigned ring_size, int socket_id)
 169{
 170        struct rte_ring *r;
 171
 172        r = rte_ring_lookup(qp->name);
 173        if (r) {
 174                if (rte_ring_get_size(r) == ring_size) {
 175                        KASUMI_LOG(INFO, "Reusing existing ring %s"
 176                                        " for processed packets",
 177                                         qp->name);
 178                        return r;
 179                }
 180
 181                KASUMI_LOG(ERR, "Unable to reuse existing ring %s"
 182                                " for processed packets",
 183                                 qp->name);
 184                return NULL;
 185        }
 186
 187        return rte_ring_create(qp->name, ring_size, socket_id,
 188                        RING_F_SP_ENQ | RING_F_SC_DEQ);
 189}
 190
 191/** Setup a queue pair */
 192static int
 193kasumi_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 194                const struct rte_cryptodev_qp_conf *qp_conf,
 195                int socket_id)
 196{
 197        struct kasumi_qp *qp = NULL;
 198        struct kasumi_private *internals = dev->data->dev_private;
 199
 200        /* Free memory prior to re-allocation if needed. */
 201        if (dev->data->queue_pairs[qp_id] != NULL)
 202                kasumi_pmd_qp_release(dev, qp_id);
 203
 204        /* Allocate the queue pair data structure. */
 205        qp = rte_zmalloc_socket("KASUMI PMD Queue Pair", sizeof(*qp),
 206                                        RTE_CACHE_LINE_SIZE, socket_id);
 207        if (qp == NULL)
 208                return (-ENOMEM);
 209
 210        qp->id = qp_id;
 211        dev->data->queue_pairs[qp_id] = qp;
 212
 213        if (kasumi_pmd_qp_set_unique_name(dev, qp))
 214                goto qp_setup_cleanup;
 215
 216        qp->processed_ops = kasumi_pmd_qp_create_processed_ops_ring(qp,
 217                        qp_conf->nb_descriptors, socket_id);
 218        if (qp->processed_ops == NULL)
 219                goto qp_setup_cleanup;
 220
 221        qp->mgr = internals->mgr;
 222        qp->sess_mp = qp_conf->mp_session;
 223        qp->sess_mp_priv = qp_conf->mp_session_private;
 224
 225        memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
 226
 227        return 0;
 228
 229qp_setup_cleanup:
 230        rte_free(qp);
 231
 232        return -1;
 233}
 234
 235/** Returns the size of the KASUMI session structure */
 236static unsigned
 237kasumi_pmd_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
 238{
 239        return sizeof(struct kasumi_session);
 240}
 241
 242/** Configure a KASUMI session from a crypto xform chain */
 243static int
 244kasumi_pmd_sym_session_configure(struct rte_cryptodev *dev,
 245                struct rte_crypto_sym_xform *xform,
 246                struct rte_cryptodev_sym_session *sess,
 247                struct rte_mempool *mempool)
 248{
 249        void *sess_private_data;
 250        int ret;
 251        struct kasumi_private *internals = dev->data->dev_private;
 252
 253        if (unlikely(sess == NULL)) {
 254                KASUMI_LOG(ERR, "invalid session struct");
 255                return -EINVAL;
 256        }
 257
 258        if (rte_mempool_get(mempool, &sess_private_data)) {
 259                KASUMI_LOG(ERR,
 260                                "Couldn't get object from session mempool");
 261                return -ENOMEM;
 262        }
 263
 264        ret = kasumi_set_session_parameters(internals->mgr,
 265                                        sess_private_data, xform);
 266        if (ret != 0) {
 267                KASUMI_LOG(ERR, "failed configure session parameters");
 268
 269                /* Return session to mempool */
 270                rte_mempool_put(mempool, sess_private_data);
 271                return ret;
 272        }
 273
 274        set_sym_session_private_data(sess, dev->driver_id,
 275                sess_private_data);
 276
 277        return 0;
 278}
 279
 280/** Clear the memory of session so it doesn't leave key material behind */
 281static void
 282kasumi_pmd_sym_session_clear(struct rte_cryptodev *dev,
 283                struct rte_cryptodev_sym_session *sess)
 284{
 285        uint8_t index = dev->driver_id;
 286        void *sess_priv = get_sym_session_private_data(sess, index);
 287
 288        /* Zero out the whole structure */
 289        if (sess_priv) {
 290                memset(sess_priv, 0, sizeof(struct kasumi_session));
 291                struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
 292                set_sym_session_private_data(sess, index, NULL);
 293                rte_mempool_put(sess_mp, sess_priv);
 294        }
 295}
 296
 297struct rte_cryptodev_ops kasumi_pmd_ops = {
 298                .dev_configure      = kasumi_pmd_config,
 299                .dev_start          = kasumi_pmd_start,
 300                .dev_stop           = kasumi_pmd_stop,
 301                .dev_close          = kasumi_pmd_close,
 302
 303                .stats_get          = kasumi_pmd_stats_get,
 304                .stats_reset        = kasumi_pmd_stats_reset,
 305
 306                .dev_infos_get      = kasumi_pmd_info_get,
 307
 308                .queue_pair_setup   = kasumi_pmd_qp_setup,
 309                .queue_pair_release = kasumi_pmd_qp_release,
 310
 311                .sym_session_get_size   = kasumi_pmd_sym_session_get_size,
 312                .sym_session_configure  = kasumi_pmd_sym_session_configure,
 313                .sym_session_clear      = kasumi_pmd_sym_session_clear
 314};
 315
 316struct rte_cryptodev_ops *rte_kasumi_pmd_ops = &kasumi_pmd_ops;
 317