get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 122817,
    "url": "http://patches.dpdk.org/api/patches/122817/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230201092310.23252-8-syalavarthi@marvell.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": "<20230201092310.23252-8-syalavarthi@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230201092310.23252-8-syalavarthi@marvell.com",
    "date": "2023-02-01T09:22:38",
    "name": "[v4,07/39] ml/cnxk: enable firmware load and device reset",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "1aabc761b824955ef11d6b8295519094d2fb00b6",
    "submitter": {
        "id": 2480,
        "url": "http://patches.dpdk.org/api/people/2480/?format=api",
        "name": "Srikanth Yalavarthi",
        "email": "syalavarthi@marvell.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20230201092310.23252-8-syalavarthi@marvell.com/mbox/",
    "series": [
        {
            "id": 26732,
            "url": "http://patches.dpdk.org/api/series/26732/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=26732",
            "date": "2023-02-01T09:22:31",
            "name": "Implementation of ML CNXK driver",
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/26732/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/122817/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/122817/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 B432E41B9D;\n\tWed,  1 Feb 2023 10:24:10 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id C95FE42D7C;\n\tWed,  1 Feb 2023 10:23:26 +0100 (CET)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173])\n by mails.dpdk.org (Postfix) with ESMTP id A468A42D29\n for <dev@dpdk.org>; Wed,  1 Feb 2023 10:23:18 +0100 (CET)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id\n 3116M427010261 for <dev@dpdk.org>; Wed, 1 Feb 2023 01:23:18 -0800",
            "from dc5-exch02.marvell.com ([199.233.59.182])\n by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3nfjrj0s0f-4\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n for <dev@dpdk.org>; Wed, 01 Feb 2023 01:23:17 -0800",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.42;\n Wed, 1 Feb 2023 01:23:15 -0800",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.42 via Frontend\n Transport; Wed, 1 Feb 2023 01:23:15 -0800",
            "from ml-host-33.caveonetworks.com (unknown [10.110.143.233])\n by maili.marvell.com (Postfix) with ESMTP id 148B93F7041;\n Wed,  1 Feb 2023 01:23:15 -0800 (PST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-type; s=pfpt0220; bh=UPjEYyEPozCd5ejVpNjXak28cqUEdXUhosGpugp2IN4=;\n b=SGMKW+ru5pqV7owiSNRnMPVOzK6b5pSn7W4cVm+GewDbjr6uoN68Ud23U6II7PQsxo9H\n HFXYj8GcpaoY+jEcY8akdEAavCJC845qcHPhPBEXbNgKfr1wrbdUgidI7Oz//DkSXC5y\n H0/A6CCoRIXYwYEkbqQbWYQ/lia5JgISOIrliVLo/zK8Nh5ThQweC2xDTW/fVxs3CLB3\n iRgoUu2gHMBvvxbXTPx4NknkBvDX9rpClgzOJg4qdyfm/8j+wqKMUWwhJZJwJ2JoeoND\n dOiZsYEgayxzNIy06961UyM1mPJADadQc/DemCwzjvFsx5TD5EhP/6eMKgJMY4rSO7wX Lw==",
        "From": "Srikanth Yalavarthi <syalavarthi@marvell.com>",
        "To": "Srikanth Yalavarthi <syalavarthi@marvell.com>",
        "CC": "<dev@dpdk.org>, <sshankarnara@marvell.com>, <jerinj@marvell.com>,\n <aprabhu@marvell.com>",
        "Subject": "[PATCH v4 07/39] ml/cnxk: enable firmware load and device reset",
        "Date": "Wed, 1 Feb 2023 01:22:38 -0800",
        "Message-ID": "<20230201092310.23252-8-syalavarthi@marvell.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20230201092310.23252-1-syalavarthi@marvell.com>",
        "References": "<20221208200220.20267-1-syalavarthi@marvell.com>\n <20230201092310.23252-1-syalavarthi@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Proofpoint-ORIG-GUID": "CFEx3IcbwxM32ZnZ8_3fuKgaomej73hx",
        "X-Proofpoint-GUID": "CFEx3IcbwxM32ZnZ8_3fuKgaomej73hx",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.219,Aquarius:18.0.930,Hydra:6.0.562,FMLib:17.11.122.1\n definitions=2023-02-01_03,2023-01-31_01,2022-06-22_01",
        "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": "Enabled support to load ML firmware on cn10ka ROC model. Reset\nMLIP device during dev_close driver operation. Device can't be\nreconfigured after a call to close. Job execution is disabled\nafter firmware load, execution is enabled in device start state.\nAdded internal request structure.\n\nSigned-off-by: Srikanth Yalavarthi <syalavarthi@marvell.com>\n---\n drivers/ml/cnxk/cn10k_ml_dev.c | 327 +++++++++++++++++++++++++++++++++\n drivers/ml/cnxk/cn10k_ml_dev.h | 156 ++++++++++++++++\n drivers/ml/cnxk/cn10k_ml_ops.c |  21 +++\n drivers/ml/cnxk/cn10k_ml_ops.h |  14 ++\n 4 files changed, 518 insertions(+)",
    "diff": "diff --git a/drivers/ml/cnxk/cn10k_ml_dev.c b/drivers/ml/cnxk/cn10k_ml_dev.c\nindex 117cac43aa..90fca45ddd 100644\n--- a/drivers/ml/cnxk/cn10k_ml_dev.c\n+++ b/drivers/ml/cnxk/cn10k_ml_dev.c\n@@ -12,6 +12,8 @@\n \n #include <roc_api.h>\n \n+#include <eal_firmware.h>\n+\n #include \"cn10k_ml_dev.h\"\n #include \"cn10k_ml_ops.h\"\n \n@@ -19,6 +21,15 @@\n \n #define CN10K_ML_FW_PATH_DEFAULT \"/lib/firmware/mlip-fw.bin\"\n \n+/* ML firmware macros */\n+#define FW_MEMZONE_NAME\t\t \"ml_cn10k_fw_mz\"\n+#define FW_STACK_BUFFER_SIZE\t 0x40000\n+#define FW_DEBUG_BUFFER_SIZE\t (2 * 0x20000)\n+#define FW_EXCEPTION_BUFFER_SIZE 0x400\n+#define FW_LINKER_OFFSET\t 0x80000\n+#define FW_WAIT_CYCLES\t\t 100\n+#define FW_LOAD_FLAGS\t\t 0x1\n+\n static const char *const valid_args[] = {CN10K_ML_FW_PATH, NULL};\n \n /* Dummy operations for ML device */\n@@ -175,6 +186,322 @@ cn10k_ml_pci_remove(struct rte_pci_device *pci_dev)\n \treturn rte_ml_dev_pmd_destroy(dev);\n }\n \n+static void\n+cn10k_ml_fw_print_info(struct cn10k_ml_fw *fw)\n+{\n+\tplt_info(\"ML Firmware Version = %s\", fw->req->jd.fw_load.version);\n+\n+\tplt_ml_dbg(\"Firmware capabilities = 0x%016lx\", fw->req->jd.fw_load.cap.u64);\n+\tplt_ml_dbg(\"Version = %s\", fw->req->jd.fw_load.version);\n+\tplt_ml_dbg(\"core0_debug_ptr = 0x%016lx\", fw->req->jd.fw_load.debug.core0_debug_ptr);\n+\tplt_ml_dbg(\"core1_debug_ptr = 0x%016lx\", fw->req->jd.fw_load.debug.core1_debug_ptr);\n+\tplt_ml_dbg(\"debug_buffer_size = %u bytes\", fw->req->jd.fw_load.debug.debug_buffer_size);\n+\tplt_ml_dbg(\"core0_exception_buffer = 0x%016lx\",\n+\t\t   fw->req->jd.fw_load.debug.core0_exception_buffer);\n+\tplt_ml_dbg(\"core1_exception_buffer = 0x%016lx\",\n+\t\t   fw->req->jd.fw_load.debug.core1_exception_buffer);\n+\tplt_ml_dbg(\"exception_state_size = %u bytes\",\n+\t\t   fw->req->jd.fw_load.debug.exception_state_size);\n+\tplt_ml_dbg(\"flags = 0x%016lx\", fw->req->jd.fw_load.flags);\n+}\n+\n+uint64_t\n+cn10k_ml_fw_flags_get(struct cn10k_ml_fw *fw)\n+{\n+\tPLT_SET_USED(fw);\n+\n+\treturn FW_LOAD_FLAGS;\n+}\n+\n+static int\n+cn10k_ml_fw_load_cn10ka(struct cn10k_ml_fw *fw, void *buffer, uint64_t size)\n+{\n+\tunion ml_a35_0_rst_vector_base_s a35_0_rst_vector_base;\n+\tunion ml_a35_0_rst_vector_base_s a35_1_rst_vector_base;\n+\tstruct cn10k_ml_dev *mldev;\n+\tuint64_t timeout_cycle;\n+\tuint64_t reg_val64;\n+\tuint32_t reg_val32;\n+\tuint64_t offset;\n+\tbool timeout;\n+\tint ret = 0;\n+\tuint8_t i;\n+\n+\tmldev = fw->mldev;\n+\n+\t/* Reset HEAD and TAIL debug pointer registers */\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_HEAD_C0);\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_TAIL_C0);\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_HEAD_C1);\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_TAIL_C1);\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_EXCEPTION_SP_C0);\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_EXCEPTION_SP_C1);\n+\n+\t/* (1) Write firmware images for ACC's two A35 cores to the ML region in LLC / DRAM. */\n+\trte_memcpy(PLT_PTR_ADD(fw->data, FW_LINKER_OFFSET), buffer, size);\n+\n+\t/* (2) Set ML(0)_MLR_BASE = Base IOVA of the ML region in LLC/DRAM. */\n+\treg_val64 = PLT_PTR_SUB_U64_CAST(fw->data, rte_eal_get_baseaddr());\n+\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_MLR_BASE);\n+\tplt_ml_dbg(\"ML_MLR_BASE => 0x%016lx\", roc_ml_reg_read64(&mldev->roc, ML_MLR_BASE));\n+\troc_ml_reg_save(&mldev->roc, ML_MLR_BASE);\n+\n+\t/* (3) Set ML(0)_AXI_BRIDGE_CTRL(1) = 0x184003 to remove back-pressure check on DMA AXI\n+\t * bridge.\n+\t */\n+\treg_val64 = (ROC_ML_AXI_BRIDGE_CTRL_AXI_RESP_CTRL |\n+\t\t     ROC_ML_AXI_BRIDGE_CTRL_BRIDGE_CTRL_MODE | ROC_ML_AXI_BRIDGE_CTRL_NCB_WR_BLK |\n+\t\t     ROC_ML_AXI_BRIDGE_CTRL_FORCE_WRESP_OK | ROC_ML_AXI_BRIDGE_CTRL_FORCE_RRESP_OK);\n+\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_AXI_BRIDGE_CTRL(1));\n+\tplt_ml_dbg(\"ML_AXI_BRIDGE_CTRL(1) => 0x%016lx\",\n+\t\t   roc_ml_reg_read64(&mldev->roc, ML_AXI_BRIDGE_CTRL(1)));\n+\n+\t/* (4) Set ML(0)_ANB(0..2)_BACKP_DISABLE = 0x3 to remove back-pressure on the AXI to NCB\n+\t * bridges.\n+\t */\n+\tfor (i = 0; i < ML_ANBX_NR; i++) {\n+\t\treg_val64 = (ROC_ML_ANBX_BACKP_DISABLE_EXTMSTR_B_BACKP_DISABLE |\n+\t\t\t     ROC_ML_ANBX_BACKP_DISABLE_EXTMSTR_R_BACKP_DISABLE);\n+\t\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_ANBX_BACKP_DISABLE(i));\n+\t\tplt_ml_dbg(\"ML_ANBX_BACKP_DISABLE(%u) => 0x%016lx\", i,\n+\t\t\t   roc_ml_reg_read64(&mldev->roc, ML_ANBX_BACKP_DISABLE(i)));\n+\t}\n+\n+\t/* (5) Set ML(0)_ANB(0..2)_NCBI_P_OVR = 0x3000 and ML(0)_ANB(0..2)_NCBI_NP_OVR = 0x3000 to\n+\t * signal all ML transactions as non-secure.\n+\t */\n+\tfor (i = 0; i < ML_ANBX_NR; i++) {\n+\t\treg_val64 = (ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_NS_OVR |\n+\t\t\t     ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_NS_OVR_VLD);\n+\t\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_ANBX_NCBI_P_OVR(i));\n+\t\tplt_ml_dbg(\"ML_ANBX_NCBI_P_OVR(%u) => 0x%016lx\", i,\n+\t\t\t   roc_ml_reg_read64(&mldev->roc, ML_ANBX_NCBI_P_OVR(i)));\n+\n+\t\treg_val64 |= (ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_NS_OVR |\n+\t\t\t      ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_NS_OVR_VLD);\n+\t\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_ANBX_NCBI_NP_OVR(i));\n+\t\tplt_ml_dbg(\"ML_ANBX_NCBI_NP_OVR(%u) => 0x%016lx\", i,\n+\t\t\t   roc_ml_reg_read64(&mldev->roc, ML_ANBX_NCBI_NP_OVR(i)));\n+\t}\n+\n+\t/* (6) Set ML(0)_CFG[MLIP_CLK_FORCE] = 1, to force turning on the MLIP clock. */\n+\treg_val64 = roc_ml_reg_read64(&mldev->roc, ML_CFG);\n+\treg_val64 |= ROC_ML_CFG_MLIP_CLK_FORCE;\n+\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_CFG);\n+\tplt_ml_dbg(\"ML_CFG => 0x%016lx\", roc_ml_reg_read64(&mldev->roc, ML_CFG));\n+\n+\t/* (7) Set ML(0)_JOB_MGR_CTRL[STALL_ON_IDLE] = 0, to make sure the boot request is accepted\n+\t * when there is no job in the command queue.\n+\t */\n+\treg_val64 = roc_ml_reg_read64(&mldev->roc, ML_JOB_MGR_CTRL);\n+\treg_val64 &= ~ROC_ML_JOB_MGR_CTRL_STALL_ON_IDLE;\n+\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_JOB_MGR_CTRL);\n+\tplt_ml_dbg(\"ML_JOB_MGR_CTRL => 0x%016lx\", roc_ml_reg_read64(&mldev->roc, ML_JOB_MGR_CTRL));\n+\n+\t/* (8) Set ML(0)_CFG[ENA] = 0 and ML(0)_CFG[MLIP_ENA] = 1 to bring MLIP out of reset while\n+\t * keeping the job manager disabled.\n+\t */\n+\treg_val64 = roc_ml_reg_read64(&mldev->roc, ML_CFG);\n+\treg_val64 |= ROC_ML_CFG_MLIP_ENA;\n+\treg_val64 &= ~ROC_ML_CFG_ENA;\n+\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_CFG);\n+\tplt_ml_dbg(\"ML_CFG => 0x%016lx\", roc_ml_reg_read64(&mldev->roc, ML_CFG));\n+\n+\t/* (9) Wait at least 70 coprocessor clock cycles. */\n+\tplt_delay_us(FW_WAIT_CYCLES);\n+\n+\t/* (10) Write ML outbound addresses pointing to the firmware images written in step 1 to the\n+\t * following registers: ML(0)_A35_0_RST_VECTOR_BASE_W(0..1) for core 0,\n+\t * ML(0)_A35_1_RST_VECTOR_BASE_W(0..1) for core 1. The value written to each register is the\n+\t * AXI outbound address divided by 4. Read after write.\n+\t */\n+\toffset = PLT_PTR_ADD_U64_CAST(\n+\t\tfw->data, FW_LINKER_OFFSET - roc_ml_reg_read64(&mldev->roc, ML_MLR_BASE));\n+\ta35_0_rst_vector_base.s.addr = (offset + ML_AXI_START_ADDR) / 4;\n+\ta35_1_rst_vector_base.s.addr = (offset + ML_AXI_START_ADDR) / 4;\n+\n+\troc_ml_reg_write32(&mldev->roc, a35_0_rst_vector_base.w.w0, ML_A35_0_RST_VECTOR_BASE_W(0));\n+\treg_val32 = roc_ml_reg_read32(&mldev->roc, ML_A35_0_RST_VECTOR_BASE_W(0));\n+\tplt_ml_dbg(\"ML_A35_0_RST_VECTOR_BASE_W(0) => 0x%08x\", reg_val32);\n+\n+\troc_ml_reg_write32(&mldev->roc, a35_0_rst_vector_base.w.w1, ML_A35_0_RST_VECTOR_BASE_W(1));\n+\treg_val32 = roc_ml_reg_read32(&mldev->roc, ML_A35_0_RST_VECTOR_BASE_W(1));\n+\tplt_ml_dbg(\"ML_A35_0_RST_VECTOR_BASE_W(1) => 0x%08x\", reg_val32);\n+\n+\troc_ml_reg_write32(&mldev->roc, a35_1_rst_vector_base.w.w0, ML_A35_1_RST_VECTOR_BASE_W(0));\n+\treg_val32 = roc_ml_reg_read32(&mldev->roc, ML_A35_1_RST_VECTOR_BASE_W(0));\n+\tplt_ml_dbg(\"ML_A35_1_RST_VECTOR_BASE_W(0) => 0x%08x\", reg_val32);\n+\n+\troc_ml_reg_write32(&mldev->roc, a35_1_rst_vector_base.w.w1, ML_A35_1_RST_VECTOR_BASE_W(1));\n+\treg_val32 = roc_ml_reg_read32(&mldev->roc, ML_A35_1_RST_VECTOR_BASE_W(1));\n+\tplt_ml_dbg(\"ML_A35_1_RST_VECTOR_BASE_W(1) => 0x%08x\", reg_val32);\n+\n+\t/* (11) Clear MLIP's ML(0)_SW_RST_CTRL[ACC_RST]. This will bring the ACC cores and other\n+\t * MLIP components out of reset. The cores will execute firmware from the ML region as\n+\t * written in step 1.\n+\t */\n+\treg_val32 = roc_ml_reg_read32(&mldev->roc, ML_SW_RST_CTRL);\n+\treg_val32 &= ~ROC_ML_SW_RST_CTRL_ACC_RST;\n+\troc_ml_reg_write32(&mldev->roc, reg_val32, ML_SW_RST_CTRL);\n+\treg_val32 = roc_ml_reg_read32(&mldev->roc, ML_SW_RST_CTRL);\n+\tplt_ml_dbg(\"ML_SW_RST_CTRL => 0x%08x\", reg_val32);\n+\n+\t/* (12) Wait for notification from firmware that ML is ready for job execution. */\n+\tfw->req->jd.hdr.jce.w1.u64 = PLT_U64_CAST(&fw->req->status);\n+\tfw->req->jd.hdr.job_type = ML_CN10K_JOB_TYPE_FIRMWARE_LOAD;\n+\tfw->req->jd.hdr.result = roc_ml_addr_ap2mlip(&mldev->roc, &fw->req->result);\n+\tfw->req->jd.fw_load.flags = cn10k_ml_fw_flags_get(fw);\n+\tplt_write64(ML_CN10K_POLL_JOB_START, &fw->req->status);\n+\tplt_wmb();\n+\n+\t/* Enqueue FW load through scratch registers */\n+\ttimeout = true;\n+\ttimeout_cycle = plt_tsc_cycles() + ML_CN10K_CMD_TIMEOUT * plt_tsc_hz();\n+\troc_ml_scratch_enqueue(&mldev->roc, &fw->req->jd);\n+\n+\tplt_rmb();\n+\tdo {\n+\t\tif (roc_ml_scratch_is_done_bit_set(&mldev->roc) &&\n+\t\t    (plt_read64(&fw->req->status) == ML_CN10K_POLL_JOB_FINISH)) {\n+\t\t\ttimeout = false;\n+\t\t\tbreak;\n+\t\t}\n+\t} while (plt_tsc_cycles() < timeout_cycle);\n+\n+\t/* Check firmware load status, clean-up and exit on failure. */\n+\tif ((!timeout) && (fw->req->result.error_code == 0)) {\n+\t\tcn10k_ml_fw_print_info(fw);\n+\t} else {\n+\t\t/* Set ML to disable new jobs */\n+\t\treg_val64 = (ROC_ML_CFG_JD_SIZE | ROC_ML_CFG_MLIP_ENA);\n+\t\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_CFG);\n+\n+\t\t/* Clear scratch registers */\n+\t\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_WORK_PTR);\n+\t\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_FW_CTRL);\n+\n+\t\tif (timeout) {\n+\t\t\tplt_err(\"Firmware load timeout\");\n+\t\t\tret = -ETIME;\n+\t\t} else {\n+\t\t\tplt_err(\"Firmware load failed\");\n+\t\t\tret = -1;\n+\t\t}\n+\n+\t\treturn ret;\n+\t}\n+\n+\t/* (13) Set ML(0)_JOB_MGR_CTRL[STALL_ON_IDLE] = 0x1; this is needed to shut down the MLIP\n+\t * clock when there are no more jobs to process.\n+\t */\n+\treg_val64 = roc_ml_reg_read64(&mldev->roc, ML_JOB_MGR_CTRL);\n+\treg_val64 |= ROC_ML_JOB_MGR_CTRL_STALL_ON_IDLE;\n+\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_JOB_MGR_CTRL);\n+\tplt_ml_dbg(\"ML_JOB_MGR_CTRL => 0x%016lx\", roc_ml_reg_read64(&mldev->roc, ML_JOB_MGR_CTRL));\n+\n+\t/* (14) Set ML(0)_CFG[MLIP_CLK_FORCE] = 0; the MLIP clock will be turned on/off based on job\n+\t * activities.\n+\t */\n+\treg_val64 = roc_ml_reg_read64(&mldev->roc, ML_CFG);\n+\treg_val64 &= ~ROC_ML_CFG_MLIP_CLK_FORCE;\n+\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_CFG);\n+\tplt_ml_dbg(\"ML_CFG => 0x%016lx\", roc_ml_reg_read64(&mldev->roc, ML_CFG));\n+\n+\t/* (15) Set ML(0)_CFG[ENA] to enable ML job execution. */\n+\treg_val64 = roc_ml_reg_read64(&mldev->roc, ML_CFG);\n+\treg_val64 |= ROC_ML_CFG_ENA;\n+\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_CFG);\n+\tplt_ml_dbg(\"ML_CFG => 0x%016lx\", roc_ml_reg_read64(&mldev->roc, ML_CFG));\n+\n+\t/* Reset scratch registers */\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_FW_CTRL);\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_WORK_PTR);\n+\n+\t/* Disable job execution, to be enabled in start */\n+\treg_val64 = roc_ml_reg_read64(&mldev->roc, ML_CFG);\n+\treg_val64 &= ~ROC_ML_CFG_ENA;\n+\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_CFG);\n+\tplt_ml_dbg(\"ML_CFG => 0x%016lx\", roc_ml_reg_read64(&mldev->roc, ML_CFG));\n+\n+\t/* Additional fixes: Set RO bit to fix O2D DMA bandwidth issue on cn10ka */\n+\tfor (i = 0; i < ML_ANBX_NR; i++) {\n+\t\treg_val64 = roc_ml_reg_read64(&mldev->roc, ML_ANBX_NCBI_P_OVR(i));\n+\t\treg_val64 |= (ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_RO_OVR |\n+\t\t\t      ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_RO_OVR_VLD);\n+\t\troc_ml_reg_write64(&mldev->roc, reg_val64, ML_ANBX_NCBI_P_OVR(i));\n+\t}\n+\n+\treturn ret;\n+}\n+\n+int\n+cn10k_ml_fw_load(struct cn10k_ml_dev *mldev)\n+{\n+\tconst struct plt_memzone *mz;\n+\tstruct cn10k_ml_fw *fw;\n+\tvoid *fw_buffer = NULL;\n+\tuint64_t mz_size = 0;\n+\tuint64_t fw_size = 0;\n+\tint ret = 0;\n+\n+\tfw = &mldev->fw;\n+\tfw->mldev = mldev;\n+\n+\t/* Read firmware image to a buffer */\n+\tret = rte_firmware_read(fw->path, &fw_buffer, &fw_size);\n+\tif (ret < 0) {\n+\t\tplt_err(\"Can't read firmware data: %s\\n\", fw->path);\n+\t\treturn ret;\n+\t}\n+\n+\t/* Reserve memzone for firmware load completion and data */\n+\tmz_size = sizeof(struct cn10k_ml_req) + fw_size + FW_STACK_BUFFER_SIZE +\n+\t\t  FW_DEBUG_BUFFER_SIZE + FW_EXCEPTION_BUFFER_SIZE;\n+\tmz = plt_memzone_reserve_aligned(FW_MEMZONE_NAME, mz_size, 0, ML_CN10K_ALIGN_SIZE);\n+\tif (mz == NULL) {\n+\t\tplt_err(\"plt_memzone_reserve failed : %s\", FW_MEMZONE_NAME);\n+\t\tif (fw_buffer != NULL)\n+\t\t\tfree(fw_buffer);\n+\t\treturn -ENOMEM;\n+\t}\n+\tfw->req = mz->addr;\n+\n+\t/* Reset firmware load completion structure */\n+\tmemset(&fw->req->jd, 0, sizeof(struct cn10k_ml_jd));\n+\tmemset(&fw->req->jd.fw_load.version[0], '\\0', MLDEV_FIRMWARE_VERSION_LENGTH);\n+\n+\t/* Reset device, if in active state */\n+\tif (roc_ml_mlip_is_enabled(&mldev->roc))\n+\t\troc_ml_mlip_reset(&mldev->roc, true);\n+\n+\t/* Load firmware */\n+\tfw->data = PLT_PTR_ADD(mz->addr, sizeof(struct cn10k_ml_req));\n+\tret = cn10k_ml_fw_load_cn10ka(fw, fw_buffer, fw_size);\n+\tif (fw_buffer != NULL)\n+\t\tfree(fw_buffer);\n+\tif (ret < 0)\n+\t\tcn10k_ml_fw_unload(mldev);\n+\n+\treturn ret;\n+}\n+\n+void\n+cn10k_ml_fw_unload(struct cn10k_ml_dev *mldev)\n+{\n+\tconst struct plt_memzone *mz;\n+\tuint64_t reg_val;\n+\n+\t/* Disable and reset device */\n+\treg_val = roc_ml_reg_read64(&mldev->roc, ML_CFG);\n+\treg_val &= ~ROC_ML_CFG_MLIP_ENA;\n+\troc_ml_reg_write64(&mldev->roc, reg_val, ML_CFG);\n+\troc_ml_mlip_reset(&mldev->roc, true);\n+\n+\tmz = plt_memzone_lookup(FW_MEMZONE_NAME);\n+\tif (mz != NULL)\n+\t\tplt_memzone_free(mz);\n+}\n+\n static struct rte_pci_id pci_id_ml_table[] = {\n \t{RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10K_ML_PF)},\n \t/* sentinel */\ndiff --git a/drivers/ml/cnxk/cn10k_ml_dev.h b/drivers/ml/cnxk/cn10k_ml_dev.h\nindex 5333566cff..00d23eb3ca 100644\n--- a/drivers/ml/cnxk/cn10k_ml_dev.h\n+++ b/drivers/ml/cnxk/cn10k_ml_dev.h\n@@ -10,6 +10,9 @@\n /* Marvell OCTEON CN10K ML PMD device name */\n #define MLDEV_NAME_CN10K_PMD ml_cn10k\n \n+/* Firmware version string length */\n+#define MLDEV_FIRMWARE_VERSION_LENGTH 32\n+\n /* Device alignment size */\n #define ML_CN10K_ALIGN_SIZE 128\n \n@@ -28,6 +31,19 @@\n /* ML command timeout in seconds */\n #define ML_CN10K_CMD_TIMEOUT 5\n \n+/* Poll mode job state */\n+#define ML_CN10K_POLL_JOB_START\t 0\n+#define ML_CN10K_POLL_JOB_FINISH 1\n+\n+/* Job types */\n+enum cn10k_ml_job_type {\n+\tML_CN10K_JOB_TYPE_MODEL_RUN = 0,\n+\tML_CN10K_JOB_TYPE_MODEL_STOP,\n+\tML_CN10K_JOB_TYPE_MODEL_START,\n+\tML_CN10K_JOB_TYPE_FIRMWARE_LOAD,\n+\tML_CN10K_JOB_TYPE_FIRMWARE_SELFTEST,\n+};\n+\n /* Device configuration state enum */\n enum cn10k_ml_dev_state {\n \t/* Probed and not configured */\n@@ -43,6 +59,136 @@ enum cn10k_ml_dev_state {\n \tML_CN10K_DEV_STATE_CLOSED\n };\n \n+/* Firmware stats */\n+struct cn10k_ml_fw_stats {\n+\t/* Firmware start cycle */\n+\tuint64_t fw_start;\n+\n+\t/* Firmware end cycle */\n+\tuint64_t fw_end;\n+\n+\t/* Hardware start cycle */\n+\tuint64_t hw_start;\n+\n+\t/* Hardware end cycle */\n+\tuint64_t hw_end;\n+};\n+\n+/* Result structure */\n+struct cn10k_ml_result {\n+\t/* Job error code */\n+\tuint64_t error_code;\n+\n+\t/* Firmware stats */\n+\tstruct cn10k_ml_fw_stats stats;\n+\n+\t/* User context pointer */\n+\tvoid *user_ptr;\n+};\n+\n+/* Firmware capability structure */\n+union cn10k_ml_fw_cap {\n+\tuint64_t u64;\n+\n+\tstruct {\n+\t\t/* CMPC completion support */\n+\t\tuint64_t cmpc_completions : 1;\n+\n+\t\t/* Poll mode completion support */\n+\t\tuint64_t poll_completions : 1;\n+\n+\t\t/* SSO completion support */\n+\t\tuint64_t sso_completions : 1;\n+\n+\t\t/* Support for model side loading */\n+\t\tuint64_t side_load_model : 1;\n+\n+\t\t/* Batch execution */\n+\t\tuint64_t batch_run : 1;\n+\n+\t\t/* Max number of models to be loaded in parallel */\n+\t\tuint64_t max_models : 8;\n+\n+\t\t/* Firmware statistics */\n+\t\tuint64_t fw_stats : 1;\n+\n+\t\t/* Hardware statistics */\n+\t\tuint64_t hw_stats : 1;\n+\n+\t\t/* Max number of batches */\n+\t\tuint64_t max_num_batches : 16;\n+\n+\t\tuint64_t rsvd : 33;\n+\t} s;\n+};\n+\n+/* Firmware debug info structure */\n+struct cn10k_ml_fw_debug {\n+\t/* ACC core 0 debug buffer */\n+\tuint64_t core0_debug_ptr;\n+\n+\t/* ACC core 1 debug buffer */\n+\tuint64_t core1_debug_ptr;\n+\n+\t/* ACC core 0 exception state buffer */\n+\tuint64_t core0_exception_buffer;\n+\n+\t/* ACC core 1 exception state buffer */\n+\tuint64_t core1_exception_buffer;\n+\n+\t/* Debug buffer size per core */\n+\tuint32_t debug_buffer_size;\n+\n+\t/* Exception state dump size */\n+\tuint32_t exception_state_size;\n+};\n+\n+/* Job descriptor header (32 bytes) */\n+struct cn10k_ml_jd_header {\n+\t/* Job completion structure */\n+\tstruct ml_jce_s jce;\n+\n+\t/* Model ID */\n+\tuint64_t model_id : 8;\n+\n+\t/* Job type */\n+\tuint64_t job_type : 8;\n+\n+\t/* Flags for fast-path jobs */\n+\tuint64_t fp_flags : 16;\n+\n+\t/* Flags for slow-path jobs */\n+\tuint64_t sp_flags : 16;\n+\tuint64_t rsvd : 16;\n+\n+\t/* Job result pointer */\n+\tuint64_t *result;\n+};\n+\n+/* Job descriptor structure */\n+struct cn10k_ml_jd {\n+\t/* Job descriptor header (32 bytes) */\n+\tstruct cn10k_ml_jd_header hdr;\n+\n+\tunion {\n+\t\tstruct cn10k_ml_jd_section_fw_load {\n+\t\t\t/* Firmware capability structure (8 bytes) */\n+\t\t\tunion cn10k_ml_fw_cap cap;\n+\n+\t\t\t/* Firmware version (32 bytes) */\n+\t\t\tuint8_t version[MLDEV_FIRMWARE_VERSION_LENGTH];\n+\n+\t\t\t/* Debug capability structure (40 bytes) */\n+\t\t\tstruct cn10k_ml_fw_debug debug;\n+\n+\t\t\t/* Flags to control error handling */\n+\t\t\tuint64_t flags;\n+\n+\t\t\tuint8_t rsvd[8];\n+\t\t} fw_load;\n+\t};\n+};\n+\n /* ML firmware structure */\n struct cn10k_ml_fw {\n \t/* Device reference */\n@@ -50,6 +196,12 @@ struct cn10k_ml_fw {\n \n \t/* Firmware file path */\n \tconst char *path;\n+\n+\t/* Data buffer */\n+\tuint8_t *data;\n+\n+\t/* Firmware load / handshake request structure */\n+\tstruct cn10k_ml_req *req;\n };\n \n /* Device private data */\n@@ -64,4 +216,8 @@ struct cn10k_ml_dev {\n \tstruct cn10k_ml_fw fw;\n };\n \n+uint64_t cn10k_ml_fw_flags_get(struct cn10k_ml_fw *fw);\n+int cn10k_ml_fw_load(struct cn10k_ml_dev *mldev);\n+void cn10k_ml_fw_unload(struct cn10k_ml_dev *mldev);\n+\n #endif /* _CN10K_ML_DEV_H_ */\ndiff --git a/drivers/ml/cnxk/cn10k_ml_ops.c b/drivers/ml/cnxk/cn10k_ml_ops.c\nindex 32d38569a3..11e1cdb7cd 100644\n--- a/drivers/ml/cnxk/cn10k_ml_ops.c\n+++ b/drivers/ml/cnxk/cn10k_ml_ops.c\n@@ -30,6 +30,7 @@ cn10k_ml_dev_configure(struct rte_ml_dev *dev, const struct rte_ml_dev_config *c\n {\n \tstruct rte_ml_dev_info dev_info;\n \tstruct cn10k_ml_dev *mldev;\n+\tint ret;\n \n \tif (dev == NULL || conf == NULL)\n \t\treturn -EINVAL;\n@@ -51,6 +52,11 @@ cn10k_ml_dev_configure(struct rte_ml_dev *dev, const struct rte_ml_dev_config *c\n \tif (mldev->state == ML_CN10K_DEV_STATE_PROBED) {\n \t\tplt_ml_dbg(\"Configuring ML device, nb_queue_pairs = %u, nb_models = %u\",\n \t\t\t   conf->nb_queue_pairs, conf->nb_models);\n+\n+\t\t/* Load firmware */\n+\t\tret = cn10k_ml_fw_load(mldev);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n \t} else if (mldev->state == ML_CN10K_DEV_STATE_CONFIGURED) {\n \t\tplt_ml_dbg(\"Re-configuring ML device, nb_queue_pairs = %u, nb_models = %u\",\n \t\t\t   conf->nb_queue_pairs, conf->nb_models);\n@@ -77,6 +83,21 @@ cn10k_ml_dev_close(struct rte_ml_dev *dev)\n \n \tmldev = dev->data->dev_private;\n \n+\t/* Unload firmware */\n+\tcn10k_ml_fw_unload(mldev);\n+\n+\t/* Clear scratch registers */\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_WORK_PTR);\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_FW_CTRL);\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_HEAD_C0);\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_TAIL_C0);\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_HEAD_C1);\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_TAIL_C1);\n+\n+\t/* Reset ML_MLR_BASE */\n+\troc_ml_reg_write64(&mldev->roc, 0, ML_MLR_BASE);\n+\tplt_ml_dbg(\"ML_MLR_BASE = 0x%016lx\", roc_ml_reg_read64(&mldev->roc, ML_MLR_BASE));\n+\n \tmldev->state = ML_CN10K_DEV_STATE_CLOSED;\n \n \t/* Remove PCI device */\ndiff --git a/drivers/ml/cnxk/cn10k_ml_ops.h b/drivers/ml/cnxk/cn10k_ml_ops.h\nindex b14221d02c..fe18730aca 100644\n--- a/drivers/ml/cnxk/cn10k_ml_ops.h\n+++ b/drivers/ml/cnxk/cn10k_ml_ops.h\n@@ -5,6 +5,20 @@\n #ifndef _CN10K_ML_OPS_H_\n #define _CN10K_ML_OPS_H_\n \n+#include \"cn10k_ml_dev.h\"\n+\n+/* ML request */\n+struct cn10k_ml_req {\n+\t/* Job descriptor */\n+\tstruct cn10k_ml_jd jd;\n+\n+\t/* Job result */\n+\tstruct cn10k_ml_result result;\n+\n+\t/* Status field for poll mode requests */\n+\tvolatile uint64_t status;\n+} __rte_aligned(ROC_ALIGN);\n+\n /* Device ops */\n extern struct rte_ml_dev_ops cn10k_ml_ops;\n \n",
    "prefixes": [
        "v4",
        "07/39"
    ]
}