test/bonding: fix RSS test when disable RSS
[dpdk.git] / drivers / crypto / mvsam / rte_mrvl_pmd_ops.c
index ef52035..f828dc9 100644 (file)
@@ -8,9 +8,10 @@
 
 #include <rte_common.h>
 #include <rte_malloc.h>
-#include <rte_cryptodev_pmd.h>
+#include <cryptodev_pmd.h>
+#include <rte_security_driver.h>
 
-#include "rte_mrvl_pmd_private.h"
+#include "mrvl_pmd_private.h"
 
 /**
  * Capabilities list to be used in reporting to DPDK.
@@ -111,7 +112,7 @@ static const struct rte_cryptodev_capabilities
                                        .increment = 1
                                },
                                .digest_size = {
-                                       .min = 28,
+                                       .min = 12,
                                        .max = 28,
                                        .increment = 0
                                },
@@ -232,7 +233,7 @@ static const struct rte_cryptodev_capabilities
                                },
                                .digest_size = {
                                        .min = 12,
-                                       .max = 48,
+                                       .max = 64,
                                        .increment = 4
                                },
                        }, }
@@ -252,7 +253,7 @@ static const struct rte_cryptodev_capabilities
                                },
                                .digest_size = {
                                        .min = 12,
-                                       .max = 48,
+                                       .max = 64,
                                        .increment = 0
                                },
                        }, }
@@ -336,9 +337,9 @@ static const struct rte_cryptodev_capabilities
                                        .increment = 0
                                },
                                .aad_size = {
-                                       .min = 8,
-                                       .max = 12,
-                                       .increment = 4
+                                       .min = 0,
+                                       .max = 64,
+                                       .increment = 1
                                },
                                .iv_size = {
                                        .min = 12,
@@ -662,6 +663,11 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
                }
 
                /*
+                * In case just one engine is enabled mapping will look as
+                * follows:
+                * qp:      0        1        2        3
+                * cio-x:y: cio-0:0, cio-0:1, cio-0:2, cio-0:3
+                *
                 * In case two crypto engines are enabled qps will
                 * be evenly spread among them. Even and odd qps will
                 * be handled by cio-0 and cio-1 respectively. qp-cio mapping
@@ -673,10 +679,17 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
                 * qp:      4        5        6        7
                 * cio-x:y: cio-0:2, cio-1:2, cio-0:3, cio-1:3
                 *
-                * In case just one engine is enabled mapping will look as
-                * follows:
+                * In case of three crypto engines are enabled qps will
+                * be mapped as following:
+                *
                 * qp:      0        1        2        3
-                * cio-x:y: cio-0:0, cio-0:1, cio-0:2, cio-0:3
+                * cio-x:y: cio-0:0, cio-1:0, cio-2:0, cio-0:1
+                *
+                * qp:      4        5        6        7
+                * cio-x:y: cio-1:1, cio-2:1, cio-0:2, cio-1:2
+                *
+                * qp:      8        9        10       11
+                * cio-x:y: cio-2:2, cio-0:3, cio-1:3, cio-2:3
                 */
                n = snprintf(match, sizeof(match), "cio-%u:%u",
                                qp_id % num, qp_id / num);
@@ -702,17 +715,6 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
        return -1;
 }
 
-/** Return the number of allocated queue pairs (PMD ops callback).
- *
- * @param dev Pointer to the device structure.
- * @returns Number of allocated queue pairs.
- */
-static uint32_t
-mrvl_crypto_pmd_qp_count(struct rte_cryptodev *dev)
-{
-       return dev->data->nb_queue_pairs;
-}
-
 /** Returns the size of the session structure (PMD ops callback).
  *
  * @param dev Pointer to the device structure [Unused].
@@ -727,7 +729,7 @@ mrvl_crypto_pmd_sym_session_get_size(__rte_unused struct rte_cryptodev *dev)
 /** Configure the session from a crypto xform chain (PMD ops callback).
  *
  * @param dev Pointer to the device structure.
- * @param xform Pointer to the crytpo configuration structure.
+ * @param xform Pointer to the crypto configuration structure.
  * @param sess Pointer to the empty session structure.
  * @returns 0 upon success, negative value otherwise.
  */
