get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 116093,
    "url": "http://patches.dpdk.org/api/patches/116093/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1662626702-17254-11-git-send-email-chaoyong.he@corigine.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1662626702-17254-11-git-send-email-chaoyong.he@corigine.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1662626702-17254-11-git-send-email-chaoyong.he@corigine.com",
    "date": "2022-09-08T08:45:00",
    "name": "[v8,10/12] net/nfp: add flower representor framework",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "0d10e18af573ad58a214418e96295993f08f819d",
    "submitter": {
        "id": 2554,
        "url": "http://patches.dpdk.org/api/people/2554/?format=api",
        "name": "Chaoyong He",
        "email": "chaoyong.he@corigine.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1662626702-17254-11-git-send-email-chaoyong.he@corigine.com/mbox/",
    "series": [
        {
            "id": 24607,
            "url": "http://patches.dpdk.org/api/series/24607/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=24607",
            "date": "2022-09-08T08:44:50",
            "name": "preparation for the rte_flow offload of nfp PMD",
            "version": 8,
            "mbox": "http://patches.dpdk.org/series/24607/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/116093/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/116093/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 35182A0548;\n\tThu,  8 Sep 2022 10:46:43 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 50ADB42B96;\n\tThu,  8 Sep 2022 10:45:51 +0200 (CEST)",
            "from NAM12-BN8-obe.outbound.protection.outlook.com\n (mail-bn8nam12on2119.outbound.protection.outlook.com [40.107.237.119])\n by mails.dpdk.org (Postfix) with ESMTP id A176F42B91\n for <dev@dpdk.org>; Thu,  8 Sep 2022 10:45:49 +0200 (CEST)",
            "from SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5)\n by MW4PR13MB5940.namprd13.prod.outlook.com (2603:10b6:303:1b8::10)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5588.3; Thu, 8 Sep\n 2022 08:45:47 +0000",
            "from SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::402d:6abc:83a8:2431]) by SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::402d:6abc:83a8:2431%6]) with mapi id 15.20.5612.009; Thu, 8 Sep 2022\n 08:45:47 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=RLb/xAvlXIUrnV6BEJ2KucXA/1hfO2qjN8HMhj0yR2dsEaYCklTyVbubCGyA5q6pBH4ON4i+haliFA3Klo3grAp6Bx5TCJvDw39O6NCe6Mc4gAHmZQA2aP/+zcm9L5GLGWPoR7iKW8McFrgOvyJopFVwzxjNYee+VQyTO4NWA9NS4UwMtvi8b7dvl8+RZfaFPkggXKKe7Src93jeuLH2MP9oBxXSEHV8KqZrX6wwvdyUdiCrXZvPlM769HvE4S7nUiof+ald253pftt8xG+2eVL7MKQbKY3GEsDHlr8pgA/cs+sfIJ9G4bwPPgl/n/9g0lRkwteDfNp0DVLS2Ggh2Q==",
        "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=SvGz3BADmhaO05G5i+6LoXuSMR9yUuQiahs8AGQpaRE=;\n b=Y3vSQ/eAkgefaaFziVy96pbcnro6V6gBrmDZm2PkyWV0R8BJIbca5LVxlk7/2a6tsVhTcA4ZWsuOGCy5CjgBsmTYD6FWt1B5P9EjAs7lMMvvVfHYr1DafXWOPBQW7CsragMMPPrcBx13+9UmMtByQPPlWJWJ/u3wt5Cvun7GMM8qLnU8Jb9koRmvSHmwbiPnb6byJDKhhuSFNC/3U3VYRCYS4V7yKWoV9UujLVXyF9WuW7aRBTtAo3CBEFuZ0+aIp24uki+jKG5BLSysMbhZrj0MhwxXQfSksoIjw1lXhVlFR1CLMB6DT62ZRAIhLkCC5j82SHg3AaDgyHRc5ugq6w==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=corigine.com; dmarc=pass action=none header.from=corigine.com;\n dkim=pass header.d=corigine.com; arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=corigine.onmicrosoft.com; s=selector2-corigine-onmicrosoft-com;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=SvGz3BADmhaO05G5i+6LoXuSMR9yUuQiahs8AGQpaRE=;\n b=EBMib3gFNxlW0F3r18fkveCcWvcqxnqY8Fltq8odGEHNk9IBeu5J7R1AahQFepOZCkLhxxhxP72JUbcQnvWlh19TV/hI7uSeENojbxdLQnsgHPR/xVyNkHAl8moU4Sv0s/ZZ7nfDf6ZNuy/j0d8xW6CvaKqx+vf7xEyb2WWrdvM=",
        "Authentication-Results": "dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=corigine.com;",
        "From": "Chaoyong He <chaoyong.he@corigine.com>",
        "To": "dev@dpdk.org",
        "Cc": "oss-drivers@corigine.com, niklas.soderlund@corigine.com,\n Chaoyong He <chaoyong.he@corigine.com>",
        "Subject": "[PATCH v8 10/12] net/nfp: add flower representor framework",
        "Date": "Thu,  8 Sep 2022 16:45:00 +0800",
        "Message-Id": "<1662626702-17254-11-git-send-email-chaoyong.he@corigine.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1662626702-17254-1-git-send-email-chaoyong.he@corigine.com>",
        "References": "<1662626702-17254-1-git-send-email-chaoyong.he@corigine.com>",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "X-ClientProxiedBy": "SI2PR01CA0023.apcprd01.prod.exchangelabs.com\n (2603:1096:4:192::17) To SJ0PR13MB5545.namprd13.prod.outlook.com\n (2603:10b6:a03:424::5)",
        "MIME-Version": "1.0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "SJ0PR13MB5545:EE_|MW4PR13MB5940:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "acdf683e-a7db-4975-6b9b-08da91768670",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n uAgCezWMTuqbPOJYrnjYuQHkwboYZKP+gjL7mAgEmbB/ofxuOiE+hCnz9PuJo2U7AWrbJus44QEf2XN39tshStm/6zeZHoyva6go0z/0HiY31pT8h/BTQg4Tmn64aWKMF9FWZ0I8MUqNq6hUCq+HF+dHbqPrb1xzQ25RbyHnxkumhAUSbk4sYc1OzmQ+P64ni7mAPmj6LFZh1PCRW92+CYOeAw69WUGbk56Oauw8731wik6CCH32YzAScxLL36SnolH6/vPTIStmVpmriDWLA7ZqaKyH23EPF5giO0i8Yryxc4mCcdVKMW4z6ayNAplAzN24yiPyjVTKCDSfWltKUqOJgD9y/vlhfO25cMCeWeutMfCdn/o/PMlxAo/6WaLJC83gpUBpkrBJ3EsGp5uyDasga8ZcsGtmYeBD0Q9Dfet0NhAQi4wg90Bka8dI5AcSjkgY0qB0ESrxtODZagA+hJl3wuuWs0zrIXrzT4UIrfw7yzScllE0Q4Ivfmb0AmGmUlHwQqBusMoSHSTOFF1a9nToNWBkMlti/29Jp65FkxbY3rwtb8DsaNg43qyPEgjPDR6pucbtzCpt05WfZobpcDQi7OwB0YtQeP9xFP5Ry5X/WkyJ3wPFiL+HAbE4O1WanCdc9lCEZlmZAzz2GdKtc/+gJvMp2+IHdFQcxQZE2sYF3/AV0tPSfbypQ19NI2j3629NAJijOv2mJn5AZoAXchjHh+znV7GcQCVQ4Jaw2NeiuVux/bU1LYSAgBv9HuZ4rQJnk4CEstsbcVKTsvfSkg==",
        "X-Forefront-Antispam-Report": "CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n IPV:NLI; SFV:NSPM; H:SJ0PR13MB5545.namprd13.prod.outlook.com; PTR:; CAT:NONE;\n SFS:(13230016)(4636009)(396003)(366004)(39840400004)(346002)(376002)(136003)(107886003)(44832011)(2616005)(30864003)(41300700001)(6916009)(38350700002)(83380400001)(66574015)(26005)(6512007)(186003)(36756003)(38100700002)(4326008)(2906002)(6506007)(316002)(66946007)(478600001)(86362001)(5660300002)(66476007)(52116002)(6486002)(6666004)(8936002)(8676002)(66556008);\n DIR:OUT; SFP:1102;",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1",
        "X-MS-Exchange-AntiSpam-MessageData-0": "=?utf-8?q?YrMBSqxtqN+jmZ90OdXPJXm/3vlT?=\n\t=?utf-8?q?3Xaq/lMqLIL5yizG5hjrTlKWeTnemUz8m48RMQcbWerTEhp9wW/qsuYhaSDzByObb?=\n\t=?utf-8?q?0+F+ayuSyoAyY4CEEWHE8UByr4rJduzaw0Z8oREmUXRMEc8wcK9B2OA5MP+4vkU0a?=\n\t=?utf-8?q?ygxwlbxcuV4rgNs5qJl4vo6wN1LKfe2Qn2w8E3lPpMsrKQINakKUx3X7MmLotE+P+?=\n\t=?utf-8?q?eGUn7h/4aR1IEdFbkxenmI9hvpmU8ZeRKtvyUTrlNfQgOe5y9FbVbflNH7eYTSSaP?=\n\t=?utf-8?q?lgsmyarfkdqNw2RWwiOeKU3lL8WaY168zQ3rkjiK7FilPISYdXr02DDagVRoIcCG+?=\n\t=?utf-8?q?qNASnHK3fHiKnRn3aZrPp+Lob2tuTlDsOitRoqhealip/O58OLpc5UFBGycZjbocN?=\n\t=?utf-8?q?WcflivHhNB0+99ELVOVX33JAqKh1No9E7/2JkCLN9cjjiO+CjLSnUt7YPSlXGv8/j?=\n\t=?utf-8?q?puzjdQVNE/yFlyddu7ue+SueL9kKUDsTg37AcEd5p+U4YjUV4BlmdRtfWniLJQAt2?=\n\t=?utf-8?q?ccAOFBPuGqupa5PtcpbZCHbLmusyCgXd2GGwMbNchVCicfJYg6xWdwNq5EEkrZpId?=\n\t=?utf-8?q?65wDH8+niZSE9nx80LKKjT+WNlwLnyLRTSQulDmlVp2UgUabrImaGnozCiGkoNEb3?=\n\t=?utf-8?q?dQNPlx9+GKCEN0Th7coIozzeP3plirS1CdAOgXy6s9YiWqfl1xSTNdC3WvDfMTK6N?=\n\t=?utf-8?q?UDDhgN67c5U5ie2vxsS1WRNj+L6MYFAV5RvtVkeS3OYHnZ2VATt+tWj1us0wG8HQ6?=\n\t=?utf-8?q?VVP0v+LT8E6SdkiY7fFqNswsyIISQheG6/T3L0rMa4PGFX71LYm0fjjRNLvPDampE?=\n\t=?utf-8?q?QY3sfV8I/EqfGEQKWICA0CDp8ZwBmCCVnWTPkzAbfMlJyis7tEOK5yJX0uITrO5Qs?=\n\t=?utf-8?q?Vp51rsRri5yhKAEtPM9/1oGBe4QBRMLgv74XFu+5WlM8h2ELx/4OXfTb1CY/KCj27?=\n\t=?utf-8?q?UhYQourNvFeh9ZucvH2s/IaHEFgIxjlWhM+wg9CCoh6sRFDlXjn4wQL0unPti7xNi?=\n\t=?utf-8?q?R5opH5dQaRRn4+CaV/lQl+vcFtDp6D1LqMqveWV55hjxUsz5XIGhpu7pPy2TCxclj?=\n\t=?utf-8?q?v9oJEDKv7OL41voQ/3A+d2+cS9WJYbHLjy/AkJA9eXq/cfnhL+q1wjltF9qE4oiWV?=\n\t=?utf-8?q?Dvb+vXN82V2ea+vrPgzgDPL1W9BoRKF+6h/CCq9TCmN2PAvh9zpKqKCRQUYyBS6F0?=\n\t=?utf-8?q?by0tpThphAMM43UMSzOM7HdwDkP0vcN5zPOmmmxL+U3mBIa5t491oUQlDmco/vfbv?=\n\t=?utf-8?q?ZOi0oTrPYdbgHO46R+fuiVxhlp37YsOJt1toqLiaP6VjDR2d211Xu9r03BPQcthVO?=\n\t=?utf-8?q?oGyFzCu3Z/Z+DmUld4MSk/t8b06lNPN5HdtrKy1B4R83H2s5kwH9DDl7E1eujDu8p?=\n\t=?utf-8?q?k69cuKqELGgJ04s/YBAkmIusEuJeuS67GCAxSd1GWCd59wK7t+M4av2OLP2VqdiFe?=\n\t=?utf-8?q?yaDeHFgjIKNg7El7VMP+ABJVZcDyS3E2d/qa3pfUt4UmJj+4sLKrQ8XWveQYVLtwl?=\n\t=?utf-8?q?JLmY5ry1vW7fT/trGWgkgjGDd0uk39YATQ=3D=3D?=",
        "X-OriginatorOrg": "corigine.com",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "MW4PR13MB5940",
        "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": "Adds the framework to support flower representors. The number of VF\nrepresentors are parsed from the command line. For physical port\nrepresentors the current logic aims to create a representor for\neach physical port present on the hardware.\n\nAn eth_dev is created for each physical port and VF, and flower\nfirmware requires a MAC repr cmsg to be transmitted to firmware\nwith info about the number of physical ports configured.\n\nReify messages are sent to hardware for each physical port representor.\nAn rte_ring is also created per representor so that traffic can be\npushed and pulled to this interface.\n\nTo up and down the real device represented by a flower representor port\na port mod message is used to convey that info to the firmware. This\nmessage will be used in the dev_ops callbacks of flower representors.\n\nEach cmsg generated by the driver is prepended with a cmsg header.\nThis commit also adds the logic to fill in the header of cmsgs.\n\nAlso add the Rx and Tx path for flower representors. For Rx packets are\ndequeued from the representor ring and passed to the eth_dev. For Tx\nthe first queue of the PF vNIC is used. Metadata about the representor\nis added before the packet is sent down to firmware.\n\nSigned-off-by: Chaoyong He <chaoyong.he@corigine.com>\nReviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>\n---\n doc/guides/rel_notes/release_22_11.rst          |   1 +\n drivers/net/nfp/flower/nfp_flower.c             |   7 +\n drivers/net/nfp/flower/nfp_flower.h             |  18 +\n drivers/net/nfp/flower/nfp_flower_cmsg.c        | 186 +++++++\n drivers/net/nfp/flower/nfp_flower_cmsg.h        | 173 ++++++\n drivers/net/nfp/flower/nfp_flower_representor.c | 664 ++++++++++++++++++++++++\n drivers/net/nfp/flower/nfp_flower_representor.h |  39 ++\n drivers/net/nfp/meson.build                     |   2 +\n 8 files changed, 1090 insertions(+)\n create mode 100644 drivers/net/nfp/flower/nfp_flower_cmsg.c\n create mode 100644 drivers/net/nfp/flower/nfp_flower_cmsg.h\n create mode 100644 drivers/net/nfp/flower/nfp_flower_representor.c\n create mode 100644 drivers/net/nfp/flower/nfp_flower_representor.h",
    "diff": "diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst\nindex 0fe928a..f2e4649 100644\n--- a/doc/guides/rel_notes/release_22_11.rst\n+++ b/doc/guides/rel_notes/release_22_11.rst\n@@ -59,6 +59,7 @@ New Features\n      Added the support of flower firmware.\n      Added the flower service infrastructure.\n      Added the control message interactive channels between PMD and firmware.\n+     Added the support of representor port.\n \n Removed Items\n -------------\ndiff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c\nindex b873eba..3f1b7d1 100644\n--- a/drivers/net/nfp/flower/nfp_flower.c\n+++ b/drivers/net/nfp/flower/nfp_flower.c\n@@ -21,6 +21,7 @@\n #include \"nfp_flower.h\"\n #include \"nfp_flower_ovs_compat.h\"\n #include \"nfp_flower_ctrl.h\"\n+#include \"nfp_flower_representor.h\"\n \n #define MAX_PKT_BURST 32\n #define MEMPOOL_CACHE_SIZE 512\n@@ -709,6 +710,12 @@\n \t\tgoto ctrl_vnic_cleanup;\n \t}\n \n+\tret = nfp_flower_repr_create(app_fw_flower);\n+\tif (ret != 0) {\n+\t\tPMD_INIT_LOG(ERR, \"Could not create representor port\");\n+\t\tgoto ctrl_vnic_cleanup;\n+\t}\n+\n \tnfp_flower_ctrl_vnic_poll(app_fw_flower);\n \n \treturn 0;\ndiff --git a/drivers/net/nfp/flower/nfp_flower.h b/drivers/net/nfp/flower/nfp_flower.h\nindex e96d3b2..5d43656 100644\n--- a/drivers/net/nfp/flower/nfp_flower.h\n+++ b/drivers/net/nfp/flower/nfp_flower.h\n@@ -14,8 +14,20 @@\n  */\n #define FLOWER_PKT_DATA_OFFSET 8\n \n+#define MAX_FLOWER_PHYPORTS 8\n+#define MAX_FLOWER_VFS 64\n+\n /* The flower application's private structure */\n struct nfp_app_fw_flower {\n+\t/* switch domain for this app */\n+\tuint16_t switch_domain_id;\n+\n+\t/* Number of VF representors */\n+\tuint8_t num_vf_reprs;\n+\n+\t/* Number of phyport representors */\n+\tuint8_t num_phyport_reprs;\n+\n \t/* Pointer to a mempool for the PF vNIC */\n \tstruct rte_mempool *pf_pktmbuf_pool;\n \n@@ -36,6 +48,12 @@ struct nfp_app_fw_flower {\n \n \t/* Ctrl vNIC Tx counter */\n \tuint64_t ctrl_vnic_tx_count;\n+\n+\t/* Array of phyport representors */\n+\tstruct nfp_flower_representor *phy_reprs[MAX_FLOWER_PHYPORTS];\n+\n+\t/* Array of VF representors */\n+\tstruct nfp_flower_representor *vf_reprs[MAX_FLOWER_VFS];\n };\n \n int nfp_init_app_fw_flower(struct nfp_pf_dev *pf_dev);\ndiff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.c b/drivers/net/nfp/flower/nfp_flower_cmsg.c\nnew file mode 100644\nindex 0000000..d16d373\n--- /dev/null\n+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.c\n@@ -0,0 +1,186 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2022 Corigine, Inc.\n+ * All rights reserved.\n+ */\n+\n+#include \"../nfpcore/nfp_nsp.h\"\n+#include \"../nfp_logs.h\"\n+#include \"../nfp_common.h\"\n+#include \"nfp_flower.h\"\n+#include \"nfp_flower_cmsg.h\"\n+#include \"nfp_flower_ctrl.h\"\n+#include \"nfp_flower_representor.h\"\n+\n+static void *\n+nfp_flower_cmsg_init(struct rte_mbuf *m,\n+\t\tenum nfp_flower_cmsg_type type,\n+\t\tuint32_t size)\n+{\n+\tchar *pkt;\n+\tuint32_t data;\n+\tuint32_t new_size = size;\n+\tstruct nfp_flower_cmsg_hdr *hdr;\n+\n+\tpkt = rte_pktmbuf_mtod(m, char *);\n+\tPMD_DRV_LOG(DEBUG, \"flower_cmsg_init using pkt at %p\", pkt);\n+\n+\tdata = rte_cpu_to_be_32(NFP_NET_META_PORTID);\n+\trte_memcpy(pkt, &data, 4);\n+\tpkt += 4;\n+\tnew_size += 4;\n+\n+\t/* First the metadata as flower requires it */\n+\tdata = rte_cpu_to_be_32(NFP_META_PORT_ID_CTRL);\n+\trte_memcpy(pkt, &data, 4);\n+\tpkt += 4;\n+\tnew_size += 4;\n+\n+\t/* Now the ctrl header */\n+\thdr = (struct nfp_flower_cmsg_hdr *)pkt;\n+\thdr->pad     = 0;\n+\thdr->type    = type;\n+\thdr->version = NFP_FLOWER_CMSG_VER1;\n+\n+\tpkt = (char *)hdr + NFP_FLOWER_CMSG_HLEN;\n+\tnew_size += NFP_FLOWER_CMSG_HLEN;\n+\n+\tm->pkt_len = new_size;\n+\tm->data_len = m->pkt_len;\n+\n+\treturn pkt;\n+}\n+\n+static void\n+nfp_flower_cmsg_mac_repr_init(struct rte_mbuf *m, int num_ports)\n+{\n+\tuint32_t size;\n+\tstruct nfp_flower_cmsg_mac_repr *msg;\n+\tenum nfp_flower_cmsg_type type = NFP_FLOWER_CMSG_TYPE_MAC_REPR;\n+\n+\tsize = sizeof(*msg) + (num_ports * sizeof(msg->ports[0]));\n+\tPMD_DRV_LOG(DEBUG, \"mac repr cmsg init with size: %u\", size);\n+\tmsg = (struct nfp_flower_cmsg_mac_repr *)nfp_flower_cmsg_init(m,\n+\t\t\ttype, size);\n+\n+\tmemset(msg->reserved, 0, sizeof(msg->reserved));\n+\tmsg->num_ports = num_ports;\n+}\n+\n+static void\n+nfp_flower_cmsg_mac_repr_fill(struct rte_mbuf *m,\n+\t\tunsigned int idx,\n+\t\tunsigned int nbi,\n+\t\tunsigned int nbi_port,\n+\t\tunsigned int phys_port)\n+{\n+\tstruct nfp_flower_cmsg_mac_repr *msg;\n+\n+\tmsg = (struct nfp_flower_cmsg_mac_repr *)nfp_flower_cmsg_get_data(m);\n+\tmsg->ports[idx].idx       = idx;\n+\tmsg->ports[idx].info      = nbi & NFP_FLOWER_CMSG_MAC_REPR_NBI;\n+\tmsg->ports[idx].nbi_port  = nbi_port;\n+\tmsg->ports[idx].phys_port = phys_port;\n+}\n+\n+int\n+nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower)\n+{\n+\tint i;\n+\tuint16_t cnt;\n+\tunsigned int nbi;\n+\tunsigned int nbi_port;\n+\tunsigned int phys_port;\n+\tstruct rte_mbuf *mbuf;\n+\tstruct nfp_eth_table *nfp_eth_table;\n+\n+\tmbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);\n+\tif (mbuf == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not allocate mac repr cmsg\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tnfp_flower_cmsg_mac_repr_init(mbuf, app_fw_flower->num_phyport_reprs);\n+\n+\t/* Fill in the mac repr cmsg */\n+\tnfp_eth_table = app_fw_flower->nfp_eth_table;\n+\tfor (i = 0; i < app_fw_flower->num_phyport_reprs; i++) {\n+\t\tnbi = nfp_eth_table->ports[i].nbi;\n+\t\tnbi_port = nfp_eth_table->ports[i].base;\n+\t\tphys_port = nfp_eth_table->ports[i].index;\n+\n+\t\tnfp_flower_cmsg_mac_repr_fill(mbuf, i, nbi, nbi_port, phys_port);\n+\t}\n+\n+\t/* Send the cmsg via the ctrl vNIC */\n+\tcnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);\n+\tif (cnt == 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Send cmsg through ctrl vnic failed.\");\n+\t\trte_pktmbuf_free(mbuf);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct nfp_flower_representor *repr)\n+{\n+\tuint16_t cnt;\n+\tstruct rte_mbuf *mbuf;\n+\tstruct nfp_flower_cmsg_port_reify *msg;\n+\n+\tmbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);\n+\tif (mbuf == NULL) {\n+\t\tPMD_DRV_LOG(DEBUG, \"alloc mbuf for repr reify failed\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tmsg = (struct nfp_flower_cmsg_port_reify *)nfp_flower_cmsg_init(mbuf,\n+\t\t\tNFP_FLOWER_CMSG_TYPE_PORT_REIFY, sizeof(*msg));\n+\n+\tmsg->portnum  = rte_cpu_to_be_32(repr->port_id);\n+\tmsg->reserved = 0;\n+\tmsg->info     = rte_cpu_to_be_16(1);\n+\n+\tcnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);\n+\tif (cnt == 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Send cmsg through ctrl vnic failed.\");\n+\t\trte_pktmbuf_free(mbuf);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+nfp_flower_cmsg_port_mod(struct nfp_app_fw_flower *app_fw_flower,\n+\t\tuint32_t port_id, bool carrier_ok)\n+{\n+\tuint16_t cnt;\n+\tstruct rte_mbuf *mbuf;\n+\tstruct nfp_flower_cmsg_port_mod *msg;\n+\n+\tmbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);\n+\tif (mbuf == NULL) {\n+\t\tPMD_DRV_LOG(DEBUG, \"alloc mbuf for repr portmod failed\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tmsg = (struct nfp_flower_cmsg_port_mod *)nfp_flower_cmsg_init(mbuf,\n+\t\t\tNFP_FLOWER_CMSG_TYPE_PORT_MOD, sizeof(*msg));\n+\n+\tmsg->portnum  = rte_cpu_to_be_32(port_id);\n+\tmsg->reserved = 0;\n+\tmsg->info     = carrier_ok;\n+\tmsg->mtu      = 9000;\n+\n+\tcnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);\n+\tif (cnt == 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Send cmsg through ctrl vnic failed.\");\n+\t\trte_pktmbuf_free(mbuf);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h\nnew file mode 100644\nindex 0000000..0bf8fc8\n--- /dev/null\n+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h\n@@ -0,0 +1,173 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2022 Corigine, Inc.\n+ * All rights reserved.\n+ */\n+\n+#ifndef _NFP_CMSG_H_\n+#define _NFP_CMSG_H_\n+\n+#include <rte_byteorder.h>\n+#include <rte_ether.h>\n+\n+struct nfp_flower_cmsg_hdr {\n+\trte_be16_t pad;\n+\tuint8_t type;\n+\tuint8_t version;\n+};\n+\n+/* Types defined for control messages */\n+enum nfp_flower_cmsg_type {\n+\tNFP_FLOWER_CMSG_TYPE_FLOW_ADD       = 0,\n+\tNFP_FLOWER_CMSG_TYPE_FLOW_MOD       = 1,\n+\tNFP_FLOWER_CMSG_TYPE_FLOW_DEL       = 2,\n+\tNFP_FLOWER_CMSG_TYPE_LAG_CONFIG     = 4,\n+\tNFP_FLOWER_CMSG_TYPE_PORT_REIFY     = 6,\n+\tNFP_FLOWER_CMSG_TYPE_MAC_REPR       = 7,\n+\tNFP_FLOWER_CMSG_TYPE_PORT_MOD       = 8,\n+\tNFP_FLOWER_CMSG_TYPE_MERGE_HINT     = 9,\n+\tNFP_FLOWER_CMSG_TYPE_NO_NEIGH       = 10,\n+\tNFP_FLOWER_CMSG_TYPE_TUN_MAC        = 11,\n+\tNFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS    = 12,\n+\tNFP_FLOWER_CMSG_TYPE_TUN_NEIGH      = 13,\n+\tNFP_FLOWER_CMSG_TYPE_TUN_IPS        = 14,\n+\tNFP_FLOWER_CMSG_TYPE_FLOW_STATS     = 15,\n+\tNFP_FLOWER_CMSG_TYPE_PORT_ECHO      = 16,\n+\tNFP_FLOWER_CMSG_TYPE_QOS_MOD        = 18,\n+\tNFP_FLOWER_CMSG_TYPE_QOS_DEL        = 19,\n+\tNFP_FLOWER_CMSG_TYPE_QOS_STATS      = 20,\n+\tNFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE   = 21,\n+\tNFP_FLOWER_CMSG_TYPE_TUN_IPS_V6     = 22,\n+\tNFP_FLOWER_CMSG_TYPE_NO_NEIGH_V6    = 23,\n+\tNFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6   = 24,\n+\tNFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS_V6 = 25,\n+\tNFP_FLOWER_CMSG_TYPE_MAX            = 32,\n+};\n+\n+/*\n+ * NFP_FLOWER_CMSG_TYPE_MAC_REPR\n+ *    Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0\n+ *    -----\\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+ *     Word +---------------+-----------+---+---------------+---------------+\n+ *       0  |                  spare                        |Number of ports|\n+ *          +---------------+-----------+---+---------------+---------------+\n+ *       1  |    Index      |   spare   |NBI|  Port on NBI  | Chip-wide port|\n+ *          +---------------+-----------+---+---------------+---------------+\n+ *                                        ....\n+ *          +---------------+-----------+---+---------------+---------------+\n+ *     N-1  |    Index      |   spare   |NBI|  Port on NBI  | Chip-wide port|\n+ *          +---------------+-----------+---+---------------+---------------+\n+ *     N    |    Index      |   spare   |NBI|  Port on NBI  | Chip-wide port|\n+ *          +---------------+-----------+---+---------------+---------------+\n+ *\n+ *          Index: index into the eth table\n+ *          NBI (bits 17-16): NBI number (0-3)\n+ *          Port on NBI (bits 15-8): “base” in the driver\n+ *            this forms NBIX.PortY notation as the NSP eth table.\n+ *          \"Chip-wide\" port (bits 7-0):\n+ */\n+struct nfp_flower_cmsg_mac_repr {\n+\tuint8_t reserved[3];\n+\tuint8_t num_ports;\n+\tstruct {\n+\t\tuint8_t idx;\n+\t\tuint8_t info;\n+\t\tuint8_t nbi_port;\n+\t\tuint8_t phys_port;\n+\t} ports[0];\n+};\n+\n+/*\n+ * NFP_FLOWER_CMSG_TYPE_PORT_REIFY\n+ *    Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0\n+ *    -----\\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+ *    Word  +-------+-------+---+---+-------+---+---+-----------+-----------+\n+ *       0  |Port Ty|Sys ID |NIC|Rsv| Spare |PCI|typ|    vNIC   |  queue    |\n+ *          +-------+-----+-+---+---+-------+---+---+-----------+---------+-+\n+ *       1  |                             Spare                           |E|\n+ *          +-------------------------------------------------------------+-+\n+ *          E: 1 = Representor exists, 0 = Representor does not exist\n+ */\n+struct nfp_flower_cmsg_port_reify {\n+\trte_be32_t portnum;\n+\trte_be16_t reserved;\n+\trte_be16_t info;\n+};\n+\n+/*\n+ * NFP_FLOWER_CMSG_TYPE_PORT_MOD\n+ *    Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0\n+ *    -----\\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+ *    Word  +-------+-------+---+---+-------+---+---+-------+---+-----------+\n+ *       0  |Port Ty|Sys ID |NIC|Rsv|       Reserved        |    Port       |\n+ *          +-------+-------+---+---+-----+-+---+---+-------+---+-----------+\n+ *       1  |            Spare            |L|              MTU              |\n+ *          +-----------------------------+-+-------------------------------+\n+ *        L: Link or Admin state bit. When message is generated by host, this\n+ *           bit indicates the admin state (0=down, 1=up). When generated by\n+ *           NFP, it indicates the link state (0=down, 1=up)\n+ *\n+ *        Port Type (word 1, bits 31 to 28) = 1 (Physical Network)\n+ *        Port: “Chip-wide number” as assigned by BSP\n+ *\n+ *    Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0\n+ *    -----\\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+ *    Word  +-------+-------+---+---+-------+---+---+-------+---+-----------+\n+ *       0  |Port Ty|Sys ID |NIC|Rsv| Spare |PCI|typ|    vNIC   |  queue    |\n+ *          +-------+-----+-+---+---+---+-+-+---+---+-------+---+-----------+\n+ *       1  |            Spare            |L|              MTU              |\n+ *          +-----------------------------+-+-------------------------------+\n+ *        L: Link or Admin state bit. When message is generated by host, this\n+ *           bit indicates the admin state (0=down, 1=up). When generated by\n+ *           NFP, it indicates the link state (0=down, 1=up)\n+ *\n+ *        Port Type (word 1, bits 31 to 28) = 2 (PCIE)\n+ */\n+struct nfp_flower_cmsg_port_mod {\n+\trte_be32_t portnum;\n+\tuint8_t reserved;\n+\tuint8_t info;\n+\trte_be16_t mtu;\n+};\n+\n+enum nfp_flower_cmsg_port_type {\n+\tNFP_FLOWER_CMSG_PORT_TYPE_UNSPEC,\n+\tNFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT,\n+\tNFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT,\n+\tNFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT,\n+};\n+\n+enum nfp_flower_cmsg_port_vnic_type {\n+\tNFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,\n+\tNFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF,\n+\tNFP_FLOWER_CMSG_PORT_VNIC_TYPE_CTRL,\n+};\n+\n+#define NFP_FLOWER_CMSG_MAC_REPR_NBI            (0x3)\n+\n+#define NFP_FLOWER_CMSG_HLEN            sizeof(struct nfp_flower_cmsg_hdr)\n+#define NFP_FLOWER_CMSG_VER1            1\n+#define NFP_NET_META_PORTID             5\n+#define NFP_META_PORT_ID_CTRL           ~0U\n+\n+#define NFP_FLOWER_CMSG_PORT_TYPE(x)            (((x) >> 28) & 0xf)  /* [31,28] */\n+#define NFP_FLOWER_CMSG_PORT_SYS_ID(x)          (((x) >> 24) & 0xf)  /* [24,27] */\n+#define NFP_FLOWER_CMSG_PORT_NFP_ID(x)          (((x) >> 22) & 0x3)  /* [22,23] */\n+#define NFP_FLOWER_CMSG_PORT_PCI(x)             (((x) >> 14) & 0x3)  /* [14,15] */\n+#define NFP_FLOWER_CMSG_PORT_VNIC_TYPE(x)       (((x) >> 12) & 0x3)  /* [12,13] */\n+#define NFP_FLOWER_CMSG_PORT_VNIC(x)            (((x) >> 6) & 0x3f)  /* [6,11] */\n+#define NFP_FLOWER_CMSG_PORT_PCIE_Q(x)          ((x) & 0x3f)         /* [0,5] */\n+#define NFP_FLOWER_CMSG_PORT_PHYS_PORT_NUM(x)   ((x) & 0xff)         /* [0,7] */\n+\n+static inline char*\n+nfp_flower_cmsg_get_data(struct rte_mbuf *m)\n+{\n+\treturn rte_pktmbuf_mtod(m, char *) + 4 + 4 + NFP_FLOWER_CMSG_HLEN;\n+}\n+\n+int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);\n+int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct nfp_flower_representor *repr);\n+int nfp_flower_cmsg_port_mod(struct nfp_app_fw_flower *app_fw_flower,\n+\t\tuint32_t port_id, bool carrier_ok);\n+\n+#endif /* _NFP_CMSG_H_ */\ndiff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c\nnew file mode 100644\nindex 0000000..cdcf098\n--- /dev/null\n+++ b/drivers/net/nfp/flower/nfp_flower_representor.c\n@@ -0,0 +1,664 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2022 Corigine, Inc.\n+ * All rights reserved.\n+ */\n+\n+#include <rte_common.h>\n+#include <ethdev_pci.h>\n+\n+#include \"../nfp_common.h\"\n+#include \"../nfp_logs.h\"\n+#include \"../nfp_ctrl.h\"\n+#include \"../nfp_rxtx.h\"\n+#include \"../nfpcore/nfp_mip.h\"\n+#include \"../nfpcore/nfp_rtsym.h\"\n+#include \"../nfpcore/nfp_nsp.h\"\n+#include \"nfp_flower.h\"\n+#include \"nfp_flower_representor.h\"\n+#include \"nfp_flower_ctrl.h\"\n+#include \"nfp_flower_cmsg.h\"\n+\n+static int\n+nfp_flower_repr_link_update(struct rte_eth_dev *dev,\n+\t\t__rte_unused int wait_to_complete)\n+{\n+\tint ret;\n+\tuint32_t nn_link_status;\n+\tstruct nfp_net_hw *pf_hw;\n+\tstruct rte_eth_link *link;\n+\tstruct nfp_flower_representor *repr;\n+\n+\tstatic const uint32_t ls_to_ethtool[] = {\n+\t\t[NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = RTE_ETH_SPEED_NUM_NONE,\n+\t\t[NFP_NET_CFG_STS_LINK_RATE_UNKNOWN]     = RTE_ETH_SPEED_NUM_NONE,\n+\t\t[NFP_NET_CFG_STS_LINK_RATE_1G]          = RTE_ETH_SPEED_NUM_1G,\n+\t\t[NFP_NET_CFG_STS_LINK_RATE_10G]         = RTE_ETH_SPEED_NUM_10G,\n+\t\t[NFP_NET_CFG_STS_LINK_RATE_25G]         = RTE_ETH_SPEED_NUM_25G,\n+\t\t[NFP_NET_CFG_STS_LINK_RATE_40G]         = RTE_ETH_SPEED_NUM_40G,\n+\t\t[NFP_NET_CFG_STS_LINK_RATE_50G]         = RTE_ETH_SPEED_NUM_50G,\n+\t\t[NFP_NET_CFG_STS_LINK_RATE_100G]        = RTE_ETH_SPEED_NUM_100G,\n+\t};\n+\n+\trepr = (struct nfp_flower_representor *)dev->data->dev_private;\n+\tlink = &repr->link;\n+\tpf_hw = repr->app_fw_flower->pf_hw;\n+\n+\tmemset(link, 0, sizeof(struct rte_eth_link));\n+\tnn_link_status = nn_cfg_readl(pf_hw, NFP_NET_CFG_STS);\n+\n+\tif (nn_link_status & NFP_NET_CFG_STS_LINK)\n+\t\tlink->link_status = RTE_ETH_LINK_UP;\n+\n+\tlink->link_duplex = RTE_ETH_LINK_FULL_DUPLEX;\n+\n+\tnn_link_status = (nn_link_status >> NFP_NET_CFG_STS_LINK_RATE_SHIFT) &\n+\t\t\t NFP_NET_CFG_STS_LINK_RATE_MASK;\n+\n+\tif (nn_link_status >= RTE_DIM(ls_to_ethtool))\n+\t\tlink->link_speed = RTE_ETH_SPEED_NUM_NONE;\n+\telse\n+\t\tlink->link_speed = ls_to_ethtool[nn_link_status];\n+\n+\tret = rte_eth_linkstatus_set(dev, link);\n+\tif (ret == 0) {\n+\t\tif (link->link_status)\n+\t\t\tPMD_DRV_LOG(INFO, \"NIC Link is Up\");\n+\t\telse\n+\t\t\tPMD_DRV_LOG(INFO, \"NIC Link is Down\");\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static int\n+nfp_flower_repr_dev_infos_get(__rte_unused struct rte_eth_dev *dev,\n+\t\tstruct rte_eth_dev_info *dev_info)\n+{\n+\t/* Hardcoded pktlen and queues for now */\n+\tdev_info->max_rx_queues = 1;\n+\tdev_info->max_tx_queues = 1;\n+\tdev_info->min_rx_bufsize = RTE_ETHER_MIN_MTU;\n+\tdev_info->max_rx_pktlen = 9000;\n+\n+\tdev_info->rx_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP;\n+\tdev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |\n+\t\t\tRTE_ETH_RX_OFFLOAD_UDP_CKSUM |\n+\t\t\tRTE_ETH_RX_OFFLOAD_TCP_CKSUM;\n+\n+\tdev_info->tx_offload_capa = RTE_ETH_TX_OFFLOAD_VLAN_INSERT;\n+\tdev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |\n+\t\t\tRTE_ETH_TX_OFFLOAD_UDP_CKSUM |\n+\t\t\tRTE_ETH_TX_OFFLOAD_TCP_CKSUM;\n+\tdev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_TCP_TSO;\n+\tdev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_MULTI_SEGS;\n+\n+\tdev_info->max_mac_addrs = 1;\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_flower_repr_dev_configure(struct rte_eth_dev *dev)\n+{\n+\tstruct nfp_net_hw *pf_hw;\n+\tstruct rte_eth_conf *dev_conf;\n+\tstruct rte_eth_rxmode *rxmode;\n+\tstruct nfp_flower_representor *repr;\n+\n+\trepr = (struct nfp_flower_representor *)dev->data->dev_private;\n+\tpf_hw = repr->app_fw_flower->pf_hw;\n+\n+\tdev_conf = &dev->data->dev_conf;\n+\trxmode = &dev_conf->rxmode;\n+\n+\t/* Checking MTU set */\n+\tif (rxmode->mtu > pf_hw->flbufsz) {\n+\t\tPMD_DRV_LOG(INFO, \"MTU (%u) larger then current mbufsize (%u) not supported\",\n+\t\t\t\trxmode->mtu, pf_hw->flbufsz);\n+\t\treturn -ERANGE;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_flower_repr_dev_start(struct rte_eth_dev *dev)\n+{\n+\tstruct nfp_app_fw_flower *app_fw_flower;\n+\tstruct nfp_flower_representor *repr;\n+\n+\trepr = (struct nfp_flower_representor *)dev->data->dev_private;\n+\tapp_fw_flower = repr->app_fw_flower;\n+\n+\tif (repr->repr_type == NFP_REPR_TYPE_PHYS_PORT)\n+\t\tnfp_eth_set_configured(app_fw_flower->pf_hw->pf_dev->cpp,\n+\t\t\t\trepr->nfp_idx, 1);\n+\n+\tnfp_flower_cmsg_port_mod(app_fw_flower, repr->port_id, true);\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_flower_repr_dev_stop(struct rte_eth_dev *dev)\n+{\n+\tstruct nfp_app_fw_flower *app_fw_flower;\n+\tstruct nfp_flower_representor *repr;\n+\n+\trepr = (struct nfp_flower_representor *)dev->data->dev_private;\n+\tapp_fw_flower = repr->app_fw_flower;\n+\n+\tnfp_flower_cmsg_port_mod(app_fw_flower, repr->port_id, false);\n+\n+\tif (repr->repr_type == NFP_REPR_TYPE_PHYS_PORT)\n+\t\tnfp_eth_set_configured(app_fw_flower->pf_hw->pf_dev->cpp,\n+\t\t\t\trepr->nfp_idx, 0);\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_flower_repr_rx_queue_setup(struct rte_eth_dev *dev,\n+\t\tuint16_t rx_queue_id,\n+\t\t__rte_unused uint16_t nb_rx_desc,\n+\t\tunsigned int socket_id,\n+\t\t__rte_unused const struct rte_eth_rxconf *rx_conf,\n+\t\t__rte_unused struct rte_mempool *mb_pool)\n+{\n+\tstruct nfp_net_rxq *rxq;\n+\tstruct nfp_net_hw *pf_hw;\n+\tstruct nfp_flower_representor *repr;\n+\n+\trepr = (struct nfp_flower_representor *)dev->data->dev_private;\n+\tpf_hw = repr->app_fw_flower->pf_hw;\n+\n+\t/* Allocating rx queue data structure */\n+\trxq = rte_zmalloc_socket(\"ethdev RX queue\", sizeof(struct nfp_net_rxq),\n+\t\t\tRTE_CACHE_LINE_SIZE, socket_id);\n+\tif (rxq == NULL)\n+\t\treturn -ENOMEM;\n+\n+\trxq->hw = pf_hw;\n+\trxq->qidx = rx_queue_id;\n+\trxq->port_id = dev->data->port_id;\n+\tdev->data->rx_queues[rx_queue_id] = rxq;\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_flower_repr_tx_queue_setup(struct rte_eth_dev *dev,\n+\t\tuint16_t tx_queue_id,\n+\t\t__rte_unused uint16_t nb_tx_desc,\n+\t\tunsigned int socket_id,\n+\t\t__rte_unused const struct rte_eth_txconf *tx_conf)\n+{\n+\tstruct nfp_net_txq *txq;\n+\tstruct nfp_net_hw *pf_hw;\n+\tstruct nfp_flower_representor *repr;\n+\n+\trepr = (struct nfp_flower_representor *)dev->data->dev_private;\n+\tpf_hw = repr->app_fw_flower->pf_hw;\n+\n+\t/* Allocating tx queue data structure */\n+\ttxq = rte_zmalloc_socket(\"ethdev TX queue\", sizeof(struct nfp_net_txq),\n+\t\t\tRTE_CACHE_LINE_SIZE, socket_id);\n+\tif (txq == NULL)\n+\t\treturn -ENOMEM;\n+\n+\ttxq->hw = pf_hw;\n+\ttxq->qidx = tx_queue_id;\n+\ttxq->port_id = dev->data->port_id;\n+\tdev->data->tx_queues[tx_queue_id] = txq;\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_flower_repr_stats_get(struct rte_eth_dev *ethdev,\n+\t\tstruct rte_eth_stats *stats)\n+{\n+\tstruct nfp_flower_representor *repr;\n+\n+\trepr = (struct nfp_flower_representor *)ethdev->data->dev_private;\n+\trte_memcpy(stats, &repr->repr_stats, sizeof(struct rte_eth_stats));\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_flower_repr_stats_reset(struct rte_eth_dev *ethdev)\n+{\n+\tstruct nfp_flower_representor *repr;\n+\n+\trepr = (struct nfp_flower_representor *)ethdev->data->dev_private;\n+\tmemset(&repr->repr_stats, 0, sizeof(struct rte_eth_stats));\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_flower_repr_promiscuous_enable(struct rte_eth_dev *dev)\n+{\n+\tstruct nfp_net_hw *pf_hw;\n+\tstruct nfp_flower_representor *repr;\n+\n+\trepr = (struct nfp_flower_representor *)dev->data->dev_private;\n+\tpf_hw = repr->app_fw_flower->pf_hw;\n+\n+\tif (!(pf_hw->cap & NFP_NET_CFG_CTRL_PROMISC)) {\n+\t\tPMD_DRV_LOG(INFO, \"Promiscuous mode not supported\");\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\tif (pf_hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) {\n+\t\tPMD_DRV_LOG(INFO, \"Promiscuous mode already enabled\");\n+\t\treturn 0;\n+\t}\n+\n+\treturn nfp_net_promisc_enable(pf_hw->eth_dev);\n+}\n+\n+static int\n+nfp_flower_repr_promiscuous_disable(struct rte_eth_dev *dev)\n+{\n+\tstruct nfp_net_hw *pf_hw;\n+\tstruct nfp_flower_representor *repr;\n+\n+\trepr = (struct nfp_flower_representor *)dev->data->dev_private;\n+\tpf_hw = repr->app_fw_flower->pf_hw;\n+\n+\tif ((pf_hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) == 0) {\n+\t\tPMD_DRV_LOG(INFO, \"Promiscuous mode already disabled\");\n+\t\treturn 0;\n+\t}\n+\n+\treturn nfp_net_promisc_disable(pf_hw->eth_dev);\n+}\n+\n+static int\n+nfp_flower_repr_mac_addr_set(struct rte_eth_dev *ethdev,\n+\t\tstruct rte_ether_addr *mac_addr)\n+{\n+\tstruct nfp_flower_representor *repr;\n+\n+\trepr = (struct nfp_flower_representor *)ethdev->data->dev_private;\n+\trte_ether_addr_copy(mac_addr, &repr->mac_addr);\n+\trte_ether_addr_copy(mac_addr, ethdev->data->mac_addrs);\n+\n+\treturn 0;\n+}\n+\n+static uint16_t\n+nfp_flower_repr_rx_burst(void *rx_queue,\n+\t\tstruct rte_mbuf **rx_pkts,\n+\t\tuint16_t nb_pkts)\n+{\n+\tunsigned int available = 0;\n+\tunsigned int total_dequeue;\n+\tstruct nfp_net_rxq *rxq;\n+\tstruct rte_eth_dev *dev;\n+\tstruct nfp_flower_representor *repr;\n+\n+\trxq = rx_queue;\n+\tif (unlikely(rxq == NULL)) {\n+\t\tPMD_RX_LOG(ERR, \"RX Bad queue\");\n+\t\treturn 0;\n+\t}\n+\n+\tdev = &rte_eth_devices[rxq->port_id];\n+\trepr = dev->data->dev_private;\n+\tif (unlikely(repr->ring == NULL)) {\n+\t\tPMD_RX_LOG(ERR, \"representor %s has no ring configured!\",\n+\t\t\t\trepr->name);\n+\t\treturn 0;\n+\t}\n+\n+\ttotal_dequeue = rte_ring_dequeue_burst(repr->ring, (void *)rx_pkts,\n+\t\t\tnb_pkts, &available);\n+\tif (total_dequeue != 0) {\n+\t\tPMD_RX_LOG(DEBUG, \"Representor Rx burst for %s, port_id: 0x%x, \"\n+\t\t\t\t\"received: %u, available: %u\", repr->name,\n+\t\t\t\trepr->port_id, total_dequeue, available);\n+\n+\t\trepr->repr_stats.ipackets += total_dequeue;\n+\t}\n+\n+\treturn total_dequeue;\n+}\n+\n+static uint16_t\n+nfp_flower_repr_tx_burst(void *tx_queue,\n+\t\tstruct rte_mbuf **tx_pkts,\n+\t\tuint16_t nb_pkts)\n+{\n+\tuint16_t i;\n+\tuint16_t sent;\n+\tchar *meta_offset;\n+\tstruct nfp_net_txq *txq;\n+\tstruct nfp_net_hw *pf_hw;\n+\tstruct rte_eth_dev *dev;\n+\tstruct rte_eth_dev *repr_dev;\n+\tstruct nfp_flower_representor *repr;\n+\n+\ttxq = tx_queue;\n+\tif (unlikely(txq == NULL)) {\n+\t\tPMD_TX_LOG(ERR, \"TX Bad queue\");\n+\t\treturn 0;\n+\t}\n+\n+\t/* This points to the PF vNIC that owns this representor */\n+\tpf_hw = txq->hw;\n+\tdev = pf_hw->eth_dev;\n+\n+\t/* Grab a handle to the representor struct */\n+\trepr_dev = &rte_eth_devices[txq->port_id];\n+\trepr = repr_dev->data->dev_private;\n+\n+\tfor (i = 0; i < nb_pkts; i++) {\n+\t\tmeta_offset = rte_pktmbuf_prepend(tx_pkts[i], FLOWER_PKT_DATA_OFFSET);\n+\t\t*(uint32_t *)meta_offset = rte_cpu_to_be_32(NFP_NET_META_PORTID);\n+\t\tmeta_offset += 4;\n+\t\t*(uint32_t *)meta_offset = rte_cpu_to_be_32(repr->port_id);\n+\t}\n+\n+\t/* Only using Tx queue 0 for now. */\n+\tsent = rte_eth_tx_burst(dev->data->port_id, 0, tx_pkts, nb_pkts);\n+\tif (sent != 0) {\n+\t\tPMD_TX_LOG(DEBUG, \"Representor Tx burst for %s, port_id: 0x%x \"\n+\t\t\t\"transmitted: %u\", repr->name, repr->port_id, sent);\n+\t\trepr->repr_stats.opackets += sent;\n+\t}\n+\n+\treturn sent;\n+}\n+\n+static const struct eth_dev_ops nfp_flower_repr_dev_ops = {\n+\t.dev_infos_get        = nfp_flower_repr_dev_infos_get,\n+\n+\t.dev_start            = nfp_flower_repr_dev_start,\n+\t.dev_configure        = nfp_flower_repr_dev_configure,\n+\t.dev_stop             = nfp_flower_repr_dev_stop,\n+\n+\t.rx_queue_setup       = nfp_flower_repr_rx_queue_setup,\n+\t.tx_queue_setup       = nfp_flower_repr_tx_queue_setup,\n+\n+\t.link_update          = nfp_flower_repr_link_update,\n+\n+\t.stats_get            = nfp_flower_repr_stats_get,\n+\t.stats_reset          = nfp_flower_repr_stats_reset,\n+\n+\t.promiscuous_enable   = nfp_flower_repr_promiscuous_enable,\n+\t.promiscuous_disable  = nfp_flower_repr_promiscuous_disable,\n+\n+\t.mac_addr_set         = nfp_flower_repr_mac_addr_set,\n+};\n+\n+static uint32_t\n+nfp_flower_get_phys_port_id(uint8_t port)\n+{\n+\treturn (NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT << 28) | port;\n+}\n+\n+static uint32_t\n+nfp_get_pcie_port_id(struct nfp_cpp *cpp,\n+\t\tint type,\n+\t\tuint8_t vnic,\n+\t\tuint8_t queue)\n+{\n+\tuint8_t nfp_pcie;\n+\tuint32_t port_id;\n+\n+\tnfp_pcie = NFP_CPP_INTERFACE_UNIT_of(nfp_cpp_interface(cpp));\n+\tport_id = ((nfp_pcie & 0x3) << 14) |\n+\t\t  ((type & 0x3) << 12) |\n+\t\t  ((vnic & 0x3f) << 6) |\n+\t\t  (queue & 0x3f) |\n+\t\t  ((NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT & 0xf) << 28);\n+\n+\treturn port_id;\n+}\n+\n+static int\n+nfp_flower_repr_init(struct rte_eth_dev *eth_dev,\n+\t\tvoid *init_params)\n+{\n+\tint ret;\n+\tunsigned int numa_node;\n+\tchar ring_name[RTE_ETH_NAME_MAX_LEN];\n+\tstruct nfp_app_fw_flower *app_fw_flower;\n+\tstruct nfp_flower_representor *repr;\n+\tstruct nfp_flower_representor *init_repr_data;\n+\n+\t/* Cast the input representor data to the correct struct here */\n+\tinit_repr_data = (struct nfp_flower_representor *)init_params;\n+\n+\tapp_fw_flower = init_repr_data->app_fw_flower;\n+\n+\t/* Memory has been allocated in the eth_dev_create() function */\n+\trepr = eth_dev->data->dev_private;\n+\n+\t/*\n+\t * We need multiproduce rings as we can have multiple PF ports.\n+\t * On the other hand, we need single consumer rings, as just one\n+\t * representor PMD will try to read from the ring.\n+\t */\n+\tsnprintf(ring_name, sizeof(ring_name), \"%s_%s\",\n+\t\tinit_repr_data->name, \"ring\");\n+\tnuma_node = rte_socket_id();\n+\trepr->ring = rte_ring_create(ring_name, 256, numa_node, RING_F_SC_DEQ);\n+\tif (repr->ring == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"rte_ring_create failed for %s\", ring_name);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/* Copy data here from the input representor template*/\n+\trepr->vf_id            = init_repr_data->vf_id;\n+\trepr->switch_domain_id = init_repr_data->switch_domain_id;\n+\trepr->port_id          = init_repr_data->port_id;\n+\trepr->nfp_idx          = init_repr_data->nfp_idx;\n+\trepr->repr_type        = init_repr_data->repr_type;\n+\trepr->app_fw_flower       = init_repr_data->app_fw_flower;\n+\n+\tsnprintf(repr->name, sizeof(repr->name), \"%s\", init_repr_data->name);\n+\n+\teth_dev->dev_ops = &nfp_flower_repr_dev_ops;\n+\n+\teth_dev->rx_pkt_burst = nfp_flower_repr_rx_burst;\n+\teth_dev->tx_pkt_burst = nfp_flower_repr_tx_burst;\n+\n+\teth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;\n+\n+\tif (repr->repr_type == NFP_REPR_TYPE_PHYS_PORT)\n+\t\teth_dev->data->representor_id = repr->vf_id;\n+\telse\n+\t\teth_dev->data->representor_id = repr->vf_id +\n+\t\t\t\tapp_fw_flower->num_phyport_reprs;\n+\n+\t/* This backer port is that of the eth_device created for the PF vNIC */\n+\teth_dev->data->backer_port_id = app_fw_flower->pf_hw->eth_dev->data->port_id;\n+\n+\t/* Only single queues for representor devices */\n+\teth_dev->data->nb_rx_queues = 1;\n+\teth_dev->data->nb_tx_queues = 1;\n+\n+\t/* Allocating memory for mac addr */\n+\teth_dev->data->mac_addrs = rte_zmalloc(\"mac_addr\",\n+\t\tRTE_ETHER_ADDR_LEN, 0);\n+\tif (eth_dev->data->mac_addrs == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to allocate memory for repr MAC\");\n+\t\tret = -ENOMEM;\n+\t\tgoto ring_cleanup;\n+\t}\n+\n+\trte_ether_addr_copy(&init_repr_data->mac_addr, &repr->mac_addr);\n+\trte_ether_addr_copy(&init_repr_data->mac_addr, eth_dev->data->mac_addrs);\n+\n+\t/* Send reify message to hardware to inform it about the new repr */\n+\tret = nfp_flower_cmsg_repr_reify(app_fw_flower, repr);\n+\tif (ret != 0) {\n+\t\tPMD_INIT_LOG(WARNING, \"Failed to send repr reify message\");\n+\t\tgoto mac_cleanup;\n+\t}\n+\n+\t/* Add repr to correct array */\n+\tif (repr->repr_type == NFP_REPR_TYPE_PHYS_PORT)\n+\t\tapp_fw_flower->phy_reprs[repr->nfp_idx] = repr;\n+\telse\n+\t\tapp_fw_flower->vf_reprs[repr->vf_id] = repr;\n+\n+\treturn 0;\n+\n+mac_cleanup:\n+\trte_free(eth_dev->data->mac_addrs);\n+ring_cleanup:\n+\trte_ring_free(repr->ring);\n+\n+\treturn ret;\n+}\n+\n+static int\n+nfp_flower_repr_alloc(struct nfp_app_fw_flower *app_fw_flower)\n+{\n+\tint i;\n+\tint ret;\n+\tstruct rte_eth_dev *eth_dev;\n+\tstruct nfp_eth_table *nfp_eth_table;\n+\tstruct nfp_eth_table_port *eth_port;\n+\tstruct nfp_flower_representor flower_repr = {\n+\t\t.switch_domain_id = app_fw_flower->switch_domain_id,\n+\t\t.app_fw_flower    = app_fw_flower,\n+\t};\n+\n+\tnfp_eth_table = app_fw_flower->nfp_eth_table;\n+\teth_dev = app_fw_flower->pf_hw->eth_dev;\n+\n+\t/* Send a NFP_FLOWER_CMSG_TYPE_MAC_REPR cmsg to hardware*/\n+\tret = nfp_flower_cmsg_mac_repr(app_fw_flower);\n+\tif (ret != 0) {\n+\t\tPMD_INIT_LOG(ERR, \"Cloud not send mac repr cmsgs\");\n+\t\treturn ret;\n+\t}\n+\n+\t/* Create a rte_eth_dev for every phyport representor */\n+\tfor (i = 0; i < app_fw_flower->num_phyport_reprs; i++) {\n+\t\teth_port = &nfp_eth_table->ports[i];\n+\t\tflower_repr.repr_type = NFP_REPR_TYPE_PHYS_PORT;\n+\t\tflower_repr.port_id = nfp_flower_get_phys_port_id(eth_port->index);\n+\t\tflower_repr.nfp_idx = eth_port->eth_index;\n+\t\tflower_repr.vf_id = i;\n+\n+\t\t/* Copy the real mac of the interface to the representor struct */\n+\t\trte_ether_addr_copy((struct rte_ether_addr *)eth_port->mac_addr,\n+\t\t\t\t&flower_repr.mac_addr);\n+\t\tsprintf(flower_repr.name, \"flower_repr_p%d\", i);\n+\n+\t\t/*\n+\t\t * Create a eth_dev for this representor\n+\t\t * This will also allocate private memory for the device\n+\t\t */\n+\t\tret = rte_eth_dev_create(eth_dev->device, flower_repr.name,\n+\t\t\t\tsizeof(struct nfp_flower_representor),\n+\t\t\t\tNULL, NULL, nfp_flower_repr_init, &flower_repr);\n+\t\tif (ret != 0) {\n+\t\t\tPMD_INIT_LOG(ERR, \"Cloud not create eth_dev for repr\");\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (i < app_fw_flower->num_phyport_reprs)\n+\t\treturn ret;\n+\n+\t/*\n+\t * Now allocate eth_dev's for VF representors.\n+\t * Also send reify messages\n+\t */\n+\tfor (i = 0; i < app_fw_flower->num_vf_reprs; i++) {\n+\t\tflower_repr.repr_type = NFP_REPR_TYPE_VF;\n+\t\tflower_repr.port_id = nfp_get_pcie_port_id(app_fw_flower->pf_hw->cpp,\n+\t\t\t\tNFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF, i, 0);\n+\t\tflower_repr.nfp_idx = 0;\n+\t\tflower_repr.vf_id = i;\n+\n+\t\t/* VF reprs get a random MAC address */\n+\t\trte_eth_random_addr(flower_repr.mac_addr.addr_bytes);\n+\n+\t\tsprintf(flower_repr.name, \"flower_repr_vf%d\", i);\n+\n+\t\t /* This will also allocate private memory for the device*/\n+\t\tret = rte_eth_dev_create(eth_dev->device, flower_repr.name,\n+\t\t\t\tsizeof(struct nfp_flower_representor),\n+\t\t\t\tNULL, NULL, nfp_flower_repr_init, &flower_repr);\n+\t\tif (ret != 0) {\n+\t\t\tPMD_INIT_LOG(ERR, \"Cloud not create eth_dev for repr\");\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (i < app_fw_flower->num_vf_reprs)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+int\n+nfp_flower_repr_create(struct nfp_app_fw_flower *app_fw_flower)\n+{\n+\tint ret;\n+\tstruct nfp_pf_dev *pf_dev;\n+\tstruct rte_pci_device *pci_dev;\n+\tstruct rte_eth_devargs eth_da = {\n+\t\t.nb_representor_ports = 0\n+\t};\n+\n+\tpf_dev = app_fw_flower->pf_hw->pf_dev;\n+\tpci_dev = pf_dev->pci_dev;\n+\n+\t/* Allocate a switch domain for the flower app */\n+\tif (app_fw_flower->switch_domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID &&\n+\t\t\trte_eth_switch_domain_alloc(&app_fw_flower->switch_domain_id)) {\n+\t\tPMD_INIT_LOG(WARNING, \"failed to allocate switch domain for device\");\n+\t}\n+\n+\t/* Now parse PCI device args passed for representor info */\n+\tif (pci_dev->device.devargs != NULL) {\n+\t\tret = rte_eth_devargs_parse(pci_dev->device.devargs->args, &eth_da);\n+\t\tif (ret != 0) {\n+\t\t\tPMD_INIT_LOG(ERR, \"devarg parse failed\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tif (eth_da.nb_representor_ports == 0) {\n+\t\tPMD_INIT_LOG(DEBUG, \"No representor port need to create.\");\n+\t\treturn 0;\n+\t}\n+\n+\t/* There always exist phy repr */\n+\tif (eth_da.nb_representor_ports < app_fw_flower->nfp_eth_table->count) {\n+\t\tPMD_INIT_LOG(ERR, \"Should also create phy representor port.\");\n+\t\treturn -ERANGE;\n+\t}\n+\n+\t/* Only support VF representor creation via the command line */\n+\tif (eth_da.type != RTE_ETH_REPRESENTOR_VF) {\n+\t\tPMD_INIT_LOG(ERR, \"Unsupported representor type: %d\", eth_da.type);\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\t/* Fill in flower app with repr counts */\n+\tapp_fw_flower->num_phyport_reprs = (uint8_t)app_fw_flower->nfp_eth_table->count;\n+\tapp_fw_flower->num_vf_reprs = eth_da.nb_representor_ports -\n+\t\t\tapp_fw_flower->nfp_eth_table->count;\n+\n+\tPMD_INIT_LOG(INFO, \"%d number of VF reprs\", app_fw_flower->num_vf_reprs);\n+\tPMD_INIT_LOG(INFO, \"%d number of phyport reprs\", app_fw_flower->num_phyport_reprs);\n+\n+\tret = nfp_flower_repr_alloc(app_fw_flower);\n+\tif (ret != 0) {\n+\t\tPMD_INIT_LOG(ERR, \"representors allocation failed\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/nfp/flower/nfp_flower_representor.h b/drivers/net/nfp/flower/nfp_flower_representor.h\nnew file mode 100644\nindex 0000000..af44ef3\n--- /dev/null\n+++ b/drivers/net/nfp/flower/nfp_flower_representor.h\n@@ -0,0 +1,39 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2022 Corigine, Inc.\n+ * All rights reserved.\n+ */\n+\n+#ifndef _NFP_FLOWER_REPRESENTOR_H_\n+#define _NFP_FLOWER_REPRESENTOR_H_\n+\n+/*\n+ * enum nfp_repr_type - type of representor\n+ * @NFP_REPR_TYPE_PHYS_PORT:   external NIC port\n+ * @NFP_REPR_TYPE_PF:          physical function\n+ * @NFP_REPR_TYPE_VF:          virtual function\n+ * @NFP_REPR_TYPE_MAX:         number of representor types\n+ */\n+enum nfp_repr_type {\n+\tNFP_REPR_TYPE_PHYS_PORT = 0,\n+\tNFP_REPR_TYPE_PF,\n+\tNFP_REPR_TYPE_VF,\n+\tNFP_REPR_TYPE_MAX,\n+};\n+\n+struct nfp_flower_representor {\n+\tuint16_t vf_id;\n+\tuint16_t switch_domain_id;\n+\tuint32_t repr_type;\n+\tuint32_t port_id;\n+\tuint32_t nfp_idx;    /* only valid for the repr of physical port */\n+\tchar name[RTE_ETH_NAME_MAX_LEN];\n+\tstruct rte_ether_addr mac_addr;\n+\tstruct nfp_app_fw_flower *app_fw_flower;\n+\tstruct rte_ring *ring;\n+\tstruct rte_eth_link link;\n+\tstruct rte_eth_stats repr_stats;\n+};\n+\n+int nfp_flower_repr_create(struct nfp_app_fw_flower *app_fw_flower);\n+\n+#endif /* _NFP_FLOWER_REPRESENTOR_H_ */\ndiff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build\nindex 8710213..8a63979 100644\n--- a/drivers/net/nfp/meson.build\n+++ b/drivers/net/nfp/meson.build\n@@ -7,7 +7,9 @@ if not is_linux or not dpdk_conf.get('RTE_ARCH_64')\n endif\n sources = files(\n         'flower/nfp_flower.c',\n+        'flower/nfp_flower_cmsg.c',\n         'flower/nfp_flower_ctrl.c',\n+        'flower/nfp_flower_representor.c',\n         'nfpcore/nfp_cpp_pcie_ops.c',\n         'nfpcore/nfp_nsp.c',\n         'nfpcore/nfp_cppcore.c',\n",
    "prefixes": [
        "v8",
        "10/12"
    ]
}