get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 94859,
    "url": "https://patches.dpdk.org/api/patches/94859/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210625093157.24436-5-ting.xu@intel.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20210625093157.24436-5-ting.xu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210625093157.24436-5-ting.xu@intel.com",
    "date": "2021-06-25T09:31:56",
    "name": "[v3,4/5] net/ice: support QoS config VF bandwidth in DCF",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "5ab0f17239bb61c65452352f0431a92ca97082fd",
    "submitter": {
        "id": 1363,
        "url": "https://patches.dpdk.org/api/people/1363/?format=api",
        "name": "Xu, Ting",
        "email": "ting.xu@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "https://patches.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20210625093157.24436-5-ting.xu@intel.com/mbox/",
    "series": [
        {
            "id": 17486,
            "url": "https://patches.dpdk.org/api/series/17486/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=17486",
            "date": "2021-06-25T09:31:52",
            "name": "Enable ETS-based Tx QoS for VF in DCF",
            "version": 3,
            "mbox": "https://patches.dpdk.org/series/17486/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/94859/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/94859/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 78D8CA0547;\n\tFri, 25 Jun 2021 11:33:59 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 0D335410EC;\n\tFri, 25 Jun 2021 11:33:44 +0200 (CEST)",
            "from mga17.intel.com (mga17.intel.com [192.55.52.151])\n by mails.dpdk.org (Postfix) with ESMTP id 5AC9940E09\n for <dev@dpdk.org>; Fri, 25 Jun 2021 11:33:35 +0200 (CEST)",
            "from orsmga001.jf.intel.com ([10.7.209.18])\n by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 25 Jun 2021 02:33:32 -0700",
            "from dpdk-xuting-main.sh.intel.com ([10.67.117.76])\n by orsmga001.jf.intel.com with ESMTP; 25 Jun 2021 02:33:30 -0700"
        ],
        "IronPort-SDR": [
            "\n uz6/7qhGnlhZ12mNeyp9Ui5185ZMVKeyIVL+IPl6Mg/HRKRlSjHT3dIql5Jz4iC4LBRjT9vgwM\n Y+2R+w419E8g==",
            "\n SRSbBGMajG5N6SthVXRqdu9iSBybaiUCnAXVegNv2LuVEyoABLlDAPHGNXVucHhPBHcjcQ+PrL\n Ws+eFUMxpz5g=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6200,9189,10025\"; a=\"188022046\"",
            "E=Sophos;i=\"5.83,298,1616482800\"; d=\"scan'208\";a=\"188022046\"",
            "E=Sophos;i=\"5.83,298,1616482800\"; d=\"scan'208\";a=\"488117912\""
        ],
        "X-ExtLoop1": "1",
        "From": "Ting Xu <ting.xu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "qi.z.zhang@intel.com, jingjing.wu@intel.com, beilei.xing@intel.com,\n qiming.yang@intel.com",
        "Date": "Fri, 25 Jun 2021 17:31:56 +0800",
        "Message-Id": "<20210625093157.24436-5-ting.xu@intel.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20210625093157.24436-1-ting.xu@intel.com>",
        "References": "<20210601014034.36100-1-ting.xu@intel.com>\n <20210625093157.24436-1-ting.xu@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v3 4/5] net/ice: support QoS config VF bandwidth\n in DCF",
        "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": "This patch supports the ETS-based QoS configuration. It enables the DCF\nto configure bandwidth limits for each VF VSI of different TCs. A\nhierarchy scheduler tree is built with port, TC and VSI nodes.\n\nSigned-off-by: Qiming Yang <qiming.yang@intel.com>\nSigned-off-by: Ting Xu <ting.xu@intel.com>\n---\n drivers/net/ice/ice_dcf.c        |   6 +-\n drivers/net/ice/ice_dcf.h        |  47 +++\n drivers/net/ice/ice_dcf_ethdev.c |  13 +\n drivers/net/ice/ice_dcf_ethdev.h |   3 +\n drivers/net/ice/ice_dcf_parent.c |  30 ++\n drivers/net/ice/ice_dcf_sched.c  | 697 +++++++++++++++++++++++++++++++\n drivers/net/ice/meson.build      |   3 +-\n 7 files changed, 797 insertions(+), 2 deletions(-)\n create mode 100644 drivers/net/ice/ice_dcf_sched.c",
    "diff": "diff --git a/drivers/net/ice/ice_dcf.c b/drivers/net/ice/ice_dcf.c\nindex d72a6f357e..4ff2216a5c 100644\n--- a/drivers/net/ice/ice_dcf.c\n+++ b/drivers/net/ice/ice_dcf.c\n@@ -235,7 +235,8 @@ ice_dcf_get_vf_resource(struct ice_dcf_hw *hw)\n \tcaps = VIRTCHNL_VF_OFFLOAD_WB_ON_ITR | VIRTCHNL_VF_OFFLOAD_RX_POLLING |\n \t       VIRTCHNL_VF_CAP_ADV_LINK_SPEED | VIRTCHNL_VF_CAP_DCF |\n \t       VIRTCHNL_VF_OFFLOAD_VLAN_V2 |\n-\t       VF_BASE_MODE_OFFLOADS | VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC;\n+\t       VF_BASE_MODE_OFFLOADS | VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC |\n+\t       VIRTCHNL_VF_OFFLOAD_QOS;\n \n \terr = ice_dcf_send_cmd_req_no_irq(hw, VIRTCHNL_OP_GET_VF_RESOURCES,\n \t\t\t\t\t  (uint8_t *)&caps, sizeof(caps));\n@@ -668,6 +669,9 @@ ice_dcf_init_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)\n \t\t}\n \t}\n \n+\tif (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS)\n+\t\tice_dcf_tm_conf_init(eth_dev);\n+\n \thw->eth_dev = eth_dev;\n \trte_intr_callback_register(&pci_dev->intr_handle,\n \t\t\t\t   ice_dcf_dev_interrupt_handler, hw);\ndiff --git a/drivers/net/ice/ice_dcf.h b/drivers/net/ice/ice_dcf.h\nindex 587093b909..e74e5d7e81 100644\n--- a/drivers/net/ice/ice_dcf.h\n+++ b/drivers/net/ice/ice_dcf.h\n@@ -6,6 +6,7 @@\n #define _ICE_DCF_H_\n \n #include <ethdev_driver.h>\n+#include <rte_tm_driver.h>\n \n #include <iavf_prototype.h>\n #include <iavf_adminq_cmd.h>\n@@ -30,6 +31,49 @@ struct dcf_virtchnl_cmd {\n \tvolatile int pending;\n };\n \n+struct ice_dcf_tm_shaper_profile {\n+\tTAILQ_ENTRY(ice_dcf_tm_shaper_profile) node;\n+\tuint32_t shaper_profile_id;\n+\tuint32_t reference_count;\n+\tstruct rte_tm_shaper_params profile;\n+};\n+\n+TAILQ_HEAD(ice_dcf_shaper_profile_list, ice_dcf_tm_shaper_profile);\n+\n+/* Struct to store Traffic Manager node configuration. */\n+struct ice_dcf_tm_node {\n+\tTAILQ_ENTRY(ice_dcf_tm_node) node;\n+\tuint32_t id;\n+\tuint32_t tc;\n+\tuint32_t priority;\n+\tuint32_t weight;\n+\tuint32_t reference_count;\n+\tstruct ice_dcf_tm_node *parent;\n+\tstruct ice_dcf_tm_shaper_profile *shaper_profile;\n+\tstruct rte_tm_node_params params;\n+};\n+\n+TAILQ_HEAD(ice_dcf_tm_node_list, ice_dcf_tm_node);\n+\n+/* node type of Traffic Manager */\n+enum ice_dcf_tm_node_type {\n+\tICE_DCF_TM_NODE_TYPE_PORT,\n+\tICE_DCF_TM_NODE_TYPE_TC,\n+\tICE_DCF_TM_NODE_TYPE_VSI,\n+\tICE_DCF_TM_NODE_TYPE_MAX,\n+};\n+\n+/* Struct to store all the Traffic Manager configuration. */\n+struct ice_dcf_tm_conf {\n+\tstruct ice_dcf_shaper_profile_list shaper_profile_list;\n+\tstruct ice_dcf_tm_node *root; /* root node - port */\n+\tstruct ice_dcf_tm_node_list tc_list; /* node list for all the TCs */\n+\tstruct ice_dcf_tm_node_list vsi_list; /* node list for all the queues */\n+\tuint32_t nb_tc_node;\n+\tuint32_t nb_vsi_node;\n+\tbool committed;\n+};\n+\n struct ice_dcf_hw {\n \tstruct iavf_hw avf;\n \n@@ -45,6 +89,8 @@ struct ice_dcf_hw {\n \tuint16_t *vf_vsi_map;\n \tuint16_t pf_vsi_id;\n \n+\tstruct ice_dcf_tm_conf tm_conf;\n+\tstruct ice_aqc_port_ets_elem *ets_config;\n \tstruct virtchnl_version_info virtchnl_version;\n \tstruct virtchnl_vf_resource *vf_res; /* VF resource */\n \tstruct virtchnl_vsi_resource *vsi_res; /* LAN VSI */\n@@ -83,5 +129,6 @@ int ice_dcf_query_stats(struct ice_dcf_hw *hw,\n int ice_dcf_add_del_all_mac_addr(struct ice_dcf_hw *hw, bool add);\n int ice_dcf_link_update(struct rte_eth_dev *dev,\n \t\t    __rte_unused int wait_to_complete);\n+void ice_dcf_tm_conf_init(struct rte_eth_dev *dev);\n \n #endif /* _ICE_DCF_H_ */\ndiff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c\nindex 0b40ebbec6..cab7c4da87 100644\n--- a/drivers/net/ice/ice_dcf_ethdev.c\n+++ b/drivers/net/ice/ice_dcf_ethdev.c\n@@ -994,6 +994,18 @@ ice_dcf_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,\n \treturn ret;\n }\n \n+static int\n+ice_dcf_tm_ops_get(struct rte_eth_dev *dev __rte_unused,\n+\t\tvoid *arg)\n+{\n+\tif (!arg)\n+\t\treturn -EINVAL;\n+\n+\t*(const void **)arg = &ice_dcf_tm_ops;\n+\n+\treturn 0;\n+}\n+\n static const struct eth_dev_ops ice_dcf_eth_dev_ops = {\n \t.dev_start               = ice_dcf_dev_start,\n \t.dev_stop                = ice_dcf_dev_stop,\n@@ -1018,6 +1030,7 @@ static const struct eth_dev_ops ice_dcf_eth_dev_ops = {\n \t.flow_ops_get            = ice_dcf_dev_flow_ops_get,\n \t.udp_tunnel_port_add\t = ice_dcf_dev_udp_tunnel_port_add,\n \t.udp_tunnel_port_del\t = ice_dcf_dev_udp_tunnel_port_del,\n+\t.tm_ops_get              = ice_dcf_tm_ops_get,\n };\n \n static int\ndiff --git a/drivers/net/ice/ice_dcf_ethdev.h b/drivers/net/ice/ice_dcf_ethdev.h\nindex e7c9d7fe41..8510e37119 100644\n--- a/drivers/net/ice/ice_dcf_ethdev.h\n+++ b/drivers/net/ice/ice_dcf_ethdev.h\n@@ -7,6 +7,8 @@\n \n #include \"base/ice_common.h\"\n #include \"base/ice_adminq_cmd.h\"\n+#include \"base/ice_dcb.h\"\n+#include \"base/ice_sched.h\"\n \n #include \"ice_ethdev.h\"\n #include \"ice_dcf.h\"\n@@ -52,6 +54,7 @@ struct ice_dcf_vf_repr {\n \tstruct ice_dcf_vlan outer_vlan_info; /* DCF always handle outer VLAN */\n };\n \n+extern const struct rte_tm_ops ice_dcf_tm_ops;\n void ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,\n \t\t\t\t uint8_t *msg, uint16_t msglen);\n int ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev);\ndiff --git a/drivers/net/ice/ice_dcf_parent.c b/drivers/net/ice/ice_dcf_parent.c\nindex 788f6dd2a0..0ea32cf8e9 100644\n--- a/drivers/net/ice/ice_dcf_parent.c\n+++ b/drivers/net/ice/ice_dcf_parent.c\n@@ -264,6 +264,29 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,\n \t}\n }\n \n+static int\n+ice_dcf_query_port_ets(struct ice_hw *parent_hw, struct ice_dcf_hw *real_hw)\n+{\n+\tint ret;\n+\n+\treal_hw->ets_config = (struct ice_aqc_port_ets_elem *)\n+\t\t\tice_malloc(real_hw, sizeof(*real_hw->ets_config));\n+\tif (!real_hw->ets_config)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\n+\tret = ice_aq_query_port_ets(parent_hw->port_info,\n+\t\t\treal_hw->ets_config, sizeof(*real_hw->ets_config),\n+\t\t\tNULL);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"DCF Query Port ETS failed\");\n+\t\trte_free(real_hw->ets_config);\n+\t\treal_hw->ets_config = NULL;\n+\t\treturn ret;\n+\t}\n+\n+\treturn ICE_SUCCESS;\n+}\n+\n static int\n ice_dcf_init_parent_hw(struct ice_hw *hw)\n {\n@@ -486,6 +509,13 @@ ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev)\n \t\treturn err;\n \t}\n \n+\terr = ice_dcf_query_port_ets(parent_hw, hw);\n+\tif (err) {\n+\t\tPMD_INIT_LOG(ERR, \"failed to query port ets with error %d\",\n+\t\t\t     err);\n+\t\tgoto uninit_hw;\n+\t}\n+\n \terr = ice_dcf_load_pkg(parent_hw);\n \tif (err) {\n \t\tPMD_INIT_LOG(ERR, \"failed to load package with error %d\",\ndiff --git a/drivers/net/ice/ice_dcf_sched.c b/drivers/net/ice/ice_dcf_sched.c\nnew file mode 100644\nindex 0000000000..1f75675ba1\n--- /dev/null\n+++ b/drivers/net/ice/ice_dcf_sched.c\n@@ -0,0 +1,697 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2017 Intel Corporation\n+ */\n+#include <rte_tm_driver.h>\n+\n+#include \"base/ice_sched.h\"\n+#include \"ice_dcf_ethdev.h\"\n+\n+static int ice_dcf_hierarchy_commit(struct rte_eth_dev *dev,\n+\t\t\t\t __rte_unused int clear_on_fail,\n+\t\t\t\t __rte_unused struct rte_tm_error *error);\n+static int ice_dcf_node_add(struct rte_eth_dev *dev, uint32_t node_id,\n+\t      uint32_t parent_node_id, uint32_t priority,\n+\t      uint32_t weight, uint32_t level_id,\n+\t      struct rte_tm_node_params *params,\n+\t      struct rte_tm_error *error);\n+static int ice_dcf_node_delete(struct rte_eth_dev *dev, uint32_t node_id,\n+\t\t\t    struct rte_tm_error *error);\n+static int ice_dcf_shaper_profile_add(struct rte_eth_dev *dev,\n+\t\t\tuint32_t shaper_profile_id,\n+\t\t\tstruct rte_tm_shaper_params *profile,\n+\t\t\tstruct rte_tm_error *error);\n+static int ice_dcf_shaper_profile_del(struct rte_eth_dev *dev,\n+\t\t\t\t   uint32_t shaper_profile_id,\n+\t\t\t\t   struct rte_tm_error *error);\n+\n+const struct rte_tm_ops ice_dcf_tm_ops = {\n+\t.shaper_profile_add = ice_dcf_shaper_profile_add,\n+\t.shaper_profile_delete = ice_dcf_shaper_profile_del,\n+\t.hierarchy_commit = ice_dcf_hierarchy_commit,\n+\t.node_add = ice_dcf_node_add,\n+\t.node_delete = ice_dcf_node_delete,\n+};\n+\n+void\n+ice_dcf_tm_conf_init(struct rte_eth_dev *dev)\n+{\n+\tstruct ice_dcf_adapter *adapter = dev->data->dev_private;\n+\tstruct ice_dcf_hw *hw = &adapter->real_hw;\n+\n+\t/* initialize shaper profile list */\n+\tTAILQ_INIT(&hw->tm_conf.shaper_profile_list);\n+\n+\t/* initialize node configuration */\n+\thw->tm_conf.root = NULL;\n+\tTAILQ_INIT(&hw->tm_conf.tc_list);\n+\tTAILQ_INIT(&hw->tm_conf.vsi_list);\n+\thw->tm_conf.nb_tc_node = 0;\n+\thw->tm_conf.nb_vsi_node = 0;\n+\thw->tm_conf.committed = false;\n+}\n+\n+static inline struct ice_dcf_tm_node *\n+dcf_tm_node_search(struct rte_eth_dev *dev,\n+\t\t    uint32_t node_id, enum ice_dcf_tm_node_type *node_type)\n+{\n+\tstruct ice_dcf_adapter *adapter = dev->data->dev_private;\n+\tstruct ice_dcf_hw *hw = &adapter->real_hw;\n+\tstruct ice_dcf_tm_node_list *vsi_list = &hw->tm_conf.vsi_list;\n+\tstruct ice_dcf_tm_node_list *tc_list = &hw->tm_conf.tc_list;\n+\tstruct ice_dcf_tm_node *tm_node;\n+\n+\tif (hw->tm_conf.root && hw->tm_conf.root->id == node_id) {\n+\t\t*node_type = ICE_DCF_TM_NODE_TYPE_PORT;\n+\t\treturn hw->tm_conf.root;\n+\t}\n+\n+\tTAILQ_FOREACH(tm_node, tc_list, node) {\n+\t\tif (tm_node->id == node_id) {\n+\t\t\t*node_type = ICE_DCF_TM_NODE_TYPE_TC;\n+\t\t\treturn tm_node;\n+\t\t}\n+\t}\n+\n+\tTAILQ_FOREACH(tm_node, vsi_list, node) {\n+\t\tif (tm_node->id == node_id) {\n+\t\t\t*node_type = ICE_DCF_TM_NODE_TYPE_VSI;\n+\t\t\treturn tm_node;\n+\t\t}\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+static inline struct ice_dcf_tm_shaper_profile *\n+dcf_shaper_profile_search(struct rte_eth_dev *dev,\n+\t\t\t   uint32_t shaper_profile_id)\n+{\n+\tstruct ice_dcf_adapter *adapter = dev->data->dev_private;\n+\tstruct ice_dcf_hw *hw = &adapter->real_hw;\n+\tstruct ice_dcf_shaper_profile_list *shaper_profile_list =\n+\t\t&hw->tm_conf.shaper_profile_list;\n+\tstruct ice_dcf_tm_shaper_profile *shaper_profile;\n+\n+\tTAILQ_FOREACH(shaper_profile, shaper_profile_list, node) {\n+\t\tif (shaper_profile_id == shaper_profile->shaper_profile_id)\n+\t\t\treturn shaper_profile;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+static int\n+dcf_node_param_check(struct ice_dcf_hw *hw, uint32_t node_id,\n+\t\t      uint32_t priority, uint32_t weight,\n+\t\t      struct rte_tm_node_params *params,\n+\t\t      struct rte_tm_error *error)\n+{\n+\t/* checked all the unsupported parameter */\n+\tif (node_id == RTE_TM_NODE_ID_NULL) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_ID;\n+\t\terror->message = \"invalid node id\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (priority) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_PRIORITY;\n+\t\terror->message = \"priority should be 0\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (weight != 1) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_WEIGHT;\n+\t\terror->message = \"weight must be 1\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* not support shared shaper */\n+\tif (params->shared_shaper_id) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_SHAPER_ID;\n+\t\terror->message = \"shared shaper not supported\";\n+\t\treturn -EINVAL;\n+\t}\n+\tif (params->n_shared_shapers) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_SHAPERS;\n+\t\terror->message = \"shared shaper not supported\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* for non-leaf node */\n+\tif (node_id >= 8 * hw->num_vfs) {\n+\t\tif (params->nonleaf.wfq_weight_mode) {\n+\t\t\terror->type =\n+\t\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_WFQ_WEIGHT_MODE;\n+\t\t\terror->message = \"WFQ not supported\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tif (params->nonleaf.n_sp_priorities != 1) {\n+\t\t\terror->type =\n+\t\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_N_SP_PRIORITIES;\n+\t\t\terror->message = \"SP priority not supported\";\n+\t\t\treturn -EINVAL;\n+\t\t} else if (params->nonleaf.wfq_weight_mode &&\n+\t\t\t   !(*params->nonleaf.wfq_weight_mode)) {\n+\t\t\terror->type =\n+\t\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_WFQ_WEIGHT_MODE;\n+\t\t\terror->message = \"WFP should be byte mode\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\treturn 0;\n+\t}\n+\n+\t/* for leaf node */\n+\tif (params->leaf.cman) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_CMAN;\n+\t\terror->message = \"Congestion management not supported\";\n+\t\treturn -EINVAL;\n+\t}\n+\tif (params->leaf.wred.wred_profile_id !=\n+\t    RTE_TM_WRED_PROFILE_ID_NONE) {\n+\t\terror->type =\n+\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_WRED_PROFILE_ID;\n+\t\terror->message = \"WRED not supported\";\n+\t\treturn -EINVAL;\n+\t}\n+\tif (params->leaf.wred.shared_wred_context_id) {\n+\t\terror->type =\n+\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_WRED_CONTEXT_ID;\n+\t\terror->message = \"WRED not supported\";\n+\t\treturn -EINVAL;\n+\t}\n+\tif (params->leaf.wred.n_shared_wred_contexts) {\n+\t\terror->type =\n+\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_WRED_CONTEXTS;\n+\t\terror->message = \"WRED not supported\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+ice_dcf_node_add(struct rte_eth_dev *dev, uint32_t node_id,\n+\t      uint32_t parent_node_id, uint32_t priority,\n+\t      uint32_t weight, uint32_t level_id,\n+\t      struct rte_tm_node_params *params,\n+\t      struct rte_tm_error *error)\n+{\n+\tenum ice_dcf_tm_node_type parent_node_type = ICE_DCF_TM_NODE_TYPE_MAX;\n+\tenum ice_dcf_tm_node_type node_type = ICE_DCF_TM_NODE_TYPE_MAX;\n+\tstruct ice_dcf_tm_shaper_profile *shaper_profile = NULL;\n+\tstruct ice_dcf_adapter *adapter = dev->data->dev_private;\n+\tstruct ice_dcf_hw *hw = &adapter->real_hw;\n+\tstruct ice_dcf_tm_node *parent_node;\n+\tstruct ice_dcf_tm_node *tm_node;\n+\tuint16_t tc_nb = 1;\n+\tint i, ret;\n+\n+\tif (!params || !error)\n+\t\treturn -EINVAL;\n+\n+\t/* if already committed */\n+\tif (hw->tm_conf.committed) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;\n+\t\terror->message = \"already committed\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = dcf_node_param_check(hw, node_id, priority, weight,\n+\t\t\t\t   params, error);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tfor (i = 1; i < ICE_MAX_TRAFFIC_CLASS; i++) {\n+\t\tif (hw->ets_config->tc_valid_bits & (1 << i))\n+\t\t\ttc_nb++;\n+\t}\n+\n+\t/* check if the node is already existed */\n+\tif (dcf_tm_node_search(dev, node_id, &node_type)) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_ID;\n+\t\terror->message = \"node id already used\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* check the shaper profile id */\n+\tif (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE) {\n+\t\tshaper_profile = dcf_shaper_profile_search(dev,\n+\t\t\tparams->shaper_profile_id);\n+\t\tif (!shaper_profile) {\n+\t\t\terror->type =\n+\t\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_SHAPER_PROFILE_ID;\n+\t\t\terror->message = \"shaper profile not exist\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\t/* add root node if not have a parent */\n+\tif (parent_node_id == RTE_TM_NODE_ID_NULL) {\n+\t\t/* check level */\n+\t\tif (level_id != ICE_DCF_TM_NODE_TYPE_PORT) {\n+\t\t\terror->type = RTE_TM_ERROR_TYPE_NODE_PARAMS;\n+\t\t\terror->message = \"Wrong level\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\t/* obviously no more than one root */\n+\t\tif (hw->tm_conf.root) {\n+\t\t\terror->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID;\n+\t\t\terror->message = \"already have a root\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\t/* add the root node */\n+\t\ttm_node = rte_zmalloc(\"ice_dcf_tm_node\",\n+\t\t\t\t      sizeof(struct ice_dcf_tm_node),\n+\t\t\t\t      0);\n+\t\tif (!tm_node)\n+\t\t\treturn -ENOMEM;\n+\t\ttm_node->id = node_id;\n+\t\ttm_node->parent = NULL;\n+\t\ttm_node->reference_count = 0;\n+\t\trte_memcpy(&tm_node->params, params,\n+\t\t\t\t sizeof(struct rte_tm_node_params));\n+\t\thw->tm_conf.root = tm_node;\n+\n+\t\treturn 0;\n+\t}\n+\n+\t/* TC or vsi node */\n+\t/* check the parent node */\n+\tparent_node = dcf_tm_node_search(dev, parent_node_id,\n+\t\t\t\t\t  &parent_node_type);\n+\tif (!parent_node) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID;\n+\t\terror->message = \"parent not exist\";\n+\t\treturn -EINVAL;\n+\t}\n+\tif (parent_node_type != ICE_DCF_TM_NODE_TYPE_PORT &&\n+\t    parent_node_type != ICE_DCF_TM_NODE_TYPE_TC) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID;\n+\t\terror->message = \"parent is not port or TC\";\n+\t\treturn -EINVAL;\n+\t}\n+\t/* check level */\n+\tif (level_id != RTE_TM_NODE_LEVEL_ID_ANY &&\n+\t    level_id != parent_node_type + 1) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_PARAMS;\n+\t\terror->message = \"Wrong level\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* check the TC node number */\n+\tif (parent_node_type == ICE_DCF_TM_NODE_TYPE_PORT) {\n+\t\t/* check the TC number */\n+\t\tif (hw->tm_conf.nb_tc_node >= tc_nb) {\n+\t\t\terror->type = RTE_TM_ERROR_TYPE_NODE_ID;\n+\t\t\terror->message = \"too many TCs\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t} else {\n+\t\t/* check the vsi node number */\n+\t\tif (parent_node->reference_count >= hw->num_vfs) {\n+\t\t\terror->type = RTE_TM_ERROR_TYPE_NODE_ID;\n+\t\t\terror->message = \"too many VSI for one TC\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\t/* check the vsi node id */\n+\t\tif (node_id > tc_nb * hw->num_vfs) {\n+\t\t\terror->type = RTE_TM_ERROR_TYPE_NODE_ID;\n+\t\t\terror->message = \"too large VSI id\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\t/* add the TC or vsi node */\n+\ttm_node = rte_zmalloc(\"ice_dcf_tm_node\",\n+\t\t\t      sizeof(struct ice_dcf_tm_node),\n+\t\t\t      0);\n+\tif (!tm_node)\n+\t\treturn -ENOMEM;\n+\ttm_node->id = node_id;\n+\ttm_node->priority = priority;\n+\ttm_node->weight = weight;\n+\ttm_node->shaper_profile = shaper_profile;\n+\ttm_node->reference_count = 0;\n+\ttm_node->parent = parent_node;\n+\trte_memcpy(&tm_node->params, params,\n+\t\t\t sizeof(struct rte_tm_node_params));\n+\tif (parent_node_type == ICE_DCF_TM_NODE_TYPE_PORT) {\n+\t\tTAILQ_INSERT_TAIL(&hw->tm_conf.tc_list,\n+\t\t\t\t  tm_node, node);\n+\t\ttm_node->tc = hw->tm_conf.nb_tc_node;\n+\t\thw->tm_conf.nb_tc_node++;\n+\t} else {\n+\t\tTAILQ_INSERT_TAIL(&hw->tm_conf.vsi_list,\n+\t\t\t\t  tm_node, node);\n+\t\ttm_node->tc = parent_node->tc;\n+\t\thw->tm_conf.nb_vsi_node++;\n+\t}\n+\ttm_node->parent->reference_count++;\n+\n+\t/* increase the reference counter of the shaper profile */\n+\tif (shaper_profile)\n+\t\tshaper_profile->reference_count++;\n+\n+\treturn 0;\n+}\n+\n+static int\n+ice_dcf_node_delete(struct rte_eth_dev *dev, uint32_t node_id,\n+\t\t struct rte_tm_error *error)\n+{\n+\tenum ice_dcf_tm_node_type node_type = ICE_DCF_TM_NODE_TYPE_MAX;\n+\tstruct ice_dcf_adapter *adapter = dev->data->dev_private;\n+\tstruct ice_dcf_hw *hw = &adapter->real_hw;\n+\tstruct ice_dcf_tm_node *tm_node;\n+\n+\tif (!error)\n+\t\treturn -EINVAL;\n+\n+\t/* if already committed */\n+\tif (hw->tm_conf.committed) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;\n+\t\terror->message = \"already committed\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (node_id == RTE_TM_NODE_ID_NULL) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_ID;\n+\t\terror->message = \"invalid node id\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* check if the node id exists */\n+\ttm_node = dcf_tm_node_search(dev, node_id, &node_type);\n+\tif (!tm_node) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_ID;\n+\t\terror->message = \"no such node\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* the node should have no child */\n+\tif (tm_node->reference_count) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_ID;\n+\t\terror->message =\n+\t\t\t\"cannot delete a node which has children\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* root node */\n+\tif (node_type == ICE_DCF_TM_NODE_TYPE_PORT) {\n+\t\tif (tm_node->shaper_profile)\n+\t\t\ttm_node->shaper_profile->reference_count--;\n+\t\trte_free(tm_node);\n+\t\thw->tm_conf.root = NULL;\n+\t\treturn 0;\n+\t}\n+\n+\t/* TC or VSI node */\n+\tif (tm_node->shaper_profile)\n+\t\ttm_node->shaper_profile->reference_count--;\n+\ttm_node->parent->reference_count--;\n+\tif (node_type == ICE_DCF_TM_NODE_TYPE_TC) {\n+\t\tTAILQ_REMOVE(&hw->tm_conf.tc_list, tm_node, node);\n+\t\thw->tm_conf.nb_tc_node--;\n+\t} else {\n+\t\tTAILQ_REMOVE(&hw->tm_conf.vsi_list, tm_node, node);\n+\t\thw->tm_conf.nb_vsi_node--;\n+\t}\n+\trte_free(tm_node);\n+\n+\treturn 0;\n+}\n+\n+static int\n+dcf_shaper_profile_param_check(struct rte_tm_shaper_params *profile,\n+\t\t\t\tstruct rte_tm_error *error)\n+{\n+\t/* min bucket size not supported */\n+\tif (profile->committed.size) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_SIZE;\n+\t\terror->message = \"committed bucket size not supported\";\n+\t\treturn -EINVAL;\n+\t}\n+\t/* max bucket size not supported */\n+\tif (profile->peak.size) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE;\n+\t\terror->message = \"peak bucket size not supported\";\n+\t\treturn -EINVAL;\n+\t}\n+\t/* length adjustment not supported */\n+\tif (profile->pkt_length_adjust) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PKT_ADJUST_LEN;\n+\t\terror->message = \"packet length adjustment not supported\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+ice_dcf_shaper_profile_add(struct rte_eth_dev *dev,\n+\t\t\tuint32_t shaper_profile_id,\n+\t\t\tstruct rte_tm_shaper_params *profile,\n+\t\t\tstruct rte_tm_error *error)\n+{\n+\tstruct ice_dcf_adapter *adapter = dev->data->dev_private;\n+\tstruct ice_dcf_hw *hw = &adapter->real_hw;\n+\tstruct ice_dcf_tm_shaper_profile *shaper_profile;\n+\tint ret;\n+\n+\tif (!profile || !error)\n+\t\treturn -EINVAL;\n+\n+\tret = dcf_shaper_profile_param_check(profile, error);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tshaper_profile = dcf_shaper_profile_search(dev, shaper_profile_id);\n+\n+\tif (shaper_profile) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID;\n+\t\terror->message = \"profile ID exist\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tshaper_profile = rte_zmalloc(\"ice_dcf_tm_shaper_profile\",\n+\t\t\t\t     sizeof(struct ice_dcf_tm_shaper_profile),\n+\t\t\t\t     0);\n+\tif (!shaper_profile)\n+\t\treturn -ENOMEM;\n+\tshaper_profile->shaper_profile_id = shaper_profile_id;\n+\trte_memcpy(&shaper_profile->profile, profile,\n+\t\t\t sizeof(struct rte_tm_shaper_params));\n+\tTAILQ_INSERT_TAIL(&hw->tm_conf.shaper_profile_list,\n+\t\t\t  shaper_profile, node);\n+\n+\treturn 0;\n+}\n+\n+static int\n+ice_dcf_shaper_profile_del(struct rte_eth_dev *dev,\n+\t\t\tuint32_t shaper_profile_id,\n+\t\t\tstruct rte_tm_error *error)\n+{\n+\tstruct ice_dcf_adapter *adapter = dev->data->dev_private;\n+\tstruct ice_dcf_hw *hw = &adapter->real_hw;\n+\tstruct ice_dcf_tm_shaper_profile *shaper_profile;\n+\n+\tif (!error)\n+\t\treturn -EINVAL;\n+\n+\tshaper_profile = dcf_shaper_profile_search(dev, shaper_profile_id);\n+\n+\tif (!shaper_profile) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID;\n+\t\terror->message = \"profile ID not exist\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* don't delete a profile if it's used by one or several nodes */\n+\tif (shaper_profile->reference_count) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE;\n+\t\terror->message = \"profile in use\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tTAILQ_REMOVE(&hw->tm_conf.shaper_profile_list, shaper_profile, node);\n+\trte_free(shaper_profile);\n+\n+\treturn 0;\n+}\n+\n+static int\n+ice_dcf_set_vf_bw(struct ice_dcf_hw *hw,\n+\t\t\tstruct virtchnl_dcf_bw_cfg_list *vf_bw,\n+\t\t\tuint16_t len)\n+{\n+\tstruct dcf_virtchnl_cmd args;\n+\tint err;\n+\n+\tmemset(&args, 0, sizeof(args));\n+\targs.v_op = VIRTCHNL_OP_DCF_CONFIG_BW;\n+\targs.req_msg = (uint8_t *)vf_bw;\n+\targs.req_msglen  = len;\n+\terr = ice_dcf_execute_virtchnl_cmd(hw, &args);\n+\tif (err)\n+\t\tPMD_DRV_LOG(ERR, \"fail to execute command %s\",\n+\t\t\t    \"VIRTCHNL_OP_DCF_CONFIG_BW\");\n+\treturn err;\n+}\n+\n+static int\n+ice_dcf_validate_tc_bw(struct virtchnl_dcf_bw_cfg_list *tc_bw,\n+\t\t\tuint32_t port_bw)\n+{\n+\tstruct virtchnl_dcf_bw_cfg *cfg;\n+\tbool lowest_cir_mark = false;\n+\tu32 total_peak, rest_peak;\n+\tu32 committed, peak;\n+\tint i;\n+\n+\ttotal_peak = 0;\n+\tfor (i = 0; i < tc_bw->num_elem; i++)\n+\t\ttotal_peak += tc_bw->cfg[i].shaper.peak;\n+\n+\tfor (i = 0; i < tc_bw->num_elem; i++) {\n+\t\tcfg = &tc_bw->cfg[i];\n+\t\tpeak = cfg->shaper.peak;\n+\t\tcommitted = cfg->shaper.committed;\n+\t\trest_peak = total_peak - peak;\n+\n+\t\tif (lowest_cir_mark && peak == 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Max bandwidth must be configured for TC%u\\n\",\n+\t\t\t\tcfg->tc_num);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (!lowest_cir_mark && committed)\n+\t\t\tlowest_cir_mark = true;\n+\n+\t\tif (committed && committed + rest_peak > port_bw) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Total value of TC%u min bandwidth and other TCs' max bandwidth %ukbps should be less than port link speed %ukbps\\n\",\n+\t\t\t\tcfg->tc_num, committed + rest_peak, port_bw);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (committed && committed < ICE_SCHED_MIN_BW) {\n+\t\t\tPMD_DRV_LOG(ERR, \"If TC%u min Tx bandwidth is set, it cannot be less than 500Kbps\\n\",\n+\t\t\t\tcfg->tc_num);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (peak && committed > peak) {\n+\t\t\tPMD_DRV_LOG(ERR, \"TC%u Min Tx bandwidth cannot be greater than max Tx bandwidth\\n\",\n+\t\t\t\tcfg->tc_num);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (peak > port_bw) {\n+\t\t\tPMD_DRV_LOG(ERR, \"TC%u max Tx bandwidth %uKbps is greater than current link speed %uKbps\\n\",\n+\t\t\t\tcfg->tc_num, peak, port_bw);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+static int ice_dcf_hierarchy_commit(struct rte_eth_dev *dev,\n+\t\t\t\t __rte_unused int clear_on_fail,\n+\t\t\t\t __rte_unused struct rte_tm_error *error)\n+{\n+\tstruct ice_dcf_adapter *adapter = dev->data->dev_private;\n+\tstruct ice_dcf_hw *hw = &adapter->real_hw;\n+\tstruct virtchnl_dcf_bw_cfg_list *vf_bw;\n+\tstruct virtchnl_dcf_bw_cfg_list *tc_bw;\n+\tstruct ice_dcf_tm_node_list *vsi_list = &hw->tm_conf.vsi_list;\n+\tstruct rte_tm_shaper_params *profile;\n+\tstruct ice_dcf_tm_node *tm_node;\n+\tuint32_t port_bw, cir_total;\n+\tuint16_t size, vf_id;\n+\tint num_elem = 0;\n+\tint ret, i;\n+\n+\tsize = sizeof(struct virtchnl_dcf_bw_cfg_list) +\n+\t\tsizeof(struct virtchnl_dcf_bw_cfg) *\n+\t\t(hw->tm_conf.nb_tc_node - 1);\n+\tvf_bw = rte_zmalloc(\"vf_bw\", size, 0);\n+\tif (!vf_bw)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\ttc_bw = rte_zmalloc(\"tc_bw\", size, 0);\n+\tif (!tc_bw)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\n+\t/* port bandwidth (Kbps) */\n+\tport_bw = hw->link_speed * 1000;\n+\tcir_total = 0;\n+\n+\t/* init tc bw configuration */\n+#define ICE_DCF_SCHED_TC_NODE 0xffff\n+\ttc_bw->vf_id = ICE_DCF_SCHED_TC_NODE;\n+\ttc_bw->node_type = VIRTCHNL_DCF_TARGET_TC_BW;\n+\ttc_bw->num_elem = hw->tm_conf.nb_tc_node;\n+\tfor (i = 0; i < tc_bw->num_elem; i++) {\n+\t\ttc_bw->cfg[i].tc_num = i;\n+\t\ttc_bw->cfg[i].type = VIRTCHNL_BW_SHAPER;\n+\t\ttc_bw->cfg[i].bw_type |=\n+\t\t\tVIRTCHNL_DCF_BW_PIR | VIRTCHNL_DCF_BW_CIR;\n+\t}\n+\n+\tfor (vf_id = 0; vf_id < hw->num_vfs; vf_id++) {\n+\t\tnum_elem = 0;\n+\t\tvf_bw->vf_id = vf_id;\n+\t\tvf_bw->node_type = VIRTCHNL_DCF_TARGET_VF_BW;\n+\t\tTAILQ_FOREACH(tm_node, vsi_list, node) {\n+\t\t\t/* scan the nodes belong to one VSI */\n+\t\t\tif (tm_node->id - hw->num_vfs * tm_node->tc != vf_id)\n+\t\t\t\tcontinue;\n+\t\t\tvf_bw->cfg[num_elem].tc_num = tm_node->tc;\n+\t\t\tvf_bw->cfg[num_elem].type = VIRTCHNL_BW_SHAPER;\n+\t\t\tif (tm_node->shaper_profile) {\n+\t\t\t\t/* Transfer from Byte per seconds to Kbps */\n+\t\t\t\tprofile = &tm_node->shaper_profile->profile;\n+\t\t\t\tvf_bw->cfg[num_elem].shaper.peak =\n+\t\t\t\tprofile->peak.rate / 1000 * BITS_PER_BYTE;\n+\t\t\t\tvf_bw->cfg[num_elem].shaper.committed =\n+\t\t\t\tprofile->committed.rate / 1000 * BITS_PER_BYTE;\n+\t\t\t\tvf_bw->cfg[num_elem].bw_type |=\n+\t\t\t\t\tVIRTCHNL_DCF_BW_PIR |\n+\t\t\t\t\tVIRTCHNL_DCF_BW_CIR;\n+\t\t\t}\n+\n+\t\t\t/* update tc node bw configuration */\n+\t\t\ttc_bw->cfg[tm_node->tc].shaper.peak +=\n+\t\t\t\tvf_bw->cfg[num_elem].shaper.peak;\n+\t\t\ttc_bw->cfg[tm_node->tc].shaper.committed +=\n+\t\t\t\tvf_bw->cfg[num_elem].shaper.committed;\n+\n+\t\t\tcir_total += vf_bw->cfg[num_elem].shaper.committed;\n+\t\t\tnum_elem++;\n+\t\t}\n+\n+\t\t/* check if total CIR is larger than port bandwidth */\n+\t\tif (cir_total > port_bw) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Total CIR of all VFs is larger than port bandwidth\");\n+\t\t\treturn ICE_ERR_PARAM;\n+\t\t}\n+\t\tvf_bw->num_elem = num_elem;\n+\t\tret = ice_dcf_set_vf_bw(hw, vf_bw, size);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\tmemset(vf_bw, 0, size);\n+\t}\n+\n+\t/* check and commit tc node bw configuration */\n+\tret = ice_dcf_validate_tc_bw(tc_bw, port_bw);\n+\tif (ret)\n+\t\treturn ret;\n+\tret = ice_dcf_set_vf_bw(hw, tc_bw, size);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\thw->tm_conf.committed = true;\n+\treturn ICE_SUCCESS;\n+}\ndiff --git a/drivers/net/ice/meson.build b/drivers/net/ice/meson.build\nindex 65750d3501..0b86d74a49 100644\n--- a/drivers/net/ice/meson.build\n+++ b/drivers/net/ice/meson.build\n@@ -70,6 +70,7 @@ endif\n sources += files('ice_dcf.c',\n          'ice_dcf_vf_representor.c',\n          'ice_dcf_ethdev.c',\n-         'ice_dcf_parent.c')\n+         'ice_dcf_parent.c',\n+\t 'ice_dcf_sched.c')\n \n headers = files('rte_pmd_ice.h')\n",
    "prefixes": [
        "v3",
        "4/5"
    ]
}