get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 11151,
    "url": "http://patchwork.dpdk.org/api/patches/11151/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/1457380086-30391-1-git-send-email-pablo.de.lara.guarch@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<1457380086-30391-1-git-send-email-pablo.de.lara.guarch@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1457380086-30391-1-git-send-email-pablo.de.lara.guarch@intel.com",
    "date": "2016-03-07T19:48:06",
    "name": "[dpdk-dev,v3] pmd/snow3g: add new SNOW 3G SW PMD",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "571e511dbeba690747d7a59668e3ba0e86bbef15",
    "submitter": {
        "id": 9,
        "url": "http://patchwork.dpdk.org/api/people/9/?format=api",
        "name": "De Lara Guarch, Pablo",
        "email": "pablo.de.lara.guarch@intel.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/1457380086-30391-1-git-send-email-pablo.de.lara.guarch@intel.com/mbox/",
    "series": [],
    "comments": "http://patchwork.dpdk.org/api/patches/11151/comments/",
    "check": "pending",
    "checks": "http://patchwork.dpdk.org/api/patches/11151/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id C074B2BE9;\n\tMon,  7 Mar 2016 20:46:02 +0100 (CET)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby dpdk.org (Postfix) with ESMTP id 170F32BDD\n\tfor <dev@dpdk.org>; Mon,  7 Mar 2016 20:45:59 +0100 (CET)",
            "from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby fmsmga103.fm.intel.com with ESMTP; 07 Mar 2016 11:45:58 -0800",
            "from sie-lab-212-116.ir.intel.com ([10.237.212.116])\n\tby fmsmga001.fm.intel.com with ESMTP; 07 Mar 2016 11:45:57 -0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.22,553,1449561600\"; d=\"scan'208\";a=\"918777233\"",
        "From": "Pablo de Lara <pablo.de.lara.guarch@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Mon,  7 Mar 2016 19:48:06 +0000",
        "Message-Id": "<1457380086-30391-1-git-send-email-pablo.de.lara.guarch@intel.com>",
        "X-Mailer": "git-send-email 2.5.0",
        "In-Reply-To": "<1457359641-29162-1-git-send-email-pablo.de.lara.guarch@intel.com>",
        "References": "<1457359641-29162-1-git-send-email-pablo.de.lara.guarch@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v3] pmd/snow3g: add new SNOW 3G SW PMD",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Added new SW PMD which makes use of the libsso SW library,\nwhich provides wireless algorithms SNOW 3G UEA2 and UIA2\nin software.\n\nThis PMD supports cipher-only, hash-only and chained operations\n(\"cipher then hash\" and \"hash then cipher\") of the following\nalgorithms:\n- RTE_CRYPTO_SYM_CIPHER_SNOW3G_UEA2\n- RTE_CRYPTO_SYM_HASH_SNOW3G_UIA2\n\nThe SNOW 3G hash and cipher algorithms, which are enabled\nby this crypto PMD are implemented by Intel's libsso software\nlibrary. For library download and build instructions,\nsee the documentation included (doc/guides/cryptodevs/snow3g.rst)\n\nThe patch also contains the related unit tests function to test the PMD\nsupported operations.\n\nSigned-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>\n---\n\nThis patch depends on \"Snow3G support for Intel Quick Assist Devices\" patchset\n(http://dpdk.org/ml/archives/dev/2016-March/034503.html).\n\nChanges in v3:\n\n- Corrected patch dependency\n\nChanges in v2:\n\n- Rebased against crypto API changes\n- Removed static config options and allow user to provide them\n  as virtual device parameters.\n- Added unit tests\n- Changed DPDK version references from 2.3 to 16.04\n- Fixed crypto operation status handling\n- Fixed copyright dates\n- Fixed enqueue error stats\n\n\n MAINTAINERS                                      |   4 +\n app/test/test_cryptodev.c                        |  78 ++++\n config/common_base                               |   6 +\n doc/guides/cryptodevs/index.rst                  |   1 +\n doc/guides/cryptodevs/snow3g.rst                 |  69 +++\n doc/guides/rel_notes/release_16_04.rst           |   4 +\n drivers/crypto/Makefile                          |   3 +-\n drivers/crypto/snow3g/Makefile                   |  64 +++\n drivers/crypto/snow3g/rte_pmd_snow3g_version.map |   3 +\n drivers/crypto/snow3g/rte_snow3g_pmd.c           | 531 +++++++++++++++++++++++\n drivers/crypto/snow3g/rte_snow3g_pmd_ops.c       | 291 +++++++++++++\n drivers/crypto/snow3g/rte_snow3g_pmd_private.h   | 107 +++++\n lib/librte_cryptodev/Makefile                    |   3 +-\n lib/librte_cryptodev/rte_cryptodev.h             | 120 ++++-\n mk/rte.app.mk                                    |   6 +-\n 15 files changed, 1286 insertions(+), 4 deletions(-)\n create mode 100644 doc/guides/cryptodevs/snow3g.rst\n create mode 100644 drivers/crypto/snow3g/Makefile\n create mode 100644 drivers/crypto/snow3g/rte_pmd_snow3g_version.map\n create mode 100644 drivers/crypto/snow3g/rte_snow3g_pmd.c\n create mode 100644 drivers/crypto/snow3g/rte_snow3g_pmd_ops.c\n create mode 100644 drivers/crypto/snow3g/rte_snow3g_pmd_private.h",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 8d84dda..c028e67 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -355,6 +355,10 @@ F: drivers/crypto/aesni_mb/\n Intel QuickAssist\n F: drivers/crypto/qat/\n \n+SNOW 3G PMD\n+M: Pablo de Lara <pablo.de.lara.guarch@intel.com>\n+F: drivers/crypto/snow3g\n+\n \n Packet processing\n -----------------\ndiff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c\nindex a37018c..1f822f0 100644\n--- a/app/test/test_cryptodev.c\n+++ b/app/test/test_cryptodev.c\n@@ -195,6 +195,20 @@ testsuite_setup(void)\n \t\t}\n \t}\n \n+\t/* Create 2 Snow3G devices if required */\n+\tif (gbl_cryptodev_type == RTE_CRYPTODEV_SNOW3G_PMD) {\n+\t\tnb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_SNOW3G_PMD);\n+\t\tif (nb_devs < 2) {\n+\t\t\tfor (i = nb_devs; i < 2; i++) {\n+\t\t\t\tTEST_ASSERT_SUCCESS(rte_eal_vdev_init(\n+\t\t\t\t\tCRYPTODEV_NAME_SNOW3G_PMD, NULL),\n+\t\t\t\t\t\"Failed to create instance %u of\"\n+\t\t\t\t\t\" pmd : %s\",\n+\t\t\t\t\ti, CRYPTODEV_NAME_SNOW3G_PMD);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n \tnb_devs = rte_cryptodev_count();\n \tif (nb_devs < 1) {\n \t\tRTE_LOG(ERR, USER1, \"No crypto devices found?\");\n@@ -3074,6 +3088,56 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite  = {\n \t}\n };\n \n+static struct unit_test_suite cryptodev_sw_snow3g_testsuite  = {\n+\t.suite_name = \"Crypto Device SW Snow3G Unit Test Suite\",\n+\t.setup = testsuite_setup,\n+\t.teardown = testsuite_teardown,\n+\t.unit_test_cases = {\n+\t\t/** Snow3G encrypt only (UEA2) */\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_encryption_test_case_1),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_encryption_test_case_2),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_encryption_test_case_3),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_encryption_test_case_4),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_encryption_test_case_5),\n+\n+\n+\t\t/** Snow3G decrypt only (UEA2) */\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_decryption_test_case_1),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_decryption_test_case_2),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_decryption_test_case_3),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_decryption_test_case_4),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_decryption_test_case_5),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_hash_generate_test_case_1),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_hash_generate_test_case_2),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_hash_generate_test_case_3),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_hash_verify_test_case_1),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_hash_verify_test_case_2),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_hash_verify_test_case_3),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_authenticated_encryption_test_case_1),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\ttest_snow3g_encrypted_authentication_test_case_1),\n+\n+\t\tTEST_CASES_END() /**< NULL terminate unit test array */\n+\t}\n+};\n+\n static int\n test_cryptodev_qat(void /*argv __rte_unused, int argc __rte_unused*/)\n {\n@@ -3098,5 +3162,19 @@ static struct test_command cryptodev_aesni_mb_cmd = {\n \t.callback = test_cryptodev_aesni_mb,\n };\n \n+static int\n+test_cryptodev_sw_snow3g(void /*argv __rte_unused, int argc __rte_unused*/)\n+{\n+\tgbl_cryptodev_type = RTE_CRYPTODEV_SNOW3G_PMD;\n+\n+\treturn unit_test_suite_runner(&cryptodev_sw_snow3g_testsuite);\n+}\n+\n+static struct test_command cryptodev_sw_snow3g_cmd = {\n+\t.command = \"cryptodev_sw_snow3g_autotest\",\n+\t.callback = test_cryptodev_sw_snow3g,\n+};\n+\n REGISTER_TEST_COMMAND(cryptodev_qat_cmd);\n REGISTER_TEST_COMMAND(cryptodev_aesni_mb_cmd);\n+REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_cmd);\ndiff --git a/config/common_base b/config/common_base\nindex 3066e9a..4202a89 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -337,6 +337,12 @@ CONFIG_RTE_AESNI_MB_PMD_MAX_NB_QUEUE_PAIRS=8\n CONFIG_RTE_AESNI_MB_PMD_MAX_NB_SESSIONS=2048\n \n #\n+# Compile PMD for SNOW 3G device\n+#\n+CONFIG_RTE_LIBRTE_PMD_SNOW3G=n\n+CONFIG_RTE_LIBRTE_PMD_SNOW3G_DEBUG=n\n+\n+#\n # Compile librte_ring\n #\n CONFIG_RTE_LIBRTE_RING=y\ndiff --git a/doc/guides/cryptodevs/index.rst b/doc/guides/cryptodevs/index.rst\nindex 16a5f4a..071e7d2 100644\n--- a/doc/guides/cryptodevs/index.rst\n+++ b/doc/guides/cryptodevs/index.rst\n@@ -36,4 +36,5 @@ Crypto Device Drivers\n     :numbered:\n \n     aesni_mb\n+    snow3g\n     qat\ndiff --git a/doc/guides/cryptodevs/snow3g.rst b/doc/guides/cryptodevs/snow3g.rst\nnew file mode 100644\nindex 0000000..9e81eeb\n--- /dev/null\n+++ b/doc/guides/cryptodevs/snow3g.rst\n@@ -0,0 +1,69 @@\n+..  BSD LICENSE\n+    Copyright(c) 2016 Intel Corporation. All rights reserved.\n+\n+    Redistribution and use in source and binary forms, with or without\n+    modification, are permitted provided that the following conditions\n+    are met:\n+\n+    * Redistributions of source code must retain the above copyright\n+    notice, this list of conditions and the following disclaimer.\n+    * Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in\n+    the documentation and/or other materials provided with the\n+    distribution.\n+    * Neither the name of Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived\n+    from this software without specific prior written permission.\n+\n+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+    \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+SNOW 3G Crypto Poll Mode Driver\n+==============================\n+\n+The SNOW 3G PMD (**librte_pmd_snow3g**) provides poll mode crypto driver\n+support for utilizing Intel Libsso library, which implements F8 and F9 functions\n+for SNOW 3G UEA2 cipher and UIA2 hash algorithms.\n+\n+Features\n+--------\n+\n+SNOW 3G PMD has support for:\n+\n+Cipher algorithm:\n+\n+* RTE_CRYPTO_SYM_CIPHER_SNOW3G_UEA2\n+\n+Hash algorithm:\n+\n+* RTE_CRYPTO_SYM_HASH_SNOW3G_UIA2\n+\n+Limitations\n+-----------\n+\n+* Chained mbufs are not supported.\n+\n+Installation\n+------------\n+\n+To build DPDK with the SNOW3G_PMD the user is required to get\n+the export controlled libsso library, sending a request to\n+`DPDKUser_software_access@intel.com`, and compile it\n+on their user system before building DPDK:\n+\n+.. code-block:: console\n+\n+\tmake -f Makefile_snow3g\n+\n+The environmental variable LIBSSO_PATH must be exported with the path\n+where you extracted and built the libsso library and finally set\n+CONFIG_RTE_LIBRTE_SNOW3G=y in config/common_linuxapp.\ndiff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst\nindex ab446ff..d7a264a 100644\n--- a/doc/guides/rel_notes/release_16_04.rst\n+++ b/doc/guides/rel_notes/release_16_04.rst\n@@ -63,6 +63,10 @@ This section should contain new features added in this release. Sample format:\n \n * **Added vhost-user live migration support.**\n \n+* **Added SNOW3G SW PMD**\n+\n+  A new Crypto PMD has been added, which provides SNOW 3G UEA2 ciphering\n+  and SNOW3G UIA2 hashing.\n \n Resolved Issues\n ---------------\ndiff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile\nindex d0258da..bf586d9 100644\n--- a/drivers/crypto/Makefile\n+++ b/drivers/crypto/Makefile\n@@ -1,6 +1,6 @@\n #   BSD LICENSE\n #\n-#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.\n+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.\n #   All rights reserved.\n #\n #   Redistribution and use in source and binary forms, with or without\n@@ -33,5 +33,6 @@ include $(RTE_SDK)/mk/rte.vars.mk\n \n DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb\n DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat\n+DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g\n \n include $(RTE_SDK)/mk/rte.subdir.mk\ndiff --git a/drivers/crypto/snow3g/Makefile b/drivers/crypto/snow3g/Makefile\nnew file mode 100644\nindex 0000000..ee58270\n--- /dev/null\n+++ b/drivers/crypto/snow3g/Makefile\n@@ -0,0 +1,64 @@\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2016 Intel Corporation. All rights reserved.\n+#\n+#   Redistribution and use in source and binary forms, with or without\n+#   modification, are permitted provided that the following conditions\n+#   are met:\n+#\n+#     * Redistributions of source code must retain the above copyright\n+#       notice, this list of conditions and the following disclaimer.\n+#     * Redistributions in binary form must reproduce the above copyright\n+#       notice, this list of conditions and the following disclaimer in\n+#       the documentation and/or other materials provided with the\n+#       distribution.\n+#     * Neither the name of Intel Corporation nor the names of its\n+#       contributors may be used to endorse or promote products derived\n+#       from this software without specific prior written permission.\n+#\n+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+#   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+ifeq ($(LIBSSO_PATH),)\n+$(error \"Please define LIBSSO_PATH environment variable\")\n+endif\n+\n+# library name\n+LIB = librte_pmd_snow3g.a\n+\n+# build flags\n+CFLAGS += -O3\n+CFLAGS += $(WERROR_FLAGS)\n+\n+# library version\n+LIBABIVER := 1\n+\n+# versioning export map\n+EXPORT_MAP := rte_pmd_snow3g_version.map\n+\n+# external library include paths\n+CFLAGS += -I$(LIBSSO_PATH)\n+CFLAGS += -I$(LIBSSO_PATH)/include\n+CFLAGS += -I$(LIBSSO_PATH)/build\n+\n+# library source files\n+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += rte_snow3g_pmd.c\n+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += rte_snow3g_pmd_ops.c\n+\n+# library dependencies\n+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += lib/librte_eal\n+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += lib/librte_mbuf\n+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += lib/librte_cryptodev\n+\n+include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/crypto/snow3g/rte_pmd_snow3g_version.map b/drivers/crypto/snow3g/rte_pmd_snow3g_version.map\nnew file mode 100644\nindex 0000000..dc4d417\n--- /dev/null\n+++ b/drivers/crypto/snow3g/rte_pmd_snow3g_version.map\n@@ -0,0 +1,3 @@\n+DPDK_16.04 {\n+\tlocal: *;\n+};\ndiff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c\nnew file mode 100644\nindex 0000000..c35e66e\n--- /dev/null\n+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c\n@@ -0,0 +1,531 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <rte_common.h>\n+#include <rte_config.h>\n+#include <rte_hexdump.h>\n+#include <rte_cryptodev.h>\n+#include <rte_cryptodev_pmd.h>\n+#include <rte_dev.h>\n+#include <rte_malloc.h>\n+#include <rte_cpuflags.h>\n+#include <rte_kvargs.h>\n+\n+#include \"rte_snow3g_pmd_private.h\"\n+\n+#define SNOW3G_MAX_BURST 8\n+\n+/**\n+ * Global static parameter used to create a unique name for each SNOW 3G\n+ * crypto device.\n+ */\n+static unsigned unique_name_id;\n+\n+static inline int\n+create_unique_device_name(char *name, size_t size)\n+{\n+\tint ret;\n+\n+\tif (name == NULL)\n+\t\treturn -EINVAL;\n+\n+\tret = snprintf(name, size, \"%s_%u\", CRYPTODEV_NAME_SNOW3G_PMD,\n+\t\t\tunique_name_id++);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\treturn 0;\n+}\n+\n+/** Get xform chain order. */\n+static enum snow3g_operation\n+snow3g_get_mode(const struct rte_crypto_sym_xform *xform)\n+{\n+\tif (xform == NULL)\n+\t\treturn SNOW3G_OP_NOT_SUPPORTED;\n+\n+\tif (xform->next)\n+\t\tif (xform->next->next != NULL)\n+\t\t\treturn SNOW3G_OP_NOT_SUPPORTED;\n+\n+\tif (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {\n+\t\tif (xform->next == NULL)\n+\t\t\treturn SNOW3G_OP_ONLY_AUTH;\n+\t\telse if (xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER)\n+\t\t\treturn SNOW3G_OP_AUTH_CIPHER;\n+\t\telse\n+\t\t\treturn SNOW3G_OP_NOT_SUPPORTED;\n+\t}\n+\n+\tif (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {\n+\t\tif (xform->next == NULL)\n+\t\t\treturn SNOW3G_OP_ONLY_CIPHER;\n+\t\telse if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)\n+\t\t\treturn SNOW3G_OP_CIPHER_AUTH;\n+\t\telse\n+\t\t\treturn SNOW3G_OP_NOT_SUPPORTED;\n+\t}\n+\n+\treturn SNOW3G_OP_NOT_SUPPORTED;\n+}\n+\n+\n+/** Parse crypto xform chain and set private session parameters. */\n+int\n+snow3g_set_session_parameters(struct snow3g_session *sess,\n+\t\tconst struct rte_crypto_sym_xform *xform)\n+{\n+\tconst struct rte_crypto_sym_xform *auth_xform = NULL;\n+\tconst struct rte_crypto_sym_xform *cipher_xform = NULL;\n+\tint mode;\n+\n+\t/* Select Crypto operation - hash then cipher / cipher then hash */\n+\tmode = snow3g_get_mode(xform);\n+\n+\tswitch (mode) {\n+\tcase SNOW3G_OP_CIPHER_AUTH:\n+\t\tauth_xform = xform->next;\n+\n+\t\t/* Fall-through */\n+\tcase SNOW3G_OP_ONLY_CIPHER:\n+\t\tcipher_xform = xform;\n+\t\tbreak;\n+\tcase SNOW3G_OP_AUTH_CIPHER:\n+\t\tcipher_xform = xform->next;\n+\t\t/* Fall-through */\n+\tcase SNOW3G_OP_ONLY_AUTH:\n+\t\tauth_xform = xform;\n+\t}\n+\n+\tif (mode == SNOW3G_OP_NOT_SUPPORTED) {\n+\t\tSNOW3G_LOG_ERR(\"Unsupported operation chain order parameter\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (cipher_xform) {\n+\t\t/* Only SNOW 3G UEA2 supported */\n+\t\tif (cipher_xform->cipher.algo != RTE_CRYPTO_CIPHER_SNOW3G_UEA2)\n+\t\t\treturn -EINVAL;\n+\t\t/* Initialize key */\n+\t\tsso_snow3g_init_key_sched(xform->cipher.key.data,\n+\t\t\t\t&sess->pKeySched_cipher);\n+\t}\n+\n+\tif (auth_xform) {\n+\t\t/* Only SNOW 3G UIA2 supported */\n+\t\tif (auth_xform->auth.algo != RTE_CRYPTO_AUTH_SNOW3G_UIA2)\n+\t\t\treturn -EINVAL;\n+\t\tsess->auth_op = auth_xform->auth.op;\n+\t\t/* Initialize key */\n+\t\tsso_snow3g_init_key_sched(xform->auth.key.data,\n+\t\t\t\t&sess->pKeySched_hash);\n+\t}\n+\n+\n+\tsess->op = mode;\n+\n+\treturn 0;\n+}\n+\n+/** Get SNOW 3G session. */\n+static struct snow3g_session *\n+snow3g_get_session(struct snow3g_qp *qp, struct rte_crypto_op *op)\n+{\n+\tstruct snow3g_session *sess;\n+\n+\tif (op->sym->type == RTE_CRYPTO_SYM_OP_WITH_SESSION) {\n+\t\tif (unlikely(op->sym->session->type !=\n+\t\t\t\tRTE_CRYPTODEV_SNOW3G_PMD))\n+\t\t\treturn NULL;\n+\n+\t\tsess = (struct snow3g_session *)op->sym->session->_private;\n+\t} else  {\n+\t\tstruct rte_cryptodev_session *c_sess = NULL;\n+\n+\t\tif (rte_mempool_get(qp->sess_mp, (void **)&c_sess))\n+\t\t\treturn NULL;\n+\n+\t\tsess = (struct snow3g_session *)c_sess->_private;\n+\n+\t\tif (unlikely(snow3g_set_session_parameters(sess,\n+\t\t\t\top->sym->xform) != 0))\n+\t\t\treturn NULL;\n+\t}\n+\n+\treturn sess;\n+}\n+\n+/** Encrypt/decrypt mbufs with same cipher key. */\n+static uint8_t\n+process_snow3g_cipher_op(struct rte_crypto_op **ops,\n+\t\tstruct snow3g_session *session,\n+\t\tuint8_t num_ops)\n+{\n+\tunsigned i;\n+\tuint8_t processed_ops = 0;\n+\tuint8_t *src[SNOW3G_MAX_BURST], *dst[SNOW3G_MAX_BURST];\n+\tuint8_t *IV[SNOW3G_MAX_BURST];\n+\tuint32_t num_bytes[SNOW3G_MAX_BURST];\n+\n+\tfor (i = 0; i < num_ops; i++) {\n+\t\t/* Sanity checks. */\n+\t\tif (ops[i]->sym->cipher.iv.length != 16) {\n+\t\t\tops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;\n+\t\t\tSNOW3G_LOG_ERR(\"iv\");\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tsrc[i] = rte_pktmbuf_mtod(ops[i]->sym->m_src, uint8_t *) +\n+\t\t\t\tops[i]->sym->cipher.data.offset;\n+\t\tdst[i] = ops[i]->sym->m_dst ?\n+\t\t\t\trte_pktmbuf_mtod(ops[i]->sym->m_dst, uint8_t *) +\n+\t\t\t\t\tops[i]->sym->cipher.data.offset :\n+\t\t\t\trte_pktmbuf_mtod(ops[i]->sym->m_src, uint8_t *) +\n+\t\t\t\t\tops[i]->sym->cipher.data.offset;\n+\t\tIV[i] = ops[i]->sym->cipher.iv.data;\n+\t\tnum_bytes[i] = ops[i]->sym->cipher.data.length;\n+\n+\t\tprocessed_ops++;\n+\t}\n+\n+\tsso_snow3g_f8_n_buffer(&session->pKeySched_cipher, IV, src, dst,\n+\t\t\tnum_bytes, processed_ops);\n+\n+\treturn processed_ops;\n+}\n+\n+/** Generate/verify hash from mbufs with same hash key. */\n+static int\n+process_snow3g_hash_op(struct rte_crypto_op **ops,\n+\t\tstruct snow3g_session *session,\n+\t\tuint8_t num_ops)\n+{\n+\tunsigned i;\n+\tuint8_t processed_ops = 0;\n+\tuint8_t *src, *dst;\n+\tuint32_t length_in_bits;\n+\n+\tfor (i = 0; i < num_ops; i++) {\n+\t\tif (ops[i]->sym->auth.aad.length != 16) {\n+\t\t\tops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;\n+\t\t\tSNOW3G_LOG_ERR(\"aad\");\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (ops[i]->sym->auth.digest.length != 4) {\n+\t\t\tops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;\n+\t\t\tSNOW3G_LOG_ERR(\"digest\");\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tlength_in_bits = ops[i]->sym->auth.data.length * 8;\n+\n+\t\tsrc = rte_pktmbuf_mtod(ops[i]->sym->m_src, uint8_t *) +\n+\t\t\t\tops[i]->sym->auth.data.offset;\n+\n+\t\tif (session->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {\n+\t\t\tdst = (uint8_t *)rte_pktmbuf_append(ops[i]->sym->m_src,\n+\t\t\t\t\tops[i]->sym->auth.digest.length);\n+\n+\t\t\tsso_snow3g_f9_1_buffer(&session->pKeySched_hash,\n+\t\t\t\t\tops[i]->sym->auth.aad.data, src,\n+\t\t\t\t\tlength_in_bits,\tdst);\n+\t\t\t/* Verify digest. */\n+\t\t\tif (memcmp(dst, ops[i]->sym->auth.digest.data,\n+\t\t\t\t\tops[i]->sym->auth.digest.length) != 0)\n+\t\t\t\tops[i]->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;\n+\n+\t\t\t/* Trim area used for digest from mbuf. */\n+\t\t\trte_pktmbuf_trim(ops[i]->sym->m_src,\n+\t\t\t\t\tops[i]->sym->auth.digest.length);\n+\t\t} else  {\n+\t\t\tdst = ops[i]->sym->auth.digest.data;\n+\n+\t\t\tsso_snow3g_f9_1_buffer(&session->pKeySched_hash,\n+\t\t\t\t\tops[i]->sym->auth.aad.data, src,\n+\t\t\t\t\tlength_in_bits, dst);\n+\t\t}\n+\t\tprocessed_ops++;\n+\t}\n+\n+\treturn processed_ops;\n+}\n+\n+/** Process a batch of crypto ops which shares the same session. */\n+static int\n+process_ops(struct rte_crypto_op **ops, struct snow3g_session *session,\n+\t\tstruct snow3g_qp *qp, uint8_t num_ops)\n+{\n+\tunsigned i;\n+\tunsigned processed_ops;\n+\n+\tswitch (session->op) {\n+\tcase SNOW3G_OP_ONLY_CIPHER:\n+\t\tprocessed_ops = process_snow3g_cipher_op(ops,\n+\t\t\t\tsession, num_ops);\n+\t\tbreak;\n+\tcase SNOW3G_OP_ONLY_AUTH:\n+\t\tprocessed_ops = process_snow3g_hash_op(ops, session,\n+\t\t\t\tnum_ops);\n+\t\tbreak;\n+\tcase SNOW3G_OP_CIPHER_AUTH:\n+\t\tprocessed_ops = process_snow3g_cipher_op(ops, session,\n+\t\t\t\tnum_ops);\n+\t\tprocess_snow3g_hash_op(ops, session, processed_ops);\n+\t\tbreak;\n+\tcase SNOW3G_OP_AUTH_CIPHER:\n+\t\tprocessed_ops = process_snow3g_hash_op(ops, session,\n+\t\t\t\tnum_ops);\n+\t\tprocess_snow3g_cipher_op(ops, session, processed_ops);\n+\t\tbreak;\n+\tdefault:\n+\t\t/* Operation not supported. */\n+\t\tprocessed_ops = 0;\n+\t}\n+\n+\tfor (i = 0; i < num_ops; i++) {\n+\t\t/*\n+\t\t * If there was no error/authentication failure,\n+\t\t * change status to successful.\n+\t\t */\n+\t\tif (ops[i]->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)\n+\t\t\tops[i]->status = RTE_CRYPTO_OP_STATUS_SUCCESS;\n+\t\t/* Free session if a session-less crypto op. */\n+\t\tif (ops[i]->sym->type == RTE_CRYPTO_SYM_OP_SESSIONLESS) {\n+\t\t\trte_mempool_put(qp->sess_mp, ops[i]->sym->session);\n+\t\t\tops[i]->sym->session = NULL;\n+\t\t}\n+\t}\n+\n+\treturn processed_ops;\n+}\n+\n+static uint16_t\n+snow3g_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,\n+\t\tuint16_t nb_ops)\n+{\n+\tstruct rte_crypto_op *c_ops[SNOW3G_MAX_BURST];\n+\tstruct rte_crypto_op *curr_c_op;\n+\n+\tstruct snow3g_session *prev_sess = NULL, *curr_sess = NULL;\n+\tstruct snow3g_qp *qp = queue_pair;\n+\tunsigned i, n;\n+\tuint8_t burst_size = 0;\n+\tuint16_t enqueued_ops = 0;\n+\tuint8_t processed_ops;\n+\n+\tfor (i = 0; i < nb_ops; i++) {\n+\t\tcurr_c_op = ops[i];\n+\n+\t\t/* Set status as enqueued (not processed yet) by default. */\n+\t\tcurr_c_op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;\n+\n+\t\tcurr_sess = snow3g_get_session(qp, curr_c_op);\n+\t\tif (unlikely(curr_sess == NULL ||\n+\t\t\t\tcurr_sess->op == SNOW3G_OP_NOT_SUPPORTED)) {\n+\t\t\tcurr_c_op->status =\n+\t\t\t\t\tRTE_CRYPTO_OP_STATUS_INVALID_SESSION;\n+\t\t\tqp->qp_stats.enqueue_err_count += nb_ops - enqueued_ops;\n+\t\t\treturn enqueued_ops;\n+\t\t}\n+\n+\t\t/* Batch ops that share the same session. */\n+\t\tif (prev_sess == NULL) {\n+\t\t\tprev_sess = curr_sess;\n+\t\t\tc_ops[burst_size++] = curr_c_op;\n+\t\t} else if (curr_sess == prev_sess) {\n+\t\t\tc_ops[burst_size++] = curr_c_op;\n+\t\t\t/*\n+\t\t\t * When there are enough ops to process in a batch,\n+\t\t\t * process them, and start a new batch.\n+\t\t\t */\n+\t\t\tif (burst_size == SNOW3G_MAX_BURST) {\n+\t\t\t\tprocessed_ops = process_ops(c_ops,\n+\t\t\t\t\t\tprev_sess, qp, burst_size);\n+\t\t\t\tn = rte_ring_enqueue_burst(qp->processed_ops,\n+\t\t\t\t\t\t(void **)c_ops,\n+\t\t\t\t\t\tprocessed_ops);\n+\t\t\t\tqp->qp_stats.enqueued_count += n;\n+\t\t\t\tenqueued_ops += n;\n+\t\t\t\tif (n < burst_size) {\n+\t\t\t\t\tqp->qp_stats.enqueue_err_count +=\n+\t\t\t\t\t\t\tnb_ops - enqueued_ops;\n+\t\t\t\t\treturn enqueued_ops;\n+\t\t\t\t}\n+\t\t\t\tburst_size = 0;\n+\n+\t\t\t\tprev_sess = NULL;\n+\t\t\t}\n+\t\t} else {\n+\t\t\t/*\n+\t\t\t * Different session, process the ops\n+\t\t\t * of the previous session.\n+\t\t\t */\n+\t\t\tprocessed_ops = process_ops(c_ops,\n+\t\t\t\t\tprev_sess, qp, burst_size);\n+\t\t\tn = rte_ring_enqueue_burst(qp->processed_ops,\n+\t\t\t\t\t(void **)c_ops,\n+\t\t\t\t\tprocessed_ops);\n+\t\t\tqp->qp_stats.enqueued_count += n;\n+\t\t\tenqueued_ops += n;\n+\t\t\tif (n < burst_size) {\n+\t\t\t\tqp->qp_stats.enqueue_err_count +=\n+\t\t\t\t\t\tnb_ops - enqueued_ops;\n+\t\t\t\treturn enqueued_ops;\n+\t\t\t}\n+\t\t\tburst_size = 0;\n+\n+\t\t\tprev_sess = curr_sess;\n+\t\t\tc_ops[burst_size++] = curr_c_op;\n+\t\t}\n+\t}\n+\n+\tif (burst_size != 0) {\n+\t\t/* Process the crypto ops of the last session. */\n+\t\tprocessed_ops = process_ops(c_ops,\n+\t\t\t\tprev_sess, qp, burst_size);\n+\t\tn = rte_ring_enqueue_burst(qp->processed_ops,\n+\t\t\t\t(void **)c_ops,\n+\t\t\t\tprocessed_ops);\n+\t\tqp->qp_stats.enqueued_count += n;\n+\t\tenqueued_ops += n;\n+\t\tif (n < burst_size) {\n+\t\t\tqp->qp_stats.enqueue_err_count +=\n+\t\t\t\t\tnb_ops - enqueued_ops;\n+\t\t\treturn enqueued_ops;\n+\t\t}\n+\t}\n+\n+\treturn enqueued_ops;\n+}\n+\n+static uint16_t\n+snow3g_pmd_dequeue_burst(void *queue_pair,\n+\t\tstruct rte_crypto_op **c_ops, uint16_t nb_ops)\n+{\n+\tstruct snow3g_qp *qp = queue_pair;\n+\n+\tunsigned nb_dequeued;\n+\n+\tnb_dequeued = rte_ring_dequeue_burst(qp->processed_ops,\n+\t\t\t(void **)c_ops, nb_ops);\n+\tqp->qp_stats.dequeued_count += nb_dequeued;\n+\n+\treturn nb_dequeued;\n+}\n+\n+static int cryptodev_snow3g_uninit(const char *name);\n+\n+static int\n+cryptodev_snow3g_create(const char *name,\n+\t\tstruct rte_crypto_vdev_init_params *init_params)\n+{\n+\tstruct rte_cryptodev *dev;\n+\tchar crypto_dev_name[RTE_CRYPTODEV_NAME_MAX_LEN];\n+\tstruct snow3g_private *internals;\n+\n+\t/* Create a unique device name. */\n+\tif (create_unique_device_name(crypto_dev_name,\n+\t\t\tRTE_CRYPTODEV_NAME_MAX_LEN) != 0) {\n+\t\tSNOW3G_LOG_ERR(\"failed to create unique cryptodev name\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tdev = rte_cryptodev_pmd_virtual_dev_init(crypto_dev_name,\n+\t\t\tsizeof(struct snow3g_private), init_params->socket_id);\n+\tif (dev == NULL) {\n+\t\tSNOW3G_LOG_ERR(\"failed to create cryptodev vdev\");\n+\t\tgoto init_error;\n+\t}\n+\n+\tdev->dev_type = RTE_CRYPTODEV_SNOW3G_PMD;\n+\tdev->dev_ops = rte_snow3g_pmd_ops;\n+\n+\t/* Register RX/TX burst functions for data path. */\n+\tdev->dequeue_burst = snow3g_pmd_dequeue_burst;\n+\tdev->enqueue_burst = snow3g_pmd_enqueue_burst;\n+\n+\tinternals = dev->data->dev_private;\n+\n+\tinternals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;\n+\tinternals->max_nb_sessions = init_params->max_nb_sessions;\n+\n+\treturn 0;\n+init_error:\n+\tSNOW3G_LOG_ERR(\"driver %s: cryptodev_snow3g_create failed\", name);\n+\n+\tcryptodev_snow3g_uninit(crypto_dev_name);\n+\treturn -EFAULT;\n+}\n+\n+static int\n+cryptodev_snow3g_init(const char *name,\n+\t\tconst char *input_args)\n+{\n+\tstruct rte_crypto_vdev_init_params init_params = {\n+\t\tRTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS,\n+\t\tRTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS,\n+\t\trte_socket_id()\n+\t};\n+\n+\trte_cryptodev_parse_vdev_init_params(&init_params, input_args);\n+\n+\tRTE_LOG(INFO, PMD, \"Initialising %s on NUMA node %d\\n\", name,\n+\t\t\tinit_params.socket_id);\n+\tRTE_LOG(INFO, PMD, \"  Max number of queue pairs = %d\\n\",\n+\t\t\tinit_params.max_nb_queue_pairs);\n+\tRTE_LOG(INFO, PMD, \"  Max number of sessions = %d\\n\",\n+\t\t\tinit_params.max_nb_sessions);\n+\n+\treturn cryptodev_snow3g_create(name, &init_params);\n+}\n+\n+static int\n+cryptodev_snow3g_uninit(const char *name)\n+{\n+\tif (name == NULL)\n+\t\treturn -EINVAL;\n+\n+\tRTE_LOG(INFO, PMD, \"Closing SNOW3G crypto device %s\"\n+\t\t\t\" on numa socket %u\\n\",\n+\t\t\tname, rte_socket_id());\n+\n+\treturn 0;\n+}\n+\n+static struct rte_driver cryptodev_snow3g_pmd_drv = {\n+\t.name = CRYPTODEV_NAME_SNOW3G_PMD,\n+\t.type = PMD_VDEV,\n+\t.init = cryptodev_snow3g_init,\n+\t.uninit = cryptodev_snow3g_uninit\n+};\n+\n+PMD_REGISTER_DRIVER(cryptodev_snow3g_pmd_drv);\ndiff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c\nnew file mode 100644\nindex 0000000..5643323\n--- /dev/null\n+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c\n@@ -0,0 +1,291 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <string.h>\n+\n+#include <rte_common.h>\n+#include <rte_malloc.h>\n+#include <rte_cryptodev_pmd.h>\n+\n+#include \"rte_snow3g_pmd_private.h\"\n+\n+/** Configure device */\n+static int\n+snow3g_pmd_config(__rte_unused struct rte_cryptodev *dev)\n+{\n+\treturn 0;\n+}\n+\n+/** Start device */\n+static int\n+snow3g_pmd_start(__rte_unused struct rte_cryptodev *dev)\n+{\n+\treturn 0;\n+}\n+\n+/** Stop device */\n+static void\n+snow3g_pmd_stop(__rte_unused struct rte_cryptodev *dev)\n+{\n+}\n+\n+/** Close device */\n+static int\n+snow3g_pmd_close(__rte_unused struct rte_cryptodev *dev)\n+{\n+\treturn 0;\n+}\n+\n+\n+/** Get device statistics */\n+static void\n+snow3g_pmd_stats_get(struct rte_cryptodev *dev,\n+\t\tstruct rte_cryptodev_stats *stats)\n+{\n+\tint qp_id;\n+\n+\tfor (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {\n+\t\tstruct snow3g_qp *qp = dev->data->queue_pairs[qp_id];\n+\n+\t\tstats->enqueued_count += qp->qp_stats.enqueued_count;\n+\t\tstats->dequeued_count += qp->qp_stats.dequeued_count;\n+\n+\t\tstats->enqueue_err_count += qp->qp_stats.enqueue_err_count;\n+\t\tstats->dequeue_err_count += qp->qp_stats.dequeue_err_count;\n+\t}\n+}\n+\n+/** Reset device statistics */\n+static void\n+snow3g_pmd_stats_reset(struct rte_cryptodev *dev)\n+{\n+\tint qp_id;\n+\n+\tfor (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {\n+\t\tstruct snow3g_qp *qp = dev->data->queue_pairs[qp_id];\n+\n+\t\tmemset(&qp->qp_stats, 0, sizeof(qp->qp_stats));\n+\t}\n+}\n+\n+\n+/** Get device info */\n+static void\n+snow3g_pmd_info_get(struct rte_cryptodev *dev,\n+\t\tstruct rte_cryptodev_info *dev_info)\n+{\n+\tstruct snow3g_private *internals = dev->data->dev_private;\n+\n+\tif (dev_info != NULL) {\n+\t\tdev_info->dev_type = dev->dev_type;\n+\t\tdev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;\n+\t\tdev_info->sym.max_nb_sessions = internals->max_nb_sessions;\n+\t}\n+}\n+\n+/** Release queue pair */\n+static int\n+snow3g_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)\n+{\n+\tif (dev->data->queue_pairs[qp_id] != NULL) {\n+\t\trte_free(dev->data->queue_pairs[qp_id]);\n+\t\tdev->data->queue_pairs[qp_id] = NULL;\n+\t}\n+\treturn 0;\n+}\n+\n+/** set a unique name for the queue pair based on its name, dev_id and qp_id */\n+static int\n+snow3g_pmd_qp_set_unique_name(struct rte_cryptodev *dev,\n+\t\tstruct snow3g_qp *qp)\n+{\n+\tunsigned n = snprintf(qp->name, sizeof(qp->name),\n+\t\t\t\"snow3g_pmd_%u_qp_%u\",\n+\t\t\tdev->data->dev_id, qp->id);\n+\n+\tif (n > sizeof(qp->name))\n+\t\treturn -1;\n+\n+\treturn 0;\n+}\n+\n+/** Create a ring to place processed ops on */\n+static struct rte_ring *\n+snow3g_pmd_qp_create_processed_ops_ring(struct snow3g_qp *qp,\n+\t\tunsigned ring_size, int socket_id)\n+{\n+\tstruct rte_ring *r;\n+\n+\tr = rte_ring_lookup(qp->name);\n+\tif (r) {\n+\t\tif (r->prod.size >= ring_size) {\n+\t\t\tSNOW3G_LOG_INFO(\"Reusing existing ring %s\"\n+\t\t\t\t\t\" for processed packets\",\n+\t\t\t\t\t qp->name);\n+\t\t\treturn r;\n+\t\t}\n+\n+\t\tSNOW3G_LOG_ERR(\"Unable to reuse existing ring %s\"\n+\t\t\t\t\" for processed packets\",\n+\t\t\t\t qp->name);\n+\t\treturn NULL;\n+\t}\n+\n+\treturn rte_ring_create(qp->name, ring_size, socket_id,\n+\t\t\tRING_F_SP_ENQ | RING_F_SC_DEQ);\n+}\n+\n+/** Setup a queue pair */\n+static int\n+snow3g_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,\n+\t\tconst struct rte_cryptodev_qp_conf *qp_conf,\n+\t\t int socket_id)\n+{\n+\tstruct snow3g_qp *qp = NULL;\n+\n+\t/* Free memory prior to re-allocation if needed. */\n+\tif (dev->data->queue_pairs[qp_id] != NULL)\n+\t\tsnow3g_pmd_qp_release(dev, qp_id);\n+\n+\t/* Allocate the queue pair data structure. */\n+\tqp = rte_zmalloc_socket(\"SNOW3G PMD Queue Pair\", sizeof(*qp),\n+\t\t\t\t\tRTE_CACHE_LINE_SIZE, socket_id);\n+\tif (qp == NULL)\n+\t\treturn (-ENOMEM);\n+\n+\tqp->id = qp_id;\n+\tdev->data->queue_pairs[qp_id] = qp;\n+\n+\tif (snow3g_pmd_qp_set_unique_name(dev, qp))\n+\t\tgoto qp_setup_cleanup;\n+\n+\tqp->processed_ops = snow3g_pmd_qp_create_processed_ops_ring(qp,\n+\t\t\tqp_conf->nb_descriptors, socket_id);\n+\tif (qp->processed_ops == NULL)\n+\t\tgoto qp_setup_cleanup;\n+\n+\tqp->sess_mp = dev->data->session_pool;\n+\n+\tmemset(&qp->qp_stats, 0, sizeof(qp->qp_stats));\n+\n+\treturn 0;\n+\n+qp_setup_cleanup:\n+\tif (qp)\n+\t\trte_free(qp);\n+\n+\treturn -1;\n+}\n+\n+/** Start queue pair */\n+static int\n+snow3g_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,\n+\t\t__rte_unused uint16_t queue_pair_id)\n+{\n+\treturn -ENOTSUP;\n+}\n+\n+/** Stop queue pair */\n+static int\n+snow3g_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,\n+\t\t__rte_unused uint16_t queue_pair_id)\n+{\n+\treturn -ENOTSUP;\n+}\n+\n+/** Return the number of allocated queue pairs */\n+static uint32_t\n+snow3g_pmd_qp_count(struct rte_cryptodev *dev)\n+{\n+\treturn dev->data->nb_queue_pairs;\n+}\n+\n+/** Returns the size of the SNOW 3G session structure */\n+static unsigned\n+snow3g_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused)\n+{\n+\treturn sizeof(struct snow3g_session);\n+}\n+\n+/** Configure a SNOW 3G session from a crypto xform chain */\n+static void *\n+snow3g_pmd_session_configure(struct rte_cryptodev *dev __rte_unused,\n+\t\tstruct rte_crypto_sym_xform *xform,\tvoid *sess)\n+{\n+\tif (unlikely(sess == NULL)) {\n+\t\tSNOW3G_LOG_ERR(\"invalid session struct\");\n+\t\treturn NULL;\n+\t}\n+\n+\tif (snow3g_set_session_parameters(sess, xform) != 0) {\n+\t\tSNOW3G_LOG_ERR(\"failed configure session parameters\");\n+\t\treturn NULL;\n+\t}\n+\n+\treturn sess;\n+}\n+\n+/** Clear the memory of session so it doesn't leave key material behind */\n+static void\n+snow3g_pmd_session_clear(struct rte_cryptodev *dev __rte_unused, void *sess)\n+{\n+\t/*\n+\t * Current just resetting the whole data structure, need to investigate\n+\t * whether a more selective reset of key would be more performant\n+\t */\n+\tif (sess)\n+\t\tmemset(sess, 0, sizeof(struct snow3g_session));\n+}\n+\n+struct rte_cryptodev_ops snow3g_pmd_ops = {\n+\t\t.dev_configure      = snow3g_pmd_config,\n+\t\t.dev_start          = snow3g_pmd_start,\n+\t\t.dev_stop           = snow3g_pmd_stop,\n+\t\t.dev_close          = snow3g_pmd_close,\n+\n+\t\t.stats_get          = snow3g_pmd_stats_get,\n+\t\t.stats_reset        = snow3g_pmd_stats_reset,\n+\n+\t\t.dev_infos_get      = snow3g_pmd_info_get,\n+\n+\t\t.queue_pair_setup   = snow3g_pmd_qp_setup,\n+\t\t.queue_pair_release = snow3g_pmd_qp_release,\n+\t\t.queue_pair_start   = snow3g_pmd_qp_start,\n+\t\t.queue_pair_stop    = snow3g_pmd_qp_stop,\n+\t\t.queue_pair_count   = snow3g_pmd_qp_count,\n+\n+\t\t.session_get_size   = snow3g_pmd_session_get_size,\n+\t\t.session_configure  = snow3g_pmd_session_configure,\n+\t\t.session_clear      = snow3g_pmd_session_clear\n+};\n+\n+struct rte_cryptodev_ops *rte_snow3g_pmd_ops = &snow3g_pmd_ops;\ndiff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h\nnew file mode 100644\nindex 0000000..b383cbc\n--- /dev/null\n+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h\n@@ -0,0 +1,107 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _RTE_SNOW3G_PMD_PRIVATE_H_\n+#define _RTE_SNOW3G_PMD_PRIVATE_H_\n+\n+#include <sso_snow3g.h>\n+\n+#define SNOW3G_LOG_ERR(fmt, args...) \\\n+\tRTE_LOG(ERR, CRYPTODEV, \"[%s] %s() line %u: \" fmt \"\\n\",  \\\n+\t\t\tCRYPTODEV_NAME_SNOW3G_PMD, \\\n+\t\t\t__func__, __LINE__, ## args)\n+\n+#ifdef RTE_LIBRTE_SNOW3G_DEBUG\n+#define SNOW3G_LOG_INFO(fmt, args...) \\\n+\tRTE_LOG(INFO, CRYPTODEV, \"[%s] %s() line %u: \" fmt \"\\n\", \\\n+\t\t\tCRYPTODEV_NAME_SNOW3G_PMD, \\\n+\t\t\t__func__, __LINE__, ## args)\n+\n+#define SNOW3G_LOG_DBG(fmt, args...) \\\n+\tRTE_LOG(DEBUG, CRYPTODEV, \"[%s] %s() line %u: \" fmt \"\\n\", \\\n+\t\t\tCRYPTODEV_NAME_SNOW3G_PMD, \\\n+\t\t\t__func__, __LINE__, ## args)\n+#else\n+#define SNOW3G_LOG_INFO(fmt, args...)\n+#define SNOW3G_LOG_DBG(fmt, args...)\n+#endif\n+\n+/** private data structure for each virtual SNOW 3G device */\n+struct snow3g_private {\n+\tunsigned max_nb_queue_pairs;\n+\t/**< Max number of queue pairs supported by device */\n+\tunsigned max_nb_sessions;\n+\t/**< Max number of sessions supported by device */\n+};\n+\n+/** SNOW 3G buffer queue pair */\n+struct snow3g_qp {\n+\tuint16_t id;\n+\t/**< Queue Pair Identifier */\n+\tchar name[RTE_CRYPTODEV_NAME_LEN];\n+\t/**< Unique Queue Pair Name */\n+\tstruct rte_ring *processed_ops;\n+\t/**< Ring for placing processed ops */\n+\tstruct rte_mempool *sess_mp;\n+\t/**< Session Mempool */\n+\tstruct rte_cryptodev_stats qp_stats;\n+\t/**< Queue pair statistics */\n+} __rte_cache_aligned;\n+\n+enum snow3g_operation {\n+\tSNOW3G_OP_ONLY_CIPHER,\n+\tSNOW3G_OP_ONLY_AUTH,\n+\tSNOW3G_OP_CIPHER_AUTH,\n+\tSNOW3G_OP_AUTH_CIPHER,\n+\tSNOW3G_OP_NOT_SUPPORTED\n+};\n+\n+/** SNOW 3G private session structure */\n+struct snow3g_session {\n+\tenum snow3g_operation op;\n+\tenum rte_crypto_auth_operation auth_op;\n+\tsso_snow3g_key_schedule_t pKeySched_cipher;\n+\tsso_snow3g_key_schedule_t pKeySched_hash;\n+} __rte_cache_aligned;\n+\n+\n+extern int\n+snow3g_set_session_parameters(struct snow3g_session *sess,\n+\t\tconst struct rte_crypto_sym_xform *xform);\n+\n+\n+/** device specific operations function pointer structure */\n+extern struct rte_cryptodev_ops *rte_snow3g_pmd_ops;\n+\n+\n+\n+#endif /* _RTE_SNOW3G_PMD_PRIVATE_H_ */\ndiff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile\nindex 0d59229..314a046 100644\n--- a/lib/librte_cryptodev/Makefile\n+++ b/lib/librte_cryptodev/Makefile\n@@ -57,5 +57,6 @@ DEPDIRS-y += lib/librte_eal\n DEPDIRS-y += lib/librte_mempool\n DEPDIRS-y += lib/librte_ring\n DEPDIRS-y += lib/librte_mbuf\n+DEPDIRS-y += lib/librte_kvargs\n \n-include $(RTE_SDK)/mk/rte.lib.mk\n\\ No newline at end of file\n+include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h\nindex aab8cff..f279c92 100644\n--- a/lib/librte_cryptodev/rte_cryptodev.h\n+++ b/lib/librte_cryptodev/rte_cryptodev.h\n@@ -48,6 +48,7 @@\n extern \"C\" {\n #endif\n \n+#include \"rte_kvargs.h\"\n #include \"rte_crypto.h\"\n #include \"rte_dev.h\"\n \n@@ -57,15 +58,17 @@ extern \"C\" {\n /**< AES-NI Multi buffer PMD device name */\n #define CRYPTODEV_NAME_QAT_SYM_PMD\t(\"cryptodev_qat_sym_pmd\")\n /**< Intel QAT Symmetric Crypto PMD device name */\n+#define CRYPTODEV_NAME_SNOW3G_PMD\t(\"cryptodev_snow3g_pmd\")\n+/**< SNOW 3G PMD device name */\n \n /** Crypto device type */\n enum rte_cryptodev_type {\n \tRTE_CRYPTODEV_NULL_PMD = 1,\t/**< Null crypto PMD */\n \tRTE_CRYPTODEV_AESNI_MB_PMD,\t/**< AES-NI multi buffer PMD */\n \tRTE_CRYPTODEV_QAT_SYM_PMD,\t/**< QAT PMD Symmetric Crypto */\n+\tRTE_CRYPTODEV_SNOW3G_PMD,\t/**< SNOW 3G PMD */\n };\n \n-\n extern const char **rte_cyptodev_names;\n \n /* Logging Macros */\n@@ -148,6 +151,121 @@ struct rte_cryptodev_stats {\n \t/**< Total error count on operations dequeued */\n };\n \n+#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS\t8\n+#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS\t2048\n+\n+/**\n+ * @internal\n+ * Initialisation parameters for virtual crypto devices\n+ */\n+struct rte_crypto_vdev_init_params {\n+\tunsigned max_nb_queue_pairs;\n+\tunsigned max_nb_sessions;\n+\tuint8_t socket_id;\n+};\n+\n+#define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG\t\t(\"max_nb_queue_pairs\")\n+#define RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG\t\t(\"max_nb_sessions\")\n+#define RTE_CRYPTODEV_VDEV_SOCKET_ID\t\t\t(\"socket_id\")\n+\n+static const char *cryptodev_vdev_valid_params[] = {\n+\tRTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,\n+\tRTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,\n+\tRTE_CRYPTODEV_VDEV_SOCKET_ID\n+};\n+\n+static inline uint8_t\n+number_of_sockets(void)\n+{\n+\tint sockets = 0;\n+\tint i;\n+\tconst struct rte_memseg *ms = rte_eal_get_physmem_layout();\n+\n+\tfor (i = 0; ((i < RTE_MAX_MEMSEG) && (ms[i].addr != NULL)); i++) {\n+\t\tif (sockets < ms[i].socket_id)\n+\t\t\tsockets = ms[i].socket_id;\n+\t}\n+\n+\t/* Number of sockets = maximum socket_id + 1 */\n+\treturn ++sockets;\n+}\n+\n+/** Parse integer from integer argument */\n+static inline int\n+__rte_cryptodev_parse_integer_arg(const char *key __rte_unused,\n+\t\tconst char *value, void *extra_args)\n+{\n+\tint *i = extra_args;\n+\n+\t*i = atoi(value);\n+\tif (*i < 0) {\n+\t\tCDEV_LOG_ERR(\"Argument has to be positive.\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Parse virtual device initialisation parameters input arguments\n+ * @internal\n+ *\n+ * @params\tparams\t\tInitialisation parameters with defaults set.\n+ * @params\tinput_args\tCommand line arguments\n+ *\n+ * @return\n+ * 0 on successful parse\n+ * <0 on failure to parse\n+ */\n+static inline int\n+rte_cryptodev_parse_vdev_init_params(struct rte_crypto_vdev_init_params *params,\n+\t\tconst char *input_args)\n+{\n+\tstruct rte_kvargs *kvlist;\n+\tint ret;\n+\n+\tif (params == NULL)\n+\t\treturn -EINVAL;\n+\n+\tif (input_args) {\n+\t\tkvlist = rte_kvargs_parse(input_args,\n+\t\t\t\tcryptodev_vdev_valid_params);\n+\t\tif (kvlist == NULL)\n+\t\t\treturn -1;\n+\n+\t\tret = rte_kvargs_process(kvlist,\n+\t\t\t\t\tRTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,\n+\t\t\t\t\t&__rte_cryptodev_parse_integer_arg,\n+\t\t\t\t\t&params->max_nb_queue_pairs);\n+\t\tif (ret < 0)\n+\t\t\tgoto free_kvlist;\n+\n+\t\tret = rte_kvargs_process(kvlist,\n+\t\t\t\t\tRTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,\n+\t\t\t\t\t&__rte_cryptodev_parse_integer_arg,\n+\t\t\t\t\t&params->max_nb_sessions);\n+\t\tif (ret < 0)\n+\t\t\tgoto free_kvlist;\n+\n+\t\tret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,\n+\t\t\t\t\t&__rte_cryptodev_parse_integer_arg,\n+\t\t\t\t\t&params->socket_id);\n+\t\tif (ret < 0)\n+\t\t\tgoto free_kvlist;\n+\n+\t\tif (params->socket_id >= number_of_sockets()) {\n+\t\t\tCDEV_LOG_ERR(\"Invalid socket id specified to create \"\n+\t\t\t\t\"the virtual crypto device on\");\n+\t\t\tgoto free_kvlist;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+\n+free_kvlist:\n+\trte_kvargs_free(kvlist);\n+\treturn ret;\n+}\n \n /**\n  * Create a virtual crypto device\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex daac09f..7e46370 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -1,6 +1,6 @@\n #   BSD LICENSE\n #\n-#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.\n+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.\n #   Copyright(c) 2014-2015 6WIND S.A.\n #   All rights reserved.\n #\n@@ -150,6 +150,10 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT)        += -lrte_pmd_qat\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)   += -lrte_pmd_aesni_mb\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)   += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB\n \n+# SNOW3G PMD is dependent on the LIBSSO library\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G)     += -lrte_pmd_snow3g\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G)     += -L$(LIBSSO_PATH)/build -lsso\n+\n endif # ! $(CONFIG_RTE_BUILD_SHARED_LIB)\n \n _LDLIBS-y += $(EXECENV_LDLIBS)\n",
    "prefixes": [
        "dpdk-dev",
        "v3"
    ]
}