get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 88569,
    "url": "http://patches.dpdk.org/api/patches/88569/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20210305133918.8005-43-ndabilpuram@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": "<20210305133918.8005-43-ndabilpuram@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210305133918.8005-43-ndabilpuram@marvell.com",
    "date": "2021-03-05T13:39:08",
    "name": "[42/52] common/cnxk: add mcam utility API",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "f4219431bda0e99590bd8e5898a279782f530f4b",
    "submitter": {
        "id": 1202,
        "url": "http://patches.dpdk.org/api/people/1202/?format=api",
        "name": "Nithin Dabilpuram",
        "email": "ndabilpuram@marvell.com"
    },
    "delegate": {
        "id": 310,
        "url": "http://patches.dpdk.org/api/users/310/?format=api",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerinj@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20210305133918.8005-43-ndabilpuram@marvell.com/mbox/",
    "series": [
        {
            "id": 15508,
            "url": "http://patches.dpdk.org/api/series/15508/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=15508",
            "date": "2021-03-05T13:38:26",
            "name": "Add Marvell CNXK common driver",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/15508/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/88569/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/88569/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 3282FA0547;\n\tFri,  5 Mar 2021 14:47:12 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 0BC7A22A44F;\n\tFri,  5 Mar 2021 14:41:40 +0100 (CET)",
            "from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com\n [67.231.148.174])\n by mails.dpdk.org (Postfix) with ESMTP id 30CB222A45D\n for <dev@dpdk.org>; Fri,  5 Mar 2021 14:41:38 +0100 (CET)",
            "from pps.filterd (m0045849.ppops.net [127.0.0.1])\n by mx0a-0016f401.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id\n 125DelHd001661 for <dev@dpdk.org>; Fri, 5 Mar 2021 05:41:37 -0800",
            "from dc5-exch01.marvell.com ([199.233.59.181])\n by mx0a-0016f401.pphosted.com with ESMTP id 372s2umrrr-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n for <dev@dpdk.org>; Fri, 05 Mar 2021 05:41:37 -0800",
            "from SC-EXCH04.marvell.com (10.93.176.84) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2;\n Fri, 5 Mar 2021 05:41:35 -0800",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by SC-EXCH04.marvell.com\n (10.93.176.84) with Microsoft SMTP Server (TLS) id 15.0.1497.2;\n Fri, 5 Mar 2021 05:41:35 -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.2 via Frontend\n Transport; Fri, 5 Mar 2021 05:41:35 -0800",
            "from hyd1588t430.marvell.com (unknown [10.29.52.204])\n by maili.marvell.com (Postfix) with ESMTP id E08A63F703F;\n Fri,  5 Mar 2021 05:41:32 -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=TB1tVPHhRAw8t+FiKQpWmkQzxZtmTuQ32EkjieuUJBc=;\n b=Vn0LlnenSEv9ahpZqh1af9i44LkO9r+0LPyXAybsVxjnOGq9D2bPvMqwBjr4nrxlIoe1\n MZ4mbNPKvn0vznbIVFcmgI1rlkUugiqHd6XC+hFk+ozCX9N+UM3qvSJL2RuH+qvAa11W\n cir6/sdiFgoNygD788ecIYKlDHvMGSOkLH5TBzOTyzQ5fQ+JjTILze5kOsEY6XGd/EYM\n JIU82WACu0WgT+bi5uG0XSfHM5xNd8wlX7+yzTHie3Z5CUWW80VjvmGWpJFuqn1nhzWZ\n I/DhPiwoqB+j9ffnuU1aT2TtwrnPkjljohrUiG9nJMs3tFreZCPkCafmMlrsBQWQ1R0N BQ==",
        "From": "Nithin Dabilpuram <ndabilpuram@marvell.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<jerinj@marvell.com>, <skori@marvell.com>, <skoteshwar@marvell.com>,\n <pbhagavatula@marvell.com>, <kirankumark@marvell.com>,\n <psatheesh@marvell.com>, <asekhar@marvell.com>",
        "Date": "Fri, 5 Mar 2021 19:09:08 +0530",
        "Message-ID": "<20210305133918.8005-43-ndabilpuram@marvell.com>",
        "X-Mailer": "git-send-email 2.8.4",
        "In-Reply-To": "<20210305133918.8005-1-ndabilpuram@marvell.com>",
        "References": "<20210305133918.8005-1-ndabilpuram@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10434:6.0.369, 18.0.761\n definitions=2021-03-05_08:2021-03-03,\n 2021-03-05 signatures=0",
        "Subject": "[dpdk-dev] [PATCH 42/52] common/cnxk: add mcam utility API",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Kiran Kumar K <kirankumark@marvell.com>\n\nAdding mcam utility functions like reading KEX and reserving and writing\nmcam rules.\n\nSigned-off-by: Kiran Kumar K <kirankumark@marvell.com>\n---\n drivers/common/cnxk/meson.build    |   1 +\n drivers/common/cnxk/roc_npc_mcam.c | 708 +++++++++++++++++++++++++++++++++++++\n drivers/common/cnxk/roc_npc_priv.h |  21 ++\n 3 files changed, 730 insertions(+)\n create mode 100644 drivers/common/cnxk/roc_npc_mcam.c",
    "diff": "diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build\nindex c4ec988..35dd3b9 100644\n--- a/drivers/common/cnxk/meson.build\n+++ b/drivers/common/cnxk/meson.build\n@@ -35,6 +35,7 @@ sources = files('roc_dev.c',\n \t\t'roc_npa.c',\n \t\t'roc_npa_debug.c',\n \t\t'roc_npa_irq.c',\n+\t\t'roc_npc_mcam.c',\n \t\t'roc_npc_utils.c',\n \t\t'roc_platform.c',\n \t\t'roc_utils.c')\ndiff --git a/drivers/common/cnxk/roc_npc_mcam.c b/drivers/common/cnxk/roc_npc_mcam.c\nnew file mode 100644\nindex 0000000..1cd7035\n--- /dev/null\n+++ b/drivers/common/cnxk/roc_npc_mcam.c\n@@ -0,0 +1,708 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2020 Marvell.\n+ */\n+#include \"roc_api.h\"\n+#include \"roc_priv.h\"\n+\n+static int\n+npc_mcam_alloc_counter(struct npc *npc, uint16_t *ctr)\n+{\n+\tstruct npc_mcam_alloc_counter_req *req;\n+\tstruct npc_mcam_alloc_counter_rsp *rsp;\n+\tstruct mbox *mbox = npc->mbox;\n+\tint rc = -ENOSPC;\n+\n+\treq = mbox_alloc_msg_npc_mcam_alloc_counter(mbox);\n+\tif (req == NULL)\n+\t\treturn rc;\n+\treq->count = 1;\n+\trc = mbox_process_msg(mbox, (void *)&rsp);\n+\tif (rc)\n+\t\treturn rc;\n+\t*ctr = rsp->cntr_list[0];\n+\treturn rc;\n+}\n+\n+int\n+npc_mcam_free_counter(struct npc *npc, uint16_t ctr_id)\n+{\n+\tstruct npc_mcam_oper_counter_req *req;\n+\tstruct mbox *mbox = npc->mbox;\n+\tint rc = -ENOSPC;\n+\n+\treq = mbox_alloc_msg_npc_mcam_free_counter(mbox);\n+\tif (req == NULL)\n+\t\treturn rc;\n+\treq->cntr = ctr_id;\n+\treturn mbox_process(mbox);\n+}\n+\n+int\n+npc_mcam_read_counter(struct npc *npc, uint32_t ctr_id, uint64_t *count)\n+{\n+\tstruct npc_mcam_oper_counter_req *req;\n+\tstruct npc_mcam_oper_counter_rsp *rsp;\n+\tstruct mbox *mbox = npc->mbox;\n+\tint rc = -ENOSPC;\n+\n+\treq = mbox_alloc_msg_npc_mcam_counter_stats(mbox);\n+\tif (req == NULL)\n+\t\treturn rc;\n+\treq->cntr = ctr_id;\n+\trc = mbox_process_msg(mbox, (void *)&rsp);\n+\tif (rc)\n+\t\treturn rc;\n+\t*count = rsp->stat;\n+\treturn rc;\n+}\n+\n+int\n+npc_mcam_clear_counter(struct npc *npc, uint32_t ctr_id)\n+{\n+\tstruct npc_mcam_oper_counter_req *req;\n+\tstruct mbox *mbox = npc->mbox;\n+\tint rc = -ENOSPC;\n+\n+\treq = mbox_alloc_msg_npc_mcam_clear_counter(mbox);\n+\tif (req == NULL)\n+\t\treturn rc;\n+\treq->cntr = ctr_id;\n+\treturn mbox_process(mbox);\n+}\n+\n+int\n+npc_mcam_free_entry(struct npc *npc, uint32_t entry)\n+{\n+\tstruct npc_mcam_free_entry_req *req;\n+\tstruct mbox *mbox = npc->mbox;\n+\tint rc = -ENOSPC;\n+\n+\treq = mbox_alloc_msg_npc_mcam_free_entry(mbox);\n+\tif (req == NULL)\n+\t\treturn rc;\n+\treq->entry = entry;\n+\treturn mbox_process(mbox);\n+}\n+\n+int\n+npc_mcam_free_all_entries(struct npc *npc)\n+{\n+\tstruct npc_mcam_free_entry_req *req;\n+\tstruct mbox *mbox = npc->mbox;\n+\tint rc = -ENOSPC;\n+\n+\treq = mbox_alloc_msg_npc_mcam_free_entry(mbox);\n+\tif (req == NULL)\n+\t\treturn rc;\n+\treq->all = 1;\n+\treturn mbox_process(mbox);\n+}\n+\n+static int\n+npc_supp_key_len(uint32_t supp_mask)\n+{\n+\tint nib_count = 0;\n+\n+\twhile (supp_mask) {\n+\t\tnib_count++;\n+\t\tsupp_mask &= (supp_mask - 1);\n+\t}\n+\treturn nib_count * 4;\n+}\n+\n+/**\n+ * Returns true if any LDATA bits are extracted for specific LID+LTYPE.\n+ *\n+ * No LFLAG extraction is taken into account.\n+ */\n+static int\n+npc_lid_lt_in_kex(struct npc *npc, uint8_t lid, uint8_t lt)\n+{\n+\tstruct npc_xtract_info *x_info;\n+\tint i;\n+\n+\tfor (i = 0; i < NPC_MAX_LD; i++) {\n+\t\tx_info = &npc->prx_dxcfg[NIX_INTF_RX][lid][lt].xtract[i];\n+\t\t/* Check for LDATA */\n+\t\tif (x_info->enable && x_info->len > 0)\n+\t\t\treturn true;\n+\t}\n+\n+\treturn false;\n+}\n+\n+static void\n+npc_construct_ldata_mask(struct npc *npc, struct plt_bitmap *bmap, uint8_t lid,\n+\t\t\t uint8_t lt, uint8_t ld)\n+{\n+\tstruct npc_xtract_info *x_info, *infoflag;\n+\tint hdr_off, keylen;\n+\tnpc_dxcfg_t *p;\n+\tnpc_fxcfg_t *q;\n+\tint i, j;\n+\n+\tp = &npc->prx_dxcfg;\n+\tx_info = &(*p)[0][lid][lt].xtract[ld];\n+\n+\tif (x_info->enable == 0)\n+\t\treturn;\n+\n+\thdr_off = x_info->hdr_off * 8;\n+\tkeylen = x_info->len * 8;\n+\tfor (i = hdr_off; i < (hdr_off + keylen); i++)\n+\t\tplt_bitmap_set(bmap, i);\n+\n+\tif (x_info->flags_enable == 0)\n+\t\treturn;\n+\n+\tif ((npc->prx_lfcfg[0].i & 0x7) != lid)\n+\t\treturn;\n+\n+\tq = &npc->prx_fxcfg;\n+\tfor (j = 0; j < NPC_MAX_LFL; j++) {\n+\t\tinfoflag = &(*q)[0][ld][j].xtract[0];\n+\t\tif (infoflag->enable) {\n+\t\t\thdr_off = infoflag->hdr_off * 8;\n+\t\t\tkeylen = infoflag->len * 8;\n+\t\t\tfor (i = hdr_off; i < (hdr_off + keylen); i++)\n+\t\t\t\tplt_bitmap_set(bmap, i);\n+\t\t}\n+\t}\n+}\n+\n+/**\n+ * Check if given LID+LTYPE combination is present in KEX\n+ *\n+ * len is non-zero, this function will return true if KEX extracts len bytes\n+ * at given offset. Otherwise it'll return true if any bytes are extracted\n+ * specifically for given LID+LTYPE combination (meaning not LFLAG based).\n+ * The second case increases flexibility for custom frames whose extracted\n+ * bits may change depending on KEX profile loaded.\n+ *\n+ * @param npc NPC context structure\n+ * @param lid Layer ID to check for\n+ * @param lt Layer Type to check for\n+ * @param offset offset into the layer header to match\n+ * @param len length of the match\n+ */\n+static bool\n+npc_is_kex_enabled(struct npc *npc, uint8_t lid, uint8_t lt, int offset,\n+\t\t   int len)\n+{\n+\tstruct plt_bitmap *bmap;\n+\tuint32_t bmap_sz;\n+\tuint8_t *mem;\n+\tint i;\n+\n+\tif (!len)\n+\t\treturn npc_lid_lt_in_kex(npc, lid, lt);\n+\n+\tbmap_sz = plt_bitmap_get_memory_footprint(300 * 8);\n+\tmem = plt_zmalloc(bmap_sz, 0);\n+\tif (mem == NULL) {\n+\t\tplt_err(\"mem alloc failed\");\n+\t\treturn false;\n+\t}\n+\tbmap = plt_bitmap_init(300 * 8, mem, bmap_sz);\n+\tif (bmap == NULL) {\n+\t\tplt_err(\"mem alloc failed\");\n+\t\tplt_free(mem);\n+\t\treturn false;\n+\t}\n+\n+\tnpc_construct_ldata_mask(npc, bmap, lid, lt, 0);\n+\tnpc_construct_ldata_mask(npc, bmap, lid, lt, 1);\n+\n+\tfor (i = offset; i < (offset + len); i++) {\n+\t\tif (plt_bitmap_get(bmap, i) != 0x1) {\n+\t\t\tplt_free(mem);\n+\t\t\treturn false;\n+\t\t}\n+\t}\n+\n+\tplt_free(mem);\n+\treturn true;\n+}\n+\n+uint64_t\n+npc_get_kex_capability(struct npc *npc)\n+{\n+\tnpc_kex_cap_terms_t kex_cap;\n+\n+\tmemset(&kex_cap, 0, sizeof(kex_cap));\n+\n+\t/* Ethtype: Offset 12B, len 2B */\n+\tkex_cap.bit.ethtype_0 = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LA, NPC_LT_LA_ETHER, 12 * 8, 2 * 8);\n+\t/* QINQ VLAN Ethtype: ofset 8B, len 2B */\n+\tkex_cap.bit.ethtype_x = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 8 * 8, 2 * 8);\n+\t/* VLAN ID0 : Outer VLAN: Offset 2B, len 2B */\n+\tkex_cap.bit.vlan_id_0 = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LB, NPC_LT_LB_CTAG, 2 * 8, 2 * 8);\n+\t/* VLAN ID0 : Inner VLAN: offset 6B, len 2B */\n+\tkex_cap.bit.vlan_id_x = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 6 * 8, 2 * 8);\n+\t/* DMCA: offset 0B, len 6B */\n+\tkex_cap.bit.dmac = npc_is_kex_enabled(npc, NPC_LID_LA, NPC_LT_LA_ETHER,\n+\t\t\t\t\t      0 * 8, 6 * 8);\n+\t/* IP proto: offset 9B, len 1B */\n+\tkex_cap.bit.ip_proto =\n+\t\tnpc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_IP, 9 * 8, 1 * 8);\n+\t/* UDP dport: offset 2B, len 2B */\n+\tkex_cap.bit.udp_dport = npc_is_kex_enabled(npc, NPC_LID_LD,\n+\t\t\t\t\t\t   NPC_LT_LD_UDP, 2 * 8, 2 * 8);\n+\t/* UDP sport: offset 0B, len 2B */\n+\tkex_cap.bit.udp_sport = npc_is_kex_enabled(npc, NPC_LID_LD,\n+\t\t\t\t\t\t   NPC_LT_LD_UDP, 0 * 8, 2 * 8);\n+\t/* TCP dport: offset 2B, len 2B */\n+\tkex_cap.bit.tcp_dport = npc_is_kex_enabled(npc, NPC_LID_LD,\n+\t\t\t\t\t\t   NPC_LT_LD_TCP, 2 * 8, 2 * 8);\n+\t/* TCP sport: offset 0B, len 2B */\n+\tkex_cap.bit.tcp_sport = npc_is_kex_enabled(npc, NPC_LID_LD,\n+\t\t\t\t\t\t   NPC_LT_LD_TCP, 0 * 8, 2 * 8);\n+\t/* IP SIP: offset 12B, len 4B */\n+\tkex_cap.bit.sip_addr = npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_IP,\n+\t\t\t\t\t\t  12 * 8, 4 * 8);\n+\t/* IP DIP: offset 14B, len 4B */\n+\tkex_cap.bit.dip_addr = npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_IP,\n+\t\t\t\t\t\t  14 * 8, 4 * 8);\n+\t/* IP6 SIP: offset 8B, len 16B */\n+\tkex_cap.bit.sip6_addr = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LC, NPC_LT_LC_IP6, 8 * 8, 16 * 8);\n+\t/* IP6 DIP: offset 24B, len 16B */\n+\tkex_cap.bit.dip6_addr = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LC, NPC_LT_LC_IP6, 24 * 8, 16 * 8);\n+\t/* ESP SPI: offset 0B, len 4B */\n+\tkex_cap.bit.ipsec_spi = npc_is_kex_enabled(npc, NPC_LID_LE,\n+\t\t\t\t\t\t   NPC_LT_LE_ESP, 0 * 8, 4 * 8);\n+\t/* VXLAN VNI: offset 4B, len 3B */\n+\tkex_cap.bit.ld_vni = npc_is_kex_enabled(npc, NPC_LID_LE,\n+\t\t\t\t\t\tNPC_LT_LE_VXLAN, 0 * 8, 3 * 8);\n+\n+\t/* Custom L3 frame: varied offset and lengths */\n+\tkex_cap.bit.custom_l3 =\n+\t\tnpc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_CUSTOM0, 0, 0);\n+\tkex_cap.bit.custom_l3 |=\n+\t\tnpc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_CUSTOM1, 0, 0);\n+\t/* SCTP sport : offset 0B, len 2B */\n+\tkex_cap.bit.sctp_sport = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LD, NPC_LT_LD_SCTP, 0 * 8, 2 * 8);\n+\t/* SCTP dport : offset 2B, len 2B */\n+\tkex_cap.bit.sctp_dport = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LD, NPC_LT_LD_SCTP, 2 * 8, 2 * 8);\n+\t/* ICMP type : offset 0B, len 1B */\n+\tkex_cap.bit.icmp_type = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LD, NPC_LT_LD_ICMP, 0 * 8, 1 * 8);\n+\t/* ICMP code : offset 1B, len 1B */\n+\tkex_cap.bit.icmp_code = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LD, NPC_LT_LD_ICMP, 1 * 8, 1 * 8);\n+\t/* ICMP id : offset 4B, len 2B */\n+\tkex_cap.bit.icmp_id = npc_is_kex_enabled(npc, NPC_LID_LD,\n+\t\t\t\t\t\t NPC_LT_LD_ICMP, 4 * 8, 2 * 8);\n+\t/* IGMP grp_addr : offset 4B, len 4B */\n+\tkex_cap.bit.igmp_grp_addr = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LD, NPC_LT_LD_IGMP, 4 * 8, 4 * 8);\n+\t/* GTPU teid : offset 4B, len 4B */\n+\tkex_cap.bit.gtpu_teid = npc_is_kex_enabled(\n+\t\tnpc, NPC_LID_LE, NPC_LT_LE_GTPU, 4 * 8, 4 * 8);\n+\treturn kex_cap.all_bits;\n+}\n+\n+#define BYTESM1_SHIFT 16\n+#define HDR_OFF_SHIFT 8\n+static void\n+npc_update_kex_info(struct npc_xtract_info *xtract_info, uint64_t val)\n+{\n+\txtract_info->len = ((val >> BYTESM1_SHIFT) & 0xf) + 1;\n+\txtract_info->hdr_off = (val >> HDR_OFF_SHIFT) & 0xff;\n+\txtract_info->key_off = val & 0x3f;\n+\txtract_info->enable = ((val >> 7) & 0x1);\n+\txtract_info->flags_enable = ((val >> 6) & 0x1);\n+}\n+\n+int\n+npc_mcam_alloc_entries(struct npc *npc, int ref_mcam, int *alloc_entry,\n+\t\t       int req_count, int prio, int *resp_count)\n+{\n+\tstruct npc_mcam_alloc_entry_req *req;\n+\tstruct npc_mcam_alloc_entry_rsp *rsp;\n+\tstruct mbox *mbox = npc->mbox;\n+\tint rc = -ENOSPC;\n+\tint i;\n+\n+\treq = mbox_alloc_msg_npc_mcam_alloc_entry(mbox);\n+\tif (req == NULL)\n+\t\treturn rc;\n+\treq->contig = 0;\n+\treq->count = req_count;\n+\treq->priority = prio;\n+\treq->ref_entry = ref_mcam;\n+\n+\trc = mbox_process_msg(mbox, (void *)&rsp);\n+\tif (rc)\n+\t\treturn rc;\n+\tfor (i = 0; i < rsp->count; i++)\n+\t\talloc_entry[i] = rsp->entry_list[i];\n+\t*resp_count = rsp->count;\n+\treturn 0;\n+}\n+\n+int\n+npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam,\n+\t\t     struct roc_npc_flow *ref_mcam, int prio, int *resp_count)\n+{\n+\tstruct npc_mcam_alloc_entry_req *req;\n+\tstruct npc_mcam_alloc_entry_rsp *rsp;\n+\tstruct mbox *mbox = npc->mbox;\n+\tint rc = -ENOSPC;\n+\n+\treq = mbox_alloc_msg_npc_mcam_alloc_entry(mbox);\n+\tif (req == NULL)\n+\t\treturn rc;\n+\treq->contig = 1;\n+\treq->count = 1;\n+\treq->priority = prio;\n+\treq->ref_entry = ref_mcam->mcam_id;\n+\n+\trc = mbox_process_msg(mbox, (void *)&rsp);\n+\tif (rc)\n+\t\treturn rc;\n+\tmemset(mcam, 0, sizeof(struct roc_npc_flow));\n+\tmcam->mcam_id = rsp->entry;\n+\tmcam->nix_intf = ref_mcam->nix_intf;\n+\t*resp_count = rsp->count;\n+\treturn 0;\n+}\n+\n+int\n+npc_mcam_ena_dis_entry(struct npc *npc, struct roc_npc_flow *mcam, bool enable)\n+{\n+\tstruct npc_mcam_ena_dis_entry_req *req;\n+\tstruct mbox *mbox = npc->mbox;\n+\tint rc = -ENOSPC;\n+\n+\tif (enable)\n+\t\treq = mbox_alloc_msg_npc_mcam_ena_entry(mbox);\n+\telse\n+\t\treq = mbox_alloc_msg_npc_mcam_dis_entry(mbox);\n+\n+\tif (req == NULL)\n+\t\treturn rc;\n+\treq->entry = mcam->mcam_id;\n+\tmcam->enable = enable;\n+\treturn mbox_process(mbox);\n+}\n+\n+int\n+npc_mcam_write_entry(struct npc *npc, struct roc_npc_flow *mcam)\n+{\n+\tstruct npc_mcam_write_entry_req *req;\n+\tstruct mbox *mbox = npc->mbox;\n+\tstruct mbox_msghdr *rsp;\n+\tint rc = -ENOSPC;\n+\tint i;\n+\n+\treq = mbox_alloc_msg_npc_mcam_write_entry(mbox);\n+\tif (req == NULL)\n+\t\treturn rc;\n+\treq->entry = mcam->mcam_id;\n+\treq->intf = mcam->nix_intf;\n+\treq->enable_entry = mcam->enable;\n+\treq->entry_data.action = mcam->npc_action;\n+\treq->entry_data.vtag_action = mcam->vtag_action;\n+\tfor (i = 0; i < NPC_MCAM_KEY_X4_WORDS; i++) {\n+\t\treq->entry_data.kw[i] = mcam->mcam_data[i];\n+\t\treq->entry_data.kw_mask[i] = mcam->mcam_mask[i];\n+\t}\n+\treturn mbox_process_msg(mbox, (void *)&rsp);\n+}\n+\n+static void\n+npc_mcam_process_mkex_cfg(struct npc *npc, struct npc_get_kex_cfg_rsp *kex_rsp)\n+{\n+\tvolatile uint64_t(\n+\t\t*q)[NPC_MAX_INTF][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD];\n+\tstruct npc_xtract_info *x_info = NULL;\n+\tint lid, lt, ld, fl, ix;\n+\tnpc_dxcfg_t *p;\n+\tuint64_t keyw;\n+\tuint64_t val;\n+\n+\tnpc->keyx_supp_nmask[NPC_MCAM_RX] =\n+\t\tkex_rsp->rx_keyx_cfg & 0x7fffffffULL;\n+\tnpc->keyx_supp_nmask[NPC_MCAM_TX] =\n+\t\tkex_rsp->tx_keyx_cfg & 0x7fffffffULL;\n+\tnpc->keyx_len[NPC_MCAM_RX] =\n+\t\tnpc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_RX]);\n+\tnpc->keyx_len[NPC_MCAM_TX] =\n+\t\tnpc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_TX]);\n+\n+\tkeyw = (kex_rsp->rx_keyx_cfg >> 32) & 0x7ULL;\n+\tnpc->keyw[NPC_MCAM_RX] = keyw;\n+\tkeyw = (kex_rsp->tx_keyx_cfg >> 32) & 0x7ULL;\n+\tnpc->keyw[NPC_MCAM_TX] = keyw;\n+\n+\t/* Update KEX_LD_FLAG */\n+\tfor (ix = 0; ix < NPC_MAX_INTF; ix++) {\n+\t\tfor (ld = 0; ld < NPC_MAX_LD; ld++) {\n+\t\t\tfor (fl = 0; fl < NPC_MAX_LFL; fl++) {\n+\t\t\t\tx_info = &npc->prx_fxcfg[ix][ld][fl].xtract[0];\n+\t\t\t\tval = kex_rsp->intf_ld_flags[ix][ld][fl];\n+\t\t\t\tnpc_update_kex_info(x_info, val);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t/* Update LID, LT and LDATA cfg */\n+\tp = &npc->prx_dxcfg;\n+\tq = (volatile uint64_t(*)[][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD])(\n+\t\t&kex_rsp->intf_lid_lt_ld);\n+\tfor (ix = 0; ix < NPC_MAX_INTF; ix++) {\n+\t\tfor (lid = 0; lid < NPC_MAX_LID; lid++) {\n+\t\t\tfor (lt = 0; lt < NPC_MAX_LT; lt++) {\n+\t\t\t\tfor (ld = 0; ld < NPC_MAX_LD; ld++) {\n+\t\t\t\t\tx_info = &(*p)[ix][lid][lt].xtract[ld];\n+\t\t\t\t\tval = (*q)[ix][lid][lt][ld];\n+\t\t\t\t\tnpc_update_kex_info(x_info, val);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t}\n+\t/* Update LDATA Flags cfg */\n+\tnpc->prx_lfcfg[0].i = kex_rsp->kex_ld_flags[0];\n+\tnpc->prx_lfcfg[1].i = kex_rsp->kex_ld_flags[1];\n+}\n+\n+int\n+npc_mcam_fetch_kex_cfg(struct npc *npc)\n+{\n+\tstruct npc_get_kex_cfg_rsp *kex_rsp;\n+\tstruct mbox *mbox = npc->mbox;\n+\tint rc = 0;\n+\n+\tmbox_alloc_msg_npc_get_kex_cfg(mbox);\n+\trc = mbox_process_msg(mbox, (void *)&kex_rsp);\n+\tif (rc) {\n+\t\tplt_err(\"Failed to fetch NPC KEX config\");\n+\t\tgoto done;\n+\t}\n+\n+\tmbox_memcpy((char *)npc->profile_name, kex_rsp->mkex_pfl_name,\n+\t\t    MKEX_NAME_LEN);\n+\n+\tnpc_mcam_process_mkex_cfg(npc, kex_rsp);\n+\n+done:\n+\treturn rc;\n+}\n+\n+int\n+npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow,\n+\t\t\t struct npc_parse_state *pst)\n+{\n+\tint use_ctr = (flow->ctr_id == NPC_COUNTER_NONE ? 0 : 1);\n+\tstruct npc_mcam_write_entry_req *req;\n+\tstruct mbox *mbox = npc->mbox;\n+\tstruct mbox_msghdr *rsp;\n+\tuint16_t ctr = ~(0);\n+\tint rc, idx;\n+\tint entry;\n+\n+\tPLT_SET_USED(pst);\n+\n+\tif (use_ctr) {\n+\t\trc = npc_mcam_alloc_counter(npc, &ctr);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t}\n+\n+\tentry = npc_check_preallocated_entry_cache(mbox, flow, npc);\n+\tif (entry < 0) {\n+\t\tnpc_mcam_free_counter(npc, ctr);\n+\t\treturn NPC_ERR_MCAM_ALLOC;\n+\t}\n+\n+\treq = mbox_alloc_msg_npc_mcam_write_entry(mbox);\n+\tif (req == NULL)\n+\t\treturn -ENOSPC;\n+\treq->set_cntr = use_ctr;\n+\treq->cntr = ctr;\n+\treq->entry = entry;\n+\n+\treq->intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;\n+\treq->enable_entry = 1;\n+\treq->entry_data.action = flow->npc_action;\n+\n+\t/*\n+\t * Driver sets vtag action on per interface basis, not\n+\t * per flow basis. It is a matter of how we decide to support\n+\t * this pmd specific behavior. There are two ways:\n+\t *\t1. Inherit the vtag action from the one configured\n+\t *\t   for this interface. This can be read from the\n+\t *\t   vtag_action configured for default mcam entry of\n+\t *\t   this pf_func.\n+\t *\t2. Do not support vtag action with npc_flow.\n+\t *\n+\t * Second approach is used now.\n+\t */\n+\treq->entry_data.vtag_action = 0ULL;\n+\n+\tfor (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {\n+\t\treq->entry_data.kw[idx] = flow->mcam_data[idx];\n+\t\treq->entry_data.kw_mask[idx] = flow->mcam_mask[idx];\n+\t}\n+\n+\tif (flow->nix_intf == NIX_INTF_RX) {\n+\t\treq->entry_data.kw[0] |= (uint64_t)npc->channel;\n+\t\treq->entry_data.kw_mask[0] |= (BIT_ULL(12) - 1);\n+\t} else {\n+\t\tuint16_t pf_func = (flow->npc_action >> 4) & 0xffff;\n+\n+\t\tpf_func = plt_cpu_to_be_16(pf_func);\n+\t\treq->entry_data.kw[0] |= ((uint64_t)pf_func << 32);\n+\t\treq->entry_data.kw_mask[0] |= ((uint64_t)0xffff << 32);\n+\t}\n+\n+\trc = mbox_process_msg(mbox, (void *)&rsp);\n+\tif (rc != 0)\n+\t\treturn rc;\n+\n+\tflow->mcam_id = entry;\n+\tif (use_ctr)\n+\t\tflow->ctr_id = ctr;\n+\treturn 0;\n+}\n+\n+int\n+npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)\n+{\n+\tstruct npc_mcam_read_base_rule_rsp *base_rule_rsp;\n+\t/* This is non-LDATA part in search key */\n+\tuint64_t key_data[2] = {0ULL, 0ULL};\n+\tuint64_t key_mask[2] = {0ULL, 0ULL};\n+\tint key_len, bit = 0, index, rc = 0;\n+\tint intf = pst->flow->nix_intf;\n+\tstruct mcam_entry *base_entry;\n+\tint off, idx, data_off = 0;\n+\tuint8_t lid, mask, data;\n+\tuint16_t layer_info;\n+\tuint64_t lt, flags;\n+\n+\t/* Skip till Layer A data start */\n+\twhile (bit < NPC_PARSE_KEX_S_LA_OFFSET) {\n+\t\tif (npc->keyx_supp_nmask[intf] & (1 << bit))\n+\t\t\tdata_off++;\n+\t\tbit++;\n+\t}\n+\n+\t/* Each bit represents 1 nibble */\n+\tdata_off *= 4;\n+\n+\tindex = 0;\n+\tfor (lid = 0; lid < NPC_MAX_LID; lid++) {\n+\t\t/* Offset in key */\n+\t\toff = NPC_PARSE_KEX_S_LID_OFFSET(lid);\n+\t\tlt = pst->lt[lid] & 0xf;\n+\t\tflags = pst->flags[lid] & 0xff;\n+\n+\t\t/* NPC_LAYER_KEX_S */\n+\t\tlayer_info = ((npc->keyx_supp_nmask[intf] >> off) & 0x7);\n+\n+\t\tif (layer_info) {\n+\t\t\tfor (idx = 0; idx <= 2; idx++) {\n+\t\t\t\tif (layer_info & (1 << idx)) {\n+\t\t\t\t\tif (idx == 2)\n+\t\t\t\t\t\tdata = lt;\n+\t\t\t\t\telse if (idx == 1)\n+\t\t\t\t\t\tdata = ((flags >> 4) & 0xf);\n+\t\t\t\t\telse\n+\t\t\t\t\t\tdata = (flags & 0xf);\n+\n+\t\t\t\t\tif (data_off >= 64) {\n+\t\t\t\t\t\tdata_off = 0;\n+\t\t\t\t\t\tindex++;\n+\t\t\t\t\t}\n+\t\t\t\t\tkey_data[index] |=\n+\t\t\t\t\t\t((uint64_t)data << data_off);\n+\t\t\t\t\tmask = 0xf;\n+\t\t\t\t\tif (lt == 0)\n+\t\t\t\t\t\tmask = 0;\n+\t\t\t\t\tkey_mask[index] |=\n+\t\t\t\t\t\t((uint64_t)mask << data_off);\n+\t\t\t\t\tdata_off += 4;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t/* Copy this into mcam string */\n+\tkey_len = (pst->npc->keyx_len[intf] + 7) / 8;\n+\tmemcpy(pst->flow->mcam_data, key_data, key_len);\n+\tmemcpy(pst->flow->mcam_mask, key_mask, key_len);\n+\n+\tif (pst->is_vf) {\n+\t\t(void)mbox_alloc_msg_npc_read_base_steer_rule(npc->mbox);\n+\t\trc = mbox_process_msg(npc->mbox, (void *)&base_rule_rsp);\n+\t\tif (rc) {\n+\t\t\tplt_err(\"Failed to fetch VF's base MCAM entry\");\n+\t\t\treturn rc;\n+\t\t}\n+\t\tbase_entry = &base_rule_rsp->entry_data;\n+\t\tfor (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {\n+\t\t\tpst->flow->mcam_data[idx] |= base_entry->kw[idx];\n+\t\t\tpst->flow->mcam_mask[idx] |= base_entry->kw_mask[idx];\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * Now we have mcam data and mask formatted as\n+\t * [Key_len/4 nibbles][0 or 1 nibble hole][data]\n+\t * hole is present if key_len is odd number of nibbles.\n+\t * mcam data must be split into 64 bits + 48 bits segments\n+\t * for each back W0, W1.\n+\t */\n+\n+\tif (mcam_alloc)\n+\t\treturn npc_mcam_alloc_and_write(npc, pst->flow, pst);\n+\telse\n+\t\treturn 0;\n+}\n+\n+int\n+npc_flow_free_all_resources(struct npc *npc)\n+{\n+\tstruct npc_mcam_ents_info *info;\n+\tstruct roc_npc_flow *flow;\n+\tstruct plt_bitmap *bmap;\n+\tint entry_count = 0;\n+\tint rc, idx;\n+\n+\tfor (idx = 0; idx < npc->flow_max_priority; idx++) {\n+\t\tinfo = &npc->flow_entry_info[idx];\n+\t\tentry_count += info->live_ent;\n+\t}\n+\n+\tif (entry_count == 0)\n+\t\treturn 0;\n+\n+\t/* Free all MCAM entries allocated */\n+\trc = npc_mcam_free_all_entries(npc);\n+\n+\t/* Free any MCAM counters and delete flow list */\n+\tfor (idx = 0; idx < npc->flow_max_priority; idx++) {\n+\t\twhile ((flow = TAILQ_FIRST(&npc->flow_list[idx])) != NULL) {\n+\t\t\tif (flow->ctr_id != NPC_COUNTER_NONE)\n+\t\t\t\trc |= npc_mcam_free_counter(npc, flow->ctr_id);\n+\n+\t\t\tTAILQ_REMOVE(&npc->flow_list[idx], flow, next);\n+\t\t\tplt_free(flow);\n+\t\t\tbmap = npc->live_entries[flow->priority];\n+\t\t\tplt_bitmap_clear(bmap, flow->mcam_id);\n+\t\t}\n+\t\tinfo = &npc->flow_entry_info[idx];\n+\t\tinfo->free_ent = 0;\n+\t\tinfo->live_ent = 0;\n+\t}\n+\treturn rc;\n+}\ndiff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h\nindex 185c60e..ef1e991 100644\n--- a/drivers/common/cnxk/roc_npc_priv.h\n+++ b/drivers/common/cnxk/roc_npc_priv.h\n@@ -379,6 +379,22 @@ roc_npc_to_npc_priv(struct roc_npc *npc)\n \treturn (struct npc *)npc->reserved;\n }\n \n+int npc_mcam_free_counter(struct npc *npc, uint16_t ctr_id);\n+int npc_mcam_read_counter(struct npc *npc, uint32_t ctr_id, uint64_t *count);\n+int npc_mcam_clear_counter(struct npc *npc, uint32_t ctr_id);\n+int npc_mcam_free_entry(struct npc *npc, uint32_t entry);\n+int npc_mcam_free_all_entries(struct npc *npc);\n+int npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow,\n+\t\t\t     struct npc_parse_state *pst);\n+int npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam,\n+\t\t\t struct roc_npc_flow *ref_mcam, int prio,\n+\t\t\t int *resp_count);\n+int npc_mcam_alloc_entries(struct npc *npc, int ref_mcam, int *alloc_entry,\n+\t\t\t   int req_count, int prio, int *resp_count);\n+\n+int npc_mcam_ena_dis_entry(struct npc *npc, struct roc_npc_flow *mcam,\n+\t\t\t   bool enable);\n+int npc_mcam_write_entry(struct npc *npc, struct roc_npc_flow *mcam);\n int npc_update_parse_state(struct npc_parse_state *pst,\n \t\t\t   struct npc_parse_item_info *info, int lid, int lt,\n \t\t\t   uint8_t flags);\n@@ -386,7 +402,12 @@ void npc_get_hw_supp_mask(struct npc_parse_state *pst,\n \t\t\t  struct npc_parse_item_info *info, int lid, int lt);\n int npc_parse_item_basic(const struct roc_npc_item_info *item,\n \t\t\t struct npc_parse_item_info *info);\n+int npc_mcam_fetch_kex_cfg(struct npc *npc);\n int npc_check_preallocated_entry_cache(struct mbox *mbox,\n \t\t\t\t       struct roc_npc_flow *flow,\n \t\t\t\t       struct npc *npc);\n+int npc_flow_free_all_resources(struct npc *npc);\n+int npc_program_mcam(struct npc *npc, struct npc_parse_state *pst,\n+\t\t     bool mcam_alloc);\n+uint64_t npc_get_kex_capability(struct npc *npc);\n #endif /* _ROC_NPC_PRIV_H_ */\n",
    "prefixes": [
        "42/52"
    ]
}