get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 118216,
    "url": "http://patches.dpdk.org/api/patches/118216/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20221014114833.13389-15-valex@nvidia.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": "<20221014114833.13389-15-valex@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20221014114833.13389-15-valex@nvidia.com",
    "date": "2022-10-14T11:48:29",
    "name": "[v3,14/18] net/mlx5/hws: Add HWS matcher object",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "925027f53543e8c87273a7fa0107cd0376c53fdf",
    "submitter": {
        "id": 2858,
        "url": "http://patches.dpdk.org/api/people/2858/?format=api",
        "name": "Alex Vesker",
        "email": "valex@nvidia.com"
    },
    "delegate": {
        "id": 3268,
        "url": "http://patches.dpdk.org/api/users/3268/?format=api",
        "username": "rasland",
        "first_name": "Raslan",
        "last_name": "Darawsheh",
        "email": "rasland@nvidia.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20221014114833.13389-15-valex@nvidia.com/mbox/",
    "series": [
        {
            "id": 25236,
            "url": "http://patches.dpdk.org/api/series/25236/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=25236",
            "date": "2022-10-14T11:48:15",
            "name": "net/mlx5: Add HW steering low level support",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/25236/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/118216/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/118216/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 98067A00C2;\n\tFri, 14 Oct 2022 13:51:16 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 4371442E00;\n\tFri, 14 Oct 2022 13:49:54 +0200 (CEST)",
            "from NAM04-MW2-obe.outbound.protection.outlook.com\n (mail-mw2nam04on2069.outbound.protection.outlook.com [40.107.101.69])\n by mails.dpdk.org (Postfix) with ESMTP id C4F3042E36\n for <dev@dpdk.org>; Fri, 14 Oct 2022 13:49:51 +0200 (CEST)",
            "from MW4PR03CA0099.namprd03.prod.outlook.com (2603:10b6:303:b7::14)\n by CY8PR12MB7363.namprd12.prod.outlook.com (2603:10b6:930:51::9) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5709.22; Fri, 14 Oct\n 2022 11:49:49 +0000",
            "from CO1NAM11FT048.eop-nam11.prod.protection.outlook.com\n (2603:10b6:303:b7:cafe::56) by MW4PR03CA0099.outlook.office365.com\n (2603:10b6:303:b7::14) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5723.26 via Frontend\n Transport; Fri, 14 Oct 2022 11:49:49 +0000",
            "from mail.nvidia.com (216.228.117.161) by\n CO1NAM11FT048.mail.protection.outlook.com (10.13.175.148) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.5723.20 via Frontend Transport; Fri, 14 Oct 2022 11:49:48 +0000",
            "from rnnvmail201.nvidia.com (10.129.68.8) by mail.nvidia.com\n (10.129.200.67) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.26; Fri, 14 Oct\n 2022 04:49:37 -0700",
            "from nvidia.com (10.126.230.35) by rnnvmail201.nvidia.com\n (10.129.68.8) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Fri, 14 Oct\n 2022 04:49:35 -0700"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=ViG9W0RJV1h+5H5apAzCMOtNvhsdIn5ZvT1XI2NIkIElusX0NZju7BP9M41rLJUFu//Iccmo6aWCuKkullYQLXUFA4ebZFxgf/vQsmoz1HeLLKZz0s1qzeMUJYYoQDgGCKp8kLQOO4hI558mhqYqmR3eX3vtBHNzeCqAt4kvvZUQwLozGEUTiei3K9lXzdd0J7UFrFuMPMWOAZbubsOD7g2Zj6bn/EWcYDgqSlB+ne0n+EfDDV332tLObGgHuZ3aiRoAkXoTCiCOVWe2uLcOBGYCv7uFDkwo5Mh6LUEaYYVnc+0NIgLK2w164ByzQIStHffjkh2eVo2df3e5GKv+Bg==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=uGA9beGv5uSn48jTLAamqzVe6RPxxTpmQzOF+HhMY+s=;\n b=PsCpabtf+w7AsYYMQ89INaO/WFn2G9GLplRhfYYzLscsEZaj2jIhVoauIQO0E+8oLprRS0XhV7OUz69NJZfaoe3sL78pk2b9E1TkSMIzodm/RNMX4cNowK/2DKejuXNAapxxc5iYTJg/2a+iBgEMuF1xou5hecMaS/hTYWoMjb2gf8EYXqusAk9CpWSmqsANjt0TIIQzz76sJrSBB/cAgnt5Q7pVgboMBCnuKi3sHiStG98iqHGhGzEcbZW0w4TIQwubMe1kKYjsOXjaxUdP0lbMuxwUk4rsjcSFw1zv6fU0wjp9LMX2Mi0PAigUtfsoEHbni36oxIAkLv5ZBd1aEw==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 216.228.117.161) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com;\n dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com;\n dkim=none (message not signed); arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com;\n s=selector2;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=uGA9beGv5uSn48jTLAamqzVe6RPxxTpmQzOF+HhMY+s=;\n b=LTOrOMXB3w531B+Q+7ue6AS67etIgYK4X23WmDlzf2kk8sjB6jtXwzFKgLWnjybBHhhrzRQKyyAjI1yRMB4Rf3AD2NwoJ5Lq0mNWKnRW5dcAE+TEgR0w2banV0gOngKtyhAqWllzqV/U9hq37kurpiyyuf9WamykbMGprIDJ4DrQrNGPItU0xtcdLg5GIRjJrtbIUyGFV/PWKW7RR3rZ3jENKiMV/c121/GE0PxgXp/7HGmFewoe3nRmedHeyFX0CUgeF54MsOgys+fL3fCICAkM8N7xPiIYlKV+73j6qPfqdB2IiwHqplXg0Hf672v7lTxUetvys5x8vLzhxWHCOQ==",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 216.228.117.161)\n smtp.mailfrom=nvidia.com;\n dkim=none (message not signed)\n header.d=none;dmarc=pass action=none header.from=nvidia.com;",
        "Received-SPF": "Pass (protection.outlook.com: domain of nvidia.com designates\n 216.228.117.161 as permitted sender) receiver=protection.outlook.com;\n client-ip=216.228.117.161; helo=mail.nvidia.com; pr=C",
        "From": "Alex Vesker <valex@nvidia.com>",
        "To": "<valex@nvidia.com>, <viacheslavo@nvidia.com>, <thomas@monjalon.net>,\n <suanmingm@nvidia.com>, Matan Azrad <matan@nvidia.com>",
        "CC": "<dev@dpdk.org>, <orika@nvidia.com>",
        "Subject": "[v3 14/18] net/mlx5/hws: Add HWS matcher object",
        "Date": "Fri, 14 Oct 2022 14:48:29 +0300",
        "Message-ID": "<20221014114833.13389-15-valex@nvidia.com>",
        "X-Mailer": "git-send-email 2.18.1",
        "In-Reply-To": "<20221014114833.13389-1-valex@nvidia.com>",
        "References": "<20220922190345.394-1-valex@nvidia.com>\n <20221014114833.13389-1-valex@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.126.230.35]",
        "X-ClientProxiedBy": "rnnvmail202.nvidia.com (10.129.68.7) To\n rnnvmail201.nvidia.com (10.129.68.8)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "CO1NAM11FT048:EE_|CY8PR12MB7363:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "abf8a4fd-cb8a-4ad1-0b68-08daadda32a8",
        "X-LD-Processed": "43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n u0T1gpABtYaYoF/ivzjIFyjXAtne6VcGQhKWBMvFSGyvCLh7IbotTL7klNjbi2emIC7oGKI1PsQ9ocnU2DuKerjOnC9G87xFL6GtZ+370RjRgjqJZNYrrauf+k05cex89gvdarbQ1/HZ9DtBisCHvcNFKHCJAhOc3OyFrljomW3FkFyWQhWCds+YNrlVRMtMCOGsOQmum7d/1tmFQCPctuGUgTeBfkjcylqecg9N1Ahrt8FzATt44YgPtOJ5Nrq0QaxNWrz0+MBfX94EJi9sClNpx06FK0rhlU2Lfj/oSC8Wpj1vNPSgM1P5bnK5kXwIBDuuTdVWTwCpwwTHUdyBaZQb6HX+OahFsFwHXBSFA+fqjNIbroCZre8HVviJkqye3wuPg5s/vEYGkMELmPAEYRIvBONDmn1pLtuK1h5FYd+8hukb/ZrOuOiMfKdIMtTHGrfOvm++DIFA5Zz44BxsBpO/eWPqVOmpW3ajH6+sLlD5SEH+LoFxXoKJSuaLX6qM4qQNyOVzEEH2Kv7O2j8KjrVI1rHXRH71LtXdudPi10U2Iq+Dlykep1CsgUo00gx2RtAVBZoUyyJMDPYZ2KxX4OjxJyA65+0jhElGu//6v8+9lcksOGYRBaZ9nGNC3MZb5iM4UEI4VPQ3aCyovAQVNc40jUZlNJVjeZ3zpn4CJWQrLjlGMolFf1/qJfmS1hEW/Do70oBtMW5zfJ+lgsJn9b8LlLrwe+R6LxmtY/oE/7pA+X5X0eDE34lmLwyemExEx9REaWaUVQ2hOrlO0xSslA==",
        "X-Forefront-Antispam-Report": "CIP:216.228.117.161; CTRY:US; LANG:en; SCL:1;\n SRV:;\n IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:dc6edge2.nvidia.com; CAT:NONE;\n SFS:(13230022)(4636009)(346002)(136003)(39860400002)(396003)(376002)(451199015)(46966006)(40470700004)(36840700001)(316002)(426003)(40480700001)(110136005)(41300700001)(55016003)(82740400003)(54906003)(6636002)(36860700001)(47076005)(8936002)(2906002)(6286002)(186003)(16526019)(26005)(107886003)(5660300002)(2616005)(30864003)(4326008)(6666004)(8676002)(7636003)(82310400005)(70586007)(36756003)(356005)(336012)(70206006)(40460700003)(7696005)(1076003)(478600001)(86362001)(83380400001);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "14 Oct 2022 11:49:48.9758 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n abf8a4fd-cb8a-4ad1-0b68-08daadda32a8",
        "X-MS-Exchange-CrossTenant-Id": "43083d15-7273-40c1-b7db-39efd9ccc17a",
        "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.117.161];\n Helo=[mail.nvidia.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n CO1NAM11FT048.eop-nam11.prod.protection.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "CY8PR12MB7363",
        "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": "HWS matcher resides under the table object, each table can\nhave multiple chained matcher with different attributes. Each\nmatcher represents a combination of match and action templates.\nEach matcher can contain multiple configurations based on the\ntemplates. Packets are steered from the table to the matcher\nand from there to other objects. The matcher allows efficent\nHW packet field matching and action execution based on the\nconfiguration done to it.\n\nSigned-off-by: Alex Vesker <valex@nvidia.com>\n---\n drivers/net/mlx5/hws/mlx5dr_matcher.c | 922 ++++++++++++++++++++++++++\n drivers/net/mlx5/hws/mlx5dr_matcher.h |  76 +++\n 2 files changed, 998 insertions(+)\n create mode 100644 drivers/net/mlx5/hws/mlx5dr_matcher.c\n create mode 100644 drivers/net/mlx5/hws/mlx5dr_matcher.h",
    "diff": "diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c\nnew file mode 100644\nindex 0000000000..835a3908eb\n--- /dev/null\n+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c\n@@ -0,0 +1,922 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2022 NVIDIA Corporation & Affiliates\n+ */\n+\n+#include \"mlx5dr_internal.h\"\n+\n+static bool mlx5dr_matcher_requires_col_tbl(uint8_t log_num_of_rules)\n+{\n+\t/* Collision table concatenation is done only for large rule tables */\n+\treturn log_num_of_rules > MLX5DR_MATCHER_ASSURED_RULES_TH;\n+}\n+\n+static uint8_t mlx5dr_matcher_rules_to_tbl_depth(uint8_t log_num_of_rules)\n+{\n+\tif (mlx5dr_matcher_requires_col_tbl(log_num_of_rules))\n+\t\treturn MLX5DR_MATCHER_ASSURED_MAIN_TBL_DEPTH;\n+\n+\t/* For small rule tables we use a single deep table to assure insertion */\n+\treturn RTE_MIN(log_num_of_rules, MLX5DR_MATCHER_ASSURED_COL_TBL_DEPTH);\n+}\n+\n+static int mlx5dr_matcher_create_end_ft(struct mlx5dr_matcher *matcher)\n+{\n+\tstruct mlx5dr_table *tbl = matcher->tbl;\n+\n+\tmatcher->end_ft = mlx5dr_table_create_default_ft(tbl);\n+\tif (!matcher->end_ft) {\n+\t\tDR_LOG(ERR, \"Failed to create matcher end flow table\");\n+\t\treturn rte_errno;\n+\t}\n+\treturn 0;\n+}\n+\n+static void mlx5dr_matcher_destroy_end_ft(struct mlx5dr_matcher *matcher)\n+{\n+\tmlx5dr_table_destroy_default_ft(matcher->tbl, matcher->end_ft);\n+}\n+\n+static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher)\n+{\n+\tstruct mlx5dr_cmd_ft_modify_attr ft_attr = {0};\n+\tstruct mlx5dr_table *tbl = matcher->tbl;\n+\tstruct mlx5dr_matcher *prev = NULL;\n+\tstruct mlx5dr_matcher *next = NULL;\n+\tstruct mlx5dr_matcher *tmp_matcher;\n+\tstruct mlx5dr_devx_obj *ft;\n+\tint ret;\n+\n+\t/* Find location in matcher list */\n+\tif (LIST_EMPTY(&tbl->head)) {\n+\t\tLIST_INSERT_HEAD(&tbl->head, matcher, next);\n+\t\tgoto connect;\n+\t}\n+\n+\tLIST_FOREACH(tmp_matcher, &tbl->head, next) {\n+\t\tif (tmp_matcher->attr.priority > matcher->attr.priority) {\n+\t\t\tnext = tmp_matcher;\n+\t\t\tbreak;\n+\t\t}\n+\t\tprev = tmp_matcher;\n+\t}\n+\n+\tif (next)\n+\t\tLIST_INSERT_BEFORE(next, matcher, next);\n+\telse\n+\t\tLIST_INSERT_AFTER(prev, matcher, next);\n+\n+connect:\n+\tft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID;\n+\tft_attr.type = tbl->fw_ft_type;\n+\n+\t/* Connect to next */\n+\tif (next) {\n+\t\tif (next->match_ste.rtc_0)\n+\t\t\tft_attr.rtc_id_0 = next->match_ste.rtc_0->id;\n+\t\tif (next->match_ste.rtc_1)\n+\t\t\tft_attr.rtc_id_1 = next->match_ste.rtc_1->id;\n+\n+\t\tret = mlx5dr_cmd_flow_table_modify(matcher->end_ft, &ft_attr);\n+\t\tif (ret) {\n+\t\t\tDR_LOG(ERR, \"Failed to connect new matcher to next RTC\");\n+\t\t\tgoto remove_from_list;\n+\t\t}\n+\t}\n+\n+\t/* Connect to previous */\n+\tft = prev ? prev->end_ft : tbl->ft;\n+\n+\tif (matcher->match_ste.rtc_0)\n+\t\tft_attr.rtc_id_0 = matcher->match_ste.rtc_0->id;\n+\tif (matcher->match_ste.rtc_1)\n+\t\tft_attr.rtc_id_1 = matcher->match_ste.rtc_1->id;\n+\n+\tret = mlx5dr_cmd_flow_table_modify(ft, &ft_attr);\n+\tif (ret) {\n+\t\tDR_LOG(ERR, \"Failed to connect new matcher to previous FT\");\n+\t\tgoto remove_from_list;\n+\t}\n+\n+\treturn 0;\n+\n+remove_from_list:\n+\tLIST_REMOVE(matcher, next);\n+\treturn ret;\n+}\n+\n+static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher)\n+{\n+\tstruct mlx5dr_cmd_ft_modify_attr ft_attr = {0};\n+\tstruct mlx5dr_table *tbl = matcher->tbl;\n+\tstruct mlx5dr_matcher *tmp_matcher;\n+\tstruct mlx5dr_devx_obj *prev_ft;\n+\tstruct mlx5dr_matcher *next;\n+\tint ret;\n+\n+\tprev_ft = matcher->tbl->ft;\n+\tLIST_FOREACH(tmp_matcher, &tbl->head, next) {\n+\t\tif (tmp_matcher == matcher)\n+\t\t\tbreak;\n+\n+\t\tprev_ft = tmp_matcher->end_ft;\n+\t}\n+\n+\tnext = matcher->next.le_next;\n+\n+\tft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID;\n+\tft_attr.type = matcher->tbl->fw_ft_type;\n+\n+\tif (next) {\n+\t\t/* Connect previous end FT to next RTC if exists */\n+\t\tif (next->match_ste.rtc_0)\n+\t\t\tft_attr.rtc_id_0 = next->match_ste.rtc_0->id;\n+\t\tif (next->match_ste.rtc_1)\n+\t\t\tft_attr.rtc_id_1 = next->match_ste.rtc_1->id;\n+\t} else {\n+\t\t/* Matcher is last, point prev end FT to default miss */\n+\t\tmlx5dr_cmd_set_attr_connect_miss_tbl(tbl->ctx,\n+\t\t\t\t\t\t     tbl->fw_ft_type,\n+\t\t\t\t\t\t     tbl->type,\n+\t\t\t\t\t\t     &ft_attr);\n+\t}\n+\n+\tret = mlx5dr_cmd_flow_table_modify(prev_ft, &ft_attr);\n+\tif (ret) {\n+\t\tDR_LOG(ERR, \"Failed to disconnect matcher\");\n+\t\treturn ret;\n+\t}\n+\n+\tLIST_REMOVE(matcher, next);\n+\n+\treturn 0;\n+}\n+\n+static void mlx5dr_matcher_set_rtc_attr_sz(struct mlx5dr_matcher *matcher,\n+\t\t\t\t\t   struct mlx5dr_cmd_rtc_create_attr *rtc_attr,\n+\t\t\t\t\t   bool is_match_rtc,\n+\t\t\t\t\t   bool is_mirror)\n+{\n+\tenum mlx5dr_matcher_flow_src flow_src = matcher->attr.optimize_flow_src;\n+\tstruct mlx5dr_pool_chunk *ste = &matcher->action_ste.ste;\n+\n+\tif ((flow_src == MLX5DR_MATCHER_FLOW_SRC_VPORT && !is_mirror) ||\n+\t    (flow_src == MLX5DR_MATCHER_FLOW_SRC_WIRE && is_mirror)) {\n+\t\t/* Optimize FDB RTC */\n+\t\trtc_attr->log_size = 0;\n+\t\trtc_attr->log_depth = 0;\n+\t} else {\n+\t\t/* Keep original values */\n+\t\trtc_attr->log_size = is_match_rtc ? matcher->attr.table.sz_row_log : ste->order;\n+\t\trtc_attr->log_depth = is_match_rtc ? matcher->attr.table.sz_col_log : 0;\n+\t}\n+}\n+\n+static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher,\n+\t\t\t\t     bool is_match_rtc)\n+{\n+\tconst char *rtc_type_str = is_match_rtc ? \"match\" : \"action\";\n+\tstruct mlx5dr_cmd_rtc_create_attr rtc_attr = {0};\n+\tstruct mlx5dr_context *ctx = matcher->tbl->ctx;\n+\tstruct mlx5dr_action_default_stc *default_stc;\n+\tstruct mlx5dr_table *tbl = matcher->tbl;\n+\tstruct mlx5dr_devx_obj **rtc_0, **rtc_1;\n+\tstruct mlx5dr_pool *ste_pool, *stc_pool;\n+\tstruct mlx5dr_devx_obj *devx_obj;\n+\tstruct mlx5dr_pool_chunk *ste;\n+\tint ret;\n+\n+\tif (is_match_rtc) {\n+\t\trtc_0 = &matcher->match_ste.rtc_0;\n+\t\trtc_1 = &matcher->match_ste.rtc_1;\n+\t\tste_pool = matcher->match_ste.pool;\n+\t\tste = &matcher->match_ste.ste;\n+\t\tste->order = matcher->attr.table.sz_col_log +\n+\t\t\t     matcher->attr.table.sz_row_log;\n+\t\trtc_attr.log_size = matcher->attr.table.sz_row_log;\n+\t\trtc_attr.log_depth = matcher->attr.table.sz_col_log;\n+\t\trtc_attr.update_index_mode = MLX5_IFC_RTC_STE_UPDATE_MODE_BY_HASH;\n+\t\t/* The first match template is used since all share the same definer */\n+\t\trtc_attr.definer_id = mlx5dr_definer_get_id(matcher->mt[0]->definer);\n+\t\trtc_attr.is_jumbo = mlx5dr_definer_is_jumbo(matcher->mt[0]->definer);\n+\t\trtc_attr.miss_ft_id = matcher->end_ft->id;\n+\t\t/* Match pool requires implicit allocation */\n+\t\tret = mlx5dr_pool_chunk_alloc(ste_pool, ste);\n+\t\tif (ret) {\n+\t\t\tDR_LOG(ERR, \"Failed to allocate STE for %s RTC\", rtc_type_str);\n+\t\t\treturn ret;\n+\t\t}\n+\t} else {\n+\t\trtc_0 = &matcher->action_ste.rtc_0;\n+\t\trtc_1 = &matcher->action_ste.rtc_1;\n+\t\tste_pool = matcher->action_ste.pool;\n+\t\tste = &matcher->action_ste.ste;\n+\t\tste->order = rte_log2_u32(matcher->action_ste.max_stes) +\n+\t\t\t     matcher->attr.table.sz_row_log;\n+\t\trtc_attr.log_size = ste->order;\n+\t\trtc_attr.log_depth = 0;\n+\t\trtc_attr.update_index_mode = MLX5_IFC_RTC_STE_UPDATE_MODE_BY_OFFSET;\n+\t\t/* The action STEs use the default always hit definer */\n+\t\trtc_attr.definer_id = ctx->caps->trivial_match_definer;\n+\t\trtc_attr.is_jumbo = false;\n+\t\trtc_attr.miss_ft_id = 0;\n+\t}\n+\n+\tdevx_obj = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste);\n+\n+\trtc_attr.pd = ctx->pd_num;\n+\trtc_attr.ste_base = devx_obj->id;\n+\trtc_attr.ste_offset = ste->offset;\n+\trtc_attr.table_type = mlx5dr_table_get_res_fw_ft_type(tbl->type, false);\n+\tmlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, is_match_rtc, false);\n+\n+\t/* STC is a single resource (devx_obj), use any STC for the ID */\n+\tstc_pool = ctx->stc_pool[tbl->type];\n+\tdefault_stc = ctx->common_res[tbl->type].default_stc;\n+\tdevx_obj = mlx5dr_pool_chunk_get_base_devx_obj(stc_pool, &default_stc->default_hit);\n+\trtc_attr.stc_base = devx_obj->id;\n+\n+\t*rtc_0 = mlx5dr_cmd_rtc_create(ctx->ibv_ctx, &rtc_attr);\n+\tif (!*rtc_0) {\n+\t\tDR_LOG(ERR, \"Failed to create matcher %s RTC\", rtc_type_str);\n+\t\tgoto free_ste;\n+\t}\n+\n+\tif (tbl->type == MLX5DR_TABLE_TYPE_FDB) {\n+\t\tdevx_obj = mlx5dr_pool_chunk_get_base_devx_obj_mirror(ste_pool, ste);\n+\t\trtc_attr.ste_base = devx_obj->id;\n+\t\trtc_attr.table_type = mlx5dr_table_get_res_fw_ft_type(tbl->type, true);\n+\n+\t\tdevx_obj = mlx5dr_pool_chunk_get_base_devx_obj_mirror(stc_pool, &default_stc->default_hit);\n+\t\trtc_attr.stc_base = devx_obj->id;\n+\t\tmlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, is_match_rtc, true);\n+\n+\t\t*rtc_1 = mlx5dr_cmd_rtc_create(ctx->ibv_ctx, &rtc_attr);\n+\t\tif (!*rtc_1) {\n+\t\t\tDR_LOG(ERR, \"Failed to create peer matcher %s RTC0\", rtc_type_str);\n+\t\t\tgoto destroy_rtc_0;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+\n+destroy_rtc_0:\n+\tmlx5dr_cmd_destroy_obj(*rtc_0);\n+free_ste:\n+\tif (is_match_rtc)\n+\t\tmlx5dr_pool_chunk_free(ste_pool, ste);\n+\treturn rte_errno;\n+}\n+\n+static void mlx5dr_matcher_destroy_rtc(struct mlx5dr_matcher *matcher,\n+\t\t\t\t       bool is_match_rtc)\n+{\n+\tstruct mlx5dr_table *tbl = matcher->tbl;\n+\tstruct mlx5dr_devx_obj *rtc_0, *rtc_1;\n+\tstruct mlx5dr_pool_chunk *ste;\n+\tstruct mlx5dr_pool *ste_pool;\n+\n+\tif (is_match_rtc) {\n+\t\trtc_0 = matcher->match_ste.rtc_0;\n+\t\trtc_1 = matcher->match_ste.rtc_1;\n+\t\tste_pool = matcher->match_ste.pool;\n+\t\tste = &matcher->match_ste.ste;\n+\t} else {\n+\t\trtc_0 = matcher->action_ste.rtc_0;\n+\t\trtc_1 = matcher->action_ste.rtc_1;\n+\t\tste_pool = matcher->action_ste.pool;\n+\t\tste = &matcher->action_ste.ste;\n+\t}\n+\n+\tif (tbl->type == MLX5DR_TABLE_TYPE_FDB)\n+\t\tmlx5dr_cmd_destroy_obj(rtc_1);\n+\n+\tmlx5dr_cmd_destroy_obj(rtc_0);\n+\tif (is_match_rtc)\n+\t\tmlx5dr_pool_chunk_free(ste_pool, ste);\n+}\n+\n+static void mlx5dr_matcher_set_pool_attr(struct mlx5dr_pool_attr *attr,\n+\t\t\t\t\t struct mlx5dr_matcher *matcher)\n+{\n+\tswitch (matcher->attr.optimize_flow_src) {\n+\tcase MLX5DR_MATCHER_FLOW_SRC_VPORT:\n+\t\tattr->opt_type = MLX5DR_POOL_OPTIMIZE_ORIG;\n+\t\tbreak;\n+\tcase MLX5DR_MATCHER_FLOW_SRC_WIRE:\n+\t\tattr->opt_type = MLX5DR_POOL_OPTIMIZE_MIRROR;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+}\n+\n+static int mlx5dr_matcher_bind_at(struct mlx5dr_matcher *matcher)\n+{\n+\tbool is_jumbo = mlx5dr_definer_is_jumbo(matcher->mt[0]->definer);\n+\tstruct mlx5dr_cmd_stc_modify_attr stc_attr = {0};\n+\tstruct mlx5dr_table *tbl = matcher->tbl;\n+\tstruct mlx5dr_pool_attr pool_attr = {0};\n+\tstruct mlx5dr_context *ctx = tbl->ctx;\n+\tuint32_t required_stes;\n+\tint i, ret;\n+\tbool valid;\n+\n+\tfor (i = 0; i < matcher->num_of_at; i++) {\n+\t\tstruct mlx5dr_action_template *at = matcher->at[i];\n+\n+\t\t/* Check if action combinabtion is valid */\n+\t\tvalid = mlx5dr_action_check_combo(at->action_type_arr, matcher->tbl->type);\n+\t\tif (!valid) {\n+\t\t\tDR_LOG(ERR, \"Invalid combination in action template %d\", i);\n+\t\t\treturn rte_errno;\n+\t\t}\n+\n+\t\t/* Process action template to setters */\n+\t\tret = mlx5dr_action_template_process(at);\n+\t\tif (ret) {\n+\t\t\tDR_LOG(ERR, \"Failed to process action template %d\", i);\n+\t\t\treturn rte_errno;\n+\t\t}\n+\n+\t\trequired_stes = at->num_of_action_stes - (!is_jumbo || at->only_term);\n+\t\tmatcher->action_ste.max_stes = RTE_MAX(matcher->action_ste.max_stes, required_stes);\n+\n+\t\t/* Future: Optimize reparse */\n+\t}\n+\n+\t/* There are no additioanl STEs required for matcher */\n+\tif (!matcher->action_ste.max_stes)\n+\t\treturn 0;\n+\n+\t/* Allocate action STE mempool */\n+\tpool_attr.table_type = tbl->type;\n+\tpool_attr.pool_type = MLX5DR_POOL_TYPE_STE;\n+\tpool_attr.flags = MLX5DR_POOL_FLAGS_FOR_STE_ACTION_POOL;\n+\tpool_attr.alloc_log_sz = rte_log2_u32(matcher->action_ste.max_stes) +\n+\t\t\t\t matcher->attr.table.sz_row_log;\n+\tmlx5dr_matcher_set_pool_attr(&pool_attr, matcher);\n+\tmatcher->action_ste.pool = mlx5dr_pool_create(ctx, &pool_attr);\n+\tif (!matcher->action_ste.pool) {\n+\t\tDR_LOG(ERR, \"Failed to create action ste pool\");\n+\t\treturn rte_errno;\n+\t}\n+\n+\t/* Allocate action RTC */\n+\tret = mlx5dr_matcher_create_rtc(matcher, false);\n+\tif (ret) {\n+\t\tDR_LOG(ERR, \"Failed to create action RTC\");\n+\t\tgoto free_ste_pool;\n+\t}\n+\n+\t/* Allocate STC for jumps to STE */\n+\tstc_attr.action_offset = MLX5DR_ACTION_OFFSET_HIT;\n+\tstc_attr.action_type = MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE;\n+\tstc_attr.ste_table.ste = matcher->action_ste.ste;\n+\tstc_attr.ste_table.ste_pool = matcher->action_ste.pool;\n+\tstc_attr.ste_table.match_definer_id = ctx->caps->trivial_match_definer;\n+\n+\tret = mlx5dr_action_alloc_single_stc(ctx, &stc_attr, tbl->type,\n+\t\t\t\t\t     &matcher->action_ste.stc);\n+\tif (ret) {\n+\t\tDR_LOG(ERR, \"Failed to create action jump to table STC\");\n+\t\tgoto free_rtc;\n+\t}\n+\n+\treturn 0;\n+\n+free_rtc:\n+\tmlx5dr_matcher_destroy_rtc(matcher, false);\n+free_ste_pool:\n+\tmlx5dr_pool_destroy(matcher->action_ste.pool);\n+\treturn rte_errno;\n+}\n+\n+static void mlx5dr_matcher_unbind_at(struct mlx5dr_matcher *matcher)\n+{\n+\tstruct mlx5dr_table *tbl = matcher->tbl;\n+\n+\tif (!matcher->action_ste.max_stes)\n+\t\treturn;\n+\n+\tmlx5dr_action_free_single_stc(tbl->ctx, tbl->type, &matcher->action_ste.stc);\n+\tmlx5dr_matcher_destroy_rtc(matcher, false);\n+\tmlx5dr_pool_destroy(matcher->action_ste.pool);\n+}\n+\n+static int mlx5dr_matcher_bind_mt(struct mlx5dr_matcher *matcher)\n+{\n+\tstruct mlx5dr_context *ctx = matcher->tbl->ctx;\n+\tstruct mlx5dr_pool_attr pool_attr = {0};\n+\tint i, created = 0;\n+\tint ret = -1;\n+\n+\tfor (i = 0; i < matcher->num_of_mt; i++) {\n+\t\t/* Get a definer for each match template */\n+\t\tret = mlx5dr_definer_get(ctx, matcher->mt[i]);\n+\t\tif (ret)\n+\t\t\tgoto definer_put;\n+\n+\t\tcreated++;\n+\n+\t\t/* Verify all templates produce the same definer */\n+\t\tif (i == 0)\n+\t\t\tcontinue;\n+\n+\t\tret = mlx5dr_definer_compare(matcher->mt[i]->definer,\n+\t\t\t\t\t     matcher->mt[i - 1]->definer);\n+\t\tif (ret) {\n+\t\t\tDR_LOG(ERR, \"Match templates cannot be used on the same matcher\");\n+\t\t\trte_errno = ENOTSUP;\n+\t\t\tgoto definer_put;\n+\t\t}\n+\t}\n+\n+\t/* Create an STE pool per matcher*/\n+\tpool_attr.pool_type = MLX5DR_POOL_TYPE_STE;\n+\tpool_attr.flags = MLX5DR_POOL_FLAGS_FOR_MATCHER_STE_POOL;\n+\tpool_attr.table_type = matcher->tbl->type;\n+\tpool_attr.alloc_log_sz = matcher->attr.table.sz_col_log +\n+\t\t\t\t matcher->attr.table.sz_row_log;\n+\tmlx5dr_matcher_set_pool_attr(&pool_attr, matcher);\n+\n+\tmatcher->match_ste.pool = mlx5dr_pool_create(ctx, &pool_attr);\n+\tif (!matcher->match_ste.pool) {\n+\t\tDR_LOG(ERR, \"Failed to allocate matcher STE pool\");\n+\t\tgoto definer_put;\n+\t}\n+\n+\treturn 0;\n+\n+definer_put:\n+\twhile (created--)\n+\t\tmlx5dr_definer_put(matcher->mt[created]);\n+\n+\treturn ret;\n+}\n+\n+static void mlx5dr_matcher_unbind_mt(struct mlx5dr_matcher *matcher)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < matcher->num_of_mt; i++)\n+\t\tmlx5dr_definer_put(matcher->mt[i]);\n+\n+\tmlx5dr_pool_destroy(matcher->match_ste.pool);\n+}\n+\n+static int\n+mlx5dr_matcher_process_attr(struct mlx5dr_cmd_query_caps *caps,\n+\t\t\t    struct mlx5dr_matcher *matcher,\n+\t\t\t    bool is_root)\n+{\n+\tstruct mlx5dr_matcher_attr *attr = &matcher->attr;\n+\n+\tif (matcher->tbl->type != MLX5DR_TABLE_TYPE_FDB  && attr->optimize_flow_src) {\n+\t\tDR_LOG(ERR, \"NIC domain doesn't support flow_src\");\n+\t\tgoto not_supported;\n+\t}\n+\n+\tif (is_root) {\n+\t\tif (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_RULE) {\n+\t\t\tDR_LOG(ERR, \"Root matcher supports only rule resource mode\");\n+\t\t\tgoto not_supported;\n+\t\t}\n+\t\tif (attr->optimize_flow_src) {\n+\t\t\tDR_LOG(ERR, \"Root matcher can't specify FDB direction\");\n+\t\t\tgoto not_supported;\n+\t\t}\n+\t\treturn 0;\n+\t}\n+\n+\t/* Convert number of rules to the required depth */\n+\tif (attr->mode == MLX5DR_MATCHER_RESOURCE_MODE_RULE)\n+\t\tattr->table.sz_col_log = mlx5dr_matcher_rules_to_tbl_depth(attr->rule.num_log);\n+\n+\tif (attr->table.sz_col_log > caps->rtc_log_depth_max) {\n+\t\tDR_LOG(ERR, \"Matcher depth exceeds limit %d\", caps->rtc_log_depth_max);\n+\t\tgoto not_supported;\n+\t}\n+\n+\tif (attr->table.sz_col_log + attr->table.sz_row_log > caps->ste_alloc_log_max) {\n+\t\tDR_LOG(ERR, \"Total matcher size exceeds limit %d\", caps->ste_alloc_log_max);\n+\t\tgoto not_supported;\n+\t}\n+\n+\tif (attr->table.sz_col_log + attr->table.sz_row_log < caps->ste_alloc_log_gran) {\n+\t\tDR_LOG(ERR, \"Total matcher size below limit %d\", caps->ste_alloc_log_gran);\n+\t\tgoto not_supported;\n+\t}\n+\n+\treturn 0;\n+\n+not_supported:\n+\trte_errno = EOPNOTSUPP;\n+\treturn rte_errno;\n+}\n+\n+static int mlx5dr_matcher_create_and_connect(struct mlx5dr_matcher *matcher)\n+{\n+\tint ret;\n+\n+\t/* Select and create the definers for current matcher */\n+\tret = mlx5dr_matcher_bind_mt(matcher);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Calculate and verify action combination */\n+\tret = mlx5dr_matcher_bind_at(matcher);\n+\tif (ret)\n+\t\tgoto unbind_mt;\n+\n+\t/* Create matcher end flow table anchor */\n+\tret = mlx5dr_matcher_create_end_ft(matcher);\n+\tif (ret)\n+\t\tgoto unbind_at;\n+\n+\t/* Allocate the RTC for the new matcher */\n+\tret = mlx5dr_matcher_create_rtc(matcher, true);\n+\tif (ret)\n+\t\tgoto destroy_end_ft;\n+\n+\t/* Connect the matcher to the matcher list */\n+\tret = mlx5dr_matcher_connect(matcher);\n+\tif (ret)\n+\t\tgoto destroy_rtc;\n+\n+\treturn 0;\n+\n+destroy_rtc:\n+\tmlx5dr_matcher_destroy_rtc(matcher, true);\n+destroy_end_ft:\n+\tmlx5dr_matcher_destroy_end_ft(matcher);\n+unbind_at:\n+\tmlx5dr_matcher_unbind_at(matcher);\n+unbind_mt:\n+\tmlx5dr_matcher_unbind_mt(matcher);\n+\treturn ret;\n+}\n+\n+static void mlx5dr_matcher_destroy_and_disconnect(struct mlx5dr_matcher *matcher)\n+{\n+\tmlx5dr_matcher_disconnect(matcher);\n+\tmlx5dr_matcher_destroy_rtc(matcher, true);\n+\tmlx5dr_matcher_destroy_end_ft(matcher);\n+\tmlx5dr_matcher_unbind_at(matcher);\n+\tmlx5dr_matcher_unbind_mt(matcher);\n+}\n+\n+static int\n+mlx5dr_matcher_create_col_matcher(struct mlx5dr_matcher *matcher)\n+{\n+\tstruct mlx5dr_context *ctx = matcher->tbl->ctx;\n+\tstruct mlx5dr_matcher *col_matcher;\n+\tint ret;\n+\n+\tif (matcher->attr.mode != MLX5DR_MATCHER_RESOURCE_MODE_RULE)\n+\t\treturn 0;\n+\n+\tif (!mlx5dr_matcher_requires_col_tbl(matcher->attr.rule.num_log))\n+\t\treturn 0;\n+\n+\tcol_matcher = simple_calloc(1, sizeof(*matcher));\n+\tif (!col_matcher) {\n+\t\trte_errno = ENOMEM;\n+\t\treturn rte_errno;\n+\t}\n+\n+\tcol_matcher->tbl = matcher->tbl;\n+\tcol_matcher->num_of_mt = matcher->num_of_mt;\n+\tmemcpy(col_matcher->mt, matcher->mt, matcher->num_of_mt * sizeof(*matcher->mt));\n+\tcol_matcher->num_of_at = matcher->num_of_at;\n+\tmemcpy(col_matcher->at, matcher->at, matcher->num_of_at * sizeof(*matcher->at));\n+\n+\tcol_matcher->attr.priority = matcher->attr.priority;\n+\tcol_matcher->attr.mode = MLX5DR_MATCHER_RESOURCE_MODE_HTABLE;\n+\tcol_matcher->attr.optimize_flow_src = matcher->attr.optimize_flow_src;\n+\tcol_matcher->attr.table.sz_row_log = matcher->attr.rule.num_log;\n+\tcol_matcher->attr.table.sz_col_log = MLX5DR_MATCHER_ASSURED_COL_TBL_DEPTH;\n+\tif (col_matcher->attr.table.sz_row_log > MLX5DR_MATCHER_ASSURED_ROW_RATIO)\n+\t\tcol_matcher->attr.table.sz_row_log -= MLX5DR_MATCHER_ASSURED_ROW_RATIO;\n+\n+\tret = mlx5dr_matcher_process_attr(ctx->caps, col_matcher, false);\n+\tif (ret)\n+\t\tgoto free_col_matcher;\n+\n+\tret = mlx5dr_matcher_create_and_connect(col_matcher);\n+\tif (ret)\n+\t\tgoto free_col_matcher;\n+\n+\tmatcher->col_matcher = col_matcher;\n+\n+\treturn 0;\n+\n+free_col_matcher:\n+\tsimple_free(col_matcher);\n+\tDR_LOG(ERR, \"Failed to create assured collision matcher\");\n+\treturn ret;\n+}\n+\n+static void\n+mlx5dr_matcher_destroy_col_matcher(struct mlx5dr_matcher *matcher)\n+{\n+\tif (matcher->attr.mode != MLX5DR_MATCHER_RESOURCE_MODE_RULE)\n+\t\treturn;\n+\n+\tif (matcher->col_matcher) {\n+\t\tmlx5dr_matcher_destroy_and_disconnect(matcher->col_matcher);\n+\t\tsimple_free(matcher->col_matcher);\n+\t}\n+}\n+\n+static int mlx5dr_matcher_init(struct mlx5dr_matcher *matcher)\n+{\n+\tstruct mlx5dr_context *ctx = matcher->tbl->ctx;\n+\tint ret;\n+\n+\tpthread_spin_lock(&ctx->ctrl_lock);\n+\n+\t/* Allocate matcher resource and connect to the packet pipe */\n+\tret = mlx5dr_matcher_create_and_connect(matcher);\n+\tif (ret)\n+\t\tgoto unlock_err;\n+\n+\t/* Create additional matcher for collision handling */\n+\tret = mlx5dr_matcher_create_col_matcher(matcher);\n+\tif (ret)\n+\t\tgoto destory_and_disconnect;\n+\n+\tpthread_spin_unlock(&ctx->ctrl_lock);\n+\n+\treturn 0;\n+\n+destory_and_disconnect:\n+\tmlx5dr_matcher_destroy_and_disconnect(matcher);\n+unlock_err:\n+\tpthread_spin_unlock(&ctx->ctrl_lock);\n+\treturn ret;\n+}\n+\n+static int mlx5dr_matcher_uninit(struct mlx5dr_matcher *matcher)\n+{\n+\tstruct mlx5dr_context *ctx = matcher->tbl->ctx;\n+\n+\tpthread_spin_lock(&ctx->ctrl_lock);\n+\tmlx5dr_matcher_destroy_col_matcher(matcher);\n+\tmlx5dr_matcher_destroy_and_disconnect(matcher);\n+\tpthread_spin_unlock(&ctx->ctrl_lock);\n+\n+\treturn 0;\n+}\n+\n+static int mlx5dr_matcher_init_root(struct mlx5dr_matcher *matcher)\n+{\n+\tenum mlx5dr_table_type type = matcher->tbl->type;\n+\tstruct mlx5dr_context *ctx = matcher->tbl->ctx;\n+\tstruct mlx5dv_flow_matcher_attr attr = {0};\n+\tstruct mlx5dv_flow_match_parameters *mask;\n+\tstruct mlx5_flow_attr flow_attr = {0};\n+\tenum mlx5dv_flow_table_type ft_type;\n+\tstruct rte_flow_error rte_error;\n+\tuint8_t match_criteria;\n+\tint ret;\n+\n+\tswitch (type) {\n+\tcase MLX5DR_TABLE_TYPE_NIC_RX:\n+\t\tft_type = MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX;\n+\t\tbreak;\n+\tcase MLX5DR_TABLE_TYPE_NIC_TX:\n+\t\tft_type = MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX;\n+\t\tbreak;\n+\tcase MLX5DR_TABLE_TYPE_FDB:\n+\t\tft_type = MLX5_IB_UAPI_FLOW_TABLE_TYPE_FDB;\n+\t\tbreak;\n+\tdefault:\n+\t\tassert(0);\n+\t\tbreak;\n+\t}\n+\n+\tif (matcher->attr.priority > UINT16_MAX) {\n+\t\tDR_LOG(ERR, \"Root matcher priority exceeds allowed limit\");\n+\t\trte_errno = EINVAL;\n+\t\treturn rte_errno;\n+\t}\n+\n+\tmask = simple_calloc(1, MLX5_ST_SZ_BYTES(fte_match_param) +\n+\t\t\t     offsetof(struct mlx5dv_flow_match_parameters, match_buf));\n+\tif (!mask) {\n+\t\trte_errno = ENOMEM;\n+\t\treturn rte_errno;\n+\t}\n+\n+\tflow_attr.tbl_type = type;\n+\n+\t/* On root table matcher, only a single match template is supported */\n+\tret = flow_dv_translate_items_hws(matcher->mt[0]->items,\n+\t\t\t\t\t  &flow_attr, mask->match_buf,\n+\t\t\t\t\t  MLX5_SET_MATCHER_HS_M, NULL,\n+\t\t\t\t\t  &match_criteria,\n+\t\t\t\t\t  &rte_error);\n+\tif (ret) {\n+\t\tDR_LOG(ERR, \"Failed to convert items to PRM [%s]\", rte_error.message);\n+\t\tgoto free_mask;\n+\t}\n+\n+\tmask->match_sz = MLX5_ST_SZ_BYTES(fte_match_param);\n+\tattr.match_mask = mask;\n+\tattr.match_criteria_enable = match_criteria;\n+\tattr.ft_type = ft_type;\n+\tattr.type = IBV_FLOW_ATTR_NORMAL;\n+\tattr.priority = matcher->attr.priority;\n+\tattr.comp_mask = MLX5DV_FLOW_MATCHER_MASK_FT_TYPE;\n+\n+\tmatcher->dv_matcher =\n+\t\tmlx5_glue->dv_create_flow_matcher_root(ctx->ibv_ctx, &attr);\n+\tif (!matcher->dv_matcher) {\n+\t\tDR_LOG(ERR, \"Failed to create DV flow matcher\");\n+\t\trte_errno = errno;\n+\t\tgoto free_mask;\n+\t}\n+\n+\tsimple_free(mask);\n+\n+\tpthread_spin_lock(&ctx->ctrl_lock);\n+\tLIST_INSERT_HEAD(&matcher->tbl->head, matcher, next);\n+\tpthread_spin_unlock(&ctx->ctrl_lock);\n+\n+\treturn 0;\n+\n+free_mask:\n+\tsimple_free(mask);\n+\treturn rte_errno;\n+}\n+\n+static int mlx5dr_matcher_uninit_root(struct mlx5dr_matcher *matcher)\n+{\n+\tstruct mlx5dr_context *ctx = matcher->tbl->ctx;\n+\tint ret;\n+\n+\tpthread_spin_lock(&ctx->ctrl_lock);\n+\tLIST_REMOVE(matcher, next);\n+\tpthread_spin_unlock(&ctx->ctrl_lock);\n+\n+\tret = mlx5_glue->dv_destroy_flow_matcher_root(matcher->dv_matcher);\n+\tif (ret) {\n+\t\tDR_LOG(ERR, \"Failed to Destroy DV flow matcher\");\n+\t\trte_errno = errno;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static int\n+mlx5dr_matcher_check_template(uint8_t num_of_mt, uint8_t num_of_at, bool is_root)\n+{\n+\tuint8_t max_num_of_mt;\n+\n+\tmax_num_of_mt = is_root ?\n+\t\tMLX5DR_MATCHER_MAX_MT_ROOT :\n+\t\tMLX5DR_MATCHER_MAX_MT;\n+\n+\tif (!num_of_mt || !num_of_at) {\n+\t\tDR_LOG(ERR, \"Number of action/match template cannot be zero\");\n+\t\tgoto out_not_sup;\n+\t}\n+\n+\tif (num_of_at > MLX5DR_MATCHER_MAX_AT) {\n+\t\tDR_LOG(ERR, \"Number of action templates exceeds limit\");\n+\t\tgoto out_not_sup;\n+\t}\n+\n+\tif (num_of_mt > max_num_of_mt) {\n+\t\tDR_LOG(ERR, \"Number of match templates exceeds limit\");\n+\t\tgoto out_not_sup;\n+\t}\n+\n+\treturn 0;\n+\n+out_not_sup:\n+\trte_errno = ENOTSUP;\n+\treturn rte_errno;\n+}\n+\n+struct mlx5dr_matcher *\n+mlx5dr_matcher_create(struct mlx5dr_table *tbl,\n+\t\t      struct mlx5dr_match_template *mt[],\n+\t\t      uint8_t num_of_mt,\n+\t\t      struct mlx5dr_action_template *at[],\n+\t\t      uint8_t num_of_at,\n+\t\t      struct mlx5dr_matcher_attr *attr)\n+{\n+\tbool is_root = mlx5dr_table_is_root(tbl);\n+\tstruct mlx5dr_matcher *matcher;\n+\tint ret;\n+\n+\tret = mlx5dr_matcher_check_template(num_of_mt, num_of_at, is_root);\n+\tif (ret)\n+\t\treturn NULL;\n+\n+\tmatcher = simple_calloc(1, sizeof(*matcher));\n+\tif (!matcher) {\n+\t\trte_errno = ENOMEM;\n+\t\treturn NULL;\n+\t}\n+\n+\tmatcher->tbl = tbl;\n+\tmatcher->attr = *attr;\n+\tmatcher->num_of_mt = num_of_mt;\n+\tmemcpy(matcher->mt, mt, num_of_mt * sizeof(*mt));\n+\tmatcher->num_of_at = num_of_at;\n+\tmemcpy(matcher->at, at, num_of_at * sizeof(*at));\n+\n+\tret = mlx5dr_matcher_process_attr(tbl->ctx->caps, matcher, is_root);\n+\tif (ret)\n+\t\tgoto free_matcher;\n+\n+\tif (is_root)\n+\t\tret = mlx5dr_matcher_init_root(matcher);\n+\telse\n+\t\tret = mlx5dr_matcher_init(matcher);\n+\n+\tif (ret) {\n+\t\tDR_LOG(ERR, \"Failed to initialise matcher: %d\", ret);\n+\t\tgoto free_matcher;\n+\t}\n+\n+\treturn matcher;\n+\n+free_matcher:\n+\tsimple_free(matcher);\n+\treturn NULL;\n+}\n+\n+int mlx5dr_matcher_destroy(struct mlx5dr_matcher *matcher)\n+{\n+\tif (mlx5dr_table_is_root(matcher->tbl))\n+\t\tmlx5dr_matcher_uninit_root(matcher);\n+\telse\n+\t\tmlx5dr_matcher_uninit(matcher);\n+\n+\tsimple_free(matcher);\n+\treturn 0;\n+}\n+\n+struct mlx5dr_match_template *\n+mlx5dr_match_template_create(const struct rte_flow_item items[],\n+\t\t\t     enum mlx5dr_match_template_flags flags)\n+{\n+\tstruct mlx5dr_match_template *mt;\n+\tstruct rte_flow_error error;\n+\tint ret, len;\n+\n+\tif (flags > MLX5DR_MATCH_TEMPLATE_FLAG_RELAXED_MATCH) {\n+\t\tDR_LOG(ERR, \"Unsupported match template flag provided\");\n+\t\trte_errno = EINVAL;\n+\t\treturn NULL;\n+\t}\n+\n+\tmt = simple_calloc(1, sizeof(*mt));\n+\tif (!mt) {\n+\t\tDR_LOG(ERR, \"Failed to allocate match template\");\n+\t\trte_errno = ENOMEM;\n+\t\treturn NULL;\n+\t}\n+\n+\tmt->flags = flags;\n+\n+\t/* Duplicate the user given items */\n+\tret = rte_flow_conv(RTE_FLOW_CONV_OP_PATTERN, NULL, 0, items, &error);\n+\tif (ret <= 0) {\n+\t\tDR_LOG(ERR, \"Unable to process items (%s): %s\",\n+\t\t       error.message ? error.message : \"unspecified\",\n+\t\t       strerror(rte_errno));\n+\t\tgoto free_template;\n+\t}\n+\n+\tlen = RTE_ALIGN(ret, 16);\n+\tmt->items = simple_calloc(1, len);\n+\tif (!mt->items) {\n+\t\tDR_LOG(ERR, \"Failed to allocate item copy\");\n+\t\trte_errno = ENOMEM;\n+\t\tgoto free_template;\n+\t}\n+\n+\tret = rte_flow_conv(RTE_FLOW_CONV_OP_PATTERN, mt->items, ret, items, &error);\n+\tif (ret <= 0)\n+\t\tgoto free_dst;\n+\n+\treturn mt;\n+\n+free_dst:\n+\tsimple_free(mt->items);\n+free_template:\n+\tsimple_free(mt);\n+\treturn NULL;\n+}\n+\n+int mlx5dr_match_template_destroy(struct mlx5dr_match_template *mt)\n+{\n+\tassert(!mt->refcount);\n+\tsimple_free(mt->items);\n+\tsimple_free(mt);\n+\treturn 0;\n+}\ndiff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h\nnew file mode 100644\nindex 0000000000..b7bf94762c\n--- /dev/null\n+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h\n@@ -0,0 +1,76 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2022 NVIDIA Corporation & Affiliates\n+ */\n+\n+#ifndef MLX5DR_MATCHER_H_\n+#define MLX5DR_MATCHER_H_\n+\n+/* Max supported match template */\n+#define MLX5DR_MATCHER_MAX_MT 2\n+#define MLX5DR_MATCHER_MAX_MT_ROOT 1\n+\n+/* Max supported action template */\n+#define MLX5DR_MATCHER_MAX_AT 4\n+\n+/* We calculated that concatenating a collision table to the main table with\n+ * 3% of the main table rows will be enough resources for high insertion\n+ * success probability.\n+ *\n+ * The calculation: log2(2^x * 3 / 100) = log2(2^x) + log2(3/100) = x - 5.05 ~ 5\n+ */\n+#define MLX5DR_MATCHER_ASSURED_ROW_RATIO 5\n+/* Thrashold to determine if amount of rules require a collision table */\n+#define MLX5DR_MATCHER_ASSURED_RULES_TH 10\n+/* Required depth of an assured collision table */\n+#define MLX5DR_MATCHER_ASSURED_COL_TBL_DEPTH 4\n+/* Required depth of the main large table */\n+#define MLX5DR_MATCHER_ASSURED_MAIN_TBL_DEPTH 2\n+\n+struct mlx5dr_match_template {\n+\tstruct rte_flow_item *items;\n+\tstruct mlx5dr_definer *definer;\n+\tstruct mlx5dr_definer_fc *fc;\n+\tuint32_t fc_sz;\n+\tuint64_t item_flags;\n+\tuint8_t vport_item_id;\n+\tenum mlx5dr_match_template_flags flags;\n+\tuint32_t refcount;\n+};\n+\n+struct mlx5dr_matcher_match_ste {\n+\tstruct mlx5dr_pool_chunk ste;\n+\tstruct mlx5dr_devx_obj *rtc_0;\n+\tstruct mlx5dr_devx_obj *rtc_1;\n+\tstruct mlx5dr_pool *pool;\n+};\n+\n+struct mlx5dr_matcher_action_ste {\n+\tstruct mlx5dr_pool_chunk ste;\n+\tstruct mlx5dr_pool_chunk stc;\n+\tstruct mlx5dr_devx_obj *rtc_0;\n+\tstruct mlx5dr_devx_obj *rtc_1;\n+\tstruct mlx5dr_pool *pool;\n+\tuint8_t max_stes;\n+};\n+\n+struct mlx5dr_matcher {\n+\tstruct mlx5dr_table *tbl;\n+\tstruct mlx5dr_matcher_attr attr;\n+\tstruct mlx5dv_flow_matcher *dv_matcher;\n+\tstruct mlx5dr_match_template *mt[MLX5DR_MATCHER_MAX_MT];\n+\tuint8_t num_of_mt;\n+\tstruct mlx5dr_action_template *at[MLX5DR_MATCHER_MAX_AT];\n+\tuint8_t num_of_at;\n+\tstruct mlx5dr_devx_obj *end_ft;\n+\tstruct mlx5dr_matcher *col_matcher;\n+\tstruct mlx5dr_matcher_match_ste match_ste;\n+\tstruct mlx5dr_matcher_action_ste action_ste;\n+\tLIST_ENTRY(mlx5dr_matcher) next;\n+};\n+\n+int mlx5dr_matcher_conv_items_to_prm(uint64_t *match_buf,\n+\t\t\t\t     struct rte_flow_item *items,\n+\t\t\t\t     uint8_t *match_criteria,\n+\t\t\t\t     bool is_value);\n+\n+#endif /* MLX5DR_MATCHER_H_ */\n",
    "prefixes": [
        "v3",
        "14/18"
    ]
}