get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 130174,
    "url": "http://patches.dpdk.org/api/patches/130174/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230811163419.165790-3-hkalra@marvell.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": "<20230811163419.165790-3-hkalra@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230811163419.165790-3-hkalra@marvell.com",
    "date": "2023-08-11T16:34:12",
    "name": "[2/9] net/cnxk: probing representor ports",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "420eb000f3561727e6401eac57afd3f43afa5353",
    "submitter": {
        "id": 1182,
        "url": "http://patches.dpdk.org/api/people/1182/?format=api",
        "name": "Harman Kalra",
        "email": "hkalra@marvell.com"
    },
    "delegate": {
        "id": 310,
        "url": "http://patches.dpdk.org/api/users/310/?format=api",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerinj@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20230811163419.165790-3-hkalra@marvell.com/mbox/",
    "series": [
        {
            "id": 29193,
            "url": "http://patches.dpdk.org/api/series/29193/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=29193",
            "date": "2023-08-11T16:34:10",
            "name": "net/cnxk: support for port representors",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/29193/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/130174/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/130174/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 131D043036;\n\tFri, 11 Aug 2023 18:35:19 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 7420743266;\n\tFri, 11 Aug 2023 18:35:10 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173])\n by mails.dpdk.org (Postfix) with ESMTP id 554D540F16\n for <dev@dpdk.org>; Fri, 11 Aug 2023 18:35:07 +0200 (CEST)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id\n 37BEGFrP021082; Fri, 11 Aug 2023 09:35:06 -0700",
            "from dc5-exch01.marvell.com ([199.233.59.181])\n by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3sd8ya2qsa-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Fri, 11 Aug 2023 09:35:06 -0700",
            "from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48;\n Fri, 11 Aug 2023 09:34:58 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.48 via Frontend\n Transport; Fri, 11 Aug 2023 09:34:58 -0700",
            "from localhost.localdomain (unknown [10.29.52.211])\n by maili.marvell.com (Postfix) with ESMTP id A3F513F7068;\n Fri, 11 Aug 2023 09:34:55 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-type; s=pfpt0220; bh=10d2VHUTdAMWym+ahjJokJKlC0amfK5q5DPnGsW7FXI=;\n b=bCbBx6pIP7CFr79Bh5koFUNz1o2L+dwUre0JjYBaQ5BHPfe+OnoZNoRggFkVFmD+5g+c\n nyTt2MzrgiZKY8plTUSLeb0sJ9+7adM8ZRrid9qggKrqxIr+OEs70sf4SsCQqyqvvdhH\n D8eL9BQ/qjIHaWtEypIYfe1O65oMwSxqeU+rj/mFvjdsCAC4ffL8BjIf1S/9NX6W4AjY\n IGdDHFNoLbpl50Oo84DXcRol0bKKSByaSsDx6aopsLMpRfG7NOY6siWnAcQg2lQQ/NvW\n hNe8bEE7p0rHvtjMijZTUpBtIZ6y0KmSaoRZx4avT7hSXQRUiCGei2UqVvN7/lid/r5j UA==",
        "From": "Harman Kalra <hkalra@marvell.com>",
        "To": "<jerinj@marvell.com>, Nithin Dabilpuram <ndabilpuram@marvell.com>, \"Kiran\n Kumar K\" <kirankumark@marvell.com>, Sunil Kumar Kori <skori@marvell.com>,\n Satha Rao <skoteshwar@marvell.com>, Anatoly Burakov\n <anatoly.burakov@intel.com>",
        "CC": "<dev@dpdk.org>, Harman Kalra <hkalra@marvell.com>",
        "Subject": "[PATCH 2/9] net/cnxk: probing representor ports",
        "Date": "Fri, 11 Aug 2023 22:04:12 +0530",
        "Message-ID": "<20230811163419.165790-3-hkalra@marvell.com>",
        "X-Mailer": "git-send-email 2.18.0",
        "In-Reply-To": "<20230811163419.165790-1-hkalra@marvell.com>",
        "References": "<20230811163419.165790-1-hkalra@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Proofpoint-ORIG-GUID": "UETJFLL380m288Gxy0ThjGYXEx9Xuf9u",
        "X-Proofpoint-GUID": "UETJFLL380m288Gxy0ThjGYXEx9Xuf9u",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26\n definitions=2023-08-11_08,2023-08-10_01,2023-05-22_02",
        "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": "Basic skeleton for probing representor devices. If PF device is\npassed with \"representor\" devargs, representor ports gets probed\nas a separate ethdev device.\n\nSigned-off-by: Harman Kalra <hkalra@marvell.com>\n---\n doc/guides/nics/cnxk.rst        |  39 +++++\n drivers/net/cnxk/cn10k_ethdev.c |   4 +-\n drivers/net/cnxk/cn9k_ethdev.c  |   4 +-\n drivers/net/cnxk/cnxk_ethdev.c  |  42 ++++-\n drivers/net/cnxk/cnxk_ethdev.h  |  12 ++\n drivers/net/cnxk/cnxk_rep.c     | 262 ++++++++++++++++++++++++++++++++\n drivers/net/cnxk/cnxk_rep.h     |  51 +++++++\n drivers/net/cnxk/cnxk_rep_ops.c | 112 ++++++++++++++\n drivers/net/cnxk/meson.build    |   2 +\n 9 files changed, 516 insertions(+), 12 deletions(-)\n create mode 100644 drivers/net/cnxk/cnxk_rep.c\n create mode 100644 drivers/net/cnxk/cnxk_rep.h\n create mode 100644 drivers/net/cnxk/cnxk_rep_ops.c",
    "diff": "diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst\nindex 9229056f6f..dd14102efa 100644\n--- a/doc/guides/nics/cnxk.rst\n+++ b/doc/guides/nics/cnxk.rst\n@@ -37,6 +37,8 @@ Features of the CNXK Ethdev PMD are:\n - Inline IPsec processing support\n - Ingress meter support\n - Queue based priority flow control support\n+- Virtual function representors\n+- Represented port pattern matching and action\n \n Prerequisites\n -------------\n@@ -581,6 +583,41 @@ Runtime Config Options for inline device\n    With the above configuration, driver would poll for soft expiry events every\n    1000 usec.\n \n+Virtual Function Representors\n+-----------------------------\n+\n+The CNXK driver supports port representor model by adding virtual ethernet\n+ports providing a logical representation in DPDK for SR-IOV virtual function\n+(VF) devices for control and monitoring.\n+\n+These port representor ethdev instances can be spawned on an as needed basis\n+through configuration parameters passed to the driver of the underlying\n+base device using devargs ``-a pci:dbdf,representor=[0]``\n+\n+.. note::\n+\n+   Base device is the PF whose VFs will be represented by these representors\n+\n+   Above devarg parameters can be provided as a range of representor device\n+   ``-a pci:dbdf,representor=[0-3]`` or a single representor device on need\n+   basis ``-a pci:dbdf,representor=[0]``\n+\n+In case of exception path (i.e. until the flow definition is offloaded to the\n+hardware), packets transmitted by the VFs shall be received by these\n+representor port, while packets transmitted by representor ports shall be\n+received by respective VFs.\n+\n+On receiving the VF traffic via these representor ports, applications holding\n+these representor ports can decide to offload the traffic flow into the HW.\n+Henceforth the matching traffic shall be directly steered to the respective\n+VFs without being received by the application.\n+\n+Current virtual representor port PMD supports following operations:\n+\n+- Get and clear VF statistics\n+- Set mac address\n+- Flow operations - create, validate, destroy, query, flush, dump\n+\n Debugging Options\n -----------------\n \n@@ -595,3 +632,5 @@ Debugging Options\n    +---+------------+-------------------------------------------------------+\n    | 2 | NPC        | --log-level='pmd\\.net.cnxk\\.flow,8'                   |\n    +---+------------+-------------------------------------------------------+\n+   | 3 | REP        | --log-level='pmd\\.net.cnxk\\.rep,8'                   |\n+   +---+------------+-------------------------------------------------------+\ndiff --git a/drivers/net/cnxk/cn10k_ethdev.c b/drivers/net/cnxk/cn10k_ethdev.c\nindex 4c4acc7cf0..a6a4665af1 100644\n--- a/drivers/net/cnxk/cn10k_ethdev.c\n+++ b/drivers/net/cnxk/cn10k_ethdev.c\n@@ -912,8 +912,8 @@ static const struct rte_pci_id cn10k_pci_nix_map[] = {\n \n static struct rte_pci_driver cn10k_pci_nix = {\n \t.id_table = cn10k_pci_nix_map,\n-\t.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA |\n-\t\t     RTE_PCI_DRV_INTR_LSC,\n+\t.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA | RTE_PCI_DRV_INTR_LSC |\n+\t\t     RTE_PCI_DRV_PROBE_AGAIN,\n \t.probe = cn10k_nix_probe,\n \t.remove = cn10k_nix_remove,\n };\ndiff --git a/drivers/net/cnxk/cn9k_ethdev.c b/drivers/net/cnxk/cn9k_ethdev.c\nindex bae4dda5e2..0448d7e219 100644\n--- a/drivers/net/cnxk/cn9k_ethdev.c\n+++ b/drivers/net/cnxk/cn9k_ethdev.c\n@@ -834,8 +834,8 @@ static const struct rte_pci_id cn9k_pci_nix_map[] = {\n \n static struct rte_pci_driver cn9k_pci_nix = {\n \t.id_table = cn9k_pci_nix_map,\n-\t.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA |\n-\t\t     RTE_PCI_DRV_INTR_LSC,\n+\t.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA | RTE_PCI_DRV_INTR_LSC |\n+\t\t     RTE_PCI_DRV_PROBE_AGAIN,\n \t.probe = cn9k_nix_probe,\n \t.remove = cn9k_nix_remove,\n };\ndiff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c\nindex 4b98faa729..902e6df72d 100644\n--- a/drivers/net/cnxk/cnxk_ethdev.c\n+++ b/drivers/net/cnxk/cnxk_ethdev.c\n@@ -2102,6 +2102,10 @@ cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool reset)\n \trte_free(eth_dev->data->mac_addrs);\n \teth_dev->data->mac_addrs = NULL;\n \n+\t/* Remove representor devices associated with PF */\n+\tif (dev->num_reps)\n+\t\tcnxk_rep_dev_remove(eth_dev);\n+\n \trc = roc_nix_dev_fini(nix);\n \t/* Can be freed later by PMD if NPA LF is in use */\n \tif (rc == -EAGAIN) {\n@@ -2180,18 +2184,40 @@ cnxk_nix_remove(struct rte_pci_device *pci_dev)\n int\n cnxk_nix_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)\n {\n-\tint rc;\n+\tstruct rte_eth_devargs eth_da = {.nb_representor_ports = 0};\n+\tstruct rte_eth_dev *pf_ethdev;\n+\tuint16_t num_rep;\n+\tint rc = 0;\n \n \tRTE_SET_USED(pci_drv);\n \n-\trc = rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct cnxk_eth_dev),\n-\t\t\t\t\t   cnxk_eth_dev_init);\n+\tif (pci_dev->device.devargs) {\n+\t\trc = rte_eth_devargs_parse(pci_dev->device.devargs->args, &eth_da);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t}\n+\n+\tnum_rep = eth_da.nb_representor_ports;\n+\tplt_rep_dbg(\"nb_representor_ports = %d\\n\", num_rep);\n \n-\t/* On error on secondary, recheck if port exists in primary or\n-\t * in mid of detach state.\n+\t/* This probing API may get invoked even after first level of probe is\n+\t * done, as part of an application bringup(OVS-DPDK vswitchd), checking\n+\t * if eth_dev is allocated for the PF device\n \t */\n-\tif (rte_eal_process_type() != RTE_PROC_PRIMARY && rc)\n-\t\tif (!rte_eth_dev_allocated(pci_dev->device.name))\n-\t\t\treturn 0;\n+\tpf_ethdev = rte_eth_dev_allocated(pci_dev->device.name);\n+\tif (pf_ethdev == NULL) {\n+\t\trc = rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct cnxk_eth_dev),\n+\t\t\t\t\t\t   cnxk_eth_dev_init);\n+\t\tif (rc || !num_rep)\n+\t\t\treturn rc;\n+\n+\t\tpf_ethdev = rte_eth_dev_allocated(pci_dev->device.name);\n+\t}\n+\n+\tif (!num_rep)\n+\t\treturn rc;\n+\n+\trc = cnxk_rep_dev_probe(pci_dev, pf_ethdev, &eth_da);\n+\n \treturn rc;\n }\ndiff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h\nindex ed531fb277..3896db38e1 100644\n--- a/drivers/net/cnxk/cnxk_ethdev.h\n+++ b/drivers/net/cnxk/cnxk_ethdev.h\n@@ -22,7 +22,9 @@\n #include <rte_tm_driver.h>\n \n #include \"roc_api.h\"\n+\n #include <cnxk_ethdev_dp.h>\n+#include <cnxk_rep.h>\n \n #define CNXK_ETH_DEV_PMD_VERSION \"1.0\"\n \n@@ -307,6 +309,10 @@ struct cnxk_macsec_sess {\n };\n TAILQ_HEAD(cnxk_macsec_sess_list, cnxk_macsec_sess);\n \n+struct cnxk_rep_info {\n+\tstruct rte_eth_dev *rep_eth_dev;\n+};\n+\n struct cnxk_eth_dev {\n \t/* ROC NIX */\n \tstruct roc_nix nix;\n@@ -414,6 +420,12 @@ struct cnxk_eth_dev {\n \t/* MCS device */\n \tstruct cnxk_mcs_dev *mcs_dev;\n \tstruct cnxk_macsec_sess_list mcs_list;\n+\n+\t/* Port representor fields */\n+\tuint16_t switch_domain_id;\n+\tuint16_t num_reps;\n+\tuint16_t rep_xport_vdev;\n+\tstruct cnxk_rep_info *rep_info;\n };\n \n struct cnxk_eth_rxq_sp {\ndiff --git a/drivers/net/cnxk/cnxk_rep.c b/drivers/net/cnxk/cnxk_rep.c\nnew file mode 100644\nindex 0000000000..ebefc34ac8\n--- /dev/null\n+++ b/drivers/net/cnxk/cnxk_rep.c\n@@ -0,0 +1,262 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2023 Marvell.\n+ */\n+#include <cnxk_rep.h>\n+\n+/* CNXK platform representor dev ops */\n+struct eth_dev_ops cnxk_rep_dev_ops = {\n+\t.dev_infos_get = cnxk_rep_dev_info_get,\n+\t.dev_configure = cnxk_rep_dev_configure,\n+\t.dev_start = cnxk_rep_dev_start,\n+\t.rx_queue_setup = cnxk_rep_rx_queue_setup,\n+\t.rx_queue_release = cnxk_rep_rx_queue_release,\n+\t.tx_queue_setup = cnxk_rep_tx_queue_setup,\n+\t.tx_queue_release = cnxk_rep_tx_queue_release,\n+\t.link_update = cnxk_rep_link_update,\n+\t.dev_close = cnxk_rep_dev_close,\n+\t.dev_stop = cnxk_rep_dev_stop,\n+\t.stats_get = cnxk_rep_stats_get,\n+\t.stats_reset = cnxk_rep_stats_reset,\n+\t.flow_ops_get = cnxk_rep_flow_ops_get\n+};\n+\n+int\n+cnxk_rep_dev_uninit(struct rte_eth_dev *ethdev)\n+{\n+\tif (rte_eal_process_type() != RTE_PROC_PRIMARY)\n+\t\treturn 0;\n+\n+\tplt_rep_dbg(\"Representor port:%d uninit\", ethdev->data->port_id);\n+\trte_free(ethdev->data->mac_addrs);\n+\tethdev->data->mac_addrs = NULL;\n+\n+\treturn 0;\n+}\n+\n+int\n+cnxk_rep_dev_remove(struct rte_eth_dev *pf_ethdev)\n+{\n+\tstruct cnxk_eth_dev *pf_dev = cnxk_eth_pmd_priv(pf_ethdev);\n+\tint rc = 0;\n+\n+\trc = rte_eth_switch_domain_free(pf_dev->switch_domain_id);\n+\tif (rc)\n+\t\tplt_err(\"Failed to alloc switch domain: %d\", rc);\n+\n+\treturn rc;\n+}\n+\n+static int\n+hotplug_rep_xport_vdev(struct cnxk_eth_dev *pf_dev)\n+{\n+\tchar rep_xport_devargs[] = CNXK_REP_XPORT_VDEV_DEVARGS;\n+\tchar name[] = CNXK_REP_XPORT_VDEV_NAME;\n+\tuint16_t portid;\n+\tint rc = 0;\n+\n+\trc = rte_eth_dev_get_port_by_name(name, &portid);\n+\tif (rc != 0) {\n+\t\tif (rc == -ENODEV) {\n+\t\t\t/* rep_xport device should get added once during first PF probe */\n+\t\t\trc = rte_eal_hotplug_add(\"vdev\", name, rep_xport_devargs);\n+\t\t\tif (rc) {\n+\t\t\t\tplt_err(\"rep base hotplug failed %d\", -rte_errno);\n+\t\t\t\tgoto fail;\n+\t\t\t}\n+\n+\t\t\t/* Get the portID of rep_xport port */\n+\t\t\tif (rte_eth_dev_get_port_by_name(name, &portid)) {\n+\t\t\t\tplt_err(\"cannot find added vdev %s\", name);\n+\t\t\t\tgoto free;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tplt_err(\"cannot find added vdev %s\", name);\n+\t\t\tgoto free;\n+\t\t}\n+\t}\n+\n+\tplt_rep_dbg(\"rep_xport vdev port %d, name %s\", portid, name);\n+\tpf_dev->rep_xport_vdev = portid;\n+\n+\treturn 0;\n+free:\n+\trte_eal_hotplug_remove(\"vdev\", name);\n+fail:\n+\treturn rc;\n+}\n+\n+static int\n+cnxk_init_rep_internal(struct cnxk_eth_dev *pf_dev)\n+{\n+\tint rc;\n+\n+\tif (pf_dev->rep_info)\n+\t\treturn 0;\n+\n+\tpf_dev->rep_info =\n+\t\tplt_zmalloc(sizeof(pf_dev->rep_info[0]) * CNXK_MAX_REP_PORTS, 0);\n+\tif (!pf_dev->rep_info) {\n+\t\tplt_err(\"Failed to alloc memory for rep info\");\n+\t\trc = -ENOMEM;\n+\t\tgoto fail;\n+\t}\n+\n+\t/* Allocate switch domain for this PF */\n+\trc = rte_eth_switch_domain_alloc(&pf_dev->switch_domain_id);\n+\tif (rc) {\n+\t\tplt_err(\"Failed to alloc switch domain: %d\", rc);\n+\t\tgoto fail;\n+\t}\n+\n+\trc = hotplug_rep_xport_vdev(pf_dev);\n+\tif (rc) {\n+\t\tplt_err(\"Failed to hotplug representor base port, err %d\", rc);\n+\t\tgoto fail;\n+\t}\n+\n+\treturn 0;\n+fail:\n+\treturn rc;\n+}\n+\n+static uint16_t\n+cnxk_rep_tx_burst(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)\n+{\n+\tPLT_SET_USED(tx_queue);\n+\tPLT_SET_USED(tx_pkts);\n+\tPLT_SET_USED(nb_pkts);\n+\n+\treturn 0;\n+}\n+\n+static uint16_t\n+cnxk_rep_rx_burst(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)\n+{\n+\tPLT_SET_USED(rx_queue);\n+\tPLT_SET_USED(rx_pkts);\n+\tPLT_SET_USED(nb_pkts);\n+\n+\treturn 0;\n+}\n+\n+static int\n+cnxk_rep_dev_init(struct rte_eth_dev *eth_dev, void *params)\n+{\n+\tstruct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);\n+\tstruct cnxk_rep_dev *rep_params = (struct cnxk_rep_dev *)params;\n+\tstruct rte_eth_link *link;\n+\tstruct cnxk_eth_dev *pf_dev;\n+\n+\trep_dev->vf_id = rep_params->vf_id;\n+\trep_dev->switch_domain_id = rep_params->switch_domain_id;\n+\trep_dev->parent_dev = rep_params->parent_dev;\n+\n+\teth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;\n+\teth_dev->data->representor_id = rep_params->vf_id;\n+\teth_dev->data->backer_port_id = rep_params->parent_dev->data->port_id;\n+\n+\teth_dev->data->mac_addrs = plt_zmalloc(RTE_ETHER_ADDR_LEN, 0);\n+\tif (!eth_dev->data->mac_addrs) {\n+\t\tplt_err(\"Failed to allocate memory for mac addr\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\trte_eth_random_addr(rep_dev->mac_addr);\n+\tmemcpy(eth_dev->data->mac_addrs, rep_dev->mac_addr, RTE_ETHER_ADDR_LEN);\n+\n+\t/* Set the device operations */\n+\teth_dev->dev_ops = &cnxk_rep_dev_ops;\n+\n+\t/* Rx/Tx functions stubs to avoid crashing */\n+\teth_dev->rx_pkt_burst = cnxk_rep_rx_burst;\n+\teth_dev->tx_pkt_burst = cnxk_rep_tx_burst;\n+\n+\t/* Link state. Inherited from PF */\n+\tpf_dev = cnxk_eth_pmd_priv(rep_dev->parent_dev);\n+\tlink = &pf_dev->eth_dev->data->dev_link;\n+\n+\teth_dev->data->dev_link.link_speed = link->link_speed;\n+\teth_dev->data->dev_link.link_duplex = link->link_duplex;\n+\teth_dev->data->dev_link.link_status = link->link_status;\n+\teth_dev->data->dev_link.link_autoneg = link->link_autoneg;\n+\n+\treturn 0;\n+}\n+\n+int\n+cnxk_rep_dev_probe(struct rte_pci_device *pci_dev, struct rte_eth_dev *pf_ethdev,\n+\t\t   struct rte_eth_devargs *eth_da)\n+{\n+\tchar name[RTE_ETH_NAME_MAX_LEN];\n+\tstruct rte_eth_dev *rep_eth_dev;\n+\tstruct cnxk_eth_dev *pf_dev;\n+\tuint16_t num_rep;\n+\tint i, rc;\n+\n+\t/* Get the PF device */\n+\tpf_dev = cnxk_eth_pmd_priv(pf_ethdev);\n+\n+\t/* Check the representor devargs */\n+\tif (eth_da->type == RTE_ETH_REPRESENTOR_NONE)\n+\t\treturn 0;\n+\tif (eth_da->type != RTE_ETH_REPRESENTOR_VF) {\n+\t\tplt_err(\"unsupported representor type %d\\n\", eth_da->type);\n+\t\treturn -ENOTSUP;\n+\t}\n+\tnum_rep = eth_da->nb_representor_ports;\n+\tif (num_rep > CNXK_MAX_REP_PORTS) {\n+\t\tplt_err(\"nb_representor_ports = %d > %d MAX VF REPS\\n\", num_rep,\n+\t\t\tCNXK_MAX_REP_PORTS);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (num_rep >= RTE_MAX_ETHPORTS) {\n+\t\tplt_err(\"nb_representor_ports = %d > %d MAX ETHPORTS\\n\", num_rep, RTE_MAX_ETHPORTS);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Initialize the internals of representor ports */\n+\tif (cnxk_init_rep_internal(pf_dev))\n+\t\treturn 0;\n+\n+\tfor (i = 0; i < num_rep; i++) {\n+\t\tstruct cnxk_rep_dev representor = {.vf_id = eth_da->representor_ports[i],\n+\t\t\t\t\t\t   .switch_domain_id = pf_dev->switch_domain_id,\n+\t\t\t\t\t\t   .parent_dev = pf_ethdev};\n+\n+\t\tif (representor.vf_id >= pci_dev->max_vfs) {\n+\t\t\tplt_err(\"VF-Rep id %d >= %d pci dev max vfs\\n\", representor.vf_id,\n+\t\t\t\tpci_dev->max_vfs);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* Representor port net_bdf_port */\n+\t\tsnprintf(name, sizeof(name), \"net_%s_representor_%d\", pci_dev->device.name,\n+\t\t\t eth_da->representor_ports[i]);\n+\n+\t\trc = rte_eth_dev_create(&pci_dev->device, name, sizeof(struct cnxk_rep_dev), NULL,\n+\t\t\t\t\tNULL, cnxk_rep_dev_init, &representor);\n+\t\tif (rc) {\n+\t\t\tplt_err(\"failed to create cnxk vf representor %s\", name);\n+\t\t\trc = -EINVAL;\n+\t\t\tgoto err;\n+\t\t}\n+\n+\t\trep_eth_dev = rte_eth_dev_allocated(name);\n+\t\tif (!rep_eth_dev) {\n+\t\t\tplt_err(\"Failed to find the eth_dev for VF-Rep: %s.\", name);\n+\t\t\trc = -ENODEV;\n+\t\t\tgoto err;\n+\t\t}\n+\n+\t\tplt_rep_dbg(\"PF portid %d switch domain %d representor portid %d (%s) probe done\",\n+\t\t\t    pf_ethdev->data->port_id, pf_dev->switch_domain_id,\n+\t\t\t    rep_eth_dev->data->port_id, name);\n+\t\tpf_dev->rep_info[representor.vf_id].rep_eth_dev = rep_eth_dev;\n+\t\tpf_dev->num_reps++;\n+\t}\n+\n+\treturn 0;\n+err:\n+\treturn rc;\n+}\ndiff --git a/drivers/net/cnxk/cnxk_rep.h b/drivers/net/cnxk/cnxk_rep.h\nnew file mode 100644\nindex 0000000000..24adb9649b\n--- /dev/null\n+++ b/drivers/net/cnxk/cnxk_rep.h\n@@ -0,0 +1,51 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2023 Marvell.\n+ */\n+#include <cnxk_ethdev.h>\n+\n+#ifndef __CNXK_REP_H__\n+#define __CNXK_REP_H__\n+\n+#define CNXK_REP_XPORT_VDEV_DEVARGS \"role=server\"\n+#define CNXK_REP_XPORT_VDEV_NAME\t   \"net_memif\"\n+#define CNXK_MAX_REP_PORTS\t   128\n+\n+/* Common ethdev ops */\n+extern struct eth_dev_ops cnxk_rep_dev_ops;\n+\n+struct cnxk_rep_dev {\n+\tuint16_t vf_id;\n+\tuint16_t switch_domain_id;\n+\tstruct rte_eth_dev *parent_dev;\n+\tuint8_t mac_addr[RTE_ETHER_ADDR_LEN];\n+};\n+\n+static inline struct cnxk_rep_dev *\n+cnxk_rep_pmd_priv(const struct rte_eth_dev *eth_dev)\n+{\n+\treturn eth_dev->data->dev_private;\n+}\n+\n+int cnxk_rep_dev_probe(struct rte_pci_device *pci_dev, struct rte_eth_dev *pf_ethdev,\n+\t\t       struct rte_eth_devargs *eth_da);\n+int cnxk_rep_dev_remove(struct rte_eth_dev *pf_ethdev);\n+int cnxk_rep_dev_uninit(struct rte_eth_dev *ethdev);\n+int cnxk_rep_dev_info_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *dev_info);\n+int cnxk_rep_dev_configure(struct rte_eth_dev *eth_dev);\n+\n+int cnxk_rep_link_update(struct rte_eth_dev *eth_dev, int wait_to_compl);\n+int cnxk_rep_dev_start(struct rte_eth_dev *eth_dev);\n+int cnxk_rep_rx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t queue_idx, uint16_t nb_desc,\n+\t\t\t    unsigned int socket_id, const struct rte_eth_rxconf *rx_conf,\n+\t\t\t    struct rte_mempool *mp);\n+int cnxk_rep_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t queue_idx, uint16_t nb_desc,\n+\t\t\t    unsigned int socket_id, const struct rte_eth_txconf *tx_conf);\n+void cnxk_rep_rx_queue_release(struct rte_eth_dev *dev, uint16_t queue_idx);\n+void cnxk_rep_tx_queue_release(struct rte_eth_dev *dev, uint16_t queue_idx);\n+int cnxk_rep_dev_stop(struct rte_eth_dev *eth_dev);\n+int cnxk_rep_dev_close(struct rte_eth_dev *eth_dev);\n+int cnxk_rep_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats);\n+int cnxk_rep_stats_reset(struct rte_eth_dev *eth_dev);\n+int cnxk_rep_flow_ops_get(struct rte_eth_dev *ethdev, const struct rte_flow_ops **ops);\n+\n+#endif /* __CNXK_REP_H__ */\ndiff --git a/drivers/net/cnxk/cnxk_rep_ops.c b/drivers/net/cnxk/cnxk_rep_ops.c\nnew file mode 100644\nindex 0000000000..3f1aab077b\n--- /dev/null\n+++ b/drivers/net/cnxk/cnxk_rep_ops.c\n@@ -0,0 +1,112 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2023 Marvell.\n+ */\n+\n+#include <cnxk_rep.h>\n+\n+int\n+cnxk_rep_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)\n+{\n+\tPLT_SET_USED(ethdev);\n+\tPLT_SET_USED(wait_to_complete);\n+\treturn 0;\n+}\n+\n+int\n+cnxk_rep_dev_info_get(struct rte_eth_dev *ethdev, struct rte_eth_dev_info *devinfo)\n+{\n+\tPLT_SET_USED(ethdev);\n+\tPLT_SET_USED(devinfo);\n+\treturn 0;\n+}\n+\n+int\n+cnxk_rep_dev_configure(struct rte_eth_dev *ethdev)\n+{\n+\tPLT_SET_USED(ethdev);\n+\treturn 0;\n+}\n+\n+int\n+cnxk_rep_dev_start(struct rte_eth_dev *ethdev)\n+{\n+\tPLT_SET_USED(ethdev);\n+\treturn 0;\n+}\n+\n+int\n+cnxk_rep_dev_close(struct rte_eth_dev *ethdev)\n+{\n+\tPLT_SET_USED(ethdev);\n+\treturn 0;\n+}\n+\n+int\n+cnxk_rep_dev_stop(struct rte_eth_dev *ethdev)\n+{\n+\tPLT_SET_USED(ethdev);\n+\treturn 0;\n+}\n+\n+int\n+cnxk_rep_rx_queue_setup(struct rte_eth_dev *ethdev, uint16_t rx_queue_id, uint16_t nb_rx_desc,\n+\t\t\tunsigned int socket_id, const struct rte_eth_rxconf *rx_conf,\n+\t\t\tstruct rte_mempool *mb_pool)\n+{\n+\tPLT_SET_USED(ethdev);\n+\tPLT_SET_USED(rx_queue_id);\n+\tPLT_SET_USED(nb_rx_desc);\n+\tPLT_SET_USED(socket_id);\n+\tPLT_SET_USED(rx_conf);\n+\tPLT_SET_USED(mb_pool);\n+\treturn 0;\n+}\n+\n+void\n+cnxk_rep_rx_queue_release(struct rte_eth_dev *ethdev, uint16_t queue_id)\n+{\n+\tPLT_SET_USED(ethdev);\n+\tPLT_SET_USED(queue_id);\n+}\n+\n+int\n+cnxk_rep_tx_queue_setup(struct rte_eth_dev *ethdev, uint16_t tx_queue_id, uint16_t nb_tx_desc,\n+\t\t\tunsigned int socket_id, const struct rte_eth_txconf *tx_conf)\n+{\n+\tPLT_SET_USED(ethdev);\n+\tPLT_SET_USED(tx_queue_id);\n+\tPLT_SET_USED(nb_tx_desc);\n+\tPLT_SET_USED(socket_id);\n+\tPLT_SET_USED(tx_conf);\n+\treturn 0;\n+}\n+\n+void\n+cnxk_rep_tx_queue_release(struct rte_eth_dev *ethdev, uint16_t queue_id)\n+{\n+\tPLT_SET_USED(ethdev);\n+\tPLT_SET_USED(queue_id);\n+}\n+\n+int\n+cnxk_rep_stats_get(struct rte_eth_dev *ethdev, struct rte_eth_stats *stats)\n+{\n+\tPLT_SET_USED(ethdev);\n+\tPLT_SET_USED(stats);\n+\treturn 0;\n+}\n+\n+int\n+cnxk_rep_stats_reset(struct rte_eth_dev *ethdev)\n+{\n+\tPLT_SET_USED(ethdev);\n+\treturn 0;\n+}\n+\n+int\n+cnxk_rep_flow_ops_get(struct rte_eth_dev *ethdev, const struct rte_flow_ops **ops)\n+{\n+\tPLT_SET_USED(ethdev);\n+\tPLT_SET_USED(ops);\n+\treturn 0;\n+}\ndiff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build\nindex e83f3c9050..38dde54ce9 100644\n--- a/drivers/net/cnxk/meson.build\n+++ b/drivers/net/cnxk/meson.build\n@@ -32,6 +32,8 @@ sources = files(\n         'cnxk_lookup.c',\n         'cnxk_ptp.c',\n         'cnxk_flow.c',\n+        'cnxk_rep.c',\n+        'cnxk_rep_ops.c',\n         'cnxk_stats.c',\n         'cnxk_tm.c',\n )\n",
    "prefixes": [
        "2/9"
    ]
}