get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/100008/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 100008,
    "url": "http://patches.dpdk.org/api/patches/100008/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20210929163035.608387-2-ciara.power@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20210929163035.608387-2-ciara.power@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210929163035.608387-2-ciara.power@intel.com",
    "date": "2021-09-29T16:30:26",
    "name": "[v3,01/10] drivers/crypto: introduce IPsec-mb framework",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "102375cdb4b068dffaebc0ae83e899d53e7dade1",
    "submitter": {
        "id": 978,
        "url": "http://patches.dpdk.org/api/people/978/?format=api",
        "name": "Power, Ciara",
        "email": "ciara.power@intel.com"
    },
    "delegate": {
        "id": 6690,
        "url": "http://patches.dpdk.org/api/users/6690/?format=api",
        "username": "akhil",
        "first_name": "akhil",
        "last_name": "goyal",
        "email": "gakhil@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20210929163035.608387-2-ciara.power@intel.com/mbox/",
    "series": [
        {
            "id": 19269,
            "url": "http://patches.dpdk.org/api/series/19269/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=19269",
            "date": "2021-09-29T16:30:25",
            "name": "drivers/crypto: introduce ipsec_mb framework",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/19269/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/100008/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/100008/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 1170AA0547;\n\tWed, 29 Sep 2021 18:30:47 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id BFA2F410F1;\n\tWed, 29 Sep 2021 18:30:44 +0200 (CEST)",
            "from mga06.intel.com (mga06.intel.com [134.134.136.31])\n by mails.dpdk.org (Postfix) with ESMTP id 2D234410ED\n for <dev@dpdk.org>; Wed, 29 Sep 2021 18:30:42 +0200 (CEST)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 29 Sep 2021 09:30:41 -0700",
            "from silpixa00400355.ir.intel.com (HELO\n silpixa00400355.ger.corp.intel.com) ([10.237.222.87])\n by orsmga002.jf.intel.com with ESMTP; 29 Sep 2021 09:30:39 -0700"
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6200,9189,10122\"; a=\"285997932\"",
            "E=Sophos;i=\"5.85,332,1624345200\"; d=\"scan'208\";a=\"285997932\"",
            "E=Sophos;i=\"5.85,332,1624345200\"; d=\"scan'208\";a=\"457092726\""
        ],
        "X-ExtLoop1": "1",
        "From": "Ciara Power <ciara.power@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "roy.fan.zhang@intel.com, piotrx.bronowski@intel.com, gakhil@marvell.com,\n Ciara Power <ciara.power@intel.com>, Thomas Monjalon <thomas@monjalon.net>,\n Pablo de Lara <pablo.de.lara.guarch@intel.com>,\n Ray Kinsella <mdr@ashroe.eu>",
        "Date": "Wed, 29 Sep 2021 16:30:26 +0000",
        "Message-Id": "<20210929163035.608387-2-ciara.power@intel.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20210929163035.608387-1-ciara.power@intel.com>",
        "References": "<20210727083832.291687-1-roy.fan.zhang@intel.com>\n <20210929163035.608387-1-ciara.power@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v3 01/10] drivers/crypto: introduce IPsec-mb\n framework",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Fan Zhang <roy.fan.zhang@intel.com>\n\nThis patch introduces the new framework to share common code between\nthe SW crypto PMDs that depend on the intel-ipsec-mb library.\nThis change helps to reduce future effort on the code maintenance and\nfeature updates.\n\nThe PMDs that will be added to this framework in subsequent patches are:\n  - AESNI MB\n  - AESNI GCM\n  - KASUMI\n  - SNOW3G\n  - ZUC\n\nThe use of these PMDs will not change, they will still be supported for\nx86, and will use the same EAL args as before.\n\nThe minimum required version for the intel-ipsec-mb library is now v1.0.\n\nSigned-off-by: Fan Zhang <roy.fan.zhang@intel.com>\nSigned-off-by: Ciara Power <ciara.power@intel.com>\n\n---\nv3:\n  - Updated intel-ipsec-mb macros.\n  - Added use of auto init function for IMB_MGR.\n  - Added detail to commit log.\nv2:\n  - Added qp NULL check in get stats function.\n  - Added maintainers file entry.\n  - Replaced strlcpy with rte_strlcpy.\n---\n MAINTAINERS                                   |   4 +\n drivers/crypto/ipsec_mb/meson.build           |  27 ++\n drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd.c    | 169 ++++++++++\n .../crypto/ipsec_mb/rte_ipsec_mb_pmd_ops.c    | 291 ++++++++++++++++++\n .../ipsec_mb/rte_ipsec_mb_pmd_private.h       | 275 +++++++++++++++++\n drivers/crypto/ipsec_mb/version.map           |   3 +\n drivers/crypto/meson.build                    |   1 +\n 7 files changed, 770 insertions(+)\n create mode 100644 drivers/crypto/ipsec_mb/meson.build\n create mode 100644 drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd.c\n create mode 100644 drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd_ops.c\n create mode 100644 drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd_private.h\n create mode 100644 drivers/crypto/ipsec_mb/version.map",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 1e0d303394..f1aaf7d408 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -1065,6 +1065,10 @@ F: drivers/common/qat/\n F: doc/guides/cryptodevs/qat.rst\n F: doc/guides/cryptodevs/features/qat.ini\n \n+IPsec MB\n+M: Fan Zhang <roy.fan.zhang@intel.com>\n+F: drivers/crypto/ipsec_mb/\n+\n KASUMI\n M: Pablo de Lara <pablo.de.lara.guarch@intel.com>\n F: drivers/crypto/kasumi/\ndiff --git a/drivers/crypto/ipsec_mb/meson.build b/drivers/crypto/ipsec_mb/meson.build\nnew file mode 100644\nindex 0000000000..3d48da60ed\n--- /dev/null\n+++ b/drivers/crypto/ipsec_mb/meson.build\n@@ -0,0 +1,27 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2018 - 2021 Intel Corporation\n+\n+IMB_required_ver = '1.0.0'\n+lib = cc.find_library('IPSec_MB', required: false)\n+if not lib.found()\n+\tbuild = false\n+\treason = 'missing dependency, \"libIPSec_MB\"'\n+else\n+\text_deps += lib\n+\n+\t# version comes with quotes, so we split based on \" and take the middle\n+\timb_ver = cc.get_define('IMB_VERSION_STR',\n+\t\tprefix : '#include<intel-ipsec-mb.h>').split('\"')[1]\n+\n+\tif (imb_ver == '') or (imb_ver.version_compare('<' + IMB_required_ver))\n+\t\treason = 'IPSec_MB version >= @0@ is required, found version @1@'.format(\n+\t\t\t\tIMB_required_ver, imb_ver)\n+\t\tbuild = false\n+\tendif\n+\n+endif\n+\n+sources = files('rte_ipsec_mb_pmd.c',\n+\t\t'rte_ipsec_mb_pmd_ops.c',\n+\t\t)\n+deps += ['bus_vdev', 'net', 'security']\ndiff --git a/drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd.c b/drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd.c\nnew file mode 100644\nindex 0000000000..3f2cefed52\n--- /dev/null\n+++ b/drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd.c\n@@ -0,0 +1,169 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2015-2021 Intel Corporation\n+ */\n+\n+#include <rte_bus_vdev.h>\n+#include <rte_common.h>\n+#include <rte_cryptodev.h>\n+\n+#include \"rte_ipsec_mb_pmd_private.h\"\n+\n+RTE_DEFINE_PER_LCORE(IMB_MGR *, mb_mgr);\n+\n+struct ipsec_mb_pmd_data ipsec_mb_pmds[IPSEC_MB_N_PMD_TYPES];\n+int ipsec_mb_logtype_driver;\n+enum ipsec_mb_vector_mode vector_mode;\n+\n+/**\n+ * Generic burst enqueue, place crypto operations on ingress queue for\n+ * processing.\n+ *\n+ * @param __qp         Queue Pair to process\n+ * @param ops          Crypto operations for processing\n+ * @param nb_ops       Number of crypto operations for processing\n+ *\n+ * @return\n+ * - Number of crypto operations enqueued\n+ */\n+static uint16_t\n+ipsec_mb_pmd_enqueue_burst(void *__qp, struct rte_crypto_op **ops,\n+\t\tuint16_t nb_ops)\n+{\n+\tstruct ipsec_mb_qp *qp = __qp;\n+\n+\tunsigned int nb_enqueued;\n+\n+\tnb_enqueued = rte_ring_enqueue_burst(qp->ingress_queue,\n+\t\t\t(void **)ops, nb_ops, NULL);\n+\n+\tqp->stats.enqueued_count += nb_enqueued;\n+\tqp->stats.enqueue_err_count += nb_ops - nb_enqueued;\n+\n+\treturn nb_enqueued;\n+}\n+\n+int\n+cryptodev_ipsec_mb_create(struct rte_vdev_device *vdev,\n+\tenum ipsec_mb_pmd_types pmd_type)\n+{\n+\tstruct rte_cryptodev *dev;\n+\tstruct ipsec_mb_private *internals;\n+\tstruct ipsec_mb_pmd_data *pmd_data = &ipsec_mb_pmds[pmd_type];\n+\tstruct rte_cryptodev_pmd_init_params init_params = {};\n+\tconst char *name, *args;\n+\tint retval;\n+\n+\tif (vector_mode == IPSEC_MB_NOT_SUPPORTED) {\n+\t\t/* Check CPU for supported vector instruction set */\n+\t\tif (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F))\n+\t\t\tvector_mode = IPSEC_MB_AVX512;\n+\t\telse if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2))\n+\t\t\tvector_mode = IPSEC_MB_AVX2;\n+\t\telse if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX))\n+\t\t\tvector_mode = IPSEC_MB_AVX;\n+\t\telse\n+\t\t\tvector_mode = IPSEC_MB_SSE;\n+\t}\n+\n+\tinit_params.private_data_size = sizeof(struct ipsec_mb_private) +\n+\t\tpmd_data->internals_priv_size;\n+\tinit_params.max_nb_queue_pairs =\n+\t\tRTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS;\n+\tinit_params.socket_id = rte_socket_id();\n+\n+\tname = rte_vdev_device_name(vdev);\n+\tif (name == NULL)\n+\t\treturn -EINVAL;\n+\n+\targs = rte_vdev_device_args(vdev);\n+\n+\tretval = rte_cryptodev_pmd_parse_input_args(&init_params, args);\n+\tif (retval) {\n+\t\tIPSEC_MB_LOG(\n+\t\t    ERR, \"Failed to parse initialisation arguments[%s]\", args);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tdev = rte_cryptodev_pmd_create(name, &vdev->device, &init_params);\n+\tif (dev == NULL) {\n+\t\tIPSEC_MB_LOG(ERR, \"driver %s: create failed\",\n+\t\t\t     init_params.name);\n+\t\treturn -ENODEV;\n+\t}\n+\n+\t/* Set vector instructions mode supported */\n+\tinternals = dev->data->dev_private;\n+\tinternals->pmd_type = pmd_type;\n+\tinternals->max_nb_queue_pairs = init_params.max_nb_queue_pairs;\n+\n+\tdev->driver_id = ipsec_mb_get_driver_id(pmd_type);\n+\tif (dev->driver_id == UINT8_MAX) {\n+\t\tIPSEC_MB_LOG(ERR, \"driver %s: create failed\",\n+\t\t\t     init_params.name);\n+\t\treturn -ENODEV;\n+\t}\n+\tdev->dev_ops = ipsec_mb_pmds[pmd_type].ops;\n+\tdev->enqueue_burst = ipsec_mb_pmd_enqueue_burst;\n+\tdev->dequeue_burst = ipsec_mb_pmds[pmd_type].dequeue_burst;\n+\n+\tif (pmd_data->dev_config) {\n+\t\tretval = (*pmd_data->dev_config)(dev);\n+\t\tif (retval < 0) {\n+\t\t\tIPSEC_MB_LOG(ERR,\n+\t\t\t\t\"Failed to configure device %s\", name);\n+\t\t\trte_cryptodev_pmd_destroy(dev);\n+\t\t\treturn retval;\n+\t\t}\n+\t}\n+\n+\tdev->feature_flags = pmd_data->feature_flags;\n+\n+\tswitch (vector_mode) {\n+\tcase IPSEC_MB_AVX512:\n+\t\tdev->feature_flags |= RTE_CRYPTODEV_FF_CPU_AVX512;\n+\t\tbreak;\n+\tcase IPSEC_MB_AVX2:\n+\t\tdev->feature_flags |= RTE_CRYPTODEV_FF_CPU_AVX2;\n+\t\tbreak;\n+\tcase IPSEC_MB_AVX:\n+\t\tdev->feature_flags |= RTE_CRYPTODEV_FF_CPU_AVX;\n+\t\tbreak;\n+\tcase IPSEC_MB_SSE:\n+\t\tdev->feature_flags |= RTE_CRYPTODEV_FF_CPU_SSE;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\tIPSEC_MB_LOG(INFO, \"IPSec Multi-buffer library version used: %s\\n\",\n+\t\t     imb_get_version_str());\n+\n+\treturn 0;\n+}\n+\n+int\n+cryptodev_ipsec_mb_remove(struct rte_vdev_device *vdev)\n+{\n+\tstruct rte_cryptodev *cryptodev;\n+\tconst char *name;\n+\n+\tname = rte_vdev_device_name(vdev);\n+\tif (name == NULL)\n+\t\treturn -EINVAL;\n+\n+\tcryptodev = rte_cryptodev_pmd_get_named_dev(name);\n+\tif (cryptodev == NULL)\n+\t\treturn -ENODEV;\n+\n+\tif (RTE_PER_LCORE(mb_mgr)) {\n+\t\tfree_mb_mgr(RTE_PER_LCORE(mb_mgr));\n+\t\tRTE_PER_LCORE(mb_mgr) = NULL;\n+\t}\n+\n+\tif (cryptodev->security_ctx) {\n+\t\trte_free(cryptodev->security_ctx);\n+\t\tcryptodev->security_ctx = NULL;\n+\t}\n+\n+\treturn rte_cryptodev_pmd_destroy(cryptodev);\n+}\ndiff --git a/drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd_ops.c b/drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd_ops.c\nnew file mode 100644\nindex 0000000000..1146297216\n--- /dev/null\n+++ b/drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd_ops.c\n@@ -0,0 +1,291 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2015-2021 Intel Corporation\n+ */\n+\n+#include <string.h>\n+\n+#include <rte_common.h>\n+#include <rte_malloc.h>\n+\n+#include \"rte_ipsec_mb_pmd_private.h\"\n+\n+/** Configure device */\n+int\n+ipsec_mb_pmd_config(__rte_unused struct rte_cryptodev *dev,\n+\t\t    __rte_unused struct rte_cryptodev_config *config)\n+{\n+\treturn 0;\n+}\n+\n+/** Start device */\n+int\n+ipsec_mb_pmd_start(__rte_unused struct rte_cryptodev *dev)\n+{\n+\treturn 0;\n+}\n+\n+/** Stop device */\n+void\n+ipsec_mb_pmd_stop(__rte_unused struct rte_cryptodev *dev)\n+{\n+}\n+\n+/** Close device */\n+int\n+ipsec_mb_pmd_close(__rte_unused struct rte_cryptodev *dev)\n+{\n+\treturn 0;\n+}\n+\n+/** Get device statistics */\n+void\n+ipsec_mb_pmd_stats_get(struct rte_cryptodev *dev,\n+\t\tstruct rte_cryptodev_stats *stats)\n+{\n+\tint qp_id;\n+\n+\tfor (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {\n+\t\tstruct ipsec_mb_qp *qp = dev->data->queue_pairs[qp_id];\n+\t\tif (qp == NULL) {\n+\t\t\tIPSEC_MB_LOG(DEBUG, \"Uninitialised qp %d\", qp_id);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tstats->enqueued_count += qp->stats.enqueued_count;\n+\t\tstats->dequeued_count += qp->stats.dequeued_count;\n+\n+\t\tstats->enqueue_err_count += qp->stats.enqueue_err_count;\n+\t\tstats->dequeue_err_count += qp->stats.dequeue_err_count;\n+\t}\n+}\n+\n+/** Reset device statistics */\n+void\n+ipsec_mb_pmd_stats_reset(struct rte_cryptodev *dev)\n+{\n+\tint qp_id;\n+\n+\tfor (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {\n+\t\tstruct ipsec_mb_qp *qp = dev->data->queue_pairs[qp_id];\n+\n+\t\tmemset(&qp->stats, 0, sizeof(qp->stats));\n+\t}\n+}\n+\n+/** Get device info */\n+void\n+ipsec_mb_pmd_info_get(struct rte_cryptodev *dev,\n+\t\tstruct rte_cryptodev_info *dev_info)\n+{\n+\tstruct ipsec_mb_private *internals = dev->data->dev_private;\n+\tstruct ipsec_mb_pmd_data *pmd_info =\n+\t\t&ipsec_mb_pmds[internals->pmd_type];\n+\n+\tif (dev_info != NULL) {\n+\t\tdev_info->driver_id = dev->driver_id;\n+\t\tdev_info->feature_flags = dev->feature_flags;\n+\t\tdev_info->capabilities = pmd_info->caps;\n+\t\tdev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;\n+\t\t/* No limit of number of sessions */\n+\t\tdev_info->sym.max_nb_sessions = 0;\n+\t}\n+}\n+\n+/** Release queue pair */\n+int\n+ipsec_mb_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)\n+{\n+\tstruct ipsec_mb_qp *qp = dev->data->queue_pairs[qp_id];\n+\tstruct rte_ring *r = NULL;\n+\n+\tif (qp != NULL) {\n+\t\tr = rte_ring_lookup(qp->name);\n+\t\tif (r)\n+\t\t\trte_ring_free(r);\n+\t\trte_free(qp);\n+\t\tdev->data->queue_pairs[qp_id] = NULL;\n+\t}\n+\treturn 0;\n+}\n+\n+/** Set a unique name for the queue pair */\n+int\n+ipsec_mb_pmd_qp_set_unique_name(struct rte_cryptodev *dev,\n+\t\t\t\t\t   struct ipsec_mb_qp *qp)\n+{\n+\tuint32_t n =\n+\t    snprintf(qp->name, sizeof(qp->name), \"ipsec_mb_pmd_%u_qp_%u\",\n+\t\t     dev->data->dev_id, qp->id);\n+\n+\tif (n >= sizeof(qp->name))\n+\t\treturn -1;\n+\n+\treturn 0;\n+}\n+\n+/** Create a ring to place processed operations on */\n+static struct rte_ring\n+*ipsec_mb_pmd_qp_create_processed_ops_ring(\n+\tstruct ipsec_mb_qp *qp, unsigned int ring_size, int socket_id)\n+{\n+\tstruct rte_ring *r;\n+\tchar ring_name[RTE_CRYPTODEV_NAME_MAX_LEN];\n+\n+\tunsigned int n = rte_strlcpy(ring_name, qp->name, sizeof(ring_name));\n+\n+\tif (n >= sizeof(ring_name))\n+\t\treturn NULL;\n+\n+\tr = rte_ring_lookup(ring_name);\n+\tif (r) {\n+\t\tif (rte_ring_get_size(r) >= ring_size) {\n+\t\t\tIPSEC_MB_LOG(\n+\t\t\t    INFO, \"Reusing existing ring %s for processed ops\",\n+\t\t\t    ring_name);\n+\t\t\treturn r;\n+\t\t}\n+\t\tIPSEC_MB_LOG(\n+\t\t    ERR, \"Unable to reuse existing ring %s for processed ops\",\n+\t\t    ring_name);\n+\t\treturn NULL;\n+\t}\n+\n+\treturn rte_ring_create(ring_name, ring_size, socket_id,\n+\t\t\t       RING_F_SP_ENQ | RING_F_SC_DEQ);\n+}\n+\n+/** Setup a queue pair */\n+int\n+ipsec_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,\n+\t\t\t\tconst struct rte_cryptodev_qp_conf *qp_conf,\n+\t\t\t\tint socket_id)\n+{\n+\tstruct ipsec_mb_qp *qp = NULL;\n+\tstruct ipsec_mb_private *internals = dev->data->dev_private;\n+\tstruct ipsec_mb_pmd_data *pmd_data =\n+\t\t&ipsec_mb_pmds[internals->pmd_type];\n+\tuint32_t qp_size;\n+\tint ret = -1;\n+\n+\t/* Free memory prior to re-allocation if needed. */\n+\tif (dev->data->queue_pairs[qp_id] != NULL)\n+\t\tipsec_mb_pmd_qp_release(dev, qp_id);\n+\n+\tqp_size = sizeof(*qp) + pmd_data->qp_priv_size;\n+\t/* Allocate the queue pair data structure. */\n+\tqp = rte_zmalloc_socket(\"IPSEC PMD Queue Pair\", qp_size,\n+\t\t\t\tRTE_CACHE_LINE_SIZE, socket_id);\n+\tif (qp == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tqp->id = qp_id;\n+\tdev->data->queue_pairs[qp_id] = qp;\n+\tif (ipsec_mb_pmd_qp_set_unique_name(dev, qp))\n+\t\tgoto qp_setup_cleanup;\n+\n+\tqp->pmd_type = internals->pmd_type;\n+\tqp->sess_mp = qp_conf->mp_session;\n+\tqp->sess_mp_priv = qp_conf->mp_session_private;\n+\n+\tqp->ingress_queue = ipsec_mb_pmd_qp_create_processed_ops_ring(qp,\n+\t\tqp_conf->nb_descriptors, socket_id);\n+\tif (qp->ingress_queue == NULL) {\n+\t\tret = -1;\n+\t\tgoto qp_setup_cleanup;\n+\t}\n+\n+\tqp->mb_mgr = alloc_init_mb_mgr();\n+\tif (!qp->mb_mgr) {\n+\t\tret = -ENOMEM;\n+\t\tgoto qp_setup_cleanup;\n+\t}\n+\n+\tmemset(&qp->stats, 0, sizeof(qp->stats));\n+\n+\tif (pmd_data->queue_pair_configure) {\n+\t\tret = pmd_data->queue_pair_configure(qp);\n+\t\tif (ret < 0)\n+\t\t\tgoto qp_setup_cleanup;\n+\t}\n+\n+\treturn 0;\n+\n+qp_setup_cleanup:\n+\tif (qp->mb_mgr)\n+\t\tfree_mb_mgr(qp->mb_mgr);\n+\tif (qp)\n+\t\trte_free(qp);\n+\treturn ret;\n+}\n+\n+/** Return the size of the specific pmd session structure */\n+unsigned\n+ipsec_mb_pmd_sym_session_get_size(struct rte_cryptodev *dev)\n+{\n+\tstruct ipsec_mb_private *internals = dev->data->dev_private;\n+\tstruct ipsec_mb_pmd_data *pmd_data =\n+\t\t&ipsec_mb_pmds[internals->pmd_type];\n+\n+\treturn pmd_data->session_priv_size;\n+}\n+\n+/** Configure pmd specific multi-buffer session from a crypto xform chain */\n+int\n+ipsec_mb_pmd_sym_session_configure(\n+\tstruct rte_cryptodev *dev, struct rte_crypto_sym_xform *xform,\n+\tstruct rte_cryptodev_sym_session *sess, struct rte_mempool *mempool)\n+{\n+\tvoid *sess_private_data;\n+\tstruct ipsec_mb_private *internals = dev->data->dev_private;\n+\tstruct ipsec_mb_pmd_data *pmd_data =\n+\t\t&ipsec_mb_pmds[internals->pmd_type];\n+\tIMB_MGR *mb_mgr = alloc_init_mb_mgr();\n+\tint ret = 0;\n+\n+\tif (!mb_mgr)\n+\t\treturn -ENOMEM;\n+\n+\tif (unlikely(sess == NULL)) {\n+\t\tIPSEC_MB_LOG(ERR, \"invalid session struct\");\n+\t\tfree_mb_mgr(mb_mgr);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (rte_mempool_get(mempool, &sess_private_data)) {\n+\t\tIPSEC_MB_LOG(ERR, \"Couldn't get object from session mempool\");\n+\t\tfree_mb_mgr(mb_mgr);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tret = (*pmd_data->session_configure)(mb_mgr, sess_private_data, xform);\n+\tif (ret != 0) {\n+\t\tIPSEC_MB_LOG(ERR, \"failed configure session parameters\");\n+\n+\t\t/* Return session to mempool */\n+\t\trte_mempool_put(mempool, sess_private_data);\n+\t\tfree_mb_mgr(mb_mgr);\n+\t\treturn ret;\n+\t}\n+\n+\tset_sym_session_private_data(sess, dev->driver_id, sess_private_data);\n+\n+\treturn 0;\n+}\n+\n+/** Clear the session memory */\n+void\n+ipsec_mb_pmd_sym_session_clear(struct rte_cryptodev *dev,\n+\t\t\t       struct rte_cryptodev_sym_session *sess)\n+{\n+\tuint8_t index = dev->driver_id;\n+\tvoid *sess_priv = get_sym_session_private_data(sess, index);\n+\n+\t/* Zero out the whole structure */\n+\tif (sess_priv) {\n+\t\tmemset(sess_priv, 0, ipsec_mb_pmd_sym_session_get_size(dev));\n+\t\tstruct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);\n+\n+\t\tset_sym_session_private_data(sess, index, NULL);\n+\t\trte_mempool_put(sess_mp, sess_priv);\n+\t}\n+}\ndiff --git a/drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd_private.h b/drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd_private.h\nnew file mode 100644\nindex 0000000000..754259aa59\n--- /dev/null\n+++ b/drivers/crypto/ipsec_mb/rte_ipsec_mb_pmd_private.h\n@@ -0,0 +1,275 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2015-2021 Intel Corporation\n+ */\n+\n+#ifndef _IPSEC_MB_PMD_PRIVATE_H_\n+#define _IPSEC_MB_PMD_PRIVATE_H_\n+\n+#include <intel-ipsec-mb.h>\n+#include <cryptodev_pmd.h>\n+#include <rte_bus_vdev.h>\n+\n+#if defined(RTE_LIB_SECURITY)\n+#define IPSEC_MB_DOCSIS_SEC_ENABLED 1\n+#include <rte_security.h>\n+#include <rte_security_driver.h>\n+#endif\n+\n+/* Maximum length for digest */\n+#define DIGEST_LENGTH_MAX 64\n+\n+enum ipsec_mb_vector_mode {\n+\tIPSEC_MB_NOT_SUPPORTED = 0,\n+\tIPSEC_MB_SSE,\n+\tIPSEC_MB_AVX,\n+\tIPSEC_MB_AVX2,\n+\tIPSEC_MB_AVX512\n+};\n+\n+extern enum ipsec_mb_vector_mode vector_mode;\n+\n+/** IMB_MGR instances, one per thread */\n+extern RTE_DEFINE_PER_LCORE(IMB_MGR *, mb_mgr);\n+\n+/** PMD LOGTYPE DRIVER, common to all PMDs */\n+extern int ipsec_mb_logtype_driver;\n+#define IPSEC_MB_LOG(level, fmt, ...)                                         \\\n+\trte_log(RTE_LOG_##level, ipsec_mb_logtype_driver,                     \\\n+\t\t\"%s() line %u: \" fmt \"\\n\", __func__, __LINE__, ##__VA_ARGS__)\n+\n+/** All supported device types */\n+enum ipsec_mb_pmd_types {\n+\tIPSEC_MB_N_PMD_TYPES\n+};\n+\n+/** Crypto operations */\n+enum ipsec_mb_operation {\n+\tIPSEC_MB_OP_ENCRYPT_THEN_HASH_GEN = 0,\n+\tIPSEC_MB_OP_HASH_VERIFY_THEN_DECRYPT,\n+\tIPSEC_MB_OP_HASH_GEN_THEN_ENCRYPT,\n+\tIPSEC_MB_OP_DECRYPT_THEN_HASH_VERIFY,\n+\tIPSEC_MB_OP_ENCRYPT_ONLY,\n+\tIPSEC_MB_OP_DECRYPT_ONLY,\n+\tIPSEC_MB_OP_HASH_GEN_ONLY,\n+\tIPSEC_MB_OP_HASH_VERIFY_ONLY,\n+\tIPSEC_MB_OP_AEAD_AUTHENTICATED_DECRYPT,\n+\tIPSEC_MB_OP_AEAD_AUTHENTICATED_ENCRYPT,\n+\tIPSEC_MB_OP_NOT_SUPPORTED\n+};\n+\n+/** Helper function. Gets driver ID based on PMD type */\n+static __rte_always_inline uint8_t\n+ipsec_mb_get_driver_id(__rte_unused enum ipsec_mb_pmd_types pmd_type)\n+{\n+\treturn UINT8_MAX;\n+}\n+\n+/** Common private data structure for each PMD */\n+struct ipsec_mb_private {\n+\tenum ipsec_mb_pmd_types pmd_type;\n+\t/**< PMD  type */\n+\tuint32_t max_nb_queue_pairs;\n+\t/**< Max number of queue pairs supported by device */\n+\t__extension__ uint8_t priv[0];\n+};\n+\n+/** IPSEC Multi buffer queue pair common queue pair data for all PMDs */\n+struct ipsec_mb_qp {\n+\tuint16_t id;\n+\t/**< Queue Pair Identifier */\n+\tchar name[RTE_CRYPTODEV_NAME_MAX_LEN];\n+\tstruct rte_ring *ingress_queue;\n+\t/**< Ring for placing operations ready for processing */\n+\tstruct rte_mempool *sess_mp;\n+\t/**< Session Mempool */\n+\tstruct rte_mempool *sess_mp_priv;\n+\t/**< Session Private Data Mempool */\n+\tstruct rte_cryptodev_stats stats;\n+\t/**< Queue pair statistics */\n+\tenum ipsec_mb_pmd_types pmd_type;\n+\t/**< pmd type */\n+\tuint8_t digest_idx;\n+\t/**< Index of the next\n+\t * slot to be used in temp_digests,\n+\t * to store the digest for a given operation\n+\t */\n+\tIMB_MGR *mb_mgr;\n+\t/* Multi buffer manager */\n+\t__extension__ uint8_t additional_data[0];\n+\t/**< Storing PMD specific additional data */\n+};\n+\n+static __rte_always_inline void *\n+ipsec_mb_get_qp_private_data(struct ipsec_mb_qp *qp)\n+{\n+\treturn (void *)qp->additional_data;\n+}\n+\n+/** Helper function. Allocates job manager */\n+static __rte_always_inline IMB_MGR *\n+alloc_init_mb_mgr(void)\n+{\n+\tIMB_MGR *mb_mgr = alloc_mb_mgr(0);\n+\n+\tif (unlikely(mb_mgr == NULL)) {\n+\t\tIPSEC_MB_LOG(ERR, \"Failed to allocate IMB_MGR data\\n\");\n+\t\treturn NULL;\n+\t}\n+\n+\tinit_mb_mgr_auto(mb_mgr, NULL);\n+\n+\treturn mb_mgr;\n+}\n+\n+/** Helper function. Gets per thread job manager */\n+static __rte_always_inline IMB_MGR *\n+get_per_thread_mb_mgr(void)\n+{\n+\tif (unlikely(RTE_PER_LCORE(mb_mgr) == NULL))\n+\t\tRTE_PER_LCORE(mb_mgr) = alloc_init_mb_mgr();\n+\n+\treturn RTE_PER_LCORE(mb_mgr);\n+}\n+\n+/** Device creation function */\n+int\n+cryptodev_ipsec_mb_create(struct rte_vdev_device *vdev,\n+\tenum ipsec_mb_pmd_types pmd_type);\n+\n+/** Device remove function */\n+int\n+cryptodev_ipsec_mb_remove(struct rte_vdev_device *vdev);\n+\n+/** Configure queue pair PMD type specific data */\n+typedef int (*ipsec_mb_queue_pair_configure_t)(struct ipsec_mb_qp *qp);\n+\n+/** Configure session PMD type specific data */\n+typedef int (*ipsec_mb_session_configure_t)(IMB_MGR *mbr_mgr,\n+\t\tvoid *session_private,\n+\t\tconst struct rte_crypto_sym_xform *xform);\n+\n+/** Configure internals PMD type specific data */\n+typedef int (*ipsec_mb_dev_configure_t)(struct rte_cryptodev *dev);\n+\n+/** Per PMD type operation and data */\n+struct ipsec_mb_pmd_data {\n+\tuint8_t is_configured;\n+\tdequeue_pkt_burst_t dequeue_burst;\n+\tipsec_mb_dev_configure_t dev_config;\n+\tipsec_mb_queue_pair_configure_t queue_pair_configure;\n+\tipsec_mb_session_configure_t session_configure;\n+\tconst struct rte_cryptodev_capabilities *caps;\n+\tstruct rte_cryptodev_ops *ops;\n+\tstruct rte_security_ops *security_ops;\n+\tuint64_t feature_flags;\n+\tuint32_t session_priv_size;\n+\tuint32_t qp_priv_size;\n+\tuint32_t internals_priv_size;\n+};\n+\n+/** Global PMD type specific data */\n+extern struct ipsec_mb_pmd_data ipsec_mb_pmds[IPSEC_MB_N_PMD_TYPES];\n+\n+int\n+ipsec_mb_pmd_config(struct rte_cryptodev *dev,\n+\tstruct rte_cryptodev_config *config);\n+\n+int\n+ipsec_mb_pmd_start(struct rte_cryptodev *dev);\n+\n+void\n+ipsec_mb_pmd_stop(struct rte_cryptodev *dev);\n+\n+int\n+ipsec_mb_pmd_close(struct rte_cryptodev *dev);\n+\n+void\n+ipsec_mb_pmd_stats_get(struct rte_cryptodev *dev,\n+\t\tstruct rte_cryptodev_stats *stats);\n+\n+void\n+ipsec_mb_pmd_stats_reset(struct rte_cryptodev *dev);\n+\n+void\n+ipsec_mb_pmd_info_get(struct rte_cryptodev *dev,\n+\t\tstruct rte_cryptodev_info *dev_info);\n+\n+int\n+ipsec_mb_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id);\n+\n+int\n+ipsec_mb_pmd_qp_set_unique_name(struct rte_cryptodev *dev,\n+\t\t\t\t\t   struct ipsec_mb_qp *qp);\n+\n+int\n+ipsec_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,\n+\t\t\t\t const struct rte_cryptodev_qp_conf *qp_conf,\n+\t\t\t\t int socket_id);\n+\n+/** Returns the size of the aesni multi-buffer session structure */\n+unsigned\n+ipsec_mb_pmd_sym_session_get_size(struct rte_cryptodev *dev);\n+\n+/** Configure an aesni multi-buffer session from a crypto xform chain */\n+int ipsec_mb_pmd_sym_session_configure(\n+\tstruct rte_cryptodev *dev,\n+\tstruct rte_crypto_sym_xform *xform,\n+\tstruct rte_cryptodev_sym_session *sess,\n+\tstruct rte_mempool *mempool);\n+\n+/** Clear the memory of session so it does not leave key material behind */\n+void\n+ipsec_mb_pmd_sym_session_clear(struct rte_cryptodev *dev,\n+\t\t\t\tstruct rte_cryptodev_sym_session *sess);\n+\n+/** Get session from op. If sessionless create a session */\n+static __rte_always_inline void *\n+ipsec_mb_get_session_private(struct ipsec_mb_qp *qp, struct rte_crypto_op *op)\n+{\n+\tvoid *sess = NULL;\n+\tuint32_t driver_id = ipsec_mb_get_driver_id(qp->pmd_type);\n+\tstruct rte_crypto_sym_op *sym_op = op->sym;\n+\tuint8_t sess_type = op->sess_type;\n+\tvoid *_sess;\n+\tvoid *_sess_private_data = NULL;\n+\tstruct ipsec_mb_pmd_data *pmd_data = &ipsec_mb_pmds[qp->pmd_type];\n+\n+\tswitch (sess_type) {\n+\tcase RTE_CRYPTO_OP_WITH_SESSION:\n+\t\tif (likely(sym_op->session != NULL))\n+\t\t\tsess = get_sym_session_private_data(sym_op->session,\n+\t\t\t\t\t\t\t    driver_id);\n+\tbreak;\n+\tcase RTE_CRYPTO_OP_SESSIONLESS:\n+\t\tif (!qp->sess_mp ||\n+\t\t    rte_mempool_get(qp->sess_mp, (void **)&_sess))\n+\t\t\treturn NULL;\n+\n+\t\tif (!qp->sess_mp_priv ||\n+\t\t    rte_mempool_get(qp->sess_mp_priv,\n+\t\t\t\t\t(void **)&_sess_private_data))\n+\t\t\treturn NULL;\n+\n+\t\tsess = _sess_private_data;\n+\t\tif (unlikely(pmd_data->session_configure(qp->mb_mgr,\n+\t\t\t\tsess, sym_op->xform) != 0)) {\n+\t\t\trte_mempool_put(qp->sess_mp, _sess);\n+\t\t\trte_mempool_put(qp->sess_mp_priv, _sess_private_data);\n+\t\t\tsess = NULL;\n+\t\t}\n+\n+\t\tsym_op->session = (struct rte_cryptodev_sym_session *)_sess;\n+\t\tset_sym_session_private_data(sym_op->session, driver_id,\n+\t\t\t\t\t     _sess_private_data);\n+\tbreak;\n+\tdefault:\n+\t\tIPSEC_MB_LOG(ERR, \"Unrecognized session type %u\", sess_type);\n+\t}\n+\n+\tif (unlikely(sess == NULL))\n+\t\top->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;\n+\n+\treturn sess;\n+}\n+\n+#endif /* _IPSEC_MB_PMD_PRIVATE_H_ */\ndiff --git a/drivers/crypto/ipsec_mb/version.map b/drivers/crypto/ipsec_mb/version.map\nnew file mode 100644\nindex 0000000000..4a76d1d52d\n--- /dev/null\n+++ b/drivers/crypto/ipsec_mb/version.map\n@@ -0,0 +1,3 @@\n+DPDK_21 {\n+\tlocal: *;\n+};\ndiff --git a/drivers/crypto/meson.build b/drivers/crypto/meson.build\nindex ea239f4c56..e40b18b17b 100644\n--- a/drivers/crypto/meson.build\n+++ b/drivers/crypto/meson.build\n@@ -6,6 +6,7 @@ if is_windows\n endif\n \n drivers = [\n+        'ipsec_mb',\n         'aesni_gcm',\n         'aesni_mb',\n         'armv8',\n",
    "prefixes": [
        "v3",
        "01/10"
    ]
}