get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 55793,
    "url": "http://patches.dpdk.org/api/patches/55793/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1562004409-382141-5-git-send-email-nicolas.chautru@intel.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<1562004409-382141-5-git-send-email-nicolas.chautru@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1562004409-382141-5-git-send-email-nicolas.chautru@intel.com",
    "date": "2019-07-01T18:06:46",
    "name": "[v5,4/7] baseband/turbo_sw: extension of turbosw PMD for 5G",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "a68e7a82a042125755cf13e9915080b46315e31b",
    "submitter": {
        "id": 1314,
        "url": "http://patches.dpdk.org/api/people/1314/?format=api",
        "name": "Chautru, Nicolas",
        "email": "nicolas.chautru@intel.com"
    },
    "delegate": {
        "id": 6690,
        "url": "http://patches.dpdk.org/api/users/6690/?format=api",
        "username": "akhil",
        "first_name": "akhil",
        "last_name": "goyal",
        "email": "gakhil@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1562004409-382141-5-git-send-email-nicolas.chautru@intel.com/mbox/",
    "series": [
        {
            "id": 5259,
            "url": "http://patches.dpdk.org/api/series/5259/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=5259",
            "date": "2019-07-01T18:06:42",
            "name": "bbdev: adding support in BBDEV for 5GNR FEC",
            "version": 5,
            "mbox": "http://patches.dpdk.org/series/5259/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/55793/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/55793/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 F1DA9A3;\n\tMon,  1 Jul 2019 20:08:03 +0200 (CEST)",
            "from mga18.intel.com (mga18.intel.com [134.134.136.126])\n\tby dpdk.org (Postfix) with ESMTP id C08242BA5\n\tfor <dev@dpdk.org>; Mon,  1 Jul 2019 20:07:57 +0200 (CEST)",
            "from orsmga008.jf.intel.com ([10.7.209.65])\n\tby orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t01 Jul 2019 11:07:56 -0700",
            "from skx-5gnr-sc12-4.sc.intel.com ([172.25.69.210])\n\tby orsmga008.jf.intel.com with ESMTP; 01 Jul 2019 11:07:54 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.63,440,1557212400\"; d=\"scan'208\";a=\"157369967\"",
        "From": "Nicolas Chautru <nicolas.chautru@intel.com>",
        "To": "akhil.goyal@nxp.com,\n\tdev@dpdk.org",
        "Cc": "ferruh.yigit@intel.com, thomas@monjalon.net, amr.mokhtar@intel.com,\n\tkamilx.chalupnik@intel.com, Nicolas Chautru <nicolas.chautru@intel.com>",
        "Date": "Mon,  1 Jul 2019 11:06:46 -0700",
        "Message-Id": "<1562004409-382141-5-git-send-email-nicolas.chautru@intel.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1562004409-382141-1-git-send-email-nicolas.chautru@intel.com>",
        "References": "<1561344776-43990-2-git-send-email-nicolas.chautru@intel.com>\n\t<1562004409-382141-1-git-send-email-nicolas.chautru@intel.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v5 4/7] baseband/turbo_sw: extension of turbosw\n\tPMD for 5G",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Implementation still based on Intel SDK libraries\noptimized for AVX512 instructions set and 5GNR.\nThis can be also build for AVX2 for 4G capability or\nwithout SDK dependency for maintenance.\n\nSigned-off-by: Nicolas Chautru <nicolas.chautru@intel.com>\nAcked-by: Amr Mokhtar <amr.mokhtar@intel.com>\n---\n config/common_base                               |   1 +\n doc/guides/rel_notes/release_19_08.rst           |  15 +-\n drivers/baseband/turbo_sw/Makefile               |  15 +-\n drivers/baseband/turbo_sw/bbdev_turbo_software.c | 677 ++++++++++++++++++++++-\n drivers/baseband/turbo_sw/meson.build            |  10 +\n mk/rte.app.mk                                    |   8 +-\n 6 files changed, 715 insertions(+), 11 deletions(-)",
    "diff": "diff --git a/config/common_base b/config/common_base\nindex e5a4ebf..c2551b1 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -536,6 +536,7 @@ CONFIG_RTE_LIBRTE_BBDEV_DEBUG=n\n CONFIG_RTE_BBDEV_MAX_DEVS=128\n CONFIG_RTE_BBDEV_OFFLOAD_COST=y\n CONFIG_RTE_BBDEV_SDK_AVX2=n\n+CONFIG_RTE_BBDEV_SDK_AVX512=n\n \n #\n # Compile PMD for NULL bbdev device\ndiff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst\nindex 55ae8ee..7c508fc 100644\n--- a/doc/guides/rel_notes/release_19_08.rst\n+++ b/doc/guides/rel_notes/release_19_08.rst\n@@ -126,6 +126,20 @@ New Features\n   Added telemetry mode to l3fwd-power application to report\n   application level busyness, empty and full polls of rte_eth_rx_burst().\n \n+* **Added a FPGA_LTE_FEC bbdev PMD.**\n+\n+  Added the new ``fpga_lte_fec`` bbdev driver for the Intel® FPGA PAC\n+  (Programmable  Acceleration Card) N3000.  See the\n+  :doc:`../bbdevs/fpga_lte_fec` BBDEV guide for more details on this new driver.\n+\n+* **Updated TURBO_SW bbdev PMD.**\n+\n+  Updated the ``turbo_sw`` bbdev driver with changes including:\n+\n+  * Added option to build the driver with or without dependency of external\n+    SDK libraries.\n+  * Added support for 5GNR encode/decode operations.\n+\n Removed Items\n -------------\n \n@@ -165,7 +179,6 @@ API Changes\n   structure (``rte_crypto_cipher_xform``, ``rte_crypto_auth_xform``, and\n   ``rte_crypto_aead_xform``) have been changed to ``const uint8_t *data``.\n \n-\n ABI Changes\n -----------\n \ndiff --git a/drivers/baseband/turbo_sw/Makefile b/drivers/baseband/turbo_sw/Makefile\nindex 414d0d9..4aa05d2 100644\n--- a/drivers/baseband/turbo_sw/Makefile\n+++ b/drivers/baseband/turbo_sw/Makefile\n@@ -3,7 +3,6 @@\n \n include $(RTE_SDK)/mk/rte.vars.mk\n \n-\n # library name\n LIB = librte_pmd_bbdev_turbo_sw.a\n \n@@ -34,6 +33,20 @@ LDLIBS += -L$(FLEXRAN_SDK)/lib_common -lcommon\n LDLIBS += -lstdc++ -lirc -limf -lipps -lsvml\n endif\n \n+ifeq ($(CONFIG_RTE_BBDEV_SDK_AVX512),y)\n+ifeq ($(CONFIG_RTE_BBDEV_SDK_AVX2),n)\n+$(error \"CONFIG_RTE_BBDEV_SDK_AVX512 requires CONFIG_RTE_BBDEV_SDK_AVX2 set\")\n+endif\n+CFLAGS += -I$(FLEXRAN_SDK)/lib_ldpc_encoder_5gnr\n+CFLAGS += -I$(FLEXRAN_SDK)/lib_ldpc_decoder_5gnr\n+CFLAGS += -I$(FLEXRAN_SDK)/lib_LDPC_ratematch_5gnr\n+CFLAGS += -I$(FLEXRAN_SDK)/lib_rate_dematching_5gnr\n+LDLIBS += -L$(FLEXRAN_SDK)/lib_ldpc_encoder_5gnr -lldpc_encoder_5gnr\n+LDLIBS += -L$(FLEXRAN_SDK)/lib_ldpc_decoder_5gnr -lldpc_decoder_5gnr\n+LDLIBS += -L$(FLEXRAN_SDK)/lib_LDPC_ratematch_5gnr -lLDPC_ratematch_5gnr\n+LDLIBS += -L$(FLEXRAN_SDK)/lib_rate_dematching_5gnr -lrate_dematching_5gnr\n+endif\n+\n # library version\n LIBABIVER := 1\n \ndiff --git a/drivers/baseband/turbo_sw/bbdev_turbo_software.c b/drivers/baseband/turbo_sw/bbdev_turbo_software.c\nindex 5551f84..2f06369 100644\n--- a/drivers/baseband/turbo_sw/bbdev_turbo_software.c\n+++ b/drivers/baseband/turbo_sw/bbdev_turbo_software.c\n@@ -14,11 +14,24 @@\n #include <rte_bbdev.h>\n #include <rte_bbdev_pmd.h>\n \n+#include <rte_common.h>\n+#include <rte_hexdump.h>\n+#include <rte_log.h>\n+\n #ifdef RTE_BBDEV_SDK_AVX2\n+#include <ipp.h>\n+#include <ipps.h>\n #include <phy_turbo.h>\n #include <phy_crc.h>\n #include <phy_rate_match.h>\n #endif\n+#ifdef RTE_BBDEV_SDK_AVX512\n+#include <bit_reverse.h>\n+#include <phy_ldpc_encoder_5gnr.h>\n+#include <phy_ldpc_decoder_5gnr.h>\n+#include <phy_LDPC_ratematch_5gnr.h>\n+#include <phy_rate_dematching_5gnr.h>\n+#endif\n \n #define DRIVER_NAME baseband_turbo_sw\n \n@@ -84,6 +97,7 @@ struct turbo_sw_queue {\n \tenum rte_bbdev_op_type type;\n } __rte_cache_aligned;\n \n+\n #ifdef RTE_BBDEV_SDK_AVX2\n static inline char *\n mbuf_append(struct rte_mbuf *m_head, struct rte_mbuf *m, uint16_t len)\n@@ -180,20 +194,53 @@ struct turbo_sw_queue {\n \t\t\t}\n \t\t},\n #endif\n+#ifdef RTE_BBDEV_SDK_AVX512\n+\t\t{\n+\t\t\t.type   = RTE_BBDEV_OP_LDPC_ENC,\n+\t\t\t.cap.ldpc_enc = {\n+\t\t\t\t.capability_flags =\n+\t\t\t\t\t\tRTE_BBDEV_LDPC_RATE_MATCH |\n+\t\t\t\t\t\tRTE_BBDEV_LDPC_CRC_24A_ATTACH |\n+\t\t\t\t\t\tRTE_BBDEV_LDPC_CRC_24B_ATTACH,\n+\t\t\t\t.num_buffers_src =\n+\t\t\t\t\t\tRTE_BBDEV_LDPC_MAX_CODE_BLOCKS,\n+\t\t\t\t.num_buffers_dst =\n+\t\t\t\t\t\tRTE_BBDEV_LDPC_MAX_CODE_BLOCKS,\n+\t\t\t}\n+\t\t},\n+\t\t{\n+\t\t.type   = RTE_BBDEV_OP_LDPC_DEC,\n+\t\t.cap.ldpc_dec = {\n+\t\t\t.capability_flags =\n+\t\t\t\t\tRTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK |\n+\t\t\t\t\tRTE_BBDEV_LDPC_CRC_TYPE_24A_CHECK |\n+\t\t\t\t\tRTE_BBDEV_LDPC_CRC_TYPE_24B_DROP |\n+\t\t\t\t\tRTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE |\n+\t\t\t\t\tRTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE |\n+\t\t\t\t\tRTE_BBDEV_LDPC_ITERATION_STOP_ENABLE,\n+\t\t\t.llr_size = 8,\n+\t\t\t.llr_decimals = 2,\n+\t\t\t.harq_memory_size = 0,\n+\t\t\t.num_buffers_src =\n+\t\t\t\t\tRTE_BBDEV_LDPC_MAX_CODE_BLOCKS,\n+\t\t\t.num_buffers_hard_out =\n+\t\t\t\t\tRTE_BBDEV_LDPC_MAX_CODE_BLOCKS,\n+\t\t\t.num_buffers_soft_out = 0,\n+\t\t}\n+\t\t},\n+#endif\n \t\tRTE_BBDEV_END_OF_CAPABILITIES_LIST()\n \t};\n \n \tstatic struct rte_bbdev_queue_conf default_queue_conf = {\n \t\t.queue_size = RTE_BBDEV_QUEUE_SIZE_LIMIT,\n \t};\n-\n #ifdef RTE_BBDEV_SDK_AVX2\n \tstatic const enum rte_cpu_flag_t cpu_flag = RTE_CPUFLAG_SSE4_2;\n \tdev_info->cpu_flag_reqs = &cpu_flag;\n #else\n \tdev_info->cpu_flag_reqs = NULL;\n #endif\n-\n \tdefault_queue_conf.socket = dev->data->socket_id;\n \n \tdev_info->driver_name = RTE_STR(DRIVER_NAME);\n@@ -280,7 +327,7 @@ struct turbo_sw_queue {\n \t\treturn -ENAMETOOLONG;\n \t}\n \tq->enc_in = rte_zmalloc_socket(name,\n-\t\t\t(RTE_BBDEV_TURBO_MAX_CB_SIZE >> 3) * sizeof(*q->enc_in),\n+\t\t\t(RTE_BBDEV_LDPC_MAX_CB_SIZE >> 3) * sizeof(*q->enc_in),\n \t\t\tRTE_CACHE_LINE_SIZE, queue_conf->socket);\n \tif (q->enc_in == NULL) {\n \t\trte_bbdev_log(ERR,\n@@ -288,7 +335,7 @@ struct turbo_sw_queue {\n \t\tgoto free_q;\n \t}\n \n-\t/* Allocate memory for Aplha Gamma temp buffer. */\n+\t/* Allocate memory for Alpha Gamma temp buffer. */\n \tret = snprintf(name, RTE_RING_NAMESIZE, RTE_STR(DRIVER_NAME)\"_ag%u:%u\",\n \t\t\tdev->data->dev_id, q_id);\n \tif ((ret < 0) || (ret >= (int)RTE_RING_NAMESIZE)) {\n@@ -423,6 +470,7 @@ struct turbo_sw_queue {\n };\n \n #ifdef RTE_BBDEV_SDK_AVX2\n+#ifdef RTE_LIBRTE_BBDEV_DEBUG\n /* Checks if the encoder input buffer is correct.\n  * Returns 0 if it's valid, -1 otherwise.\n  */\n@@ -478,16 +526,21 @@ struct turbo_sw_queue {\n \treturn 0;\n }\n #endif\n+#endif\n \n static inline void\n process_enc_cb(struct turbo_sw_queue *q, struct rte_bbdev_enc_op *op,\n \t\tuint8_t r, uint8_t c, uint16_t k, uint16_t ncb,\n \t\tuint32_t e, struct rte_mbuf *m_in, struct rte_mbuf *m_out_head,\n-\t\tstruct rte_mbuf *m_out, uint16_t in_offset, uint16_t out_offset,\n+\t\tstruct rte_mbuf *m_out,\tuint16_t in_offset, uint16_t out_offset,\n \t\tuint16_t in_length, struct rte_bbdev_stats *q_stats)\n {\n #ifdef RTE_BBDEV_SDK_AVX2\n+#ifdef RTE_LIBRTE_BBDEV_DEBUG\n \tint ret;\n+#else\n+\tRTE_SET_USED(in_length);\n+#endif\n \tint16_t k_idx;\n \tuint16_t m;\n \tuint8_t *in, *out0, *out1, *out2, *tmp_out, *rm_out;\n@@ -511,11 +564,14 @@ struct turbo_sw_queue {\n \t/* CRC24A (for TB) */\n \tif ((enc->op_flags & RTE_BBDEV_TURBO_CRC_24A_ATTACH) &&\n \t\t(enc->code_block_mode == 1)) {\n+#ifdef RTE_LIBRTE_BBDEV_DEBUG\n \t\tret = is_enc_input_valid(k - 24, k_idx, in_length);\n \t\tif (ret != 0) {\n \t\t\top->status |= 1 << RTE_BBDEV_DATA_ERROR;\n \t\t\treturn;\n \t\t}\n+#endif\n+\n \t\tcrc_req.data = in;\n \t\tcrc_req.len = k - 24;\n \t\t/* Check if there is a room for CRC bits if not use\n@@ -544,11 +600,14 @@ struct turbo_sw_queue {\n #endif\n \t} else if (enc->op_flags & RTE_BBDEV_TURBO_CRC_24B_ATTACH) {\n \t\t/* CRC24B */\n+#ifdef RTE_LIBRTE_BBDEV_DEBUG\n \t\tret = is_enc_input_valid(k - 24, k_idx, in_length);\n \t\tif (ret != 0) {\n \t\t\top->status |= 1 << RTE_BBDEV_DATA_ERROR;\n \t\t\treturn;\n \t\t}\n+#endif\n+\n \t\tcrc_req.data = in;\n \t\tcrc_req.len = k - 24;\n \t\t/* Check if there is a room for CRC bits if this is the last\n@@ -575,13 +634,16 @@ struct turbo_sw_queue {\n #ifdef RTE_BBDEV_OFFLOAD_COST\n \t\tq_stats->acc_offload_cycles += rte_rdtsc_precise() - start_time;\n #endif\n-\t} else {\n+\t}\n+#ifdef RTE_LIBRTE_BBDEV_DEBUG\n+\telse {\n \t\tret = is_enc_input_valid(k, k_idx, in_length);\n \t\tif (ret != 0) {\n \t\t\top->status |= 1 << RTE_BBDEV_DATA_ERROR;\n \t\t\treturn;\n \t\t}\n \t}\n+#endif\n \n \t/* Turbo encoder */\n \n@@ -757,6 +819,143 @@ struct turbo_sw_queue {\n #endif\n }\n \n+\n+static inline void\n+process_ldpc_enc_cb(struct turbo_sw_queue *q, struct rte_bbdev_enc_op *op,\n+\t\tuint32_t e, struct rte_mbuf *m_in, struct rte_mbuf *m_out_head,\n+\t\tstruct rte_mbuf *m_out,\tuint16_t in_offset, uint16_t out_offset,\n+\t\tuint16_t seg_total_left, struct rte_bbdev_stats *q_stats)\n+{\n+#ifdef RTE_BBDEV_SDK_AVX512\n+\tRTE_SET_USED(seg_total_left);\n+\tuint8_t *in, *rm_out;\n+\tstruct rte_bbdev_op_ldpc_enc *enc = &op->ldpc_enc;\n+\tstruct bblib_ldpc_encoder_5gnr_request ldpc_req;\n+\tstruct bblib_ldpc_encoder_5gnr_response ldpc_resp;\n+\tstruct bblib_LDPC_ratematch_5gnr_request rm_req;\n+\tstruct bblib_LDPC_ratematch_5gnr_response rm_resp;\n+\tstruct bblib_crc_request crc_req;\n+\tstruct bblib_crc_response crc_resp;\n+\tuint16_t msgLen, puntBits, parity_offset, out_len;\n+\tuint16_t K = (enc->basegraph == 1 ? 22 : 10) * enc->z_c;\n+\tuint16_t in_length_in_bits = K - enc->n_filler;\n+\tuint16_t in_length_in_bytes = (in_length_in_bits + 7) >> 3;\n+\n+#ifdef RTE_BBDEV_OFFLOAD_COST\n+\tuint64_t start_time = rte_rdtsc_precise();\n+#else\n+\tRTE_SET_USED(q_stats);\n+#endif\n+\n+\tin = rte_pktmbuf_mtod_offset(m_in, uint8_t *, in_offset);\n+\n+\t/* Masking the Filler bits explicitly */\n+\tmemset(q->enc_in  + (in_length_in_bytes - 3), 0,\n+\t\t\t((K + 7) >> 3) - (in_length_in_bytes - 3));\n+\t/* CRC Generation */\n+\tif (enc->op_flags & RTE_BBDEV_LDPC_CRC_24A_ATTACH) {\n+\t\trte_memcpy(q->enc_in, in, in_length_in_bytes - 3);\n+\t\tcrc_req.data = in;\n+\t\tcrc_req.len = in_length_in_bits - 24;\n+\t\tcrc_resp.data = q->enc_in;\n+\t\tbblib_lte_crc24a_gen(&crc_req, &crc_resp);\n+\t} else if (enc->op_flags & RTE_BBDEV_LDPC_CRC_24B_ATTACH) {\n+\t\trte_memcpy(q->enc_in, in, in_length_in_bytes - 3);\n+\t\tcrc_req.data = in;\n+\t\tcrc_req.len = in_length_in_bits - 24;\n+\t\tcrc_resp.data = q->enc_in;\n+\t\tbblib_lte_crc24b_gen(&crc_req, &crc_resp);\n+\t} else\n+\t\trte_memcpy(q->enc_in, in, in_length_in_bytes);\n+\n+\t/* LDPC Encoding */\n+\tldpc_req.Zc = enc->z_c;\n+\tldpc_req.baseGraph = enc->basegraph;\n+\t/* Number of rows set to maximum */\n+\tldpc_req.nRows = ldpc_req.baseGraph == 1 ? 46 : 42;\n+\tldpc_req.numberCodeblocks = 1;\n+\tldpc_req.input[0] = (int8_t *) q->enc_in;\n+\tldpc_resp.output[0] = (int8_t *) q->enc_out;\n+\n+\tbblib_bit_reverse(ldpc_req.input[0], in_length_in_bytes << 3);\n+\n+\tif (bblib_ldpc_encoder_5gnr(&ldpc_req, &ldpc_resp) != 0) {\n+\t\top->status |= 1 << RTE_BBDEV_DRV_ERROR;\n+\t\trte_bbdev_log(ERR, \"LDPC Encoder failed\");\n+\t\treturn;\n+\t}\n+\n+\t/*\n+\t * Systematic + Parity : Recreating stream with filler bits, ideally\n+\t * the bit select could handle this in the RM SDK\n+\t */\n+\tmsgLen = (ldpc_req.baseGraph == 1 ? 22 : 10) * ldpc_req.Zc;\n+\tpuntBits = 2 * ldpc_req.Zc;\n+\tparity_offset = msgLen - puntBits;\n+\tippsCopyBE_1u(((uint8_t *) ldpc_req.input[0]) + (puntBits / 8),\n+\t\t\tpuntBits%8, q->adapter_output, 0, parity_offset);\n+\tippsCopyBE_1u(q->enc_out, 0, q->adapter_output + (parity_offset / 8),\n+\t\t\tparity_offset % 8, ldpc_req.nRows * ldpc_req.Zc);\n+\n+\tout_len = (e + 7) >> 3;\n+\t/* get output data starting address */\n+\trm_out = (uint8_t *)mbuf_append(m_out_head, m_out, out_len);\n+\tif (rm_out == NULL) {\n+\t\top->status |= 1 << RTE_BBDEV_DATA_ERROR;\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Too little space in output mbuf\");\n+\t\treturn;\n+\t}\n+\t/*\n+\t * rte_bbdev_op_data.offset can be different than the offset\n+\t * of the appended bytes\n+\t */\n+\trm_out = rte_pktmbuf_mtod_offset(m_out, uint8_t *, out_offset);\n+\n+\t/* Rate-Matching */\n+\trm_req.E = e;\n+\trm_req.Ncb = enc->n_cb;\n+\trm_req.Qm = enc->q_m;\n+\trm_req.Zc = enc->z_c;\n+\trm_req.baseGraph = enc->basegraph;\n+\trm_req.input = q->adapter_output;\n+\trm_req.nLen = enc->n_filler;\n+\trm_req.nullIndex = parity_offset - enc->n_filler;\n+\trm_req.rvidx = enc->rv_index;\n+\trm_resp.output = q->deint_output;\n+\n+\tif (bblib_LDPC_ratematch_5gnr(&rm_req, &rm_resp) != 0) {\n+\t\top->status |= 1 << RTE_BBDEV_DRV_ERROR;\n+\t\trte_bbdev_log(ERR, \"Rate matching failed\");\n+\t\treturn;\n+\t}\n+\n+\t/* RM SDK may provide non zero bits on last byte */\n+\tif ((e % 8) != 0)\n+\t\tq->deint_output[out_len-1] &= (1 << (e % 8)) - 1;\n+\n+\tbblib_bit_reverse((int8_t *) q->deint_output, out_len << 3);\n+\n+\trte_memcpy(rm_out, q->deint_output, out_len);\n+\tenc->output.length += out_len;\n+\n+#ifdef RTE_BBDEV_OFFLOAD_COST\n+\tq_stats->acc_offload_cycles += rte_rdtsc_precise() - start_time;\n+#endif\n+#else\n+\tRTE_SET_USED(q);\n+\tRTE_SET_USED(op);\n+\tRTE_SET_USED(e);\n+\tRTE_SET_USED(m_in);\n+\tRTE_SET_USED(m_out_head);\n+\tRTE_SET_USED(m_out);\n+\tRTE_SET_USED(in_offset);\n+\tRTE_SET_USED(out_offset);\n+\tRTE_SET_USED(seg_total_left);\n+\tRTE_SET_USED(q_stats);\n+#endif\n+}\n+\n static inline void\n enqueue_enc_one_op(struct turbo_sw_queue *q, struct rte_bbdev_enc_op *op,\n \t\tstruct rte_bbdev_stats *queue_stats)\n@@ -850,6 +1049,93 @@ struct turbo_sw_queue {\n \t}\n }\n \n+\n+static inline void\n+enqueue_ldpc_enc_one_op(struct turbo_sw_queue *q, struct rte_bbdev_enc_op *op,\n+\t\tstruct rte_bbdev_stats *queue_stats)\n+{\n+\tuint8_t c, r, crc24_bits = 0;\n+\tuint32_t e;\n+\tstruct rte_bbdev_op_ldpc_enc *enc = &op->ldpc_enc;\n+\tuint16_t in_offset = enc->input.offset;\n+\tuint16_t out_offset = enc->output.offset;\n+\tstruct rte_mbuf *m_in = enc->input.data;\n+\tstruct rte_mbuf *m_out = enc->output.data;\n+\tstruct rte_mbuf *m_out_head = enc->output.data;\n+\tuint32_t in_length, mbuf_total_left = enc->input.length;\n+\n+\tuint16_t seg_total_left;\n+\n+\t/* Clear op status */\n+\top->status = 0;\n+\n+\tif (mbuf_total_left > RTE_BBDEV_TURBO_MAX_TB_SIZE >> 3) {\n+\t\trte_bbdev_log(ERR, \"TB size (%u) is too big, max: %d\",\n+\t\t\t\tmbuf_total_left, RTE_BBDEV_TURBO_MAX_TB_SIZE);\n+\t\top->status = 1 << RTE_BBDEV_DATA_ERROR;\n+\t\treturn;\n+\t}\n+\n+\tif (m_in == NULL || m_out == NULL) {\n+\t\trte_bbdev_log(ERR, \"Invalid mbuf pointer\");\n+\t\top->status = 1 << RTE_BBDEV_DATA_ERROR;\n+\t\treturn;\n+\t}\n+\n+\tif ((enc->op_flags & RTE_BBDEV_TURBO_CRC_24B_ATTACH) ||\n+\t\t(enc->op_flags & RTE_BBDEV_TURBO_CRC_24A_ATTACH))\n+\t\tcrc24_bits = 24;\n+\n+\tif (enc->code_block_mode == 0) { /* For Transport Block mode */\n+\t\tc = enc->tb_params.c;\n+\t\tr = enc->tb_params.r;\n+\t} else { /* For Code Block mode */\n+\t\tc = 1;\n+\t\tr = 0;\n+\t}\n+\n+\twhile (mbuf_total_left > 0 && r < c) {\n+\n+\t\tseg_total_left = rte_pktmbuf_data_len(m_in) - in_offset;\n+\n+\t\tif (enc->code_block_mode == 0) {\n+\t\t\te = (r < enc->tb_params.cab) ?\n+\t\t\t\tenc->tb_params.ea : enc->tb_params.eb;\n+\t\t} else {\n+\t\t\te = enc->cb_params.e;\n+\t\t}\n+\n+\t\tprocess_ldpc_enc_cb(q, op, e, m_in, m_out_head,\n+\t\t\t\tm_out, in_offset, out_offset, seg_total_left,\n+\t\t\t\tqueue_stats);\n+\t\t/* Update total_left */\n+\t\tin_length = (enc->basegraph == 1 ? 22 : 10) * enc->z_c;\n+\t\tin_length = ((in_length - crc24_bits - enc->n_filler) >> 3);\n+\t\tmbuf_total_left -= in_length;\n+\t\t/* Update offsets for next CBs (if exist) */\n+\t\tin_offset += in_length;\n+\t\tout_offset += (e + 7) >> 3;\n+\n+\t\t/* Update offsets */\n+\t\tif (seg_total_left == in_length) {\n+\t\t\t/* Go to the next mbuf */\n+\t\t\tm_in = m_in->next;\n+\t\t\tm_out = m_out->next;\n+\t\t\tin_offset = 0;\n+\t\t\tout_offset = 0;\n+\t\t}\n+\t\tr++;\n+\t}\n+\n+\t/* check if all input data was processed */\n+\tif (mbuf_total_left != 0) {\n+\t\top->status |= 1 << RTE_BBDEV_DATA_ERROR;\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Mismatch between mbuf length and included CBs sizes %d\",\n+\t\t\t\tmbuf_total_left);\n+\t}\n+}\n+\n static inline uint16_t\n enqueue_enc_all_ops(struct turbo_sw_queue *q, struct rte_bbdev_enc_op **ops,\n \t\tuint16_t nb_ops, struct rte_bbdev_stats *queue_stats)\n@@ -866,6 +1152,23 @@ struct turbo_sw_queue {\n \t\t\tNULL);\n }\n \n+static inline uint16_t\n+enqueue_ldpc_enc_all_ops(struct turbo_sw_queue *q,\n+\t\tstruct rte_bbdev_enc_op **ops,\n+\t\tuint16_t nb_ops, struct rte_bbdev_stats *queue_stats)\n+{\n+\tuint16_t i;\n+#ifdef RTE_BBDEV_OFFLOAD_COST\n+\tqueue_stats->acc_offload_cycles = 0;\n+#endif\n+\n+\tfor (i = 0; i < nb_ops; ++i)\n+\t\tenqueue_ldpc_enc_one_op(q, ops[i], queue_stats);\n+\n+\treturn rte_ring_enqueue_burst(q->processed_pkts, (void **)ops, nb_ops,\n+\t\t\tNULL);\n+}\n+\n #ifdef RTE_BBDEV_SDK_AVX2\n static inline void\n move_padding_bytes(const uint8_t *in, uint8_t *out, uint16_t k,\n@@ -890,7 +1193,11 @@ struct turbo_sw_queue {\n \t\tstruct rte_bbdev_stats *q_stats)\n {\n #ifdef RTE_BBDEV_SDK_AVX2\n+#ifdef RTE_LIBRTE_BBDEV_DEBUG\n \tint ret;\n+#else\n+\tRTE_SET_USED(in_length);\n+#endif\n \tint32_t k_idx;\n \tint32_t iter_cnt;\n \tuint8_t *in, *out, *adapter_input;\n@@ -908,11 +1215,13 @@ struct turbo_sw_queue {\n \n \tk_idx = compute_idx(k);\n \n+#ifdef RTE_LIBRTE_BBDEV_DEBUG\n \tret = is_dec_input_valid(k_idx, kw, in_length);\n \tif (ret != 0) {\n \t\top->status |= 1 << RTE_BBDEV_DATA_ERROR;\n \t\treturn;\n \t}\n+#endif\n \n \tin = rte_pktmbuf_mtod_offset(m_in, uint8_t *, in_offset);\n \tncb = kw;\n@@ -928,11 +1237,12 @@ struct turbo_sw_queue {\n \t\tdeint_resp.pinteleavebuffer = q->deint_output;\n \n #ifdef RTE_BBDEV_OFFLOAD_COST\n-\t\tstart_time = rte_rdtsc_precise();\n+\tstart_time = rte_rdtsc_precise();\n #endif\n+\t\t/* Sub-block De-Interleaving */\n \t\tbblib_deinterleave_ul(&deint_req, &deint_resp);\n #ifdef RTE_BBDEV_OFFLOAD_COST\n-\t\tq_stats->acc_offload_cycles += rte_rdtsc_precise() - start_time;\n+\tq_stats->acc_offload_cycles += rte_rdtsc_precise() - start_time;\n #endif\n \t} else\n \t\tmove_padding_bytes(in, q->deint_output, k, ncb);\n@@ -1025,6 +1335,202 @@ struct turbo_sw_queue {\n }\n \n static inline void\n+process_ldpc_dec_cb(struct turbo_sw_queue *q, struct rte_bbdev_dec_op *op,\n+\t\tuint8_t c, uint16_t out_length, uint16_t e,\n+\t\tstruct rte_mbuf *m_in,\n+\t\tstruct rte_mbuf *m_out_head, struct rte_mbuf *m_out,\n+\t\tstruct rte_mbuf *m_harq_in,\n+\t\tstruct rte_mbuf *m_harq_out_head, struct rte_mbuf *m_harq_out,\n+\t\tuint16_t in_offset, uint16_t out_offset,\n+\t\tuint16_t harq_in_offset, uint16_t harq_out_offset,\n+\t\tbool check_crc_24b,\n+\t\tuint16_t crc24_overlap, uint16_t in_length,\n+\t\tstruct rte_bbdev_stats *q_stats)\n+{\n+#ifdef RTE_BBDEV_SDK_AVX512\n+\tRTE_SET_USED(in_length);\n+\tRTE_SET_USED(c);\n+\tuint8_t *in, *out, *harq_in, *harq_out, *adapter_input;\n+\tstruct bblib_rate_dematching_5gnr_request derm_req;\n+\tstruct bblib_rate_dematching_5gnr_response derm_resp;\n+\tstruct bblib_ldpc_decoder_5gnr_request dec_req;\n+\tstruct bblib_ldpc_decoder_5gnr_response dec_resp;\n+\tstruct bblib_crc_request crc_req;\n+\tstruct bblib_crc_response crc_resp;\n+\tstruct rte_bbdev_op_ldpc_dec *dec = &op->ldpc_dec;\n+\tuint16_t K, parity_offset, sys_cols, outLenWithCrc;\n+\tint16_t deRmOutSize, numRows;\n+\n+\t/* Compute some LDPC BG lengths */\n+\toutLenWithCrc = out_length + (crc24_overlap >> 3);\n+\tsys_cols = (dec->basegraph == 1) ? 22 : 10;\n+\tK = sys_cols * dec->z_c;\n+\tparity_offset = K - 2 * dec->z_c;\n+\n+#ifdef RTE_BBDEV_OFFLOAD_COST\n+\tuint64_t start_time = rte_rdtsc_precise();\n+#else\n+\tRTE_SET_USED(q_stats);\n+#endif\n+\n+\tin = rte_pktmbuf_mtod_offset(m_in, uint8_t *, in_offset);\n+\n+\tif (check_bit(dec->op_flags, RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) {\n+\t\t/**\n+\t\t *  Single contiguous block from the first LLR of the\n+\t\t *  circular buffer.\n+\t\t */\n+\t\tharq_in = NULL;\n+\t\tif (m_harq_in != NULL)\n+\t\t\tharq_in = rte_pktmbuf_mtod_offset(m_harq_in,\n+\t\t\t\tuint8_t *, harq_in_offset);\n+\t\tif (harq_in == NULL) {\n+\t\t\top->status |= 1 << RTE_BBDEV_DATA_ERROR;\n+\t\t\trte_bbdev_log(ERR, \"No space in harq input mbuf\");\n+\t\t\treturn;\n+\t\t}\n+\t\tuint16_t harq_in_length = RTE_MIN(\n+\t\t\t\tdec->harq_combined_input.length,\n+\t\t\t\t(uint32_t) dec->n_cb);\n+\t\tmemset(q->ag + harq_in_length, 0,\n+\t\t\t\tdec->n_cb - harq_in_length);\n+\t\trte_memcpy(q->ag, harq_in, harq_in_length);\n+\t}\n+\n+\tderm_req.p_in = (int8_t *) in;\n+\tderm_req.p_harq = q->ag; /* This doesn't include the filler bits */\n+\tderm_req.base_graph = dec->basegraph;\n+\tderm_req.zc = dec->z_c;\n+\tderm_req.ncb = dec->n_cb;\n+\tderm_req.e = e;\n+\tderm_req.k0 = 0; /* Actual output from SDK */\n+\tderm_req.isretx = check_bit(dec->op_flags,\n+\t\t\tRTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE);\n+\tderm_req.rvid = dec->rv_index;\n+\tderm_req.modulation_order = dec->q_m;\n+\tderm_req.start_null_index = parity_offset - dec->n_filler;\n+\tderm_req.num_of_null = dec->n_filler;\n+\n+\tbblib_rate_dematching_5gnr(&derm_req, &derm_resp);\n+\n+\t/* Compute RM out size and number of rows */\n+\tdeRmOutSize = RTE_MIN(\n+\t\t\tderm_req.k0 + derm_req.e -\n+\t\t\t((derm_req.k0 < derm_req.start_null_index) ?\n+\t\t\t\t\t0 : dec->n_filler),\n+\t\t\tdec->n_cb - dec->n_filler);\n+\tif (m_harq_in != NULL)\n+\t\tdeRmOutSize = RTE_MAX(deRmOutSize,\n+\t\t\t\tRTE_MIN(dec->n_cb - dec->n_filler,\n+\t\t\t\t\t\tm_harq_in->data_len));\n+\tnumRows = ((deRmOutSize + dec->n_filler + dec->z_c - 1) / dec->z_c)\n+\t\t\t- sys_cols + 2;\n+\tnumRows = RTE_MAX(4, numRows);\n+\n+\t/* get output data starting address */\n+\tout = (uint8_t *)mbuf_append(m_out_head, m_out, out_length);\n+\tif (out == NULL) {\n+\t\top->status |= 1 << RTE_BBDEV_DATA_ERROR;\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Too little space in LDPC decoder output mbuf\");\n+\t\treturn;\n+\t}\n+\n+\t/* rte_bbdev_op_data.offset can be different than the offset\n+\t * of the appended bytes\n+\t */\n+\tout = rte_pktmbuf_mtod_offset(m_out, uint8_t *, out_offset);\n+\tadapter_input = q->enc_out;\n+\n+\tdec_req.Zc = dec->z_c;\n+\tdec_req.baseGraph = dec->basegraph;\n+\tdec_req.nRows = numRows;\n+\tdec_req.numChannelLlrs = deRmOutSize;\n+\tdec_req.varNodes = derm_req.p_harq;\n+\tdec_req.numFillerBits = dec->n_filler;\n+\tdec_req.maxIterations = dec->iter_max;\n+\tdec_req.enableEarlyTermination = check_bit(dec->op_flags,\n+\t\t\tRTE_BBDEV_LDPC_ITERATION_STOP_ENABLE);\n+\tdec_resp.varNodes = (int16_t *) q->adapter_output;\n+\tdec_resp.compactedMessageBytes = q->enc_out;\n+\n+\tbblib_ldpc_decoder_5gnr(&dec_req, &dec_resp);\n+\n+\tdec->iter_count = RTE_MAX(dec_resp.iterationAtTermination,\n+\t\t\tdec->iter_count);\n+\tif (!dec_resp.parityPassedAtTermination)\n+\t\top->status |= 1 << RTE_BBDEV_SYNDROME_ERROR;\n+\n+\tbblib_bit_reverse((int8_t *) q->enc_out, outLenWithCrc << 3);\n+\n+\tif (check_bit(dec->op_flags, RTE_BBDEV_LDPC_CRC_TYPE_24A_CHECK) ||\n+\t\t\tcheck_bit(dec->op_flags,\n+\t\t\t\t\tRTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK)) {\n+\t\tcrc_req.data = adapter_input;\n+\t\tcrc_req.len  = K - dec->n_filler - 24;\n+\t\tcrc_resp.check_passed = false;\n+\t\tcrc_resp.data = adapter_input;\n+\t\tif (check_crc_24b)\n+\t\t\tbblib_lte_crc24b_check(&crc_req, &crc_resp);\n+\t\telse\n+\t\t\tbblib_lte_crc24a_check(&crc_req, &crc_resp);\n+\t\tif (!crc_resp.check_passed)\n+\t\t\top->status |= 1 << RTE_BBDEV_CRC_ERROR;\n+\t}\n+\n+#ifdef RTE_BBDEV_OFFLOAD_COST\n+\tq_stats->acc_offload_cycles += rte_rdtsc_precise() - start_time;\n+#endif\n+\tif (check_bit(dec->op_flags, RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE)) {\n+\t\tharq_out = NULL;\n+\t\tif (m_harq_out != NULL) {\n+\t\t\t/* Initialize HARQ data length since we overwrite */\n+\t\t\tm_harq_out->data_len = 0;\n+\t\t\t/* Check there is enough space\n+\t\t\t * in the HARQ outbound buffer\n+\t\t\t */\n+\t\t\tharq_out = (uint8_t *)mbuf_append(m_harq_out_head,\n+\t\t\t\t\tm_harq_out, deRmOutSize);\n+\t\t}\n+\t\tif (harq_out == NULL) {\n+\t\t\top->status |= 1 << RTE_BBDEV_DATA_ERROR;\n+\t\t\trte_bbdev_log(ERR, \"No space in HARQ output mbuf\");\n+\t\t\treturn;\n+\t\t}\n+\t\t/* get output data starting address and overwrite the data */\n+\t\tharq_out = rte_pktmbuf_mtod_offset(m_harq_out, uint8_t *,\n+\t\t\t\tharq_out_offset);\n+\t\trte_memcpy(harq_out, derm_req.p_harq, deRmOutSize);\n+\t\tdec->harq_combined_output.length += deRmOutSize;\n+\t}\n+\n+\trte_memcpy(out, adapter_input, out_length);\n+\tdec->hard_output.length += out_length;\n+#else\n+\tRTE_SET_USED(q);\n+\tRTE_SET_USED(op);\n+\tRTE_SET_USED(c);\n+\tRTE_SET_USED(out_length);\n+\tRTE_SET_USED(e);\n+\tRTE_SET_USED(m_in);\n+\tRTE_SET_USED(m_out_head);\n+\tRTE_SET_USED(m_out);\n+\tRTE_SET_USED(m_harq_in);\n+\tRTE_SET_USED(m_harq_out_head);\n+\tRTE_SET_USED(m_harq_out);\n+\tRTE_SET_USED(harq_in_offset);\n+\tRTE_SET_USED(harq_out_offset);\n+\tRTE_SET_USED(in_offset);\n+\tRTE_SET_USED(out_offset);\n+\tRTE_SET_USED(check_crc_24b);\n+\tRTE_SET_USED(crc24_overlap);\n+\tRTE_SET_USED(in_length);\n+\tRTE_SET_USED(q_stats);\n+#endif\n+}\n+\n+\n+static inline void\n enqueue_dec_one_op(struct turbo_sw_queue *q, struct rte_bbdev_dec_op *op,\n \t\tstruct rte_bbdev_stats *queue_stats)\n {\n@@ -1083,6 +1589,7 @@ struct turbo_sw_queue {\n \t\t\t\tin_offset, out_offset, check_bit(dec->op_flags,\n \t\t\t\tRTE_BBDEV_TURBO_CRC_TYPE_24B), crc24_overlap,\n \t\t\t\tseg_total_left, queue_stats);\n+\n \t\t/* To keep CRC24 attached to end of Code block, use\n \t\t * RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP flag as it\n \t\t * removed by default once verified.\n@@ -1104,6 +1611,103 @@ struct turbo_sw_queue {\n \t\t}\n \t\tr++;\n \t}\n+\n+\tif (mbuf_total_left != 0) {\n+\t\top->status |= 1 << RTE_BBDEV_DATA_ERROR;\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Mismatch between mbuf length and included Circular buffer sizes\");\n+\t}\n+}\n+\n+static inline void\n+enqueue_ldpc_dec_one_op(struct turbo_sw_queue *q, struct rte_bbdev_dec_op *op,\n+\t\tstruct rte_bbdev_stats *queue_stats)\n+{\n+\tuint8_t c, r = 0;\n+\tuint16_t e, out_length;\n+\tuint16_t crc24_overlap = 0;\n+\tstruct rte_bbdev_op_ldpc_dec *dec = &op->ldpc_dec;\n+\tstruct rte_mbuf *m_in = dec->input.data;\n+\tstruct rte_mbuf *m_harq_in = dec->harq_combined_input.data;\n+\tstruct rte_mbuf *m_harq_out = dec->harq_combined_output.data;\n+\tstruct rte_mbuf *m_harq_out_head = dec->harq_combined_output.data;\n+\tstruct rte_mbuf *m_out = dec->hard_output.data;\n+\tstruct rte_mbuf *m_out_head = dec->hard_output.data;\n+\tuint16_t in_offset = dec->input.offset;\n+\tuint16_t harq_in_offset = dec->harq_combined_input.offset;\n+\tuint16_t harq_out_offset = dec->harq_combined_output.offset;\n+\tuint16_t out_offset = dec->hard_output.offset;\n+\tuint32_t mbuf_total_left = dec->input.length;\n+\tuint16_t seg_total_left;\n+\n+\t/* Clear op status */\n+\top->status = 0;\n+\n+\tif (m_in == NULL || m_out == NULL) {\n+\t\trte_bbdev_log(ERR, \"Invalid mbuf pointer\");\n+\t\top->status = 1 << RTE_BBDEV_DATA_ERROR;\n+\t\treturn;\n+\t}\n+\n+\tif (dec->code_block_mode == 0) { /* For Transport Block mode */\n+\t\tc = dec->tb_params.c;\n+\t\te = dec->tb_params.ea;\n+\t} else { /* For Code Block mode */\n+\t\tc = 1;\n+\t\te = dec->cb_params.e;\n+\t}\n+\n+\tif (check_bit(dec->op_flags, RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP))\n+\t\tcrc24_overlap = 24;\n+\n+\tout_length = (dec->basegraph == 1 ? 22 : 10) * dec->z_c; /* K */\n+\tout_length = ((out_length - crc24_overlap - dec->n_filler) >> 3);\n+\n+\twhile (mbuf_total_left > 0) {\n+\t\tif (dec->code_block_mode == 0)\n+\t\t\te = (r < dec->tb_params.cab) ?\n+\t\t\t\tdec->tb_params.ea : dec->tb_params.eb;\n+\n+\t\tseg_total_left = rte_pktmbuf_data_len(m_in) - in_offset;\n+\n+\t\tprocess_ldpc_dec_cb(q, op, c, out_length, e,\n+\t\t\t\tm_in, m_out_head, m_out,\n+\t\t\t\tm_harq_in, m_harq_out_head, m_harq_out,\n+\t\t\t\tin_offset, out_offset, harq_in_offset,\n+\t\t\t\tharq_out_offset,\n+\t\t\t\tcheck_bit(dec->op_flags,\n+\t\t\t\tRTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK),\n+\t\t\t\tcrc24_overlap,\n+\t\t\t\tseg_total_left, queue_stats);\n+\n+\t\t/* To keep CRC24 attached to end of Code block, use\n+\t\t * RTE_BBDEV_LDPC_DEC_TB_CRC_24B_KEEP flag as it\n+\t\t * removed by default once verified.\n+\t\t */\n+\n+\t\tmbuf_total_left -= e;\n+\n+\t\t/* Update offsets */\n+\t\tif (seg_total_left == e) {\n+\t\t\t/* Go to the next mbuf */\n+\t\t\tm_in = m_in->next;\n+\t\t\tm_out = m_out->next;\n+\t\t\tif (m_harq_in != NULL)\n+\t\t\t\tm_harq_in = m_harq_in->next;\n+\t\t\tif (m_harq_out != NULL)\n+\t\t\t\tm_harq_out = m_harq_out->next;\n+\t\t\tin_offset = 0;\n+\t\t\tout_offset = 0;\n+\t\t\tharq_in_offset = 0;\n+\t\t\tharq_out_offset = 0;\n+\t\t} else {\n+\t\t\t/* Update offsets for next CBs (if exist) */\n+\t\t\tin_offset += e;\n+\t\t\tout_offset += out_length;\n+\t\t}\n+\t\tr++;\n+\t}\n+\n \tif (mbuf_total_left != 0) {\n \t\top->status |= 1 << RTE_BBDEV_DATA_ERROR;\n \t\trte_bbdev_log(ERR,\n@@ -1127,6 +1731,23 @@ struct turbo_sw_queue {\n \t\t\tNULL);\n }\n \n+static inline uint16_t\n+enqueue_ldpc_dec_all_ops(struct turbo_sw_queue *q,\n+\t\tstruct rte_bbdev_dec_op **ops,\n+\t\tuint16_t nb_ops, struct rte_bbdev_stats *queue_stats)\n+{\n+\tuint16_t i;\n+#ifdef RTE_BBDEV_OFFLOAD_COST\n+\tqueue_stats->acc_offload_cycles = 0;\n+#endif\n+\n+\tfor (i = 0; i < nb_ops; ++i)\n+\t\tenqueue_ldpc_dec_one_op(q, ops[i], queue_stats);\n+\n+\treturn rte_ring_enqueue_burst(q->processed_pkts, (void **)ops, nb_ops,\n+\t\t\tNULL);\n+}\n+\n /* Enqueue burst */\n static uint16_t\n enqueue_enc_ops(struct rte_bbdev_queue_data *q_data,\n@@ -1146,6 +1767,24 @@ struct turbo_sw_queue {\n \n /* Enqueue burst */\n static uint16_t\n+enqueue_ldpc_enc_ops(struct rte_bbdev_queue_data *q_data,\n+\t\tstruct rte_bbdev_enc_op **ops, uint16_t nb_ops)\n+{\n+\tvoid *queue = q_data->queue_private;\n+\tstruct turbo_sw_queue *q = queue;\n+\tuint16_t nb_enqueued = 0;\n+\n+\tnb_enqueued = enqueue_ldpc_enc_all_ops(\n+\t\t\tq, ops, nb_ops, &q_data->queue_stats);\n+\n+\tq_data->queue_stats.enqueue_err_count += nb_ops - nb_enqueued;\n+\tq_data->queue_stats.enqueued_count += nb_enqueued;\n+\n+\treturn nb_enqueued;\n+}\n+\n+/* Enqueue burst */\n+static uint16_t\n enqueue_dec_ops(struct rte_bbdev_queue_data *q_data,\n \t\t struct rte_bbdev_dec_op **ops, uint16_t nb_ops)\n {\n@@ -1161,6 +1800,24 @@ struct turbo_sw_queue {\n \treturn nb_enqueued;\n }\n \n+/* Enqueue burst */\n+static uint16_t\n+enqueue_ldpc_dec_ops(struct rte_bbdev_queue_data *q_data,\n+\t\t struct rte_bbdev_dec_op **ops, uint16_t nb_ops)\n+{\n+\tvoid *queue = q_data->queue_private;\n+\tstruct turbo_sw_queue *q = queue;\n+\tuint16_t nb_enqueued = 0;\n+\n+\tnb_enqueued = enqueue_ldpc_dec_all_ops(q, ops, nb_ops,\n+\t\t\t&q_data->queue_stats);\n+\n+\tq_data->queue_stats.enqueue_err_count += nb_ops - nb_enqueued;\n+\tq_data->queue_stats.enqueued_count += nb_enqueued;\n+\n+\treturn nb_enqueued;\n+}\n+\n /* Dequeue decode burst */\n static uint16_t\n dequeue_dec_ops(struct rte_bbdev_queue_data *q_data,\n@@ -1273,6 +1930,10 @@ struct turbo_sw_queue {\n \tbbdev->dequeue_dec_ops = dequeue_dec_ops;\n \tbbdev->enqueue_enc_ops = enqueue_enc_ops;\n \tbbdev->enqueue_dec_ops = enqueue_dec_ops;\n+\tbbdev->dequeue_ldpc_enc_ops = dequeue_enc_ops;\n+\tbbdev->dequeue_ldpc_dec_ops = dequeue_dec_ops;\n+\tbbdev->enqueue_ldpc_enc_ops = enqueue_ldpc_enc_ops;\n+\tbbdev->enqueue_ldpc_dec_ops = enqueue_ldpc_dec_ops;\n \t((struct bbdev_private *) bbdev->data->dev_private)->max_nb_queues =\n \t\t\tinit_params->queues_num;\n \ndiff --git a/drivers/baseband/turbo_sw/meson.build b/drivers/baseband/turbo_sw/meson.build\nindex 438b5a7..33345aa 100644\n--- a/drivers/baseband/turbo_sw/meson.build\n+++ b/drivers/baseband/turbo_sw/meson.build\n@@ -23,6 +23,16 @@ if dpdk_conf.has('RTE_BBDEV_SDK_AVX2')\n \t\tincludes += include_directories(path + '/lib_common')\n \tendif\n endif\n+if dpdk_conf.has('RTE_BBDEV_SDK_AVX512')\n+\text_deps += cc.find_library('libldpc_encoder_5gnr', dirs: [path + '/lib_ldpc_encoder_5gnr'], required: true)\n+\text_deps += cc.find_library('libldpc_decoder_5gnr', dirs: [path + '/lib_ldpc_decoder_5gnr'], required: true)\n+\text_deps += cc.find_library('libLDPC_ratematch_5gnr', dirs: [path + '/lib_LDPC_ratematch_5gnr'], required: true)\n+\text_deps += cc.find_library('librate_dematching_5gnr', dirs: [path + '/lib_rate_dematching_5gnr'], required: true)\n+\tincludes += include_directories(path + '/lib_ldpc_encoder_5gnr')\n+\tincludes += include_directories(path + '/lib_ldpc_decoder_5gnr')\n+\tincludes += include_directories(path + '/lib_LDPC_ratematch_5gnr')\n+\tincludes += include_directories(path + '/lib_rate_dematching_5gnr')\n+endif\n \n deps += ['bbdev', 'bus_vdev', 'ring']\n name = 'bbdev_turbo_sw'\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex c9fbdd6..1036df7 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -232,7 +232,13 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_crc -lcr\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_turbo -lturbo\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_rate_matching -lrate_matching\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_common -lcommon\n-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -lirc -limf -lstdc++ -lipps\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -lirc -limf -lstdc++ -lipps -lsvml\n+ifeq ($(CONFIG_RTE_BBDEV_SDK_AVX512),y)\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_LDPC_ratematch_5gnr -lLDPC_ratematch_5gnr\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_ldpc_encoder_5gnr -lldpc_encoder_5gnr\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_ldpc_decoder_5gnr -lldpc_decoder_5gnr\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW) += -L$(FLEXRAN_SDK)/lib_rate_dematching_5gnr -lrate_dematching_5gnr\n+endif # CONFIG_RTE_BBDEV_SDK_AVX512\n endif # CONFIG_RTE_BBDEV_SDK_AVX2\n endif # CONFIG_RTE_LIBRTE_BBDEV\n \n",
    "prefixes": [
        "v5",
        "4/7"
    ]
}