crypto/aesni_mb: support DOCSIS protocol
[dpdk.git] / drivers / crypto / aesni_mb / rte_aesni_mb_pmd_ops.c
index c90f6ba..ed93dae 100644 (file)
@@ -4,11 +4,13 @@
 
 #include <string.h>
 
+#include <rte_string_fns.h>
 #include <rte_common.h>
 #include <rte_malloc.h>
+#include <rte_ether.h>
 #include <rte_cryptodev_pmd.h>
 
-#include "rte_aesni_mb_pmd_private.h"
+#include "aesni_mb_pmd_private.h"
 
 
 static const struct rte_cryptodev_capabilities aesni_mb_pmd_capabilities[] = {
@@ -313,8 +315,13 @@ static const struct rte_cryptodev_capabilities aesni_mb_pmd_capabilities[] = {
                                .block_size = 16,
                                .key_size = {
                                        .min = 16,
+#if IMB_VERSION_NUM >= IMB_VERSION(0, 53, 3)
+                                       .max = 32,
+                                       .increment = 16
+#else
                                        .max = 16,
                                        .increment = 0
+#endif
                                },
                                .iv_size = {
                                        .min = 16,
@@ -493,6 +500,55 @@ static const struct rte_cryptodev_capabilities aesni_mb_pmd_capabilities[] = {
        RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
 
+#ifdef AESNI_MB_DOCSIS_SEC_ENABLED
+static const struct rte_cryptodev_capabilities
+                                       aesni_mb_pmd_security_crypto_cap[] = {
+       {       /* AES DOCSIS BPI */
+               .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+               {.sym = {
+                       .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+                       {.cipher = {
+                               .algo = RTE_CRYPTO_CIPHER_AES_DOCSISBPI,
+                               .block_size = 16,
+                               .key_size = {
+                                       .min = 16,
+                                       .max = 32,
+                                       .increment = 16
+                               },
+                               .iv_size = {
+                                       .min = 16,
+                                       .max = 16,
+                                       .increment = 0
+                               }
+                       }, }
+               }, }
+       },
+
+       RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
+};
+
+static const struct rte_security_capability aesni_mb_pmd_security_cap[] = {
+       {       /* DOCSIS Uplink */
+               .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+               .protocol = RTE_SECURITY_PROTOCOL_DOCSIS,
+               .docsis = {
+                       .direction = RTE_SECURITY_DOCSIS_UPLINK
+               },
+               .crypto_capabilities = aesni_mb_pmd_security_crypto_cap
+       },
+       {       /* DOCSIS Downlink */
+               .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+               .protocol = RTE_SECURITY_PROTOCOL_DOCSIS,
+               .docsis = {
+                       .direction = RTE_SECURITY_DOCSIS_DOWNLINK
+               },
+               .crypto_capabilities = aesni_mb_pmd_security_crypto_cap
+       },
+       {
+               .action = RTE_SECURITY_ACTION_TYPE_NONE
+       }
+};
+#endif
 
 /** Configure device */
 static int
@@ -614,7 +670,7 @@ aesni_mb_pmd_qp_create_processed_ops_ring(struct aesni_mb_qp *qp,
        struct rte_ring *r;
        char ring_name[RTE_CRYPTODEV_NAME_MAX_LEN];
 
-       unsigned int n = snprintf(ring_name, sizeof(ring_name), "%s", qp->name);
+       unsigned int n = strlcpy(ring_name, qp->name, sizeof(ring_name));
 
        if (n >= sizeof(ring_name))
                return NULL;
@@ -640,7 +696,7 @@ aesni_mb_pmd_qp_create_processed_ops_ring(struct aesni_mb_qp *qp,
 static int
 aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
                const struct rte_cryptodev_qp_conf *qp_conf,
-               int socket_id, struct rte_mempool *session_pool)
+               int socket_id)
 {
        struct aesni_mb_qp *qp = NULL;
        struct aesni_mb_private *internals = dev->data->dev_private;
@@ -699,7 +755,8 @@ aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
                goto qp_setup_cleanup;
        }
 
-       qp->sess_mp = session_pool;
+       qp->sess_mp = qp_conf->mp_session;
+       qp->sess_mp_priv = qp_conf->mp_session_private;
 
        memset(&qp->stats, 0, sizeof(qp->stats));
 
@@ -719,13 +776,6 @@ qp_setup_cleanup:
        return ret;
 }
 
-/** Return the number of allocated queue pairs */
-static uint32_t
-aesni_mb_pmd_qp_count(struct rte_cryptodev *dev)
-{
-       return dev->data->nb_queue_pairs;
-}
-
 /** Returns the size of the aesni multi-buffer session structure */
 static unsigned
 aesni_mb_pmd_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
@@ -801,7 +851,8 @@ struct rte_cryptodev_ops aesni_mb_pmd_ops = {
 
                .queue_pair_setup       = aesni_mb_pmd_qp_setup,
                .queue_pair_release     = aesni_mb_pmd_qp_release,
-               .queue_pair_count       = aesni_mb_pmd_qp_count,
+
+               .sym_cpu_process        = aesni_mb_cpu_crypto_process_bulk,
 
                .sym_session_get_size   = aesni_mb_pmd_sym_session_get_size,
                .sym_session_configure  = aesni_mb_pmd_sym_session_configure,
@@ -809,3 +860,78 @@ struct rte_cryptodev_ops aesni_mb_pmd_ops = {
 };
 
 struct rte_cryptodev_ops *rte_aesni_mb_pmd_ops = &aesni_mb_pmd_ops;
+
+#ifdef AESNI_MB_DOCSIS_SEC_ENABLED
+/**
+ * Configure a aesni multi-buffer session from a security session
+ * configuration
+ */
+static int
+aesni_mb_pmd_sec_sess_create(void *dev, struct rte_security_session_conf *conf,
+               struct rte_security_session *sess,
+               struct rte_mempool *mempool)
+{
+       void *sess_private_data;
+       struct rte_cryptodev *cdev = (struct rte_cryptodev *)dev;
+       int ret;
+
+       if (rte_mempool_get(mempool, &sess_private_data)) {
+               AESNI_MB_LOG(ERR, "Couldn't get object from session mempool");
+               return -ENOMEM;
+       }
+
+       if (conf->protocol != RTE_SECURITY_PROTOCOL_DOCSIS) {
+               AESNI_MB_LOG(ERR, "Invalid security protocol");
+               return -EINVAL;
+       }
+
+       ret = aesni_mb_set_docsis_sec_session_parameters(cdev, conf,
+                       sess_private_data);
+
+       if (ret != 0) {
+               AESNI_MB_LOG(ERR, "Failed to configure session parameters");
+
+               /* Return session to mempool */
+               rte_mempool_put(mempool, sess_private_data);
+               return ret;
+       }
+
+       set_sec_session_private_data(sess, sess_private_data);
+
+       return ret;
+}
+
+/** Clear the memory of session so it doesn't leave key material behind */
+static int
+aesni_mb_pmd_sec_sess_destroy(void *dev __rte_unused,
+               struct rte_security_session *sess)
+{
+       void *sess_priv = get_sec_session_private_data(sess);
+
+       if (sess_priv) {
+               struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
+               memset(sess, 0, sizeof(struct aesni_mb_session));
+               set_sec_session_private_data(sess, NULL);
+               rte_mempool_put(sess_mp, sess_priv);
+       }
+       return 0;
+}
+
+/** Get security capabilities for aesni multi-buffer */
+static const struct rte_security_capability *
+aesni_mb_pmd_sec_capa_get(void *device __rte_unused)
+{
+       return aesni_mb_pmd_security_cap;
+}
+
+static struct rte_security_ops aesni_mb_pmd_sec_ops = {
+               .session_create = aesni_mb_pmd_sec_sess_create,
+               .session_update = NULL,
+               .session_stats_get = NULL,
+               .session_destroy = aesni_mb_pmd_sec_sess_destroy,
+               .set_pkt_metadata = NULL,
+               .capabilities_get = aesni_mb_pmd_sec_capa_get
+};
+
+struct rte_security_ops *rte_aesni_mb_pmd_sec_ops = &aesni_mb_pmd_sec_ops;
+#endif