get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 99744,
    "url": "http://patches.dpdk.org/api/patches/99744/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20210927082223.757436-27-skori@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": "<20210927082223.757436-27-skori@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210927082223.757436-27-skori@marvell.com",
    "date": "2021-09-27T08:22:23",
    "name": "[v2,27/27] net/cnxk: support meter action to flow create",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "e6b63722e6597476598bf178ee0b0df5e8f44693",
    "submitter": {
        "id": 1318,
        "url": "http://patches.dpdk.org/api/people/1318/?format=api",
        "name": "Sunil Kumar Kori",
        "email": "skori@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/20210927082223.757436-27-skori@marvell.com/mbox/",
    "series": [
        {
            "id": 19182,
            "url": "http://patches.dpdk.org/api/series/19182/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=19182",
            "date": "2021-09-27T08:21:57",
            "name": "[v2,01/27] common/cnxk: update policer MBOX APIs and HW definitions",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/19182/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/99744/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/99744/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 DF125A0547;\n\tMon, 27 Sep 2021 10:25:42 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 498AA4119B;\n\tMon, 27 Sep 2021 10:23:37 +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 4F2CA4119A\n for <dev@dpdk.org>; Mon, 27 Sep 2021 10:23:36 +0200 (CEST)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 18QLbnww025340\n for <dev@dpdk.org>; Mon, 27 Sep 2021 01:23:34 -0700",
            "from dc5-exch02.marvell.com ([199.233.59.182])\n by mx0b-0016f401.pphosted.com with ESMTP id 3bavvuhtvy-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n for <dev@dpdk.org>; Mon, 27 Sep 2021 01:23:34 -0700",
            "from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18;\n Mon, 27 Sep 2021 01:23:32 -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.18 via Frontend\n Transport; Mon, 27 Sep 2021 01:23:32 -0700",
            "from localhost.localdomain (unknown [10.28.34.25])\n by maili.marvell.com (Postfix) with ESMTP id 928F83F7043;\n Mon, 27 Sep 2021 01:23:30 -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-transfer-encoding : content-type; s=pfpt0220;\n bh=Z6Pmueh7pccKyqfaQZgZ0ZO9OWvC2FteCIAJ2Hy4f8g=;\n b=VhdfpwU40Fl6RVGWVYfEHd29BmHoSQH83X0QDdwi5VYljGAgTgtzC8bi/Mb/HmYW9nlD\n oav0MntlveofULpisXO/2zynIVOknex0BBmVFfs4ywCmNzOz5AloPmkbEuuD7pZf+kDz\n btk5lIWDFjBUMIR7uy18WFqFjf5KT3Iu9bQexz+ANFR/MFZeG4XmDIfdAdJOfkDhJ87w\n 9G1po43MNEyNokLbu2RyHqHy/u/5ay/+AJiIYEXB9gfjv6EG7qoS1huife1TYsOqTWCX\n IZyfYzrQcpscK9jtnA7+0531Xtv0vHiJnwOFHASE2hECIZuiMoTvKbE9U6qLRnf2NXAB 9A==",
        "From": "<skori@marvell.com>",
        "To": "Nithin Dabilpuram <ndabilpuram@marvell.com>, Kiran Kumar K\n <kirankumark@marvell.com>, Sunil Kumar Kori <skori@marvell.com>, Satha Rao\n <skoteshwar@marvell.com>",
        "CC": "<dev@dpdk.org>, Rakesh Kudurumalla <rkudurumalla@marvell.com>",
        "Date": "Mon, 27 Sep 2021 13:52:23 +0530",
        "Message-ID": "<20210927082223.757436-27-skori@marvell.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20210927082223.757436-1-skori@marvell.com>",
        "References": "<20210927082223.757436-1-skori@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-ORIG-GUID": "WvYT7xCNPkpNMsJAxBkNVQeyR9rtavN4",
        "X-Proofpoint-GUID": "WvYT7xCNPkpNMsJAxBkNVQeyR9rtavN4",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.182.1,Aquarius:18.0.790,Hydra:6.0.391,FMLib:17.0.607.475\n definitions=2021-09-27_02,2021-09-24_02,2020-04-07_01",
        "Subject": "[dpdk-dev] [PATCH v2 27/27] net/cnxk: support meter action to flow\n create",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Sunil Kumar Kori <skori@marvell.com>\n\nMeters are configured per flow using rte_flow_create API.\nImplement support for meter action applied on the flow.\n\nSigned-off-by: Sunil Kumar Kori <skori@marvell.com>\nSigned-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>\n---\nv2:\n - Rebase support on latest DPDK\n - Handled multilevel chaining for linear hierarchy\n - Review comments incorporated\n\n doc/guides/nics/features/cnxk.ini    |   1 +\n doc/guides/nics/features/cnxk_vf.ini |   1 +\n drivers/net/cnxk/cn10k_ethdev_mtr.c  | 388 +++++++++++++++++++++++++++\n drivers/net/cnxk/cn10k_rte_flow.c    | 155 ++++++++++-\n drivers/net/cnxk/cnxk_ethdev.h       |  15 ++\n drivers/net/cnxk/cnxk_rte_flow.c     |   4 +\n 6 files changed, 563 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/doc/guides/nics/features/cnxk.ini b/doc/guides/nics/features/cnxk.ini\nindex 5d456257bd..7bbce7dafc 100644\n--- a/doc/guides/nics/features/cnxk.ini\n+++ b/doc/guides/nics/features/cnxk.ini\n@@ -78,6 +78,7 @@ count                = Y\n drop                 = Y\n flag                 = Y\n mark                 = Y\n+meter                = Y\n of_pop_vlan          = Y\n of_push_vlan         = Y\n of_set_vlan_pcp      = Y\ndiff --git a/doc/guides/nics/features/cnxk_vf.ini b/doc/guides/nics/features/cnxk_vf.ini\nindex 7b4299f0be..89802a27f9 100644\n--- a/doc/guides/nics/features/cnxk_vf.ini\n+++ b/doc/guides/nics/features/cnxk_vf.ini\n@@ -70,6 +70,7 @@ count                = Y\n drop                 = Y\n flag                 = Y\n mark                 = Y\n+meter                = Y\n of_pop_vlan          = Y\n of_push_vlan         = Y\n of_set_vlan_pcp      = Y\ndiff --git a/drivers/net/cnxk/cn10k_ethdev_mtr.c b/drivers/net/cnxk/cn10k_ethdev_mtr.c\nindex c0482d1418..75193b3db1 100644\n--- a/drivers/net/cnxk/cn10k_ethdev_mtr.c\n+++ b/drivers/net/cnxk/cn10k_ethdev_mtr.c\n@@ -790,3 +790,391 @@ cn10k_nix_mtr_ops_get(struct rte_eth_dev *dev, void *ops)\n \t*(const void **)ops = &nix_mtr_ops;\n \treturn 0;\n }\n+\n+int\n+nix_mtr_validate(struct rte_eth_dev *eth_dev, uint32_t id)\n+{\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tstruct cnxk_mtr_profile_node *profile;\n+\tstruct cnxk_mtr_policy_node *policy;\n+\tstruct cnxk_meter_node *mtr;\n+\n+\tmtr = nix_mtr_find(dev, id);\n+\tif (mtr == NULL)\n+\t\treturn -EINVAL;\n+\n+\tprofile = nix_mtr_profile_find(dev, mtr->params.meter_profile_id);\n+\tif (profile == NULL)\n+\t\treturn -EINVAL;\n+\n+\tpolicy = nix_mtr_policy_find(dev, mtr->params.meter_policy_id);\n+\tif (policy == NULL)\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n+int\n+nix_mtr_policy_act_get(struct rte_eth_dev *eth_dev, uint32_t id,\n+\t\t       struct cnxk_mtr_policy_node **policy_act)\n+{\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tstruct cnxk_mtr_policy_node *policy;\n+\tstruct cnxk_meter_node *mtr;\n+\n+\tmtr = nix_mtr_find(dev, id);\n+\tif (mtr == NULL)\n+\t\treturn -EINVAL;\n+\n+\tpolicy = nix_mtr_policy_find(dev, mtr->params.meter_policy_id);\n+\tif (policy == NULL)\n+\t\treturn -EINVAL;\n+\n+\t*policy_act = policy;\n+\n+\treturn 0;\n+}\n+\n+int\n+nix_mtr_rq_update(struct rte_eth_dev *eth_dev, uint32_t id, uint32_t queue_num,\n+\t\t  const uint16_t *queue)\n+{\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tstruct cnxk_meter_node *mtr;\n+\tuint32_t i;\n+\n+\tmtr = nix_mtr_find(dev, id);\n+\tif (mtr == NULL)\n+\t\treturn -EINVAL;\n+\n+\tmtr->rq_id = plt_zmalloc(queue_num * sizeof(uint32_t), ROC_ALIGN);\n+\tif (mtr->rq_id == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tmtr->rq_num = queue_num;\n+\tfor (i = 0; i < queue_num; i++)\n+\t\tmtr->rq_id[i] = queue[i];\n+\n+\treturn 0;\n+}\n+\n+int\n+nix_mtr_chain_reset(struct rte_eth_dev *eth_dev, uint32_t cur_id)\n+{\n+\tstruct cnxk_meter_node *mtr[ROC_NIX_BPF_LEVEL_MAX] = {0};\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tuint32_t mtr_id = cur_id;\n+\tint i = 0;\n+\n+\tfor (i = 0; i < ROC_NIX_BPF_LEVEL_MAX; i++) {\n+\t\tmtr[i] = nix_mtr_find(dev, mtr_id);\n+\t\tif (mtr[i])\n+\t\t\tmtr_id = mtr[i]->next_id;\n+\t}\n+\tfor (i = 0; i < ROC_NIX_BPF_LEVEL_MAX; i++) {\n+\t\tif (mtr[i]) {\n+\t\t\tmtr[i]->level = ROC_NIX_BPF_LEVEL_IDX_INVALID;\n+\t\t\tmtr[i]->prev_id = ROC_NIX_BPF_ID_INVALID;\n+\t\t\tmtr[i]->next_id = ROC_NIX_BPF_ID_INVALID;\n+\t\t\tmtr[i]->is_prev = false;\n+\t\t\tmtr[i]->is_next = false;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+nix_mtr_chain_update(struct rte_eth_dev *eth_dev, uint32_t cur_id,\n+\t\t     uint32_t prev_id, uint32_t next_id)\n+{\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tstruct cnxk_meter_node *mtr;\n+\n+\tmtr = nix_mtr_find(dev, cur_id);\n+\tif (mtr == NULL)\n+\t\treturn -EINVAL;\n+\n+\tswitch (lvl_map[mtr->level]) {\n+\tcase ROC_NIX_BPF_LEVEL_F_LEAF:\n+\t\tmtr->prev_id = ROC_NIX_BPF_ID_INVALID;\n+\t\tmtr->next_id = next_id;\n+\t\tmtr->is_prev = false;\n+\t\tmtr->is_next = true;\n+\t\tbreak;\n+\tcase ROC_NIX_BPF_LEVEL_F_MID:\n+\t\tmtr->prev_id = prev_id;\n+\t\tmtr->next_id = next_id;\n+\t\tmtr->is_prev = true;\n+\t\tmtr->is_next = true;\n+\t\tbreak;\n+\tcase ROC_NIX_BPF_LEVEL_F_TOP:\n+\t\tmtr->prev_id = prev_id;\n+\t\tmtr->next_id = ROC_NIX_BPF_ID_INVALID;\n+\t\tmtr->is_prev = true;\n+\t\tmtr->is_next = false;\n+\t\tbreak;\n+\tdefault:\n+\t\tplt_err(\"Invalid meter level\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+nix_mtr_level_update(struct rte_eth_dev *eth_dev, uint32_t id, uint32_t level)\n+{\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tstruct cnxk_meter_node *mtr;\n+\n+\tmtr = nix_mtr_find(dev, id);\n+\tif (mtr == NULL)\n+\t\treturn -EINVAL;\n+\n+\tmtr->level = level;\n+\treturn 0;\n+}\n+\n+static void\n+nix_mtr_config_map(struct cnxk_meter_node *mtr, struct roc_nix_bpf_cfg *cfg)\n+{\n+\tenum roc_nix_bpf_algo alg_map[] = {\n+\t\tROC_NIX_BPF_ALGO_NONE, ROC_NIX_BPF_ALGO_2697,\n+\t\tROC_NIX_BPF_ALGO_2698, ROC_NIX_BPF_ALGO_4115};\n+\tstruct cnxk_mtr_profile_node *profile = mtr->profile;\n+\tstruct cnxk_mtr_policy_node *policy = mtr->policy;\n+\n+\tcfg->alg = alg_map[profile->profile.alg];\n+\tcfg->lmode = profile->profile.packet_mode;\n+\n+\tswitch (cfg->alg) {\n+\tcase ROC_NIX_BPF_ALGO_2697:\n+\t\tcfg->algo2697.cir = profile->profile.srtcm_rfc2697.cir * 8;\n+\t\tcfg->algo2697.cbs = profile->profile.srtcm_rfc2697.cbs;\n+\t\tcfg->algo2697.ebs = profile->profile.srtcm_rfc2697.ebs;\n+\t\tbreak;\n+\tcase ROC_NIX_BPF_ALGO_2698:\n+\t\tcfg->algo2698.cir = profile->profile.trtcm_rfc2698.cir * 8;\n+\t\tcfg->algo2698.pir = profile->profile.trtcm_rfc2698.pir * 8;\n+\t\tcfg->algo2698.cbs = profile->profile.trtcm_rfc2698.cbs;\n+\t\tcfg->algo2698.pbs = profile->profile.trtcm_rfc2698.pbs;\n+\t\tbreak;\n+\tcase ROC_NIX_BPF_ALGO_4115:\n+\t\tcfg->algo4115.cir = profile->profile.trtcm_rfc4115.cir * 8;\n+\t\tcfg->algo4115.eir = profile->profile.trtcm_rfc4115.eir * 8;\n+\t\tcfg->algo4115.cbs = profile->profile.trtcm_rfc4115.cbs;\n+\t\tcfg->algo4115.ebs = profile->profile.trtcm_rfc4115.ebs;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\tcfg->action[ROC_NIX_BPF_COLOR_GREEN] = ROC_NIX_BPF_ACTION_PASS;\n+\tcfg->action[ROC_NIX_BPF_COLOR_YELLOW] = ROC_NIX_BPF_ACTION_PASS;\n+\tcfg->action[ROC_NIX_BPF_COLOR_RED] = ROC_NIX_BPF_ACTION_PASS;\n+\n+\tif (policy->actions[RTE_COLOR_GREEN].action_fate ==\n+\t    RTE_FLOW_ACTION_TYPE_DROP)\n+\t\tcfg->action[ROC_NIX_BPF_COLOR_GREEN] = ROC_NIX_BPF_ACTION_DROP;\n+\n+\tif (policy->actions[RTE_COLOR_YELLOW].action_fate ==\n+\t    RTE_FLOW_ACTION_TYPE_DROP)\n+\t\tcfg->action[ROC_NIX_BPF_COLOR_YELLOW] = ROC_NIX_BPF_ACTION_DROP;\n+\n+\tif (policy->actions[RTE_COLOR_RED].action_fate ==\n+\t    RTE_FLOW_ACTION_TYPE_DROP)\n+\t\tcfg->action[ROC_NIX_BPF_COLOR_RED] = ROC_NIX_BPF_ACTION_DROP;\n+}\n+\n+static void\n+nix_dscp_table_map(struct cnxk_meter_node *mtr,\n+\t\t   struct roc_nix_bpf_precolor *tbl)\n+{\n+\tenum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,\n+\t\t\t\t\t      ROC_NIX_BPF_COLOR_YELLOW,\n+\t\t\t\t\t      ROC_NIX_BPF_COLOR_RED};\n+\tint i;\n+\n+\ttbl->count = ROC_NIX_BPF_PRE_COLOR_MAX;\n+\ttbl->mode = ROC_NIX_BPF_PC_MODE_DSCP_OUTER;\n+\n+\tfor (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)\n+\t\ttbl->color[i] = ROC_NIX_BPF_COLOR_GREEN;\n+\n+\tif (mtr->params.dscp_table) {\n+\t\tfor (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)\n+\t\t\ttbl->color[i] = color_map[mtr->params.dscp_table[i]];\n+\t}\n+}\n+\n+int\n+nix_mtr_configure(struct rte_eth_dev *eth_dev, uint32_t id)\n+{\n+\tstruct cnxk_meter_node *mtr[ROC_NIX_BPF_LEVEL_MAX] = {0};\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tstruct roc_nix_bpf_objs profs[ROC_NIX_BPF_LEVEL_MAX];\n+\tuint8_t idx0 = ROC_NIX_BPF_LEVEL_IDX_INVALID;\n+\tuint8_t idx1 = ROC_NIX_BPF_LEVEL_IDX_INVALID;\n+\tuint8_t idx2 = ROC_NIX_BPF_LEVEL_IDX_INVALID;\n+\tuint16_t per_lvl_cnt[ROC_NIX_BPF_LEVEL_MAX];\n+\tint num_mtr[ROC_NIX_BPF_LEVEL_MAX] = {0};\n+\tstruct roc_nix *nix = &dev->nix;\n+\tstruct roc_nix_bpf_precolor tbl;\n+\tstruct roc_nix_bpf_cfg cfg;\n+\tstruct roc_nix_rq *rq;\n+\tuint8_t lvl_mask;\n+\tuint32_t i;\n+\tuint32_t j;\n+\tint rc;\n+\n+\tmtr[0] = nix_mtr_find(dev, id);\n+\tif (mtr[0] == NULL)\n+\t\treturn -EINVAL;\n+\n+\tnum_mtr[0] = 1;\n+\tidx0 = roc_nix_bpf_level_to_idx(lvl_map[mtr[0]->level]);\n+\tif (idx0 == ROC_NIX_BPF_LEVEL_IDX_INVALID)\n+\t\treturn -EINVAL;\n+\n+\tlvl_mask = ROC_NIX_BPF_LEVEL_F_LEAF;\n+\tper_lvl_cnt[idx0] = 1;\n+\n+\tif (mtr[0]->is_next) {\n+\t\tmtr[1] = nix_mtr_find(dev, mtr[0]->next_id);\n+\t\tif (mtr[1] == NULL)\n+\t\t\treturn -EINVAL;\n+\t\tnum_mtr[1] = 1;\n+\t\tidx1 = roc_nix_bpf_level_to_idx(lvl_map[mtr[1]->level]);\n+\t\tif (idx1 == ROC_NIX_BPF_LEVEL_IDX_INVALID)\n+\t\t\treturn -EINVAL;\n+\n+\t\tlvl_mask |= ROC_NIX_BPF_LEVEL_F_MID;\n+\t\tper_lvl_cnt[idx1] = 1;\n+\t}\n+\n+\tif (mtr[1] && mtr[1]->is_next) {\n+\t\tmtr[2] = nix_mtr_find(dev, mtr[1]->next_id);\n+\t\tif (mtr[2] == NULL)\n+\t\t\treturn -EINVAL;\n+\n+\t\tnum_mtr[2] = 1;\n+\t\tidx2 = roc_nix_bpf_level_to_idx(lvl_map[mtr[2]->level]);\n+\t\tif (idx2 == ROC_NIX_BPF_LEVEL_IDX_INVALID)\n+\t\t\treturn -EINVAL;\n+\n+\t\tlvl_mask |= ROC_NIX_BPF_LEVEL_F_TOP;\n+\t\tper_lvl_cnt[idx2] = 1;\n+\t}\n+\n+\trc = roc_nix_bpf_alloc(nix, lvl_mask, per_lvl_cnt, profs);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tmtr[0]->bpf_id = profs[idx0].ids[0];\n+\n+\tif (num_mtr[0])\n+\t\tif (mtr[0]->is_next && idx1 != ROC_NIX_BPF_LEVEL_IDX_INVALID)\n+\t\t\tmtr[1]->bpf_id = profs[idx1].ids[0];\n+\n+\tif (num_mtr[1])\n+\t\tif (mtr[1]->is_next && idx2 != ROC_NIX_BPF_LEVEL_IDX_INVALID)\n+\t\t\tmtr[2]->bpf_id = profs[idx2].ids[0];\n+\n+\tfor (i = 0; i < ROC_NIX_BPF_LEVEL_MAX; i++) {\n+\t\tif (num_mtr[i]) {\n+\t\t\tmemset(&cfg, 0, sizeof(struct roc_nix_bpf_cfg));\n+\t\t\tnix_mtr_config_map(mtr[i], &cfg);\n+\t\t\trc = roc_nix_bpf_config(nix, mtr[i]->bpf_id,\n+\t\t\t\t\t\tlvl_map[mtr[i]->level], &cfg);\n+\n+\t\t\tmemset(&tbl, 0, sizeof(struct roc_nix_bpf_precolor));\n+\t\t\tnix_dscp_table_map(mtr[i], &tbl);\n+\t\t\trc = roc_nix_bpf_pre_color_tbl_setup(nix,\n+\t\t\t\t\t\t     mtr[i]->bpf_id,\n+\t\t\t\t\t\t     lvl_map[mtr[i]->level],\n+\t\t\t\t\t\t     &tbl);\n+\n+\t\t\tif (mtr[i]->params.meter_enable) {\n+\t\t\t\tfor (j = 0; j < mtr[i]->rq_num; j++) {\n+\t\t\t\t\trq = &dev->rqs[mtr[i]->rq_id[j]];\n+\t\t\t\t\trc = roc_nix_bpf_ena_dis(nix,\n+\t\t\t\t\t\t\t mtr[i]->bpf_id, rq,\n+\t\t\t\t\t\t\t true);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn rc;\n+}\n+\n+int\n+nix_mtr_color_action_validate(struct rte_eth_dev *eth_dev, uint32_t id,\n+\t\t\t      uint32_t *prev_id, uint32_t *next_id,\n+\t\t\t      struct cnxk_mtr_policy_node *policy,\n+\t\t\t      int *tree_level)\n+{\n+\tuint32_t action_fate_red = policy->actions[RTE_COLOR_RED].action_fate;\n+\tuint32_t action_fate_green =\n+\t\tpolicy->actions[RTE_COLOR_GREEN].action_fate;\n+\tuint32_t action_fate_yellow =\n+\t\tpolicy->actions[RTE_COLOR_YELLOW].action_fate;\n+\n+\tuint32_t cur_mtr_id = *next_id;\n+\tuint32_t next_mtr_id = 0xffff;\n+\tuint32_t prev_mtr_id = 0xffff;\n+\n+\tif (action_fate_green == RTE_FLOW_ACTION_TYPE_METER)\n+\t\tnext_mtr_id = policy->actions[RTE_COLOR_GREEN].mtr_id;\n+\n+\tif (action_fate_yellow == RTE_FLOW_ACTION_TYPE_METER)\n+\t\tnext_mtr_id = policy->actions[RTE_COLOR_YELLOW].mtr_id;\n+\n+\tif (action_fate_red == RTE_FLOW_ACTION_TYPE_METER)\n+\t\tnext_mtr_id = policy->actions[RTE_COLOR_RED].mtr_id;\n+\n+\tif (next_mtr_id != 0xffff) {\n+\t\tswitch (*tree_level) {\n+\t\tcase 0:\n+\t\t\tnix_mtr_level_update(eth_dev, cur_mtr_id, 0);\n+\t\t\tnix_mtr_chain_update(eth_dev, cur_mtr_id, -1,\n+\t\t\t\t\t     next_mtr_id);\n+\t\t\t(*tree_level)++;\n+\t\t\t*next_id = next_mtr_id;\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tnix_mtr_level_update(eth_dev, cur_mtr_id, 1);\n+\t\t\tprev_mtr_id = id;\n+\t\t\tnix_mtr_chain_update(eth_dev, cur_mtr_id, prev_mtr_id,\n+\t\t\t\t\t     next_mtr_id);\n+\t\t\t(*tree_level)++;\n+\t\t\t*next_id = next_mtr_id;\n+\t\t\t*prev_id = cur_mtr_id;\n+\t\t\tbreak;\n+\t\tcase 2:\n+\t\t\tnix_mtr_chain_reset(eth_dev, id);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t} else {\n+\t\tswitch (*tree_level) {\n+\t\tcase 0:\n+\t\t\tnix_mtr_level_update(eth_dev, cur_mtr_id, 0);\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tnix_mtr_level_update(eth_dev, cur_mtr_id, 1);\n+\t\t\tprev_mtr_id = id;\n+\t\t\tnix_mtr_chain_update(eth_dev, cur_mtr_id, prev_mtr_id,\n+\t\t\t\t\t     -1);\n+\t\t\tbreak;\n+\t\tcase 2:\n+\t\t\tnix_mtr_level_update(eth_dev, cur_mtr_id, 2);\n+\t\t\tprev_mtr_id = *prev_id;\n+\t\t\tnix_mtr_chain_update(eth_dev, cur_mtr_id, prev_mtr_id,\n+\t\t\t\t\t     -1);\n+\t\t\tbreak;\n+\t\t}\n+\t\t*next_id = 0xffff;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/cnxk/cn10k_rte_flow.c b/drivers/net/cnxk/cn10k_rte_flow.c\nindex b04de6a7e6..128dc2dd4f 100644\n--- a/drivers/net/cnxk/cn10k_rte_flow.c\n+++ b/drivers/net/cnxk/cn10k_rte_flow.c\n@@ -6,6 +6,107 @@\n #include \"cn10k_ethdev.h\"\n #include \"cn10k_rx.h\"\n \n+static int\n+cn10k_mtr_configure(struct rte_eth_dev *eth_dev,\n+\t\t    const struct rte_flow_action actions[])\n+{\n+\tuint32_t mtr_id = 0xffff, prev_mtr_id = 0xffff, next_mtr_id = 0xffff;\n+\tconst struct rte_flow_action_meter *mtr_conf;\n+\tconst struct rte_flow_action_queue *q_conf;\n+\tconst struct rte_flow_action_rss *rss_conf;\n+\tstruct cnxk_mtr_policy_node *policy;\n+\tbool is_mtr_act = false;\n+\tint tree_level = 0;\n+\tint rc = -EINVAL, i;\n+\n+\tfor (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {\n+\t\tif (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) {\n+\t\t\tmtr_conf = (const struct rte_flow_action_meter\n+\t\t\t\t\t    *)(actions->conf);\n+\t\t\tmtr_id = mtr_conf->mtr_id;\n+\t\t\tis_mtr_act = true;\n+\t\t}\n+\t\tif (actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) {\n+\t\t\tq_conf = (const struct rte_flow_action_queue\n+\t\t\t\t\t  *)(actions->conf);\n+\t\t\tif (is_mtr_act)\n+\t\t\t\tnix_mtr_rq_update(eth_dev, mtr_id, 1,\n+\t\t\t\t\t\t  &q_conf->index);\n+\t\t}\n+\t\tif (actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) {\n+\t\t\trss_conf = (const struct rte_flow_action_rss\n+\t\t\t\t\t    *)(actions->conf);\n+\t\t\tif (is_mtr_act)\n+\t\t\t\tnix_mtr_rq_update(eth_dev, mtr_id,\n+\t\t\t\t\t\t  rss_conf->queue_num,\n+\t\t\t\t\t\t  rss_conf->queue);\n+\t\t}\n+\t}\n+\n+\tif (!is_mtr_act)\n+\t\treturn rc;\n+\n+\tprev_mtr_id = mtr_id;\n+\tnext_mtr_id = mtr_id;\n+\twhile (next_mtr_id != 0xffff) {\n+\t\trc = nix_mtr_validate(eth_dev, next_mtr_id);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\n+\t\trc = nix_mtr_policy_act_get(eth_dev, next_mtr_id, &policy);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\n+\t\trc = nix_mtr_color_action_validate(eth_dev, mtr_id,\n+\t\t\t\t\t\t   &prev_mtr_id, &next_mtr_id,\n+\t\t\t\t\t\t   policy, &tree_level);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t}\n+\n+\treturn nix_mtr_configure(eth_dev, mtr_id);\n+}\n+\n+static int\n+cn10k_rss_action_validate(struct rte_eth_dev *eth_dev,\n+\t\t\t  const struct rte_flow_attr *attr,\n+\t\t\t  const struct rte_flow_action *act)\n+{\n+\tconst struct rte_flow_action_rss *rss;\n+\n+\tif (act == NULL)\n+\t\treturn -EINVAL;\n+\n+\trss = (const struct rte_flow_action_rss *)act->conf;\n+\n+\tif (attr->egress) {\n+\t\tplt_err(\"No support of RSS in egress\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (eth_dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS) {\n+\t\tplt_err(\"multi-queue mode is disabled\");\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\tif (!rss || !rss->queue_num) {\n+\t\tplt_err(\"no valid queues\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {\n+\t\tplt_err(\"non-default RSS hash functions are not supported\");\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\tif (rss->key_len && rss->key_len > ROC_NIX_RSS_KEY_LEN) {\n+\t\tplt_err(\"RSS hash key too large\");\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\treturn 0;\n+}\n+\n struct rte_flow *\n cn10k_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,\n \t\t  const struct rte_flow_item pattern[],\n@@ -13,13 +114,65 @@ cn10k_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,\n \t\t  struct rte_flow_error *error)\n {\n \tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tconst struct rte_flow_action *action_rss = NULL;\n+\tconst struct rte_flow_action_meter *mtr = NULL;\n \tint mark_actions = 0, vtag_actions = 0;\n \tstruct roc_npc *npc = &dev->npc;\n \tstruct roc_npc_flow *flow;\n+\tuint32_t req_act = 0;\n+\tint i, rc;\n+\n+\tfor (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {\n+\t\tif (actions[i].type == RTE_FLOW_ACTION_TYPE_METER)\n+\t\t\treq_act |= ROC_NPC_ACTION_TYPE_METER;\n+\n+\t\tif (actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE)\n+\t\t\treq_act |= ROC_NPC_ACTION_TYPE_QUEUE;\n+\n+\t\tif (actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) {\n+\t\t\treq_act |= ROC_NPC_ACTION_TYPE_RSS;\n+\t\t\taction_rss = &actions[i];\n+\t\t}\n+\t}\n+\n+\tif (req_act & ROC_NPC_ACTION_TYPE_METER) {\n+\t\tif ((req_act & ROC_NPC_ACTION_TYPE_RSS) &&\n+\t\t    ((req_act & ROC_NPC_ACTION_TYPE_QUEUE))) {\n+\t\t\treturn NULL;\n+\t\t}\n+\t\tif (req_act & ROC_NPC_ACTION_TYPE_RSS) {\n+\t\t\trc = cn10k_rss_action_validate(eth_dev, attr,\n+\t\t\t\t\t\t       action_rss);\n+\t\t\tif (rc)\n+\t\t\t\treturn NULL;\n+\t\t} else if (req_act & ROC_NPC_ACTION_TYPE_QUEUE) {\n+\t\t} else {\n+\t\t\treturn NULL;\n+\t\t}\n+\t}\n+\n+\tfor (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {\n+\t\tif (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) {\n+\t\t\tmtr = (const struct rte_flow_action_meter *)actions[i]\n+\t\t\t\t      .conf;\n+\t\t\trc = cn10k_mtr_configure(eth_dev, actions);\n+\t\t\tif (rc) {\n+\t\t\t\trte_flow_error_set(error, 0,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ACTION, NULL,\n+\t\t\t\t\t\"Failed to configure mtr \");\n+\t\t\t\treturn NULL;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\t}\n \n \tflow = cnxk_flow_create(eth_dev, attr, pattern, actions, error);\n-\tif (!flow)\n+\tif (!flow) {\n+\t\tif (mtr)\n+\t\t\tnix_mtr_chain_reset(eth_dev, mtr->mtr_id);\n+\n \t\treturn NULL;\n+\t}\n \n \tmark_actions = roc_npc_mark_actions_get(npc);\n \ndiff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h\nindex 0ad06f1536..2dce42e20c 100644\n--- a/drivers/net/cnxk/cnxk_ethdev.h\n+++ b/drivers/net/cnxk/cnxk_ethdev.h\n@@ -454,6 +454,21 @@ int cnxk_nix_dev_get_reg(struct rte_eth_dev *eth_dev,\n \n /* Other private functions */\n int nix_recalc_mtu(struct rte_eth_dev *eth_dev);\n+int nix_mtr_validate(struct rte_eth_dev *dev, uint32_t id);\n+int nix_mtr_policy_act_get(struct rte_eth_dev *eth_dev, uint32_t id,\n+\t\t\t   struct cnxk_mtr_policy_node **policy);\n+int nix_mtr_rq_update(struct rte_eth_dev *eth_dev, uint32_t id,\n+\t\t      uint32_t queue_num, const uint16_t *queue);\n+int nix_mtr_chain_update(struct rte_eth_dev *eth_dev, uint32_t cur_id,\n+\t\t\t uint32_t prev_id, uint32_t next_id);\n+int nix_mtr_chain_reset(struct rte_eth_dev *eth_dev, uint32_t cur_id);\n+int nix_mtr_level_update(struct rte_eth_dev *eth_dev, uint32_t id,\n+\t\t\t uint32_t level);\n+int nix_mtr_configure(struct rte_eth_dev *eth_dev, uint32_t id);\n+int nix_mtr_color_action_validate(struct rte_eth_dev *eth_dev, uint32_t id,\n+\t\t\t\t  uint32_t *prev_id, uint32_t *next_id,\n+\t\t\t\t  struct cnxk_mtr_policy_node *policy,\n+\t\t\t\t  int *tree_level);\n \n /* Inlines */\n static __rte_always_inline uint64_t\ndiff --git a/drivers/net/cnxk/cnxk_rte_flow.c b/drivers/net/cnxk/cnxk_rte_flow.c\nindex 32c1b5dee5..56dcd36c61 100644\n--- a/drivers/net/cnxk/cnxk_rte_flow.c\n+++ b/drivers/net/cnxk/cnxk_rte_flow.c\n@@ -195,6 +195,10 @@ cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,\n \t\t\t\tROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT;\n \t\t\tin_actions[i].conf = actions->conf;\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_METER:\n+\t\t\tin_actions[i].type = ROC_NPC_ACTION_TYPE_METER;\n+\t\t\tin_actions[i].conf = actions->conf;\n+\t\t\tbreak;\n \t\tdefault:\n \t\t\tplt_npc_dbg(\"Action is not supported = %d\",\n \t\t\t\t    actions->type);\n",
    "prefixes": [
        "v2",
        "27/27"
    ]
}