get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 67798,
    "url": "https://patches.dpdk.org/api/patches/67798/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20200403163656.60545-3-david.coyle@intel.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": "<20200403163656.60545-3-david.coyle@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200403163656.60545-3-david.coyle@intel.com",
    "date": "2020-04-03T16:36:54",
    "name": "[v2,2/4] raw/aesni_mb: add aesni_mb raw device",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "e6d1c425ff7a41e41e3001321561a6d00d1ad4eb",
    "submitter": {
        "id": 961,
        "url": "https://patches.dpdk.org/api/people/961/?format=api",
        "name": "Coyle, David",
        "email": "david.coyle@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20200403163656.60545-3-david.coyle@intel.com/mbox/",
    "series": [
        {
            "id": 9194,
            "url": "https://patches.dpdk.org/api/series/9194/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=9194",
            "date": "2020-04-03T16:36:52",
            "name": "introduce multi-function processing support",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/9194/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/67798/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/67798/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 7CA40A0562;\n\tFri,  3 Apr 2020 18:48:59 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id D61321C1ED;\n\tFri,  3 Apr 2020 18:48:40 +0200 (CEST)",
            "from mga17.intel.com (mga17.intel.com [192.55.52.151])\n by dpdk.org (Postfix) with ESMTP id 71CEF1C1DE\n for <dev@dpdk.org>; Fri,  3 Apr 2020 18:48:38 +0200 (CEST)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 03 Apr 2020 09:48:38 -0700",
            "from silpixa00399912.ir.intel.com (HELO\n silpixa00399912.ger.corp.intel.com) ([10.237.223.64])\n by fmsmga004.fm.intel.com with ESMTP; 03 Apr 2020 09:48:35 -0700"
        ],
        "IronPort-SDR": [
            "\n WPNmdJcYsBBpl9Q2HsKw9GeE/KeyU/etnW3UNN/s9E+oYLhHgCkvBcTKO7A6D0RFwO+sPSHFGn\n oslj8qPTg+uQ==",
            "\n b2mBGYksB/pTrv1b6nsHc1h6+ZYoKxSlbVuKbDPazbEXXg3rIpyLSj/2u/Q8WzmAjr/RijxfQD\n /9nkWr3w8IjA=="
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.72,340,1580803200\"; d=\"scan'208\";a=\"274016897\"",
        "From": "David Coyle <david.coyle@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "declan.doherty@intel.com, fiona.trahe@intel.com,\n pablo.de.lara.guarch@intel.com, brendan.ryan@intel.com,\n shreyansh.jain@nxp.com, hemant.agrawal@nxp.com,\n David Coyle <david.coyle@intel.com>,\n Mairtin o Loingsigh <mairtin.oloingsigh@intel.com>",
        "Date": "Fri,  3 Apr 2020 17:36:54 +0100",
        "Message-Id": "<20200403163656.60545-3-david.coyle@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20200403163656.60545-1-david.coyle@intel.com>",
        "References": "<20200403163656.60545-1-david.coyle@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 2/4] raw/aesni_mb: add aesni_mb raw device",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "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": "Adding an AESNI-MB raw device, thereby exposing AESNI-MB to the\nrawdev API. The AESNI-MB raw device will use the multi-function\ninterface to allow combined operations be sent to the AESNI-MB\nsoftware library.\n\nSigned-off-by: David Coyle <david.coyle@intel.com>\nSigned-off-by: Mairtin o Loingsigh <mairtin.oloingsigh@intel.com>\n---\n config/common_base                            |    6 +\n drivers/raw/Makefile                          |    2 +\n drivers/raw/aesni_mb/Makefile                 |   47 +\n drivers/raw/aesni_mb/aesni_mb_rawdev.c        | 1536 +++++++++++++++++\n drivers/raw/aesni_mb/aesni_mb_rawdev.h        |  112 ++\n drivers/raw/aesni_mb/aesni_mb_rawdev_test.c   | 1102 ++++++++++++\n .../aesni_mb/aesni_mb_rawdev_test_vectors.h   | 1183 +++++++++++++\n drivers/raw/aesni_mb/meson.build              |   26 +\n .../aesni_mb/rte_rawdev_aesni_mb_version.map  |    3 +\n drivers/raw/meson.build                       |    3 +-\n mk/rte.app.mk                                 |    2 +\n 11 files changed, 4021 insertions(+), 1 deletion(-)\n create mode 100644 drivers/raw/aesni_mb/Makefile\n create mode 100644 drivers/raw/aesni_mb/aesni_mb_rawdev.c\n create mode 100644 drivers/raw/aesni_mb/aesni_mb_rawdev.h\n create mode 100644 drivers/raw/aesni_mb/aesni_mb_rawdev_test.c\n create mode 100644 drivers/raw/aesni_mb/aesni_mb_rawdev_test_vectors.h\n create mode 100644 drivers/raw/aesni_mb/meson.build\n create mode 100644 drivers/raw/aesni_mb/rte_rawdev_aesni_mb_version.map",
    "diff": "diff --git a/config/common_base b/config/common_base\nindex 4f004968b..7ac6a3428 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -818,6 +818,12 @@ CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_EP_RAWDEV=y\n #\n CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y\n \n+#\n+# Compile PMD for AESNI raw device\n+#\n+CONFIG_RTE_LIBRTE_PMD_AESNI_MB_RAWDEV=n\n+CONFIG_RTE_LIBRTE_PMD_AESNI_MB_RAWDEV_DEBUG=n\n+\n #\n # Compile multi-fn raw device interface\n #\ndiff --git a/drivers/raw/Makefile b/drivers/raw/Makefile\nindex e16da8d95..5aa608e1e 100644\n--- a/drivers/raw/Makefile\n+++ b/drivers/raw/Makefile\n@@ -15,5 +15,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb\n DIRS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_DMA_RAWDEV) += octeontx2_dma\n DIRS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_EP_RAWDEV) += octeontx2_ep\n DIRS-y += common\n+DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB_RAWDEV) += aesni_mb\n+DEPDIRS-aesni_mb := common\n \n include $(RTE_SDK)/mk/rte.subdir.mk\ndiff --git a/drivers/raw/aesni_mb/Makefile b/drivers/raw/aesni_mb/Makefile\nnew file mode 100644\nindex 000000000..0a40b75b4\n--- /dev/null\n+++ b/drivers/raw/aesni_mb/Makefile\n@@ -0,0 +1,47 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2020 Intel Corporation.\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+# library name\n+LIB = librte_pmd_aesni_mb_rawdev.a\n+\n+# build flags\n+CFLAGS += -O3\n+CFLAGS += $(WERROR_FLAGS)\n+CFLAGS += -DALLOW_EXPERIMENTAL_API\n+\n+# versioning export map\n+EXPORT_MAP := rte_rawdev_aesni_mb_version.map\n+\n+# external library dependencies\n+LDLIBS += -lIPSec_MB\n+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring\n+LDLIBS += -lrte_rawdev\n+LDLIBS += -lrte_bus_vdev\n+LDLIBS += -lrte_multi_fn\n+\n+ifneq ($(CONFIG_RTE_LIBRTE_MULTI_FN_COMMON),y)\n+$(error \"RTE_LIBRTE_MULTI_FN_COMMON is required to build aesni_mb raw device\")\n+endif\n+\n+IMB_HDR = $(shell echo '\\#include <intel-ipsec-mb.h>' | \\\n+\t$(CC) -E $(EXTRA_CFLAGS) - | grep 'intel-ipsec-mb.h' | \\\n+\thead -n1 | cut -d'\"' -f2)\n+\n+# Detect library version\n+IMB_VERSION = $(shell grep -e \"IMB_VERSION_STR\" $(IMB_HDR) | cut -d'\"' -f2)\n+IMB_VERSION_NUM = $(shell grep -e \"IMB_VERSION_NUM\" $(IMB_HDR) | cut -d' ' -f3)\n+\n+ifeq ($(IMB_VERSION),)\n+$(error \"IPSec_MB version >= 0.53.3 is required to build aesni_mb raw device\")\n+endif\n+\n+ifeq ($(shell expr $(IMB_VERSION_NUM) \\< 0x3503), 1)\n+$(error \"IPSec_MB version >= 0.53.3 is required to build aesni_mb raw device\")\n+endif\n+\n+SRCS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB_RAWDEV) += aesni_mb_rawdev.c\n+SRCS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB_RAWDEV) += aesni_mb_rawdev_test.c\n+\n+include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/raw/aesni_mb/aesni_mb_rawdev.c b/drivers/raw/aesni_mb/aesni_mb_rawdev.c\nnew file mode 100644\nindex 000000000..946bdd871\n--- /dev/null\n+++ b/drivers/raw/aesni_mb/aesni_mb_rawdev.c\n@@ -0,0 +1,1536 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation.\n+ */\n+\n+#include <stdbool.h>\n+\n+#include <intel-ipsec-mb.h>\n+\n+#include <rte_common.h>\n+#include <rte_hexdump.h>\n+#include <rte_cryptodev.h>\n+#include <rte_dev.h>\n+#include <rte_eal.h>\n+#include <rte_bus_vdev.h>\n+#include <rte_malloc.h>\n+#include <rte_cpuflags.h>\n+#include <rte_rawdev.h>\n+#include <rte_rawdev_pmd.h>\n+#include <rte_string_fns.h>\n+#include <rte_multi_fn.h>\n+#include <rte_ether.h>\n+\n+#include \"aesni_mb_rawdev.h\"\n+\n+#define MAX_QUEUES        (64)\n+#define RING_NAME_MAX_LEN (64)\n+\n+#define PON_BIP_LEN             (4)\n+#define PON_AUTH_TAG_CRC_OFFSET (4)\n+\n+static const uint16_t err_detect_output_byte_lengths[] = {\n+\t[IMB_AUTH_DOCSIS_CRC32] = RTE_ETHER_CRC_LEN,\n+\t[IMB_AUTH_PON_CRC_BIP] = (PON_BIP_LEN + RTE_ETHER_CRC_LEN),\n+};\n+\n+static const char * const xstat_names[] = {\n+\t\t\"successful_enqueues\", \"successful_dequeues\",\n+\t\t\"failed_enqueues\", \"failed_dequeues\",\n+};\n+\n+static const char *driver_name = \"rawdev_aesni_mb\";\n+\n+static int\n+qp_unique_name_set(struct rte_rawdev *rawdev, struct aesni_mb_rawdev_qp *qp)\n+{\n+\tunsigned int n = snprintf(qp->name,\n+\t\t\t\t  sizeof(qp->name),\n+\t\t\t\t  \"aesni_mb_rawdev_pmd_%u_qp_%u\",\n+\t\t\t\t  rawdev->dev_id,\n+\t\t\t\t  qp->id);\n+\n+\tif (n >= sizeof(qp->name))\n+\t\treturn -1;\n+\n+\treturn 0;\n+}\n+\n+static struct rte_ring *\n+qp_processed_ops_ring_create(struct aesni_mb_rawdev_qp *qp,\n+\t\t\t     unsigned int ring_size,\n+\t\t\t     int socket_id)\n+{\n+\tstruct rte_ring *r;\n+\tchar ring_name[RING_NAME_MAX_LEN];\n+\n+\tunsigned int n = 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\tAESNI_MB_RAWDEV_DEBUG(\n+\t\t\t\t\"Reusing existing ring %s for processed ops\",\n+\t\t\t\tring_name);\n+\t\t\treturn r;\n+\t\t}\n+\n+\t\tAESNI_MB_RAWDEV_ERR(\n+\t\t\t\"Unable to reuse existing ring %s for processed ops\",\n+\t\t\tring_name);\n+\t\treturn NULL;\n+\t}\n+\n+\treturn rte_ring_create(ring_name,\n+\t\t\t       ring_size,\n+\t\t\t       socket_id,\n+\t\t\t       RING_F_SP_ENQ | RING_F_SC_DEQ);\n+}\n+\n+static uint16_t\n+err_detect_output_byte_length_get(JOB_HASH_ALG algo)\n+{\n+\treturn err_detect_output_byte_lengths[algo];\n+}\n+\n+static bool\n+docsis_crc_crypto_encrypt_check(struct rte_multi_fn_xform *xform)\n+{\n+\tstruct rte_crypto_sym_xform *crypto_sym;\n+\tstruct rte_multi_fn_err_detect_xform *err_detect;\n+\tstruct rte_multi_fn_xform *next;\n+\n+\tif (xform->type == RTE_MULTI_FN_XFORM_TYPE_ERR_DETECT) {\n+\n+\t\terr_detect = &xform->err_detect;\n+\t\tnext = xform->next;\n+\n+\t\tif (err_detect->algo ==\n+\t\t\t\tRTE_MULTI_FN_ERR_DETECT_CRC32_ETH &&\n+\t\t    err_detect->op ==\n+\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_GENERATE &&\n+\t\t    next != NULL &&\n+\t\t    next->type == RTE_MULTI_FN_XFORM_TYPE_CRYPTO_SYM) {\n+\n+\t\t\tcrypto_sym = &next->crypto_sym;\n+\t\t\tnext = next->next;\n+\n+\t\t\tif (crypto_sym->type ==\n+\t\t\t\t\tRTE_CRYPTO_SYM_XFORM_CIPHER &&\n+\t\t\t    crypto_sym->cipher.op ==\n+\t\t\t\t\tRTE_CRYPTO_CIPHER_OP_ENCRYPT &&\n+\t\t\t    crypto_sym->cipher.algo ==\n+\t\t\t\t\tRTE_CRYPTO_CIPHER_AES_DOCSISBPI &&\n+\t\t\t    crypto_sym->cipher.key.length ==\n+\t\t\t\t\tIMB_KEY_AES_128_BYTES &&\n+\t\t\t    crypto_sym->cipher.iv.length ==\n+\t\t\t\t\tAES_BLOCK_SIZE &&\n+\t\t\t    next == NULL)\n+\t\t\t\treturn true;\n+\t\t}\n+\t}\n+\n+\treturn false;\n+}\n+\n+static bool\n+docsis_crypto_decrypt_crc_check(struct rte_multi_fn_xform *xform)\n+{\n+\tstruct rte_crypto_sym_xform *crypto_sym;\n+\tstruct rte_multi_fn_err_detect_xform *err_detect;\n+\tstruct rte_multi_fn_xform *next;\n+\n+\tif (xform->type == RTE_MULTI_FN_XFORM_TYPE_CRYPTO_SYM) {\n+\n+\t\tcrypto_sym = &xform->crypto_sym;\n+\t\tnext = xform->next;\n+\n+\t\tif (crypto_sym->type ==\n+\t\t\t\tRTE_CRYPTO_SYM_XFORM_CIPHER &&\n+\t\t    crypto_sym->cipher.op ==\n+\t\t\t\tRTE_CRYPTO_CIPHER_OP_DECRYPT &&\n+\t\t    crypto_sym->cipher.algo ==\n+\t\t\t\tRTE_CRYPTO_CIPHER_AES_DOCSISBPI &&\n+\t\t    crypto_sym->cipher.key.length ==\n+\t\t\t\tIMB_KEY_AES_128_BYTES &&\n+\t\t    crypto_sym->cipher.iv.length ==\n+\t\t\t\tAES_BLOCK_SIZE &&\n+\t\t    next != NULL &&\n+\t\t    next->type == RTE_MULTI_FN_XFORM_TYPE_ERR_DETECT) {\n+\n+\t\t\terr_detect = &next->err_detect;\n+\t\t\tnext = next->next;\n+\n+\t\t\tif (err_detect->algo ==\n+\t\t\t\t\tRTE_MULTI_FN_ERR_DETECT_CRC32_ETH &&\n+\t\t\t    err_detect->op ==\n+\t\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_VERIFY &&\n+\t\t\t    next == NULL)\n+\t\t\t\treturn true;\n+\t\t}\n+\t}\n+\n+\treturn false;\n+}\n+\n+static bool\n+pon_crc_crypto_encrypt_bip_check(struct rte_multi_fn_xform *xform)\n+{\n+\tstruct rte_crypto_sym_xform *crypto_sym;\n+\tstruct rte_multi_fn_err_detect_xform *err_detect;\n+\tstruct rte_multi_fn_xform *next;\n+\n+\tif (xform->type == RTE_MULTI_FN_XFORM_TYPE_ERR_DETECT) {\n+\n+\t\terr_detect = &xform->err_detect;\n+\t\tnext = xform->next;\n+\n+\t\tif (err_detect->algo ==\n+\t\t\t\tRTE_MULTI_FN_ERR_DETECT_CRC32_ETH &&\n+\t\t    err_detect->op ==\n+\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_GENERATE &&\n+\t\t    next != NULL &&\n+\t\t    next->type == RTE_MULTI_FN_XFORM_TYPE_CRYPTO_SYM) {\n+\n+\t\t\tcrypto_sym = &next->crypto_sym;\n+\t\t\tnext = next->next;\n+\n+\t\t\tif (crypto_sym->type ==\n+\t\t\t\t\tRTE_CRYPTO_SYM_XFORM_CIPHER &&\n+\t\t\t    crypto_sym->cipher.op ==\n+\t\t\t\t\tRTE_CRYPTO_CIPHER_OP_ENCRYPT &&\n+\t\t\t    crypto_sym->cipher.algo ==\n+\t\t\t\t\tRTE_CRYPTO_CIPHER_AES_CTR &&\n+\t\t\t    crypto_sym->cipher.key.length ==\n+\t\t\t\t\tIMB_KEY_AES_128_BYTES &&\n+\t\t\t    crypto_sym->cipher.iv.length ==\n+\t\t\t\t\tAES_BLOCK_SIZE &&\n+\t\t\t    next != NULL &&\n+\t\t\t    next->type ==\n+\t\t\t\tRTE_MULTI_FN_XFORM_TYPE_ERR_DETECT) {\n+\n+\t\t\t\terr_detect = &next->err_detect;\n+\t\t\t\tnext = next->next;\n+\n+\t\t\t\tif (err_detect->algo ==\n+\t\t\t\t\tRTE_MULTI_FN_ERR_DETECT_BIP32 &&\n+\t\t\t\t    err_detect->op ==\n+\t\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_GENERATE &&\n+\t\t\t\t    next == NULL)\n+\t\t\t\t\treturn true;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn false;\n+}\n+\n+static bool\n+pon_bip_crypto_decrypt_crc_check(struct rte_multi_fn_xform *xform)\n+{\n+\tstruct rte_crypto_sym_xform *crypto_sym;\n+\tstruct rte_multi_fn_err_detect_xform *err_detect;\n+\tstruct rte_multi_fn_xform *next;\n+\n+\tif (xform->type == RTE_MULTI_FN_XFORM_TYPE_ERR_DETECT) {\n+\n+\t\terr_detect = &xform->err_detect;\n+\t\tnext = xform->next;\n+\n+\t\tif (err_detect->algo ==\n+\t\t\t\tRTE_MULTI_FN_ERR_DETECT_BIP32 &&\n+\t\t    err_detect->op ==\n+\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_GENERATE &&\n+\t\t    next != NULL &&\n+\t\t    next->type == RTE_MULTI_FN_XFORM_TYPE_CRYPTO_SYM) {\n+\n+\t\t\tcrypto_sym = &next->crypto_sym;\n+\t\t\tnext = next->next;\n+\n+\t\t\tif (crypto_sym->type ==\n+\t\t\t\t\tRTE_CRYPTO_SYM_XFORM_CIPHER &&\n+\t\t\t    crypto_sym->cipher.op ==\n+\t\t\t\t\tRTE_CRYPTO_CIPHER_OP_DECRYPT &&\n+\t\t\t    crypto_sym->cipher.algo ==\n+\t\t\t\t\tRTE_CRYPTO_CIPHER_AES_CTR &&\n+\t\t\t    crypto_sym->cipher.key.length ==\n+\t\t\t\t\tIMB_KEY_AES_128_BYTES &&\n+\t\t\t    crypto_sym->cipher.iv.length ==\n+\t\t\t\t\tAES_BLOCK_SIZE &&\n+\t\t\t    next != NULL &&\n+\t\t\t    next->type ==\n+\t\t\t\tRTE_MULTI_FN_XFORM_TYPE_ERR_DETECT) {\n+\n+\t\t\t\terr_detect = &next->err_detect;\n+\t\t\t\tnext = next->next;\n+\n+\t\t\t\tif (err_detect->algo ==\n+\t\t\t\t\tRTE_MULTI_FN_ERR_DETECT_CRC32_ETH &&\n+\t\t\t\t    err_detect->op ==\n+\t\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_VERIFY &&\n+\t\t\t\t    next == NULL)\n+\t\t\t\t\treturn true;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn false;\n+}\n+\n+static enum aesni_mb_rawdev_op\n+session_support_check(struct rte_multi_fn_xform *xform)\n+{\n+\tenum aesni_mb_rawdev_op op = AESNI_MB_RAWDEV_OP_NOT_SUPPORTED;\n+\n+\tif (docsis_crc_crypto_encrypt_check(xform))\n+\t\top = AESNI_MB_RAWDEV_OP_DOCSIS_CRC_CRYPTO;\n+\telse if (docsis_crypto_decrypt_crc_check(xform))\n+\t\top = AESNI_MB_RAWDEV_OP_DOCSIS_CRYPTO_CRC;\n+\telse if (pon_crc_crypto_encrypt_bip_check(xform))\n+\t\top = AESNI_MB_RAWDEV_OP_PON_CRC_CRYPTO_BIP;\n+\telse if (pon_bip_crypto_decrypt_crc_check(xform))\n+\t\top = AESNI_MB_RAWDEV_OP_PON_BIP_CRYPTO_CRC;\n+\n+\treturn op;\n+}\n+\n+static int\n+session_err_detect_parameters_set(struct aesni_mb_rawdev_session *sess)\n+{\n+\tswitch (sess->op) {\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRC_CRYPTO:\n+\t\tsess->err_detect.operation =\n+\t\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_GENERATE;\n+\t\tsess->err_detect.algo = IMB_AUTH_DOCSIS_CRC32;\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRYPTO_CRC:\n+\t\tsess->err_detect.operation = RTE_MULTI_FN_ERR_DETECT_OP_VERIFY;\n+\t\tsess->err_detect.algo = IMB_AUTH_DOCSIS_CRC32;\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_OP_PON_CRC_CRYPTO_BIP:\n+\t\tsess->err_detect.operation =\n+\t\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_GENERATE;\n+\t\tsess->err_detect.algo = IMB_AUTH_PON_CRC_BIP;\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_OP_PON_BIP_CRYPTO_CRC:\n+\t\tsess->err_detect.operation = RTE_MULTI_FN_ERR_DETECT_OP_VERIFY;\n+\t\tsess->err_detect.algo = IMB_AUTH_PON_CRC_BIP;\n+\t\tbreak;\n+\tdefault:\n+\t\tAESNI_MB_RAWDEV_ERR(\n+\t\t\t\t\"Unsupported operation for error detection\");\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\tsess->err_detect.gen_output_len =\n+\t\terr_detect_output_byte_length_get(sess->err_detect.algo);\n+\n+\treturn 0;\n+}\n+\n+static int\n+session_cipher_parameters_set(const MB_MGR *mb_mgr,\n+\t\t\t      struct aesni_mb_rawdev_session *sess,\n+\t\t\t      const struct rte_crypto_sym_xform *xform)\n+{\n+\n+\tif (xform == NULL) {\n+\t\tsess->cipher.mode = IMB_CIPHER_NULL;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER) {\n+\t\tAESNI_MB_RAWDEV_ERR(\"Crypto xform not of type cipher\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Select cipher direction */\n+\tswitch (sess->op) {\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRC_CRYPTO:\n+\t\tsess->cipher.direction = IMB_DIR_ENCRYPT;\n+\t\tsess->cipher.mode = IMB_CIPHER_DOCSIS_SEC_BPI;\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRYPTO_CRC:\n+\t\tsess->cipher.direction = IMB_DIR_DECRYPT;\n+\t\tsess->cipher.mode = IMB_CIPHER_DOCSIS_SEC_BPI;\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_OP_PON_CRC_CRYPTO_BIP:\n+\t\tsess->cipher.direction = IMB_DIR_ENCRYPT;\n+\t\tsess->cipher.mode = IMB_CIPHER_PON_AES_CNTR;\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_OP_PON_BIP_CRYPTO_CRC:\n+\t\tsess->cipher.direction = IMB_DIR_DECRYPT;\n+\t\tsess->cipher.mode = IMB_CIPHER_PON_AES_CNTR;\n+\t\tbreak;\n+\tdefault:\n+\t\tAESNI_MB_RAWDEV_ERR(\"Unsupported operation for cipher\");\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\t/* Set IV parameters */\n+\tsess->iv.offset = xform->cipher.iv.offset;\n+\tsess->iv.length = xform->cipher.iv.length;\n+\n+\t/* Check key length and choose key expansion function for AES */\n+\tswitch (xform->cipher.key.length) {\n+\tcase IMB_KEY_AES_128_BYTES:\n+\t\tsess->cipher.key_length_in_bytes = IMB_KEY_AES_128_BYTES;\n+\t\tIMB_AES_KEYEXP_128(mb_mgr,\n+\t\t\t\t   xform->cipher.key.data,\n+\t\t\t\t   sess->cipher.expanded_aes_keys.encode,\n+\t\t\t\t   sess->cipher.expanded_aes_keys.decode);\n+\t\tbreak;\n+\tcase IMB_KEY_AES_256_BYTES:\n+\t\tsess->cipher.key_length_in_bytes = IMB_KEY_AES_256_BYTES;\n+\t\tIMB_AES_KEYEXP_256(mb_mgr,\n+\t\t\t\t   xform->cipher.key.data,\n+\t\t\t\t   sess->cipher.expanded_aes_keys.encode,\n+\t\t\t\t   sess->cipher.expanded_aes_keys.decode);\n+\t\tbreak;\n+\tdefault:\n+\t\tAESNI_MB_RAWDEV_ERR(\"Invalid cipher key length\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static inline struct aesni_mb_rawdev_session *\n+session_get(struct rte_multi_fn_op *op)\n+{\n+\tstruct aesni_mb_rawdev_session *sess = NULL;\n+\n+\tif (likely(op->sess != NULL))\n+\t\tsess = op->sess->sess_private_data;\n+\telse\n+\t\top->overall_status = RTE_MULTI_FN_STATUS_INVALID_SESSION;\n+\n+\treturn sess;\n+}\n+\n+static inline int\n+op_chain_parse(struct aesni_mb_rawdev_session *sess,\n+\t       struct rte_multi_fn_op *op_chain,\n+\t       struct rte_multi_fn_op **cipher_op,\n+\t       struct rte_multi_fn_op **crc_op,\n+\t       struct rte_multi_fn_op **bip_op)\n+{\n+\t*cipher_op = NULL;\n+\t*crc_op = NULL;\n+\t*bip_op = NULL;\n+\n+\tswitch (sess->op) {\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRC_CRYPTO:\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRYPTO_CRC:\n+\t\tif (unlikely(op_chain == NULL || op_chain->next == NULL)) {\n+\t\t\treturn -EINVAL;\n+\t\t} else if (sess->op == AESNI_MB_RAWDEV_OP_DOCSIS_CRC_CRYPTO) {\n+\t\t\t*crc_op = op_chain;\n+\t\t\t*cipher_op = op_chain->next;\n+\t\t} else {\n+\t\t\t*cipher_op = op_chain;\n+\t\t\t*crc_op = op_chain->next;\n+\t\t}\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_OP_PON_CRC_CRYPTO_BIP:\n+\tcase AESNI_MB_RAWDEV_OP_PON_BIP_CRYPTO_CRC:\n+\t\tif (unlikely(op_chain == NULL ||\n+\t\t\t     op_chain->next == NULL ||\n+\t\t\t     op_chain->next->next == NULL)) {\n+\t\t\treturn -EINVAL;\n+\t\t} else if (sess->op == AESNI_MB_RAWDEV_OP_PON_CRC_CRYPTO_BIP) {\n+\t\t\t*crc_op = op_chain;\n+\t\t\t*cipher_op = op_chain->next;\n+\t\t\t*bip_op = op_chain->next->next;\n+\t\t} else {\n+\t\t\t*bip_op = op_chain;\n+\t\t\t*cipher_op = op_chain->next;\n+\t\t\t*crc_op = op_chain->next->next;\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static inline void\n+op_statuses_set(struct rte_multi_fn_op *first_op,\n+\t\tstruct rte_multi_fn_op *cipher_op,\n+\t\tstruct rte_multi_fn_op *crc_op,\n+\t\tstruct rte_multi_fn_op *bip_op,\n+\t\tenum rte_multi_fn_op_status overall_status,\n+\t\tuint8_t crypto_status,\n+\t\tuint8_t err_detect_status)\n+{\n+\tfirst_op->overall_status = overall_status;\n+\n+\tif (cipher_op != NULL)\n+\t\tcipher_op->op_status = crypto_status;\n+\tif (crc_op != NULL)\n+\t\tcrc_op->op_status = err_detect_status;\n+\tif (bip_op != NULL)\n+\t\tbip_op->op_status = err_detect_status;\n+}\n+\n+#ifdef RTE_LIBRTE_PMD_AESNI_MB_RAWDEV_DEBUG\n+#define DOCSIS_CIPHER_CRC_OFFSET_DIFF (RTE_ETHER_HDR_LEN - RTE_ETHER_TYPE_LEN)\n+#define DOCSIS_CIPHER_CRC_LENGTH_DIFF (RTE_ETHER_HDR_LEN - \\\n+\t\t\t\t\tRTE_ETHER_TYPE_LEN - \\\n+\t\t\t\t\tRTE_ETHER_CRC_LEN)\n+\n+static inline int\n+docsis_crypto_crc_check(struct rte_multi_fn_op *first_op,\n+\t\t\tstruct rte_multi_fn_op *cipher_op,\n+\t\t\tstruct rte_multi_fn_op *crc_op)\n+{\n+\tstruct rte_multi_fn_op *err_op = NULL;\n+\tuint8_t err_op_status;\n+\tconst uint32_t offset_diff = DOCSIS_CIPHER_CRC_OFFSET_DIFF;\n+\n+\tif (cipher_op->crypto_sym.cipher.data.length &&\n+\t    crc_op->err_detect.data.length) {\n+\t\t/* Cipher offset must be at least 12 greater than CRC offset */\n+\t\tif (cipher_op->crypto_sym.cipher.data.offset <\n+\t\t    ((uint32_t)crc_op->err_detect.data.offset + offset_diff)) {\n+\t\t\terr_op = crc_op;\n+\t\t\terr_op_status = RTE_MULTI_FN_ERR_DETECT_OP_STATUS_ERROR;\n+\t\t/*\n+\t\t * Cipher length must be at least 8 less than CRC length, taking\n+\t\t * known differences of what is ciphered and what is crc'ed into\n+\t\t * account\n+\t\t */\n+\t\t} else if ((cipher_op->crypto_sym.cipher.data.length +\n+\t\t\t\tDOCSIS_CIPHER_CRC_LENGTH_DIFF) >\n+\t\t\t    crc_op->err_detect.data.length) {\n+\t\t\terr_op = crc_op;\n+\t\t\terr_op_status = RTE_MULTI_FN_ERR_DETECT_OP_STATUS_ERROR;\n+\t\t}\n+\t}\n+\n+\tif (err_op != NULL) {\n+\t\terr_op->op_status = err_op_status;\n+\t\tfirst_op->overall_status = RTE_MULTI_FN_OP_STATUS_FAILURE;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+#define PON_FRAME_HDR_SIZE      (8U)\n+#define PON_FRAME_MULTIPLE_SIZE (4)\n+#define PON_PLI_SHIFT_BITS      (2)\n+\n+static inline int\n+pon_crypto_crc_bip_check(struct rte_multi_fn_op *first_op,\n+\t\t\t struct rte_multi_fn_op *crc_op,\n+\t\t\t struct rte_multi_fn_op *bip_op,\n+\t\t\t struct rte_mbuf *m_src)\n+{\n+\tstruct rte_multi_fn_op *err_op = NULL;\n+\tuint8_t err_op_status;\n+\n+\t/*\n+\t * BIP length must be multiple of 4 and be at least a full PON header\n+\t * in size\n+\t */\n+\tif (bip_op->err_detect.data.length % PON_FRAME_MULTIPLE_SIZE != 0 ||\n+\t    bip_op->err_detect.data.length < PON_FRAME_HDR_SIZE) {\n+\t\terr_op = bip_op;\n+\t\terr_op_status = RTE_MULTI_FN_ERR_DETECT_OP_STATUS_ERROR;\n+\t}\n+\n+\t/*\n+\t * Check the PLI field in the PON frame header matches the\n+\t * CRC length\n+\t */\n+\tuint16_t *pli_key_idx = rte_pktmbuf_mtod(m_src, uint16_t *);\n+\tuint16_t pli = rte_bswap16(*pli_key_idx) >> PON_PLI_SHIFT_BITS;\n+\tif (crc_op->err_detect.data.length != 0 &&\n+\t    crc_op->err_detect.data.length != (pli - RTE_ETHER_CRC_LEN)) {\n+\t\terr_op = crc_op;\n+\t\terr_op_status = RTE_MULTI_FN_ERR_DETECT_OP_STATUS_ERROR;\n+\t}\n+\n+\tif (err_op != NULL) {\n+\t\terr_op->op_status = err_op_status;\n+\t\tfirst_op->overall_status = RTE_MULTI_FN_OP_STATUS_FAILURE;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+#endif /* RTE_LIBRTE_PMD_AESNI_MB_RAWDEV_DEBUG */\n+\n+static inline int\n+mb_job_params_set(JOB_AES_HMAC *job,\n+\t\t  struct aesni_mb_rawdev_qp *qp,\n+\t\t  struct rte_multi_fn_op *op,\n+\t\t  uint8_t *output_idx)\n+{\n+\tstruct rte_mbuf *m_src, *m_dst;\n+\tstruct rte_multi_fn_op *cipher_op;\n+\tstruct rte_multi_fn_op *crc_op;\n+\tstruct rte_multi_fn_op *bip_op;\n+\tuint32_t cipher_offset;\n+\tstruct aesni_mb_rawdev_session *session;\n+\n+\tsession = session_get(op);\n+\tif (unlikely(session == NULL)) {\n+\t\top->overall_status = RTE_MULTI_FN_STATUS_INVALID_SESSION;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (unlikely(op_chain_parse(session,\n+\t\t\t\t    op,\n+\t\t\t\t    &cipher_op,\n+\t\t\t\t    &crc_op,\n+\t\t\t\t    &bip_op) < 0)) {\n+\t\top_statuses_set(\n+\t\t\top,\n+\t\t\tcipher_op,\n+\t\t\tcrc_op,\n+\t\t\tbip_op,\n+\t\t\tRTE_MULTI_FN_OP_STATUS_FAILURE,\n+\t\t\tRTE_CRYPTO_OP_STATUS_NOT_PROCESSED,\n+\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_STATUS_NOT_PROCESSED);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\top_statuses_set(op,\n+\t\t\tcipher_op,\n+\t\t\tcrc_op,\n+\t\t\tbip_op,\n+\t\t\tRTE_MULTI_FN_OP_STATUS_NOT_PROCESSED,\n+\t\t\tRTE_CRYPTO_OP_STATUS_NOT_PROCESSED,\n+\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_STATUS_NOT_PROCESSED);\n+\n+\tm_src = op->m_src;\n+\n+\tif (op->m_dst == NULL || op->m_dst == op->m_src) {\n+\t\t/* in-place operation */\n+\t\tm_dst = m_src;\n+\t} else {\n+\t\t/* out-of-place operation not supported */\n+\t\top->overall_status = RTE_MULTI_FN_OP_STATUS_FAILURE;\n+\t\treturn -EINVAL;\n+\t}\n+\n+#ifdef RTE_LIBRTE_PMD_AESNI_MB_RAWDEV_DEBUG\n+\tswitch (session->op) {\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRC_CRYPTO:\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRYPTO_CRC:\n+\t\tif (docsis_crypto_crc_check(op, cipher_op, crc_op) < 0)\n+\t\t\treturn -EINVAL;\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_OP_PON_CRC_CRYPTO_BIP:\n+\tcase AESNI_MB_RAWDEV_OP_PON_BIP_CRYPTO_CRC:\n+\t/*\n+\t * session->op is known to be ok at this point so ok to include\n+\t * default case here\n+\t */\n+\tdefault:\n+\t\tif (pon_crypto_crc_bip_check(op, crc_op, bip_op, m_src) < 0)\n+\t\t\treturn -EINVAL;\n+\t\tbreak;\n+\t}\n+#endif\n+\n+\t/* Set order */\n+\tjob->chain_order = session->chain_order;\n+\n+\t/* Set cipher parameters */\n+\tjob->cipher_direction = session->cipher.direction;\n+\tjob->cipher_mode = session->cipher.mode;\n+\n+\tjob->key_len_in_bytes = session->cipher.key_length_in_bytes;\n+\tjob->enc_keys = session->cipher.expanded_aes_keys.encode;\n+\tjob->dec_keys = session->cipher.expanded_aes_keys.decode;\n+\n+\t/*\n+\t * Set error detection parameters\n+\t * In intel-ipsec-mb, error detection is treated as a hash algorithm\n+\t */\n+\tjob->hash_alg = session->err_detect.algo;\n+\n+\tjob->auth_tag_output = qp->temp_outputs[*output_idx];\n+\t*output_idx = (*output_idx + 1) % MAX_JOBS;\n+\n+\tjob->auth_tag_output_len_in_bytes = session->err_detect.gen_output_len;\n+\n+\t/* Set data parameters */\n+\tcipher_offset = cipher_op->crypto_sym.cipher.data.offset;\n+\n+\tjob->src = rte_pktmbuf_mtod(m_src, uint8_t *);\n+\tjob->dst = rte_pktmbuf_mtod_offset(m_dst, uint8_t *, cipher_offset);\n+\n+\tjob->cipher_start_src_offset_in_bytes =\tcipher_offset;\n+\tjob->msg_len_to_cipher_in_bytes =\n+\t\t\t\tcipher_op->crypto_sym.cipher.data.length;\n+\n+\tswitch (session->op) {\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRC_CRYPTO:\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRYPTO_CRC:\n+\t\tjob->hash_start_src_offset_in_bytes =\n+\t\t\t\t\t\tcrc_op->err_detect.data.offset;\n+\t\tjob->msg_len_to_hash_in_bytes = crc_op->err_detect.data.length;\n+\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_OP_PON_CRC_CRYPTO_BIP:\n+\tcase AESNI_MB_RAWDEV_OP_PON_BIP_CRYPTO_CRC:\n+\t/*\n+\t * session->op is known to be ok at this point so ok to include\n+\t * default case here\n+\t */\n+\tdefault:\n+\t\tjob->hash_start_src_offset_in_bytes =\n+\t\t\t\t\t\tbip_op->err_detect.data.offset;\n+\t\tjob->msg_len_to_hash_in_bytes = bip_op->err_detect.data.length;\n+\n+#ifdef RTE_LIBRTE_PMD_AESNI_MB_RAWDEV_DEBUG\n+#endif\n+\t\tbreak;\n+\t}\n+\n+\t/* Set IV parameters */\n+\tjob->iv_len_in_bytes = session->iv.length;\n+\tjob->iv = (uint8_t *)cipher_op + session->iv.offset;\n+\n+\tjob->user_data = op;\n+\n+\treturn 0;\n+}\n+\n+static inline void\n+bip_copy(JOB_AES_HMAC *job, struct rte_multi_fn_op *bip_op)\n+{\n+\tif (bip_op->err_detect.data.length == 0)\n+\t\treturn;\n+\n+\t/* Copy BIP to output location */\n+\tmemcpy(bip_op->err_detect.output.data,\n+\t       job->auth_tag_output,\n+\t       PON_BIP_LEN);\n+}\n+\n+static inline void\n+crc_verify(JOB_AES_HMAC *job,\n+\t   struct rte_multi_fn_op *crc_op,\n+\t   uint8_t auth_tag_crc_offset)\n+{\n+\tif (crc_op->err_detect.data.length == 0)\n+\t\treturn;\n+\n+\t/* Verify CRC */\n+\tif (memcmp(job->auth_tag_output + auth_tag_crc_offset,\n+\t\t   crc_op->err_detect.output.data,\n+\t\t   RTE_ETHER_CRC_LEN) != 0)\n+\t\tcrc_op->op_status =\n+\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_STATUS_VERIFY_FAILED;\n+}\n+\n+static inline struct rte_multi_fn_op *\n+mb_job_post_process(JOB_AES_HMAC *job)\n+{\n+\tstruct rte_multi_fn_op *op = (struct rte_multi_fn_op *)job->user_data;\n+\tstruct aesni_mb_rawdev_session *sess = op->sess->sess_private_data;\n+\tstruct rte_multi_fn_op *cipher_op;\n+\tstruct rte_multi_fn_op *crc_op;\n+\tstruct rte_multi_fn_op *bip_op;\n+\n+\tif (unlikely(op_chain_parse(sess,\n+\t\t\t\t    op,\n+\t\t\t\t    &cipher_op,\n+\t\t\t\t    &crc_op,\n+\t\t\t\t    &bip_op) < 0)) {\n+\t\top_statuses_set(\n+\t\t\top,\n+\t\t\tcipher_op,\n+\t\t\tcrc_op,\n+\t\t\tbip_op,\n+\t\t\tRTE_MULTI_FN_OP_STATUS_FAILURE,\n+\t\t\tRTE_CRYPTO_OP_STATUS_ERROR,\n+\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_STATUS_ERROR);\n+\n+\t} else if (op->overall_status ==\n+\t\t\t\tRTE_MULTI_FN_OP_STATUS_NOT_PROCESSED) {\n+\t\tswitch (job->status) {\n+\t\tcase STS_COMPLETED:\n+\t\t\tif (unlikely(job->hash_alg == IMB_AUTH_NULL))\n+\t\t\t\tbreak;\n+\n+\t\t\top_statuses_set(\n+\t\t\t\top,\n+\t\t\t\tcipher_op,\n+\t\t\t\tcrc_op,\n+\t\t\t\tbip_op,\n+\t\t\t\tRTE_MULTI_FN_OP_STATUS_SUCCESS,\n+\t\t\t\tRTE_CRYPTO_OP_STATUS_SUCCESS,\n+\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_STATUS_SUCCESS);\n+\n+\t\t\tif (job->hash_alg == IMB_AUTH_PON_CRC_BIP)\n+\t\t\t\tbip_copy(job, bip_op);\n+\n+\t\t\tif (sess->err_detect.operation ==\n+\t\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_VERIFY)\n+\t\t\t\tcrc_verify(\n+\t\t\t\t\tjob,\n+\t\t\t\t\tcrc_op,\n+\t\t\t\t\tjob->hash_alg == IMB_AUTH_PON_CRC_BIP ?\n+\t\t\t\t\t\tPON_AUTH_TAG_CRC_OFFSET : 0);\n+\n+\t\t\tif (crc_op->op_status !=\n+\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_STATUS_SUCCESS)\n+\t\t\t\top->overall_status =\n+\t\t\t\t\tRTE_MULTI_FN_OP_STATUS_FAILURE;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\top_statuses_set(\n+\t\t\t\top,\n+\t\t\t\tcipher_op,\n+\t\t\t\tcrc_op,\n+\t\t\t\tbip_op,\n+\t\t\t\tRTE_MULTI_FN_OP_STATUS_FAILURE,\n+\t\t\t\tRTE_CRYPTO_OP_STATUS_ERROR,\n+\t\t\t\tRTE_MULTI_FN_ERR_DETECT_OP_STATUS_ERROR);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn op;\n+}\n+\n+static unsigned\n+completed_jobs_handle(struct aesni_mb_rawdev_qp *qp,\n+\t\t      JOB_AES_HMAC *job,\n+\t\t      struct rte_multi_fn_op **ops,\n+\t\t      uint16_t nb_ops)\n+{\n+\tstruct rte_multi_fn_op *op = NULL;\n+\tunsigned int processed_jobs = 0;\n+\n+\twhile (job != NULL) {\n+\t\top = mb_job_post_process(job);\n+\n+\t\tif (op) {\n+\t\t\tops[processed_jobs++] = op;\n+\t\t\tqp->stats.dequeued_count++;\n+\t\t} else {\n+\t\t\tqp->stats.dequeue_err_count++;\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (processed_jobs == nb_ops)\n+\t\t\tbreak;\n+\n+\t\tjob = IMB_GET_COMPLETED_JOB(qp->mb_mgr);\n+\t}\n+\n+\treturn processed_jobs;\n+}\n+\n+static inline uint16_t\n+mb_mgr_flush(struct aesni_mb_rawdev_qp *qp,\n+\t     struct rte_multi_fn_op **ops,\n+\t     uint16_t nb_ops)\n+{\n+\tint processed_ops = 0;\n+\n+\t/* Flush the remaining jobs */\n+\tJOB_AES_HMAC *job = IMB_FLUSH_JOB(qp->mb_mgr);\n+\n+\tif (job)\n+\t\tprocessed_ops += completed_jobs_handle(qp,\n+\t\t\t\t\t\t       job,\n+\t\t\t\t\t\t       &ops[processed_ops],\n+\t\t\t\t\t\t       nb_ops - processed_ops);\n+\n+\treturn processed_ops;\n+}\n+\n+static inline JOB_AES_HMAC *\n+mb_job_params_null_set(JOB_AES_HMAC *job, struct rte_multi_fn_op *op)\n+{\n+\tjob->chain_order = IMB_ORDER_HASH_CIPHER;\n+\tjob->cipher_mode = IMB_CIPHER_NULL;\n+\tjob->hash_alg = IMB_AUTH_NULL;\n+\tjob->cipher_direction = IMB_DIR_DECRYPT;\n+\n+\t/* Set user data to be crypto operation data struct */\n+\tjob->user_data = op;\n+\n+\treturn job;\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_config(const struct rte_rawdev *rawdev,\n+\t\t\t   rte_rawdev_obj_t config)\n+{\n+\tstruct aesni_mb_rawdev *aesni_mb_dev = rawdev->dev_private;\n+\tstruct rte_multi_fn_dev_config *conf = config;\n+\n+\taesni_mb_dev->nb_queue_pairs = conf->nb_queues;\n+\n+\taesni_mb_dev->queue_pairs =\n+\t\t\trte_zmalloc_socket(\n+\t\t\t\t\"aesni_mb_rawdev_qps\",\n+\t\t\t\taesni_mb_dev->nb_queue_pairs *\n+\t\t\t\t\tsizeof(struct aesni_mb_rawdev_qp *),\n+\t\t\t\tRTE_CACHE_LINE_SIZE,\n+\t\t\t\trawdev->socket_id);\n+\n+\tif (aesni_mb_dev->queue_pairs == NULL) {\n+\t\tAESNI_MB_RAWDEV_ERR(\"Unable to allocate queue pairs\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void\n+aesni_mb_rawdev_pmd_info_get(struct rte_rawdev *rawdev,\n+\t\t\t     rte_rawdev_obj_t dev_info)\n+{\n+\tstruct aesni_mb_rawdev *aesni_mb_dev = rawdev->dev_private;\n+\tstruct rte_multi_fn_dev_info *info = dev_info;\n+\n+\tif (info != NULL)\n+\t\tinfo->max_nb_queues = aesni_mb_dev->max_nb_queue_pairs;\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_start(__rte_unused struct rte_rawdev *rawdev)\n+{\n+\treturn 0;\n+}\n+\n+static void\n+aesni_mb_rawdev_pmd_stop(__rte_unused struct rte_rawdev *rawdev)\n+{\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_close(struct rte_rawdev *rawdev)\n+{\n+\tstruct aesni_mb_rawdev *aesni_mb_dev = rawdev->dev_private;\n+\n+\tif (aesni_mb_dev->queue_pairs != NULL)\n+\t\trte_free(aesni_mb_dev->queue_pairs);\n+\n+\treturn 0;\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_qp_release(struct rte_rawdev *rawdev, uint16_t qp_id)\n+{\n+\tstruct aesni_mb_rawdev *aesni_mb_dev = rawdev->dev_private;\n+\tstruct aesni_mb_rawdev_qp *qp = aesni_mb_dev->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\tif (qp->mb_mgr)\n+\t\t\tfree_mb_mgr(qp->mb_mgr);\n+\t\trte_free(qp);\n+\t\taesni_mb_dev->queue_pairs[qp_id] = NULL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_qp_setup(struct rte_rawdev *rawdev,\n+\t\t\t     uint16_t qp_id,\n+\t\t\t     rte_rawdev_obj_t qp_c)\n+{\n+\tstruct aesni_mb_rawdev *aesni_mb_dev = rawdev->dev_private;\n+\tstruct aesni_mb_rawdev_qp *qp = NULL;\n+\tconst struct rte_multi_fn_qp_config *qp_conf =\n+\t\t\t(const struct rte_multi_fn_qp_config *)qp_c;\n+\tint ret = -1;\n+\n+\tif (qp_id >= aesni_mb_dev->max_nb_queue_pairs) {\n+\t\tAESNI_MB_RAWDEV_ERR(\"Invalid queue pair id=%d\", qp_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Free memory prior to re-allocation if needed */\n+\tif (aesni_mb_dev->queue_pairs[qp_id] != NULL)\n+\t\taesni_mb_rawdev_pmd_qp_release(rawdev, qp_id);\n+\n+\t/* Allocate the queue pair data structure */\n+\tqp = rte_zmalloc_socket(\"aesni_mb_rawdev_qp\",\n+\t\t\t\tsizeof(struct aesni_mb_rawdev_qp),\n+\t\t\t\tRTE_CACHE_LINE_SIZE,\n+\t\t\t\trawdev->socket_id);\n+\tif (qp == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tqp->id = qp_id;\n+\taesni_mb_dev->queue_pairs[qp_id] = qp;\n+\n+\tif (qp_unique_name_set(rawdev, qp))\n+\t\tgoto qp_setup_cleanup;\n+\n+\tqp->mb_mgr = alloc_mb_mgr(0);\n+\tif (qp->mb_mgr == NULL) {\n+\t\tret = -ENOMEM;\n+\t\tgoto qp_setup_cleanup;\n+\t}\n+\n+\tswitch (aesni_mb_dev->vector_mode) {\n+\tcase AESNI_MB_RAWDEV_SSE:\n+\t\tinit_mb_mgr_sse(qp->mb_mgr);\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_AVX:\n+\t\tinit_mb_mgr_avx(qp->mb_mgr);\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_AVX2:\n+\t\tinit_mb_mgr_avx2(qp->mb_mgr);\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_AVX512:\n+\t\tinit_mb_mgr_avx512(qp->mb_mgr);\n+\t\tbreak;\n+\tdefault:\n+\t\tAESNI_MB_RAWDEV_ERR(\"Unsupported vector mode %u\",\n+\t\t\t\t    aesni_mb_dev->vector_mode);\n+\t\tgoto qp_setup_cleanup;\n+\t}\n+\n+\tqp->ingress_queue = qp_processed_ops_ring_create(\n+\t\t\t\t\t\tqp,\n+\t\t\t\t\t\tqp_conf->nb_descriptors,\n+\t\t\t\t\t\trawdev->socket_id);\n+\tif (qp->ingress_queue == NULL) {\n+\t\tret = -1;\n+\t\tgoto qp_setup_cleanup;\n+\t}\n+\n+\tmemset(&qp->stats, 0, sizeof(qp->stats));\n+\n+\treturn 0;\n+\n+qp_setup_cleanup:\n+\tif (qp) {\n+\t\tif (qp->mb_mgr)\n+\t\t\tfree_mb_mgr(qp->mb_mgr);\n+\t\trte_free(qp);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static uint16_t\n+aesni_mb_rawdev_pmd_qp_count(struct rte_rawdev *rawdev)\n+{\n+\tstruct aesni_mb_rawdev *aesni_mb_dev = rawdev->dev_private;\n+\n+\treturn aesni_mb_dev->nb_queue_pairs;\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_enq(struct rte_rawdev *rawdev,\n+\t\t\tstruct rte_rawdev_buf **ops,\n+\t\t\tunsigned int nb_ops,\n+\t\t\trte_rawdev_obj_t q_id)\n+{\n+\tstruct aesni_mb_rawdev *aesni_mb_dev = rawdev->dev_private;\n+\tstruct aesni_mb_rawdev_qp *qp;\n+\tunsigned int nb_enqueued;\n+\n+\tqp = aesni_mb_dev->queue_pairs[*(uint16_t *)q_id];\n+\n+\tnb_enqueued = rte_ring_enqueue_burst(qp->ingress_queue,\n+\t\t\t\t\t     (void **)ops,\n+\t\t\t\t\t     nb_ops,\n+\t\t\t\t\t     NULL);\n+\n+\tqp->stats.enqueued_count += nb_enqueued;\n+\n+\treturn nb_enqueued;\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_deq(struct rte_rawdev *rawdev,\n+\t\t\tstruct rte_rawdev_buf **ops,\n+\t\t\tunsigned int nb_ops,\n+\t\t\trte_rawdev_obj_t q_id)\n+{\n+\tstruct aesni_mb_rawdev *aesni_mb_dev = rawdev->dev_private;\n+\tstruct aesni_mb_rawdev_qp *qp;\n+\tstruct rte_multi_fn_op *op;\n+\tJOB_AES_HMAC *job;\n+\tuint8_t output_idx;\n+\tunsigned int processed_jobs = 0;\n+\tint ret;\n+\n+\tqp = aesni_mb_dev->queue_pairs[*(uint16_t *)q_id];\n+\n+\tif (unlikely(nb_ops == 0))\n+\t\treturn 0;\n+\n+\toutput_idx = qp->output_idx;\n+\n+\tdo {\n+\t\t/* Get next free mb job struct from mb manager */\n+\t\tjob = IMB_GET_NEXT_JOB(qp->mb_mgr);\n+\t\tif (unlikely(job == NULL)) {\n+\t\t\t/* if no free mb job structs we need to flush mb_mgr */\n+\t\t\tprocessed_jobs += mb_mgr_flush(\n+\t\t\t\t\t\tqp,\n+\t\t\t\t\t\t(struct rte_multi_fn_op **)\n+\t\t\t\t\t\t\t&ops[processed_jobs],\n+\t\t\t\t\t\tnb_ops - processed_jobs);\n+\n+\t\t\tif (nb_ops == processed_jobs)\n+\t\t\t\tbreak;\n+\n+\t\t\tjob = IMB_GET_NEXT_JOB(qp->mb_mgr);\n+\t\t}\n+\n+\t\t/*\n+\t\t * Get next operation to process from ingress queue.\n+\t\t * There is no need to return the job to the MB_MGR if there\n+\t\t * are no more operations to process, since the MB_MGR can use\n+\t\t * that pointer again in next get_next calls.\n+\t\t */\n+\t\tret = rte_ring_dequeue(qp->ingress_queue, (void **)&op);\n+\t\tif (ret < 0)\n+\t\t\tbreak;\n+\n+\t\tret = mb_job_params_set(job, qp, op, &output_idx);\n+\t\tif (unlikely(ret != 0)) {\n+\t\t\tqp->stats.dequeue_err_count++;\n+\t\t\tmb_job_params_null_set(job, op);\n+\t\t}\n+\n+\t\t/* Submit job to multi-buffer for processing */\n+#ifdef RTE_LIBRTE_PMD_AESNI_MB_RAWDEV_DEBUG\n+\t\tjob = IMB_SUBMIT_JOB(qp->mb_mgr);\n+#else\n+\t\tjob = IMB_SUBMIT_JOB_NOCHECK(qp->mb_mgr);\n+#endif\n+\t\t/*\n+\t\t * If submit returns a processed job then handle it,\n+\t\t * before submitting subsequent jobs\n+\t\t */\n+\t\tif (job)\n+\t\t\tprocessed_jobs += completed_jobs_handle(\n+\t\t\t\t\t\tqp,\n+\t\t\t\t\t\tjob,\n+\t\t\t\t\t\t(struct rte_multi_fn_op **)\n+\t\t\t\t\t\t\t&ops[processed_jobs],\n+\t\t\t\t\t\tnb_ops - processed_jobs);\n+\n+\t} while (processed_jobs < nb_ops);\n+\n+\tqp->output_idx = output_idx;\n+\n+\tif (processed_jobs < 1)\n+\t\tprocessed_jobs += mb_mgr_flush(qp,\n+\t\t\t\t\t       (struct rte_multi_fn_op **)\n+\t\t\t\t\t\t\t&ops[processed_jobs],\n+\t\t\t\t\t       nb_ops - processed_jobs);\n+\n+\treturn processed_jobs;\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_xstats_get(const struct rte_rawdev *rawdev,\n+\t\t\t       const unsigned int ids[],\n+\t\t\t       uint64_t values[],\n+\t\t\t       unsigned int n)\n+{\n+\tstruct aesni_mb_rawdev *aesni_mb_dev = rawdev->dev_private;\n+\tstruct aesni_mb_rawdev_qp *qp;\n+\tstruct aesni_mb_rawdev_stats stats = {0};\n+\tint qp_id;\n+\tunsigned int i;\n+\n+\tfor (qp_id = 0; qp_id < aesni_mb_dev->nb_queue_pairs; qp_id++) {\n+\t\tqp = aesni_mb_dev->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+\tfor (i = 0; i < n; i++) {\n+\t\tswitch (ids[i]) {\n+\t\tcase 0:\n+\t\t\tvalues[i] = stats.enqueued_count;\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tvalues[i] = stats.dequeued_count;\n+\t\t\tbreak;\n+\t\tcase 2:\n+\t\t\tvalues[i] = stats.enqueue_err_count;\n+\t\t\tbreak;\n+\t\tcase 3:\n+\t\t\tvalues[i] = stats.dequeue_err_count;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tvalues[i] = 0;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn n;\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_xstats_get_names(\n+\t\t\t\t__rte_unused const struct rte_rawdev *rawdev,\n+\t\t\t\tstruct rte_rawdev_xstats_name *names,\n+\t\t\t\tunsigned int size)\n+{\n+\tunsigned int i;\n+\n+\tif (size < RTE_DIM(xstat_names))\n+\t\treturn RTE_DIM(xstat_names);\n+\n+\tfor (i = 0; i < RTE_DIM(xstat_names); i++)\n+\t\tstrlcpy(names[i].name, xstat_names[i], sizeof(names[i]));\n+\n+\treturn RTE_DIM(xstat_names);\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_xstats_reset(struct rte_rawdev *rawdev,\n+\t\t\t\t const uint32_t *ids,\n+\t\t\t\t uint32_t nb_ids)\n+{\n+\tstruct aesni_mb_rawdev *aesni_mb_dev = rawdev->dev_private;\n+\tstruct aesni_mb_rawdev_qp *qp;\n+\tunsigned int i;\n+\tint qp_id;\n+\n+\tif (!ids) {\n+\t\tfor (qp_id = 0; qp_id < aesni_mb_dev->nb_queue_pairs; qp_id++) {\n+\t\t\tqp = aesni_mb_dev->queue_pairs[qp_id];\n+\t\t\tqp->stats.enqueued_count = 0;\n+\t\t\tqp->stats.dequeued_count = 0;\n+\t\t\tqp->stats.enqueue_err_count = 0;\n+\t\t\tqp->stats.dequeue_err_count = 0;\n+\t\t}\n+\n+\t\treturn 0;\n+\t}\n+\n+\tfor (i = 0; i < nb_ids; i++) {\n+\t\tswitch (ids[i]) {\n+\t\tcase 0:\n+\t\t\tfor (qp_id = 0;\n+\t\t\t     qp_id < aesni_mb_dev->nb_queue_pairs;\n+\t\t\t     qp_id++) {\n+\t\t\t\tqp = aesni_mb_dev->queue_pairs[qp_id];\n+\t\t\t\tqp->stats.enqueued_count = 0;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tfor (qp_id = 0;\n+\t\t\t     qp_id < aesni_mb_dev->nb_queue_pairs;\n+\t\t\t     qp_id++) {\n+\t\t\t\tqp = aesni_mb_dev->queue_pairs[qp_id];\n+\t\t\t\tqp->stats.dequeued_count = 0;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase 2:\n+\t\t\tfor (qp_id = 0;\n+\t\t\t     qp_id < aesni_mb_dev->nb_queue_pairs;\n+\t\t\t     qp_id++) {\n+\t\t\t\tqp = aesni_mb_dev->queue_pairs[qp_id];\n+\t\t\t\tqp->stats.enqueue_err_count = 0;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase 3:\n+\t\t\tfor (qp_id = 0;\n+\t\t\t     qp_id < aesni_mb_dev->nb_queue_pairs;\n+\t\t\t     qp_id++) {\n+\t\t\t\tqp = aesni_mb_dev->queue_pairs[qp_id];\n+\t\t\t\tqp->stats.dequeue_err_count = 0;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tAESNI_MB_RAWDEV_ERR(\"Invalid xstat id - cannot reset\");\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_selftest(uint16_t dev_id)\n+{\n+\treturn aesni_mb_rawdev_test(dev_id);\n+}\n+\n+static struct rte_multi_fn_session *\n+aesni_mb_rawdev_pmd_session_create(struct rte_rawdev *rawdev,\n+\t\t\t\t   struct rte_multi_fn_xform *xform,\n+\t\t\t\t   int socket_id)\n+{\n+\tstruct aesni_mb_rawdev *aesni_mb_dev = rawdev->dev_private;\n+\tstruct aesni_mb_rawdev_session *aesni_sess = NULL;\n+\tstruct rte_multi_fn_session *session;\n+\tstruct rte_crypto_sym_xform *cipher_xform;\n+\tenum aesni_mb_rawdev_op op;\n+\tint ret;\n+\n+\top = session_support_check(xform);\n+\n+\t/* Allocate multi-function session */\n+\tsession = rte_zmalloc_socket(\"multi_fn_session\",\n+\t\t\t\t     sizeof(struct rte_multi_fn_session),\n+\t\t\t\t     RTE_CACHE_LINE_MIN_SIZE,\n+\t\t\t\t     socket_id);\n+\n+\tif (session == NULL) {\n+\t\tAESNI_MB_RAWDEV_ERR(\"Multi-function session allocation failed\");\n+\t\treturn NULL;\n+\t}\n+\n+\t/* Allocate AESNI-MB_rawdev session */\n+\taesni_sess = rte_zmalloc_socket(\"aesni_mb_rawdev_session\",\n+\t\t\t\t\tsizeof(struct aesni_mb_rawdev_session),\n+\t\t\t\t\tRTE_CACHE_LINE_MIN_SIZE,\n+\t\t\t\t\tsocket_id);\n+\n+\tif (aesni_sess == NULL) {\n+\t\tAESNI_MB_RAWDEV_ERR(\n+\t\t\t\t\"AESNI-MB rawdev session allocation failed\");\n+\t\treturn NULL;\n+\t}\n+\n+\tsession->sess_private_data = aesni_sess;\n+\taesni_sess->op = op;\n+\n+\tswitch (op) {\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRC_CRYPTO:\n+\tcase AESNI_MB_RAWDEV_OP_PON_CRC_CRYPTO_BIP:\n+\t\taesni_sess->chain_order = IMB_ORDER_HASH_CIPHER;\n+\t\tcipher_xform = &xform->next->crypto_sym;\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_OP_DOCSIS_CRYPTO_CRC:\n+\t\taesni_sess->chain_order = IMB_ORDER_CIPHER_HASH;\n+\t\tcipher_xform = &xform->crypto_sym;\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_OP_PON_BIP_CRYPTO_CRC:\n+\t\taesni_sess->chain_order = IMB_ORDER_CIPHER_HASH;\n+\t\tcipher_xform = &xform->next->crypto_sym;\n+\t\tbreak;\n+\tdefault:\n+\t\tAESNI_MB_RAWDEV_ERR(\"Unsupported multi-function xform chain\");\n+\t\treturn NULL;\n+\t}\n+\n+\tret = session_err_detect_parameters_set(aesni_sess);\n+\n+\tif (ret != 0) {\n+\t\tAESNI_MB_RAWDEV_ERR(\n+\t\t\t\t\"Invalid/unsupported error detect parameters\");\n+\t\treturn NULL;\n+\t}\n+\n+\tret = session_cipher_parameters_set(aesni_mb_dev->mb_mgr,\n+\t\t\t\t\t    aesni_sess,\n+\t\t\t\t\t    cipher_xform);\n+\n+\tif (ret != 0) {\n+\t\tAESNI_MB_RAWDEV_ERR(\"Invalid/unsupported cipher parameters\");\n+\t\treturn NULL;\n+\t}\n+\n+\treturn session;\n+}\n+\n+static int\n+aesni_mb_rawdev_pmd_session_destroy(__rte_unused struct rte_rawdev *rawdev,\n+\t\t\t\t    struct rte_multi_fn_session *sess)\n+{\n+\n+\tif (sess) {\n+\t\tif (sess->sess_private_data)\n+\t\t\trte_free(sess->sess_private_data);\n+\t\trte_free(sess);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static const struct rte_rawdev_ops aesni_mb_rawdev_ops = {\n+\t.dev_configure = aesni_mb_rawdev_pmd_config,\n+\t.dev_info_get = aesni_mb_rawdev_pmd_info_get,\n+\t.dev_start = aesni_mb_rawdev_pmd_start,\n+\t.dev_stop = aesni_mb_rawdev_pmd_stop,\n+\t.dev_close = aesni_mb_rawdev_pmd_close,\n+\t.queue_setup = aesni_mb_rawdev_pmd_qp_setup,\n+\t.queue_release = aesni_mb_rawdev_pmd_qp_release,\n+\t.queue_count = aesni_mb_rawdev_pmd_qp_count,\n+\t.enqueue_bufs = aesni_mb_rawdev_pmd_enq,\n+\t.dequeue_bufs = aesni_mb_rawdev_pmd_deq,\n+\t.xstats_get = aesni_mb_rawdev_pmd_xstats_get,\n+\t.xstats_get_names = aesni_mb_rawdev_pmd_xstats_get_names,\n+\t.xstats_reset = aesni_mb_rawdev_pmd_xstats_reset,\n+\t.dev_selftest = aesni_mb_rawdev_pmd_selftest,\n+};\n+\n+static const struct rte_multi_fn_ops mf_ops = {\n+\t.session_create = aesni_mb_rawdev_pmd_session_create,\n+\t.session_destroy = aesni_mb_rawdev_pmd_session_destroy,\n+};\n+\n+static int\n+aesni_mb_rawdev_create(const char *name,\n+\t\t       struct rte_vdev_device *vdev,\n+\t\t       unsigned int socket_id)\n+{\n+\tstruct rte_rawdev *rawdev;\n+\tstruct aesni_mb_rawdev *aesni_mb_dev;\n+\tenum aesni_mb_rawdev_vector_mode vector_mode;\n+\tMB_MGR *mb_mgr;\n+\n+\t/* Allocate device structure */\n+\trawdev = rte_rawdev_pmd_allocate(name,\n+\t\t\t\t\t sizeof(struct aesni_mb_rawdev),\n+\t\t\t\t\t socket_id);\n+\tif (!rawdev) {\n+\t\tAESNI_MB_RAWDEV_ERR(\"Unable to allocate raw device\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\trawdev->dev_ops = &aesni_mb_rawdev_ops;\n+\trawdev->device = &vdev->device;\n+\trawdev->driver_name = driver_name;\n+\n+\t/* Check CPU for supported vector instruction set */\n+\tif (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F))\n+\t\tvector_mode = AESNI_MB_RAWDEV_AVX512;\n+\telse if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2))\n+\t\tvector_mode = AESNI_MB_RAWDEV_AVX2;\n+\telse if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX))\n+\t\tvector_mode = AESNI_MB_RAWDEV_AVX;\n+\telse\n+\t\tvector_mode = AESNI_MB_RAWDEV_SSE;\n+\n+\t/* Check CPU for support for AES instruction set */\n+\tif (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_AES))\n+\t\tAESNI_MB_RAWDEV_WARN(\"AES instructions not supported by CPU\");\n+\n+\tmb_mgr = alloc_mb_mgr(0);\n+\n+\tif (mb_mgr == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tswitch (vector_mode) {\n+\tcase AESNI_MB_RAWDEV_SSE:\n+\t\tinit_mb_mgr_sse(mb_mgr);\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_AVX:\n+\t\tinit_mb_mgr_avx(mb_mgr);\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_AVX2:\n+\t\tinit_mb_mgr_avx2(mb_mgr);\n+\t\tbreak;\n+\tcase AESNI_MB_RAWDEV_AVX512:\n+\t\tinit_mb_mgr_avx512(mb_mgr);\n+\t\tbreak;\n+\tdefault:\n+\t\tAESNI_MB_RAWDEV_ERR(\"Unsupported vector mode %u\",\n+\t\t\t\t    vector_mode);\n+\t\tfree_mb_mgr(mb_mgr);\n+\t\tmb_mgr = NULL;\n+\t\tbreak;\n+\t}\n+\n+\tif (mb_mgr == NULL) {\n+\t\trte_rawdev_pmd_release(rawdev);\n+\t\treturn -1;\n+\t}\n+\n+\t/* Set the device's private data */\n+\taesni_mb_dev = rawdev->dev_private;\n+\taesni_mb_dev->mf_ops = &mf_ops;\n+\taesni_mb_dev->vector_mode = vector_mode;\n+\taesni_mb_dev->max_nb_queue_pairs = MAX_QUEUES;\n+\taesni_mb_dev->mb_mgr = mb_mgr;\n+\n+\tAESNI_MB_RAWDEV_INFO(\"IPSec Multi-buffer library version used: %s\",\n+\t\t\t     imb_get_version_str());\n+\n+\treturn 0;\n+}\n+\n+static int\n+aesni_mb_rawdev_destroy(const char *name)\n+{\n+\tstruct rte_rawdev *rawdev;\n+\tstruct aesni_mb_rawdev *aesni_mb_dev;\n+\tint ret;\n+\n+\trawdev = rte_rawdev_pmd_get_named_dev(name);\n+\tif (rawdev == NULL) {\n+\t\tAESNI_MB_RAWDEV_ERR(\"Invalid device name (%s)\", name);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\taesni_mb_dev = rawdev->dev_private;\n+\tfree_mb_mgr(aesni_mb_dev->mb_mgr);\n+\n+\tret = rte_rawdev_pmd_release(rawdev);\n+\tif (ret)\n+\t\tAESNI_MB_RAWDEV_DEBUG(\"Device cleanup failed\");\n+\n+\treturn 0;\n+}\n+\n+static int\n+aesni_mb_rawdev_probe(struct rte_vdev_device *vdev)\n+{\n+\tconst char *name;\n+\n+\tname = rte_vdev_device_name(vdev);\n+\tif (name == NULL)\n+\t\treturn -EINVAL;\n+\n+\tAESNI_MB_RAWDEV_INFO(\"Init %s on NUMA node %d\", name, rte_socket_id());\n+\n+\treturn aesni_mb_rawdev_create(name, vdev, rte_socket_id());\n+}\n+\n+static int\n+aesni_mb_rawdev_remove(struct rte_vdev_device *vdev)\n+{\n+\tconst char *name;\n+\n+\tname = rte_vdev_device_name(vdev);\n+\tif (name == NULL)\n+\t\treturn -1;\n+\n+\tAESNI_MB_RAWDEV_INFO(\"Closing %s on NUMA node %d\",\n+\t\t\t     name,\n+\t\t\t     rte_socket_id());\n+\n+\treturn aesni_mb_rawdev_destroy(name);\n+}\n+\n+static struct rte_vdev_driver rawdev_aesni_mb_pmd_drv = {\n+\t.probe = aesni_mb_rawdev_probe,\n+\t.remove = aesni_mb_rawdev_remove\n+};\n+\n+RTE_PMD_REGISTER_VDEV(rawdev_aesni_mb, rawdev_aesni_mb_pmd_drv);\n+\n+RTE_INIT(aesni_mb_raw_init_log)\n+{\n+\taesni_mb_rawdev_pmd_logtype = rte_log_register(\"rawdev.aesni_mb\");\n+\tif (aesni_mb_rawdev_pmd_logtype >= 0)\n+\t\trte_log_set_level(aesni_mb_rawdev_pmd_logtype, RTE_LOG_INFO);\n+}\ndiff --git a/drivers/raw/aesni_mb/aesni_mb_rawdev.h b/drivers/raw/aesni_mb/aesni_mb_rawdev.h\nnew file mode 100644\nindex 000000000..59d78b8d8\n--- /dev/null\n+++ b/drivers/raw/aesni_mb/aesni_mb_rawdev.h\n@@ -0,0 +1,112 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation.\n+ */\n+\n+#ifndef _AESNI_MB_RAWDEV_H_\n+#define _AESNI_MB_RAWDEV_H_\n+\n+#include <intel-ipsec-mb.h>\n+#include <rte_rawdev.h>\n+#include <rte_multi_fn.h>\n+#include <rte_multi_fn_driver.h>\n+\n+/* AESNI-MB Rawdev PMD logtype */\n+int aesni_mb_rawdev_pmd_logtype;\n+\n+#define AESNI_MB_RAWDEV_LOG(level, fmt, args...)  \\\n+\trte_log(RTE_LOG_ ## level, aesni_mb_rawdev_pmd_logtype,  \\\n+\t\t\"%s() line %u: \" fmt \"\\n\", \\\n+\t\t__func__, __LINE__, ##args)\n+#define AESNI_MB_RAWDEV_DEBUG(fmt, args...) \\\n+\tAESNI_MB_RAWDEV_LOG(DEBUG, fmt, ## args)\n+#define AESNI_MB_RAWDEV_INFO(fmt, args...) \\\n+\tAESNI_MB_RAWDEV_LOG(INFO, fmt, ## args)\n+#define AESNI_MB_RAWDEV_ERR(fmt, args...) \\\n+\tAESNI_MB_RAWDEV_LOG(ERR, fmt, ## args)\n+#define AESNI_MB_RAWDEV_WARN(fmt, args...) \\\n+\tAESNI_MB_RAWDEV_LOG(WARNING, fmt, ## args)\n+\n+\n+/* Maximum length for output */\n+#define OUTPUT_LENGTH_MAX 8\n+\n+/* AESNI-MB supported operations */\n+enum aesni_mb_rawdev_op {\n+\tAESNI_MB_RAWDEV_OP_DOCSIS_CRC_CRYPTO,  /* DOCSIS encrypt direction */\n+\tAESNI_MB_RAWDEV_OP_DOCSIS_CRYPTO_CRC,  /* DOCSIS decrypt direction */\n+\tAESNI_MB_RAWDEV_OP_PON_CRC_CRYPTO_BIP, /* PON encrypt direction */\n+\tAESNI_MB_RAWDEV_OP_PON_BIP_CRYPTO_CRC, /* PON decrypt direction */\n+\tAESNI_MB_RAWDEV_OP_NOT_SUPPORTED\n+};\n+\n+/* AESNI-MB device statistics */\n+struct aesni_mb_rawdev_stats {\n+\tuint64_t enqueued_count;\n+\tuint64_t dequeued_count;\n+\tuint64_t enqueue_err_count;\n+\tuint64_t dequeue_err_count;\n+};\n+\n+/* AESNI-MB queue pair */\n+struct aesni_mb_rawdev_qp {\n+\tuint16_t id;\n+\tchar name[RTE_RAWDEV_NAME_MAX_LEN];\n+\tMB_MGR *mb_mgr;\n+\tstruct rte_ring *ingress_queue;\n+\tstruct aesni_mb_rawdev_stats stats;\n+\tuint8_t output_idx;\n+\tuint8_t temp_outputs[MAX_JOBS][OUTPUT_LENGTH_MAX];\n+} __rte_cache_aligned;\n+\n+/* AESNI-MB vector modes */\n+enum aesni_mb_rawdev_vector_mode {\n+\tAESNI_MB_RAWDEV_NOT_SUPPORTED = 0,\n+\tAESNI_MB_RAWDEV_SSE,\n+\tAESNI_MB_RAWDEV_AVX,\n+\tAESNI_MB_RAWDEV_AVX2,\n+\tAESNI_MB_RAWDEV_AVX512\n+};\n+\n+/* AESNI-MB device data */\n+struct aesni_mb_rawdev {\n+\tconst struct rte_multi_fn_ops *mf_ops; /* MUST be first */\n+\tMB_MGR *mb_mgr;\n+\tstruct aesni_mb_rawdev_qp **queue_pairs;\n+\tenum aesni_mb_rawdev_vector_mode vector_mode;\n+\tuint16_t max_nb_queue_pairs;\n+\tuint16_t nb_queue_pairs;\n+};\n+\n+/* AESNI-MB private session structure */\n+struct aesni_mb_rawdev_session {\n+\tenum aesni_mb_rawdev_op op;\n+\tJOB_CHAIN_ORDER chain_order;\n+\tstruct {\n+\t\tuint16_t length;\n+\t\tuint16_t offset;\n+\t} iv;\n+\tstruct {\n+\t\tJOB_CIPHER_DIRECTION direction;\n+\t\tJOB_CIPHER_MODE mode;\n+\n+\t\tuint64_t key_length_in_bytes;\n+\n+\t\tunion {\n+\t\t\tstruct {\n+\t\t\t\tuint32_t encode[60] __rte_aligned(16);\n+\t\t\t\tuint32_t decode[60] __rte_aligned(16);\n+\t\t\t} expanded_aes_keys;\n+\t\t};\n+\t} cipher;\n+\tstruct {\n+\t\tJOB_HASH_ALG algo;\n+\t\tenum rte_multi_fn_err_detect_operation operation;\n+\t\tuint16_t gen_output_len;\n+\n+\t} err_detect;\n+} __rte_cache_aligned;\n+\n+int\n+aesni_mb_rawdev_test(uint16_t dev_id);\n+\n+#endif /* _AESNI_MB_RAWDEV_H_ */\ndiff --git a/drivers/raw/aesni_mb/aesni_mb_rawdev_test.c b/drivers/raw/aesni_mb/aesni_mb_rawdev_test.c\nnew file mode 100644\nindex 000000000..a8051cc80\n--- /dev/null\n+++ b/drivers/raw/aesni_mb/aesni_mb_rawdev_test.c\n@@ -0,0 +1,1102 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation.\n+ */\n+\n+#include <rte_common.h>\n+#include <rte_mbuf.h>\n+#include <rte_malloc.h>\n+#include <rte_memcpy.h>\n+#include <rte_dev.h>\n+#include <rte_bus_vdev.h>\n+#include <rte_rawdev.h>\n+#include <rte_multi_fn.h>\n+#include <rte_ether.h>\n+#include <rte_test.h>\n+\n+#include \"aesni_mb_rawdev.h\"\n+#include \"aesni_mb_rawdev_test_vectors.h\"\n+\n+#define TEST_DEV_NAME \"rawdev_aesni_mb\"\n+\n+#define TEST(setup, teardown, run, data, suffix) \\\n+\ttest_run(setup, teardown, run, data, RTE_STR(run)\"_\"suffix)\n+\n+#define TEST_SUCCESS 0\n+#define TEST_FAILED  -1\n+\n+#define QP_NB_DESC (4096)\n+\n+#define MBUF_POOL_NAME        \"aesni_mb_rawdev_mbuf_pool\"\n+#define MBUF_POOL_SIZE        (8191)\n+#define MBUF_CACHE_SIZE       (256)\n+#define MBUF_DATAPAYLOAD_SIZE (2048)\n+#define MBUF_SIZE             (sizeof(struct rte_mbuf) + \\\n+\t\t\t\tRTE_PKTMBUF_HEADROOM + MBUF_DATAPAYLOAD_SIZE)\n+\n+#define OP_POOL_NAME  \"aesni_mb_rawdev_op_pool\"\n+#define OP_POOL_SIZE  (8191)\n+#define OP_PRIV_SIZE  (16)\n+#define OP_CACHE_SIZE (256)\n+\n+#define MAX_OPS (3)\n+\n+static int eal_log_level;\n+\n+struct testsuite_params {\n+\tuint16_t dev_id;\n+\tstruct rte_mempool *mbuf_pool;\n+\tstruct rte_mempool *op_pool;\n+};\n+\n+struct unittest_params {\n+\tstruct rte_multi_fn_session *sess;\n+\tstruct rte_multi_fn_op *ops[MAX_OPS];\n+\tstruct rte_mbuf *ibuf;\n+\tstruct rte_mbuf *obuf;\n+};\n+\n+static struct testsuite_params testsuite_params;\n+static struct unittest_params unittest_params;\n+\n+static int total;\n+static int passed;\n+static int failed;\n+static int unsupported;\n+\n+static int\n+testsuite_setup(uint16_t dev_id)\n+{\n+\tstruct testsuite_params *ts_params = &testsuite_params;\n+\tuint8_t count = rte_rawdev_count();\n+\n+\teal_log_level = rte_log_get_level(RTE_LOGTYPE_EAL);\n+\trte_log_set_level(RTE_LOGTYPE_EAL, RTE_LOG_DEBUG);\n+\n+\tmemset(ts_params, 0, sizeof(*ts_params));\n+\n+\tif (!count) {\n+\t\tAESNI_MB_RAWDEV_INFO(\"No existing rawdev found - creating %s\",\n+\t\t\t\t     TEST_DEV_NAME);\n+\t\treturn rte_vdev_init(TEST_DEV_NAME, NULL);\n+\t}\n+\n+\tts_params->dev_id = dev_id;\n+\n+\tts_params->mbuf_pool = rte_mempool_lookup(MBUF_POOL_NAME);\n+\tif (ts_params->mbuf_pool == NULL) {\n+\t\t/* Not already created so create */\n+\t\tts_params->mbuf_pool = rte_pktmbuf_pool_create(\n+\t\t\t\t\t\tMBUF_POOL_NAME,\n+\t\t\t\t\t\tMBUF_POOL_SIZE,\n+\t\t\t\t\t\tMBUF_CACHE_SIZE,\n+\t\t\t\t\t\t0,\n+\t\t\t\t\t\tMBUF_SIZE,\n+\t\t\t\t\t\trte_socket_id());\n+\t\tif (ts_params->mbuf_pool == NULL) {\n+\t\t\tAESNI_MB_RAWDEV_ERR(\"Cannot create AESNI-MB rawdev \"\n+\t\t\t\t\t    \"mbuf pool\");\n+\t\t\treturn TEST_FAILED;\n+\t\t}\n+\t}\n+\n+\tts_params->op_pool = rte_multi_fn_op_pool_create(OP_POOL_NAME,\n+\t\t\t\t\t\t\t  OP_POOL_SIZE,\n+\t\t\t\t\t\t\t  OP_CACHE_SIZE,\n+\t\t\t\t\t\t\t  OP_PRIV_SIZE,\n+\t\t\t\t\t\t\t  rte_socket_id());\n+\n+\tif (ts_params->op_pool == NULL) {\n+\t\tAESNI_MB_RAWDEV_ERR(\"Cannot create AESNI-MB rawdev operation \"\n+\t\t\t\t     \"pool\");\n+\t\treturn TEST_FAILED;\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static void\n+testsuite_teardown(void)\n+{\n+\tstruct testsuite_params *ts_params = &testsuite_params;\n+\n+\tif (ts_params->mbuf_pool != NULL) {\n+\t\trte_mempool_free(ts_params->mbuf_pool);\n+\t\tts_params->mbuf_pool = NULL;\n+\t}\n+\n+\tif (ts_params->op_pool != NULL) {\n+\t\trte_mempool_free(ts_params->op_pool);\n+\t\tts_params->op_pool = NULL;\n+\t}\n+\n+\trte_vdev_uninit(TEST_DEV_NAME);\n+\n+\trte_log_set_level(RTE_LOGTYPE_EAL, eal_log_level);\n+}\n+\n+static int\n+test_setup(void)\n+{\n+\tstruct testsuite_params *ts_params = &testsuite_params;\n+\tstruct unittest_params *ut_params = &unittest_params;\n+\n+\tstruct rte_rawdev_info info = {0};\n+\tstruct rte_multi_fn_dev_config mf_dev_conf = {0};\n+\tstruct rte_multi_fn_qp_config qp_conf = {0};\n+\tuint16_t qp_id;\n+\tint ret;\n+\n+\t/* Clear unit test parameters before running test */\n+\tmemset(ut_params, 0, sizeof(*ut_params));\n+\n+\t/* Configure device and queue pairs */\n+\tmf_dev_conf.nb_queues = 1;\n+\tinfo.dev_private = &mf_dev_conf;\n+\tqp_conf.nb_descriptors = QP_NB_DESC;\n+\n+\tret = rte_rawdev_configure(ts_params->dev_id, &info);\n+\tRTE_TEST_ASSERT_SUCCESS(ret,\n+\t\t\t\t\"Failed to configure rawdev %u\",\n+\t\t\t\tts_params->dev_id);\n+\n+\tfor (qp_id = 0; qp_id < mf_dev_conf.nb_queues; qp_id++) {\n+\t\tret = rte_rawdev_queue_setup(ts_params->dev_id,\n+\t\t\t\t\t     qp_id,\n+\t\t\t\t\t     &qp_conf);\n+\t\tRTE_TEST_ASSERT_SUCCESS(ret,\n+\t\t\t\t\t\"Failed to setup queue pair %u on \"\n+\t\t\t\t\t\"rawdev %u\",\n+\t\t\t\t\tqp_id,\n+\t\t\t\t\tts_params->dev_id);\n+\t}\n+\n+\tret = rte_rawdev_xstats_reset(ts_params->dev_id, NULL, 0);\n+\tRTE_TEST_ASSERT_SUCCESS(ret,\n+\t\t\t\t\"Failed to reset stats on rawdev %u\",\n+\t\t\t\tts_params->dev_id);\n+\n+\t/* Start the device */\n+\tret = rte_rawdev_start(ts_params->dev_id);\n+\tRTE_TEST_ASSERT_SUCCESS(ret,\n+\t\t\t\t\"Failed to start rawdev %u\",\n+\t\t\t\tts_params->dev_id);\n+\n+\treturn 0;\n+}\n+\n+static void\n+test_teardown(void)\n+{\n+\tstruct testsuite_params *ts_params = &testsuite_params;\n+\tstruct unittest_params *ut_params = &unittest_params;\n+\n+\tint i;\n+\n+\t/* Free multi-function operations */\n+\tfor (i = 0; i < MAX_OPS; i++) {\n+\t\tif (ut_params->ops[i] != NULL) {\n+\t\t\trte_multi_fn_op_free(ut_params->ops[i]);\n+\t\t\tut_params->ops[i] = NULL;\n+\t\t}\n+\t}\n+\n+\t/* Free multi-function session */\n+\tif (ut_params->sess != NULL) {\n+\t\trte_multi_fn_session_destroy(ts_params->dev_id,\n+\t\t\t\t\t     ut_params->sess);\n+\t\tut_params->sess = NULL;\n+\t}\n+\n+\t/*\n+\t * Free mbuf - both obuf and ibuf are usually the same,\n+\t * so check if they point at the same address is necessary,\n+\t * to avoid freeing the mbuf twice.\n+\t */\n+\tif (ut_params->obuf != NULL) {\n+\t\trte_pktmbuf_free(ut_params->obuf);\n+\t\tif (ut_params->ibuf == ut_params->obuf)\n+\t\t\tut_params->ibuf = NULL;\n+\t\tut_params->obuf = NULL;\n+\t}\n+\tif (ut_params->ibuf != NULL) {\n+\t\trte_pktmbuf_free(ut_params->ibuf);\n+\t\tut_params->ibuf = NULL;\n+\t}\n+\n+\t/* Stop the device */\n+\trte_rawdev_stop(ts_params->dev_id);\n+}\n+\n+static int\n+test_docsis_encrypt(void *vtdata)\n+{\n+\tstruct docsis_test_data *tdata = (struct docsis_test_data *)vtdata;\n+\tstruct testsuite_params *ts_params = &testsuite_params;\n+\tstruct unittest_params *ut_params = &unittest_params;\n+\n+\t/* Xforms */\n+\tstruct rte_multi_fn_xform xform1 = {0};\n+\tstruct rte_multi_fn_xform xform2 = {0};\n+\tstruct rte_crypto_cipher_xform *xform_cipher;\n+\n+\t/* Operations */\n+\tstruct rte_multi_fn_op *result;\n+\tstruct rte_crypto_sym_op *cipher_op;\n+\tstruct rte_multi_fn_err_detect_op *crc_op;\n+\n+\t/* Cipher params */\n+\tint cipher_len = 0;\n+\tuint8_t *iv_ptr;\n+\n+\t/* CRC params */\n+\tint crc_len = 0, crc_data_len = 0;\n+\n+\t/* Test data */\n+\tuint8_t *plaintext = NULL, *ciphertext = NULL;\n+\n+\t/* Stats */\n+\tuint64_t stats[4] = {0};\n+\tstruct rte_rawdev_xstats_name stats_names[4] = {0};\n+\tconst unsigned int stats_id[4] = {0, 1, 2, 3};\n+\tint num_stats = 0, num_names = 0;\n+\n+\tuint16_t qp_id = 0, nb_enq, nb_deq = 0, nb_ops;\n+\tint i, ret = TEST_SUCCESS;\n+\n+\t/* Setup source mbuf */\n+\tut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);\n+\tRTE_TEST_ASSERT_NOT_NULL(ut_params->ibuf,\n+\t\t\t\t \"Failed to allocate source mbuf\");\n+\tmemset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *),\n+\t       0,\n+\t       rte_pktmbuf_tailroom(ut_params->ibuf));\n+\tplaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,\n+\t\t\t\t\t\t  tdata->plaintext.len);\n+\tmemcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len);\n+\n+\t/* Create session */\n+\txform1.type = RTE_MULTI_FN_XFORM_TYPE_ERR_DETECT;\n+\txform1.err_detect.algo = RTE_MULTI_FN_ERR_DETECT_CRC32_ETH;\n+\txform1.err_detect.op = RTE_MULTI_FN_ERR_DETECT_OP_GENERATE;\n+\txform1.next = &xform2;\n+\n+\txform2.type = RTE_MULTI_FN_XFORM_TYPE_CRYPTO_SYM;\n+\txform2.crypto_sym.type = RTE_CRYPTO_SYM_XFORM_CIPHER;\n+\txform_cipher = &xform2.crypto_sym.cipher;\n+\txform_cipher->op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;\n+\txform_cipher->algo = RTE_CRYPTO_CIPHER_AES_DOCSISBPI;\n+\txform_cipher->key.data = tdata->key.data;\n+\txform_cipher->key.length = tdata->key.len;\n+\txform_cipher->iv.offset = sizeof(struct rte_multi_fn_op);\n+\txform_cipher->iv.length = tdata->cipher_iv.len;\n+\txform2.next = NULL;\n+\n+\tut_params->sess = rte_multi_fn_session_create(ts_params->dev_id,\n+\t\t\t\t\t\t      &xform1,\n+\t\t\t\t\t\t      rte_socket_id());\n+\n+\tRTE_TEST_ASSERT((ut_params->sess != NULL &&\n+\t\t\t ut_params->sess->sess_private_data != NULL),\n+\t\t\t\"Failed to create multi-function session\");\n+\n+\t/* Create operations */\n+\tnb_ops = rte_multi_fn_op_bulk_alloc(ts_params->op_pool,\n+\t\t\t\t\t    ut_params->ops,\n+\t\t\t\t\t    2);\n+\tRTE_TEST_ASSERT_EQUAL(nb_ops,\n+\t\t\t      2,\n+\t\t\t      \"Failed to allocate multi-function operations\");\n+\n+\tut_params->ops[0]->next = ut_params->ops[1];\n+\tut_params->ops[0]->m_src = ut_params->ibuf;\n+\tut_params->ops[0]->m_dst = NULL;\n+\tut_params->ops[1]->next = NULL;\n+\n+\t/* CRC op config */\n+\tcrc_len = tdata->plaintext.no_crc == false ?\n+\t\t\t\t\t(tdata->plaintext.len -\n+\t\t\t\t\t tdata->plaintext.crc_offset -\n+\t\t\t\t\t RTE_ETHER_CRC_LEN) :\n+\t\t\t\t\t0;\n+\tcrc_len = crc_len > 0 ? crc_len : 0;\n+\tcrc_data_len = crc_len == 0 ? 0 : RTE_ETHER_CRC_LEN;\n+\tcrc_op = &ut_params->ops[0]->err_detect;\n+\tcrc_op->data.offset = tdata->plaintext.crc_offset;\n+\tcrc_op->data.length = crc_len;\n+\tcrc_op->output.data = rte_pktmbuf_mtod_offset(\n+\t\t\t\t\t\tut_params->ibuf,\n+\t\t\t\t\t\tuint8_t *,\n+\t\t\t\t\t\tut_params->ibuf->data_len -\n+\t\t\t\t\t\t\tcrc_data_len);\n+\n+\t/* Cipher encrypt op config */\n+\tcipher_len = tdata->plaintext.no_cipher == false ?\n+\t\t\t\t\t(tdata->plaintext.len -\n+\t\t\t\t\t tdata->plaintext.cipher_offset) :\n+\t\t\t\t\t0;\n+\tcipher_len = cipher_len > 0 ? cipher_len : 0;\n+\tcipher_op = &ut_params->ops[1]->crypto_sym;\n+\tcipher_op->cipher.data.offset = tdata->plaintext.cipher_offset;\n+\tcipher_op->cipher.data.length = cipher_len;\n+\tiv_ptr = (uint8_t *)(ut_params->ops[1]) +\n+\t\t\t\tsizeof(struct rte_multi_fn_op);\n+\trte_memcpy(iv_ptr, tdata->cipher_iv.data, tdata->cipher_iv.len);\n+\n+\t/* Attach session to operation */\n+\tut_params->ops[0]->sess = ut_params->sess;\n+\n+\t/* Enqueue to device */\n+\tnb_enq = rte_rawdev_enqueue_buffers(\n+\t\t\t\tts_params->dev_id,\n+\t\t\t\t(struct rte_rawdev_buf **)ut_params->ops,\n+\t\t\t\t1,\n+\t\t\t\t(rte_rawdev_obj_t)&qp_id);\n+\n+\tRTE_TEST_ASSERT_EQUAL(nb_enq,\n+\t\t\t      1,\n+\t\t\t      \"Failed to enqueue multi-function operations\");\n+\n+\t/* Dequeue from device */\n+\tdo {\n+\t\tnb_deq = rte_rawdev_dequeue_buffers(\n+\t\t\t\t\tts_params->dev_id,\n+\t\t\t\t\t(struct rte_rawdev_buf **)&result,\n+\t\t\t\t\t1,\n+\t\t\t\t\t(rte_rawdev_obj_t)&qp_id);\n+\t} while (nb_deq < 1);\n+\n+\tRTE_TEST_ASSERT_EQUAL(nb_deq,\n+\t\t\t      1,\n+\t\t\t      \"Failed to dequeue multi-function operations\");\n+\n+\t/* Check results */\n+\tciphertext = plaintext;\n+\n+\t/* Validate ciphertext */\n+\tret = memcmp(ciphertext, tdata->ciphertext.data, tdata->ciphertext.len);\n+\tRTE_TEST_ASSERT_SUCCESS(ret, \"Ciphertext not as expected\");\n+\n+\tRTE_TEST_ASSERT_EQUAL(result->overall_status,\n+\t\t\t      RTE_MULTI_FN_OP_STATUS_SUCCESS,\n+\t\t\t      \"Multi-function op processing failed\");\n+\n+\t/* Print stats */\n+\tnum_stats = rte_rawdev_xstats_get(ts_params->dev_id,\n+\t\t\t\t\t  stats_id,\n+\t\t\t\t\t  stats,\n+\t\t\t\t\t  4);\n+\tnum_names = rte_rawdev_xstats_names_get(ts_params->dev_id,\n+\t\t\t\t\t\tstats_names,\n+\t\t\t\t\t\t4);\n+\tRTE_TEST_ASSERT_EQUAL(num_stats, 4, \"Failed to get stats\");\n+\tRTE_TEST_ASSERT_EQUAL(num_names, 4, \"Failed to get stats names\");\n+\n+\tfor (i = 0; i < num_stats; i++)\n+\t\tAESNI_MB_RAWDEV_DEBUG(\"%s:  %\"PRIu64,\n+\t\t\t\t      stats_names[i].name,\n+\t\t\t\t      stats[i]);\n+\n+\treturn 0;\n+}\n+\n+static int\n+test_docsis_decrypt(void *vtdata)\n+{\n+\tstruct docsis_test_data *tdata = (struct docsis_test_data *)vtdata;\n+\tstruct testsuite_params *ts_params = &testsuite_params;\n+\tstruct unittest_params *ut_params = &unittest_params;\n+\n+\t/* Xforms */\n+\tstruct rte_multi_fn_xform xform1 = {0};\n+\tstruct rte_multi_fn_xform xform2 = {0};\n+\tstruct rte_crypto_cipher_xform *xform_cipher;\n+\n+\t/* Operations */\n+\tstruct rte_multi_fn_op *result;\n+\tstruct rte_crypto_sym_op *cipher_op;\n+\tstruct rte_multi_fn_err_detect_op *crc_op;\n+\n+\t/* Cipher params */\n+\tint cipher_len = 0;\n+\tuint8_t *iv_ptr;\n+\n+\t/* CRC params */\n+\tint crc_len = 0, crc_data_len;\n+\n+\t/* Test data */\n+\tuint8_t *plaintext = NULL, *ciphertext = NULL;\n+\n+\t/* Stats */\n+\tuint64_t stats[4] = {0};\n+\tstruct rte_rawdev_xstats_name stats_names[4] = {0};\n+\tconst unsigned int stats_id[4] = {0, 1, 2, 3};\n+\tint num_stats = 0, num_names = 0;\n+\n+\tuint16_t qp_id = 0, nb_enq, nb_deq = 0, nb_ops;\n+\tint i, ret = TEST_SUCCESS;\n+\n+\t/* Setup source mbuf */\n+\tut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);\n+\tRTE_TEST_ASSERT_NOT_NULL(ut_params->ibuf,\n+\t\t\t\t \"Failed to allocate source mbuf\");\n+\tmemset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *),\n+\t       0,\n+\t       rte_pktmbuf_tailroom(ut_params->ibuf));\n+\tciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,\n+\t\t\t\t\t\t   tdata->ciphertext.len);\n+\tmemcpy(ciphertext, tdata->ciphertext.data, tdata->ciphertext.len);\n+\n+\t/* Create session */\n+\txform1.type = RTE_MULTI_FN_XFORM_TYPE_CRYPTO_SYM;\n+\txform1.crypto_sym.type = RTE_CRYPTO_SYM_XFORM_CIPHER;\n+\txform_cipher = &xform1.crypto_sym.cipher;\n+\txform_cipher->op = RTE_CRYPTO_CIPHER_OP_DECRYPT;\n+\txform_cipher->algo = RTE_CRYPTO_CIPHER_AES_DOCSISBPI;\n+\txform_cipher->key.data = tdata->key.data;\n+\txform_cipher->key.length = tdata->key.len;\n+\txform_cipher->iv.offset = sizeof(struct rte_multi_fn_op);\n+\txform_cipher->iv.length = tdata->cipher_iv.len;\n+\txform1.next = &xform2;\n+\n+\txform2.type = RTE_MULTI_FN_XFORM_TYPE_ERR_DETECT;\n+\txform2.err_detect.algo = RTE_MULTI_FN_ERR_DETECT_CRC32_ETH;\n+\txform2.err_detect.op = RTE_MULTI_FN_ERR_DETECT_OP_VERIFY;\n+\txform2.next = NULL;\n+\n+\tut_params->sess = rte_multi_fn_session_create(ts_params->dev_id,\n+\t\t\t\t\t\t      &xform1,\n+\t\t\t\t\t\t      rte_socket_id());\n+\n+\tRTE_TEST_ASSERT((ut_params->sess != NULL &&\n+\t\t\t ut_params->sess->sess_private_data != NULL),\n+\t\t\t\"Failed to create multi-function session\");\n+\n+\t/* Create operations */\n+\tnb_ops = rte_multi_fn_op_bulk_alloc(ts_params->op_pool,\n+\t\t\t\t\t    ut_params->ops,\n+\t\t\t\t\t    2);\n+\tRTE_TEST_ASSERT_EQUAL(nb_ops,\n+\t\t\t      2,\n+\t\t\t      \"Failed to allocate multi-function operations\");\n+\n+\tut_params->ops[0]->next = ut_params->ops[1];\n+\tut_params->ops[0]->m_src = ut_params->ibuf;\n+\tut_params->ops[0]->m_dst = NULL;\n+\tut_params->ops[1]->next = NULL;\n+\n+\t/* Cipher decrypt op config */\n+\tcipher_len = tdata->ciphertext.no_cipher == false ?\n+\t\t\t\t\t(tdata->ciphertext.len -\n+\t\t\t\t\t tdata->ciphertext.cipher_offset) :\n+\t\t\t\t\t0;\n+\tcipher_len = cipher_len > 0 ? cipher_len : 0;\n+\tcipher_op = &ut_params->ops[0]->crypto_sym;\n+\tcipher_op->cipher.data.offset = tdata->ciphertext.cipher_offset;\n+\tcipher_op->cipher.data.length = cipher_len;\n+\tiv_ptr = (uint8_t *)(ut_params->ops[1]) +\n+\t\t\t\tsizeof(struct rte_multi_fn_op);\n+\trte_memcpy(iv_ptr, tdata->cipher_iv.data, tdata->cipher_iv.len);\n+\n+\t/* CRC op config */\n+\tcrc_len = tdata->plaintext.no_crc == false ?\n+\t\t\t\t\t(tdata->ciphertext.len -\n+\t\t\t\t\t tdata->ciphertext.crc_offset -\n+\t\t\t\t\t RTE_ETHER_CRC_LEN) :\n+\t\t\t\t\t0;\n+\tcrc_len = crc_len > 0 ? crc_len : 0;\n+\tcrc_data_len = crc_len == 0 ? 0 : RTE_ETHER_CRC_LEN;\n+\tcrc_op = &ut_params->ops[1]->err_detect;\n+\tcrc_op->data.offset = tdata->ciphertext.crc_offset;\n+\tcrc_op->data.length = crc_len;\n+\tcrc_op->output.data = rte_pktmbuf_mtod_offset(\n+\t\t\t\t\t\tut_params->ibuf,\n+\t\t\t\t\t\tuint8_t *,\n+\t\t\t\t\t\tut_params->ibuf->data_len -\n+\t\t\t\t\t\t\tcrc_data_len);\n+\n+\t/* Attach session to operation */\n+\tut_params->ops[0]->sess = ut_params->sess;\n+\n+\t/* Enqueue to device */\n+\tnb_enq = rte_rawdev_enqueue_buffers(\n+\t\t\t\tts_params->dev_id,\n+\t\t\t\t(struct rte_rawdev_buf **)ut_params->ops,\n+\t\t\t\t1,\n+\t\t\t\t(rte_rawdev_obj_t)&qp_id);\n+\n+\tRTE_TEST_ASSERT_EQUAL(nb_enq,\n+\t\t\t      1,\n+\t\t\t      \"Failed to enqueue multi-function operations\");\n+\n+\t/* Dequeue to device */\n+\tdo {\n+\t\tnb_deq = rte_rawdev_dequeue_buffers(\n+\t\t\t\t\tts_params->dev_id,\n+\t\t\t\t\t(struct rte_rawdev_buf **)&result,\n+\t\t\t\t\t1,\n+\t\t\t\t\t(rte_rawdev_obj_t)&qp_id);\n+\t} while (nb_deq < 1);\n+\n+\tRTE_TEST_ASSERT_EQUAL(nb_deq,\n+\t\t\t      1,\n+\t\t\t      \"Failed to dequeue multi-function operations\");\n+\n+\t/* Check results */\n+\tplaintext = ciphertext;\n+\n+\t/* Validate plaintext */\n+\tret = memcmp(plaintext,\n+\t\t     tdata->plaintext.data,\n+\t\t     /* Check only as far as CRC - CRC is checked internally */\n+\t\t     tdata->plaintext.len - crc_data_len);\n+\tRTE_TEST_ASSERT_SUCCESS(ret, \"Plaintext not as expected\");\n+\n+\tRTE_TEST_ASSERT_EQUAL(result->overall_status,\n+\t\t\t      RTE_MULTI_FN_OP_STATUS_SUCCESS,\n+\t\t\t      \"Multi-function op processing failed\");\n+\n+\t/* Print stats */\n+\tnum_stats = rte_rawdev_xstats_get(ts_params->dev_id,\n+\t\t\t\t\t  stats_id,\n+\t\t\t\t\t  stats,\n+\t\t\t\t\t  4);\n+\tnum_names = rte_rawdev_xstats_names_get(ts_params->dev_id,\n+\t\t\t\t\t\tstats_names,\n+\t\t\t\t\t\t4);\n+\tRTE_TEST_ASSERT_EQUAL(num_stats, 4, \"Failed to get stats\");\n+\tRTE_TEST_ASSERT_EQUAL(num_names, 4, \"Failed to get stats names\");\n+\n+\tfor (i = 0; i < num_stats; i++)\n+\t\tAESNI_MB_RAWDEV_DEBUG(\"%s:  %\"PRIu64,\n+\t\t\t\t      stats_names[i].name,\n+\t\t\t\t      stats[i]);\n+\n+\treturn 0;\n+}\n+\n+static int\n+test_pon_encrypt(void *vtdata)\n+{\n+\tstruct pon_test_data *tdata = (struct pon_test_data *)vtdata;\n+\tstruct testsuite_params *ts_params = &testsuite_params;\n+\tstruct unittest_params *ut_params = &unittest_params;\n+\n+\t/* Xforms */\n+\tstruct rte_multi_fn_xform xform1 = {0};\n+\tstruct rte_multi_fn_xform xform2 = {0};\n+\tstruct rte_multi_fn_xform xform3 = {0};\n+\tstruct rte_crypto_cipher_xform *xform_cipher;\n+\n+\t/* Operations */\n+\tstruct rte_multi_fn_op *result;\n+\tstruct rte_crypto_sym_op *cipher_op;\n+\tstruct rte_multi_fn_err_detect_op *crc_op;\n+\tstruct rte_multi_fn_err_detect_op *bip_op;\n+\n+\t/* Cipher params */\n+\tint cipher_len = 0;\n+\tuint8_t *iv_ptr;\n+\n+\t/* CRC params */\n+\tint crc_len = 0, crc_data_len = 0;\n+\n+\t/* BIP params */\n+\tint bip_len = 0;\n+\n+\t/* Test data */\n+\tuint8_t *plaintext = NULL, *ciphertext = NULL;\n+\n+\t/* Stats */\n+\tuint64_t stats[4] = {0};\n+\tstruct rte_rawdev_xstats_name stats_names[4] = {0};\n+\tconst unsigned int stats_id[4] = {0, 1, 2, 3};\n+\tint num_stats = 0, num_names = 0;\n+\n+\tuint16_t qp_id = 0, nb_enq, nb_deq = 0, nb_ops;\n+\tint i, ret = TEST_SUCCESS;\n+\n+\t/* Setup source mbuf */\n+\tut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);\n+\tRTE_TEST_ASSERT_NOT_NULL(ut_params->ibuf,\n+\t\t\t\t \"Failed to allocate source mbuf\");\n+\tmemset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *),\n+\t       0,\n+\t       rte_pktmbuf_tailroom(ut_params->ibuf));\n+\tplaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,\n+\t\t\t\t\t\t  tdata->plaintext.len);\n+\tmemcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len);\n+\n+\t/* Create session */\n+\txform1.type = RTE_MULTI_FN_XFORM_TYPE_ERR_DETECT;\n+\txform1.err_detect.algo = RTE_MULTI_FN_ERR_DETECT_CRC32_ETH;\n+\txform1.err_detect.op = RTE_MULTI_FN_ERR_DETECT_OP_GENERATE;\n+\txform1.next = &xform2;\n+\n+\txform2.type = RTE_MULTI_FN_XFORM_TYPE_CRYPTO_SYM;\n+\txform2.crypto_sym.type = RTE_CRYPTO_SYM_XFORM_CIPHER;\n+\txform_cipher = &xform2.crypto_sym.cipher;\n+\txform_cipher->op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;\n+\txform_cipher->algo = RTE_CRYPTO_CIPHER_AES_CTR;\n+\txform_cipher->key.data = tdata->key.data;\n+\txform_cipher->key.length = tdata->key.len;\n+\txform_cipher->iv.offset = sizeof(struct rte_multi_fn_op);\n+\txform_cipher->iv.length = tdata->cipher_iv.len;\n+\txform2.next = &xform3;\n+\n+\txform3.type = RTE_MULTI_FN_XFORM_TYPE_ERR_DETECT;\n+\txform3.err_detect.algo = RTE_MULTI_FN_ERR_DETECT_BIP32;\n+\txform3.err_detect.op = RTE_MULTI_FN_ERR_DETECT_OP_GENERATE;\n+\txform3.next = NULL;\n+\n+\tut_params->sess = rte_multi_fn_session_create(ts_params->dev_id,\n+\t\t\t\t\t\t      &xform1,\n+\t\t\t\t\t\t      rte_socket_id());\n+\n+\tRTE_TEST_ASSERT((ut_params->sess != NULL &&\n+\t\t\t ut_params->sess->sess_private_data != NULL),\n+\t\t\t\"Failed to create multi-function session\");\n+\n+\t/* Create operations */\n+\tnb_ops = rte_multi_fn_op_bulk_alloc(ts_params->op_pool,\n+\t\t\t\t\t    ut_params->ops,\n+\t\t\t\t\t    3);\n+\tRTE_TEST_ASSERT_EQUAL(nb_ops,\n+\t\t\t      3,\n+\t\t\t      \"Failed to allocate multi-function operations\");\n+\n+\tut_params->ops[0]->next = ut_params->ops[1];\n+\tut_params->ops[0]->m_src = ut_params->ibuf;\n+\tut_params->ops[0]->m_dst = NULL;\n+\tut_params->ops[1]->next = ut_params->ops[2];\n+\tut_params->ops[2]->next = NULL;\n+\n+\t/* CRC op config */\n+\tcrc_len = tdata->plaintext.len -\n+\t\t\ttdata->plaintext.crc_offset -\n+\t\t\ttdata->plaintext.padding_len -\n+\t\t\tRTE_ETHER_CRC_LEN;\n+\tcrc_len = crc_len > 0 ? crc_len : 0;\n+\tcrc_data_len = crc_len == 0 ? 0 : RTE_ETHER_CRC_LEN;\n+\tcrc_op = &ut_params->ops[0]->err_detect;\n+\tcrc_op->data.offset = tdata->plaintext.crc_offset;\n+\tcrc_op->data.length = crc_len;\n+\tcrc_op->output.data = rte_pktmbuf_mtod_offset(\n+\t\t\t\t\tut_params->ibuf,\n+\t\t\t\t\tuint8_t *,\n+\t\t\t\t\tut_params->ibuf->data_len -\n+\t\t\t\t\t\ttdata->plaintext.padding_len -\n+\t\t\t\t\t\tcrc_data_len);\n+\n+\t/* Cipher encrypt op config */\n+\tcipher_len = tdata->plaintext.no_cipher == false ?\n+\t\t\t\t\t(tdata->plaintext.len -\n+\t\t\t\t\t tdata->plaintext.cipher_offset) :\n+\t\t\t\t\t0;\n+\tcipher_len = cipher_len > 0 ? cipher_len : 0;\n+\tcipher_op = &ut_params->ops[1]->crypto_sym;\n+\tcipher_op->cipher.data.offset = tdata->plaintext.cipher_offset;\n+\tcipher_op->cipher.data.length = cipher_len;\n+\tiv_ptr = (uint8_t *)(ut_params->ops[1]) +\n+\t\t\t\tsizeof(struct rte_multi_fn_op);\n+\trte_memcpy(iv_ptr, tdata->cipher_iv.data, tdata->cipher_iv.len);\n+\n+\t/* BIP op config */\n+\tbip_len = tdata->plaintext.len - tdata->plaintext.bip_offset;\n+\tbip_len = bip_len > 0 ? bip_len : 0;\n+\tbip_op = &ut_params->ops[2]->err_detect;\n+\tbip_op->data.offset = tdata->plaintext.bip_offset;\n+\tbip_op->data.length = bip_len;\n+\tbip_op->output.data = (uint8_t *)(ut_params->ops[2]) +\n+\t\t\t\tsizeof(struct rte_multi_fn_op);\n+\n+\t/* Attach session to op */\n+\tut_params->ops[0]->sess = ut_params->sess;\n+\n+\t/* Enqueue to device */\n+\tnb_enq = rte_rawdev_enqueue_buffers(\n+\t\t\t\tts_params->dev_id,\n+\t\t\t\t(struct rte_rawdev_buf **)ut_params->ops,\n+\t\t\t\t1,\n+\t\t\t\t(rte_rawdev_obj_t)&qp_id);\n+\n+\tRTE_TEST_ASSERT_EQUAL(nb_enq,\n+\t\t\t      1,\n+\t\t\t      \"Failed to enqueue multi-function operations\");\n+\n+\t/* Dequeue from device */\n+\tdo {\n+\t\tnb_deq = rte_rawdev_dequeue_buffers(\n+\t\t\t\t\tts_params->dev_id,\n+\t\t\t\t\t(struct rte_rawdev_buf **)&result,\n+\t\t\t\t\t1,\n+\t\t\t\t\t(rte_rawdev_obj_t)&qp_id);\n+\t} while (nb_deq < 1);\n+\n+\t/* Check results */\n+\tciphertext = plaintext;\n+\n+\t/* Validate ciphertext */\n+\tret = memcmp(ciphertext, tdata->ciphertext.data, tdata->ciphertext.len);\n+\tRTE_TEST_ASSERT_SUCCESS(ret, \"Ciphertext not as expected\");\n+\n+\tret = memcmp(bip_op->output.data,\n+\t\t     tdata->output.data,\n+\t\t     tdata->output.len);\n+\tRTE_TEST_ASSERT_SUCCESS(ret, \"BIP not as expected\");\n+\n+\tRTE_TEST_ASSERT_EQUAL(result->overall_status,\n+\t\t\t      RTE_MULTI_FN_OP_STATUS_SUCCESS,\n+\t\t\t      \"Multi-function op processing failed\");\n+\n+\t/* Print stats */\n+\tnum_stats = rte_rawdev_xstats_get(ts_params->dev_id,\n+\t\t\t\t\t  stats_id,\n+\t\t\t\t\t  stats,\n+\t\t\t\t\t  4);\n+\tnum_names = rte_rawdev_xstats_names_get(ts_params->dev_id,\n+\t\t\t\t\t\tstats_names,\n+\t\t\t\t\t\t4);\n+\tRTE_TEST_ASSERT_EQUAL(num_stats, 4, \"Failed to get stats\");\n+\tRTE_TEST_ASSERT_EQUAL(num_names, 4, \"Failed to get stats names\");\n+\n+\tfor (i = 0; i < num_stats; i++)\n+\t\tAESNI_MB_RAWDEV_DEBUG(\"%s:  %\"PRIu64,\n+\t\t\t\t      stats_names[i].name,\n+\t\t\t\t      stats[i]);\n+\n+\treturn 0;\n+}\n+\n+static int\n+test_pon_decrypt(void *vtdata)\n+{\n+\tstruct pon_test_data *tdata = (struct pon_test_data *)vtdata;\n+\tstruct testsuite_params *ts_params = &testsuite_params;\n+\tstruct unittest_params *ut_params = &unittest_params;\n+\n+\t/* Xforms */\n+\tstruct rte_multi_fn_xform xform1 = {0};\n+\tstruct rte_multi_fn_xform xform2 = {0};\n+\tstruct rte_multi_fn_xform xform3 = {0};\n+\tstruct rte_crypto_cipher_xform *xform_cipher;\n+\n+\t/* Operations */\n+\tstruct rte_multi_fn_op *result;\n+\tstruct rte_crypto_sym_op *cipher_op;\n+\tstruct rte_multi_fn_err_detect_op *crc_op;\n+\tstruct rte_multi_fn_err_detect_op *bip_op;\n+\n+\t/* Cipher params */\n+\tint cipher_len = 0;\n+\tuint8_t *iv_ptr;\n+\n+\t/* CRC params */\n+\tint crc_len = 0, crc_data_len = 0;\n+\n+\t/* BIP params */\n+\tint bip_len = 0;\n+\n+\t/* Test data */\n+\tuint8_t *plaintext = NULL, *ciphertext = NULL;\n+\n+\t/* Stats */\n+\tuint64_t stats[4] = {0};\n+\tstruct rte_rawdev_xstats_name stats_names[4] = {0};\n+\tconst unsigned int stats_id[4] = {0, 1, 2, 3};\n+\tint num_stats = 0, num_names = 0;\n+\n+\tuint16_t qp_id = 0, nb_enq, nb_deq = 0, nb_ops;\n+\tint i, ret = TEST_SUCCESS;\n+\n+\t/* Setup source mbuf */\n+\tut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);\n+\tRTE_TEST_ASSERT_NOT_NULL(ut_params->ibuf,\n+\t\t\t\t \"Failed to allocate source mbuf\");\n+\tmemset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *),\n+\t       0,\n+\t       rte_pktmbuf_tailroom(ut_params->ibuf));\n+\tciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,\n+\t\t\t\t\t\t   tdata->ciphertext.len);\n+\tmemcpy(ciphertext, tdata->ciphertext.data, tdata->ciphertext.len);\n+\n+\t/* Create session */\n+\txform1.type = RTE_MULTI_FN_XFORM_TYPE_ERR_DETECT;\n+\txform1.err_detect.algo = RTE_MULTI_FN_ERR_DETECT_BIP32;\n+\txform1.err_detect.op = RTE_MULTI_FN_ERR_DETECT_OP_GENERATE;\n+\txform1.next = &xform2;\n+\n+\txform2.type = RTE_MULTI_FN_XFORM_TYPE_CRYPTO_SYM;\n+\txform2.crypto_sym.type = RTE_CRYPTO_SYM_XFORM_CIPHER;\n+\txform_cipher = &xform2.crypto_sym.cipher;\n+\txform_cipher->op = RTE_CRYPTO_CIPHER_OP_DECRYPT;\n+\txform_cipher->algo = RTE_CRYPTO_CIPHER_AES_CTR;\n+\txform_cipher->key.data = tdata->key.data;\n+\txform_cipher->key.length = tdata->key.len;\n+\txform_cipher->iv.offset = sizeof(struct rte_multi_fn_op);\n+\txform_cipher->iv.length = tdata->cipher_iv.len;\n+\txform2.next = &xform3;\n+\n+\txform3.type = RTE_MULTI_FN_XFORM_TYPE_ERR_DETECT;\n+\txform3.err_detect.algo = RTE_MULTI_FN_ERR_DETECT_CRC32_ETH;\n+\txform3.err_detect.op = RTE_MULTI_FN_ERR_DETECT_OP_VERIFY;\n+\txform3.next = NULL;\n+\n+\tut_params->sess = rte_multi_fn_session_create(ts_params->dev_id,\n+\t\t\t\t\t\t      &xform1,\n+\t\t\t\t\t\t      rte_socket_id());\n+\n+\tRTE_TEST_ASSERT((ut_params->sess != NULL &&\n+\t\t\t ut_params->sess->sess_private_data != NULL),\n+\t\t\t\"Failed to create multi-function session\");\n+\n+\t/* Create operations */\n+\tnb_ops = rte_multi_fn_op_bulk_alloc(ts_params->op_pool,\n+\t\t\t\t\t    ut_params->ops,\n+\t\t\t\t\t    3);\n+\tRTE_TEST_ASSERT_EQUAL(nb_ops,\n+\t\t\t      3,\n+\t\t\t      \"Failed to allocate multi-function operations\");\n+\n+\tut_params->ops[0]->next = ut_params->ops[1];\n+\tut_params->ops[0]->m_src = ut_params->ibuf;\n+\tut_params->ops[0]->m_dst = NULL;\n+\tut_params->ops[1]->next = ut_params->ops[2];\n+\tut_params->ops[2]->next = NULL;\n+\n+\t/* BIP op config */\n+\tbip_len = tdata->ciphertext.len - tdata->ciphertext.bip_offset;\n+\tbip_len = bip_len > 0 ? bip_len : 0;\n+\tbip_op = &ut_params->ops[0]->err_detect;\n+\tbip_op->data.offset = tdata->ciphertext.bip_offset;\n+\tbip_op->data.length = bip_len;\n+\tbip_op->output.data = (uint8_t *)(ut_params->ops[0]) +\n+\t\t\t\tsizeof(struct rte_multi_fn_op);\n+\n+\t/* Cipher encrypt op config */\n+\tcipher_len = tdata->ciphertext.no_cipher == false ?\n+\t\t\t\t\t(tdata->ciphertext.len -\n+\t\t\t\t\t tdata->ciphertext.cipher_offset) :\n+\t\t\t\t\t0;\n+\tcipher_len = cipher_len > 0 ? cipher_len : 0;\n+\tcipher_op = &ut_params->ops[1]->crypto_sym;\n+\tcipher_op->cipher.data.offset = tdata->ciphertext.cipher_offset;\n+\tcipher_op->cipher.data.length = cipher_len;\n+\tiv_ptr = (uint8_t *)(ut_params->ops[1]) +\n+\t\t\t\tsizeof(struct rte_multi_fn_op);\n+\trte_memcpy(iv_ptr, tdata->cipher_iv.data, tdata->cipher_iv.len);\n+\n+\t/* CRC op config */\n+\tcrc_len = tdata->ciphertext.len -\n+\t\t\ttdata->ciphertext.crc_offset -\n+\t\t\ttdata->ciphertext.padding_len -\n+\t\t\tRTE_ETHER_CRC_LEN;\n+\tcrc_len = crc_len > 0 ? crc_len : 0;\n+\tcrc_data_len = crc_len == 0 ? 0 : RTE_ETHER_CRC_LEN;\n+\tcrc_op = &ut_params->ops[2]->err_detect;\n+\tcrc_op->data.offset = tdata->ciphertext.crc_offset;\n+\tcrc_op->data.length = crc_len;\n+\tcrc_op->output.data = rte_pktmbuf_mtod_offset(\n+\t\t\t\t\tut_params->ibuf,\n+\t\t\t\t\tuint8_t *,\n+\t\t\t\t\tut_params->ibuf->data_len -\n+\t\t\t\t\t\ttdata->ciphertext.padding_len -\n+\t\t\t\t\t\tcrc_data_len);\n+\n+\t/* Attach session to op */\n+\tut_params->ops[0]->sess = ut_params->sess;\n+\n+\t/* Enqueue to device */\n+\tnb_enq = rte_rawdev_enqueue_buffers(\n+\t\t\t\tts_params->dev_id,\n+\t\t\t\t(struct rte_rawdev_buf **)ut_params->ops,\n+\t\t\t\t1,\n+\t\t\t\t(rte_rawdev_obj_t)&qp_id);\n+\n+\tRTE_TEST_ASSERT_EQUAL(nb_enq,\n+\t\t\t      1,\n+\t\t\t      \"Failed to enqueue multi-function operations\");\n+\n+\t/* Dequeue from device */\n+\tdo {\n+\t\tnb_deq = rte_rawdev_dequeue_buffers(\n+\t\t\t\t\tts_params->dev_id,\n+\t\t\t\t\t(struct rte_rawdev_buf **)&result,\n+\t\t\t\t\t1,\n+\t\t\t\t\t(rte_rawdev_obj_t)&qp_id);\n+\t} while (nb_deq < 1);\n+\n+\t/* Check results */\n+\tplaintext = ciphertext;\n+\n+\t/* Validate plaintext */\n+\tret = memcmp(plaintext,\n+\t\t     tdata->plaintext.data,\n+\t\t     /* Check only as far as CRC - CRC is checked internally */\n+\t\t     tdata->plaintext.len -\n+\t\t\ttdata->plaintext.padding_len -\n+\t\t\tcrc_data_len);\n+\tRTE_TEST_ASSERT_SUCCESS(ret, \"Plaintext not as expected\");\n+\n+\tret = memcmp(bip_op->output.data,\n+\t\t     tdata->output.data,\n+\t\t     tdata->output.len);\n+\tRTE_TEST_ASSERT_SUCCESS(ret, \"BIP not as expected\");\n+\n+\tRTE_TEST_ASSERT_EQUAL(result->overall_status,\n+\t\t\t      RTE_MULTI_FN_OP_STATUS_SUCCESS,\n+\t\t\t      \"Multi-function op processing failed\");\n+\n+\t/* Print stats */\n+\tnum_stats = rte_rawdev_xstats_get(ts_params->dev_id,\n+\t\t\t\t\t  stats_id,\n+\t\t\t\t\t  stats,\n+\t\t\t\t\t  4);\n+\tnum_names = rte_rawdev_xstats_names_get(ts_params->dev_id,\n+\t\t\t\t\t\tstats_names,\n+\t\t\t\t\t\t4);\n+\tRTE_TEST_ASSERT_EQUAL(num_stats, 4, \"Failed to get stats\");\n+\tRTE_TEST_ASSERT_EQUAL(num_names, 4, \"Failed to get stats names\");\n+\n+\tfor (i = 0; i < num_stats; i++)\n+\t\tAESNI_MB_RAWDEV_DEBUG(\"%s:  %\"PRIu64,\n+\t\t\t\t      stats_names[i].name,\n+\t\t\t\t      stats[i]);\n+\n+\treturn 0;\n+}\n+\n+static void\n+test_run(int (*setup)(void),\n+\t void (*teardown)(void),\n+\t int (*run)(void *),\n+\t void *data,\n+\t const char *name)\n+{\n+\tint ret = 0;\n+\n+\tif (setup != NULL) {\n+\t\tret = setup();\n+\t\tif (ret < 0) {\n+\t\t\tAESNI_MB_RAWDEV_INFO(\"Error setting up test %s\", name);\n+\t\t\tunsupported++;\n+\t\t}\n+\t}\n+\n+\tif (run != NULL) {\n+\t\tret = run(data);\n+\t\tif (ret < 0) {\n+\t\t\tfailed++;\n+\t\t\tAESNI_MB_RAWDEV_INFO(\"%s Failed\", name);\n+\t\t} else {\n+\t\t\tpassed++;\n+\t\t\tAESNI_MB_RAWDEV_INFO(\"%s Passed\", name);\n+\t\t}\n+\t}\n+\n+\tif (teardown != NULL)\n+\t\tteardown();\n+\n+\ttotal++;\n+}\n+\n+int\n+aesni_mb_rawdev_test(uint16_t dev_id)\n+{\n+\tif (testsuite_setup(dev_id) != TEST_SUCCESS) {\n+\t\tAESNI_MB_RAWDEV_ERR(\"Setup failed\");\n+\t\ttestsuite_teardown();\n+\t\treturn TEST_FAILED;\n+\t}\n+\n+\t/* DOCSIS: Crypto-CRC */\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_1, \"1\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_2, \"2\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_3, \"3\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_4, \"4\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_5, \"5\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_6, \"6\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_7, \"7\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_8, \"8\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_9, \"9\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_10, \"10\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_11, \"11\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_12, \"12\");\n+\tTEST(test_setup, test_teardown, test_docsis_encrypt,\n+\t     &docsis_test_case_13, \"13\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_1, \"1\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_2, \"2\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_3, \"3\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_4, \"4\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_5, \"5\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_6, \"6\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_7, \"7\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_8, \"8\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_9, \"9\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_10, \"10\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_11, \"11\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_12, \"12\");\n+\tTEST(test_setup, test_teardown, test_docsis_decrypt,\n+\t     &docsis_test_case_13, \"13\");\n+\n+\t/* PON: Crypto-CRC-BIP */\n+\tTEST(test_setup, test_teardown, test_pon_encrypt,\n+\t     &pon_test_case_1, \"1\");\n+\tTEST(test_setup, test_teardown, test_pon_encrypt,\n+\t     &pon_test_case_2, \"2\");\n+\tTEST(test_setup, test_teardown, test_pon_encrypt,\n+\t     &pon_test_case_3, \"3\");\n+\tTEST(test_setup, test_teardown, test_pon_encrypt,\n+\t     &pon_test_case_4, \"4\");\n+\tTEST(test_setup, test_teardown, test_pon_encrypt,\n+\t     &pon_test_case_5, \"5\");\n+\tTEST(test_setup, test_teardown, test_pon_encrypt,\n+\t     &pon_test_case_6, \"6\");\n+\tTEST(test_setup, test_teardown, test_pon_decrypt,\n+\t     &pon_test_case_1, \"1\");\n+\tTEST(test_setup, test_teardown, test_pon_decrypt,\n+\t     &pon_test_case_2, \"2\");\n+\tTEST(test_setup, test_teardown, test_pon_decrypt,\n+\t     &pon_test_case_3, \"3\");\n+\tTEST(test_setup, test_teardown, test_pon_decrypt,\n+\t     &pon_test_case_4, \"4\");\n+\tTEST(test_setup, test_teardown, test_pon_decrypt,\n+\t     &pon_test_case_5, \"5\");\n+\tTEST(test_setup, test_teardown, test_pon_decrypt,\n+\t     &pon_test_case_6, \"6\");\n+\n+\ttestsuite_teardown();\n+\n+\tprintf(\"Total tests   : %d\\n\", total);\n+\tprintf(\"Passed        : %d\\n\", passed);\n+\tprintf(\"Failed        : %d\\n\", failed);\n+\tprintf(\"Not supported : %d\\n\", unsupported);\n+\n+\tif (failed)\n+\t\treturn TEST_FAILED;\n+\n+\treturn TEST_SUCCESS;\n+}\ndiff --git a/drivers/raw/aesni_mb/aesni_mb_rawdev_test_vectors.h b/drivers/raw/aesni_mb/aesni_mb_rawdev_test_vectors.h\nnew file mode 100644\nindex 000000000..46bb220f4\n--- /dev/null\n+++ b/drivers/raw/aesni_mb/aesni_mb_rawdev_test_vectors.h\n@@ -0,0 +1,1183 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation.\n+ */\n+\n+#ifndef _AESNI_MB_RAWDEV_TEST_VECTORS_H_\n+#define _AESNI_MB_RAWDEV_TEST_VECTORS_H_\n+\n+#include <stdbool.h>\n+\n+/*\n+ * DOCSIS test data and cases\n+ * - encrypt direction: CRC-Crypto\n+ * - decrypt direction: Crypto-CRC\n+ */\n+struct docsis_test_data {\n+\tstruct {\n+\t\tuint8_t data[16];\n+\t\tunsigned int len;\n+\t} key;\n+\n+\tstruct {\n+\t\tuint8_t data[16] __rte_aligned(16);\n+\t\tunsigned int len;\n+\t} cipher_iv;\n+\n+\tstruct {\n+\t\tuint8_t data[1024];\n+\t\tunsigned int len;\n+\t\tunsigned int cipher_offset;\n+\t\tunsigned int crc_offset;\n+\t\tbool no_cipher;\n+\t\tbool no_crc;\n+\t} plaintext;\n+\n+\tstruct {\n+\t\tuint8_t data[1024];\n+\t\tunsigned int len;\n+\t\tunsigned int cipher_offset;\n+\t\tunsigned int crc_offset;\n+\t\tbool no_cipher;\n+\t\tbool no_crc;\n+\t} ciphertext;\n+};\n+\n+struct docsis_test_data docsis_test_case_1 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x7A, 0xF0,\n+\t\t\t/* CRC */\n+\t\t\t0x61, 0xF8, 0x63, 0x42\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_2 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 25,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x7A, 0xF0, 0xDF,\n+\t\t\t/* CRC */\n+\t\t\t0xFE, 0x12, 0x99, 0xE5\n+\t\t},\n+\t\t.len = 25,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_3 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 34,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0xD6, 0xE2, 0x70, 0x5C,\n+\t\t\t0xE6, 0x4D, 0xCC, 0x8C, 0x47, 0xB7, 0x09, 0xD6,\n+\t\t\t/* CRC */\n+\t\t\t0x54, 0x85, 0xF8, 0x32\n+\t\t},\n+\t\t.len = 34,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_4 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 35,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x92, 0x6A, 0xC2, 0xDC,\n+\t\t\t0xEE, 0x3B, 0x31, 0xEC, 0x03, 0xDE, 0x95, 0x33,\n+\t\t\t0x5E,\n+\t\t\t/* CRC */\n+\t\t\t0xFE, 0x47, 0x3E, 0x22\n+\t\t},\n+\t\t.len = 35,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_5 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 82,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x77, 0x74, 0x56, 0x05,\n+\t\t\t0xD1, 0x14, 0xA2, 0x8D, 0x2C, 0x9A, 0x11, 0xFC,\n+\t\t\t0x7D, 0xB0, 0xE7, 0x18, 0xCE, 0x75, 0x7C, 0x89,\n+\t\t\t0x14, 0x56, 0xE2, 0xF2, 0xB7, 0x47, 0x08, 0x27,\n+\t\t\t0xF7, 0x08, 0x7A, 0x13, 0x90, 0x81, 0x75, 0xB0,\n+\t\t\t0xC7, 0x91, 0x04, 0x83, 0xAD, 0x11, 0x46, 0x46,\n+\t\t\t0xF8, 0x54, 0x87, 0xA0, 0x42, 0xF3, 0x71, 0xA9,\n+\t\t\t0x8A, 0xCD, 0x59, 0x77, 0x67, 0x11, 0x1A, 0x87,\n+\t\t\t/* CRC */\n+\t\t\t0xAB, 0xED, 0x2C, 0x26\n+\t\t},\n+\t\t.len = 82,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_6 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 83,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x77, 0x74, 0x56, 0x05,\n+\t\t\t0xD1, 0x14, 0xA2, 0x8D, 0x2C, 0x9A, 0x11, 0xFC,\n+\t\t\t0x7D, 0xB0, 0xE7, 0x18, 0xCE, 0x75, 0x7C, 0x89,\n+\t\t\t0x14, 0x56, 0xE2, 0xF2, 0xB7, 0x47, 0x08, 0x27,\n+\t\t\t0xF7, 0x08, 0x7A, 0x13, 0x90, 0x81, 0x75, 0xB0,\n+\t\t\t0xC7, 0x91, 0x04, 0x83, 0xAD, 0x11, 0x46, 0x46,\n+\t\t\t0xF8, 0x54, 0x87, 0xA0, 0xA4, 0x0C, 0xC2, 0xF0,\n+\t\t\t0x81, 0x49, 0xA8, 0xA6, 0x6C, 0x48, 0xEB, 0x1F,\n+\t\t\t0x4B,\n+\t\t\t/* CRC */\n+\t\t\t0x2F, 0xD4, 0x48, 0x18\n+\t\t},\n+\t\t.len = 83,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_7 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 83,\n+\t\t.cipher_offset = 40,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0x3B, 0x9F, 0x72, 0x4C, 0xB5, 0x72,\n+\t\t\t0x3E, 0x56, 0x54, 0x49, 0x13, 0x53, 0xC4, 0xAA,\n+\t\t\t0xCD, 0xEA, 0x6A, 0x88, 0x99, 0x07, 0x86, 0xF4,\n+\t\t\t0xCF, 0x03, 0x4E, 0xDF, 0x65, 0x61, 0x47, 0x5B,\n+\t\t\t0x2F, 0x81, 0x09, 0x12, 0x9A, 0xC2, 0x24, 0x8C,\n+\t\t\t0x09,\n+\t\t\t/* CRC */\n+\t\t\t0x11, 0xB4, 0x06, 0x33\n+\t\t},\n+\t\t.len = 83,\n+\t\t.cipher_offset = 40,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = false\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_8 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = true\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x7A, 0xF0,\n+\t\t\t/* CRC */\n+\t\t\t0x8A, 0x0F, 0x74, 0xE8\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = true\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_9 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 83,\n+\t\t.cipher_offset = 40,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = true\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0x3B, 0x9F, 0x72, 0x4C, 0xB5, 0x72,\n+\t\t\t0x3E, 0x56, 0x54, 0x49, 0x13, 0x53, 0xC4, 0xAA,\n+\t\t\t0xCD, 0xEA, 0x6A, 0x88, 0x99, 0x07, 0x86, 0xF4,\n+\t\t\t0xCF, 0x03, 0x4E, 0xDF, 0x65, 0x61, 0x47, 0x5B,\n+\t\t\t0x2F, 0x81, 0x09, 0x12, 0x9A, 0xC2, 0x24, 0x8C,\n+\t\t\t0x09,\n+\t\t\t/* CRC */\n+\t\t\t0x5D, 0x2B, 0x12, 0xF4\n+\t\t},\n+\t\t.len = 83,\n+\t\t.cipher_offset = 40,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = false,\n+\t\t.no_crc = true\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_10 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = true,\n+\t\t.no_crc = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00,\n+\t\t\t/* CRC */\n+\t\t\t0x14, 0x08, 0xE8, 0x55\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = true,\n+\t\t.no_crc = false\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_11 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 83,\n+\t\t.cipher_offset = 40,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = true,\n+\t\t.no_crc = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA,\n+\t\t\t/* CRC */\n+\t\t\t0xB3, 0x60, 0xEB, 0x38\n+\t\t},\n+\t\t.len = 83,\n+\t\t.cipher_offset = 40,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = true,\n+\t\t.no_crc = false\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_12 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = true,\n+\t\t.no_crc = true\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 18,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = true,\n+\t\t.no_crc = true\n+\t}\n+};\n+\n+struct docsis_test_data docsis_test_case_13 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 83,\n+\t\t.cipher_offset = 40,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = true,\n+\t\t.no_crc = true\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* DOCSIS header */\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t\t0xAA,\n+\t\t\t/* CRC */\n+\t\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t\t},\n+\t\t.len = 83,\n+\t\t.cipher_offset = 40,\n+\t\t.crc_offset = 6,\n+\t\t.no_cipher = true,\n+\t\t.no_crc = true\n+\t}\n+};\n+\n+/*\n+ * PON test data and cases\n+ * - encrypt direction: CRC-Crypto-BIP\n+ * - decrypt direction: BIP-Crypto-CRC\n+ */\n+struct pon_test_data {\n+\tstruct {\n+\t\tuint8_t data[16];\n+\t\tunsigned int len;\n+\t} key;\n+\n+\tstruct {\n+\t\tuint8_t data[16] __rte_aligned(16);\n+\t\tunsigned int len;\n+\t} cipher_iv;\n+\n+\tstruct {\n+\t\tuint8_t data[1024];\n+\t\tunsigned int len;\n+\t\tunsigned int cipher_offset;\n+\t\tunsigned int crc_offset;\n+\t\tunsigned int bip_offset;\n+\t\tunsigned int padding_len;\n+\t\tbool no_cipher;\n+\t} plaintext;\n+\n+\tstruct {\n+\t\tuint8_t data[1024];\n+\t\tunsigned int len;\n+\t\tunsigned int cipher_offset;\n+\t\tunsigned int crc_offset;\n+\t\tunsigned int bip_offset;\n+\t\tunsigned int padding_len;\n+\t\tbool no_cipher;\n+\t} ciphertext;\n+\n+\tstruct {\n+\tuint8_t data[8];\n+\t\tunsigned int len;\n+\t} output;\n+};\n+\n+struct pon_test_data pon_test_case_1 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,\n+\t\t\t0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x00, 0x20, 0x27, 0x11, 0x00, 0x00, 0x21, 0x23,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04,\n+\t\t\t/* CRC */\n+\t\t\t0x05, 0x06, 0x01, 0x01\n+\t\t},\n+\t\t.len = 16,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 0,\n+\t\t.no_cipher = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x00, 0x20, 0x27, 0x11, 0x00, 0x00, 0x21, 0x23,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0xC7, 0x62, 0x82, 0xCA,\n+\t\t\t/* CRC */\n+\t\t\t0x3E, 0x92, 0xC8, 0x5A\n+\t\t},\n+\t\t.len = 16,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 0,\n+\t\t.no_cipher = false\n+\t},\n+\t.output = {\n+\t\t/* Expected BIP */\n+\t\t.data = {0xF9, 0xD0, 0x4C, 0xA2},\n+\t\t.len  = 4\n+\t}\n+};\n+\n+struct pon_test_data pon_test_case_2 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,\n+\t\t\t0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x00, 0x40, 0x27, 0x11, 0x00, 0x00, 0x29, 0x3C,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, 0x01,\n+\t\t\t0x01, 0x01, 0x01, 0x01,\n+\t\t\t/* CRC */\n+\t\t\t0x81, 0x00, 0x00, 0x01\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 0,\n+\t\t.no_cipher = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x00, 0x40, 0x27, 0x11, 0x00, 0x00, 0x29, 0x3C,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0xC7, 0x62, 0x82, 0xCA, 0xF6, 0x6F, 0xF5, 0xED,\n+\t\t\t0xB7, 0x90, 0x1E, 0x02,\n+\t\t\t/* CRC */\n+\t\t\t0xEA, 0x38, 0xA1, 0x78\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 0,\n+\t\t.no_cipher = false\n+\t},\n+\t.output = {\n+\t\t/* Expected BIP */\n+\t\t.data = {0x6C, 0xE5, 0xC6, 0x70},\n+\t\t.len  = 4\n+\t}\n+};\n+\n+struct pon_test_data pon_test_case_3 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,\n+\t\t\t0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x01, 0x00, 0x27, 0x11, 0x00, 0x00, 0x33, 0x0B,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, 0x01,\n+\t\t\t0x01, 0x01, 0x01, 0x01, 0x81, 0x00, 0x00, 0x01,\n+\t\t\t0x08, 0x00, 0x45, 0x00, 0x00, 0x6A, 0xB0, 0x7E,\n+\t\t\t0x00, 0x00, 0x04, 0x06, 0x83, 0xBD, 0xC0, 0xA8,\n+\t\t\t0x00, 0x01, 0xC0, 0xA8, 0x01, 0x01, 0x04, 0xD2,\n+\t\t\t0x16, 0x2E, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34,\n+\t\t\t0x56, 0x90, 0x50, 0x10, 0x20, 0x00, 0xA6, 0x33,\n+\t\t\t0x00, 0x00, 0x30, 0x31,\n+\t\t\t/* CRC */\n+\t\t\t0x32, 0x33, 0x34, 0x35\n+\t\t},\n+\t\t.len = 72,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 0,\n+\t\t.no_cipher = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x01, 0x00, 0x27, 0x11, 0x00, 0x00, 0x33, 0x0B,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0xC7, 0x62, 0x82, 0xCA, 0xF6, 0x6F, 0xF5, 0xED,\n+\t\t\t0xB7, 0x90, 0x1E, 0x02, 0x6B, 0x2C, 0x08, 0x7D,\n+\t\t\t0x3C, 0x90, 0xE8, 0x2C, 0x44, 0x30, 0x03, 0x29,\n+\t\t\t0x5F, 0x88, 0xA9, 0xD6, 0x1E, 0xF9, 0xD1, 0xF1,\n+\t\t\t0xD6, 0x16, 0x8C, 0x72, 0xA4, 0xCD, 0xD2, 0x8F,\n+\t\t\t0x63, 0x26, 0xC9, 0x66, 0xB0, 0x65, 0x24, 0x9B,\n+\t\t\t0x60, 0x5B, 0x18, 0x60, 0xBD, 0xD5, 0x06, 0x13,\n+\t\t\t0x40, 0xC9, 0x60, 0x64,\n+\t\t\t/* CRC */\n+\t\t\t0x36, 0x5F, 0x86, 0x8C\n+\t\t},\n+\t\t.len = 72,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 0,\n+\t\t.no_cipher = false\n+\t},\n+\t.output = {\n+\t\t/* Expected BIP */\n+\t\t.data = {0xDF, 0xE0, 0xAD, 0xFB},\n+\t\t.len  = 4\n+\t}\n+};\n+\n+struct pon_test_data pon_test_case_4 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,\n+\t\t\t0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x00, 0x39, 0x03, 0xFD, 0x00, 0x00, 0xB3, 0x6A,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,\n+\t\t\t0x10, 0x11,\n+\t\t\t/* CRC */\n+\t\t\t0x20, 0x21, 0x22, 0x23,\n+\t\t\t/* Padding */\n+\t\t\t0x55, 0x55\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 2,\n+\t\t.no_cipher = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x00, 0x39, 0x03, 0xFD, 0x00, 0x00, 0xB3, 0x6A,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x73, 0xE0, 0x5D, 0x5D, 0x32, 0x9C, 0x3B, 0xFA,\n+\t\t\t0x6B, 0x66,\n+\t\t\t/* CRC */\n+\t\t\t0xF6, 0x8E, 0x5B, 0xD5,\n+\t\t\t/* Padding */\n+\t\t\t0xAB, 0xCD\n+\t\t},\n+\t\t.len = 24,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 2,\n+\t\t.no_cipher = false\n+\t},\n+\t.output = {\n+\t\t/* Expected BIP */\n+\t\t.data = {0x71, 0xF6, 0x8B, 0x73},\n+\t\t.len  = 4\n+\t}\n+};\n+\n+struct pon_test_data pon_test_case_5 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,\n+\t\t\t0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x00, 0x05, 0x03, 0xFD, 0x00, 0x00, 0xB9, 0xB4,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x08,\n+\t\t\t/* Padding */\n+\t\t\t0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55\n+\t\t},\n+\t\t.len = 16,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 7,\n+\t\t.no_cipher = false\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x00, 0x05, 0x03, 0xFD, 0x00, 0x00, 0xB9, 0xB4,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x73,\n+\t\t\t/* Padding */\n+\t\t\t0xBC, 0x02, 0x03, 0x6B, 0xC4, 0x60, 0xA0\n+\t\t},\n+\t\t.len = 16,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 7,\n+\t\t.no_cipher = false\n+\t},\n+\t.output = {\n+\t\t/* Expected BIP */\n+\t\t.data = {0x18, 0x7D, 0xD8, 0xEA},\n+\t\t.len  = 4\n+\t}\n+};\n+\n+struct pon_test_data pon_test_case_6 = {\n+\t.key = {\n+\t\t.data = {\n+\t\t\t0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,\n+\t\t\t0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.cipher_iv = {\n+\t\t.data = {\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n+\t\t},\n+\t\t.len = 16\n+\t},\n+\t.plaintext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x01, 0x00, 0x27, 0x11, 0x00, 0x00, 0x33, 0x0B,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, 0x01,\n+\t\t\t0x01, 0x01, 0x01, 0x01, 0x81, 0x00, 0x00, 0x01,\n+\t\t\t0x08, 0x00, 0x45, 0x00, 0x00, 0x6A, 0xB0, 0x7E,\n+\t\t\t0x00, 0x00, 0x04, 0x06, 0x83, 0xBD, 0xC0, 0xA8,\n+\t\t\t0x00, 0x01, 0xC0, 0xA8, 0x01, 0x01, 0x04, 0xD2,\n+\t\t\t0x16, 0x2E, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34,\n+\t\t\t0x56, 0x90, 0x50, 0x10, 0x20, 0x00, 0xA6, 0x33,\n+\t\t\t0x00, 0x00, 0x30, 0x31,\n+\t\t\t/* CRC */\n+\t\t\t0x32, 0x33, 0x34, 0x35\n+\t\t},\n+\t\t.len = 72,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 0,\n+\t\t.no_cipher = true\n+\t},\n+\t.ciphertext = {\n+\t\t.data = {\n+\t\t\t/* XGEM header */\n+\t\t\t0x01, 0x00, 0x27, 0x11, 0x00, 0x00, 0x33, 0x0B,\n+\t\t\t/* Ethernet frame */\n+\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, 0x01,\n+\t\t\t0x01, 0x01, 0x01, 0x01, 0x81, 0x00, 0x00, 0x01,\n+\t\t\t0x08, 0x00, 0x45, 0x00, 0x00, 0x6a, 0xb0, 0x7e,\n+\t\t\t0x00, 0x00, 0x04, 0x06, 0x83, 0xbd, 0xc0, 0xa8,\n+\t\t\t0x00, 0x01, 0xc0, 0xa8, 0x01, 0x01, 0x04, 0xd2,\n+\t\t\t0x16, 0x2e, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34,\n+\t\t\t0x56, 0x90, 0x50, 0x10, 0x20, 0x00, 0xa6, 0x33,\n+\t\t\t0x00, 0x00, 0x30, 0x31,\n+\t\t\t/* CRC */\n+\t\t\t0x53, 0xC1, 0xE6, 0x0C\n+\t\t},\n+\t\t.len = 72,\n+\t\t.cipher_offset = 8,\n+\t\t.crc_offset = 8,\n+\t\t.bip_offset = 0,\n+\t\t.padding_len = 0,\n+\t\t.no_cipher = true\n+\t},\n+\t.output = {\n+\t\t/* Expected BIP */\n+\t\t.data = {0x6A, 0xD5, 0xC2, 0xAB},\n+\t\t.len  = 4\n+\t}\n+};\n+#endif /* _AESNI_MB_RAWDEV_TEST_VECTORS_H_ */\ndiff --git a/drivers/raw/aesni_mb/meson.build b/drivers/raw/aesni_mb/meson.build\nnew file mode 100644\nindex 000000000..085f629be\n--- /dev/null\n+++ b/drivers/raw/aesni_mb/meson.build\n@@ -0,0 +1,26 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2020 Intel Corporation.\n+\n+IMB_required_ver = '0.53.3-dev'\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('aesni_mb_rawdev.c', 'aesni_mb_rawdev_test.c')\n+allow_experimental_apis = true\n+deps += ['bus_vdev', 'net', 'rawdev', 'cryptodev', 'common_multi_fn']\ndiff --git a/drivers/raw/aesni_mb/rte_rawdev_aesni_mb_version.map b/drivers/raw/aesni_mb/rte_rawdev_aesni_mb_version.map\nnew file mode 100644\nindex 000000000..fa9e17c29\n--- /dev/null\n+++ b/drivers/raw/aesni_mb/rte_rawdev_aesni_mb_version.map\n@@ -0,0 +1,3 @@\n+DPDK_20.0 {\n+\tlocal: *;\n+};\n\\ No newline at end of file\ndiff --git a/drivers/raw/meson.build b/drivers/raw/meson.build\nindex bb5797760..c0bbc84a6 100644\n--- a/drivers/raw/meson.build\n+++ b/drivers/raw/meson.build\n@@ -5,7 +5,8 @@ drivers = ['dpaa2_cmdif', 'dpaa2_qdma',\n \t'ifpga', 'ioat', 'ntb',\n \t'octeontx2_dma',\n \t'octeontx2_ep',\n-\t'skeleton']\n+\t'skeleton',\n+\t'aesni_mb']\n std_deps = ['rawdev']\n config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'\n driver_name_fmt = 'rte_rawdev_@0@'\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex b836d220d..a6e1e925f 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -347,6 +347,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -lrte_rawdev_ioat\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_rawdev_ntb\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_DMA_RAWDEV) += -lrte_rawdev_octeontx2_dma\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_EP_RAWDEV) += -lrte_rawdev_octeontx2_ep\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB_RAWDEV) += -lrte_pmd_aesni_mb_rawdev\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB_RAWDEV) += -lIPSec_MB\n _LDLIBS-$(CONFIG_RTE_LIBRTE_MULTI_FN_COMMON) += -lrte_multi_fn\n endif # CONFIG_RTE_LIBRTE_RAWDEV\n \n",
    "prefixes": [
        "v2",
        "2/4"
    ]
}