get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 29449,
    "url": "https://patches.dpdk.org/api/patches/29449/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1506735475-77078-4-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-4-git-send-email-amr.mokhtar@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1506735475-77078-4-git-send-email-amr.mokhtar@intel.com",
    "date": "2017-09-30T01:37:53",
    "name": "[dpdk-dev,v1,4/6] bbdev: sample app",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "26d64b2f042a4f9538c82384380b75fcd35e959e",
    "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-4-git-send-email-amr.mokhtar@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/29449/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/29449/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 53C561B1C0;\n\tSat, 30 Sep 2017 03:38:11 +0200 (CEST)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id 0239B1B1A6\n\tfor <dev@dpdk.org>; Sat, 30 Sep 2017 03:38:05 +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:05 -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:03 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos; i=\"5.42,455,1500966000\"; d=\"scan'208\";\n\ta=\"1020035470\"",
        "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:53 +0100",
        "Message-Id": "<1506735475-77078-4-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 4/6] bbdev: sample app",
        "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 examples/Makefile           |    1 +\n examples/bbdev_app/Makefile |   50 ++\n examples/bbdev_app/main.c   | 1260 +++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 1311 insertions(+)\n create mode 100644 examples/bbdev_app/Makefile\n create mode 100644 examples/bbdev_app/main.c",
    "diff": "diff --git a/examples/Makefile b/examples/Makefile\nindex 28354ff..976deb3 100644\n--- a/examples/Makefile\n+++ b/examples/Makefile\n@@ -101,5 +101,6 @@ endif\n endif\n \n DIRS-y += eventdev_pipeline_sw_pmd\n+DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += bbdev_app\n \n include $(RTE_SDK)/mk/rte.extsubdir.mk\ndiff --git a/examples/bbdev_app/Makefile b/examples/bbdev_app/Makefile\nnew file mode 100644\nindex 0000000..1583251\n--- /dev/null\n+++ b/examples/bbdev_app/Makefile\n@@ -0,0 +1,50 @@\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+ifeq ($(RTE_SDK),)\n+$(error \"Please define RTE_SDK environment variable\")\n+endif\n+\n+# Default target, can be overridden by command line or environment\n+RTE_TARGET ?= x86_64-native-linuxapp-gcc\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+# binary name\n+APP = bbdev\n+\n+# all source are stored in SRCS-y\n+SRCS-y := main.c\n+\n+CFLAGS += -O3\n+CFLAGS += $(WERROR_FLAGS)\n+\n+include $(RTE_SDK)/mk/rte.extapp.mk\ndiff --git a/examples/bbdev_app/main.c b/examples/bbdev_app/main.c\nnew file mode 100644\nindex 0000000..cf656d5\n--- /dev/null\n+++ b/examples/bbdev_app/main.c\n@@ -0,0 +1,1260 @@\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 <stdlib.h>\n+#include <string.h>\n+#include <stdint.h>\n+#include <inttypes.h>\n+#include <sys/types.h>\n+#include <sys/unistd.h>\n+#include <sys/queue.h>\n+#include <stdarg.h>\n+#include <ctype.h>\n+#include <errno.h>\n+#include <math.h>\n+#include <assert.h>\n+#include <getopt.h>\n+#include <signal.h>\n+#include <inttypes.h>\n+\n+#include \"rte_common.h\"\n+#include \"rte_eal.h\"\n+#include \"rte_cycles.h\"\n+#include \"rte_eal.h\"\n+#include \"rte_ether.h\"\n+#include \"rte_ethdev.h\"\n+#include \"rte_ip.h\"\n+#include \"rte_lcore.h\"\n+#include \"rte_malloc.h\"\n+#include \"rte_mbuf.h\"\n+#include \"rte_memory.h\"\n+#include \"rte_mempool.h\"\n+#include \"rte_log.h\"\n+#include \"rte_bbdev.h\"\n+#include \"rte_bbdev_op.h\"\n+\n+#define MAX_PKT_BURST 32\n+#define NB_MBUF 8163\n+#define MAX_RX_QUEUE_PER_LCORE 16\n+#define MAX_TX_QUEUE_PER_LCORE 16\n+#define MEMPOOL_CACHE_SIZE 256\n+\n+/*Configurable number of RX/TX ring descriptors */\n+#define RTE_TEST_RX_DESC_DEFAULT 128\n+#define RTE_TEST_TX_DESC_DEFAULT 512\n+\n+#define BBDEV_ASSERT(a) do { \\\n+\tif (!(a)) { \\\n+\t\tusage(prgname); \\\n+\t\treturn -1; \\\n+\t} \\\n+} while (0)\n+\n+static struct rte_mempool *ethdev_mbuf_mempool;\n+\n+struct dev_qs {\n+\tunsigned int port_id;\n+\tunsigned int queues_list[RTE_MAX_QUEUES_PER_PORT];\n+\tunsigned int queues;\n+};\n+\n+static struct rte_mempool *bbdev_op_pool[RTE_BBDEV_OP_TYPE_COUNT];\n+\n+/**all lcores used*/\n+struct lcore_setup {\n+\tunsigned int rxte_lcores;\n+\tunsigned int rxte_lcore_list[RTE_MAX_LCORE];\n+\tunsigned int tetx_lcores;\n+\tunsigned int tetx_lcore_list[RTE_MAX_LCORE];\n+\tunsigned int rxtd_lcores;\n+\tunsigned int rxtd_lcore_list[RTE_MAX_LCORE];\n+\tunsigned int tdtx_lcores;\n+\tunsigned int tdtx_lcore_list[RTE_MAX_LCORE];\n+};\n+\n+/** each lcore configuration */\n+struct lcore_queue_conf {\n+\tunsigned int nb_ports;\n+\tstruct dev_qs port_list[RTE_MAX_ETHPORTS];\n+\t/* ethernet addresses of ports */\n+\tstruct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS];\n+\n+\tunsigned int bbdev_id;\n+\n+\tunsigned int bbdev_qs[128];\n+\tunsigned int nb_bbdev_qs;\n+\n+\tstruct rte_mempool *mbuf_pool;\n+} __rte_cache_aligned;\n+\n+static struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE];\n+\n+static const struct rte_eth_conf port_conf = {\n+\t.rxmode = {\n+\t\t.mq_mode = ETH_MQ_RX_NONE,\n+\t\t.max_rx_pkt_len = ETHER_MAX_LEN,\n+\t\t.split_hdr_size = 0,\n+\t\t.header_split = 0, /**< Header Split disabled */\n+\t\t.hw_ip_checksum = 0, /**< IP checksum offload disabled */\n+\t\t.hw_vlan_filter = 0, /**< VLAN filtering disabled */\n+\t\t.jumbo_frame = 0, /**< Jumbo Frame Support disabled */\n+\t\t.hw_strip_crc = 0, /**< CRC stripped by hardware */\n+\t},\n+\t.txmode = {\n+\t\t.mq_mode = ETH_MQ_TX_NONE,\n+\t},\n+};\n+\n+struct rte_bbdev_op_turbo_enc def_op_enc = {\n+\t.rv_index = 0,\n+\t.code_block_mode = 1,\n+\t.cb_params.k = 112,\n+\t.cb_params.e = 272,\n+\t.cb_params.ncb = 192,\n+\t.op_flags = RTE_BBDEV_TURBO_CRC_24B_ATTACH\n+};\n+\n+struct rte_bbdev_op_turbo_dec def_op_dec = {\n+\t.cb_params.e = 44,\n+\t.cb_params.k = 112,\n+\t.rv_index = 0,\n+\t.iter_max = 8,\n+\t.iter_min = 4,\n+\t.ext_scale = 15,\n+\t.num_maps = 0,\n+\t.op_flags = RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE |\n+\t\tRTE_BBDEV_TURBO_EQUALIZER | RTE_BBDEV_TURBO_SOFT_OUTPUT\n+};\n+\n+struct bbdev_config_params {\n+\tuint8_t downlink_lcores;\n+\tuint8_t uplink_lcores;\n+\n+\tuint8_t downlink_rx_ports;\n+\tuint8_t downlink_tx_ports;\n+\n+\tuint8_t uplink_rx_ports;\n+\tuint8_t uplink_tx_ports;\n+\n+\tunsigned int rx_port_list[MAX_RX_QUEUE_PER_LCORE];\n+\tunsigned int tx_port_list[MAX_TX_QUEUE_PER_LCORE];\n+};\n+\n+struct lcore_statistics {\n+\tunsigned int enqueued;\n+\tunsigned int dequeued;\n+\tunsigned int lost_packets;\n+} __rte_cache_aligned;\n+\n+static struct lcore_statistics lcore_stats[RTE_MAX_LCORE];\n+\n+static volatile int global_exit_flag;\n+\n+struct port_queues {\n+\tunsigned int nb_rx_qs;\n+\tunsigned int nb_tx_qs;\n+};\n+\n+static struct port_queues ports_qs[RTE_MAX_ETHPORTS];\n+\n+/* display usage */\n+static inline void\n+usage(const char *prgname)\n+{\n+\tprintf(\"%s [EAL options] \"\n+\t\t\"  --\\n\"\n+\t\t\"  --downlink_cores - downlink cores mask\\n\"\n+\t\t\"  --uplink_cores - uplink cores mask\\n\"\n+\t\t\"  --downlink_rx_ports - downlink Rx ports mask\\n\"\n+\t\t\"  --downlink_tx_ports - downlink Tx ports mask\\n\"\n+\t\t\"  --uplink_tx_ports -uplink Tx ports mask\\n\"\n+\t\t\"  --uplink_rx_ports -uplink Rx ports msk\\n\"\n+\t\t\"\\n\", prgname);\n+}\n+\n+/* parse port or core mask */\n+static inline\n+uint8_t bbdev_parse_mask(const char *mask)\n+{\n+\tchar *end = NULL;\n+\tunsigned long pm;\n+\n+\t/* parse hexadecimal string */\n+\tpm = strtoul(mask, &end, 16);\n+\tif ((mask[0] == '\\0') || (end == NULL) || (*end != '\\0'))\n+\t\treturn 0;\n+\n+\tif (pm == 0)\n+\t\treturn 0;\n+\n+\treturn pm;\n+}\n+\n+static int\n+bbdev_parse_args(int argc, char **argv,\n+\t\tstruct bbdev_config_params *bbdev_params)\n+{\n+\tint optind = 0;\n+\tint opt;\n+\tint opt_indx = 0;\n+\tchar *prgname = argv[0];\n+\n+\tmemset(bbdev_params, 0, sizeof(*bbdev_params));\n+\n+\tstatic struct option lgopts[] = {\n+\t\t\t{ \"downlink_cores\", required_argument, 0, 'c' },\n+\t\t\t{ \"uplink_cores\", required_argument, 0, 'C' },\n+\t\t\t{ \"downlink_rx_ports\", required_argument, 0, 'r' },\n+\t\t\t{ \"downlink_tx_ports\", required_argument, 0, 't' },\n+\t\t\t{ \"uplink_rx_ports\", required_argument, 0, 'R' },\n+\t\t\t{ \"uplink_tx_ports\", required_argument, 0, 'T' },\n+\t\t\t{ NULL, 0, 0, 0 }\n+\t};\n+\n+\tBBDEV_ASSERT(argc != 0);\n+\tBBDEV_ASSERT(argv != NULL);\n+\tBBDEV_ASSERT(bbdev_params != NULL);\n+\n+\twhile ((opt = getopt_long(argc, argv, \"c:C:r:t:R:T:\", lgopts,\n+\t\t\t&opt_indx)) != EOF) {\n+\n+\t\tswitch (opt) {\n+\t\tcase 'c':\n+\t\t\tbbdev_params->downlink_lcores =\n+\t\t\t\t\tbbdev_parse_mask(optarg);\n+\t\t\tif (bbdev_params->downlink_lcores == 0) {\n+\t\t\t\tusage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase 'C':\n+\t\t\tbbdev_params->uplink_lcores =\n+\t\t\t\t\tbbdev_parse_mask(optarg);\n+\t\t\tif (bbdev_params->uplink_lcores == 0) {\n+\t\t\t\tusage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase 'r':\n+\t\t\tbbdev_params->downlink_rx_ports =\n+\t\t\t\t\tbbdev_parse_mask(optarg);\n+\t\t\tif (bbdev_params->downlink_rx_ports == 0) {\n+\t\t\t\tusage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase 't':\n+\t\t\tbbdev_params->downlink_tx_ports =\n+\t\t\t\t\tbbdev_parse_mask(optarg);\n+\t\t\tif (bbdev_params->downlink_tx_ports == 0) {\n+\t\t\t\tusage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase 'R':\n+\t\t\tbbdev_params->uplink_rx_ports =\n+\t\t\t\t\tbbdev_parse_mask(optarg);\n+\t\t\tif (bbdev_params->uplink_rx_ports == 0) {\n+\t\t\t\tusage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase 'T':\n+\t\t\tbbdev_params->uplink_tx_ports =\n+\t\t\t\t\tbbdev_parse_mask(optarg);\n+\t\t\tif (bbdev_params->uplink_tx_ports == 0) {\n+\t\t\t\tusage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tdefault:\n+\t\t\tusage(prgname);\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\toptind = 0;\n+\treturn optind;\n+}\n+\n+static void\n+signal_handler(int signum)\n+{\n+\tprintf(\"\\nSignal %d received\", signum);\n+\tglobal_exit_flag = 1;\n+}\n+\n+static void\n+print_mac(unsigned int portid, struct ether_addr *bbdev_ports_eth_address)\n+{\n+\tprintf(\"Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\\n\\n\",\n+\t\t\t(unsigned int) portid,\n+\t\t\tbbdev_ports_eth_address[portid].addr_bytes[0],\n+\t\t\tbbdev_ports_eth_address[portid].addr_bytes[1],\n+\t\t\tbbdev_ports_eth_address[portid].addr_bytes[2],\n+\t\t\tbbdev_ports_eth_address[portid].addr_bytes[3],\n+\t\t\tbbdev_ports_eth_address[portid].addr_bytes[4],\n+\t\t\tbbdev_ports_eth_address[portid].addr_bytes[5]);\n+}\n+\n+/* Check the link status of all ports in up to 9s, and print them finally */\n+static void\n+check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)\n+{\n+#define CHECK_INTERVAL 100 /* 100ms */\n+#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */\n+\tuint8_t portid, count, all_ports_up, print_flag = 0;\n+\tstruct rte_eth_link link;\n+\n+\tprintf(\"\\nChecking link status\");\n+\tfflush(stdout);\n+\n+\tfor (count = 0; count <= MAX_CHECK_TIME; count++) {\n+\t\tall_ports_up = 1;\n+\t\tfor (portid = 0; portid < port_num; portid++) {\n+\t\t\tif ((port_mask & (1 << portid)) == 0)\n+\t\t\t\tcontinue;\n+\t\t\tmemset(&link, 0, sizeof(link));\n+\t\t\trte_eth_link_get_nowait(portid, &link);\n+\t\t\t/* print link status if flag set */\n+\t\t\tif (print_flag == 1) {\n+\t\t\t\tif (link.link_status) {\n+\t\t\t\t\tconst char *dp = (link.link_duplex ==\n+\t\t\t\t\t\t\tETH_LINK_FULL_DUPLEX) ?\n+\t\t\t\t\t\t\t\"full-duplex\" :\n+\t\t\t\t\t\t\t\"half-duplex\";\n+\t\t\t\t\tprintf(\"Port %u Link Up - speed %u Mbps\"\n+\t\t\t\t\t\t\t\" - %s\\n\", portid,\n+\t\t\t\t\t\t\tlink.link_speed,\n+\t\t\t\t\t\t\tdp);\n+\t\t\t\t} else\n+\t\t\t\t\tprintf(\"Port %d Link Down\\n\", portid);\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\t/* clear all_ports_up flag if any link down */\n+\t\t\tif (link.link_status == 0) {\n+\t\t\t\tall_ports_up = 0;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\t/* after finally printing all link status, get out */\n+\t\tif (print_flag == 1)\n+\t\t\tbreak;\n+\n+\t\tif (all_ports_up == 0) {\n+\t\t\tprintf(\".\");\n+\t\t\tfflush(stdout);\n+\t\t\trte_delay_ms(CHECK_INTERVAL);\n+\t\t}\n+\n+\t\t/* set the print_flag if all ports up or timeout */\n+\t\tif (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {\n+\t\t\tprint_flag = 1;\n+\t\t\tprintf(\"done\\n\");\n+\t\t}\n+\t}\n+}\n+\n+static void\n+update_pkt_mac(uint16_t n, struct rte_mbuf *pkts_burst[],\n+\t\tstruct ether_addr *addr, unsigned int dest_portid)\n+{\n+\tstruct ether_hdr *eth;\n+\tvoid *tmp;\n+\n+\tfor (uint16_t i = 0; i < n; i++) {\n+\t\teth = rte_pktmbuf_mtod(pkts_burst[i], struct ether_hdr *);\n+\t\t/* 02:00:00:00:00:xx */\n+\t\ttmp = &eth->d_addr.addr_bytes[0];\n+\t\t*((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dest_portid << 40);\n+\t\t/* src addr */\n+\t\tether_addr_copy(addr, &eth->s_addr);\n+\t}\n+}\n+\n+static int\n+initialize_ports(uint8_t ports_mask, char link, char port_type,\n+\t\tuint32_t *bbdev_enabled_port_mask)\n+{\n+\tuint8_t portid;\n+\tunsigned int enabled_portcount = 0, q;\n+\tint ret;\n+\tstruct port_queues *port_qs;\n+\t/* ethernet addresses of ports */\n+\tstruct ether_addr bbdev_dl_ports_eth_addr[RTE_MAX_ETHPORTS];\n+\tstruct ether_addr bbdev_ul_ports_eth_addr[RTE_MAX_ETHPORTS];\n+\n+\tuint8_t nb_ports = rte_eth_dev_count();\n+\tif (nb_ports == 0) {\n+\t\tprintf(\"No Ethernet ports available\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tfor (portid = 0; portid < nb_ports; portid++) {\n+\n+\t\t/* Skip ports that are not enabled */\n+\t\tif ((ports_mask & (1 << portid)) == 0)\n+\t\t\tcontinue;\n+\n+\t\tport_qs = &ports_qs[portid];\n+\t\t/* initialize ports */\n+\t\tprintf(\"\\nInitializing %cx port %u... \",\n+\t\t\t\tport_type, (unsigned) portid);\n+\t\tfflush(stdout);\n+\t\tret = rte_eth_dev_configure(portid, port_qs->nb_rx_qs,\n+\t\t\t\tport_qs->nb_tx_qs, &port_conf);\n+\n+\t\tif (ret < 0) {\n+\t\t\tprintf(\"Cannot configure device: err=%d, port=%u\\n\",\n+\t\t\t\t\tret, (unsigned) portid);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tfflush(stdout);\n+\n+\t\t/* initialize one RX or TX queue on each port*/\n+\t\tif (port_type == 'R')\n+\t\t\tfor (q = 0; q < port_qs->nb_rx_qs; q++)\n+\t\t\t\tret = rte_eth_rx_queue_setup(portid, q,\n+\t\t\t\t\t\tRTE_TEST_RX_DESC_DEFAULT,\n+\t\t\t\t\t\trte_eth_dev_socket_id(portid),\n+\t\t\t\t\t\tNULL, ethdev_mbuf_mempool);\n+\t\telse if (port_type == 'T')\n+\t\t\tfor (q = 0; q < port_qs->nb_rx_qs; q++)\n+\t\t\t\tret = rte_eth_tx_queue_setup(portid, q,\n+\t\t\t\t\t\tRTE_TEST_TX_DESC_DEFAULT,\n+\t\t\t\t\t\trte_eth_dev_socket_id(portid),\n+\t\t\t\t\t\tNULL);\n+\n+\t\tif (ret < 0) {\n+\t\t\tprintf(\"%cL rte_eth_%cx_queue_setup:err=%d, port=%u\\n\",\n+\t\t\t\t\tport_type, link, ret,\n+\t\t\t\t\t(unsigned int) portid);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\trte_eth_promiscuous_enable(portid);\n+\n+\t\tif (link == 'D') {\n+\t\t\trte_eth_macaddr_get(portid,\n+\t\t\t\t\t&bbdev_dl_ports_eth_addr[portid]);\n+\t\t\tprint_mac(portid, bbdev_dl_ports_eth_addr);\n+\t\t} else {\n+\t\t\trte_eth_macaddr_get(portid,\n+\t\t\t\t\t&bbdev_ul_ports_eth_addr[portid]);\n+\t\t\tprint_mac(portid, bbdev_ul_ports_eth_addr);\n+\t\t}\n+\n+\t\t*bbdev_enabled_port_mask |= (1 << portid);\n+\t\tenabled_portcount++;\n+\t}\n+\treturn enabled_portcount;\n+}\n+\n+static int\n+start_ethdev_ports(uint8_t nb_ports, uint32_t bbdev_enabled_port_mask)\n+{\n+\tunsigned int portid;\n+\tint ret, ports_started = 0;\n+\n+\tfor (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {\n+\n+\t\tif ((bbdev_enabled_port_mask & (uint32_t)(1 << portid)) == 0)\n+\t\t\tcontinue;\n+\t\tret = rte_eth_dev_start(portid);\n+\t\tif (ret < 0) {\n+\t\t\tprintf(\"rte_eth_dev_start:err=%d, port=%u\\n\", ret,\n+\t\t\t\t\t(unsigned int) portid);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tports_started++;\n+\t\tif (ports_started == nb_ports)\n+\t\t\tbreak;\n+\t}\n+\treturn ports_started;\n+}\n+\n+static int\n+lcore_queue_init(uint8_t nb_ports, struct bbdev_config_params *bbdev_params,\n+\t\tstruct lcore_setup *l_setup)\n+{\n+\tuint16_t port;\n+\tunsigned int lcore;\n+\tint lcount, total_count = 0;\n+\tstruct lcore_queue_conf *qconf;\n+\n+\t/*\n+\t * for each core in the uplink populate the array of ports (rx or tx).\n+\t * core with odd id receives rx ports, core with even id receives all\n+\t * tx ports.\n+\t */\n+\tfor (lcore = 0, lcount = 0; lcore < sizeof(int) * 8; lcore++) {\n+\n+\t\t/* get the lcore_id  */\n+\t\tif ((bbdev_params->downlink_lcores & (1 << lcore)) == 0)\n+\t\t\tcontinue;\n+\n+\t\tlcount++;\n+\t\tfor (port = 0; port <= nb_ports; port++) {\n+\t\t\tif ((lcount & 1) == 1) {\n+\t\t\t\tif (port < nb_ports) {\n+\t\t\t\t\t/*get the port id*/\n+\t\t\t\t\tif ((bbdev_params->downlink_rx_ports &\n+\t\t\t\t\t\t\t(1 << port)) == 0)\n+\t\t\t\t\t\tcontinue;\n+\n+\t\t\t\t\tl_setup->rxte_lcore_list[\n+\t\t\t\t\t\t\tl_setup->rxte_lcores] =\n+\t\t\t\t\t\t\tlcore;\n+\t\t\t\t\tprintf(\"Lcore %d: DL RX port %d\\n\",\n+\t\t\t\t\t\t\tlcore, port);\n+\t\t\t\t} else {\n+\t\t\t\t\tl_setup->rxte_lcores++;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\n+\t\t\t} else {\n+\t\t\t\tif (port < nb_ports) {\n+\t\t\t\t\tif ((bbdev_params->downlink_tx_ports &\n+\t\t\t\t\t\t\t(1 << port)) == 0)\n+\t\t\t\t\t\tcontinue;\n+\n+\t\t\t\t\tl_setup->tdtx_lcore_list[\n+\t\t\t\t\t\t\tl_setup->tdtx_lcores] =\n+\t\t\t\t\t\t\tlcore;\n+\t\t\t\t\tprintf(\"Lcore %d: DL TX port %d\\n\",\n+\t\t\t\t\t\t\tlcore, port);\n+\t\t\t\t} else {\n+\t\t\t\t\tl_setup->tdtx_lcores++;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tqconf = &lcore_queue_conf[lcore];\n+\t\t\tqconf->port_list[qconf->nb_ports].queues++;\n+\t\t\tqconf->port_list[qconf->nb_ports].port_id = port;\n+\t\t\trte_eth_macaddr_get(port,\n+\t\t\t\t\t&qconf->ports_eth_addr[qconf->nb_ports]);\n+\t\t\tqconf->nb_ports++;\n+\t\t}\n+\t}\n+\n+\tif (lcount % 2) {\n+\t\tprintf(\"\\nNumber of DL lcores is not an even number\");\n+\t\treturn -1;\n+\t}\n+\n+\ttotal_count += lcount;\n+\n+\t/*\n+\t * for each core in the downlink populate the array of ports (rx or tx).\n+\t * core with odd id receives rx ports, core with even id receives all\n+\t * tx ports\n+\t */\n+\tfor (lcore = 0, lcount = 0; lcore < (sizeof(int) * 8); lcore++) {\n+\t\tif ((bbdev_params->uplink_lcores & (1 << lcore)) == 0)\n+\t\t\tcontinue;\n+\n+\t\tlcount++;\n+\t\tfor (port = 0; port <= nb_ports; port++) {\n+\n+\t\t\tif ((lcount & 1) == 1) {\n+\t\t\t\tif (port < nb_ports) {\n+\t\t\t\t\tif ((bbdev_params->uplink_rx_ports &\n+\t\t\t\t\t\t\t(1 << port)) == 0)\n+\t\t\t\t\t\tcontinue;\n+\n+\t\t\t\t\tl_setup->rxtd_lcore_list[\n+\t\t\t\t\t\t\tl_setup->rxtd_lcores] =\n+\t\t\t\t\t\t\tlcore;\n+\t\t\t\t\tprintf(\"Lcore %u: UL RX port %u\\n\",\n+\t\t\t\t\t\t\tlcore, port);\n+\t\t\t\t} else {\n+\t\t\t\t\tl_setup->rxtd_lcores++;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\n+\t\t\t} else {\n+\t\t\t\tif (port < nb_ports) {\n+\t\t\t\t\tif ((bbdev_params->uplink_tx_ports &\n+\t\t\t\t\t\t\t(1 << port)) == 0)\n+\t\t\t\t\t\tcontinue;\n+\n+\t\t\t\t\tl_setup->tetx_lcore_list[\n+\t\t\t\t\t\t\tl_setup->tetx_lcores] =\n+\t\t\t\t\t\t\tlcore;\n+\t\t\t\t\tprintf(\"Lcore %d: UL TX port %d\\n\",\n+\t\t\t\t\t\t\tlcore, port);\n+\t\t\t\t} else {\n+\t\t\t\t\tl_setup->tetx_lcores++;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tqconf = &lcore_queue_conf[lcore];\n+\t\t\tqconf->port_list[qconf->nb_ports].queues++;\n+\t\t\tqconf->port_list[qconf->nb_ports].port_id = port;\n+\t\t\trte_eth_macaddr_get(port,\n+\t\t\t\t\t&qconf->ports_eth_addr[qconf->nb_ports]);\n+\t\t\tqconf->nb_ports++;\n+\t\t}\n+\t}\n+\tif (lcount % 2) {\n+\t\tprintf(\"\\nNumber of DL lcores is not an even number\");\n+\t\treturn -1;\n+\t}\n+\ttotal_count += lcount;\n+\t/*return number of lcores processed*/\n+\treturn total_count;\n+}\n+\n+static void\n+bbdev_dequeue(enum rte_bbdev_op_type op_type)\n+{\n+\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST];\n+\tstruct rte_bbdev_op *ops_burst[MAX_PKT_BURST];\n+\tunsigned int i, j, portid, nb_tx, lcoreid, qid = 0, q, nb_tx_sent = 0;\n+\tstruct lcore_queue_conf *qconf;\n+\tstruct lcore_statistics *lcore_stat;\n+\n+\tlcoreid = rte_lcore_id();\n+\tlcore_stat = &lcore_stats[lcoreid];\n+\tqconf = &lcore_queue_conf[lcoreid];\n+\n+\tif (qconf->nb_ports == 0)\n+\t\treturn;\n+\n+\twhile (!global_exit_flag) {\n+\t\tfor (i = 0; i < qconf->nb_ports; i++) {\n+\t\t\tportid = qconf->port_list[i].port_id;\n+\n+\t\t\tfor (q = 0; q < qconf->port_list[i].queues; q++) {\n+\t\t\t\tqid = qconf->port_list[i].queues_list[q];\n+\t\t\t\t/* Dequeue packets from bbdev device*/\n+\t\t\t\tnb_tx = rte_bbdev_dequeue_ops(qconf->bbdev_id,\n+\t\t\t\t\t\tqconf->bbdev_qs[q], ops_burst,\n+\t\t\t\t\t\tMAX_PKT_BURST);\n+\n+\t\t\t\tif (!nb_tx)\n+\t\t\t\t\tcontinue;\n+\n+\t\t\t\tlcore_stat->dequeued += nb_tx;\n+\n+\t\t\t\tswitch (op_type) {\n+\t\t\t\tcase RTE_BBDEV_OP_TURBO_ENC:\n+\t\t\t\t\tfor (j = 0; j < nb_tx; j++) {\n+\t\t\t\t\t\tpkts_burst[j] =\n+\t\t\t\t\t\t\tops_burst[j]->turbo_enc->output.data;\n+\t\t\t\t\t\t/* input mbufs are no longer needed, release! */\n+\t\t\t\t\t\trte_pktmbuf_free(ops_burst[j]->turbo_enc->input.data);\n+\t\t\t\t\t}\n+\t\t\t\t\tbreak;\n+\n+\t\t\t\tcase RTE_BBDEV_OP_TURBO_DEC:\n+\t\t\t\t\tfor (j = 0; j < nb_tx; j++) {\n+\t\t\t\t\t\tpkts_burst[j] =\n+\t\t\t\t\t\t\tops_burst[j]->turbo_dec->hard_output.data;\n+\t\t\t\t\t\t/* input mbufs are no longer needed, release! */\n+\t\t\t\t\t\trte_pktmbuf_free(ops_burst[j]->turbo_dec->input.data);\n+\t\t\t\t\t}\n+\t\t\t\t\tbreak;\n+\n+\t\t\t\tdefault:\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\n+\t\t\t\trte_bbdev_op_free_bulk(ops_burst, nb_tx);\n+\n+\t\t\t\tupdate_pkt_mac(nb_tx, pkts_burst,\n+\t\t\t\t\t\t&(qconf->ports_eth_addr[portid]),\n+\t\t\t\t\t\tportid);\n+\n+\t\t\t\t/*Enqueue packets to ethdev*/\n+\t\t\t\tnb_tx_sent = rte_eth_tx_burst(\n+\t\t\t\t\t\t(uint8_t)portid, qid,\n+\t\t\t\t\t\tpkts_burst, nb_tx);\n+\t\t\t\tif (unlikely(nb_tx_sent < nb_tx)) {\n+\t\t\t\t\tlcore_stat->lost_packets +=\n+\t\t\t\t\t\t\tnb_tx - nb_tx_sent;\n+\t\t\t\t\tfor (j = nb_tx_sent; j < nb_tx; j++)\n+\t\t\t\t\t\trte_pktmbuf_free(pkts_burst[j]);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t}\n+}\n+\n+static void\n+bbdev_enqueue(enum rte_bbdev_op_type op_type)\n+{\n+\tunsigned int i, portid, nb_rx = 0, j, lcoreid, q, qid = 0;\n+\tint ret;\n+\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST];\n+\tstruct rte_mbuf *bbdev_pkts[MAX_PKT_BURST];\n+\tstruct rte_bbdev_op *ops_burst[MAX_PKT_BURST];\n+\tstruct lcore_statistics *lcore_stat;\n+\tstruct lcore_queue_conf *qconf = &lcore_queue_conf[rte_lcore_id()];\n+\n+\tif (qconf->nb_ports == 0)\n+\t\treturn;\n+\n+\tlcoreid = rte_lcore_id();\n+\tlcore_stat = &lcore_stats[lcoreid];\n+\n+\t/* Read packet from RX queues*/\n+\twhile (!global_exit_flag) {\n+\n+\t\tfor (i = 0; i < qconf->nb_ports; i++) {\n+\t\t\tportid = qconf->port_list[i].port_id;\n+\n+\t\t\tfor (q = 0; q < qconf->port_list[i].queues; q++) {\n+\n+\t\t\t\tqid = qconf->port_list[i].queues_list[q];\n+\t\t\t\t/* Dequeue packets from ethdev */\n+\t\t\t\tnb_rx = rte_eth_rx_burst((uint8_t) portid, qid,\n+\t\t\t\t\t\tpkts_burst, MAX_PKT_BURST);\n+\n+\t\t\t\tif (!nb_rx)\n+\t\t\t\t\tcontinue;\n+\n+\t\t\t\tif (rte_bbdev_op_alloc_bulk(bbdev_op_pool[op_type],\n+\t\t\t\t\t\top_type, ops_burst, nb_rx) != 0)\n+\t\t\t\t\tcontinue;\n+\n+\t\t\t\tret = rte_pktmbuf_alloc_bulk(qconf->mbuf_pool, bbdev_pkts,\n+\t\t\t\t\t\tMAX_PKT_BURST);\n+\t\t\t\tif (ret < 0)\n+\t\t\t\t\tcontinue;\n+\n+\t\t\t\tswitch (op_type) {\n+\t\t\t\tcase RTE_BBDEV_OP_TURBO_ENC:\n+\t\t\t\t\tfor (j = 0; j < nb_rx; j++) {\n+\t\t\t\t\t\t/* append the size of the ethernet header */\n+\t\t\t\t\t\trte_pktmbuf_append(bbdev_pkts[j],\n+\t\t\t\t\t\t\t\tsizeof(struct ether_hdr));\n+\t\t\t\t\t\t/* copy the ethernet header */\n+\t\t\t\t\t\tvoid *in_buf = rte_pktmbuf_mtod(pkts_burst[j],\n+\t\t\t\t\t\t\t\tvoid *);\n+\t\t\t\t\t\tvoid *out_buf = rte_pktmbuf_mtod(bbdev_pkts[j],\n+\t\t\t\t\t\t\t\tvoid *);\n+\t\t\t\t\t\trte_memcpy(out_buf, in_buf,\n+\t\t\t\t\t\t\t\tsizeof(struct ether_hdr));\n+\t\t\t\t\t\t/* set op */\n+\t\t\t\t\t\tops_burst[j]->type = RTE_BBDEV_OP_TURBO_ENC;\n+\t\t\t\t\t\t*(ops_burst[j]->turbo_enc) = def_op_enc;\n+\t\t\t\t\t\tops_burst[j]->turbo_enc->input.offset =\n+\t\t\t\t\t\t\t\tsizeof(struct ether_hdr);\n+\t\t\t\t\t\tops_burst[j]->turbo_enc->input.length =\n+\t\t\t\t\t\t\t\trte_pktmbuf_pkt_len(bbdev_pkts[j]);\n+\t\t\t\t\t\tops_burst[j]->turbo_enc->input.data =\n+\t\t\t\t\t\t\t\tpkts_burst[j];\n+\t\t\t\t\t\tops_burst[j]->turbo_enc->output.offset =\n+\t\t\t\t\t\t\t\tsizeof(struct ether_hdr);\n+\t\t\t\t\t\tops_burst[j]->turbo_enc->output.data =\n+\t\t\t\t\t\t\t\tbbdev_pkts[j];\n+\t\t\t\t\t}\n+\t\t\t\t\tbreak;\n+\n+\t\t\t\tcase RTE_BBDEV_OP_TURBO_DEC:\n+\t\t\t\t\tfor (j = 0; j < nb_rx; j++) {\n+\t\t\t\t\t\t/* append the size of the ethernet header */\n+\t\t\t\t\t\trte_pktmbuf_append(bbdev_pkts[j],\n+\t\t\t\t\t\t\tsizeof(struct ether_hdr));\n+\t\t\t\t\t\t/* copy the ethernet header */\n+\t\t\t\t\t\tvoid *in_buf = rte_pktmbuf_mtod(pkts_burst[j],\n+\t\t\t\t\t\t\t\tvoid *);\n+\t\t\t\t\t\tvoid *out_buf = rte_pktmbuf_mtod(bbdev_pkts[j],\n+\t\t\t\t\t\t\t\tvoid *);\n+\t\t\t\t\t\trte_memcpy(out_buf, in_buf,\n+\t\t\t\t\t\t\t\tsizeof(struct ether_hdr));\n+\t\t\t\t\t\t/* set op */\n+\t\t\t\t\t\tops_burst[j]->type = RTE_BBDEV_OP_TURBO_DEC;\n+\t\t\t\t\t\t*(ops_burst[j]->turbo_dec) = def_op_dec;\n+\t\t\t\t\t\tops_burst[j]->turbo_dec->input.offset =\n+\t\t\t\t\t\t\t\tsizeof(struct ether_hdr);\n+\t\t\t\t\t\tops_burst[j]->turbo_dec->input.length =\n+\t\t\t\t\t\t\t\trte_pktmbuf_pkt_len(bbdev_pkts[j]);\n+\t\t\t\t\t\tops_burst[j]->turbo_dec->input.data =\n+\t\t\t\t\t\t\t\tpkts_burst[j];\n+\t\t\t\t\t\tops_burst[j]->turbo_enc->output.offset =\n+\t\t\t\t\t\t\t\tsizeof(struct ether_hdr);\n+\t\t\t\t\t\tops_burst[j]->turbo_dec->hard_output.data =\n+\t\t\t\t\t\t\t\tbbdev_pkts[j];\n+\t\t\t\t\t}\n+\t\t\t\t\tbreak;\n+\n+\t\t\t\tdefault:\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\t/* Enqueue packets on BBDEV device */\n+\t\t\t\tnb_rx = rte_bbdev_enqueue_ops(qconf->bbdev_id,\n+\t\t\t\t\t\tqconf->bbdev_qs[q], ops_burst,\n+\t\t\t\t\t\tnb_rx);\n+\t\t\t\tlcore_stat->enqueued += nb_rx;\n+\t\t\t}\n+\t\t}\n+\t}\n+}\n+\n+static void\n+print_lcore_stats(unsigned lcore_id)\n+{\n+\tstruct lcore_statistics *lcore_stat;\n+\tstatic const char *stats_border = \"_______\";\n+\n+\tlcore_stat = &lcore_stats[lcore_id];\n+\tprintf(\"\\nLcore %d: %s enqueued count:\\t\\t%u\\n\",\n+\t\t\tlcore_id, stats_border, lcore_stat->enqueued);\n+\tprintf(\"Lcore %d: %s dequeued count:\\t\\t%u\\n\",\n+\t\t\tlcore_id, stats_border, lcore_stat->dequeued);\n+}\n+\n+static void\n+print_stats(struct lcore_setup *lcore_setup)\n+{\n+\tunsigned l_id;\n+\tint x, nb_ports, dev_id, len, ret, i;\n+\n+\tstruct rte_eth_xstat *xstats;\n+\tstruct rte_eth_xstat_name *xstats_names;\n+\tstruct rte_bbdev_stats bbstats;\n+\tstatic const char *stats_border = \"_______\";\n+\n+\tconst char clr[] = { 27, '[', '2', 'J', '\\0' };\n+\tconst char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\\0' };\n+\n+\t/* Clear screen and move to top left */\n+\tprintf(\"%s%s\", clr, topLeft);\n+\n+\tnb_ports = rte_eth_dev_count();\n+\tprintf(\"PORT STATISTICS:\\n================\\n\");\n+\tfor (x = 0; x < nb_ports; x++) {\n+\n+\t\tlen = rte_eth_xstats_get(x, NULL, 0);\n+\t\tif (len < 0)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\t\"rte_eth_xstats_get(%hhu) failed: %d\",\n+\t\t\t\t\tx, len);\n+\n+\t\txstats = calloc(len, sizeof(*xstats));\n+\t\tif (xstats == NULL)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\t\"Failed to calloc memory for xstats\");\n+\n+\t\tret = rte_eth_xstats_get(x, xstats, len);\n+\t\tif (ret < 0 || ret > len)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\t\"rte_eth_xstats_get(%hhu) len%i failed: %d\",\n+\t\t\t\t\tx, len, ret);\n+\n+\t\txstats_names = calloc(len, sizeof(*xstats_names));\n+\t\tif (xstats_names == NULL)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\t\"Failed to calloc memory for xstats_names\");\n+\n+\t\tret = rte_eth_xstats_get_names(x, xstats_names, len);\n+\t\tif (ret < 0 || ret > len)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\t\"rte_eth_xstats_get_names(%hhu) len%i failed: %d\",\n+\t\t\t\t\tx, len, ret);\n+\n+\t\tfor (i = 0; i < len; i++) {\n+\t\t\tif (xstats[i].value > 0)\n+\t\t\t\tprintf(\"Port %u: %s %s:\\t\\t%\"PRIu64\"\\n\",\n+\t\t\t\t\t\tx, stats_border,\n+\t\t\t\t\t\txstats_names[i].name,\n+\t\t\t\t\t\txstats[i].value);\n+\t\t}\n+\t}\n+\n+\tprintf(\"\\nBBDEV STATISTICS:\\n=================\\n\");\n+\tRTE_BBDEV_FOREACH(dev_id) {\n+\t\trte_bbdev_stats_get((uint8_t) dev_id, &bbstats);\n+\t\tprintf(\"BBDEV %u: %s enqueue count:\\t\\t%\"PRIu64\"\\n\",\n+\t\t\t\tdev_id, stats_border,\n+\t\t\t\tbbstats.enqueued_count);\n+\t\tprintf(\"BBDEV %u: %s dequeue count:\\t\\t%\"PRIu64\"\\n\",\n+\t\t\t\tdev_id, stats_border,\n+\t\t\t\tbbstats.dequeued_count);\n+\t\tprintf(\"BBDEV %u: %s enqueue error count:\\t\\t%\"PRIu64\"\\n\",\n+\t\t\t\tdev_id, stats_border,\n+\t\t\t\tbbstats.enqueue_err_count);\n+\t\tprintf(\"BBDEV %u: %s dequeue error count:\\t\\t%\"PRIu64\"\\n\\n\",\n+\t\t\t\tdev_id, stats_border,\n+\t\t\t\tbbstats.dequeue_err_count);\n+\t}\n+\n+\tprintf(\"LCORE STATISTICS:\\n=================\\n\");\n+\tfor (l_id = 0; l_id < lcore_setup->tdtx_lcores; l_id++)\n+\t\tprint_lcore_stats(lcore_setup->tdtx_lcore_list[l_id]);\n+\tfor (l_id = 0; l_id < lcore_setup->tetx_lcores; l_id++)\n+\t\tprint_lcore_stats(lcore_setup->tetx_lcore_list[l_id]);\n+\tfor (l_id = 0; l_id < lcore_setup->rxtd_lcores; l_id++)\n+\t\tprint_lcore_stats(lcore_setup->rxtd_lcore_list[l_id]);\n+\tfor (l_id = 0; l_id < lcore_setup->rxte_lcores; l_id++)\n+\t\tprint_lcore_stats(lcore_setup->rxte_lcore_list[l_id]);\n+}\n+\n+static void\n+qs_to_lcores(unsigned int nb_lcores, unsigned int lcores[])\n+{\n+\tunsigned int port = 0, l = 0, lcore, y, x, queue, nb_ports = 0, q_id;\n+\tstruct lcore_queue_conf *qconf;\n+\tstruct dev_qs temp[RTE_MAX_LCORE];\n+\tint count = 0;\n+\tstruct dev_qs *p;\n+\tstruct port_queues *port_qs;\n+\n+\t/*\n+\t * for each core copy array of ports (holding all ports available to\n+\t * this lcore) from qconf into temp array and empty the one in qconf\n+\t */\n+\tfor (x = 0; x < nb_lcores; x++) {\n+\n+\t\tlcore = lcores[x];\n+\t\tqconf = &lcore_queue_conf[lcore];\n+\t\tnb_ports = qconf->nb_ports;\n+\t\tqconf->nb_ports = 0;\n+\t\tp = qconf->port_list;\n+\n+\t\tfor (y = 0; y < nb_ports; y++, p++) {\n+\t\t\ttemp[y] = *p;\n+\t\t\tp->port_id = 0;\n+\t\t}\n+\t}\n+\t/*\n+\t * re-populate array of ports and queues in qconf according to number\n+\t * of available lcores, ports, and queues so only the required ports\n+\t * and queues stay in the configuration of each particular lcore\n+\t */\n+\twhile (port < nb_ports || l < nb_lcores) {\n+\n+\t\tif (port < nb_ports && l == nb_lcores) {\n+\t\t\tl = 0;\n+\t\t\tcount++;\n+\t\t}\n+\t\tif (port == nb_ports && l < nb_lcores)\n+\t\t\tport = 0;\n+\n+\t\tlcore = lcores[l];\n+\t\tqconf = &lcore_queue_conf[lcore];\n+\t\tport_qs = &ports_qs[temp[port].port_id];\n+\n+\t\tif ((lcore & 1) == 1) {\n+\t\t\tqconf->port_list[count].port_id =\n+\t\t\t\t\ttemp[port].port_id;\n+\n+\t\t\tfor (q_id = 0; q_id < qconf->port_list[count].queues;\n+\t\t\t\t\tq_id++) {\n+\t\t\t\tqconf->port_list[count].queues_list[q_id] =\n+\t\t\t\t\t\tport_qs->nb_tx_qs;\n+\t\t\t\tport_qs->nb_tx_qs++;\n+\t\t\t}\n+\n+\t\t\tqconf->nb_ports++;\n+\t\t\tqueue++;\n+\t\t} else {\n+\t\t\tqconf->port_list[count].port_id =\n+\t\t\t\t\ttemp[port].port_id;\n+\t\t\tfor (q_id = 0; q_id < qconf->port_list[count].queues;\n+\t\t\t\t\tq_id++) {\n+\t\t\t\tqconf->port_list[count].queues_list[q_id] =\n+\t\t\t\t\t\tport_qs->nb_rx_qs;\n+\t\t\t\tport_qs->nb_rx_qs++;\n+\t\t\t}\n+\t\t\tqconf->nb_ports++;\n+\t\t\tqueue++;\n+\t\t}\n+\t\tprintf(\"Lcore: %u connected to port: %u\\n\",\n+\t\t\t\tlcores[l], temp[port].port_id);\n+\t\tport++;\n+\t\tl++;\n+\t}\n+}\n+\n+static void\n+main_loop(struct lcore_setup *lcore_setup)\n+{\n+\tunsigned int i = 0, this_lcore;\n+\tthis_lcore = rte_lcore_id();\n+\n+\t/* print stats on master core */\n+\tif (rte_get_master_lcore() == this_lcore) {\n+\t\twhile (!global_exit_flag) {\n+\t\t\tprint_stats(lcore_setup);\n+\t\t\trte_delay_ms(500);\n+\t\t}\n+\t}\n+\n+\tfor (i = 0; i < lcore_setup->rxte_lcores; i++) {\n+\t\tif (lcore_setup->rxte_lcore_list[i] == this_lcore)\n+\t\t\tbbdev_enqueue(RTE_BBDEV_OP_TURBO_ENC);\n+\t}\n+\n+\tfor (i = 0; i < lcore_setup->tetx_lcores; i++) {\n+\t\tif (lcore_setup->tetx_lcore_list[i] == this_lcore)\n+\t\t\tbbdev_dequeue(RTE_BBDEV_OP_TURBO_ENC);\n+\t}\n+\n+\tfor (i = 0; i < lcore_setup->rxtd_lcores; i++) {\n+\t\tif (lcore_setup->rxtd_lcore_list[i] == this_lcore)\n+\t\t\tbbdev_enqueue(RTE_BBDEV_OP_TURBO_DEC);\n+\t}\n+\n+\tfor (i = 0; i < lcore_setup->tdtx_lcores; i++) {\n+\t\tif (lcore_setup->tdtx_lcore_list[i] == this_lcore)\n+\t\t\tbbdev_dequeue(RTE_BBDEV_OP_TURBO_DEC);\n+\t}\n+}\n+\n+static int\n+launch_one_lcore(void *arg)\n+{\n+\tmain_loop((struct lcore_setup *)arg);\n+\treturn 0;\n+}\n+\n+static int\n+prepare_bbdev_device(unsigned int dev_id, uint8_t qs_nb)\n+{\n+\tint ret;\n+\tunsigned int q_id;\n+\tstruct rte_bbdev_info info;\n+\tstruct rte_bbdev_queue_conf qconf = {0};\n+\n+\tret = rte_bbdev_configure(dev_id, qs_nb, NULL);\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\"ERROR(%d): BBDEV %u not configured properly\\n\",\n+\t\t\t\tret, dev_id);\n+\n+\trte_bbdev_info_get(dev_id, &info);\n+\n+\t/* setup device queues */\n+\tqconf.socket = info.socket_id;\n+\tqconf.queue_size = info.drv.queue_size_lim;\n+\tqconf.op_type = (dev_id & 0x1) ? RTE_BBDEV_OP_TURBO_DEC :\n+\t\t\tRTE_BBDEV_OP_TURBO_ENC;\n+\n+\tfor (q_id = 0; q_id < qs_nb; q_id++) {\n+\n+\t\tret = rte_bbdev_queue_configure(dev_id, q_id, &qconf);\n+\t\tif (ret < 0)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\t\"ERROR(%d): BBDEV %u queue %u not configured properly\\n\",\n+\t\t\t\t\tret, dev_id, q_id);\n+\t}\n+\n+\tret = rte_bbdev_start(dev_id);\n+\n+\tif (ret != 0)\n+\t\trte_exit(EXIT_FAILURE, \"ERROR(%d): BBDEV %u not started\\n\",\n+\t\t\tret, dev_id);\n+\n+\tprintf(\"BBdev %u started\\n\", dev_id);\n+\n+\treturn 0;\n+}\n+\n+static void\n+enable_bbdev(unsigned int lcores[], unsigned int nb_lcores, unsigned int dev_id)\n+{\n+\tunsigned int i, nb_qs, tot_nb_bbdev_qs = 1, lcore, lcoreid;\n+\tstruct lcore_queue_conf *qconf, *qconf_next;\n+\tunsigned int nb_bbdev_qs = 0;\n+\tchar pool_name[RTE_MEMPOOL_NAMESIZE];\n+\n+\t/* set num of port queues and bbdev queues for each lcore on the link */\n+\tfor (lcore = 0; lcore < nb_lcores; lcore++) {\n+\t\tnb_qs = 0;\n+\t\tlcoreid = lcores[lcore];\n+\t\tqconf = &lcore_queue_conf[lcoreid];\n+\n+\t\tfor (i = 0; i < qconf->nb_ports; i++)\n+\t\t\tnb_qs += qconf->port_list->queues;\n+\n+\t\tfor (i = 0; i < nb_qs; i++) {\n+\t\t\tqconf->bbdev_qs[i] = nb_bbdev_qs;\n+\t\t\tnb_bbdev_qs++;\n+\t\t}\n+\n+\t\t/* create the mbuf mempool for ethdev pkts */\n+\t\tsnprintf(pool_name, sizeof(pool_name), \"bbdev%d_mbuf_pool%d\",\n+\t\t\t\tdev_id, lcore);\n+\t\tqconf->mbuf_pool = rte_pktmbuf_pool_create(pool_name,\n+\t\t\t\tNB_MBUF, MEMPOOL_CACHE_SIZE, 0,\n+\t\t\t\tRTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());\n+\t\tif (qconf->mbuf_pool == NULL)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\t\"Unable to create '%s' pool\\n\", pool_name);\n+\n+\t\tqconf->nb_bbdev_qs = nb_qs;\n+\t\tqconf->bbdev_id = dev_id;\n+\t\tprintf(\"BBdev: %u, lcore %u\\n\", dev_id, lcoreid);\n+\n+\t\tqconf_next = &lcore_queue_conf[lcoreid + 1];\n+\t\tqconf_next->bbdev_id = dev_id;\n+\n+\t\tfor (i = 0; i < nb_qs; i++)\n+\t\t\tqconf_next->bbdev_qs[i] = qconf->bbdev_qs[i];\n+\n+\t\tqconf_next->nb_bbdev_qs = nb_qs;\n+\t\tprintf(\"BBdev: %u, lcore %u\\n\", dev_id, lcoreid + 1);\n+\t}\n+\n+\t/* count the number of queues needed on the bbdev device on this link */\n+\tfor (lcore = 0; lcore < nb_lcores; lcore++) {\n+\t\tlcoreid = lcores[lcore];\n+\t\tqconf = &lcore_queue_conf[lcoreid];\n+\t\ttot_nb_bbdev_qs += qconf->nb_bbdev_qs;\n+\t}\n+\n+\tprepare_bbdev_device(dev_id, tot_nb_bbdev_qs);\n+}\n+\n+int\n+main(int argc, char **argv)\n+{\n+\tint ret, nb_bbdevs, nb_ports;\n+\tint enabled_portcount = 0;\n+\tuint8_t lcore_id;\n+\tchar rx = 'R', tx = 'T', up_link = 'U', down_link = 'D';\n+\tvoid *sigret;\n+\tuint32_t bbdev_enabled_port_mask = 0;\n+\tstruct lcore_setup lcore_setup = { 0 };\n+\tstruct bbdev_config_params bbdev_params = { 0 };\n+\n+\tsigret = signal(SIGTERM, signal_handler);\n+\tif (sigret == SIG_ERR)\n+\t\trte_exit(EXIT_FAILURE, \"signal(%d, ...) failed\", SIGTERM);\n+\n+\tsigret = signal(SIGINT, signal_handler);\n+\tif (sigret == SIG_ERR)\n+\t\trte_exit(EXIT_FAILURE, \"signal(%d, ...) failed\", SIGINT);\n+\n+\tret = rte_eal_init(argc, argv);\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Invalid EAL arguments\\n\");\n+\n+\targc -= ret;\n+\targv += ret;\n+\n+\t/* parse application arguments (after the EAL ones) */\n+\tret = bbdev_parse_args(argc, argv, &bbdev_params);\n+\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Invalid BBDEV arguments\\n\");\n+\n+\t/* Get number of available bbdev devices */\n+\tnb_bbdevs = rte_bbdev_count();\n+\tif (nb_bbdevs == 0)\n+\t\trte_exit(EXIT_FAILURE, \"No bbdevs detected!\\n\");\n+\tprintf(\"Number of bbdevs detected: %d\\n\", nb_bbdevs);\n+\n+\t/* Get number of available ethdev devices */\n+\tnb_ports = rte_eth_dev_count();\n+\t/* Initialize the port/queue configuration of each logical core */\n+\tret = lcore_queue_init(nb_ports, &bbdev_params, &lcore_setup);\n+\tif (ret < nb_bbdevs * 2)\n+\t\trte_exit(EXIT_FAILURE, \"Failed to initialize queues.\\n\");\n+\n+\t/* reconfigure ports to lcores assignment to allow for multiple lcores\n+\t * usage\n+\t */\n+\tqs_to_lcores(lcore_setup.rxte_lcores, lcore_setup.rxte_lcore_list);\n+\tqs_to_lcores(lcore_setup.rxtd_lcores, lcore_setup.rxtd_lcore_list);\n+\tqs_to_lcores(lcore_setup.tdtx_lcores, lcore_setup.tdtx_lcore_list);\n+\tqs_to_lcores(lcore_setup.tetx_lcores, lcore_setup.tetx_lcore_list);\n+\n+\t/* create the mbuf mempool for ethdev pkts */\n+\tethdev_mbuf_mempool = rte_pktmbuf_pool_create(\"ethdev_mbuf_pool\",\n+\t\t\tNB_MBUF, MEMPOOL_CACHE_SIZE, 0,\n+\t\t\tRTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());\n+\tif (ethdev_mbuf_mempool == NULL)\n+\t\trte_exit(EXIT_FAILURE, \"Cannot create ethdev mbuf mempool\\n\");\n+\n+\t/*initialize ports*/\n+\tenabled_portcount = initialize_ports(bbdev_params.downlink_rx_ports,\n+\t\t\tdown_link, rx, &bbdev_enabled_port_mask);\n+\tenabled_portcount += initialize_ports(bbdev_params.downlink_tx_ports,\n+\t\t\tdown_link, tx, &bbdev_enabled_port_mask);\n+\tenabled_portcount += initialize_ports(bbdev_params.uplink_rx_ports,\n+\t\t\tup_link, rx, &bbdev_enabled_port_mask);\n+\tenabled_portcount += initialize_ports(bbdev_params.uplink_tx_ports,\n+\t\t\tup_link, tx, &bbdev_enabled_port_mask);\n+\n+\tif (enabled_portcount < 1)\n+\t\trte_exit(EXIT_FAILURE, \"Failed to initialize Ethernet ports\\n\");\n+\n+\t/*start Ethernet devices*/\n+\tret = start_ethdev_ports(nb_ports, bbdev_enabled_port_mask);\n+\tif (ret <= 0)\n+\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\"Failed to start Ethernet devices on ports\\n\");\n+\tcheck_all_ports_link_status(nb_ports, bbdev_enabled_port_mask);\n+\n+\t/*create bbdev op pools*/\n+\tbbdev_op_pool[RTE_BBDEV_OP_TURBO_DEC] =\n+\t\t\trte_bbdev_op_pool_create(\"bbdev_op_pool_dec\",\n+\t\t\tRTE_BBDEV_OP_TURBO_DEC, NB_MBUF, 128, rte_socket_id());\n+\tbbdev_op_pool[RTE_BBDEV_OP_TURBO_ENC] =\n+\t\t\trte_bbdev_op_pool_create(\"bbdev_op_pool_enc\",\n+\t\t\tRTE_BBDEV_OP_TURBO_ENC, NB_MBUF, 128, rte_socket_id());\n+\n+\tif ((bbdev_op_pool[RTE_BBDEV_OP_TURBO_DEC] == NULL) ||\n+\t\t\t(bbdev_op_pool[RTE_BBDEV_OP_TURBO_ENC] == NULL))\n+\t\trte_exit(EXIT_FAILURE, \"Cannot create bbdev op pools\\n\");\n+\n+\t/*start DL bbdev device*/\n+\tif (lcore_setup.rxte_lcores)\n+\t\tenable_bbdev(lcore_setup.rxte_lcore_list,\n+\t\t\t\tlcore_setup.rxte_lcores, 0);\n+\t/*start UL bbdev device*/\n+\tif (lcore_setup.rxtd_lcores)\n+\t\tenable_bbdev(lcore_setup.rxtd_lcore_list,\n+\t\t\t\tlcore_setup.rxtd_lcores, 1);\n+\n+\t/*launch per-lcore init on every lcore*/\n+\trte_eal_mp_remote_launch(launch_one_lcore, (void *)&lcore_setup,\n+\t\t\tCALL_MASTER);\n+\n+\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n+\t\tif (rte_eal_wait_lcore(lcore_id) < 0)\n+\t\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n",
    "prefixes": [
        "dpdk-dev",
        "v1",
        "4/6"
    ]
}