get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 98064,
    "url": "http://patchwork.dpdk.org/api/patches/98064/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20210906075450.1452123-27-skori@marvell.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20210906075450.1452123-27-skori@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210906075450.1452123-27-skori@marvell.com",
    "date": "2021-09-06T07:54:50",
    "name": "[27/27] net/cnxk: support meter action to flow create",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "d723dff294caf2b26f5ccd1b4e6c2d176847d7c2",
    "submitter": {
        "id": 1318,
        "url": "http://patchwork.dpdk.org/api/people/1318/?format=api",
        "name": "Sunil Kumar Kori",
        "email": "skori@marvell.com"
    },
    "delegate": {
        "id": 310,
        "url": "http://patchwork.dpdk.org/api/users/310/?format=api",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerinj@marvell.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20210906075450.1452123-27-skori@marvell.com/mbox/",
    "series": [
        {
            "id": 18696,
            "url": "http://patchwork.dpdk.org/api/series/18696/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=18696",
            "date": "2021-09-06T07:54:24",
            "name": "[01/27] common/cnxk: update policer MBOX APIs and HW definitions",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/18696/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/98064/comments/",
    "check": "fail",
    "checks": "http://patchwork.dpdk.org/api/patches/98064/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 8DC2BA0C4D;\n\tMon,  6 Sep 2021 09:57:31 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 4A401411A0;\n\tMon,  6 Sep 2021 09:55:58 +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 2F9A641193\n for <dev@dpdk.org>; Mon,  6 Sep 2021 09:55:57 +0200 (CEST)",
            "from pps.filterd (m0045849.ppops.net [127.0.0.1])\n by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1861UwOo022975\n for <dev@dpdk.org>; Mon, 6 Sep 2021 00:55:56 -0700",
            "from dc5-exch01.marvell.com ([199.233.59.181])\n by mx0a-0016f401.pphosted.com with ESMTP id 3aw9d2s57k-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n for <dev@dpdk.org>; Mon, 06 Sep 2021 00:55:56 -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.18;\n Mon, 6 Sep 2021 00:55:54 -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.18 via Frontend\n Transport; Mon, 6 Sep 2021 00:55:55 -0700",
            "from localhost.localdomain (unknown [10.28.34.25])\n by maili.marvell.com (Postfix) with ESMTP id 78F883F70A0;\n Mon,  6 Sep 2021 00:55:53 -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=aqUfv0vrGSzSBZcvRr5gZ1sobsQ8M9zUcuGaHSaZTbE=;\n b=fX67l1Eu8RPis/oOGwcoZDekFqI83zM8SCbaHXwMNx6BhJ9nLkdbxbz477VHid4GRIV+\n Z1456qjgf9F797gpsMd56Ji01cTL8rVOK58lKNbQoiAigAPXk4oqC7pRUEWHb0ExkPd9\n zB4LpWJLgbqY98lhqZb3MSz90UHrQorl+HiU/vlzV+JcF5xD2Wdqq35CL8tFZkvW27Eu\n iDCAAGXJaENWvwiq55uYGNFUFK9pguwrQSgLtdD2u28/HTmPV1UD8dpeS6745rolYLWM\n lJinNyp2LoMUsO3d5aONo3WGEKdAD3jglso0wE88SSY4mJvbosixq+XfNYhOBDIUOYlh BA==",
        "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>",
        "Date": "Mon, 6 Sep 2021 13:24:50 +0530",
        "Message-ID": "<20210906075450.1452123-27-skori@marvell.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20210906075450.1452123-1-skori@marvell.com>",
        "References": "<20210906075450.1452123-1-skori@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-GUID": "n_RHskf1LddqaNJzv4sXGPwcDSLVM9jR",
        "X-Proofpoint-ORIG-GUID": "n_RHskf1LddqaNJzv4sXGPwcDSLVM9jR",
        "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-06_02,2021-09-03_01,2020-04-07_01",
        "Subject": "[dpdk-dev] [PATCH 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>\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  | 270 +++++++++++++++++++++++++++\n drivers/net/cnxk/cnxk_ethdev.h       |  10 +\n drivers/net/cnxk/cnxk_rte_flow.c     | 251 +++++++++++++++++++++++++\n 5 files changed, 533 insertions(+)",
    "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 76e3adcfb1..f38d55cf99 100644\n--- a/drivers/net/cnxk/cn10k_ethdev_mtr.c\n+++ b/drivers/net/cnxk/cn10k_ethdev_mtr.c\n@@ -735,3 +735,273 @@ 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 cn10k_flow_meter_profile *profile;\n+\tstruct cn10k_flow_meter_policy *policy;\n+\tstruct cn10k_flow_meter *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 rte_flow_action actions[RTE_COLORS])\n+{\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tstruct cn10k_flow_meter_policy *policy;\n+\tstruct cn10k_flow_meter *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+\tactions[RTE_COLOR_GREEN] = *policy->policy.actions[RTE_COLOR_GREEN];\n+\tactions[RTE_COLOR_YELLOW] = *policy->policy.actions[RTE_COLOR_YELLOW];\n+\tactions[RTE_COLOR_RED] = *policy->policy.actions[RTE_COLOR_RED];\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 cn10k_flow_meter *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_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 cn10k_flow_meter *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 cn10k_flow_meter *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 cn10k_flow_meter *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 cn10k_flow_meter_profile *profile = mtr->profile;\n+\tstruct cn10k_flow_meter_policy *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;\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;\n+\t\tcfg->algo2698.pir = profile->profile.trtcm_rfc2698.pir;\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;\n+\t\tcfg->algo4115.eir = profile->profile.trtcm_rfc4115.eir;\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->policy.actions[RTE_COLOR_GREEN]->type ==\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->policy.actions[RTE_COLOR_YELLOW]->type ==\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->policy.actions[RTE_COLOR_RED]->type ==\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 cn10k_flow_meter *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] = color_map[mtr->params.dscp_table[i]];\n+}\n+\n+int\n+nix_mtr_configure(struct rte_eth_dev *eth_dev, uint32_t id)\n+{\n+\tstruct cn10k_flow_meter *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+\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+\tint rc;\n+\n+\tmtr[0] = nix_mtr_find(dev, id);\n+\tif (mtr[0] == NULL)\n+\t\treturn -EINVAL;\n+\n+\tidx0 = roc_nix_bpf_level_to_idx(lvl_map[mtr[0]->level]);\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+\n+\t\tidx1 = roc_nix_bpf_level_to_idx(lvl_map[mtr[1]->level]);\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\tidx2 = roc_nix_bpf_level_to_idx(lvl_map[mtr[2]->level]);\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 (mtr[0]->is_next)\n+\t\tmtr[1]->bpf_id = profs[idx1].ids[0];\n+\n+\tif (mtr[1]->is_next)\n+\t\tmtr[2]->bpf_id = profs[idx2].ids[0];\n+\n+\tfor (i = 0; i < ROC_NIX_BPF_LEVEL_MAX; i++) {\n+\t\tmemset(&cfg, 0, sizeof(struct roc_nix_bpf_cfg));\n+\t\tnix_mtr_config_map(mtr[i], &cfg);\n+\t\trc = roc_nix_bpf_config(nix, mtr[i]->bpf_id,\n+\t\t\t\t\tlvl_map[mtr[i]->level], &cfg);\n+\n+\t\tmemset(&tbl, 0, sizeof(struct roc_nix_bpf_cfg));\n+\t\tnix_dscp_table_map(mtr[i], &tbl);\n+\t\trc = roc_nix_bpf_pre_color_tbl_setup(nix, 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\tif (mtr[i]->params.meter_enable) {\n+\t\t\tfor (i = 0; mtr[i]->rq_num; i++) {\n+\t\t\t\trq = &dev->rqs[mtr[i]->rq_id[i]];\n+\t\t\t\trc = roc_nix_bpf_ena_dis(nix, mtr[i]->bpf_id,\n+\t\t\t\t\t\t\t rq, true);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn rc;\n+}\ndiff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h\nindex 55b1a56a8b..764e6296c4 100644\n--- a/drivers/net/cnxk/cnxk_ethdev.h\n+++ b/drivers/net/cnxk/cnxk_ethdev.h\n@@ -432,6 +432,16 @@ 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 rte_flow_action actions[RTE_COLORS]);\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_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 \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..7e3db9458b 100644\n--- a/drivers/net/cnxk/cnxk_rte_flow.c\n+++ b/drivers/net/cnxk/cnxk_rte_flow.c\n@@ -92,6 +92,243 @@ npc_rss_action_validate(struct rte_eth_dev *eth_dev,\n \treturn 0;\n }\n \n+static int\n+npc_mtr_green_color_action_validate(struct rte_eth_dev *eth_dev, uint32_t id,\n+\t\t\t\t    const struct rte_flow_action actions[],\n+\t\t\t\t    struct rte_flow_action *green_act,\n+\t\t\t\t    uint32_t *prev_id, uint32_t *next_id)\n+{\n+\tconst struct rte_flow_action_queue *q2_conf =\n+\t\t(const struct rte_flow_action_queue *)green_act->conf;\n+\tconst struct rte_flow_action_rss *rss2_conf =\n+\t\t(const struct rte_flow_action_rss *)green_act->conf;\n+\tconst struct rte_flow_action_meter *mtr_conf;\n+\tconst struct rte_flow_action_queue *q1_conf;\n+\tconst struct rte_flow_action_rss *rss1_conf;\n+\tint i;\n+\n+\tif (green_act->type == RTE_FLOW_ACTION_TYPE_QUEUE)\n+\t\tnix_mtr_rq_update(eth_dev, id, 1, &q2_conf->index);\n+\n+\tfor (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {\n+\t\tif (green_act->type == RTE_FLOW_ACTION_TYPE_QUEUE &&\n+\t\t    actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) {\n+\t\t\tq1_conf =\n+\t\t\t\t(const struct rte_flow_action_queue *)actions[i]\n+\t\t\t\t\t.conf;\n+\n+\t\t\tif (q1_conf->index != q2_conf->index)\n+\t\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tif (green_act->type == RTE_FLOW_ACTION_TYPE_RSS) {\n+\t\tnix_mtr_rq_update(eth_dev, id, rss2_conf->queue_num,\n+\t\t\t\t  rss2_conf->queue);\n+\t}\n+\n+\tfor (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {\n+\t\tif (green_act->type == RTE_FLOW_ACTION_TYPE_RSS &&\n+\t\t    actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) {\n+\t\t\trss1_conf =\n+\t\t\t\t(const struct rte_flow_action_rss *)actions[i]\n+\t\t\t\t\t.conf;\n+\n+\t\t\tif (memcmp(rss1_conf, rss2_conf,\n+\t\t\t\t   sizeof(struct rte_flow_action_rss)))\n+\t\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tif (green_act->type == RTE_FLOW_ACTION_TYPE_METER) {\n+\t\tmtr_conf =\n+\t\t\t(const struct rte_flow_action_meter *)green_act->conf;\n+\t\t*next_id = mtr_conf->mtr_id;\n+\t\tnix_mtr_level_update(eth_dev, id, 0);\n+\t\tnix_mtr_chain_update(eth_dev, id, *prev_id, *next_id);\n+\t\t*prev_id = id;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+npc_mtr_yellow_color_action_validate(struct rte_eth_dev *eth_dev, uint32_t id,\n+\t\t\t\t     const struct rte_flow_action actions[],\n+\t\t\t\t     struct rte_flow_action *yellow_act,\n+\t\t\t\t     uint32_t *prev_id, uint32_t *next_id)\n+{\n+\tconst struct rte_flow_action_queue *q2_conf =\n+\t\t(const struct rte_flow_action_queue *)yellow_act->conf;\n+\tconst struct rte_flow_action_rss *rss2_conf =\n+\t\t(const struct rte_flow_action_rss *)yellow_act->conf;\n+\tconst struct rte_flow_action_meter *mtr_conf;\n+\tconst struct rte_flow_action_rss *rss1_conf;\n+\tconst struct rte_flow_action_queue *q1_conf;\n+\tint i;\n+\n+\tif (yellow_act->type == RTE_FLOW_ACTION_TYPE_QUEUE)\n+\t\tnix_mtr_rq_update(eth_dev, id, 1, &q2_conf->index);\n+\n+\tfor (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {\n+\t\tif (yellow_act->type == RTE_FLOW_ACTION_TYPE_QUEUE &&\n+\t\t    actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) {\n+\t\t\tq1_conf = (const struct rte_flow_action_queue *)\n+\t\t\t\t\t  yellow_act->conf;\n+\n+\t\t\tif (q1_conf->index != q2_conf->index)\n+\t\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tif (yellow_act->type == RTE_FLOW_ACTION_TYPE_RSS) {\n+\t\tnix_mtr_rq_update(eth_dev, id, rss2_conf->queue_num,\n+\t\t\t\t  rss2_conf->queue);\n+\t}\n+\n+\tfor (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {\n+\t\tif (yellow_act->type == RTE_FLOW_ACTION_TYPE_RSS &&\n+\t\t    actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) {\n+\t\t\trss1_conf =\n+\t\t\t\t(const struct rte_flow_action_rss *)actions[i]\n+\t\t\t\t\t.conf;\n+\n+\t\t\tif (memcmp(rss1_conf, rss2_conf,\n+\t\t\t\t   sizeof(struct rte_flow_action_rss)))\n+\t\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\t*next_id = 0xffff;\n+\tif (yellow_act->type == RTE_FLOW_ACTION_TYPE_METER) {\n+\t\tmtr_conf =\n+\t\t\t(const struct rte_flow_action_meter *)yellow_act->conf;\n+\t\t*next_id = mtr_conf->mtr_id;\n+\t\tnix_mtr_level_update(eth_dev, id, 0);\n+\t\tnix_mtr_chain_update(eth_dev, id, *prev_id, *next_id);\n+\t\t*prev_id = id;\n+\t\treturn true;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+npc_mtr_red_color_action_validate(struct rte_eth_dev *eth_dev, uint32_t id,\n+\t\t\t\t  const struct rte_flow_action actions[],\n+\t\t\t\t  struct rte_flow_action *red_act,\n+\t\t\t\t  uint32_t *prev_id, uint32_t *next_id)\n+{\n+\tconst struct rte_flow_action_queue *q2_conf =\n+\t\t(const struct rte_flow_action_queue *)red_act->conf;\n+\tconst struct rte_flow_action_rss *rss2_conf =\n+\t\t(const struct rte_flow_action_rss *)red_act->conf;\n+\tconst struct rte_flow_action_meter *mtr_conf;\n+\tconst struct rte_flow_action_rss *rss1_conf;\n+\tconst struct rte_flow_action_queue *q1_conf;\n+\tint i;\n+\n+\tif (red_act->type == RTE_FLOW_ACTION_TYPE_QUEUE)\n+\t\tnix_mtr_rq_update(eth_dev, id, 1, &q2_conf->index);\n+\n+\tfor (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {\n+\t\tif (red_act->type == RTE_FLOW_ACTION_TYPE_QUEUE &&\n+\t\t    actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) {\n+\t\t\tq1_conf = (const struct rte_flow_action_queue *)\n+\t\t\t\t\t  red_act->conf;\n+\n+\t\t\tif (q1_conf->index != q2_conf->index)\n+\t\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tif (red_act->type == RTE_FLOW_ACTION_TYPE_RSS) {\n+\t\tnix_mtr_rq_update(eth_dev, id, rss2_conf->queue_num,\n+\t\t\t\t  rss2_conf->queue);\n+\t}\n+\n+\tfor (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {\n+\t\tif (red_act->type == RTE_FLOW_ACTION_TYPE_RSS &&\n+\t\t    actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) {\n+\t\t\trss1_conf =\n+\t\t\t\t(const struct rte_flow_action_rss *)actions[i]\n+\t\t\t\t\t.conf;\n+\n+\t\t\tif (memcmp(rss1_conf, rss2_conf,\n+\t\t\t\t   sizeof(struct rte_flow_action_rss)))\n+\t\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\t*next_id = 0xffff;\n+\tif (red_act->type == RTE_FLOW_ACTION_TYPE_METER) {\n+\t\tmtr_conf = (const struct rte_flow_action_meter *)red_act->conf;\n+\t\t*next_id = mtr_conf->mtr_id;\n+\t\tnix_mtr_level_update(eth_dev, id, 0);\n+\t\tnix_mtr_chain_update(eth_dev, id, *prev_id, *next_id);\n+\t\t*prev_id = id;\n+\t\treturn true;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+npc_mtr_configure(struct rte_eth_dev *eth_dev,\n+\t\t  const struct rte_flow_action actions[], int *is_mtr)\n+{\n+\tuint32_t mtr_id, prev_mtr_id = 0xffff, next_mtr_id = 0xffff;\n+\tconst struct rte_flow_action_meter *mtr_conf;\n+\tstruct rte_flow_action mtr_acts[RTE_COLORS];\n+\tbool is_mtr_act = false;\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\t*is_mtr = 1;\n+\t\t\tbreak;\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, mtr_acts);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\n+\t\trc = npc_mtr_green_color_action_validate(eth_dev, mtr_id,\n+\t\t\tactions, &mtr_acts[RTE_COLOR_GREEN], &prev_mtr_id,\n+\t\t\t&next_mtr_id);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\n+\t\trc = npc_mtr_yellow_color_action_validate(eth_dev, mtr_id,\n+\t\t\tactions, &mtr_acts[RTE_COLOR_YELLOW], &prev_mtr_id,\n+\t\t\t&next_mtr_id);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\n+\t\trc = npc_mtr_red_color_action_validate(eth_dev, mtr_id, actions,\n+\t\t\t&mtr_acts[RTE_COLOR_RED], &prev_mtr_id, &next_mtr_id);\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 void\n npc_rss_flowkey_get(struct cnxk_eth_dev *eth_dev,\n \t\t    const struct roc_npc_action *rss_action,\n@@ -195,6 +432,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@@ -281,6 +522,7 @@ cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,\n \tstruct roc_npc_attr in_attr;\n \tstruct roc_npc_flow *flow;\n \tint errcode = 0;\n+\tint is_mtr = 0;\n \tint rc;\n \n \trc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr,\n@@ -292,6 +534,15 @@ cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,\n \t\treturn NULL;\n \t}\n \n+\tif (roc_model_is_cn10k()) {\n+\t\trc = npc_mtr_configure(eth_dev, actions, &is_mtr);\n+\t\tif (rc && is_mtr) {\n+\t\t\trte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t   NULL, \"Failed to configure mtr \");\n+\t\t\treturn NULL;\n+\t\t}\n+\t}\n+\n \tflow = roc_npc_flow_create(npc, &in_attr, in_pattern, in_actions,\n \t\t\t\t   &errcode);\n \tif (errcode != 0) {\n",
    "prefixes": [
        "27/27"
    ]
}