1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2020-2021 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 dpaa2_tm_init(struct rte_eth_dev *dev) 23 { 24 struct dpaa2_dev_priv *priv = dev->data->dev_private; 25 26 LIST_INIT(&priv->shaper_profiles); 27 LIST_INIT(&priv->nodes); 28 29 return 0; 30 } 31 32 void dpaa2_tm_deinit(struct rte_eth_dev *dev) 33 { 34 struct dpaa2_dev_priv *priv = dev->data->dev_private; 35 struct dpaa2_tm_shaper_profile *profile = 36 LIST_FIRST(&priv->shaper_profiles); 37 struct dpaa2_tm_node *node = LIST_FIRST(&priv->nodes); 38 39 while (profile) { 40 struct dpaa2_tm_shaper_profile *next = LIST_NEXT(profile, next); 41 42 LIST_REMOVE(profile, next); 43 rte_free(profile); 44 profile = next; 45 } 46 47 while (node) { 48 struct dpaa2_tm_node *next = LIST_NEXT(node, next); 49 50 LIST_REMOVE(node, next); 51 rte_free(node); 52 node = next; 53 } 54 } 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 LIST_FOREACH(node, &priv->nodes, next) 62 if (node->id == node_id) 63 return node; 64 65 return NULL; 66 } 67 68 static int 69 dpaa2_capabilities_get(struct rte_eth_dev *dev, 70 struct rte_tm_capabilities *cap, 71 struct rte_tm_error *error) 72 { 73 struct dpaa2_dev_priv *priv = dev->data->dev_private; 74 75 if (!cap) 76 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 cap->n_nodes_max = 1 + priv->num_channels + dev->data->nb_tx_queues; 86 cap->n_levels_max = MAX_LEVEL; 87 cap->non_leaf_nodes_identical = 1; 88 cap->leaf_nodes_identical = 1; 89 90 cap->shaper_n_max = 1 + priv->num_channels; /* LNI + channels */ 91 cap->shaper_private_n_max = 1 + priv->num_channels; 92 cap->shaper_private_dual_rate_n_max = 1 + priv->num_channels; 93 cap->shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE; 94 cap->shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE; 95 cap->shaper_pkt_length_adjust_min = DPAA2_PKT_ADJUST_LEN_MIN; 96 cap->shaper_pkt_length_adjust_max = DPAA2_PKT_ADJUST_LEN_MAX; 97 98 if (priv->num_channels > DPNI_MAX_TC) 99 cap->sched_n_children_max = priv->num_channels; 100 else 101 cap->sched_n_children_max = DPNI_MAX_TC; 102 103 cap->sched_sp_n_priorities_max = DPNI_MAX_TC; 104 cap->sched_wfq_n_children_per_group_max = DPNI_MAX_TC; 105 cap->sched_wfq_n_groups_max = 2; 106 cap->sched_wfq_weight_max = DPAA2_WEIGHT_MAX / 100; 107 cap->stats_mask = RTE_TM_STATS_N_PKTS | RTE_TM_STATS_N_BYTES; 108 109 return 0; 110 } 111 112 static int 113 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 struct dpaa2_dev_priv *priv = dev->data->dev_private; 119 120 if (!cap) 121 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 if (level_id > QUEUE_LEVEL) 128 return -rte_tm_error_set(error, EINVAL, 129 RTE_TM_ERROR_TYPE_LEVEL_ID, 130 NULL, "Wrong level id\n"); 131 132 if (level_id == LNI_LEVEL) { /* Root node (LNI) */ 133 cap->n_nodes_max = 1; 134 cap->n_nodes_nonleaf_max = 1; 135 cap->non_leaf_nodes_identical = 1; 136 137 cap->nonleaf.shaper_private_supported = 1; 138 cap->nonleaf.shaper_private_dual_rate_supported = 1; 139 cap->nonleaf.shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE; 140 cap->nonleaf.shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE; 141 142 cap->nonleaf.sched_n_children_max = priv->num_channels; /* no. of channels */ 143 cap->nonleaf.sched_sp_n_priorities_max = 1; 144 cap->nonleaf.sched_wfq_n_children_per_group_max = 1; 145 cap->nonleaf.sched_wfq_n_groups_max = 1; 146 cap->nonleaf.sched_wfq_weight_max = 1; 147 cap->nonleaf.stats_mask = RTE_TM_STATS_N_PKTS | 148 RTE_TM_STATS_N_BYTES; 149 } else if (level_id == CHANNEL_LEVEL) { /* channels */ 150 cap->n_nodes_max = priv->num_channels; 151 cap->n_nodes_nonleaf_max = priv->num_channels; 152 cap->n_nodes_leaf_max = 0; 153 cap->non_leaf_nodes_identical = 1; 154 155 cap->nonleaf.shaper_private_supported = 1; 156 cap->nonleaf.shaper_private_dual_rate_supported = 1; 157 cap->nonleaf.shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE; 158 cap->nonleaf.shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE; 159 160 /* no. of class queues per channel */ 161 cap->nonleaf.sched_n_children_max = priv->num_tx_tc; 162 cap->nonleaf.sched_sp_n_priorities_max = priv->num_tx_tc; 163 cap->nonleaf.sched_wfq_n_children_per_group_max = priv->num_tx_tc; 164 cap->nonleaf.sched_wfq_n_groups_max = 2; 165 cap->nonleaf.sched_wfq_weight_max = DPAA2_WEIGHT_MAX / 100; 166 } else { /* leaf nodes */ 167 /* queues per channels * channel */ 168 cap->n_nodes_max = priv->num_tx_tc * priv->num_channels; 169 cap->n_nodes_leaf_max = priv->num_tx_tc * priv->num_channels; 170 cap->leaf_nodes_identical = 1; 171 172 cap->leaf.shaper_private_supported = 0; 173 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 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 struct dpaa2_dev_priv *priv = dev->data->dev_private; 187 188 if (!cap) 189 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 if (!node) 197 return -rte_tm_error_set(error, ENODEV, 198 RTE_TM_ERROR_TYPE_NODE_ID, 199 NULL, "Node id does not exist\n"); 200 201 if (node->level_id == LNI_LEVEL) { 202 cap->shaper_private_supported = 1; 203 cap->shaper_private_dual_rate_supported = 1; 204 cap->shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE; 205 cap->shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE; 206 207 cap->nonleaf.sched_n_children_max = priv->num_channels; 208 cap->nonleaf.sched_sp_n_priorities_max = 1; 209 cap->nonleaf.sched_wfq_n_children_per_group_max = 1; 210 cap->nonleaf.sched_wfq_n_groups_max = 1; 211 cap->nonleaf.sched_wfq_weight_max = 1; 212 cap->stats_mask = RTE_TM_STATS_N_PKTS | 213 RTE_TM_STATS_N_BYTES; 214 } else if (node->level_id == CHANNEL_LEVEL) { 215 cap->shaper_private_supported = 1; 216 cap->shaper_private_dual_rate_supported = 1; 217 cap->shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE; 218 cap->shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE; 219 220 cap->nonleaf.sched_n_children_max = priv->num_tx_tc; 221 cap->nonleaf.sched_sp_n_priorities_max = priv->num_tx_tc; 222 cap->nonleaf.sched_wfq_n_children_per_group_max = priv->num_tx_tc; 223 cap->nonleaf.sched_wfq_n_groups_max = 2; 224 cap->nonleaf.sched_wfq_weight_max = DPAA2_WEIGHT_MAX / 100; 225 } else { 226 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 dpaa2_node_type_get(struct rte_eth_dev *dev, uint32_t node_id, int *is_leaf, 235 struct rte_tm_error *error) 236 { 237 struct dpaa2_dev_priv *priv = dev->data->dev_private; 238 struct dpaa2_tm_node *node; 239 240 if (!is_leaf) 241 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 if (!node) 247 return -rte_tm_error_set(error, ENODEV, 248 RTE_TM_ERROR_TYPE_NODE_ID, 249 NULL, "Node id does not exist\n"); 250 251 *is_leaf = node->type == LEAF_NODE ? 1 : 0; 252 253 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 LIST_FOREACH(profile, &priv->shaper_profiles, next) 263 if (profile->id == shaper_profile_id) 264 return profile; 265 266 return NULL; 267 } 268 269 static int 270 dpaa2_shaper_profile_add(struct rte_eth_dev *dev, uint32_t shaper_profile_id, 271 struct rte_tm_shaper_params *params, 272 struct rte_tm_error *error) 273 { 274 struct dpaa2_dev_priv *priv = dev->data->dev_private; 275 struct dpaa2_tm_shaper_profile *profile; 276 277 if (!params) 278 return -rte_tm_error_set(error, EINVAL, 279 RTE_TM_ERROR_TYPE_UNSPECIFIED, 280 NULL, NULL); 281 if (params->committed.rate > DPAA2_SHAPER_MAX_RATE) 282 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 if (params->committed.size > DPAA2_BURST_MAX) 287 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 if (params->peak.rate > DPAA2_SHAPER_MAX_RATE) 292 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 if (params->peak.size > DPAA2_BURST_MAX) 297 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 if (shaper_profile_id == RTE_TM_SHAPER_PROFILE_ID_NONE) 302 return -rte_tm_error_set(error, EINVAL, 303 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID, 304 NULL, "Wrong shaper profile id\n"); 305 306 if (params->pkt_length_adjust > DPAA2_PKT_ADJUST_LEN_MAX || 307 params->pkt_length_adjust < DPAA2_PKT_ADJUST_LEN_MIN) 308 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 if (profile) 315 return -rte_tm_error_set(error, EEXIST, 316 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID, 317 NULL, "Profile id already exists\n"); 318 319 profile = rte_zmalloc_socket(NULL, sizeof(*profile), 0, 320 rte_socket_id()); 321 if (!profile) 322 return -rte_tm_error_set(error, ENOMEM, 323 RTE_TM_ERROR_TYPE_UNSPECIFIED, 324 NULL, NULL); 325 326 profile->id = shaper_profile_id; 327 rte_memcpy(&profile->params, params, sizeof(profile->params)); 328 329 LIST_INSERT_HEAD(&priv->shaper_profiles, profile, next); 330 331 return 0; 332 } 333 334 static int 335 dpaa2_shaper_profile_delete(struct rte_eth_dev *dev, uint32_t shaper_profile_id, 336 struct rte_tm_error *error) 337 { 338 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 if (!profile) 343 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 if (profile->refcnt) 348 return -rte_tm_error_set(error, EPERM, 349 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID, 350 NULL, "Profile is used\n"); 351 352 LIST_REMOVE(profile, next); 353 rte_free(profile); 354 355 return 0; 356 } 357 358 static int 359 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 struct rte_tm_node_params *params, 363 struct rte_tm_error *error) 364 { 365 if (node_id == RTE_TM_NODE_ID_NULL) 366 return -rte_tm_error_set(error, EINVAL, RTE_TM_NODE_ID_NULL, 367 NULL, "Node id is invalid\n"); 368 369 if (weight > DPAA2_WEIGHT_MAX) 370 return -rte_tm_error_set(error, EINVAL, 371 RTE_TM_ERROR_TYPE_NODE_WEIGHT, 372 NULL, "Weight is out of range\n"); 373 374 if (level_id > QUEUE_LEVEL) 375 return -rte_tm_error_set(error, EINVAL, 376 RTE_TM_ERROR_TYPE_LEVEL_ID, 377 NULL, "Wrong level id\n"); 378 379 if (!params) 380 return -rte_tm_error_set(error, EINVAL, 381 RTE_TM_ERROR_TYPE_UNSPECIFIED, 382 NULL, NULL); 383 384 if (params->shared_shaper_id) 385 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 if (params->n_shared_shapers) 390 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 if (node_id >= dev->data->nb_tx_queues) { 396 if (params->nonleaf.wfq_weight_mode) 397 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 if (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE) 402 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 if (level_id == QUEUE_LEVEL) { 409 if (params->leaf.cman != RTE_TM_CMAN_TAIL_DROP) 410 return -rte_tm_error_set(error, ENODEV, 411 RTE_TM_ERROR_TYPE_NODE_PARAMS_CMAN, 412 NULL, "Only taildrop is supported\n"); 413 if (params->stats_mask & ~(RTE_TM_STATS_N_PKTS | 414 RTE_TM_STATS_N_BYTES)) 415 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 } else if (level_id == LNI_LEVEL) { 420 if (params->stats_mask & ~(RTE_TM_STATS_N_PKTS | 421 RTE_TM_STATS_N_BYTES)) 422 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 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, struct rte_tm_node_params *params, 435 struct rte_tm_error *error) 436 { 437 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 ret = dpaa2_node_check_params(dev, node_id, priority, weight, level_id, 448 params, error); 449 if (ret) 450 return ret; 451 452 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 if (!profile) 456 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 if (parent_node_id == RTE_TM_NODE_ID_NULL) { 461 LIST_FOREACH(node, &priv->nodes, next) { 462 if (node->level_id != LNI_LEVEL) 463 continue; 464 465 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 if (!parent) 472 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 if (node) 479 return -rte_tm_error_set(error, ENODEV, 480 RTE_TM_ERROR_TYPE_NODE_ID, 481 NULL, "Node id already exists\n"); 482 483 node = rte_zmalloc_socket(NULL, sizeof(*node), 0, rte_socket_id()); 484 if (!node) 485 return -rte_tm_error_set(error, ENOMEM, 486 RTE_TM_ERROR_TYPE_UNSPECIFIED, 487 NULL, NULL); 488 489 node->id = node_id; 490 491 if (node_id > dev->data->nb_tx_queues) 492 node->type = NON_LEAF_NODE; 493 else 494 node->type = LEAF_NODE; 495 496 node->level_id = level_id; 497 if (node->level_id == CHANNEL_LEVEL) { 498 if (priv->channel_inuse < priv->num_channels) { 499 node->channel_id = priv->channel_inuse; 500 priv->channel_inuse++; 501 } else { 502 printf("error no channel id available\n"); 503 } 504 } 505 506 if (parent) { 507 node->parent = parent; 508 parent->refcnt++; 509 } 510 511 /* TODO: add check if refcnt is more than supported children */ 512 513 if (profile) { 514 node->profile = profile; 515 profile->refcnt++; 516 } 517 518 node->weight = weight; 519 node->priority = priority; 520 node->stats_mask = params->stats_mask; 521 522 LIST_INSERT_HEAD(&priv->nodes, node, next); 523 524 return 0; 525 } 526 527 static int 528 dpaa2_node_delete(struct rte_eth_dev *dev, uint32_t node_id, 529 struct rte_tm_error *error) 530 { 531 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 if (!node) 543 return -rte_tm_error_set(error, ENODEV, 544 RTE_TM_ERROR_TYPE_NODE_ID, 545 NULL, "Node id does not exist\n"); 546 547 if (node->refcnt) 548 return -rte_tm_error_set(error, EPERM, 549 RTE_TM_ERROR_TYPE_NODE_ID, 550 NULL, "Node id is used\n"); 551 552 if (node->parent) 553 node->parent->refcnt--; 554 555 if (node->profile) 556 node->profile->refcnt--; 557 558 LIST_REMOVE(node, next); 559 rte_free(node); 560 561 return 0; 562 } 563 564 static int 565 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 struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; 573 struct dpaa2_dev_priv *priv = dev->data->dev_private; 574 struct dpaa2_queue *dpaa2_q; 575 576 memset(&tx_flow_cfg, 0, sizeof(struct dpni_queue)); 577 dpaa2_q = (struct dpaa2_queue *)dev->data->tx_queues[node->id]; 578 tc_id = node->parent->tc_id; 579 node->parent->tc_id++; 580 flow_id = 0; 581 582 if (dpaa2_q == NULL) { 583 printf("Queue is not configured for node = %d\n", node->id); 584 return -1; 585 } 586 587 DPAA2_PMD_DEBUG("tc_id = %d, channel = %d\n\n", tc_id, 588 node->parent->channel_id); 589 ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX, 590 ((node->parent->channel_id << 8) | tc_id), 591 flow_id, options, &tx_flow_cfg); 592 if (ret) { 593 printf("Error in setting the tx flow: " 594 "channel id = %d tc_id= %d, param = 0x%x " 595 "flow=%d err=%d\n", node->parent->channel_id, tc_id, 596 ((node->parent->channel_id << 8) | tc_id), flow_id, 597 ret); 598 return -1; 599 } 600 601 dpaa2_q->flow_id = flow_id; 602 dpaa2_q->tc_index = tc_id; 603 604 ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token, 605 DPNI_QUEUE_TX, ((node->parent->channel_id << 8) | dpaa2_q->tc_index), 606 dpaa2_q->flow_id, &tx_flow_cfg, &qid); 607 if (ret) { 608 printf("Error in getting LFQID err=%d", ret); 609 return -1; 610 } 611 dpaa2_q->fqid = qid.fqid; 612 613 /* setting congestion notification */ 614 if (!(priv->flags & DPAA2_TX_CGR_OFF)) { 615 struct dpni_congestion_notification_cfg cong_notif_cfg = {0}; 616 617 cong_notif_cfg.units = DPNI_CONGESTION_UNIT_FRAMES; 618 cong_notif_cfg.threshold_entry = dpaa2_q->nb_desc; 619 /* Notify that the queue is not congested when the data in 620 * the queue is below this thershold.(90% of value) 621 */ 622 cong_notif_cfg.threshold_exit = (dpaa2_q->nb_desc * 9) / 10; 623 cong_notif_cfg.message_ctx = 0; 624 cong_notif_cfg.message_iova = 625 (size_t)DPAA2_VADDR_TO_IOVA(dpaa2_q->cscn); 626 cong_notif_cfg.dest_cfg.dest_type = DPNI_DEST_NONE; 627 cong_notif_cfg.notification_mode = 628 DPNI_CONG_OPT_WRITE_MEM_ON_ENTER | 629 DPNI_CONG_OPT_WRITE_MEM_ON_EXIT | 630 DPNI_CONG_OPT_COHERENT_WRITE; 631 cong_notif_cfg.cg_point = DPNI_CP_QUEUE; 632 633 ret = dpni_set_congestion_notification(dpni, CMD_PRI_LOW, 634 priv->token, 635 DPNI_QUEUE_TX, 636 ((node->parent->channel_id << 8) | tc_id), 637 &cong_notif_cfg); 638 if (ret) { 639 printf("Error in setting tx congestion notification: " 640 "err=%d", ret); 641 return -ret; 642 } 643 } 644 645 return 0; 646 } 647 648 static void 649 dpaa2_tm_sort_and_configure(struct rte_eth_dev *dev, 650 struct dpaa2_tm_node **nodes, int n) 651 { 652 struct dpaa2_tm_node *temp_node; 653 int i; 654 655 if (n == 1) { 656 DPAA2_PMD_DEBUG("node id = %d\n, priority = %d, index = %d\n", 657 nodes[n - 1]->id, nodes[n - 1]->priority, 658 n - 1); 659 dpaa2_tm_configure_queue(dev, nodes[n - 1]); 660 return; 661 } 662 663 for (i = 0; i < n - 1; i++) { 664 if (nodes[i]->priority > nodes[i + 1]->priority) { 665 temp_node = nodes[i]; 666 nodes[i] = nodes[i + 1]; 667 nodes[i + 1] = temp_node; 668 } 669 } 670 dpaa2_tm_sort_and_configure(dev, nodes, n - 1); 671 672 DPAA2_PMD_DEBUG("node id = %d\n, priority = %d, index = %d\n", 673 nodes[n - 1]->id, nodes[n - 1]->priority, 674 n - 1); 675 dpaa2_tm_configure_queue(dev, nodes[n - 1]); 676 } 677 678 static int 679 dpaa2_hierarchy_commit(struct rte_eth_dev *dev, int clear_on_fail, 680 struct rte_tm_error *error) 681 { 682 struct dpaa2_dev_priv *priv = dev->data->dev_private; 683 struct dpaa2_tm_node *node; 684 struct dpaa2_tm_node *leaf_node, *temp_leaf_node, *channel_node; 685 struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; 686 int ret, t; 687 688 /* Populate TCs */ 689 LIST_FOREACH(channel_node, &priv->nodes, next) { 690 struct dpaa2_tm_node *nodes[DPNI_MAX_TC]; 691 int i = 0; 692 693 if (channel_node->level_id != CHANNEL_LEVEL) 694 continue; 695 696 LIST_FOREACH(leaf_node, &priv->nodes, next) { 697 if (leaf_node->level_id == LNI_LEVEL || 698 leaf_node->level_id == CHANNEL_LEVEL) 699 continue; 700 701 if (leaf_node->parent == channel_node) { 702 if (i >= DPNI_MAX_TC) { 703 ret = -rte_tm_error_set(error, EINVAL, 704 RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL, 705 "More children than supported\n"); 706 goto out; 707 } 708 nodes[i++] = leaf_node; 709 } 710 } 711 if (i > 0) { 712 DPAA2_PMD_DEBUG("Configure queues\n"); 713 dpaa2_tm_sort_and_configure(dev, nodes, i); 714 } 715 } 716 717 /* Shaping */ 718 LIST_FOREACH(node, &priv->nodes, next) { 719 if (node->type == NON_LEAF_NODE) { 720 if (!node->profile) 721 continue; 722 struct dpni_tx_shaping_cfg tx_cr_shaper, tx_er_shaper; 723 uint32_t param = 0; 724 725 tx_cr_shaper.max_burst_size = 726 node->profile->params.committed.size; 727 tx_cr_shaper.rate_limit = 728 node->profile->params.committed.rate / 729 (1024 * 1024); 730 tx_er_shaper.max_burst_size = 731 node->profile->params.peak.size; 732 tx_er_shaper.rate_limit = 733 node->profile->params.peak.rate / (1024 * 1024); 734 /* root node */ 735 if (node->parent == NULL) { 736 DPAA2_PMD_DEBUG("LNI S.rate = %u, burst =%u\n", 737 tx_cr_shaper.rate_limit, 738 tx_cr_shaper.max_burst_size); 739 param = 0x2; 740 param |= node->profile->params.pkt_length_adjust << 16; 741 } else { 742 DPAA2_PMD_DEBUG("Channel = %d S.rate = %u\n", 743 node->channel_id, 744 tx_cr_shaper.rate_limit); 745 param = (node->channel_id << 8); 746 } 747 ret = dpni_set_tx_shaping(dpni, 0, priv->token, 748 &tx_cr_shaper, &tx_er_shaper, param); 749 if (ret) { 750 ret = -rte_tm_error_set(error, EINVAL, 751 RTE_TM_ERROR_TYPE_SHAPER_PROFILE, NULL, 752 "Error in setting Shaping\n"); 753 goto out; 754 } 755 continue; 756 } 757 } 758 759 LIST_FOREACH(channel_node, &priv->nodes, next) { 760 int wfq_grp = 0, is_wfq_grp = 0, conf[DPNI_MAX_TC]; 761 struct dpni_tx_priorities_cfg prio_cfg; 762 763 memset(&prio_cfg, 0, sizeof(prio_cfg)); 764 memset(conf, 0, sizeof(conf)); 765 766 /* Process for each channel */ 767 if (channel_node->level_id != CHANNEL_LEVEL) 768 continue; 769 770 LIST_FOREACH(leaf_node, &priv->nodes, next) { 771 struct dpaa2_queue *leaf_dpaa2_q; 772 uint8_t leaf_tc_id; 773 774 if (leaf_node->level_id == LNI_LEVEL || 775 leaf_node->level_id == CHANNEL_LEVEL) 776 continue; 777 778 /* level 2, all leaf nodes */ 779 if (leaf_node->id >= dev->data->nb_tx_queues) { 780 ret = -rte_tm_error_set(error, EINVAL, 781 RTE_TM_ERROR_TYPE_NODE_ID, NULL, 782 "Not enough txqs configured\n"); 783 goto out; 784 } 785 786 if (conf[leaf_node->id]) 787 continue; 788 789 if (leaf_node->parent != channel_node) 790 continue; 791 792 leaf_dpaa2_q = (struct dpaa2_queue *)dev->data->tx_queues[leaf_node->id]; 793 leaf_tc_id = leaf_dpaa2_q->tc_index; 794 /* Process sibling leaf nodes */ 795 LIST_FOREACH(temp_leaf_node, &priv->nodes, next) { 796 if (temp_leaf_node->id == leaf_node->id || 797 temp_leaf_node->level_id == LNI_LEVEL || 798 temp_leaf_node->level_id == CHANNEL_LEVEL) 799 continue; 800 801 if (temp_leaf_node->parent != channel_node) 802 continue; 803 804 if (conf[temp_leaf_node->id]) 805 continue; 806 807 if (leaf_node->priority == temp_leaf_node->priority) { 808 struct dpaa2_queue *temp_leaf_dpaa2_q; 809 uint8_t temp_leaf_tc_id; 810 811 temp_leaf_dpaa2_q = (struct dpaa2_queue *) 812 dev->data->tx_queues[temp_leaf_node->id]; 813 temp_leaf_tc_id = temp_leaf_dpaa2_q->tc_index; 814 if (wfq_grp == 0) { 815 prio_cfg.tc_sched[temp_leaf_tc_id].mode = 816 DPNI_TX_SCHED_WEIGHTED_A; 817 /* DPAA2 support weight in multiple of 100 */ 818 prio_cfg.tc_sched[temp_leaf_tc_id].delta_bandwidth = 819 temp_leaf_node->weight * 100; 820 } else if (wfq_grp == 1) { 821 prio_cfg.tc_sched[temp_leaf_tc_id].mode = 822 DPNI_TX_SCHED_WEIGHTED_B; 823 prio_cfg.tc_sched[temp_leaf_tc_id].delta_bandwidth = 824 temp_leaf_node->weight * 100; 825 } else { 826 ret = -rte_tm_error_set(error, EINVAL, 827 RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL, 828 "Only 2 WFQ Groups are supported\n"); 829 goto out; 830 } 831 is_wfq_grp = 1; 832 conf[temp_leaf_node->id] = 1; 833 } 834 } 835 if (is_wfq_grp) { 836 if (wfq_grp == 0) { 837 prio_cfg.tc_sched[leaf_tc_id].mode = 838 DPNI_TX_SCHED_WEIGHTED_A; 839 prio_cfg.tc_sched[leaf_tc_id].delta_bandwidth = 840 leaf_node->weight * 100; 841 prio_cfg.prio_group_A = leaf_node->priority; 842 } else if (wfq_grp == 1) { 843 prio_cfg.tc_sched[leaf_tc_id].mode = 844 DPNI_TX_SCHED_WEIGHTED_B; 845 prio_cfg.tc_sched[leaf_tc_id].delta_bandwidth = 846 leaf_node->weight * 100; 847 prio_cfg.prio_group_B = leaf_node->priority; 848 } 849 wfq_grp++; 850 is_wfq_grp = 0; 851 } 852 conf[leaf_node->id] = 1; 853 } 854 if (wfq_grp > 1) { 855 prio_cfg.separate_groups = 1; 856 if (prio_cfg.prio_group_B < prio_cfg.prio_group_A) { 857 prio_cfg.prio_group_A = 0; 858 prio_cfg.prio_group_B = 1; 859 } else { 860 prio_cfg.prio_group_A = 1; 861 prio_cfg.prio_group_B = 0; 862 } 863 } 864 865 prio_cfg.prio_group_A = 1; 866 prio_cfg.channel_idx = channel_node->channel_id; 867 ret = dpni_set_tx_priorities(dpni, 0, priv->token, &prio_cfg); 868 if (ret) { 869 ret = -rte_tm_error_set(error, EINVAL, 870 RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL, 871 "Scheduling Failed\n"); 872 goto out; 873 } 874 DPAA2_PMD_DEBUG("########################################\n"); 875 DPAA2_PMD_DEBUG("Channel idx = %d\n", prio_cfg.channel_idx); 876 for (t = 0; t < DPNI_MAX_TC; t++) { 877 DPAA2_PMD_DEBUG("tc = %d mode = %d ", t, prio_cfg.tc_sched[t].mode); 878 DPAA2_PMD_DEBUG("delta = %d\n", prio_cfg.tc_sched[t].delta_bandwidth); 879 } 880 DPAA2_PMD_DEBUG("prioritya = %d\n", prio_cfg.prio_group_A); 881 DPAA2_PMD_DEBUG("priorityb = %d\n", prio_cfg.prio_group_B); 882 DPAA2_PMD_DEBUG("separate grps = %d\n\n", prio_cfg.separate_groups); 883 } 884 return 0; 885 886 out: 887 if (clear_on_fail) { 888 dpaa2_tm_deinit(dev); 889 dpaa2_tm_init(dev); 890 } 891 892 return ret; 893 } 894 895 static int 896 dpaa2_node_stats_read(struct rte_eth_dev *dev, uint32_t node_id, 897 struct rte_tm_node_stats *stats, uint64_t *stats_mask, 898 int clear, struct rte_tm_error *error) 899 { 900 struct dpaa2_dev_priv *priv = dev->data->dev_private; 901 struct dpaa2_tm_node *node; 902 struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; 903 union dpni_statistics value; 904 int ret = 0; 905 906 node = dpaa2_node_from_id(priv, node_id); 907 if (!node) 908 return -rte_tm_error_set(error, ENODEV, 909 RTE_TM_ERROR_TYPE_NODE_ID, 910 NULL, "Node id does not exist\n"); 911 912 if (stats_mask) 913 *stats_mask = node->stats_mask; 914 915 if (!stats) 916 return 0; 917 918 memset(stats, 0, sizeof(*stats)); 919 memset(&value, 0, sizeof(union dpni_statistics)); 920 921 if (node->level_id == LNI_LEVEL) { 922 uint8_t page1 = 1; 923 924 ret = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, 925 page1, 0, &value); 926 if (ret) 927 return -rte_tm_error_set(error, -ret, 928 RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL, 929 "Failed to read port statistics\n"); 930 931 if (node->stats_mask & RTE_TM_STATS_N_PKTS) 932 stats->n_pkts = value.page_1.egress_all_frames; 933 934 if (node->stats_mask & RTE_TM_STATS_N_BYTES) 935 stats->n_bytes = value.page_1.egress_all_bytes; 936 937 if (clear) { 938 ret = dpni_reset_statistics(dpni, CMD_PRI_LOW, priv->token); 939 return -rte_tm_error_set(error, -ret, 940 RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL, 941 "Failed to reset port statistics\n"); 942 } 943 } else if (node->level_id == QUEUE_LEVEL) { 944 uint8_t page3 = 3; 945 struct dpaa2_queue *dpaa2_q; 946 dpaa2_q = (struct dpaa2_queue *)dev->data->tx_queues[node->id]; 947 948 ret = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, 949 page3, 950 (node->parent->channel_id << 8 | 951 dpaa2_q->tc_index), &value); 952 if (ret) 953 return -rte_tm_error_set(error, -ret, 954 RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL, 955 "Failed to read queue statistics\n"); 956 957 if (node->stats_mask & RTE_TM_STATS_N_PKTS) 958 stats->n_pkts = value.page_3.ceetm_dequeue_frames; 959 if (node->stats_mask & RTE_TM_STATS_N_BYTES) 960 stats->n_bytes = value.page_3.ceetm_dequeue_bytes; 961 } else { 962 return -rte_tm_error_set(error, -1, 963 RTE_TM_ERROR_TYPE_UNSPECIFIED, NULL, 964 "Failed to read channel statistics\n"); 965 } 966 967 return 0; 968 } 969 970 const struct rte_tm_ops dpaa2_tm_ops = { 971 .node_type_get = dpaa2_node_type_get, 972 .capabilities_get = dpaa2_capabilities_get, 973 .level_capabilities_get = dpaa2_level_capabilities_get, 974 .node_capabilities_get = dpaa2_node_capabilities_get, 975 .shaper_profile_add = dpaa2_shaper_profile_add, 976 .shaper_profile_delete = dpaa2_shaper_profile_delete, 977 .node_add = dpaa2_node_add, 978 .node_delete = dpaa2_node_delete, 979 .hierarchy_commit = dpaa2_hierarchy_commit, 980 .node_stats_read = dpaa2_node_stats_read, 981 }; 982