From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 68CC9C75A for ; Sat, 30 Jan 2016 14:12:32 +0100 (CET) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga101.jf.intel.com with ESMTP; 30 Jan 2016 05:12:32 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,370,1449561600"; d="scan'208";a="737143108" Received: from dwdohert-dpdk.ir.intel.com ([163.33.213.167]) by orsmga003.jf.intel.com with ESMTP; 30 Jan 2016 05:12:30 -0800 From: Declan Doherty To: dev@dpdk.org Date: Sat, 30 Jan 2016 13:10:57 +0000 Message-Id: <1454159457-6857-1-git-send-email-declan.doherty@intel.com> X-Mailer: git-send-email 2.5.0 Subject: [dpdk-dev] [PATCH] cryptodev: add capabilities discovery mechanism X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Jan 2016 13:12:33 -0000 This patch add a mechanism for discovery of crypto device features and supported crypto operations and algorithms. It also provides a method for a crypto PMD to publish any data range limitations it may have for the operations and algorithms it supports. The parameter feature_flags added to rte_cryptodev struct is used to capture features such as operations supported (symmetric crypto, operation chaining etc) as well parameter such as whether the device is hardware accelerated or uses SIMD instructions. The capabilities parameter allows a PMD to define an array of supported operations with any limitation which that implementation may have. Finally the rte_cryptodev_info struct has been extended to allow retrieval of these parameter using the existing rte_cryptodev_info_get() API. Signed-off-by: Declan Doherty --- drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 19 ++++ drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c | 83 +++++++++++++++++ drivers/crypto/qat/qat_crypto.c | 83 ++++++++++++++++- drivers/crypto/qat/rte_qat_cryptodev.c | 2 + lib/librte_cryptodev/rte_crypto.h | 7 ++ lib/librte_cryptodev/rte_cryptodev.c | 28 ++++++ lib/librte_cryptodev/rte_cryptodev.h | 123 +++++++++++++++++++++++++ lib/librte_cryptodev/rte_cryptodev_version.map | 2 +- 8 files changed, 345 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c index d8ccf05..a759829 100644 --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c @@ -572,6 +572,7 @@ aesni_mb_pmd_dequeue_burst(void *queue_pair, } + static int cryptodev_aesni_mb_uninit(const char *name); static int @@ -622,6 +623,24 @@ cryptodev_aesni_mb_create(const char *name, unsigned socket_id) dev->dequeue_burst = aesni_mb_pmd_dequeue_burst; dev->enqueue_burst = aesni_mb_pmd_enqueue_burst; + dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | + RTE_CRYPTODEV_FF_OPERATION_CHAINING | + RTE_CRYPTODEV_FF_CPU_AESNI; + + switch (vector_mode) { + case RTE_AESNI_MB_SSE: + dev->feature_flags |= RTE_CRYPTODEV_FF_CPU_SSE; + break; + case RTE_AESNI_MB_AVX: + dev->feature_flags |= RTE_CRYPTODEV_FF_CPU_AVX; + break; + case RTE_AESNI_MB_AVX2: + dev->feature_flags |= RTE_CRYPTODEV_FF_CPU_AVX2; + break; + default: + break; + } + /* Set vector instructions mode supported */ internals = dev->data->dev_private; diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c index 96d22f6..368a803 100644 --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c @@ -38,6 +38,87 @@ #include "rte_aesni_mb_pmd_private.h" + +static const struct rte_cryptodev_capabilities aesni_mb_pmd_capabilities[] = { + { /* MD5 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_MD5_HMAC, 64, 16, 12, { 0 } + } + } + }, + { /* SHA1 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_SHA1_HMAC, 20, 64, 12, { 0 } + } + } + }, + { /* SHA224 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_SHA224_HMAC, 28, 64, 14, { 0 } + } + } + }, + { /* SHA256 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_SHA256_HMAC, 32, 64, 16, { 0 } + } + } + }, + { /* SHA384 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_SHA384_HMAC, 48, 128, 24, { 0 } + } + } + }, + { /* SHA512 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_SHA512_HMAC, 64, 128, 32, { 0 } + } + } + }, + { /* AES XCBC HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_AES_XCBC_MAC, 16, 16, 12, + .aad = { 0 } + } + } + }, + { /* AES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_CIPHER, + .cipher = { + RTE_CRYPTO_CIPHER_AES_CBC, + .key = { 16, 16, 0 }, + .iv = { 16, 16, 0 } + } + } + }, + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() +}; + + /** Configure device */ static int aesni_mb_pmd_config(__rte_unused struct rte_cryptodev *dev) @@ -107,6 +188,8 @@ aesni_mb_pmd_info_get(struct rte_cryptodev *dev, if (dev_info != NULL) { dev_info->dev_type = dev->dev_type; + dev_info->feature_flags = dev->feature_flags; + dev_info->capabilities = aesni_mb_pmd_capabilities; dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs; dev_info->max_nb_sessions = internals->max_nb_sessions; } diff --git a/drivers/crypto/qat/qat_crypto.c b/drivers/crypto/qat/qat_crypto.c index 47b257f..dce055f 100644 --- a/drivers/crypto/qat/qat_crypto.c +++ b/drivers/crypto/qat/qat_crypto.c @@ -68,6 +68,86 @@ #include "adf_transport_access_macros.h" +static const struct rte_cryptodev_capabilities qat_pmd_capabilities[] = { + { /* MD5 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_MD5_HMAC, 64, 16, 16, { 0 } + } + } + }, + { /* SHA1 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_SHA1_HMAC, 64, 20, 20, { 0 } + } + } + }, + { /* SHA256 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_SHA256_HMAC, 64, 32, 32, { 0 } + } + } + }, + { /* SHA384 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_SHA384_HMAC, 128, 48, 48, { 0 } + } + } + }, + { /* SHA512 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_SHA512_HMAC, 128, 64, 64, { 0 } + } + } + }, + { /* AES XCBC HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_AUTH, + .auth = { + RTE_CRYPTO_AUTH_AES_XCBC_MAC, 16, 16, 16, { 0 } + } + } + }, + { /* AES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_CIPHER, + .cipher = { + RTE_CRYPTO_CIPHER_AES_CBC, + .key = { 16, 16, 0 }, + .iv = { 16, 16, 0 } + } + } + }, + { /* AES CTR */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .type = RTE_CRYPTO_XFORM_CIPHER, + .cipher = { + RTE_CRYPTO_CIPHER_AES_CTR, + .key = { 16, 16, 0 }, + .iv = { 16, 16, 0 } + } + } + }, + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() +}; + static inline uint32_t adf_modulo(uint32_t data, uint32_t shift); @@ -519,7 +599,8 @@ void qat_dev_info_get(__rte_unused struct rte_cryptodev *dev, info->max_nb_queue_pairs = ADF_NUM_SYM_QPS_PER_BUNDLE * ADF_NUM_BUNDLES_PER_DEV; - + info->feature_flags = dev->feature_flags; + info->capabilities = qat_pmd_capabilities; info->max_nb_sessions = internals->max_nb_sessions; info->dev_type = RTE_CRYPTODEV_QAT_PMD; } diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c index e500c1e..169ef24 100644 --- a/drivers/crypto/qat/rte_qat_cryptodev.c +++ b/drivers/crypto/qat/rte_qat_cryptodev.c @@ -95,6 +95,8 @@ crypto_qat_dev_init(__attribute__((unused)) struct rte_cryptodev_driver *crypto_ cryptodev->enqueue_burst = qat_crypto_pkt_tx_burst; cryptodev->dequeue_burst = qat_crypto_pkt_rx_burst; + cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | + RTE_CRYPTODEV_FF_HW_ACCELERATED; internals = cryptodev->data->dev_private; internals->max_nb_sessions = RTE_QAT_PMD_MAX_NB_SESSIONS; diff --git a/lib/librte_cryptodev/rte_crypto.h b/lib/librte_cryptodev/rte_crypto.h index 42343a8..3e39693 100644 --- a/lib/librte_cryptodev/rte_crypto.h +++ b/lib/librte_cryptodev/rte_crypto.h @@ -581,6 +581,13 @@ struct rte_crypto_op { }; +enum rte_crypto_op_type { + RTE_CRYPTO_OP_TYPE_UNDEFINED = 0, + + RTE_CRYPTO_OP_TYPE_SYMMETRIC +}; + + /** * Reset the fields of a crypto operation to their default values. * diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c index f09f67e..f8fd992 100644 --- a/lib/librte_cryptodev/rte_cryptodev.c +++ b/lib/librte_cryptodev/rte_cryptodev.c @@ -102,6 +102,34 @@ struct rte_cryptodev_callback { uint32_t active; /**< Callback is executing */ }; + +const char * +rte_cryptodev_get_feature_name(uint64_t flag) +{ + switch (flag) { + case RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO: + return "SYMMETRIC_CRYPTO"; + case RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO: + return "ASYMMETRIC_CRYPTO"; + case RTE_CRYPTODEV_FF_OPERATION_CHAINING: + return "OPERATION_CHAINING"; + case RTE_CRYPTODEV_FF_CPU_SSE: + return "CPU_SSE"; + case RTE_CRYPTODEV_FF_CPU_AVX: + return "CPU_AVX"; + case RTE_CRYPTODEV_FF_CPU_AVX2: + return "CPU_AVX2"; + case RTE_CRYPTODEV_FF_CPU_AESNI: + return "CPU_AESNI"; + case RTE_CRYPTODEV_FF_HW_ACCELERATED: + return "HW_ACCELERATED"; + + default: + return NULL; + } +} + + int rte_cryptodev_create_vdev(const char *name, const char *args) { diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h index 892375d..61a162b 100644 --- a/lib/librte_cryptodev/rte_cryptodev.h +++ b/lib/librte_cryptodev/rte_cryptodev.h @@ -91,12 +91,131 @@ enum rte_cryptodev_type { #define CDEV_PMD_TRACE(fmt, args...) #endif + +/** + * Symmetric Crypto Capability + */ +struct rte_cryptodev_symmetric_capability { + enum rte_crypto_xform_type type; + /**< Transform type : Authentication / Cipher */ + + union { + struct { + enum rte_crypto_auth_algorithm algo; + /**< authentication algorithm */ + uint16_t block; + /**< algorithm block size */ + uint16_t key; + /**< Key size supported */ + uint16_t digest; + /**< Maximum digest size supported */ + struct { + uint16_t min; /**< minimum aad size */ + uint16_t max; /**< maximum aad size */ + uint16_t increment; + /**< if a range of sizes are supported, + * this parameter is used to indicate + * increments in byte size that are supported + * between the minimum and maximum */ + } aad; + /**< Additional authentication data size range */ + } auth; + /**< Symmetric Authentication transform capabilities */ + struct { + enum rte_crypto_cipher_algorithm algo; + /**< cipher algorithm */ + uint16_t block_size; + /**< algorithm block size */ + struct { + uint16_t min; /**< minimum key size */ + uint16_t max; /**< maximum key size */ + uint16_t increment; + /**< if a range of sizes are supported, + * this parameter is used to indicate + * increments in byte size that are supported + * between the minimum and maximum */ + } key; + /**< cipher key size range */ + struct { + uint16_t min; /**< minimum iv size */ + uint16_t max; /**< maximum iv size */ + uint16_t increment; + /**< if a range of sizes are supported, + * this parameter is used to indicate + * increments in byte size that are supported + * between the minimum and maximum */ + } iv; + /**< Initialisation vector data size range */ + } cipher; + /**< Symmetric Cipher transform capabilities */ + }; +}; + +/** Structure used to capture a capability of a crypto device */ +struct rte_cryptodev_capabilities { + enum rte_crypto_op_type op; + /**< Operation type */ + + union { + struct rte_cryptodev_symmetric_capability sym; + /**< Symmetric operation capability parameters */ + }; +}; + +/** Macro used at end of crypto PMD list */ +#define RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() \ + { RTE_CRYPTO_OP_TYPE_UNDEFINED } + + +/** + * Crypto device supported feature flags + * + * Note: + * New features flags should be added to the end of the list + * + * Keep these flags synchronised with rte_cryptodev_get_feature_name() + */ +#define RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO (1ULL << 0) +/**< Symmetric crypto operations are supported */ +#define RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO (1ULL << 1) +/**< Asymmetric crypto operations are supported */ +#define RTE_CRYPTODEV_FF_OPERATION_CHAINING (1ULL << 2) +/**< Chaining crypto operations are supported */ +#define RTE_CRYPTODEV_FF_CPU_SSE (1ULL << 3) +/**< Utilises CPU SIMD SSE instructions */ +#define RTE_CRYPTODEV_FF_CPU_AVX (1ULL << 4) +/**< Utilises CPU SIMD AVX instructions */ +#define RTE_CRYPTODEV_FF_CPU_AVX2 (1ULL << 5) +/**< Utilises CPU SIMD AVX2 instructions */ +#define RTE_CRYPTODEV_FF_CPU_AESNI (1ULL << 6) +/**< Utilises CPU AES-NI instructions */ +#define RTE_CRYPTODEV_FF_HW_ACCELERATED (1ULL << 7) +/**< Operations are off-loaded to an external hardware accelerator */ + + +/** + * Get the name of a crypto device feature flag + * + * @param mask The mask describing the flag. + * + * @return + * The name of this flag, or NULL if it's not a valid feature flag. + */ + +extern const char * +rte_cryptodev_get_feature_name(uint64_t flag); + /** Crypto device information */ struct rte_cryptodev_info { const char *driver_name; /**< Driver name. */ enum rte_cryptodev_type dev_type; /**< Device type */ struct rte_pci_device *pci_dev; /**< PCI information. */ + uint64_t feature_flags; /**< Feature flags */ + + const struct rte_cryptodev_capabilities *capabilities; + /**< Array of devices supported capabilities */ + unsigned max_nb_queue_pairs; /**< Maximum number of queues pairs supported by device. */ unsigned max_nb_sessions; @@ -449,6 +568,8 @@ typedef uint16_t (*enqueue_pkt_burst_t)(void *qp, struct rte_mbuf **pkts, /**< Enqueue packets for processing on queue pair of a device. */ + + struct rte_cryptodev_callback; /** Structure to keep track of registered callbacks */ @@ -467,6 +588,8 @@ struct rte_cryptodev { /**< Pointer to device data */ struct rte_cryptodev_ops *dev_ops; /**< Functions exported by PMD */ + uint64_t feature_flags; + /**< Supported features */ struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */ diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map index ff8e93d..9cd12cf 100644 --- a/lib/librte_cryptodev/rte_cryptodev_version.map +++ b/lib/librte_cryptodev/rte_cryptodev_version.map @@ -10,6 +10,7 @@ DPDK_2.2 { rte_cryptodev_configure; rte_cryptodev_create_vdev; rte_cryptodev_get_dev_id; + rte_cryptodev_get_feature_name; rte_cryptodev_info_get; rte_cryptodev_pmd_allocate; rte_cryptodev_pmd_callback_process; @@ -27,6 +28,5 @@ DPDK_2.2 { rte_cryptodev_queue_pair_setup; rte_cryptodev_queue_pair_start; rte_cryptodev_queue_pair_stop; - local: *; }; \ No newline at end of file -- 2.5.0