1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2021 Marvell.
9 nix_tm_lvl2nix_tl1_root(uint32_t lvl)
13 return NIX_TXSCH_LVL_TL1;
15 return NIX_TXSCH_LVL_TL2;
17 return NIX_TXSCH_LVL_TL3;
19 return NIX_TXSCH_LVL_TL4;
21 return NIX_TXSCH_LVL_SMQ;
23 return NIX_TXSCH_LVL_CNT;
28 nix_tm_lvl2nix_tl2_root(uint32_t lvl)
32 return NIX_TXSCH_LVL_TL2;
34 return NIX_TXSCH_LVL_TL3;
36 return NIX_TXSCH_LVL_TL4;
38 return NIX_TXSCH_LVL_SMQ;
40 return NIX_TXSCH_LVL_CNT;
45 nix_tm_lvl2nix(struct nix *nix, uint32_t lvl)
47 if (nix_tm_have_tl1_access(nix))
48 return nix_tm_lvl2nix_tl1_root(lvl);
50 return nix_tm_lvl2nix_tl2_root(lvl);
54 struct nix_tm_shaper_profile *
55 nix_tm_shaper_profile_search(struct nix *nix, uint32_t id)
57 struct nix_tm_shaper_profile *profile;
59 TAILQ_FOREACH(profile, &nix->shaper_profile_list, shaper) {
60 if (profile->id == id)
67 nix_tm_node_search(struct nix *nix, uint32_t node_id, enum roc_nix_tm_tree tree)
69 struct nix_tm_node_list *list;
70 struct nix_tm_node *node;
72 list = nix_tm_node_list(nix, tree);
73 TAILQ_FOREACH(node, list, node) {
74 if (node->id == node_id)
81 nix_tm_max_prio(struct nix *nix, uint16_t hw_lvl)
83 if (hw_lvl >= NIX_TXSCH_LVL_CNT)
86 /* MDQ does not support SP */
87 if (hw_lvl == NIX_TXSCH_LVL_MDQ)
90 /* PF's TL1 with VF's enabled does not support SP */
91 if (hw_lvl == NIX_TXSCH_LVL_TL1 && (!nix_tm_have_tl1_access(nix) ||
92 (nix->tm_flags & NIX_TM_TL1_NO_SP)))
95 return NIX_TM_TLX_SP_PRIO_MAX - 1;
99 nix_tm_validate_prio(struct nix *nix, uint32_t lvl, uint32_t parent_id,
100 uint32_t priority, enum roc_nix_tm_tree tree)
102 uint8_t priorities[NIX_TM_TLX_SP_PRIO_MAX];
103 struct nix_tm_node_list *list;
104 struct nix_tm_node *node;
108 list = nix_tm_node_list(nix, tree);
109 /* Validate priority against max */
110 if (priority > nix_tm_max_prio(nix, nix_tm_lvl2nix(nix, lvl - 1)))
111 return NIX_ERR_TM_PRIO_EXCEEDED;
113 if (parent_id == ROC_NIX_TM_NODE_ID_INVALID)
116 memset(priorities, 0, sizeof(priorities));
117 priorities[priority] = 1;
119 TAILQ_FOREACH(node, list, node) {
123 if (node->parent->id != parent_id)
126 priorities[node->priority]++;
129 for (i = 0; i < NIX_TM_TLX_SP_PRIO_MAX; i++)
130 if (priorities[i] > 1)
133 /* At max, one rr groups per parent */
135 return NIX_ERR_TM_MULTIPLE_RR_GROUPS;
137 /* Check for previous priority to avoid holes in priorities */
138 if (priority && !priorities[priority - 1])
139 return NIX_ERR_TM_PRIO_ORDER;
145 nix_tm_sw_xoff_prep(struct nix_tm_node *node, bool enable,
146 volatile uint64_t *reg, volatile uint64_t *regval)
148 uint32_t hw_lvl = node->hw_lvl;
149 uint32_t schq = node->hw_id;
152 plt_tm_dbg("sw xoff config node %s(%u) lvl %u id %u, enable %u (%p)",
153 nix_tm_hwlvl2str(hw_lvl), schq, node->lvl, node->id, enable,
159 case NIX_TXSCH_LVL_MDQ:
160 reg[k] = NIX_AF_MDQX_SW_XOFF(schq);
163 case NIX_TXSCH_LVL_TL4:
164 reg[k] = NIX_AF_TL4X_SW_XOFF(schq);
167 case NIX_TXSCH_LVL_TL3:
168 reg[k] = NIX_AF_TL3X_SW_XOFF(schq);
171 case NIX_TXSCH_LVL_TL2:
172 reg[k] = NIX_AF_TL2X_SW_XOFF(schq);
175 case NIX_TXSCH_LVL_TL1:
176 reg[k] = NIX_AF_TL1X_SW_XOFF(schq);
187 nix_tm_resource_avail(struct nix *nix, uint8_t hw_lvl, bool contig)
189 uint32_t pos = 0, start_pos = 0;
190 struct plt_bitmap *bmp;
194 bmp = contig ? nix->schq_contig_bmp[hw_lvl] : nix->schq_bmp[hw_lvl];
195 plt_bitmap_scan_init(bmp);
197 if (!plt_bitmap_scan(bmp, &pos, &slab))
203 count += __builtin_popcountll(slab);
204 if (!plt_bitmap_scan(bmp, &pos, &slab))
206 } while (pos != start_pos);
212 roc_nix_tm_node_lvl(struct roc_nix *roc_nix, uint32_t node_id)
214 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
215 struct nix_tm_node *node;
217 node = nix_tm_node_search(nix, node_id, ROC_NIX_TM_USER);
219 return NIX_ERR_TM_INVALID_NODE;
224 struct roc_nix_tm_node *
225 roc_nix_tm_node_get(struct roc_nix *roc_nix, uint32_t node_id)
227 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
228 struct nix_tm_node *node;
230 node = nix_tm_node_search(nix, node_id, ROC_NIX_TM_USER);
231 return (struct roc_nix_tm_node *)node;
234 struct roc_nix_tm_node *
235 roc_nix_tm_node_next(struct roc_nix *roc_nix, struct roc_nix_tm_node *__prev)
237 struct nix_tm_node *prev = (struct nix_tm_node *)__prev;
238 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
239 struct nix_tm_node_list *list;
241 list = nix_tm_node_list(nix, ROC_NIX_TM_USER);
243 /* HEAD of the list */
245 return (struct roc_nix_tm_node *)TAILQ_FIRST(list);
248 if (prev->tree != ROC_NIX_TM_USER)
251 return (struct roc_nix_tm_node *)TAILQ_NEXT(prev, node);
255 nix_tm_node_alloc(void)
257 struct nix_tm_node *node;
259 node = plt_zmalloc(sizeof(struct nix_tm_node), 0);
263 node->free_fn = plt_free;
268 nix_tm_node_free(struct nix_tm_node *node)
270 if (!node || node->free_fn == NULL)
273 (node->free_fn)(node);