get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 133671,
    "url": "http://patchwork.dpdk.org/api/patches/133671/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20231031142733.2009166-7-dsosnowski@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": "<20231031142733.2009166-7-dsosnowski@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231031142733.2009166-7-dsosnowski@nvidia.com",
    "date": "2023-10-31T14:27:31",
    "name": "[6/8] net/mlx5: support port probing of Multiport E-Switch device",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "39c59cbbdd25f0c48e99ba7bbed013500e0b664d",
    "submitter": {
        "id": 2386,
        "url": "http://patchwork.dpdk.org/api/people/2386/?format=api",
        "name": "Dariusz Sosnowski",
        "email": "dsosnowski@nvidia.com"
    },
    "delegate": {
        "id": 3268,
        "url": "http://patchwork.dpdk.org/api/users/3268/?format=api",
        "username": "rasland",
        "first_name": "Raslan",
        "last_name": "Darawsheh",
        "email": "rasland@nvidia.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20231031142733.2009166-7-dsosnowski@nvidia.com/mbox/",
    "series": [
        {
            "id": 30075,
            "url": "http://patchwork.dpdk.org/api/series/30075/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=30075",
            "date": "2023-10-31T14:27:26",
            "name": "net/mlx5: add Multiport E-Switch support",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/30075/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/133671/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/133671/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 0879843252;\n\tTue, 31 Oct 2023 15:28:38 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 7CE6940ED9;\n\tTue, 31 Oct 2023 15:28:23 +0100 (CET)",
            "from NAM11-BN8-obe.outbound.protection.outlook.com\n (mail-bn8nam11on2040.outbound.protection.outlook.com [40.107.236.40])\n by mails.dpdk.org (Postfix) with ESMTP id A58C540E54\n for <dev@dpdk.org>; Tue, 31 Oct 2023 15:28:20 +0100 (CET)",
            "from DS7PR03CA0288.namprd03.prod.outlook.com (2603:10b6:5:3ad::23)\n by DS0PR12MB8044.namprd12.prod.outlook.com (2603:10b6:8:148::14) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6933.28; Tue, 31 Oct\n 2023 14:28:18 +0000",
            "from CY4PEPF0000EDD3.namprd03.prod.outlook.com\n (2603:10b6:5:3ad:cafe::25) by DS7PR03CA0288.outlook.office365.com\n (2603:10b6:5:3ad::23) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6933.29 via Frontend\n Transport; Tue, 31 Oct 2023 14:28:17 +0000",
            "from mail.nvidia.com (216.228.117.161) by\n CY4PEPF0000EDD3.mail.protection.outlook.com (10.167.241.207) with Microsoft\n SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.6954.19 via Frontend Transport; Tue, 31 Oct 2023 14:28:17 +0000",
            "from rnnvmail201.nvidia.com (10.129.68.8) by mail.nvidia.com\n (10.129.200.67) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.41; Tue, 31 Oct\n 2023 07:28:06 -0700",
            "from nvidia.com (10.126.231.35) by rnnvmail201.nvidia.com\n (10.129.68.8) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.41; Tue, 31 Oct\n 2023 07:28:03 -0700"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=K1kWGSKXIPAW2SVkZR3yzYJelkwKiQMccO9EXlwUfVAi474isoG/a2R+z3n1jM/F1SbN2LY6WhEuQ+jRirjlVGRuJIs8NptY0Vf7xdFoGb2YGDLqC8Oo7f+gzyORr+yTQAK9jIDdmpUR2dkXs8Nfss6+bk4tV+B9SttAGtmXv40a1cS+T7xruTWdAwtAMdbDY0Yag21NxE5vfkzMtb3sEEbaTAX0gyG01HAeRKVi1tp9OSO2rBbGuHfnsouQMk2uOqu2jlu5yO3Iw3ry9estV8DugbliC+Ekr++yMnPi9UoNQJrqEahZdoLyMFHipEomZbMWVUsY/nzH4HrGA4ogYA==",
        "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=jjgZdKTBjxgmIKtarOxCKhf8ybBmBW2FY07G8GM5nQM=;\n b=KkG633QnvOZHJlf15utxQOCzT8QX6DIwn4sW5o5bTRKitjjLzykabrVIK6atCEOdwIYaJgn0KxPtk2BpqRT2O3luSHnoLrFrcbriK9reRxE3wznZTkwJa4L2ZhDfBbLHb/Vg8X1pE5iea4Rz7//OZf/HYMRRz1sZGyMLHrUnsj2WUldprmnkqGGRFmf2+oqv5B3f6fSiqRWATHjQqPjsSqYDKBPa19wZeclkjZdW/TEj7frTMSVM1/yU1po09sj/NTzWSbXGxKsyDW+Kk3h6n7d7Vi3T/r62x4VeDPD43OWPxLR2IJL15oM127dtWnNLGryfG/YGtyhg09ZYe4zcbg==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 216.228.117.161) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com;\n dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com;\n dkim=none (message not signed); arc=none (0)",
        "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=jjgZdKTBjxgmIKtarOxCKhf8ybBmBW2FY07G8GM5nQM=;\n b=Jxw3IcNoKujFrt8rFBPsB3mJmdFt50uWsSlqgC3zxugHiiDATbD/Omz0spMy6R0fEFsKT9N1bQZHQIjHBkG0T/dGFoEAeDmHq3qqoe/1w1Kp8ihcCMcGuBdxiW7CQV87LkuKff3/F9sT0XCXacY2XfhTlIqdpOi0MmVm+8fePTQECYdXZA+TbRfOHWn9rC/lyjh7sIP1m8r594j4Ox8gHwKX0AekbAxp9G2G11PaxJL2NGrqOBloYD31k59o9C2oOI0KF0S6kvI416nvrc5M2Y7UQF18/InBla/WImU+8pbNlDNeavSqj964pIg1f6EnZi//zGfhRqqrwhaxjEJ37w==",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 216.228.117.161)\n smtp.mailfrom=nvidia.com;\n dkim=none (message not signed)\n header.d=none;dmarc=pass action=none header.from=nvidia.com;",
        "Received-SPF": "Pass (protection.outlook.com: domain of nvidia.com designates\n 216.228.117.161 as permitted sender) receiver=protection.outlook.com;\n client-ip=216.228.117.161; helo=mail.nvidia.com; pr=C",
        "From": "Dariusz Sosnowski <dsosnowski@nvidia.com>",
        "To": "Matan Azrad <matan@nvidia.com>, Viacheslav Ovsiienko\n <viacheslavo@nvidia.com>, Ori Kam <orika@nvidia.com>, Suanming Mou\n <suanmingm@nvidia.com>",
        "CC": "<dev@dpdk.org>, Raslan Darawsheh <rasland@nvidia.com>, Bing Zhao\n <bingz@nvidia.com>",
        "Subject": "[PATCH 6/8] net/mlx5: support port probing of Multiport E-Switch\n device",
        "Date": "Tue, 31 Oct 2023 16:27:31 +0200",
        "Message-ID": "<20231031142733.2009166-7-dsosnowski@nvidia.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20231031142733.2009166-1-dsosnowski@nvidia.com>",
        "References": "<20231031142733.2009166-1-dsosnowski@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.126.231.35]",
        "X-ClientProxiedBy": "rnnvmail202.nvidia.com (10.129.68.7) To\n rnnvmail201.nvidia.com (10.129.68.8)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "CY4PEPF0000EDD3:EE_|DS0PR12MB8044:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "ade21f74-67c6-4af9-1434-08dbda1da031",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n 9p1esC9Hf2HO0XbhlDrrOlqWWJAKKi6NZ34GQQPP1s+Ng+BuLRQe0mSaVV1ahuZfhYOLJLz6LTZIXXRmIyQK20dg45nza68lAfDezrIVQb/YhfzJ9oWRxzzXD7ZGorOLnbsTtV8lurWcTg+sPnHB3UzK1ypKnhyoLX6IQRHlUmeIXvbBPGplUJSV2bcqEfju4VDYAaXAltfJzobUxC4j0d4xQ1X/TVAeiq9tuhJpSkS/+kWB5tcto0SXr5y992O4GcQ0yb33hBubBVWUcSaWMtKJZ5DDUVepH5WQ6g5IczFNpcJZRq43+A/I5e1qhmSPgznVgeemWgrGhGJ5zsvKaYhJeAjotmeD9sSqy8oLm+ZpjwGVuk02Fu33/kQRw2HlmQ60g8TfxcDPC2Fenv2QPY6j9uFHL7WorF1IkHW0V/TIfm5iW8pRizp/U/65BNVNoX9iEaL738TecSwLCC9qlNDUg3qbrhslfQUv85WOlIt8O5WTULyUU73W/U57UsPrwItJ9wC2+yCp5oRR8J29DxLXZ/X3H6oB2sGYQCZpvIOJjGVZ5YvhnlWw6QkdMbYU+wlCFsULd9RTfy0Xn98JCKGT1/Q73ut9sFqGcJHYBFQYY9AzZ30327VTe5hlxvzYsFeQDyfw7ALXRyqajVEqAgNHE5O4pUMfNw3ShfRU6PohsbAdPdnJ7doi9YvF+ivlRnGlqN2v4KUr27RIrOd9GdGFPwHfpQDkZKCcvPB2JmQeXwPI3AP1Bm4Ghkg0rC2LK/4yrXhq9UZinuzTLcQbg1MudYycrpRAJvnADtKgLDRttiO40WE+XsvJ4Wph7R04",
        "X-Forefront-Antispam-Report": "CIP:216.228.117.161; CTRY:US; LANG:en; SCL:1;\n SRV:;\n IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:dc6edge2.nvidia.com; CAT:NONE;\n SFS:(13230031)(4636009)(346002)(39860400002)(136003)(376002)(396003)(230173577357003)(230922051799003)(230273577357003)(451199024)(1800799009)(82310400011)(64100799003)(186009)(36840700001)(46966006)(40470700004)(40480700001)(55016003)(40460700003)(6286002)(2616005)(1076003)(26005)(16526019)(478600001)(6666004)(7696005)(36860700001)(426003)(336012)(47076005)(83380400001)(2906002)(70586007)(110136005)(41300700001)(70206006)(107886003)(8676002)(4326008)(54906003)(316002)(6636002)(5660300002)(8936002)(356005)(7636003)(82740400003)(86362001)(36756003)(30864003)(309714004);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "31 Oct 2023 14:28:17.8442 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n ade21f74-67c6-4af9-1434-08dbda1da031",
        "X-MS-Exchange-CrossTenant-Id": "43083d15-7273-40c1-b7db-39efd9ccc17a",
        "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.117.161];\n Helo=[mail.nvidia.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n CY4PEPF0000EDD3.namprd03.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "DS0PR12MB8044",
        "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": "This patch adds support for probing ports of a Multiport\nE-Switch device to mlx5 PMD.\n\nMultiport E-Switch is a configuration of NVIDIA ConnectX/BlueField HCAs\nwhere all connected entities (i.e. physical ports, VFs and SFs)\nshare the same switch domain.\nIn this mode, applications are allowed to create transfer flow rules\nwhich explicitly match on the physical port on which traffic\narrives and/or on VFs and SFs, regardless of the root PF.\nOn top of that, forwarding to any of these entities is allowed.\nNotably, applications are allowed to explicitly forward traffic\nto any of the physical ports of the HCA.\n\nThis patch implements the following procedure for probing ports\nof the device configured as Multiport E-Switch:\n\n1. EAL calls mlx5 PMD to probe certain PCI device (with address BDF).\n2. mlx5 PMD iterates over all existing IB devices:\n   2.1. Check if IB device has a PCI address which matches BDF.\n   2.2. Check if IB device is configured as Multiport E-Switch device,\n        using devlink interface.\n   2.3. Iterate over all IB ports of this device to find a netdev with\n        matching PCI address.\n        If any is found, IB device is chosen to instantiate DPDK ports\n        from it.\n3. Iterate over all IB ports of the selected IB device,\n   to choose which ports to instantiate:\n   3.1. Choose IB ports which match the selected representor ports\n        (selected through representor devarg).\n        Instantiate DPDK ports based on those.\n   3.2. If IB port represented an uplink port and this port corresponds\n        to the probed PCI device, instantiated DPDK port is selected\n        as a switch master port.\n\nBulk of this work was done in mlx5_os_pci_probe_pf().\n\nTo properly enable support for Multiport E-Switch, this patch also\nchanges the following:\n\n- Probing of representors of type RTE_ETH_REPRESENTOR_PF is allowed,\n  but if and only if Multiport E-Switch is enabled.\n- Uplink ports have a representor type NONE and have\n  representor ID equal to UINT16_MAX.\n  rte_eth_dev_representor_info struct returned for uplink ports\n  have their index stored in `pf` field.\n- flow_hw_set_port_info() used by HWS steering layer sets `is_wire`\n  field to true if a port is an uplink port,\n  if Multiport E-Switch is enabled.\n- Changing MAC address of a port marked as representor is done directly\n  through its corresponding netdev if it is a Multiport E-Switch uplink.\n\nSigned-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>\nSigned-off-by: Bing Zhao <bingz@nvidia.com>\nAcked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>\n---\n doc/guides/nics/mlx5.rst               | 141 ++++++++++++++\n doc/guides/rel_notes/release_23_11.rst |   1 +\n drivers/common/mlx5/mlx5_common.h      |   1 +\n drivers/net/mlx5/linux/mlx5_os.c       | 255 ++++++++++++++++++++++---\n drivers/net/mlx5/mlx5.h                |  39 ++++\n drivers/net/mlx5/mlx5_ethdev.c         |  53 ++++-\n drivers/net/mlx5/mlx5_flow_hw.c        |   4 +-\n drivers/net/mlx5/mlx5_mac.c            |   8 +-\n 8 files changed, 464 insertions(+), 38 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst\nindex be5054e68a..584f592433 100644\n--- a/doc/guides/nics/mlx5.rst\n+++ b/doc/guides/nics/mlx5.rst\n@@ -1759,6 +1759,147 @@ behavior as librte_net_mlx4::\n    > port config all rss all\n    > port start all\n \n+\n+Multiport E-Switch\n+------------------\n+\n+In standard deployments of NVIDIA ConnectX and BlueField HCAs, where embedded switch is enabled,\n+each physical port is associated with a single switching domain.\n+Only PFs, VFs and SFs related to that physical port are connected to this domain\n+and offloaded flow rules are allowed to steer traffic only between the entities in the given domain.\n+\n+The following diagram pictures the high level overview of this architecture:\n+\n+::\n+\n+       .---. .------. .------. .---. .------. .------.\n+       |PF0| |PF0VFi| |PF0SFi| |PF1| |PF1VFi| |PF1SFi|\n+       .-+-. .--+---. .--+---. .-+-. .--+---. .--+---.\n+         |      |        |       |      |        |\n+     .---|------|--------|-------|------|--------|---------.\n+     |   |      |        |       |      |        |      HCA|\n+     | .-+------+--------+---. .-+------+--------+---.     |\n+     | |                     | |                     |     |\n+     | |      E-Switch       | |     E-Switch        |     |\n+     | |         PF0         | |        PF1          |     |\n+     | |                     | |                     |     |\n+     | .---------+-----------. .--------+------------.     |\n+     |           |                      |                  |\n+     .--------+--+---+---------------+--+---+--------------.\n+              |      |               |      |\n+              | PHY0 |               | PHY1 |\n+              |      |               |      |\n+              .------.               .------.\n+\n+Multiport E-Switch is a deployment scenario where:\n+\n+- All physical ports, PFs, VFs and SFs share the same switching domain.\n+- Each physical port gets a separate representor port.\n+- Traffic can be matched or forwarded explicitly between any of the entities\n+  connected to the domain.\n+\n+The following diagram pictures the high level overview of this architecture:\n+\n+::\n+\n+\n+       .---. .------. .------. .---. .------. .------.\n+       |PF0| |PF0VFi| |PF0SFi| |PF1| |PF1VFi| |PF1SFi|\n+       .-+-. .--+---. .--+---. .-+-. .--+---. .--+---.\n+         |      |        |       |      |        |\n+     .---|------|--------|-------|------|--------|---------.\n+     |   |      |        |       |      |        |      HCA|\n+     | .-+------+--------+-------+------+--------+---.     |\n+     | |                                             |     |\n+     | |                   Shared                    |     |\n+     | |                  E-Switch                   |     |\n+     | |                                             |     |\n+     | .---------+----------------------+------------.     |\n+     |           |                      |                  |\n+     .--------+--+---+---------------+--+---+--------------.\n+              |      |               |      |\n+              | PHY0 |               | PHY1 |\n+              |      |               |      |\n+              .------.               .------.\n+\n+\n+In this deployment a single application can control the switching and forwarding behavior for all\n+entities on the HCA.\n+\n+With this configuration, mlx5 PMD supports:\n+\n+- matching traffic coming from physical port, PF, VF or SF using REPRESENTED_PORT items;\n+- forwarding traffic to physical port, PF, VF or SF using REPRESENTED_PORT actions;\n+\n+\n+Requirements\n+~~~~~~~~~~~~\n+\n+Supported HCAs:\n+\n+- ConnectX family: ConnectX-6 Dx and above.\n+- BlueField family: BlueField-2 and above.\n+- FW version: at least ``XX.37.1014``.\n+\n+Supported mlx5 kernel modules versions:\n+\n+- Upstream Linux - from version 6.3.\n+- Modules packaged in MLNX_OFED - from version v23.04-0.5.3.3.\n+\n+\n+Configuration\n+~~~~~~~~~~~~~\n+\n+#. Apply required FW configuration::\n+\n+      sudo mlxconfig -d /dev/mst/mt4125_pciconf0 set LAG_RESOURCE_ALLOCATION=1\n+\n+#. Reset FW or cold reboot the host.\n+#. Switch E-Switch mode on all of the PFs to ``switchdev`` mode::\n+\n+      sudo devlink dev eswitch set pci/0000:08:00.0 mode switchdev\n+      sudo devlink dev eswitch set pci/0000:08:00.1 mode switchdev\n+\n+#. Enable Multiport E-Switch on all of the PFs::\n+\n+      sudo devlink dev param set pci/0000:08:00.0 name esw_multiport value true cmode runtime\n+      sudo devlink dev param set pci/0000:08:00.1 name esw_multiport value true cmode runtime\n+\n+#. Configure required number of VFs/SFs::\n+\n+      echo 4 | sudo tee /sys/class/net/eth2/device/sriov_numvfs\n+      echo 4 | sudo tee /sys/class/net/eth3/device/sriov_numvfs\n+\n+#. Start testpmd and verify that all ports are visible::\n+\n+      $ sudo dpdk-testpmd -a 08:00.0,dv_flow_en=2,representor=pf0-1vf0-3 -- -i\n+      testpmd> show port summary all\n+      Number of available ports: 10\n+      Port MAC Address       Name         Driver         Status   Link\n+      0    E8:EB:D5:18:22:BC 08:00.0_p0   mlx5_pci       up       200 Gbps\n+      1    E8:EB:D5:18:22:BD 08:00.0_p1   mlx5_pci       up       200 Gbps\n+      2    D2:F6:43:0B:9E:19 08:00.0_representor_c0pf0vf0 mlx5_pci       up       200 Gbps\n+      3    E6:42:27:B7:68:BD 08:00.0_representor_c0pf0vf1 mlx5_pci       up       200 Gbps\n+      4    A6:5B:7F:8B:B8:47 08:00.0_representor_c0pf0vf2 mlx5_pci       up       200 Gbps\n+      5    12:93:50:45:89:02 08:00.0_representor_c0pf0vf3 mlx5_pci       up       200 Gbps\n+      6    06:D3:B2:79:FE:AC 08:00.0_representor_c0pf1vf0 mlx5_pci       up       200 Gbps\n+      7    12:FC:08:E4:C2:CA 08:00.0_representor_c0pf1vf1 mlx5_pci       up       200 Gbps\n+      8    8E:A9:9A:D0:35:4C 08:00.0_representor_c0pf1vf2 mlx5_pci       up       200 Gbps\n+      9    E6:35:83:1F:B0:A9 08:00.0_representor_c0pf1vf3 mlx5_pci       up       200 Gbps\n+\n+\n+Limitations\n+~~~~~~~~~~~\n+\n+- Multiport E-Switch is not supported on Windows.\n+- Multiport E-Switch is supported only with HW Steering flow engine (``dv_flow_en=2``).\n+- Matching traffic coming from a physical port and forwarding it to a physical port\n+  (either the same or other one) is not supported.\n+\n+  In order to achieve such a functionality, an application has to setup hairpin queues between\n+  physical port representors and forward the traffic using hairpin queues.\n+\n+\n Usage example\n -------------\n \ndiff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst\nindex 93999893bd..f337db19f0 100644\n--- a/doc/guides/rel_notes/release_23_11.rst\n+++ b/doc/guides/rel_notes/release_23_11.rst\n@@ -157,6 +157,7 @@ New Features\n   * Added support for ``RTE_FLOW_ACTION_TYPE_INDIRECT_LIST`` flow action.\n   * Added support for ``RTE_FLOW_ITEM_TYPE_PTYPE`` flow item.\n   * Added support for ``RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR`` flow action and mirror.\n+  * Added support for Multiport E-Switch.\n \n * **Updated Solarflare net driver.**\n \ndiff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h\nindex 28f9f41528..9c80277d74 100644\n--- a/drivers/common/mlx5/mlx5_common.h\n+++ b/drivers/common/mlx5/mlx5_common.h\n@@ -169,6 +169,7 @@ struct mlx5_switch_info {\n \tint32_t ctrl_num; /**< Controller number (valid for c#pf#vf# format). */\n \tint32_t pf_num; /**< PF number (valid for pfxvfx format only). */\n \tint32_t port_name; /**< Representor port name. */\n+\tint32_t mpesw_owner; /**< MPESW owner port number. */\n \tuint64_t switch_id; /**< Switch identifier. */\n };\n \ndiff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c\nindex 8a57edc470..8ddf38288e 100644\n--- a/drivers/net/mlx5/linux/mlx5_os.c\n+++ b/drivers/net/mlx5/linux/mlx5_os.c\n@@ -959,7 +959,30 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,\n \tuint16_t repr_id = mlx5_representor_id_encode(switch_info,\n \t\t\t\t\t\t      eth_da->type);\n \n+\t/*\n+\t * Assuming Multiport E-Switch device was detected,\n+\t * if spawned port is an uplink, check if the port\n+\t * was requested through representor devarg.\n+\t */\n+\tif (mlx5_is_probed_port_on_mpesw_device(spawn) &&\n+\t    switch_info->name_type == MLX5_PHYS_PORT_NAME_TYPE_UPLINK) {\n+\t\tfor (p = 0; p < eth_da->nb_ports; ++p)\n+\t\t\tif (switch_info->port_name == eth_da->ports[p])\n+\t\t\t\treturn true;\n+\t\trte_errno = EBUSY;\n+\t\treturn false;\n+\t}\n \tswitch (eth_da->type) {\n+\tcase RTE_ETH_REPRESENTOR_PF:\n+\t\t/*\n+\t\t * PF representors provided in devargs translate to uplink ports, but\n+\t\t * if and only if the device is a part of MPESW device.\n+\t\t */\n+\t\tif (!mlx5_is_probed_port_on_mpesw_device(spawn)) {\n+\t\t\trte_errno = EBUSY;\n+\t\t\treturn false;\n+\t\t}\n+\t\tbreak;\n \tcase RTE_ETH_REPRESENTOR_SF:\n \t\tif (!(spawn->info.port_name == -1 &&\n \t\t      switch_info->name_type ==\n@@ -989,7 +1012,7 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,\n \t}\n \t/* Check representor ID: */\n \tfor (p = 0; p < eth_da->nb_ports; ++p) {\n-\t\tif (spawn->pf_bond < 0) {\n+\t\tif (!mlx5_is_probed_port_on_mpesw_device(spawn) && spawn->pf_bond < 0) {\n \t\t\t/* For non-LAG mode, allow and ignore pf. */\n \t\t\tswitch_info->pf_num = eth_da->ports[p];\n \t\t\trepr_id = mlx5_representor_id_encode(switch_info,\n@@ -1051,17 +1074,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,\n \t    !mlx5_representor_match(spawn, eth_da))\n \t\treturn NULL;\n \t/* Build device name. */\n-\tif (spawn->pf_bond < 0) {\n-\t\t/* Single device. */\n-\t\tif (!switch_info->representor)\n-\t\t\tstrlcpy(name, dpdk_dev->name, sizeof(name));\n-\t\telse\n-\t\t\terr = snprintf(name, sizeof(name), \"%s_representor_%s%u\",\n-\t\t\t\t dpdk_dev->name,\n-\t\t\t\t switch_info->name_type ==\n-\t\t\t\t MLX5_PHYS_PORT_NAME_TYPE_PFSF ? \"sf\" : \"vf\",\n-\t\t\t\t switch_info->port_name);\n-\t} else {\n+\tif (spawn->pf_bond >= 0) {\n \t\t/* Bonding device. */\n \t\tif (!switch_info->representor) {\n \t\t\terr = snprintf(name, sizeof(name), \"%s_%s\",\n@@ -1075,6 +1088,30 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,\n \t\t\t\tMLX5_PHYS_PORT_NAME_TYPE_PFSF ? \"sf\" : \"vf\",\n \t\t\t\tswitch_info->port_name);\n \t\t}\n+\t} else if (mlx5_is_probed_port_on_mpesw_device(spawn)) {\n+\t\t/* MPESW device. */\n+\t\tif (switch_info->name_type == MLX5_PHYS_PORT_NAME_TYPE_UPLINK) {\n+\t\t\terr = snprintf(name, sizeof(name), \"%s_p%d\",\n+\t\t\t\t       dpdk_dev->name, spawn->mpesw_port);\n+\t\t} else {\n+\t\t\terr = snprintf(name, sizeof(name), \"%s_representor_c%dpf%d%s%u\",\n+\t\t\t\tdpdk_dev->name,\n+\t\t\t\tswitch_info->ctrl_num,\n+\t\t\t\tswitch_info->pf_num,\n+\t\t\t\tswitch_info->name_type ==\n+\t\t\t\tMLX5_PHYS_PORT_NAME_TYPE_PFSF ? \"sf\" : \"vf\",\n+\t\t\t\tswitch_info->port_name);\n+\t\t}\n+\t} else {\n+\t\t/* Single device. */\n+\t\tif (!switch_info->representor)\n+\t\t\tstrlcpy(name, dpdk_dev->name, sizeof(name));\n+\t\telse\n+\t\t\terr = snprintf(name, sizeof(name), \"%s_representor_%s%u\",\n+\t\t\t\t dpdk_dev->name,\n+\t\t\t\t switch_info->name_type ==\n+\t\t\t\t MLX5_PHYS_PORT_NAME_TYPE_PFSF ? \"sf\" : \"vf\",\n+\t\t\t\t switch_info->port_name);\n \t}\n \tif (err >= (int)sizeof(name))\n \t\tDRV_LOG(WARNING, \"device name overflow %s\", name);\n@@ -1202,13 +1239,25 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,\n \tpriv->vport_meta_tag = 0;\n \tpriv->vport_meta_mask = 0;\n \tpriv->pf_bond = spawn->pf_bond;\n+\tpriv->mpesw_port = spawn->mpesw_port;\n+\tpriv->mpesw_uplink = false;\n+\tpriv->mpesw_owner = spawn->info.mpesw_owner;\n+\tif (mlx5_is_port_on_mpesw_device(priv))\n+\t\tpriv->mpesw_uplink = (spawn->info.name_type == MLX5_PHYS_PORT_NAME_TYPE_UPLINK);\n \n \tDRV_LOG(DEBUG,\n-\t\t\"dev_port=%u bus=%s pci=%s master=%d representor=%d pf_bond=%d\\n\",\n+\t\t\"dev_port=%u bus=%s pci=%s master=%d representor=%d pf_bond=%d \"\n+\t\t\"mpesw_port=%d mpesw_uplink=%d\",\n \t\tpriv->dev_port, dpdk_dev->bus->name,\n \t\tpriv->pci_dev ? priv->pci_dev->name : \"NONE\",\n-\t\tpriv->master, priv->representor, priv->pf_bond);\n+\t\tpriv->master, priv->representor, priv->pf_bond,\n+\t\tpriv->mpesw_port, priv->mpesw_uplink);\n \n+\tif (mlx5_is_port_on_mpesw_device(priv) && priv->sh->config.dv_flow_en != 2) {\n+\t\tDRV_LOG(ERR, \"MPESW device is supported only with HWS\");\n+\t\terr = ENOTSUP;\n+\t\tgoto error;\n+\t}\n \t/*\n \t * If we have E-Switch we should determine the vport attributes.\n \t * E-Switch may use either source vport field or reg_c[0] metadata\n@@ -2029,7 +2078,7 @@ mlx5_sysfs_esw_multiport_get(struct ibv_device *ibv, struct rte_pci_addr *pci_ad\n \treturn ret;\n }\n \n-static __rte_unused int\n+static int\n mlx5_is_mpesw_enabled(struct ibv_device *ibv, struct rte_pci_addr *ibv_pci_addr, int *enabled)\n {\n \t/*\n@@ -2049,6 +2098,84 @@ mlx5_is_mpesw_enabled(struct ibv_device *ibv, struct rte_pci_addr *ibv_pci_addr,\n \treturn -rte_errno;\n }\n \n+static int\n+mlx5_device_mpesw_pci_match(struct ibv_device *ibv,\n+\t\t\t    const struct rte_pci_addr *owner_pci,\n+\t\t\t    int nl_rdma)\n+{\n+\tstruct rte_pci_addr ibdev_pci_addr = { 0 };\n+\tchar ifname[IF_NAMESIZE + 1] = { 0 };\n+\tunsigned int ifindex;\n+\tunsigned int np;\n+\tunsigned int i;\n+\tint enabled = 0;\n+\tint ret;\n+\n+\t/* Check if IB device's PCI address matches the probed PCI address. */\n+\tif (mlx5_get_pci_addr(ibv->ibdev_path, &ibdev_pci_addr)) {\n+\t\tDRV_LOG(DEBUG, \"Skipping MPESW check for IB device %s since \"\n+\t\t\t       \"there is no underlying PCI device\", ibv->name);\n+\t\trte_errno = ENOENT;\n+\t\treturn -rte_errno;\n+\t}\n+\tif (ibdev_pci_addr.domain != owner_pci->domain ||\n+\t    ibdev_pci_addr.bus != owner_pci->bus ||\n+\t    ibdev_pci_addr.devid != owner_pci->devid ||\n+\t    ibdev_pci_addr.function != owner_pci->function) {\n+\t\treturn -1;\n+\t}\n+\t/* Check if IB device has MPESW enabled. */\n+\tif (mlx5_is_mpesw_enabled(ibv, &ibdev_pci_addr, &enabled))\n+\t\treturn -1;\n+\tif (!enabled)\n+\t\treturn -1;\n+\t/* Iterate through IB ports to find MPESW master uplink port. */\n+\tif (nl_rdma < 0)\n+\t\treturn -1;\n+\tnp = mlx5_nl_portnum(nl_rdma, ibv->name);\n+\tif (!np)\n+\t\treturn -1;\n+\tfor (i = 1; i <= np; ++i) {\n+\t\tstruct rte_pci_addr pci_addr;\n+\t\tFILE *file;\n+\t\tchar port_name[IF_NAMESIZE + 1];\n+\t\tstruct mlx5_switch_info\tinfo;\n+\n+\t\t/* Check whether IB port has a corresponding netdev. */\n+\t\tifindex = mlx5_nl_ifindex(nl_rdma, ibv->name, i);\n+\t\tif (!ifindex)\n+\t\t\tcontinue;\n+\t\tif (!if_indextoname(ifindex, ifname))\n+\t\t\tcontinue;\n+\t\t/* Read port name and determine its type. */\n+\t\tMKSTR(ifphysportname, \"/sys/class/net/%s/phys_port_name\", ifname);\n+\t\tfile = fopen(ifphysportname, \"rb\");\n+\t\tif (!file)\n+\t\t\tcontinue;\n+\t\tret = fscanf(file, \"%16s\", port_name);\n+\t\tfclose(file);\n+\t\tif (ret != 1)\n+\t\t\tcontinue;\n+\t\tmemset(&info, 0, sizeof(info));\n+\t\tmlx5_translate_port_name(port_name, &info);\n+\t\tif (info.name_type != MLX5_PHYS_PORT_NAME_TYPE_UPLINK)\n+\t\t\tcontinue;\n+\t\t/* Fetch PCI address of the device to which the netdev is bound. */\n+\t\tMKSTR(ifpath, \"/sys/class/net/%s\", ifname);\n+\t\tif (mlx5_get_pci_addr(ifpath, &pci_addr))\n+\t\t\tcontinue;\n+\t\tif (pci_addr.domain == ibdev_pci_addr.domain &&\n+\t\t    pci_addr.bus == ibdev_pci_addr.bus &&\n+\t\t    pci_addr.devid == ibdev_pci_addr.devid &&\n+\t\t    pci_addr.function == ibdev_pci_addr.function) {\n+\t\t\tMLX5_ASSERT(info.port_name >= 0);\n+\t\t\treturn info.port_name;\n+\t\t}\n+\t}\n+\t/* No matching MPESW uplink port was found. */\n+\treturn -1;\n+}\n+\n /**\n  * Register a PCI device within bonding.\n  *\n@@ -2097,6 +2224,12 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,\n \t *  >= 0 - bonding device (value is slave PF index)\n \t */\n \tint bd = -1;\n+\t/*\n+\t * Multiport E-Switch (MPESW) device:\n+\t *   < 0 - no MPESW device or could not determine if it is MPESW device,\n+\t *  >= 0 - MPESW device. Value is the port index of the MPESW owner.\n+\t */\n+\tint mpesw = MLX5_MPESW_PORT_INVALID;\n \tstruct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev);\n \tstruct mlx5_dev_spawn_data *list = NULL;\n \tstruct rte_eth_devargs eth_da = *req_eth_da;\n@@ -2150,17 +2283,38 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,\n \t\t\t\tbd, ibv_list[ret]->name);\n \t\t\tibv_match[nd++] = ibv_list[ret];\n \t\t\tbreak;\n-\t\t} else {\n-\t\t\t/* Bonding device not found. */\n-\t\t\tif (mlx5_get_pci_addr(ibv_list[ret]->ibdev_path,\n-\t\t\t\t\t      &pci_addr))\n-\t\t\t\tcontinue;\n-\t\t\tif (rte_pci_addr_cmp(&owner_pci, &pci_addr) != 0)\n-\t\t\t\tcontinue;\n-\t\t\tDRV_LOG(INFO, \"PCI information matches for device \\\"%s\\\"\",\n+\t\t}\n+\t\tmpesw = mlx5_device_mpesw_pci_match(ibv_list[ret], &owner_pci, nl_rdma);\n+\t\tif (mpesw >= 0) {\n+\t\t\t/*\n+\t\t\t * MPESW device detected. Only one matching IB device is allowed,\n+\t\t\t * so if any matches were found previously, fail gracefully.\n+\t\t\t */\n+\t\t\tif (nd) {\n+\t\t\t\tDRV_LOG(ERR,\n+\t\t\t\t\t\"PCI information matches MPESW device \\\"%s\\\", \"\n+\t\t\t\t\t\"but multiple matching PCI devices were found. \"\n+\t\t\t\t\t\"Probing failed.\",\n+\t\t\t\t\tibv_list[ret]->name);\n+\t\t\t\trte_errno = ENOENT;\n+\t\t\t\tret = -rte_errno;\n+\t\t\t\tgoto exit;\n+\t\t\t}\n+\t\t\tDRV_LOG(INFO,\n+\t\t\t\t\"PCI information matches MPESW device \\\"%s\\\"\",\n \t\t\t\tibv_list[ret]->name);\n \t\t\tibv_match[nd++] = ibv_list[ret];\n+\t\t\tbreak;\n \t\t}\n+\t\t/* Bonding or MPESW device was not found. */\n+\t\tif (mlx5_get_pci_addr(ibv_list[ret]->ibdev_path,\n+\t\t\t\t\t&pci_addr))\n+\t\t\tcontinue;\n+\t\tif (rte_pci_addr_cmp(&owner_pci, &pci_addr) != 0)\n+\t\t\tcontinue;\n+\t\tDRV_LOG(INFO, \"PCI information matches for device \\\"%s\\\"\",\n+\t\t\tibv_list[ret]->name);\n+\t\tibv_match[nd++] = ibv_list[ret];\n \t}\n \tibv_match[nd] = NULL;\n \tif (!nd) {\n@@ -2192,6 +2346,12 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,\n \t\t\tret = -rte_errno;\n \t\t\tgoto exit;\n \t\t}\n+\t\tif (mpesw >= 0 && !np) {\n+\t\t\tDRV_LOG(ERR, \"Cannot get ports for MPESW device.\");\n+\t\t\trte_errno = ENOENT;\n+\t\t\tret = -rte_errno;\n+\t\t\tgoto exit;\n+\t\t}\n \t}\n \t/* Now we can determine the maximal amount of devices to be spawned. */\n \tlist = mlx5_malloc(MLX5_MEM_ZERO,\n@@ -2203,7 +2363,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,\n \t\tret = -rte_errno;\n \t\tgoto exit;\n \t}\n-\tif (bd >= 0 || np > 1) {\n+\tif (bd >= 0 || mpesw >= 0 || np > 1) {\n \t\t/*\n \t\t * Single IB device with multiple ports found,\n \t\t * it may be E-Switch master device and representors.\n@@ -2222,6 +2382,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,\n \t\t\tlist[ns].pci_dev = pci_dev;\n \t\t\tlist[ns].cdev = cdev;\n \t\t\tlist[ns].pf_bond = bd;\n+\t\t\tlist[ns].mpesw_port = MLX5_MPESW_PORT_INVALID;\n \t\t\tlist[ns].ifindex = mlx5_nl_ifindex(nl_rdma,\n \t\t\t\t\t\t\t   ibv_match[0]->name,\n \t\t\t\t\t\t\t   i);\n@@ -2278,6 +2439,46 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,\n \t\t\t\t}\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!ret && mpesw >= 0) {\n+\t\t\t\tswitch (list[ns].info.name_type) {\n+\t\t\t\tcase MLX5_PHYS_PORT_NAME_TYPE_UPLINK:\n+\t\t\t\t\t/* Owner port is treated as master port. */\n+\t\t\t\t\tif (list[ns].info.port_name == mpesw) {\n+\t\t\t\t\t\tlist[ns].info.master = 1;\n+\t\t\t\t\t\tlist[ns].info.representor = 0;\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\tlist[ns].info.master = 0;\n+\t\t\t\t\t\tlist[ns].info.representor = 1;\n+\t\t\t\t\t}\n+\t\t\t\t\t/*\n+\t\t\t\t\t * Ports of this type have uplink port index\n+\t\t\t\t\t * encoded in the name. This index is also a PF index.\n+\t\t\t\t\t */\n+\t\t\t\t\tlist[ns].info.pf_num = list[ns].info.port_name;\n+\t\t\t\t\tlist[ns].mpesw_port = list[ns].info.port_name;\n+\t\t\t\t\tlist[ns].info.mpesw_owner = mpesw;\n+\t\t\t\t\tns++;\n+\t\t\t\t\tbreak;\n+\t\t\t\tcase MLX5_PHYS_PORT_NAME_TYPE_PFHPF:\n+\t\t\t\tcase MLX5_PHYS_PORT_NAME_TYPE_PFVF:\n+\t\t\t\tcase MLX5_PHYS_PORT_NAME_TYPE_PFSF:\n+\t\t\t\t\t/* Only spawn representors related to the probed PF. */\n+\t\t\t\t\tif (list[ns].info.pf_num == owner_id) {\n+\t\t\t\t\t\t/*\n+\t\t\t\t\t\t * Ports of this type have PF index encoded in name,\n+\t\t\t\t\t\t * which translate to the related uplink port index.\n+\t\t\t\t\t\t */\n+\t\t\t\t\t\tlist[ns].mpesw_port = list[ns].info.pf_num;\n+\t\t\t\t\t\t/* MPESW owner is also saved but not used now. */\n+\t\t\t\t\t\tlist[ns].info.mpesw_owner = mpesw;\n+\t\t\t\t\t\tns++;\n+\t\t\t\t\t}\n+\t\t\t\t\tbreak;\n+\t\t\t\tdefault:\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!ret && (list[ns].info.representor ^\n \t\t\t\t     list[ns].info.master))\n \t\t\t\tns++;\n@@ -2317,6 +2518,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,\n \t\t\tlist[ns].pci_dev = pci_dev;\n \t\t\tlist[ns].cdev = cdev;\n \t\t\tlist[ns].pf_bond = -1;\n+\t\t\tlist[ns].mpesw_port = MLX5_MPESW_PORT_INVALID;\n \t\t\tlist[ns].ifindex = 0;\n \t\t\tif (nl_rdma >= 0)\n \t\t\t\tlist[ns].ifindex = mlx5_nl_ifindex\n@@ -2597,7 +2799,10 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev,\n \t\t\tstruct mlx5_kvargs_ctrl *mkvlist)\n {\n \tstruct rte_eth_devargs eth_da = { .nb_ports = 0 };\n-\tstruct mlx5_dev_spawn_data spawn = { .pf_bond = -1 };\n+\tstruct mlx5_dev_spawn_data spawn = {\n+\t\t.pf_bond = -1,\n+\t\t.mpesw_port = MLX5_MPESW_PORT_INVALID,\n+\t};\n \tstruct rte_device *dev = cdev->dev;\n \tstruct rte_auxiliary_device *adev = RTE_DEV_TO_AUXILIARY(dev);\n \tstruct rte_eth_dev *eth_dev;\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex a20acb6ca8..484c5eb3df 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -186,12 +186,15 @@ struct mlx5_dev_cap {\n \tchar fw_ver[64]; /* Firmware version of this device. */\n };\n \n+#define MLX5_MPESW_PORT_INVALID (-1)\n+\n /** Data associated with devices to spawn. */\n struct mlx5_dev_spawn_data {\n \tuint32_t ifindex; /**< Network interface index. */\n \tuint32_t max_port; /**< Device maximal port index. */\n \tuint32_t phys_port; /**< Device physical port index. */\n \tint pf_bond; /**< bonding device PF index. < 0 - no bonding */\n+\tint mpesw_port; /**< MPESW uplink index. Valid if mpesw_owner_port >= 0. */\n \tstruct mlx5_switch_info info; /**< Switch information. */\n \tconst char *phys_dev_name; /**< Name of physical device. */\n \tstruct rte_eth_dev *eth_dev; /**< Associated Ethernet device. */\n@@ -200,6 +203,23 @@ struct mlx5_dev_spawn_data {\n \tstruct mlx5_bond_info *bond_info;\n };\n \n+/**\n+ * Check if the port requested to be probed is MPESW physical device\n+ * or a representor port.\n+ *\n+ * @param spawn\n+ *   Parameters of the probed port.\n+ *\n+ * @return\n+ *   True if the probed port is a physical device or representor in MPESW setup.\n+ *   False otherwise or MPESW was not configured.\n+ */\n+static inline bool\n+mlx5_is_probed_port_on_mpesw_device(struct mlx5_dev_spawn_data *spawn)\n+{\n+\treturn spawn->mpesw_port >= 0;\n+}\n+\n /** Data associated with socket messages. */\n struct mlx5_flow_dump_req  {\n \tuint32_t port_id; /**< There are plans in DPDK to extend port_id. */\n@@ -1768,6 +1788,9 @@ struct mlx5_priv {\n \tuint32_t vport_meta_mask; /* Used for vport index field match mask. */\n \tuint16_t representor_id; /* UINT16_MAX if not a representor. */\n \tint32_t pf_bond; /* >=0, representor owner PF index in bonding. */\n+\tint32_t mpesw_owner; /* >=0, representor owner PF index in MPESW. */\n+\tint32_t mpesw_port; /* Related port index of MPESW device. < 0 - no MPESW. */\n+\tbool mpesw_uplink; /* If true, port is an uplink port. */\n \tunsigned int if_index; /* Associated kernel network device index. */\n \t/* RX/TX queues. */\n \tunsigned int rxqs_n; /* RX queues array size. */\n@@ -1933,6 +1956,22 @@ mlx5_devx_obj_ops_en(struct mlx5_dev_ctx_shared *sh)\n \t\tsh->dev_cap.dest_tir);\n }\n \n+/**\n+ * Check if the port is either MPESW physical device or a representor port.\n+ *\n+ * @param priv\n+ *   Pointer to port's private data.\n+ *\n+ * @return\n+ *   True if the port is a physical device or representor in MPESW setup.\n+ *   False otherwise or MPESW was not configured.\n+ */\n+static inline bool\n+mlx5_is_port_on_mpesw_device(struct mlx5_priv *priv)\n+{\n+\treturn priv->mpesw_port >= 0;\n+}\n+\n /* mlx5.c */\n \n int mlx5_getenv_int(const char *);\ndiff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c\nindex 4a85415ff3..cd84960b7e 100644\n--- a/drivers/net/mlx5/mlx5_ethdev.c\n+++ b/drivers/net/mlx5/mlx5_ethdev.c\n@@ -395,18 +395,30 @@ uint16_t\n mlx5_representor_id_encode(const struct mlx5_switch_info *info,\n \t\t\t   enum rte_eth_representor_type hpf_type)\n {\n-\tenum rte_eth_representor_type type = RTE_ETH_REPRESENTOR_VF;\n+\tenum rte_eth_representor_type type;\n \tuint16_t repr = info->port_name;\n-\n-\tif (info->representor == 0)\n-\t\treturn UINT16_MAX;\n-\tif (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFSF)\n+\tint32_t pf = info->pf_num;\n+\n+\tswitch (info->name_type) {\n+\tcase MLX5_PHYS_PORT_NAME_TYPE_UPLINK:\n+\t\tif (!info->representor)\n+\t\t\treturn UINT16_MAX;\n+\t\ttype = RTE_ETH_REPRESENTOR_PF;\n+\t\tpf = info->mpesw_owner;\n+\t\tbreak;\n+\tcase MLX5_PHYS_PORT_NAME_TYPE_PFSF:\n \t\ttype = RTE_ETH_REPRESENTOR_SF;\n-\tif (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFHPF) {\n+\t\tbreak;\n+\tcase MLX5_PHYS_PORT_NAME_TYPE_PFHPF:\n \t\ttype = hpf_type;\n \t\trepr = UINT16_MAX;\n+\t\tbreak;\n+\tcase MLX5_PHYS_PORT_NAME_TYPE_PFVF:\n+\tdefault:\n+\t\ttype = RTE_ETH_REPRESENTOR_VF;\n+\t\tbreak;\n \t}\n-\treturn MLX5_REPRESENTOR_ID(info->pf_num, type, repr);\n+\treturn MLX5_REPRESENTOR_ID(pf, type, repr);\n }\n \n /**\n@@ -430,7 +442,7 @@ mlx5_representor_info_get(struct rte_eth_dev *dev,\n \t\t\t  struct rte_eth_representor_info *info)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tint n_type = 4; /* Representor types, VF, HPF@VF, SF and HPF@SF. */\n+\tint n_type = 5; /* Representor types: PF, VF, HPF@VF, SF and HPF@SF. */\n \tint n_pf = 2; /* Number of PFs. */\n \tint i = 0, pf;\n \tint n_entries;\n@@ -443,7 +455,30 @@ mlx5_representor_info_get(struct rte_eth_dev *dev,\n \t\tn_entries = info->nb_ranges_alloc;\n \n \tinfo->controller = 0;\n-\tinfo->pf = priv->pf_bond >= 0 ? priv->pf_bond : 0;\n+\tinfo->pf = 0;\n+\tif (mlx5_is_port_on_mpesw_device(priv)) {\n+\t\tinfo->pf = priv->mpesw_port;\n+\t\t/* PF range, both ports will show the same information. */\n+\t\tinfo->ranges[i].type = RTE_ETH_REPRESENTOR_PF;\n+\t\tinfo->ranges[i].controller = 0;\n+\t\tinfo->ranges[i].pf = priv->mpesw_owner + 1;\n+\t\tinfo->ranges[i].vf = 0;\n+\t\t/*\n+\t\t * The representor indexes should be the values set of \"priv->mpesw_port\".\n+\t\t * In the real case now, only 1 PF/UPLINK representor is supported.\n+\t\t * The port index will always be the value of \"owner + 1\".\n+\t\t */\n+\t\tinfo->ranges[i].id_base =\n+\t\t\tMLX5_REPRESENTOR_ID(priv->mpesw_owner, info->ranges[i].type,\n+\t\t\t\t\t    info->ranges[i].pf);\n+\t\tinfo->ranges[i].id_end =\n+\t\t\tMLX5_REPRESENTOR_ID(priv->mpesw_owner, info->ranges[i].type,\n+\t\t\t\t\t    info->ranges[i].pf);\n+\t\tsnprintf(info->ranges[i].name, sizeof(info->ranges[i].name),\n+\t\t\t \"pf%d\", info->ranges[i].pf);\n+\t\ti++;\n+\t} else if (priv->pf_bond >= 0)\n+\t\tinfo->pf = priv->pf_bond;\n \tfor (pf = 0; pf < n_pf; ++pf) {\n \t\t/* VF range. */\n \t\tinfo->ranges[i].type = RTE_ETH_REPRESENTOR_VF;\ndiff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c\nindex 977751394e..9700f0342a 100644\n--- a/drivers/net/mlx5/mlx5_flow_hw.c\n+++ b/drivers/net/mlx5/mlx5_flow_hw.c\n@@ -1331,7 +1331,7 @@ flow_hw_represented_port_compile(struct rte_eth_dev *dev,\n \tif (!priv->master)\n \t\treturn rte_flow_error_set(error, EINVAL,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n-\t\t\t\t\t  \"represented_port acton must\"\n+\t\t\t\t\t  \"represented_port action must\"\n \t\t\t\t\t  \" be used on proxy port\");\n \tif (m && !!m->port_id) {\n \t\tstruct mlx5_priv *port_priv;\n@@ -9188,7 +9188,7 @@ flow_hw_set_port_info(struct rte_eth_dev *dev)\n \tinfo = &mlx5_flow_hw_port_infos[port_id];\n \tinfo->regc_mask = priv->vport_meta_mask;\n \tinfo->regc_value = priv->vport_meta_tag;\n-\tinfo->is_wire = priv->master;\n+\tinfo->is_wire = mlx5_is_port_on_mpesw_device(priv) ? priv->mpesw_uplink : priv->master;\n }\n \n /* Clears vport tag and mask used for HWS rules. */\ndiff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c\nindex b9d1e33ac3..22a756a52b 100644\n--- a/drivers/net/mlx5/mlx5_mac.c\n+++ b/drivers/net/mlx5/mlx5_mac.c\n@@ -157,9 +157,13 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)\n \n \t/*\n \t * Configuring the VF instead of its representor,\n-\t * need to skip the special case of HPF on BlueField.\n+\t * need to skip the special cases:\n+\t * - HPF on BlueField,\n+\t * - SF representors,\n+\t * - uplink ports when running in MPESW mode.\n \t */\n-\tif (priv->representor && !mlx5_is_hpf(dev) && !mlx5_is_sf_repr(dev)) {\n+\tif (priv->representor && !mlx5_is_hpf(dev) && !mlx5_is_sf_repr(dev) &&\n+\t    !priv->mpesw_uplink) {\n \t\tDRV_LOG(DEBUG, \"VF represented by port %u setting primary MAC address\",\n \t\t\tdev->data->port_id);\n \t\tif (priv->pf_bond >= 0) {\n",
    "prefixes": [
        "6/8"
    ]
}