get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 29450,
    "url": "https://patches.dpdk.org/api/patches/29450/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1506735475-77078-3-git-send-email-amr.mokhtar@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": "<1506735475-77078-3-git-send-email-amr.mokhtar@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1506735475-77078-3-git-send-email-amr.mokhtar@intel.com",
    "date": "2017-09-30T01:37:52",
    "name": "[dpdk-dev,v1,3/6] bbdev: test applications",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "b30119eb22b0f9d4d1d703b32d1a294fe158f3ee",
    "submitter": {
        "id": 807,
        "url": "https://patches.dpdk.org/api/people/807/?format=api",
        "name": "Mokhtar, Amr",
        "email": "amr.mokhtar@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1506735475-77078-3-git-send-email-amr.mokhtar@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/29450/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/29450/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 280231B1B5;\n\tSat, 30 Sep 2017 03:38:10 +0200 (CEST)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id 0960E1B1A3\n\tfor <dev@dpdk.org>; Sat, 30 Sep 2017 03:38:04 +0200 (CEST)",
            "from orsmga003.jf.intel.com ([10.7.209.27])\n\tby fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t29 Sep 2017 18:38:03 -0700",
            "from silpixa00391537.ir.intel.com (HELO\n\tsilpixa00391537.ger.corp.intel.com) ([10.237.222.189])\n\tby orsmga003.jf.intel.com with ESMTP; 29 Sep 2017 18:38:01 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos; i=\"5.42,455,1500966000\"; d=\"scan'208\";\n\ta=\"1020035455\"",
        "From": "Amr Mokhtar <amr.mokhtar@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "niall.power@intel.com, chris.macnamara@intel.com,\n\tAmr Mokhtar <amr.mokhtar@intel.com>",
        "Date": "Sat, 30 Sep 2017 02:37:52 +0100",
        "Message-Id": "<1506735475-77078-3-git-send-email-amr.mokhtar@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1506735475-77078-1-git-send-email-amr.mokhtar@intel.com>",
        "References": "<1506735475-77078-1-git-send-email-amr.mokhtar@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v1 3/6] bbdev: test applications",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Signed-off-by: Amr Mokhtar <amr.mokhtar@intel.com>\n---\n app/Makefile                                       |    1 +\n app/test-bbdev/Makefile                            |   56 +\n app/test-bbdev/main.c                              |  317 ++++\n app/test-bbdev/main.h                              |  144 ++\n app/test-bbdev/test-bbdev.py                       |  132 ++\n app/test-bbdev/test_bbdev.c                        | 1406 ++++++++++++++++\n app/test-bbdev/test_bbdev_perf.c                   | 1700 ++++++++++++++++++++\n app/test-bbdev/test_bbdev_vector.c                 |  852 ++++++++++\n app/test-bbdev/test_bbdev_vector.h                 |   98 ++\n app/test-bbdev/test_vectors/bbdev_vector_null.data |   32 +\n .../test_vectors/bbdev_vector_td_default.data      |   80 +\n .../test_vectors/bbdev_vector_te_default.data      |   60 +\n 12 files changed, 4878 insertions(+)\n create mode 100644 app/test-bbdev/Makefile\n create mode 100644 app/test-bbdev/main.c\n create mode 100644 app/test-bbdev/main.h\n create mode 100755 app/test-bbdev/test-bbdev.py\n create mode 100644 app/test-bbdev/test_bbdev.c\n create mode 100644 app/test-bbdev/test_bbdev_perf.c\n create mode 100644 app/test-bbdev/test_bbdev_vector.c\n create mode 100644 app/test-bbdev/test_bbdev_vector.h\n create mode 100644 app/test-bbdev/test_vectors/bbdev_vector_null.data\n create mode 100644 app/test-bbdev/test_vectors/bbdev_vector_td_default.data\n create mode 100644 app/test-bbdev/test_vectors/bbdev_vector_te_default.data",
    "diff": "diff --git a/app/Makefile b/app/Makefile\nindex 7ea02b0..f3caeb4 100644\n--- a/app/Makefile\n+++ b/app/Makefile\n@@ -32,6 +32,7 @@\n include $(RTE_SDK)/mk/rte.vars.mk\n \n DIRS-$(CONFIG_RTE_TEST_PMD) += test-pmd\n+DIRS-$(CONFIG_RTE_TEST_BBDEV) += test-bbdev\n DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += proc_info\n DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += pdump\n \ndiff --git a/app/test-bbdev/Makefile b/app/test-bbdev/Makefile\nnew file mode 100644\nindex 0000000..7069d67\n--- /dev/null\n+++ b/app/test-bbdev/Makefile\n@@ -0,0 +1,56 @@\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2017 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 ($(CONFIG_RTE_TEST_BBDEV),y)\n+\n+#\n+# library name\n+#\n+APP = testbbdev\n+\n+CFLAGS += -O3\n+CFLAGS += $(WERROR_FLAGS)\n+\n+#\n+# all sources are stored in SRCS-y\n+#\n+SRCS-$(CONFIG_RTE_LIBRTE_BBDEV) += main.c\n+SRCS-$(CONFIG_RTE_LIBRTE_BBDEV) += test_bbdev.c\n+SRCS-$(CONFIG_RTE_LIBRTE_BBDEV) += test_bbdev_perf.c\n+SRCS-$(CONFIG_RTE_LIBRTE_BBDEV) += test_bbdev_vector.c\n+\n+# this application needs libraries first\n+DEPDIRS-y += lib drivers\n+\n+include $(RTE_SDK)/mk/rte.app.mk\n+\n+endif\ndiff --git a/app/test-bbdev/main.c b/app/test-bbdev/main.c\nnew file mode 100644\nindex 0000000..f02eefa\n--- /dev/null\n+++ b/app/test-bbdev/main.c\n@@ -0,0 +1,317 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 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 <getopt.h>\n+#include <inttypes.h>\n+#include <stdio.h>\n+#include <string.h>\n+#include <stdbool.h>\n+\n+#include <rte_eal.h>\n+#include <rte_common.h>\n+#include <rte_string_fns.h>\n+#include <rte_cycles.h>\n+\n+#include \"main.h\"\n+\n+/* Defines how many testcases can be specified as cmdline args */\n+#define MAX_CMDLINE_TESTCASES 8\n+\n+static const char tc_sep = ',';\n+\n+static struct test_params {\n+\tstruct test_command *test_to_run[MAX_CMDLINE_TESTCASES];\n+\tunsigned int num_tests;\n+\tunsigned int num_ops;\n+\tunsigned int burst_sz;\n+\tchar test_vector_filename[PATH_MAX];\n+} test_params;\n+\n+static struct test_commands_list commands_list =\n+\tTAILQ_HEAD_INITIALIZER(commands_list);\n+\n+void\n+add_test_command(struct test_command *t)\n+{\n+\tTAILQ_INSERT_TAIL(&commands_list, t, next);\n+}\n+\n+int\n+unit_test_suite_runner(struct unit_test_suite *suite)\n+{\n+\tint test_result = TEST_SUCCESS;\n+\tunsigned int total = 0, skipped = 0, succeeded = 0, failed = 0;\n+\tuint64_t start, end;\n+\n+\tprintf(\n+\t\t\t\"\\n + ------------------------------------------------------- +\\n\");\n+\tprintf(\" + Starting Test Suite : %s\\n\", suite->suite_name);\n+\n+\tstart = rte_rdtsc_precise();\n+\n+\tif (suite->setup) {\n+\t\ttest_result = suite->setup();\n+\t\tif (test_result == TEST_FAILED) {\n+\t\t\tprintf(\" + Test suite setup %s failed!\\n\",\n+\t\t\t\t\tsuite->suite_name);\n+\t\t\tprintf(\n+\t\t\t\t\t\" + ------------------------------------------------------- +\\n\");\n+\t\t\treturn 1;\n+\t\t}\n+\t\tif (test_result == TEST_SKIPPED) {\n+\t\t\tprintf(\" + Test suite setup %s skipped!\\n\",\n+\t\t\t\t\tsuite->suite_name);\n+\t\t\tprintf(\n+\t\t\t\t\t\" + ------------------------------------------------------- +\\n\");\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\n+\twhile (suite->unit_test_cases[total].testcase) {\n+\t\tif (suite->unit_test_cases[total].setup)\n+\t\t\ttest_result = suite->unit_test_cases[total].setup();\n+\n+\t\tif (test_result == TEST_SUCCESS)\n+\t\t\ttest_result = suite->unit_test_cases[total].testcase();\n+\n+\t\tif (suite->unit_test_cases[total].teardown)\n+\t\t\tsuite->unit_test_cases[total].teardown();\n+\n+\t\tif (test_result == TEST_SUCCESS) {\n+\t\t\tsucceeded++;\n+\t\t\tprintf(\" + TestCase [%2d] : %s passed\\n\", total,\n+\t\t\t\t\tsuite->unit_test_cases[total].name);\n+\t\t} else if (test_result == TEST_SKIPPED) {\n+\t\t\tskipped++;\n+\t\t\tprintf(\" + TestCase [%2d] : %s skipped\\n\", total,\n+\t\t\t\t\tsuite->unit_test_cases[total].name);\n+\t\t} else {\n+\t\t\tfailed++;\n+\t\t\tprintf(\" + TestCase [%2d] : %s failed\\n\", total,\n+\t\t\t\t\tsuite->unit_test_cases[total].name);\n+\t\t}\n+\n+\t\ttotal++;\n+\t}\n+\n+\t/* Run test suite teardown */\n+\tif (suite->teardown)\n+\t\tsuite->teardown();\n+\n+\tend = rte_rdtsc_precise();\n+\n+\tprintf(\" + ------------------------------------------------------- +\\n\");\n+\tprintf(\" + Test Suite Summary : %s\\n\", suite->suite_name);\n+\tprintf(\" + Tests Total :       %2d\\n\", total);\n+\tprintf(\" + Tests Skipped :     %2d\\n\", skipped);\n+\tprintf(\" + Tests Passed :      %2d\\n\", succeeded);\n+\tprintf(\" + Tests Failed :      %2d\\n\", failed);\n+\tprintf(\" + Tests Lasted :       %lg ms\\n\",\n+\t\t\t((end - start) * 1000) / (double)rte_get_tsc_hz());\n+\tprintf(\" + ------------------------------------------------------- +\\n\");\n+\n+\treturn (failed > 0) ? 1 : 0;\n+}\n+\n+const char *\n+get_vector_filename(void)\n+{\n+\treturn test_params.test_vector_filename;\n+}\n+\n+unsigned int\n+get_num_ops(void)\n+{\n+\treturn test_params.num_ops;\n+}\n+\n+unsigned int\n+get_burst_sz(void)\n+{\n+\treturn test_params.burst_sz;\n+}\n+\n+static void\n+print_usage(const char *prog_name)\n+{\n+\tstruct test_command *t;\n+\n+\tprintf(\"Usage: %s [EAL params] [-- [-n/--num-ops NUM_OPS]\\n\"\n+\t\t\t\"\\t[-b/--burst-size BURST_SIZE]\\n\"\n+\t\t\t\"\\t[-v/--test-vector VECTOR_FILE]\\n\"\n+\t\t\t\"\\t[-c/--test-cases TEST_CASE[,TEST_CASE,...]]]\\n\",\n+\t\t\tprog_name);\n+\n+\tprintf(\"Available testcases: \");\n+\tTAILQ_FOREACH(t, &commands_list, next)\n+\t\tprintf(\"%s \", t->command);\n+\tprintf(\"\\n\");\n+}\n+\n+static int\n+parse_args(int argc, char **argv, struct test_params *tp)\n+{\n+\tint opt, option_index;\n+\tunsigned int num_tests = 0;\n+\tbool test_cases_present = false;\n+\tbool test_vector_present = false;\n+\tstruct test_command *t;\n+\tchar *tokens[MAX_CMDLINE_TESTCASES];\n+\tint tc, ret;\n+\n+\tstatic struct option lgopts[] = {\n+\t\t{ \"num-ops\", 1, 0, 'n' },\n+\t\t{ \"burst-size\", 1, 0, 'b' },\n+\t\t{ \"test-cases\", 1, 0, 'c' },\n+\t\t{ \"test-vector\", 1, 0, 'v' },\n+\t\t{ \"help\", 0, 0, 'h' },\n+\t\t{ NULL,  0, 0, 0 }\n+\t};\n+\n+\twhile ((opt = getopt_long(argc, argv, \"hn:b:c:v:\", lgopts,\n+\t\t\t&option_index)) != EOF)\n+\t\tswitch (opt) {\n+\t\tcase 'n':\n+\t\t\tTEST_ASSERT(strlen(optarg) > 0,\n+\t\t\t\t\t\"Num of operations is not provided\");\n+\t\t\ttp->num_ops = strtol(optarg, NULL, 10);\n+\t\t\tbreak;\n+\t\tcase 'b':\n+\t\t\tTEST_ASSERT(strlen(optarg) > 0,\n+\t\t\t\t\t\"Burst size is not provided\");\n+\t\t\ttp->burst_sz = strtol(optarg, NULL, 10);\n+\t\t\tTEST_ASSERT(tp->burst_sz <= MAX_BURST,\n+\t\t\t\t\t\"Burst size mustn't be greater than %u\",\n+\t\t\t\t\tMAX_BURST);\n+\t\t\tbreak;\n+\t\tcase 'c':\n+\t\t\tTEST_ASSERT(test_cases_present == false,\n+\t\t\t\t\t\"Test cases provided more than once\");\n+\t\t\ttest_cases_present = true;\n+\n+\t\t\tret = rte_strsplit(optarg, strlen(optarg),\n+\t\t\t\t\ttokens, MAX_CMDLINE_TESTCASES, tc_sep);\n+\n+\t\t\tTEST_ASSERT(ret <= MAX_CMDLINE_TESTCASES,\n+\t\t\t\t\t\"Too many test cases (max=%d)\",\n+\t\t\t\t\tMAX_CMDLINE_TESTCASES);\n+\n+\t\t\tfor (tc = 0; tc < ret; ++tc) {\n+\t\t\t\t/* Find matching test case */\n+\t\t\t\tTAILQ_FOREACH(t, &commands_list, next)\n+\t\t\t\t\tif (!strcmp(tokens[tc], t->command))\n+\t\t\t\t\t\ttp->test_to_run[num_tests] = t;\n+\n+\t\t\t\tTEST_ASSERT(tp->test_to_run[num_tests] != NULL,\n+\t\t\t\t\t\t\"Unknown test case: %s\",\n+\t\t\t\t\t\ttokens[tc]);\n+\t\t\t\t++num_tests;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase 'v':\n+\t\t\tTEST_ASSERT(test_vector_present == false,\n+\t\t\t\t\t\"Test vector provided more than once\");\n+\t\t\ttest_vector_present = true;\n+\n+\t\t\tTEST_ASSERT(strlen(optarg) > 0,\n+\t\t\t\t\t\"Config file name is null\");\n+\n+\t\t\tstrncpy(tp->test_vector_filename, optarg,\n+\t\t\t\t\tsizeof(tp->test_vector_filename));\n+\t\t\tbreak;\n+\t\tcase 'h':\n+\t\t\tprint_usage(argv[0]);\n+\t\t\texit(EXIT_SUCCESS);\n+\t\tdefault:\n+\t\t\tprintf(\"ERROR: Unknown option: -%c\\n\", opt);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\tTEST_ASSERT(tp->burst_sz <= tp->num_ops,\n+\t\t\t\"Burst size (%u) mustn't be greater than num ops (%u)\",\n+\t\t\ttp->burst_sz, tp->num_ops);\n+\n+\ttp->num_tests = num_tests;\n+\treturn 0;\n+}\n+\n+static int\n+run_all_tests(void)\n+{\n+\tint ret = TEST_SUCCESS;\n+\tstruct test_command *t;\n+\n+\tTAILQ_FOREACH(t, &commands_list, next)\n+\t\tret |= t->callback();\n+\n+\treturn ret;\n+}\n+\n+static int\n+run_parsed_tests(struct test_params *tp)\n+{\n+\tint ret = TEST_SUCCESS;\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < tp->num_tests; ++i)\n+\t\tret |= tp->test_to_run[i]->callback();\n+\n+\treturn ret;\n+}\n+\n+int\n+main(int argc, char **argv)\n+{\n+\tint ret;\n+\n+\t/* Init EAL */\n+\tret = rte_eal_init(argc, argv);\n+\tif (ret < 0)\n+\t\treturn 1;\n+\targc -= ret;\n+\targv += ret;\n+\n+\t/* Parse application arguments (after the EAL ones) */\n+\tret = parse_args(argc, argv, &test_params);\n+\tif (ret < 0) {\n+\t\tprint_usage(argv[0]);\n+\t\treturn 1;\n+\t}\n+\n+\trte_log_set_global_level(RTE_LOG_INFO);\n+\n+\t/* If no argument provided - run all tests */\n+\tif (test_params.num_tests == 0)\n+\t\treturn run_all_tests();\n+\telse\n+\t\treturn run_parsed_tests(&test_params);\n+}\ndiff --git a/app/test-bbdev/main.h b/app/test-bbdev/main.h\nnew file mode 100644\nindex 0000000..a60076d\n--- /dev/null\n+++ b/app/test-bbdev/main.h\n@@ -0,0 +1,144 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 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 _MAIN_H_\n+#define _MAIN_H_\n+\n+#include <stddef.h>\n+#include <sys/queue.h>\n+\n+#include <rte_common.h>\n+#include <rte_hexdump.h>\n+#include <rte_log.h>\n+\n+#define TEST_SUCCESS    0\n+#define TEST_FAILED     -1\n+#define TEST_SKIPPED    1\n+\n+#define MAX_BURST 512U\n+\n+#define TEST_ASSERT(cond, msg, ...) do {  \\\n+\t\tif (!(cond)) {  \\\n+\t\t\tprintf(\"TestCase %s() line %d failed: \" \\\n+\t\t\t\tmsg \"\\n\", __func__, __LINE__, ##__VA_ARGS__); \\\n+\t\t\treturn TEST_FAILED;  \\\n+\t\t} \\\n+} while (0)\n+\n+/* Compare two buffers (length in bytes) */\n+#define TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, len, msg, ...) do { \\\n+\tif (memcmp((a), (b), len)) { \\\n+\t\tprintf(\"TestCase %s() line %d failed: \" \\\n+\t\t\tmsg \"\\n\", __func__, __LINE__, ##__VA_ARGS__); \\\n+\t\trte_memdump(stdout, \"Buffer A\", (a), len); \\\n+\t\trte_memdump(stdout, \"Buffer B\", (b), len); \\\n+\t\treturn TEST_FAILED; \\\n+\t} \\\n+} while (0)\n+\n+#define TEST_ASSERT_SUCCESS(val, msg, ...) do { \\\n+\t\ttypeof(val) _val = (val); \\\n+\t\tif (!(_val == 0)) { \\\n+\t\t\tprintf(\"TestCase %s() line %d failed (err %d): \" \\\n+\t\t\t\tmsg \"\\n\", __func__, __LINE__, _val, \\\n+\t\t\t\t##__VA_ARGS__); \\\n+\t\t\treturn TEST_FAILED; \\\n+\t\t} \\\n+} while (0)\n+\n+#define TEST_ASSERT_FAIL(val, msg, ...) \\\n+\tTEST_ASSERT_SUCCESS(!(val), msg, ##__VA_ARGS__)\n+\n+#define TEST_ASSERT_NOT_NULL(val, msg, ...) do { \\\n+\t\tif ((val) == NULL) { \\\n+\t\t\tprintf(\"TestCase %s() line %d failed (null): \" \\\n+\t\t\t\tmsg \"\\n\", __func__, __LINE__, ##__VA_ARGS__); \\\n+\t\t\treturn TEST_FAILED;  \\\n+\t\t} \\\n+} while (0)\n+\n+struct unit_test_case {\n+\tint (*setup)(void);\n+\tvoid (*teardown)(void);\n+\tint (*testcase)(void);\n+\tconst char *name;\n+};\n+\n+#define TEST_CASE(testcase) {NULL, NULL, testcase, #testcase}\n+\n+#define TEST_CASE_ST(setup, teardown, testcase) \\\n+\t\t{setup, teardown, testcase, #testcase}\n+\n+#define TEST_CASES_END() {NULL, NULL, NULL, NULL}\n+\n+struct unit_test_suite {\n+\tconst char *suite_name;\n+\tint (*setup)(void);\n+\tvoid (*teardown)(void);\n+\tstruct unit_test_case unit_test_cases[];\n+};\n+\n+int unit_test_suite_runner(struct unit_test_suite *suite);\n+\n+typedef int (test_callback)(void);\n+TAILQ_HEAD(test_commands_list, test_command);\n+struct test_command {\n+\tTAILQ_ENTRY(test_command) next;\n+\tconst char *command;\n+\ttest_callback *callback;\n+};\n+\n+void add_test_command(struct test_command *t);\n+\n+/* Register a test function */\n+#define REGISTER_TEST_COMMAND(name, testsuite) \\\n+\tstatic int test_func_##name(void) \\\n+\t{ \\\n+\t\treturn unit_test_suite_runner(&testsuite); \\\n+\t} \\\n+\tstatic struct test_command test_struct_##name = { \\\n+\t\t.command = RTE_STR(name), \\\n+\t\t.callback = test_func_##name, \\\n+\t}; \\\n+\tstatic void __attribute__((constructor, used)) \\\n+\ttest_register_##name(void) \\\n+\t{ \\\n+\t\tadd_test_command(&test_struct_##name); \\\n+\t}\n+\n+const char *get_vector_filename(void);\n+\n+unsigned int get_num_ops(void);\n+\n+unsigned int get_burst_sz(void);\n+\n+#endif\ndiff --git a/app/test-bbdev/test-bbdev.py b/app/test-bbdev/test-bbdev.py\nnew file mode 100755\nindex 0000000..09dd2d7\n--- /dev/null\n+++ b/app/test-bbdev/test-bbdev.py\n@@ -0,0 +1,132 @@\n+#!/usr/bin/env python\n+\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2017 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+import sys\n+import os\n+import argparse\n+import subprocess\n+import shlex\n+\n+from threading import Timer\n+\n+def kill(process):\n+    print \"ERROR: Test app timed out\"\n+    process.kill()\n+\n+if \"RTE_SDK\" in os.environ:\n+    dpdk_path = os.environ[\"RTE_SDK\"]\n+else:\n+    dpdk_path = \"../..\"\n+\n+if \"RTE_TARGET\" in os.environ:\n+    dpdk_target = os.environ[\"RTE_TARGET\"]\n+else:\n+    dpdk_target = \"x86_64-native-linuxapp-gcc\"\n+\n+parser = argparse.ArgumentParser(\n+                    description='BBdev Unit Test Application',\n+                    formatter_class=argparse.ArgumentDefaultsHelpFormatter)\n+parser.add_argument(\"-p\", \"--testapp-path\",\n+                    help=\"specifies path to the bbdev test app\",\n+                    default=dpdk_path + \"/\" + dpdk_target + \"/app/testbbdev\")\n+parser.add_argument(\"-e\", \"--eal-params\",\n+                    help=\"EAL arguments which are passed to the test app\",\n+                    default=\"--vdev=bbdev_null0\")\n+parser.add_argument(\"-t\", \"--timeout\",\n+                    type=int,\n+                    help=\"Timeout in seconds\",\n+                    default=300)\n+parser.add_argument(\"-c\", \"--test-cases\",\n+                    nargs=\"+\",\n+                    help=\"Defines test cases to run. Run all if not specified\")\n+parser.add_argument(\"-v\", \"--test-vector\",\n+                    nargs=\"+\",\n+                    help=\"Specifies paths to the test vector files.\",\n+                    default=[dpdk_path +\n+                    \"/app/test-bbdev/test_vectors/bbdev_vector_null.data\"])\n+parser.add_argument(\"-n\", \"--num-ops\",\n+                    type=int,\n+                    help=\"Number of operations to process on device.\",\n+                    default=32)\n+parser.add_argument(\"-b\", \"--burst-size\",\n+                    nargs=\"+\",\n+                    type=int,\n+                    help=\"Operations enqueue/dequeue burst size.\",\n+                    default=[32])\n+\n+args = parser.parse_args()\n+\n+if not os.path.exists(args.testapp_path):\n+    print \"No such file: \" + args.testapp_path\n+    sys.exit(1)\n+\n+params = [args.testapp_path]\n+if args.eal_params:\n+    params.extend(shlex.split(args.eal_params))\n+\n+params.extend([\"--\"])\n+\n+if args.num_ops:\n+    params.extend([\"-n\", str(args.num_ops)])\n+\n+if args.test_cases:\n+    params.extend([\"-c\"])\n+    params.extend([\",\".join(args.test_cases)])\n+\n+exit_status = 0\n+for vector in args.test_vector:\n+    for burst_size in args.burst_size:\n+        call_params = params[:]\n+        call_params.extend([\"-v\", vector])\n+        call_params.extend([\"-b\", str(burst_size)])\n+        params_string = \" \".join(call_params)\n+\n+        print(\"Executing: {}\".format(params_string))\n+        app_proc = subprocess.Popen(call_params)\n+        if args.timeout > 0:\n+            timer = Timer(args.timeout, kill, [app_proc])\n+            timer.start()\n+\n+        try:\n+            app_proc.communicate()\n+        except:\n+            print(\"Error: failed to execute: {}\".format(params_string))\n+        finally:\n+            timer.cancel()\n+\n+        if app_proc.returncode != 0:\n+            exit_status = 1\n+            print(\"ERROR TestCase failed. Failed test for vector {}. Return code: {}\".format(\n+                vector, app_proc.returncode))\n+\n+sys.exit(exit_status)\ndiff --git a/app/test-bbdev/test_bbdev.c b/app/test-bbdev/test_bbdev.c\nnew file mode 100644\nindex 0000000..4b1a3a4\n--- /dev/null\n+++ b/app/test-bbdev/test_bbdev.c\n@@ -0,0 +1,1406 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 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+ *\t * Redistributions of source code must retain the above copyright\n+ *\t   notice, this list of conditions and the following disclaimer.\n+ *\t * Redistributions in binary form must reproduce the above copyright\n+ *\t   notice, this list of conditions and the following disclaimer in\n+ *\t   the documentation and/or other materials provided with the\n+ *\t   distribution.\n+ *\t * Neither the name of Intel Corporation nor the names of its\n+ *\t   contributors may be used to endorse or promote products derived\n+ *\t   from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <rte_common.h>\n+#include <rte_hexdump.h>\n+#include <rte_mbuf.h>\n+#include <rte_malloc.h>\n+#include <rte_memcpy.h>\n+#include <rte_cycles.h>\n+\n+#include <rte_dev.h>\n+\n+#include <rte_bbdev.h>\n+#include <rte_bbdev_op.h>\n+#include <rte_bbdev_pmd.h>\n+\n+#include \"main.h\"\n+\n+\n+#define BBDEV_NAME_NULL          (\"bbdev_null\")\n+\n+struct bbdev_testsuite_params {\n+\tstruct rte_bbdev_queue_conf qconf;\n+};\n+\n+static struct bbdev_testsuite_params testsuite_params;\n+\n+static uint8_t null_dev_id;\n+\n+static int\n+testsuite_setup(void)\n+{\n+\tuint8_t nb_devs;\n+\tint ret;\n+\tchar buf[RTE_BBDEV_NAME_MAX_LEN];\n+\n+\t/* Create test device */\n+\tsnprintf(buf, sizeof(buf), \"%s_unittest\", BBDEV_NAME_NULL);\n+\tret = rte_vdev_init(buf, NULL);\n+\tTEST_ASSERT(ret == 0, \"Failed to create instance of pmd: %s\", buf);\n+\n+\tnb_devs = rte_bbdev_count();\n+\tTEST_ASSERT(nb_devs != 0, \"No devices found\");\n+\n+\t/* Most recently created device is our device */\n+\tnull_dev_id = nb_devs - 1;\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static void\n+testsuite_teardown(void)\n+{\n+\tchar buf[RTE_BBDEV_NAME_MAX_LEN];\n+\n+\tsnprintf(buf, sizeof(buf), \"%s_unittest\", BBDEV_NAME_NULL);\n+\trte_vdev_uninit(buf);\n+}\n+\n+static int\n+ut_setup(void)\n+{\n+\tstruct bbdev_testsuite_params *ts_params = &testsuite_params;\n+\tuint8_t num_queues;\n+\n+\t/* Valid queue configuration */\n+\tts_params->qconf.priority = 0;\n+\tts_params->qconf.socket = SOCKET_ID_ANY;\n+\tts_params->qconf.deferred_start = 1;\n+\n+\tnum_queues = 1;\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_configure(null_dev_id, num_queues, NULL),\n+\t\t\t\t\"Failed to configure bbdev %u\", 0);\n+\n+\t/* Start the device */\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_start(null_dev_id),\n+\t\t\t\"Failed to start bbdev %u\", 0);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static void\n+ut_teardown(void)\n+{\n+\trte_bbdev_close(null_dev_id);\n+}\n+\n+static int\n+test_bbdev_configure_invalid_dev_id(void)\n+{\n+\tuint8_t dev_id;\n+\tuint8_t num_queues;\n+\n+\tnum_queues = 1;\n+\tfor (dev_id = 0; dev_id < RTE_BBDEV_MAX_DEVS; dev_id++) {\n+\t\tif (!rte_bbdev_is_valid(dev_id)) {\n+\t\t\tTEST_ASSERT_FAIL(rte_bbdev_configure(dev_id, num_queues,\n+\t\t\t\t\tNULL),\n+\t\t\t\t\t\"Failed test for rte_bbdev_configure: \"\n+\t\t\t\t\t\"invalid dev_num %u\", dev_id);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_bbdev_configure_invalid_num_queues(void)\n+{\n+\tstruct rte_bbdev_info info;\n+\tuint8_t dev_id, num_devs;\n+\tuint8_t num_queues;\n+\tint return_value;\n+\n+\tTEST_ASSERT((num_devs = rte_bbdev_count()) >= 1,\n+\t\t\t\"Need at least %d devices for test\", 1);\n+\n+\t/* valid num_queues values */\n+\tnum_queues = 8;\n+\n+\t/* valid dev_id values */\n+\tdev_id = null_dev_id;\n+\n+\t/* Stop the device in case it's started so it can be configured */\n+\trte_bbdev_stop(dev_id);\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_configure(dev_id, 0, NULL),\n+\t\t\t\"Failed test for rte_bbdev_configure: \"\n+\t\t\t\"invalid num_queues %d\", 0);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_configure(dev_id, num_queues, NULL),\n+\t\t\t\"Failed test for rte_bbdev_configure: \"\n+\t\t\t\"invalid dev_num %u\", dev_id);\n+\n+\tTEST_ASSERT_FAIL(return_value = rte_bbdev_info_get(dev_id, NULL),\n+\t\t\t \"Failed test for rte_bbdev_info_get: \"\n+\t\t\t \"returned value:%i\", return_value);\n+\n+\tTEST_ASSERT_SUCCESS(return_value = rte_bbdev_info_get(dev_id, &info),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid return value:%i\", return_value);\n+\n+\tTEST_ASSERT(info.num_queues == num_queues,\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid num_queues:%u\", info.num_queues);\n+\n+\tnum_queues = info.drv.max_num_queues;\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_configure(dev_id, num_queues, NULL),\n+\t\t\t\"Failed test for rte_bbdev_configure: \"\n+\t\t\t\"invalid num_queues: %u\", num_queues);\n+\n+\tnum_queues++;\n+\tTEST_ASSERT_FAIL(rte_bbdev_configure(dev_id, num_queues, NULL),\n+\t\t\t\"Failed test for rte_bbdev_configure: \"\n+\t\t\t\"invalid num_queues: %u\", num_queues);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_bbdev_configure_stop_device(void)\n+{\n+\tstruct rte_bbdev_info info;\n+\tuint8_t dev_id;\n+\tint return_value;\n+\n+\t/* valid dev_id values */\n+\tdev_id = null_dev_id;\n+\n+\t/* Stop the device so it can be configured */\n+\trte_bbdev_stop(dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(return_value = rte_bbdev_info_get(dev_id, &info),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid return value from \"\n+\t\t\t\"rte_bbdev_info_get function: %i\", return_value);\n+\n+\tTEST_ASSERT_SUCCESS(info.started, \"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"started value: %u\", info.started);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_configure(dev_id, info.drv.max_num_queues,\n+\t\t\tNULL), \"Failed test for rte_bbdev_configure: \"\n+\t\t\t\"device should be stopped, dev_id: %u\", dev_id);\n+\n+\t/* Start the device so it cannot be configured */\n+\tTEST_ASSERT_FAIL(rte_bbdev_start(RTE_BBDEV_MAX_DEVS),\n+\t\t\t\"Failed to start bbdev %u\", dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_start(dev_id),\n+\t\t\t\"Failed to start bbdev %u\", dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(return_value = rte_bbdev_info_get(dev_id, &info),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid return value from \"\n+\t\t\t\"rte_bbdev_info_get function: %i\", return_value);\n+\n+\tTEST_ASSERT_FAIL(info.started, \"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"started value: %u\", info.started);\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_configure(dev_id, info.drv.max_num_queues,\n+\t\t\tNULL), \"Failed test for rte_bbdev_configure: \"\n+\t\t\t\"device should be started, dev_id: %u\", dev_id);\n+\n+\t/* Stop again the device so it can be once again configured */\n+\tTEST_ASSERT_FAIL(rte_bbdev_stop(RTE_BBDEV_MAX_DEVS),\n+\t\t\t\"Failed to start bbdev %u\", dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stop(dev_id), \"Failed to stop bbdev %u\",\n+\t\t\tdev_id);\n+\n+\tTEST_ASSERT_SUCCESS(return_value = rte_bbdev_info_get(dev_id, &info),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid return value from \"\n+\t\t\t\"rte_bbdev_info_get function: %i\", return_value);\n+\n+\tTEST_ASSERT_SUCCESS(info.started, \"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"started value: %u\", info.started);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_configure(dev_id, info.drv.max_num_queues,\n+\t\t\tNULL), \"Failed test for rte_bbdev_configure: \"\n+\t\t\t\"device should be stopped, dev_id: %u\", dev_id);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_bbdev_configure_stop_queue(void)\n+{\n+\tstruct bbdev_testsuite_params *ts_params = &testsuite_params;\n+\tstruct rte_bbdev_info info;\n+\tstruct rte_bbdev_queue_info qinfo;\n+\tuint8_t dev_id;\n+\tuint16_t queue_id;\n+\tint return_value;\n+\n+\t/* Valid dev_id values */\n+\tdev_id = null_dev_id;\n+\n+\t/* Valid queue_id values */\n+\tqueue_id = 0;\n+\n+\trte_bbdev_stop(dev_id);\n+\tTEST_ASSERT_SUCCESS(return_value = rte_bbdev_info_get(dev_id, &info),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid return value:%i\", return_value);\n+\n+\t/* Valid queue configuration */\n+\tts_params->qconf.queue_size = info.drv.queue_size_lim;\n+\tts_params->qconf.priority = info.drv.max_queue_priority;\n+\n+\t/* Device - started; queue - started */\n+\trte_bbdev_start(dev_id);\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"queue:%u on device:%u should be stopped\",\n+\t\t\t queue_id, dev_id);\n+\n+\t/* Device - stopped; queue - started */\n+\trte_bbdev_stop(dev_id);\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"queue:%u on device:%u should be stopped\",\n+\t\t\t queue_id, dev_id);\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_stop(RTE_BBDEV_MAX_DEVS, queue_id),\n+\t\t\t\"Failed test for rte_bbdev_queue_stop \"\n+\t\t\t\"invalid dev_id \");\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_stop(dev_id, RTE_MAX_QUEUES_PER_PORT),\n+\t\t\t\"Failed test for rte_bbdev_queue_stop \"\n+\t\t\t\"invalid queue_id \");\n+\n+\t/* Device - stopped; queue - stopped */\n+\trte_bbdev_queue_stop(dev_id, queue_id);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"queue:%u on device:%u should be stopped\", queue_id,\n+\t\t\tdev_id);\n+\n+\tTEST_ASSERT_SUCCESS(return_value = rte_bbdev_queue_info_get(dev_id,\n+\t\t\tqueue_id, &qinfo),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid return value from \"\n+\t\t\t\"rte_bbdev_queue_info_get function: %i\", return_value);\n+\n+\tTEST_ASSERT(qinfo.conf.socket == ts_params->qconf.socket,\n+\t\t\t\"Failed test for rte_bbdev_queue_info_get: \"\n+\t\t\t\"invalid queue_size:%u\", qinfo.conf.socket);\n+\n+\tTEST_ASSERT(qinfo.conf.queue_size == ts_params->qconf.queue_size,\n+\t\t\t\"Failed test for rte_bbdev_queue_info_get: \"\n+\t\t\t\"invalid queue_size:%u\", qinfo.conf.queue_size);\n+\n+\tTEST_ASSERT(qinfo.conf.priority == ts_params->qconf.priority,\n+\t\t\t\"Failed test for rte_bbdev_queue_info_get: \"\n+\t\t\t\"invalid queue_size:%u\", qinfo.conf.priority);\n+\n+\tTEST_ASSERT(qinfo.conf.deferred_start ==\n+\t\t\tts_params->qconf.deferred_start,\n+\t\t\t\"Failed test for rte_bbdev_queue_info_get: \"\n+\t\t\t\"invalid queue_size:%u\", qinfo.conf.deferred_start);\n+\n+\t/* Device - started; queue - stopped */\n+\trte_bbdev_start(dev_id);\n+\trte_bbdev_queue_stop(dev_id, queue_id);\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"queue:%u on device:%u should be stopped\", queue_id,\n+\t\t\tdev_id);\n+\n+\trte_bbdev_stop(dev_id);\n+\n+\t/* After rte_bbdev_start(dev_id):\n+\t * - queue should be still stopped if deferred_start ==\n+\t */\n+\trte_bbdev_start(dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(return_value = rte_bbdev_queue_info_get(dev_id,\n+\t\t\tqueue_id, &qinfo),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid return value from \"\n+\t\t\t\"rte_bbdev_queue_info_get function: %i\", return_value);\n+\n+\tTEST_ASSERT(qinfo.started == 0,\n+\t\t\t\"Failed test for rte_bbdev_queue_info_get: \"\n+\t\t\t\"invalid value for qinfo.started:%u\", qinfo.started);\n+\n+\trte_bbdev_stop(dev_id);\n+\n+\t/* After rte_bbdev_start(dev_id):\n+\t * - queue should be started if deferred_start ==\n+\t */\n+\tts_params->qconf.deferred_start = 0;\n+\trte_bbdev_queue_configure(dev_id, queue_id, &ts_params->qconf);\n+\trte_bbdev_start(dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(return_value = rte_bbdev_queue_info_get(dev_id,\n+\t\t\tqueue_id, &qinfo),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid return value from \"\n+\t\t\t\"rte_bbdev_queue_info_get function: %i\", return_value);\n+\n+\tTEST_ASSERT(qinfo.started == 1,\n+\t\t\t\"Failed test for rte_bbdev_queue_info_get: \"\n+\t\t\t\"invalid value for qinfo.started:%u\", qinfo.started);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_bbdev_configure_invalid_queue_configure(void)\n+{\n+\tstruct bbdev_testsuite_params *ts_params = &testsuite_params;\n+\tint return_value;\n+\tstruct rte_bbdev_info info;\n+\tuint8_t dev_id;\n+\tuint16_t queue_id;\n+\n+\t/* Valid dev_id values */\n+\tdev_id = null_dev_id;\n+\n+\t/* Valid queue_id values */\n+\tqueue_id = 0;\n+\n+\trte_bbdev_stop(dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(return_value = rte_bbdev_info_get(dev_id, &info),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid return value:%i\", return_value);\n+\n+\trte_bbdev_queue_stop(dev_id, queue_id);\n+\n+\tts_params->qconf.queue_size = info.drv.queue_size_lim + 1;\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"invalid value qconf.queue_size: %u\",\n+\t\t\tts_params->qconf.queue_size);\n+\n+\tts_params->qconf.queue_size = info.drv.queue_size_lim;\n+\tts_params->qconf.priority = info.drv.max_queue_priority + 1;\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"invalid value qconf.queue_size: %u\",\n+\t\t\tts_params->qconf.queue_size);\n+\n+\tts_params->qconf.priority = info.drv.max_queue_priority;\n+\tqueue_id = info.num_queues;\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"invalid value queue_id: %u\", queue_id);\n+\n+\tqueue_id = 0;\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_configure(dev_id, queue_id, NULL),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"NULL qconf structure \");\n+\n+\tts_params->qconf.socket = RTE_MAX_NUMA_NODES;\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"invalid socket number \");\n+\n+\tts_params->qconf.socket = SOCKET_ID_ANY;\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"invalid value qconf.queue_size: %u\",\n+\t\t\tts_params->qconf.queue_size);\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(RTE_BBDEV_MAX_DEVS, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"invalid dev_id\");\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_configure(dev_id, queue_id, NULL),\n+\t\t\t\"Failed test for rte_bbdev_queue_configure: \"\n+\t\t\t\"invalid value qconf.queue_size: %u\",\n+\t\t\tts_params->qconf.queue_size);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_bbdev_op_pool(void)\n+{\n+\tstruct rte_mempool *mp;\n+\n+\tunsigned int bbdev_op_size = sizeof(struct rte_bbdev_op);\n+\tunsigned int dec_size = bbdev_op_size +\n+\t\tsizeof(struct rte_bbdev_op_turbo_dec);\n+\tunsigned int enc_size = bbdev_op_size +\n+\t\t\tsizeof(struct rte_bbdev_op_turbo_enc);\n+\n+\tconst char *pool_dec = \"Test_DEC\";\n+\tconst char *pool_enc = \"Test_ENC\";\n+\n+\t/* Valid pool configuration */\n+\tuint32_t size = 256;\n+\tuint32_t cache_size = 128;\n+\n+\tTEST_ASSERT(rte_bbdev_op_pool_create(NULL,\n+\t\t\tRTE_BBDEV_OP_TURBO_DEC, size, cache_size, 0) == NULL,\n+\t\t\t\"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"NULL name parameter\");\n+\n+\tTEST_ASSERT((mp = rte_bbdev_op_pool_create(pool_dec,\n+\t\t\tRTE_BBDEV_OP_TURBO_DEC, size, cache_size, 0)) != NULL,\n+\t\t\t\"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"returned value is empty\");\n+\n+\tTEST_ASSERT(mp->size == size,\n+\t\t\t\"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"invalid size of the mempool, mp->size: %u\", mp->size);\n+\n+\tTEST_ASSERT(mp->cache_size == cache_size,\n+\t\t\t\"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"invalid size of the mempool, mp->size: %u\",\n+\t\t\tmp->cache_size);\n+\n+\tTEST_ASSERT_SUCCESS(strcmp(mp->name, pool_dec),\n+\t\t\t\"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"invalid name of mempool, mp->name: %s\", mp->name);\n+\n+\tTEST_ASSERT(mp->elt_size == dec_size,\n+\t\t\t\"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"invalid element size for RTE_BBDEV_OP_TURBO_DEC, \"\n+\t\t\t\"mp->elt_size: %u\", mp->elt_size);\n+\n+\trte_mempool_free(mp);\n+\n+\tTEST_ASSERT((mp = rte_bbdev_op_pool_create(pool_enc,\n+\t\t\tRTE_BBDEV_OP_TURBO_ENC, size, cache_size, 0)) != NULL,\n+\t\t\t \"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"returned value is empty\");\n+\n+\tTEST_ASSERT(mp->elt_size == enc_size,\n+\t\t\t\"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"invalid element size for RTE_BBDEV_OP_TURBO_ENC, \"\n+\t\t\t\"mp->elt_size: %u\", mp->elt_size);\n+\n+\trte_mempool_free(mp);\n+\n+\tTEST_ASSERT((mp = rte_bbdev_op_pool_create(\"Test_NONE\",\n+\t\t\tRTE_BBDEV_OP_NONE, size, cache_size, 0)) != NULL,\n+\t\t\t\"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"returned value is empty for RTE_BBDEV_OP_NONE\");\n+\n+\tTEST_ASSERT(mp->elt_size == (enc_size > dec_size ? enc_size : dec_size),\n+\t\t\t\"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"invalid  size for RTE_BBDEV_OP_NONE, mp->elt_size: %u\",\n+\t\t\tmp->elt_size);\n+\n+\trte_mempool_free(mp);\n+\n+\tTEST_ASSERT((mp = rte_bbdev_op_pool_create(\"Test_INV\",\n+\t\t\tRTE_BBDEV_OP_TYPE_COUNT, size, cache_size, 0)) == NULL,\n+\t\t\t\"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"returned value is not NULL for invalid type\");\n+\n+\t/* Invalid pool configuration */\n+\tsize = 128;\n+\tcache_size = 256;\n+\n+\tTEST_ASSERT((mp = rte_bbdev_op_pool_create(\"Test_InvSize\",\n+\t\t\tRTE_BBDEV_OP_NONE, size, cache_size, 0)) == NULL,\n+\t\t\t\"Failed test for rte_bbdev_op_pool_create: \"\n+\t\t\t\"returned value should be empty \"\n+\t\t\t\"because size of per-lcore local cache \"\n+\t\t\t\"is greater than size of the mempool.\");\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+/**\n+ *  Create pool of OP types RTE_BBDEV_OP_NONE, RTE_BBDEV_OP_TURBO_DEC and\n+ *  RTE_BBDEV_OP_TURBO_ENC and check that only ops of that type can be\n+ *  allocated\n+ */\n+static int\n+test_bbdev_op_type(void)\n+{\n+\tstruct rte_mempool *mp_none, *mp_dec;\n+\n+\tconst unsigned int OPS_COUNT = 32;\n+\tstruct rte_bbdev_op *ops_arr[OPS_COUNT];\n+\n+\tconst char *pool_none = \"Test_op_none\";\n+\tconst char *pool_dec = \"Test_op_dec\";\n+\n+\t/* Valid pool configuration */\n+\tuint32_t num_elements = 256;\n+\tuint32_t cache_size = 128;\n+\n+\t/* mempool type : RTE_BBDEV_OP_NONE */\n+\tmp_none = rte_bbdev_op_pool_create(pool_none, RTE_BBDEV_OP_NONE,\n+\t\t\tnum_elements, cache_size, 0);\n+\tTEST_ASSERT(mp_none != NULL, \"Failed to create %s mempool\", pool_none);\n+\n+\tTEST_ASSERT(rte_bbdev_op_alloc_bulk(mp_none,\n+\t\t\tRTE_BBDEV_OP_NONE, ops_arr, 1) == 0,\n+\t\t\t\"Failed test for rte_bbdev_op_alloc_bulk MP_NONE: \"\n+\t\t\t\"OPs type: RTE_BBDEV_OP_NONE\");\n+\n+\tTEST_ASSERT(rte_bbdev_op_alloc_bulk(mp_none,\n+\t\t\tRTE_BBDEV_OP_TURBO_DEC, ops_arr, 1) == 0,\n+\t\t\t\"Failed test for rte_bbdev_op_alloc_bulk MP_NONE:\"\n+\t\t\t\" OPs type: RTE_BBDEV_OP_TURBO_DEC\");\n+\n+\tTEST_ASSERT(rte_bbdev_op_alloc_bulk(mp_none,\n+\t\t\tRTE_BBDEV_OP_TURBO_ENC, ops_arr, 1) == 0,\n+\t\t\t\"Failed test for rte_bbdev_op_alloc_bulk MP_NONE: \"\n+\t\t\t\"OPs type: RTE_BBDEV_OP_TURBO_ENC\");\n+\n+\t/* mempool type : RTE_BBDEV_OP_TURBO_DEC */\n+\tmp_dec = rte_bbdev_op_pool_create(pool_dec,\n+\t\t\tRTE_BBDEV_OP_TURBO_DEC, num_elements, cache_size, 0);\n+\tTEST_ASSERT(mp_dec != NULL, \"Failed to create %s mempool\", pool_dec);\n+\n+\tTEST_ASSERT(rte_bbdev_op_alloc_bulk(mp_dec,\n+\t\t\tRTE_BBDEV_OP_NONE, ops_arr, 1) != 0,\n+\t\t\t\"Failed test for rte_bbdev_op_alloc_bulk TURBO_DEC: \"\n+\t\t\t\"OPs type: RTE_BBDEV_OP_NONE\");\n+\n+\tTEST_ASSERT(rte_bbdev_op_alloc_bulk(mp_dec,\n+\t\t\tRTE_BBDEV_OP_TURBO_DEC, ops_arr, 1) == 0,\n+\t\t\t\"Failed test for rte_bbdev_op_alloc_bulk TURBO_DEC: \"\n+\t\t\t\"OPs type: RTE_BBDEV_OP_TURBO_DEC\");\n+\n+\tTEST_ASSERT(rte_bbdev_op_alloc_bulk(mp_dec,\n+\t\t\tRTE_BBDEV_OP_TURBO_ENC, ops_arr, 1) != 0,\n+\t\t\t\"Failed test for rte_bbdev_op_alloc_bulk TURBO_DEC: \"\n+\t\t\t\"OPs type: RTE_BBDEV_OP_TURBO_ENC\");\n+\n+\trte_mempool_free(mp_none);\n+\trte_mempool_free(mp_dec);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_bbdev_op_pool_size(void)\n+{\n+\tstruct rte_mempool *mp_none;\n+\n+\tconst unsigned int OPS_COUNT = 128;\n+\tstruct rte_bbdev_op *ops_enc_arr[OPS_COUNT];\n+\tstruct rte_bbdev_op *ops_dec_arr[OPS_COUNT];\n+\tstruct rte_bbdev_op *ops_ext_arr[OPS_COUNT];\n+\n+\tconst char *pool_none = \"Test_pool_size\";\n+\n+\t/* Valid pool configuration */\n+\tuint32_t num_elements = 256;\n+\tuint32_t cache_size = 0;\n+\n+\t/* Create mempool type : RTE_BBDEV_OP_NONE, size : 256 */\n+\tmp_none = rte_bbdev_op_pool_create(pool_none, RTE_BBDEV_OP_NONE,\n+\t\t\tnum_elements, cache_size, 0);\n+\tTEST_ASSERT(mp_none != NULL, \"Failed to create %s mempool\", pool_none);\n+\n+\t/* Add 128 RTE_BBDEV_OP_TURBO_ENC ops */\n+\trte_bbdev_op_alloc_bulk(mp_none, RTE_BBDEV_OP_TURBO_ENC,\n+\t\t\tops_enc_arr, OPS_COUNT);\n+\n+\t/* Add 128 RTE_BBDEV_OP_TURBO_DEC ops */\n+\tTEST_ASSERT(rte_bbdev_op_alloc_bulk(mp_none, RTE_BBDEV_OP_TURBO_DEC,\n+\t\t\tops_dec_arr, OPS_COUNT) == 0,\n+\t\t\t\"Failed test for allocating bbdev ops: \"\n+\t\t\t\"Mempool size: 256, Free : 128, Attempted to add: 128\");\n+\n+\t/* Try adding 128 more RTE_BBDEV_OP_TURBO_DEC ops, this should fail */\n+\tTEST_ASSERT(rte_bbdev_op_alloc_bulk(mp_none,\n+\t\t\tRTE_BBDEV_OP_TURBO_DEC, ops_ext_arr, OPS_COUNT) != 0,\n+\t\t\t\"Failed test for allocating bbdev ops: \"\n+\t\t\t\"Mempool size: 256, Free : 0, Attempted to add: 128\");\n+\n+\t/* Free-up 128 RTE_BBDEV_OP_TURBO_ENC ops */\n+\trte_bbdev_op_free_bulk(ops_enc_arr, OPS_COUNT);\n+\n+\t/* Try adding 128 RTE_BBDEV_OP_TURBO_DEC ops, this should succeed */\n+\t/* Cache size > 0 causes reallocation of ops size > 127 fail */\n+\tTEST_ASSERT(rte_bbdev_op_alloc_bulk(mp_none,\n+\t\t\tRTE_BBDEV_OP_TURBO_DEC, ops_ext_arr, OPS_COUNT) == 0,\n+\t\t\t\"Failed test for allocating ops after mempool freed:  \"\n+\t\t\t\"Mempool size: 256, Free : 128, Attempted to add: 128\");\n+\n+\trte_mempool_free(mp_none);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_bbdev_count(void)\n+{\n+\tuint8_t num_devs, num_valid_devs = 0;\n+\n+\tfor (num_devs = 0; num_devs < RTE_BBDEV_MAX_DEVS; num_devs++) {\n+\t\tif (rte_bbdev_is_valid(num_devs))\n+\t\t\tnum_valid_devs++;\n+\t}\n+\n+\tnum_devs = rte_bbdev_count();\n+\tTEST_ASSERT(num_valid_devs == num_devs,\n+\t\t\t\"Failed test for rte_bbdev_is_valid: \"\n+\t\t\t\"invalid num_devs %u \", num_devs);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_bbdev_stats(void)\n+{\n+\tuint8_t dev_id = null_dev_id;\n+\tuint16_t queue_id = 0;\n+\tstruct rte_bbdev_op *ops[4096] = { 0 };\n+\tstruct rte_bbdev_op *proc_ops[4096] = { 0 };\n+\tuint16_t num_ops = 236;\n+\tstruct rte_bbdev_stats stats;\n+\tstruct bbdev_testsuite_params *ts_params = &testsuite_params;\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_stop(dev_id, queue_id),\n+\t\t\t\"Failed to stop queue %u on device %u \", queue_id,\n+\t\t\tdev_id);\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stop(dev_id),\n+\t\t\t\"Failed to stop bbdev %u \", dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed to configure queue %u on device %u \",\n+\t\t\tqueue_id, dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_start(dev_id),\n+\t\t\t\"Failed to start bbdev %u \", dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_start(dev_id, queue_id),\n+\t\t\t\"Failed to start queue %u on device %u \", queue_id,\n+\t\t\tdev_id);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_start(dev_id, queue_id),\n+\t\t\t\"Failed to start queue %u on device %u \", queue_id,\n+\t\t\tdev_id);\n+\n+\t/* Tests after enqueue operation */\n+\trte_bbdev_enqueue_ops(dev_id, queue_id, ops, num_ops);\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_stats_get(RTE_BBDEV_MAX_DEVS, &stats),\n+\t\t\t\"Failed test for rte_bbdev_stats_get on device %u \",\n+\t\t\tdev_id);\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_stats_get(dev_id, NULL),\n+\t\t\t\"Failed test for rte_bbdev_stats_get on device %u \",\n+\t\t\tdev_id);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stats_get(dev_id, &stats),\n+\t\t\t\"Failed test for rte_bbdev_stats_get on device %u \",\n+\t\t\tdev_id);\n+\n+\tTEST_ASSERT(stats.enqueued_count == num_ops,\n+\t\t\t\"Failed test for rte_bbdev_enqueue_ops: \"\n+\t\t\t\"invalid enqueued_count %\" PRIu64 \" \",\n+\t\t\tstats.enqueued_count);\n+\n+\tTEST_ASSERT(stats.dequeued_count == 0,\n+\t\t\t\"Failed test for rte_bbdev_stats_reset: \"\n+\t\t\t\"invalid dequeued_count %\" PRIu64 \" \",\n+\t\t\tstats.dequeued_count);\n+\n+\t/* Tests after dequeue operation */\n+\trte_bbdev_dequeue_ops(dev_id, queue_id, proc_ops, num_ops);\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stats_get(dev_id, &stats),\n+\t\t\t\"Failed test for rte_bbdev_stats_get on device %u \",\n+\t\t\tdev_id);\n+\n+\tTEST_ASSERT(stats.dequeued_count == num_ops,\n+\t\t\t\"Failed test for rte_bbdev_dequeue_ops: \"\n+\t\t\t\"invalid enqueued_count %\" PRIu64 \" \",\n+\t\t\tstats.dequeued_count);\n+\n+\tTEST_ASSERT(stats.enqueue_err_count == 0,\n+\t\t\t\"Failed test for rte_bbdev_stats_reset: \"\n+\t\t\t\"invalid enqueue_err_count %\" PRIu64 \" \",\n+\t\t\tstats.enqueue_err_count);\n+\n+\tTEST_ASSERT(stats.dequeue_err_count == 0,\n+\t\t\t\"Failed test for rte_bbdev_stats_reset: \"\n+\t\t\t\"invalid dequeue_err_count %\" PRIu64 \" \",\n+\t\t\tstats.dequeue_err_count);\n+\n+\t/* Tests after reset operation */\n+\tTEST_ASSERT_FAIL(rte_bbdev_stats_reset(RTE_BBDEV_MAX_DEVS),\n+\t\t\t\"Failed to reset statistic for device %u \", dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stats_reset(dev_id),\n+\t\t\t\"Failed to reset statistic for device %u \", dev_id);\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stats_get(dev_id, &stats),\n+\t\t\t\"Failed test for rte_bbdev_stats_get on device %u \",\n+\t\t\tdev_id);\n+\n+\tTEST_ASSERT(stats.enqueued_count == 0,\n+\t\t\t\"Failed test for rte_bbdev_stats_reset: \"\n+\t\t\t\"invalid enqueued_count %\" PRIu64 \" \",\n+\t\t\tstats.enqueued_count);\n+\n+\tTEST_ASSERT(stats.dequeued_count == 0,\n+\t\t\t\"Failed test for rte_bbdev_stats_reset: \"\n+\t\t\t\"invalid dequeued_count %\" PRIu64 \" \",\n+\t\t\tstats.dequeued_count);\n+\n+\tTEST_ASSERT(stats.enqueue_err_count == 0,\n+\t\t\t\"Failed test for rte_bbdev_stats_reset: \"\n+\t\t\t\"invalid enqueue_err_count %\" PRIu64 \" \",\n+\t\t\tstats.enqueue_err_count);\n+\n+\tTEST_ASSERT(stats.dequeue_err_count == 0,\n+\t\t\t\"Failed test for rte_bbdev_stats_reset: \"\n+\t\t\t\"invalid dequeue_err_count %\" PRIu64 \" \",\n+\t\t\tstats.dequeue_err_count);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_bbdev_driver_init(void)\n+{\n+\tstruct rte_bbdev *dev1, *dev2;\n+\tconst char *name = \"dev_name\";\n+\tchar name_tmp[16];\n+\tint num_devs, num_devs_tmp;\n+\n+\tdev1 = rte_bbdev_allocate(NULL);\n+\tTEST_ASSERT(dev1 == NULL,\n+\t\t\t\"Failed initialize bbdev driver with NULL name\");\n+\n+\tdev1 = rte_bbdev_allocate(name);\n+\tTEST_ASSERT(dev1 != NULL, \"Failed to initialize bbdev driver\");\n+\n+\tdev2 = rte_bbdev_allocate(name);\n+\tTEST_ASSERT(dev2 == NULL,\n+\t\t\t\"Failed to initialize bbdev driver: \"\n+\t\t\t\"driver with the same name has been initialized before\");\n+\n+\tnum_devs = rte_bbdev_count() - 1;\n+\tnum_devs_tmp = num_devs;\n+\n+\t/* Initialize the maximum amount of devices */\n+\tdo {\n+\t\tsprintf(name_tmp, \"%s%i\", \"name_\", num_devs);\n+\t\tdev2 = rte_bbdev_allocate(name_tmp);\n+\t\tTEST_ASSERT(dev2 != NULL,\n+\t\t\t\t\"Failed to initialize bbdev driver\");\n+\t\t++num_devs;\n+\t} while (num_devs < (RTE_BBDEV_MAX_DEVS - 1));\n+\n+\tsprintf(name_tmp, \"%s%i\", \"name_\", num_devs);\n+\tdev2 = rte_bbdev_allocate(name_tmp);\n+\tTEST_ASSERT(dev2 == NULL, \"Failed to initialize bbdev driver number %d \"\n+\t\t\t\"more drivers than RTE_BBDEV_MAX_DEVS: %d \", num_devs,\n+\t\t\tRTE_BBDEV_MAX_DEVS);\n+\n+\tnum_devs--;\n+\n+\twhile (num_devs >= num_devs_tmp) {\n+\t\tsprintf(name_tmp, \"%s%i\", \"name_\", num_devs);\n+\t\tdev2 = rte_bbdev_get_named_dev(name_tmp);\n+\t\tTEST_ASSERT_SUCCESS(rte_bbdev_release(dev2),\n+\t\t\t\t\"Failed to uninitialize bbdev driver %s \",\n+\t\t\t\tname_tmp);\n+\t\tnum_devs--;\n+\t}\n+\n+\tTEST_ASSERT(dev1->data->dev_id < RTE_BBDEV_MAX_DEVS,\n+\t\t\t\"Failed test rte_bbdev_allocate: \"\n+\t\t\t\"invalid dev_id %\" PRIu8 \", max number of devices %d \",\n+\t\t\tdev1->data->dev_id, RTE_BBDEV_MAX_DEVS);\n+\n+\tTEST_ASSERT(dev1->attached == true, \"Failed test rte_bbdev_allocate:\"\n+\t\t\t\" invalid attached value %d \", dev1->attached);\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_release(NULL),\n+\t\t\t\"Failed to uninitialize bbdev driver with NULL bbdev\");\n+\n+\tsprintf(name_tmp, \"%s\", \"invalid_name\");\n+\tdev2 = rte_bbdev_get_named_dev(name_tmp);\n+\tTEST_ASSERT_FAIL(rte_bbdev_release(dev2),\n+\t\t\t\"Failed to uninitialize bbdev driver with invalid name\");\n+\n+\tdev2 = rte_bbdev_get_named_dev(name);\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_release(dev2),\n+\t\t\t\"Failed to uninitialize bbdev driver: %s \", name);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static void\n+event_callback(uint16_t dev_id, enum rte_bbdev_event_type type, void *param,\n+\t\tvoid *ret_param)\n+{\n+\tRTE_SET_USED(dev_id);\n+\tRTE_SET_USED(ret_param);\n+\n+\tif (param == NULL)\n+\t\treturn;\n+\n+\tif (type == RTE_BBDEV_EVENT_UNKNOWN ||\n+\t\t\ttype == RTE_BBDEV_EVENT_ERROR ||\n+\t\t\ttype == RTE_BBDEV_EVENT_MAX)\n+\t\t*(int *)param = type;\n+}\n+\n+static int\n+test_bbdev_callback(void)\n+{\n+\tstruct rte_bbdev *dev1, *dev2;\n+\tconst char *name = \"dev_name1\";\n+\tconst char *name2 = \"dev_name2\";\n+\tint event_status;\n+\tuint8_t invalid_dev_id = 7;\n+\tenum rte_bbdev_event_type invalid_event_type = RTE_BBDEV_EVENT_MAX;\n+\tuint8_t dev_id;\n+\n+\tdev1 = rte_bbdev_allocate(name);\n+\tTEST_ASSERT(dev1 != NULL, \"Failed to initialize bbdev driver\");\n+\n+\t/*\n+\t * RTE_BBDEV_EVENT_UNKNOWN - unregistered\n+\t * RTE_BBDEV_EVENT_ERROR - unregistered\n+\t */\n+\tevent_status = -1;\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_ERROR, NULL);\n+\tTEST_ASSERT(event_status == -1,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process: \"\n+\t\t\t\"events were not registered \");\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_callback_register(dev1->data->dev_id,\n+\t\t\tRTE_BBDEV_EVENT_MAX, event_callback, NULL),\n+\t\t\t\"Failed to callback register for RTE_BBDEV_EVENT_MAX \");\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_callback_unregister(dev1->data->dev_id,\n+\t\t\tRTE_BBDEV_EVENT_MAX, event_callback, NULL),\n+\t\t\t\"Failed to unregister RTE_BBDEV_EVENT_MAX \");\n+\n+\t/*\n+\t * RTE_BBDEV_EVENT_UNKNOWN - registered\n+\t * RTE_BBDEV_EVENT_ERROR - unregistered\n+\t */\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_callback_register(dev1->data->dev_id,\n+\t\t\tRTE_BBDEV_EVENT_UNKNOWN, event_callback, &event_status),\n+\t\t\t\"Failed to callback rgstr for RTE_BBDEV_EVENT_UNKNOWN\");\n+\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\tTEST_ASSERT(event_status == 0,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process \"\n+\t\t\t\"for RTE_BBDEV_EVENT_UNKNOWN \");\n+\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_ERROR, NULL);\n+\tTEST_ASSERT(event_status == 0,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process: \"\n+\t\t\t\"event RTE_BBDEV_EVENT_ERROR was not registered \");\n+\n+\t/*\n+\t * RTE_BBDEV_EVENT_UNKNOWN - registered\n+\t * RTE_BBDEV_EVENT_ERROR - registered\n+\t */\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_callback_register(dev1->data->dev_id,\n+\t\t\tRTE_BBDEV_EVENT_ERROR, event_callback, &event_status),\n+\t\t\t\"Failed to callback rgstr for RTE_BBDEV_EVENT_ERROR \");\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_callback_register(dev1->data->dev_id,\n+\t\t\tRTE_BBDEV_EVENT_ERROR, event_callback, &event_status),\n+\t\t\t\"Failed to callback register for RTE_BBDEV_EVENT_ERROR\"\n+\t\t\t\"(re-registration) \");\n+\n+\tevent_status = -1;\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\tTEST_ASSERT(event_status == 0,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process \"\n+\t\t\t\"for RTE_BBDEV_EVENT_UNKNOWN \");\n+\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_ERROR, NULL);\n+\tTEST_ASSERT(event_status == 1,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process \"\n+\t\t\t\"for RTE_BBDEV_EVENT_ERROR \");\n+\n+\t/*\n+\t * RTE_BBDEV_EVENT_UNKNOWN - registered\n+\t * RTE_BBDEV_EVENT_ERROR - unregistered\n+\t */\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_callback_unregister(dev1->data->dev_id,\n+\t\t\tRTE_BBDEV_EVENT_ERROR, event_callback, &event_status),\n+\t\t\t\"Failed to unregister RTE_BBDEV_EVENT_ERROR \");\n+\n+\tevent_status = -1;\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\tTEST_ASSERT(event_status == 0,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process \"\n+\t\t\t\"for RTE_BBDEV_EVENT_UNKNOWN \");\n+\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_ERROR, NULL);\n+\tTEST_ASSERT(event_status == 0,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process: \"\n+\t\t\t\"event RTE_BBDEV_EVENT_ERROR was unregistered \");\n+\n+\t/* rte_bbdev_callback_register with invalid inputs */\n+\tTEST_ASSERT_FAIL(rte_bbdev_callback_register(invalid_dev_id,\n+\t\t\tRTE_BBDEV_EVENT_ERROR, event_callback, &event_status),\n+\t\t\t\"Failed test for rte_bbdev_callback_register \"\n+\t\t\t\"for invalid_dev_id \");\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_callback_register(dev1->data->dev_id,\n+\t\t\tinvalid_event_type, event_callback, &event_status),\n+\t\t\t\"Failed to callback register for invalid event type \");\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_callback_register(dev1->data->dev_id,\n+\t\t\tRTE_BBDEV_EVENT_ERROR, NULL, &event_status),\n+\t\t\t\"Failed to callback register - no callback function \");\n+\n+\t/* The impact of devices on each other */\n+\tdev2 = rte_bbdev_allocate(name2);\n+\tTEST_ASSERT(dev2 != NULL,\n+\t\t\t\"Failed to initialize bbdev driver\");\n+\n+\t/*\n+\t * dev2:\n+\t * RTE_BBDEV_EVENT_UNKNOWN - unregistered\n+\t * RTE_BBDEV_EVENT_ERROR - unregistered\n+\t */\n+\tevent_status = -1;\n+\trte_bbdev_pmd_callback_process(dev2, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\trte_bbdev_pmd_callback_process(dev2, RTE_BBDEV_EVENT_ERROR, NULL);\n+\tTEST_ASSERT(event_status == -1,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process: \"\n+\t\t\t\"events were not registered \");\n+\n+\t/*\n+\t * dev1: RTE_BBDEV_EVENT_ERROR - unregistered\n+\t * dev2: RTE_BBDEV_EVENT_ERROR - registered\n+\t */\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_callback_register(dev2->data->dev_id,\n+\t\t\tRTE_BBDEV_EVENT_ERROR, event_callback, &event_status),\n+\t\t\t\"Failed to callback rgstr for RTE_BBDEV_EVENT_ERROR\");\n+\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_ERROR, NULL);\n+\tTEST_ASSERT(event_status == -1,\n+\t\t\"Failed test for rte_bbdev_pmd_callback_process in dev1 \"\n+\t\t\"for RTE_BBDEV_EVENT_ERROR \");\n+\n+\trte_bbdev_pmd_callback_process(dev2, RTE_BBDEV_EVENT_ERROR, NULL);\n+\tTEST_ASSERT(event_status == 1,\n+\t\t\"Failed test for rte_bbdev_pmd_callback_process in dev2 \"\n+\t\t\"for RTE_BBDEV_EVENT_ERROR \");\n+\n+\t/*\n+\t * dev1: RTE_BBDEV_EVENT_UNKNOWN - registered\n+\t * dev2: RTE_BBDEV_EVENT_UNKNOWN - unregistered\n+\t */\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_callback_register(dev2->data->dev_id,\n+\t\t\tRTE_BBDEV_EVENT_UNKNOWN, event_callback, &event_status),\n+\t\t\t\"Failed to callback register for RTE_BBDEV_EVENT_UNKNOWN \"\n+\t\t\t\"in dev 2 \");\n+\n+\trte_bbdev_pmd_callback_process(dev2, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\tTEST_ASSERT(event_status == 0,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process in dev2\"\n+\t\t\t\" for RTE_BBDEV_EVENT_UNKNOWN \");\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_callback_unregister(dev2->data->dev_id,\n+\t\t\tRTE_BBDEV_EVENT_UNKNOWN, event_callback, &event_status),\n+\t\t\t\"Failed to unregister RTE_BBDEV_EVENT_UNKNOWN \");\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_callback_unregister(dev2->data->dev_id,\n+\t\t\tRTE_BBDEV_EVENT_UNKNOWN, event_callback, &event_status),\n+\t\t\t\"Failed to unregister RTE_BBDEV_EVENT_UNKNOWN : \"\n+\t\t\t\"unregister function called once again \");\n+\n+\tevent_status = -1;\n+\trte_bbdev_pmd_callback_process(dev2, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\tTEST_ASSERT(event_status == -1,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process in dev2\"\n+\t\t\" for RTE_BBDEV_EVENT_UNKNOWN \");\n+\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\tTEST_ASSERT(event_status == 0,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process in dev2 \"\n+\t\t\t\"for RTE_BBDEV_EVENT_UNKNOWN \");\n+\n+\t/* rte_bbdev_pmd_callback_process with invalid inputs */\n+\trte_bbdev_pmd_callback_process(NULL, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\n+\tevent_status = -1;\n+\trte_bbdev_pmd_callback_process(dev1, invalid_event_type, NULL);\n+\tTEST_ASSERT(event_status == -1,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process: \"\n+\t\t\t\"for invalid event type \");\n+\n+\t/* rte_dev_callback_unregister with invalid inputs */\n+\tTEST_ASSERT_FAIL(rte_bbdev_callback_unregister(invalid_dev_id,\n+\t\t\tRTE_BBDEV_EVENT_UNKNOWN, event_callback, &event_status),\n+\t\t\t\"Failed test for rte_dev_callback_unregister \"\n+\t\t\t\"for invalid_dev_id \");\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_callback_unregister(dev1->data->dev_id,\n+\t\t\tinvalid_event_type, event_callback, &event_status),\n+\t\t\t\"Failed rte_dev_callback_unregister \"\n+\t\t\t\"for invalid event type \");\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_callback_unregister(dev1->data->dev_id,\n+\t\t\tinvalid_event_type, NULL, &event_status),\n+\t\t\t\"Failed rte_dev_callback_unregister \"\n+\t\t\t\"when no callback function \");\n+\n+\tdev_id = dev1->data->dev_id;\n+\n+\trte_bbdev_release(dev1);\n+\trte_bbdev_release(dev2);\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_callback_register(dev_id,\n+\t\t\tRTE_BBDEV_EVENT_ERROR, event_callback, &event_status),\n+\t\t\t\"Failed test for rte_bbdev_callback_register: \"\n+\t\t\t\"function called after rte_bbdev_driver_uninit .\");\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_callback_unregister(dev_id,\n+\t\t\tRTE_BBDEV_EVENT_ERROR, event_callback, &event_status),\n+\t\t\t\"Failed test for rte_dev_callback_unregister: \"\n+\t\t\t\"function called after rte_bbdev_driver_uninit. \");\n+\n+\tevent_status = -1;\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\trte_bbdev_pmd_callback_process(dev1, RTE_BBDEV_EVENT_ERROR, NULL);\n+\trte_bbdev_pmd_callback_process(dev2, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\trte_bbdev_pmd_callback_process(dev2, RTE_BBDEV_EVENT_ERROR, NULL);\n+\tTEST_ASSERT(event_status == -1,\n+\t\t\t\"Failed test for rte_bbdev_pmd_callback_process: \"\n+\t\t\t\"callback function was called after rte_bbdev_driver_uninit\");\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_bbdev_invalid_driver(void)\n+{\n+\tstruct rte_bbdev dev1, *dev2;\n+\tuint8_t dev_id = null_dev_id;\n+\tuint16_t queue_id = 0;\n+\tstruct rte_bbdev_stats stats;\n+\tstruct bbdev_testsuite_params *ts_params = &testsuite_params;\n+\tstruct rte_bbdev_queue_info qinfo;\n+\tstruct rte_bbdev_ops dev_ops_tmp;\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stop(dev_id), \"Failed to stop bbdev %u \",\n+\t\t\tdev_id);\n+\n+\tdev1 = rte_bbdev_devices[dev_id];\n+\tdev2 = &rte_bbdev_devices[dev_id];\n+\n+\t/* Tests for rte_bbdev_configure */\n+\tdev2->dev_ops = NULL;\n+\tTEST_ASSERT_FAIL(rte_bbdev_configure(dev_id, 1, NULL),\n+\t\t\t\"Failed test for rte_bbdev_configure: \"\n+\t\t\t\"NULL dev_ops structure \");\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tdev_ops_tmp = *dev2->dev_ops;\n+\tdev_ops_tmp.info_get = NULL;\n+\tdev2->dev_ops = &dev_ops_tmp;\n+\tTEST_ASSERT_FAIL(rte_bbdev_configure(dev_id, 1, NULL),\n+\t\t\t\"Failed test for rte_bbdev_configure: \"\n+\t\t\t\"NULL info_get \");\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tdev_ops_tmp = *dev2->dev_ops;\n+\tdev_ops_tmp.queue_release = NULL;\n+\tdev2->dev_ops = &dev_ops_tmp;\n+\tTEST_ASSERT_FAIL(rte_bbdev_configure(dev_id, 1, NULL),\n+\t\t\t\"Failed test for rte_bbdev_configure: \"\n+\t\t\t\"NULL queue_release \");\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tdev2->data->socket_id = SOCKET_ID_ANY;\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_configure(dev_id, 1, NULL),\n+\t\t\t\"Failed to configure bbdev %u\", dev_id);\n+\n+\t/* Test for rte_bbdev_queue_configure */\n+\tdev2->dev_ops = NULL;\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed to configure queue %u on device %u \"\n+\t\t\t\"with NULL dev_ops structure \", queue_id, dev_id);\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tdev_ops_tmp = *dev2->dev_ops;\n+\tdev_ops_tmp.queue_setup = NULL;\n+\tdev2->dev_ops = &dev_ops_tmp;\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed to configure queue %u on device %u \"\n+\t\t\t\"with NULL queue_setup \", queue_id, dev_id);\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tdev_ops_tmp = *dev2->dev_ops;\n+\tdev_ops_tmp.info_get = NULL;\n+\tdev2->dev_ops = &dev_ops_tmp;\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed to configure queue %u on device %u \"\n+\t\t\t\"with NULL info_get \", queue_id, dev_id);\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_configure(RTE_BBDEV_MAX_DEVS,\n+\t\t\tqueue_id, &ts_params->qconf),\n+\t\t\t\"Failed to configure queue %u on device %u \",\n+\t\t\tqueue_id, dev_id);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_configure(dev_id, queue_id,\n+\t\t\t&ts_params->qconf),\n+\t\t\t\"Failed to configure queue %u on device %u \",\n+\t\t\tqueue_id, dev_id);\n+\n+\t/* Test for rte_bbdev_queue_info_get */\n+\tdev2->dev_ops = NULL;\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_info_get(dev_id, queue_id, &qinfo),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"NULL dev_ops structure  \");\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_info_get(RTE_BBDEV_MAX_DEVS,\n+\t\t\tqueue_id, &qinfo),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid dev_id \");\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_info_get(dev_id,\n+\t\t\tRTE_MAX_QUEUES_PER_PORT, &qinfo),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid queue_id \");\n+\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_info_get(dev_id, queue_id, NULL),\n+\t\t\t\"Failed test for rte_bbdev_info_get: \"\n+\t\t\t\"invalid dev_info \");\n+\n+\t/* Test for rte_bbdev_start */\n+\tdev2->dev_ops = NULL;\n+\tTEST_ASSERT_FAIL(rte_bbdev_start(dev_id),\n+\t\t\t\"Failed to start bbdev %u \"\n+\t\t\t\"with NULL dev_ops structure \", dev_id);\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_start(dev_id),\n+\t\t\t\"Failed to start bbdev %u \", dev_id);\n+\n+\t/* Test for rte_bbdev_queue_start */\n+\tdev2->dev_ops = NULL;\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_start(dev_id, queue_id),\n+\t\t\t\"Failed to start queue %u on device %u: \"\n+\t\t\t\"NULL dev_ops structure\", queue_id, dev_id);\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_start(dev_id, queue_id),\n+\t\t\t\"Failed to start queue %u on device %u \", queue_id,\n+\t\t\tdev_id);\n+\n+\t/* Tests for rte_bbdev_stats_get */\n+\tdev2->dev_ops = NULL;\n+\tTEST_ASSERT_FAIL(rte_bbdev_stats_get(dev_id, &stats),\n+\t\t\t\"Failed test for rte_bbdev_stats_get on device %u \",\n+\t\t\tdev_id);\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tdev_ops_tmp = *dev2->dev_ops;\n+\tdev_ops_tmp.stats_reset = NULL;\n+\tdev2->dev_ops = &dev_ops_tmp;\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stats_get(dev_id, &stats),\n+\t\t\t\"Failed test for rte_bbdev_stats_get: \"\n+\t\t\t\"NULL stats_get \");\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stats_get(dev_id, &stats),\n+\t\t\t\"Failed test for rte_bbdev_stats_get on device %u \",\n+\t\t\tdev_id);\n+\n+\t/*\n+\t * Tests for:\n+\t * rte_bbdev_callback_register,\n+\t * rte_bbdev_pmd_callback_process,\n+\t * rte_dev_callback_unregister\n+\t */\n+\tdev2->dev_ops = NULL;\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_callback_register(dev_id,\n+\t\t\tRTE_BBDEV_EVENT_UNKNOWN, event_callback, NULL),\n+\t\t\t\"Failed to callback rgstr for RTE_BBDEV_EVENT_UNKNOWN\");\n+\trte_bbdev_pmd_callback_process(dev2, RTE_BBDEV_EVENT_UNKNOWN, NULL);\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_callback_unregister(dev_id,\n+\t\t\tRTE_BBDEV_EVENT_UNKNOWN, event_callback, NULL),\n+\t\t\t\"Failed to unregister RTE_BBDEV_EVENT_ERROR \");\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\t/* Tests for rte_bbdev_stats_reset */\n+\tdev2->dev_ops = NULL;\n+\tTEST_ASSERT_FAIL(rte_bbdev_stats_reset(dev_id),\n+\t\t\t\"Failed to reset statistic for device %u \", dev_id);\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tdev_ops_tmp = *dev2->dev_ops;\n+\tdev_ops_tmp.stats_reset = NULL;\n+\tdev2->dev_ops = &dev_ops_tmp;\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stats_reset(dev_id),\n+\t\t\t\"Failed test for rte_bbdev_stats_reset: \"\n+\t\t\t\"NULL stats_reset \");\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stats_reset(dev_id),\n+\t\t\t\"Failed to reset statistic for device %u \", dev_id);\n+\n+\t/* Tests for rte_bbdev_queue_stop */\n+\tdev2->dev_ops = NULL;\n+\tTEST_ASSERT_FAIL(rte_bbdev_queue_stop(dev_id, queue_id),\n+\t\t\t\"Failed to stop queue %u on device %u: \"\n+\t\t\t\"NULL dev_ops structure\", queue_id, dev_id);\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_stop(dev_id, queue_id),\n+\t\t\t\"Failed to stop queue %u on device %u \", queue_id,\n+\t\t\tdev_id);\n+\n+\t/* Tests for rte_bbdev_stop */\n+\tdev2->dev_ops = NULL;\n+\tTEST_ASSERT_FAIL(rte_bbdev_stop(dev_id),\n+\t\t\t\"Failed to stop bbdev %u with NULL dev_ops structure \",\n+\t\t\tdev_id);\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_stop(dev_id),\n+\t\t\t\"Failed to stop bbdev %u \", dev_id);\n+\n+\t/* Tests for rte_bbdev_close */\n+\tTEST_ASSERT_FAIL(rte_bbdev_close(RTE_BBDEV_MAX_DEVS),\n+\t\t\t\"Failed to close bbdev with invalid dev_id\");\n+\n+\tdev2->dev_ops = NULL;\n+\tTEST_ASSERT_FAIL(rte_bbdev_close(dev_id),\n+\t\t\t\"Failed to close bbdev %u with NULL dev_ops structure \",\n+\t\t\tdev_id);\n+\tdev2->dev_ops = dev1.dev_ops;\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_close(dev_id),\n+\t\t\t\"Failed to close bbdev %u \", dev_id);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_bbdev_get_named_dev(void)\n+{\n+\tstruct rte_bbdev *dev, *dev_tmp;\n+\tconst char *name = \"name\";\n+\n+\tdev = rte_bbdev_allocate(name);\n+\tTEST_ASSERT(dev != NULL, \"Failed to initialize bbdev driver\");\n+\n+\tdev_tmp = rte_bbdev_get_named_dev(NULL);\n+\tTEST_ASSERT(dev_tmp == NULL, \"Failed test for rte_bbdev_get_named_dev: \"\n+\t\t\t\"function called with NULL parameter\");\n+\n+\tdev_tmp = rte_bbdev_get_named_dev(name);\n+\n+\tTEST_ASSERT(dev == dev_tmp, \"Failed test for rte_bbdev_get_named_dev: \"\n+\t\t\t\"wrong device was returned \");\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_release(dev),\n+\t\t\t\"Failed to uninitialize bbdev driver %s \", name);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static struct unit_test_suite bbdev_null_testsuite = {\n+\t.suite_name = \"BBDEV NULL Unit Test Suite\",\n+\t.setup = testsuite_setup,\n+\t.teardown = testsuite_teardown,\n+\t.unit_test_cases = {\n+\n+\t\tTEST_CASE(test_bbdev_configure_invalid_dev_id),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_configure_invalid_num_queues),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_configure_stop_device),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_configure_stop_queue),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_configure_invalid_queue_configure),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_op_pool),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_op_type),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_op_pool_size),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_stats),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_driver_init),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_callback),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_invalid_driver),\n+\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown,\n+\t\t\t\ttest_bbdev_get_named_dev),\n+\n+\t\tTEST_CASE(test_bbdev_count),\n+\n+\t\tTEST_CASES_END() /**< NULL terminate unit test array */\n+\t}\n+};\n+\n+REGISTER_TEST_COMMAND(unittest, bbdev_null_testsuite);\ndiff --git a/app/test-bbdev/test_bbdev_perf.c b/app/test-bbdev/test_bbdev_perf.c\nnew file mode 100644\nindex 0000000..e1ca3af\n--- /dev/null\n+++ b/app/test-bbdev/test_bbdev_perf.c\n@@ -0,0 +1,1700 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 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 <stdio.h>\n+#include <inttypes.h>\n+\n+#include <rte_eal.h>\n+#include <rte_common.h>\n+#include <rte_dev.h>\n+#include <rte_launch.h>\n+#include <rte_bbdev.h>\n+#include <rte_cycles.h>\n+#include <rte_lcore.h>\n+#include <rte_malloc.h>\n+#include <rte_random.h>\n+#include <rte_hexdump.h>\n+\n+#include \"main.h\"\n+#include \"test_bbdev_vector.h\"\n+\n+#define GET_SOCKET(socket_id) (((socket_id) == SOCKET_ID_ANY) ? 0 : (socket_id))\n+\n+#define MAX_QUEUES RTE_MAX_LCORE\n+\n+#define OPS_CACHE_SIZE 256U\n+#define OPS_POOL_SIZE_MIN 511U /* 0.5K per queue */\n+\n+#define SYNC_WAIT 0\n+#define SYNC_START 1\n+\n+#define INVALID_QUEUE_ID -1\n+\n+static struct test_bbdev_vector test_vector;\n+\n+/* Switch between PMD and Interrupt for throughput TC */\n+static bool intr_enabled;\n+\n+/* Represents tested active devices */\n+static struct active_device {\n+\tconst char *driver_name;\n+\tuint8_t dev_id;\n+\tuint16_t supported_ops;\n+\tuint16_t queue_ids[MAX_QUEUES];\n+\tuint16_t nb_queues;\n+\tstruct rte_mempool *ops_mempool;\n+\tstruct rte_mempool *in_mbuf_pool;\n+\tstruct rte_mempool *hard_out_mbuf_pool;\n+\tstruct rte_mempool *soft_out_mbuf_pool;\n+} active_devs[RTE_BBDEV_MAX_DEVS];\n+\n+static uint8_t nb_active_devs;\n+\n+/* Data buffers used by BBDEV ops */\n+struct test_buffers {\n+\tstruct rte_bbdev_op_data *inputs;\n+\tstruct rte_bbdev_op_data *hard_outputs;\n+\tstruct rte_bbdev_op_data *soft_outputs;\n+};\n+\n+/* Operation parameters specific for given test case */\n+struct test_op_params {\n+\tstruct rte_mempool *mp;\n+\tstruct rte_bbdev_op *ref_op;\n+\tuint16_t burst_sz;\n+\tuint16_t num_to_process;\n+\tint vector_mask;\n+\trte_atomic16_t sync;\n+\tstruct test_buffers q_bufs[RTE_MAX_NUMA_NODES][MAX_QUEUES];\n+};\n+\n+/* Contains per lcore params */\n+struct thread_params {\n+\tuint8_t dev_id;\n+\tuint16_t queue_id;\n+\tuint64_t start_time;\n+\trte_atomic16_t nb_dequeued;\n+\trte_atomic16_t processing_status;\n+\tstruct test_op_params *op_params;\n+};\n+\n+typedef int (test_case_function)(struct active_device *ad,\n+\t\tstruct test_op_params *op_params);\n+\n+static inline void\n+set_avail_op(struct active_device *ad, enum rte_bbdev_op_type op_type)\n+{\n+\tad->supported_ops |= (1 << op_type);\n+}\n+\n+static inline bool\n+is_avail_op(struct active_device *ad, enum rte_bbdev_op_type op_type)\n+{\n+\treturn ad->supported_ops & (1 << op_type);\n+}\n+\n+/* calculates optimal mempool size not smaller than the val */\n+static unsigned int\n+optimal_mempool_size(unsigned int val)\n+{\n+\treturn rte_align32pow2(val + 1) - 1;\n+}\n+\n+/* allocates mbuf mempool for inputs and outputs */\n+static struct rte_mempool *\n+create_mbuf_pool(struct op_data_entries *entries, uint8_t dev_id,\n+\t\tint socket_id, unsigned int mbuf_pool_size,\n+\t\tconst char *op_type_str)\n+{\n+\tunsigned int i;\n+\tuint32_t max_seg_sz = 0;\n+\tchar pool_name[RTE_MEMPOOL_NAMESIZE];\n+\n+\t/* find max input segment size */\n+\tfor (i = 0; i < entries->nb_segments; ++i)\n+\t\tif (entries->segments[i].length > max_seg_sz)\n+\t\t\tmax_seg_sz = entries->segments[i].length;\n+\n+\tsnprintf(pool_name, sizeof(pool_name), \"%s_pool_%u\", op_type_str,\n+\t\t\tdev_id);\n+\treturn rte_pktmbuf_pool_create(pool_name, mbuf_pool_size, 0, 0,\n+\t\t\tRTE_MAX(max_seg_sz + RTE_PKTMBUF_HEADROOM,\n+\t\t\t(unsigned)RTE_MBUF_DEFAULT_BUF_SIZE), socket_id);\n+}\n+\n+static int\n+create_mempools(struct active_device *ad, int socket_id,\n+\t\tenum rte_bbdev_op_type op_type, uint16_t num_ops)\n+{\n+\tstruct rte_mempool *mp;\n+\tunsigned int ops_pool_size, mbuf_pool_size = 0;\n+\tchar pool_name[RTE_MEMPOOL_NAMESIZE];\n+\n+\tstruct op_data_entries *in = &test_vector.entries[DATA_INPUT];\n+\tstruct op_data_entries *hard_out =\n+\t\t\t&test_vector.entries[DATA_HARD_OUTPUT];\n+\tstruct op_data_entries *soft_out =\n+\t\t\t&test_vector.entries[DATA_SOFT_OUTPUT];\n+\n+\t/* allocate ops mempool */\n+\tops_pool_size = optimal_mempool_size(RTE_MAX(\n+\t\t\t/* Ops used plus 1 reference op */\n+\t\t\tRTE_MAX((unsigned)(ad->nb_queues * num_ops + 1),\n+\t\t\t/* Minimal cache size plus 1 reference op */\n+\t\t\t(unsigned)(1.5 * rte_lcore_count() * OPS_CACHE_SIZE + 1)),\n+\t\t\tOPS_POOL_SIZE_MIN));\n+\tsnprintf(pool_name, sizeof(pool_name), \"%s_pool_%u\",\n+\t\t\trte_bbdev_op_type_str(op_type), ad->dev_id);\n+\tmp = rte_bbdev_op_pool_create(pool_name, op_type,\n+\t\t\tops_pool_size, OPS_CACHE_SIZE, socket_id);\n+\tTEST_ASSERT_NOT_NULL(mp,\n+\t\t\t\"ERROR Failed to create %u items ops pool for dev %u on socket %u.\",\n+\t\t\tops_pool_size,\n+\t\t\tad->dev_id,\n+\t\t\tsocket_id);\n+\tad->ops_mempool = mp;\n+\n+\t/* Inputs */\n+\tmbuf_pool_size = optimal_mempool_size(ops_pool_size * in->nb_segments);\n+\tmp = create_mbuf_pool(in, ad->dev_id, socket_id, mbuf_pool_size, \"in\");\n+\tTEST_ASSERT_NOT_NULL(mp,\n+\t\t\t\"ERROR Failed to create %u items input pktmbuf pool for dev %u on socket %u.\",\n+\t\t\tmbuf_pool_size,\n+\t\t\tad->dev_id,\n+\t\t\tsocket_id);\n+\tad->in_mbuf_pool = mp;\n+\n+\t/* Hard outputs */\n+\tmbuf_pool_size = optimal_mempool_size(ops_pool_size *\n+\t\t\thard_out->nb_segments);\n+\tmp = create_mbuf_pool(hard_out, ad->dev_id, socket_id, mbuf_pool_size,\n+\t\t\t\"hard_out\");\n+\tTEST_ASSERT_NOT_NULL(mp,\n+\t\t\t\"ERROR Failed to create %u items hard output pktmbuf pool for dev %u on socket %u.\",\n+\t\t\tmbuf_pool_size,\n+\t\t\tad->dev_id,\n+\t\t\tsocket_id);\n+\tad->hard_out_mbuf_pool = mp;\n+\n+\tif (soft_out->nb_segments == 0)\n+\t\treturn TEST_SUCCESS;\n+\n+\t/* Soft outputs */\n+\tmbuf_pool_size = optimal_mempool_size(ops_pool_size *\n+\t\t\tsoft_out->nb_segments);\n+\tmp = create_mbuf_pool(soft_out, ad->dev_id, socket_id, mbuf_pool_size,\n+\t\t\t\"soft_out\");\n+\tTEST_ASSERT_NOT_NULL(mp,\n+\t\t\t\"ERROR Failed to create %uB soft output pktmbuf pool for dev %u on socket %u.\",\n+\t\t\tmbuf_pool_size,\n+\t\t\tad->dev_id,\n+\t\t\tsocket_id);\n+\tad->soft_out_mbuf_pool = mp;\n+\n+\treturn 0;\n+}\n+\n+static int\n+add_bbdev_dev(uint8_t dev_id, struct rte_bbdev_info *info,\n+\t\tstruct test_bbdev_vector *vector)\n+{\n+\tint ret;\n+\tunsigned int queue_id;\n+\tstruct rte_bbdev_queue_conf qconf;\n+\tstruct active_device *ad = &active_devs[nb_active_devs];\n+\tunsigned int nb_queues;\n+\tenum rte_bbdev_op_type op_type = vector->op_type;\n+\n+\tnb_queues = RTE_MIN(rte_lcore_count(), info->drv.max_num_queues);\n+\t/* setup device */\n+\tret = rte_bbdev_configure(dev_id, nb_queues, NULL);\n+\tif (ret < 0) {\n+\t\tprintf(\"rte_bbdev_configure(%u, %u, NULL) ret %i\\n\",\n+\t\t\t\tdev_id, nb_queues, ret);\n+\t\treturn TEST_FAILED;\n+\t}\n+\n+\t/* setup device queues */\n+\tqconf.socket = info->socket_id;\n+\tqconf.queue_size = info->drv.default_queue_conf.queue_size;\n+\tqconf.priority = 0;\n+\tqconf.deferred_start = 0;\n+\tqconf.op_type = op_type;\n+\n+\tfor (queue_id = 0; queue_id < nb_queues; ++queue_id) {\n+\t\tret = rte_bbdev_queue_configure(dev_id, queue_id, &qconf);\n+\t\tif (ret != 0) {\n+\t\t\tprintf(\n+\t\t\t\t\t\"Allocated all queues (id=%u) at prio%u on dev%u\\n\",\n+\t\t\t\t\tqueue_id, qconf.priority, dev_id);\n+\t\t\tqconf.priority++;\n+\t\t\tret = rte_bbdev_queue_configure(ad->dev_id, queue_id,\n+\t\t\t\t\t&qconf);\n+\t\t}\n+\t\tif (ret != 0) {\n+\t\t\tprintf(\"All queues on dev %u allocated: %u\\n\",\n+\t\t\t\t\tdev_id, queue_id);\n+\t\t\tbreak;\n+\t\t}\n+\t\tad->queue_ids[queue_id] = queue_id;\n+\t}\n+\tTEST_ASSERT(queue_id != 0,\n+\t\t\t\"ERROR Failed to configure any queues on dev %u\",\n+\t\t\tdev_id);\n+\tad->nb_queues = queue_id;\n+\n+\tset_avail_op(ad, op_type);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+add_active_device(uint8_t dev_id, struct rte_bbdev_info *info,\n+\t\tstruct test_bbdev_vector *vector)\n+{\n+\tint ret;\n+\n+\tactive_devs[nb_active_devs].driver_name = info->drv.driver_name;\n+\tactive_devs[nb_active_devs].dev_id = dev_id;\n+\n+\tret = add_bbdev_dev(dev_id, info, vector);\n+\tif (ret == TEST_SUCCESS)\n+\t\t++nb_active_devs;\n+\treturn ret;\n+}\n+\n+static inline bool\n+flags_match(uint32_t flags_req, uint32_t flags_present)\n+{\n+\treturn (flags_req & flags_present) == flags_req;\n+}\n+\n+static int\n+check_dev_cap(const struct rte_bbdev_info *dev_info)\n+{\n+\tunsigned int i;\n+\tunsigned int nb_inputs, nb_soft_outputs, nb_hard_outputs;\n+\tconst struct rte_bbdev_op_cap *op_cap = dev_info->drv.capabilities;\n+\n+\tnb_inputs = test_vector.entries[DATA_INPUT].nb_segments;\n+\tnb_soft_outputs = test_vector.entries[DATA_SOFT_OUTPUT].nb_segments;\n+\tnb_hard_outputs = test_vector.entries[DATA_HARD_OUTPUT].nb_segments;\n+\n+\tfor (i = 0; op_cap->type != RTE_BBDEV_OP_NONE; ++i, ++op_cap) {\n+\t\tif (op_cap->type != test_vector.op_type)\n+\t\t\tcontinue;\n+\n+\t\tif (op_cap->type == RTE_BBDEV_OP_TURBO_DEC) {\n+\t\t\tconst struct rte_bbdev_op_cap_turbo_dec *cap =\n+\t\t\t\t\t&op_cap->cap.turbo_dec;\n+\t\t\t/* Ignore lack of soft output capability, just skip\n+\t\t\t * checking if soft output is valid.\n+\t\t\t */\n+\t\t\tif ((test_vector.turbo_dec.op_flags &\n+\t\t\t\t\tRTE_BBDEV_TURBO_SOFT_OUTPUT) &&\n+\t\t\t\t\t!(cap->capability_flags &\n+\t\t\t\t\tRTE_BBDEV_TURBO_SOFT_OUTPUT)) {\n+\t\t\t\tprintf(\n+\t\t\t\t\t\"WARNING: Device \\\"%s\\\" does not support soft output, RTE_BBDEV_TURBO_SOFT_OUTPUT flag will be ignored.\\n\",\n+\t\t\t\t\tdev_info->dev_name);\n+\t\t\t\ttest_vector.turbo_dec.op_flags &=\n+\t\t\t\t\t\t~RTE_BBDEV_TURBO_SOFT_OUTPUT;\n+\t\t\t}\n+\n+\t\t\tif (!flags_match(test_vector.turbo_dec.op_flags,\n+\t\t\t\t\tcap->capability_flags))\n+\t\t\t\treturn TEST_FAILED;\n+\t\t\tif (nb_inputs > cap->num_buffers_src) {\n+\t\t\t\tprintf(\"Too many inputs defined: %u, max: %u\\n\",\n+\t\t\t\t\tnb_inputs, cap->num_buffers_src);\n+\t\t\t\treturn TEST_FAILED;\n+\t\t\t}\n+\t\t\tif (nb_soft_outputs > cap->num_buffers_soft_out &&\n+\t\t\t\t\t(test_vector.turbo_dec.op_flags &\n+\t\t\t\t\tRTE_BBDEV_TURBO_SOFT_OUTPUT)) {\n+\t\t\t\tprintf(\n+\t\t\t\t\t\"Too many soft outputs defined: %u, max: %u\\n\",\n+\t\t\t\t\t\tnb_soft_outputs,\n+\t\t\t\t\t\tcap->num_buffers_soft_out);\n+\t\t\t\treturn TEST_FAILED;\n+\t\t\t}\n+\t\t\tif (nb_hard_outputs > cap->num_buffers_hard_out) {\n+\t\t\t\tprintf(\n+\t\t\t\t\t\"Too many hard outputs defined: %u, max: %u\\n\",\n+\t\t\t\t\t\tnb_hard_outputs,\n+\t\t\t\t\t\tcap->num_buffers_hard_out);\n+\t\t\t\treturn TEST_FAILED;\n+\t\t\t}\n+\t\t\tif (intr_enabled && !(cap->capability_flags &\n+\t\t\t\t\tRTE_BBDEV_TURBO_DEC_INTERRUPTS)) {\n+\t\t\t\tprintf(\n+\t\t\t\t\t\"Dequeue interrupts are not supported!\\n\");\n+\t\t\t\treturn TEST_FAILED;\n+\t\t\t}\n+\n+\t\t\treturn TEST_SUCCESS;\n+\t\t} else if (op_cap->type == RTE_BBDEV_OP_TURBO_ENC) {\n+\t\t\tconst struct rte_bbdev_op_cap_turbo_enc *cap =\n+\t\t\t\t\t&op_cap->cap.turbo_enc;\n+\n+\t\t\tif (!flags_match(test_vector.turbo_enc.op_flags,\n+\t\t\t\t\tcap->capability_flags))\n+\t\t\t\treturn TEST_FAILED;\n+\t\t\tif (nb_inputs > cap->num_buffers_src) {\n+\t\t\t\tprintf(\"Too many inputs defined: %u, max: %u\\n\",\n+\t\t\t\t\tnb_inputs, cap->num_buffers_src);\n+\t\t\t\treturn TEST_FAILED;\n+\t\t\t}\n+\t\t\tif (nb_hard_outputs > cap->num_buffers_dst) {\n+\t\t\t\tprintf(\n+\t\t\t\t\t\"Too many hard outputs defined: %u, max: %u\\n\",\n+\t\t\t\t\tnb_hard_outputs, cap->num_buffers_src);\n+\t\t\t\treturn TEST_FAILED;\n+\t\t\t}\n+\t\t\tif (intr_enabled && !(cap->capability_flags &\n+\t\t\t\t\tRTE_BBDEV_TURBO_ENC_INTERRUPTS)) {\n+\t\t\t\tprintf(\n+\t\t\t\t\t\"Dequeue interrupts are not supported!\\n\");\n+\t\t\t\treturn TEST_FAILED;\n+\t\t\t}\n+\n+\t\t\treturn TEST_SUCCESS;\n+\t\t}\n+\t}\n+\n+\tif ((i == 0) && (test_vector.op_type == RTE_BBDEV_OP_NONE))\n+\t\treturn TEST_SUCCESS; /* Special case for NULL device */\n+\n+\treturn TEST_FAILED;\n+}\n+\n+static uint8_t\n+populate_active_devices(void)\n+{\n+\tint ret;\n+\tuint8_t dev_id;\n+\tuint8_t nb_devs_added = 0;\n+\tstruct rte_bbdev_info info;\n+\n+\tRTE_BBDEV_FOREACH(dev_id) {\n+\t\trte_bbdev_info_get(dev_id, &info);\n+\n+\t\tif (check_dev_cap(&info)) {\n+\t\t\tprintf(\n+\t\t\t\t\"Device %d (%s) does not support specified capabilities\\n\",\n+\t\t\t\t\tdev_id, info.dev_name);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tret = add_active_device(dev_id, &info, &test_vector);\n+\t\tif (ret != 0) {\n+\t\t\tprintf(\"Adding active bbdev %s skipped\\n\",\n+\t\t\t\t\tinfo.dev_name);\n+\t\t\tcontinue;\n+\t\t}\n+\t\tnb_devs_added++;\n+\t}\n+\n+\treturn nb_devs_added;\n+}\n+\n+static int\n+read_test_vector(void)\n+{\n+\tint ret;\n+\n+\tmemset(&test_vector, 0, sizeof(test_vector));\n+\tprintf(\"Test vector file = %s\\n\", get_vector_filename());\n+\tret = test_bbdev_vector_read(get_vector_filename(), &test_vector);\n+\tTEST_ASSERT_SUCCESS(ret, \"Failed to parse file %s\\n\",\n+\t\t\tget_vector_filename());\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+testsuite_setup(void)\n+{\n+\tTEST_ASSERT_SUCCESS(read_test_vector(), \"Test suite setup failed\\n\");\n+\n+\tif (populate_active_devices() == 0) {\n+\t\tprintf(\"No suitable devices found!\\n\");\n+\t\treturn TEST_SKIPPED;\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+interrupt_testsuite_setup(void)\n+{\n+\tTEST_ASSERT_SUCCESS(read_test_vector(), \"Test suite setup failed\\n\");\n+\n+\t/* Enable interrupts */\n+\tintr_enabled = true;\n+\n+\t/* Special case for NULL device (RTE_BBDEV_OP_NONE) */\n+\tif (populate_active_devices() == 0 ||\n+\t\t\ttest_vector.op_type == RTE_BBDEV_OP_NONE) {\n+\t\tintr_enabled = false;\n+\t\tprintf(\"No suitable devices found!\\n\");\n+\t\treturn TEST_SKIPPED;\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static void\n+testsuite_teardown(void)\n+{\n+\tuint8_t dev_id;\n+\n+\t/* Unconfigure devices */\n+\tRTE_BBDEV_FOREACH(dev_id)\n+\t\trte_bbdev_close(dev_id);\n+\n+\t/* Clear active devices structs. */\n+\tmemset(active_devs, 0, sizeof(active_devs));\n+\tnb_active_devs = 0;\n+}\n+\n+static int\n+ut_setup(void)\n+{\n+\tuint8_t i, dev_id;\n+\n+\tfor (i = 0; i < nb_active_devs; i++) {\n+\t\tdev_id = active_devs[i].dev_id;\n+\t\t/* reset bbdev stats */\n+\t\tTEST_ASSERT_SUCCESS(rte_bbdev_stats_reset(dev_id),\n+\t\t\t\t\"Failed to reset stats of bbdev %u\", dev_id);\n+\t\t/* start the device */\n+\t\tTEST_ASSERT_SUCCESS(rte_bbdev_start(dev_id),\n+\t\t\t\t\"Failed to start bbdev %u\", dev_id);\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static void\n+ut_teardown(void)\n+{\n+\tuint8_t i, dev_id;\n+\tstruct rte_bbdev_stats stats;\n+\n+\tfor (i = 0; i < nb_active_devs; i++) {\n+\t\tdev_id = active_devs[i].dev_id;\n+\t\t/* read stats and print */\n+\t\trte_bbdev_stats_get(dev_id, &stats);\n+\t\t/* Stop the device */\n+\t\trte_bbdev_stop(dev_id);\n+\t}\n+}\n+\n+static int\n+init_op_data_objs(struct rte_bbdev_op_data *bufs,\n+\t\tstruct op_data_entries *ref_entries,\n+\t\tstruct rte_mempool *mbuf_pool, const uint16_t n,\n+\t\tenum op_data_type op_type, uint16_t min_alignment)\n+{\n+\tint ret;\n+\tunsigned int i, j;\n+\n+\tfor (i = 0; i < n; ++i) {\n+\t\tchar *data;\n+\t\tstruct op_data_buf *seg = &ref_entries->segments[0];\n+\t\tstruct rte_mbuf *m_head = rte_pktmbuf_alloc(mbuf_pool);\n+\t\tTEST_ASSERT_NOT_NULL(m_head,\n+\t\t\t\t\"Not enough mbufs in %d data type mbuf pool (needed %u, available %u)\",\n+\t\t\t\top_type, n * ref_entries->nb_segments,\n+\t\t\t\tmbuf_pool->size);\n+\n+\t\tbufs[i].data = m_head;\n+\t\tbufs[i].offset = 0;\n+\t\tbufs[i].length = 0;\n+\n+\t\tif (op_type == DATA_INPUT) {\n+\t\t\tdata = rte_pktmbuf_append(m_head, seg->length);\n+\t\t\tTEST_ASSERT_NOT_NULL(data,\n+\t\t\t\t\t\"Couldn't append %u bytes to mbuf from %d data type mbuf pool\",\n+\t\t\t\t\tseg->length, op_type);\n+\n+\t\t\tTEST_ASSERT(data == RTE_PTR_ALIGN(data, min_alignment),\n+\t\t\t\t\t\"Data addr in mbuf (%p) is not aligned to device min alignment (%u)\",\n+\t\t\t\t\tdata, min_alignment);\n+\t\t\trte_memcpy(data, seg->addr, seg->length);\n+\t\t\tbufs[i].length += seg->length;\n+\n+\n+\t\t\tfor (j = 1; j < ref_entries->nb_segments; ++j) {\n+\t\t\t\tstruct rte_mbuf *m_tail =\n+\t\t\t\t\t\trte_pktmbuf_alloc(mbuf_pool);\n+\t\t\t\tTEST_ASSERT_NOT_NULL(m_tail,\n+\t\t\t\t\t\t\"Not enough mbufs in %d data type mbuf pool (needed %u, available %u)\",\n+\t\t\t\t\t\top_type,\n+\t\t\t\t\t\tn * ref_entries->nb_segments,\n+\t\t\t\t\t\tmbuf_pool->size);\n+\t\t\t\tseg += 1;\n+\n+\t\t\t\tdata = rte_pktmbuf_append(m_tail, seg->length);\n+\t\t\t\tTEST_ASSERT_NOT_NULL(data,\n+\t\t\t\t\t\t\"Couldn't append %u bytes to mbuf from %d data type mbuf pool\",\n+\t\t\t\t\t\tseg->length, op_type);\n+\n+\t\t\t\tTEST_ASSERT(data == RTE_PTR_ALIGN(data,\n+\t\t\t\t\t\tmin_alignment),\n+\t\t\t\t\t\t\"Data addr in mbuf (%p) is not aligned to device min alignment (%u)\",\n+\t\t\t\t\t\tdata, min_alignment);\n+\t\t\t\trte_memcpy(data, seg->addr, seg->length);\n+\t\t\t\tbufs[i].length += seg->length;\n+\n+\t\t\t\tret = rte_pktmbuf_chain(m_head, m_tail);\n+\t\t\t\tTEST_ASSERT_SUCCESS(ret,\n+\t\t\t\t\t\t\"Couldn't chain mbufs from %d data type mbuf pool\",\n+\t\t\t\t\t\top_type);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+allocate_buffers_on_socket(struct rte_bbdev_op_data **buffers, const int len,\n+\t\tconst int socket)\n+{\n+\tint i;\n+\n+\t*buffers = rte_zmalloc_socket(NULL, len, 0, socket);\n+\tif (*buffers == NULL) {\n+\t\tprintf(\"WARNING: Failed to allocate op_data on socket %d\\n\",\n+\t\t\t\tsocket);\n+\t\t/* try to allocate memory on other detected sockets */\n+\t\tfor (i = 0; i < socket; i++) {\n+\t\t\t*buffers = rte_zmalloc_socket(NULL, len, 0, i);\n+\t\t\tif (*buffers != NULL)\n+\t\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn (*buffers == NULL) ? TEST_FAILED : TEST_SUCCESS;\n+}\n+\n+static int\n+fill_queue_buffers(struct test_op_params *op_params,\n+\t\tstruct rte_mempool *in_mp, struct rte_mempool *hard_out_mp,\n+\t\tstruct rte_mempool *soft_out_mp, uint16_t queue_id,\n+\t\tuint16_t min_alignment, const int socket_id)\n+{\n+\tint ret;\n+\tenum op_data_type type;\n+\tconst uint16_t n = op_params->num_to_process;\n+\n+\tstruct rte_mempool *mbuf_pools[DATA_NUM_TYPES] = {\n+\t\tin_mp,\n+\t\tsoft_out_mp,\n+\t\thard_out_mp,\n+\t};\n+\n+\tstruct rte_bbdev_op_data **queue_ops[DATA_NUM_TYPES] = {\n+\t\t&op_params->q_bufs[socket_id][queue_id].inputs,\n+\t\t&op_params->q_bufs[socket_id][queue_id].soft_outputs,\n+\t\t&op_params->q_bufs[socket_id][queue_id].hard_outputs,\n+\t};\n+\n+\tfor (type = DATA_INPUT; type < DATA_NUM_TYPES; ++type) {\n+\t\tstruct op_data_entries *ref_entries =\n+\t\t\t\t&test_vector.entries[type];\n+\t\tif (ref_entries->nb_segments == 0)\n+\t\t\tcontinue;\n+\n+\t\tret = allocate_buffers_on_socket(queue_ops[type],\n+\t\t\t\tn * sizeof(struct rte_bbdev_op_data),\n+\t\t\t\tsocket_id);\n+\t\tTEST_ASSERT_SUCCESS(ret,\n+\t\t\t\t\"Couldn't allocate memory for rte_bbdev_op_data structs\");\n+\n+\t\tret = init_op_data_objs(*queue_ops[type], ref_entries,\n+\t\t\t\tmbuf_pools[type], n, type, min_alignment);\n+\t\tTEST_ASSERT_SUCCESS(ret,\n+\t\t\t\t\"Couldn't init rte_bbdev_op_data structs\");\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void\n+free_buffers(struct active_device *ad, struct test_op_params *op_params)\n+{\n+\tunsigned int i, j;\n+\n+\trte_mempool_free(ad->ops_mempool);\n+\trte_mempool_free(ad->in_mbuf_pool);\n+\trte_mempool_free(ad->hard_out_mbuf_pool);\n+\trte_mempool_free(ad->soft_out_mbuf_pool);\n+\n+\tfor (i = 0; i < rte_lcore_count(); ++i) {\n+\t\tfor (j = 0; j < RTE_MAX_NUMA_NODES; ++j) {\n+\t\t\trte_free(op_params->q_bufs[j][i].inputs);\n+\t\t\trte_free(op_params->q_bufs[j][i].hard_outputs);\n+\t\t\trte_free(op_params->q_bufs[j][i].soft_outputs);\n+\t\t}\n+\t}\n+}\n+\n+static void\n+copy_reference_op(struct rte_bbdev_op **ops, unsigned int n,\n+\t\tunsigned int start_idx,\n+\t\tstruct rte_bbdev_op_data *inputs,\n+\t\tstruct rte_bbdev_op_data *hard_outputs,\n+\t\tstruct rte_bbdev_op_data *soft_outputs,\n+\t\tstruct rte_bbdev_op *ref_op)\n+{\n+\tunsigned int i;\n+\n+\tswitch (ref_op->type) {\n+\tcase RTE_BBDEV_OP_NONE:\n+\tcase RTE_BBDEV_OP_TYPE_COUNT:\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_TURBO_ENC:\n+\t\tfor (i = 0; i < n; ++i) {\n+\t\t\tstruct rte_bbdev_op_turbo_enc *turbo_enc\n+\t\t\t\t\t= ref_op->turbo_enc;\n+\t\t\tif (ref_op->turbo_enc->code_block_mode == 0) {\n+\t\t\t\tops[i]->turbo_enc->tb_params.ea =\n+\t\t\t\t\t\tturbo_enc->tb_params.ea;\n+\t\t\t\tops[i]->turbo_enc->tb_params.eb =\n+\t\t\t\t\t\tturbo_enc->tb_params.eb;\n+\t\t\t\tops[i]->turbo_enc->tb_params.k_pos =\n+\t\t\t\t\t\tturbo_enc->tb_params.k_pos;\n+\t\t\t\tops[i]->turbo_enc->tb_params.k_neg =\n+\t\t\t\t\t\tturbo_enc->tb_params.k_neg;\n+\t\t\t\tops[i]->turbo_enc->tb_params.c =\n+\t\t\t\t\t\tturbo_enc->tb_params.c;\n+\t\t\t\tops[i]->turbo_enc->tb_params.c_neg =\n+\t\t\t\t\t\tturbo_enc->tb_params.c_neg;\n+\t\t\t\tops[i]->turbo_enc->tb_params.cab =\n+\t\t\t\t\t\tturbo_enc->tb_params.cab;\n+\t\t\t\tops[i]->turbo_enc->tb_params.ncb_pos =\n+\t\t\t\t\t\tturbo_enc->tb_params.ncb_pos;\n+\t\t\t\tops[i]->turbo_enc->tb_params.ncb_neg =\n+\t\t\t\t\t\tturbo_enc->tb_params.ncb_neg;\n+\t\t\t\t/* total number of bits available for the\n+\t\t\t\t * transmission of one TB\n+\t\t\t\t */\n+\t\t\t\tops[i]->turbo_enc->g =\n+\t\t\t\t\t\tturbo_enc->tb_params.ncb_pos\n+\t\t\t\t\t\t* 3;\n+\t\t\t} else {\n+\t\t\t\tops[i]->turbo_enc->cb_params.e =\n+\t\t\t\t\t\tturbo_enc->cb_params.e;\n+\t\t\t\tops[i]->turbo_enc->cb_params.k =\n+\t\t\t\t\t\tturbo_enc->cb_params.k;\n+\t\t\t\tops[i]->turbo_enc->cb_params.ncb =\n+\t\t\t\t\t\tturbo_enc->cb_params.ncb;\n+\t\t\t\t/* total number of bits available for the\n+\t\t\t\t * transmission of one TB\n+\t\t\t\t */\n+\t\t\t\tops[i]->turbo_enc->g =\n+\t\t\t\t\t\tturbo_enc->cb_params.ncb * 3;\n+\t\t\t}\n+\t\t\t/* For UE category 1 number of soft bits is 250368\n+\t\t\t * according to TS 36.306 Table 4.1-1\n+\t\t\t */\n+\t\t\tops[i]->turbo_enc->n_soft = 250368;\n+\t\t\tops[i]->turbo_enc->k_mimo = 1;\n+\t\t\t/* Max number of DL HARQ depends on UL/DL configuration\n+\t\t\t * according to TS 36.213 Table 7-1\n+\t\t\t */\n+\t\t\tops[i]->turbo_enc->mdl_harq = 4;\n+\t\t\tops[i]->turbo_enc->nl = 1;\n+\t\t\tops[i]->turbo_enc->qm = 2;\n+\t\t\tops[i]->turbo_enc->rv_index = turbo_enc->rv_index;\n+\t\t\tops[i]->turbo_enc->op_flags = turbo_enc->op_flags;\n+\t\t\tops[i]->turbo_enc->code_block_mode =\n+\t\t\t\t\tref_op->turbo_enc->code_block_mode;\n+\n+\t\t\tops[i]->turbo_enc->output =\n+\t\t\t\t\thard_outputs[start_idx + i];\n+\t\t\tops[i]->turbo_enc->input =\n+\t\t\t\t\tinputs[start_idx + i];\n+\t\t}\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_TURBO_DEC:\n+\t\tfor (i = 0; i < n; ++i) {\n+\t\t\tstruct rte_bbdev_op_turbo_dec *turbo_dec\n+\t\t\t\t\t= ref_op->turbo_dec;\n+\t\t\tif (ref_op->turbo_dec->code_block_mode == 0) {\n+\t\t\t\tops[i]->turbo_dec->tb_params.ea =\n+\t\t\t\t\t\tturbo_dec->tb_params.ea;\n+\t\t\t\tops[i]->turbo_dec->tb_params.eb =\n+\t\t\t\t\t\tturbo_dec->tb_params.eb;\n+\t\t\t\tops[i]->turbo_dec->tb_params.k_pos =\n+\t\t\t\t\t\tturbo_dec->tb_params.k_pos;\n+\t\t\t\tops[i]->turbo_dec->tb_params.k_neg =\n+\t\t\t\t\t\tturbo_dec->tb_params.k_neg;\n+\t\t\t\tops[i]->turbo_dec->tb_params.c =\n+\t\t\t\t\t\tturbo_dec->tb_params.c;\n+\t\t\t\tops[i]->turbo_dec->tb_params.c_neg =\n+\t\t\t\t\t\tturbo_dec->tb_params.c_neg;\n+\t\t\t\tops[i]->turbo_dec->tb_params.cab =\n+\t\t\t\t\t\tturbo_dec->tb_params.cab;\n+\t\t\t} else {\n+\t\t\t\tops[i]->turbo_dec->cb_params.e =\n+\t\t\t\t\t\tturbo_dec->cb_params.e;\n+\t\t\t\tops[i]->turbo_dec->cb_params.k =\n+\t\t\t\t\t\tturbo_dec->cb_params.k;\n+\t\t\t}\n+\n+\t\t\tops[i]->turbo_dec->ext_scale = turbo_dec->ext_scale;\n+\t\t\tops[i]->turbo_dec->iter_max = turbo_dec->iter_max;\n+\t\t\tops[i]->turbo_dec->iter_min = turbo_dec->iter_min;\n+\t\t\tops[i]->turbo_dec->op_flags = turbo_dec->op_flags;\n+\t\t\tops[i]->turbo_dec->rv_index = turbo_dec->rv_index;\n+\t\t\tops[i]->turbo_dec->num_maps = turbo_dec->num_maps;\n+\t\t\tops[i]->turbo_dec->code_block_mode =\n+\t\t\t\t\tturbo_dec->code_block_mode;\n+\n+\t\t\tops[i]->turbo_dec->hard_output =\n+\t\t\t\t\thard_outputs[start_idx + i];\n+\t\t\tops[i]->turbo_dec->input = inputs[start_idx + i];\n+\t\t\tif (soft_outputs != NULL)\n+\t\t\t\tops[i]->turbo_dec->soft_output =\n+\t\t\t\t\tsoft_outputs[start_idx + i];\n+\t\t}\n+\t\tbreak;\n+\t}\n+}\n+\n+static int\n+check_status_and_ordering(struct rte_bbdev_op *op, unsigned int order_idx,\n+\t\tconst int expected_status)\n+{\n+\tTEST_ASSERT(op->status == expected_status,\n+\t\t\t\"op_status (%d) != expected_status (%d)\",\n+\t\t\top->status, expected_status);\n+\n+\tTEST_ASSERT((void *)(uintptr_t)order_idx == op->opaque_data,\n+\t\t\t\"Ordering error, expected %p, got %p\",\n+\t\t\t(void *)(uintptr_t)order_idx, op->opaque_data);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static inline int\n+validate_op_chain(struct rte_bbdev_op_data *op,\n+\t\tstruct op_data_entries *orig_op)\n+{\n+\tuint8_t i;\n+\tstruct rte_mbuf *m = op->data;\n+\tuint8_t nb_dst_segments = orig_op->nb_segments;\n+\n+\tTEST_ASSERT(nb_dst_segments == m->nb_segs,\n+\t\t\t\"Number of segments differ in original (%u) and filled (%u) op\",\n+\t\t\tnb_dst_segments, m->nb_segs);\n+\n+\tfor (i = 0; i < nb_dst_segments; ++i) {\n+\t\t/* Apply offset to the first mbuf segment */\n+\t\tuint16_t offset = (i == 0) ? op->offset : 0;\n+\t\tuint16_t data_len = m->data_len - offset;\n+\n+\t\tTEST_ASSERT(orig_op->segments[i].length == data_len,\n+\t\t\t\t\"Length of segment differ in original (%u) and filled (%u) op\",\n+\t\t\t\torig_op->segments[i].length, data_len);\n+\t\tTEST_ASSERT_BUFFERS_ARE_EQUAL(orig_op->segments[i].addr,\n+\t\t\t\trte_pktmbuf_mtod_offset(m, uint32_t *, offset),\n+\t\t\t\tdata_len,\n+\t\t\t\t\"Output buffers (CB=%u) are not equal\", i);\n+\t\tm = m->next;\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+validate_buffers(struct rte_bbdev_op *ref_op, struct test_buffers *bufs,\n+\t\tconst uint16_t num_to_process)\n+{\n+\tint i;\n+\n+\tstruct op_data_entries *hard_data_orig =\n+\t\t\t&test_vector.entries[DATA_HARD_OUTPUT];\n+\tstruct op_data_entries *soft_data_orig =\n+\t\t\t&test_vector.entries[DATA_SOFT_OUTPUT];\n+\n+\tfor (i = 0; i < num_to_process; i++) {\n+\t\tif (ref_op->type == RTE_BBDEV_OP_TURBO_DEC) {\n+\t\t\tTEST_ASSERT_SUCCESS(validate_op_chain(\n+\t\t\t\t\t&bufs->hard_outputs[i], hard_data_orig),\n+\t\t\t\t\t\"Hard output buffers are not equal\");\n+\t\t\tif (ref_op->turbo_dec->op_flags &\n+\t\t\t\t\tRTE_BBDEV_TURBO_SOFT_OUTPUT)\n+\t\t\t\tTEST_ASSERT_SUCCESS(validate_op_chain(\n+\t\t\t\t\t\t&bufs->soft_outputs[i],\n+\t\t\t\t\t\tsoft_data_orig),\n+\t\t\t\t\t\t\"Soft output buffers are not equal\");\n+\t\t} else if (ref_op->type == RTE_BBDEV_OP_TURBO_ENC)\n+\t\t\tTEST_ASSERT_SUCCESS(validate_op_chain(\n+\t\t\t\t\t&bufs->hard_outputs[i],\n+\t\t\t\t\thard_data_orig), \"\");\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+validate_op(struct rte_bbdev_op **ops, const uint16_t n,\n+\t\tstruct rte_bbdev_op *ref_op, const int vector_mask)\n+{\n+\tunsigned int i;\n+\tint ret;\n+\tstruct op_data_entries *hard_data_orig =\n+\t\t\t&test_vector.entries[DATA_HARD_OUTPUT];\n+\tstruct op_data_entries *soft_data_orig =\n+\t\t\t&test_vector.entries[DATA_SOFT_OUTPUT];\n+\n+\tswitch (ref_op->type) {\n+\tcase RTE_BBDEV_OP_NONE:\n+\tcase RTE_BBDEV_OP_TYPE_COUNT:\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_TURBO_ENC:\n+\t\tfor (i = 0; i < n; ++i) {\n+\t\t\tret = check_status_and_ordering(ops[i], i,\n+\t\t\t\t\tref_op->status);\n+\t\t\tTEST_ASSERT_SUCCESS(ret,\n+\t\t\t\t\t\"Checking status and ordering for encoder failed\");\n+\t\t\tTEST_ASSERT_SUCCESS(validate_op_chain(\n+\t\t\t\t\t&ops[i]->turbo_enc->output,\n+\t\t\t\t\thard_data_orig),\n+\t\t\t\t\t\"Output buffers (CB=%u) are not equal\",\n+\t\t\t\t\ti);\n+\t\t}\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_TURBO_DEC:\n+\t\tfor (i = 0; i < n; ++i) {\n+\t\t\tstruct rte_bbdev_op_turbo_dec *ops_td =\n+\t\t\t\t\tops[i]->turbo_dec;\n+\t\t\tstruct rte_bbdev_op_turbo_dec *ref_td =\n+\t\t\t\t\tref_op->turbo_dec;\n+\t\t\tstruct rte_bbdev_op_data *hard_output =\n+\t\t\t\t\t&ops_td->hard_output;\n+\t\t\tstruct rte_bbdev_op_data *soft_output =\n+\t\t\t\t\t&ops_td->soft_output;\n+\n+\t\t\tif (vector_mask & TEST_BBDEV_VF_EXPECTED_ITER_COUNT)\n+\t\t\t\tTEST_ASSERT(ops_td->iter_count <=\n+\t\t\t\t\t\tref_td->iter_count,\n+\t\t\t\t\t\t\"Returned iter_count (%d) > expected iter_count (%d)\",\n+\t\t\t\t\t\tops_td->iter_count,\n+\t\t\t\t\t\tref_td->iter_count);\n+\t\t\tret = check_status_and_ordering(ops[i], i,\n+\t\t\t\t\tref_op->status);\n+\t\t\tTEST_ASSERT_SUCCESS(ret,\n+\t\t\t\t\t\"Checking status and ordering for decoder failed\");\n+\n+\t\t\tTEST_ASSERT_SUCCESS(validate_op_chain(\n+\t\t\t\t\thard_output, hard_data_orig),\n+\t\t\t\t\t\"Hard output buffers (CB=%u) are not equal\",\n+\t\t\t\t\ti);\n+\n+\t\t\tif (ref_op->turbo_dec->op_flags &\n+\t\t\t\t\tRTE_BBDEV_TURBO_SOFT_OUTPUT)\n+\t\t\t\tTEST_ASSERT_SUCCESS(validate_op_chain(\n+\t\t\t\t\t\tsoft_output, soft_data_orig),\n+\t\t\t\t\t\t\"Soft output buffers (CB=%u) are not equal\",\n+\t\t\t\t\t\ti);\n+\t\t}\n+\t\tbreak;\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static void\n+create_reference_op(struct rte_bbdev_op *op)\n+{\n+\tswitch (op->type) {\n+\tcase RTE_BBDEV_OP_NONE:\n+\tcase RTE_BBDEV_OP_TYPE_COUNT:\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_TURBO_ENC:\n+\t\t*op->turbo_enc = test_vector.turbo_enc;\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_TURBO_DEC:\n+\t\t*op->turbo_dec = test_vector.turbo_dec;\n+\t}\n+}\n+\n+static int\n+init_test_op_params(struct test_op_params *op_params,\n+\t\tenum rte_bbdev_op_type op_type, const int expected_status,\n+\t\tconst int vector_mask, struct rte_mempool *ops_mp,\n+\t\tuint16_t burst_sz, uint16_t num_to_process)\n+{\n+\tint ret = rte_bbdev_op_alloc_bulk(ops_mp, op_type,\n+\t\t\t&op_params->ref_op, 1);\n+\tTEST_ASSERT_SUCCESS(ret, \"rte_bbdev_op_alloc_bulk() failed\");\n+\n+\top_params->mp = ops_mp;\n+\top_params->burst_sz = burst_sz;\n+\top_params->num_to_process = num_to_process;\n+\top_params->ref_op->type = op_type;\n+\top_params->ref_op->status = expected_status;\n+\top_params->vector_mask = vector_mask;\n+\n+\treturn 0;\n+}\n+\n+static int\n+run_test_case_on_device(test_case_function *test_case_func, uint8_t dev_id,\n+\t\tstruct test_op_params *op_params)\n+{\n+\tint t_ret, f_ret, socket_id = SOCKET_ID_ANY;\n+\tunsigned int i;\n+\tstruct active_device *ad;\n+\tunsigned int burst_sz = get_burst_sz();\n+\n+\tad = &active_devs[dev_id];\n+\n+\t/* Check if device supports op_type */\n+\tif (!is_avail_op(ad, test_vector.op_type))\n+\t\treturn TEST_SUCCESS;\n+\n+\tstruct rte_bbdev_info info;\n+\trte_bbdev_info_get(ad->dev_id, &info);\n+\tsocket_id = GET_SOCKET(info.socket_id);\n+\n+\tf_ret = create_mempools(ad, socket_id, test_vector.op_type,\n+\t\t\tget_num_ops());\n+\tif (f_ret != TEST_SUCCESS) {\n+\t\tprintf(\"Couldn't create mempools\");\n+\t\tgoto fail;\n+\t}\n+\n+\tf_ret = init_test_op_params(op_params, test_vector.op_type,\n+\t\t\ttest_vector.expected_status,\n+\t\t\ttest_vector.mask,\n+\t\t\tad->ops_mempool,\n+\t\t\tburst_sz,\n+\t\t\tget_num_ops());\n+\tif (f_ret != TEST_SUCCESS) {\n+\t\tprintf(\"Couldn't init test op params\");\n+\t\tgoto fail;\n+\t}\n+\n+\tcreate_reference_op(op_params->ref_op);\n+\n+\tfor (i = 0; i < ad->nb_queues; ++i) {\n+\t\tf_ret = fill_queue_buffers(op_params,\n+\t\t\t\tad->in_mbuf_pool,\n+\t\t\t\tad->hard_out_mbuf_pool,\n+\t\t\t\tad->soft_out_mbuf_pool,\n+\t\t\t\tad->queue_ids[i],\n+\t\t\t\tinfo.drv.min_alignment,\n+\t\t\t\tsocket_id);\n+\t\tif (f_ret != TEST_SUCCESS) {\n+\t\t\tprintf(\"Couldn't init queue buffers\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t}\n+\n+\t/* Run test case function */\n+\tt_ret = test_case_func(ad, op_params);\n+\n+\t/* Free active device resources and return */\n+\tfree_buffers(ad, op_params);\n+\treturn t_ret;\n+\n+fail:\n+\tfree_buffers(ad, op_params);\n+\treturn TEST_FAILED;\n+}\n+\n+/* Run given test function per active device per supported op type\n+ * per burst size.\n+ */\n+static int\n+run_test_case(test_case_function *test_case_func)\n+{\n+\tint ret = 0;\n+\tuint8_t dev;\n+\n+\t/* Alloc op_params */\n+\tstruct test_op_params *op_params = rte_zmalloc(NULL,\n+\t\t\tsizeof(struct test_op_params), RTE_CACHE_LINE_SIZE);\n+\tTEST_ASSERT_NOT_NULL(op_params, \"Failed to alloc %zuB for op_params\",\n+\t\t\tRTE_ALIGN(sizeof(struct test_op_params),\n+\t\t\t\tRTE_CACHE_LINE_SIZE));\n+\n+\t/* For each device run test case function */\n+\tfor (dev = 0; dev < nb_active_devs; ++dev)\n+\t\tret |= run_test_case_on_device(test_case_func, dev, op_params);\n+\n+\trte_free(op_params);\n+\n+\treturn ret;\n+}\n+\n+static void\n+dequeue_event_callback(uint16_t dev_id,\n+\t\tenum rte_bbdev_event_type event, void *cb_arg,\n+\t\tvoid *ret_param)\n+{\n+\tint ret;\n+\tunsigned i;\n+\tuint64_t total_time;\n+\tuint16_t deq, burst_sz, num_to_process;\n+\tuint16_t queue_id = INVALID_QUEUE_ID;\n+\tstruct rte_bbdev_op *ops[MAX_BURST];\n+\tstruct test_buffers *bufs;\n+\tstruct rte_bbdev_info info;\n+\tstruct rte_bbdev_op *ref_op;\n+\n+\t/* Input length in bytes, million operations per second,\n+\t * million bits per second.\n+\t */\n+\tdouble in_len, mops, mbps;\n+\n+\tstruct thread_params *tp = cb_arg;\n+\n+\tRTE_SET_USED(ret_param);\n+\n+\t/* Find matching thread params using queue_id */\n+\tfor (i = 0; i < MAX_QUEUES; ++i, ++tp)\n+\t\tif (tp->queue_id == queue_id)\n+\t\t\tbreak;\n+\n+\tif (i == MAX_QUEUES) {\n+\t\tprintf(\"%s: Queue_id from interrupt details was not found!\\n\",\n+\t\t\t\t__func__);\n+\t\treturn;\n+\t}\n+\n+\tif (unlikely(event != RTE_BBDEV_EVENT_DEQUEUE)) {\n+\t\trte_atomic16_set(&tp->processing_status, TEST_FAILED);\n+\t\tprintf(\n+\t\t\t\"Dequeue interrupt handler called for incorrect event!\\n\");\n+\t\treturn;\n+\t}\n+\n+\tburst_sz = tp->op_params->burst_sz;\n+\tnum_to_process = tp->op_params->num_to_process;\n+\n+\tdeq = rte_bbdev_dequeue_ops(dev_id, queue_id, ops, burst_sz);\n+\n+\tif (deq < burst_sz) {\n+\t\tprintf(\n+\t\t\t\"After receiving the interrupt all operations should be dequeued. Expected: %u, got: %u\\n\",\n+\t\t\tburst_sz, deq);\n+\t\trte_atomic16_set(&tp->processing_status, TEST_FAILED);\n+\t\treturn;\n+\t}\n+\n+\tif (rte_atomic16_read(&tp->nb_dequeued) + deq < num_to_process) {\n+\t\trte_atomic16_add(&tp->nb_dequeued, deq);\n+\t\treturn;\n+\t}\n+\n+\ttotal_time = rte_rdtsc_precise() - tp->start_time;\n+\n+\trte_bbdev_info_get(dev_id, &info);\n+\n+\tbufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];\n+\tret = validate_buffers(tp->op_params->ref_op, bufs, num_to_process);\n+\tif (ret) {\n+\t\tprintf(\"Buffers validation failed\\n\");\n+\t\trte_atomic16_set(&tp->processing_status, TEST_FAILED);\n+\t}\n+\n+\tref_op = tp->op_params->ref_op;\n+\n+\tswitch (ref_op->type) {\n+\tcase RTE_BBDEV_OP_TURBO_DEC:\n+\t\tin_len = ref_op->turbo_dec->input.length;\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_TURBO_ENC:\n+\t\tin_len = ref_op->turbo_enc->input.length;\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_NONE:\n+\t\tin_len = 0.0;\n+\t\tbreak;\n+\tdefault:\n+\t\tprintf(\"Unknown op type: %d\\n\", ref_op->type);\n+\t\trte_atomic16_set(&tp->processing_status, TEST_FAILED);\n+\t\treturn;\n+\t}\n+\n+\tmops = ((double)num_to_process / 1000000.0) /\n+\t\t\t((double)total_time / (double)rte_get_tsc_hz());\n+\tmbps = ((double)num_to_process * in_len * 8 / 1000000.0) /\n+\t\t\t((double)total_time / (double)rte_get_tsc_hz());\n+\n+\tif (ref_op->type != RTE_BBDEV_OP_NONE)\n+\t\tprintf(\"\\tqueue_id: %u, throughput: %lg MOPS, %lg Mbps\\n\",\n+\t\t\tqueue_id, mops, mbps);\n+\telse\n+\t\tprintf(\"\\tqueue_id: %u, throughput: %lg MOPS\\n\",\n+\t\t\tqueue_id, mops);\n+\n+\trte_atomic16_add(&tp->nb_dequeued, deq);\n+}\n+\n+static int\n+throughput_intr_lcore(void *arg)\n+{\n+\tstruct thread_params *tp = arg;\n+\tunsigned int enqueued;\n+\tstruct rte_bbdev_op *ops[MAX_BURST];\n+\tconst uint16_t queue_id = tp->queue_id;\n+\tconst uint16_t burst_sz = tp->op_params->burst_sz;\n+\tconst uint16_t num_to_process = tp->op_params->num_to_process;\n+\tconst enum rte_bbdev_op_type op_type = tp->op_params->ref_op->type;\n+\tstruct test_buffers *bufs = NULL;\n+\tunsigned int allocs_failed = 0;\n+\tstruct rte_bbdev_info info;\n+\tint ret;\n+\n+\tif (burst_sz > MAX_BURST) {\n+\t\tprintf(\"Operations table size > MAX_BURST\\n\");\n+\t\treturn TEST_FAILED;\n+\t}\n+\n+\tTEST_ASSERT_SUCCESS(rte_bbdev_queue_intr_enable(tp->dev_id, queue_id),\n+\t\t\t\"Failed to enable interrupts for dev: %u, queue_id: %u\",\n+\t\t\ttp->dev_id, queue_id);\n+\n+\trte_bbdev_info_get(tp->dev_id, &info);\n+\tbufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];\n+\n+\trte_atomic16_clear(&tp->processing_status);\n+\trte_atomic16_clear(&tp->nb_dequeued);\n+\n+\twhile (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT)\n+\t\trte_pause();\n+\n+\ttp->start_time = rte_rdtsc_precise();\n+\tfor (enqueued = 0; enqueued < num_to_process;) {\n+\n+\t\tuint16_t num_to_enq = burst_sz;\n+\n+\t\tif (unlikely(num_to_process - enqueued < num_to_enq))\n+\t\t\tnum_to_enq = num_to_process - enqueued;\n+\n+\t\tret = rte_bbdev_op_alloc_bulk(tp->op_params->mp,\n+\t\t\t\top_type, ops, num_to_enq);\n+\t\tif (ret != 0) {\n+\t\t\tallocs_failed++;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tcopy_reference_op(ops, num_to_enq, enqueued,\n+\t\t\t\tbufs->inputs,\n+\t\t\t\tbufs->hard_outputs,\n+\t\t\t\tbufs->soft_outputs,\n+\t\t\t\ttp->op_params->ref_op);\n+\n+\t\tenqueued += rte_bbdev_enqueue_ops(tp->dev_id, queue_id, ops,\n+\t\t\t\tnum_to_enq);\n+\n+\t\trte_bbdev_op_free_bulk(ops, num_to_enq);\n+\t}\n+\n+\tif (allocs_failed > 0)\n+\t\tprintf(\"WARNING: op allocations failed: %u times\\n\",\n+\t\t\t\tallocs_failed);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+throughput_pmd_lcore(void *arg)\n+{\n+\tstruct thread_params *tp = arg;\n+\tunsigned int enqueued, dequeued;\n+\tstruct rte_bbdev_op *ops[MAX_BURST];\n+\tuint64_t total_time, start_time;\n+\tconst uint16_t queue_id = tp->queue_id;\n+\tconst uint16_t burst_sz = tp->op_params->burst_sz;\n+\tconst uint16_t num_to_process = tp->op_params->num_to_process;\n+\tstruct rte_bbdev_op *ref_op = tp->op_params->ref_op;\n+\tstruct test_buffers *bufs = NULL;\n+\tunsigned int allocs_failed = 0;\n+\tint ret;\n+\tstruct rte_bbdev_info info;\n+\n+\t/* Input length in bytes, million operations per second, million bits\n+\t * per second.\n+\t */\n+\tdouble in_len, mops, mbps;\n+\n+\tif (burst_sz > MAX_BURST) {\n+\t\tprintf(\"Operations table size > MAX_BURST\\n\");\n+\t\treturn TEST_FAILED;\n+\t}\n+\n+\trte_bbdev_info_get(tp->dev_id, &info);\n+\tbufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];\n+\n+\twhile (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT)\n+\t\trte_pause();\n+\n+\tstart_time = rte_rdtsc_precise();\n+\tfor (enqueued = 0, dequeued = 0; dequeued < num_to_process;) {\n+\t\tuint16_t deq;\n+\n+\t\tif (likely(enqueued < num_to_process)) {\n+\n+\t\t\tuint16_t num_to_enq = burst_sz;\n+\n+\t\t\tif (unlikely(num_to_process - enqueued < num_to_enq))\n+\t\t\t\tnum_to_enq = num_to_process - enqueued;\n+\n+\t\t\tret = rte_bbdev_op_alloc_bulk(tp->op_params->mp,\n+\t\t\t\t\tref_op->type, ops, num_to_enq);\n+\t\t\tif (ret != 0) {\n+\t\t\t\tallocs_failed++;\n+\t\t\t\tgoto do_dequeue;\n+\t\t\t}\n+\n+\t\t\tcopy_reference_op(ops, num_to_enq, enqueued,\n+\t\t\t\t\tbufs->inputs,\n+\t\t\t\t\tbufs->hard_outputs,\n+\t\t\t\t\tbufs->soft_outputs,\n+\t\t\t\t\ttp->op_params->ref_op);\n+\n+\t\t\tenqueued += rte_bbdev_enqueue_ops(tp->dev_id, queue_id,\n+\t\t\t\t\tops, num_to_enq);\n+\t\t}\n+do_dequeue:\n+\t\tdeq = rte_bbdev_dequeue_ops(tp->dev_id, queue_id, ops,\n+\t\t\t\tburst_sz);\n+\t\tdequeued += deq;\n+\t\trte_bbdev_op_free_bulk(ops, deq);\n+\t}\n+\ttotal_time = rte_rdtsc_precise() - start_time;\n+\n+\tif (allocs_failed > 0)\n+\t\tprintf(\"WARNING: op allocations failed: %u times\\n\",\n+\t\t\t\tallocs_failed);\n+\n+\tTEST_ASSERT(enqueued == dequeued, \"enqueued (%u) != dequeued (%u)\",\n+\t\t\tenqueued, dequeued);\n+\n+\tif (ref_op->type != RTE_BBDEV_OP_NONE) {\n+\t\tret = validate_buffers(tp->op_params->ref_op, bufs,\n+\t\t\t\tnum_to_process);\n+\t\tTEST_ASSERT_SUCCESS(ret, \"Buffers validation failed\");\n+\t}\n+\n+\tswitch (ref_op->type) {\n+\tcase RTE_BBDEV_OP_TURBO_DEC:\n+\t\tin_len = ref_op->turbo_dec->input.length;\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_TURBO_ENC:\n+\t\tin_len = ref_op->turbo_enc->input.length;\n+\t\tbreak;\n+\tcase RTE_BBDEV_OP_NONE:\n+\t\tin_len = 0.0;\n+\t\tbreak;\n+\tdefault:\n+\t\tprintf(\"Unknown op type: %d\\n\", ref_op->type);\n+\t\treturn TEST_FAILED;\n+\t}\n+\n+\tmops = ((double)num_to_process / 1000000.0) /\n+\t\t\t((double)total_time / (double)rte_get_tsc_hz());\n+\tmbps = ((double)in_len * 8 / 1000000.0) /\n+\t\t\t((double)total_time / (double)rte_get_tsc_hz());\n+\n+\tif (ref_op->type != RTE_BBDEV_OP_NONE)\n+\t\tprintf(\"\\tlcore_id: %u, throughput: %lg MOPS, %lg Mbps\\n\",\n+\t\t\trte_lcore_id(), mops, mbps);\n+\telse\n+\t\tprintf(\"\\tlcore_id: %u, throughput: %lg MOPS\\n\",\n+\t\t\trte_lcore_id(), mops);\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+/*\n+ * Test function that determines how long an enqueue + dequeue of a burst\n+ * takes on available lcores.\n+ */\n+static int\n+throughput_test(struct active_device *ad,\n+\t\tstruct test_op_params *op_params)\n+{\n+\tint ret;\n+\n+\tunsigned int lcore_id, used_cores = 0;\n+\tstruct thread_params t_params[MAX_QUEUES];\n+\tstruct rte_bbdev_info info;\n+\tlcore_function_t *throughput_function;\n+\n+\trte_bbdev_info_get(ad->dev_id, &info);\n+\n+\tprintf(\n+\t\t\"Throughput test: dev: %s, burst size: %u, num ops: %u, op type: %s, int mode: %s, GHz: %lg\\n\",\n+\t\t\tinfo.dev_name, op_params->burst_sz,\n+\t\t\top_params->num_to_process,\n+\t\t\trte_bbdev_op_type_str(op_params->ref_op->type),\n+\t\t\tintr_enabled ? \"Interrupt mode\" : \"PMD mode\",\n+\t\t\t(double)rte_get_tsc_hz() / 1000000000.0);\n+\n+\tif (intr_enabled) {\n+\t\tthroughput_function = throughput_intr_lcore;\n+\t\t/* Dequeue interrupt callback registration */\n+\t\trte_bbdev_callback_register(ad->dev_id, RTE_BBDEV_EVENT_DEQUEUE,\n+\t\t\t\tdequeue_event_callback,\n+\t\t\t\t&t_params);\n+\t} else\n+\t\tthroughput_function = throughput_pmd_lcore;\n+\n+\trte_atomic16_set(&op_params->sync, SYNC_WAIT);\n+\n+\tt_params[rte_lcore_id()].dev_id = ad->dev_id;\n+\tt_params[rte_lcore_id()].op_params = op_params;\n+\tt_params[rte_lcore_id()].queue_id =\n+\t\t\tad->queue_ids[used_cores++];\n+\n+\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n+\t\tif (used_cores >= ad->nb_queues)\n+\t\t\tbreak;\n+\n+\t\tt_params[lcore_id].dev_id = ad->dev_id;\n+\t\tt_params[lcore_id].op_params = op_params;\n+\t\tt_params[lcore_id].queue_id = ad->queue_ids[used_cores++];\n+\n+\t\trte_eal_remote_launch(throughput_function, &t_params[lcore_id],\n+\t\t\t\tlcore_id);\n+\t}\n+\n+\trte_atomic16_set(&op_params->sync, SYNC_START);\n+\tret = throughput_function(&t_params[rte_lcore_id()]);\n+\n+\t/* Master core is always used */\n+\tused_cores = 1;\n+\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n+\t\tif (used_cores++ >= ad->nb_queues)\n+\t\t\tbreak;\n+\n+\t\tret |= rte_eal_wait_lcore(lcore_id);\n+\t}\n+\n+\t/* If interrupts are disabled or throughput_intr_lcore failed, return */\n+\tif (!intr_enabled || ret)\n+\t\treturn ret;\n+\n+\t/* In interrupt TC we need to wait for the interrupt callback to deqeue\n+\t * all pending operations. Skip waiting for queues which reported an\n+\t * error using processing_status variable.\n+\t */\n+\tused_cores = 1;\n+\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n+\t\tstruct thread_params *tp = &t_params[lcore_id];\n+\t\tif (used_cores++ >= ad->nb_queues)\n+\t\t\tbreak;\n+\n+\t\twhile ((rte_atomic16_read(&tp->nb_dequeued) <\n+\t\t\t\top_params->num_to_process) &&\n+\t\t\t\t(rte_atomic16_read(&tp->processing_status) !=\n+\t\t\t\tTEST_FAILED))\n+\t\t\trte_pause();\n+\n+\t\tret |= rte_atomic16_read(&tp->processing_status);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static int\n+operation_latency_test(struct active_device *ad,\n+\t\tstruct test_op_params *op_params)\n+{\n+\tint ret = TEST_SUCCESS;\n+\tuint16_t i, j, dequeued;\n+\tstruct rte_bbdev_op *ops[MAX_BURST];\n+\tuint16_t burst_sz = op_params->burst_sz;\n+\tconst uint16_t num_to_process = op_params->num_to_process;\n+\tconst enum rte_bbdev_op_type op_type = op_params->ref_op->type;\n+\tconst uint16_t queue_id = ad->queue_ids[0];\n+\tstruct test_buffers *bufs = NULL;\n+\tstruct rte_bbdev_info info;\n+\tuint64_t start_time = 0, total_time = 0;\n+\n+\trte_bbdev_info_get(ad->dev_id, &info);\n+\tbufs = &op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];\n+\n+\tprintf(\n+\t\t\"Validation/Latency test: dev: %s, burst size: %u, num ops: %u, op type: %s\\n\",\n+\t\t\tinfo.dev_name, burst_sz, num_to_process,\n+\t\t\trte_bbdev_op_type_str(op_type));\n+\n+\tfor (i = 0, dequeued = 0; dequeued < op_params->num_to_process; ++i) {\n+\t\tuint16_t enq = 0, deq = 0;\n+\t\tbool first_time = true;\n+\n+\t\tif (unlikely(op_params->num_to_process - dequeued < burst_sz))\n+\t\t\tburst_sz = op_params->num_to_process - dequeued;\n+\n+\t\trte_bbdev_op_alloc_bulk(op_params->mp, op_type, ops, burst_sz);\n+\t\tcopy_reference_op(ops, burst_sz, dequeued,\n+\t\t\t\tbufs->inputs,\n+\t\t\t\tbufs->hard_outputs,\n+\t\t\t\tbufs->soft_outputs,\n+\t\t\t\top_params->ref_op);\n+\n+\t\t/* Set counter to validate the ordering */\n+\t\tfor (j = 0; j < burst_sz; ++j)\n+\t\t\tops[j]->opaque_data = (void *)(uintptr_t)j;\n+\n+\t\tstart_time = rte_rdtsc_precise();\n+\n+\t\tenq = rte_bbdev_enqueue_ops(ad->dev_id, queue_id,\n+\t\t\t\t&ops[enq], burst_sz);\n+\t\tTEST_ASSERT(enq == burst_sz,\n+\t\t\t\t\"Error enqueueing burst, expected %u, got %u\",\n+\t\t\t\tburst_sz, enq);\n+\n+\t\t/* Dequeue */\n+\t\tdo {\n+\t\t\tdeq += rte_bbdev_dequeue_ops(ad->dev_id, queue_id,\n+\t\t\t\t\t&ops[deq], burst_sz - deq);\n+\t\t\tif (likely(first_time && (deq > 0))) {\n+\t\t\t\ttotal_time += rte_rdtsc_precise() - start_time;\n+\t\t\t\tfirst_time = false;\n+\t\t\t}\n+\t\t} while (unlikely(burst_sz != deq));\n+\n+\t\tret = validate_op(ops, burst_sz, op_params->ref_op,\n+\t\t\t\top_params->vector_mask);\n+\t\tTEST_ASSERT_SUCCESS(ret, \"Validation failed!\");\n+\n+\t\trte_bbdev_op_free_bulk(ops, deq);\n+\t\tdequeued += deq;\n+\t}\n+\n+\tprintf(\"\\toperation avg. latency: %lg cycles, %lg us\\n\",\n+\t\t\t(double)total_time / (double)i,\n+\t\t\t(double)(total_time * 1000000) / (double)i /\n+\t\t\t(double)rte_get_tsc_hz());\n+\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+offload_latency_test(struct active_device *ad,\n+\t\tstruct test_op_params *op_params)\n+{\n+\tuint16_t i, dequeued;\n+\tstruct rte_bbdev_op *ops[MAX_BURST];\n+\tuint64_t enq_start_time, enq_total_time = 0;\n+\tuint64_t deq_start_time, deq_total_time = 0;\n+\tuint16_t burst_sz = op_params->burst_sz;\n+\tconst uint16_t num_to_process = op_params->num_to_process;\n+\tconst enum rte_bbdev_op_type op_type = op_params->ref_op->type;\n+\tconst uint16_t queue_id = ad->queue_ids[0];\n+\tstruct test_buffers *bufs = NULL;\n+\tstruct rte_bbdev_info info;\n+\n+\trte_bbdev_info_get(ad->dev_id, &info);\n+\tbufs = &op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];\n+\n+\tprintf(\n+\t\t\"Offload latency test: dev: %s, burst size: %u, num ops: %u, op type: %s\\n\",\n+\t\t\tinfo.dev_name, burst_sz, num_to_process,\n+\t\t\trte_bbdev_op_type_str(op_type));\n+\n+\tfor (i = 0, dequeued = 0; dequeued < op_params->num_to_process; ++i) {\n+\t\tuint16_t enq = 0, deq = 0;\n+\n+\t\tif (unlikely(op_params->num_to_process - dequeued < burst_sz))\n+\t\t\tburst_sz = op_params->num_to_process - dequeued;\n+\n+\t\trte_bbdev_op_alloc_bulk(op_params->mp, op_type, ops, burst_sz);\n+\t\tcopy_reference_op(ops, burst_sz, dequeued,\n+\t\t\t\tbufs->inputs,\n+\t\t\t\tbufs->hard_outputs,\n+\t\t\t\tbufs->soft_outputs,\n+\t\t\t\top_params->ref_op);\n+\n+\t\t/* Start time measurment for enqueue function offload latency */\n+\t\tenq_start_time = rte_rdtsc();\n+\t\tdo {\n+\t\t\tenq += rte_bbdev_enqueue_ops(ad->dev_id, queue_id,\n+\t\t\t\t\t&ops[enq], burst_sz - enq);\n+\t\t} while (unlikely(burst_sz != enq));\n+\t\tenq_total_time += rte_rdtsc() - enq_start_time;\n+\n+\t\t/* ensure enqueue has been completed */\n+\t\trte_delay_ms(10);\n+\n+\t\t/* Start time measurment for dequeue function offload latency */\n+\t\tdeq_start_time = rte_rdtsc();\n+\t\tdo {\n+\t\t\tdeq += rte_bbdev_dequeue_ops(ad->dev_id, queue_id,\n+\t\t\t\t\t&ops[deq], burst_sz - deq);\n+\t\t} while (unlikely(burst_sz != deq));\n+\t\tdeq_total_time += rte_rdtsc() - deq_start_time;\n+\n+\t\trte_bbdev_op_free_bulk(ops, deq);\n+\t\tdequeued += deq;\n+\t}\n+\n+\tprintf(\"\\tenq offload avg. latency: %lg cycles, %lg us\\n\",\n+\t\t\t(double)enq_total_time / (double)i,\n+\t\t\t(double)(enq_total_time * 1000000) / (double)i /\n+\t\t\t(double)rte_get_tsc_hz());\n+\n+\tprintf(\"\\tdeq offload avg. latency: %lg cycles, %lg us\\n\",\n+\t\t\t(double)deq_total_time / (double)i,\n+\t\t\t(double)(deq_total_time * 1000000) / (double)i /\n+\t\t\t(double)rte_get_tsc_hz());\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+offload_latency_empty_q_test(struct active_device *ad,\n+\t\tstruct test_op_params *op_params)\n+{\n+\tuint16_t i, deq_total;\n+\tstruct rte_bbdev_op *ops[MAX_BURST];\n+\tuint64_t deq_start_time, deq_total_time = 0;\n+\tuint16_t burst_sz = op_params->burst_sz;\n+\tconst uint16_t num_to_process = op_params->num_to_process;\n+\tconst enum rte_bbdev_op_type op_type = op_params->ref_op->type;\n+\tconst uint16_t queue_id = ad->queue_ids[0];\n+\tstruct rte_bbdev_info info;\n+\n+\trte_bbdev_info_get(ad->dev_id, &info);\n+\n+\tprintf(\n+\t\t\"Offload latency empty dequeue test: dev: %s, burst size: %u, num ops: %u, op type: %s\\n\",\n+\t\t\tinfo.dev_name, burst_sz, num_to_process,\n+\t\t\trte_bbdev_op_type_str(op_type));\n+\n+\t/* Test deq offload latency from an empty queue */\n+\tdeq_start_time = rte_rdtsc_precise();\n+\tfor (i = 0, deq_total = 0; deq_total < num_to_process;\n+\t\t\t++i, deq_total += burst_sz) {\n+\t\tif (unlikely(num_to_process - deq_total < burst_sz))\n+\t\t\tburst_sz = num_to_process - deq_total;\n+\t\trte_bbdev_dequeue_ops(ad->dev_id, queue_id, ops, burst_sz);\n+\t}\n+\tdeq_total_time = rte_rdtsc_precise() - deq_start_time;\n+\n+\tprintf(\"\\tempty deq offload avg. latency: %lg cycles, %lg us\\n\",\n+\t\t\t(double)deq_total_time / (double)i,\n+\t\t\t(double)(deq_total_time * 1000000) / (double)i /\n+\t\t\t(double)rte_get_tsc_hz());\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+throughput_tc(void)\n+{\n+\treturn run_test_case(throughput_test);\n+}\n+\n+static int\n+offload_latency_tc(void)\n+{\n+\treturn run_test_case(offload_latency_test);\n+}\n+\n+static int\n+offload_latency_empty_q_tc(void)\n+{\n+\treturn run_test_case(offload_latency_empty_q_test);\n+}\n+\n+static int\n+operation_latency_tc(void)\n+{\n+\treturn run_test_case(operation_latency_test);\n+}\n+\n+static int\n+interrupt_tc(void)\n+{\n+\treturn run_test_case(throughput_test);\n+}\n+\n+static struct unit_test_suite bbdev_throughput_testsuite = {\n+\t.suite_name = \"BBdev Throughput Tests\",\n+\t.setup = testsuite_setup,\n+\t.teardown = testsuite_teardown,\n+\t.unit_test_cases = {\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown, throughput_tc),\n+\t\tTEST_CASES_END() /**< NULL terminate unit test array */\n+\t}\n+};\n+\n+static struct unit_test_suite bbdev_validation_testsuite = {\n+\t.suite_name = \"BBdev Validation Tests\",\n+\t.setup = testsuite_setup,\n+\t.teardown = testsuite_teardown,\n+\t.unit_test_cases = {\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown, operation_latency_tc),\n+\t\tTEST_CASES_END() /**< NULL terminate unit test array */\n+\t}\n+};\n+\n+static struct unit_test_suite bbdev_latency_testsuite = {\n+\t.suite_name = \"BBdev Latency Tests\",\n+\t.setup = testsuite_setup,\n+\t.teardown = testsuite_teardown,\n+\t.unit_test_cases = {\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown, offload_latency_tc),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown, offload_latency_empty_q_tc),\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown, operation_latency_tc),\n+\t\tTEST_CASES_END() /**< NULL terminate unit test array */\n+\t}\n+};\n+\n+static struct unit_test_suite bbdev_interrupt_testsuite = {\n+\t.suite_name = \"BBdev Interrupt Tests\",\n+\t.setup = interrupt_testsuite_setup,\n+\t.teardown = testsuite_teardown,\n+\t.unit_test_cases = {\n+\t\tTEST_CASE_ST(ut_setup, ut_teardown, interrupt_tc),\n+\t\tTEST_CASES_END() /**< NULL terminate unit test array */\n+\t}\n+};\n+\n+REGISTER_TEST_COMMAND(throughput, bbdev_throughput_testsuite);\n+REGISTER_TEST_COMMAND(validation, bbdev_validation_testsuite);\n+REGISTER_TEST_COMMAND(latency, bbdev_latency_testsuite);\n+REGISTER_TEST_COMMAND(interrupt, bbdev_interrupt_testsuite);\ndiff --git a/app/test-bbdev/test_bbdev_vector.c b/app/test-bbdev/test_bbdev_vector.c\nnew file mode 100644\nindex 0000000..a6b691a\n--- /dev/null\n+++ b/app/test-bbdev/test_bbdev_vector.c\n@@ -0,0 +1,852 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 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 <stdio.h>\n+#include <stdbool.h>\n+#include <rte_malloc.h>\n+\n+#include \"test_bbdev_vector.h\"\n+\n+#define VALUE_DELIMITER \",\"\n+#define ENTRY_DELIMITER \"=\"\n+\n+const char *op_data_prefixes[] = {\n+\t\"input\",\n+\t\"soft_output\",\n+\t\"hard_output\",\n+};\n+\n+/* trim leading and trailing spaces */\n+static void\n+trim_space(char *str)\n+{\n+\tchar *start, *end;\n+\n+\tfor (start = str; *start; start++) {\n+\t\tif (!isspace((unsigned char) start[0]))\n+\t\t\tbreak;\n+\t}\n+\n+\tfor (end = start + strlen(start); end > start + 1; end--) {\n+\t\tif (!isspace((unsigned char) end[-1]))\n+\t\t\tbreak;\n+\t}\n+\n+\t*end = 0;\n+\n+\t/* Shift from \"start\" to the beginning of the string */\n+\tif (start > str)\n+\t\tmemmove(str, start, (end - start) + 1);\n+}\n+\n+static bool\n+starts_with(const char *str, const char *pre)\n+{\n+\treturn strncmp(pre, str, strlen(pre)) == 0;\n+}\n+\n+/* tokenization test values separated by a comma */\n+static int\n+parse_values(char *tokens, uint32_t **data, uint32_t *data_length)\n+{\n+\tuint32_t n_tokens = 0;\n+\tuint32_t data_size = 32;\n+\n+\tuint32_t *values, *values_resized;\n+\tchar *tok, *error = NULL;\n+\n+\ttok = strtok(tokens, VALUE_DELIMITER);\n+\tif (tok == NULL)\n+\t\treturn -1;\n+\n+\tvalues = (uint32_t *)\n+\t\t\trte_zmalloc(NULL, sizeof(uint32_t) * data_size, 0);\n+\tif (values == NULL)\n+\t\treturn -1;\n+\n+\twhile (tok != NULL) {\n+\t\tvalues_resized = NULL;\n+\n+\t\tif (n_tokens >= data_size) {\n+\t\t\tdata_size *= 2;\n+\n+\t\t\tvalues_resized = (uint32_t *) rte_realloc(values,\n+\t\t\t\tsizeof(uint32_t) * data_size, 0);\n+\t\t\tif (values_resized == NULL) {\n+\t\t\t\trte_free(values);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tvalues = values_resized;\n+\t\t}\n+\n+\t\tvalues[n_tokens] = (uint32_t) strtoul(tok, &error, 0);\n+\t\tif ((error == NULL) || (*error != '\\0')) {\n+\t\t\tprintf(\"Failed with convert '%s'\\n\", tok);\n+\t\t\trte_free(values);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t*data_length = *data_length + (strlen(tok) - strlen(\"0x\"))/2;\n+\n+\t\ttok = strtok(NULL, VALUE_DELIMITER);\n+\t\tif (tok == NULL)\n+\t\t\tbreak;\n+\n+\t\tn_tokens++;\n+\t}\n+\n+\tvalues_resized = (uint32_t *) rte_realloc(values,\n+\t\tsizeof(uint32_t) * (n_tokens + 1), 0);\n+\n+\tif (values_resized == NULL) {\n+\t\trte_free(values);\n+\t\treturn -1;\n+\t}\n+\n+\t*data = values_resized;\n+\n+\treturn 0;\n+}\n+\n+/* convert turbo decoder flag from string to unsigned long int*/\n+static int\n+op_decoder_flag_strtoul(char *token, uint32_t *op_flag_value)\n+{\n+\tif (!strcmp(token, \"RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE;\n+\telse if (!strcmp(token, \"RTE_BBDEV_TURBO_CRC_TYPE_24B\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_CRC_TYPE_24B;\n+\telse if (!strcmp(token, \"RTE_BBDEV_TURBO_EQUALIZER\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_EQUALIZER;\n+\telse if (!strcmp(token, \"RTE_BBDEV_TURBO_SOFT_OUT_SATURATE\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_SOFT_OUT_SATURATE;\n+\telse if (!strcmp(token, \"RTE_BBDEV_TURBO_HALF_ITERATION_EVEN\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_HALF_ITERATION_EVEN;\n+\telse if (!strcmp(token, \"RTE_BBDEV_TURBO_CONTINUE_CRC_MATCH\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_CONTINUE_CRC_MATCH;\n+\telse if (!strcmp(token, \"RTE_BBDEV_TURBO_SOFT_OUTPUT\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_SOFT_OUTPUT;\n+\telse if (!strcmp(token, \"RTE_BBDEV_TURBO_EARLY_TERMINATION\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_EARLY_TERMINATION;\n+\telse if (!strcmp(token, \"RTE_BBDEV_TURBO_RAW_INPUT_DATA\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_RAW_INPUT_DATA;\n+\telse {\n+\t\tprintf(\"The given value is not a turbo decoder flag\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* convert turbo encoder flag from string to unsigned long int*/\n+static int\n+op_encoder_flag_strtoul(char *token, uint32_t *op_flag_value)\n+{\n+\tif (!strcmp(token, \"RTE_BBDEV_TURBO_RV_INDEX_BYPASS\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_RV_INDEX_BYPASS;\n+\telse if (!strcmp(token, \"RTE_BBDEV_TURBO_RATE_MATCH\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_RATE_MATCH;\n+\telse if (!strcmp(token, \"RTE_BBDEV_TURBO_CRC_24B_ATTACH\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_CRC_24B_ATTACH;\n+\telse if (!strcmp(token, \"RTE_BBDEV_TURBO_CRC_24A_ATTACH\"))\n+\t\t*op_flag_value = RTE_BBDEV_TURBO_CRC_24A_ATTACH;\n+\telse {\n+\t\tprintf(\"The given value is not a turbo encoder flag\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* tokenization turbo decoder/encoder flags values separated by a comma */\n+static int\n+parse_turbo_flags(char *tokens, uint32_t *op_flags,\n+\t\tenum rte_bbdev_op_type op_type)\n+{\n+\tchar *tok = NULL;\n+\tuint32_t op_flag_value = 0;\n+\n+\ttok = strtok(tokens, VALUE_DELIMITER);\n+\tif (tok == NULL)\n+\t\treturn -1;\n+\n+\twhile (tok != NULL) {\n+\t\ttrim_space(tok);\n+\t\tif (op_type == RTE_BBDEV_OP_TURBO_DEC) {\n+\t\t\tif (op_decoder_flag_strtoul(tok, &op_flag_value) == -1)\n+\t\t\t\treturn -1;\n+\t\t} else if (op_type == RTE_BBDEV_OP_TURBO_ENC) {\n+\t\t\tif (op_encoder_flag_strtoul(tok, &op_flag_value) == -1)\n+\t\t\t\treturn -1;\n+\t\t} else {\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t*op_flags = *op_flags | op_flag_value;\n+\n+\t\ttok = strtok(NULL, VALUE_DELIMITER);\n+\t\tif (tok == NULL)\n+\t\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* convert turbo encoder/decoder op_type from string to enum*/\n+static int\n+op_turbo_type_strtol(char *token, enum rte_bbdev_op_type *op_type)\n+{\n+\ttrim_space(token);\n+\tif (!strcmp(token, \"RTE_BBDEV_OP_TURBO_DEC\"))\n+\t\t*op_type = RTE_BBDEV_OP_TURBO_DEC;\n+\telse if (!strcmp(token, \"RTE_BBDEV_OP_TURBO_ENC\"))\n+\t\t*op_type = RTE_BBDEV_OP_TURBO_ENC;\n+\telse if (!strcmp(token, \"RTE_BBDEV_OP_NONE\"))\n+\t\t*op_type = RTE_BBDEV_OP_NONE;\n+\telse {\n+\t\tprintf(\"Not valid turbo op_type: '%s'\\n\", token);\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* tokenization expected status values separated by a comma */\n+static int\n+parse_expected_status(char *tokens, int *status, enum rte_bbdev_op_type op_type)\n+{\n+\tchar *tok = NULL;\n+\tbool status_ok = false;\n+\n+\ttok = strtok(tokens, VALUE_DELIMITER);\n+\tif (tok == NULL)\n+\t\treturn -1;\n+\n+\twhile (tok != NULL) {\n+\t\ttrim_space(tok);\n+\t\tif (!strcmp(tok, \"OK\"))\n+\t\t\tstatus_ok = true;\n+\t\telse if (!strcmp(tok, \"DMA\"))\n+\t\t\t*status = *status | (1 << RTE_BBDEV_DRV_ERROR);\n+\t\telse if (!strcmp(tok, \"FCW\"))\n+\t\t\t*status = *status | (1 << RTE_BBDEV_DATA_ERROR);\n+\t\telse if (!strcmp(tok, \"CRC\")) {\n+\t\t\tif (op_type == RTE_BBDEV_OP_TURBO_DEC)\n+\t\t\t\t*status = *status | (1 << RTE_BBDEV_CRC_ERROR);\n+\t\t\telse {\n+\t\t\t\tprintf(\n+\t\t\t\t\t\t\"CRC is only a valid value for turbo decoder\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tprintf(\"Not valid status: '%s'\\n\", tok);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\ttok = strtok(NULL, VALUE_DELIMITER);\n+\t\tif (tok == NULL)\n+\t\t\tbreak;\n+\t}\n+\n+\tif (status_ok && *status != 0) {\n+\t\tprintf(\n+\t\t\t\t\"Not valid status values. Cannot be OK and ERROR at the same time.\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* parse ops data entry (there can be more than 1 input entry, each will be\n+ * contained in a separate op_data_buf struct)\n+ */\n+static int\n+parse_data_entry(const char *key_token, char *token,\n+\t\tstruct test_bbdev_vector *vector, enum op_data_type type,\n+\t\tconst char *prefix)\n+{\n+\tint ret;\n+\tuint32_t data_length = 0;\n+\tuint32_t *data = NULL;\n+\tunsigned int id;\n+\tstruct op_data_buf *op_data;\n+\tunsigned int *nb_ops;\n+\n+\tif (type < 0 || type > DATA_NUM_TYPES) {\n+\t\tprintf(\"Unknown op type: %d!\\n\", type);\n+\t\treturn -1;\n+\t}\n+\n+\top_data = vector->entries[type].segments;\n+\tnb_ops = &vector->entries[type].nb_segments;\n+\n+\tif (*nb_ops >= RTE_BBDEV_MAX_CODE_BLOCKS) {\n+\t\tprintf(\"Too many segments (code blocks defined): %u, max %d!\\n\",\n+\t\t\t\t*nb_ops, RTE_BBDEV_MAX_CODE_BLOCKS);\n+\t\treturn -1;\n+\t}\n+\n+\tif (sscanf(key_token + strlen(prefix), \"%u\", &id) != 1) {\n+\t\tprintf(\"Missing ID of %s\\n\", prefix);\n+\t\treturn -1;\n+\t}\n+\tif (id != *nb_ops) {\n+\t\tprintf(\n+\t\t\t\"Please order data entries sequentially, i.e. %s0, %s1, ...\\n\",\n+\t\t\t\tprefix, prefix);\n+\t\treturn -1;\n+\t}\n+\n+\t/* Clear new op data struct */\n+\tmemset(op_data + *nb_ops, 0, sizeof(struct op_data_buf));\n+\n+\tret = parse_values(token, &data, &data_length);\n+\tif (!ret) {\n+\t\top_data[*nb_ops].addr = data;\n+\t\top_data[*nb_ops].length = data_length;\n+\t\t++(*nb_ops);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+/* parses turbo decoder parameters and assigns to global variable */\n+static int\n+parse_decoder_params(const char *key_token, char *token,\n+\t\tstruct test_bbdev_vector *vector)\n+{\n+\tint ret = 0, status = 0;\n+\tuint32_t op_flags = 0;\n+\tchar *err = NULL;\n+\n+\tstruct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;\n+\n+\t/* compare keys */\n+\tif (starts_with(key_token, op_data_prefixes[DATA_INPUT]))\n+\t\tret = parse_data_entry(key_token, token, vector,\n+\t\t\t\tDATA_INPUT, op_data_prefixes[DATA_INPUT]);\n+\n+\telse if (starts_with(key_token, op_data_prefixes[DATA_SOFT_OUTPUT]))\n+\t\tret = parse_data_entry(key_token, token, vector,\n+\t\t\t\tDATA_SOFT_OUTPUT,\n+\t\t\t\top_data_prefixes[DATA_SOFT_OUTPUT]);\n+\n+\telse if (starts_with(key_token, op_data_prefixes[DATA_HARD_OUTPUT]))\n+\t\tret = parse_data_entry(key_token, token, vector,\n+\t\t\t\tDATA_HARD_OUTPUT,\n+\t\t\t\top_data_prefixes[DATA_HARD_OUTPUT]);\n+\telse if (!strcmp(key_token, \"e\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_E;\n+\t\tturbo_dec->cb_params.e = (uint32_t) strtoul(token, &err, 0);\n+\t} else if (!strcmp(key_token, \"ea\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_EA;\n+\t\tturbo_dec->tb_params.ea = (uint32_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"eb\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_EB;\n+\t\tturbo_dec->tb_params.eb = (uint32_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"k\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_K;\n+\t\tturbo_dec->cb_params.k = (uint16_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"k_pos\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_K_POS;\n+\t\tturbo_dec->tb_params.k_pos = (uint16_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"k_neg\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_K_NEG;\n+\t\tturbo_dec->tb_params.k_neg = (uint16_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"c\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_C;\n+\t\tturbo_dec->tb_params.c = (uint16_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"c_neg\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_C_NEG;\n+\t\tturbo_dec->tb_params.c_neg = (uint16_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"cab\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_CAB;\n+\t\tturbo_dec->tb_params.cab = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"rv_index\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_RV_INDEX;\n+\t\tturbo_dec->rv_index = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"iter_max\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_ITER_MAX;\n+\t\tturbo_dec->iter_max = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"iter_min\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_ITER_MIN;\n+\t\tturbo_dec->iter_min = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"expected_iter_count\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_EXPECTED_ITER_COUNT;\n+\t\tturbo_dec->iter_count = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"ext_scale\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_EXT_SCALE;\n+\t\tturbo_dec->ext_scale = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"num_maps\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_NUM_MAPS;\n+\t\tturbo_dec->num_maps = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"code_block_mode\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_CODE_BLOCK_MODE;\n+\t\tturbo_dec->code_block_mode = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"op_flags\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_OP_FLAGS;\n+\t\tret = parse_turbo_flags(token, &op_flags,\n+\t\t\tvector->op_type);\n+\t\tif (!ret)\n+\t\t\tturbo_dec->op_flags = op_flags;\n+\t} else if (!strcmp(key_token, \"expected_status\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_EXPECTED_STATUS;\n+\t\tret = parse_expected_status(token, &status, vector->op_type);\n+\t\tif (!ret)\n+\t\t\tvector->expected_status = status;\n+\t} else {\n+\t\tprintf(\"Not valid dec key: '%s'\\n\", key_token);\n+\t\treturn -1;\n+\t}\n+\n+\tif (ret != 0) {\n+\t\tprintf(\"Failed with convert '%s\\t%s'\\n\", key_token, token);\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* parses turbo encoder parameters and assigns to global variable */\n+static int\n+parse_encoder_params(const char *key_token, char *token,\n+\t\tstruct test_bbdev_vector *vector)\n+{\n+\tint ret = 0, status = 0;\n+\tuint32_t op_flags = 0;\n+\tchar *err = NULL;\n+\n+\n+\tstruct rte_bbdev_op_turbo_enc *turbo_enc = &vector->turbo_enc;\n+\n+\tif (starts_with(key_token, op_data_prefixes[DATA_INPUT]))\n+\t\tret = parse_data_entry(key_token, token, vector,\n+\t\t\t\tDATA_INPUT, op_data_prefixes[DATA_INPUT]);\n+\telse if (starts_with(key_token, \"output\"))\n+\t\tret = parse_data_entry(key_token, token, vector,\n+\t\t\t\tDATA_HARD_OUTPUT, \"output\");\n+\telse if (!strcmp(key_token, \"e\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_E;\n+\t\tturbo_enc->cb_params.e = (uint32_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"ea\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_EA;\n+\t\tturbo_enc->tb_params.ea = (uint32_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"eb\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_EB;\n+\t\tturbo_enc->tb_params.eb = (uint32_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"k\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_K;\n+\t\tturbo_enc->cb_params.k = (uint16_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"k_neg\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_K_NEG;\n+\t\tturbo_enc->tb_params.k_neg = (uint16_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"k_pos\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_K_POS;\n+\t\tturbo_enc->tb_params.k_pos = (uint16_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"c_neg\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_C_NEG;\n+\t\tturbo_enc->tb_params.c_neg = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"c\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_C;\n+\t\tturbo_enc->tb_params.c = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"cab\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_CAB;\n+\t\tturbo_enc->tb_params.cab = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"rv_index\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_RV_INDEX;\n+\t\tturbo_enc->rv_index = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"ncb\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_NCB;\n+\t\tturbo_enc->cb_params.ncb = (uint16_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"ncb_neg\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_NCB_NEG;\n+\t\tturbo_enc->tb_params.ncb_neg =\n+\t\t\t\t(uint16_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"ncb_pos\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_NCB_POS;\n+\t\tturbo_enc->tb_params.ncb_pos =\n+\t\t\t\t(uint16_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"code_block_mode\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_CODE_BLOCK_MODE;\n+\t\tturbo_enc->code_block_mode = (uint8_t) strtoul(token, &err, 0);\n+\t\tret = ((err == NULL) || (*err != '\\0')) ? -1 : 0;\n+\t} else if (!strcmp(key_token, \"op_flags\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_OP_FLAGS;\n+\t\tret = parse_turbo_flags(token, &op_flags,\n+\t\t\t\tvector->op_type);\n+\t\tif (!ret)\n+\t\t\tturbo_enc->op_flags = op_flags;\n+\t} else if (!strcmp(key_token, \"expected_status\")) {\n+\t\tvector->mask |= TEST_BBDEV_VF_EXPECTED_STATUS;\n+\t\tret = parse_expected_status(token, &status, vector->op_type);\n+\t\tif (!ret)\n+\t\t\tvector->expected_status = status;\n+\t} else {\n+\t\tprintf(\"Not valid enc key: '%s'\\n\", key_token);\n+\t\treturn -1;\n+\t}\n+\n+\tif (ret != 0) {\n+\t\tprintf(\"Failed with convert '%s\\t%s'\\n\", key_token, token);\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* checks the type of key and assigns data */\n+static int\n+parse_entry(char *entry, struct test_bbdev_vector *vector)\n+{\n+\tint ret = 0;\n+\tchar *token, *key_token;\n+\tenum rte_bbdev_op_type op_type = RTE_BBDEV_OP_NONE;\n+\n+\tif (entry == NULL) {\n+\t\tprintf(\"Expected entry value\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\t/* get key */\n+\ttoken = strtok(entry, ENTRY_DELIMITER);\n+\tkey_token = token;\n+\t/* get values for key */\n+\ttoken = strtok(NULL, ENTRY_DELIMITER);\n+\n+\tif (key_token == NULL || token == NULL) {\n+\t\tprintf(\"Expected 'key = values' but was '%.40s'..\\n\", entry);\n+\t\treturn -1;\n+\t}\n+\ttrim_space(key_token);\n+\n+\t/* first key_token has to specify type of operation */\n+\tif (vector->op_type == RTE_BBDEV_OP_NONE) {\n+\t\tif (!strcmp(key_token, \"op_type\")) {\n+\t\t\tret = op_turbo_type_strtol(token, &op_type);\n+\t\t\tif (!ret)\n+\t\t\t\tvector->op_type = op_type;\n+\t\t\treturn (!ret) ? 0 : -1;\n+\t\t}\n+\t\tprintf(\"First key_token (%s) does not specify op_type\\n\",\n+\t\t\t\tkey_token);\n+\t\treturn -1;\n+\t}\n+\n+\t/* compare keys */\n+\tif (vector->op_type == RTE_BBDEV_OP_TURBO_DEC) {\n+\t\tif (parse_decoder_params(key_token, token, vector) == -1)\n+\t\t\treturn -1;\n+\t} else if (vector->op_type == RTE_BBDEV_OP_TURBO_ENC) {\n+\t\tif (parse_encoder_params(key_token, token, vector) == -1)\n+\t\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* checks decoder parameters */\n+static int\n+check_decoder(struct test_bbdev_vector *vector, const int mask)\n+{\n+\tstruct rte_bbdev_op_turbo_dec *turbo_dec = &vector->turbo_dec;\n+\n+\tif (vector->entries[DATA_INPUT].nb_segments == 0 ||\n+\t\t\tvector->entries[DATA_INPUT].segments == NULL)\n+\t\treturn -1;\n+\tif (vector->entries[DATA_HARD_OUTPUT].nb_segments == 0 ||\n+\t\t\tvector->entries[DATA_HARD_OUTPUT].segments == NULL)\n+\t\treturn -1;\n+\tif ((turbo_dec->op_flags & RTE_BBDEV_TURBO_SOFT_OUTPUT) &&\n+\t\t\t(vector->entries[DATA_SOFT_OUTPUT].nb_segments == 0 ||\n+\t\t\tvector->entries[DATA_SOFT_OUTPUT].segments == NULL))\n+\t\treturn -1;\n+\n+\tif (!(mask & TEST_BBDEV_VF_CODE_BLOCK_MODE)) {\n+\t\tprintf(\n+\t\t\t\"WARNING: code_block_mode was not specified in vector file and will be set to 1 (0 - TB Mode, 1 - CB mode)\\n\");\n+\t\tturbo_dec->code_block_mode = 1;\n+\t}\n+\tif (turbo_dec->code_block_mode == 0) {\n+\t\tif (!(mask & TEST_BBDEV_VF_EA))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: ea was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_EB))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: eb was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_K_NEG))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: k_neg was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_K_POS))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: k_pos was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_C_NEG))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: c_neg was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_C)) {\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: c was not specified in vector file and will be set to 1\\n\");\n+\t\t\tturbo_dec->tb_params.c = 1;\n+\t\t}\n+\t\tif (!(mask & TEST_BBDEV_VF_CAB))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: cab was not specified in vector file and will be set to 0\\n\");\n+\t} else {\n+\t\tif (!(mask & TEST_BBDEV_VF_E))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: e was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_K))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: k was not specified in vector file and will be set to 0\\n\");\n+\t}\n+\tif (!(mask & TEST_BBDEV_VF_RV_INDEX))\n+\t\tprintf(\n+\t\t\t\"WARNING: rv_index was not specified in vector file and will be set to 0\\n\");\n+\tif (!(mask & TEST_BBDEV_VF_ITER_MIN))\n+\t\tprintf(\n+\t\t\t\"WARNING: iter_min was not specified in vector file and will be set to 0\\n\");\n+\tif (!(mask & TEST_BBDEV_VF_ITER_MAX))\n+\t\tprintf(\n+\t\t\t\"WARNING: iter_max was not specified in vector file and will be set to 0\\n\");\n+\tif (!(mask & TEST_BBDEV_VF_EXPECTED_ITER_COUNT))\n+\t\tprintf(\n+\t\t\t\"WARNING: expected_iter_count was not specified in vector file and iter_count will not be validated\\n\");\n+\tif (!(mask & TEST_BBDEV_VF_EXT_SCALE))\n+\t\tprintf(\n+\t\t\t\"WARNING: ext_scale was not specified in vector file and will be set to 0\\n\");\n+\tif (!(mask & TEST_BBDEV_VF_NUM_MAPS))\n+\t\tprintf(\n+\t\t\t\"WARNING: num_maps was not specified in vector file and will be set to 0\\n\");\n+\tif (!(mask & TEST_BBDEV_VF_OP_FLAGS))\n+\t\tprintf(\n+\t\t\t\"WARNING: op_flags was not specified in vector file and capabilities will not be validated\\n\");\n+\tif (!(mask & TEST_BBDEV_VF_EXPECTED_STATUS))\n+\t\tprintf(\n+\t\t\t\"WARNING: expected_status was not specified in vector file and will be set to 0\\n\");\n+\treturn 0;\n+}\n+\n+/* checks encoder parameters */\n+static int\n+check_encoder(struct test_bbdev_vector *vector, const int mask)\n+{\n+\tif (vector->entries[DATA_INPUT].nb_segments == 0 ||\n+\t\t\tvector->entries[DATA_INPUT].segments == NULL)\n+\t\treturn -1;\n+\tif (vector->entries[DATA_HARD_OUTPUT].nb_segments == 0 ||\n+\t\t\tvector->entries[DATA_HARD_OUTPUT].segments == NULL)\n+\t\treturn -1;\n+\n+\tif (!(mask & TEST_BBDEV_VF_CODE_BLOCK_MODE)) {\n+\t\tprintf(\n+\t\t\t\"WARNING: code_block_mode was not specified in vector file and will be set to 1\\n\");\n+\t\tvector->turbo_enc.code_block_mode = 1;\n+\t}\n+\tif (vector->turbo_enc.code_block_mode == 0) {\n+\t\tif (!(mask & TEST_BBDEV_VF_EA))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: ea was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_EB))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: eb was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_K_NEG))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: k_neg was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_K_POS))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: k_pos was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_C_NEG))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: c_neg was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_C)) {\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: c was not specified in vector file and will be set to 1\\n\");\n+\t\t\tvector->turbo_enc.tb_params.c = 1;\n+\t\t}\n+\t\tif (!(mask & TEST_BBDEV_VF_CAB))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: cab was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_NCB_NEG))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: ncb_neg was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_NCB_POS))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: ncb_pos was not specified in vector file and will be set to 0\\n\");\n+\t} else {\n+\t\tif (!(mask & TEST_BBDEV_VF_E))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: e was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_K))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: k was not specified in vector file and will be set to 0\\n\");\n+\t\tif (!(mask & TEST_BBDEV_VF_NCB))\n+\t\t\tprintf(\n+\t\t\t\t\"WARNING: ncb was not specified in vector file and will be set to 0\\n\");\n+\t}\n+\tif (!(mask & TEST_BBDEV_VF_RV_INDEX))\n+\t\tprintf(\n+\t\t\t\"WARNING: rv_index was not specified in vector file and will be set to 0\\n\");\n+\tif (!(mask & TEST_BBDEV_VF_OP_FLAGS))\n+\t\tprintf(\n+\t\t\t\"WARNING: op_flags was not specified in vector file and capabilities will not be validated\\n\");\n+\tif (!(mask & TEST_BBDEV_VF_EXPECTED_STATUS))\n+\t\tprintf(\n+\t\t\t\"WARNING: expected_status was not specified in vector file and will be set to 0\\n\");\n+\n+\treturn 0;\n+}\n+\n+static int\n+bbdev_check_vector(struct test_bbdev_vector *vector)\n+{\n+\tif (vector->op_type == RTE_BBDEV_OP_TURBO_DEC) {\n+\t\tif (check_decoder(vector, vector->mask) == -1)\n+\t\t\treturn -1;\n+\t} else if (vector->op_type == RTE_BBDEV_OP_TURBO_ENC) {\n+\t\tif (check_encoder(vector, vector->mask) == -1)\n+\t\t\treturn -1;\n+\t} else if (vector->op_type != RTE_BBDEV_OP_NONE) {\n+\t\tprintf(\"Vector was not filled\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+test_bbdev_vector_read(const char *filename,\n+\t\tstruct test_bbdev_vector *vector)\n+{\n+\tint ret = 0;\n+\tsize_t len = 0;\n+\n+\tFILE *fp = NULL;\n+\tchar *line = NULL;\n+\tchar *entry = NULL;\n+\n+\tfp = fopen(filename, \"r\");\n+\tif (fp == NULL) {\n+\t\tprintf(\"File %s does not exist\\n\", filename);\n+\t\treturn -1;\n+\t}\n+\n+\twhile (getline(&line, &len, fp) != -1) {\n+\n+\t\t/* ignore comments and new lines */\n+\t\tif (line[0] == '#' || line[0] == '/' || line[0] == '\\n'\n+\t\t\t|| line[0] == '\\r')\n+\t\t\tcontinue;\n+\n+\t\ttrim_space(line);\n+\n+\t\t/* buffer for multiline */\n+\t\tentry = realloc(entry, strlen(line) + 1);\n+\t\tif (entry == NULL) {\n+\t\t\tprintf(\"Fail to realloc %zu bytes\\n\", strlen(line) + 1);\n+\t\t\tret = -ENOMEM;\n+\t\t\tgoto exit;\n+\t\t}\n+\n+\t\tmemset(entry, 0, strlen(line) + 1);\n+\t\tstrncpy(entry, line, strlen(line));\n+\n+\t\t/* check if entry ends with , or = */\n+\t\tif (entry[strlen(entry) - 1] == ','\n+\t\t\t|| entry[strlen(entry) - 1] == '=') {\n+\t\t\twhile (getline(&line, &len, fp) != -1) {\n+\t\t\t\ttrim_space(line);\n+\n+\t\t\t\t/* extend entry about length of new line */\n+\t\t\t\tchar *entry_extended = realloc(entry,\n+\t\t\t\t\t\tstrlen(line) +\n+\t\t\t\t\t\tstrlen(entry) + 1);\n+\n+\t\t\t\tif (entry_extended == NULL) {\n+\t\t\t\t\tprintf(\"Fail to allocate %zu bytes\\n\",\n+\t\t\t\t\t\t\tstrlen(line) +\n+\t\t\t\t\t\t\tstrlen(entry) + 1);\n+\t\t\t\t\tret = -ENOMEM;\n+\t\t\t\t\tgoto exit;\n+\t\t\t\t}\n+\n+\t\t\t\tentry = entry_extended;\n+\t\t\t\tstrncat(entry, line, strlen(line));\n+\n+\t\t\t\tif (entry[strlen(entry) - 1] != ',')\n+\t\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\tret = parse_entry(entry, vector);\n+\t\tif (ret != 0) {\n+\t\t\tprintf(\"An error occurred while parsing!\\n\");\n+\t\t\tgoto exit;\n+\t\t}\n+\t}\n+\n+\tret = bbdev_check_vector(vector);\n+\tif (ret != 0)\n+\t\tprintf(\"An error occurred while checking!\\n\");\n+\n+exit:\n+\tfclose(fp);\n+\tfree(line);\n+\tfree(entry);\n+\n+\treturn ret;\n+}\ndiff --git a/app/test-bbdev/test_bbdev_vector.h b/app/test-bbdev/test_bbdev_vector.h\nnew file mode 100644\nindex 0000000..75de330\n--- /dev/null\n+++ b/app/test-bbdev/test_bbdev_vector.h\n@@ -0,0 +1,98 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 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 TEST_BBDEV_VECTOR_H_\n+#define TEST_BBDEV_VECTOR_H_\n+\n+#include <rte_bbdev_op.h>\n+\n+/* Flags which are set when specific parameter is define in vector file */\n+enum {\n+\tTEST_BBDEV_VF_E = (1ULL << 0),\n+\tTEST_BBDEV_VF_EA = (1ULL << 1),\n+\tTEST_BBDEV_VF_EB = (1ULL << 2),\n+\tTEST_BBDEV_VF_K = (1ULL << 3),\n+\tTEST_BBDEV_VF_K_NEG = (1ULL << 4),\n+\tTEST_BBDEV_VF_K_POS = (1ULL << 5),\n+\tTEST_BBDEV_VF_C_NEG = (1ULL << 6),\n+\tTEST_BBDEV_VF_C = (1ULL << 7),\n+\tTEST_BBDEV_VF_CAB = (1ULL << 8),\n+\tTEST_BBDEV_VF_RV_INDEX = (1ULL << 9),\n+\tTEST_BBDEV_VF_ITER_MAX = (1ULL << 10),\n+\tTEST_BBDEV_VF_ITER_MIN = (1ULL << 11),\n+\tTEST_BBDEV_VF_EXPECTED_ITER_COUNT = (1ULL << 12),\n+\tTEST_BBDEV_VF_EXT_SCALE = (1ULL << 13),\n+\tTEST_BBDEV_VF_NUM_MAPS = (1ULL << 14),\n+\tTEST_BBDEV_VF_NCB = (1ULL << 15),\n+\tTEST_BBDEV_VF_NCB_NEG = (1ULL << 16),\n+\tTEST_BBDEV_VF_NCB_POS = (1ULL << 17),\n+\tTEST_BBDEV_VF_CODE_BLOCK_MODE = (1ULL << 18),\n+\tTEST_BBDEV_VF_OP_FLAGS = (1ULL << 19),\n+\tTEST_BBDEV_VF_EXPECTED_STATUS = (1ULL << 20),\n+};\n+\n+enum op_data_type {\n+\tDATA_INPUT = 0,\n+\tDATA_SOFT_OUTPUT,\n+\tDATA_HARD_OUTPUT,\n+\tDATA_NUM_TYPES,\n+};\n+\n+struct op_data_buf {\n+\tuint32_t *addr;\n+\tuint32_t length;\n+};\n+\n+struct op_data_entries {\n+\tstruct op_data_buf segments[RTE_BBDEV_MAX_CODE_BLOCKS];\n+\tunsigned int nb_segments;\n+};\n+\n+struct test_bbdev_vector {\n+\tenum rte_bbdev_op_type op_type;\n+\tint expected_status;\n+\tint mask;\n+\tunion {\n+\t\tstruct rte_bbdev_op_turbo_dec turbo_dec;\n+\t\tstruct rte_bbdev_op_turbo_enc turbo_enc;\n+\t};\n+\t/* Additional storage for op data entries */\n+\tstruct op_data_entries entries[DATA_NUM_TYPES];\n+};\n+\n+/* fills test vector paramaters based on test file */\n+int\n+test_bbdev_vector_read(const char *filename,\n+\t\tstruct test_bbdev_vector *vector);\n+\n+\n+#endif /* TEST_BBDEV_VECTOR_H_ */\ndiff --git a/app/test-bbdev/test_vectors/bbdev_vector_null.data b/app/test-bbdev/test_vectors/bbdev_vector_null.data\nnew file mode 100644\nindex 0000000..91aea62\n--- /dev/null\n+++ b/app/test-bbdev/test_vectors/bbdev_vector_null.data\n@@ -0,0 +1,32 @@\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2017 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+op_type =\n+RTE_BBDEV_OP_NONE\n\\ No newline at end of file\ndiff --git a/app/test-bbdev/test_vectors/bbdev_vector_td_default.data b/app/test-bbdev/test_vectors/bbdev_vector_td_default.data\nnew file mode 100644\nindex 0000000..db20640\n--- /dev/null\n+++ b/app/test-bbdev/test_vectors/bbdev_vector_td_default.data\n@@ -0,0 +1,80 @@\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2017 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+op_type =\n+RTE_BBDEV_OP_TURBO_DEC\n+\n+input0 =\n+0x7f007f00, 0x7f817f00, 0x767f8100, 0x817f8100, 0x81008100, 0x7f818100, 0x81817f00, 0x7f818100,\n+0x86007f00, 0x7f818100, 0x887f8100, 0x81815200, 0x81008100, 0x817f7f00, 0x7f7f8100, 0x9e817f00,\n+0x7f7f0000, 0xb97f0000, 0xa7810000, 0x7f7f4a7f, 0x7f810000, 0x7f7f7f7f, 0x81720000, 0x40658181,\n+0x84810000, 0x817f0000, 0x81810000, 0x7f818181, 0x7f810000, 0x81815a81, 0x817f0000, 0x7a867f7b,\n+0x817f0000, 0x6b7f0000, 0x7f810000, 0x81818181, 0x817f0000, 0x7f7f817f, 0x7f7f0000, 0xab7f4f7f,\n+0x817f0000, 0x817f6c00, 0x81810000, 0x817f8181, 0x7f810000, 0x81816981, 0x7f7f0000, 0x007f8181\n+\n+hard_output0 =\n+0xa7d6732e, 0x61\n+\n+soft_output0 =\n+0x7f7f7f7f, 0x81817f7f, 0x7f817f81, 0x817f7f81, 0x81817f81, 0x81817f81, 0x8181817f, 0x7f81817f,\n+0x7f81817f, 0x7f817f7f, 0x81817f7f, 0x817f8181, 0x81818181, 0x817f7f7f, 0x7f818181, 0x817f817f,\n+0x81818181, 0x81817f7f, 0x7f817f81, 0x7f81817f, 0x817f7f7f, 0x817f7f7f, 0x7f81817f, 0x817f817f,\n+0x81817f7f, 0x81817f7f, 0x81817f7f, 0x7f817f7f, 0x817f7f81, 0x7f7f8181, 0x81817f81, 0x817f7f7f,\n+0x7f7f8181\n+\n+e =\n+17280\n+\n+k =\n+40\n+\n+rv_index =\n+1\n+\n+iter_max =\n+8\n+\n+iter_min =\n+4\n+\n+expected_iter_count =\n+8\n+\n+ext_scale =\n+15\n+\n+num_maps =\n+0\n+\n+op_flags =\n+RTE_BBDEV_TURBO_SOFT_OUTPUT, RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE\n+\n+expected_status =\n+OK\ndiff --git a/app/test-bbdev/test_vectors/bbdev_vector_te_default.data b/app/test-bbdev/test_vectors/bbdev_vector_te_default.data\nnew file mode 100644\nindex 0000000..b5cecf4\n--- /dev/null\n+++ b/app/test-bbdev/test_vectors/bbdev_vector_te_default.data\n@@ -0,0 +1,60 @@\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2017 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+op_type =\n+RTE_BBDEV_OP_TURBO_ENC\n+\n+input0 =\n+0x11d2bcac, 0x4d\n+\n+output0 =\n+0xd2399179, 0x640eb999, 0x2cbaf577, 0xaf224ae2, 0x9d139927, 0xe6909b29, 0xa25b7f47, 0x2aa224ce,\n+0x79f2\n+\n+e =\n+272\n+\n+k =\n+40\n+\n+ncb =\n+192\n+\n+rv_index =\n+0\n+\n+code_block_mode =\n+1\n+\n+op_flags =\n+RTE_BBDEV_TURBO_RATE_MATCH\n+\n+expected_status =\n+OK\n",
    "prefixes": [
        "dpdk-dev",
        "v1",
        "3/6"
    ]
}