get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 136541,
    "url": "http://patches.dpdk.org/api/patches/136541/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20240208165038.36265-6-hernan.vargas@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": "<20240208165038.36265-6-hernan.vargas@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240208165038.36265-6-hernan.vargas@intel.com",
    "date": "2024-02-08T16:50:37",
    "name": "[v7,5/6] baseband/fpga_5gnr_fec: add AGX100 support",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "89015cea42dcc3d4c82bd0bcbc831e521e2392aa",
    "submitter": {
        "id": 2659,
        "url": "http://patches.dpdk.org/api/people/2659/?format=api",
        "name": "Hernan Vargas",
        "email": "hernan.vargas@intel.com"
    },
    "delegate": {
        "id": 2642,
        "url": "http://patches.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20240208165038.36265-6-hernan.vargas@intel.com/mbox/",
    "series": [
        {
            "id": 31054,
            "url": "http://patches.dpdk.org/api/series/31054/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=31054",
            "date": "2024-02-08T16:50:32",
            "name": "changes for 24.03",
            "version": 7,
            "mbox": "http://patches.dpdk.org/series/31054/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/136541/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/136541/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 6467443AE0;\n\tThu,  8 Feb 2024 17:54:36 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 5FEB742E54;\n\tThu,  8 Feb 2024 17:54:04 +0100 (CET)",
            "from mgamail.intel.com (mgamail.intel.com [192.198.163.13])\n by mails.dpdk.org (Postfix) with ESMTP id 59CF14028B\n for <dev@dpdk.org>; Thu,  8 Feb 2024 17:53:57 +0100 (CET)",
            "from fmviesa008.fm.intel.com ([10.60.135.148])\n by fmvoesa107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 08 Feb 2024 08:53:56 -0800",
            "from unknown (HELO csl-npg-qt0.la.intel.com) ([10.233.181.103])\n by fmviesa008.fm.intel.com with ESMTP; 08 Feb 2024 08:53:56 -0800"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1707411238; x=1738947238;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=rc4L2uOGN99wLbcYHU2NVlM1Y69pNNKEtt8aEavndao=;\n b=S/FyS8xyQvWCBBD8IIZ+9Sts2YaejLMI5nCLp0vOcedxHlOdtDQE7lmS\n hJV9UWGwmne7FgY7nkE+Ib6Hs/ogksFv36LFph3sVAv3vxqSoVf7jnGQp\n RN3kXL5hg7SjL/ht+zsHusoSG3gKzV9XORhLrPCNnwjOtn2pwmhniaSRo\n cX10dE+DERkSss68dFi9bCdOzMng8zgMfxsgKHuGxQ0iGdLYd0bqNesRB\n GYAbN43XBuotECegFGGXs9Qdc0ByYIXkUU4NoAS1vs9cl8AjF5pwNLim/\n nI0YvFAK8sDSRc+LWaWr7qNVhOc8kbmmVff8o66ZZcnwft8kMIxcoJ+l9 g==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6600,9927,10978\"; a=\"4244315\"",
            "E=Sophos;i=\"6.05,254,1701158400\";\n   d=\"scan'208\";a=\"4244315\"",
            "E=Sophos;i=\"6.05,254,1701158400\";\n   d=\"scan'208\";a=\"1933647\""
        ],
        "X-ExtLoop1": "1",
        "From": "Hernan Vargas <hernan.vargas@intel.com>",
        "To": "dev@dpdk.org, gakhil@marvell.com, trix@redhat.com,\n maxime.coquelin@redhat.com",
        "Cc": "nicolas.chautru@intel.com, qi.z.zhang@intel.com,\n Hernan Vargas <hernan.vargas@intel.com>",
        "Subject": "[PATCH v7 5/6] baseband/fpga_5gnr_fec: add AGX100 support",
        "Date": "Thu,  8 Feb 2024 08:50:37 -0800",
        "Message-Id": "<20240208165038.36265-6-hernan.vargas@intel.com>",
        "X-Mailer": "git-send-email 2.37.1",
        "In-Reply-To": "<20240208165038.36265-1-hernan.vargas@intel.com>",
        "References": "<20240208165038.36265-1-hernan.vargas@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "Add support for new FPGA variant AGX100 (on Arrow Creek N6000).\n\nSigned-off-by: Hernan Vargas <hernan.vargas@intel.com>\nReviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>\n---\n doc/guides/bbdevs/fpga_5gnr_fec.rst           |   69 +-\n drivers/baseband/fpga_5gnr_fec/agx100_pmd.h   |  273 ++++\n .../baseband/fpga_5gnr_fec/fpga_5gnr_fec.h    |   10 +-\n .../fpga_5gnr_fec/rte_fpga_5gnr_fec.c         | 1199 +++++++++++++++--\n drivers/baseband/fpga_5gnr_fec/vc_5gnr_pmd.h  |    1 -\n 5 files changed, 1438 insertions(+), 114 deletions(-)\n create mode 100644 drivers/baseband/fpga_5gnr_fec/agx100_pmd.h",
    "diff": "diff --git a/doc/guides/bbdevs/fpga_5gnr_fec.rst b/doc/guides/bbdevs/fpga_5gnr_fec.rst\nindex 99fc936829a8..1ae192a86b25 100644\n--- a/doc/guides/bbdevs/fpga_5gnr_fec.rst\n+++ b/doc/guides/bbdevs/fpga_5gnr_fec.rst\n@@ -6,12 +6,13 @@ Intel(R) FPGA 5GNR FEC Poll Mode Driver\n \n The BBDEV FPGA 5GNR FEC poll mode driver (PMD) supports an FPGA implementation of a VRAN\n LDPC Encode / Decode 5GNR wireless acceleration function, using Intel's PCI-e and FPGA\n-based Vista Creek device.\n+based Vista Creek (N3000, referred to as VC_5GNR in the code) as well as Arrow Creek (N6000,\n+referred to as AGX100 in the code).\n \n Features\n --------\n \n-FPGA 5GNR FEC PMD supports the following features:\n+FPGA 5GNR FEC PMD supports the following BBDEV capabilities:\n \n - LDPC Encode in the DL\n - LDPC Decode in the UL\n@@ -67,10 +68,18 @@ Initialization\n \n When the device first powers up, its PCI Physical Functions (PF) can be listed through this command:\n \n+Vista Creek (N3000)\n+\n .. code-block:: console\n \n   sudo lspci -vd8086:0d8f\n \n+Arrow Creek (N6000)\n+\n+.. code-block:: console\n+\n+  sudo lspci -vd8086:5799\n+\n The physical and virtual functions are compatible with Linux UIO drivers:\n ``vfio_pci`` and ``igb_uio``. However, in order to work the FPGA 5GNR FEC device firstly needs\n to be bound to one of these linux drivers through DPDK.\n@@ -78,6 +87,7 @@ to be bound to one of these linux drivers through DPDK.\n For more details on how to bind the PF device and create VF devices, see\n :ref:`linux_gsg_binding_kernel`.\n \n+\n Configure the VFs through PF\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n \n@@ -110,12 +120,12 @@ parameters defined in ``rte_fpga_5gnr_fec_conf`` structure:\n \n - ``vf_*l_queues_number``: defines the hardware queue mapping for every VF.\n \n-- ``*l_bandwidth``: in case of congestion on PCIe interface. The device\n-  allocates different bandwidth to UL and DL. The weight is configured by this\n-  setting. The unit of weight is 3 code blocks. For example, if the code block\n-  cbps (code block per second) ratio between UL and DL is 12:1, then the\n-  configuration value should be set to 36:3. The schedule algorithm is based\n-  on code block regardless the length of each block.\n+- ``*l_bandwidth``: Only used for the Vista Creek schedule algorithm in case of\n+  congestion on PCIe interface. The device allocates different bandwidth to UL\n+  and DL. The weight is configured by this setting. The unit of weight is 3 code\n+  blocks. For example, if the code block cbps (code block per second) ratio between\n+  UL and DL is 12:1, then the configuration value should be set to 36:3.\n+  The schedule algorithm is based on code block regardless the length of each block.\n \n - ``*l_load_balance``: hardware queues are load-balanced in a round-robin\n   fashion. Queues get filled first-in first-out until they reach a pre-defined\n@@ -159,8 +169,38 @@ Test Application\n BBDEV provides a test application, ``test-bbdev.py`` and range of test data for testing\n the functionality of the device, depending on the device's capabilities.\n \n-For more details on how to use the test application,\n-see :ref:`test_bbdev_application`.\n+.. code-block:: console\n+\n+  \"-p\", \"--testapp-path\": specifies path to the bbdev test app.\n+  \"-e\", \"--eal-params\"\t: EAL arguments which are passed to the test app.\n+  \"-t\", \"--timeout\"\t: Timeout in seconds (default=300).\n+  \"-c\", \"--test-cases\"\t: Defines test cases to run. Run all if not specified.\n+  \"-v\", \"--test-vector\"\t: Test vector path (default=dpdk_path+/app/test-bbdev/test_vectors/bbdev_null.data).\n+  \"-n\", \"--num-ops\"\t: Number of operations to process on device (default=32).\n+  \"-b\", \"--burst-size\"\t: Operations enqueue/dequeue burst size (default=32).\n+  \"-l\", \"--num-lcores\"\t: Number of lcores to run (default=16).\n+  \"-i\", \"--init-device\" : Initialise PF device with default values.\n+\n+\n+To execute the test application tool using simple decode or encode data,\n+type one of the following:\n+\n+.. code-block:: console\n+\n+  ./test-bbdev.py -c validation -n 64 -b 1 -v ./ldpc_dec_default.data\n+  ./test-bbdev.py -c validation -n 64 -b 1 -v ./ldpc_enc_default.data\n+\n+\n+The test application ``test-bbdev.py``, supports the ability to configure the PF device with\n+a default set of values, if the \"-i\" or \"- -init-device\" option is included. The default values\n+are defined in test_bbdev_perf.c as:\n+\n+- VF_UL_QUEUE_VALUE 4\n+- VF_DL_QUEUE_VALUE 4\n+- UL_BANDWIDTH 3\n+- DL_BANDWIDTH 3\n+- UL_LOAD_BALANCE 128\n+- DL_LOAD_BALANCE 128\n \n \n Test Vectors\n@@ -184,7 +224,16 @@ See for more details: https://github.com/intel/pf-bb-config\n \n Specifically for the BBDEV FPGA 5GNR FEC PMD, the command below can be used:\n \n+Vista Creek (N3000)\n+\n .. code-block:: console\n \n   ./pf_bb_config FPGA_5GNR -c fpga_5gnr/fpga_5gnr_config_vf.cfg\n   ./test-bbdev.py -e=\"-c 0xff0 -a${VF_PCI_ADDR}\" -c validation -n 64 -b 32 -l 1 -v ./ldpc_dec_default.data\n+\n+Arrow Creek (N6000)\n+\n+.. code-block:: console\n+\n+  ./pf_bb_config AGX100 -c agx100/agx100_config_1vf.cfg\n+  ./test-bbdev.py -e=\"-c 0xff0 -a${VF_PCI_ADDR}\" -c validation -n 64 -b 32 -l 1 -v ./ldpc_dec_default.data\ndiff --git a/drivers/baseband/fpga_5gnr_fec/agx100_pmd.h b/drivers/baseband/fpga_5gnr_fec/agx100_pmd.h\nnew file mode 100644\nindex 000000000000..5e562376c966\n--- /dev/null\n+++ b/drivers/baseband/fpga_5gnr_fec/agx100_pmd.h\n@@ -0,0 +1,273 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2022 Intel Corporation\n+ */\n+\n+#ifndef _AGX100_H_\n+#define _AGX100_H_\n+\n+#include <stdint.h>\n+#include <stdbool.h>\n+\n+/* AGX100 PCI vendor & device IDs. */\n+#define AGX100_VENDOR_ID (0x8086)\n+#define AGX100_PF_DEVICE_ID (0x5799)\n+#define AGX100_VF_DEVICE_ID (0x579A)\n+\n+/* Maximum number of possible queues supported on device. */\n+#define AGX100_MAXIMUM_QUEUES_SUPPORTED (64)\n+\n+/* AGX100 Ring size is in 256 bits (64 bytes) units. */\n+#define AGX100_RING_DESC_LEN_UNIT_BYTES (64)\n+\n+/* Align DMA descriptors to 256 bytes - cache-aligned. */\n+#define AGX100_RING_DESC_ENTRY_LENGTH (8)\n+\n+/* AGX100 Register mapping on BAR0. */\n+enum {\n+\tAGX100_FLR_TIME_OUT = 0x0000000E, /* len: 2B. */\n+\tAGX100_QUEUE_MAP = 0x00000100\t/* len: 256B. */\n+};\n+\n+/* AGX100 DESCRIPTOR ERROR. */\n+enum {\n+\tAGX100_DESC_ERR_NO_ERR = 0x00, /**< 4'b0000 2'b00. */\n+\tAGX100_DESC_ERR_E_NOT_LEGAL = 0x11, /**< 4'b0001 2'b01. */\n+\tAGX100_DESC_ERR_K_P_OUT_OF_RANGE = 0x21, /**< 4'b0010 2'b01. */\n+\tAGX100_DESC_ERR_NCB_OUT_OF_RANGE = 0x31, /**< 4'b0011 2'b01. */\n+\tAGX100_DESC_ERR_Z_C_NOT_LEGAL = 0x41, /**< 4'b0100 2'b01. */\n+\tAGX100_DESC_ERR_DESC_INDEX_ERR = 0x03, /**< 4'b0000 2'b11. */\n+\tAGX100_DESC_ERR_HARQ_INPUT_LEN_A = 0x51, /**< 4'b0101 2'b01. */\n+\tAGX100_DESC_ERR_HARQ_INPUT_LEN_B = 0x61, /**< 4'b0110 2'b01. */\n+\tAGX100_DESC_ERR_HBSTORE_OFFSET_ERR = 0x71, /**< 4'b0111 2'b01. */\n+\tAGX100_DESC_ERR_TB_CBG_ERR = 0x81, /**< 4'b1000 2'b01. */\n+\tAGX100_DESC_ERR_CBG_OUT_OF_RANGE = 0x91, /**< 4'b1001 2'b01. */\n+\tAGX100_DESC_ERR_CW_RM_NOT_LEGAL = 0xA1, /**< 4'b1010 2'b01. */\n+\tAGX100_DESC_ERR_UNSUPPORTED_REQ = 0x12, /**< 4'b0000 2'b10. */\n+\tAGX100_DESC_ERR_RESERVED = 0x22, /**< 4'b0010 2'b10. */\n+\tAGX100_DESC_ERR_DESC_ABORT = 0x42, /**< 4'b0100 2'b10. */\n+\tAGX100_DESC_ERR_DESC_READ_TLP_POISONED = 0x82 /**< 4'b1000 2'b10. */\n+};\n+\n+/* AGX100 TX Slice Descriptor. */\n+struct __rte_packed agx100_input_slice_desc {\n+\tuint32_t input_start_addr_lo;\n+\tuint32_t input_start_addr_hi;\n+\tuint32_t input_slice_length:21,\n+\t\trsrvd0:9,\n+\t\tend_of_pkt:1,\n+\t\tstart_of_pkt:1;\n+\tuint32_t input_slice_time_stamp:31,\n+\t\tinput_c:1;\n+};\n+\n+/* AGX100 RX Slice Descriptor. */\n+struct __rte_packed agx100_output_slice_desc {\n+\tuint32_t output_start_addr_lo;\n+\tuint32_t output_start_addr_hi;\n+\tuint32_t output_slice_length:21,\n+\t\trsrvd0:9,\n+\t\tend_of_pkt:1,\n+\t\tstart_of_pkt:1;\n+\tuint32_t output_slice_time_stamp:31,\n+\t\toutput_c:1;\n+};\n+\n+/* AGX100 DL DMA Encoding Request Descriptor. */\n+struct __rte_packed agx100_dma_enc_desc {\n+\tuint32_t done:1, /**< 0: not completed 1: completed. */\n+\t\trsrvd0:17,\n+\t\terror_msg:2,\n+\t\terror_code:4,\n+\t\trsrvd1:8;\n+\tuint32_t ncb:16, /**< Limited circular buffer size. */\n+\t\tbg_idx:1, /**< Base Graph 0: BG1 1: BG2.*/\n+\t\tqm_idx:3, /**< 0: BPSK; 1: QPSK; 2: 16QAM; 3: 64QAM; 4: 256QAM. */\n+\t\tzc:9, /**< Lifting size. */\n+\t\trv:2, /**< Redundancy version number. */\n+\t\tint_en:1; /**< Interrupt enable. */\n+\tuint32_t max_cbg:4, /**< Only valid when workload is TB or CBGs. */\n+\t\trsrvd2:4,\n+\t\tcbgti:8, /**< CBG bitmap. */\n+\t\trsrvd3:4,\n+\t\tcbgs:1, /**< 0: TB or CB 1: CBGs. */\n+\t\tdesc_idx:11; /**< Sequence number of the descriptor. */\n+\tuint32_t ca:10, /**< Code block number with Ea in TB or CBG. */\n+\t\tc:10, /**< Total code block number in TB or CBG. */\n+\t\trsrvd4:2,\n+\t\tnum_null:10; /**< Number of null bits. */\n+\tuint32_t ea:21, /**< Value of E when workload is CB. */\n+\t\trsrvd5:11;\n+\tuint32_t eb:21, /**< Only valid when workload is TB or CBGs. */\n+\t\trsrvd6:11;\n+\tuint32_t k_:16, /**< Code block length without null bits. */\n+\t\trsrvd7:8,\n+\t\ten_slice_ts:1, /**< Enable slice descriptor timestamp. */\n+\t\ten_host_ts:1, /**< Enable host descriptor timestamp. */\n+\t\ten_cb_wr_status:1, /**< Enable code block write back status. */\n+\t\ten_output_sg:1, /**< Enable RX scatter-gather. */\n+\t\ten_input_sg:1, /**< Enable TX scatter-gather. */\n+\t\ttb_cb:1, /**< 2'b10: the descriptor is for a TrBlk.\n+\t\t\t   * 2'b00: the descriptor is for a CBlk.\n+\t\t\t   * 2'b11 or 01: the descriptor is for a CBGs.\n+\t\t\t   */\n+\t\tcrc_en:1, /**< 1: CB CRC enabled 0: CB CRC disabled.\n+\t\t\t    * Only valid when workload is CB or CBGs.\n+\t\t\t    */\n+\t\trsrvd8:1;\n+\tuint32_t rsrvd9;\n+\tunion {\n+\t\tuint32_t input_slice_table_addr_lo; /**<Used when scatter-gather enabled.*/\n+\t\tuint32_t input_start_addr_lo; /**< Used when scatter-gather disabled. */\n+\t};\n+\tunion {\n+\t\tuint32_t input_slice_table_addr_hi; /**<Used when scatter-gather enabled.*/\n+\t\tuint32_t input_start_addr_hi; /**< Used when scatter-gather disabled. */\n+\t};\n+\tunion {\n+\t\tuint32_t input_slice_num:21, /**< Used when scatter-gather enabled. */\n+\t\t\trsrvd10:11;\n+\t\tuint32_t input_length:26, /**< Used when scatter-gather disabled. */\n+\t\t\trsrvd11:6;\n+\t};\n+\tunion {\n+\t\tuint32_t output_slice_table_addr_lo; /**< Used when scatter-gather enabled.*/\n+\t\tuint32_t output_start_addr_lo; /**< Used when scatter-gather disabled. */\n+\t};\n+\tunion {\n+\t\tuint32_t output_slice_table_addr_hi; /**< Used when scatter-gather enabled.*/\n+\t\tuint32_t output_start_addr_hi; /**< Used when scatter-gather disabled. */\n+\t};\n+\tunion {\n+\t\tuint32_t output_slice_num:21, /**< Used when scatter-gather enabled. */\n+\t\t\trsrvd12:11;\n+\t\tuint32_t output_length:26, /**< Used when scatter-gather disabled. */\n+\t\t\trsrvd13:6;\n+\t};\n+\tuint32_t enqueue_timestamp:31, /**< Time when AGX100 receives descriptor. */\n+\t\trsrvd14:1;\n+\tuint32_t completion_timestamp:31, /**< Time when AGX100 completes descriptor. */\n+\t\trsrvd15:1;\n+\n+\tunion {\n+\t\tstruct {\n+\t\t\t/** Virtual addresses used to retrieve SW context info. */\n+\t\t\tvoid *op_addr;\n+\t\t\t/** Stores information about total number of Code Blocks\n+\t\t\t * in currently processed Transport Block\n+\t\t\t */\n+\t\t\tuint64_t cbs_in_op;\n+\t\t};\n+\n+\t\tuint8_t sw_ctxt[AGX100_RING_DESC_LEN_UNIT_BYTES *\n+\t\t\t\t\t(AGX100_RING_DESC_ENTRY_LENGTH - 1)];\n+\t};\n+};\n+\n+/* AGX100 UL DMA Decoding Request Descriptor. */\n+struct __rte_packed agx100_dma_dec_desc {\n+\tuint32_t done:1, /**< 0: not completed 1: completed. */\n+\t\ttb_crc_pass:1, /**< 0: doesn't pass 1: pass. */\n+\t\tcb_crc_all_pass:1, /**< 0: doesn't pass 1: pass. */\n+\t\tcb_all_et_pass:1, /**< 0: not all decoded 1: all decoded. */\n+\t\tmax_iter_ret:6, /**< Iteration number returned by LDPC decoder. */\n+\t\tcgb_crc_bitmap:8, /**< Field valid only when workload is TB or CBGs. */\n+\t\terror_msg:2,\n+\t\terror_code:4,\n+\t\tet_dis:1, /**< Disable the early termination feature of LDPC decoder. */\n+\t\tharq_in_en:1, /**< 0: combine disabled 1: combine enable.*/\n+\t\tmax_iter:6; /**< Maximum value of iteration for decoding CB. */\n+\tuint32_t ncb:16, /**< Limited circular buffer size. */\n+\t\tbg_idx:1, /**< Base Graph 0: BG1 1: BG2.*/\n+\t\tqm_idx:3, /**< 0: BPSK; 1: QPSK; 2: 16QAM; 3: 64QAM; 4: 256QAM. */\n+\t\tzc:9, /**< Lifting size. */\n+\t\trv:2, /**< Redundancy version number. */\n+\t\tint_en:1; /**< Interrupt enable. */\n+\tuint32_t max_cbg:4, /**< Only valid when workload is TB or CBGs. */\n+\t\trsrvd0:4,\n+\t\tcbgti:8, /**< CBG bitmap. */\n+\t\tcbgfi:1, /**< 0: overwrite HARQ buffer 1: enable HARQ for CBGs. */\n+\t\trsrvd1:3,\n+\t\tcbgs:1, /**< 0: TB or CB 1: CBGs. */\n+\t\tdesc_idx:11; /**< Sequence number of the descriptor. */\n+\tuint32_t ca:10, /**< Code block number with Ea in TB or CBG. */\n+\t\tc:10, /**< Total code block number in TB or CBG. */\n+\t\tllr_pckg:1, /**< 0: 8-bit LLR 1: 6-bit LLR packed together. */\n+\t\tsyndrome_check_mode:1, /**<0: full syndrome check 1: 4-layer syndome check.*/\n+\t\tnum_null:10; /**< Number of null bits. */\n+\tuint32_t ea:21, /**< Value of E when workload is CB. */\n+\t\trsrvd2:3,\n+\t\teba:8; /**< Only valid when workload is TB or CBGs. */\n+\tuint32_t hbstore_offset_out:24, /**< HARQ buffer write address. */\n+\t\trsrvd3:8;\n+\tuint32_t hbstore_offset_in:24, /**< HARQ buffer read address. */\n+\t\ten_slice_ts:1, /**< Enable slice descriptor timestamp. */\n+\t\ten_host_ts:1, /**< Enable host descriptor timestamp. */\n+\t\ten_cb_wr_status:1, /**< Enable code block write back status. */\n+\t\ten_output_sg:1, /**< Enable RX scatter-gather. */\n+\t\ten_input_sg:1, /**< Enable TX scatter-gather. */\n+\t\ttb_cb:1, /**< 2'b10: the descriptor is for a TrBlk.\n+\t\t\t   * 2'b00: the descriptor is for a CBlk.\n+\t\t\t   * 2'b11 or 01: the descriptor is for a CBGs.\n+\t\t\t   */\n+\t\tcrc24b_ind:1,  /**< 1: CB includes CRC, need LDPC-V to check the CB CRC.\n+\t\t\t\t * 0: There is no CB CRC check.\n+\t\t\t\t * Only valid when workload is CB or CBGs.\n+\t\t\t\t */\n+\t\tdrop_crc24b:1; /**< 1: CB CRC will be dropped. */\n+\tuint32_t harq_input_length_a: 16, /**< HARQ_input_length for CB. */\n+\t\tharq_input_length_b:16; /**< Only valid when workload is TB or CBGs. */\n+\tunion {\n+\t\tuint32_t input_slice_table_addr_lo; /**< Used when scatter-gather enabled.*/\n+\t\tuint32_t input_start_addr_lo; /**< Used when scatter-gather disabled. */\n+\t};\n+\tunion {\n+\t\tuint32_t input_slice_table_addr_hi; /**< Used when scatter-gather enabled.*/\n+\t\tuint32_t input_start_addr_hi; /**< Used when scatter-gather disabled. */\n+\t};\n+\tunion {\n+\t\tuint32_t input_slice_num:21, /**< Used when scatter-gather enabled. */\n+\t\t\trsrvd4:11;\n+\t\tuint32_t input_length:26, /**< Used when scatter-gather disabled. */\n+\t\t\trsrvd5:6;\n+\t};\n+\tunion {\n+\t\tuint32_t output_slice_table_addr_lo; /**< Used when scatter-gather enabled.*/\n+\t\tuint32_t output_start_addr_lo; /**< Used when scatter-gather disabled. */\n+\t};\n+\tunion {\n+\t\tuint32_t output_slice_table_addr_hi; /**< Used when scatter-gather enabled.*/\n+\t\tuint32_t output_start_addr_hi; /**< Used when scatter-gather disabled. */\n+\t};\n+\tunion {\n+\t\tuint32_t output_slice_num:21, /**< Used when scatter-gather enabled. */\n+\t\t\trsrvd6:11;\n+\t\tuint32_t output_length:26, /**< Used when scatter-gather disabled. */\n+\t\t\trsrvd7:6;\n+\t};\n+\tuint32_t enqueue_timestamp:31, /**< Time when AGX100 receives descriptor. */\n+\t\trsrvd8:1;\n+\tuint32_t completion_timestamp:31, /**< Time when AGX100 completes descriptor. */\n+\t\trsrvd9:1;\n+\n+\tunion {\n+\t\tstruct {\n+\t\t\t/** Virtual addresses used to retrieve SW context info. */\n+\t\t\tvoid *op_addr;\n+\t\t\t/** Stores information about total number of Code Blocks\n+\t\t\t * in currently processed Transport Block\n+\t\t\t */\n+\t\t\tuint8_t cbs_in_op;\n+\t\t};\n+\n+\t\tuint8_t sw_ctxt[AGX100_RING_DESC_LEN_UNIT_BYTES *\n+\t\t\t\t\t(AGX100_RING_DESC_ENTRY_LENGTH - 1)];\n+\t};\n+};\n+\n+/* AGX100 DMA Descriptor. */\n+union agx100_dma_desc {\n+\tstruct agx100_dma_enc_desc enc_req;\n+\tstruct agx100_dma_dec_desc dec_req;\n+};\n+\n+#endif /* _AGX100_H_ */\ndiff --git a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h\nindex 879e5467ef3d..224684902569 100644\n--- a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h\n+++ b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h\n@@ -8,6 +8,7 @@\n #include <stdint.h>\n #include <stdbool.h>\n \n+#include \"agx100_pmd.h\"\n #include \"vc_5gnr_pmd.h\"\n \n /* Helper macro for logging */\n@@ -133,12 +134,19 @@ struct fpga_5gnr_fec_device {\n \tbool pf_device;\n \t/** Maximum number of possible queues for this device. */\n \tuint8_t total_num_queues;\n+\t/** FPGA Variant. VC_5GNR_FPGA_VARIANT = 0; AGX100_FPGA_VARIANT = 1. */\n+\tuint8_t fpga_variant;\n };\n \n /** Structure associated with each queue. */\n struct __rte_cache_aligned fpga_5gnr_queue {\n \tstruct fpga_5gnr_ring_ctrl_reg ring_ctrl_reg;  /**< Ring Control Register */\n-\tunion vc_5gnr_dma_desc *vc_5gnr_ring_addr; /**< Virtual address of VC 5GNR software ring. */\n+\tunion {\n+\t\t/** Virtual address of VC 5GNR software ring. */\n+\t\tunion vc_5gnr_dma_desc *vc_5gnr_ring_addr;\n+\t\t/** Virtual address of AGX100 software ring. */\n+\t\tunion agx100_dma_desc *agx100_ring_addr;\n+\t};\n \tuint64_t *ring_head_addr;  /* Virtual address of completion_head */\n \tuint64_t shadow_completion_head; /* Shadow completion head value */\n \tuint16_t head_free_desc;  /* Ring head */\ndiff --git a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c\nindex 3fb505775f61..6beb10e546c4 100644\n--- a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c\n+++ b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c\n@@ -18,8 +18,8 @@\n #include <rte_bbdev.h>\n #include <rte_bbdev_pmd.h>\n \n-#include \"fpga_5gnr_fec.h\"\n #include \"rte_pmd_fpga_5gnr_fec.h\"\n+#include \"fpga_5gnr_fec.h\"\n \n #ifdef RTE_LIBRTE_BBDEV_DEBUG\n RTE_LOG_REGISTER_DEFAULT(fpga_5gnr_fec_logtype, DEBUG);\n@@ -71,24 +71,28 @@ print_ring_reg_debug_info(void *mmio_base, uint32_t offset)\n \n /* Read Static Register of Vista Creek device. */\n static inline void\n-print_static_reg_debug_info(void *mmio_base)\n+print_static_reg_debug_info(void *mmio_base, uint8_t fpga_variant)\n {\n-\tuint16_t config = fpga_5gnr_reg_read_16(mmio_base, VC_5GNR_CONFIGURATION);\n-\tuint8_t qmap_done = fpga_5gnr_reg_read_8(mmio_base,\n-\t\t\tFPGA_5GNR_FEC_QUEUE_PF_VF_MAP_DONE);\n-\tuint16_t lb_factor = fpga_5gnr_reg_read_16(mmio_base,\n-\t\t\tFPGA_5GNR_FEC_LOAD_BALANCE_FACTOR);\n-\tuint16_t ring_desc_len = fpga_5gnr_reg_read_16(mmio_base,\n-\t\t\tFPGA_5GNR_FEC_RING_DESC_LEN);\n-\n-\trte_bbdev_log_debug(\"UL.DL Weights = %u.%u\",\n-\t\t\t((uint8_t)config), ((uint8_t)(config >> 8)));\n+\tuint16_t config;\n+\tuint8_t qmap_done = fpga_5gnr_reg_read_8(mmio_base, FPGA_5GNR_FEC_QUEUE_PF_VF_MAP_DONE);\n+\tuint16_t lb_factor = fpga_5gnr_reg_read_16(mmio_base, FPGA_5GNR_FEC_LOAD_BALANCE_FACTOR);\n+\tuint16_t ring_desc_len = fpga_5gnr_reg_read_16(mmio_base, FPGA_5GNR_FEC_RING_DESC_LEN);\n+\tif (fpga_variant == VC_5GNR_FPGA_VARIANT)\n+\t\tconfig = fpga_5gnr_reg_read_16(mmio_base, VC_5GNR_CONFIGURATION);\n+\n+\tif (fpga_variant == VC_5GNR_FPGA_VARIANT)\n+\t\trte_bbdev_log_debug(\"UL.DL Weights = %u.%u\",\n+\t\t\t\t((uint8_t)config), ((uint8_t)(config >> 8)));\n \trte_bbdev_log_debug(\"UL.DL Load Balance = %u.%u\",\n \t\t\t((uint8_t)lb_factor), ((uint8_t)(lb_factor >> 8)));\n \trte_bbdev_log_debug(\"Queue-PF/VF Mapping Table = %s\",\n \t\t\t(qmap_done > 0) ? \"READY\" : \"NOT-READY\");\n-\trte_bbdev_log_debug(\"Ring Descriptor Size = %u bytes\",\n-\t\t\tring_desc_len*VC_5GNR_RING_DESC_LEN_UNIT_BYTES);\n+\tif (fpga_variant == VC_5GNR_FPGA_VARIANT)\n+\t\trte_bbdev_log_debug(\"Ring Descriptor Size = %u bytes\",\n+\t\t\t\tring_desc_len * VC_5GNR_RING_DESC_LEN_UNIT_BYTES);\n+\telse\n+\t\trte_bbdev_log_debug(\"Ring Descriptor Size = %u bytes\",\n+\t\t\t\tring_desc_len * AGX100_RING_DESC_LEN_UNIT_BYTES);\n }\n \n /* Print decode DMA Descriptor of Vista Creek Decoder device. */\n@@ -142,6 +146,108 @@ vc_5gnr_print_dma_dec_desc_debug_info(union vc_5gnr_dma_desc *desc)\n \t\t\tword[4], word[5], word[6], word[7]);\n }\n \n+/* Print decode DMA Descriptor of AGX100 Decoder device. */\n+static void\n+agx100_print_dma_dec_desc_debug_info(union agx100_dma_desc *desc)\n+{\n+\trte_bbdev_log_debug(\"DMA response desc %p\\n\"\n+\t\t\t\"\\t-- done(%\"PRIu32\") | tb_crc_pass(%\"PRIu32\") | cb_crc_all_pass(%\"PRIu32\")\"\n+\t\t\t\" | cb_all_et_pass(%\"PRIu32\") | max_iter_ret(%\"PRIu32\") |\"\n+\t\t\t\"cgb_crc_bitmap(%\"PRIu32\") | error_msg(%\"PRIu32\") | error_code(%\"PRIu32\") |\"\n+\t\t\t\"et_dis (%\"PRIu32\") | harq_in_en(%\"PRIu32\") | max_iter(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- ncb(%\"PRIu32\") | bg_idx (%\"PRIu32\") | qm_idx (%\"PRIu32\")\"\n+\t\t\t\"| zc(%\"PRIu32\") | rv(%\"PRIu32\") | int_en(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- max_cbg(%\"PRIu32\") | cbgti(%\"PRIu32\") | cbgfi(%\"PRIu32\") |\"\n+\t\t\t\"cbgs(%\"PRIu32\") | desc_idx(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- ca(%\"PRIu32\") | c(%\"PRIu32\") | llr_pckg(%\"PRIu32\") |\"\n+\t\t\t\"syndrome_check_mode(%\"PRIu32\") | num_null(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- ea(%\"PRIu32\") | eba(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- hbstore_offset_out(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- hbstore_offset_in(%\"PRIu32\") | en_slice_ts(%\"PRIu32\") |\"\n+\t\t\t\"en_host_ts(%\"PRIu32\") | en_cb_wr_status(%\"PRIu32\")\"\n+\t\t\t\" | en_output_sg(%\"PRIu32\") | en_input_sg(%\"PRIu32\") | tb_cb(%\"PRIu32\")\"\n+\t\t\t\" | crc24b_ind(%\"PRIu32\")| drop_crc24b(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- harq_input_length_a(%\"PRIu32\") | harq_input_length_b(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- input_slice_table_addr_lo(%\"PRIu32\")\"\n+\t\t\t\" | input_start_addr_lo(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- input_slice_table_addr_hi(%\"PRIu32\")\"\n+\t\t\t\" | input_start_addr_hi(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- input_slice_num(%\"PRIu32\") | input_length(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- output_slice_table_addr_lo(%\"PRIu32\")\"\n+\t\t\t\" | output_start_addr_lo(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- output_slice_table_addr_hi(%\"PRIu32\")\"\n+\t\t\t\" | output_start_addr_hi(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- output_slice_num(%\"PRIu32\") | output_length(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- enqueue_timestamp(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- completion_timestamp(%\"PRIu32\")\\n\",\n+\t\t\tdesc,\n+\t\t\t(uint32_t)desc->dec_req.done,\n+\t\t\t(uint32_t)desc->dec_req.tb_crc_pass,\n+\t\t\t(uint32_t)desc->dec_req.cb_crc_all_pass,\n+\t\t\t(uint32_t)desc->dec_req.cb_all_et_pass,\n+\t\t\t(uint32_t)desc->dec_req.max_iter_ret,\n+\t\t\t(uint32_t)desc->dec_req.cgb_crc_bitmap,\n+\t\t\t(uint32_t)desc->dec_req.error_msg,\n+\t\t\t(uint32_t)desc->dec_req.error_code,\n+\t\t\t(uint32_t)desc->dec_req.et_dis,\n+\t\t\t(uint32_t)desc->dec_req.harq_in_en,\n+\t\t\t(uint32_t)desc->dec_req.max_iter,\n+\t\t\t(uint32_t)desc->dec_req.ncb,\n+\t\t\t(uint32_t)desc->dec_req.bg_idx,\n+\t\t\t(uint32_t)desc->dec_req.qm_idx,\n+\t\t\t(uint32_t)desc->dec_req.zc,\n+\t\t\t(uint32_t)desc->dec_req.rv,\n+\t\t\t(uint32_t)desc->dec_req.int_en,\n+\t\t\t(uint32_t)desc->dec_req.max_cbg,\n+\t\t\t(uint32_t)desc->dec_req.cbgti,\n+\t\t\t(uint32_t)desc->dec_req.cbgfi,\n+\t\t\t(uint32_t)desc->dec_req.cbgs,\n+\t\t\t(uint32_t)desc->dec_req.desc_idx,\n+\t\t\t(uint32_t)desc->dec_req.ca,\n+\t\t\t(uint32_t)desc->dec_req.c,\n+\t\t\t(uint32_t)desc->dec_req.llr_pckg,\n+\t\t\t(uint32_t)desc->dec_req.syndrome_check_mode,\n+\t\t\t(uint32_t)desc->dec_req.num_null,\n+\t\t\t(uint32_t)desc->dec_req.ea,\n+\t\t\t(uint32_t)desc->dec_req.eba,\n+\t\t\t(uint32_t)desc->dec_req.hbstore_offset_out,\n+\t\t\t(uint32_t)desc->dec_req.hbstore_offset_in,\n+\t\t\t(uint32_t)desc->dec_req.en_slice_ts,\n+\t\t\t(uint32_t)desc->dec_req.en_host_ts,\n+\t\t\t(uint32_t)desc->dec_req.en_cb_wr_status,\n+\t\t\t(uint32_t)desc->dec_req.en_output_sg,\n+\t\t\t(uint32_t)desc->dec_req.en_input_sg,\n+\t\t\t(uint32_t)desc->dec_req.tb_cb,\n+\t\t\t(uint32_t)desc->dec_req.crc24b_ind,\n+\t\t\t(uint32_t)desc->dec_req.drop_crc24b,\n+\t\t\t(uint32_t)desc->dec_req.harq_input_length_a,\n+\t\t\t(uint32_t)desc->dec_req.harq_input_length_b,\n+\t\t\t(uint32_t)desc->dec_req.input_slice_table_addr_lo,\n+\t\t\t(uint32_t)desc->dec_req.input_start_addr_lo,\n+\t\t\t(uint32_t)desc->dec_req.input_slice_table_addr_hi,\n+\t\t\t(uint32_t)desc->dec_req.input_start_addr_hi,\n+\t\t\t(uint32_t)desc->dec_req.input_slice_num,\n+\t\t\t(uint32_t)desc->dec_req.input_length,\n+\t\t\t(uint32_t)desc->dec_req.output_slice_table_addr_lo,\n+\t\t\t(uint32_t)desc->dec_req.output_start_addr_lo,\n+\t\t\t(uint32_t)desc->dec_req.output_slice_table_addr_hi,\n+\t\t\t(uint32_t)desc->dec_req.output_start_addr_hi,\n+\t\t\t(uint32_t)desc->dec_req.output_slice_num,\n+\t\t\t(uint32_t)desc->dec_req.output_length,\n+\t\t\t(uint32_t)desc->dec_req.enqueue_timestamp,\n+\t\t\t(uint32_t)desc->dec_req.completion_timestamp);\n+\n+\tuint32_t *word = (uint32_t *) desc;\n+\trte_bbdev_log_debug(\"%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n\"\n+\t\t\t\"%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n\"\n+\t\t\t\"%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n\"\n+\t\t\t\"%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n\",\n+\t\t\tword[0], word[1], word[2], word[3],\n+\t\t\tword[4], word[5], word[6], word[7],\n+\t\t\tword[8], word[9], word[10], word[11],\n+\t\t\tword[12], word[13], word[14], word[15]);\n+}\n+\n /* Print decode DMA Descriptor of Vista Creek encoder device. */\n static void\n vc_5gnr_print_dma_enc_desc_debug_info(union vc_5gnr_dma_desc *desc)\n@@ -175,8 +281,102 @@ vc_5gnr_print_dma_enc_desc_debug_info(union vc_5gnr_dma_desc *desc)\n \t\t\tword[4], word[5], word[6], word[7]);\n }\n \n+/* Print decode DMA Descriptor of AGX100 encoder device. */\n+static void\n+agx100_print_dma_enc_desc_debug_info(union agx100_dma_desc *desc)\n+{\n+\trte_bbdev_log_debug(\"DMA response desc %p\\n\"\n+\t\t\t\"\\t-- done(%\"PRIu32\") | error_msg(%\"PRIu32\") | error_code(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- ncb(%\"PRIu32\") | bg_idx (%\"PRIu32\") | qm_idx (%\"PRIu32\")\"\n+\t\t\t\"| zc(%\"PRIu32\") | rv(%\"PRIu32\") | int_en(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- max_cbg(%\"PRIu32\") | cbgti(%\"PRIu32\") | cbgs(%\"PRIu32\") | \"\n+\t\t\t\"desc_idx(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- ca(%\"PRIu32\") | c(%\"PRIu32\") | num_null(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- ea(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- eb(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- k_(%\"PRIu32\") | en_slice_ts(%\"PRIu32\") | en_host_ts(%\"PRIu32\") | \"\n+\t\t\t\"en_cb_wr_status(%\"PRIu32\") | en_output_sg(%\"PRIu32\") | \"\n+\t\t\t\"en_input_sg(%\"PRIu32\") | tb_cb(%\"PRIu32\") | crc_en(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- input_slice_table_addr_lo(%\"PRIu32\")\"\n+\t\t\t\" | input_start_addr_lo(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- input_slice_table_addr_hi(%\"PRIu32\")\"\n+\t\t\t\" | input_start_addr_hi(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- input_slice_num(%\"PRIu32\") | input_length(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- output_slice_table_addr_lo(%\"PRIu32\")\"\n+\t\t\t\" | output_start_addr_lo(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- output_slice_table_addr_hi(%\"PRIu32\")\"\n+\t\t\t\" | output_start_addr_hi(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- output_slice_num(%\"PRIu32\") | output_length(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- enqueue_timestamp(%\"PRIu32\")\\n\"\n+\t\t\t\"\\t-- completion_timestamp(%\"PRIu32\")\\n\",\n+\t\t\tdesc,\n+\t\t\t(uint32_t)desc->enc_req.done,\n+\t\t\t(uint32_t)desc->enc_req.error_msg,\n+\t\t\t(uint32_t)desc->enc_req.error_code,\n+\t\t\t(uint32_t)desc->enc_req.ncb,\n+\t\t\t(uint32_t)desc->enc_req.bg_idx,\n+\t\t\t(uint32_t)desc->enc_req.qm_idx,\n+\t\t\t(uint32_t)desc->enc_req.zc,\n+\t\t\t(uint32_t)desc->enc_req.rv,\n+\t\t\t(uint32_t)desc->enc_req.int_en,\n+\t\t\t(uint32_t)desc->enc_req.max_cbg,\n+\t\t\t(uint32_t)desc->enc_req.cbgti,\n+\t\t\t(uint32_t)desc->enc_req.cbgs,\n+\t\t\t(uint32_t)desc->enc_req.desc_idx,\n+\t\t\t(uint32_t)desc->enc_req.ca,\n+\t\t\t(uint32_t)desc->enc_req.c,\n+\t\t\t(uint32_t)desc->enc_req.num_null,\n+\t\t\t(uint32_t)desc->enc_req.ea,\n+\t\t\t(uint32_t)desc->enc_req.eb,\n+\t\t\t(uint32_t)desc->enc_req.k_,\n+\t\t\t(uint32_t)desc->enc_req.en_slice_ts,\n+\t\t\t(uint32_t)desc->enc_req.en_host_ts,\n+\t\t\t(uint32_t)desc->enc_req.en_cb_wr_status,\n+\t\t\t(uint32_t)desc->enc_req.en_output_sg,\n+\t\t\t(uint32_t)desc->enc_req.en_input_sg,\n+\t\t\t(uint32_t)desc->enc_req.tb_cb,\n+\t\t\t(uint32_t)desc->enc_req.crc_en,\n+\t\t\t(uint32_t)desc->enc_req.input_slice_table_addr_lo,\n+\t\t\t(uint32_t)desc->enc_req.input_start_addr_lo,\n+\t\t\t(uint32_t)desc->enc_req.input_slice_table_addr_hi,\n+\t\t\t(uint32_t)desc->enc_req.input_start_addr_hi,\n+\t\t\t(uint32_t)desc->enc_req.input_slice_num,\n+\t\t\t(uint32_t)desc->enc_req.input_length,\n+\t\t\t(uint32_t)desc->enc_req.output_slice_table_addr_lo,\n+\t\t\t(uint32_t)desc->enc_req.output_start_addr_lo,\n+\t\t\t(uint32_t)desc->enc_req.output_slice_table_addr_hi,\n+\t\t\t(uint32_t)desc->enc_req.output_start_addr_hi,\n+\t\t\t(uint32_t)desc->enc_req.output_slice_num,\n+\t\t\t(uint32_t)desc->enc_req.output_length,\n+\t\t\t(uint32_t)desc->enc_req.enqueue_timestamp,\n+\t\t\t(uint32_t)desc->enc_req.completion_timestamp);\n+\n+\tuint32_t *word = (uint32_t *) desc;\n+\trte_bbdev_log_debug(\"%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n\"\n+\t\t\t\"%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n\"\n+\t\t\t\"%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n\"\n+\t\t\t\"%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n%08\"PRIx32\"\\n\",\n+\t\t\tword[0], word[1], word[2], word[3],\n+\t\t\tword[4], word[5], word[6], word[7],\n+\t\t\tword[8], word[9], word[10], word[11],\n+\t\t\tword[12], word[13], word[14], word[15]);\n+}\n+\n #endif\n \n+/**\n+ * Helper function that returns queue ID if queue is valid\n+ * or FPGA_5GNR_INVALID_HW_QUEUE_ID otherwise.\n+ */\n+static inline uint32_t\n+fpga_5gnr_get_queue_map(struct fpga_5gnr_fec_device *d, uint32_t q_id)\n+{\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT)\n+\t\treturn fpga_5gnr_reg_read_32(d->mmio_base, VC_5GNR_QUEUE_MAP + (q_id << 2));\n+\telse\n+\t\treturn fpga_5gnr_reg_read_32(d->mmio_base, AGX100_QUEUE_MAP + (q_id << 2));\n+}\n+\n static int\n fpga_5gnr_setup_queues(struct rte_bbdev *dev, uint16_t num_queues, int socket_id)\n {\n@@ -204,8 +404,7 @@ fpga_5gnr_setup_queues(struct rte_bbdev *dev, uint16_t num_queues, int socket_id\n \t * FPGA_5GNR_INVALID_HW_QUEUE_ID is returned.\n \t */\n \tfor (q_id = 0; q_id < d->total_num_queues; ++q_id) {\n-\t\tuint32_t hw_q_id = fpga_5gnr_reg_read_32(d->mmio_base,\n-\t\t\t\tVC_5GNR_QUEUE_MAP + (q_id << 2));\n+\t\tuint32_t hw_q_id = fpga_5gnr_get_queue_map(d, q_id);\n \n \t\trte_bbdev_log_debug(\"%s: queue ID: %u, registry queue ID: %u\",\n \t\t\t\tdev->device->name, q_id, hw_q_id);\n@@ -231,8 +430,10 @@ fpga_5gnr_setup_queues(struct rte_bbdev *dev, uint16_t num_queues, int socket_id\n \t\t\tdev->device->name, num_queues, hw_q_num);\n \t\treturn -EINVAL;\n \t}\n-\n-\tring_size = FPGA_5GNR_RING_MAX_SIZE * sizeof(struct vc_5gnr_dma_dec_desc);\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT)\n+\t\tring_size = FPGA_5GNR_RING_MAX_SIZE * sizeof(struct vc_5gnr_dma_dec_desc);\n+\telse\n+\t\tring_size = FPGA_5GNR_RING_MAX_SIZE * sizeof(struct agx100_dma_dec_desc);\n \n \t/* Enforce 32 byte alignment */\n \tRTE_BUILD_BUG_ON((RTE_CACHE_LINE_SIZE % 32) != 0);\n@@ -293,7 +494,7 @@ fpga_5gnr_dev_info_get(struct rte_bbdev *dev, struct rte_bbdev_driver_info *dev_\n \tstruct fpga_5gnr_fec_device *d = dev->data->dev_private;\n \tuint32_t q_id = 0;\n \n-\tstatic const struct rte_bbdev_op_cap bbdev_capabilities[] = {\n+\tstatic const struct rte_bbdev_op_cap vc_5gnr_bbdev_capabilities[] = {\n \t\t{\n \t\t\t.type   = RTE_BBDEV_OP_LDPC_ENC,\n \t\t\t.cap.ldpc_enc = {\n@@ -333,6 +534,44 @@ fpga_5gnr_dev_info_get(struct rte_bbdev *dev, struct rte_bbdev_driver_info *dev_\n \t\tRTE_BBDEV_END_OF_CAPABILITIES_LIST()\n \t};\n \n+\tstatic const struct rte_bbdev_op_cap agx100_bbdev_capabilities[] = {\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_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_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\t\tRTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE |\n+\t\t\t\t\tRTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE |\n+\t\t\t\t\tRTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK |\n+\t\t\t\t\tRTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_FILLERS,\n+\t\t\t.llr_size = 6,\n+\t\t\t.llr_decimals = 2,\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+\t\tRTE_BBDEV_END_OF_CAPABILITIES_LIST()\n+\t};\n+\n \t/* Check the HARQ DDR size available */\n \tuint8_t timeout_counter = 0;\n \tuint32_t harq_buf_ready = fpga_5gnr_reg_read_32(d->mmio_base,\n@@ -357,10 +596,16 @@ fpga_5gnr_dev_info_get(struct rte_bbdev *dev, struct rte_bbdev_driver_info *dev_\n \tdev_info->driver_name = dev->device->driver->name;\n \tdev_info->queue_size_lim = FPGA_5GNR_RING_MAX_SIZE;\n \tdev_info->hardware_accelerated = true;\n-\tdev_info->min_alignment = 64;\n-\tdev_info->harq_buffer_size = (harq_buf_size >> 10) + 1;\n+\tdev_info->min_alignment = 1;\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT)\n+\t\tdev_info->harq_buffer_size = (harq_buf_size >> 10) + 1;\n+\telse\n+\t\tdev_info->harq_buffer_size = harq_buf_size << 10;\n \tdev_info->default_queue_conf = default_queue_conf;\n-\tdev_info->capabilities = bbdev_capabilities;\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT)\n+\t\tdev_info->capabilities = vc_5gnr_bbdev_capabilities;\n+\telse\n+\t\tdev_info->capabilities = agx100_bbdev_capabilities;\n \tdev_info->cpu_flag_reqs = NULL;\n \tdev_info->data_endianness = RTE_LITTLE_ENDIAN;\n \tdev_info->device_status = RTE_BBDEV_DEV_NOT_SUPPORTED;\n@@ -368,8 +613,8 @@ fpga_5gnr_dev_info_get(struct rte_bbdev *dev, struct rte_bbdev_driver_info *dev_\n \t/* Calculates number of queues assigned to device */\n \tdev_info->max_num_queues = 0;\n \tfor (q_id = 0; q_id < d->total_num_queues; ++q_id) {\n-\t\tuint32_t hw_q_id = fpga_5gnr_reg_read_32(d->mmio_base,\n-\t\t\t\tVC_5GNR_QUEUE_MAP + (q_id << 2));\n+\t\tuint32_t hw_q_id = fpga_5gnr_get_queue_map(d, q_id);\n+\n \t\tif (hw_q_id != FPGA_5GNR_INVALID_HW_QUEUE_ID)\n \t\t\tdev_info->max_num_queues++;\n \t}\n@@ -445,7 +690,11 @@ fpga_5gnr_queue_setup(struct rte_bbdev *dev, uint16_t queue_id,\n \tq->q_idx = q_idx;\n \n \t/* Set ring_base_addr */\n-\tq->vc_5gnr_ring_addr = RTE_PTR_ADD(d->sw_rings, (d->sw_ring_size * queue_id));\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT)\n+\t\tq->vc_5gnr_ring_addr = RTE_PTR_ADD(d->sw_rings, (d->sw_ring_size * queue_id));\n+\telse\n+\t\tq->agx100_ring_addr = RTE_PTR_ADD(d->sw_rings, (d->sw_ring_size * queue_id));\n+\n \tq->ring_ctrl_reg.ring_base_addr = d->sw_rings_phys + (d->sw_ring_size * queue_id);\n \n \t/* Allocate memory for Completion Head variable*/\n@@ -781,6 +1030,48 @@ static const struct rte_bbdev_ops fpga_5gnr_ops = {\n \t.queue_intr_disable = fpga_5gnr_queue_intr_disable\n };\n \n+/* Provide the descriptor index on a given queue */\n+static inline uint16_t\n+fpga_5gnr_desc_idx(struct fpga_5gnr_queue *q, uint16_t offset)\n+{\n+\treturn (q->head_free_desc + offset) & q->sw_ring_wrap_mask;\n+}\n+\n+/* Provide the VC 5GNR descriptor pointer on a given queue */\n+static inline union vc_5gnr_dma_desc*\n+vc_5gnr_get_desc(struct fpga_5gnr_queue *q, uint16_t offset)\n+{\n+\treturn q->vc_5gnr_ring_addr + fpga_5gnr_desc_idx(q, offset);\n+}\n+\n+/* Provide the AGX100 descriptor pointer on a given queue */\n+static inline union agx100_dma_desc*\n+agx100_get_desc(struct fpga_5gnr_queue *q, uint16_t offset)\n+{\n+\treturn q->agx100_ring_addr + fpga_5gnr_desc_idx(q, offset);\n+}\n+\n+/* Provide the descriptor index for the tail of a given queue */\n+static inline uint16_t\n+fpga_5gnr_desc_idx_tail(struct fpga_5gnr_queue *q, uint16_t offset)\n+{\n+\treturn (q->tail + offset) & q->sw_ring_wrap_mask;\n+}\n+\n+/* Provide the descriptor tail pointer on a given queue */\n+static inline union vc_5gnr_dma_desc*\n+vc_5gnr_get_desc_tail(struct fpga_5gnr_queue *q, uint16_t offset)\n+{\n+\treturn q->vc_5gnr_ring_addr + fpga_5gnr_desc_idx_tail(q, offset);\n+}\n+\n+/* Provide the descriptor tail pointer on a given queue */\n+static inline union agx100_dma_desc*\n+agx100_get_desc_tail(struct fpga_5gnr_queue *q, uint16_t offset)\n+{\n+\treturn q->agx100_ring_addr + fpga_5gnr_desc_idx_tail(q, offset);\n+}\n+\n static inline void\n fpga_5gnr_dma_enqueue(struct fpga_5gnr_queue *q, uint16_t num_desc,\n \t\tstruct rte_bbdev_stats *queue_stats)\n@@ -789,7 +1080,7 @@ fpga_5gnr_dma_enqueue(struct fpga_5gnr_queue *q, uint16_t num_desc,\n \tqueue_stats->acc_offload_cycles = 0;\n \n \t/* Update tail and shadow_tail register */\n-\tq->tail = (q->tail + num_desc) & q->sw_ring_wrap_mask;\n+\tq->tail = fpga_5gnr_desc_idx_tail(q, num_desc);\n \n \trte_wmb();\n \n@@ -859,6 +1150,72 @@ vc_5gnr_check_desc_error(uint32_t error_code) {\n \treturn 1;\n }\n \n+/* AGX100 FPGA descriptor errors\n+ * Print an error if a descriptor error has occurred.\n+ * Return 0 on success, 1 on failure\n+ */\n+static inline int\n+agx100_check_desc_error(uint32_t error_code, uint32_t error_msg) {\n+\tuint8_t error = error_code << 4 | error_msg;\n+\tswitch (error) {\n+\tcase AGX100_DESC_ERR_NO_ERR:\n+\t\treturn 0;\n+\tcase AGX100_DESC_ERR_E_NOT_LEGAL:\n+\t\trte_bbdev_log(ERR, \"Invalid output length of rate matcher E\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_K_P_OUT_OF_RANGE:\n+\t\trte_bbdev_log(ERR, \"Encode block size K' is out of range\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_NCB_OUT_OF_RANGE:\n+\t\trte_bbdev_log(ERR, \"Ncb circular buffer size is out of range\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_Z_C_NOT_LEGAL:\n+\t\trte_bbdev_log(ERR, \"Zc is illegal\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_DESC_INDEX_ERR:\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Desc_index received does not meet the expectation in the AGX100\"\n+\t\t\t\t);\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_HARQ_INPUT_LEN_A:\n+\t\trte_bbdev_log(ERR, \"HARQ input length A is invalid.\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_HARQ_INPUT_LEN_B:\n+\t\trte_bbdev_log(ERR, \"HARQ input length B is invalid.\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_HBSTORE_OFFSET_ERR:\n+\t\trte_bbdev_log(ERR, \"Hbstore exceeds HARQ buffer size.\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_TB_CBG_ERR:\n+\t\trte_bbdev_log(ERR, \"Total CB number C=0 or CB number with Ea Ca=0 or Ca>C.\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_CBG_OUT_OF_RANGE:\n+\t\trte_bbdev_log(ERR, \"Cbgti or max_cbg is out of range\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_CW_RM_NOT_LEGAL:\n+\t\trte_bbdev_log(ERR, \"Cw_rm is illegal\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_UNSUPPORTED_REQ:\n+\t\trte_bbdev_log(ERR, \"Unsupported request for descriptor\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_RESERVED:\n+\t\trte_bbdev_log(ERR, \"Reserved\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_DESC_ABORT:\n+\t\trte_bbdev_log(ERR, \"Completed abort for descriptor\");\n+\t\tbreak;\n+\tcase AGX100_DESC_ERR_DESC_READ_TLP_POISONED:\n+\t\trte_bbdev_log(ERR, \"Descriptor read TLP poisoned\");\n+\t\tbreak;\n+\tdefault:\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Descriptor error unknown error code %u error msg %u\",\n+\t\t\t\terror_code, error_msg);\n+\t\tbreak;\n+\t}\n+\treturn 1;\n+}\n+\n /* Compute value of k0.\n  * Based on 3GPP 38.212 Table 5.4.2.1-2\n  * Starting position of different redundancy versions, k0\n@@ -956,6 +1313,88 @@ vc_5gnr_dma_desc_te_fill(struct rte_bbdev_enc_op *op,\n \treturn 0;\n }\n \n+/**\n+ * AGX100 FPGA\n+ * Set DMA descriptor for encode operation (1 Code Block)\n+ *\n+ * @param op\n+ *   Pointer to a single encode operation.\n+ * @param desc\n+ *   Pointer to DMA descriptor.\n+ * @param input\n+ *   Pointer to pointer to input data which will be decoded.\n+ * @param e\n+ *   E value (length of output in bits).\n+ * @param ncb\n+ *   Ncb value (size of the soft buffer).\n+ * @param out_length\n+ *   Length of output buffer\n+ * @param in_offset\n+ *   Input offset in rte_mbuf structure. It is used for calculating the point\n+ *   where data is starting.\n+ * @param out_offset\n+ *   Output offset in rte_mbuf structure. It is used for calculating the point\n+ *   where hard output data will be stored.\n+ * @param cbs_in_op\n+ *   Number of CBs contained in one operation.\n+ */\n+static inline int\n+agx100_dma_desc_le_fill(struct rte_bbdev_enc_op *op,\n+\t\tstruct agx100_dma_enc_desc *desc, struct rte_mbuf *input,\n+\t\tstruct rte_mbuf *output, uint16_t k_,  uint32_t e,\n+\t\tuint32_t in_offset, uint32_t out_offset, uint16_t desc_offset,\n+\t\tuint8_t cbs_in_op)\n+{\n+\t/* reset. */\n+\tdesc->done = 0;\n+\tdesc->error_msg = 0;\n+\tdesc->error_code = 0;\n+\tdesc->ncb = op->ldpc_enc.n_cb;\n+\tdesc->bg_idx = op->ldpc_enc.basegraph - 1;\n+\tdesc->qm_idx = op->ldpc_enc.q_m >> 1;\n+\tdesc->zc = op->ldpc_enc.z_c;\n+\tdesc->rv = op->ldpc_enc.rv_index;\n+\tdesc->int_en = 0;\t/**< Set by device externally. */\n+\tdesc->max_cbg = 0;\t/**< TODO: CBG specific. */\n+\tdesc->cbgti = 0;\t/**< TODO: CBG specific. */\n+\tdesc->cbgs = 0;\t\t/**< TODO: CBG specific. */\n+\tdesc->desc_idx = desc_offset;\n+\tdesc->ca = 0;\t/**< TODO: CBG specific. */\n+\tdesc->c = 0;\t/**< TODO: CBG specific. */\n+\tdesc->num_null = op->ldpc_enc.n_filler;\n+\tdesc->ea = e;\n+\tdesc->eb = e;\t/**< TODO: TB/CBG specific. */\n+\tdesc->k_ = k_;\n+\tdesc->en_slice_ts = 0;\t/**< TODO: Slice specific. */\n+\tdesc->en_host_ts = 0;\t/**< TODO: Slice specific. */\n+\tdesc->en_cb_wr_status = 0;\t/**< TODO: Event Queue specific. */\n+\tdesc->en_output_sg = 0;\t/**< TODO: Slice specific. */\n+\tdesc->en_input_sg = 0;\t/**< TODO: Slice specific. */\n+\tdesc->tb_cb = 0;\t/**< Descriptor for CB. TODO: Add TB and CBG logic. */\n+\tdesc->crc_en = check_bit(op->ldpc_enc.op_flags,\n+\t\t\tRTE_BBDEV_LDPC_CRC_24B_ATTACH);\n+\n+\t/* Set inbound/outbound data buffer address. */\n+\t/* TODO: add logic for input_slice. */\n+\tdesc->output_start_addr_hi = (uint32_t)(\n+\t\t\trte_pktmbuf_iova_offset(output, out_offset) >> 32);\n+\tdesc->output_start_addr_lo = (uint32_t)(\n+\t\t\trte_pktmbuf_iova_offset(output, out_offset));\n+\tdesc->input_start_addr_hi = (uint32_t)(\n+\t\t\trte_pktmbuf_iova_offset(input, in_offset) >> 32);\n+\tdesc->input_start_addr_lo = (uint32_t)(\n+\t\t\trte_pktmbuf_iova_offset(input, in_offset));\n+\tdesc->output_length = (e + 7) >> 3; /* in bytes. */\n+\tdesc->input_length = input->data_len;\n+\tdesc->enqueue_timestamp = 0;\n+\tdesc->completion_timestamp = 0;\n+\t/* Save software context needed for dequeue. */\n+\tdesc->op_addr = op;\n+\t/* Set total number of CBs in an op. */\n+\tdesc->cbs_in_op = cbs_in_op;\n+\treturn 0;\n+}\n+\n /**\n  * Vista Creek 5GNR FPGA\n  * Set DMA descriptor for decode operation (1 Code Block)\n@@ -1024,6 +1463,105 @@ vc_5gnr_dma_desc_ld_fill(struct rte_bbdev_dec_op *op,\n \treturn 0;\n }\n \n+/**\n+ * AGX100 FPGA\n+ * Set DMA descriptor for decode operation (1 Code Block)\n+ *\n+ * @param op\n+ *   Pointer to a single encode operation.\n+ * @param desc\n+ *   Pointer to DMA descriptor.\n+ * @param input\n+ *   Pointer to pointer to input data which will be decoded.\n+ * @param in_offset\n+ *   Input offset in rte_mbuf structure. It is used for calculating the point\n+ *   where data is starting.\n+ * @param out_offset\n+ *   Output offset in rte_mbuf structure. It is used for calculating the point\n+ *   where hard output data will be stored.\n+ * @param cbs_in_op\n+ *   Number of CBs contained in one operation.\n+ */\n+static inline int\n+agx100_dma_desc_ld_fill(struct rte_bbdev_dec_op *op,\n+\t\tstruct agx100_dma_dec_desc *desc,\n+\t\tstruct rte_mbuf *input,\tstruct rte_mbuf *output,\n+\t\tuint16_t harq_in_length,\n+\t\tuint32_t in_offset, uint32_t out_offset,\n+\t\tuint32_t harq_in_offset,\n+\t\tuint32_t harq_out_offset,\n+\t\tuint16_t desc_offset,\n+\t\tuint8_t cbs_in_op)\n+{\n+\t/* reset. */\n+\tdesc->done = 0;\n+\tdesc->tb_crc_pass = 0;\n+\tdesc->cb_crc_all_pass = 0;\n+\tdesc->cb_all_et_pass = 0;\n+\tdesc->max_iter_ret = 0;\n+\tdesc->cgb_crc_bitmap = 0;\t/**< TODO: CBG specific. */\n+\tdesc->error_msg = 0;\n+\tdesc->error_code = 0;\n+\tdesc->et_dis = !check_bit(op->ldpc_dec.op_flags,\n+\t\t\tRTE_BBDEV_LDPC_ITERATION_STOP_ENABLE);\n+\tdesc->harq_in_en = check_bit(op->ldpc_dec.op_flags,\n+\t\t\tRTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE);\n+\tdesc->max_iter = op->ldpc_dec.iter_max;\n+\tdesc->ncb = op->ldpc_dec.n_cb;\n+\tdesc->bg_idx = op->ldpc_dec.basegraph - 1;\n+\tdesc->qm_idx = op->ldpc_dec.q_m >> 1;\n+\tdesc->zc = op->ldpc_dec.z_c;\n+\tdesc->rv = op->ldpc_dec.rv_index;\n+\tdesc->int_en = 0;\t/**< Set by device externally. */\n+\tdesc->max_cbg = 0;\t/**< TODO: CBG specific. */\n+\tdesc->cbgti = 0;\t/**< TODO: CBG specific. */\n+\tdesc->cbgfi = 0;\t/**< TODO: CBG specific. */\n+\tdesc->cbgs = 0;\t\t/**< TODO: CBG specific. */\n+\tdesc->desc_idx = desc_offset;\n+\tdesc->ca = 0;\t/**< TODO: CBG specific. */\n+\tdesc->c = 0;\t\t/**< TODO: CBG specific. */\n+\tdesc->llr_pckg = 0;\t\t/**< TODO: Not implemented yet. */\n+\tdesc->syndrome_check_mode = 1;\t/**< TODO: Make it configurable. */\n+\tdesc->num_null = op->ldpc_dec.n_filler;\n+\tdesc->ea = op->ldpc_dec.cb_params.e;\t/**< TODO: TB/CBG specific. */\n+\tdesc->eba = 0;\t/**< TODO: TB/CBG specific. */\n+\tdesc->hbstore_offset_out = harq_out_offset >> 10;\n+\tdesc->hbstore_offset_in = harq_in_offset >> 10;\n+\tdesc->en_slice_ts = 0;\t/**< TODO: Slice specific. */\n+\tdesc->en_host_ts = 0;\t/**< TODO: Slice specific. */\n+\tdesc->en_cb_wr_status = 0;\t/**< TODO: Event Queue specific. */\n+\tdesc->en_output_sg = 0;\t/**< TODO: Slice specific. */\n+\tdesc->en_input_sg = 0;\t/**< TODO: Slice specific. */\n+\tdesc->tb_cb = 0; /**< Descriptor for CB. TODO: Add TB and CBG logic. */\n+\tdesc->crc24b_ind = check_bit(op->ldpc_dec.op_flags,\n+\t\t\tRTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK);\n+\tdesc->drop_crc24b = check_bit(op->ldpc_dec.op_flags,\n+\t\t\tRTE_BBDEV_LDPC_CRC_TYPE_24B_DROP);\n+\tdesc->harq_input_length_a =\n+\t\t\tharq_in_length; /**< Descriptor for CB. TODO: Add TB and CBG logic. */\n+\tdesc->harq_input_length_b = 0; /**< Descriptor for CB. TODO: Add TB and CBG logic. */\n+\t/* Set inbound/outbound data buffer address. */\n+\t/* TODO: add logic for input_slice. */\n+\tdesc->output_start_addr_hi = (uint32_t)(\n+\t\t\trte_pktmbuf_iova_offset(output, out_offset) >> 32);\n+\tdesc->output_start_addr_lo = (uint32_t)(\n+\t\t\trte_pktmbuf_iova_offset(output, out_offset));\n+\tdesc->input_start_addr_hi = (uint32_t)(\n+\t\t\trte_pktmbuf_iova_offset(input, in_offset) >> 32);\n+\tdesc->input_start_addr_lo = (uint32_t)(\n+\t\t\trte_pktmbuf_iova_offset(input, in_offset));\n+\tdesc->output_length = (((op->ldpc_dec.basegraph == 1) ? 22 : 10) * op->ldpc_dec.z_c\n+\t\t\t- op->ldpc_dec.n_filler - desc->drop_crc24b * 24) >> 3;\n+\tdesc->input_length = op->ldpc_dec.cb_params.e;\t/**< TODO: TB/CBG specific. */\n+\tdesc->enqueue_timestamp = 0;\n+\tdesc->completion_timestamp = 0;\n+\t/* Save software context needed for dequeue. */\n+\tdesc->op_addr = op;\n+\t/* Set total number of CBs in an op. */\n+\tdesc->cbs_in_op = cbs_in_op;\n+\treturn 0;\n+}\n+\n /* Validates LDPC encoder parameters for VC 5GNR FPGA. */\n static inline int\n vc_5gnr_validate_ldpc_enc_op(struct rte_bbdev_enc_op *op)\n@@ -1487,27 +2025,35 @@ fpga_5gnr_harq_write_loopback(struct fpga_5gnr_queue *q,\n \tuint64_t *input = NULL;\n \tuint32_t last_transaction = left_length % FPGA_5GNR_DDR_WR_DATA_LEN_IN_BYTES;\n \tuint64_t last_word;\n+\tstruct fpga_5gnr_fec_device *d = q->d;\n \n \tif (last_transaction > 0)\n \t\tleft_length -= last_transaction;\n-\n-\t/*\n-\t * Get HARQ buffer size for each VF/PF: When 0x00, there is no\n-\t * available DDR space for the corresponding VF/PF.\n-\t */\n-\treg_32 = fpga_5gnr_reg_read_32(q->d->mmio_base, FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);\n-\tif (reg_32 < harq_in_length) {\n-\t\tleft_length = reg_32;\n-\t\trte_bbdev_log(ERR, \"HARQ in length > HARQ buffer size\\n\");\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT) {\n+\t\t/*\n+\t\t * Get HARQ buffer size for each VF/PF: When 0x00, there is no\n+\t\t * available DDR space for the corresponding VF/PF.\n+\t\t */\n+\t\treg_32 = fpga_5gnr_reg_read_32(q->d->mmio_base, FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);\n+\t\tif (reg_32 < harq_in_length) {\n+\t\t\tleft_length = reg_32;\n+\t\t\trte_bbdev_log(ERR, \"HARQ in length > HARQ buffer size\\n\");\n+\t\t}\n \t}\n \n \tinput = (uint64_t *)rte_pktmbuf_mtod_offset(harq_input, uint8_t *, in_offset);\n \n \twhile (left_length > 0) {\n \t\tif (fpga_5gnr_reg_read_8(q->d->mmio_base, FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS) ==  1) {\n-\t\t\tfpga_5gnr_reg_write_32(q->d->mmio_base,\n-\t\t\t\t\tFPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,\n-\t\t\t\t\tout_offset);\n+\t\t\tif (d->fpga_variant == AGX100_FPGA_VARIANT) {\n+\t\t\t\tfpga_5gnr_reg_write_32(q->d->mmio_base,\n+\t\t\t\t\t\tFPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,\n+\t\t\t\t\t\tout_offset >> 3);\n+\t\t\t} else {\n+\t\t\t\tfpga_5gnr_reg_write_32(q->d->mmio_base,\n+\t\t\t\t\t\tFPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,\n+\t\t\t\t\t\tout_offset);\n+\t\t\t}\n \t\t\tfpga_5gnr_reg_write_64(q->d->mmio_base,\n \t\t\t\t\tFPGA_5GNR_FEC_DDR4_WR_DATA_REGS,\n \t\t\t\t\tinput[increment]);\n@@ -1519,12 +2065,17 @@ fpga_5gnr_harq_write_loopback(struct fpga_5gnr_queue *q,\n \t}\n \twhile (last_transaction > 0) {\n \t\tif (fpga_5gnr_reg_read_8(q->d->mmio_base, FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS) ==  1) {\n-\t\t\tfpga_5gnr_reg_write_32(q->d->mmio_base,\n-\t\t\t\t\tFPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,\n-\t\t\t\t\tout_offset);\n+\t\t\tif (d->fpga_variant == AGX100_FPGA_VARIANT) {\n+\t\t\t\tfpga_5gnr_reg_write_32(q->d->mmio_base,\n+\t\t\t\t\t\tFPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,\n+\t\t\t\t\t\tout_offset >> 3);\n+\t\t\t} else {\n+\t\t\t\tfpga_5gnr_reg_write_32(q->d->mmio_base,\n+\t\t\t\t\t\tFPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,\n+\t\t\t\t\t\tout_offset);\n+\t\t\t}\n \t\t\tlast_word = input[increment];\n-\t\t\tlast_word &= (uint64_t)(1 << (last_transaction * 4))\n-\t\t\t\t\t- 1;\n+\t\t\tlast_word &= (uint64_t)(1ULL << (last_transaction * 4)) - 1;\n \t\t\tfpga_5gnr_reg_write_64(q->d->mmio_base,\n \t\t\t\t\tFPGA_5GNR_FEC_DDR4_WR_DATA_REGS,\n \t\t\t\t\tlast_word);\n@@ -1547,14 +2098,17 @@ fpga_5gnr_harq_read_loopback(struct fpga_5gnr_queue *q,\n \tuint32_t increment = 0;\n \tuint64_t *input = NULL;\n \tuint32_t last_transaction = harq_in_length % FPGA_5GNR_DDR_WR_DATA_LEN_IN_BYTES;\n+\tstruct fpga_5gnr_fec_device *d = q->d;\n \n \tif (last_transaction > 0)\n \t\tharq_in_length += (8 - last_transaction);\n \n-\treg = fpga_5gnr_reg_read_32(q->d->mmio_base, FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);\n-\tif (reg < harq_in_length) {\n-\t\tharq_in_length = reg;\n-\t\trte_bbdev_log(ERR, \"HARQ in length > HARQ buffer size\\n\");\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT) {\n+\t\treg = fpga_5gnr_reg_read_32(q->d->mmio_base, FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);\n+\t\tif (reg < harq_in_length) {\n+\t\t\tharq_in_length = reg;\n+\t\t\trte_bbdev_log(ERR, \"HARQ in length > HARQ buffer size\\n\");\n+\t\t}\n \t}\n \n \tif (!mbuf_append(harq_output, harq_output, harq_in_length)) {\n@@ -1573,9 +2127,15 @@ fpga_5gnr_harq_read_loopback(struct fpga_5gnr_queue *q,\n \tinput = (uint64_t *)rte_pktmbuf_mtod_offset(harq_output, uint8_t *, harq_out_offset);\n \n \twhile (left_length > 0) {\n-\t\tfpga_5gnr_reg_write_32(q->d->mmio_base,\n-\t\t\t\tFPGA_5GNR_FEC_DDR4_RD_ADDR_REGS,\n-\t\t\t\tin_offset);\n+\t\tif (d->fpga_variant == AGX100_FPGA_VARIANT) {\n+\t\t\tfpga_5gnr_reg_write_32(q->d->mmio_base,\n+\t\t\t\t\tFPGA_5GNR_FEC_DDR4_RD_ADDR_REGS,\n+\t\t\t\t\tin_offset >> 3);\n+\t\t} else {\n+\t\t\tfpga_5gnr_reg_write_32(q->d->mmio_base,\n+\t\t\t\t\tFPGA_5GNR_FEC_DDR4_RD_ADDR_REGS,\n+\t\t\t\t\tin_offset);\n+\t\t}\n \t\tfpga_5gnr_reg_write_8(q->d->mmio_base, FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 1);\n \t\treg = fpga_5gnr_reg_read_8(q->d->mmio_base, FPGA_5GNR_FEC_DDR4_RD_RDY_REGS);\n \t\twhile (reg != 1) {\n@@ -1590,7 +2150,10 @@ fpga_5gnr_harq_read_loopback(struct fpga_5gnr_queue *q,\n \t\tleft_length -= FPGA_5GNR_DDR_RD_DATA_LEN_IN_BYTES;\n \t\tin_offset += FPGA_5GNR_DDR_WR_DATA_LEN_IN_BYTES;\n \t\tincrement++;\n-\t\tfpga_5gnr_reg_write_8(q->d->mmio_base, FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 0);\n+\t\tif (d->fpga_variant == AGX100_FPGA_VARIANT)\n+\t\t\tfpga_5gnr_reg_write_8(q->d->mmio_base, FPGA_5GNR_FEC_DDR4_RD_RDY_REGS, 0);\n+\t\telse\n+\t\t\tfpga_5gnr_reg_write_8(q->d->mmio_base, FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 0);\n \t}\n \tfpga_5gnr_mutex_free(q);\n \treturn 1;\n@@ -1601,6 +2164,7 @@ enqueue_ldpc_enc_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_enc_op *o\n \t\tuint16_t desc_offset)\n {\n \tunion vc_5gnr_dma_desc *vc_5gnr_desc;\n+\tunion agx100_dma_desc *agx100_desc;\n \tint ret;\n \tuint8_t c, crc24_bits = 0;\n \tstruct rte_bbdev_op_ldpc_enc *enc = &op->ldpc_enc;\n@@ -1613,10 +2177,13 @@ enqueue_ldpc_enc_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_enc_op *o\n \tuint16_t total_left = enc->input.length;\n \tuint16_t ring_offset;\n \tuint16_t K, k_;\n+\tstruct fpga_5gnr_fec_device *d = q->d;\n \n-\tif (vc_5gnr_validate_ldpc_enc_op(op) == -1) {\n-\t\trte_bbdev_log(ERR, \"LDPC encoder validation rejected\");\n-\t\treturn -EINVAL;\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT) {\n+\t\tif (vc_5gnr_validate_ldpc_enc_op(op) == -1) {\n+\t\t\trte_bbdev_log(ERR, \"LDPC encoder validation rejected\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n \t}\n \n \t/* Clear op status */\n@@ -1632,14 +2199,13 @@ enqueue_ldpc_enc_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_enc_op *o\n \t\tcrc24_bits = 24;\n \n \tif (enc->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {\n-\t\t/* For Transport Block mode */\n-\t\t/* FIXME */\n-\t\tc = enc->tb_params.c;\n-\t\te = enc->tb_params.ea;\n-\t} else { /* For Code Block mode */\n-\t\tc = 1;\n-\t\te = enc->cb_params.e;\n+\t\t/* TODO: For Transport Block mode. */\n+\t\trte_bbdev_log(ERR, \"Transport Block not supported yet\");\n+\t\treturn -1;\n \t}\n+\t/* For Code Block mode. */\n+\tc = 1;\n+\te = enc->cb_params.e;\n \n \t/* Update total_left */\n \tK = (enc->basegraph == 1 ? 22 : 10) * enc->z_c;\n@@ -1659,13 +2225,22 @@ enqueue_ldpc_enc_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_enc_op *o\n \n \tmbuf_append(m_out_head, m_out, out_length);\n \n-\t/* Offset into the ring */\n-\tring_offset = ((q->tail + desc_offset) & q->sw_ring_wrap_mask);\n-\t/* Setup DMA Descriptor */\n-\tvc_5gnr_desc = q->vc_5gnr_ring_addr + ring_offset;\n-\tret = vc_5gnr_dma_desc_te_fill(op, &vc_5gnr_desc->enc_req, m_in, m_out,\n-\t\t\tk_, e, in_offset, out_offset, ring_offset, c);\n-\tif (unlikely(ret < 0))\n+\t/* Offset into the ring. */\n+\tring_offset = fpga_5gnr_desc_idx_tail(q, desc_offset);\n+\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT) {\n+\t\t/* Setup DMA Descriptor. */\n+\t\tvc_5gnr_desc = vc_5gnr_get_desc_tail(q, desc_offset);\n+\t\tret = vc_5gnr_dma_desc_te_fill(op, &vc_5gnr_desc->enc_req, m_in, m_out,\n+\t\t\t\tk_, e, in_offset, out_offset, ring_offset, c);\n+\t} else {\n+\t\t/* Setup DMA Descriptor. */\n+\t\tagx100_desc = agx100_get_desc_tail(q, desc_offset);\n+\t\tret = agx100_dma_desc_le_fill(op, &agx100_desc->enc_req, m_in, m_out,\n+\t\t\t\tk_, e, in_offset, out_offset, ring_offset, c);\n+\t}\n+\n+\tif (unlikely(ret < 0))\n \t\treturn ret;\n \n \t/* Update lengths */\n@@ -1680,7 +2255,10 @@ enqueue_ldpc_enc_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_enc_op *o\n \t}\n \n #ifdef RTE_LIBRTE_BBDEV_DEBUG\n-\tvc_5gnr_print_dma_enc_desc_debug_info(vc_5gnr_desc);\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT)\n+\t\tvc_5gnr_print_dma_enc_desc_debug_info(vc_5gnr_desc);\n+\telse\n+\t\tagx100_print_dma_enc_desc_debug_info(agx100_desc);\n #endif\n \treturn 1;\n }\n@@ -1713,8 +2291,8 @@ vc_5gnr_enqueue_ldpc_dec_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_d\n \top->status = 0;\n \n \t/* Setup DMA Descriptor */\n-\tring_offset = ((q->tail + desc_offset) & q->sw_ring_wrap_mask);\n-\tdesc = q->vc_5gnr_ring_addr + ring_offset;\n+\tring_offset = fpga_5gnr_desc_idx_tail(q, desc_offset);\n+\tdesc = vc_5gnr_get_desc_tail(q, desc_offset);\n \n \tif (check_bit(dec->op_flags, RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK)) {\n \t\tstruct rte_mbuf *harq_in = dec->harq_combined_input.data;\n@@ -1820,6 +2398,128 @@ vc_5gnr_enqueue_ldpc_dec_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_d\n \treturn 1;\n }\n \n+static inline int\n+agx100_enqueue_ldpc_dec_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_dec_op *op,\n+\t\tuint16_t desc_offset)\n+{\n+\tunion agx100_dma_desc *desc;\n+\tint ret;\n+\tuint16_t ring_offset;\n+\tuint8_t c;\n+\tuint16_t e, in_length, out_length, k0, l, seg_total_left, sys_cols;\n+\tuint16_t K, parity_offset, harq_in_length = 0, harq_out_length = 0;\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_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 out_offset = dec->hard_output.offset;\n+\tuint32_t harq_in_offset = 0;\n+\tuint32_t harq_out_offset = 0;\n+\n+\t/* Clear op status. */\n+\top->status = 0;\n+\n+\t/* Setup DMA Descriptor. */\n+\tring_offset = fpga_5gnr_desc_idx_tail(q, desc_offset);\n+\tdesc = agx100_get_desc_tail(q, desc_offset);\n+\n+\tif (check_bit(dec->op_flags, RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK)) {\n+\t\tstruct rte_mbuf *harq_in = dec->harq_combined_input.data;\n+\t\tstruct rte_mbuf *harq_out = dec->harq_combined_output.data;\n+\t\tharq_in_length = dec->harq_combined_input.length;\n+\t\tuint32_t harq_in_offset = dec->harq_combined_input.offset;\n+\t\tuint32_t harq_out_offset = dec->harq_combined_output.offset;\n+\n+\t\tif (check_bit(dec->op_flags, RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE)) {\n+\t\t\tret = fpga_5gnr_harq_write_loopback(q, harq_in,\n+\t\t\t\t\tharq_in_length, harq_in_offset,\n+\t\t\t\t\tharq_out_offset);\n+\t\t} else if (check_bit(dec->op_flags,\n+\t\t\t\tRTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE)) {\n+\t\t\tret = fpga_5gnr_harq_read_loopback(q, harq_out,\n+\t\t\t\t\tharq_in_length, harq_in_offset,\n+\t\t\t\t\tharq_out_offset);\n+\t\t\tdec->harq_combined_output.length = harq_in_length;\n+\t\t} else {\n+\t\t\trte_bbdev_log(ERR, \"OP flag Err!\");\n+\t\t\tret = -1;\n+\t\t}\n+\n+\t\t/* Set descriptor for dequeue. */\n+\t\tdesc->dec_req.done = 1;\n+\t\tdesc->dec_req.error_code = 0;\n+\t\tdesc->dec_req.error_msg = 0;\n+\t\tdesc->dec_req.op_addr = op;\n+\t\tdesc->dec_req.cbs_in_op = 1;\n+\n+\t\t/* Mark this dummy descriptor to be dropped by HW. */\n+\t\tdesc->dec_req.desc_idx = (ring_offset + 1) & q->sw_ring_wrap_mask;\n+\n+\t\treturn ret; /* Error or number of CB. */\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 -1;\n+\t}\n+\n+\tc = 1;\n+\te = dec->cb_params.e;\n+\n+\tif (check_bit(dec->op_flags, RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP))\n+\t\tcrc24_overlap = 24;\n+\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+\tout_length = ((K - crc24_overlap - dec->n_filler) >> 3);\n+\tin_length = e;\n+\tseg_total_left = dec->input.length;\n+\n+\tif (check_bit(dec->op_flags, RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE))\n+\t\tharq_in_length = RTE_MIN(dec->harq_combined_input.length, (uint32_t)dec->n_cb);\n+\n+\tif (check_bit(dec->op_flags, RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE)) {\n+\t\tk0 = get_k0(dec->n_cb, dec->z_c, dec->basegraph, dec->rv_index);\n+\t\tif (k0 > parity_offset)\n+\t\t\tl = k0 + e;\n+\t\telse\n+\t\t\tl = k0 + e + dec->n_filler;\n+\t\tharq_out_length = RTE_MIN(RTE_MAX(harq_in_length, l), dec->n_cb);\n+\t\tdec->harq_combined_output.length = harq_out_length;\n+\t}\n+\n+\tmbuf_append(m_out_head, m_out, out_length);\n+\tharq_in_offset = dec->harq_combined_input.offset;\n+\tharq_out_offset = dec->harq_combined_output.offset;\n+\n+\tret = agx100_dma_desc_ld_fill(op, &desc->dec_req, m_in, m_out,\n+\t\tharq_in_length, in_offset, out_offset, harq_in_offset,\n+\t\tharq_out_offset, ring_offset, c);\n+\n+\tif (unlikely(ret < 0))\n+\t\treturn ret;\n+\t/* Update lengths. */\n+\tseg_total_left -= in_length;\n+\top->ldpc_dec.hard_output.length += out_length;\n+\tif (seg_total_left > 0) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Mismatch between mbuf length and included CB sizes: mbuf len %u, cb len %u\",\n+\t\t\t\tseg_total_left, in_length);\n+\t\treturn -1;\n+\t}\n+\n+#ifdef RTE_LIBRTE_BBDEV_DEBUG\n+\tagx100_print_dma_dec_desc_debug_info(desc);\n+#endif\n+\n+\treturn 1;\n+}\n+\n static uint16_t\n fpga_5gnr_enqueue_ldpc_enc(struct rte_bbdev_queue_data *q_data,\n \t\tstruct rte_bbdev_enc_op **ops, uint16_t num)\n@@ -1829,9 +2529,11 @@ fpga_5gnr_enqueue_ldpc_enc(struct rte_bbdev_queue_data *q_data,\n \tint enqueued_cbs;\n \tstruct fpga_5gnr_queue *q = q_data->queue_private;\n \tunion vc_5gnr_dma_desc *vc_5gnr_desc;\n+\tunion agx100_dma_desc *agx100_desc;\n+\tstruct fpga_5gnr_fec_device *d = q->d;\n \n \t/* Check if queue is not full */\n-\tif (unlikely(((q->tail + 1) & q->sw_ring_wrap_mask) == q->head_free_desc))\n+\tif (unlikely((fpga_5gnr_desc_idx_tail(q, 1)) == q->head_free_desc))\n \t\treturn 0;\n \n \t/* Calculates available space */\n@@ -1861,9 +2563,13 @@ fpga_5gnr_enqueue_ldpc_enc(struct rte_bbdev_queue_data *q_data,\n \t/* Set interrupt bit for last CB in enqueued ops. FPGA issues interrupt\n \t * only when all previous CBs were already processed.\n \t */\n-\tvc_5gnr_desc = q->vc_5gnr_ring_addr +\n-\t\t\t((q->tail + total_enqueued_cbs - 1) & q->sw_ring_wrap_mask);\n-\tvc_5gnr_desc->enc_req.irq_en = q->irq_enable;\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT) {\n+\t\tvc_5gnr_desc = vc_5gnr_get_desc_tail(q, total_enqueued_cbs - 1);\n+\t\tvc_5gnr_desc->enc_req.irq_en = q->irq_enable;\n+\t} else {\n+\t\tagx100_desc = agx100_get_desc_tail(q, total_enqueued_cbs - 1);\n+\t\tagx100_desc->enc_req.int_en = q->irq_enable;\n+\t}\n \n \tfpga_5gnr_dma_enqueue(q, total_enqueued_cbs, &q_data->queue_stats);\n \n@@ -1883,9 +2589,11 @@ fpga_5gnr_enqueue_ldpc_dec(struct rte_bbdev_queue_data *q_data,\n \tint enqueued_cbs;\n \tstruct fpga_5gnr_queue *q = q_data->queue_private;\n \tunion vc_5gnr_dma_desc *vc_5gnr_desc;\n+\tunion agx100_dma_desc *agx100_desc;\n+\tstruct fpga_5gnr_fec_device *d = q->d;\n \n \t/* Check if queue is not full */\n-\tif (unlikely(((q->tail + 1) & q->sw_ring_wrap_mask) == q->head_free_desc))\n+\tif (unlikely((fpga_5gnr_desc_idx_tail(q, 1)) == q->head_free_desc))\n \t\treturn 0;\n \n \t/* Calculates available space */\n@@ -1901,8 +2609,13 @@ fpga_5gnr_enqueue_ldpc_dec(struct rte_bbdev_queue_data *q_data,\n \t\tif (unlikely(avail - 1 < 0))\n \t\t\tbreak;\n \t\tavail -= 1;\n-\t\tenqueued_cbs = vc_5gnr_enqueue_ldpc_dec_one_op_cb(q, ops[i],\n-\t\t\t\ttotal_enqueued_cbs);\n+\t\tif (q->d->fpga_variant == VC_5GNR_FPGA_VARIANT) {\n+\t\t\tenqueued_cbs = vc_5gnr_enqueue_ldpc_dec_one_op_cb(q, ops[i],\n+\t\t\t\t\ttotal_enqueued_cbs);\n+\t\t} else {\n+\t\t\tenqueued_cbs = agx100_enqueue_ldpc_dec_one_op_cb(q, ops[i],\n+\t\t\t\t\ttotal_enqueued_cbs);\n+\t\t}\n \n \t\tif (enqueued_cbs < 0)\n \t\t\tbreak;\n@@ -1921,9 +2634,14 @@ fpga_5gnr_enqueue_ldpc_dec(struct rte_bbdev_queue_data *q_data,\n \t/* Set interrupt bit for last CB in enqueued ops. FPGA issues interrupt\n \t * only when all previous CBs were already processed.\n \t */\n-\tvc_5gnr_desc = q->vc_5gnr_ring_addr +\n-\t\t\t((q->tail + total_enqueued_cbs - 1) & q->sw_ring_wrap_mask);\n-\tvc_5gnr_desc->enc_req.irq_en = q->irq_enable;\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT) {\n+\t\tvc_5gnr_desc = vc_5gnr_get_desc_tail(q, total_enqueued_cbs - 1);\n+\t\tvc_5gnr_desc->enc_req.irq_en = q->irq_enable;\n+\t} else {\n+\t\tagx100_desc = agx100_get_desc_tail(q, total_enqueued_cbs - 1);\n+\t\tagx100_desc->enc_req.int_en = q->irq_enable;\n+\t}\n+\n \tfpga_5gnr_dma_enqueue(q, total_enqueued_cbs, &q_data->queue_stats);\n \treturn i;\n }\n@@ -1936,7 +2654,7 @@ vc_5gnr_dequeue_ldpc_enc_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_e\n \tunion vc_5gnr_dma_desc *desc;\n \tint desc_error;\n \t/* Set current desc */\n-\tdesc = q->vc_5gnr_ring_addr + ((q->head_free_desc + desc_offset) & q->sw_ring_wrap_mask);\n+\tdesc = vc_5gnr_get_desc(q, desc_offset);\n \n \t/*check if done */\n \tif (desc->enc_req.done == 0)\n@@ -1958,6 +2676,36 @@ vc_5gnr_dequeue_ldpc_enc_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_e\n \treturn 1;\n }\n \n+static inline int\n+agx100_dequeue_ldpc_enc_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_enc_op **op,\n+\t\tuint16_t desc_offset)\n+{\n+\tunion agx100_dma_desc *desc;\n+\tint desc_error;\n+\n+\t/* Set current desc. */\n+\tdesc = agx100_get_desc(q, desc_offset);\n+\t/*check if done */\n+\tif (desc->enc_req.done == 0)\n+\t\treturn -1;\n+\n+\t/* make sure the response is read atomically. */\n+\trte_smp_rmb();\n+\n+\trte_bbdev_log_debug(\"DMA response desc %p\", desc);\n+\n+#ifdef RTE_LIBRTE_BBDEV_DEBUG\n+\tagx100_print_dma_enc_desc_debug_info(desc);\n+#endif\n+\t*op = desc->enc_req.op_addr;\n+\t/* Check the descriptor error field, return 1 on error. */\n+\tdesc_error = agx100_check_desc_error(desc->enc_req.error_code,\n+\t\t\tdesc->enc_req.error_msg);\n+\n+\t(*op)->status = desc_error << RTE_BBDEV_DATA_ERROR;\n+\n+\treturn 1;\n+}\n \n static inline int\n vc_5gnr_dequeue_ldpc_dec_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_dec_op **op,\n@@ -1967,7 +2715,7 @@ vc_5gnr_dequeue_ldpc_dec_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_d\n \tint desc_error;\n \n \t/* Set descriptor */\n-\tdesc = q->vc_5gnr_ring_addr + ((q->head_free_desc + desc_offset) & q->sw_ring_wrap_mask);\n+\tdesc = vc_5gnr_get_desc(q, desc_offset);\n \n \t/* Verify done bit is set */\n \tif (desc->dec_req.done == 0)\n@@ -2006,6 +2754,51 @@ vc_5gnr_dequeue_ldpc_dec_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_d\n \treturn 1;\n }\n \n+static inline int\n+agx100_dequeue_ldpc_dec_one_op_cb(struct fpga_5gnr_queue *q, struct rte_bbdev_dec_op **op,\n+\t\tuint16_t desc_offset)\n+{\n+\tunion agx100_dma_desc *desc;\n+\tint desc_error;\n+\n+\t/* Set descriptor. */\n+\tdesc = agx100_get_desc(q, desc_offset);\n+\t/* Verify done bit is set. */\n+\tif (desc->dec_req.done == 0)\n+\t\treturn -1;\n+\n+\t/* make sure the response is read atomically. */\n+\trte_smp_rmb();\n+\n+#ifdef RTE_LIBRTE_BBDEV_DEBUG\n+\tagx100_print_dma_dec_desc_debug_info(desc);\n+#endif\n+\n+\t*op = desc->dec_req.op_addr;\n+\n+\tif (check_bit((*op)->ldpc_dec.op_flags, RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK)) {\n+\t\t(*op)->status = 0;\n+\t\treturn 1;\n+\t}\n+\n+\t/* FPGA reports iterations based on round-up minus 1. */\n+\t(*op)->ldpc_dec.iter_count = desc->dec_req.max_iter_ret + 1;\n+\n+\t/* CRC Check criteria. */\n+\tif (desc->dec_req.crc24b_ind && !(desc->dec_req.cb_crc_all_pass))\n+\t\t(*op)->status = 1 << RTE_BBDEV_CRC_ERROR;\n+\n+\t/* et_pass = 0 when decoder fails. */\n+\t(*op)->status |= !(desc->dec_req.cb_all_et_pass) << RTE_BBDEV_SYNDROME_ERROR;\n+\n+\t/* Check the descriptor error field, return 1 on error. */\n+\tdesc_error = agx100_check_desc_error(desc->dec_req.error_code,\n+\t\t\tdesc->dec_req.error_msg);\n+\n+\t(*op)->status |= desc_error << RTE_BBDEV_DATA_ERROR;\n+\treturn 1;\n+}\n+\n static uint16_t\n fpga_5gnr_dequeue_ldpc_enc(struct rte_bbdev_queue_data *q_data,\n \t\tstruct rte_bbdev_enc_op **ops, uint16_t num)\n@@ -2017,7 +2810,10 @@ fpga_5gnr_dequeue_ldpc_enc(struct rte_bbdev_queue_data *q_data,\n \tint ret;\n \n \tfor (i = 0; (i < num) && (dequeued_cbs < avail); ++i) {\n-\t\tret = vc_5gnr_dequeue_ldpc_enc_one_op_cb(q, &ops[i], dequeued_cbs);\n+\t\tif (q->d->fpga_variant == VC_5GNR_FPGA_VARIANT)\n+\t\t\tret = vc_5gnr_dequeue_ldpc_enc_one_op_cb(q, &ops[i], dequeued_cbs);\n+\t\telse\n+\t\t\tret = agx100_dequeue_ldpc_enc_one_op_cb(q, &ops[i], dequeued_cbs);\n \n \t\tif (ret < 0)\n \t\t\tbreak;\n@@ -2029,8 +2825,7 @@ fpga_5gnr_dequeue_ldpc_enc(struct rte_bbdev_queue_data *q_data,\n \t}\n \n \t/* Update head */\n-\tq->head_free_desc = (q->head_free_desc + dequeued_cbs) &\n-\t\t\tq->sw_ring_wrap_mask;\n+\tq->head_free_desc = fpga_5gnr_desc_idx(q, dequeued_cbs);\n \n \t/* Update stats */\n \tq_data->queue_stats.dequeued_count += i;\n@@ -2049,7 +2844,10 @@ fpga_5gnr_dequeue_ldpc_dec(struct rte_bbdev_queue_data *q_data,\n \tint ret;\n \n \tfor (i = 0; (i < num) && (dequeued_cbs < avail); ++i) {\n-\t\tret = vc_5gnr_dequeue_ldpc_dec_one_op_cb(q, &ops[i], dequeued_cbs);\n+\t\tif (q->d->fpga_variant == VC_5GNR_FPGA_VARIANT)\n+\t\t\tret = vc_5gnr_dequeue_ldpc_dec_one_op_cb(q, &ops[i], dequeued_cbs);\n+\t\telse\n+\t\t\tret = agx100_dequeue_ldpc_dec_one_op_cb(q, &ops[i], dequeued_cbs);\n \n \t\tif (ret < 0)\n \t\t\tbreak;\n@@ -2061,7 +2859,7 @@ fpga_5gnr_dequeue_ldpc_dec(struct rte_bbdev_queue_data *q_data,\n \t}\n \n \t/* Update head */\n-\tq->head_free_desc = (q->head_free_desc + dequeued_cbs) & q->sw_ring_wrap_mask;\n+\tq->head_free_desc = fpga_5gnr_desc_idx(q, dequeued_cbs);\n \n \t/* Update stats */\n \tq_data->queue_stats.dequeued_count += i;\n@@ -2082,12 +2880,29 @@ fpga_5gnr_fec_init(struct rte_bbdev *dev, struct rte_pci_driver *drv)\n \tdev->dequeue_ldpc_enc_ops = fpga_5gnr_dequeue_ldpc_enc;\n \tdev->dequeue_ldpc_dec_ops = fpga_5gnr_dequeue_ldpc_dec;\n \n-\t((struct fpga_5gnr_fec_device *) dev->data->dev_private)->pf_device =\n-\t\t\t!strcmp(drv->driver.name, RTE_STR(FPGA_5GNR_FEC_PF_DRIVER_NAME));\n-\t((struct fpga_5gnr_fec_device *) dev->data->dev_private)->mmio_base =\n-\t\t\tpci_dev->mem_resource[0].addr;\n-\t((struct fpga_5gnr_fec_device *) dev->data->dev_private)->total_num_queues =\n-\t\t\tVC_5GNR_TOTAL_NUM_QUEUES;\n+\t/* Device variant specific handling. */\n+\tif ((pci_dev->id.device_id == AGX100_PF_DEVICE_ID) ||\n+\t\t\t(pci_dev->id.device_id == AGX100_VF_DEVICE_ID)) {\n+\t\t((struct fpga_5gnr_fec_device *) dev->data->dev_private)->fpga_variant =\n+\t\t\t\tAGX100_FPGA_VARIANT;\n+\t\t((struct fpga_5gnr_fec_device *) dev->data->dev_private)->pf_device =\n+\t\t\t\t!strcmp(drv->driver.name, RTE_STR(FPGA_5GNR_FEC_PF_DRIVER_NAME));\n+\t\t((struct fpga_5gnr_fec_device *) dev->data->dev_private)->mmio_base =\n+\t\t\t\tpci_dev->mem_resource[0].addr;\n+\t\t/* Maximum number of queues possible for this device. */\n+\t\t((struct fpga_5gnr_fec_device *) dev->data->dev_private)->total_num_queues =\n+\t\t\t\tfpga_5gnr_reg_read_32(pci_dev->mem_resource[0].addr,\n+\t\t\t\tFPGA_5GNR_FEC_VERSION_ID) >> 24;\n+\t} else {\n+\t\t((struct fpga_5gnr_fec_device *) dev->data->dev_private)->fpga_variant =\n+\t\t\t\tVC_5GNR_FPGA_VARIANT;\n+\t\t((struct fpga_5gnr_fec_device *) dev->data->dev_private)->pf_device =\n+\t\t\t\t!strcmp(drv->driver.name, RTE_STR(FPGA_5GNR_FEC_PF_DRIVER_NAME));\n+\t\t((struct fpga_5gnr_fec_device *) dev->data->dev_private)->mmio_base =\n+\t\t\t\tpci_dev->mem_resource[0].addr;\n+\t\t((struct fpga_5gnr_fec_device *) dev->data->dev_private)->total_num_queues =\n+\t\t\t\tVC_5GNR_TOTAL_NUM_QUEUES;\n+\t}\n \n \trte_bbdev_log_debug(\n \t\t\t\"Init device %s [%s] @ virtaddr %p phyaddr %#\"PRIx64,\n@@ -2102,6 +2917,7 @@ fpga_5gnr_fec_probe(struct rte_pci_driver *pci_drv,\n {\n \tstruct rte_bbdev *bbdev = NULL;\n \tchar dev_name[RTE_BBDEV_NAME_MAX_LEN];\n+\tstruct fpga_5gnr_fec_device *d;\n \n \tif (pci_dev == NULL) {\n \t\trte_bbdev_log(ERR, \"NULL PCI device\");\n@@ -2140,15 +2956,24 @@ fpga_5gnr_fec_probe(struct rte_pci_driver *pci_drv,\n \trte_bbdev_log_debug(\"bbdev id = %u [%s]\",\n \t\t\tbbdev->data->dev_id, dev_name);\n \n-\tstruct fpga_5gnr_fec_device *d = bbdev->data->dev_private;\n-\tuint32_t version_id = fpga_5gnr_reg_read_32(d->mmio_base, FPGA_5GNR_FEC_VERSION_ID);\n-\trte_bbdev_log(INFO, \"Vista Creek FPGA RTL v%u.%u\",\n-\t\t((uint16_t)(version_id >> 16)), ((uint16_t)version_id));\n+\td = bbdev->data->dev_private;\n+\tif (d->fpga_variant == VC_5GNR_FPGA_VARIANT) {\n+\t\tuint32_t version_id = fpga_5gnr_reg_read_32(d->mmio_base, FPGA_5GNR_FEC_VERSION_ID);\n+\t\trte_bbdev_log(INFO, \"Vista Creek FPGA RTL v%u.%u\",\n+\t\t\t\t((uint16_t)(version_id >> 16)), ((uint16_t)version_id));\n+\t} else {\n+\t\tuint32_t version_num_queues = fpga_5gnr_reg_read_32(d->mmio_base,\n+\t\t\t\tFPGA_5GNR_FEC_VERSION_ID);\n+\t\tuint8_t major_version_id = version_num_queues >> 16;\n+\t\tuint8_t minor_version_id = version_num_queues >> 8;\n+\t\tuint8_t patch_id = version_num_queues;\n+\n+\t\trte_bbdev_log(INFO, \"AGX100 RTL v%u.%u.%u\",\n+\t\t\t\tmajor_version_id, minor_version_id, patch_id);\n+\t}\n \n #ifdef RTE_LIBRTE_BBDEV_DEBUG\n-\tif (!strcmp(pci_drv->driver.name,\n-\t\t\tRTE_STR(FPGA_5GNR_FEC_PF_DRIVER_NAME)))\n-\t\tprint_static_reg_debug_info(d->mmio_base);\n+\tprint_static_reg_debug_info(d->mmio_base, d->fpga_variant);\n #endif\n \treturn 0;\n }\n@@ -2374,7 +3199,169 @@ static int vc_5gnr_configure(const char *dev_name, const struct rte_fpga_5gnr_fe\n \trte_bbdev_log_debug(\"PF Vista Creek 5GNR FPGA configuration complete for %s\", dev_name);\n \n #ifdef RTE_LIBRTE_BBDEV_DEBUG\n-\tprint_static_reg_debug_info(d->mmio_base);\n+\tprint_static_reg_debug_info(d->mmio_base, d->fpga_variant);\n+#endif\n+\treturn 0;\n+}\n+\n+/* Initial configuration of AGX100 device. */\n+static int agx100_configure(const char *dev_name, const struct rte_fpga_5gnr_fec_conf *conf)\n+{\n+\tuint32_t payload_32, address;\n+\tuint16_t payload_16;\n+\tuint8_t payload_8;\n+\tuint16_t q_id, vf_id, total_q_id, total_ul_q_id, total_dl_q_id;\n+\tstruct rte_bbdev *bbdev = rte_bbdev_get_named_dev(dev_name);\n+\tstruct rte_fpga_5gnr_fec_conf def_conf;\n+\n+\tif (bbdev == NULL) {\n+\t\trte_bbdev_log(ERR,\n+\t\t\t\t\"Invalid dev_name (%s), or device is not yet initialised\",\n+\t\t\t\tdev_name);\n+\t\treturn -ENODEV;\n+\t}\n+\n+\tstruct fpga_5gnr_fec_device *d = bbdev->data->dev_private;\n+\n+\tif (conf == NULL) {\n+\t\trte_bbdev_log(ERR, \"AGX100 Configuration was not provided.\");\n+\t\trte_bbdev_log(ERR, \"Default configuration will be loaded.\");\n+\t\tfpga_5gnr_set_default_conf(&def_conf);\n+\t\tconf = &def_conf;\n+\t}\n+\n+\tuint8_t total_num_queues = d->total_num_queues;\n+\tuint8_t num_ul_queues = total_num_queues >> 1;\n+\tuint8_t num_dl_queues = total_num_queues >> 1;\n+\n+\t/* Clear all queues registers */\n+\tpayload_32 = FPGA_5GNR_INVALID_HW_QUEUE_ID;\n+\tfor (q_id = 0; q_id < total_num_queues; ++q_id) {\n+\t\taddress = (q_id << 2) + AGX100_QUEUE_MAP;\n+\t\tfpga_5gnr_reg_write_32(d->mmio_base, address, payload_32);\n+\t}\n+\n+\t/*\n+\t * If PF mode is enabled allocate all queues for PF only.\n+\t *\n+\t * For VF mode each VF can have different number of UL and DL queues.\n+\t * Total number of queues to configure cannot exceed AGX100\n+\t * capabilities - 64 queues - 32 queues for UL and 32 queues for DL.\n+\t * Queues mapping is done according to configuration:\n+\t *\n+\t * UL queues:\n+\t * |                Q_ID              | VF_ID |\n+\t * |                 0                |   0   |\n+\t * |                ...               |   0   |\n+\t * | conf->vf_dl_queues_number[0] - 1 |   0   |\n+\t * | conf->vf_dl_queues_number[0]     |   1   |\n+\t * |                ...               |   1   |\n+\t * | conf->vf_dl_queues_number[1] - 1 |   1   |\n+\t * |                ...               |  ...  |\n+\t * | conf->vf_dl_queues_number[7] - 1 |   7   |\n+\t *\n+\t * DL queues:\n+\t * |                Q_ID              | VF_ID |\n+\t * |                 32               |   0   |\n+\t * |                ...               |   0   |\n+\t * | conf->vf_ul_queues_number[0] - 1 |   0   |\n+\t * | conf->vf_ul_queues_number[0]     |   1   |\n+\t * |                ...               |   1   |\n+\t * | conf->vf_ul_queues_number[1] - 1 |   1   |\n+\t * |                ...               |  ...  |\n+\t * | conf->vf_ul_queues_number[7] - 1 |   7   |\n+\t *\n+\t * Example of configuration:\n+\t * conf->vf_ul_queues_number[0] = 4;  -> 4 UL queues for VF0\n+\t * conf->vf_dl_queues_number[0] = 4;  -> 4 DL queues for VF0\n+\t * conf->vf_ul_queues_number[1] = 2;  -> 2 UL queues for VF1\n+\t * conf->vf_dl_queues_number[1] = 2;  -> 2 DL queues for VF1\n+\t *\n+\t * UL:\n+\t * | Q_ID | VF_ID |\n+\t * |   0  |   0   |\n+\t * |   1  |   0   |\n+\t * |   2  |   0   |\n+\t * |   3  |   0   |\n+\t * |   4  |   1   |\n+\t * |   5  |   1   |\n+\t *\n+\t * DL:\n+\t * | Q_ID | VF_ID |\n+\t * |  32  |   0   |\n+\t * |  33  |   0   |\n+\t * |  34  |   0   |\n+\t * |  35  |   0   |\n+\t * |  36  |   1   |\n+\t * |  37  |   1   |\n+\t */\n+\tif (conf->pf_mode_en) {\n+\t\tpayload_32 = 0x1;\n+\t\tfor (q_id = 0; q_id < total_num_queues; ++q_id) {\n+\t\t\taddress = (q_id << 2) + AGX100_QUEUE_MAP;\n+\t\t\tfpga_5gnr_reg_write_32(d->mmio_base, address, payload_32);\n+\t\t}\n+\t} else {\n+\t\t/* Calculate total number of UL and DL queues to configure. */\n+\t\ttotal_ul_q_id = total_dl_q_id = 0;\n+\t\tfor (vf_id = 0; vf_id < FPGA_5GNR_FEC_NUM_VFS; ++vf_id) {\n+\t\t\ttotal_ul_q_id += conf->vf_ul_queues_number[vf_id];\n+\t\t\ttotal_dl_q_id += conf->vf_dl_queues_number[vf_id];\n+\t\t}\n+\t\ttotal_q_id = total_dl_q_id + total_ul_q_id;\n+\t\t/*\n+\t\t * Check if total number of queues to configure does not exceed\n+\t\t * AGX100 capabilities (64 queues - 32 UL and 32 DL queues)\n+\t\t */\n+\t\tif ((total_ul_q_id > num_ul_queues) ||\n+\t\t\t\t(total_dl_q_id > num_dl_queues) ||\n+\t\t\t\t(total_q_id > total_num_queues)) {\n+\t\t\trte_bbdev_log(ERR,\n+\t\t\t\t\t\"AGX100 Configuration failed. Too many queues to configure: UL_Q %u, DL_Q %u, AGX100_Q %u\",\n+\t\t\t\t\ttotal_ul_q_id, total_dl_q_id,\n+\t\t\t\t\ttotal_num_queues);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\ttotal_ul_q_id = 0;\n+\t\tfor (vf_id = 0; vf_id < FPGA_5GNR_FEC_NUM_VFS; ++vf_id) {\n+\t\t\tfor (q_id = 0; q_id < conf->vf_ul_queues_number[vf_id];\n+\t\t\t\t\t++q_id, ++total_ul_q_id) {\n+\t\t\t\taddress = (total_ul_q_id << 2) + AGX100_QUEUE_MAP;\n+\t\t\t\tpayload_32 = ((0x80 + vf_id) << 16) | 0x1;\n+\t\t\t\tfpga_5gnr_reg_write_32(d->mmio_base, address, payload_32);\n+\t\t\t}\n+\t\t}\n+\t\ttotal_dl_q_id = 0;\n+\t\tfor (vf_id = 0; vf_id < FPGA_5GNR_FEC_NUM_VFS; ++vf_id) {\n+\t\t\tfor (q_id = 0; q_id < conf->vf_dl_queues_number[vf_id];\n+\t\t\t\t\t++q_id, ++total_dl_q_id) {\n+\t\t\t\taddress = ((total_dl_q_id + num_ul_queues)\n+\t\t\t\t\t\t<< 2) + AGX100_QUEUE_MAP;\n+\t\t\t\tpayload_32 = ((0x80 + vf_id) << 16) | 0x1;\n+\t\t\t\tfpga_5gnr_reg_write_32(d->mmio_base, address, payload_32);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t/* Setting Load Balance Factor. */\n+\tpayload_16 = (conf->dl_load_balance << 8) | (conf->ul_load_balance);\n+\taddress = FPGA_5GNR_FEC_LOAD_BALANCE_FACTOR;\n+\tfpga_5gnr_reg_write_16(d->mmio_base, address, payload_16);\n+\n+\t/* Setting length of ring descriptor entry. */\n+\tpayload_16 = FPGA_5GNR_RING_DESC_ENTRY_LENGTH;\n+\taddress = FPGA_5GNR_FEC_RING_DESC_LEN;\n+\tfpga_5gnr_reg_write_16(d->mmio_base, address, payload_16);\n+\n+\t/* Queue PF/VF mapping table is ready. */\n+\tpayload_8 = 0x1;\n+\taddress = FPGA_5GNR_FEC_QUEUE_PF_VF_MAP_DONE;\n+\tfpga_5gnr_reg_write_8(d->mmio_base, address, payload_8);\n+\n+\trte_bbdev_log_debug(\"PF AGX100 configuration complete for %s\", dev_name);\n+\n+#ifdef RTE_LIBRTE_BBDEV_DEBUG\n+\tprint_static_reg_debug_info(d->mmio_base, d->fpga_variant);\n #endif\n \treturn 0;\n }\n@@ -2391,6 +3378,8 @@ int rte_fpga_5gnr_fec_configure(const char *dev_name, const struct rte_fpga_5gnr\n \tprintf(\"Configure dev id %x\\n\", pci_dev->id.device_id);\n \tif (pci_dev->id.device_id == VC_5GNR_PF_DEVICE_ID)\n \t\treturn vc_5gnr_configure(dev_name, conf);\n+\telse if (pci_dev->id.device_id == AGX100_PF_DEVICE_ID)\n+\t\treturn agx100_configure(dev_name, conf);\n \n \trte_bbdev_log(ERR, \"Invalid device_id (%d)\", pci_dev->id.device_id);\n \treturn -ENODEV;\n@@ -2398,6 +3387,9 @@ int rte_fpga_5gnr_fec_configure(const char *dev_name, const struct rte_fpga_5gnr\n \n /* FPGA 5GNR FEC PCI PF address map */\n static struct rte_pci_id pci_id_fpga_5gnr_fec_pf_map[] = {\n+\t{\n+\t\tRTE_PCI_DEVICE(AGX100_VENDOR_ID, AGX100_PF_DEVICE_ID)\n+\t},\n \t{\n \t\tRTE_PCI_DEVICE(VC_5GNR_VENDOR_ID, VC_5GNR_PF_DEVICE_ID)\n \t},\n@@ -2413,6 +3405,9 @@ static struct rte_pci_driver fpga_5gnr_fec_pci_pf_driver = {\n \n /* FPGA 5GNR FEC PCI VF address map */\n static struct rte_pci_id pci_id_fpga_5gnr_fec_vf_map[] = {\n+\t{\n+\t\tRTE_PCI_DEVICE(AGX100_VENDOR_ID, AGX100_VF_DEVICE_ID)\n+\t},\n \t{\n \t\tRTE_PCI_DEVICE(VC_5GNR_VENDOR_ID, VC_5GNR_VF_DEVICE_ID)\n \t},\ndiff --git a/drivers/baseband/fpga_5gnr_fec/vc_5gnr_pmd.h b/drivers/baseband/fpga_5gnr_fec/vc_5gnr_pmd.h\nindex 47fb43199f86..9a488ae8d6d1 100644\n--- a/drivers/baseband/fpga_5gnr_fec/vc_5gnr_pmd.h\n+++ b/drivers/baseband/fpga_5gnr_fec/vc_5gnr_pmd.h\n@@ -16,7 +16,6 @@\n #define VC_5GNR_NUM_UL_QUEUES (32)\n #define VC_5GNR_NUM_DL_QUEUES (32)\n #define VC_5GNR_TOTAL_NUM_QUEUES (VC_5GNR_NUM_UL_QUEUES + VC_5GNR_NUM_DL_QUEUES)\n-#define VC_5GNR_NUM_INTR_VEC (VC_5GNR_TOTAL_NUM_QUEUES - RTE_INTR_VEC_RXTX_OFFSET)\n \n /* VC 5GNR Ring size is in 256 bits (32 bytes) units. */\n #define VC_5GNR_RING_DESC_LEN_UNIT_BYTES (32)\n",
    "prefixes": [
        "v7",
        "5/6"
    ]
}