1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2019 Marvell International Ltd.
5 #include <rte_malloc.h>
7 #include "otx2_ethdev.h"
10 /* Use last LVL_CNT nodes as default nodes */
11 #define NIX_DEFAULT_NODE_ID_START (RTE_TM_NODE_ID_NULL - NIX_TXSCH_LVL_CNT)
13 enum otx2_tm_node_level {
24 nix_tm_have_tl1_access(struct otx2_eth_dev *dev)
26 bool is_lbk = otx2_dev_is_lbk(dev);
27 return otx2_dev_is_pf(dev) && !otx2_dev_is_A0(dev) &&
28 !is_lbk && !dev->maxvf;
31 static struct otx2_nix_tm_shaper_profile *
32 nix_tm_shaper_profile_search(struct otx2_eth_dev *dev, uint32_t shaper_id)
34 struct otx2_nix_tm_shaper_profile *tm_shaper_profile;
36 TAILQ_FOREACH(tm_shaper_profile, &dev->shaper_profile_list, shaper) {
37 if (tm_shaper_profile->shaper_profile_id == shaper_id)
38 return tm_shaper_profile;
43 static struct otx2_nix_tm_node *
44 nix_tm_node_search(struct otx2_eth_dev *dev,
45 uint32_t node_id, bool user)
47 struct otx2_nix_tm_node *tm_node;
49 TAILQ_FOREACH(tm_node, &dev->node_list, node) {
50 if (tm_node->id == node_id &&
51 (user == !!(tm_node->flags & NIX_TM_NODE_USER)))
58 nix_tm_node_add_to_list(struct otx2_eth_dev *dev, uint32_t node_id,
59 uint32_t parent_node_id, uint32_t priority,
60 uint32_t weight, uint16_t hw_lvl_id,
61 uint16_t level_id, bool user,
62 struct rte_tm_node_params *params)
64 struct otx2_nix_tm_shaper_profile *shaper_profile;
65 struct otx2_nix_tm_node *tm_node, *parent_node;
66 uint32_t shaper_profile_id;
68 shaper_profile_id = params->shaper_profile_id;
69 shaper_profile = nix_tm_shaper_profile_search(dev, shaper_profile_id);
71 parent_node = nix_tm_node_search(dev, parent_node_id, user);
73 tm_node = rte_zmalloc("otx2_nix_tm_node",
74 sizeof(struct otx2_nix_tm_node), 0);
78 tm_node->level_id = level_id;
79 tm_node->hw_lvl_id = hw_lvl_id;
81 tm_node->id = node_id;
82 tm_node->priority = priority;
83 tm_node->weight = weight;
84 tm_node->rr_prio = 0xf;
85 tm_node->max_prio = UINT32_MAX;
86 tm_node->hw_id = UINT32_MAX;
89 tm_node->flags = NIX_TM_NODE_USER;
90 rte_memcpy(&tm_node->params, params, sizeof(struct rte_tm_node_params));
93 shaper_profile->reference_count++;
94 tm_node->parent = parent_node;
95 tm_node->parent_hw_id = UINT32_MAX;
97 TAILQ_INSERT_TAIL(&dev->node_list, tm_node, node);
103 nix_tm_clear_shaper_profiles(struct otx2_eth_dev *dev)
105 struct otx2_nix_tm_shaper_profile *shaper_profile;
107 while ((shaper_profile = TAILQ_FIRST(&dev->shaper_profile_list))) {
108 if (shaper_profile->reference_count)
109 otx2_tm_dbg("Shaper profile %u has non zero references",
110 shaper_profile->shaper_profile_id);
111 TAILQ_REMOVE(&dev->shaper_profile_list, shaper_profile, shaper);
112 rte_free(shaper_profile);
119 nix_tm_prepare_default_tree(struct rte_eth_dev *eth_dev)
121 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
122 uint32_t def = eth_dev->data->nb_tx_queues;
123 struct rte_tm_node_params params;
124 uint32_t leaf_parent, i;
128 memset(¶ms, 0, sizeof(params));
129 params.shaper_profile_id = RTE_TM_SHAPER_PROFILE_ID_NONE;
131 if (nix_tm_have_tl1_access(dev)) {
132 dev->otx2_tm_root_lvl = NIX_TXSCH_LVL_TL1;
133 rc = nix_tm_node_add_to_list(dev, def, RTE_TM_NODE_ID_NULL, 0,
136 OTX2_TM_LVL_ROOT, false, ¶ms);
139 rc = nix_tm_node_add_to_list(dev, def + 1, def, 0,
142 OTX2_TM_LVL_SCH1, false, ¶ms);
146 rc = nix_tm_node_add_to_list(dev, def + 2, def + 1, 0,
149 OTX2_TM_LVL_SCH2, false, ¶ms);
153 rc = nix_tm_node_add_to_list(dev, def + 3, def + 2, 0,
156 OTX2_TM_LVL_SCH3, false, ¶ms);
160 rc = nix_tm_node_add_to_list(dev, def + 4, def + 3, 0,
163 OTX2_TM_LVL_SCH4, false, ¶ms);
167 leaf_parent = def + 4;
169 dev->otx2_tm_root_lvl = NIX_TXSCH_LVL_TL2;
170 rc = nix_tm_node_add_to_list(dev, def, RTE_TM_NODE_ID_NULL, 0,
173 OTX2_TM_LVL_ROOT, false, ¶ms);
177 rc = nix_tm_node_add_to_list(dev, def + 1, def, 0,
180 OTX2_TM_LVL_SCH1, false, ¶ms);
184 rc = nix_tm_node_add_to_list(dev, def + 2, def + 1, 0,
187 OTX2_TM_LVL_SCH2, false, ¶ms);
191 rc = nix_tm_node_add_to_list(dev, def + 3, def + 2, 0,
194 OTX2_TM_LVL_SCH3, false, ¶ms);
198 leaf_parent = def + 3;
202 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
203 rc = nix_tm_node_add_to_list(dev, i, leaf_parent, 0,
206 OTX2_TM_LVL_QUEUE, false, ¶ms);
215 void otx2_nix_tm_conf_init(struct rte_eth_dev *eth_dev)
217 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
219 TAILQ_INIT(&dev->node_list);
220 TAILQ_INIT(&dev->shaper_profile_list);
223 int otx2_nix_tm_init_default(struct rte_eth_dev *eth_dev)
225 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
226 uint16_t sq_cnt = eth_dev->data->nb_tx_queues;
229 /* Clear shaper profiles */
230 nix_tm_clear_shaper_profiles(dev);
231 dev->tm_flags = NIX_TM_DEFAULT_TREE;
233 rc = nix_tm_prepare_default_tree(eth_dev);
237 dev->tm_leaf_cnt = sq_cnt;
243 otx2_nix_tm_fini(struct rte_eth_dev *eth_dev)
245 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
247 /* Clear shaper profiles */
248 nix_tm_clear_shaper_profiles(dev);