get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 96158,
    "url": "http://patchwork.dpdk.org/api/patches/96158/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20210721143743.24626-3-xuemingl@nvidia.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20210721143743.24626-3-xuemingl@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210721143743.24626-3-xuemingl@nvidia.com",
    "date": "2021-07-21T14:37:29",
    "name": "[v4,02/16] common/mlx5: add common device driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "ea58a8a719cb1d8fa2e5bc1407fda156b476d41f",
    "submitter": {
        "id": 1904,
        "url": "http://patchwork.dpdk.org/api/people/1904/?format=api",
        "name": "Xueming Li",
        "email": "xuemingl@nvidia.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20210721143743.24626-3-xuemingl@nvidia.com/mbox/",
    "series": [
        {
            "id": 17938,
            "url": "http://patchwork.dpdk.org/api/series/17938/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=17938",
            "date": "2021-07-21T14:37:27",
            "name": "net/mlx5: support Sub-Function",
            "version": 4,
            "mbox": "http://patchwork.dpdk.org/series/17938/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/96158/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/96158/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 A3DD2A0C51;\n\tWed, 21 Jul 2021 16:38:44 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8DD96410DA;\n\tWed, 21 Jul 2021 16:38:40 +0200 (CEST)",
            "from NAM12-MW2-obe.outbound.protection.outlook.com\n (mail-mw2nam12on2054.outbound.protection.outlook.com [40.107.244.54])\n by mails.dpdk.org (Postfix) with ESMTP id 8E4DD40F35\n for <dev@dpdk.org>; Wed, 21 Jul 2021 16:38:38 +0200 (CEST)",
            "from BN9PR03CA0643.namprd03.prod.outlook.com (2603:10b6:408:13b::18)\n by DM4PR12MB5117.namprd12.prod.outlook.com (2603:10b6:5:390::15) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4331.23; Wed, 21 Jul\n 2021 14:38:36 +0000",
            "from BN8NAM11FT019.eop-nam11.prod.protection.outlook.com\n (2603:10b6:408:13b:cafe::a6) by BN9PR03CA0643.outlook.office365.com\n (2603:10b6:408:13b::18) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4331.22 via Frontend\n Transport; Wed, 21 Jul 2021 14:38:36 +0000",
            "from mail.nvidia.com (216.228.112.34) by\n BN8NAM11FT019.mail.protection.outlook.com (10.13.176.158) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id\n 15.20.4352.24 via Frontend Transport; Wed, 21 Jul 2021 14:38:35 +0000",
            "from nvidia.com (172.20.187.5) by HQMAIL107.nvidia.com\n (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 21 Jul\n 2021 14:38:33 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=DJC8rV4mA0e6Ydd99nbxaFTyrG8qp/LMZD9tGxDicbcmU9tjiQ/x6em1NhHmvfH8W7LMGnnU7USyrWvTI+sU4Lxu6Zav9b5JymWSKtHx2iqeP+6OvFwNW2+F3PsVVQpwM4BpwJoDGimuJc+FDLIgncJTMAyGUNbezx6lSMtDN2qSLHgDlzT0vqMnV7QbkuH5cq0wEctLGQbPIbcVva8Vj1lN5yCtVPcGiEjDHGj8BMq4lslAzqe0Fz6np3jP5RmGIPawyqSg2/OasbtKTl1FUMGAMREVsaLO0cI1iI9wYkw6zLAyj2/OlWkaoAGJNV5qcx0V6+cKO0tndl9QFsaRsA==",
        "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-SenderADCheck;\n bh=5G0eCClNTtsTWqLvHuQtLWcmc1T98Jqxd2R4BXdEzjQ=;\n b=f7MGUknphI4O5wDT0Sv+SwV9vDEzzS49opf1uthyLhqTKYXvGR9srKHRQn8ZAtpk7GPjt4cFQffw52Zs9h9b9hsfzHwmUxWqe1hjUxsAM7u+NHPNjcgcAE+ox6GJh0JWy4a5n+JuUL7+bfL5LweAz5PoH22+/EErt7zKheEd6TiyJ5tgaL2M1F+0AjIAA4NjyGVxeX1eJ6KksiKGdTblRuEgtsnbnHJzXfnf6anPO5tJdezR5FG8zdvQnx5hGX0e6MSzNu9zhXjHK25gnB5CqiMR7sIiR1jZt7UaFSXYTaNB/vg+bBxGuaIIRZ1e2zx7uaAsY5R3MAkC7Qw0NSVeXg==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 216.228.112.34) smtp.rcpttodomain=ashroe.eu smtp.mailfrom=nvidia.com;\n dmarc=pass (p=quarantine sp=none 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=5G0eCClNTtsTWqLvHuQtLWcmc1T98Jqxd2R4BXdEzjQ=;\n b=c672iKq6eHyOX38M14K7lLdygTclpuyBMSniSuFa4wemduzDmWMrGzfkgCy9YdEFiez7s25KunDOr/tCq0QZCBmN41Be/6MQC6AVuJD3NnWXCP4AZSXW6ou5MQUD7+j/d+E3YNzeUympwwbIGSa0A8JUEKbzUYDRCA4BD1a3NtpkVE0/ToBY5WaEvQesjxyKNT/L5M/aSogswFLX6PIsPfofifSTruuAwQE0dN6wGPIrfqsi0tLe1gtpGG8YPzUGjOt48FEYHluoT8hlh6nIZVhkpzStbwgAba17i9PHQ7fuGC9TTmPS6cjoDJv9BLSvKVjFEKbM2iQi6PCHHYNIQA==",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 216.228.112.34)\n smtp.mailfrom=nvidia.com; ashroe.eu; dkim=none (message not signed)\n header.d=none;ashroe.eu; dmarc=pass action=none header.from=nvidia.com;",
        "Received-SPF": "Pass (protection.outlook.com: domain of nvidia.com designates\n 216.228.112.34 as permitted sender) receiver=protection.outlook.com;\n client-ip=216.228.112.34; helo=mail.nvidia.com;",
        "From": "Xueming Li <xuemingl@nvidia.com>",
        "To": "Viacheslav Ovsiienko <viacheslavo@nvidia.com>",
        "CC": "<dev@dpdk.org>, <xuemingl@nvidia.com>, Matan Azrad <matan@nvidia.com>,\n Shahaf Shuler <shahafs@nvidia.com>, Ray Kinsella <mdr@ashroe.eu>",
        "Date": "Wed, 21 Jul 2021 22:37:29 +0800",
        "Message-ID": "<20210721143743.24626-3-xuemingl@nvidia.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20210721143743.24626-1-xuemingl@nvidia.com>",
        "References": "<20210616040935.311733-1-xuemingl@nvidia.com>\n <20210721143743.24626-1-xuemingl@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[172.20.187.5]",
        "X-ClientProxiedBy": "HQMAIL105.nvidia.com (172.20.187.12) To\n HQMAIL107.nvidia.com (172.20.187.13)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "141a51b7-0a70-4733-c4ae-08d94c5538fc",
        "X-MS-TrafficTypeDiagnostic": "DM4PR12MB5117:",
        "X-Microsoft-Antispam-PRVS": "\n <DM4PR12MB51171C83F8456FD593C67EC4A1E39@DM4PR12MB5117.namprd12.prod.outlook.com>",
        "X-MS-Oob-TLC-OOBClassifiers": "OLM:6108;",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n nNB4cbgyP82AVyUWlka4wIWDuP15eT+nSi0fSyVcJzbeS2Bl8PE7wDBe6TTxIy9OSuFhfYDqzd4DAQSLKJfkknyLJKcE/I6BnmNAUIaqnHE0ERlBRfRrYaa1bFORhWzp9/i5x92IOsAYVrucSnRkJP7jmoAJ2002nWw/5FDcJk+wbp9f2/J/Gg2RL9hfOwTuIe13IOgGi5FZYAJUASJZr2xjcV1kqE7oMb50/DbNpRjvf+Ytlbnkm26X8IdRm17gizxbLrHaBWSbsHOfy6bzc7l4OkLMSf7gSiOHIc8z+th7HXSfyXQvainsXsv897lCTt0mIOeRT6R+WA7pw7k5nhBszPKVycCBk3sUTttZSXHo9Em0jfawySOzgTg2eEtg30MPbnP772lcHFSjf6+pHhi4Os0sKr2nNq1Ovh5S5KN+IlTHQSTArQ0HoB8j9DIIKIGBsIiSV9Q3HC7wlhDzsbXY3KnQ/wbmZu4xfVzb9dmryc4H9Co2gLmYojW0wHauEupOYl8ZYu+oHdIgLxEY5lqXyhrELvUEdF1zMURhnj2TAP21tLWCzPpZU7pq8rKkN02mqXNTr7kJwTcv9bYjj6xNjzRxb6optdJPunWl3j0rMp72g0g73d0+sPo5DXp5cfMKgje+vVlDrbPccfxqZHGCgGCrcdxneabySHPejAj4WfdRv71hRLtNnrc8z/257j0wmjmwMP/xSBpjkiMyPQ==",
        "X-Forefront-Antispam-Report": "CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1;\n SRV:;\n IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE;\n SFS:(4636009)(136003)(376002)(346002)(39860400002)(396003)(36840700001)(46966006)(4326008)(478600001)(36906005)(316002)(83380400001)(70586007)(426003)(16526019)(8936002)(82740400003)(2906002)(6286002)(186003)(6862004)(36756003)(356005)(8676002)(54906003)(30864003)(26005)(7696005)(82310400003)(1076003)(6636002)(86362001)(47076005)(37006003)(6666004)(70206006)(336012)(55016002)(7636003)(2616005)(36860700001)(5660300002);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "21 Jul 2021 14:38:35.9417 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 141a51b7-0a70-4733-c4ae-08d94c5538fc",
        "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.112.34];\n Helo=[mail.nvidia.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n BN8NAM11FT019.eop-nam11.prod.protection.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "DM4PR12MB5117",
        "Subject": "[dpdk-dev] [PATCH v4 02/16] common/mlx5: add common device driver",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "To support auxiliary bus, introduces common device driver and callbacks,\nsuppose to replace mlx5 common PCI bus driver.\n\nMlx5 class drivers, i.e. eth, vDPA, regex and compress normally consumes\nsingle Verbs device context to probe a device. The Verbs device comes\nfrom PCI address if the device is PCI bus device, from Auxiliary sysfs\nif the device is auxiliary bus device. Currently only PCI bus is\nsupported.\n\nCommon device driver is a middle layer between mlx5 class drivers and\nbus, resolve and abstract bus info to Verbs device for class drivers.\nBoth PCI bus driver and Auxiliary bus driver can utilize the common\ndriver layer to cast bus operations to mlx5 class drivers.\n\nLegacy mlx5 common PCI bus driver still being used by mlx5 eth, vDPA,\nregex and compress PMD, will remove once all PMD drivers migrate to new\ncommon driver.\n\nSigned-off-by: Xueming Li <xuemingl@nvidia.com>\nAcked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>\n---\n doc/guides/rel_notes/release_21_08.rst        |   5 +\n drivers/common/mlx5/linux/mlx5_common_os.c    |   2 +-\n drivers/common/mlx5/linux/mlx5_common_os.h    |   7 +-\n drivers/common/mlx5/linux/mlx5_common_verbs.c |  21 +-\n drivers/common/mlx5/mlx5_common.c             | 363 +++++++++++++++++-\n drivers/common/mlx5/mlx5_common.h             | 128 ++++++\n drivers/common/mlx5/mlx5_common_pci.c         | 133 ++++++-\n drivers/common/mlx5/mlx5_common_private.h     |  41 ++\n drivers/common/mlx5/mlx5_common_utils.h       |   2 +\n drivers/common/mlx5/version.map               |   4 +\n 10 files changed, 688 insertions(+), 18 deletions(-)\n create mode 100644 drivers/common/mlx5/mlx5_common_private.h",
    "diff": "diff --git a/doc/guides/rel_notes/release_21_08.rst b/doc/guides/rel_notes/release_21_08.rst\nindex 409f9980e9..27d591137e 100644\n--- a/doc/guides/rel_notes/release_21_08.rst\n+++ b/doc/guides/rel_notes/release_21_08.rst\n@@ -148,6 +148,11 @@ New Features\n   The experimental PMD power management API now supports managing\n   multiple Ethernet Rx queues per lcore.\n \n+* **Added Sub-Function support for mlx5 PMDs**\n+\n+  Added Sub-Function support based on auxiliary bus for mlx5 PMDs:\n+  net, vDPA, compress and regex.\n+\n \n Removed Items\n -------------\ndiff --git a/drivers/common/mlx5/linux/mlx5_common_os.c b/drivers/common/mlx5/linux/mlx5_common_os.c\nindex ea0b71e425..78a9723075 100644\n--- a/drivers/common/mlx5/linux/mlx5_common_os.c\n+++ b/drivers/common/mlx5/linux/mlx5_common_os.c\n@@ -425,7 +425,7 @@ mlx5_glue_constructor(void)\n }\n \n struct ibv_device *\n-mlx5_os_get_ibv_device(struct rte_pci_addr *addr)\n+mlx5_os_get_ibv_device(const struct rte_pci_addr *addr)\n {\n \tint n;\n \tstruct ibv_device **ibv_list = mlx5_glue->get_device_list(&n);\ndiff --git a/drivers/common/mlx5/linux/mlx5_common_os.h b/drivers/common/mlx5/linux/mlx5_common_os.h\nindex 72d6bf828b..86d0cb09b0 100644\n--- a/drivers/common/mlx5/linux/mlx5_common_os.h\n+++ b/drivers/common/mlx5/linux/mlx5_common_os.h\n@@ -291,6 +291,11 @@ mlx5_os_free(void *addr)\n \n __rte_internal\n struct ibv_device *\n-mlx5_os_get_ibv_device(struct rte_pci_addr *addr);\n+mlx5_os_get_ibv_device(const struct rte_pci_addr *addr);\n+\n+__rte_internal\n+struct ibv_device *\n+mlx5_os_get_ibv_dev(const struct rte_device *dev);\n+\n \n #endif /* RTE_PMD_MLX5_COMMON_OS_H_ */\ndiff --git a/drivers/common/mlx5/linux/mlx5_common_verbs.c b/drivers/common/mlx5/linux/mlx5_common_verbs.c\nindex aa560f05f2..6a6ab7a7a2 100644\n--- a/drivers/common/mlx5/linux/mlx5_common_verbs.c\n+++ b/drivers/common/mlx5/linux/mlx5_common_verbs.c\n@@ -10,11 +10,31 @@\n #include <sys/mman.h>\n #include <inttypes.h>\n \n+#include <rte_errno.h>\n+#include <rte_bus_pci.h>\n+\n+#include \"mlx5_common_utils.h\"\n+#include \"mlx5_common_log.h\"\n+#include \"mlx5_common_private.h\"\n #include \"mlx5_autoconf.h\"\n #include <mlx5_glue.h>\n #include <mlx5_common.h>\n #include <mlx5_common_mr.h>\n \n+struct ibv_device *\n+mlx5_os_get_ibv_dev(const struct rte_device *dev)\n+{\n+\tstruct ibv_device *ibv = NULL;\n+\n+\tif (mlx5_dev_is_pci(dev))\n+\t\tibv = mlx5_os_get_ibv_device(&RTE_DEV_TO_PCI_CONST(dev)->addr);\n+\tif (ibv == NULL) {\n+\t\trte_errno = ENODEV;\n+\t\tDRV_LOG(ERR, \"Verbs device not found: %s\", dev->name);\n+\t}\n+\treturn ibv;\n+}\n+\n /**\n  * Register mr. Given protection domain pointer, pointer to addr and length\n  * register the memory region.\n@@ -68,4 +88,3 @@ mlx5_common_verbs_dereg_mr(struct mlx5_pmd_mr *pmd_mr)\n \t\tmemset(pmd_mr, 0, sizeof(*pmd_mr));\n \t}\n }\n-\ndiff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c\nindex 25e9f09108..97d3e3e60e 100644\n--- a/drivers/common/mlx5/mlx5_common.c\n+++ b/drivers/common/mlx5/mlx5_common.c\n@@ -8,11 +8,14 @@\n \n #include <rte_errno.h>\n #include <rte_mempool.h>\n+#include <rte_class.h>\n+#include <rte_malloc.h>\n \n #include \"mlx5_common.h\"\n #include \"mlx5_common_os.h\"\n #include \"mlx5_common_log.h\"\n #include \"mlx5_common_pci.h\"\n+#include \"mlx5_common_private.h\"\n \n uint8_t haswell_broadwell_cpu;\n \n@@ -41,6 +44,362 @@ static inline void mlx5_cpu_id(unsigned int level,\n \n RTE_LOG_REGISTER_DEFAULT(mlx5_common_logtype, NOTICE)\n \n+/* Head of list of drivers. */\n+static TAILQ_HEAD(mlx5_drivers, mlx5_class_driver) drivers_list =\n+\t\t\t\tTAILQ_HEAD_INITIALIZER(drivers_list);\n+\n+/* Head of devices. */\n+static TAILQ_HEAD(mlx5_devices, mlx5_common_device) devices_list =\n+\t\t\t\tTAILQ_HEAD_INITIALIZER(devices_list);\n+\n+static const struct {\n+\tconst char *name;\n+\tunsigned int drv_class;\n+} mlx5_classes[] = {\n+\t{ .name = \"vdpa\", .drv_class = MLX5_CLASS_VDPA },\n+\t{ .name = \"eth\", .drv_class = MLX5_CLASS_ETH },\n+\t/* Keep class \"net\" for backward compatibility. */\n+\t{ .name = \"net\", .drv_class = MLX5_CLASS_ETH },\n+\t{ .name = \"regex\", .drv_class = MLX5_CLASS_REGEX },\n+\t{ .name = \"compress\", .drv_class = MLX5_CLASS_COMPRESS },\n+\t{ .name = \"crypto\", .drv_class = MLX5_CLASS_CRYPTO },\n+};\n+\n+static int\n+class_name_to_value(const char *class_name)\n+{\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < RTE_DIM(mlx5_classes); i++) {\n+\t\tif (strcmp(class_name, mlx5_classes[i].name) == 0)\n+\t\t\treturn mlx5_classes[i].drv_class;\n+\t}\n+\treturn -EINVAL;\n+}\n+\n+static struct mlx5_class_driver *\n+driver_get(uint32_t class)\n+{\n+\tstruct mlx5_class_driver *driver;\n+\n+\tTAILQ_FOREACH(driver, &drivers_list, next) {\n+\t\tif ((uint32_t)driver->drv_class == class)\n+\t\t\treturn driver;\n+\t}\n+\treturn NULL;\n+}\n+\n+static int\n+devargs_class_handler(__rte_unused const char *key,\n+\t\t      const char *class_names, void *opaque)\n+{\n+\tint *ret = opaque;\n+\tint class_val;\n+\tchar *scratch;\n+\tchar *found;\n+\tchar *refstr = NULL;\n+\n+\t*ret = 0;\n+\tscratch = strdup(class_names);\n+\tif (scratch == NULL) {\n+\t\t*ret = -ENOMEM;\n+\t\treturn *ret;\n+\t}\n+\tfound = strtok_r(scratch, \":\", &refstr);\n+\tif (found == NULL)\n+\t\t/* Empty string. */\n+\t\tgoto err;\n+\tdo {\n+\t\t/* Extract each individual class name. Multiple\n+\t\t * classes can be supplied as class=net:regex:foo:bar.\n+\t\t */\n+\t\tclass_val = class_name_to_value(found);\n+\t\t/* Check if its a valid class. */\n+\t\tif (class_val < 0) {\n+\t\t\t*ret = -EINVAL;\n+\t\t\tgoto err;\n+\t\t}\n+\t\t*ret |= class_val;\n+\t\tfound = strtok_r(NULL, \":\", &refstr);\n+\t} while (found != NULL);\n+err:\n+\tfree(scratch);\n+\tif (*ret < 0)\n+\t\tDRV_LOG(ERR, \"Invalid mlx5 class options: %s.\\n\", class_names);\n+\treturn *ret;\n+}\n+\n+static int\n+parse_class_options(const struct rte_devargs *devargs)\n+{\n+\tstruct rte_kvargs *kvlist;\n+\tint ret = 0;\n+\n+\tif (devargs == NULL)\n+\t\treturn 0;\n+\tif (devargs->cls != NULL && devargs->cls->name != NULL)\n+\t\t/* Global syntax, only one class type. */\n+\t\treturn class_name_to_value(devargs->cls->name);\n+\t/* Legacy devargs support multiple classes. */\n+\tkvlist = rte_kvargs_parse(devargs->args, NULL);\n+\tif (kvlist == NULL)\n+\t\treturn 0;\n+\trte_kvargs_process(kvlist, RTE_DEVARGS_KEY_CLASS,\n+\t\t\t   devargs_class_handler, &ret);\n+\trte_kvargs_free(kvlist);\n+\treturn ret;\n+}\n+\n+static const unsigned int mlx5_class_invalid_combinations[] = {\n+\tMLX5_CLASS_ETH | MLX5_CLASS_VDPA,\n+\t/* New class combination should be added here. */\n+};\n+\n+static int\n+is_valid_class_combination(uint32_t user_classes)\n+{\n+\tunsigned int i;\n+\n+\t/* Verify if user specified unsupported combination. */\n+\tfor (i = 0; i < RTE_DIM(mlx5_class_invalid_combinations); i++) {\n+\t\tif ((mlx5_class_invalid_combinations[i] & user_classes) ==\n+\t\t    mlx5_class_invalid_combinations[i])\n+\t\t\treturn -EINVAL;\n+\t}\n+\t/* Not found any invalid class combination. */\n+\treturn 0;\n+}\n+\n+static bool\n+device_class_enabled(const struct mlx5_common_device *device, uint32_t class)\n+{\n+\treturn (device->classes_loaded & class) > 0;\n+}\n+\n+static bool\n+mlx5_bus_match(const struct mlx5_class_driver *drv,\n+\t       const struct rte_device *dev)\n+{\n+\tif (mlx5_dev_is_pci(dev))\n+\t\treturn mlx5_dev_pci_match(drv, dev);\n+\treturn true;\n+}\n+\n+static struct mlx5_common_device *\n+to_mlx5_device(const struct rte_device *rte_dev)\n+{\n+\tstruct mlx5_common_device *dev;\n+\n+\tTAILQ_FOREACH(dev, &devices_list, next) {\n+\t\tif (rte_dev == dev->dev)\n+\t\t\treturn dev;\n+\t}\n+\treturn NULL;\n+}\n+\n+static void\n+dev_release(struct mlx5_common_device *dev)\n+{\n+\tTAILQ_REMOVE(&devices_list, dev, next);\n+\trte_free(dev);\n+}\n+\n+static int\n+drivers_remove(struct mlx5_common_device *dev, uint32_t enabled_classes)\n+{\n+\tstruct mlx5_class_driver *driver;\n+\tint local_ret = -ENODEV;\n+\tunsigned int i = 0;\n+\tint ret = 0;\n+\n+\tenabled_classes &= dev->classes_loaded;\n+\twhile (enabled_classes) {\n+\t\tdriver = driver_get(RTE_BIT64(i));\n+\t\tif (driver != NULL) {\n+\t\t\tlocal_ret = driver->remove(dev->dev);\n+\t\t\tif (local_ret == 0)\n+\t\t\t\tdev->classes_loaded &= ~RTE_BIT64(i);\n+\t\t\telse if (ret == 0)\n+\t\t\t\tret = local_ret;\n+\t\t}\n+\t\tenabled_classes &= ~RTE_BIT64(i);\n+\t\ti++;\n+\t}\n+\tif (local_ret != 0 && ret == 0)\n+\t\tret = local_ret;\n+\treturn ret;\n+}\n+\n+static int\n+drivers_probe(struct mlx5_common_device *dev, uint32_t user_classes)\n+{\n+\tstruct mlx5_class_driver *driver;\n+\tuint32_t enabled_classes = 0;\n+\tbool already_loaded;\n+\tint ret;\n+\n+\tTAILQ_FOREACH(driver, &drivers_list, next) {\n+\t\tif ((driver->drv_class & user_classes) == 0)\n+\t\t\tcontinue;\n+\t\tif (!mlx5_bus_match(driver, dev->dev))\n+\t\t\tcontinue;\n+\t\talready_loaded = dev->classes_loaded & driver->drv_class;\n+\t\tif (already_loaded && driver->probe_again == 0) {\n+\t\t\tDRV_LOG(ERR, \"Device %s is already probed\",\n+\t\t\t\tdev->dev->name);\n+\t\t\tret = -EEXIST;\n+\t\t\tgoto probe_err;\n+\t\t}\n+\t\tret = driver->probe(dev->dev);\n+\t\tif (ret < 0) {\n+\t\t\tDRV_LOG(ERR, \"Failed to load driver %s\",\n+\t\t\t\tdriver->name);\n+\t\t\tgoto probe_err;\n+\t\t}\n+\t\tenabled_classes |= driver->drv_class;\n+\t}\n+\tdev->classes_loaded |= enabled_classes;\n+\treturn 0;\n+probe_err:\n+\t/* Only unload drivers which are enabled which were enabled\n+\t * in this probe instance.\n+\t */\n+\tdrivers_remove(dev, enabled_classes);\n+\treturn ret;\n+}\n+\n+int\n+mlx5_common_dev_probe(struct rte_device *eal_dev)\n+{\n+\tstruct mlx5_common_device *dev;\n+\tuint32_t classes = 0;\n+\tbool new_device = false;\n+\tint ret;\n+\n+\tDRV_LOG(INFO, \"probe device \\\"%s\\\".\", eal_dev->name);\n+\tret = parse_class_options(eal_dev->devargs);\n+\tif (ret < 0) {\n+\t\tDRV_LOG(ERR, \"Unsupported mlx5 class type: %s\",\n+\t\t\teal_dev->devargs->args);\n+\t\treturn ret;\n+\t}\n+\tclasses = ret;\n+\tif (classes == 0)\n+\t\t/* Default to net class. */\n+\t\tclasses = MLX5_CLASS_ETH;\n+\tdev = to_mlx5_device(eal_dev);\n+\tif (!dev) {\n+\t\tdev = rte_zmalloc(\"mlx5_common_device\", sizeof(*dev), 0);\n+\t\tif (!dev)\n+\t\t\treturn -ENOMEM;\n+\t\tdev->dev = eal_dev;\n+\t\tTAILQ_INSERT_HEAD(&devices_list, dev, next);\n+\t\tnew_device = true;\n+\t} else {\n+\t\t/* Validate combination here. */\n+\t\tret = is_valid_class_combination(classes |\n+\t\t\t\t\t\t dev->classes_loaded);\n+\t\tif (ret != 0) {\n+\t\t\tDRV_LOG(ERR, \"Unsupported mlx5 classes combination.\");\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\tret = drivers_probe(dev, classes);\n+\tif (ret)\n+\t\tgoto class_err;\n+\treturn 0;\n+class_err:\n+\tif (new_device)\n+\t\tdev_release(dev);\n+\treturn ret;\n+}\n+\n+int\n+mlx5_common_dev_remove(struct rte_device *eal_dev)\n+{\n+\tstruct mlx5_common_device *dev;\n+\tint ret;\n+\n+\tdev = to_mlx5_device(eal_dev);\n+\tif (!dev)\n+\t\treturn -ENODEV;\n+\t/* Matching device found, cleanup and unload drivers. */\n+\tret = drivers_remove(dev, dev->classes_loaded);\n+\tif (ret != 0)\n+\t\tdev_release(dev);\n+\treturn ret;\n+}\n+\n+int\n+mlx5_common_dev_dma_map(struct rte_device *dev, void *addr, uint64_t iova,\n+\t\t\tsize_t len)\n+{\n+\tstruct mlx5_class_driver *driver = NULL;\n+\tstruct mlx5_class_driver *temp;\n+\tstruct mlx5_common_device *mdev;\n+\tint ret = -EINVAL;\n+\n+\tmdev = to_mlx5_device(dev);\n+\tif (!mdev)\n+\t\treturn -ENODEV;\n+\tTAILQ_FOREACH(driver, &drivers_list, next) {\n+\t\tif (!device_class_enabled(mdev, driver->drv_class) ||\n+\t\t    driver->dma_map == NULL)\n+\t\t\tcontinue;\n+\t\tret = driver->dma_map(dev, addr, iova, len);\n+\t\tif (ret)\n+\t\t\tgoto map_err;\n+\t}\n+\treturn ret;\n+map_err:\n+\tTAILQ_FOREACH(temp, &drivers_list, next) {\n+\t\tif (temp == driver)\n+\t\t\tbreak;\n+\t\tif (device_class_enabled(mdev, temp->drv_class) &&\n+\t\t    temp->dma_map && temp->dma_unmap)\n+\t\t\ttemp->dma_unmap(dev, addr, iova, len);\n+\t}\n+\treturn ret;\n+}\n+\n+int\n+mlx5_common_dev_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova,\n+\t\t\t  size_t len)\n+{\n+\tstruct mlx5_class_driver *driver;\n+\tstruct mlx5_common_device *mdev;\n+\tint local_ret = -EINVAL;\n+\tint ret = 0;\n+\n+\tmdev = to_mlx5_device(dev);\n+\tif (!mdev)\n+\t\treturn -ENODEV;\n+\t/* There is no unmap error recovery in current implementation. */\n+\tTAILQ_FOREACH_REVERSE(driver, &drivers_list, mlx5_drivers, next) {\n+\t\tif (!device_class_enabled(mdev, driver->drv_class) ||\n+\t\t    driver->dma_unmap == NULL)\n+\t\t\tcontinue;\n+\t\tlocal_ret = driver->dma_unmap(dev, addr, iova, len);\n+\t\tif (local_ret && (ret == 0))\n+\t\t\tret = local_ret;\n+\t}\n+\tif (local_ret)\n+\t\tret = local_ret;\n+\treturn ret;\n+}\n+\n+void\n+mlx5_class_driver_register(struct mlx5_class_driver *driver)\n+{\n+\tmlx5_common_driver_on_register_pci(driver);\n+\tTAILQ_INSERT_TAIL(&drivers_list, driver, next);\n+}\n+\n+static void mlx5_common_driver_init(void)\n+{\n+\tmlx5_common_pci_init();\n+}\n+\n static bool mlx5_common_initialized;\n \n /**\n@@ -55,7 +414,7 @@ mlx5_common_init(void)\n \t\treturn;\n \n \tmlx5_glue_constructor();\n-\tmlx5_common_pci_init();\n+\tmlx5_common_driver_init();\n \tmlx5_common_initialized = true;\n }\n \n@@ -214,3 +573,5 @@ mlx5_devx_alloc_uar(void *ctx, int mapping)\n exit:\n \treturn uar;\n }\n+\n+RTE_PMD_EXPORT_NAME(mlx5_common_driver, __COUNTER__);\ndiff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h\nindex 05008983ea..6ba1e70223 100644\n--- a/drivers/common/mlx5/mlx5_common.h\n+++ b/drivers/common/mlx5/mlx5_common.h\n@@ -245,4 +245,132 @@ extern uint8_t haswell_broadwell_cpu;\n __rte_internal\n void mlx5_common_init(void);\n \n+/**\n+ * Common Driver Interface\n+ * ConnectX common driver supports multiple classes: net,vdpa,regex,crypto and\n+ * compress devices. This layer enables creating such multiple class of devices\n+ * on a single device by allowing to bind multiple class specific device\n+ * driver to attach to common driver.\n+ *\n+ * ------------  -------------  --------------  -----------------  ------------\n+ * | mlx5 net |  | mlx5 vdpa |  | mlx5 regex |  | mlx5 compress |  | mlx5 ... |\n+ * |  driver  |  |  driver   |  |   driver   |  |     driver    |  |  drivers |\n+ * ------------  -------------  --------------  -----------------  ------------\n+ *                               ||\n+ *                        -----------------\n+ *                        |     mlx5      |\n+ *                        | common driver |\n+ *                        -----------------\n+ *                          |          |\n+ *                 -----------        -----------------\n+ *                 |   mlx5  |        |   mlx5        |\n+ *                 | pci dev |        | auxiliary dev |\n+ *                 -----------        -----------------\n+ *\n+ * - mlx5 pci bus driver binds to mlx5 PCI devices defined by PCI\n+ *   ID table of all related mlx5 PCI devices.\n+ * - mlx5 class driver such as net, vdpa, regex PMD defines its\n+ *   specific PCI ID table and mlx5 bus driver probes matching\n+ *   class drivers.\n+ * - mlx5 common driver is central place that validates supported\n+ *   class combinations.\n+ * - mlx5 common driver hide bus difference by resolving device address\n+ *   from devargs, locating target RDMA device and probing with it.\n+ */\n+\n+/**\n+ * Initialization function for the driver called during device probing.\n+ */\n+typedef int (mlx5_class_driver_probe_t)(struct rte_device *dev);\n+\n+/**\n+ * Uninitialization function for the driver called during hot-unplugging.\n+ */\n+typedef int (mlx5_class_driver_remove_t)(struct rte_device *dev);\n+\n+/**\n+ * Driver-specific DMA mapping. After a successful call the device\n+ * will be able to read/write from/to this segment.\n+ *\n+ * @param dev\n+ *   Pointer to the device.\n+ * @param addr\n+ *   Starting virtual address of memory to be mapped.\n+ * @param iova\n+ *   Starting IOVA address of memory to be mapped.\n+ * @param len\n+ *   Length of memory segment being mapped.\n+ * @return\n+ *   - 0 On success.\n+ *   - Negative value and rte_errno is set otherwise.\n+ */\n+typedef int (mlx5_class_driver_dma_map_t)(struct rte_device *dev, void *addr,\n+\t\t\t\t\t  uint64_t iova, size_t len);\n+\n+/**\n+ * Driver-specific DMA un-mapping. After a successful call the device\n+ * will not be able to read/write from/to this segment.\n+ *\n+ * @param dev\n+ *   Pointer to the device.\n+ * @param addr\n+ *   Starting virtual address of memory to be unmapped.\n+ * @param iova\n+ *   Starting IOVA address of memory to be unmapped.\n+ * @param len\n+ *   Length of memory segment being unmapped.\n+ * @return\n+ *   - 0 On success.\n+ *   - Negative value and rte_errno is set otherwise.\n+ */\n+typedef int (mlx5_class_driver_dma_unmap_t)(struct rte_device *dev, void *addr,\n+\t\t\t\t\t    uint64_t iova, size_t len);\n+\n+/** Device already probed can be probed again to check for new ports. */\n+#define MLX5_DRV_PROBE_AGAIN 0x0004\n+\n+/**\n+ * A structure describing a mlx5 common class driver.\n+ */\n+struct mlx5_class_driver {\n+\tTAILQ_ENTRY(mlx5_class_driver) next;\n+\tenum mlx5_class drv_class;            /**< Class of this driver. */\n+\tconst char *name;                     /**< Driver name. */\n+\tmlx5_class_driver_probe_t *probe;     /**< Device Probe function. */\n+\tmlx5_class_driver_remove_t *remove;   /**< Device Remove function. */\n+\tmlx5_class_driver_dma_map_t *dma_map; /**< device dma map function. */\n+\tmlx5_class_driver_dma_unmap_t *dma_unmap;\n+\t/**< device dma unmap function. */\n+\tconst struct rte_pci_id *id_table;    /**< ID table, NULL terminated. */\n+\tuint32_t probe_again:1;\n+\t/**< Device already probed can be probed again to check new device. */\n+\tuint32_t intr_lsc:1; /**< Supports link state interrupt. */\n+\tuint32_t intr_rmv:1; /**< Supports device remove interrupt. */\n+};\n+\n+/**\n+ * Register a mlx5 device driver.\n+ *\n+ * @param driver\n+ *   A pointer to a mlx5_driver structure describing the driver\n+ *   to be registered.\n+ */\n+__rte_internal\n+void\n+mlx5_class_driver_register(struct mlx5_class_driver *driver);\n+\n+/**\n+ * Test a device is PCI bus device.\n+ *\n+ * @param dev\n+ *   Pointer to device.\n+ *\n+ * @return\n+ *   - True on device devargs is a PCI bus device.\n+ *   - False otherwise.\n+ */\n+__rte_internal\n+bool\n+mlx5_dev_is_pci(const struct rte_device *dev);\n+\n #endif /* RTE_PMD_MLX5_COMMON_H_ */\ndiff --git a/drivers/common/mlx5/mlx5_common_pci.c b/drivers/common/mlx5/mlx5_common_pci.c\nindex 591054468d..a7db6e2c11 100644\n--- a/drivers/common/mlx5/mlx5_common_pci.c\n+++ b/drivers/common/mlx5/mlx5_common_pci.c\n@@ -3,11 +3,19 @@\n  */\n \n #include <stdlib.h>\n+\n #include <rte_malloc.h>\n+#include <rte_devargs.h>\n+#include <rte_errno.h>\n #include <rte_class.h>\n \n #include \"mlx5_common_log.h\"\n #include \"mlx5_common_pci.h\"\n+#include \"mlx5_common_private.h\"\n+\n+static struct rte_pci_driver mlx5_common_pci_driver;\n+\n+/********** Legacy PCI bus driver, to be removed ********/\n \n struct mlx5_pci_device {\n \tstruct rte_pci_device *pci_dev;\n@@ -298,8 +306,8 @@ drivers_probe(struct mlx5_pci_device *dev, struct rte_pci_driver *pci_drv,\n  *   0 on success, a negative errno value otherwise and rte_errno is set.\n  */\n static int\n-mlx5_common_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n-\t\t      struct rte_pci_device *pci_dev)\n+mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n+\t       struct rte_pci_device *pci_dev)\n {\n \tstruct mlx5_pci_device *dev;\n \tuint32_t user_classes = 0;\n@@ -352,7 +360,7 @@ mlx5_common_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n  *   0 on success, the function cannot fail.\n  */\n static int\n-mlx5_common_pci_remove(struct rte_pci_device *pci_dev)\n+mlx5_pci_remove(struct rte_pci_device *pci_dev)\n {\n \tstruct mlx5_pci_device *dev;\n \tint ret;\n@@ -368,8 +376,8 @@ mlx5_common_pci_remove(struct rte_pci_device *pci_dev)\n }\n \n static int\n-mlx5_common_pci_dma_map(struct rte_pci_device *pci_dev, void *addr,\n-\t\t\tuint64_t iova, size_t len)\n+mlx5_pci_dma_map(struct rte_pci_device *pci_dev, void *addr,\n+\t\t uint64_t iova, size_t len)\n {\n \tstruct mlx5_pci_driver *driver = NULL;\n \tstruct mlx5_pci_driver *temp;\n@@ -401,8 +409,8 @@ mlx5_common_pci_dma_map(struct rte_pci_device *pci_dev, void *addr,\n }\n \n static int\n-mlx5_common_pci_dma_unmap(struct rte_pci_device *pci_dev, void *addr,\n-\t\t\t  uint64_t iova, size_t len)\n+mlx5_pci_dma_unmap(struct rte_pci_device *pci_dev, void *addr,\n+\t\t   uint64_t iova, size_t len)\n {\n \tstruct mlx5_pci_driver *driver;\n \tstruct mlx5_pci_device *dev;\n@@ -435,10 +443,10 @@ static struct rte_pci_driver mlx5_pci_driver = {\n \t.driver = {\n \t\t.name = MLX5_PCI_DRIVER_NAME,\n \t},\n-\t.probe = mlx5_common_pci_probe,\n-\t.remove = mlx5_common_pci_remove,\n-\t.dma_map = mlx5_common_pci_dma_map,\n-\t.dma_unmap = mlx5_common_pci_dma_unmap,\n+\t.probe = mlx5_pci_probe,\n+\t.remove = mlx5_pci_remove,\n+\t.dma_map = mlx5_pci_dma_map,\n+\t.dma_unmap = mlx5_pci_dma_unmap,\n };\n \n static int\n@@ -502,7 +510,7 @@ pci_ids_table_update(const struct rte_pci_id *driver_id_table)\n \tupdated_table = calloc(num_ids, sizeof(*updated_table));\n \tif (!updated_table)\n \t\treturn -ENOMEM;\n-\tif (TAILQ_EMPTY(&drv_list)) {\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->vendor_id != 0;\n \t\t     id_iter++, i++)\n@@ -518,6 +526,7 @@ pci_ids_table_update(const struct rte_pci_id *driver_id_table)\n \t/* Terminate table with empty entry. */\n \tupdated_table[i].vendor_id = 0;\n \tmlx5_pci_driver.id_table = updated_table;\n+\tmlx5_common_pci_driver.id_table = updated_table;\n \tmlx5_pci_id_table = updated_table;\n \tif (old_table)\n \t\tfree(old_table);\n@@ -536,6 +545,101 @@ mlx5_pci_driver_register(struct mlx5_pci_driver *driver)\n \tTAILQ_INSERT_TAIL(&drv_list, driver, next);\n }\n \n+/********** New common PCI bus driver ********/\n+\n+bool\n+mlx5_dev_is_pci(const struct rte_device *dev)\n+{\n+\treturn strcmp(dev->bus->name, \"pci\") == 0;\n+}\n+\n+bool\n+mlx5_dev_pci_match(const struct mlx5_class_driver *drv,\n+\t\t   const struct rte_device *dev)\n+{\n+\tconst struct rte_pci_device *pci_dev;\n+\tconst struct rte_pci_id *id_table;\n+\n+\tif (!mlx5_dev_is_pci(dev))\n+\t\treturn false;\n+\tpci_dev = RTE_DEV_TO_PCI_CONST(dev);\n+\tfor (id_table = drv->id_table; id_table->vendor_id != 0;\n+\t     id_table++) {\n+\t\t/* Check if device's ids match the class driver's ids. */\n+\t\tif (id_table->vendor_id != pci_dev->id.vendor_id &&\n+\t\t    id_table->vendor_id != RTE_PCI_ANY_ID)\n+\t\t\tcontinue;\n+\t\tif (id_table->device_id != pci_dev->id.device_id &&\n+\t\t    id_table->device_id != RTE_PCI_ANY_ID)\n+\t\t\tcontinue;\n+\t\tif (id_table->subsystem_vendor_id !=\n+\t\t    pci_dev->id.subsystem_vendor_id &&\n+\t\t    id_table->subsystem_vendor_id != RTE_PCI_ANY_ID)\n+\t\t\tcontinue;\n+\t\tif (id_table->subsystem_device_id !=\n+\t\t    pci_dev->id.subsystem_device_id &&\n+\t\t    id_table->subsystem_device_id != RTE_PCI_ANY_ID)\n+\t\t\tcontinue;\n+\t\tif (id_table->class_id != pci_dev->id.class_id &&\n+\t\t    id_table->class_id != RTE_CLASS_ANY_ID)\n+\t\t\tcontinue;\n+\t\treturn true;\n+\t}\n+\treturn false;\n+}\n+\n+static int\n+mlx5_common_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n+\t\t      struct rte_pci_device *pci_dev)\n+{\n+\treturn mlx5_common_dev_probe(&pci_dev->device);\n+}\n+\n+static int\n+mlx5_common_pci_remove(struct rte_pci_device *pci_dev)\n+{\n+\treturn mlx5_common_dev_remove(&pci_dev->device);\n+}\n+\n+static int\n+mlx5_common_pci_dma_map(struct rte_pci_device *pci_dev, void *addr,\n+\t\t\tuint64_t iova, size_t len)\n+{\n+\treturn mlx5_common_dev_dma_map(&pci_dev->device, addr, iova, len);\n+}\n+\n+static int\n+mlx5_common_pci_dma_unmap(struct rte_pci_device *pci_dev, void *addr,\n+\t\t\t  uint64_t iova, size_t len)\n+{\n+\treturn mlx5_common_dev_dma_unmap(&pci_dev->device, addr, iova, len);\n+}\n+\n+void\n+mlx5_common_driver_on_register_pci(struct mlx5_class_driver *driver)\n+{\n+\tif (driver->id_table != NULL) {\n+\t\tif (pci_ids_table_update(driver->id_table) != 0)\n+\t\t\treturn;\n+\t}\n+\tif (driver->probe_again)\n+\t\tmlx5_common_pci_driver.drv_flags |= RTE_PCI_DRV_PROBE_AGAIN;\n+\tif (driver->intr_lsc)\n+\t\tmlx5_common_pci_driver.drv_flags |= RTE_PCI_DRV_INTR_LSC;\n+\tif (driver->intr_rmv)\n+\t\tmlx5_common_pci_driver.drv_flags |= RTE_PCI_DRV_INTR_RMV;\n+}\n+\n+static struct rte_pci_driver mlx5_common_pci_driver = {\n+\t.driver = {\n+\t\t   .name = MLX5_PCI_DRIVER_NAME,\n+\t},\n+\t.probe = mlx5_common_pci_probe,\n+\t.remove = mlx5_common_pci_remove,\n+\t.dma_map = mlx5_common_pci_dma_map,\n+\t.dma_unmap = mlx5_common_pci_dma_unmap,\n+};\n+\n void mlx5_common_pci_init(void)\n {\n \tconst struct rte_pci_id empty_table[] = {\n@@ -551,7 +655,7 @@ void mlx5_common_pci_init(void)\n \t */\n \tif (mlx5_pci_id_table == NULL && pci_ids_table_update(empty_table))\n \t\treturn;\n-\trte_pci_register(&mlx5_pci_driver);\n+\trte_pci_register(&mlx5_common_pci_driver);\n }\n \n RTE_FINI(mlx5_common_pci_finish)\n@@ -560,8 +664,9 @@ RTE_FINI(mlx5_common_pci_finish)\n \t\t/* Constructor doesn't register with PCI bus if it failed\n \t\t * to build the table.\n \t\t */\n-\t\trte_pci_unregister(&mlx5_pci_driver);\n+\t\trte_pci_unregister(&mlx5_common_pci_driver);\n \t\tfree(mlx5_pci_id_table);\n \t}\n }\n+\n RTE_PMD_EXPORT_NAME(mlx5_common_pci, __COUNTER__);\ndiff --git a/drivers/common/mlx5/mlx5_common_private.h b/drivers/common/mlx5/mlx5_common_private.h\nnew file mode 100644\nindex 0000000000..791eb3cd77\n--- /dev/null\n+++ b/drivers/common/mlx5/mlx5_common_private.h\n@@ -0,0 +1,41 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2021 Mellanox Technologies, Ltd\n+ */\n+\n+#ifndef _MLX5_COMMON_PRIVATE_H_\n+#define _MLX5_COMMON_PRIVATE_H_\n+\n+#include <rte_pci.h>\n+\n+#include \"mlx5_common.h\"\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif /* __cplusplus */\n+\n+/* Common bus driver: */\n+\n+struct mlx5_common_device {\n+\tstruct rte_device *dev;\n+\tTAILQ_ENTRY(mlx5_common_device) next;\n+\tuint32_t classes_loaded;\n+};\n+\n+int mlx5_common_dev_probe(struct rte_device *eal_dev);\n+int mlx5_common_dev_remove(struct rte_device *eal_dev);\n+int mlx5_common_dev_dma_map(struct rte_device *dev, void *addr, uint64_t iova,\n+\t\t\t    size_t len);\n+int mlx5_common_dev_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova,\n+\t\t\t      size_t len);\n+\n+/* Common PCI bus driver: */\n+\n+void mlx5_common_driver_on_register_pci(struct mlx5_class_driver *driver);\n+bool mlx5_dev_pci_match(const struct mlx5_class_driver *drv,\n+\t\t\tconst struct rte_device *dev);\n+\n+#ifdef __cplusplus\n+}\n+#endif /* __cplusplus */\n+\n+#endif /* _MLX5_COMMON_PRIVATE_H_ */\ndiff --git a/drivers/common/mlx5/mlx5_common_utils.h b/drivers/common/mlx5/mlx5_common_utils.h\nindex 613d29de0c..98e487e7ef 100644\n--- a/drivers/common/mlx5/mlx5_common_utils.h\n+++ b/drivers/common/mlx5/mlx5_common_utils.h\n@@ -5,6 +5,8 @@\n #ifndef RTE_PMD_MLX5_COMMON_UTILS_H_\n #define RTE_PMD_MLX5_COMMON_UTILS_H_\n \n+#include <rte_rwlock.h>\n+\n #include \"mlx5_common.h\"\n \n /************************ mlx5 list *****************************/\ndiff --git a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map\nindex e6586d6f6f..e9d43dc1e5 100644\n--- a/drivers/common/mlx5/version.map\n+++ b/drivers/common/mlx5/version.map\n@@ -3,6 +3,8 @@ INTERNAL {\n \n \thaswell_broadwell_cpu;\n \n+\tmlx5_class_driver_register;\n+\n \tmlx5_common_init;\n \n \tmlx5_common_verbs_reg_mr; # WINDOWS_NO_EXPORT\n@@ -10,6 +12,7 @@ INTERNAL {\n \n \tmlx5_create_mr_ext;\n \n+\tmlx5_dev_is_pci; # WINDOWS_NO_EXPORT\n \tmlx5_dev_to_pci_addr; # WINDOWS_NO_EXPORT\n \n \tmlx5_devx_alloc_uar; # WINDOWS_NO_EXPORT\n@@ -137,6 +140,7 @@ INTERNAL {\n \tmlx5_os_alloc_pd;\n \tmlx5_os_dealloc_pd;\n \tmlx5_os_dereg_mr;\n+\tmlx5_os_get_ibv_dev; # WINDOWS_NO_EXPORT\n \tmlx5_os_get_ibv_device; # WINDOWS_NO_EXPORT\n \tmlx5_os_reg_mr;\n \tmlx5_os_umem_dereg;\n",
    "prefixes": [
        "v4",
        "02/16"
    ]
}