get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 130178,
    "url": "http://patches.dpdk.org/api/patches/130178/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230811163419.165790-8-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-8-hkalra@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230811163419.165790-8-hkalra@marvell.com",
    "date": "2023-08-11T16:34:17",
    "name": "[7/9] net/cnxk: representor flow ops",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "41e0ea208307c0fb0f95a4e10acb82e28228ac63",
    "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-8-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/130178/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/130178/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 C6F3943036;\n\tFri, 11 Aug 2023 18:35:52 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 7EBBC4327D;\n\tFri, 11 Aug 2023 18:35:18 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com\n [67.231.148.174])\n by mails.dpdk.org (Postfix) with ESMTP id D8F994327D\n for <dev@dpdk.org>; Fri, 11 Aug 2023 18:35:16 +0200 (CEST)",
            "from pps.filterd (m0045849.ppops.net [127.0.0.1])\n by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id\n 37BBmUgq001610 for <dev@dpdk.org>; Fri, 11 Aug 2023 09:35:16 -0700",
            "from dc5-exch01.marvell.com ([199.233.59.181])\n by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3sd8ypb92p-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n for <dev@dpdk.org>; Fri, 11 Aug 2023 09:35:15 -0700",
            "from DC5-EXCH02.marvell.com (10.69.176.39) 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:35:14 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend\n Transport; Fri, 11 Aug 2023 09:35:14 -0700",
            "from localhost.localdomain (unknown [10.29.52.211])\n by maili.marvell.com (Postfix) with ESMTP id C7DC23F705F;\n Fri, 11 Aug 2023 09:35:11 -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=leJPPRq1hJLXIBmKpFWiaMH0a9dB7FHyd6mcCT3l4y8=;\n b=fLSxCm6r+dHZ9d/QVluUdI7qLUZ+y5uEx/zRxIALf/AonmfDyBb7bG9HZZj5FS+svvGK\n DYEzlSfu4aiYTPo90PFipzAlUntEN94r7nUdlKlfFy48EwK9Hvy2Guwo4pkBsmFOlyne\n CCV5CQhwY2YRPblkEnGksTRLmJGmAKe61HHSKU7fFWizqkKd2cbrlcyaCq7Yzyj9cKzq\n VjUHQIs/MTrYAgeULNmBpDxntm+7jzBofVZvSRLp3iGTRypc6wj3dbd93FVsoQcbFGHV\n sB5tZiVL7gbOyjpFx4A39yiBjdDnxetjCpW/DVZRYnLSYLMgVuqlMnpy/QE5aYPgWE9j Zw==",
        "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>",
        "CC": "<dev@dpdk.org>, Harman Kalra <hkalra@marvell.com>",
        "Subject": "[PATCH 7/9] net/cnxk: representor flow ops",
        "Date": "Fri, 11 Aug 2023 22:04:17 +0530",
        "Message-ID": "<20230811163419.165790-8-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": "Cn6biVzL4X0No_h5EiOut6FTtfPJJZha",
        "X-Proofpoint-GUID": "Cn6biVzL4X0No_h5EiOut6FTtfPJJZha",
        "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": "Implementing flow operation callbacks for port representors PMD\n\nSigned-off-by: Harman Kalra <hkalra@marvell.com>\n---\n drivers/net/cnxk/cnxk_flow.h     |   9 +-\n drivers/net/cnxk/cnxk_rep.h      |   3 +\n drivers/net/cnxk/cnxk_rep_flow.c | 715 +++++++++++++++++++++++++++++++\n drivers/net/cnxk/cnxk_rep_msg.h  |  58 +++\n drivers/net/cnxk/cnxk_rep_ops.c  |   3 +-\n drivers/net/cnxk/meson.build     |   1 +\n 6 files changed, 786 insertions(+), 3 deletions(-)\n create mode 100644 drivers/net/cnxk/cnxk_rep_flow.c",
    "diff": "diff --git a/drivers/net/cnxk/cnxk_flow.h b/drivers/net/cnxk/cnxk_flow.h\nindex bb23629819..303002176b 100644\n--- a/drivers/net/cnxk/cnxk_flow.h\n+++ b/drivers/net/cnxk/cnxk_flow.h\n@@ -16,8 +16,13 @@ struct cnxk_rte_flow_term_info {\n \tuint16_t item_size;\n };\n \n-struct roc_npc_flow *cnxk_flow_create(struct rte_eth_dev *dev,\n-\t\t\t\t      const struct rte_flow_attr *attr,\n+struct cnxk_rte_flow_action_info {\n+\tuint16_t conf_size;\n+};\n+\n+extern const struct cnxk_rte_flow_term_info term[];\n+\n+struct roc_npc_flow *cnxk_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,\n \t\t\t\t      const struct rte_flow_item pattern[],\n \t\t\t\t      const struct rte_flow_action actions[],\n \t\t\t\t      struct rte_flow_error *error);\ndiff --git a/drivers/net/cnxk/cnxk_rep.h b/drivers/net/cnxk/cnxk_rep.h\nindex 2b6403f003..4886527f83 100644\n--- a/drivers/net/cnxk/cnxk_rep.h\n+++ b/drivers/net/cnxk/cnxk_rep.h\n@@ -15,6 +15,9 @@\n /* Common ethdev ops */\n extern struct eth_dev_ops cnxk_rep_dev_ops;\n \n+/* Flow ops for representor ports */\n+extern struct rte_flow_ops cnxk_rep_flow_ops;\n+\n /* Representor base device configurations */\n typedef struct rep_xport_vdev_cfg_s {\n \tstruct plt_bitmap *q_map;\ndiff --git a/drivers/net/cnxk/cnxk_rep_flow.c b/drivers/net/cnxk/cnxk_rep_flow.c\nnew file mode 100644\nindex 0000000000..9e181f5173\n--- /dev/null\n+++ b/drivers/net/cnxk/cnxk_rep_flow.c\n@@ -0,0 +1,715 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2023 Marvell.\n+ */\n+\n+#include <fcntl.h>\n+#include <unistd.h>\n+\n+#include <cnxk_flow.h>\n+#include <cnxk_rep.h>\n+#include <cnxk_rep_msg.h>\n+\n+#define DEFAULT_DUMP_FILE_NAME\t\"/tmp/fdump\"\n+#define MAX_BUFFER_SIZE\t\t1500\n+\n+const struct cnxk_rte_flow_action_info action_info[] = {\n+\t[RTE_FLOW_ACTION_TYPE_MARK] = {sizeof(struct rte_flow_action_mark)},\n+\t[RTE_FLOW_ACTION_TYPE_VF] = {sizeof(struct rte_flow_action_vf)},\n+\t[RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT] = {sizeof(struct rte_flow_action_port_id)},\n+\t[RTE_FLOW_ACTION_TYPE_PORT_ID] = {sizeof(struct rte_flow_action_port_id)},\n+\t[RTE_FLOW_ACTION_TYPE_QUEUE] = {sizeof(struct rte_flow_action_queue)},\n+\t[RTE_FLOW_ACTION_TYPE_RSS] = {sizeof(struct rte_flow_action_rss)},\n+\t[RTE_FLOW_ACTION_TYPE_SECURITY] = {sizeof(struct rte_flow_action_security)},\n+\t[RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID] = {sizeof(struct rte_flow_action_of_set_vlan_vid)},\n+\t[RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN] = {sizeof(struct rte_flow_action_of_push_vlan)},\n+\t[RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP] = {sizeof(struct rte_flow_action_of_set_vlan_pcp)},\n+\t[RTE_FLOW_ACTION_TYPE_METER] = {sizeof(struct rte_flow_action_meter)},\n+\t[RTE_FLOW_ACTION_TYPE_OF_POP_MPLS] = {sizeof(struct rte_flow_action_of_pop_mpls)},\n+\t[RTE_FLOW_ACTION_TYPE_OF_PUSH_MPLS] = {sizeof(struct rte_flow_action_of_push_mpls)},\n+\t[RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP] = {sizeof(struct rte_flow_action_vxlan_encap)},\n+\t[RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP] = {sizeof(struct rte_flow_action_nvgre_encap)},\n+\t[RTE_FLOW_ACTION_TYPE_RAW_ENCAP] = {sizeof(struct rte_flow_action_raw_encap)},\n+\t[RTE_FLOW_ACTION_TYPE_RAW_DECAP] = {sizeof(struct rte_flow_action_raw_decap)},\n+\t[RTE_FLOW_ACTION_TYPE_COUNT] = {sizeof(struct rte_flow_action_count)},\n+};\n+\n+static void\n+cnxk_flow_params_count(const struct rte_flow_item pattern[], const struct rte_flow_action actions[],\n+\t\t       uint16_t *n_pattern, uint16_t *n_action)\n+{\n+\tint i = 0;\n+\n+\tfor (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++)\n+\t\ti++;\n+\n+\t*n_pattern = ++i;\n+\tplt_rep_dbg(\"Total patterns is %d\", *n_pattern);\n+\n+\ti = 0;\n+\tfor (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++)\n+\t\ti++;\n+\t*n_action = ++i;\n+\tplt_rep_dbg(\"Total actions is %d\", *n_action);\n+}\n+\n+static void\n+populate_attr_data(void *buffer, uint32_t *length, const struct rte_flow_attr *attr)\n+{\n+\tuint32_t sz = sizeof(struct rte_flow_attr);\n+\tuint32_t len;\n+\n+\tcnxk_rep_msg_populate_type(buffer, length, CNXK_TYPE_ATTR, sz);\n+\n+\tlen = *length;\n+\t/* Populate the attribute data */\n+\trte_memcpy(RTE_PTR_ADD(buffer, len), attr, sz);\n+\tlen += sz;\n+\n+\t*length = len;\n+}\n+\n+static uint16_t\n+prepare_pattern_data(const struct rte_flow_item *pattern, uint16_t nb_pattern,\n+\t\t     uint64_t *pattern_data)\n+{\n+\tcnxk_pattern_hdr_t hdr;\n+\tuint16_t len = 0;\n+\tint i = 0;\n+\n+\tfor (i = 0; i < nb_pattern; i++) {\n+\t\t/* Populate the pattern type hdr */\n+\t\tmemset(&hdr, 0, sizeof(cnxk_pattern_hdr_t));\n+\t\thdr.type = pattern->type;\n+\t\tif (pattern->spec) {\n+\t\t\thdr.spec_sz = term[pattern->type].item_size;\n+\t\t\thdr.last_sz = 0;\n+\t\t\thdr.mask_sz = term[pattern->type].item_size;\n+\t\t}\n+\n+\t\trte_memcpy(RTE_PTR_ADD(pattern_data, len), &hdr, sizeof(cnxk_pattern_hdr_t));\n+\t\tlen += sizeof(cnxk_pattern_hdr_t);\n+\n+\t\t/* Copy pattern spec data */\n+\t\tif (pattern->spec) {\n+\t\t\trte_memcpy(RTE_PTR_ADD(pattern_data, len), pattern->spec,\n+\t\t\t\t   term[pattern->type].item_size);\n+\t\t\tlen += term[pattern->type].item_size;\n+\t\t}\n+\n+\t\t/* Copy pattern last data */\n+\t\tif (pattern->last) {\n+\t\t\trte_memcpy(RTE_PTR_ADD(pattern_data, len), pattern->last,\n+\t\t\t\t   term[pattern->type].item_size);\n+\t\t\tlen += term[pattern->type].item_size;\n+\t\t}\n+\n+\t\t/* Copy pattern mask data */\n+\t\tif (pattern->mask) {\n+\t\t\trte_memcpy(RTE_PTR_ADD(pattern_data, len), pattern->mask,\n+\t\t\t\t   term[pattern->type].item_size);\n+\t\t\tlen += term[pattern->type].item_size;\n+\t\t}\n+\t\tpattern++;\n+\t}\n+\n+\treturn len;\n+}\n+\n+static void\n+populate_pattern_data(void *buffer, uint32_t *length, const struct rte_flow_item *pattern,\n+\t\t      uint16_t nb_pattern)\n+{\n+\tuint64_t pattern_data[BUFSIZ];\n+\tuint32_t len;\n+\tuint32_t sz;\n+\n+\t/* Prepare pattern_data */\n+\tsz = prepare_pattern_data(pattern, nb_pattern, pattern_data);\n+\n+\tcnxk_rep_msg_populate_type(buffer, length, CNXK_TYPE_PATTERN, sz);\n+\n+\tlen = *length;\n+\t/* Populate the pattern data */\n+\trte_memcpy(RTE_PTR_ADD(buffer, len), pattern_data, sz);\n+\tlen += sz;\n+\n+\t*length = len;\n+}\n+\n+static uint16_t\n+populate_rss_action_conf(const struct rte_flow_action_rss *conf, void\n+\t\t\t *rss_action_conf)\n+{\n+\tint len, sz;\n+\n+\tlen = sizeof(struct rte_flow_action_rss) - sizeof(conf->key) -\n+\t\tsizeof(conf->queue);\n+\n+\tif (rss_action_conf)\n+\t\trte_memcpy(rss_action_conf, conf, len);\n+\n+\tif (conf->key) {\n+\t\tsz = conf->key_len;\n+\t\tif (rss_action_conf)\n+\t\t\trte_memcpy(RTE_PTR_ADD(rss_action_conf, len), conf->key,\n+\t\t\t\t   sz);\n+\t\tlen += sz;\n+\t}\n+\n+\tif (conf->queue) {\n+\t\tsz = conf->queue_num * sizeof(conf->queue);\n+\t\tif (rss_action_conf)\n+\t\t\trte_memcpy(RTE_PTR_ADD(rss_action_conf, len),\n+\t\t\t\t   conf->queue, sz);\n+\t\tlen += sz;\n+\t}\n+\n+\treturn len;\n+}\n+\n+static uint16_t\n+prepare_action_data(const struct rte_flow_action *action, uint16_t nb_action, uint64_t *action_data)\n+{\n+\tvoid *action_conf_data = NULL;\n+\tcnxk_action_hdr_t hdr;\n+\tuint16_t len = 0, sz = 0;\n+\tint i = 0;\n+\n+\tfor (i = 0; i < nb_action; i++) {\n+\t\tif (action->conf) {\n+\t\t\tif (action->type == RTE_FLOW_ACTION_TYPE_RSS) {\n+\t\t\t\tsz = populate_rss_action_conf(action->conf, NULL);\n+\t\t\t\taction_conf_data = plt_zmalloc(sz, 0);\n+\t\t\t\tif (populate_rss_action_conf(action->conf,\n+\t\t\t\t\t\t\t     action_conf_data) != sz) {\n+\t\t\t\t\tplt_err(\"Populating RSS action config failed\");\n+\t\t\t\t\t\treturn 0;\n+\t\t\t\t}\n+\t\t\t} else {\n+\t\t\t\tsz = action_info[action->type].conf_size;\n+\t\t\t\taction_conf_data = plt_zmalloc(sz, 0);\n+\t\t\t\trte_memcpy(action_conf_data, action->conf, sz);\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* Populate the action type hdr */\n+\t\tmemset(&hdr, 0, sizeof(cnxk_action_hdr_t));\n+\t\thdr.type = action->type;\n+\t\thdr.conf_sz = sz;\n+\n+\t\trte_memcpy(RTE_PTR_ADD(action_data, len), &hdr, sizeof(cnxk_action_hdr_t));\n+\t\tlen += sizeof(cnxk_action_hdr_t);\n+\n+\t\t/* Copy action conf data */\n+\t\tif (action_conf_data) {\n+\t\t\trte_memcpy(RTE_PTR_ADD(action_data, len),\n+\t\t\t\t   action_conf_data, sz);\n+\t\t\tlen += sz;\n+\t\t\tplt_free(action_conf_data);\n+\t\t\taction_conf_data = NULL;\n+\t\t}\n+\n+\t\taction++;\n+\t}\n+\n+\treturn len;\n+}\n+\n+static void\n+populate_action_data(void *buffer, uint32_t *length, const struct rte_flow_action *action,\n+\t\t     uint16_t nb_action)\n+{\n+\tuint64_t action_data[BUFSIZ];\n+\tuint32_t len;\n+\tuint32_t sz;\n+\n+\t/* Prepare action_data */\n+\tsz = prepare_action_data(action, nb_action, action_data);\n+\n+\tcnxk_rep_msg_populate_type(buffer, length, CNXK_TYPE_ACTION, sz);\n+\n+\tlen = *length;\n+\t/* Populate the action data */\n+\trte_memcpy(RTE_PTR_ADD(buffer, len), action_data, sz);\n+\tlen += sz;\n+\n+\t*length = len;\n+}\n+\n+static int\n+process_flow_destroy(struct cnxk_rep_dev *rep_dev, void *flow, cnxk_rep_msg_ack_data_t *adata)\n+{\n+\tcnxk_rep_msg_flow_destroy_meta_t msg_fd_meta;\n+\tuint32_t len = 0, rc;\n+\tvoid *buffer;\n+\tsize_t size;\n+\n+\t/* If representor not representing any active VF, return 0 */\n+\tif (!rep_dev->is_vf_active)\n+\t\treturn 0;\n+\n+\tsize = MAX_BUFFER_SIZE;\n+\tbuffer = plt_zmalloc(size, 0);\n+\tif (!buffer) {\n+\t\tplt_err(\"Failed to allocate mem\");\n+\t\trc = -ENOMEM;\n+\t\tgoto fail;\n+\t}\n+\n+\tcnxk_rep_msg_populate_header(buffer, &len);\n+\n+\tmsg_fd_meta.portid = rep_dev->u.rep_portid;\n+\tmsg_fd_meta.flow = (uint64_t)flow;\n+\tplt_rep_dbg(\"Flow Destroy: flow 0x%lx, portid %d\", msg_fd_meta.flow, msg_fd_meta.portid);\n+\tcnxk_rep_msg_populate_command_meta(buffer, &len, &msg_fd_meta,\n+\t\t\t\t\t   sizeof(cnxk_rep_msg_flow_destroy_meta_t),\n+\t\t\t\t\t   CNXK_REP_MSG_FLOW_DESTROY);\n+\tcnxk_rep_msg_populate_msg_end(buffer, &len);\n+\n+\trc = cnxk_rep_msg_send_process(rep_dev, buffer, len, adata);\n+\tif (rc) {\n+\t\tplt_err(\"Failed to process the message, err %d\", rc);\n+\t\tgoto fail;\n+\t}\n+\n+\treturn 0;\n+fail:\n+\treturn rc;\n+}\n+\n+static int\n+copy_flow_dump_file(FILE *target)\n+{\n+\tFILE *source = NULL;\n+\tint pos;\n+\tchar ch;\n+\n+\tsource = fopen(DEFAULT_DUMP_FILE_NAME, \"r\");\n+\tif (source == NULL) {\n+\t\tplt_err(\"Failed to read default dump file: %s, err %d\", DEFAULT_DUMP_FILE_NAME,\n+\t\t\terrno);\n+\t\treturn errno;\n+\t}\n+\n+\tfseek(source, 0L, SEEK_END);\n+\tpos = ftell(source);\n+\tfseek(source, 0L, SEEK_SET);\n+\twhile (pos--) {\n+\t\tch = fgetc(source);\n+\t\tfputc(ch, target);\n+\t}\n+\n+\tfclose(source);\n+\n+\t/* Remove the default file after reading */\n+\tremove(DEFAULT_DUMP_FILE_NAME);\n+\n+\treturn 0;\n+}\n+\n+static int\n+process_flow_dump(struct cnxk_rep_dev *rep_dev, struct rte_flow *flow, FILE *file,\n+\t\t  cnxk_rep_msg_ack_data_t *adata)\n+{\n+\tcnxk_rep_msg_flow_dump_meta_t msg_fp_meta;\n+\tuint32_t len = 0, rc;\n+\tvoid *buffer;\n+\tsize_t size;\n+\n+\tsize = MAX_BUFFER_SIZE;\n+\tbuffer = plt_zmalloc(size, 0);\n+\tif (!buffer) {\n+\t\tplt_err(\"Failed to allocate mem\");\n+\t\trc = -ENOMEM;\n+\t\tgoto fail;\n+\t}\n+\n+\tcnxk_rep_msg_populate_header(buffer, &len);\n+\n+\tmsg_fp_meta.portid = rep_dev->u.rep_portid;\n+\tmsg_fp_meta.flow = (uint64_t)flow;\n+\tmsg_fp_meta.is_stdout = (file == stdout) ? 1 : 0;\n+\n+\tplt_rep_dbg(\"Flow Dump: flow 0x%lx, portid %d stdout %d\", msg_fp_meta.flow,\n+\t\t    msg_fp_meta.portid, msg_fp_meta.is_stdout);\n+\tcnxk_rep_msg_populate_command_meta(buffer, &len, &msg_fp_meta,\n+\t\t\t\t\t   sizeof(cnxk_rep_msg_flow_dump_meta_t),\n+\t\t\t\t\t   CNXK_REP_MSG_FLOW_DUMP);\n+\tcnxk_rep_msg_populate_msg_end(buffer, &len);\n+\n+\trc = cnxk_rep_msg_send_process(rep_dev, buffer, len, adata);\n+\tif (rc) {\n+\t\tplt_err(\"Failed to process the message, err %d\", rc);\n+\t\tgoto fail;\n+\t}\n+\n+\t/* Copy contents from default file to user file */\n+\tif (file != stdout)\n+\t\tcopy_flow_dump_file(file);\n+\n+\treturn 0;\n+fail:\n+\treturn rc;\n+}\n+\n+static int\n+process_flow_flush(struct cnxk_rep_dev *rep_dev, cnxk_rep_msg_ack_data_t *adata)\n+{\n+\tcnxk_rep_msg_flow_flush_meta_t msg_ff_meta;\n+\tuint32_t len = 0, rc;\n+\tvoid *buffer;\n+\tsize_t size;\n+\n+\tsize = MAX_BUFFER_SIZE;\n+\tbuffer = plt_zmalloc(size, 0);\n+\tif (!buffer) {\n+\t\tplt_err(\"Failed to allocate mem\");\n+\t\trc = -ENOMEM;\n+\t\tgoto fail;\n+\t}\n+\n+\tcnxk_rep_msg_populate_header(buffer, &len);\n+\n+\tmsg_ff_meta.portid = rep_dev->u.rep_portid;\n+\tplt_rep_dbg(\"Flow Flush: portid %d\", msg_ff_meta.portid);\n+\tcnxk_rep_msg_populate_command_meta(buffer, &len, &msg_ff_meta,\n+\t\t\t\t\t   sizeof(cnxk_rep_msg_flow_flush_meta_t),\n+\t\t\t\t\t   CNXK_REP_MSG_FLOW_FLUSH);\n+\tcnxk_rep_msg_populate_msg_end(buffer, &len);\n+\n+\trc = cnxk_rep_msg_send_process(rep_dev, buffer, len, adata);\n+\tif (rc) {\n+\t\tplt_err(\"Failed to process the message, err %d\", rc);\n+\t\tgoto fail;\n+\t}\n+\n+\treturn 0;\n+fail:\n+\treturn rc;\n+}\n+\n+static int\n+process_flow_query(struct cnxk_rep_dev *rep_dev, struct rte_flow *flow,\n+\t\t   const struct rte_flow_action *action, cnxk_rep_msg_ack_data_t *adata)\n+{\n+\tcnxk_rep_msg_flow_query_meta_t *msg_fq_meta;\n+\tuint32_t len = 0, rc, sz, total_sz;\n+\tuint64_t action_data[BUFSIZ];\n+\tvoid *buffer;\n+\tsize_t size;\n+\n+\tsize = MAX_BUFFER_SIZE;\n+\tbuffer = plt_zmalloc(size, 0);\n+\tif (!buffer) {\n+\t\tplt_err(\"Failed to allocate mem\");\n+\t\trc = -ENOMEM;\n+\t\tgoto fail;\n+\t}\n+\n+\tcnxk_rep_msg_populate_header(buffer, &len);\n+\n+\tsz = prepare_action_data(action, 1, action_data);\n+\ttotal_sz = sz + sizeof(cnxk_rep_msg_flow_query_meta_t);\n+\n+\tmsg_fq_meta = plt_zmalloc(total_sz, 0);\n+\tif (!msg_fq_meta) {\n+\t\tplt_err(\"Failed to allocate memory\");\n+\t\trc = -ENOMEM;\n+\t\tgoto fail;\n+\t}\n+\n+\tmsg_fq_meta->portid = rep_dev->u.rep_portid;\n+\tmsg_fq_meta->flow = (uint64_t)flow;\n+\t/* Populate the action data */\n+\trte_memcpy(msg_fq_meta->action_data, action_data, sz);\n+\tmsg_fq_meta->action_data_sz = sz;\n+\n+\tplt_rep_dbg(\"Flow query: flow 0x%lx, portid %d, action type %d total sz %d action sz %d\",\n+\t\t    msg_fq_meta->flow, msg_fq_meta->portid, action->type, total_sz, sz);\n+\tcnxk_rep_msg_populate_command_meta(buffer, &len, msg_fq_meta, total_sz,\n+\t\t\t\t\t   CNXK_REP_MSG_FLOW_QUERY);\n+\tcnxk_rep_msg_populate_msg_end(buffer, &len);\n+\n+\trc = cnxk_rep_msg_send_process(rep_dev, buffer, len, adata);\n+\tif (rc) {\n+\t\tplt_err(\"Failed to process the message, err %d\", rc);\n+\t\tgoto free;\n+\t}\n+\n+\trte_free(msg_fq_meta);\n+\n+\treturn 0;\n+\n+free:\n+\trte_free(msg_fq_meta);\n+fail:\n+\treturn rc;\n+}\n+\n+static int\n+process_flow_rule(struct cnxk_rep_dev *rep_dev, const struct rte_flow_attr *attr,\n+\t\t  const struct rte_flow_item pattern[], const struct rte_flow_action actions[],\n+\t\t  struct rte_flow_error *error, cnxk_rep_msg_ack_data_t *adata, cnxk_rep_msg_t msg)\n+{\n+\tcnxk_rep_msg_flow_create_meta_t msg_fc_meta;\n+\tuint16_t n_pattern, n_action;\n+\tuint32_t len = 0, rc = 0;\n+\tvoid *buffer;\n+\tsize_t size;\n+\n+\tRTE_SET_USED(error);\n+\tsize = MAX_BUFFER_SIZE;\n+\tbuffer = plt_zmalloc(size, 0);\n+\tif (!buffer) {\n+\t\tplt_err(\"Failed to allocate mem\");\n+\t\trc = -ENOMEM;\n+\t\tgoto fail;\n+\t}\n+\n+\t/* Get no of actions and patterns */\n+\tcnxk_flow_params_count(pattern, actions, &n_pattern, &n_action);\n+\n+\t/* Adding the header */\n+\tcnxk_rep_msg_populate_header(buffer, &len);\n+\n+\t/* Representor port identified as rep_xport queue */\n+\tmsg_fc_meta.portid = rep_dev->u.rep_portid;\n+\tmsg_fc_meta.nb_pattern = n_pattern;\n+\tmsg_fc_meta.nb_action = n_action;\n+\n+\tcnxk_rep_msg_populate_command_meta(buffer, &len, &msg_fc_meta,\n+\t\t\t\t\t   sizeof(cnxk_rep_msg_flow_create_meta_t), msg);\n+\n+\t/* Populate flow create parameters data */\n+\tpopulate_attr_data(buffer, &len, attr);\n+\tpopulate_pattern_data(buffer, &len, pattern, n_pattern);\n+\tpopulate_action_data(buffer, &len, actions, n_action);\n+\n+\tcnxk_rep_msg_populate_msg_end(buffer, &len);\n+\n+\trc = cnxk_rep_msg_send_process(rep_dev, buffer, len, adata);\n+\tif (rc) {\n+\t\tplt_err(\"Failed to process the message, err %d\", rc);\n+\t\tgoto fail;\n+\t}\n+\n+\treturn 0;\n+fail:\n+\treturn rc;\n+}\n+\n+static struct rte_flow *\n+cnxk_rep_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,\n+\t\t     const struct rte_flow_item pattern[], const struct rte_flow_action actions[],\n+\t\t     struct rte_flow_error *error)\n+{\n+\tstruct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);\n+\tstruct rte_flow *flow = NULL;\n+\tcnxk_rep_msg_ack_data_t adata;\n+\tint rc = 0;\n+\n+\t/* If representor not representing any active VF, return 0 */\n+\tif (!rep_dev->is_vf_active)\n+\t\treturn 0;\n+\n+\trc = process_flow_rule(rep_dev, attr, pattern, actions, error, &adata,\n+\t\t\t       CNXK_REP_MSG_FLOW_CREATE);\n+\tif (!rc || adata.u.sval < 0) {\n+\t\tif (adata.u.sval < 0) {\n+\t\t\trc = (int)adata.u.sval;\n+\t\t\trte_flow_error_set(error, adata.u.sval, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t   NULL, \"Failed to validate flow\");\n+\t\t\tgoto fail;\n+\t\t}\n+\n+\t\tflow = adata.u.data;\n+\t\tif (!flow) {\n+\t\t\trte_flow_error_set(error, adata.u.sval, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t   NULL, \"Failed to create flow\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t} else {\n+\t\trte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"Failed to create flow\");\n+\t}\n+\tplt_rep_dbg(\"Flow %p created successfully\", adata.u.data);\n+\n+\treturn flow;\n+fail:\n+\treturn NULL;\n+}\n+\n+static int\n+cnxk_rep_flow_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,\n+\t\t       const struct rte_flow_item pattern[], const struct rte_flow_action actions[],\n+\t\t       struct rte_flow_error *error)\n+{\n+\tstruct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);\n+\tcnxk_rep_msg_ack_data_t adata;\n+\tint rc = 0;\n+\n+\t/* If representor not representing any active VF, return 0 */\n+\tif (!rep_dev->is_vf_active)\n+\t\treturn 0;\n+\n+\trc = process_flow_rule(rep_dev, attr, pattern, actions, error, &adata,\n+\t\t\t       CNXK_REP_MSG_FLOW_VALIDATE);\n+\tif (!rc || adata.u.sval < 0) {\n+\t\tif (adata.u.sval < 0) {\n+\t\t\trc = (int)adata.u.sval;\n+\t\t\trte_flow_error_set(error, adata.u.sval, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t   NULL, \"Failed to validate flow\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t} else {\n+\t\trte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"Failed to validate flow\");\n+\t}\n+\n+\tplt_rep_dbg(\"Flow %p validated successfully\", adata.u.data);\n+\n+fail:\n+\treturn rc;\n+}\n+\n+static int\n+cnxk_rep_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *flow,\n+\t\t      struct rte_flow_error *error)\n+{\n+\tstruct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);\n+\tcnxk_rep_msg_ack_data_t adata;\n+\tint rc;\n+\n+\tRTE_SET_USED(error);\n+\t/* If representor not representing any active VF, return 0 */\n+\tif (!rep_dev->is_vf_active)\n+\t\treturn 0;\n+\n+\trc = process_flow_destroy(rep_dev, flow, &adata);\n+\tif (rc || adata.u.sval < 0) {\n+\t\tif (adata.u.sval < 0)\n+\t\t\trc = adata.u.sval;\n+\n+\t\trte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"Failed to destroy flow\");\n+\t\tgoto fail;\n+\t}\n+\n+\treturn 0;\n+fail:\n+\treturn rc;\n+}\n+\n+static int\n+cnxk_rep_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,\n+\t\t    const struct rte_flow_action *action, void *data, struct rte_flow_error *error)\n+{\n+\tstruct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);\n+\tcnxk_rep_msg_ack_data_t adata;\n+\tint rc;\n+\n+\t/* If representor not representing any active VF, return 0 */\n+\tif (!rep_dev->is_vf_active)\n+\t\treturn 0;\n+\n+\tif (action->type != RTE_FLOW_ACTION_TYPE_COUNT) {\n+\t\trc = -ENOTSUP;\n+\t\trte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"Only COUNT is supported in query\");\n+\t\tgoto fail;\n+\t}\n+\n+\trc = process_flow_query(rep_dev, flow, action, &adata);\n+\tif (rc || adata.u.sval < 0) {\n+\t\tif (adata.u.sval < 0)\n+\t\t\trc = adata.u.sval;\n+\n+\t\trte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"Failed to query the flow\");\n+\t\tgoto fail;\n+\t}\n+\n+\trte_memcpy(data, adata.u.data, adata.size);\n+\n+\treturn 0;\n+fail:\n+\treturn rc;\n+}\n+\n+static int\n+cnxk_rep_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)\n+{\n+\tstruct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);\n+\tcnxk_rep_msg_ack_data_t adata;\n+\tint rc;\n+\n+\t/* If representor not representing any active VF, return 0 */\n+\tif (!rep_dev->is_vf_active)\n+\t\treturn 0;\n+\n+\trc = process_flow_flush(rep_dev, &adata);\n+\tif (rc || adata.u.sval < 0) {\n+\t\tif (adata.u.sval < 0)\n+\t\t\trc = adata.u.sval;\n+\n+\t\trte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"Failed to destroy flow\");\n+\t\tgoto fail;\n+\t}\n+\n+\treturn 0;\n+fail:\n+\treturn rc;\n+}\n+\n+static int\n+cnxk_rep_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow, FILE *file,\n+\t\t       struct rte_flow_error *error)\n+{\n+\tstruct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);\n+\tcnxk_rep_msg_ack_data_t adata;\n+\tint rc;\n+\n+\tRTE_SET_USED(error);\n+\t/* If representor not representing any active VF, return 0 */\n+\tif (!rep_dev->is_vf_active)\n+\t\treturn 0;\n+\n+\trc = process_flow_dump(rep_dev, flow, file, &adata);\n+\tif (rc || adata.u.sval < 0) {\n+\t\tif (adata.u.sval < 0)\n+\t\t\trc = adata.u.sval;\n+\n+\t\trte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"Failed to destroy flow\");\n+\t\tgoto fail;\n+\t}\n+\n+\treturn 0;\n+fail:\n+\treturn rc;\n+}\n+\n+static int\n+cnxk_rep_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused, int enable __rte_unused,\n+\t\t      struct rte_flow_error *error)\n+{\n+\t/* If we support, we need to un-install the default mcam\n+\t * entry for this port.\n+\t */\n+\n+\trte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t   \"Flow isolation not supported\");\n+\n+\treturn -rte_errno;\n+}\n+\n+struct rte_flow_ops cnxk_rep_flow_ops = {\n+\t.validate = cnxk_rep_flow_validate,\n+\t.create = cnxk_rep_flow_create,\n+\t.destroy = cnxk_rep_flow_destroy,\n+\t.query = cnxk_rep_flow_query,\n+\t.flush = cnxk_rep_flow_flush,\n+\t.isolate = cnxk_rep_flow_isolate,\n+\t.dev_dump = cnxk_rep_flow_dev_dump,\n+};\ndiff --git a/drivers/net/cnxk/cnxk_rep_msg.h b/drivers/net/cnxk/cnxk_rep_msg.h\nindex 554122d7f8..23fd72434c 100644\n--- a/drivers/net/cnxk/cnxk_rep_msg.h\n+++ b/drivers/net/cnxk/cnxk_rep_msg.h\n@@ -12,6 +12,10 @@\n typedef enum CNXK_TYPE {\n \tCNXK_TYPE_HEADER = 0,\n \tCNXK_TYPE_MSG,\n+\tCNXK_TYPE_ATTR,\n+\tCNXK_TYPE_PATTERN,\n+\tCNXK_TYPE_ACTION,\n+\tCNXK_TYPE_FLOW\n } cnxk_type_t;\n \n typedef enum CNXK_REP_MSG {\n@@ -23,6 +27,13 @@ typedef enum CNXK_REP_MSG {\n \tCNXK_REP_MSG_ETH_SET_MAC,\n \tCNXK_REP_MSG_ETH_STATS_GET,\n \tCNXK_REP_MSG_ETH_STATS_CLEAR,\n+\t/* Flow operation msgs */\n+\tCNXK_REP_MSG_FLOW_CREATE,\n+\tCNXK_REP_MSG_FLOW_DESTROY,\n+\tCNXK_REP_MSG_FLOW_VALIDATE,\n+\tCNXK_REP_MSG_FLOW_FLUSH,\n+\tCNXK_REP_MSG_FLOW_DUMP,\n+\tCNXK_REP_MSG_FLOW_QUERY,\n \t/* End of messaging sequence */\n \tCNXK_REP_MSG_END,\n } cnxk_rep_msg_t;\n@@ -79,6 +90,53 @@ typedef struct cnxk_rep_msg_eth_stats_meta {\n \tuint16_t portid;\n } __rte_packed cnxk_rep_msg_eth_stats_meta_t;\n \n+/* Flow create msg meta */\n+typedef struct cnxk_rep_msg_flow_create_meta {\n+\tuint16_t portid;\n+\tuint16_t nb_pattern;\n+\tuint16_t nb_action;\n+} __rte_packed cnxk_rep_msg_flow_create_meta_t;\n+\n+/* Flow destroy msg meta */\n+typedef struct cnxk_rep_msg_flow_destroy_meta {\n+\tuint64_t flow;\n+\tuint16_t portid;\n+} __rte_packed cnxk_rep_msg_flow_destroy_meta_t;\n+\n+/* Flow flush msg meta */\n+typedef struct cnxk_rep_msg_flow_flush_meta {\n+\tuint16_t portid;\n+} __rte_packed cnxk_rep_msg_flow_flush_meta_t;\n+\n+/* Flow dump msg meta */\n+typedef struct cnxk_rep_msg_flow_dump_meta {\n+\tuint64_t flow;\n+\tuint16_t portid;\n+\tuint8_t is_stdout;\n+} __rte_packed cnxk_rep_msg_flow_dump_meta_t;\n+\n+/* Flow query msg meta */\n+typedef struct cnxk_rep_msg_flow_query_meta {\n+\tuint64_t flow;\n+\tuint16_t portid;\n+\tuint32_t action_data_sz;\n+\tuint8_t action_data[];\n+} __rte_packed cnxk_rep_msg_flow_query_meta_t;\n+\n+/* Type pattern meta */\n+typedef struct cnxk_pattern_hdr {\n+\tuint16_t type;\n+\tuint16_t spec_sz;\n+\tuint16_t last_sz;\n+\tuint16_t mask_sz;\n+} __rte_packed cnxk_pattern_hdr_t;\n+\n+/* Type action meta */\n+typedef struct cnxk_action_hdr {\n+\tuint16_t type;\n+\tuint16_t conf_sz;\n+} __rte_packed cnxk_action_hdr_t;\n+\n void cnxk_rep_msg_populate_command(void *buffer, uint32_t *length, cnxk_rep_msg_t type,\n \t\t\t\t   uint32_t size);\n void cnxk_rep_msg_populate_command_meta(void *buffer, uint32_t *length, void *msg_meta, uint32_t sz,\ndiff --git a/drivers/net/cnxk/cnxk_rep_ops.c b/drivers/net/cnxk/cnxk_rep_ops.c\nindex 022a5137df..c418ecf383 100644\n--- a/drivers/net/cnxk/cnxk_rep_ops.c\n+++ b/drivers/net/cnxk/cnxk_rep_ops.c\n@@ -661,7 +661,8 @@ 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+\t*ops = &cnxk_rep_flow_ops;\n+\n \treturn 0;\n }\n \ndiff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build\nindex 0e7334f5cd..d4b1110f38 100644\n--- a/drivers/net/cnxk/meson.build\n+++ b/drivers/net/cnxk/meson.build\n@@ -35,6 +35,7 @@ sources = files(\n         'cnxk_rep.c',\n         'cnxk_rep_msg.c',\n         'cnxk_rep_ops.c',\n+        'cnxk_rep_flow.c',\n         'cnxk_stats.c',\n         'cnxk_tm.c',\n )\n",
    "prefixes": [
        "7/9"
    ]
}