get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 129065,
    "url": "http://patchwork.dpdk.org/api/patches/129065/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20230628162927.92858-8-ajit.khaparde@broadcom.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": "<20230628162927.92858-8-ajit.khaparde@broadcom.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230628162927.92858-8-ajit.khaparde@broadcom.com",
    "date": "2023-06-28T16:29:23",
    "name": "[v4,07/11] net/bnxt: add support for rte meter",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "c0197180538f52ecdefd3a39be1b70890b8286dc",
    "submitter": {
        "id": 501,
        "url": "http://patchwork.dpdk.org/api/people/501/?format=api",
        "name": "Ajit Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "delegate": {
        "id": 1766,
        "url": "http://patchwork.dpdk.org/api/users/1766/?format=api",
        "username": "ajitkhaparde",
        "first_name": "Ajit",
        "last_name": "Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20230628162927.92858-8-ajit.khaparde@broadcom.com/mbox/",
    "series": [
        {
            "id": 28693,
            "url": "http://patchwork.dpdk.org/api/series/28693/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=28693",
            "date": "2023-06-28T16:29:16",
            "name": "sync Truflow support with latest release",
            "version": 4,
            "mbox": "http://patchwork.dpdk.org/series/28693/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/129065/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/129065/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 5B6D342D82;\n\tWed, 28 Jun 2023 18:32:13 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 136A942D4B;\n\tWed, 28 Jun 2023 18:31:24 +0200 (CEST)",
            "from mail-pl1-f175.google.com (mail-pl1-f175.google.com\n [209.85.214.175])\n by mails.dpdk.org (Postfix) with ESMTP id C709342D48\n for <dev@dpdk.org>; Wed, 28 Jun 2023 18:31:21 +0200 (CEST)",
            "by mail-pl1-f175.google.com with SMTP id\n d9443c01a7336-1b801e6ce85so553985ad.1\n for <dev@dpdk.org>; Wed, 28 Jun 2023 09:31:21 -0700 (PDT)",
            "from localhost.localdomain ([192.19.252.250])\n by smtp.gmail.com with ESMTPSA id\n h12-20020a170902f7cc00b001b8229942a0sm3092403plw.34.2023.06.28.09.31.17\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 28 Jun 2023 09:31:19 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=broadcom.com; s=google; t=1687969881; x=1690561881;\n h=mime-version:references:in-reply-to:message-id:date:subject:cc:to\n :from:from:to:cc:subject:date:message-id:reply-to;\n bh=xgtw+J8v/RANDK2q8rQIiA4vWX71tYkAIxsmvUBfrXM=;\n b=gMcYmHEfWmrtc/IuSiE6akCEYuWJ3cH8E1WOP/Ei+/zGEWLhkcmKwwyGuzRUWRIvUa\n xVxi/C5GYU13G1UzPN3wMgVVvzRwoYy6R9CFM+gkquy3oDArLHuysnW1BIpIsoksiCbB\n beq0qBg9LTeaGkMM0UMkLk5HCajHibkERT40I=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20221208; t=1687969881; x=1690561881;\n h=mime-version:references:in-reply-to:message-id:date:subject:cc:to\n :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n bh=xgtw+J8v/RANDK2q8rQIiA4vWX71tYkAIxsmvUBfrXM=;\n b=NFYWPz18Cb2AQ8kpANVJjIVwAb0R6mCKHMjOMukdB3bsdDztyNpkudsyN7mU4AkkzG\n jWmtWTvfH2ed1T1rXlM6ixxzJ7pGd9GKZfAwsNL+MLFY/b7hQ0LqrdyUrhlBw02kuN8g\n dmQkNwMSO1dvX9+uqUY/v+PQ552VJZZoIBOgjs+g632G1BPNefmL9Iv2FHEwR6T6fVi+\n 1SOV6DsE9Ju3UaXta8hha9EBt7zA6k1TCr1NkBk2MAkCSWS4pcAqMWjMosXo8qHUqn7S\n lqRuA4mnE+KPLhgL+SC4faa5ymJXm5hAEf1VtiZuRWCCyHXVao0ZclCeGFazJ1ImGVxn\n Ekfg==",
        "X-Gm-Message-State": "AC+VfDy8zYBT/oSzIy8QZxxB76X21ZG2+bd5N1bPj/z/rn9T8zrT7oT3\n AIhCX1UP6qSHYq8sRIOCarzubd0zPQLzBFLOWf4H1tNUh1D/7VxTdo4PquLIFa2h7X4l3zvTRXg\n VjnZ+nOZ0TH6sy61HYhkEq9mgDFGtEBbCophISL4tJ71bF+lA+Jtn1klhxacH6r8xuIcm+3Q=",
        "X-Google-Smtp-Source": "\n ACHHUZ7AD7l0oonynLiYnZsO2rYMn5gRioIDRQ6VXtN1i2s6XbkTuyLkMNdM+qDFGW89mz80sLC7NA==",
        "X-Received": "by 2002:a17:902:c244:b0:1b6:6dc8:edeb with SMTP id\n 4-20020a170902c24400b001b66dc8edebmr2168698plg.21.1687969880219;\n Wed, 28 Jun 2023 09:31:20 -0700 (PDT)",
        "From": "Ajit Khaparde <ajit.khaparde@broadcom.com>",
        "To": "dev@dpdk.org",
        "Cc": "ferruh.yigit@intel.com, thomas@monjalon.net,\n Randy Schacher <stuart.schacher@broadcom.com>,\n Jay Ding <jay.ding@broadcom.com>",
        "Subject": "[PATCH v4 07/11] net/bnxt: add support for rte meter",
        "Date": "Wed, 28 Jun 2023 09:29:23 -0700",
        "Message-Id": "<20230628162927.92858-8-ajit.khaparde@broadcom.com>",
        "X-Mailer": "git-send-email 2.39.2 (Apple Git-143)",
        "In-Reply-To": "<20230628162927.92858-1-ajit.khaparde@broadcom.com>",
        "References": "<1826961.atdPhlSkOF@thomas>\n <20230628162927.92858-1-ajit.khaparde@broadcom.com>",
        "MIME-Version": "1.0",
        "Content-Type": "multipart/signed; protocol=\"application/pkcs7-signature\";\n micalg=sha-256; boundary=\"00000000000026910405ff331d2a\"",
        "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": "From: Randy Schacher <stuart.schacher@broadcom.com>\n\nAdd RTE meter support into the ULP layer.\nCurrently:\n- Chaining of meters is not supported\n- Meter can be shared by multiple flows\n- srtcm_rfc2697 type is supported\n- Stats are not supported in the implementation yet\n\nSigned-off-by: Randy Schacher <stuart.schacher@broadcom.com>\nSigned-off-by: Jay Ding <jay.ding@broadcom.com>\nAcked-by: Ajit Khaparde <ajit.khaparde@broadcom.com>\n---\n doc/guides/nics/features/bnxt.ini             |   1 +\n drivers/net/bnxt/bnxt.h                       |   2 +\n drivers/net/bnxt/bnxt_ethdev.c                |   1 +\n drivers/net/bnxt/tf_ulp/bnxt_ulp.c            |   8 +\n drivers/net/bnxt/tf_ulp/bnxt_ulp.h            |   3 +\n drivers/net/bnxt/tf_ulp/bnxt_ulp_meter.c      | 909 ++++++++++++++++++\n drivers/net/bnxt/tf_ulp/meson.build           |   1 +\n drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c |   4 +-\n drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      |  29 +\n drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |   5 +\n 10 files changed, 961 insertions(+), 2 deletions(-)\n create mode 100644 drivers/net/bnxt/tf_ulp/bnxt_ulp_meter.c",
    "diff": "diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini\nindex b225878a78..8b523e3bef 100644\n--- a/doc/guides/nics/features/bnxt.ini\n+++ b/doc/guides/nics/features/bnxt.ini\n@@ -77,6 +77,7 @@ dec_ttl              = Y\n drop                 = Y\n jump                 = 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/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h\nindex 6dd3c8b87c..7d508c7c23 100644\n--- a/drivers/net/bnxt/bnxt.h\n+++ b/drivers/net/bnxt/bnxt.h\n@@ -1014,6 +1014,7 @@ bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,\n \t\t\t    struct rte_eth_udp_tunnel *udp_tunnel);\n \n extern const struct rte_flow_ops bnxt_flow_ops;\n+extern const struct rte_flow_ops bnxt_flow_meter_ops;\n \n #define bnxt_acquire_flow_lock(bp) \\\n \tpthread_mutex_lock(&(bp)->flow_lock)\n@@ -1065,6 +1066,7 @@ int bnxt_flow_ops_get_op(struct rte_eth_dev *dev,\n int bnxt_dev_start_op(struct rte_eth_dev *eth_dev);\n int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev);\n void bnxt_handle_vf_cfg_change(void *arg);\n+int bnxt_flow_meter_ops_get(struct rte_eth_dev *eth_dev, void *arg);\n struct bnxt_vnic_info *bnxt_get_default_vnic(struct bnxt *bp);\n struct tf *bnxt_get_tfp_session(struct bnxt *bp, enum bnxt_session_type type);\n #endif\ndiff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c\nindex 4d84aaee0c..7bceb0524a 100644\n--- a/drivers/net/bnxt/bnxt_ethdev.c\n+++ b/drivers/net/bnxt/bnxt_ethdev.c\n@@ -4091,6 +4091,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {\n \t.timesync_adjust_time = bnxt_timesync_adjust_time,\n \t.timesync_read_rx_timestamp = bnxt_timesync_read_rx_timestamp,\n \t.timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp,\n+\t.mtr_ops_get = bnxt_flow_meter_ops_get,\n };\n \n static uint32_t bnxt_map_reset_regs(struct bnxt *bp, uint32_t reg)\ndiff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c\nindex 08eb0c6063..3459140f18 100644\n--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c\n+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c\n@@ -1681,6 +1681,14 @@ bnxt_ulp_init(struct bnxt *bp,\n \t\treturn rc;\n \t}\n \n+\tif (ulp_dev_id == BNXT_ULP_DEVICE_ID_THOR) {\n+\t\trc = bnxt_flow_meter_init(bp);\n+\t\tif (rc) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Failed to config meter\\n\");\n+\t\t\tgoto jump_to_error;\n+\t\t}\n+\t}\n+\n \tBNXT_TF_DBG(DEBUG, \"ulp ctx has been initialized\\n\");\n \treturn rc;\n \ndiff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h\nindex 53d76e1465..a6ad5c1eaa 100644\n--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h\n+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h\n@@ -371,6 +371,9 @@ bnxt_ulp_vxlan_ip_port_set(struct bnxt_ulp_context *ulp_ctx,\n unsigned int\n bnxt_ulp_vxlan_ip_port_get(struct bnxt_ulp_context *ulp_ctx);\n \n+int32_t\n+bnxt_flow_meter_init(struct bnxt *bp);\n+\n uint32_t\n bnxt_ulp_cntxt_convert_dev_id(uint32_t ulp_dev_id);\n \ndiff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_meter.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp_meter.c\nnew file mode 100644\nindex 0000000000..2461c46f90\n--- /dev/null\n+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_meter.c\n@@ -0,0 +1,909 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2014-2023 Broadcom\n+ * All rights reserved.\n+ */\n+\n+#include <math.h>\n+#include <sys/queue.h>\n+\n+#include <rte_log.h>\n+#include <rte_malloc.h>\n+#include <rte_flow.h>\n+#include <rte_flow_driver.h>\n+#include <rte_tailq.h>\n+#include <rte_alarm.h>\n+#include <rte_cycles.h>\n+#include <rte_mtr.h>\n+#include <rte_mtr_driver.h>\n+\n+#include \"bnxt.h\"\n+#include \"bnxt_filter.h\"\n+#include \"bnxt_hwrm.h\"\n+#include \"bnxt_ring.h\"\n+#include \"bnxt_rxq.h\"\n+#include \"bnxt_rxr.h\"\n+#include \"bnxt_vnic.h\"\n+#include \"hsi_struct_def_dpdk.h\"\n+\n+#include \"tfp.h\"\n+#include \"bnxt_tf_common.h\"\n+#include \"ulp_rte_parser.h\"\n+#include \"ulp_matcher.h\"\n+#include \"ulp_flow_db.h\"\n+#include \"ulp_mapper.h\"\n+#include \"ulp_fc_mgr.h\"\n+#include \"ulp_port_db.h\"\n+#include \"ulp_ha_mgr.h\"\n+#include \"ulp_tun.h\"\n+#include <rte_malloc.h>\n+\n+/**\n+ * Meter init status\n+ */\n+int bnxt_meter_initialized;\n+\n+/**\n+ * Internal api to config global config.\n+ * returns 0 on success.\n+ */\n+static int32_t\n+bnxt_meter_global_cfg_update(struct bnxt *bp,\n+\t\t\t     enum tf_dir dir,\n+\t\t\t     enum tf_global_config_type type,\n+\t\t\t     uint32_t offset,\n+\t\t\t     uint32_t value,\n+\t\t\t     uint32_t set_flag)\n+{\n+\tuint32_t global_cfg = 0;\n+\tstruct tf_global_cfg_parms parms = { 0 };\n+\tstruct tf *tfp;\n+\tint32_t rc = 0;\n+\n+\tparms.dir = dir,\n+\tparms.type = type,\n+\tparms.offset = offset,\n+\tparms.config = (uint8_t *)&global_cfg,\n+\tparms.config_sz_in_bytes = sizeof(global_cfg);\n+\n+\ttfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);\n+\trc = tf_get_global_cfg(tfp, &parms);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to get global cfg 0x%x rc:%d\\n\",\n+\t\t\t    type, rc);\n+\t\treturn rc;\n+\t}\n+\n+\tif (set_flag)\n+\t\tglobal_cfg |= value;\n+\telse\n+\t\tglobal_cfg &= ~value;\n+\n+\trc = tf_set_global_cfg(tfp, &parms);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to set global cfg 0x%x rc:%d\\n\",\n+\t\t\t    type, rc);\n+\t\treturn rc;\n+\t}\n+\treturn rc;\n+}\n+\n+/**\n+ * When a port is initialized by dpdk. This functions is called\n+ * to enable the meter and initializes the meter global configurations.\n+ */\n+#define BNXT_THOR_FMTCR_NUM_MET_MET_1K (0x7UL << 20)\n+#define BNXT_THOR_FMTCR_CNTRS_ENABLE (0x1UL << 25)\n+#define BNXT_THOR_FMTCR_INTERVAL_1K (1024)\n+int32_t\n+bnxt_flow_meter_init(struct bnxt *bp)\n+{\n+\tint rc = 0;\n+\n+\t/*\n+\t * Enable metering. Set the meter global configuration register.\n+\t * Set number of meter to 1K. Disable the drop counter for now.\n+\t */\n+\trc = bnxt_meter_global_cfg_update(bp, TF_DIR_RX, TF_METER_CFG,\n+\t\t\t\t\t  0,\n+\t\t\t\t\t  BNXT_THOR_FMTCR_NUM_MET_MET_1K,\n+\t\t\t\t\t  1);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to set rx meter configuration\\n\");\n+\t\tgoto jump_to_error;\n+\t}\n+\n+\trc = bnxt_meter_global_cfg_update(bp, TF_DIR_TX, TF_METER_CFG,\n+\t\t\t\t\t0,\n+\t\t\t\t\tBNXT_THOR_FMTCR_NUM_MET_MET_1K,\n+\t\t\t\t\t1);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to set tx meter configuration\\n\");\n+\t\tgoto jump_to_error;\n+\t}\n+\n+\t/*\n+\t * Set meter refresh rate to 1024 clock cycle. This value works for\n+\t * most bit rates especially for high rates.\n+\t */\n+\trc = bnxt_meter_global_cfg_update(bp, TF_DIR_RX, TF_METER_INTERVAL_CFG,\n+\t\t\t\t\t  0,\n+\t\t\t\t\t  BNXT_THOR_FMTCR_INTERVAL_1K,\n+\t\t\t\t\t  1);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to set rx meter interval\\n\");\n+\t\tgoto jump_to_error;\n+\t}\n+\n+\trc = bnxt_meter_global_cfg_update(bp, TF_DIR_TX, TF_METER_INTERVAL_CFG,\n+\t\t\t\t\t  0,\n+\t\t\t\t\t  BNXT_THOR_FMTCR_INTERVAL_1K,\n+\t\t\t\t\t  1);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to set tx meter interval\\n\");\n+\t\tgoto jump_to_error;\n+\t}\n+\n+\tbnxt_meter_initialized = 1;\n+\tBNXT_TF_DBG(DEBUG, \"Bnxt flow meter has been initialized\\n\");\n+\treturn rc;\n+\n+jump_to_error:\n+\treturn rc;\n+}\n+\n+/**\n+ * Get meter capabilities.\n+ */\n+#define MAX_FLOW_PER_METER 1024\n+#define MAX_METER_RATE_100GBPS ((1ULL << 30) * 100 / 8)\n+static int\n+bnxt_flow_mtr_cap_get(struct rte_eth_dev *dev,\n+\t\t      struct rte_mtr_capabilities *cap,\n+\t\t      struct rte_mtr_error *error)\n+{\n+\tstruct bnxt *bp = dev->data->dev_private;\n+\tuint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;\n+\tstruct tf_get_session_info_parms iparms;\n+\tstruct tf *tfp;\n+\tint32_t rc = 0;\n+\n+\tif (!bnxt_meter_initialized)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"Bnxt meter is not initialized\");\n+\n+\trc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);\n+\tif (rc)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"Unable to get device id from ulp\");\n+\n+\t/* Get number of meter reserved for this session */\n+\tmemset(&iparms, 0, sizeof(iparms));\n+\ttfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);\n+\trc = tf_get_session_info(tfp, &iparms);\n+\tif (rc != 0)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"Failed to get session resource info\");\n+\n+\tmemset(cap, 0, sizeof(struct rte_mtr_capabilities));\n+\n+\tcap->n_max = iparms.session_info.tbl[TF_DIR_RX].info[TF_TBL_TYPE_METER_INST].stride;\n+\tif (!cap->n_max)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t  \"Meter is not supported\");\n+\n+\tcap->srtcm_rfc2697_byte_mode_supported = 1;\n+\tcap->n_shared_max = cap->n_max;\n+\t/* No meter is identical */\n+\tcap->identical = 1;\n+\tcap->shared_identical = 1;\n+\tcap->shared_n_flows_per_mtr_max = MAX_FLOW_PER_METER;\n+\tcap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */\n+\tcap->meter_srtcm_rfc2697_n_max = cap->n_max;\n+\tcap->meter_rate_max = MAX_METER_RATE_100GBPS;\n+\t/* No stats supported now */\n+\tcap->stats_mask = 0;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Calculate mantissa and exponent for cir / eir reg.\n+ */\n+#define BNXT_CPU_CLOCK 800\n+#define MEGA 1000000\n+#define NUM_BIT_PER_BYTE 8\n+static inline void\n+bnxt_ulp_flow_meter_xir_calc(int64_t xir, uint32_t *reg)\n+{\n+\tint64_t temp;\n+\tuint16_t m = 0;\n+\tuint16_t e = 0;\n+\tuint8_t *swap = 0;\n+\n+\t/* Special case xir == 0 ? both exp and matissa are 0. */\n+\tif (xir == 0) {\n+\t\t*reg = 0;\n+\t\treturn;\n+\t}\n+\n+\t/*\n+\t * e = floor(log2(cir)) + 27\n+\t * a (MBps) = xir (bps) / MEGA\n+\t * b (MBpc) = a (MBps) / CPU_CLOCK (Mcps)\n+\t * e = floor(log2(b)) + 27\n+\t */\n+\ttemp = xir * (1 << 24) / (BNXT_CPU_CLOCK >> 3) / MEGA;\n+\te = log2(temp);\n+\n+\t/*\n+\t * m = round(b/2^(e-27) - 1) * 2048\n+\t *   = round(b*2^(27-e) - 1) * 2^11\n+\t *   = round(b*2^(38-e) - 2^11)\n+\t *\n+\t */\n+\tm = xir * (1 << (38 - e)) / BNXT_CPU_CLOCK / MEGA - (1 << 11);\n+\t*reg = ((m & 0x7FF) << 6) | (e & 0x3F);\n+\tswap = (uint8_t *)reg;\n+\t*reg = swap[0] << 16 | swap[1] << 8 | swap[2];\n+}\n+\n+/**\n+ * Calculate mantissa and exponent for cbs / ebs reg.\n+ */\n+static inline void\n+bnxt_ulp_flow_meter_xbs_calc(int64_t xbs, uint16_t *reg)\n+{\n+\tuint16_t m = 0;\n+\tuint16_t e = 0;\n+\n+\tif (xbs == 0) {\n+\t\t*reg = 0;\n+\t\treturn;\n+\t}\n+\n+\t/*\n+\t * e = floor(log2(xbs)) + 1\n+\t */\n+\te = log2(xbs) + 1;\n+\n+\t/*\n+\t * m = round(xbs/2^(e-1) - 1) * 128\n+\t *   = round(xbs*2^(1-e) - 1) * 2^7\n+\t *   = round(xbs*2^(8-e) - 2^7)\n+\t *\n+\t */\n+\tm = xbs / (1 << (e - 8)) - (1 << 7);\n+\t*reg = ((m & 0x7F) << 5) | (e & 0x1F);\n+\t*reg = rte_cpu_to_be_16(*reg);\n+}\n+\n+/**\n+ * Parse the meter profile.\n+ */\n+static inline int\n+bnxt_ulp_meter_profile_parse(struct ulp_rte_act_prop *act_prop,\n+\t\t\t     const struct rte_mtr_meter_profile *profile,\n+\t\t\t     struct rte_mtr_error *error)\n+{\n+\tuint64_t cir, cbs, eir, ebs;\n+\tuint32_t cir_reg, eir_reg;\n+\tuint16_t cbs_reg, ebs_reg;\n+\tbool alg_rfc2698 = false;\n+\tbool pm = false;\n+\n+\t/* Profile must not be NULL. */\n+\tif (profile == NULL)\n+\t\treturn -rte_mtr_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_METER_PROFILE,\n+\t\t\t\t\t  NULL, \"Meter profile is null.\");\n+\n+\tif (profile->packet_mode)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_METER_PROFILE,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"Metering packet_mode is not supported\");\n+\n+\tswitch (profile->alg) {\n+\tcase RTE_MTR_SRTCM_RFC2697:\n+\t\tcir = profile->srtcm_rfc2697.cir;\n+\t\tcbs = profile->srtcm_rfc2697.cbs;\n+\t\teir = 0;\n+\t\tebs = profile->srtcm_rfc2697.ebs;\n+\t\tbreak;\n+\tcase RTE_MTR_TRTCM_RFC2698:\n+\t\tcir = profile->trtcm_rfc2698.cir;\n+\t\tcbs = profile->trtcm_rfc2698.cbs;\n+\t\teir = profile->trtcm_rfc2698.pir;\n+\t\tebs = profile->trtcm_rfc2698.pbs;\n+\t\talg_rfc2698 = true;\n+\t\tbreak;\n+\tcase RTE_MTR_TRTCM_RFC4115:\n+\t\tcir = profile->trtcm_rfc4115.cir;\n+\t\tcbs = profile->trtcm_rfc4115.cbs;\n+\t\teir = profile->trtcm_rfc4115.eir;\n+\t\tebs = profile->trtcm_rfc4115.ebs;\n+\t\talg_rfc2698 = true;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -rte_mtr_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_METER_PROFILE,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"Metering algorithm type is invalid\");\n+\t}\n+\n+\t/* The CBS and EBS must be configured so that at least one\n+\t * of them is larger than 0.  It is recommended that when\n+\t * the value of the CBS or the EBS is larger than 0, it\n+\t * is larger than or equal to the size of the largest possible\n+\t * IP packet in the stream.\n+\t */\n+\tif (cbs == 0 && ebs == 0)\n+\t\treturn -rte_mtr_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_METER_PROFILE,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"CBS & EBS cannot both be 0. One of\"\n+\t\t\t\t\t  \" them should be larger than the MTU\");\n+\n+\tif (alg_rfc2698 && eir < cir)\n+\t\treturn -rte_mtr_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_METER_PROFILE,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"PIR must be equal to or greater than CIR\");\n+\n+\tbnxt_ulp_flow_meter_xir_calc(cir, &cir_reg);\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_CIR],\n+\t       &cir_reg,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_PROF_CIR);\n+\n+\tbnxt_ulp_flow_meter_xir_calc(eir, &eir_reg);\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_EIR],\n+\t       &eir_reg,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_PROF_EIR);\n+\n+\tbnxt_ulp_flow_meter_xbs_calc(cbs, &cbs_reg);\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_CBS],\n+\t       &cbs_reg,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_PROF_CBS);\n+\n+\tbnxt_ulp_flow_meter_xbs_calc(ebs, &ebs_reg);\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_EBS],\n+\t       &ebs_reg,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_PROF_EBS);\n+\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_RFC2698],\n+\t       &alg_rfc2698,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_PROF_RFC2698);\n+\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_PM],\n+\t       &pm,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_PROF_PM);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Add MTR profile.\n+ */\n+static int\n+bnxt_flow_meter_profile_add(struct rte_eth_dev *dev,\n+\t\t\t    uint32_t meter_profile_id,\n+\t\t\t    struct rte_mtr_meter_profile *profile,\n+\t\t\t    struct rte_mtr_error *error)\n+{\n+\tstruct bnxt_ulp_context *ulp_ctx;\n+\tstruct ulp_rte_parser_params params;\n+\tstruct ulp_rte_act_prop *act_prop = &params.act_prop;\n+\tstruct bnxt_ulp_mapper_create_parms mparms = { 0 };\n+\tuint32_t act_tid;\n+\tuint16_t func_id;\n+\tint ret;\n+\tuint32_t tmp_profile_id;\n+\n+\tif (!bnxt_meter_initialized)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"Bnxt meter is not initialized\");\n+\n+\tulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);\n+\tif (!ulp_ctx)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"ULP context is not initialized\");\n+\n+\t/* Initialize the parser params */\n+\tmemset(&params, 0, sizeof(struct ulp_rte_parser_params));\n+\tparams.ulp_ctx = ulp_ctx;\n+\tparams.act_bitmap.bits = BNXT_ULP_ACT_BIT_METER_PROFILE;\n+\t/* not direction from rte_mtr. Set ingress by default */\n+\tparams.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;\n+\n+\ttmp_profile_id = tfp_cpu_to_be_32(meter_profile_id);\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_ID],\n+\t       &tmp_profile_id,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_PROF_ID);\n+\n+\tret = bnxt_ulp_meter_profile_parse(act_prop, profile, error);\n+\tif (ret)\n+\t\tgoto parse_error;\n+\n+\tret = ulp_matcher_action_match(&params, &act_tid);\n+\tif (ret != BNXT_TF_RC_SUCCESS)\n+\t\tgoto act_error;\n+\n+\tbnxt_ulp_init_mapper_params(&mparms, &params,\n+\t\t\t\t    BNXT_ULP_FDB_TYPE_REGULAR);\n+\tmparms.act_tid = act_tid;\n+\n+\t/* Get the function id */\n+\tif (ulp_port_db_port_func_id_get(ulp_ctx,\n+\t\t\t\t\t dev->data->port_id,\n+\t\t\t\t\t &func_id)) {\n+\t\tBNXT_TF_DBG(ERR, \"conversion of port to func id failed\\n\");\n+\t\tgoto act_error;\n+\t}\n+\n+\t/* Protect flow creation */\n+\tif (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {\n+\t\tBNXT_TF_DBG(ERR, \"Flow db lock acquire failed\\n\");\n+\t\tgoto act_error;\n+\t}\n+\n+\tret = ulp_mapper_flow_create(params.ulp_ctx, &mparms);\n+\tbnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);\n+\n+\tif (ret)\n+\t\tgoto act_error;\n+\n+\treturn 0;\n+parse_error:\n+\treturn ret;\n+act_error:\n+\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t  NULL,\n+\t\t\t\t  \"Failed to add meter profile.\");\n+}\n+\n+/**\n+ * Delete meter profile.\n+ */\n+static int\n+bnxt_flow_meter_profile_delete(struct rte_eth_dev *dev,\n+\t\t\t       uint32_t meter_profile_id,\n+\t\t\t       struct rte_mtr_error *error)\n+{\n+\tstruct bnxt_ulp_context *ulp_ctx;\n+\tstruct ulp_rte_parser_params params;\n+\tstruct ulp_rte_act_prop *act_prop = &params.act_prop;\n+\tstruct bnxt_ulp_mapper_create_parms mparms = { 0 };\n+\tuint32_t act_tid;\n+\tuint16_t func_id;\n+\tint ret;\n+\tuint32_t tmp_profile_id;\n+\n+\tif (!bnxt_meter_initialized)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"Bnxt meter is not initialized\");\n+\n+\tulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);\n+\tif (!ulp_ctx)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"ULP context is not initialized\");\n+\n+\t/* Initialize the parser params */\n+\tmemset(&params, 0, sizeof(struct ulp_rte_parser_params));\n+\tparams.ulp_ctx = ulp_ctx;\n+\tparams.act_bitmap.bits = BNXT_ULP_ACT_BIT_METER_PROFILE;\n+\tparams.act_bitmap.bits |= BNXT_ULP_ACT_BIT_DELETE;\n+\t/* not direction from rte_mtr. Set ingress by default */\n+\tparams.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;\n+\n+\ttmp_profile_id = tfp_cpu_to_be_32(meter_profile_id);\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_ID],\n+\t       &tmp_profile_id,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_PROF_ID);\n+\n+\tret = ulp_matcher_action_match(&params, &act_tid);\n+\tif (ret != BNXT_TF_RC_SUCCESS)\n+\t\tgoto parse_error;\n+\n+\tbnxt_ulp_init_mapper_params(&mparms, &params,\n+\t\t\t\t    BNXT_ULP_FDB_TYPE_REGULAR);\n+\tmparms.act_tid = act_tid;\n+\n+\t/* Get the function id */\n+\tif (ulp_port_db_port_func_id_get(ulp_ctx,\n+\t\t\t\t\t dev->data->port_id,\n+\t\t\t\t\t &func_id)) {\n+\t\tBNXT_TF_DBG(ERR, \"conversion of port to func id failed\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\t/* Protect flow creation */\n+\tif (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {\n+\t\tBNXT_TF_DBG(ERR, \"Flow db lock acquire failed\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tret = ulp_mapper_flow_create(params.ulp_ctx, &mparms);\n+\tbnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);\n+\n+\tif (ret)\n+\t\tgoto parse_error;\n+\n+\tBNXT_TF_DBG(DEBUG, \"Bnxt flow meter profile %d deleted\\n\",\n+\t\t    meter_profile_id);\n+\n+\treturn 0;\n+\n+parse_error:\n+\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t  NULL,\n+\t\t\t\t  \"Failed to delete meter profile.\");\n+}\n+\n+/**\n+ * Create meter.\n+ */\n+static int\n+bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,\n+\t\t       struct rte_mtr_params *params, int shared __rte_unused,\n+\t\t       struct rte_mtr_error *error)\n+{\n+\tstruct bnxt_ulp_context *ulp_ctx;\n+\tstruct ulp_rte_parser_params pparams;\n+\tstruct ulp_rte_act_prop *act_prop = &pparams.act_prop;\n+\tstruct bnxt_ulp_mapper_create_parms mparms = { 0 };\n+\tuint32_t act_tid;\n+\tuint16_t func_id;\n+\tbool meter_en = params->meter_enable ? true : false;\n+\tint ret;\n+\tuint32_t tmp_meter_id, tmp_profile_id;\n+\n+\tif (!bnxt_meter_initialized)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"Bnxt meter is not initialized\");\n+\n+\tulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);\n+\tif (!ulp_ctx)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"ULP context is not initialized\");\n+\n+\t/* Initialize the parser params */\n+\tmemset(&pparams, 0, sizeof(struct ulp_rte_parser_params));\n+\tpparams.ulp_ctx = ulp_ctx;\n+\tpparams.act_bitmap.bits = BNXT_ULP_ACT_BIT_SHARED_METER;\n+\t/* not direction from rte_mtr. Set ingress by default */\n+\tpparams.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;\n+\n+\ttmp_meter_id = tfp_cpu_to_be_32(meter_id);\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_ID],\n+\t       &tmp_meter_id,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_INST_ID);\n+\n+\ttmp_profile_id = tfp_cpu_to_be_32(params->meter_profile_id);\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_ID],\n+\t       &tmp_profile_id,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_PROF_ID);\n+\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_MTR_VAL],\n+\t       &meter_en,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_INST_MTR_VAL);\n+\n+\tret = ulp_matcher_action_match(&pparams, &act_tid);\n+\tif (ret != BNXT_TF_RC_SUCCESS)\n+\t\tgoto parse_error;\n+\n+\tbnxt_ulp_init_mapper_params(&mparms, &pparams,\n+\t\t\t\t    BNXT_ULP_FDB_TYPE_REGULAR);\n+\tmparms.act_tid = act_tid;\n+\n+\t/* Get the function id */\n+\tif (ulp_port_db_port_func_id_get(ulp_ctx,\n+\t\t\t\t\t dev->data->port_id,\n+\t\t\t\t\t &func_id)) {\n+\t\tBNXT_TF_DBG(ERR, \"conversion of port to func id failed\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\t/* Protect flow creation */\n+\tif (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {\n+\t\tBNXT_TF_DBG(ERR, \"Flow db lock acquire failed\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tret = ulp_mapper_flow_create(pparams.ulp_ctx, &mparms);\n+\tbnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);\n+\n+\tif (ret)\n+\t\tgoto parse_error;\n+\n+\tBNXT_TF_DBG(DEBUG, \"Bnxt flow meter %d is created\\n\", meter_id);\n+\n+\treturn 0;\n+parse_error:\n+\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t  NULL,\n+\t\t\t\t  \"Failed to add meter.\");\n+}\n+\n+/**\n+ * Destroy meter.\n+ */\n+static int\n+bnxt_flow_meter_destroy(struct rte_eth_dev *dev,\n+\t\t\tuint32_t meter_id,\n+\t\t\tstruct rte_mtr_error *error)\n+{\n+\tstruct bnxt_ulp_context *ulp_ctx;\n+\tstruct ulp_rte_parser_params pparams;\n+\tstruct ulp_rte_act_prop *act_prop = &pparams.act_prop;\n+\tstruct bnxt_ulp_mapper_create_parms mparms = { 0 };\n+\tuint32_t act_tid;\n+\tuint16_t func_id;\n+\tint ret;\n+\tuint32_t tmp_meter_id;\n+\n+\tif (!bnxt_meter_initialized)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"Bnxt meter is not initialized\");\n+\n+\tulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);\n+\tif (!ulp_ctx)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"ULP context is not initialized\");\n+\n+\t/* Initialize the parser params */\n+\tmemset(&pparams, 0, sizeof(struct ulp_rte_parser_params));\n+\tpparams.ulp_ctx = ulp_ctx;\n+\tpparams.act_bitmap.bits = BNXT_ULP_ACT_BIT_SHARED_METER;\n+\tpparams.act_bitmap.bits |= BNXT_ULP_ACT_BIT_DELETE;\n+\t/* not direction from rte_mtr. Set ingress by default */\n+\tpparams.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;\n+\n+\ttmp_meter_id = tfp_cpu_to_be_32(meter_id);\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_ID],\n+\t       &tmp_meter_id,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_INST_ID);\n+\n+\tret = ulp_matcher_action_match(&pparams, &act_tid);\n+\tif (ret != BNXT_TF_RC_SUCCESS)\n+\t\tgoto parse_error;\n+\n+\tbnxt_ulp_init_mapper_params(&mparms, &pparams,\n+\t\t\t\t    BNXT_ULP_FDB_TYPE_REGULAR);\n+\tmparms.act_tid = act_tid;\n+\n+\t/* Get the function id */\n+\tif (ulp_port_db_port_func_id_get(ulp_ctx,\n+\t\t\t\t\t dev->data->port_id,\n+\t\t\t\t\t &func_id)) {\n+\t\tBNXT_TF_DBG(ERR, \"conversion of port to func id failed\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\t/* Protect flow creation */\n+\tif (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {\n+\t\tBNXT_TF_DBG(ERR, \"Flow db lock acquire failed\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tret = ulp_mapper_flow_create(pparams.ulp_ctx, &mparms);\n+\tbnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);\n+\n+\tif (ret)\n+\t\tgoto parse_error;\n+\n+\tBNXT_TF_DBG(DEBUG, \"Bnxt flow meter %d is deleted\\n\", meter_id);\n+\n+\treturn 0;\n+parse_error:\n+\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t  NULL,\n+\t\t\t\t  \"Failed to delete meter.\");\n+}\n+\n+/**\n+ * Set meter valid/invalid.\n+ */\n+static int\n+bnxt_flow_meter_enable_set(struct rte_eth_dev *dev,\n+\t\t\t   uint32_t meter_id,\n+\t\t\t   uint8_t val,\n+\t\t\t   struct rte_mtr_error *error)\n+{\n+\tstruct bnxt_ulp_context *ulp_ctx;\n+\tstruct ulp_rte_parser_params pparams;\n+\tstruct ulp_rte_act_prop *act_prop = &pparams.act_prop;\n+\tstruct bnxt_ulp_mapper_create_parms mparms = { 0 };\n+\tuint32_t act_tid;\n+\tuint16_t func_id;\n+\tint ret;\n+\tuint32_t tmp_meter_id;\n+\n+\tif (!bnxt_meter_initialized)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"Bnxt meter is not initialized\");\n+\n+\tulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);\n+\tif (!ulp_ctx)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"ULP context is not initialized\");\n+\n+\t/* Initialize the parser params */\n+\tmemset(&pparams, 0, sizeof(struct ulp_rte_parser_params));\n+\tpparams.ulp_ctx = ulp_ctx;\n+\tpparams.act_bitmap.bits = BNXT_ULP_ACT_BIT_SHARED_METER;\n+\tpparams.act_bitmap.bits |= BNXT_ULP_ACT_BIT_UPDATE;\n+\t/* not direction from rte_mtr. Set ingress by default */\n+\tpparams.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;\n+\n+\ttmp_meter_id = tfp_cpu_to_be_32(meter_id);\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_ID],\n+\t       &tmp_meter_id,\n+\t       BNXT_ULP_ACT_PROP_SZ_METER_INST_ID);\n+\tact_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_MTR_VAL_UPDATE] = 1;\n+\tact_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_MTR_VAL] = val;\n+\n+\tret = ulp_matcher_action_match(&pparams, &act_tid);\n+\tif (ret != BNXT_TF_RC_SUCCESS)\n+\t\tgoto parse_error;\n+\n+\tbnxt_ulp_init_mapper_params(&mparms, &pparams,\n+\t\t\t\t    BNXT_ULP_FDB_TYPE_REGULAR);\n+\tmparms.act_tid = act_tid;\n+\n+\t/* Get the function id */\n+\tif (ulp_port_db_port_func_id_get(ulp_ctx,\n+\t\t\t\t\t dev->data->port_id,\n+\t\t\t\t\t &func_id)) {\n+\t\tBNXT_TF_DBG(ERR, \"conversion of port to func id failed\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\t/* Protect flow creation */\n+\tif (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {\n+\t\tBNXT_TF_DBG(ERR, \"Flow db lock acquire failed\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tret = ulp_mapper_flow_create(pparams.ulp_ctx, &mparms);\n+\tbnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);\n+\n+\tif (ret)\n+\t\tgoto parse_error;\n+\n+\tBNXT_TF_DBG(DEBUG, \"Bnxt flow meter %d is %s\\n\",\n+\t\t    meter_id, val ? \"enabled\" : \"disabled\");\n+\n+\treturn 0;\n+parse_error:\n+\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t  NULL,\n+\t\t\t\t  \"Failed to enable/disable meter.\");\n+}\n+\n+/**\n+ * Enable flow meter.\n+ */\n+static int\n+bnxt_flow_meter_enable(struct rte_eth_dev *dev,\n+\t\t       uint32_t meter_id,\n+\t\t       struct rte_mtr_error *error)\n+{\n+\treturn bnxt_flow_meter_enable_set(dev, meter_id, 1, error);\n+}\n+\n+/**\n+ * Disable flow meter.\n+ */\n+static int\n+bnxt_flow_meter_disable(struct rte_eth_dev *dev,\n+\t\t\tuint32_t meter_id,\n+\t\t\tstruct rte_mtr_error *error)\n+{\n+\treturn bnxt_flow_meter_enable_set(dev, meter_id, 0, error);\n+}\n+\n+/**\n+ * Update meter profile.\n+ */\n+static int\n+bnxt_flow_meter_profile_update(struct rte_eth_dev *dev __rte_unused,\n+\t\t\t       uint32_t meter_id __rte_unused,\n+\t\t\t       uint32_t meter_profile_id __rte_unused,\n+\t\t\t       struct rte_mtr_error *error)\n+{\n+\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t  NULL,\n+\t\t\t\t  \"Meter_profile_update not supported\");\n+}\n+\n+/**\n+ * Udate meter stats mask.\n+ */\n+static int\n+bnxt_flow_meter_stats_update(struct rte_eth_dev *dev __rte_unused,\n+\t\t\t     uint32_t meter_id __rte_unused,\n+\t\t\t     uint64_t stats_mask __rte_unused,\n+\t\t\t     struct rte_mtr_error *error)\n+{\n+\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t  NULL,\n+\t\t\t\t  \"Meter_stats_update not supported\");\n+}\n+\n+/**\n+ * Read meter statistics.\n+ */\n+static int\n+bnxt_flow_meter_stats_read(struct rte_eth_dev *dev __rte_unused,\n+\t\t\t   uint32_t meter_id __rte_unused,\n+\t\t\t   struct rte_mtr_stats *stats __rte_unused,\n+\t\t\t   uint64_t *stats_mask __rte_unused,\n+\t\t\t   int clear __rte_unused,\n+\t\t\t   struct rte_mtr_error *error)\n+{\n+\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t  NULL,\n+\t\t\t\t  \"Meter_stats_read not supported yet\");\n+}\n+\n+static const struct rte_mtr_ops bnxt_flow_mtr_ops = {\n+\t.capabilities_get = bnxt_flow_mtr_cap_get,\n+\t.meter_profile_add = bnxt_flow_meter_profile_add,\n+\t.meter_profile_delete = bnxt_flow_meter_profile_delete,\n+\t.meter_policy_validate = NULL,\n+\t.meter_policy_add = NULL,\n+\t.meter_policy_delete = NULL,\n+\t.create = bnxt_flow_meter_create,\n+\t.destroy = bnxt_flow_meter_destroy,\n+\t.meter_enable = bnxt_flow_meter_enable,\n+\t.meter_disable = bnxt_flow_meter_disable,\n+\t.meter_profile_update = bnxt_flow_meter_profile_update,\n+\t.meter_dscp_table_update = NULL,\n+\t.stats_update = bnxt_flow_meter_stats_update,\n+\t.stats_read = bnxt_flow_meter_stats_read,\n+};\n+\n+/**\n+ * Get meter operations.\n+ */\n+int\n+bnxt_flow_meter_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)\n+{\n+\t*(const struct rte_mtr_ops **)arg = &bnxt_flow_mtr_ops;\n+\treturn 0;\n+}\ndiff --git a/drivers/net/bnxt/tf_ulp/meson.build b/drivers/net/bnxt/tf_ulp/meson.build\nindex c7df7e42f1..53a34b4413 100644\n--- a/drivers/net/bnxt/tf_ulp/meson.build\n+++ b/drivers/net/bnxt/tf_ulp/meson.build\n@@ -11,6 +11,7 @@ sources += files(\n         'bnxt_tf_pmd_shim.c',\n         'bnxt_ulp.c',\n         'bnxt_ulp_flow.c',\n+        'bnxt_ulp_meter.c',\n         'ulp_def_rules.c',\n         'ulp_fc_mgr.c',\n         'ulp_flow_db.c',\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c\nindex 1fbfe18db3..af02f857d3 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c\n@@ -66,8 +66,8 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {\n \t.proto_act_func          = ulp_rte_port_act_handler\n \t},\n \t[RTE_FLOW_ACTION_TYPE_METER] = {\n-\t.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,\n-\t.proto_act_func          = NULL\n+\t.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,\n+\t.proto_act_func          = ulp_rte_meter_act_handler\n \t},\n \t[RTE_FLOW_ACTION_TYPE_SECURITY] = {\n \t.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c\nindex d7450b92ff..d64c9e4968 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c\n@@ -2697,6 +2697,35 @@ ulp_rte_queue_act_handler(const struct rte_flow_action *action_item,\n \treturn BNXT_TF_RC_SUCCESS;\n }\n \n+/* Function to handle the parsing of RTE Flow action meter. */\n+int32_t\n+ulp_rte_meter_act_handler(const struct rte_flow_action *action_item,\n+\t\t\t  struct ulp_rte_parser_params *params)\n+{\n+\tconst struct rte_flow_action_meter *meter;\n+\tstruct ulp_rte_act_prop *act_prop = &params->act_prop;\n+\tuint32_t tmp_meter_id;\n+\n+\tif (action_item == NULL || action_item->conf == NULL) {\n+\t\tBNXT_TF_DBG(ERR, \"Parse Err: invalid meter configuration\\n\");\n+\t\treturn BNXT_TF_RC_ERROR;\n+\t}\n+\n+\tmeter = action_item->conf;\n+\tif (meter) {\n+\t\t/* validate the mtr_id and update the reference counter */\n+\t\ttmp_meter_id = tfp_cpu_to_be_32(meter->mtr_id);\n+\t\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER],\n+\t\t       &tmp_meter_id,\n+\t\t       BNXT_ULP_ACT_PROP_SZ_METER);\n+\t}\n+\n+\t/* set the meter action header bit */\n+\tULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACT_BIT_METER);\n+\n+\treturn BNXT_TF_RC_SUCCESS;\n+}\n+\n /* Function to handle the parsing of RTE Flow action set mac src.*/\n int32_t\n ulp_rte_set_mac_src_act_handler(const struct rte_flow_action *action_item,\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h\nindex 401ce4885d..74c7170a45 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h\n+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h\n@@ -292,4 +292,9 @@ ulp_rte_set_mac_src_act_handler(const struct rte_flow_action *action_item,\n int32_t\n ulp_rte_set_mac_dst_act_handler(const struct rte_flow_action *action_item,\n \t\t\t\tstruct ulp_rte_parser_params *params);\n+\n+/* Function to handle the parsing of RTE Flow action meter. */\n+int32_t\n+ulp_rte_meter_act_handler(const struct rte_flow_action *action_item,\n+\t\t\t  struct ulp_rte_parser_params *params);\n #endif /* _ULP_RTE_PARSER_H_ */\n",
    "prefixes": [
        "v4",
        "07/11"
    ]
}