get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 96026,
    "url": "http://patches.dpdk.org/api/patches/96026/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20210719025410.15483-3-xuemingl@nvidia.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20210719025410.15483-3-xuemingl@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210719025410.15483-3-xuemingl@nvidia.com",
    "date": "2021-07-19T02:53:57",
    "name": "[v3,02/15] common/mlx5: add common device driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "0b9788bdda347db93cf41aa0c9be8358d84d28e3",
    "submitter": {
        "id": 1904,
        "url": "http://patches.dpdk.org/api/people/1904/?format=api",
        "name": "Xueming Li",
        "email": "xuemingl@nvidia.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20210719025410.15483-3-xuemingl@nvidia.com/mbox/",
    "series": [
        {
            "id": 17884,
            "url": "http://patches.dpdk.org/api/series/17884/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=17884",
            "date": "2021-07-19T02:53:55",
            "name": "net/mlx5: support Sub-Function",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/17884/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/96026/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/96026/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 639B6A0C45;\n\tMon, 19 Jul 2021 04:55:07 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id B868E41191;\n\tMon, 19 Jul 2021 04:55:01 +0200 (CEST)",
            "from NAM10-BN7-obe.outbound.protection.outlook.com\n (mail-bn7nam10on2075.outbound.protection.outlook.com [40.107.92.75])\n by mails.dpdk.org (Postfix) with ESMTP id 8B9D04118F\n for <dev@dpdk.org>; Mon, 19 Jul 2021 04:54:59 +0200 (CEST)",
            "from MW2PR16CA0060.namprd16.prod.outlook.com (2603:10b6:907:1::37)\n by BL1PR12MB5380.namprd12.prod.outlook.com (2603:10b6:208:314::7) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4308.25; Mon, 19 Jul\n 2021 02:54:58 +0000",
            "from CO1NAM11FT048.eop-nam11.prod.protection.outlook.com\n (2603:10b6:907:1:cafe::c1) by MW2PR16CA0060.outlook.office365.com\n (2603:10b6:907:1::37) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4331.21 via Frontend\n Transport; Mon, 19 Jul 2021 02:54:57 +0000",
            "from mail.nvidia.com (216.228.112.34) by\n CO1NAM11FT048.mail.protection.outlook.com (10.13.175.148) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id\n 15.20.4331.21 via Frontend Transport; Mon, 19 Jul 2021 02:54:57 +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; Mon, 19 Jul\n 2021 02:54:54 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=RIrCzvXEUi1lZWw2JaFFTUMU4Js/vluzDF2Bjv4mjKIsG2T7AgXlm5xf54otaZvAWYCzu6ThnGfBycfry5sMvLLMHtFhAWpHcXqM8CgPAgVQkW4Ymlw08YsupE8/x4e3R6Zgr5YWg8dneNUWNIU2VLfh8AxScz1FAIt8oEpknqPik8h8ZnDJVojhKN14Wm343H5yWBSduIz7kvMMYQDGcLjASboMztC7OMsdpFffsor/TXMDh3VgxgEzrus5C+4+TCLXRjYsMDzZzy14pzGrn0bQgasVfAjFZUaNY5bxmd9GxFziEVfAvucJv21Ozy/aEEu13e1Cc2eSQqSp2P0xZg==",
        "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=NmNIhHL5YzrVq0nL0FAWMcW+qnzBZVLV1nkiHggXPJE=;\n b=RijdXMKAGW4gNzE/jnlR4mjtyMvnFFWooz8f7CcaP+j9j4cVrVmLMtFzHLe0KtOhRRz/mPvgDE58QnuskCz/EgG2mMW86DnLzVAtFZZGn5zETPFSaBwNT9ZnwseUE899fbToweMxuRFBWDKefnU+U6oAx57D+14nI+rsopiDdOAQFdLTRVvLrCrEtUrN2eisnJfELSWed6/6xUYAtPtr9bgfea3Z/d442QgkhwZB68/CkEAkEFv4F63V/v9DycC+ibPbFJu/CPmgvfSShaCqLsuBB/qzX5V+hgl8pd9pHRoP5jsP99Rvc8rV0MkolQL6stHD6WcDjYQDuNWNWt/oVg==",
        "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=NmNIhHL5YzrVq0nL0FAWMcW+qnzBZVLV1nkiHggXPJE=;\n b=grNs3LEtpfbeNLp/q2PBGopZQchWkxGaH+XbLNjigB0liQjlqtqhUBkuMmCX317/EXopCGOo3UJ7wqif3qREE+PEbz1X3BD17sG4vchGTYM2ipVc8twVoiO3t+hNk+onnOvBOfGvUmbH5CqvQjyJVV59Yg0ZKx1ZOvM6VYbMroU67idA9zcHjoua2X0tJARNoivzTX/h4rS5MlnxobV2For+0Ol/2ySb8IGCcDQPJ0dbBD1kUXdHpC4Fe7/K6x5Wvuwh6QPkUr9aLNoGq0EayqbYpQKWjA1GIQ29kmdN4s9k4ZFjhgvkHwbNKE188eQJbMbW1xcjhfbbcShm2FgosQ==",
        "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": "Mon, 19 Jul 2021 10:53:57 +0800",
        "Message-ID": "<20210719025410.15483-3-xuemingl@nvidia.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20210713131437.30170-2-xuemingl@nvidia.com>",
        "References": "<20210713131437.30170-2-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": "8974311c-6766-491a-50f6-08d94a6097b7",
        "X-MS-TrafficTypeDiagnostic": "BL1PR12MB5380:",
        "X-Microsoft-Antispam-PRVS": "\n <BL1PR12MB53802580B78804172CA89C95A1E19@BL1PR12MB5380.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 Bc3fGnW+E4dQq5xiGtdpZavkFRmvovSOd/ywKf3Fey583Ww/OCIompB0pTUXmskz10czHUB1nhG6OUGf3Q1t938UzsvFY51Al5UuWZvzLZWQRe6m8PlKUXNF9N1pstFGEYPtuuyUb/JdHDpIflSnVlHmWKvltPRRKrXA5S7oN4Fsn1shEt7pvvMth4E9/cpH6YIbwNYfjaBoNWs5fpmc+9y0e4vd6QKL0oDcBBipbYooshATZRGOHL/iOYg3QArmR3StUibRyRwRjCWJvcKYKCikqI2z8VZrn0LhyUlJGv6JiZPd1Vd20bWL4BI5nViEmVsdeXLFMCpUbXYWvgOdvku4rB1vQlNggCt+0z7YSc/+06hxWjWt9UVU5q7p6hVi9CLRbTQCR95L+/WRNULD9sLPDVE8YbEuTs1ZuPgvzq3wUXoMg/QAJ53NmSA+FfAlc3dabZklcGIBnreUjvF9VCN1pZ2CJmn3nkX/LzOPN120rdhLulDELeOa5THlKPwJpcYF6h3iiEHIVU7Dd9eYgaIog/CX8yakbYaZqqHBGud1W75dnJ+CTYCf9FMTgNnsJULvRadQFf1s2BAdn3zsOWTPVulOUnclqiXwTa4mbrgRZkvmUbnI15dCLVr8yhYmlwXGdyHzko+JV6saDC/5FoTFesuF1oyawvtO/+613dGF0o53pjqR43Am/zX552vwtE2bJwvBFo3ngFCFeduZcQ==",
        "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)(39860400002)(376002)(136003)(396003)(346002)(36840700001)(46966006)(2616005)(55016002)(16526019)(82740400003)(186003)(26005)(83380400001)(426003)(6636002)(356005)(5660300002)(316002)(2906002)(4326008)(6286002)(336012)(8676002)(7636003)(6862004)(36906005)(7696005)(86362001)(30864003)(1076003)(47076005)(70206006)(478600001)(8936002)(54906003)(82310400003)(37006003)(36860700001)(36756003)(70586007);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "19 Jul 2021 02:54:57.0686 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 8974311c-6766-491a-50f6-08d94a6097b7",
        "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 CO1NAM11FT048.eop-nam11.prod.protection.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "BL1PR12MB5380",
        "Subject": "[dpdk-dev] [PATCH v3 02/15] 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>\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             | 362 +++++++++++++++++-\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, 687 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 1b38b1aa51..768e5362f8 100644\n--- a/doc/guides/rel_notes/release_21_08.rst\n+++ b/doc/guides/rel_notes/release_21_08.rst\n@@ -125,6 +125,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..8734081a6e 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,361 @@ 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+};\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 +413,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 +572,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 e8cd5182ac..a2a69ebf5e 100644\n--- a/drivers/common/mlx5/mlx5_common.h\n+++ b/drivers/common/mlx5/mlx5_common.h\n@@ -244,4 +244,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 1e3c1de12d..f2d2015f9d 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@@ -284,8 +292,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@@ -338,7 +346,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@@ -354,8 +362,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@@ -387,8 +395,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@@ -421,10 +429,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@@ -488,7 +496,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@@ -504,6 +512,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@@ -522,6 +531,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@@ -537,7 +641,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@@ -546,8 +650,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": [
        "v3",
        "02/15"
    ]
}