get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 133444,
    "url": "http://patches.dpdk.org/api/patches/133444/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20231027030001.602639-2-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": "<20231027030001.602639-2-chaoyong.he@corigine.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231027030001.602639-2-chaoyong.he@corigine.com",
    "date": "2023-10-27T02:59:38",
    "name": "[v4,01/24] common/nfp: introduce driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "7b0dabd4e17e473a5b9cb79eca9e8a6db8930180",
    "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/20231027030001.602639-2-chaoyong.he@corigine.com/mbox/",
    "series": [
        {
            "id": 30016,
            "url": "http://patches.dpdk.org/api/series/30016/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=30016",
            "date": "2023-10-27T02:59:37",
            "name": "add the NFP vDPA PMD",
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/30016/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/133444/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/133444/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 190224320F;\n\tFri, 27 Oct 2023 05:00:36 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 2F05740E68;\n\tFri, 27 Oct 2023 05:00:31 +0200 (CEST)",
            "from NAM12-DM6-obe.outbound.protection.outlook.com\n (mail-dm6nam12on2121.outbound.protection.outlook.com [40.107.243.121])\n by mails.dpdk.org (Postfix) with ESMTP id 6D58540DF6\n for <dev@dpdk.org>; Fri, 27 Oct 2023 05:00:27 +0200 (CEST)",
            "from SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5)\n by SA0PR13MB4048.namprd13.prod.outlook.com (2603:10b6:806:97::13)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6933.24; Fri, 27 Oct\n 2023 03:00:25 +0000",
            "from SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::45b3:d83c:cff2:4a1b]) by SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::45b3:d83c:cff2:4a1b%6]) with mapi id 15.20.6933.022; Fri, 27 Oct 2023\n 03:00:25 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=Pc8TElO2K4ZRu9JMW2aR8vDLfq4CQPC1s9OM8PcjOu2VnvXD7WQMofXg3QNnsxIPn3S9khV3nYBo14OswfsLmx9+ithPKiompqD3oZPO2Ab1CN31POe5LoU4pLdz6x/JXIrOR0SkmCXYRARDXUiTHl91JSdN0UZh4Wq+jL4hSSQQzVGXWGOTlUIU0PPFcwYXYkKVgctQLwnuDJzb/Qx1tWylID8RAFwe/+/vsUFQGU0i7iGW8g8wJ7lfnQt+BfzlCwoj84lvJ0bB1t/KXBK34B+El2RxNuZ2m0KsgzuGSn5TDQiR4QC7e4bH9FSY+M1nOmHvNvaduH6dvYyNkEV1uw==",
        "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=4Q9QnKwYORzPcV269h57iRczxLtSD5GDi7BNAf/pqww=;\n b=RzooYzf9ECptuQnz/mH7s8sVOik9ewr664onnr7NzFfEilf/GYDEObFIs8Nc6EZv0HYOK4t3FfmpJndde/NAQKkYpMV/YAXgUrhYVLp6WiNwRjS9gAPC6JrNv6LSLvzp+FbhjVVk3hTV+mGCNJ0eoe74oiEywT5uyN+1k5vHr5DwZzM9paqoIdgNg679udLwNTk4AhNMJeoaxEEw9eLUyWWMZ63dy1NnXf+L0zj+NkPjberbdOW/2qDLaB08e8VJ2LHqaXaUWtugfo2KcbH6rOotGN9o7e4N3EjTl/s2icSrGatURVuh2tvHrgihrtkqzzA17wprLqSA4/052UTLkg==",
        "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=4Q9QnKwYORzPcV269h57iRczxLtSD5GDi7BNAf/pqww=;\n b=trTsunXCE976g9yRLnyuRtnbkVOctRBCNZRgTMntUOztvge3MRTBKO2/qZ9FMGzmCvtEP5L8MNoAuIlTEWP8IM3ryf9Ou9GzRnQEQydd6ucPJ/UWnhEn5/g4HFBPHINbC54FoSACBFO6VUiz5LIIAAgbfkC9cGK8zA1XVu4bkbo=",
        "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, Chaoyong He <chaoyong.he@corigine.com>,\n Shujing Dong <shujing.dong@corigine.com>, Long Wu <long.wu@corigine.com>,\n Peng Zhang <peng.zhang@corigine.com>",
        "Subject": "[PATCH v4 01/24] common/nfp: introduce driver",
        "Date": "Fri, 27 Oct 2023 10:59:38 +0800",
        "Message-Id": "<20231027030001.602639-2-chaoyong.he@corigine.com>",
        "X-Mailer": "git-send-email 2.39.1",
        "In-Reply-To": "<20231027030001.602639-1-chaoyong.he@corigine.com>",
        "References": "<20231026064324.177531-1-chaoyong.he@corigine.com>\n <20231027030001.602639-1-chaoyong.he@corigine.com>",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-ClientProxiedBy": "BYAPR08CA0065.namprd08.prod.outlook.com\n (2603:10b6:a03:117::42) 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_|SA0PR13MB4048:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "c49970ca-c119-4d60-7d6f-08dbd698de27",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n jwI4PAXXwlQF18fhLBv/GvmGl4lKCXcvRHo3VHA5s93AoCKlx1ZwjGYvBKWHIn6FULO0k5SO4k5bJ5kJcd1waK+NlqHpndAGV+bwlG+hvdIGFS2+qYQawdKjRfexNaBrBovE9mcaYdVJaKymlWEIB2v9UidqBoti9HX7puk7E6GvJ/bognw7+Pxzjz7EKFpZEqWQGyebnRD5l4RGLOpb6Sb3jXMOVOa0WTLKQmk3+k358mpMDVEKHQFR5avdXbqseRVJUmpn4uFo68N/uoEQPU9gSbZNrjnwihNEqT/uGD1CV4gxfp+8K+S5zvBb3AlyiSbedyLBz2JlaAzvgJhNbsQEUHRjkdyy5V+Zr1Inrz6edBcJlaBmzSZ9589/zyYy1EnRl+Q+ZoS7sFmXK33Pfero4IEyXjWfDwSLkloGD9V/6BipOF1tCOa/18gxRDjNXhYj1zWFbnTOVq5GV43bmyLQi2uSTFojJDLq13t2tf4NCONq66VBhRQyx1UVY95QHxJ8ZcxjAxZNd3wUunZoXJByKdmlzgPwCVE7zxpyyROvUuWf7Ws4VKjzM5MF/VR1/ku2LEqeY1tCyE9R4N3DgM0PXzbLtM/HeyMYjths9WPOFU9oNQq7QqUo4ThAI4l9rHUiBl5ZjE8n8b9aBSXbW2V5ApNy5vRTqPbaJ5/qgJM=",
        "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:(13230031)(376002)(396003)(39840400004)(366004)(346002)(136003)(230922051799003)(64100799003)(186009)(1800799009)(451199024)(6512007)(6666004)(52116002)(6506007)(6486002)(86362001)(36756003)(478600001)(38100700002)(30864003)(2906002)(6916009)(41300700001)(83380400001)(1076003)(107886003)(26005)(2616005)(38350700005)(66946007)(316002)(66556008)(66476007)(4326008)(8936002)(8676002)(44832011)(5660300002)(54906003);\n DIR:OUT; SFP:1102;",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1",
        "X-MS-Exchange-AntiSpam-MessageData-0": "\n YshQtnNzyLDJPml91uGnZ2dLph/m87S0Cb+SdtdCOhDbi8gpkn4pZZQLG6RVPW99/Ywa3VkjAFZaIXsuLEdwfpoNeKbQ0T/tA2VTakJbm1c7K38ppvkGkOBLRyH56neT/aSQm2xCt8DDa7MlS7q0UacQG6OJX84uoQBRnrM2Frxovp77C35Or3aKuvWnjabVI50qRompx1LTy+KQEhCFjXs9zlA14QCLlABeDqd0TMv7VT+bCFq5b+L0CQ1WI7Hrk4JjRgsxNoshGZvhXPRFHHeJ50yr1+30WsofzFaM/6ga6iAUZPxUsFpqjeWk4jGnJ2OQS9Oo+8XjdFL5dc3t7qbjT1iXw/RUSWSyhA8WZMNUatejtykBkC4m+aUjI6RUHtO7PwIQmxj/1LsRBxymHxklW033zgNRZjmsSqUdRQKPkHR2/ukTi2crDcoYjEIVkLN5/oBogzQnl2AOAwAOV2i9KdlcKNgyoxbZeqIEk3lVGY11/rCz4/qdvnnI9ynFhbIOwrsLw1gvR6SiO7Avd+ZbBgI63AKV5ntSO8zkUbY0X6ZbdRQHQW4T2rT7MbuMvotX0tyxz+AOp23ijOKkoM0361Jf2Y9TExJIkMurg0dKgeG3FDz4e45LcklDXOL0f4S8vTlBM2CPKFQ0PUh1gIqvTKXqQGs5+JrUkL2oKNbu8Hbkzlc4AB+oByfNS+4gulfvLhIROxyXNbAL77eflClZzka4slYuSmAbg7dUZOFXctWBtfwRYVedSLWJZiu64meb7kxFJlyvY1sPXzsqhmLXR7ZbWZNt8yvOUtwt+9j6Q1pgantpKhRakGq/eSQGOnK5tCx8CydMAzqNv1herqjnETvdrKRaGhYP6Ty/GzSPPwxrl6LRRgNaVylfCFjG1uAFa4UsmJ2KiVt8jbyP+y+i93AfAwnH2jinjvH0ke9vm9srmVnmStaUYDR26ns7d8HznAalesz4ac/uBZjX42k0mZoJk29HETTPg8zh1BgHOVN+fM98PfWmL6/H23V5T71VLgexsPKYU9CNA2NnD9D5LQMbOr1vZpZj3uZSzs6B8fcyzXduIDgNPOkY+oya2+/In9xDAeH/YSprTBkRHFl6wMtZl65+b0hRdqypgBXomgIPl0LzP2k/FxbbagDzwqBzhntoEuTc1JogbA3vRuOcoI91a9GpMJ1+ztPElL9ExHK3cTueShhZy/AAnny/ZFcKqCEHO3XrMcBmRW3dxVt6GJXFgLx1TzTDP/c8YCsqVGtYM1LSUAu4J9beMcIhSVxVisA+TTmxKFJ97lpuZZnv55sR0+XIS7yNg1NU3w4n4nFBLsZzZbuDv7uzcbcdXCOC8YewaLqRoXnGBwZc+MVmuC0oqQKqOkdeB2krBogrDI5W/OI/qO9qLFThNQJz4EQYFw+CHnKx21AUu1kyTyJ3e3c4A0+yDnnvg+xEYJlo3cjufC9a+ZI8fTK9+JucnbAfzEGOHyuT9UZxTYyS3Hbz4sqdqsKkVbxS61f+XLaH2MlYbguVgqFNts3eAMUCR5+5SFnh9gqLsusgp8bSC4oLpDd9rEERDswWGQdfHEkp337igd4OVzCi2vNw0i63I6msLKuvrqywE241gQ8TrA==",
        "X-OriginatorOrg": "corigine.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n c49970ca-c119-4d60-7d6f-08dbd698de27",
        "X-MS-Exchange-CrossTenant-AuthSource": "SJ0PR13MB5545.namprd13.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Internal",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "27 Oct 2023 03:00:25.7227 (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 UYPzYnsncaP1hzXeGOnbMJqirziFoah/d08Uao+DhnESbny6XRohj3UeGKq8oMfb7FqoTcWLtx6I9ZPyUGEJuN2KzUPIm4mWHkcTGiSg3fE=",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "SA0PR13MB4048",
        "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": "A new NFP vdpa PMD will be added to support vdpa operations by NFP\nadapters.\n\nThis vdpa PMD share some logic with the net/nfp PMD. So create a new\ncommon library in drivers/common for NFP PMDs.\n\nWe import a 'nfp_class_driver' layer and which can support various\ndevice type in addition to the ethernet device.\n\nThe shared logic will move into this common library in the following\ncommits.\n\nSigned-off-by: Chaoyong He <chaoyong.he@corigine.com>\nSigned-off-by: Shujing Dong <shujing.dong@corigine.com>\nReviewed-by: Long Wu <long.wu@corigine.com>\nReviewed-by: Peng Zhang <peng.zhang@corigine.com>\n---\n .mailmap                            |   1 +\n MAINTAINERS                         |   1 +\n drivers/common/nfp/meson.build      |  14 ++\n drivers/common/nfp/nfp_common_log.c |   8 +\n drivers/common/nfp/nfp_common_log.h |  16 ++\n drivers/common/nfp/nfp_common_pci.c | 274 ++++++++++++++++++++++++++++\n drivers/common/nfp/nfp_common_pci.h |  44 +++++\n drivers/common/nfp/version.map      |   7 +\n drivers/meson.build                 |   1 +\n 9 files changed, 366 insertions(+)\n create mode 100644 drivers/common/nfp/meson.build\n create mode 100644 drivers/common/nfp/nfp_common_log.c\n create mode 100644 drivers/common/nfp/nfp_common_log.h\n create mode 100644 drivers/common/nfp/nfp_common_pci.c\n create mode 100644 drivers/common/nfp/nfp_common_pci.h\n create mode 100644 drivers/common/nfp/version.map",
    "diff": "diff --git a/.mailmap b/.mailmap\nindex 3f5bab26a8..9d9e015607 100644\n--- a/.mailmap\n+++ b/.mailmap\n@@ -1299,6 +1299,7 @@ Shuanglin Wang <shuanglin.wang@broadcom.com>\n Shuki Katzenelson <shuki@lightbitslabs.com>\n Shun Hao <shunh@nvidia.com>\n Shu Shen <shu.shen@radisys.com>\n+Shujing Dong <shujing.dong@corigine.com>\n Shweta Choudaha <shweta.choudaha@att.com>\n Shyam Kumar Shrivastav <shrivastav.shyam@gmail.com>\n Shy Shyman <shys@nvidia.com> <shys@mellanox.com>\ndiff --git a/MAINTAINERS b/MAINTAINERS\nindex 4083658697..5273ab9812 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -900,6 +900,7 @@ F: doc/guides/nics/features/nfb.ini\n \n Netronome nfp\n M: Chaoyong He <chaoyong.he@corigine.com>\n+F: drivers/common/nfp/\n F: drivers/net/nfp/\n F: doc/guides/nics/nfp.rst\n F: doc/guides/nics/features/nfp*.ini\ndiff --git a/drivers/common/nfp/meson.build b/drivers/common/nfp/meson.build\nnew file mode 100644\nindex 0000000000..cda5a930c7\n--- /dev/null\n+++ b/drivers/common/nfp/meson.build\n@@ -0,0 +1,14 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright (c) 2023 Corigine, Inc.\n+\n+if not is_linux or not dpdk_conf.get('RTE_ARCH_64')\n+    build = false\n+    reason = 'only supported on 64-bit Linux'\n+endif\n+\n+sources = files(\n+        'nfp_common_log.c',\n+        'nfp_common_pci.c',\n+)\n+\n+deps += ['bus_pci']\ndiff --git a/drivers/common/nfp/nfp_common_log.c b/drivers/common/nfp/nfp_common_log.c\nnew file mode 100644\nindex 0000000000..e69e608eb9\n--- /dev/null\n+++ b/drivers/common/nfp/nfp_common_log.c\n@@ -0,0 +1,8 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2023 Corigine, Inc.\n+ * All rights reserved.\n+ */\n+\n+#include \"nfp_common_log.h\"\n+\n+RTE_LOG_REGISTER_SUFFIX(nfp_logtype_common, common, NOTICE);\ndiff --git a/drivers/common/nfp/nfp_common_log.h b/drivers/common/nfp/nfp_common_log.h\nnew file mode 100644\nindex 0000000000..066e38e688\n--- /dev/null\n+++ b/drivers/common/nfp/nfp_common_log.h\n@@ -0,0 +1,16 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2023 Corigine, Inc.\n+ * All rights reserved.\n+ */\n+\n+#ifndef __NFP_COMMON_LOG_H__\n+#define __NFP_COMMON_LOG_H__\n+\n+#include <rte_log.h>\n+\n+extern int nfp_logtype_common;\n+#define PMD_DRV_LOG(level, fmt, args...) \\\n+\trte_log(RTE_LOG_ ## level, nfp_logtype_common, \\\n+\t\t\t\"%s(): \" fmt \"\\n\", __func__, ## args)\n+\n+#endif/* __NFP_COMMON_LOG_H__ */\ndiff --git a/drivers/common/nfp/nfp_common_pci.c b/drivers/common/nfp/nfp_common_pci.c\nnew file mode 100644\nindex 0000000000..65f189b05e\n--- /dev/null\n+++ b/drivers/common/nfp/nfp_common_pci.c\n@@ -0,0 +1,274 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2023 Corigine, Inc.\n+ * All rights reserved.\n+ */\n+\n+#include \"nfp_common_pci.h\"\n+\n+#include <string.h>\n+\n+#include <rte_class.h>\n+#include <rte_devargs.h>\n+#include <rte_kvargs.h>\n+\n+#include \"nfp_common_log.h\"\n+\n+/* Reported driver name. */\n+#define NFP_PCI_DRIVER_NAME \"nfp_common_pci\"\n+\n+static struct rte_pci_driver nfp_common_pci_driver;\n+\n+/* PCI ID table is build dynamically based on registered nfp drivers. */\n+static struct rte_pci_id *nfp_pci_id_table;\n+\n+/* Head of list of drivers. */\n+static TAILQ_HEAD(nfp_drivers, nfp_class_driver) nfp_drivers_list =\n+\t\tTAILQ_HEAD_INITIALIZER(nfp_drivers_list);\n+\n+static bool nfp_common_initialized;\n+\n+static const struct {\n+\tconst char *name;\n+\tenum nfp_class drv_class;\n+} nfp_classes[] = {\n+\t{ .name = \"eth\",      .drv_class = NFP_CLASS_ETH },\n+};\n+\n+static enum nfp_class\n+nfp_class_name_to_value(const char *class_name)\n+{\n+\tuint32_t i;\n+\n+\tfor (i = 0; i < RTE_DIM(nfp_classes); i++) {\n+\t\tif (strcmp(class_name, nfp_classes[i].name) == 0)\n+\t\t\treturn nfp_classes[i].drv_class;\n+\t}\n+\n+\treturn NFP_CLASS_INVALID;\n+}\n+\n+static uint32_t\n+nfp_pci_id_table_size_get(const struct rte_pci_id *id_table)\n+{\n+\tuint32_t table_size;\n+\n+\tif (id_table == NULL)\n+\t\treturn 0;\n+\n+\tfor (table_size = 0; id_table->vendor_id != 0; id_table++)\n+\t\ttable_size++;\n+\n+\treturn table_size;\n+}\n+\n+static bool\n+nfp_pci_id_exists(const struct rte_pci_id *id,\n+\t\tconst struct rte_pci_id *table,\n+\t\tuint32_t next_idx)\n+{\n+\tuint32_t i;\n+\n+\tif (next_idx == 0)\n+\t\treturn false;\n+\n+\tfor (i = 0; i < next_idx; i++) {\n+\t\tif (id->device_id == table[i].device_id &&\n+\t\t\t\tid->vendor_id == table[i].vendor_id &&\n+\t\t\t\tid->subsystem_vendor_id == table[i].subsystem_vendor_id &&\n+\t\t\t\tid->subsystem_device_id == table[i].subsystem_device_id)\n+\t\t\treturn true;\n+\t}\n+\n+\treturn false;\n+}\n+\n+static void\n+nfp_pci_id_insert(struct rte_pci_id *new_table,\n+\t\tuint32_t *next_idx,\n+\t\tconst struct rte_pci_id *id_table)\n+{\n+\tif (id_table == NULL)\n+\t\treturn;\n+\n+\t/* Add non duplicate entries to new table. */\n+\tfor (; id_table->vendor_id != 0; id_table++) {\n+\t\tif (!nfp_pci_id_exists(id_table, new_table, *next_idx)) {\n+\t\t\tnew_table[*next_idx] = *id_table;\n+\t\t\t(*next_idx)++;\n+\t\t}\n+\t}\n+}\n+\n+static int\n+nfp_pci_id_table_update(const struct rte_pci_id *driver_id_table)\n+{\n+\tuint32_t i = 0;\n+\tuint32_t num_ids = 0;\n+\tstruct rte_pci_id *old_table;\n+\tconst struct rte_pci_id *id_iter;\n+\tstruct rte_pci_id *updated_table;\n+\n+\told_table = nfp_pci_id_table;\n+\tif (old_table != NULL)\n+\t\tnum_ids = nfp_pci_id_table_size_get(old_table);\n+\tnum_ids += nfp_pci_id_table_size_get(driver_id_table);\n+\n+\t/* Increase size by one for the termination entry of vendor_id = 0. */\n+\tnum_ids += 1;\n+\tupdated_table = calloc(num_ids, sizeof(struct rte_pci_id));\n+\tif (updated_table == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tif (old_table == NULL) {\n+\t\t/* Copy the first driver's ID table. */\n+\t\tfor (id_iter = driver_id_table; id_iter[i].vendor_id != 0; i++)\n+\t\t\tupdated_table[i] = id_iter[i];\n+\t} else {\n+\t\t/* First copy existing table entries. */\n+\t\tfor (id_iter = old_table; id_iter[i].vendor_id != 0; i++)\n+\t\t\tupdated_table[i] = id_iter[i];\n+\t\t/* New id to be added at the end of current ID table. */\n+\t\tnfp_pci_id_insert(updated_table, &i, driver_id_table);\n+\n+\t\tfree(old_table);\n+\t}\n+\n+\t/* Terminate table with empty entry. */\n+\tupdated_table[i].vendor_id = 0;\n+\tnfp_pci_id_table = updated_table;\n+\tnfp_common_pci_driver.id_table = nfp_pci_id_table;\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_kvarg_dev_class_handler(__rte_unused const char *key,\n+\t\tconst char *class_str,\n+\t\tvoid *opaque)\n+{\n+\tenum nfp_class *dev_class = opaque;\n+\n+\tif (class_str == NULL)\n+\t\treturn *dev_class;\n+\n+\t*dev_class = nfp_class_name_to_value(class_str);\n+\n+\treturn 0;\n+}\n+\n+static enum nfp_class\n+nfp_parse_class_options(const struct rte_devargs *devargs)\n+{\n+\tstruct rte_kvargs *kvargs;\n+\tenum nfp_class dev_class = NFP_CLASS_ETH;\n+\n+\tif (devargs == NULL)\n+\t\treturn dev_class;\n+\n+\tkvargs = rte_kvargs_parse(devargs->args, NULL);\n+\tif (kvargs == NULL)\n+\t\treturn dev_class;\n+\n+\tif (rte_kvargs_count(kvargs, RTE_DEVARGS_KEY_CLASS) != 0) {\n+\t\trte_kvargs_process(kvargs, RTE_DEVARGS_KEY_CLASS,\n+\t\t\t\tnfp_kvarg_dev_class_handler, &dev_class);\n+\t}\n+\n+\trte_kvargs_free(kvargs);\n+\n+\treturn dev_class;\n+}\n+\n+static int\n+nfp_drivers_probe(struct rte_pci_device *pci_dev,\n+\t\tenum nfp_class class)\n+{\n+\tint32_t ret = 0;\n+\tstruct nfp_class_driver *driver;\n+\n+\tTAILQ_FOREACH(driver, &nfp_drivers_list, next) {\n+\t\tif (driver->drv_class != class)\n+\t\t\tcontinue;\n+\n+\t\tret = driver->probe(pci_dev);\n+\t\tif (ret < 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to load driver %s\", driver->name);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_common_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n+\t\tstruct rte_pci_device *pci_dev)\n+{\n+\tenum nfp_class class;\n+\tstruct rte_device *eal_dev = &pci_dev->device;\n+\n+\tPMD_DRV_LOG(INFO, \"probe device %s.\", eal_dev->name);\n+\n+\tclass = nfp_parse_class_options(eal_dev->devargs);\n+\tif (class == NFP_CLASS_INVALID) {\n+\t\tPMD_DRV_LOG(ERR, \"Unsupported nfp class type: %s\",\n+\t\t\t\teal_dev->devargs->args);\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\treturn nfp_drivers_probe(pci_dev, class);\n+}\n+\n+static int\n+nfp_common_pci_remove(__rte_unused struct rte_pci_device *pci_dev)\n+{\n+\treturn 0;\n+}\n+\n+static struct rte_pci_driver nfp_common_pci_driver = {\n+\t.driver = {\n+\t\t.name = NFP_PCI_DRIVER_NAME,\n+\t},\n+\t.probe = nfp_common_pci_probe,\n+\t.remove = nfp_common_pci_remove,\n+};\n+\n+static void\n+nfp_common_init(void)\n+{\n+\tconst struct rte_pci_id empty_table[] = {\n+\t\t{\n+\t\t\t.vendor_id = 0\n+\t\t},\n+\t};\n+\n+\tif (nfp_common_initialized)\n+\t\treturn;\n+\n+\t/*\n+\t * All the constructor of NFP PMDs run at same priority. So any of the PMD\n+\t * including this one can register the PCI table first. If any other\n+\t * PMD(s) have registered the PCI ID table, no need to register an empty\n+\t * default one.\n+\t */\n+\tif (nfp_pci_id_table == NULL && nfp_pci_id_table_update(empty_table) != 0)\n+\t\treturn;\n+\n+\trte_pci_register(&nfp_common_pci_driver);\n+\tnfp_common_initialized = true;\n+}\n+\n+void\n+nfp_class_driver_register(struct nfp_class_driver *driver)\n+{\n+\tnfp_common_init();\n+\n+\tif (driver->id_table != NULL) {\n+\t\tif (nfp_pci_id_table_update(driver->id_table) != 0)\n+\t\t\treturn;\n+\t}\n+\n+\tnfp_common_pci_driver.drv_flags |= driver->drv_flags;\n+\n+\tTAILQ_INSERT_TAIL(&nfp_drivers_list, driver, next);\n+}\ndiff --git a/drivers/common/nfp/nfp_common_pci.h b/drivers/common/nfp/nfp_common_pci.h\nnew file mode 100644\nindex 0000000000..21465fca68\n--- /dev/null\n+++ b/drivers/common/nfp/nfp_common_pci.h\n@@ -0,0 +1,44 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2023 Corigine, Inc.\n+ * All rights reserved.\n+ */\n+\n+#ifndef __NFP_COMMON_PCI_H__\n+#define __NFP_COMMON_PCI_H__\n+\n+#include <bus_pci_driver.h>\n+\n+/* Initialization function for the driver called during device probing. */\n+typedef int (nfp_class_driver_probe_t)(struct rte_pci_device *dev);\n+\n+/* Uninitialization function for the driver called during hot-unplugging. */\n+typedef int (nfp_class_driver_remove_t)(struct rte_pci_device *dev);\n+\n+enum nfp_class {\n+\tNFP_CLASS_ETH,\n+\tNFP_CLASS_INVALID,\n+};\n+\n+/* Describing a nfp common class driver. */\n+struct nfp_class_driver {\n+\tTAILQ_ENTRY(nfp_class_driver) next;\n+\tenum nfp_class drv_class;            /**< Class of this driver. */\n+\tconst char *name;                    /**< Driver name. */\n+\tconst struct rte_pci_id *id_table;   /**< ID table, NULL terminated. */\n+\tuint32_t drv_flags;                  /**< Flags RTE_PCI_DRV_*. */\n+\tnfp_class_driver_probe_t *probe;     /**< Device probe function. */\n+\tnfp_class_driver_remove_t *remove;   /**< Device remove function. */\n+};\n+\n+/**\n+ * Register a nfp device driver.\n+ *\n+ * @param driver\n+ *   A pointer to a nfp_driver structure describing the driver\n+ *   to be registered.\n+ */\n+__rte_internal\n+void\n+nfp_class_driver_register(struct nfp_class_driver *driver);\n+\n+#endif /* __NFP_COMMON_PCI_H__ */\ndiff --git a/drivers/common/nfp/version.map b/drivers/common/nfp/version.map\nnew file mode 100644\nindex 0000000000..25e48c39d6\n--- /dev/null\n+++ b/drivers/common/nfp/version.map\n@@ -0,0 +1,7 @@\n+INTERNAL {\n+\tglobal:\n+\n+\tnfp_class_driver_register;\n+\n+\tlocal: *;\n+};\ndiff --git a/drivers/meson.build b/drivers/meson.build\nindex 8c775bbe62..af70ed322c 100644\n--- a/drivers/meson.build\n+++ b/drivers/meson.build\n@@ -15,6 +15,7 @@ subdirs = [\n         'common/mlx5',    # depends on bus.\n         'common/qat',     # depends on bus.\n         'common/sfc_efx', # depends on bus.\n+        'common/nfp',     # depends on bus.\n         'mempool',        # depends on common and bus.\n         'dma',            # depends on common and bus.\n         'net',            # depends on common, bus, mempool\n",
    "prefixes": [
        "v4",
        "01/24"
    ]
}