get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 118679,
    "url": "http://patches.dpdk.org/api/patches/118679/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1666232391-29152-3-git-send-email-chaoyong.he@corigine.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": "<1666232391-29152-3-git-send-email-chaoyong.he@corigine.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1666232391-29152-3-git-send-email-chaoyong.he@corigine.com",
    "date": "2022-10-20T02:19:28",
    "name": "[v5,02/25] net/nfp: add the structures and functions for flow offload",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "22605e78fd39bbcced734b165606f22af9cea5f6",
    "submitter": {
        "id": 2554,
        "url": "http://patches.dpdk.org/api/people/2554/?format=api",
        "name": "Chaoyong He",
        "email": "chaoyong.he@corigine.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1666232391-29152-3-git-send-email-chaoyong.he@corigine.com/mbox/",
    "series": [
        {
            "id": 25325,
            "url": "http://patches.dpdk.org/api/series/25325/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=25325",
            "date": "2022-10-20T02:19:26",
            "name": "add the basic rte_flow offload support of nfp PMD",
            "version": 5,
            "mbox": "http://patches.dpdk.org/series/25325/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/118679/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/118679/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 3C8A4A0A02;\n\tThu, 20 Oct 2022 04:21:10 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id DA4F942C56;\n\tThu, 20 Oct 2022 04:21:04 +0200 (CEST)",
            "from NAM04-MW2-obe.outbound.protection.outlook.com\n (mail-mw2nam04on2126.outbound.protection.outlook.com [40.107.101.126])\n by mails.dpdk.org (Postfix) with ESMTP id 5C79940A7D\n for <dev@dpdk.org>; Thu, 20 Oct 2022 04:21:00 +0200 (CEST)",
            "from SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5)\n by DM4PR13MB5906.namprd13.prod.outlook.com (2603:10b6:8:4c::10) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5746.16; Thu, 20 Oct\n 2022 02:20:58 +0000",
            "from SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::7c26:1a0b:2825:6f4b]) by SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::7c26:1a0b:2825:6f4b%4]) with mapi id 15.20.5723.014; Thu, 20 Oct 2022\n 02:20:58 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=NPITQIzXM3RSiObe9Kv6NIw7/lRupRr3l/oEfGv73sXgnzjIRyi29UQbLEf+DotRj8zzX1f+hX9P1AzpG5mjGBWdrgqrKhS16/MJj06gX7dBTlRmz049a5CJ8rr8A9iD3MbL2KlOF+u7nhPhESmfCCqIH6USJ6cqv957alHWD7IKUSCwNwbeFXt+eh8/4CiHMQZlu/ZRDKCNtYUKD5lTTUKObsst3CYAPInaNEUJsrIUzda4ZQQsA2o7imcPJGdvUsmJMN1nQYBZA1d+iawWoyje+tWKtACOGD2oFPYhvSFaAxp/jTJiiA2azgLA8XIAmU2x6gGzi6pnZjrYOeLodw==",
        "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=enAN14GIsDe9ZMobDVk2JgLK8RlXo7fy318USD8ySck=;\n b=DAcnrLV6Mxx0HpVtDfi4WhUh0STfMV40qedLZ0X9dbRKikN97FDyJrdEEyurDt/6dgJcYE6uFaR5AUgBW1BNvlrJkRT91wFGqGjOaPRe/SYC7Aco7Ku1/9X3kdwhIspCITzFL66iuIyAQqyhxScH32H7KqhUyw2oe5oTo08mwpz4mP7otxsoIfVWtJyk+0CsicF54bWHi3oXTDDeZgU14H1JquU/XdTC80HmlVI3kp/A3p0egWRwcD+Sioc/Th/XLkI1M/fbC3U2GYxOxxAd46uBdvTHLHRwOXrBHoirf9o5ji6wXsAXHsMMD6icBc842VVo1ane6NEH5RhA6VTsLg==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=corigine.com; dmarc=pass action=none header.from=corigine.com;\n dkim=pass header.d=corigine.com; arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=corigine.onmicrosoft.com; s=selector2-corigine-onmicrosoft-com;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=enAN14GIsDe9ZMobDVk2JgLK8RlXo7fy318USD8ySck=;\n b=J1ZMXf82VQwxEfOQC7lfXmbZMmaVlnqMdyOoao9gB3fLrm6CCOtu6qTuKou6zww590yveE/nC8lGXLnFtA1u2GSLFWqMbmTVjvBHa85fVRoqD4103krvDtoEpp8vSRIABbSYe5FVifelJGIVk7mgXr5n/oftoZakJA7ehmDnflc=",
        "Authentication-Results": "dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=corigine.com;",
        "From": "Chaoyong He <chaoyong.he@corigine.com>",
        "To": "dev@dpdk.org",
        "Cc": "oss-drivers@corigine.com, niklas.soderlund@corigine.com,\n Chaoyong He <chaoyong.he@corigine.com>",
        "Subject": "[PATCH v5 02/25] net/nfp: add the structures and functions for flow\n offload",
        "Date": "Thu, 20 Oct 2022 10:19:28 +0800",
        "Message-Id": "<1666232391-29152-3-git-send-email-chaoyong.he@corigine.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1666232391-29152-1-git-send-email-chaoyong.he@corigine.com>",
        "References": "<1666092434-10357-1-git-send-email-chaoyong.he@corigine.com>\n <1666232391-29152-1-git-send-email-chaoyong.he@corigine.com>",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "X-ClientProxiedBy": "SI2PR02CA0048.apcprd02.prod.outlook.com\n (2603:1096:4:196::23) To SJ0PR13MB5545.namprd13.prod.outlook.com\n (2603:10b6:a03:424::5)",
        "MIME-Version": "1.0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "SJ0PR13MB5545:EE_|DM4PR13MB5906:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "400e6996-1b65-4161-0381-08dab241b97f",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n u8JAZxF3qscB6n9q8KhXv1ia/wsJceVU9APTNFBP0O9Fz9mKBGtn3MtlxBXGpctT+mfaDTqhPUKC7aqoZtlGzwT3TrUv05JF9spNfTBfRj1m5KFF479Avm4px06QrrhZOhJrQRwDNhNAgEGzE5EJBYzl07kD9fZS+lhaQSjwrP9VDbU8olDsz/gfZUhQrCx3AJsmob3BKNkAhIKhhXin0rN+D2dCWJzrBA7x43ASp4mrQDJHfMoW8N/ZCx6DvuhSnkdsnBWsOpGL04GDHkPjNv065MfG1951m2SOGKuf+nqxV2SNHgBThkqbAXJ9QhHJmdEjiaLSGA8wSl8aWnaMos32AJlLTMRuDSlu3q7Xit9dUEt4oqF9mymjQ38Vo/j+C62dUdbZg5Y6aDlzy6BgjIDR6AU9PFns1smiBSwP4M2nf3zZ4o6ovqDwpcwwAnf5r0dD+goi8BqX6enZypeznT3rTog5vI2KXb2+AXmOPlzSoA8ZeECJscoAWtCv0HUE1z9RjyImG31+pjvaePSHVWiCJ4cpv+9HbUsb8TLUfvCu/IhI0jFasi2Sy50zmUvtMLO2hcPzLbpbOOcIq8/41kDqlozrMzL9Xvq2GXWPU8TamSulXUFvwKCwlov09ttV/drZcyvO2qUA3H4NVNZYnCVcQrt+Iljq2D41wrua3TEvSazq505J3sP8RyhJMCE4b90iZ/a7CYatoE6qS8WvuAZ06zL1VwSTvd2F4A1fpoaJNk6Xb6og2wRFcBEt3qSOufbhOnrJ3h7owuQecqUG0o7ULFuOTJ25AB3orjgnRx059xJ/vaa8QrDmGI4DfGXJ",
        "X-Forefront-Antispam-Report": "CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n IPV:NLI; SFV:NSPM; H:SJ0PR13MB5545.namprd13.prod.outlook.com; PTR:; CAT:NONE;\n SFS:(13230022)(4636009)(136003)(376002)(39840400004)(346002)(396003)(366004)(451199015)(38100700002)(478600001)(38350700002)(316002)(6916009)(2906002)(186003)(66476007)(52116002)(66556008)(6666004)(66946007)(107886003)(4326008)(6506007)(2616005)(41300700001)(5660300002)(36756003)(8676002)(6486002)(8936002)(26005)(66574015)(44832011)(86362001)(30864003)(83380400001)(6512007);\n DIR:OUT; SFP:1102;",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1",
        "X-MS-Exchange-AntiSpam-MessageData-0": "=?utf-8?q?DLz2z4779iQkXx+WUorJLFcBtLa+?=\n\t=?utf-8?q?KMMQOTE+CD0dy3WCwEweJJPQlFjeGZAxudLiCSNp0uY2k5m8M0VMTN+WpEUCqk/CK?=\n\t=?utf-8?q?+PfJwbVN6jKLtSI8zWdz5ljUM9cKdwkggUpaeJGN+KOvGD06Gw5AwYKTmJTCJEOB/?=\n\t=?utf-8?q?XYL158CgneOmkKFZCs62jq3qTg7rWF3PJaYz/J7Th7WRkLP1AkcPCvE3ESg01w3VY?=\n\t=?utf-8?q?3G0d7T3ZS6eIlSEy83mOHzq84hitVQY94wQB6ofcFuxXgyA6mq55Hobo9KbVx5vrV?=\n\t=?utf-8?q?mHptkJ5whussL+iORGCIuxAmGbBwE7k9lU8XT23XZxag8TK1LHEBL1m52D9mTtkMa?=\n\t=?utf-8?q?6siM8ajkxO9pHcGG2Lj9dWckGTYHme4J4Y/C46mEM7xou7q9/VwjTxAvs2SxtKQcb?=\n\t=?utf-8?q?ZGHtjGyUtj6L/unlJiMnE6irHOxtaMz/Fl6ZzfWmd1arN8cYQhN+1lDAoCv3rX3FQ?=\n\t=?utf-8?q?5Mkb8aAAiCqQmg/CyEfdUI/9Vb2cfAHqDET6ETVKZessNf5EYP7l+aa/2MvziRYcF?=\n\t=?utf-8?q?Z0SteoXS52jLx5hrlRQQBy2OgpLLyEazTfuFWf78YNkSA46FlGVXGCUGHQq3e4DZA?=\n\t=?utf-8?q?Ix8WwYr5Y22zZQIxmlFs6dIxt+YgRHLYjMq18m6PQHvwW/A/R21ZGPBVrIgJuUcr8?=\n\t=?utf-8?q?P5dog4OHkuutcjlZ7pOvqP58E1fiLMk0CSFZ/dO27v+jjaD1lYtBJ29f6ddiC1uQZ?=\n\t=?utf-8?q?0LlLLtohrm0C80scIjJfVMgkaKTKjbLJSXHjD/Po7x9loP3BywYkHrpt46h+nMjdY?=\n\t=?utf-8?q?fyEVQJcUaLf8XzKA7jj0u8Ioouj0eFVVvlFot8NMSrfRXaabkYfh3RcdjnpSN0gev?=\n\t=?utf-8?q?J7ynYkBcd/AoMrQ3rC9ywNmJ1aeLybLDnnOg9q+IoCE0Aih9eLW7O9jb+94OkBxTH?=\n\t=?utf-8?q?n0Qh/TXFcQ5DFGRRyRzRBZ4UQu+1k/5E4fLYam8RLGzEoMQHerk+myqdDSA5iEsae?=\n\t=?utf-8?q?wJGHpDgPrIRBWuXh7TNPyvrix4n3yOx0IUp3+lw0Rjq9G0ig9Q8cQroqVfj7+Cj4K?=\n\t=?utf-8?q?6x3/DXjGDu/AoKGu1v3HzGc3+ErIvgqK6bQFZ2AZMrXRydY0BfdCwbFt9INgdQJkz?=\n\t=?utf-8?q?kA5BpF8CpAPg8F5LpAh9bIuPA79ZMn8v66lhTMSZTNPJi7TQ8FjkFbtBynGXa4TqF?=\n\t=?utf-8?q?vo+zmfsBcsttLjFMcEkQHf3HBlQd5DierHSLGXY6WVHWVy4ODLhFigrAYfp+xwmJg?=\n\t=?utf-8?q?bY5vjzJSZpfWK3F9Fm53xDtTjMnX8n41Tg9uh+MHcrRezwErhQCcIBzA/cY4NV+yZ?=\n\t=?utf-8?q?BCDQHnulUmfjoEdeJjjr/wreFg5/cFw8oIJ+bNCJfAE9c33PzBkFkTJTR98OQA9rg?=\n\t=?utf-8?q?yS64Hd8xe9BPQfGxKXb2npaA4+5oTni9w1hno2aTgdsOzJLQJRBaX/i3MXtIAFzqn?=\n\t=?utf-8?q?i9Qt87PDomtdYxRgVSkiH/26evnjJR0O/4sdZ0ehpCE+gELOYhVzuPsr+kWUiBA1O?=\n\t=?utf-8?q?HHGy6LCF6uk5fsF+QU8LARKadfPm1acnn/w6M74qt1vXU8FXeuRF0J1YjPZnb2VUi?=\n\t=?utf-8?q?TTG54Q6Go7Datnu/qnffT8aJo6kTjJBMOA=3D=3D?=",
        "X-OriginatorOrg": "corigine.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 400e6996-1b65-4161-0381-08dab241b97f",
        "X-MS-Exchange-CrossTenant-AuthSource": "SJ0PR13MB5545.namprd13.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Internal",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "20 Oct 2022 02:20:58.2817 (UTC)",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "fe128f2c-073b-4c20-818e-7246a585940c",
        "X-MS-Exchange-CrossTenant-MailboxType": "HOSTED",
        "X-MS-Exchange-CrossTenant-UserPrincipalName": "\n deemdJTclR27M1YuO2t46T9D1SIwn4SAexf6DFvsCrSERp+pd7A6b1eJNrGBE6naZdB1dALUNe8kzDS8f2huK8MwSpWieYh3PuCyva8h2DY=",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "DM4PR13MB5906",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "Add the structures and functions to process mask table, flow\ntable, and flow stats id, which are used in the rte_flow\noffload logics.\n\nSigned-off-by: Chaoyong He <chaoyong.he@corigine.com>\nReviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>\n---\n drivers/net/nfp/flower/nfp_flower.c |  11 +-\n drivers/net/nfp/flower/nfp_flower.h |   2 +\n drivers/net/nfp/meson.build         |   3 +\n drivers/net/nfp/nfp_flow.c          | 496 ++++++++++++++++++++++++++++++++++++\n drivers/net/nfp/nfp_flow.h          | 102 ++++++++\n 5 files changed, 613 insertions(+), 1 deletion(-)\n create mode 100644 drivers/net/nfp/nfp_flow.c\n create mode 100644 drivers/net/nfp/nfp_flow.h",
    "diff": "diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c\nindex 3e97f5c..168bf0c 100644\n--- a/drivers/net/nfp/flower/nfp_flower.c\n+++ b/drivers/net/nfp/flower/nfp_flower.c\n@@ -15,6 +15,7 @@\n #include \"../nfp_ctrl.h\"\n #include \"../nfp_cpp_bridge.h\"\n #include \"../nfp_rxtx.h\"\n+#include \"../nfp_flow.h\"\n #include \"../nfpcore/nfp_mip.h\"\n #include \"../nfpcore/nfp_rtsym.h\"\n #include \"../nfpcore/nfp_nsp.h\"\n@@ -1089,13 +1090,19 @@\n \n \tpf_dev->app_fw_priv = app_fw_flower;\n \n+\tret = nfp_flow_priv_init(pf_dev);\n+\tif (ret != 0) {\n+\t\tPMD_INIT_LOG(ERR, \"init flow priv failed\");\n+\t\tgoto app_cleanup;\n+\t}\n+\n \t/* Allocate memory for the PF AND ctrl vNIC here (hence the * 2) */\n \tpf_hw = rte_zmalloc_socket(\"nfp_pf_vnic\", 2 * sizeof(struct nfp_net_adapter),\n \t\t\tRTE_CACHE_LINE_SIZE, numa_node);\n \tif (pf_hw == NULL) {\n \t\tPMD_INIT_LOG(ERR, \"Could not malloc nfp pf vnic\");\n \t\tret = -ENOMEM;\n-\t\tgoto app_cleanup;\n+\t\tgoto flow_priv_cleanup;\n \t}\n \n \t/* Map the PF ctrl bar */\n@@ -1173,6 +1180,8 @@\n \tnfp_cpp_area_free(pf_dev->ctrl_area);\n vnic_cleanup:\n \trte_free(pf_hw);\n+flow_priv_cleanup:\n+\tnfp_flow_priv_uninit(pf_dev);\n app_cleanup:\n \trte_free(app_fw_flower);\n \ndiff --git a/drivers/net/nfp/flower/nfp_flower.h b/drivers/net/nfp/flower/nfp_flower.h\nindex 48f597a..b90391c 100644\n--- a/drivers/net/nfp/flower/nfp_flower.h\n+++ b/drivers/net/nfp/flower/nfp_flower.h\n@@ -51,6 +51,8 @@ struct nfp_app_fw_flower {\n \n \t/* PF representor */\n \tstruct nfp_flower_representor *pf_repr;\n+\n+\tstruct nfp_flow_priv *flow_priv;\n };\n \n int nfp_init_app_fw_flower(struct nfp_pf_dev *pf_dev);\ndiff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build\nindex 8a63979..7416fd3 100644\n--- a/drivers/net/nfp/meson.build\n+++ b/drivers/net/nfp/meson.build\n@@ -27,4 +27,7 @@ sources = files(\n         'nfp_cpp_bridge.c',\n         'nfp_ethdev_vf.c',\n         'nfp_ethdev.c',\n+        'nfp_flow.c',\n )\n+\n+deps += ['hash']\ndiff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c\nnew file mode 100644\nindex 0000000..8c36e97\n--- /dev/null\n+++ b/drivers/net/nfp/nfp_flow.c\n@@ -0,0 +1,496 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2022 Corigine, Inc.\n+ * All rights reserved.\n+ */\n+\n+#include <rte_flow_driver.h>\n+#include <rte_hash.h>\n+#include <rte_jhash.h>\n+#include <bus_pci_driver.h>\n+\n+#include \"nfp_common.h\"\n+#include \"nfp_flow.h\"\n+#include \"nfp_logs.h\"\n+#include \"flower/nfp_flower.h\"\n+#include \"nfpcore/nfp_mip.h\"\n+#include \"nfpcore/nfp_rtsym.h\"\n+\n+struct nfp_mask_id_entry {\n+\tuint32_t hash_key;\n+\tuint32_t ref_cnt;\n+\tuint8_t mask_id;\n+};\n+\n+static int\n+nfp_mask_id_alloc(struct nfp_flow_priv *priv, uint8_t *mask_id)\n+{\n+\tuint8_t temp_id;\n+\tuint8_t freed_id;\n+\tstruct circ_buf *ring;\n+\n+\t/* Checking for unallocated entries first. */\n+\tif (priv->mask_ids.init_unallocated > 0) {\n+\t\t*mask_id = priv->mask_ids.init_unallocated;\n+\t\tpriv->mask_ids.init_unallocated--;\n+\t\treturn 0;\n+\t}\n+\n+\t/* Checking if buffer is empty. */\n+\tfreed_id = NFP_FLOWER_MASK_ENTRY_RS - 1;\n+\tring = &priv->mask_ids.free_list;\n+\tif (ring->head == ring->tail) {\n+\t\t*mask_id = freed_id;\n+\t\treturn -ENOENT;\n+\t}\n+\n+\trte_memcpy(&temp_id, &ring->buf[ring->tail], NFP_FLOWER_MASK_ELEMENT_RS);\n+\t*mask_id = temp_id;\n+\n+\trte_memcpy(&ring->buf[ring->tail], &freed_id, NFP_FLOWER_MASK_ELEMENT_RS);\n+\tring->tail = (ring->tail + NFP_FLOWER_MASK_ELEMENT_RS) %\n+\t\t\t(NFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS);\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_mask_id_free(struct nfp_flow_priv *priv, uint8_t mask_id)\n+{\n+\tstruct circ_buf *ring;\n+\n+\tring = &priv->mask_ids.free_list;\n+\n+\t/* Checking if buffer is full. */\n+\tif (CIRC_SPACE(ring->head, ring->tail, NFP_FLOWER_MASK_ENTRY_RS) == 0)\n+\t\treturn -ENOBUFS;\n+\n+\trte_memcpy(&ring->buf[ring->head], &mask_id, NFP_FLOWER_MASK_ELEMENT_RS);\n+\tring->head = (ring->head + NFP_FLOWER_MASK_ELEMENT_RS) %\n+\t\t\t(NFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS);\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_mask_table_add(struct nfp_flow_priv *priv,\n+\t\tchar *mask_data,\n+\t\tuint32_t mask_len,\n+\t\tuint8_t *id)\n+{\n+\tint ret;\n+\tuint8_t mask_id;\n+\tuint32_t hash_key;\n+\tstruct nfp_mask_id_entry *mask_entry;\n+\n+\tmask_entry = rte_zmalloc(\"mask_entry\", sizeof(struct nfp_mask_id_entry), 0);\n+\tif (mask_entry == NULL) {\n+\t\tret = -ENOMEM;\n+\t\tgoto exit;\n+\t}\n+\n+\tret = nfp_mask_id_alloc(priv, &mask_id);\n+\tif (ret != 0)\n+\t\tgoto mask_entry_free;\n+\n+\thash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);\n+\tmask_entry->mask_id  = mask_id;\n+\tmask_entry->hash_key = hash_key;\n+\tmask_entry->ref_cnt  = 1;\n+\tPMD_DRV_LOG(DEBUG, \"hash_key=%#x id=%u ref=%u\", hash_key,\n+\t\t\tmask_id, mask_entry->ref_cnt);\n+\n+\tret = rte_hash_add_key_data(priv->mask_table, &hash_key, mask_entry);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Add to mask table failed.\");\n+\t\tgoto mask_id_free;\n+\t}\n+\n+\t*id = mask_id;\n+\treturn 0;\n+\n+mask_id_free:\n+\tnfp_mask_id_free(priv, mask_id);\n+mask_entry_free:\n+\trte_free(mask_entry);\n+exit:\n+\treturn ret;\n+}\n+\n+static int\n+nfp_mask_table_del(struct nfp_flow_priv *priv,\n+\t\tchar *mask_data,\n+\t\tuint32_t mask_len,\n+\t\tuint8_t id)\n+{\n+\tint ret;\n+\tuint32_t hash_key;\n+\n+\thash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);\n+\tret = rte_hash_del_key(priv->mask_table, &hash_key);\n+\tif (ret < 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Delete from mask table failed.\");\n+\t\treturn ret;\n+\t}\n+\n+\tret = nfp_mask_id_free(priv, id);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Free mask id failed.\");\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static struct nfp_mask_id_entry *\n+nfp_mask_table_search(struct nfp_flow_priv *priv,\n+\t\tchar *mask_data,\n+\t\tuint32_t mask_len)\n+{\n+\tint index;\n+\tuint32_t hash_key;\n+\tstruct nfp_mask_id_entry *entry;\n+\n+\thash_key = rte_jhash(mask_data, mask_len, priv->hash_seed);\n+\tindex = rte_hash_lookup_data(priv->mask_table, &hash_key, (void **)&entry);\n+\tif (index < 0) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Data NOT found in the mask table.\");\n+\t\treturn NULL;\n+\t}\n+\n+\treturn entry;\n+}\n+\n+__rte_unused static bool\n+nfp_check_mask_add(struct nfp_flow_priv *priv,\n+\t\tchar *mask_data,\n+\t\tuint32_t mask_len,\n+\t\tuint8_t *meta_flags,\n+\t\tuint8_t *mask_id)\n+{\n+\tint ret;\n+\tstruct nfp_mask_id_entry *mask_entry;\n+\n+\tmask_entry = nfp_mask_table_search(priv, mask_data, mask_len);\n+\tif (mask_entry == NULL) {\n+\t\t/* mask entry does not exist, let's create one */\n+\t\tret = nfp_mask_table_add(priv, mask_data, mask_len, mask_id);\n+\t\tif (ret != 0)\n+\t\t\treturn false;\n+\n+\t\t*meta_flags |= NFP_FL_META_FLAG_MANAGE_MASK;\n+\t} else {\n+\t\t/* mask entry already exist */\n+\t\tmask_entry->ref_cnt++;\n+\t\t*mask_id = mask_entry->mask_id;\n+\t}\n+\n+\treturn true;\n+}\n+\n+__rte_unused static bool\n+nfp_check_mask_remove(struct nfp_flow_priv *priv,\n+\t\tchar *mask_data,\n+\t\tuint32_t mask_len,\n+\t\tuint8_t *meta_flags)\n+{\n+\tint ret;\n+\tstruct nfp_mask_id_entry *mask_entry;\n+\n+\tmask_entry = nfp_mask_table_search(priv, mask_data, mask_len);\n+\tif (mask_entry == NULL)\n+\t\treturn false;\n+\n+\tmask_entry->ref_cnt--;\n+\tif (mask_entry->ref_cnt == 0) {\n+\t\tret = nfp_mask_table_del(priv, mask_data, mask_len,\n+\t\t\t\tmask_entry->mask_id);\n+\t\tif (ret != 0)\n+\t\t\treturn false;\n+\n+\t\trte_free(mask_entry);\n+\t\tif (meta_flags)\n+\t\t\t*meta_flags &= ~NFP_FL_META_FLAG_MANAGE_MASK;\n+\t}\n+\n+\treturn true;\n+}\n+\n+__rte_unused static int\n+nfp_flow_table_add(struct nfp_flow_priv *priv,\n+\t\tstruct rte_flow *nfp_flow)\n+{\n+\tint ret;\n+\n+\tret = rte_hash_add_key_data(priv->flow_table, &nfp_flow->hash_key, nfp_flow);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Add to flow table failed.\");\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+__rte_unused static int\n+nfp_flow_table_delete(struct nfp_flow_priv *priv,\n+\t\tstruct rte_flow *nfp_flow)\n+{\n+\tint ret;\n+\n+\tret = rte_hash_del_key(priv->flow_table, &nfp_flow->hash_key);\n+\tif (ret < 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Delete from flow table failed.\");\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+__rte_unused static struct rte_flow *\n+nfp_flow_table_search(struct nfp_flow_priv *priv,\n+\t\tstruct rte_flow *nfp_flow)\n+{\n+\tint index;\n+\tstruct rte_flow *flow_find;\n+\n+\tindex = rte_hash_lookup_data(priv->flow_table, &nfp_flow->hash_key,\n+\t\t\t(void **)&flow_find);\n+\tif (index < 0) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Data NOT found in the flow table.\");\n+\t\treturn NULL;\n+\t}\n+\n+\treturn flow_find;\n+}\n+\n+__rte_unused static struct rte_flow *\n+nfp_flow_alloc(struct nfp_fl_key_ls *key_layer)\n+{\n+\tchar *tmp;\n+\tsize_t len;\n+\tstruct rte_flow *nfp_flow;\n+\tstruct nfp_fl_payload *payload;\n+\n+\tnfp_flow = rte_zmalloc(\"nfp_flow\", sizeof(struct rte_flow), 0);\n+\tif (nfp_flow == NULL)\n+\t\tgoto exit;\n+\n+\tlen = key_layer->key_size + key_layer->key_size + key_layer->act_size;\n+\ttmp = rte_zmalloc(\"nfp_flow_payload\", len + sizeof(struct nfp_fl_rule_metadata), 0);\n+\tif (tmp == NULL)\n+\t\tgoto free_flow;\n+\n+\tnfp_flow->length = len;\n+\n+\tpayload                = &nfp_flow->payload;\n+\tpayload->meta          = (struct nfp_fl_rule_metadata *)tmp;\n+\tpayload->unmasked_data = tmp + sizeof(struct nfp_fl_rule_metadata);\n+\tpayload->mask_data     = payload->unmasked_data + key_layer->key_size;\n+\tpayload->action_data   = payload->mask_data + key_layer->key_size;\n+\n+\treturn nfp_flow;\n+\n+free_flow:\n+\trte_free(nfp_flow);\n+exit:\n+\treturn NULL;\n+}\n+\n+__rte_unused static void\n+nfp_flow_free(struct rte_flow *nfp_flow)\n+{\n+\trte_free(nfp_flow->payload.meta);\n+\trte_free(nfp_flow);\n+}\n+\n+__rte_unused static int\n+nfp_stats_id_alloc(struct nfp_flow_priv *priv, uint32_t *ctx)\n+{\n+\tstruct circ_buf *ring;\n+\tuint32_t freed_stats_id;\n+\tuint32_t temp_stats_id;\n+\n+\t/* Check for unallocated entries first. */\n+\tif (priv->stats_ids.init_unallocated > 0) {\n+\t\t*ctx = ((priv->stats_ids.init_unallocated - 1) & NFP_FL_STAT_ID_STAT) |\n+\t\t\t\t(priv->active_mem_unit & NFP_FL_STAT_ID_MU_NUM);\n+\t\tif (++priv->active_mem_unit == priv->total_mem_units) {\n+\t\t\tpriv->stats_ids.init_unallocated--;\n+\t\t\tpriv->active_mem_unit = 0;\n+\t\t}\n+\t\treturn 0;\n+\t}\n+\n+\t/* Check if buffer is empty */\n+\tring = &priv->stats_ids.free_list;\n+\tfreed_stats_id = priv->stats_ring_size;\n+\tif (ring->head == ring->tail) {\n+\t\t*ctx = freed_stats_id;\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tmemcpy(&temp_stats_id, &ring->buf[ring->tail], NFP_FL_STATS_ELEM_RS);\n+\t*ctx = temp_stats_id;\n+\tmemcpy(&ring->buf[ring->tail], &freed_stats_id, NFP_FL_STATS_ELEM_RS);\n+\tring->tail = (ring->tail + NFP_FL_STATS_ELEM_RS) %\n+\t\t\t(priv->stats_ring_size * NFP_FL_STATS_ELEM_RS);\n+\n+\treturn 0;\n+}\n+\n+__rte_unused static int\n+nfp_stats_id_free(struct nfp_flow_priv *priv, uint32_t ctx)\n+{\n+\tstruct circ_buf *ring;\n+\n+\t/* Check if buffer is full */\n+\tring = &priv->stats_ids.free_list;\n+\tif (!CIRC_SPACE(ring->head, ring->tail, priv->stats_ring_size *\n+\t\t\tNFP_FL_STATS_ELEM_RS - NFP_FL_STATS_ELEM_RS + 1))\n+\t\treturn -ENOBUFS;\n+\n+\tmemcpy(&ring->buf[ring->head], &ctx, NFP_FL_STATS_ELEM_RS);\n+\tring->head = (ring->head + NFP_FL_STATS_ELEM_RS) %\n+\t\t\t(priv->stats_ring_size * NFP_FL_STATS_ELEM_RS);\n+\n+\treturn 0;\n+}\n+\n+int\n+nfp_flow_priv_init(struct nfp_pf_dev *pf_dev)\n+{\n+\tint ret = 0;\n+\tuint64_t ctx_count;\n+\tuint64_t ctx_split;\n+\tsize_t stats_size;\n+\tstruct nfp_flow_priv *priv;\n+\tstruct nfp_app_fw_flower *app_fw_flower;\n+\n+\tstruct rte_hash_parameters mask_hash_params = {\n+\t\t.name       = \"mask_hash_table\",\n+\t\t.entries    = NFP_MASK_TABLE_ENTRIES,\n+\t\t.hash_func  = rte_jhash,\n+\t\t.socket_id  = rte_socket_id(),\n+\t\t.key_len    = sizeof(uint32_t),\n+\t\t.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,\n+\t};\n+\n+\tstruct rte_hash_parameters flow_hash_params = {\n+\t\t.name       = \"flow_hash_table\",\n+\t\t.hash_func  = rte_jhash,\n+\t\t.socket_id  = rte_socket_id(),\n+\t\t.key_len    = sizeof(uint32_t),\n+\t\t.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,\n+\t};\n+\n+\tctx_count = nfp_rtsym_read_le(pf_dev->sym_tbl,\n+\t\t\t\"CONFIG_FC_HOST_CTX_COUNT\", &ret);\n+\tif (ret < 0) {\n+\t\tPMD_INIT_LOG(ERR, \"Read CTX_COUNT from symbol table failed\");\n+\t\tgoto exit;\n+\t}\n+\n+\tctx_split = nfp_rtsym_read_le(pf_dev->sym_tbl,\n+\t\t\t\"CONFIG_FC_HOST_CTX_SPLIT\", &ret);\n+\tif (ret < 0) {\n+\t\tPMD_INIT_LOG(ERR, \"Read CTX_SPLIT from symbol table failed\");\n+\t\tgoto exit;\n+\t}\n+\n+\tpriv = rte_zmalloc(\"nfp_app_flow_priv\", sizeof(struct nfp_flow_priv), 0);\n+\tif (priv == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"nfp app flow priv creation failed\");\n+\t\tret = -ENOMEM;\n+\t\tgoto exit;\n+\t}\n+\n+\tapp_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);\n+\tapp_fw_flower->flow_priv = priv;\n+\tpriv->hash_seed = (uint32_t)rte_rand();\n+\tpriv->stats_ring_size = ctx_count;\n+\tpriv->total_mem_units = ctx_split;\n+\n+\t/* Init ring buffer and unallocated mask_ids. */\n+\tpriv->mask_ids.init_unallocated = NFP_FLOWER_MASK_ENTRY_RS - 1;\n+\tpriv->mask_ids.free_list.buf = rte_zmalloc(\"nfp_app_mask_ids\",\n+\t\t\tNFP_FLOWER_MASK_ENTRY_RS * NFP_FLOWER_MASK_ELEMENT_RS, 0);\n+\tif (priv->mask_ids.free_list.buf == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"mask id free list creation failed\");\n+\t\tret = -ENOMEM;\n+\t\tgoto free_priv;\n+\t}\n+\n+\t/* Init ring buffer and unallocated stats_ids. */\n+\tpriv->stats_ids.init_unallocated = ctx_count / ctx_split;\n+\tpriv->stats_ids.free_list.buf = rte_zmalloc(\"nfp_app_stats_ids\",\n+\t\t\tpriv->stats_ring_size * NFP_FL_STATS_ELEM_RS, 0);\n+\tif (priv->stats_ids.free_list.buf == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"stats id free list creation failed\");\n+\t\tret = -ENOMEM;\n+\t\tgoto free_mask_id;\n+\t}\n+\n+\t/* flow stats */\n+\trte_spinlock_init(&priv->stats_lock);\n+\tstats_size = (ctx_count & NFP_FL_STAT_ID_STAT) |\n+\t\t\t((ctx_split - 1) & NFP_FL_STAT_ID_MU_NUM);\n+\tPMD_INIT_LOG(INFO, \"ctx_count:%0lx, ctx_split:%0lx, stats_size:%0lx \",\n+\t\t\tctx_count, ctx_split, stats_size);\n+\tpriv->stats = rte_zmalloc(\"nfp_flow_stats\",\n+\t\t\tstats_size * sizeof(struct nfp_fl_stats), 0);\n+\tif (priv->stats == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"flow stats creation failed\");\n+\t\tret = -ENOMEM;\n+\t\tgoto free_stats_id;\n+\t}\n+\n+\t/* mask table */\n+\tmask_hash_params.hash_func_init_val = priv->hash_seed;\n+\tpriv->mask_table = rte_hash_create(&mask_hash_params);\n+\tif (priv->mask_table == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"mask hash table creation failed\");\n+\t\tret = -ENOMEM;\n+\t\tgoto free_stats;\n+\t}\n+\n+\t/* flow table */\n+\tflow_hash_params.hash_func_init_val = priv->hash_seed;\n+\tflow_hash_params.entries = ctx_count;\n+\tpriv->flow_table = rte_hash_create(&flow_hash_params);\n+\tif (priv->flow_table == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"flow hash table creation failed\");\n+\t\tret = -ENOMEM;\n+\t\tgoto free_mask_table;\n+\t}\n+\n+\treturn 0;\n+\n+free_mask_table:\n+\trte_free(priv->mask_table);\n+free_stats:\n+\trte_free(priv->stats);\n+free_stats_id:\n+\trte_free(priv->stats_ids.free_list.buf);\n+free_mask_id:\n+\trte_free(priv->mask_ids.free_list.buf);\n+free_priv:\n+\trte_free(priv);\n+exit:\n+\treturn ret;\n+}\n+\n+void\n+nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev)\n+{\n+\tstruct nfp_app_fw_flower *app_fw_flower;\n+\tstruct nfp_flow_priv *priv;\n+\n+\tapp_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);\n+\tpriv = app_fw_flower->flow_priv;\n+\n+\trte_hash_free(priv->flow_table);\n+\trte_hash_free(priv->mask_table);\n+\trte_free(priv->stats);\n+\trte_free(priv->stats_ids.free_list.buf);\n+\trte_free(priv->mask_ids.free_list.buf);\n+\trte_free(priv);\n+}\ndiff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h\nnew file mode 100644\nindex 0000000..e8fd22a\n--- /dev/null\n+++ b/drivers/net/nfp/nfp_flow.h\n@@ -0,0 +1,102 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2022 Corigine, Inc.\n+ * All rights reserved.\n+ */\n+\n+#ifndef _NFP_FLOW_H_\n+#define _NFP_FLOW_H_\n+\n+#define NFP_FL_META_FLAG_MANAGE_MASK    (1 << 7)\n+\n+#define NFP_MASK_TABLE_ENTRIES          1024\n+\n+enum nfp_flower_tun_type {\n+\tNFP_FL_TUN_NONE   = 0,\n+\tNFP_FL_TUN_GRE    = 1,\n+\tNFP_FL_TUN_VXLAN  = 2,\n+\tNFP_FL_TUN_GENEVE = 4,\n+};\n+\n+struct nfp_fl_key_ls {\n+\tuint32_t key_layer_two;\n+\tuint8_t key_layer;\n+\tint key_size;\n+\tint act_size;\n+\tuint32_t port;\n+\tuint16_t vlan;\n+\tenum nfp_flower_tun_type tun_type;\n+};\n+\n+struct nfp_fl_rule_metadata {\n+\tuint8_t key_len;\n+\tuint8_t mask_len;\n+\tuint8_t act_len;\n+\tuint8_t flags;\n+\trte_be32_t host_ctx_id;\n+\trte_be64_t host_cookie __rte_packed;\n+\trte_be64_t flow_version __rte_packed;\n+\trte_be32_t shortcut;\n+};\n+\n+struct nfp_fl_payload {\n+\tstruct nfp_fl_rule_metadata *meta;\n+\tchar *unmasked_data;\n+\tchar *mask_data;\n+\tchar *action_data;\n+};\n+\n+#define CIRC_CNT(head, tail, size)     (((head) - (tail)) & ((size) - 1))\n+#define CIRC_SPACE(head, tail, size)   CIRC_CNT((tail), ((head) + 1), (size))\n+struct circ_buf {\n+\tuint32_t head;\n+\tuint32_t tail;\n+\tchar *buf;\n+};\n+\n+#define NFP_FLOWER_MASK_ENTRY_RS        256\n+#define NFP_FLOWER_MASK_ELEMENT_RS      sizeof(uint8_t)\n+struct nfp_fl_mask_id {\n+\tstruct circ_buf free_list;\n+\tuint8_t init_unallocated;\n+};\n+\n+#define NFP_FL_STATS_ELEM_RS            sizeof(uint32_t)\n+struct nfp_fl_stats_id {\n+\tstruct circ_buf free_list;\n+\tuint32_t init_unallocated;\n+};\n+\n+#define NFP_FL_STAT_ID_MU_NUM           0xffc00000\n+#define NFP_FL_STAT_ID_STAT             0x003fffff\n+struct nfp_fl_stats {\n+\tuint64_t pkts;\n+\tuint64_t bytes;\n+};\n+\n+struct nfp_flow_priv {\n+\tuint32_t hash_seed; /**< Hash seed for hash tables in this structure. */\n+\t/* mask hash table */\n+\tstruct nfp_fl_mask_id mask_ids; /**< Entry for mask hash table */\n+\tstruct rte_hash *mask_table; /**< Hash table to store mask ids. */\n+\t/* flow hash table */\n+\tstruct rte_hash *flow_table; /**< Hash table to store flow rules. */\n+\t/* flow stats */\n+\tuint32_t active_mem_unit; /**< The size of active mem units. */\n+\tuint32_t total_mem_units; /**< The size of total mem units. */\n+\tuint32_t stats_ring_size; /**< The size of stats id ring. */\n+\tstruct nfp_fl_stats_id stats_ids; /**< The stats id ring. */\n+\tstruct nfp_fl_stats *stats; /**< Store stats of flow. */\n+\trte_spinlock_t stats_lock; /** < Lock the update of 'stats' field. */\n+};\n+\n+struct rte_flow {\n+\tstruct nfp_fl_payload payload;\n+\tsize_t length;\n+\tuint32_t hash_key;\n+\tbool install_flag;\n+};\n+\n+int nfp_flow_priv_init(struct nfp_pf_dev *pf_dev);\n+void nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev);\n+\n+#endif /* _NFP_FLOW_H_ */\n",
    "prefixes": [
        "v5",
        "02/25"
    ]
}