get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 30046,
    "url": "https://patches.dpdk.org/api/patches/30046/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1507637842-4417-2-git-send-email-tdu@semihalf.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<1507637842-4417-2-git-send-email-tdu@semihalf.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1507637842-4417-2-git-send-email-tdu@semihalf.com",
    "date": "2017-10-10T12:17:19",
    "name": "[dpdk-dev,v4,1/4] crypto/mrvl: add mrvl crypto pmd driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "632e3224c87ff78718ccae4cd4c3cde3e3249402",
    "submitter": {
        "id": 846,
        "url": "https://patches.dpdk.org/api/people/846/?format=api",
        "name": "Tomasz Duszynski",
        "email": "tdu@semihalf.com"
    },
    "delegate": {
        "id": 22,
        "url": "https://patches.dpdk.org/api/users/22/?format=api",
        "username": "pdelarag",
        "first_name": "Pablo",
        "last_name": "de Lara Guarch",
        "email": "pablo.de.lara.guarch@intel.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1507637842-4417-2-git-send-email-tdu@semihalf.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/30046/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/30046/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 0B93A1B2B4;\n\tTue, 10 Oct 2017 14:17:41 +0200 (CEST)",
            "from mail-lf0-f42.google.com (mail-lf0-f42.google.com\n\t[209.85.215.42]) by dpdk.org (Postfix) with ESMTP id 179511B2A0\n\tfor <dev@dpdk.org>; Tue, 10 Oct 2017 14:17:37 +0200 (CEST)",
            "by mail-lf0-f42.google.com with SMTP id a132so22675418lfa.7\n\tfor <dev@dpdk.org>; Tue, 10 Oct 2017 05:17:37 -0700 (PDT)",
            "from tdu.semihalf.local (31-172-191-173.noc.fibertech.net.pl.\n\t[31.172.191.173]) by smtp.gmail.com with ESMTPSA id\n\te13sm1677728ljb.93.2017.10.10.05.17.33\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tTue, 10 Oct 2017 05:17:33 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=semihalf-com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=hPSJAAkhpYbb2s7ozZeWyV9XgvaTTXJAQizuuC0nIKI=;\n\tb=L79QAIo9e6icH3mzGH9jiVl1gF0yK8WhqwPtu6Ggd53JTl69x5g/Rq9n9CDANQ/B36\n\taLDk8LeU5iS/MNwjOtYZdRxMkwCSYU9xtwXvWDZw1hMVYr3fv4UTQz9Ro6iTgfM1rlFJ\n\tncrEkrfQzDK2LHll1oVmuykfJtNYdcBNFAWb8GgMEOTkFwf98GpisPStBVjXq/i2R2sM\n\tcRPYf5ROB/eZXLQ00xogcB6+0ZXPYRu8A9H6nB4/KbrKmv26fTFc7etU6CK4vEwu2ICf\n\tmYIUtfFcV/N4kyWROf/e6uTiJpK6CC1z6maBfTyxAcYlQcGycatmrjJuV8o0fHjMEujU\n\t6t7w==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=hPSJAAkhpYbb2s7ozZeWyV9XgvaTTXJAQizuuC0nIKI=;\n\tb=dz6gAzc+4d+i0T+V13cLe+SpNr9Ob3dSxbH/LjtUKz3XtTky/YR+R68TMN4H8y3g81\n\tyrIexWg4dZFjI8N2vpiIFTSp0MUvOlw7UvvEaeVzDST3WwAM1NRefnkPI5HKXeK/qqqz\n\txHjfC6INij/SYJLNgOwCVDr4mp6/V+1lPSqpDbQkxaMb0WiHebHR12BNDqaLgAJei1G7\n\tOYvdmO0e7j7t/JpnMb4cLHCOJztN/lwmNd6ew/RMPYFa8eH06IJUcURfkqjzfMVL6vD4\n\tWSdrgoh97hf920HCItfeUljAhpR0a8uPwQxUM/zRVXk8ghG8/CE7Qwob6C26d4dvHNqA\n\tZPEw==",
        "X-Gm-Message-State": "AMCzsaWo6+V+A9WiDptkN8Ijz7+B6/hrBErKXET45XbKicu7qsUdDcFN\n\t/d6hqFE9diFAH91jR+5hVsu5Y7Rh7dM=",
        "X-Google-Smtp-Source": "AOwi7QDtFPmqA/fZIMAFyGZ6UEfNvZIDG9yR0Zrq1eA3x3QaThJMkCpJi1ZYXWYVF88EzNQsYzgtqQ==",
        "X-Received": "by 10.25.211.75 with SMTP id k72mr4992802lfg.120.1507637854850; \n\tTue, 10 Oct 2017 05:17:34 -0700 (PDT)",
        "From": "Tomasz Duszynski <tdu@semihalf.com>",
        "To": "dev@dpdk.org",
        "Cc": "mw@semihalf.com, dima@marvell.com, nsamsono@marvell.com,\n\tJianbo.liu@arm.org, Tomasz Duszynski <tdu@semihalf.com>,\n\tJacek Siuda <jck@semihalf.com>",
        "Date": "Tue, 10 Oct 2017 14:17:19 +0200",
        "Message-Id": "<1507637842-4417-2-git-send-email-tdu@semihalf.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1507637842-4417-1-git-send-email-tdu@semihalf.com>",
        "References": "<1507408106-11292-1-git-send-email-tdu@semihalf.com>\n\t<1507637842-4417-1-git-send-email-tdu@semihalf.com>",
        "Subject": "[dpdk-dev] [PATCH v4 1/4] crypto/mrvl: add mrvl crypto pmd driver",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add support for the Marvell Security Crypto Accelerator EIP197.\nDriver is based on external, publicly available, Marvell MUSDK\nlibrary that provides access to the hardware with minimum overhead\nand high performance.\n\nDriver comes with support for the following features:\n\n* Symmetric crypto\n* Sym operation chaining\n* AES CBC (128)\n* AES CBC (192)\n* AES CBC (256)\n* AES CTR (128)\n* AES CTR (192)\n* AES CTR (256)\n* 3DES CBC\n* 3DES CTR\n* MD5\n* MD5 HMAC\n* SHA1\n* SHA1 HMAC\n* SHA256\n* SHA256 HMAC\n* SHA384\n* SHA384 HMAC\n* SHA512\n* SHA512 HMAC\n* AES GCM (128)\n\nDriver was engineered cooperatively by Semihalf and Marvell teams.\n\nSemihalf:\nJacek Siuda <jck@semihalf.com>\nTomasz Duszynski <tdu@semihalf.com>\n\nMarvell:\nDmitri Epshtein <dima@marvell.com>\nNatalie Samsonov <nsamsono@marvell.com>\n\nSigned-off-by: Jacek Siuda <jck@semihalf.com>\nSigned-off-by: Tomasz Duszynski <tdu@semihalf.com>\n---\n v4:\n * Allocated driver structure statically.\n\n v3:\n * Added MRVL CRYPTO PMD to the test-build.sh.\n * Updated release notes.\n * Updated cryptoperf documentation.\n * Removed cryptodev_mrvl_pmd driver alias.\n * Fixed min,max key sizes used by HMACs in capabilities table.\n * Renamed map file.\n\n config/common_base                           |   6 +\n devtools/test-build.sh                       |   4 +\n doc/guides/rel_notes/release_17_11.rst       |   5 +\n doc/guides/tools/cryptoperf.rst              |   1 +\n drivers/crypto/Makefile                      |   2 +\n drivers/crypto/mrvl/Makefile                 |  63 ++\n drivers/crypto/mrvl/rte_mrvl_compat.h        |  48 ++\n drivers/crypto/mrvl/rte_mrvl_pmd.c           | 872 +++++++++++++++++++++++++++\n drivers/crypto/mrvl/rte_mrvl_pmd_ops.c       | 776 ++++++++++++++++++++++++\n drivers/crypto/mrvl/rte_mrvl_pmd_private.h   | 121 ++++\n drivers/crypto/mrvl/rte_pmd_mrvl_version.map |   3 +\n mk/rte.app.mk                                |   1 +\n 12 files changed, 1902 insertions(+)\n create mode 100644 drivers/crypto/mrvl/Makefile\n create mode 100644 drivers/crypto/mrvl/rte_mrvl_compat.h\n create mode 100644 drivers/crypto/mrvl/rte_mrvl_pmd.c\n create mode 100644 drivers/crypto/mrvl/rte_mrvl_pmd_ops.c\n create mode 100644 drivers/crypto/mrvl/rte_mrvl_pmd_private.h\n create mode 100644 drivers/crypto/mrvl/rte_pmd_mrvl_version.map\n\n--\n2.7.4",
    "diff": "diff --git a/config/common_base b/config/common_base\nindex 8adcb09..db1e20b 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -528,6 +528,12 @@ CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER_DEBUG=n\n CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO=y\n\n #\n+# Compile PMD for Marvell Crypto device\n+#\n+CONFIG_RTE_LIBRTE_PMD_MRVL_CRYPTO=n\n+CONFIG_RTE_LIBRTE_PMD_MRVL_CRYPTO_DEBUG=n\n+\n+#\n # Compile generic event device library\n #\n CONFIG_RTE_LIBRTE_EVENTDEV=y\ndiff --git a/devtools/test-build.sh b/devtools/test-build.sh\nindex c6dfaf0..d82e3f4 100755\n--- a/devtools/test-build.sh\n+++ b/devtools/test-build.sh\n@@ -50,6 +50,7 @@ default_path=$PATH\n # - LIBSSO_SNOW3G_PATH\n # - LIBSSO_KASUMI_PATH\n # - LIBSSO_ZUC_PATH\n+# - LIBMUSDK_PATH\n . $(dirname $(readlink -e $0))/load-devel-config\n\n print_usage () {\n@@ -133,6 +134,7 @@ reset_env ()\n \tunset LIBSSO_KASUMI_PATH\n \tunset LIBSSO_ZUC_PATH\n \tunset PQOS_INSTALL_PATH\n+\tunset LIBMUSDK_PATH\n }\n\n config () # <directory> <target> <options>\n@@ -193,6 +195,8 @@ config () # <directory> <target> <options>\n \t\ttest \"$DPDK_DEP_SSL\" != y || \\\n \t\tsed -ri            's,(PMD_QAT=)n,\\1y,' $1/.config\n \t\tsed -ri           's,(SCHED_.*=)n,\\1y,' $1/.config\n+\t\ttest -z \"$LIBMUSDK_PATH\" || \\\n+\t\tsed -ri    's,(PMD_MRVL_CRYPTO=)n,\\1y,' $1/.config\n \t\tbuild_config_hook $1 $2 $3\n\n \t\t# Explicit enabler/disabler (uppercase)\ndiff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst\nindex f452f0b..6ff86e4 100644\n--- a/doc/guides/rel_notes/release_17_11.rst\n+++ b/doc/guides/rel_notes/release_17_11.rst\n@@ -122,6 +122,11 @@ New Features\n   added. See the \"Crypto Device Drivers\" document for more details on this\n   driver.\n\n+* **Added MRVL crypto PMD.**\n+\n+  A new crypto PMD has been added, which provides several ciphering and hashing\n+  algorithms. All cryptography operations use the MUSDK library crypto API.\n+\n\n Resolved Issues\n ---------------\ndiff --git a/doc/guides/tools/cryptoperf.rst b/doc/guides/tools/cryptoperf.rst\nindex 2b3a5b6..7e12677 100644\n--- a/doc/guides/tools/cryptoperf.rst\n+++ b/doc/guides/tools/cryptoperf.rst\n@@ -194,6 +194,7 @@ The following are the appication command-line options:\n            crypto_dpaa2_sec\n            crypto_armv8\n            crypto_scheduler\n+           crypto_mrvl\n\n * ``--optype <name>``\n\ndiff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile\nindex 8ca5f18..d8c8740 100644\n--- a/drivers/crypto/Makefile\n+++ b/drivers/crypto/Makefile\n@@ -51,6 +51,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += kasumi\n DEPDIRS-kasumi = $(core-libs)\n DIRS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += zuc\n DEPDIRS-zuc = $(core-libs)\n+DIRS-$(CONFIG_RTE_LIBRTE_PMD_MRVL_CRYPTO) += mrvl\n+DEPDIRS-mrvl = $(core-libs)\n DIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += null\n DEPDIRS-null = $(core-libs)\n DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC) += dpaa2_sec\ndiff --git a/drivers/crypto/mrvl/Makefile b/drivers/crypto/mrvl/Makefile\nnew file mode 100644\nindex 0000000..a00a19e\n--- /dev/null\n+++ b/drivers/crypto/mrvl/Makefile\n@@ -0,0 +1,63 @@\n+#   BSD LICENSE\n+#\n+#   Copyright (C) Semihalf 2017. All rights reserved.\n+#\n+#   Redistribution and use in source and binary forms, with or without\n+#   modification, are permitted provided that the following conditions\n+#   are met:\n+#\n+#     * Redistributions of source code must retain the above copyright\n+#       notice, this list of conditions and the following disclaimer.\n+#     * Redistributions in binary form must reproduce the above copyright\n+#       notice, this list of conditions and the following disclaimer in\n+#       the documentation and/or other materials provided with the\n+#       distribution.\n+#     * Neither the name of Semihalf nor the names of its\n+#       contributors may be used to endorse or promote products derived\n+#       from this software without specific prior written permission.\n+#\n+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+#   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+ifneq ($(MAKECMDGOALS),clean)\n+ifneq ($(MAKECMDGOALS),config)\n+ifeq ($(LIBMUSDK_PATH),)\n+$(error \"Please define LIBMUSDK_PATH environment variable\")\n+endif\n+endif\n+endif\n+\n+# library name\n+LIB = librte_pmd_mrvl_crypto.a\n+\n+# build flags\n+CFLAGS += -O3\n+CFLAGS += $(WERROR_FLAGS)\n+CFLAGS += -I$(LIBMUSDK_PATH)/include\n+CFLAGS += -DMVCONF_ARCH_DMA_ADDR_T_64BIT\n+\n+# library version\n+LIBABIVER := 1\n+\n+# versioning export map\n+EXPORT_MAP := rte_mrvl_pmd_version.map\n+\n+# external library dependencies\n+LDLIBS += -L$(LIBMUSDK_PATH)/lib -lmusdk\n+\n+# library source files\n+SRCS-$(CONFIG_RTE_LIBRTE_PMD_MRVL_CRYPTO) += rte_mrvl_pmd.c\n+SRCS-$(CONFIG_RTE_LIBRTE_PMD_MRVL_CRYPTO) += rte_mrvl_pmd_ops.c\n+\n+include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/crypto/mrvl/rte_mrvl_compat.h b/drivers/crypto/mrvl/rte_mrvl_compat.h\nnew file mode 100644\nindex 0000000..11d53fc\n--- /dev/null\n+++ b/drivers/crypto/mrvl/rte_mrvl_compat.h\n@@ -0,0 +1,48 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright (C) Semihalf 2017. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Semihalf nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _RTE_MRVL_COMPAT_H_\n+#define _RTE_MRVL_COMPAT_H_\n+\n+/* Unluckily, container_of is defined by both DPDK and MUSDK,\n+ * we'll declare only one version.\n+ *\n+ * Note that it is not used in this PMD anyway.\n+ */\n+#ifdef container_of\n+#undef container_of\n+#endif\n+#include \"drivers/mv_sam.h\"\n+#include \"drivers/mv_sam_cio.h\"\n+#include \"drivers/mv_sam_session.h\"\n+\n+#endif /* _RTE_MRVL_COMPAT_H_ */\ndiff --git a/drivers/crypto/mrvl/rte_mrvl_pmd.c b/drivers/crypto/mrvl/rte_mrvl_pmd.c\nnew file mode 100644\nindex 0000000..0c540fa\n--- /dev/null\n+++ b/drivers/crypto/mrvl/rte_mrvl_pmd.c\n@@ -0,0 +1,872 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright (C) Semihalf 2017. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Semihalf nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <rte_common.h>\n+#include <rte_hexdump.h>\n+#include <rte_cryptodev.h>\n+#include <rte_cryptodev_pmd.h>\n+#include <rte_cryptodev_vdev.h>\n+#include <rte_vdev.h>\n+#include <rte_malloc.h>\n+#include <rte_cpuflags.h>\n+\n+#include \"rte_mrvl_pmd_private.h\"\n+\n+#ifndef RTE_MRVL_MUSDK_DMA_MEMSIZE\n+#define RTE_MRVL_MUSDK_DMA_MEMSIZE 41943040\n+#endif\n+\n+static uint8_t cryptodev_driver_id;\n+\n+/**\n+ * Flag if particular crypto algorithm is supported by PMD/MUSDK.\n+ *\n+ * The idea is to have Not Supported value as default (0).\n+ * This way we need only to define proper map sizes,\n+ * non-initialized entries will be by default not supported.\n+ */\n+enum algo_supported {\n+\tALGO_NOT_SUPPORTED = 0,\n+\tALGO_SUPPORTED = 1,\n+};\n+\n+/** Map elements for cipher mapping.*/\n+struct cipher_params_mapping {\n+\tenum algo_supported  supported;   /**< On/Off switch */\n+\tenum sam_cipher_alg  cipher_alg;  /**< Cipher algorithm */\n+\tenum sam_cipher_mode cipher_mode; /**< Cipher mode */\n+\tunsigned int max_key_len;         /**< Maximum key length (in bytes)*/\n+}\n+/* We want to squeeze in multiple maps into the cache line. */\n+__rte_aligned(32);\n+\n+/** Map elements for auth mapping.*/\n+struct auth_params_mapping {\n+\tenum algo_supported supported;  /**< On/off switch */\n+\tenum sam_auth_alg   auth_alg;   /**< Auth algorithm */\n+}\n+/* We want to squeeze in multiple maps into the cache line. */\n+__rte_aligned(32);\n+\n+/**\n+ * Map of supported cipher algorithms.\n+ */\n+static const\n+struct cipher_params_mapping cipher_map[RTE_CRYPTO_CIPHER_LIST_END] = {\n+\t[RTE_CRYPTO_CIPHER_3DES_CBC] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.cipher_alg = SAM_CIPHER_3DES,\n+\t\t.cipher_mode = SAM_CIPHER_CBC,\n+\t\t.max_key_len = BITS2BYTES(192) },\n+\t[RTE_CRYPTO_CIPHER_3DES_CTR] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.cipher_alg = SAM_CIPHER_3DES,\n+\t\t.cipher_mode = SAM_CIPHER_CTR,\n+\t\t.max_key_len = BITS2BYTES(192) },\n+\t[RTE_CRYPTO_CIPHER_3DES_ECB] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.cipher_alg = SAM_CIPHER_3DES,\n+\t\t.cipher_mode = SAM_CIPHER_ECB,\n+\t\t.max_key_len = BITS2BYTES(192) },\n+\t[RTE_CRYPTO_CIPHER_AES_CBC] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.cipher_alg = SAM_CIPHER_AES,\n+\t\t.cipher_mode = SAM_CIPHER_CBC,\n+\t\t.max_key_len = BITS2BYTES(256) },\n+\t[RTE_CRYPTO_CIPHER_AES_CTR] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.cipher_alg = SAM_CIPHER_AES,\n+\t\t.cipher_mode = SAM_CIPHER_CTR,\n+\t\t.max_key_len = BITS2BYTES(256) },\n+};\n+\n+/**\n+ * Map of supported auth algorithms.\n+ */\n+static const\n+struct auth_params_mapping auth_map[RTE_CRYPTO_AUTH_LIST_END] = {\n+\t[RTE_CRYPTO_AUTH_MD5_HMAC] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_HMAC_MD5 },\n+\t[RTE_CRYPTO_AUTH_MD5] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_HASH_MD5 },\n+\t[RTE_CRYPTO_AUTH_SHA1_HMAC] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_HMAC_SHA1 },\n+\t[RTE_CRYPTO_AUTH_SHA1] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_HASH_SHA1 },\n+\t[RTE_CRYPTO_AUTH_SHA224] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_HASH_SHA2_224 },\n+\t[RTE_CRYPTO_AUTH_SHA256_HMAC] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_HMAC_SHA2_256 },\n+\t[RTE_CRYPTO_AUTH_SHA256] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_HASH_SHA2_256 },\n+\t[RTE_CRYPTO_AUTH_SHA384_HMAC] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_HMAC_SHA2_384 },\n+\t[RTE_CRYPTO_AUTH_SHA384] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_HASH_SHA2_384 },\n+\t[RTE_CRYPTO_AUTH_SHA512_HMAC] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_HMAC_SHA2_512 },\n+\t[RTE_CRYPTO_AUTH_SHA512] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_HASH_SHA2_512 },\n+\t[RTE_CRYPTO_AUTH_AES_GMAC] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.auth_alg = SAM_AUTH_AES_GMAC },\n+};\n+\n+/**\n+ * Map of supported aead algorithms.\n+ */\n+static const\n+struct cipher_params_mapping aead_map[RTE_CRYPTO_AEAD_LIST_END] = {\n+\t[RTE_CRYPTO_AEAD_AES_GCM] = {\n+\t\t.supported = ALGO_SUPPORTED,\n+\t\t.cipher_alg = SAM_CIPHER_AES,\n+\t\t.cipher_mode = SAM_CIPHER_GCM,\n+\t\t.max_key_len = BITS2BYTES(256) },\n+};\n+\n+/*\n+ *-----------------------------------------------------------------------------\n+ * Forward declarations.\n+ *-----------------------------------------------------------------------------\n+ */\n+static int cryptodev_mrvl_crypto_uninit(struct rte_vdev_device *vdev);\n+\n+/*\n+ *-----------------------------------------------------------------------------\n+ * Session Preparation.\n+ *-----------------------------------------------------------------------------\n+ */\n+\n+/**\n+ * Get xform chain order.\n+ *\n+ * @param xform Pointer to configuration structure chain for crypto operations.\n+ * @returns Order of crypto operations.\n+ */\n+static enum mrvl_crypto_chain_order\n+mrvl_crypto_get_chain_order(const struct rte_crypto_sym_xform *xform)\n+{\n+\t/* Currently, Marvell supports max 2 operations in chain */\n+\tif (xform->next != NULL && xform->next->next != NULL)\n+\t\treturn MRVL_CRYPTO_CHAIN_NOT_SUPPORTED;\n+\n+\tif (xform->next != NULL) {\n+\t\tif ((xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) &&\n+\t\t\t(xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER))\n+\t\t\treturn MRVL_CRYPTO_CHAIN_AUTH_CIPHER;\n+\n+\t\tif ((xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&\n+\t\t\t(xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH))\n+\t\t\treturn MRVL_CRYPTO_CHAIN_CIPHER_AUTH;\n+\t} else {\n+\t\tif (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH)\n+\t\t\treturn MRVL_CRYPTO_CHAIN_AUTH_ONLY;\n+\n+\t\tif (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER)\n+\t\t\treturn MRVL_CRYPTO_CHAIN_CIPHER_ONLY;\n+\n+\t\tif (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)\n+\t\t\treturn MRVL_CRYPTO_CHAIN_COMBINED;\n+\t}\n+\treturn MRVL_CRYPTO_CHAIN_NOT_SUPPORTED;\n+}\n+\n+/**\n+ * Set session parameters for cipher part.\n+ *\n+ * @param sess Crypto session pointer.\n+ * @param cipher_xform Pointer to configuration structure for cipher operations.\n+ * @returns 0 in case of success, negative value otherwise.\n+ */\n+static int\n+mrvl_crypto_set_cipher_session_parameters(struct mrvl_crypto_session *sess,\n+\t\tconst struct rte_crypto_sym_xform *cipher_xform)\n+{\n+\t/* Make sure we've got proper struct */\n+\tif (cipher_xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Wrong xform struct provided!\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* See if map data is present and valid */\n+\tif ((cipher_xform->cipher.algo > RTE_DIM(cipher_map)) ||\n+\t\t(cipher_map[cipher_xform->cipher.algo].supported\n+\t\t\t!= ALGO_SUPPORTED)) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Cipher algorithm not supported!\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tsess->cipher_iv_offset = cipher_xform->cipher.iv.offset;\n+\n+\tsess->sam_sess_params.dir =\n+\t\t(cipher_xform->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) ?\n+\t\tSAM_DIR_ENCRYPT : SAM_DIR_DECRYPT;\n+\tsess->sam_sess_params.cipher_alg =\n+\t\tcipher_map[cipher_xform->cipher.algo].cipher_alg;\n+\tsess->sam_sess_params.cipher_mode =\n+\t\tcipher_map[cipher_xform->cipher.algo].cipher_mode;\n+\n+\t/* Assume IV will be passed together with data. */\n+\tsess->sam_sess_params.cipher_iv = NULL;\n+\n+\t/* Get max key length. */\n+\tif (cipher_xform->cipher.key.length >\n+\t\tcipher_map[cipher_xform->cipher.algo].max_key_len) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Wrong key length!\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tsess->sam_sess_params.cipher_key_len = cipher_xform->cipher.key.length;\n+\tsess->sam_sess_params.cipher_key = cipher_xform->cipher.key.data;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Set session parameters for authentication part.\n+ *\n+ * @param sess Crypto session pointer.\n+ * @param auth_xform Pointer to configuration structure for auth operations.\n+ * @returns 0 in case of success, negative value otherwise.\n+ */\n+static int\n+mrvl_crypto_set_auth_session_parameters(struct mrvl_crypto_session *sess,\n+\t\tconst struct rte_crypto_sym_xform *auth_xform)\n+{\n+\t/* Make sure we've got proper struct */\n+\tif (auth_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Wrong xform struct provided!\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* See if map data is present and valid */\n+\tif ((auth_xform->auth.algo > RTE_DIM(auth_map)) ||\n+\t\t(auth_map[auth_xform->auth.algo].supported != ALGO_SUPPORTED)) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Auth algorithm not supported!\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tsess->sam_sess_params.dir =\n+\t\t(auth_xform->auth.op == RTE_CRYPTO_AUTH_OP_GENERATE) ?\n+\t\tSAM_DIR_ENCRYPT : SAM_DIR_DECRYPT;\n+\tsess->sam_sess_params.auth_alg =\n+\t\tauth_map[auth_xform->auth.algo].auth_alg;\n+\tsess->sam_sess_params.u.basic.auth_icv_len =\n+\t\tauth_xform->auth.digest_length;\n+\t/* auth_key must be NULL if auth algorithm does not use HMAC */\n+\tsess->sam_sess_params.auth_key = auth_xform->auth.key.length ?\n+\t\t\t\t\t auth_xform->auth.key.data : NULL;\n+\tsess->sam_sess_params.auth_key_len = auth_xform->auth.key.length;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Set session parameters for aead part.\n+ *\n+ * @param sess Crypto session pointer.\n+ * @param aead_xform Pointer to configuration structure for aead operations.\n+ * @returns 0 in case of success, negative value otherwise.\n+ */\n+static int\n+mrvl_crypto_set_aead_session_parameters(struct mrvl_crypto_session *sess,\n+\t\tconst struct rte_crypto_sym_xform *aead_xform)\n+{\n+\t/* Make sure we've got proper struct */\n+\tif (aead_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Wrong xform struct provided!\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* See if map data is present and valid */\n+\tif ((aead_xform->aead.algo > RTE_DIM(aead_map)) ||\n+\t\t(aead_map[aead_xform->aead.algo].supported\n+\t\t\t!= ALGO_SUPPORTED)) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"AEAD algorithm not supported!\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tsess->sam_sess_params.dir =\n+\t\t(aead_xform->aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT) ?\n+\t\tSAM_DIR_ENCRYPT : SAM_DIR_DECRYPT;\n+\tsess->sam_sess_params.cipher_alg =\n+\t\taead_map[aead_xform->aead.algo].cipher_alg;\n+\tsess->sam_sess_params.cipher_mode =\n+\t\taead_map[aead_xform->aead.algo].cipher_mode;\n+\n+\t/* Assume IV will be passed together with data. */\n+\tsess->sam_sess_params.cipher_iv = NULL;\n+\n+\t/* Get max key length. */\n+\tif (aead_xform->aead.key.length >\n+\t\taead_map[aead_xform->aead.algo].max_key_len) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Wrong key length!\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tsess->sam_sess_params.cipher_key = aead_xform->aead.key.data;\n+\tsess->sam_sess_params.cipher_key_len = aead_xform->aead.key.length;\n+\n+\tif (sess->sam_sess_params.cipher_mode == SAM_CIPHER_GCM)\n+\t\tsess->sam_sess_params.auth_alg = SAM_AUTH_AES_GCM;\n+\n+\tsess->sam_sess_params.u.basic.auth_icv_len =\n+\t\taead_xform->aead.digest_length;\n+\n+\tsess->sam_sess_params.u.basic.auth_aad_len =\n+\t\taead_xform->aead.aad_length;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Parse crypto transform chain and setup session parameters.\n+ *\n+ * @param dev Pointer to crypto device\n+ * @param sess Poiner to crypto session\n+ * @param xform Pointer to configuration structure chain for crypto operations.\n+ * @returns 0 in case of success, negative value otherwise.\n+ */\n+int\n+mrvl_crypto_set_session_parameters(struct mrvl_crypto_session *sess,\n+\t\tconst struct rte_crypto_sym_xform *xform)\n+{\n+\tconst struct rte_crypto_sym_xform *cipher_xform = NULL;\n+\tconst struct rte_crypto_sym_xform *auth_xform = NULL;\n+\tconst struct rte_crypto_sym_xform *aead_xform = NULL;\n+\n+\t/* Filter out spurious/broken requests */\n+\tif (xform == NULL)\n+\t\treturn -EINVAL;\n+\n+\tsess->chain_order = mrvl_crypto_get_chain_order(xform);\n+\tswitch (sess->chain_order) {\n+\tcase MRVL_CRYPTO_CHAIN_CIPHER_AUTH:\n+\t\tcipher_xform = xform;\n+\t\tauth_xform = xform->next;\n+\t\tbreak;\n+\tcase MRVL_CRYPTO_CHAIN_AUTH_CIPHER:\n+\t\tauth_xform = xform;\n+\t\tcipher_xform = xform->next;\n+\t\tbreak;\n+\tcase MRVL_CRYPTO_CHAIN_CIPHER_ONLY:\n+\t\tcipher_xform = xform;\n+\t\tbreak;\n+\tcase MRVL_CRYPTO_CHAIN_AUTH_ONLY:\n+\t\tauth_xform = xform;\n+\t\tbreak;\n+\tcase MRVL_CRYPTO_CHAIN_COMBINED:\n+\t\taead_xform = xform;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif ((cipher_xform != NULL) &&\n+\t\t(mrvl_crypto_set_cipher_session_parameters(\n+\t\t\tsess, cipher_xform) < 0)) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Invalid/unsupported cipher parameters\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif ((auth_xform != NULL) &&\n+\t\t(mrvl_crypto_set_auth_session_parameters(\n+\t\t\tsess, auth_xform) < 0)) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Invalid/unsupported auth parameters\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif ((aead_xform != NULL) &&\n+\t\t(mrvl_crypto_set_aead_session_parameters(\n+\t\t\tsess, aead_xform) < 0)) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Invalid/unsupported aead parameters\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/*\n+ *-----------------------------------------------------------------------------\n+ * Process Operations\n+ *-----------------------------------------------------------------------------\n+ */\n+\n+/**\n+ * Prepare a single request.\n+ *\n+ * This function basically translates DPDK crypto request into one\n+ * understandable by MUDSK's SAM. If this is a first request in a session,\n+ * it starts the session.\n+ *\n+ * @param request Pointer to pre-allocated && reset request buffer [Out].\n+ * @param src_bd Pointer to pre-allocated source descriptor [Out].\n+ * @param dst_bd Pointer to pre-allocated destination descriptor [Out].\n+ * @param op Pointer to DPDK crypto operation struct [In].\n+ */\n+static inline int\n+mrvl_request_prepare(struct sam_cio_op_params *request,\n+\t\tstruct sam_buf_info *src_bd,\n+\t\tstruct sam_buf_info *dst_bd,\n+\t\tstruct rte_crypto_op *op)\n+{\n+\tstruct mrvl_crypto_session *sess;\n+\tstruct rte_mbuf *dst_mbuf;\n+\tuint8_t *digest;\n+\n+\tif (unlikely(op->sess_type == RTE_CRYPTO_OP_SESSIONLESS)) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"MRVL CRYPTO PMD only supports session \"\n+\t\t\t\t\"oriented requests, op (%p) is sessionless.\",\n+\t\t\t\top);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tsess = (struct mrvl_crypto_session *)get_session_private_data(\n+\t\t\top->sym->session, cryptodev_driver_id);\n+\tif (unlikely(sess == NULL)) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Session was not created for this device\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/*\n+\t * If application delivered us null dst buffer, it means it expects\n+\t * us to deliver the result in src buffer.\n+\t */\n+\tdst_mbuf = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;\n+\n+\trequest->sa = sess->sam_sess;\n+\trequest->cookie = op;\n+\n+\t/* Single buffers only, sorry. */\n+\trequest->num_bufs = 1;\n+\trequest->src = src_bd;\n+\tsrc_bd->vaddr = rte_pktmbuf_mtod(op->sym->m_src, void *);\n+\tsrc_bd->paddr = rte_pktmbuf_mtophys(op->sym->m_src);\n+\tsrc_bd->len = rte_pktmbuf_data_len(op->sym->m_src);\n+\n+\t/* Empty source. */\n+\tif (rte_pktmbuf_data_len(op->sym->m_src) == 0) {\n+\t\t/* EIP does not support 0 length buffers. */\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Buffer length == 0 not supported!\");\n+\t\treturn -1;\n+\t}\n+\n+\t/* Empty destination. */\n+\tif (rte_pktmbuf_data_len(dst_mbuf) == 0) {\n+\t\t/* Make dst buffer fit at least source data. */\n+\t\tif (rte_pktmbuf_append(dst_mbuf,\n+\t\t\trte_pktmbuf_data_len(op->sym->m_src)) == NULL) {\n+\t\t\tMRVL_CRYPTO_LOG_ERR(\"Unable to set big enough dst buffer!\");\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\trequest->dst = dst_bd;\n+\tdst_bd->vaddr = rte_pktmbuf_mtod(dst_mbuf, void *);\n+\tdst_bd->paddr = rte_pktmbuf_mtophys(dst_mbuf);\n+\n+\t/*\n+\t * We can use all available space in dst_mbuf,\n+\t * not only what's used currently.\n+\t */\n+\tdst_bd->len = dst_mbuf->buf_len - rte_pktmbuf_headroom(dst_mbuf);\n+\n+\tif (sess->chain_order == MRVL_CRYPTO_CHAIN_COMBINED) {\n+\t\trequest->cipher_len = op->sym->aead.data.length;\n+\t\trequest->cipher_offset = op->sym->aead.data.offset;\n+\t\trequest->cipher_iv = rte_crypto_op_ctod_offset(op, uint8_t *,\n+\t\t\tsess->cipher_iv_offset);\n+\n+\t\trequest->auth_aad = op->sym->aead.aad.data;\n+\t\trequest->auth_offset = request->cipher_offset;\n+\t\trequest->auth_len = request->cipher_len;\n+\t} else {\n+\t\trequest->cipher_len = op->sym->cipher.data.length;\n+\t\trequest->cipher_offset = op->sym->cipher.data.offset;\n+\t\trequest->cipher_iv = rte_crypto_op_ctod_offset(op, uint8_t *,\n+\t\t\t\tsess->cipher_iv_offset);\n+\n+\t\trequest->auth_offset = op->sym->auth.data.offset;\n+\t\trequest->auth_len = op->sym->auth.data.length;\n+\t}\n+\n+\tdigest = sess->chain_order == MRVL_CRYPTO_CHAIN_COMBINED ?\n+\t\top->sym->aead.digest.data : op->sym->auth.digest.data;\n+\tif (digest == NULL) {\n+\t\t/* No auth - no worry. */\n+\t\treturn 0;\n+\t}\n+\n+\trequest->auth_icv_offset = request->auth_offset + request->auth_len;\n+\n+\t/*\n+\t * EIP supports only scenarios where ICV(digest buffer) is placed at\n+\t * auth_icv_offset. Any other placement means risking errors.\n+\t */\n+\tif (sess->sam_sess_params.dir == SAM_DIR_ENCRYPT) {\n+\t\t/*\n+\t\t * This should be the most common case anyway,\n+\t\t * EIP will overwrite DST buffer at auth_icv_offset.\n+\t\t */\n+\t\tif (rte_pktmbuf_mtod_offset(\n+\t\t\t\tdst_mbuf, uint8_t *,\n+\t\t\t\trequest->auth_icv_offset) == digest) {\n+\t\t\treturn 0;\n+\t\t}\n+\t} else {/* sess->sam_sess_params.dir == SAM_DIR_DECRYPT */\n+\t\t/*\n+\t\t * EIP will look for digest at auth_icv_offset\n+\t\t * offset in SRC buffer.\n+\t\t */\n+\t\tif (rte_pktmbuf_mtod_offset(\n+\t\t\t\top->sym->m_src, uint8_t *,\n+\t\t\t\trequest->auth_icv_offset) == digest) {\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * If we landed here it means that digest pointer is\n+\t * at different than expected place.\n+\t */\n+\treturn -1;\n+}\n+\n+/*\n+ *-----------------------------------------------------------------------------\n+ * PMD Framework handlers\n+ *-----------------------------------------------------------------------------\n+ */\n+\n+/**\n+ * Enqueue burst.\n+ *\n+ * @param queue_pair Pointer to queue pair.\n+ * @param ops Pointer to ops requests array.\n+ * @param nb_ops Number of elements in ops requests array.\n+ * @returns Number of elements consumed from ops.\n+ */\n+static uint16_t\n+mrvl_crypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,\n+\t\tuint16_t nb_ops)\n+{\n+\tuint16_t iter_ops = 0;\n+\tuint16_t to_enq = 0;\n+\tuint16_t consumed = 0;\n+\tint ret;\n+\tstruct sam_cio_op_params requests[nb_ops];\n+\t/*\n+\t * DPDK uses single fragment buffers, so we can KISS descriptors.\n+\t * SAM does not store bd pointers, so on-stack scope will be enough.\n+\t */\n+\tstruct sam_buf_info src_bd[nb_ops];\n+\tstruct sam_buf_info dst_bd[nb_ops];\n+\tstruct mrvl_crypto_qp *qp = (struct mrvl_crypto_qp *)queue_pair;\n+\n+\tif (nb_ops == 0)\n+\t\treturn 0;\n+\n+\t/* Prepare the burst. */\n+\tmemset(&requests, 0, sizeof(requests));\n+\n+\t/* Iterate through */\n+\tfor (; iter_ops < nb_ops; ++iter_ops) {\n+\t\tif (mrvl_request_prepare(&requests[iter_ops],\n+\t\t\t\t\t&src_bd[iter_ops],\n+\t\t\t\t\t&dst_bd[iter_ops],\n+\t\t\t\t\tops[iter_ops]) < 0) {\n+\t\t\tMRVL_CRYPTO_LOG_ERR(\n+\t\t\t\t\"Error while parameters preparation!\");\n+\t\t\tqp->stats.enqueue_err_count++;\n+\t\t\tops[iter_ops]->status = RTE_CRYPTO_OP_STATUS_ERROR;\n+\n+\t\t\t/*\n+\t\t\t * Number of handled ops is increased\n+\t\t\t * (even if the result of handling is error).\n+\t\t\t */\n+\t\t\t++consumed;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tops[iter_ops]->status =\n+\t\t\tRTE_CRYPTO_OP_STATUS_NOT_PROCESSED;\n+\n+\t\t/* Increase the number of ops to enqueue. */\n+\t\t++to_enq;\n+\t} /* for (; iter_ops < nb_ops;... */\n+\n+\tif (to_enq > 0) {\n+\t\t/* Send the burst */\n+\t\tret = sam_cio_enq(qp->cio, requests, &to_enq);\n+\t\tconsumed += to_enq;\n+\t\tif (ret < 0) {\n+\t\t\t/*\n+\t\t\t * Trust SAM that in this case returned value will be at\n+\t\t\t * some point correct (now it is returned unmodified).\n+\t\t\t */\n+\t\t\tqp->stats.enqueue_err_count += to_enq;\n+\t\t\tfor (iter_ops = 0; iter_ops < to_enq; ++iter_ops)\n+\t\t\t\tops[iter_ops]->status =\n+\t\t\t\t\tRTE_CRYPTO_OP_STATUS_ERROR;\n+\t\t}\n+\t}\n+\n+\tqp->stats.enqueued_count += to_enq;\n+\treturn consumed;\n+}\n+\n+/**\n+ * Dequeue burst.\n+ *\n+ * @param queue_pair Pointer to queue pair.\n+ * @param ops Pointer to ops requests array.\n+ * @param nb_ops Number of elements in ops requests array.\n+ * @returns Number of elements dequeued.\n+ */\n+static uint16_t\n+mrvl_crypto_pmd_dequeue_burst(void *queue_pair,\n+\t\tstruct rte_crypto_op **ops,\n+\t\tuint16_t nb_ops)\n+{\n+\tint ret;\n+\tstruct mrvl_crypto_qp *qp = queue_pair;\n+\tstruct sam_cio *cio = qp->cio;\n+\tstruct sam_cio_op_result results[nb_ops];\n+\tuint16_t i;\n+\n+\tret = sam_cio_deq(cio, results, &nb_ops);\n+\tif (ret < 0) {\n+\t\t/* Count all dequeued as error. */\n+\t\tqp->stats.dequeue_err_count += nb_ops;\n+\n+\t\t/* But act as they were dequeued anyway*/\n+\t\tqp->stats.dequeued_count += nb_ops;\n+\n+\t\treturn 0;\n+\t}\n+\n+\t/* Unpack and check results. */\n+\tfor (i = 0; i < nb_ops; ++i) {\n+\t\tops[i] = results[i].cookie;\n+\n+\t\tswitch (results[i].status) {\n+\t\tcase SAM_CIO_OK:\n+\t\t\tops[i]->status = RTE_CRYPTO_OP_STATUS_SUCCESS;\n+\t\t\tbreak;\n+\t\tcase SAM_CIO_ERR_ICV:\n+\t\t\tMRVL_CRYPTO_LOG_DBG(\"CIO returned SAM_CIO_ERR_ICV.\");\n+\t\t\tops[i]->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tMRVL_CRYPTO_LOG_DBG(\n+\t\t\t\t\"CIO returned Error: %d\", results[i].status);\n+\t\t\tops[i]->status = RTE_CRYPTO_OP_STATUS_ERROR;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tqp->stats.dequeued_count += nb_ops;\n+\treturn nb_ops;\n+}\n+\n+/**\n+ * Create a new crypto device.\n+ *\n+ * @param name Driver name.\n+ * @param vdev Pointer to device structure.\n+ * @param init_params Pointer to initialization parameters.\n+ * @returns 0 in case of success, negative value otherwise.\n+ */\n+static int\n+cryptodev_mrvl_crypto_create(const char *name,\n+\t\tstruct rte_vdev_device *vdev,\n+\t\tstruct rte_crypto_vdev_init_params *init_params)\n+{\n+\tstruct rte_cryptodev *dev;\n+\tstruct mrvl_crypto_private *internals;\n+\tstruct sam_init_params\tsam_params;\n+\tint ret;\n+\n+\tif (init_params->name[0] == '\\0') {\n+\t\tret = rte_cryptodev_pmd_create_dev_name(\n+\t\t\t\tinit_params->name, name);\n+\n+\t\tif (ret < 0) {\n+\t\t\tMRVL_CRYPTO_LOG_ERR(\"failed to create unique name\");\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\tdev = rte_cryptodev_vdev_pmd_init(init_params->name,\n+\t\t\t\tsizeof(struct mrvl_crypto_private),\n+\t\t\t\tinit_params->socket_id, vdev);\n+\tif (dev == NULL) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"failed to create cryptodev vdev\");\n+\t\tgoto init_error;\n+\t}\n+\n+\tdev->driver_id = cryptodev_driver_id;\n+\tdev->dev_ops = rte_mrvl_crypto_pmd_ops;\n+\n+\t/* Register rx/tx burst functions for data path. */\n+\tdev->enqueue_burst = mrvl_crypto_pmd_enqueue_burst;\n+\tdev->dequeue_burst = mrvl_crypto_pmd_dequeue_burst;\n+\n+\tdev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |\n+\t\t\tRTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |\n+\t\t\tRTE_CRYPTODEV_FF_HW_ACCELERATED;\n+\n+\t/* Set vector instructions mode supported */\n+\tinternals = dev->data->dev_private;\n+\n+\tinternals->max_nb_qpairs = init_params->max_nb_queue_pairs;\n+\tinternals->max_nb_sessions = init_params->max_nb_sessions;\n+\n+\t/*\n+\t * ret == -EEXIST is correct, it means DMA\n+\t * has been already initialized.\n+\t */\n+\tret = mv_sys_dma_mem_init(RTE_MRVL_MUSDK_DMA_MEMSIZE);\n+\tif ((ret < 0) && (ret != -EEXIST))\n+\t\treturn ret;\n+\n+\tsam_params.max_num_sessions = internals->max_nb_sessions;\n+\n+\treturn sam_init(&sam_params);\n+\n+init_error:\n+\tMRVL_CRYPTO_LOG_ERR(\n+\t\t\"driver %s: %s failed\", init_params->name, __func__);\n+\n+\tcryptodev_mrvl_crypto_uninit(vdev);\n+\treturn -EFAULT;\n+}\n+\n+/**\n+ * Initialize the crypto device.\n+ *\n+ * @param vdev Pointer to device structure.\n+ * @returns 0 in case of success, negative value otherwise.\n+ */\n+static int\n+cryptodev_mrvl_crypto_init(struct rte_vdev_device *vdev)\n+{\n+\tstruct rte_crypto_vdev_init_params init_params = { };\n+\tconst char *name;\n+\tconst char *input_args;\n+\tint ret;\n+\n+\tname = rte_vdev_device_name(vdev);\n+\tif (name == NULL)\n+\t\treturn -EINVAL;\n+\tinput_args = rte_vdev_device_args(vdev);\n+\n+\tif (!input_args)\n+\t\treturn -EINVAL;\n+\n+\tinit_params.max_nb_queue_pairs = sam_get_num_inst() * SAM_HW_RING_NUM;\n+\tinit_params.max_nb_sessions =\n+\t\tRTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS;\n+\tinit_params.socket_id = rte_socket_id();\n+\n+\tret = rte_cryptodev_vdev_parse_init_params(&init_params, input_args);\n+\tif (ret) {\n+\t\tRTE_LOG(ERR, PMD, \"Failed to parse input arguments\\n\");\n+\t\treturn ret;\n+\t}\n+\n+\tRTE_LOG(INFO, PMD, \"Initialising %s on NUMA node %d\\n\", name,\n+\t\t\tinit_params.socket_id);\n+\tif (init_params.name[0] != '\\0') {\n+\t\tRTE_LOG(INFO, PMD, \"  User defined name = %s\\n\",\n+\t\t\tinit_params.name);\n+\t}\n+\tRTE_LOG(INFO, PMD, \"  Max number of queue pairs = %d\\n\",\n+\t\t\tinit_params.max_nb_queue_pairs);\n+\tRTE_LOG(INFO, PMD, \"  Max number of sessions = %d\\n\",\n+\t\t\tinit_params.max_nb_sessions);\n+\n+\treturn cryptodev_mrvl_crypto_create(name, vdev, &init_params);\n+}\n+\n+/**\n+ * Uninitialize the crypto device\n+ *\n+ * @param vdev Pointer to device structure.\n+ * @returns 0 in case of success, negative value otherwise.\n+ */\n+static int\n+cryptodev_mrvl_crypto_uninit(struct rte_vdev_device *vdev)\n+{\n+\tconst char *name = rte_vdev_device_name(vdev);\n+\n+\tif (name == NULL)\n+\t\treturn -EINVAL;\n+\n+\tRTE_LOG(INFO, PMD,\n+\t\t\"Closing Marvell crypto device %s on numa socket %u\\n\",\n+\t\tname, rte_socket_id());\n+\n+\tsam_deinit();\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Basic driver handlers for use in the constructor.\n+ */\n+static struct rte_vdev_driver cryptodev_mrvl_pmd_drv = {\n+\t.probe = cryptodev_mrvl_crypto_init,\n+\t.remove = cryptodev_mrvl_crypto_uninit\n+};\n+\n+static struct cryptodev_driver mrvl_crypto_drv;\n+\n+/* Register the driver in constructor. */\n+RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_MRVL_PMD, cryptodev_mrvl_pmd_drv);\n+RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_MRVL_PMD,\n+\t\"max_nb_queue_pairs=<int> \"\n+\t\"max_nb_sessions=<int> \"\n+\t\"socket_id=<int>\");\n+RTE_PMD_REGISTER_CRYPTO_DRIVER(mrvl_crypto_drv, cryptodev_mrvl_pmd_drv,\n+\t\tcryptodev_driver_id);\ndiff --git a/drivers/crypto/mrvl/rte_mrvl_pmd_ops.c b/drivers/crypto/mrvl/rte_mrvl_pmd_ops.c\nnew file mode 100644\nindex 0000000..495fec6\n--- /dev/null\n+++ b/drivers/crypto/mrvl/rte_mrvl_pmd_ops.c\n@@ -0,0 +1,776 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright (C) Semihalf 2017. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Semihalf nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <string.h>\n+\n+#include <rte_common.h>\n+#include <rte_malloc.h>\n+#include <rte_cryptodev_pmd.h>\n+\n+#include \"rte_mrvl_pmd_private.h\"\n+\n+/**\n+ * Capabilities list to be used in reporting to DPDK.\n+ */\n+static const struct rte_cryptodev_capabilities\n+\tmrvl_crypto_pmd_capabilities[] = {\n+\t{\t/* MD5 HMAC */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t{.auth = {\n+\t\t\t\t.algo = RTE_CRYPTO_AUTH_MD5_HMAC,\n+\t\t\t\t.block_size = 64,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 1,\n+\t\t\t\t\t.max = 64,\n+\t\t\t\t\t.increment = 1\n+\t\t\t\t},\n+\t\t\t\t.digest_size = {\n+\t\t\t\t\t.min = 16,\n+\t\t\t\t\t.max = 16,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\t{\t/* MD5 */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t\t{.sym = {\n+\t\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t\t{.auth = {\n+\t\t\t\t\t.algo = RTE_CRYPTO_AUTH_MD5,\n+\t\t\t\t\t.block_size = 64,\n+\t\t\t\t\t.key_size = {\n+\t\t\t\t\t\t.min = 0,\n+\t\t\t\t\t\t.max = 0,\n+\t\t\t\t\t\t.increment = 0\n+\t\t\t\t\t},\n+\t\t\t\t\t.digest_size = {\n+\t\t\t\t\t\t.min = 16,\n+\t\t\t\t\t\t.max = 16,\n+\t\t\t\t\t\t.increment = 0\n+\t\t\t\t\t},\n+\t\t\t\t}, }\n+\t\t\t}, }\n+\t},\n+\t{\t/* SHA1 HMAC */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t\t{.sym = {\n+\t\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t\t{.auth = {\n+\t\t\t\t\t.algo = RTE_CRYPTO_AUTH_SHA1_HMAC,\n+\t\t\t\t\t.block_size = 64,\n+\t\t\t\t\t.key_size = {\n+\t\t\t\t\t\t.min = 1,\n+\t\t\t\t\t\t.max = 64,\n+\t\t\t\t\t\t.increment = 1\n+\t\t\t\t\t},\n+\t\t\t\t\t.digest_size = {\n+\t\t\t\t\t\t.min = 20,\n+\t\t\t\t\t\t.max = 20,\n+\t\t\t\t\t\t.increment = 0\n+\t\t\t\t\t},\n+\t\t\t\t}, }\n+\t\t\t}, }\n+\t},\n+\t{\t/* SHA1 */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t{.auth = {\n+\t\t\t\t.algo = RTE_CRYPTO_AUTH_SHA1,\n+\t\t\t\t.block_size = 64,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 0,\n+\t\t\t\t\t.max = 0,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t\t.digest_size = {\n+\t\t\t\t\t.min = 20,\n+\t\t\t\t\t.max = 20,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\t{\t/* SHA224 */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t{.auth = {\n+\t\t\t\t.algo = RTE_CRYPTO_AUTH_SHA224,\n+\t\t\t\t.block_size = 64,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 0,\n+\t\t\t\t\t.max = 0,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t\t.digest_size = {\n+\t\t\t\t\t.min = 28,\n+\t\t\t\t\t.max = 28,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\t{\t/* SHA256 HMAC */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t\t{.sym = {\n+\t\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t\t{.auth = {\n+\t\t\t\t\t.algo = RTE_CRYPTO_AUTH_SHA256_HMAC,\n+\t\t\t\t\t.block_size = 64,\n+\t\t\t\t\t.key_size = {\n+\t\t\t\t\t\t.min = 1,\n+\t\t\t\t\t\t.max = 64,\n+\t\t\t\t\t\t.increment = 1\n+\t\t\t\t\t},\n+\t\t\t\t\t.digest_size = {\n+\t\t\t\t\t\t.min = 32,\n+\t\t\t\t\t\t.max = 32,\n+\t\t\t\t\t\t.increment = 0\n+\t\t\t\t\t},\n+\t\t\t\t}, }\n+\t\t\t}, }\n+\t},\n+\t{\t/* SHA256 */\n+\t\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t\t{.sym = {\n+\t\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t\t{.auth = {\n+\t\t\t\t\t.algo = RTE_CRYPTO_AUTH_SHA256,\n+\t\t\t\t\t.block_size = 64,\n+\t\t\t\t\t.key_size = {\n+\t\t\t\t\t\t.min = 0,\n+\t\t\t\t\t\t.max = 0,\n+\t\t\t\t\t\t.increment = 0\n+\t\t\t\t\t},\n+\t\t\t\t\t.digest_size = {\n+\t\t\t\t\t\t.min = 32,\n+\t\t\t\t\t\t.max = 32,\n+\t\t\t\t\t\t.increment = 0\n+\t\t\t\t\t},\n+\t\t\t\t}, }\n+\t\t\t}, }\n+\t\t},\n+\t{\t/* SHA384 HMAC */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t{.auth = {\n+\t\t\t\t.algo = RTE_CRYPTO_AUTH_SHA384_HMAC,\n+\t\t\t\t.block_size = 128,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 1,\n+\t\t\t\t\t.max = 128,\n+\t\t\t\t\t.increment = 1\n+\t\t\t\t},\n+\t\t\t\t.digest_size = {\n+\t\t\t\t\t.min = 48,\n+\t\t\t\t\t.max = 48,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\t{\t/* SHA384 */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t{.auth = {\n+\t\t\t\t.algo = RTE_CRYPTO_AUTH_SHA384,\n+\t\t\t\t.block_size = 128,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 0,\n+\t\t\t\t\t.max = 0,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t\t.digest_size = {\n+\t\t\t\t\t.min = 48,\n+\t\t\t\t\t.max = 48,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\t{\t/* SHA512 HMAC */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t{.auth = {\n+\t\t\t\t.algo = RTE_CRYPTO_AUTH_SHA512_HMAC,\n+\t\t\t\t.block_size = 128,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 1,\n+\t\t\t\t\t.max = 128,\n+\t\t\t\t\t.increment = 1\n+\t\t\t\t},\n+\t\t\t\t.digest_size = {\n+\t\t\t\t\t.min = 64,\n+\t\t\t\t\t.max = 64,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\t{\t/* SHA512  */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t{.auth = {\n+\t\t\t\t.algo = RTE_CRYPTO_AUTH_SHA512,\n+\t\t\t\t.block_size = 128,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 0,\n+\t\t\t\t\t.max = 0,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t\t.digest_size = {\n+\t\t\t\t\t.min = 64,\n+\t\t\t\t\t.max = 64,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\t{\t/* AES CBC */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t\t{.sym = {\n+\t\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,\n+\t\t\t\t{.cipher = {\n+\t\t\t\t\t.algo = RTE_CRYPTO_CIPHER_AES_CBC,\n+\t\t\t\t\t.block_size = 16,\n+\t\t\t\t\t.key_size = {\n+\t\t\t\t\t\t.min = 16,\n+\t\t\t\t\t\t.max = 32,\n+\t\t\t\t\t\t.increment = 8\n+\t\t\t\t\t},\n+\t\t\t\t\t.iv_size = {\n+\t\t\t\t\t\t.min = 16,\n+\t\t\t\t\t\t.max = 16,\n+\t\t\t\t\t\t.increment = 0\n+\t\t\t\t\t}\n+\t\t\t\t}, }\n+\t\t\t}, }\n+\t},\n+\t{\t/* AES CTR */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,\n+\t\t\t{.cipher = {\n+\t\t\t\t.algo = RTE_CRYPTO_CIPHER_AES_CTR,\n+\t\t\t\t.block_size = 16,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 16,\n+\t\t\t\t\t.max = 32,\n+\t\t\t\t\t.increment = 8\n+\t\t\t\t},\n+\t\t\t\t.iv_size = {\n+\t\t\t\t\t.min = 16,\n+\t\t\t\t\t.max = 16,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t}\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\t{\t/* AES GCM */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,\n+\t\t\t{.aead = {\n+\t\t\t\t.algo = RTE_CRYPTO_AEAD_AES_GCM,\n+\t\t\t\t.block_size = 16,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 16,\n+\t\t\t\t\t.max = 32,\n+\t\t\t\t\t.increment = 8\n+\t\t\t\t},\n+\t\t\t\t.digest_size = {\n+\t\t\t\t\t.min = 16,\n+\t\t\t\t\t.max = 16,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t\t.aad_size = {\n+\t\t\t\t\t.min = 8,\n+\t\t\t\t\t.max = 12,\n+\t\t\t\t\t.increment = 4\n+\t\t\t\t},\n+\t\t\t\t.iv_size = {\n+\t\t\t\t\t.min = 12,\n+\t\t\t\t\t.max = 16,\n+\t\t\t\t\t.increment = 4\n+\t\t\t\t}\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\t{\t/* AES GMAC (AUTH) */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,\n+\t\t\t{.auth = {\n+\t\t\t\t.algo = RTE_CRYPTO_AUTH_AES_GMAC,\n+\t\t\t\t.block_size = 16,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 16,\n+\t\t\t\t\t.max = 32,\n+\t\t\t\t\t.increment = 8\n+\t\t\t\t},\n+\t\t\t\t.digest_size = {\n+\t\t\t\t\t.min = 16,\n+\t\t\t\t\t.max = 16,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t\t.iv_size = {\n+\t\t\t\t\t.min = 8,\n+\t\t\t\t\t.max = 65532,\n+\t\t\t\t\t.increment = 4\n+\t\t\t\t}\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\t{\t/* 3DES CBC */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,\n+\t\t\t{.cipher = {\n+\t\t\t\t.algo = RTE_CRYPTO_CIPHER_3DES_CBC,\n+\t\t\t\t.block_size = 8,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 24,\n+\t\t\t\t\t.max = 24,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t\t.iv_size = {\n+\t\t\t\t\t.min = 8,\n+\t\t\t\t\t.max = 8,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t}\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\t{\t/* 3DES CTR */\n+\t\t.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t{.sym = {\n+\t\t\t.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,\n+\t\t\t{.cipher = {\n+\t\t\t\t.algo = RTE_CRYPTO_CIPHER_3DES_CTR,\n+\t\t\t\t.block_size = 8,\n+\t\t\t\t.key_size = {\n+\t\t\t\t\t.min = 24,\n+\t\t\t\t\t.max = 24,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t},\n+\t\t\t\t.iv_size = {\n+\t\t\t\t\t.min = 8,\n+\t\t\t\t\t.max = 8,\n+\t\t\t\t\t.increment = 0\n+\t\t\t\t}\n+\t\t\t}, }\n+\t\t}, }\n+\t},\n+\n+\tRTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()\n+};\n+\n+\n+/**\n+ * Configure device (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @param config Pointer to configuration structure.\n+ * @returns 0. Always.\n+ */\n+static int\n+mrvl_crypto_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+/**\n+ * Start device (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @returns 0. Always.\n+ */\n+static int\n+mrvl_crypto_pmd_start(__rte_unused struct rte_cryptodev *dev)\n+{\n+\treturn 0;\n+}\n+\n+/**\n+ * Stop device (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @returns 0. Always.\n+ */\n+static void\n+mrvl_crypto_pmd_stop(__rte_unused struct rte_cryptodev *dev)\n+{\n+}\n+\n+/**\n+ * Get device statistics (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @param stats Pointer to statistics structure [out].\n+ */\n+static void\n+mrvl_crypto_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 mrvl_crypto_qp *qp = dev->data->queue_pairs[qp_id];\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+/**\n+ * Reset device statistics (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure.\n+ */\n+static void\n+mrvl_crypto_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 mrvl_crypto_qp *qp = dev->data->queue_pairs[qp_id];\n+\n+\t\tmemset(&qp->stats, 0, sizeof(qp->stats));\n+\t}\n+}\n+\n+/**\n+ * Get device info (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @param dev_info Pointer to the device info structure [out].\n+ */\n+static void\n+mrvl_crypto_pmd_info_get(struct rte_cryptodev *dev,\n+\t\tstruct rte_cryptodev_info *dev_info)\n+{\n+\tstruct mrvl_crypto_private *internals = dev->data->dev_private;\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 = mrvl_crypto_pmd_capabilities;\n+\t\tdev_info->max_nb_queue_pairs = internals->max_nb_qpairs;\n+\t\tdev_info->sym.max_nb_sessions = internals->max_nb_sessions;\n+\t}\n+}\n+\n+/**\n+ * Release queue pair (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @param qp_id ID of Queue Pair to release.\n+ * @returns 0. Always.\n+ */\n+static int\n+mrvl_crypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)\n+{\n+\tstruct mrvl_crypto_qp *qp =\n+\t\t\t(struct mrvl_crypto_qp *)dev->data->queue_pairs[qp_id];\n+\n+\tif (dev->data->queue_pairs[qp_id] != NULL) {\n+\t\tsam_cio_flush(qp->cio);\n+\t\tsam_cio_deinit(qp->cio);\n+\t\trte_free(dev->data->queue_pairs[qp_id]);\n+\t\tdev->data->queue_pairs[qp_id] = NULL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Close device (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @returns 0. Always.\n+ */\n+static int\n+mrvl_crypto_pmd_close(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\tmrvl_crypto_pmd_qp_release(dev, qp_id);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Setup a queue pair (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @param qp_id ID of the Queue Pair.\n+ * @param qp_conf Queue pair configuration (nb of descriptors).\n+ * @param socket_id NUMA socket to allocate memory on.\n+ * @returns 0 upon success, negative value otherwise.\n+ */\n+static int\n+mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,\n+\t\tconst struct rte_cryptodev_qp_conf *qp_conf,\n+\t\tint socket_id, struct rte_mempool *session_pool)\n+{\n+\tstruct mrvl_crypto_qp *qp = NULL;\n+\tchar match[RTE_CRYPTODEV_NAME_LEN];\n+\tunsigned int n;\n+\n+\t/* Allocate the queue pair data structure. */\n+\tqp = rte_zmalloc_socket(\"MRVL Crypto PMD Queue Pair\", sizeof(*qp),\n+\t\t\t\t\tRTE_CACHE_LINE_SIZE, socket_id);\n+\tif (qp == NULL)\n+\t\treturn -ENOMEM;\n+\n+\t/* Free old qp prior setup if needed. */\n+\tif (dev->data->queue_pairs[qp_id] != NULL)\n+\t\tmrvl_crypto_pmd_qp_release(dev, qp_id);\n+\n+\tdo { /* Error handling block */\n+\n+\t\t/*\n+\t\t * This extra check is necessary due to a bug in\n+\t\t * crypto library.\n+\t\t */\n+\t\tint num = sam_get_num_inst();\n+\t\tif (num == 0) {\n+\t\t\tMRVL_CRYPTO_LOG_ERR(\"No crypto engines detected.\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t/*\n+\t\t * In case two crypto engines are enabled qps will\n+\t\t * be evenly spread among them. Even and odd qps will\n+\t\t * be handled by cio-0 and cio-1 respectively. qp-cio mapping\n+\t\t * will look as follows:\n+\t\t *\n+\t\t * qp:      0        1        2        3\n+\t\t * cio-x:y: cio-0:0, cio-1:0, cio-0:1, cio-1:1\n+\t\t *\n+\t\t * qp:      4        5        6        7\n+\t\t * cio-x:y: cio-0:2, cio-1:2, cio-0:3, cio-1:3\n+\t\t *\n+\t\t * In case just one engine is enabled mapping will look as\n+\t\t * follows:\n+\t\t * qp:      0        1        2        3\n+\t\t * cio-x:y: cio-0:0, cio-0:1, cio-0:2, cio-0:3\n+\t\t */\n+\t\tn = snprintf(match, sizeof(match), \"cio-%u:%u\",\n+\t\t\t\tqp_id % num, qp_id / num);\n+\n+\t\tif (n >= sizeof(match))\n+\t\t\tbreak;\n+\n+\t\tqp->cio_params.match = match;\n+\t\tqp->cio_params.size = qp_conf->nb_descriptors;\n+\n+\t\tif (sam_cio_init(&qp->cio_params, &qp->cio) < 0)\n+\t\t\tbreak;\n+\n+\t\tqp->sess_mp = session_pool;\n+\n+\t\tmemset(&qp->stats, 0, sizeof(qp->stats));\n+\t\tdev->data->queue_pairs[qp_id] = qp;\n+\t\treturn 0;\n+\t} while (0);\n+\n+\trte_free(qp);\n+\treturn -1;\n+}\n+\n+/** Start queue pair (PMD ops callback) - not supported.\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @param qp_id ID of the Queue Pair.\n+ * @returns -ENOTSUP. Always.\n+ */\n+static int\n+mrvl_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,\n+\t\t__rte_unused uint16_t queue_pair_id)\n+{\n+\treturn -ENOTSUP;\n+}\n+\n+/** Stop queue pair (PMD ops callback) - not supported.\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @param qp_id ID of the Queue Pair.\n+ * @returns -ENOTSUP. Always.\n+ */\n+static int\n+mrvl_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,\n+\t\t__rte_unused uint16_t queue_pair_id)\n+{\n+\treturn -ENOTSUP;\n+}\n+\n+/** Return the number of allocated queue pairs (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @returns Number of allocated queue pairs.\n+ */\n+static uint32_t\n+mrvl_crypto_pmd_qp_count(struct rte_cryptodev *dev)\n+{\n+\treturn dev->data->nb_queue_pairs;\n+}\n+\n+/** Returns the size of the session structure (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure [Unused].\n+ * @returns Size of Marvell crypto session.\n+ */\n+static unsigned\n+mrvl_crypto_pmd_session_get_size(__rte_unused struct rte_cryptodev *dev)\n+{\n+\treturn sizeof(struct mrvl_crypto_session);\n+}\n+\n+/** Configure the session from a crypto xform chain (PMD ops callback).\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @param xform Pointer to the crytpo configuration structure.\n+ * @param sess Pointer to the empty session structure.\n+ * @returns 0 upon success, negative value otherwise.\n+ */\n+static int\n+mrvl_crypto_pmd_session_configure(__rte_unused struct rte_cryptodev *dev,\n+\t\tstruct rte_crypto_sym_xform *xform,\n+\t\tstruct rte_cryptodev_sym_session *sess,\n+\t\tstruct rte_mempool *mp)\n+{\n+\tstruct mrvl_crypto_session *mrvl_sess;\n+\tvoid *sess_private_data;\n+\tint ret;\n+\n+\tif (sess == NULL) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Invalid session struct.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (rte_mempool_get(mp, &sess_private_data)) {\n+\t\tCDEV_LOG_ERR(\"Couldn't get object from session mempool.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tret = mrvl_crypto_set_session_parameters(sess_private_data, xform);\n+\tif (ret != 0) {\n+\t\tMRVL_CRYPTO_LOG_ERR(\"Failed to configure session parameters.\");\n+\n+\t\t/* Return session to mempool */\n+\t\trte_mempool_put(mp, sess_private_data);\n+\t\treturn ret;\n+\t}\n+\n+\tset_session_private_data(sess, dev->driver_id, sess_private_data);\n+\n+\tmrvl_sess = (struct mrvl_crypto_session *)sess_private_data;\n+\tif (sam_session_create(&mrvl_sess->sam_sess_params,\n+\t\t\t\t&mrvl_sess->sam_sess) < 0) {\n+\t\tMRVL_CRYPTO_LOG_DBG(\"Failed to create session!\");\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Clear the memory of session so it doesn't leave key material behind.\n+ *\n+ * @param dev Pointer to the device structure.\n+ * @returns 0. Always.\n+ */\n+static void\n+mrvl_crypto_pmd_session_clear(struct rte_cryptodev *dev,\n+\t\tstruct rte_cryptodev_sym_session *sess)\n+{\n+\n+\tuint8_t index = dev->driver_id;\n+\tvoid *sess_priv = get_session_private_data(sess, index);\n+\n+\t/* Zero out the whole structure */\n+\tif (sess_priv) {\n+\t\tstruct mrvl_crypto_session *mrvl_sess =\n+\t\t\t(struct mrvl_crypto_session *)sess_priv;\n+\n+\t\tif (mrvl_sess->sam_sess &&\n+\t\t    sam_session_destroy(mrvl_sess->sam_sess) < 0) {\n+\t\t\tMRVL_CRYPTO_LOG_INFO(\"Error while destroying session!\");\n+\t\t}\n+\n+\t\tmemset(sess, 0, sizeof(struct mrvl_crypto_session));\n+\t\tstruct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);\n+\t\tset_session_private_data(sess, index, NULL);\n+\t\trte_mempool_put(sess_mp, sess_priv);\n+\t}\n+}\n+\n+/**\n+ * PMD handlers for crypto ops.\n+ */\n+static struct rte_cryptodev_ops mrvl_crypto_pmd_ops = {\n+\t\t.dev_configure\t\t= mrvl_crypto_pmd_config,\n+\t\t.dev_start\t\t= mrvl_crypto_pmd_start,\n+\t\t.dev_stop\t\t= mrvl_crypto_pmd_stop,\n+\t\t.dev_close\t\t= mrvl_crypto_pmd_close,\n+\n+\t\t.dev_infos_get\t\t= mrvl_crypto_pmd_info_get,\n+\n+\t\t.stats_get\t\t= mrvl_crypto_pmd_stats_get,\n+\t\t.stats_reset\t\t= mrvl_crypto_pmd_stats_reset,\n+\n+\t\t.queue_pair_setup\t= mrvl_crypto_pmd_qp_setup,\n+\t\t.queue_pair_release\t= mrvl_crypto_pmd_qp_release,\n+\t\t.queue_pair_start\t= mrvl_crypto_pmd_qp_start,\n+\t\t.queue_pair_stop\t= mrvl_crypto_pmd_qp_stop,\n+\t\t.queue_pair_count\t= mrvl_crypto_pmd_qp_count,\n+\n+\t\t.session_get_size\t= mrvl_crypto_pmd_session_get_size,\n+\t\t.session_configure\t= mrvl_crypto_pmd_session_configure,\n+\t\t.session_clear\t\t= mrvl_crypto_pmd_session_clear\n+};\n+\n+struct rte_cryptodev_ops *rte_mrvl_crypto_pmd_ops = &mrvl_crypto_pmd_ops;\ndiff --git a/drivers/crypto/mrvl/rte_mrvl_pmd_private.h b/drivers/crypto/mrvl/rte_mrvl_pmd_private.h\nnew file mode 100644\nindex 0000000..2da14b8\n--- /dev/null\n+++ b/drivers/crypto/mrvl/rte_mrvl_pmd_private.h\n@@ -0,0 +1,121 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright (C) Semihalf 2017. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Semihalf nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _RTE_MRVL_PMD_PRIVATE_H_\n+#define _RTE_MRVL_PMD_PRIVATE_H_\n+\n+#include \"rte_mrvl_compat.h\"\n+\n+#define CRYPTODEV_NAME_MRVL_PMD crypto_mrvl\n+/**< Marvell PMD device name */\n+\n+#define MRVL_CRYPTO_LOG_ERR(fmt, args...) \\\n+\tRTE_LOG(ERR, CRYPTODEV, \"[%s] %s() line %u: \" fmt \"\\n\",  \\\n+\t\t\tRTE_STR(CRYPTODEV_NAME_MRVL_CRYPTO_PMD), \\\n+\t\t\t__func__, __LINE__, ## args)\n+\n+#ifdef RTE_LIBRTE_MRVL_CRYPTO_DEBUG\n+#define MRVL_CRYPTO_LOG_INFO(fmt, args...) \\\n+\tRTE_LOG(INFO, CRYPTODEV, \"[%s] %s() line %u: \" fmt \"\\n\", \\\n+\t\t\tRTE_STR(CRYPTODEV_NAME_MRVL_CRYPTO_PMD), \\\n+\t\t\t__func__, __LINE__, ## args)\n+\n+#define MRVL_CRYPTO_LOG_DBG(fmt, args...) \\\n+\tRTE_LOG(DEBUG, CRYPTODEV, \"[%s] %s() line %u: \" fmt \"\\n\", \\\n+\t\t\tRTE_STR(CRYPTODEV_NAME_MRVL_CRYPTO_PMD), \\\n+\t\t\t__func__, __LINE__, ## args)\n+\n+#else\n+#define MRVL_CRYPTO_LOG_INFO(fmt, args...)\n+#define MRVL_CRYPTO_LOG_DBG(fmt, args...)\n+#endif\n+\n+/**\n+ * Handy bits->bytes conversion macro.\n+ */\n+#define BITS2BYTES(x) ((x) >> 3)\n+\n+/** The operation order mode enumerator. */\n+enum mrvl_crypto_chain_order {\n+\tMRVL_CRYPTO_CHAIN_CIPHER_ONLY,\n+\tMRVL_CRYPTO_CHAIN_AUTH_ONLY,\n+\tMRVL_CRYPTO_CHAIN_CIPHER_AUTH,\n+\tMRVL_CRYPTO_CHAIN_AUTH_CIPHER,\n+\tMRVL_CRYPTO_CHAIN_COMBINED,\n+\tMRVL_CRYPTO_CHAIN_NOT_SUPPORTED,\n+};\n+\n+/** Private data structure for each crypto device. */\n+struct mrvl_crypto_private {\n+\tunsigned int max_nb_qpairs;\t/**< Max number of queue pairs */\n+\tunsigned int max_nb_sessions;\t/**< Max number of sessions */\n+};\n+\n+/** MRVL crypto queue pair structure. */\n+struct mrvl_crypto_qp {\n+\t/** SAM CIO (MUSDK Queue Pair equivalent).*/\n+\tstruct sam_cio *cio;\n+\n+\t/** Session Mempool. */\n+\tstruct rte_mempool *sess_mp;\n+\n+\t/** Queue pair statistics. */\n+\tstruct rte_cryptodev_stats stats;\n+\n+\t/** CIO initialization parameters.*/\n+\tstruct sam_cio_params cio_params;\n+} __rte_cache_aligned;\n+\n+/** MRVL crypto private session structure. */\n+struct mrvl_crypto_session {\n+\t/** Crypto operations chain order. */\n+\tenum mrvl_crypto_chain_order chain_order;\n+\n+\t/** Session initialization parameters. */\n+\tstruct sam_session_params sam_sess_params;\n+\n+\t/** SAM session pointer. */\n+\tstruct sam_sa *sam_sess;\n+\n+\t/** Cipher IV offset. */\n+\tuint16_t cipher_iv_offset;\n+} __rte_cache_aligned;\n+\n+/** Set and validate MRVL crypto session parameters */\n+extern int\n+mrvl_crypto_set_session_parameters(struct mrvl_crypto_session *sess,\n+\t\tconst struct rte_crypto_sym_xform *xform);\n+\n+/** device specific operations function pointer structure */\n+extern struct rte_cryptodev_ops *rte_mrvl_crypto_pmd_ops;\n+\n+#endif /* _RTE_MRVL_PMD_PRIVATE_H_ */\ndiff --git a/drivers/crypto/mrvl/rte_pmd_mrvl_version.map b/drivers/crypto/mrvl/rte_pmd_mrvl_version.map\nnew file mode 100644\nindex 0000000..a753031\n--- /dev/null\n+++ b/drivers/crypto/mrvl/rte_pmd_mrvl_version.map\n@@ -0,0 +1,3 @@\n+DPDK_17.11 {\n+\tlocal: *;\n+};\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex 51b97e3..c6d21df 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -172,6 +172,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC)         += -lrte_pmd_zuc\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC)         += -L$(LIBSSO_ZUC_PATH)/build -lsso_zuc\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO)    += -lrte_pmd_armv8\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO)    += -L$(ARMV8_CRYPTO_LIB_PATH) -larmv8_crypto\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_MRVL_CRYPTO) += -L$(LIBMUSDK_PATH)/lib -lrte_pmd_mrvl_crypto -lmusdk\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER) += -lrte_pmd_crypto_scheduler\n ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC)   += -lrte_pmd_dpaa2_sec\n",
    "prefixes": [
        "dpdk-dev",
        "v4",
        "1/4"
    ]
}