Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2020-2023 NXP
3 : : */
4 : :
5 : : #include <rte_ethdev.h>
6 : : #include <rte_malloc.h>
7 : : #include <rte_tm_driver.h>
8 : :
9 : : #include "dpaa2_ethdev.h"
10 : : #include "dpaa2_pmd_logs.h"
11 : : #include <dpaa2_hw_dpio.h>
12 : :
13 : : #define DPAA2_BURST_MAX (64 * 1024)
14 : :
15 : : #define DPAA2_SHAPER_MIN_RATE 0
16 : : #define DPAA2_SHAPER_MAX_RATE 107374182400ull
17 : : #define DPAA2_WEIGHT_MAX 24701
18 : : #define DPAA2_PKT_ADJUST_LEN_MIN 0
19 : : #define DPAA2_PKT_ADJUST_LEN_MAX 0x7ff
20 : :
21 : : int
22 : 0 : dpaa2_tm_init(struct rte_eth_dev *dev)
23 : : {
24 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
25 : :
26 : 0 : LIST_INIT(&priv->shaper_profiles);
27 : 0 : LIST_INIT(&priv->nodes);
28 : :
29 : 0 : return 0;
30 : : }
31 : :
32 : 0 : void dpaa2_tm_deinit(struct rte_eth_dev *dev)
33 : : {
34 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
35 : 0 : struct dpaa2_tm_shaper_profile *profile =
36 : : LIST_FIRST(&priv->shaper_profiles);
37 : 0 : struct dpaa2_tm_node *node = LIST_FIRST(&priv->nodes);
38 : :
39 [ # # ]: 0 : while (profile) {
40 : 0 : struct dpaa2_tm_shaper_profile *next = LIST_NEXT(profile, next);
41 : :
42 [ # # ]: 0 : LIST_REMOVE(profile, next);
43 : 0 : rte_free(profile);
44 : : profile = next;
45 : : }
46 : :
47 [ # # ]: 0 : while (node) {
48 : 0 : struct dpaa2_tm_node *next = LIST_NEXT(node, next);
49 : :
50 [ # # ]: 0 : LIST_REMOVE(node, next);
51 : 0 : rte_free(node);
52 : : node = next;
53 : : }
54 : 0 : }
55 : :
56 : : static struct dpaa2_tm_node *
57 : : dpaa2_node_from_id(struct dpaa2_dev_priv *priv, uint32_t node_id)
58 : : {
59 : : struct dpaa2_tm_node *node;
60 : :
61 [ # # # # : 0 : LIST_FOREACH(node, &priv->nodes, next)
# # # # #
# # # ]
62 [ # # # # : 0 : if (node->id == node_id)
# # # # #
# # # ]
63 : : return node;
64 : :
65 : : return NULL;
66 : : }
67 : :
68 : : static int
69 : 0 : dpaa2_capabilities_get(struct rte_eth_dev *dev,
70 : : struct rte_tm_capabilities *cap,
71 : : struct rte_tm_error *error)
72 : : {
73 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
74 : :
75 [ # # ]: 0 : if (!cap)
76 : 0 : return -rte_tm_error_set(error, EINVAL,
77 : : RTE_TM_ERROR_TYPE_UNSPECIFIED,
78 : : NULL, "Capabilities are NULL\n");
79 : :
80 : : memset(cap, 0, sizeof(*cap));
81 : :
82 : : /* root node(port) + channels + txqs number, assuming each TX
83 : : * Queue is mapped to each TC
84 : : */
85 : 0 : cap->n_nodes_max = 1 + priv->num_channels + dev->data->nb_tx_queues;
86 : 0 : cap->n_levels_max = MAX_LEVEL;
87 : 0 : cap->non_leaf_nodes_identical = 1;
88 : 0 : cap->leaf_nodes_identical = 1;
89 : :
90 : 0 : cap->shaper_n_max = 1 + priv->num_channels; /* LNI + channels */
91 : 0 : cap->shaper_private_n_max = 1 + priv->num_channels;
92 : 0 : cap->shaper_private_dual_rate_n_max = 1 + priv->num_channels;
93 : : cap->shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE;
94 : 0 : cap->shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE;
95 : : cap->shaper_pkt_length_adjust_min = DPAA2_PKT_ADJUST_LEN_MIN;
96 : 0 : cap->shaper_pkt_length_adjust_max = DPAA2_PKT_ADJUST_LEN_MAX;
97 : :
98 [ # # ]: 0 : if (priv->num_channels > DPNI_MAX_TC)
99 : 0 : cap->sched_n_children_max = priv->num_channels;
100 : : else
101 : 0 : cap->sched_n_children_max = DPNI_MAX_TC;
102 : :
103 : 0 : cap->sched_sp_n_priorities_max = DPNI_MAX_TC;
104 : 0 : cap->sched_wfq_n_children_per_group_max = DPNI_MAX_TC;
105 : 0 : cap->sched_wfq_n_groups_max = 2;
106 : 0 : cap->sched_wfq_weight_max = DPAA2_WEIGHT_MAX / 100;
107 : 0 : cap->stats_mask = RTE_TM_STATS_N_PKTS | RTE_TM_STATS_N_BYTES;
108 : :
109 : 0 : return 0;
110 : : }
111 : :
112 : : static int
113 : 0 : dpaa2_level_capabilities_get(struct rte_eth_dev *dev,
114 : : uint32_t level_id,
115 : : struct rte_tm_level_capabilities *cap,
116 : : struct rte_tm_error *error)
117 : : {
118 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
119 : :
120 [ # # ]: 0 : if (!cap)
121 : 0 : return -rte_tm_error_set(error, EINVAL,
122 : : RTE_TM_ERROR_TYPE_UNSPECIFIED,
123 : : NULL, NULL);
124 : :
125 : : memset(cap, 0, sizeof(*cap));
126 : :
127 [ # # ]: 0 : if (level_id > QUEUE_LEVEL)
128 : 0 : return -rte_tm_error_set(error, EINVAL,
129 : : RTE_TM_ERROR_TYPE_LEVEL_ID,
130 : : NULL, "Wrong level id\n");
131 : :
132 [ # # ]: 0 : if (level_id == LNI_LEVEL) { /* Root node (LNI) */
133 : 0 : cap->n_nodes_max = 1;
134 : 0 : cap->n_nodes_nonleaf_max = 1;
135 : 0 : cap->non_leaf_nodes_identical = 1;
136 : :
137 : 0 : cap->nonleaf.shaper_private_supported = 1;
138 : 0 : cap->nonleaf.shaper_private_dual_rate_supported = 1;
139 : : cap->nonleaf.shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE;
140 : 0 : cap->nonleaf.shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE;
141 : :
142 : 0 : cap->nonleaf.sched_n_children_max = priv->num_channels; /* no. of channels */
143 : 0 : cap->nonleaf.sched_sp_n_priorities_max = 1;
144 : 0 : cap->nonleaf.sched_wfq_n_children_per_group_max = 1;
145 : 0 : cap->nonleaf.sched_wfq_n_groups_max = 1;
146 : 0 : cap->nonleaf.sched_wfq_weight_max = 1;
147 : 0 : cap->nonleaf.stats_mask = RTE_TM_STATS_N_PKTS |
148 : : RTE_TM_STATS_N_BYTES;
149 [ # # ]: 0 : } else if (level_id == CHANNEL_LEVEL) { /* channels */
150 : 0 : cap->n_nodes_max = priv->num_channels;
151 : 0 : cap->n_nodes_nonleaf_max = priv->num_channels;
152 : : cap->n_nodes_leaf_max = 0;
153 : 0 : cap->non_leaf_nodes_identical = 1;
154 : :
155 : 0 : cap->nonleaf.shaper_private_supported = 1;
156 : 0 : cap->nonleaf.shaper_private_dual_rate_supported = 1;
157 : : cap->nonleaf.shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE;
158 : 0 : cap->nonleaf.shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE;
159 : :
160 : : /* no. of class queues per channel */
161 : 0 : cap->nonleaf.sched_n_children_max = priv->num_tx_tc;
162 : 0 : cap->nonleaf.sched_sp_n_priorities_max = priv->num_tx_tc;
163 : 0 : cap->nonleaf.sched_wfq_n_children_per_group_max = priv->num_tx_tc;
164 : 0 : cap->nonleaf.sched_wfq_n_groups_max = 2;
165 : 0 : cap->nonleaf.sched_wfq_weight_max = DPAA2_WEIGHT_MAX / 100;
166 : : } else { /* leaf nodes */
167 : : /* queues per channels * channel */
168 : 0 : cap->n_nodes_max = priv->num_tx_tc * priv->num_channels;
169 : 0 : cap->n_nodes_leaf_max = priv->num_tx_tc * priv->num_channels;
170 : 0 : cap->leaf_nodes_identical = 1;
171 : :
172 : : cap->leaf.shaper_private_supported = 0;
173 : 0 : cap->leaf.stats_mask = RTE_TM_STATS_N_PKTS |
174 : : RTE_TM_STATS_N_BYTES;
175 : : }
176 : :
177 : : return 0;
178 : : }
179 : :
180 : : static int
181 : 0 : dpaa2_node_capabilities_get(struct rte_eth_dev *dev, uint32_t node_id,
182 : : struct rte_tm_node_capabilities *cap,
183 : : struct rte_tm_error *error)
184 : : {
185 : : struct dpaa2_tm_node *node;
186 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
187 : :
188 [ # # ]: 0 : if (!cap)
189 : 0 : return -rte_tm_error_set(error, EINVAL,
190 : : RTE_TM_ERROR_TYPE_UNSPECIFIED,
191 : : NULL, NULL);
192 : :
193 : : memset(cap, 0, sizeof(*cap));
194 : :
195 : : node = dpaa2_node_from_id(priv, node_id);
196 [ # # ]: 0 : if (!node)
197 : 0 : return -rte_tm_error_set(error, ENODEV,
198 : : RTE_TM_ERROR_TYPE_NODE_ID,
199 : : NULL, "Node id does not exist\n");
200 : :
201 [ # # ]: 0 : if (node->level_id == LNI_LEVEL) {
202 : 0 : cap->shaper_private_supported = 1;
203 : 0 : cap->shaper_private_dual_rate_supported = 1;
204 : : cap->shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE;
205 : 0 : cap->shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE;
206 : :
207 : 0 : cap->nonleaf.sched_n_children_max = priv->num_channels;
208 : 0 : cap->nonleaf.sched_sp_n_priorities_max = 1;
209 : 0 : cap->nonleaf.sched_wfq_n_children_per_group_max = 1;
210 : 0 : cap->nonleaf.sched_wfq_n_groups_max = 1;
211 : 0 : cap->nonleaf.sched_wfq_weight_max = 1;
212 : 0 : cap->stats_mask = RTE_TM_STATS_N_PKTS |
213 : : RTE_TM_STATS_N_BYTES;
214 [ # # ]: 0 : } else if (node->level_id == CHANNEL_LEVEL) {
215 : 0 : cap->shaper_private_supported = 1;
216 : 0 : cap->shaper_private_dual_rate_supported = 1;
217 : : cap->shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE;
218 : 0 : cap->shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE;
219 : :
220 : 0 : cap->nonleaf.sched_n_children_max = priv->num_tx_tc;
221 : 0 : cap->nonleaf.sched_sp_n_priorities_max = priv->num_tx_tc;
222 : 0 : cap->nonleaf.sched_wfq_n_children_per_group_max = priv->num_tx_tc;
223 : 0 : cap->nonleaf.sched_wfq_n_groups_max = 2;
224 : 0 : cap->nonleaf.sched_wfq_weight_max = DPAA2_WEIGHT_MAX / 100;
225 : : } else {
226 : 0 : cap->stats_mask = RTE_TM_STATS_N_PKTS |
227 : : RTE_TM_STATS_N_BYTES;
228 : : }
229 : :
230 : : return 0;
231 : : }
232 : :
233 : : static int
234 : 0 : dpaa2_node_type_get(struct rte_eth_dev *dev, uint32_t node_id, int *is_leaf,
235 : : struct rte_tm_error *error)
236 : : {
237 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
238 : : struct dpaa2_tm_node *node;
239 : :
240 [ # # ]: 0 : if (!is_leaf)
241 : 0 : return -rte_tm_error_set(error, EINVAL,
242 : : RTE_TM_ERROR_TYPE_UNSPECIFIED,
243 : : NULL, NULL);
244 : :
245 : : node = dpaa2_node_from_id(priv, node_id);
246 [ # # ]: 0 : if (!node)
247 : 0 : return -rte_tm_error_set(error, ENODEV,
248 : : RTE_TM_ERROR_TYPE_NODE_ID,
249 : : NULL, "Node id does not exist\n");
250 : :
251 : 0 : *is_leaf = node->type == LEAF_NODE ? 1 : 0;
252 : :
253 : 0 : return 0;
254 : : }
255 : :
256 : : static struct dpaa2_tm_shaper_profile *
257 : : dpaa2_shaper_profile_from_id(struct dpaa2_dev_priv *priv,
258 : : uint32_t shaper_profile_id)
259 : : {
260 : : struct dpaa2_tm_shaper_profile *profile;
261 : :
262 [ # # # # : 0 : LIST_FOREACH(profile, &priv->shaper_profiles, next)
# # ]
263 [ # # # # : 0 : if (profile->id == shaper_profile_id)
# # ]
264 : : return profile;
265 : :
266 : : return NULL;
267 : : }
268 : :
269 : : static int
270 : 0 : dpaa2_shaper_profile_add(struct rte_eth_dev *dev, uint32_t shaper_profile_id,
271 : : const struct rte_tm_shaper_params *params,
272 : : struct rte_tm_error *error)
273 : : {
274 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
275 : : struct dpaa2_tm_shaper_profile *profile;
276 : :
277 [ # # ]: 0 : if (!params)
278 : 0 : return -rte_tm_error_set(error, EINVAL,
279 : : RTE_TM_ERROR_TYPE_UNSPECIFIED,
280 : : NULL, NULL);
281 [ # # ]: 0 : if (params->committed.rate > DPAA2_SHAPER_MAX_RATE)
282 : 0 : return -rte_tm_error_set(error, EINVAL,
283 : : RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE,
284 : : NULL, "committed rate is out of range\n");
285 : :
286 [ # # ]: 0 : if (params->committed.size > DPAA2_BURST_MAX)
287 : 0 : return -rte_tm_error_set(error, EINVAL,
288 : : RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE,
289 : : NULL, "committed size is out of range\n");
290 : :
291 [ # # ]: 0 : if (params->peak.rate > DPAA2_SHAPER_MAX_RATE)
292 : 0 : return -rte_tm_error_set(error, EINVAL,
293 : : RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE,
294 : : NULL, "Peak rate is out of range\n");
295 : :
296 [ # # ]: 0 : if (params->peak.size > DPAA2_BURST_MAX)
297 : 0 : return -rte_tm_error_set(error, EINVAL,
298 : : RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE,
299 : : NULL, "Peak size is out of range\n");
300 : :
301 [ # # ]: 0 : if (shaper_profile_id == RTE_TM_SHAPER_PROFILE_ID_NONE)
302 : 0 : return -rte_tm_error_set(error, EINVAL,
303 : : RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
304 : : NULL, "Wrong shaper profile id\n");
305 : :
306 [ # # ]: 0 : if (params->pkt_length_adjust > DPAA2_PKT_ADJUST_LEN_MAX ||
307 : : params->pkt_length_adjust < DPAA2_PKT_ADJUST_LEN_MIN)
308 : 0 : return -rte_tm_error_set(error, EINVAL,
309 : : RTE_TM_ERROR_TYPE_CAPABILITIES,
310 : : NULL,
311 : : "Not supported pkt adjust length\n");
312 : :
313 : : profile = dpaa2_shaper_profile_from_id(priv, shaper_profile_id);
314 [ # # ]: 0 : if (profile)
315 : 0 : return -rte_tm_error_set(error, EEXIST,
316 : : RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
317 : : NULL, "Profile id already exists\n");
318 : :
319 : 0 : profile = rte_zmalloc_socket(NULL, sizeof(*profile), 0,
320 : 0 : rte_socket_id());
321 [ # # ]: 0 : if (!profile)
322 : 0 : return -rte_tm_error_set(error, ENOMEM,
323 : : RTE_TM_ERROR_TYPE_UNSPECIFIED,
324 : : NULL, NULL);
325 : :
326 : 0 : profile->id = shaper_profile_id;
327 [ # # ]: 0 : rte_memcpy(&profile->params, params, sizeof(profile->params));
328 : :
329 [ # # ]: 0 : LIST_INSERT_HEAD(&priv->shaper_profiles, profile, next);
330 : :
331 : 0 : return 0;
332 : : }
333 : :
334 : : static int
335 : 0 : dpaa2_shaper_profile_delete(struct rte_eth_dev *dev, uint32_t shaper_profile_id,
336 : : struct rte_tm_error *error)
337 : : {
338 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
339 : : struct dpaa2_tm_shaper_profile *profile;
340 : :
341 : : profile = dpaa2_shaper_profile_from_id(priv, shaper_profile_id);
342 [ # # ]: 0 : if (!profile)
343 : 0 : return -rte_tm_error_set(error, ENODEV,
344 : : RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
345 : : NULL, "Profile id does not exist\n");
346 : :
347 [ # # ]: 0 : if (profile->refcnt)
348 : 0 : return -rte_tm_error_set(error, EPERM,
349 : : RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
350 : : NULL, "Profile is used\n");
351 : :
352 [ # # ]: 0 : LIST_REMOVE(profile, next);
353 : 0 : rte_free(profile);
354 : :
355 : 0 : return 0;
356 : : }
357 : :
358 : : static int
359 : 0 : dpaa2_node_check_params(struct rte_eth_dev *dev, uint32_t node_id,
360 : : __rte_unused uint32_t priority, uint32_t weight,
361 : : uint32_t level_id,
362 : : const struct rte_tm_node_params *params,
363 : : struct rte_tm_error *error)
364 : : {
365 [ # # ]: 0 : if (node_id == RTE_TM_NODE_ID_NULL)
366 : 0 : return -rte_tm_error_set(error, EINVAL, RTE_TM_NODE_ID_NULL,
367 : : NULL, "Node id is invalid\n");
368 : :
369 [ # # ]: 0 : if (weight > DPAA2_WEIGHT_MAX)
370 : 0 : return -rte_tm_error_set(error, EINVAL,
371 : : RTE_TM_ERROR_TYPE_NODE_WEIGHT,
372 : : NULL, "Weight is out of range\n");
373 : :
374 [ # # ]: 0 : if (level_id > QUEUE_LEVEL)
375 : 0 : return -rte_tm_error_set(error, EINVAL,
376 : : RTE_TM_ERROR_TYPE_LEVEL_ID,
377 : : NULL, "Wrong level id\n");
378 : :
379 [ # # ]: 0 : if (!params)
380 : 0 : return -rte_tm_error_set(error, EINVAL,
381 : : RTE_TM_ERROR_TYPE_UNSPECIFIED,
382 : : NULL, NULL);
383 : :
384 [ # # ]: 0 : if (params->shared_shaper_id)
385 : 0 : return -rte_tm_error_set(error, EINVAL,
386 : : RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_SHAPER_ID,
387 : : NULL, "Shared shaper is not supported\n");
388 : :
389 [ # # ]: 0 : if (params->n_shared_shapers)
390 : 0 : return -rte_tm_error_set(error, EINVAL,
391 : : RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_SHAPERS,
392 : : NULL, "Shared shaper is not supported\n");
393 : :
394 : : /* verify non leaf nodes settings */
395 [ # # ]: 0 : if (node_id >= dev->data->nb_tx_queues) {
396 [ # # ]: 0 : if (params->nonleaf.wfq_weight_mode)
397 : 0 : return -rte_tm_error_set(error, EINVAL,
398 : : RTE_TM_ERROR_TYPE_NODE_PARAMS_WFQ_WEIGHT_MODE,
399 : : NULL, "WFQ weight mode is not supported\n");
400 : : } else {
401 [ # # ]: 0 : if (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE)
402 : 0 : return -rte_tm_error_set(error, EINVAL,
403 : : RTE_TM_ERROR_TYPE_NODE_PARAMS_SHAPER_PROFILE_ID,
404 : : NULL, "Private shaper not supported on leaf\n");
405 : : }
406 : :
407 : : /* check leaf node */
408 [ # # ]: 0 : if (level_id == QUEUE_LEVEL) {
409 [ # # ]: 0 : if (params->leaf.cman != RTE_TM_CMAN_TAIL_DROP)
410 : 0 : return -rte_tm_error_set(error, ENODEV,
411 : : RTE_TM_ERROR_TYPE_NODE_PARAMS_CMAN,
412 : : NULL, "Only taildrop is supported\n");
413 [ # # ]: 0 : if (params->stats_mask & ~(RTE_TM_STATS_N_PKTS |
414 : : RTE_TM_STATS_N_BYTES))
415 : 0 : return -rte_tm_error_set(error, EINVAL,
416 : : RTE_TM_ERROR_TYPE_NODE_PARAMS_STATS,
417 : : NULL,
418 : : "Requested port stats are not supported\n");
419 [ # # ]: 0 : } else if (level_id == LNI_LEVEL) {
420 [ # # ]: 0 : if (params->stats_mask & ~(RTE_TM_STATS_N_PKTS |
421 : : RTE_TM_STATS_N_BYTES))
422 : 0 : return -rte_tm_error_set(error, EINVAL,
423 : : RTE_TM_ERROR_TYPE_NODE_PARAMS_STATS,
424 : : NULL,
425 : : "Requested port stats are not supported\n");
426 : : }
427 : :
428 : : return 0;
429 : : }
430 : :
431 : : static int
432 : 0 : dpaa2_node_add(struct rte_eth_dev *dev, uint32_t node_id,
433 : : uint32_t parent_node_id, uint32_t priority, uint32_t weight,
434 : : uint32_t level_id, const struct rte_tm_node_params *params,
435 : : struct rte_tm_error *error)
436 : : {
437 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
438 : : struct dpaa2_tm_shaper_profile *profile = NULL;
439 : : struct dpaa2_tm_node *node, *parent = NULL;
440 : : int ret;
441 : :
442 : : if (0/* If device is started*/)
443 : : return -rte_tm_error_set(error, EPERM,
444 : : RTE_TM_ERROR_TYPE_UNSPECIFIED,
445 : : NULL, "Port is already started\n");
446 : :
447 : 0 : ret = dpaa2_node_check_params(dev, node_id, priority, weight, level_id,
448 : : params, error);
449 [ # # ]: 0 : if (ret)
450 : : return ret;
451 : :
452 [ # # ]: 0 : if (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE) {
453 : : profile = dpaa2_shaper_profile_from_id(priv,
454 : : params->shaper_profile_id);
455 [ # # ]: 0 : if (!profile)
456 : 0 : return -rte_tm_error_set(error, ENODEV,
457 : : RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
458 : : NULL, "Shaper id does not exist\n");
459 : : }
460 [ # # ]: 0 : if (parent_node_id == RTE_TM_NODE_ID_NULL) {
461 [ # # ]: 0 : LIST_FOREACH(node, &priv->nodes, next) {
462 [ # # ]: 0 : if (node->level_id != LNI_LEVEL)
463 : : continue;
464 : :
465 : 0 : return -rte_tm_error_set(error, EINVAL,
466 : : RTE_TM_ERROR_TYPE_UNSPECIFIED,
467 : : NULL, "Root node exists\n");
468 : : }
469 : : } else {
470 : : parent = dpaa2_node_from_id(priv, parent_node_id);
471 [ # # ]: 0 : if (!parent)
472 : 0 : return -rte_tm_error_set(error, EINVAL,
473 : : RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID,
474 : : NULL, "Parent node id not exist\n");
475 : : }
476 : :
477 : : node = dpaa2_node_from_id(priv, node_id);
478 [ # # ]: 0 : if (node)
479 : 0 : return -rte_tm_error_set(error, ENODEV,
480 : : RTE_TM_ERROR_TYPE_NODE_ID,
481 : : NULL, "Node id already exists\n");
482 : :
483 : 0 : node = rte_zmalloc_socket(NULL, sizeof(*node), 0, rte_socket_id());
484 [ # # ]: 0 : if (!node)
485 : 0 : return -rte_tm_error_set(error, ENOMEM,
486 : : RTE_TM_ERROR_TYPE_UNSPECIFIED,
487 : : NULL, NULL);
488 : :
489 : 0 : node->id = node_id;
490 : :
491 [ # # ]: 0 : if (node_id > dev->data->nb_tx_queues)
492 : 0 : node->type = NON_LEAF_NODE;
493 : : else
494 : 0 : node->type = LEAF_NODE;
495 : :
496 : 0 : node->level_id = level_id;
497 [ # # ]: 0 : if (node->level_id == CHANNEL_LEVEL) {
498 [ # # ]: 0 : if (priv->channel_inuse < priv->num_channels) {
499 : 0 : node->channel_id = priv->channel_inuse;
500 : 0 : priv->channel_inuse++;
501 : : } else {
502 : 0 : DPAA2_PMD_ERR("error no channel id available");
503 : : }
504 : : }
505 : :
506 [ # # ]: 0 : if (parent) {
507 : 0 : node->parent = parent;
508 : 0 : parent->refcnt++;
509 : : }
510 : :
511 : : /* TODO: add check if refcnt is more than supported children */
512 : :
513 [ # # ]: 0 : if (profile) {
514 : 0 : node->profile = profile;
515 : 0 : profile->refcnt++;
516 : : }
517 : :
518 : 0 : node->weight = weight;
519 : 0 : node->priority = priority;
520 : 0 : node->stats_mask = params->stats_mask;
521 : :
522 [ # # ]: 0 : LIST_INSERT_HEAD(&priv->nodes, node, next);
523 : :
524 : 0 : return 0;
525 : : }
526 : :
527 : : static int
528 : 0 : dpaa2_node_delete(struct rte_eth_dev *dev, uint32_t node_id,
529 : : struct rte_tm_error *error)
530 : : {
531 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
532 : : struct dpaa2_tm_node *node;
533 : :
534 : : /* XXX: update it */
535 : : if (0) {
536 : : return -rte_tm_error_set(error, EPERM,
537 : : RTE_TM_ERROR_TYPE_UNSPECIFIED,
538 : : NULL, "Port is already started\n");
539 : : }
540 : :
541 : : node = dpaa2_node_from_id(priv, node_id);
542 [ # # ]: 0 : if (!node)
543 : 0 : return -rte_tm_error_set(error, ENODEV,
544 : : RTE_TM_ERROR_TYPE_NODE_ID,
545 : : NULL, "Node id does not exist\n");
546 : :
547 [ # # ]: 0 : if (node->refcnt)
548 : 0 : return -rte_tm_error_set(error, EPERM,
549 : : RTE_TM_ERROR_TYPE_NODE_ID,
550 : : NULL, "Node id is used\n");
551 : :
552 [ # # ]: 0 : if (node->parent)
553 : 0 : node->parent->refcnt--;
554 : :
555 [ # # ]: 0 : if (node->profile)
556 : 0 : node->profile->refcnt--;
557 : :
558 [ # # ]: 0 : LIST_REMOVE(node, next);
559 : 0 : rte_free(node);
560 : :
561 : 0 : return 0;
562 : : }
563 : :
564 : : static int
565 : 0 : dpaa2_tm_configure_queue(struct rte_eth_dev *dev, struct dpaa2_tm_node *node)
566 : : {
567 : : int ret = 0;
568 : : uint32_t tc_id;
569 : : uint8_t flow_id, options = 0;
570 : : struct dpni_queue tx_flow_cfg;
571 : : struct dpni_queue_id qid;
572 : 0 : struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
573 [ # # ]: 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
574 : : struct dpaa2_queue *dpaa2_q;
575 : : uint64_t iova;
576 : :
577 : : memset(&tx_flow_cfg, 0, sizeof(struct dpni_queue));
578 : 0 : dpaa2_q = (struct dpaa2_queue *)dev->data->tx_queues[node->id];
579 : 0 : tc_id = node->parent->tc_id;
580 : 0 : node->parent->tc_id++;
581 : : flow_id = 0;
582 : :
583 [ # # ]: 0 : if (!dpaa2_q) {
584 : 0 : DPAA2_PMD_ERR("Queue is not configured for node = %d",
585 : : node->id);
586 : 0 : return -ENOMEM;
587 : : }
588 : :
589 : 0 : DPAA2_PMD_DEBUG("tc_id = %d, channel = %d", tc_id,
590 : : node->parent->channel_id);
591 : 0 : ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX,
592 : 0 : ((node->parent->channel_id << 8) | tc_id),
593 : : flow_id, options, &tx_flow_cfg);
594 [ # # ]: 0 : if (ret) {
595 : 0 : DPAA2_PMD_ERR("Set the TC[%d].ch[%d].TX flow[%d] (err=%d)",
596 : : tc_id, node->parent->channel_id, flow_id,
597 : : ret);
598 : 0 : return ret;
599 : : }
600 : :
601 : 0 : dpaa2_q->flow_id = flow_id;
602 : 0 : dpaa2_q->tc_index = tc_id;
603 : :
604 : 0 : ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token,
605 : : DPNI_QUEUE_TX,
606 : 0 : ((node->parent->channel_id << 8) | dpaa2_q->tc_index),
607 : : dpaa2_q->flow_id, &tx_flow_cfg, &qid);
608 [ # # ]: 0 : if (ret) {
609 : 0 : DPAA2_PMD_ERR("Error in getting LFQID err=%d", ret);
610 : 0 : return ret;
611 : : }
612 : 0 : dpaa2_q->fqid = qid.fqid;
613 : :
614 : : /* setting congestion notification */
615 [ # # ]: 0 : if (!(priv->flags & DPAA2_TX_CGR_OFF)) {
616 : 0 : struct dpni_congestion_notification_cfg cong_notif_cfg = {0};
617 : :
618 : 0 : cong_notif_cfg.units = DPNI_CONGESTION_UNIT_FRAMES;
619 : 0 : cong_notif_cfg.threshold_entry = dpaa2_q->nb_desc;
620 : : /* Notify that the queue is not congested when the data in
621 : : * the queue is below this thershold.(90% of value)
622 : : */
623 : 0 : cong_notif_cfg.threshold_exit = (dpaa2_q->nb_desc * 9) / 10;
624 : : cong_notif_cfg.message_ctx = 0;
625 : 0 : iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(dpaa2_q->cscn,
626 : : sizeof(struct qbman_result));
627 [ # # ]: 0 : if (iova == RTE_BAD_IOVA) {
628 : 0 : DPAA2_PMD_ERR("No IOMMU map for cscn(%p)", dpaa2_q->cscn);
629 : 0 : return -ENOBUFS;
630 : : }
631 : 0 : cong_notif_cfg.message_iova = iova;
632 : 0 : cong_notif_cfg.dest_cfg.dest_type = DPNI_DEST_NONE;
633 : 0 : cong_notif_cfg.notification_mode =
634 : : DPNI_CONG_OPT_WRITE_MEM_ON_ENTER |
635 : : DPNI_CONG_OPT_WRITE_MEM_ON_EXIT |
636 : : DPNI_CONG_OPT_COHERENT_WRITE;
637 : 0 : cong_notif_cfg.cg_point = DPNI_CP_QUEUE;
638 : :
639 : 0 : ret = dpni_set_congestion_notification(dpni, CMD_PRI_LOW,
640 : 0 : priv->token,
641 : : DPNI_QUEUE_TX,
642 : 0 : ((node->parent->channel_id << 8) | tc_id),
643 : : &cong_notif_cfg);
644 [ # # ]: 0 : if (ret) {
645 : 0 : DPAA2_PMD_ERR("Error in setting tx congestion notification: "
646 : : "err=%d", ret);
647 : 0 : return -ret;
648 : : }
649 : : }
650 : 0 : dpaa2_q->tm_sw_td = true;
651 : :
652 : 0 : return 0;
653 : : }
654 : :
655 : : static void
656 : 0 : dpaa2_tm_sort_and_configure(struct rte_eth_dev *dev,
657 : : struct dpaa2_tm_node **nodes, int n)
658 : : {
659 : : struct dpaa2_tm_node *temp_node;
660 : : int i;
661 : :
662 [ # # ]: 0 : if (n == 1) {
663 : 0 : DPAA2_PMD_DEBUG("node id = %d, priority = %d, index = %d",
664 : : nodes[n - 1]->id, nodes[n - 1]->priority,
665 : : n - 1);
666 : 0 : dpaa2_tm_configure_queue(dev, nodes[n - 1]);
667 : 0 : return;
668 : : }
669 : :
670 [ # # ]: 0 : for (i = 0; i < n - 1; i++) {
671 [ # # ]: 0 : if (nodes[i]->priority > nodes[i + 1]->priority) {
672 : : temp_node = nodes[i];
673 : 0 : nodes[i] = nodes[i + 1];
674 : 0 : nodes[i + 1] = temp_node;
675 : : }
676 : : }
677 : 0 : dpaa2_tm_sort_and_configure(dev, nodes, n - 1);
678 : :
679 : 0 : DPAA2_PMD_DEBUG("node id = %d, priority = %d, index = %d",
680 : : nodes[n - 1]->id, nodes[n - 1]->priority,
681 : : n - 1);
682 : 0 : dpaa2_tm_configure_queue(dev, nodes[n - 1]);
683 : : }
684 : :
685 : : static int
686 : 0 : dpaa2_hierarchy_commit(struct rte_eth_dev *dev, int clear_on_fail,
687 : : struct rte_tm_error *error)
688 : : {
689 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
690 : : struct dpaa2_tm_node *node;
691 : : struct dpaa2_tm_node *leaf_node, *temp_leaf_node, *channel_node;
692 : 0 : struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
693 : : int ret, t;
694 : : bool conf_schedule = false;
695 : :
696 : : /* Populate TCs */
697 [ # # ]: 0 : LIST_FOREACH(channel_node, &priv->nodes, next) {
698 : : struct dpaa2_tm_node *nodes[DPNI_MAX_TC];
699 : : int i = 0;
700 : :
701 [ # # ]: 0 : if (channel_node->level_id != CHANNEL_LEVEL)
702 : 0 : continue;
703 : :
704 [ # # ]: 0 : LIST_FOREACH(leaf_node, &priv->nodes, next) {
705 [ # # ]: 0 : if (leaf_node->level_id == LNI_LEVEL ||
706 : : leaf_node->level_id == CHANNEL_LEVEL)
707 : 0 : continue;
708 : :
709 [ # # ]: 0 : if (leaf_node->parent == channel_node) {
710 [ # # ]: 0 : if (i >= DPNI_MAX_TC) {
711 : : ret = -rte_tm_error_set(error, EINVAL,
712 : : RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,
713 : : "More children than supported\n");
714 : 0 : goto out;
715 : : }
716 : 0 : nodes[i++] = leaf_node;
717 : : }
718 : : }
719 [ # # ]: 0 : if (i > 0) {
720 : 0 : DPAA2_PMD_DEBUG("Configure queues");
721 : 0 : dpaa2_tm_sort_and_configure(dev, nodes, i);
722 : : }
723 : : }
724 : :
725 : : /* Shaping */
726 [ # # ]: 0 : LIST_FOREACH(node, &priv->nodes, next) {
727 [ # # ]: 0 : if (node->type == NON_LEAF_NODE) {
728 [ # # ]: 0 : if (!node->profile)
729 : 0 : continue;
730 : : struct dpni_tx_shaping_cfg tx_cr_shaper, tx_er_shaper;
731 : : uint32_t param = 0;
732 : :
733 : 0 : tx_cr_shaper.max_burst_size =
734 : 0 : node->profile->params.committed.size;
735 : 0 : tx_cr_shaper.rate_limit =
736 : 0 : node->profile->params.committed.rate /
737 : : (1024 * 1024);
738 : 0 : tx_er_shaper.max_burst_size =
739 : 0 : node->profile->params.peak.size;
740 : 0 : tx_er_shaper.rate_limit =
741 : 0 : node->profile->params.peak.rate / (1024 * 1024);
742 : : /* root node */
743 [ # # ]: 0 : if (node->parent == NULL) {
744 : 0 : DPAA2_PMD_DEBUG("LNI S.rate = %u, burst =%u",
745 : : tx_cr_shaper.rate_limit,
746 : : tx_cr_shaper.max_burst_size);
747 : : param = 0x2;
748 : 0 : param |= node->profile->params.pkt_length_adjust << 16;
749 : : } else {
750 : 0 : DPAA2_PMD_DEBUG("Channel = %d S.rate = %u",
751 : : node->channel_id,
752 : : tx_cr_shaper.rate_limit);
753 : 0 : param = (node->channel_id << 8);
754 : : }
755 : 0 : ret = dpni_set_tx_shaping(dpni, 0, priv->token,
756 : : &tx_cr_shaper, &tx_er_shaper, param);
757 [ # # ]: 0 : if (ret) {
758 : : ret = -rte_tm_error_set(error, EINVAL,
759 : : RTE_TM_ERROR_TYPE_SHAPER_PROFILE, NULL,
760 : : "Error in setting Shaping\n");
761 : 0 : goto out;
762 : : }
763 : 0 : continue;
764 : : }
765 : : }
766 : :
767 [ # # ]: 0 : LIST_FOREACH(channel_node, &priv->nodes, next) {
768 [ # # ]: 0 : int wfq_grp = 0, is_wfq_grp = 0, conf[priv->nb_tx_queues];
769 : : struct dpni_tx_priorities_cfg prio_cfg;
770 : :
771 : : memset(&prio_cfg, 0, sizeof(prio_cfg));
772 : : memset(conf, 0, sizeof(conf));
773 : :
774 : : /* Process for each channel */
775 [ # # ]: 0 : if (channel_node->level_id != CHANNEL_LEVEL)
776 : 0 : continue;
777 : :
778 : : conf_schedule = false;
779 [ # # ]: 0 : LIST_FOREACH(leaf_node, &priv->nodes, next) {
780 : : struct dpaa2_queue *leaf_dpaa2_q;
781 : : uint8_t leaf_tc_id;
782 : :
783 [ # # ]: 0 : if (leaf_node->level_id == LNI_LEVEL ||
784 : : leaf_node->level_id == CHANNEL_LEVEL)
785 : 0 : continue;
786 : :
787 : : /* level 2, all leaf nodes */
788 [ # # ]: 0 : if (leaf_node->id >= dev->data->nb_tx_queues) {
789 : : ret = -rte_tm_error_set(error, EINVAL,
790 : : RTE_TM_ERROR_TYPE_NODE_ID, NULL,
791 : : "Not enough txqs configured\n");
792 : 0 : goto out;
793 : : }
794 : :
795 [ # # ]: 0 : if (conf[leaf_node->id])
796 : 0 : continue;
797 : :
798 [ # # ]: 0 : if (leaf_node->parent != channel_node)
799 : 0 : continue;
800 : :
801 : : conf_schedule = true;
802 : 0 : leaf_dpaa2_q = (struct dpaa2_queue *)dev->data->tx_queues[leaf_node->id];
803 : 0 : leaf_tc_id = leaf_dpaa2_q->tc_index;
804 : : /* Process sibling leaf nodes */
805 [ # # ]: 0 : LIST_FOREACH(temp_leaf_node, &priv->nodes, next) {
806 [ # # ]: 0 : if (temp_leaf_node->id == leaf_node->id ||
807 [ # # # # ]: 0 : temp_leaf_node->level_id == LNI_LEVEL ||
808 : : temp_leaf_node->level_id == CHANNEL_LEVEL)
809 : 0 : continue;
810 : :
811 [ # # ]: 0 : if (temp_leaf_node->parent != channel_node)
812 : 0 : continue;
813 : :
814 [ # # ]: 0 : if (conf[temp_leaf_node->id])
815 : 0 : continue;
816 : :
817 [ # # ]: 0 : if (leaf_node->priority == temp_leaf_node->priority) {
818 : : struct dpaa2_queue *temp_leaf_dpaa2_q;
819 : : uint8_t temp_leaf_tc_id;
820 : :
821 : 0 : temp_leaf_dpaa2_q = (struct dpaa2_queue *)
822 : 0 : dev->data->tx_queues[temp_leaf_node->id];
823 : 0 : temp_leaf_tc_id = temp_leaf_dpaa2_q->tc_index;
824 [ # # ]: 0 : if (wfq_grp == 0) {
825 : 0 : prio_cfg.tc_sched[temp_leaf_tc_id].mode =
826 : : DPNI_TX_SCHED_WEIGHTED_A;
827 : : /* DPAA2 support weight in multiple of 100 */
828 : 0 : prio_cfg.tc_sched[temp_leaf_tc_id].delta_bandwidth =
829 : 0 : temp_leaf_node->weight * 100;
830 [ # # ]: 0 : } else if (wfq_grp == 1) {
831 : 0 : prio_cfg.tc_sched[temp_leaf_tc_id].mode =
832 : : DPNI_TX_SCHED_WEIGHTED_B;
833 : 0 : prio_cfg.tc_sched[temp_leaf_tc_id].delta_bandwidth =
834 : 0 : temp_leaf_node->weight * 100;
835 : : } else {
836 : : ret = -rte_tm_error_set(error, EINVAL,
837 : : RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,
838 : : "Only 2 WFQ Groups are supported\n");
839 : 0 : goto out;
840 : : }
841 : : is_wfq_grp = 1;
842 : : }
843 : 0 : conf[temp_leaf_node->id] = 1;
844 : : }
845 [ # # ]: 0 : if (is_wfq_grp) {
846 [ # # ]: 0 : if (wfq_grp == 0) {
847 : 0 : prio_cfg.tc_sched[leaf_tc_id].mode =
848 : : DPNI_TX_SCHED_WEIGHTED_A;
849 : 0 : prio_cfg.tc_sched[leaf_tc_id].delta_bandwidth =
850 : 0 : leaf_node->weight * 100;
851 : 0 : prio_cfg.prio_group_A = leaf_node->priority;
852 [ # # ]: 0 : } else if (wfq_grp == 1) {
853 : 0 : prio_cfg.tc_sched[leaf_tc_id].mode =
854 : : DPNI_TX_SCHED_WEIGHTED_B;
855 : 0 : prio_cfg.tc_sched[leaf_tc_id].delta_bandwidth =
856 : 0 : leaf_node->weight * 100;
857 : 0 : prio_cfg.prio_group_B = leaf_node->priority;
858 : : }
859 : 0 : wfq_grp++;
860 : : is_wfq_grp = 0;
861 : : }
862 : 0 : conf[leaf_node->id] = 1;
863 : : }
864 [ # # ]: 0 : if (!conf_schedule)
865 : 0 : continue;
866 : :
867 [ # # ]: 0 : if (wfq_grp > 1) {
868 : 0 : prio_cfg.separate_groups = 1;
869 [ # # ]: 0 : if (prio_cfg.prio_group_B < prio_cfg.prio_group_A) {
870 : : prio_cfg.prio_group_A = 0;
871 : 0 : prio_cfg.prio_group_B = 1;
872 : : } else {
873 : : prio_cfg.prio_group_A = 1;
874 : 0 : prio_cfg.prio_group_B = 0;
875 : : }
876 : : }
877 : :
878 : 0 : prio_cfg.prio_group_A = 1;
879 : 0 : prio_cfg.channel_idx = channel_node->channel_id;
880 : 0 : DPAA2_PMD_DEBUG("########################################");
881 : 0 : DPAA2_PMD_DEBUG("Channel idx = %d", prio_cfg.channel_idx);
882 [ # # ]: 0 : for (t = 0; t < DPNI_MAX_TC; t++)
883 : 0 : DPAA2_PMD_DEBUG("tc = %d mode = %d, delta = %d", t,
884 : : prio_cfg.tc_sched[t].mode,
885 : : prio_cfg.tc_sched[t].delta_bandwidth);
886 : :
887 : 0 : DPAA2_PMD_DEBUG("prioritya = %d, priorityb = %d, separate grps"
888 : : " = %d", prio_cfg.prio_group_A,
889 : : prio_cfg.prio_group_B, prio_cfg.separate_groups);
890 : 0 : ret = dpni_set_tx_priorities(dpni, 0, priv->token, &prio_cfg);
891 [ # # ]: 0 : if (ret) {
892 : : ret = -rte_tm_error_set(error, EINVAL,
893 : : RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,
894 : : "Scheduling Failed\n");
895 : 0 : goto out;
896 : : }
897 : : }
898 : : return 0;
899 : :
900 : 0 : out:
901 [ # # ]: 0 : if (clear_on_fail) {
902 : 0 : dpaa2_tm_deinit(dev);
903 : 0 : dpaa2_tm_init(dev);
904 : : }
905 : :
906 : : return ret;
907 : : }
908 : :
909 : : static int
910 : 0 : dpaa2_node_stats_read(struct rte_eth_dev *dev, uint32_t node_id,
911 : : struct rte_tm_node_stats *stats, uint64_t *stats_mask,
912 : : int clear, struct rte_tm_error *error)
913 : : {
914 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
915 : : struct dpaa2_tm_node *node;
916 : 0 : struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
917 : : union dpni_statistics value;
918 : : int ret = 0;
919 : :
920 : : node = dpaa2_node_from_id(priv, node_id);
921 [ # # ]: 0 : if (!node)
922 : 0 : return -rte_tm_error_set(error, ENODEV,
923 : : RTE_TM_ERROR_TYPE_NODE_ID,
924 : : NULL, "Node id does not exist\n");
925 : :
926 [ # # ]: 0 : if (stats_mask)
927 : 0 : *stats_mask = node->stats_mask;
928 : :
929 [ # # ]: 0 : if (!stats)
930 : : return 0;
931 : :
932 : : memset(stats, 0, sizeof(*stats));
933 : : memset(&value, 0, sizeof(union dpni_statistics));
934 : :
935 [ # # ]: 0 : if (node->level_id == LNI_LEVEL) {
936 : : uint8_t page1 = 1;
937 : :
938 : 0 : ret = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
939 : : page1, 0, &value);
940 [ # # ]: 0 : if (ret)
941 [ # # ]: 0 : return -rte_tm_error_set(error, -ret,
942 : : RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,
943 : : "Failed to read port statistics\n");
944 : :
945 [ # # ]: 0 : if (node->stats_mask & RTE_TM_STATS_N_PKTS)
946 : 0 : stats->n_pkts = value.page_1.egress_all_frames;
947 : :
948 [ # # ]: 0 : if (node->stats_mask & RTE_TM_STATS_N_BYTES)
949 : 0 : stats->n_bytes = value.page_1.egress_all_bytes;
950 : :
951 [ # # ]: 0 : if (clear) {
952 : 0 : ret = dpni_reset_statistics(dpni, CMD_PRI_LOW, priv->token);
953 [ # # ]: 0 : return -rte_tm_error_set(error, -ret,
954 : : RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,
955 : : "Failed to reset port statistics\n");
956 : : }
957 [ # # ]: 0 : } else if (node->level_id == QUEUE_LEVEL) {
958 : : uint8_t page3 = 3;
959 : : struct dpaa2_queue *dpaa2_q;
960 : 0 : dpaa2_q = (struct dpaa2_queue *)dev->data->tx_queues[node->id];
961 : :
962 : 0 : ret = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
963 : : page3,
964 : 0 : (node->parent->channel_id << 8 |
965 : 0 : dpaa2_q->tc_index), &value);
966 [ # # ]: 0 : if (ret)
967 [ # # ]: 0 : return -rte_tm_error_set(error, -ret,
968 : : RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,
969 : : "Failed to read queue statistics\n");
970 : :
971 [ # # ]: 0 : if (node->stats_mask & RTE_TM_STATS_N_PKTS)
972 : 0 : stats->n_pkts = value.page_3.ceetm_dequeue_frames;
973 [ # # ]: 0 : if (node->stats_mask & RTE_TM_STATS_N_BYTES)
974 : 0 : stats->n_bytes = value.page_3.ceetm_dequeue_bytes;
975 : : } else {
976 : 0 : return -rte_tm_error_set(error, -1,
977 : : RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,
978 : : "Failed to read channel statistics\n");
979 : : }
980 : :
981 : : return 0;
982 : : }
983 : :
984 : : const struct rte_tm_ops dpaa2_tm_ops = {
985 : : .node_type_get = dpaa2_node_type_get,
986 : : .capabilities_get = dpaa2_capabilities_get,
987 : : .level_capabilities_get = dpaa2_level_capabilities_get,
988 : : .node_capabilities_get = dpaa2_node_capabilities_get,
989 : : .shaper_profile_add = dpaa2_shaper_profile_add,
990 : : .shaper_profile_delete = dpaa2_shaper_profile_delete,
991 : : .node_add = dpaa2_node_add,
992 : : .node_delete = dpaa2_node_delete,
993 : : .hierarchy_commit = dpaa2_hierarchy_commit,
994 : : .node_stats_read = dpaa2_node_stats_read,
995 : : };
|