@@ -751,6 +753,8 @@ mrvl_crypto_pmd_sym_session_configure(__rte_unused struct rte_cryptodev *dev,
                return -ENOMEM;
        }
 
+       memset(sess_private_data, 0, sizeof(struct mrvl_crypto_session));
+
        ret = mrvl_crypto_set_session_parameters(sess_private_data, xform);
        if (ret != 0) {
                MRVL_LOG(ERR, "Failed to configure session parameters!");
@@ -769,6 +773,10 @@ mrvl_crypto_pmd_sym_session_configure(__rte_unused struct rte_cryptodev *dev,
                return -EIO;
        }
 
+       /* free the keys memory allocated for session creation */
+       free(mrvl_sess->sam_sess_params.cipher_key);
+       free(mrvl_sess->sam_sess_params.auth_key);
+
        return 0;
 }
 
@@ -796,7 +804,7 @@ mrvl_crypto_pmd_sym_session_clear(struct rte_cryptodev *dev,
                        MRVL_LOG(ERR, "Error while destroying session!");
                }
 
-               memset(sess, 0, sizeof(struct mrvl_crypto_session));
+               memset(mrvl_sess, 0, sizeof(struct mrvl_crypto_session));
                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);
@@ -819,7 +827,6 @@ static struct rte_cryptodev_ops mrvl_crypto_pmd_ops = {
 
                .queue_pair_setup       = mrvl_crypto_pmd_qp_setup,
                .queue_pair_release     = mrvl_crypto_pmd_qp_release,
-               .queue_pair_count       = mrvl_crypto_pmd_qp_count,
 
                .sym_session_get_size   = mrvl_crypto_pmd_sym_session_get_size,
                .sym_session_configure  = mrvl_crypto_pmd_sym_session_configure,
@@ -827,3 +834,177 @@ static struct rte_cryptodev_ops mrvl_crypto_pmd_ops = {
 };
 
 struct rte_cryptodev_ops *rte_mrvl_crypto_pmd_ops = &mrvl_crypto_pmd_ops;
+
+/* IPSEC full offloading */
+
+/** Configure the session from a crypto xform chain (PMD ops callback).
+ *
+ * @param dev Pointer to the device structure.
+ * @param conf Pointer to the security session configuration structure.
+ * @param sess Pointer to the empty session structure.
+ * @param mempool Pointer to memory pool.
+ * @returns 0 upon success, negative value otherwise.
+ */
+static int
+mrvl_crypto_pmd_security_session_create(__rte_unused void *dev,
+                                struct rte_security_session_conf *conf,
+                                struct rte_security_session *sess,
+                                struct rte_mempool *mempool)
+{
+       struct mrvl_crypto_session *mrvl_sess;
+       void *sess_private_data;
+       int ret;
+
+       if (sess == NULL) {
+               MRVL_LOG(ERR, "Invalid session struct.");
+               return -EINVAL;
+       }
+
+       if (rte_mempool_get(mempool, &sess_private_data)) {
+               MRVL_LOG(ERR, "Couldn't get object from session mempool.");
+               return -ENOMEM;
+       }
+
+       switch (conf->protocol) {
+       case RTE_SECURITY_PROTOCOL_IPSEC:
+               mrvl_sess = (struct mrvl_crypto_session *)sess_private_data;
+
+               struct rte_security_ipsec_xform *ipsec_xform = &conf->ipsec;
+               struct rte_crypto_sym_xform *crypto_xform = conf->crypto_xform;
+
+               ret = mrvl_ipsec_set_session_parameters(mrvl_sess,
+                                                       ipsec_xform,
+                                                       crypto_xform);
+               if (ret != 0) {
+                       MRVL_LOG(ERR, "Failed to configure session parameters.");
+
+                       /* Return session to mempool */
+                       rte_mempool_put(mempool, sess_private_data);
+                       return ret;
+               }
+
+               if (mrvl_sess->sam_sess_params.cipher_mode == SAM_CIPHER_GCM) {
+                       /* Nonce is must for all counter modes */
+                       mrvl_sess->sam_sess_params.cipher_iv =
+                               (uint8_t *)&(conf->ipsec.salt);
+               }
+
+               ret = sam_session_create(&mrvl_sess->sam_sess_params,
+                               &mrvl_sess->sam_sess);
+               if (ret < 0) {
+                       MRVL_LOG(ERR, "PMD: failed to create IPSEC session.");
+                       /* Return session to mempool */
+                       rte_mempool_put(mempool, sess_private_data);
+                       return ret;
+               }
+               break;
+       case RTE_SECURITY_PROTOCOL_MACSEC:
+               return -ENOTSUP;
+       default:
+               return -EINVAL;
+       }
+
+       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
+mrvl_crypto_pmd_security_session_destroy(void *dev __rte_unused,
+               struct rte_security_session *sess)
+{
+       void *sess_priv = get_sec_session_private_data(sess);
+
+       /* Zero out the whole structure */
+       if (sess_priv) {
+               struct mrvl_crypto_session *mrvl_sess =
+                       (struct mrvl_crypto_session *)sess_priv;
+               struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
+
+               if (mrvl_sess->sam_sess &&
+                   sam_session_destroy(mrvl_sess->sam_sess) < 0) {
+                       MRVL_LOG(ERR, "Error while destroying session!");
+               }
+
+               rte_free(mrvl_sess->sam_sess_params.cipher_key);
+               rte_free(mrvl_sess->sam_sess_params.auth_key);
+               rte_free(mrvl_sess->sam_sess_params.cipher_iv);
+               memset(sess, 0, sizeof(struct rte_security_session));
+               set_sec_session_private_data(sess, NULL);
+               rte_mempool_put(sess_mp, sess_priv);
+       }
+       return 0;
+}
+
+static const
+struct rte_security_capability mrvl_crypto_pmd_sec_security_cap[] = {
+       { /* IPsec Lookaside Protocol offload ESP Tunnel Egress */
+               .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+               .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+               .ipsec = {
+                       .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+                       .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
+                       .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
+                       .options = { 0 },
+                       .replay_win_sz_max = 128
+               },
+               .crypto_capabilities = mrvl_crypto_pmd_capabilities
+       },
+       { /* IPsec Lookaside Protocol offload ESP Tunnel Ingress */
+               .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+               .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+               .ipsec = {
+                       .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+                       .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
+                       .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+                       .options = { 0 },
+                       .replay_win_sz_max = 128
+               },
+               .crypto_capabilities = mrvl_crypto_pmd_capabilities
+       },
+       { /* IPsec Lookaside Protocol offload ESP Transport Egress */
+               .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+               .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+               .ipsec = {
+                       .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+                       .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
+                       .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
+                       .options = { 0 },
+                       .replay_win_sz_max = 128
+               },
+               .crypto_capabilities = mrvl_crypto_pmd_capabilities
+       },
+       { /* IPsec Lookaside Protocol offload ESP Transport Ingress */
+               .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+               .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+               .ipsec = {
+                       .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+                       .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
+                       .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+                       .options = { 0 },
+                       .replay_win_sz_max = 128
+               },
+               .crypto_capabilities = mrvl_crypto_pmd_capabilities
+       },
+       {
+               .action = RTE_SECURITY_ACTION_TYPE_NONE
+       }
+};
+
+static const struct rte_security_capability *
+mrvl_crypto_pmd_security_capabilities_get(void *device __rte_unused)
+{
+       return mrvl_crypto_pmd_sec_security_cap;
+}
+
+struct rte_security_ops mrvl_sec_security_pmd_ops = {
+       .session_create = mrvl_crypto_pmd_security_session_create,
+       .session_update = NULL,
+       .session_stats_get = NULL,
+       .session_destroy = mrvl_crypto_pmd_security_session_destroy,
+       .set_pkt_metadata = NULL,
+       .capabilities_get = mrvl_crypto_pmd_security_capabilities_get
+};
+
+struct rte_security_ops *rte_mrvl_security_pmd_ops = &mrvl_sec_security_pmd_ops;