1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019 Intel Corporation 3 */ 4 5 #include <stdint.h> 6 #include <stdlib.h> 7 #include <string.h> 8 9 #include <rte_bus_pci.h> 10 #include <rte_ethdev.h> 11 #include <rte_pci.h> 12 #include <rte_malloc.h> 13 #include <rte_tm_driver.h> 14 15 #include <rte_mbuf.h> 16 #include <rte_sched.h> 17 #include <rte_ethdev_driver.h> 18 19 #include <rte_io.h> 20 #include <rte_rawdev.h> 21 #include <rte_rawdev_pmd.h> 22 #include <rte_bus_ifpga.h> 23 #include <ifpga_logs.h> 24 25 #include "ipn3ke_rawdev_api.h" 26 #include "ipn3ke_flow.h" 27 #include "ipn3ke_logs.h" 28 #include "ipn3ke_ethdev.h" 29 30 #define BYTES_IN_MBPS (1000 * 1000 / 8) 31 #define SUBPORT_TC_PERIOD 10 32 #define PIPE_TC_PERIOD 40 33 34 struct ipn3ke_tm_shaper_params_range_type { 35 uint32_t m1; 36 uint32_t m2; 37 uint32_t exp; 38 uint32_t exp2; 39 uint32_t low; 40 uint32_t high; 41 }; 42 struct ipn3ke_tm_shaper_params_range_type ipn3ke_tm_shaper_params_rang[] = { 43 { 0, 1, 0, 1, 0, 4}, 44 { 2, 3, 0, 1, 8, 12}, 45 { 4, 7, 0, 1, 16, 28}, 46 { 8, 15, 0, 1, 32, 60}, 47 { 16, 31, 0, 1, 64, 124}, 48 { 32, 63, 0, 1, 128, 252}, 49 { 64, 127, 0, 1, 256, 508}, 50 {128, 255, 0, 1, 512, 1020}, 51 {256, 511, 0, 1, 1024, 2044}, 52 {512, 1023, 0, 1, 2048, 4092}, 53 {512, 1023, 1, 2, 4096, 8184}, 54 {512, 1023, 2, 4, 8192, 16368}, 55 {512, 1023, 3, 8, 16384, 32736}, 56 {512, 1023, 4, 16, 32768, 65472}, 57 {512, 1023, 5, 32, 65536, 130944}, 58 {512, 1023, 6, 64, 131072, 261888}, 59 {512, 1023, 7, 128, 262144, 523776}, 60 {512, 1023, 8, 256, 524288, 1047552}, 61 {512, 1023, 9, 512, 1048576, 2095104}, 62 {512, 1023, 10, 1024, 2097152, 4190208}, 63 {512, 1023, 11, 2048, 4194304, 8380416}, 64 {512, 1023, 12, 4096, 8388608, 16760832}, 65 {512, 1023, 13, 8192, 16777216, 33521664}, 66 {512, 1023, 14, 16384, 33554432, 67043328}, 67 {512, 1023, 15, 32768, 67108864, 134086656}, 68 }; 69 70 #define IPN3KE_TM_SHAPER_RANGE_NUM (sizeof(ipn3ke_tm_shaper_params_rang) / \ 71 sizeof(struct ipn3ke_tm_shaper_params_range_type)) 72 73 #define IPN3KE_TM_SHAPER_COMMITTED_RATE_MAX \ 74 (ipn3ke_tm_shaper_params_rang[IPN3KE_TM_SHAPER_RANGE_NUM - 1].high) 75 76 #define IPN3KE_TM_SHAPER_PEAK_RATE_MAX \ 77 (ipn3ke_tm_shaper_params_rang[IPN3KE_TM_SHAPER_RANGE_NUM - 1].high) 78 79 int 80 ipn3ke_hw_tm_init(struct ipn3ke_hw *hw) 81 { 82 #define SCRATCH_DATA 0xABCDEF 83 struct ipn3ke_tm_node *nodes; 84 struct ipn3ke_tm_tdrop_profile *tdrop_profile; 85 int node_num; 86 int i; 87 88 if (hw == NULL) 89 return -EINVAL; 90 #if IPN3KE_TM_SCRATCH_RW 91 uint32_t scratch_data; 92 IPN3KE_MASK_WRITE_REG(hw, 93 IPN3KE_TM_SCRATCH, 94 0, 95 SCRATCH_DATA, 96 0xFFFFFFFF); 97 scratch_data = IPN3KE_MASK_READ_REG(hw, 98 IPN3KE_TM_SCRATCH, 99 0, 100 0xFFFFFFFF); 101 if (scratch_data != SCRATCH_DATA) 102 return -EINVAL; 103 #endif 104 /* alloc memory for all hierarchy nodes */ 105 node_num = hw->port_num + 106 IPN3KE_TM_VT_NODE_NUM + 107 IPN3KE_TM_COS_NODE_NUM; 108 109 nodes = rte_zmalloc("ipn3ke_tm_nodes", 110 sizeof(struct ipn3ke_tm_node) * node_num, 111 0); 112 if (!nodes) 113 return -ENOMEM; 114 115 /* alloc memory for Tail Drop Profile */ 116 tdrop_profile = rte_zmalloc("ipn3ke_tm_tdrop_profile", 117 sizeof(struct ipn3ke_tm_tdrop_profile) * 118 IPN3KE_TM_TDROP_PROFILE_NUM, 119 0); 120 if (!tdrop_profile) { 121 rte_free(nodes); 122 return -ENOMEM; 123 } 124 125 hw->nodes = nodes; 126 hw->port_nodes = nodes; 127 hw->vt_nodes = hw->port_nodes + hw->port_num; 128 hw->cos_nodes = hw->vt_nodes + IPN3KE_TM_VT_NODE_NUM; 129 hw->tdrop_profile = tdrop_profile; 130 hw->tdrop_profile_num = IPN3KE_TM_TDROP_PROFILE_NUM; 131 132 for (i = 0, nodes = hw->port_nodes; 133 i < hw->port_num; 134 i++, nodes++) { 135 nodes->node_index = i; 136 nodes->level = IPN3KE_TM_NODE_LEVEL_PORT; 137 nodes->tm_id = RTE_TM_NODE_ID_NULL; 138 nodes->node_state = IPN3KE_TM_NODE_STATE_IDLE; 139 nodes->parent_node_id = RTE_TM_NODE_ID_NULL; 140 nodes->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0; 141 nodes->weight = 0; 142 nodes->parent_node = NULL; 143 nodes->shaper_profile.valid = 0; 144 nodes->tdrop_profile = NULL; 145 nodes->n_children = 0; 146 TAILQ_INIT(&nodes->children_node_list); 147 } 148 149 for (i = 0, nodes = hw->vt_nodes; 150 i < IPN3KE_TM_VT_NODE_NUM; 151 i++, nodes++) { 152 nodes->node_index = i; 153 nodes->level = IPN3KE_TM_NODE_LEVEL_VT; 154 nodes->tm_id = RTE_TM_NODE_ID_NULL; 155 nodes->node_state = IPN3KE_TM_NODE_STATE_IDLE; 156 nodes->parent_node_id = RTE_TM_NODE_ID_NULL; 157 nodes->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0; 158 nodes->weight = 0; 159 nodes->parent_node = NULL; 160 nodes->shaper_profile.valid = 0; 161 nodes->tdrop_profile = NULL; 162 nodes->n_children = 0; 163 TAILQ_INIT(&nodes->children_node_list); 164 } 165 166 for (i = 0, nodes = hw->cos_nodes; 167 i < IPN3KE_TM_COS_NODE_NUM; 168 i++, nodes++) { 169 nodes->node_index = i; 170 nodes->level = IPN3KE_TM_NODE_LEVEL_COS; 171 nodes->tm_id = RTE_TM_NODE_ID_NULL; 172 nodes->node_state = IPN3KE_TM_NODE_STATE_IDLE; 173 nodes->parent_node_id = RTE_TM_NODE_ID_NULL; 174 nodes->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0; 175 nodes->weight = 0; 176 nodes->parent_node = NULL; 177 nodes->shaper_profile.valid = 0; 178 nodes->tdrop_profile = NULL; 179 nodes->n_children = 0; 180 TAILQ_INIT(&nodes->children_node_list); 181 } 182 183 for (i = 0, tdrop_profile = hw->tdrop_profile; 184 i < IPN3KE_TM_TDROP_PROFILE_NUM; 185 i++, tdrop_profile++) { 186 tdrop_profile->tdrop_profile_id = i; 187 tdrop_profile->n_users = 0; 188 tdrop_profile->valid = 0; 189 } 190 191 return 0; 192 } 193 194 void 195 ipn3ke_tm_init(struct ipn3ke_rpst *rpst) 196 { 197 struct ipn3ke_tm_internals *tm; 198 struct ipn3ke_tm_node *port_node; 199 200 tm = &rpst->tm; 201 202 port_node = &rpst->hw->port_nodes[rpst->port_id]; 203 tm->h.port_node = port_node; 204 205 tm->h.n_shaper_profiles = 0; 206 tm->h.n_tdrop_profiles = 0; 207 tm->h.n_vt_nodes = 0; 208 tm->h.n_cos_nodes = 0; 209 210 tm->h.port_commit_node = NULL; 211 TAILQ_INIT(&tm->h.vt_commit_node_list); 212 TAILQ_INIT(&tm->h.cos_commit_node_list); 213 214 tm->hierarchy_frozen = 0; 215 tm->tm_started = 1; 216 tm->tm_id = rpst->port_id; 217 } 218 219 static struct ipn3ke_tm_shaper_profile * 220 ipn3ke_hw_tm_shaper_profile_search(struct ipn3ke_hw *hw, 221 uint32_t shaper_profile_id, struct rte_tm_error *error) 222 { 223 struct ipn3ke_tm_shaper_profile *sp = NULL; 224 uint32_t level_of_node_id; 225 uint32_t node_index; 226 227 /* Shaper profile ID must not be NONE. */ 228 if (shaper_profile_id == RTE_TM_SHAPER_PROFILE_ID_NONE) { 229 rte_tm_error_set(error, 230 EINVAL, 231 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID, 232 NULL, 233 rte_strerror(EINVAL)); 234 235 return NULL; 236 } 237 238 level_of_node_id = shaper_profile_id / IPN3KE_TM_NODE_LEVEL_MOD; 239 node_index = shaper_profile_id % IPN3KE_TM_NODE_LEVEL_MOD; 240 241 switch (level_of_node_id) { 242 case IPN3KE_TM_NODE_LEVEL_PORT: 243 if (node_index >= hw->port_num) 244 rte_tm_error_set(error, 245 EEXIST, 246 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID, 247 NULL, 248 rte_strerror(EEXIST)); 249 else 250 sp = &hw->port_nodes[node_index].shaper_profile; 251 252 break; 253 254 case IPN3KE_TM_NODE_LEVEL_VT: 255 if (node_index >= IPN3KE_TM_VT_NODE_NUM) 256 rte_tm_error_set(error, 257 EEXIST, 258 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID, 259 NULL, 260 rte_strerror(EEXIST)); 261 else 262 sp = &hw->vt_nodes[node_index].shaper_profile; 263 264 break; 265 266 case IPN3KE_TM_NODE_LEVEL_COS: 267 if (node_index >= IPN3KE_TM_COS_NODE_NUM) 268 rte_tm_error_set(error, 269 EEXIST, 270 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID, 271 NULL, 272 rte_strerror(EEXIST)); 273 else 274 sp = &hw->cos_nodes[node_index].shaper_profile; 275 276 break; 277 default: 278 rte_tm_error_set(error, 279 EEXIST, 280 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID, 281 NULL, 282 rte_strerror(EEXIST)); 283 } 284 285 return sp; 286 } 287 288 static struct ipn3ke_tm_tdrop_profile * 289 ipn3ke_hw_tm_tdrop_profile_search(struct ipn3ke_hw *hw, 290 uint32_t tdrop_profile_id) 291 { 292 struct ipn3ke_tm_tdrop_profile *tdrop_profile; 293 294 if (tdrop_profile_id >= hw->tdrop_profile_num) 295 return NULL; 296 297 tdrop_profile = &hw->tdrop_profile[tdrop_profile_id]; 298 if (tdrop_profile->valid) 299 return tdrop_profile; 300 301 return NULL; 302 } 303 304 static struct ipn3ke_tm_node * 305 ipn3ke_hw_tm_node_search(struct ipn3ke_hw *hw, uint32_t tm_id, 306 uint32_t node_id, uint32_t state_mask) 307 { 308 uint32_t level_of_node_id; 309 uint32_t node_index; 310 struct ipn3ke_tm_node *n; 311 312 level_of_node_id = node_id / IPN3KE_TM_NODE_LEVEL_MOD; 313 node_index = node_id % IPN3KE_TM_NODE_LEVEL_MOD; 314 315 switch (level_of_node_id) { 316 case IPN3KE_TM_NODE_LEVEL_PORT: 317 if (node_index >= hw->port_num) 318 return NULL; 319 n = &hw->port_nodes[node_index]; 320 321 break; 322 case IPN3KE_TM_NODE_LEVEL_VT: 323 if (node_index >= IPN3KE_TM_VT_NODE_NUM) 324 return NULL; 325 n = &hw->vt_nodes[node_index]; 326 327 break; 328 case IPN3KE_TM_NODE_LEVEL_COS: 329 if (node_index >= IPN3KE_TM_COS_NODE_NUM) 330 return NULL; 331 n = &hw->cos_nodes[node_index]; 332 333 break; 334 default: 335 return NULL; 336 } 337 338 /* Check tm node status */ 339 if (n->node_state == IPN3KE_TM_NODE_STATE_IDLE) { 340 if (n->tm_id != RTE_TM_NODE_ID_NULL || 341 n->parent_node_id != RTE_TM_NODE_ID_NULL || 342 n->parent_node != NULL || 343 n->n_children > 0) { 344 IPN3KE_AFU_PMD_ERR("tm node check error %d", 1); 345 } 346 } else if (n->node_state < IPN3KE_TM_NODE_STATE_MAX) { 347 if (n->tm_id == RTE_TM_NODE_ID_NULL || 348 (level_of_node_id != IPN3KE_TM_NODE_LEVEL_PORT && 349 n->parent_node_id == RTE_TM_NODE_ID_NULL) || 350 (level_of_node_id != IPN3KE_TM_NODE_LEVEL_PORT && 351 n->parent_node == NULL)) { 352 IPN3KE_AFU_PMD_ERR("tm node check error %d", 1); 353 } 354 } else { 355 IPN3KE_AFU_PMD_ERR("tm node check error %d", 1); 356 } 357 358 if (IPN3KE_BIT_ISSET(state_mask, n->node_state)) { 359 if (n->node_state == IPN3KE_TM_NODE_STATE_IDLE) 360 return n; 361 else if (n->tm_id == tm_id) 362 return n; 363 else 364 return NULL; 365 } else { 366 return NULL; 367 } 368 } 369 370 /* Traffic manager node type get */ 371 static int 372 ipn3ke_pmd_tm_node_type_get(struct rte_eth_dev *dev, 373 uint32_t node_id, int *is_leaf, struct rte_tm_error *error) 374 { 375 struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev); 376 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 377 uint32_t tm_id; 378 struct ipn3ke_tm_node *node; 379 uint32_t state_mask; 380 381 if (is_leaf == NULL) 382 return -rte_tm_error_set(error, 383 EINVAL, 384 RTE_TM_ERROR_TYPE_UNSPECIFIED, 385 NULL, 386 rte_strerror(EINVAL)); 387 388 tm_id = tm->tm_id; 389 390 state_mask = 0; 391 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_COMMITTED); 392 node = ipn3ke_hw_tm_node_search(hw, tm_id, node_id, state_mask); 393 if (node_id == RTE_TM_NODE_ID_NULL || 394 node == NULL) 395 return -rte_tm_error_set(error, 396 EINVAL, 397 RTE_TM_ERROR_TYPE_NODE_ID, 398 NULL, 399 rte_strerror(EINVAL)); 400 401 *is_leaf = (node->level == IPN3KE_TM_NODE_LEVEL_COS) ? 1 : 0; 402 403 return 0; 404 } 405 406 #define WRED_SUPPORTED 0 407 408 #define STATS_MASK_DEFAULT \ 409 (RTE_TM_STATS_N_PKTS | \ 410 RTE_TM_STATS_N_BYTES | \ 411 RTE_TM_STATS_N_PKTS_GREEN_DROPPED | \ 412 RTE_TM_STATS_N_BYTES_GREEN_DROPPED) 413 414 #define STATS_MASK_QUEUE \ 415 (STATS_MASK_DEFAULT | RTE_TM_STATS_N_PKTS_QUEUED) 416 417 /* Traffic manager capabilities get */ 418 static int 419 ipn3ke_tm_capabilities_get(__rte_unused struct rte_eth_dev *dev, 420 struct rte_tm_capabilities *cap, struct rte_tm_error *error) 421 { 422 if (cap == NULL) 423 return -rte_tm_error_set(error, 424 EINVAL, 425 RTE_TM_ERROR_TYPE_CAPABILITIES, 426 NULL, 427 rte_strerror(EINVAL)); 428 429 /* set all the parameters to 0 first. */ 430 memset(cap, 0, sizeof(*cap)); 431 432 cap->n_nodes_max = 1 + IPN3KE_TM_COS_NODE_NUM + IPN3KE_TM_VT_NODE_NUM; 433 cap->n_levels_max = IPN3KE_TM_NODE_LEVEL_MAX; 434 435 cap->non_leaf_nodes_identical = 0; 436 cap->leaf_nodes_identical = 1; 437 438 cap->shaper_n_max = 1 + IPN3KE_TM_VT_NODE_NUM; 439 cap->shaper_private_n_max = 1 + IPN3KE_TM_VT_NODE_NUM; 440 cap->shaper_private_dual_rate_n_max = 0; 441 cap->shaper_private_rate_min = 1; 442 cap->shaper_private_rate_max = 1 + IPN3KE_TM_VT_NODE_NUM; 443 cap->shaper_private_packet_mode_supported = 0; 444 cap->shaper_private_byte_mode_supported = 1; 445 446 cap->shaper_shared_n_max = 0; 447 cap->shaper_shared_n_nodes_per_shaper_max = 0; 448 cap->shaper_shared_n_shapers_per_node_max = 0; 449 cap->shaper_shared_dual_rate_n_max = 0; 450 cap->shaper_shared_rate_min = 0; 451 cap->shaper_shared_rate_max = 0; 452 cap->shaper_shared_packet_mode_supported = 0; 453 cap->shaper_shared_byte_mode_supported = 0; 454 455 cap->shaper_pkt_length_adjust_min = RTE_TM_ETH_FRAMING_OVERHEAD_FCS; 456 cap->shaper_pkt_length_adjust_max = RTE_TM_ETH_FRAMING_OVERHEAD_FCS; 457 458 cap->sched_n_children_max = IPN3KE_TM_COS_NODE_NUM; 459 cap->sched_sp_n_priorities_max = 3; 460 cap->sched_wfq_n_children_per_group_max = UINT32_MAX; 461 cap->sched_wfq_n_groups_max = 1; 462 cap->sched_wfq_weight_max = UINT32_MAX; 463 cap->sched_wfq_packet_mode_supported = 0; 464 cap->sched_wfq_byte_mode_supported = 1; 465 466 cap->cman_wred_packet_mode_supported = 0; 467 cap->cman_wred_byte_mode_supported = 0; 468 cap->cman_head_drop_supported = 0; 469 cap->cman_wred_context_n_max = 0; 470 cap->cman_wred_context_private_n_max = 0; 471 cap->cman_wred_context_shared_n_max = 0; 472 cap->cman_wred_context_shared_n_nodes_per_context_max = 0; 473 cap->cman_wred_context_shared_n_contexts_per_node_max = 0; 474 475 /** 476 * cap->mark_vlan_dei_supported = {0, 0, 0}; 477 * cap->mark_ip_ecn_tcp_supported = {0, 0, 0}; 478 * cap->mark_ip_ecn_sctp_supported = {0, 0, 0}; 479 * cap->mark_ip_dscp_supported = {0, 0, 0}; 480 */ 481 482 cap->dynamic_update_mask = 0; 483 484 cap->stats_mask = 0; 485 486 return 0; 487 } 488 489 /* Traffic manager level capabilities get */ 490 static int 491 ipn3ke_tm_level_capabilities_get(struct rte_eth_dev *dev, 492 uint32_t level_id, struct rte_tm_level_capabilities *cap, 493 struct rte_tm_error *error) 494 { 495 struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev); 496 497 if (cap == NULL) 498 return -rte_tm_error_set(error, 499 EINVAL, 500 RTE_TM_ERROR_TYPE_CAPABILITIES, 501 NULL, 502 rte_strerror(EINVAL)); 503 504 if (level_id >= IPN3KE_TM_NODE_LEVEL_MAX) 505 return -rte_tm_error_set(error, 506 EINVAL, 507 RTE_TM_ERROR_TYPE_LEVEL_ID, 508 NULL, 509 rte_strerror(EINVAL)); 510 511 /* set all the parameters to 0 first. */ 512 memset(cap, 0, sizeof(*cap)); 513 514 switch (level_id) { 515 case IPN3KE_TM_NODE_LEVEL_PORT: 516 cap->n_nodes_max = hw->port_num; 517 cap->n_nodes_nonleaf_max = IPN3KE_TM_VT_NODE_NUM; 518 cap->n_nodes_leaf_max = 0; 519 cap->non_leaf_nodes_identical = 0; 520 cap->leaf_nodes_identical = 0; 521 522 cap->nonleaf.shaper_private_supported = 0; 523 cap->nonleaf.shaper_private_dual_rate_supported = 0; 524 cap->nonleaf.shaper_private_rate_min = 1; 525 cap->nonleaf.shaper_private_rate_max = UINT32_MAX; 526 cap->nonleaf.shaper_private_packet_mode_supported = 0; 527 cap->nonleaf.shaper_private_byte_mode_supported = 1; 528 cap->nonleaf.shaper_shared_n_max = 0; 529 cap->nonleaf.shaper_shared_packet_mode_supported = 0; 530 cap->nonleaf.shaper_shared_byte_mode_supported = 0; 531 532 cap->nonleaf.sched_n_children_max = IPN3KE_TM_VT_NODE_NUM; 533 cap->nonleaf.sched_sp_n_priorities_max = 1; 534 cap->nonleaf.sched_wfq_n_children_per_group_max = 0; 535 cap->nonleaf.sched_wfq_n_groups_max = 0; 536 cap->nonleaf.sched_wfq_weight_max = 0; 537 cap->nonleaf.sched_wfq_packet_mode_supported = 0; 538 cap->nonleaf.sched_wfq_byte_mode_supported = 0; 539 540 cap->nonleaf.stats_mask = STATS_MASK_DEFAULT; 541 break; 542 543 case IPN3KE_TM_NODE_LEVEL_VT: 544 cap->n_nodes_max = IPN3KE_TM_VT_NODE_NUM; 545 cap->n_nodes_nonleaf_max = IPN3KE_TM_COS_NODE_NUM; 546 cap->n_nodes_leaf_max = 0; 547 cap->non_leaf_nodes_identical = 0; 548 cap->leaf_nodes_identical = 0; 549 550 cap->nonleaf.shaper_private_supported = 0; 551 cap->nonleaf.shaper_private_dual_rate_supported = 0; 552 cap->nonleaf.shaper_private_rate_min = 1; 553 cap->nonleaf.shaper_private_rate_max = UINT32_MAX; 554 cap->nonleaf.shaper_private_packet_mode_supported = 0; 555 cap->nonleaf.shaper_private_byte_mode_supported = 1; 556 cap->nonleaf.shaper_shared_n_max = 0; 557 cap->nonleaf.shaper_shared_packet_mode_supported = 0; 558 cap->nonleaf.shaper_shared_byte_mode_supported = 0; 559 560 cap->nonleaf.sched_n_children_max = IPN3KE_TM_COS_NODE_NUM; 561 cap->nonleaf.sched_sp_n_priorities_max = 1; 562 cap->nonleaf.sched_wfq_n_children_per_group_max = 0; 563 cap->nonleaf.sched_wfq_n_groups_max = 0; 564 cap->nonleaf.sched_wfq_weight_max = 0; 565 cap->nonleaf.sched_wfq_packet_mode_supported = 0; 566 cap->nonleaf.sched_wfq_byte_mode_supported = 0; 567 568 cap->nonleaf.stats_mask = STATS_MASK_DEFAULT; 569 break; 570 571 case IPN3KE_TM_NODE_LEVEL_COS: 572 cap->n_nodes_max = IPN3KE_TM_COS_NODE_NUM; 573 cap->n_nodes_nonleaf_max = 0; 574 cap->n_nodes_leaf_max = IPN3KE_TM_COS_NODE_NUM; 575 cap->non_leaf_nodes_identical = 0; 576 cap->leaf_nodes_identical = 0; 577 578 cap->leaf.shaper_private_supported = 0; 579 cap->leaf.shaper_private_dual_rate_supported = 0; 580 cap->leaf.shaper_private_rate_min = 0; 581 cap->leaf.shaper_private_rate_max = 0; 582 cap->leaf.shaper_private_packet_mode_supported = 0; 583 cap->leaf.shaper_private_byte_mode_supported = 1; 584 cap->leaf.shaper_shared_n_max = 0; 585 cap->leaf.shaper_shared_packet_mode_supported = 0; 586 cap->leaf.shaper_shared_byte_mode_supported = 0; 587 588 cap->leaf.cman_head_drop_supported = 0; 589 cap->leaf.cman_wred_packet_mode_supported = WRED_SUPPORTED; 590 cap->leaf.cman_wred_byte_mode_supported = 0; 591 cap->leaf.cman_wred_context_private_supported = WRED_SUPPORTED; 592 cap->leaf.cman_wred_context_shared_n_max = 0; 593 594 cap->leaf.stats_mask = STATS_MASK_QUEUE; 595 break; 596 597 default: 598 return -rte_tm_error_set(error, 599 EINVAL, 600 RTE_TM_ERROR_TYPE_LEVEL_ID, 601 NULL, 602 rte_strerror(EINVAL)); 603 break; 604 } 605 606 return 0; 607 } 608 609 /* Traffic manager node capabilities get */ 610 static int 611 ipn3ke_tm_node_capabilities_get(struct rte_eth_dev *dev, 612 uint32_t node_id, struct rte_tm_node_capabilities *cap, 613 struct rte_tm_error *error) 614 { 615 struct ipn3ke_rpst *representor = IPN3KE_DEV_PRIVATE_TO_RPST(dev); 616 struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev); 617 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 618 uint32_t tm_id; 619 struct ipn3ke_tm_node *tm_node; 620 uint32_t state_mask; 621 622 if (cap == NULL) 623 return -rte_tm_error_set(error, 624 EINVAL, 625 RTE_TM_ERROR_TYPE_CAPABILITIES, 626 NULL, 627 rte_strerror(EINVAL)); 628 629 tm_id = tm->tm_id; 630 631 state_mask = 0; 632 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_COMMITTED); 633 tm_node = ipn3ke_hw_tm_node_search(hw, tm_id, node_id, state_mask); 634 if (tm_node == NULL) 635 return -rte_tm_error_set(error, 636 EINVAL, 637 RTE_TM_ERROR_TYPE_NODE_ID, 638 NULL, 639 rte_strerror(EINVAL)); 640 641 if (tm_node->tm_id != representor->port_id) 642 return -rte_tm_error_set(error, 643 EINVAL, 644 RTE_TM_ERROR_TYPE_NODE_ID, 645 NULL, 646 rte_strerror(EINVAL)); 647 648 /* set all the parameters to 0 first. */ 649 memset(cap, 0, sizeof(*cap)); 650 651 switch (tm_node->level) { 652 case IPN3KE_TM_NODE_LEVEL_PORT: 653 cap->shaper_private_supported = 1; 654 cap->shaper_private_dual_rate_supported = 0; 655 cap->shaper_private_rate_min = 1; 656 cap->shaper_private_rate_max = UINT32_MAX; 657 cap->shaper_private_packet_mode_supported = 0; 658 cap->shaper_private_byte_mode_supported = 1; 659 cap->shaper_shared_n_max = 0; 660 cap->shaper_shared_packet_mode_supported = 0; 661 cap->shaper_shared_byte_mode_supported = 0; 662 663 cap->nonleaf.sched_n_children_max = IPN3KE_TM_VT_NODE_NUM; 664 cap->nonleaf.sched_sp_n_priorities_max = 1; 665 cap->nonleaf.sched_wfq_n_children_per_group_max = 666 IPN3KE_TM_VT_NODE_NUM; 667 cap->nonleaf.sched_wfq_n_groups_max = 1; 668 cap->nonleaf.sched_wfq_weight_max = 1; 669 cap->nonleaf.sched_wfq_packet_mode_supported = 0; 670 cap->nonleaf.sched_wfq_byte_mode_supported = 0; 671 672 cap->stats_mask = STATS_MASK_DEFAULT; 673 break; 674 675 case IPN3KE_TM_NODE_LEVEL_VT: 676 cap->shaper_private_supported = 1; 677 cap->shaper_private_dual_rate_supported = 0; 678 cap->shaper_private_rate_min = 1; 679 cap->shaper_private_rate_max = UINT32_MAX; 680 cap->shaper_private_packet_mode_supported = 0; 681 cap->shaper_private_byte_mode_supported = 1; 682 cap->shaper_shared_n_max = 0; 683 cap->shaper_shared_packet_mode_supported = 0; 684 cap->shaper_shared_byte_mode_supported = 0; 685 686 cap->nonleaf.sched_n_children_max = IPN3KE_TM_COS_NODE_NUM; 687 cap->nonleaf.sched_sp_n_priorities_max = 1; 688 cap->nonleaf.sched_wfq_n_children_per_group_max = 689 IPN3KE_TM_COS_NODE_NUM; 690 cap->nonleaf.sched_wfq_n_groups_max = 1; 691 cap->nonleaf.sched_wfq_weight_max = 1; 692 cap->nonleaf.sched_wfq_packet_mode_supported = 0; 693 cap->nonleaf.sched_wfq_byte_mode_supported = 0; 694 695 cap->stats_mask = STATS_MASK_DEFAULT; 696 break; 697 698 case IPN3KE_TM_NODE_LEVEL_COS: 699 cap->shaper_private_supported = 0; 700 cap->shaper_private_dual_rate_supported = 0; 701 cap->shaper_private_rate_min = 0; 702 cap->shaper_private_rate_max = 0; 703 cap->shaper_private_packet_mode_supported = 0; 704 cap->shaper_private_byte_mode_supported = 0; 705 cap->shaper_shared_n_max = 0; 706 cap->shaper_shared_packet_mode_supported = 0; 707 cap->shaper_shared_byte_mode_supported = 0; 708 709 cap->leaf.cman_head_drop_supported = 0; 710 cap->leaf.cman_wred_packet_mode_supported = WRED_SUPPORTED; 711 cap->leaf.cman_wred_byte_mode_supported = 0; 712 cap->leaf.cman_wred_context_private_supported = WRED_SUPPORTED; 713 cap->leaf.cman_wred_context_shared_n_max = 0; 714 715 cap->stats_mask = STATS_MASK_QUEUE; 716 break; 717 default: 718 break; 719 } 720 721 return 0; 722 } 723 724 static int 725 ipn3ke_tm_shaper_parame_trans(struct rte_tm_shaper_params *profile, 726 struct ipn3ke_tm_shaper_profile *local_profile, 727 const struct ipn3ke_tm_shaper_params_range_type *ref_data) 728 { 729 uint32_t i; 730 const struct ipn3ke_tm_shaper_params_range_type *r; 731 uint64_t rate; 732 733 rate = profile->peak.rate; 734 for (i = 0, r = ref_data; i < IPN3KE_TM_SHAPER_RANGE_NUM; i++, r++) { 735 if (rate >= r->low && 736 rate <= r->high) { 737 local_profile->m = (rate / 4) / r->exp2; 738 local_profile->e = r->exp; 739 local_profile->rate = rate; 740 741 return 0; 742 } 743 } 744 745 return -1; 746 } 747 748 static int 749 ipn3ke_tm_shaper_profile_add(struct rte_eth_dev *dev, 750 uint32_t shaper_profile_id, struct rte_tm_shaper_params *profile, 751 struct rte_tm_error *error) 752 { 753 struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev); 754 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 755 struct ipn3ke_tm_shaper_profile *sp; 756 757 /* Shaper profile must not exist. */ 758 sp = ipn3ke_hw_tm_shaper_profile_search(hw, shaper_profile_id, error); 759 if (!sp || (sp && sp->valid)) 760 return -rte_tm_error_set(error, 761 EEXIST, 762 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID, 763 NULL, 764 rte_strerror(EEXIST)); 765 766 /* Profile must not be NULL. */ 767 if (profile == NULL) 768 return -rte_tm_error_set(error, 769 EINVAL, 770 RTE_TM_ERROR_TYPE_SHAPER_PROFILE, 771 NULL, 772 rte_strerror(EINVAL)); 773 774 /* Peak rate: non-zero, 32-bit */ 775 if (profile->peak.rate == 0 || 776 profile->peak.rate > IPN3KE_TM_SHAPER_PEAK_RATE_MAX) 777 return -rte_tm_error_set(error, 778 EINVAL, 779 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE, 780 NULL, 781 rte_strerror(EINVAL)); 782 783 /* Peak size: non-zero, 32-bit */ 784 if (profile->peak.size != 0) 785 return -rte_tm_error_set(error, 786 EINVAL, 787 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE, 788 NULL, 789 rte_strerror(EINVAL)); 790 791 /* Dual-rate profiles are not supported. */ 792 if (profile->committed.rate > IPN3KE_TM_SHAPER_COMMITTED_RATE_MAX) 793 return -rte_tm_error_set(error, 794 EINVAL, 795 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_RATE, 796 NULL, 797 rte_strerror(EINVAL)); 798 799 /* Packet length adjust: 24 bytes */ 800 if (profile->pkt_length_adjust != 0) 801 return -rte_tm_error_set(error, 802 EINVAL, 803 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PKT_ADJUST_LEN, 804 NULL, 805 rte_strerror(EINVAL)); 806 807 if (ipn3ke_tm_shaper_parame_trans(profile, 808 sp, 809 ipn3ke_tm_shaper_params_rang)) { 810 return -rte_tm_error_set(error, 811 EINVAL, 812 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE, 813 NULL, 814 rte_strerror(EINVAL)); 815 } else { 816 sp->valid = 1; 817 rte_memcpy(&sp->params, profile, sizeof(sp->params)); 818 } 819 820 tm->h.n_shaper_profiles++; 821 822 return 0; 823 } 824 825 /* Traffic manager shaper profile delete */ 826 static int 827 ipn3ke_tm_shaper_profile_delete(struct rte_eth_dev *dev, 828 uint32_t shaper_profile_id, struct rte_tm_error *error) 829 { 830 struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev); 831 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 832 struct ipn3ke_tm_shaper_profile *sp; 833 834 /* Check existing */ 835 sp = ipn3ke_hw_tm_shaper_profile_search(hw, shaper_profile_id, error); 836 if (!sp || (sp && !sp->valid)) 837 return -rte_tm_error_set(error, 838 EINVAL, 839 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID, 840 NULL, 841 rte_strerror(EINVAL)); 842 843 sp->valid = 0; 844 tm->h.n_shaper_profiles--; 845 846 return 0; 847 } 848 849 static int 850 ipn3ke_tm_tdrop_profile_check(__rte_unused struct rte_eth_dev *dev, 851 uint32_t tdrop_profile_id, struct rte_tm_wred_params *profile, 852 struct rte_tm_error *error) 853 { 854 enum rte_color color; 855 856 /* TDROP profile ID must not be NONE. */ 857 if (tdrop_profile_id == RTE_TM_WRED_PROFILE_ID_NONE) 858 return -rte_tm_error_set(error, 859 EINVAL, 860 RTE_TM_ERROR_TYPE_WRED_PROFILE_ID, 861 NULL, 862 rte_strerror(EINVAL)); 863 864 /* Profile must not be NULL. */ 865 if (profile == NULL) 866 return -rte_tm_error_set(error, 867 EINVAL, 868 RTE_TM_ERROR_TYPE_WRED_PROFILE, 869 NULL, 870 rte_strerror(EINVAL)); 871 872 /* TDROP profile should be in packet mode */ 873 if (profile->packet_mode != 0) 874 return -rte_tm_error_set(error, 875 ENOTSUP, 876 RTE_TM_ERROR_TYPE_WRED_PROFILE, 877 NULL, 878 rte_strerror(ENOTSUP)); 879 880 /* min_th <= max_th, max_th > 0 */ 881 for (color = RTE_COLOR_GREEN; color <= RTE_COLOR_GREEN; color++) { 882 uint64_t min_th = profile->red_params[color].min_th; 883 uint64_t max_th = profile->red_params[color].max_th; 884 885 if (((min_th >> IPN3KE_TDROP_TH1_SHIFT) >> 886 IPN3KE_TDROP_TH1_SHIFT) || 887 max_th != 0) 888 return -rte_tm_error_set(error, 889 EINVAL, 890 RTE_TM_ERROR_TYPE_WRED_PROFILE, 891 NULL, 892 rte_strerror(EINVAL)); 893 } 894 895 return 0; 896 } 897 898 static int 899 ipn3ke_hw_tm_tdrop_wr(struct ipn3ke_hw *hw, 900 struct ipn3ke_tm_tdrop_profile *tp) 901 { 902 if (tp->valid) { 903 IPN3KE_MASK_WRITE_REG(hw, 904 IPN3KE_CCB_PROFILE_MS, 905 0, 906 tp->th2, 907 IPN3KE_CCB_PROFILE_MS_MASK); 908 909 IPN3KE_MASK_WRITE_REG(hw, 910 IPN3KE_CCB_PROFILE_P, 911 tp->tdrop_profile_id, 912 tp->th1, 913 IPN3KE_CCB_PROFILE_MASK); 914 } else { 915 IPN3KE_MASK_WRITE_REG(hw, 916 IPN3KE_CCB_PROFILE_MS, 917 0, 918 0, 919 IPN3KE_CCB_PROFILE_MS_MASK); 920 921 IPN3KE_MASK_WRITE_REG(hw, 922 IPN3KE_CCB_PROFILE_P, 923 tp->tdrop_profile_id, 924 0, 925 IPN3KE_CCB_PROFILE_MASK); 926 } 927 928 return 0; 929 } 930 931 /* Traffic manager TDROP profile add */ 932 static int 933 ipn3ke_tm_tdrop_profile_add(struct rte_eth_dev *dev, 934 uint32_t tdrop_profile_id, struct rte_tm_wred_params *profile, 935 struct rte_tm_error *error) 936 { 937 struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev); 938 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 939 struct ipn3ke_tm_tdrop_profile *tp; 940 int status; 941 uint64_t min_th; 942 uint32_t th1, th2; 943 944 /* Check input params */ 945 status = ipn3ke_tm_tdrop_profile_check(dev, 946 tdrop_profile_id, 947 profile, 948 error); 949 if (status) 950 return status; 951 952 /* Memory allocation */ 953 tp = &hw->tdrop_profile[tdrop_profile_id]; 954 955 /* Fill in */ 956 tp->valid = 1; 957 min_th = profile->red_params[RTE_COLOR_GREEN].min_th; 958 th1 = (uint32_t)(min_th & IPN3KE_TDROP_TH1_MASK); 959 th2 = (uint32_t)((min_th >> IPN3KE_TDROP_TH1_SHIFT) & 960 IPN3KE_TDROP_TH2_MASK); 961 tp->th1 = th1; 962 tp->th2 = th2; 963 rte_memcpy(&tp->params, profile, sizeof(tp->params)); 964 965 /* Add to list */ 966 tm->h.n_tdrop_profiles++; 967 968 /* Write FPGA */ 969 ipn3ke_hw_tm_tdrop_wr(hw, tp); 970 971 return 0; 972 } 973 974 /* Traffic manager TDROP profile delete */ 975 static int 976 ipn3ke_tm_tdrop_profile_delete(struct rte_eth_dev *dev, 977 uint32_t tdrop_profile_id, struct rte_tm_error *error) 978 { 979 struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev); 980 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 981 struct ipn3ke_tm_tdrop_profile *tp; 982 983 /* Check existing */ 984 tp = ipn3ke_hw_tm_tdrop_profile_search(hw, tdrop_profile_id); 985 if (tp == NULL) 986 return -rte_tm_error_set(error, 987 EINVAL, 988 RTE_TM_ERROR_TYPE_WRED_PROFILE_ID, 989 NULL, 990 rte_strerror(EINVAL)); 991 992 /* Check unused */ 993 if (tp->n_users) 994 return -rte_tm_error_set(error, 995 EBUSY, 996 RTE_TM_ERROR_TYPE_WRED_PROFILE_ID, 997 NULL, 998 rte_strerror(EBUSY)); 999 1000 /* Set free */ 1001 tp->valid = 0; 1002 tm->h.n_tdrop_profiles--; 1003 1004 /* Write FPGA */ 1005 ipn3ke_hw_tm_tdrop_wr(hw, tp); 1006 1007 return 0; 1008 } 1009 1010 static int 1011 ipn3ke_tm_node_add_check_parameter(uint32_t tm_id, 1012 uint32_t node_id, uint32_t parent_node_id, uint32_t priority, 1013 uint32_t weight, uint32_t level_id, struct rte_tm_node_params *params, 1014 struct rte_tm_error *error) 1015 { 1016 uint32_t level_of_node_id; 1017 uint32_t node_index; 1018 uint32_t parent_level_id; 1019 1020 if (node_id == RTE_TM_NODE_ID_NULL) 1021 return -rte_tm_error_set(error, 1022 EINVAL, 1023 RTE_TM_ERROR_TYPE_NODE_ID, 1024 NULL, 1025 rte_strerror(EINVAL)); 1026 1027 /* priority: must be 0, 1, 2, 3 */ 1028 if (priority > IPN3KE_TM_NODE_PRIORITY_HIGHEST) 1029 return -rte_tm_error_set(error, 1030 EINVAL, 1031 RTE_TM_ERROR_TYPE_NODE_PRIORITY, 1032 NULL, 1033 rte_strerror(EINVAL)); 1034 1035 /* weight: must be 1 .. 255 */ 1036 if (weight > IPN3KE_TM_NODE_WEIGHT_MAX) 1037 return -rte_tm_error_set(error, 1038 EINVAL, 1039 RTE_TM_ERROR_TYPE_NODE_WEIGHT, 1040 NULL, 1041 rte_strerror(EINVAL)); 1042 1043 /* check node id and parent id*/ 1044 level_of_node_id = node_id / IPN3KE_TM_NODE_LEVEL_MOD; 1045 if (level_of_node_id != level_id) 1046 return -rte_tm_error_set(error, 1047 EINVAL, 1048 RTE_TM_ERROR_TYPE_NODE_ID, 1049 NULL, 1050 rte_strerror(EINVAL)); 1051 node_index = node_id % IPN3KE_TM_NODE_LEVEL_MOD; 1052 parent_level_id = parent_node_id / IPN3KE_TM_NODE_LEVEL_MOD; 1053 switch (level_id) { 1054 case IPN3KE_TM_NODE_LEVEL_PORT: 1055 if (node_index != tm_id) 1056 return -rte_tm_error_set(error, 1057 EINVAL, 1058 RTE_TM_ERROR_TYPE_NODE_ID, 1059 NULL, 1060 rte_strerror(EINVAL)); 1061 if (parent_node_id != RTE_TM_NODE_ID_NULL) 1062 return -rte_tm_error_set(error, 1063 EINVAL, 1064 RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID, 1065 NULL, 1066 rte_strerror(EINVAL)); 1067 break; 1068 1069 case IPN3KE_TM_NODE_LEVEL_VT: 1070 if (node_index >= IPN3KE_TM_VT_NODE_NUM) 1071 return -rte_tm_error_set(error, 1072 EINVAL, 1073 RTE_TM_ERROR_TYPE_NODE_ID, 1074 NULL, 1075 rte_strerror(EINVAL)); 1076 if (parent_level_id != IPN3KE_TM_NODE_LEVEL_PORT) 1077 return -rte_tm_error_set(error, 1078 EINVAL, 1079 RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID, 1080 NULL, 1081 rte_strerror(EINVAL)); 1082 break; 1083 1084 case IPN3KE_TM_NODE_LEVEL_COS: 1085 if (node_index >= IPN3KE_TM_COS_NODE_NUM) 1086 return -rte_tm_error_set(error, 1087 EINVAL, 1088 RTE_TM_ERROR_TYPE_NODE_ID, 1089 NULL, 1090 rte_strerror(EINVAL)); 1091 if (parent_level_id != IPN3KE_TM_NODE_LEVEL_VT) 1092 return -rte_tm_error_set(error, 1093 EINVAL, 1094 RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID, 1095 NULL, 1096 rte_strerror(EINVAL)); 1097 break; 1098 default: 1099 return -rte_tm_error_set(error, 1100 EINVAL, 1101 RTE_TM_ERROR_TYPE_LEVEL_ID, 1102 NULL, 1103 rte_strerror(EINVAL)); 1104 } 1105 1106 /* params: must not be NULL */ 1107 if (params == NULL) 1108 return -rte_tm_error_set(error, 1109 EINVAL, 1110 RTE_TM_ERROR_TYPE_NODE_PARAMS, 1111 NULL, 1112 rte_strerror(EINVAL)); 1113 /* No shared shapers */ 1114 if (params->n_shared_shapers != 0) 1115 return -rte_tm_error_set(error, 1116 EINVAL, 1117 RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_SHAPERS, 1118 NULL, 1119 rte_strerror(EINVAL)); 1120 return 0; 1121 } 1122 1123 static int 1124 ipn3ke_tm_node_add_check_mount(uint32_t tm_id, 1125 uint32_t node_id, uint32_t parent_node_id, uint32_t level_id, 1126 struct rte_tm_error *error) 1127 { 1128 uint32_t node_index; 1129 uint32_t parent_index; 1130 uint32_t parent_index1; 1131 1132 node_index = node_id % IPN3KE_TM_NODE_LEVEL_MOD; 1133 parent_index = parent_node_id % IPN3KE_TM_NODE_LEVEL_MOD; 1134 parent_index1 = node_index / IPN3KE_TM_NODE_MOUNT_MAX; 1135 switch (level_id) { 1136 case IPN3KE_TM_NODE_LEVEL_PORT: 1137 break; 1138 1139 case IPN3KE_TM_NODE_LEVEL_VT: 1140 if (parent_index != tm_id) 1141 return -rte_tm_error_set(error, 1142 EINVAL, 1143 RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID, 1144 NULL, 1145 rte_strerror(EINVAL)); 1146 break; 1147 1148 case IPN3KE_TM_NODE_LEVEL_COS: 1149 if (parent_index != parent_index1) 1150 return -rte_tm_error_set(error, 1151 EINVAL, 1152 RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID, 1153 NULL, 1154 rte_strerror(EINVAL)); 1155 break; 1156 default: 1157 return -rte_tm_error_set(error, 1158 EINVAL, 1159 RTE_TM_ERROR_TYPE_LEVEL_ID, 1160 NULL, 1161 rte_strerror(EINVAL)); 1162 } 1163 1164 return 0; 1165 } 1166 1167 /* Traffic manager node add */ 1168 static int 1169 ipn3ke_tm_node_add(struct rte_eth_dev *dev, 1170 uint32_t node_id, uint32_t parent_node_id, uint32_t priority, 1171 uint32_t weight, uint32_t level_id, struct rte_tm_node_params *params, 1172 struct rte_tm_error *error) 1173 { 1174 struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev); 1175 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 1176 uint32_t tm_id; 1177 struct ipn3ke_tm_node *n, *parent_node; 1178 uint32_t node_state, state_mask; 1179 int status; 1180 1181 /* Checks */ 1182 if (tm->hierarchy_frozen) 1183 return -rte_tm_error_set(error, 1184 EBUSY, 1185 RTE_TM_ERROR_TYPE_UNSPECIFIED, 1186 NULL, 1187 rte_strerror(EBUSY)); 1188 1189 tm_id = tm->tm_id; 1190 1191 status = ipn3ke_tm_node_add_check_parameter(tm_id, 1192 node_id, 1193 parent_node_id, 1194 priority, 1195 weight, 1196 level_id, 1197 params, 1198 error); 1199 if (status) 1200 return status; 1201 1202 status = ipn3ke_tm_node_add_check_mount(tm_id, 1203 node_id, 1204 parent_node_id, 1205 level_id, 1206 error); 1207 if (status) 1208 return status; 1209 1210 /* Shaper profile ID must not be NONE. */ 1211 if (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE && 1212 params->shaper_profile_id != node_id) 1213 return -rte_tm_error_set(error, 1214 EINVAL, 1215 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID, 1216 NULL, 1217 rte_strerror(EINVAL)); 1218 1219 /* Memory allocation */ 1220 state_mask = 0; 1221 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_IDLE); 1222 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_CONFIGURED_DEL); 1223 n = ipn3ke_hw_tm_node_search(hw, tm_id, node_id, state_mask); 1224 if (!n) 1225 return -rte_tm_error_set(error, 1226 EINVAL, 1227 RTE_TM_ERROR_TYPE_UNSPECIFIED, 1228 NULL, 1229 rte_strerror(EINVAL)); 1230 node_state = n->node_state; 1231 1232 /* Check parent node */ 1233 state_mask = 0; 1234 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_CONFIGURED_ADD); 1235 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_COMMITTED); 1236 if (parent_node_id != RTE_TM_NODE_ID_NULL) { 1237 parent_node = ipn3ke_hw_tm_node_search(hw, 1238 tm_id, 1239 parent_node_id, 1240 state_mask); 1241 if (!parent_node) 1242 return -rte_tm_error_set(error, 1243 EINVAL, 1244 RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID, 1245 NULL, 1246 rte_strerror(EINVAL)); 1247 } else { 1248 parent_node = NULL; 1249 } 1250 1251 switch (level_id) { 1252 case IPN3KE_TM_NODE_LEVEL_PORT: 1253 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_ADD; 1254 n->tm_id = tm_id; 1255 tm->h.port_commit_node = n; 1256 break; 1257 1258 case IPN3KE_TM_NODE_LEVEL_VT: 1259 if (node_state == IPN3KE_TM_NODE_STATE_IDLE) { 1260 TAILQ_INSERT_TAIL(&tm->h.vt_commit_node_list, n, node); 1261 if (parent_node) 1262 parent_node->n_children++; 1263 tm->h.n_vt_nodes++; 1264 } else if (node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) { 1265 if (parent_node) 1266 parent_node->n_children++; 1267 tm->h.n_vt_nodes++; 1268 } 1269 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_ADD; 1270 n->parent_node_id = parent_node_id; 1271 n->tm_id = tm_id; 1272 n->parent_node = parent_node; 1273 1274 break; 1275 1276 case IPN3KE_TM_NODE_LEVEL_COS: 1277 if (node_state == IPN3KE_TM_NODE_STATE_IDLE) { 1278 TAILQ_INSERT_TAIL(&tm->h.cos_commit_node_list, 1279 n, node); 1280 if (parent_node) 1281 parent_node->n_children++; 1282 tm->h.n_cos_nodes++; 1283 } else if (node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) { 1284 if (parent_node) 1285 parent_node->n_children++; 1286 tm->h.n_cos_nodes++; 1287 } 1288 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_ADD; 1289 n->parent_node_id = parent_node_id; 1290 n->tm_id = tm_id; 1291 n->parent_node = parent_node; 1292 1293 break; 1294 default: 1295 return -rte_tm_error_set(error, 1296 EINVAL, 1297 RTE_TM_ERROR_TYPE_LEVEL_ID, 1298 NULL, 1299 rte_strerror(EINVAL)); 1300 } 1301 1302 /* Fill in */ 1303 n->priority = priority; 1304 n->weight = weight; 1305 1306 if (n->level == IPN3KE_TM_NODE_LEVEL_COS && 1307 params->leaf.cman == RTE_TM_CMAN_TAIL_DROP) 1308 n->tdrop_profile = ipn3ke_hw_tm_tdrop_profile_search(hw, 1309 params->leaf.wred.wred_profile_id); 1310 1311 rte_memcpy(&n->params, params, sizeof(n->params)); 1312 1313 return 0; 1314 } 1315 1316 static int 1317 ipn3ke_tm_node_del_check_parameter(uint32_t tm_id, 1318 uint32_t node_id, struct rte_tm_error *error) 1319 { 1320 uint32_t level_of_node_id; 1321 uint32_t node_index; 1322 1323 if (node_id == RTE_TM_NODE_ID_NULL) 1324 return -rte_tm_error_set(error, 1325 EINVAL, 1326 RTE_TM_ERROR_TYPE_NODE_ID, 1327 NULL, 1328 rte_strerror(EINVAL)); 1329 1330 /* check node id and parent id*/ 1331 level_of_node_id = node_id / IPN3KE_TM_NODE_LEVEL_MOD; 1332 node_index = node_id % IPN3KE_TM_NODE_LEVEL_MOD; 1333 switch (level_of_node_id) { 1334 case IPN3KE_TM_NODE_LEVEL_PORT: 1335 if (node_index != tm_id) 1336 return -rte_tm_error_set(error, 1337 EINVAL, 1338 RTE_TM_ERROR_TYPE_NODE_ID, 1339 NULL, 1340 rte_strerror(EINVAL)); 1341 break; 1342 1343 case IPN3KE_TM_NODE_LEVEL_VT: 1344 if (node_index >= IPN3KE_TM_VT_NODE_NUM) 1345 return -rte_tm_error_set(error, 1346 EINVAL, 1347 RTE_TM_ERROR_TYPE_NODE_ID, 1348 NULL, 1349 rte_strerror(EINVAL)); 1350 break; 1351 1352 case IPN3KE_TM_NODE_LEVEL_COS: 1353 if (node_index >= IPN3KE_TM_COS_NODE_NUM) 1354 return -rte_tm_error_set(error, 1355 EINVAL, 1356 RTE_TM_ERROR_TYPE_NODE_ID, 1357 NULL, 1358 rte_strerror(EINVAL)); 1359 break; 1360 default: 1361 return -rte_tm_error_set(error, 1362 EINVAL, 1363 RTE_TM_ERROR_TYPE_LEVEL_ID, 1364 NULL, 1365 rte_strerror(EINVAL)); 1366 } 1367 1368 return 0; 1369 } 1370 1371 /* Traffic manager node delete */ 1372 static int 1373 ipn3ke_pmd_tm_node_delete(struct rte_eth_dev *dev, 1374 uint32_t node_id, struct rte_tm_error *error) 1375 { 1376 struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev); 1377 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 1378 struct ipn3ke_tm_node *n, *parent_node; 1379 uint32_t tm_id; 1380 int status; 1381 uint32_t level_of_node_id; 1382 uint32_t node_state; 1383 uint32_t state_mask; 1384 1385 /* Check hierarchy changes are currently allowed */ 1386 if (tm->hierarchy_frozen) 1387 return -rte_tm_error_set(error, 1388 EBUSY, 1389 RTE_TM_ERROR_TYPE_UNSPECIFIED, 1390 NULL, 1391 rte_strerror(EBUSY)); 1392 1393 tm_id = tm->tm_id; 1394 1395 status = ipn3ke_tm_node_del_check_parameter(tm_id, 1396 node_id, 1397 error); 1398 if (status) 1399 return status; 1400 1401 /* Check existing */ 1402 state_mask = 0; 1403 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_CONFIGURED_ADD); 1404 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_COMMITTED); 1405 n = ipn3ke_hw_tm_node_search(hw, tm_id, node_id, state_mask); 1406 if (n == NULL) 1407 return -rte_tm_error_set(error, 1408 EINVAL, 1409 RTE_TM_ERROR_TYPE_NODE_ID, 1410 NULL, 1411 rte_strerror(EINVAL)); 1412 1413 if (n->n_children > 0) 1414 return -rte_tm_error_set(error, 1415 EINVAL, 1416 RTE_TM_ERROR_TYPE_NODE_ID, 1417 NULL, 1418 rte_strerror(EINVAL)); 1419 1420 node_state = n->node_state; 1421 1422 level_of_node_id = node_id / IPN3KE_TM_NODE_LEVEL_MOD; 1423 1424 /* Check parent node */ 1425 if (n->parent_node_id != RTE_TM_NODE_ID_NULL) { 1426 state_mask = 0; 1427 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_CONFIGURED_ADD); 1428 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_COMMITTED); 1429 parent_node = ipn3ke_hw_tm_node_search(hw, 1430 tm_id, 1431 n->parent_node_id, 1432 state_mask); 1433 if (!parent_node) 1434 return -rte_tm_error_set(error, 1435 EINVAL, 1436 RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID, 1437 NULL, 1438 rte_strerror(EINVAL)); 1439 if (n->parent_node != parent_node) 1440 return -rte_tm_error_set(error, 1441 EINVAL, 1442 RTE_TM_ERROR_TYPE_NODE_ID, 1443 NULL, 1444 rte_strerror(EINVAL)); 1445 } else { 1446 parent_node = NULL; 1447 } 1448 1449 switch (level_of_node_id) { 1450 case IPN3KE_TM_NODE_LEVEL_PORT: 1451 if (tm->h.port_node != n) 1452 return -rte_tm_error_set(error, 1453 EINVAL, 1454 RTE_TM_ERROR_TYPE_NODE_ID, 1455 NULL, 1456 rte_strerror(EINVAL)); 1457 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_DEL; 1458 tm->h.port_commit_node = n; 1459 1460 break; 1461 1462 case IPN3KE_TM_NODE_LEVEL_VT: 1463 if (node_state == IPN3KE_TM_NODE_STATE_COMMITTED) { 1464 if (parent_node) 1465 TAILQ_REMOVE(&parent_node->children_node_list, 1466 n, node); 1467 TAILQ_INSERT_TAIL(&tm->h.vt_commit_node_list, n, node); 1468 if (parent_node) 1469 parent_node->n_children--; 1470 tm->h.n_vt_nodes--; 1471 } else if (node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) { 1472 if (parent_node) 1473 parent_node->n_children--; 1474 tm->h.n_vt_nodes--; 1475 } 1476 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_DEL; 1477 1478 break; 1479 1480 case IPN3KE_TM_NODE_LEVEL_COS: 1481 if (node_state == IPN3KE_TM_NODE_STATE_COMMITTED) { 1482 if (parent_node) 1483 TAILQ_REMOVE(&parent_node->children_node_list, 1484 n, node); 1485 TAILQ_INSERT_TAIL(&tm->h.cos_commit_node_list, 1486 n, node); 1487 if (parent_node) 1488 parent_node->n_children--; 1489 tm->h.n_cos_nodes--; 1490 } else if (node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) { 1491 if (parent_node) 1492 parent_node->n_children--; 1493 tm->h.n_cos_nodes--; 1494 } 1495 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_DEL; 1496 1497 break; 1498 default: 1499 return -rte_tm_error_set(error, 1500 EINVAL, 1501 RTE_TM_ERROR_TYPE_LEVEL_ID, 1502 NULL, 1503 rte_strerror(EINVAL)); 1504 } 1505 1506 return 0; 1507 } 1508 1509 static int 1510 ipn3ke_tm_hierarchy_commit_check(struct rte_eth_dev *dev, 1511 struct rte_tm_error *error) 1512 { 1513 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 1514 uint32_t tm_id; 1515 struct ipn3ke_tm_node_list *nl; 1516 struct ipn3ke_tm_node *n, *parent_node; 1517 1518 tm_id = tm->tm_id; 1519 1520 nl = &tm->h.cos_commit_node_list; 1521 TAILQ_FOREACH(n, nl, node) { 1522 parent_node = n->parent_node; 1523 if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) { 1524 if (n->parent_node_id == RTE_TM_NODE_ID_NULL || 1525 n->level != IPN3KE_TM_NODE_LEVEL_COS || 1526 n->tm_id != tm_id || 1527 parent_node == NULL || 1528 (parent_node && 1529 parent_node->node_state == 1530 IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) || 1531 (parent_node && 1532 parent_node->node_state == 1533 IPN3KE_TM_NODE_STATE_IDLE) || 1534 n->shaper_profile.valid == 0) { 1535 return -rte_tm_error_set(error, 1536 EINVAL, 1537 RTE_TM_ERROR_TYPE_UNSPECIFIED, 1538 NULL, 1539 rte_strerror(EINVAL)); 1540 } 1541 } else if (n->node_state == 1542 IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) { 1543 if (n->level != IPN3KE_TM_NODE_LEVEL_COS || 1544 n->n_children != 0) { 1545 return -rte_tm_error_set(error, 1546 EINVAL, 1547 RTE_TM_ERROR_TYPE_UNSPECIFIED, 1548 NULL, 1549 rte_strerror(EINVAL)); 1550 } 1551 } 1552 } 1553 1554 nl = &tm->h.vt_commit_node_list; 1555 TAILQ_FOREACH(n, nl, node) { 1556 parent_node = n->parent_node; 1557 if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) { 1558 if (n->parent_node_id == RTE_TM_NODE_ID_NULL || 1559 n->level != IPN3KE_TM_NODE_LEVEL_VT || 1560 n->tm_id != tm_id || 1561 parent_node == NULL || 1562 (parent_node && 1563 parent_node->node_state == 1564 IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) || 1565 (parent_node && 1566 parent_node->node_state == 1567 IPN3KE_TM_NODE_STATE_IDLE) || 1568 n->shaper_profile.valid == 0) { 1569 return -rte_tm_error_set(error, 1570 EINVAL, 1571 RTE_TM_ERROR_TYPE_UNSPECIFIED, 1572 NULL, 1573 rte_strerror(EINVAL)); 1574 } 1575 } else if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) 1576 return -rte_tm_error_set(error, 1577 EINVAL, 1578 RTE_TM_ERROR_TYPE_UNSPECIFIED, 1579 NULL, 1580 rte_strerror(EINVAL)); 1581 } 1582 1583 n = tm->h.port_commit_node; 1584 if (n && 1585 (n->parent_node_id != RTE_TM_NODE_ID_NULL || 1586 n->level != IPN3KE_TM_NODE_LEVEL_PORT || 1587 n->tm_id != tm_id || 1588 n->parent_node != NULL || 1589 n->shaper_profile.valid == 0)) { 1590 return -rte_tm_error_set(error, 1591 EINVAL, 1592 RTE_TM_ERROR_TYPE_UNSPECIFIED, 1593 NULL, 1594 rte_strerror(EINVAL)); 1595 } 1596 1597 return 0; 1598 } 1599 1600 static int 1601 ipn3ke_hw_tm_node_wr(struct ipn3ke_hw *hw, 1602 struct ipn3ke_tm_node *n, 1603 struct ipn3ke_tm_node *parent_node) 1604 { 1605 uint32_t level; 1606 1607 level = n->level; 1608 1609 switch (level) { 1610 case IPN3KE_TM_NODE_LEVEL_PORT: 1611 /** 1612 * Configure Type 1613 */ 1614 IPN3KE_MASK_WRITE_REG(hw, 1615 IPN3KE_QOS_TYPE_L3_X, 1616 n->node_index, 1617 n->priority, 1618 IPN3KE_QOS_TYPE_MASK); 1619 1620 /** 1621 * Configure Sch_wt 1622 */ 1623 IPN3KE_MASK_WRITE_REG(hw, 1624 IPN3KE_QOS_SCH_WT_L3_X, 1625 n->node_index, 1626 n->weight, 1627 IPN3KE_QOS_SCH_WT_MASK); 1628 1629 /** 1630 * Configure Shap_wt 1631 */ 1632 if (n->shaper_profile.valid) 1633 IPN3KE_MASK_WRITE_REG(hw, 1634 IPN3KE_QOS_SHAP_WT_L3_X, 1635 n->node_index, 1636 ((n->shaper_profile.e << 10) | 1637 n->shaper_profile.m), 1638 IPN3KE_QOS_SHAP_WT_MASK); 1639 1640 break; 1641 case IPN3KE_TM_NODE_LEVEL_VT: 1642 /** 1643 * Configure Type 1644 */ 1645 IPN3KE_MASK_WRITE_REG(hw, 1646 IPN3KE_QOS_TYPE_L2_X, 1647 n->node_index, 1648 n->priority, 1649 IPN3KE_QOS_TYPE_MASK); 1650 1651 /** 1652 * Configure Sch_wt 1653 */ 1654 IPN3KE_MASK_WRITE_REG(hw, 1655 IPN3KE_QOS_SCH_WT_L2_X, 1656 n->node_index, 1657 n->weight, 1658 IPN3KE_QOS_SCH_WT_MASK); 1659 1660 /** 1661 * Configure Shap_wt 1662 */ 1663 if (n->shaper_profile.valid) 1664 IPN3KE_MASK_WRITE_REG(hw, 1665 IPN3KE_QOS_SHAP_WT_L2_X, 1666 n->node_index, 1667 ((n->shaper_profile.e << 10) | 1668 n->shaper_profile.m), 1669 IPN3KE_QOS_SHAP_WT_MASK); 1670 1671 /** 1672 * Configure Map 1673 */ 1674 if (parent_node) 1675 IPN3KE_MASK_WRITE_REG(hw, 1676 IPN3KE_QOS_MAP_L2_X, 1677 n->node_index, 1678 parent_node->node_index, 1679 IPN3KE_QOS_MAP_L2_MASK); 1680 1681 break; 1682 case IPN3KE_TM_NODE_LEVEL_COS: 1683 /** 1684 * Configure Tail Drop mapping 1685 */ 1686 if (n->tdrop_profile && n->tdrop_profile->valid) { 1687 IPN3KE_MASK_WRITE_REG(hw, 1688 IPN3KE_CCB_QPROFILE_Q, 1689 n->node_index, 1690 n->tdrop_profile->tdrop_profile_id, 1691 IPN3KE_CCB_QPROFILE_MASK); 1692 } 1693 1694 /** 1695 * Configure Type 1696 */ 1697 IPN3KE_MASK_WRITE_REG(hw, 1698 IPN3KE_QOS_TYPE_L1_X, 1699 n->node_index, 1700 n->priority, 1701 IPN3KE_QOS_TYPE_MASK); 1702 1703 /** 1704 * Configure Sch_wt 1705 */ 1706 IPN3KE_MASK_WRITE_REG(hw, 1707 IPN3KE_QOS_SCH_WT_L1_X, 1708 n->node_index, 1709 n->weight, 1710 IPN3KE_QOS_SCH_WT_MASK); 1711 1712 /** 1713 * Configure Shap_wt 1714 */ 1715 if (n->shaper_profile.valid) 1716 IPN3KE_MASK_WRITE_REG(hw, 1717 IPN3KE_QOS_SHAP_WT_L1_X, 1718 n->node_index, 1719 ((n->shaper_profile.e << 10) | 1720 n->shaper_profile.m), 1721 IPN3KE_QOS_SHAP_WT_MASK); 1722 1723 /** 1724 * Configure COS queue to port 1725 */ 1726 while (IPN3KE_MASK_READ_REG(hw, 1727 IPN3KE_QM_UID_CONFIG_CTRL, 1728 0, 1729 0x80000000)) 1730 ; 1731 1732 if (parent_node && parent_node->parent_node) 1733 IPN3KE_MASK_WRITE_REG(hw, 1734 IPN3KE_QM_UID_CONFIG_DATA, 1735 0, 1736 (1 << 8 | parent_node->parent_node->node_index), 1737 0x1FF); 1738 1739 IPN3KE_MASK_WRITE_REG(hw, 1740 IPN3KE_QM_UID_CONFIG_CTRL, 1741 0, 1742 n->node_index, 1743 0xFFFFF); 1744 1745 while (IPN3KE_MASK_READ_REG(hw, 1746 IPN3KE_QM_UID_CONFIG_CTRL, 1747 0, 1748 0x80000000)) 1749 ; 1750 1751 /** 1752 * Configure Map 1753 */ 1754 if (parent_node) 1755 IPN3KE_MASK_WRITE_REG(hw, 1756 IPN3KE_QOS_MAP_L1_X, 1757 n->node_index, 1758 parent_node->node_index, 1759 IPN3KE_QOS_MAP_L1_MASK); 1760 1761 break; 1762 default: 1763 return -1; 1764 } 1765 1766 return 0; 1767 } 1768 1769 static int 1770 ipn3ke_tm_hierarchy_hw_commit(struct rte_eth_dev *dev, 1771 struct rte_tm_error *error) 1772 { 1773 struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev); 1774 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 1775 struct ipn3ke_tm_node_list *nl; 1776 struct ipn3ke_tm_node *n, *nn, *parent_node; 1777 1778 n = tm->h.port_commit_node; 1779 if (n) { 1780 if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) { 1781 tm->h.port_commit_node = NULL; 1782 1783 n->node_state = IPN3KE_TM_NODE_STATE_COMMITTED; 1784 } else if (n->node_state == 1785 IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) { 1786 tm->h.port_commit_node = NULL; 1787 1788 n->node_state = IPN3KE_TM_NODE_STATE_IDLE; 1789 n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0; 1790 n->weight = 0; 1791 n->tm_id = RTE_TM_NODE_ID_NULL; 1792 } else { 1793 return -rte_tm_error_set(error, 1794 EINVAL, 1795 RTE_TM_ERROR_TYPE_UNSPECIFIED, 1796 NULL, 1797 rte_strerror(EINVAL)); 1798 } 1799 parent_node = n->parent_node; 1800 ipn3ke_hw_tm_node_wr(hw, n, parent_node); 1801 } 1802 1803 nl = &tm->h.vt_commit_node_list; 1804 for (n = TAILQ_FIRST(nl); n != NULL; n = nn) { 1805 nn = TAILQ_NEXT(n, node); 1806 if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) { 1807 n->node_state = IPN3KE_TM_NODE_STATE_COMMITTED; 1808 parent_node = n->parent_node; 1809 TAILQ_REMOVE(nl, n, node); 1810 TAILQ_INSERT_TAIL(&parent_node->children_node_list, 1811 n, node); 1812 } else if (n->node_state == 1813 IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) { 1814 parent_node = n->parent_node; 1815 TAILQ_REMOVE(nl, n, node); 1816 1817 n->node_state = IPN3KE_TM_NODE_STATE_IDLE; 1818 n->parent_node_id = RTE_TM_NODE_ID_NULL; 1819 n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0; 1820 n->weight = 0; 1821 n->tm_id = RTE_TM_NODE_ID_NULL; 1822 n->parent_node = NULL; 1823 } else { 1824 return -rte_tm_error_set(error, 1825 EINVAL, 1826 RTE_TM_ERROR_TYPE_UNSPECIFIED, 1827 NULL, 1828 rte_strerror(EINVAL)); 1829 } 1830 ipn3ke_hw_tm_node_wr(hw, n, parent_node); 1831 } 1832 1833 nl = &tm->h.cos_commit_node_list; 1834 for (n = TAILQ_FIRST(nl); n != NULL; n = nn) { 1835 nn = TAILQ_NEXT(n, node); 1836 if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) { 1837 n->node_state = IPN3KE_TM_NODE_STATE_COMMITTED; 1838 parent_node = n->parent_node; 1839 TAILQ_REMOVE(nl, n, node); 1840 TAILQ_INSERT_TAIL(&parent_node->children_node_list, 1841 n, node); 1842 } else if (n->node_state == 1843 IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) { 1844 n->node_state = IPN3KE_TM_NODE_STATE_IDLE; 1845 parent_node = n->parent_node; 1846 TAILQ_REMOVE(nl, n, node); 1847 1848 n->node_state = IPN3KE_TM_NODE_STATE_IDLE; 1849 n->parent_node_id = RTE_TM_NODE_ID_NULL; 1850 n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0; 1851 n->weight = 0; 1852 n->tm_id = RTE_TM_NODE_ID_NULL; 1853 n->parent_node = NULL; 1854 1855 if (n->tdrop_profile) 1856 n->tdrop_profile->n_users--; 1857 } else { 1858 return -rte_tm_error_set(error, 1859 EINVAL, 1860 RTE_TM_ERROR_TYPE_UNSPECIFIED, 1861 NULL, 1862 rte_strerror(EINVAL)); 1863 } 1864 ipn3ke_hw_tm_node_wr(hw, n, parent_node); 1865 } 1866 1867 return 0; 1868 } 1869 1870 static int 1871 ipn3ke_tm_hierarchy_commit_clear(struct rte_eth_dev *dev) 1872 { 1873 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 1874 struct ipn3ke_tm_node_list *nl; 1875 struct ipn3ke_tm_node *n; 1876 struct ipn3ke_tm_node *nn; 1877 1878 n = tm->h.port_commit_node; 1879 if (n) { 1880 n->node_state = IPN3KE_TM_NODE_STATE_IDLE; 1881 n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0; 1882 n->weight = 0; 1883 n->tm_id = RTE_TM_NODE_ID_NULL; 1884 n->n_children = 0; 1885 1886 tm->h.port_commit_node = NULL; 1887 } 1888 1889 nl = &tm->h.vt_commit_node_list; 1890 for (n = TAILQ_FIRST(nl); n != NULL; n = nn) { 1891 nn = TAILQ_NEXT(n, node); 1892 1893 n->node_state = IPN3KE_TM_NODE_STATE_IDLE; 1894 n->parent_node_id = RTE_TM_NODE_ID_NULL; 1895 n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0; 1896 n->weight = 0; 1897 n->tm_id = RTE_TM_NODE_ID_NULL; 1898 n->parent_node = NULL; 1899 n->n_children = 0; 1900 tm->h.n_vt_nodes--; 1901 1902 TAILQ_REMOVE(nl, n, node); 1903 } 1904 1905 nl = &tm->h.cos_commit_node_list; 1906 for (n = TAILQ_FIRST(nl); n != NULL; n = nn) { 1907 nn = TAILQ_NEXT(n, node); 1908 1909 n->node_state = IPN3KE_TM_NODE_STATE_IDLE; 1910 n->parent_node_id = RTE_TM_NODE_ID_NULL; 1911 n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0; 1912 n->weight = 0; 1913 n->tm_id = RTE_TM_NODE_ID_NULL; 1914 n->parent_node = NULL; 1915 tm->h.n_cos_nodes--; 1916 1917 TAILQ_REMOVE(nl, n, node); 1918 } 1919 1920 return 0; 1921 } 1922 1923 static void 1924 ipn3ke_tm_show(struct rte_eth_dev *dev) 1925 { 1926 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 1927 uint32_t tm_id; 1928 struct ipn3ke_tm_node_list *vt_nl, *cos_nl; 1929 struct ipn3ke_tm_node *port_n, *vt_n, *cos_n; 1930 const char *str_state[IPN3KE_TM_NODE_STATE_MAX] = {"Idle", 1931 "CfgAdd", 1932 "CfgDel", 1933 "Committed"}; 1934 1935 tm_id = tm->tm_id; 1936 1937 IPN3KE_AFU_PMD_DEBUG("***HQoS Tree(%d)***\n", tm_id); 1938 1939 port_n = tm->h.port_node; 1940 IPN3KE_AFU_PMD_DEBUG("Port: (%d|%s)\n", port_n->node_index, 1941 str_state[port_n->node_state]); 1942 1943 vt_nl = &tm->h.port_node->children_node_list; 1944 TAILQ_FOREACH(vt_n, vt_nl, node) { 1945 cos_nl = &vt_n->children_node_list; 1946 IPN3KE_AFU_PMD_DEBUG(" VT%d: ", vt_n->node_index); 1947 TAILQ_FOREACH(cos_n, cos_nl, node) { 1948 if (cos_n->parent_node_id != 1949 (vt_n->node_index + IPN3KE_TM_NODE_LEVEL_MOD)) 1950 IPN3KE_AFU_PMD_ERR("(%d|%s), ", 1951 cos_n->node_index, 1952 str_state[cos_n->node_state]); 1953 } 1954 IPN3KE_AFU_PMD_DEBUG("\n"); 1955 } 1956 } 1957 1958 static void 1959 ipn3ke_tm_show_commmit(struct rte_eth_dev *dev) 1960 { 1961 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 1962 uint32_t tm_id; 1963 struct ipn3ke_tm_node_list *nl; 1964 struct ipn3ke_tm_node *n; 1965 const char *str_state[IPN3KE_TM_NODE_STATE_MAX] = {"Idle", 1966 "CfgAdd", 1967 "CfgDel", 1968 "Committed"}; 1969 1970 tm_id = tm->tm_id; 1971 1972 IPN3KE_AFU_PMD_DEBUG("***Commit Tree(%d)***\n", tm_id); 1973 n = tm->h.port_commit_node; 1974 IPN3KE_AFU_PMD_DEBUG("Port: "); 1975 if (n) 1976 IPN3KE_AFU_PMD_DEBUG("(%d|%s)", 1977 n->node_index, 1978 str_state[n->node_state]); 1979 IPN3KE_AFU_PMD_DEBUG("\n"); 1980 1981 nl = &tm->h.vt_commit_node_list; 1982 IPN3KE_AFU_PMD_DEBUG("VT : "); 1983 TAILQ_FOREACH(n, nl, node) { 1984 IPN3KE_AFU_PMD_DEBUG("(%d|%s), ", 1985 n->node_index, 1986 str_state[n->node_state]); 1987 } 1988 IPN3KE_AFU_PMD_DEBUG("\n"); 1989 1990 nl = &tm->h.cos_commit_node_list; 1991 IPN3KE_AFU_PMD_DEBUG("COS : "); 1992 TAILQ_FOREACH(n, nl, node) { 1993 IPN3KE_AFU_PMD_DEBUG("(%d|%s), ", 1994 n->node_index, 1995 str_state[n->node_state]); 1996 } 1997 IPN3KE_AFU_PMD_DEBUG("\n"); 1998 } 1999 2000 /* Traffic manager hierarchy commit */ 2001 static int 2002 ipn3ke_tm_hierarchy_commit(struct rte_eth_dev *dev, 2003 int clear_on_fail, struct rte_tm_error *error) 2004 { 2005 struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev); 2006 int status; 2007 2008 /* Checks */ 2009 if (tm->hierarchy_frozen) 2010 return -rte_tm_error_set(error, 2011 EBUSY, 2012 RTE_TM_ERROR_TYPE_UNSPECIFIED, 2013 NULL, 2014 rte_strerror(EBUSY)); 2015 2016 ipn3ke_tm_show_commmit(dev); 2017 2018 status = ipn3ke_tm_hierarchy_commit_check(dev, error); 2019 if (status) { 2020 if (clear_on_fail) 2021 ipn3ke_tm_hierarchy_commit_clear(dev); 2022 return status; 2023 } 2024 2025 ipn3ke_tm_hierarchy_hw_commit(dev, error); 2026 ipn3ke_tm_show(dev); 2027 2028 return 0; 2029 } 2030 2031 const struct rte_tm_ops ipn3ke_tm_ops = { 2032 .node_type_get = ipn3ke_pmd_tm_node_type_get, 2033 .capabilities_get = ipn3ke_tm_capabilities_get, 2034 .level_capabilities_get = ipn3ke_tm_level_capabilities_get, 2035 .node_capabilities_get = ipn3ke_tm_node_capabilities_get, 2036 2037 .wred_profile_add = ipn3ke_tm_tdrop_profile_add, 2038 .wred_profile_delete = ipn3ke_tm_tdrop_profile_delete, 2039 .shared_wred_context_add_update = NULL, 2040 .shared_wred_context_delete = NULL, 2041 2042 .shaper_profile_add = ipn3ke_tm_shaper_profile_add, 2043 .shaper_profile_delete = ipn3ke_tm_shaper_profile_delete, 2044 .shared_shaper_add_update = NULL, 2045 .shared_shaper_delete = NULL, 2046 2047 .node_add = ipn3ke_tm_node_add, 2048 .node_delete = ipn3ke_pmd_tm_node_delete, 2049 .node_suspend = NULL, 2050 .node_resume = NULL, 2051 .hierarchy_commit = ipn3ke_tm_hierarchy_commit, 2052 2053 .node_parent_update = NULL, 2054 .node_shaper_update = NULL, 2055 .node_shared_shaper_update = NULL, 2056 .node_stats_update = NULL, 2057 .node_wfq_weight_mode_update = NULL, 2058 .node_cman_update = NULL, 2059 .node_wred_context_update = NULL, 2060 .node_shared_wred_context_update = NULL, 2061 2062 .node_stats_read = NULL, 2063 }; 2064 2065 int 2066 ipn3ke_tm_ops_get(struct rte_eth_dev *ethdev, 2067 void *arg) 2068 { 2069 struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(ethdev); 2070 struct ipn3ke_rpst *rpst = IPN3KE_DEV_PRIVATE_TO_RPST(ethdev); 2071 struct rte_eth_dev *i40e_pf_eth; 2072 const struct rte_tm_ops *ops; 2073 2074 if (!arg) 2075 return -EINVAL; 2076 2077 if (hw->acc_tm) { 2078 *(const void **)arg = &ipn3ke_tm_ops; 2079 } else if (rpst->i40e_pf_eth) { 2080 i40e_pf_eth = rpst->i40e_pf_eth; 2081 if (i40e_pf_eth->dev_ops->tm_ops_get == NULL || 2082 i40e_pf_eth->dev_ops->tm_ops_get(i40e_pf_eth, 2083 &ops) != 0 || 2084 ops == NULL) { 2085 return -EINVAL; 2086 } 2087 *(const void **)arg = ops; 2088 } else { 2089 return -EINVAL; 2090 } 2091 2092 return 0; 2093 } 2094