1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2018, Intel Corporation. */ 3 4 #include <net/devlink.h> 5 #include "ice_sched.h" 6 7 /** 8 * ice_sched_add_root_node - Insert the Tx scheduler root node in SW DB 9 * @pi: port information structure 10 * @info: Scheduler element information from firmware 11 * 12 * This function inserts the root node of the scheduling tree topology 13 * to the SW DB. 14 */ 15 static int 16 ice_sched_add_root_node(struct ice_port_info *pi, 17 struct ice_aqc_txsched_elem_data *info) 18 { 19 struct ice_sched_node *root; 20 struct ice_hw *hw; 21 22 if (!pi) 23 return -EINVAL; 24 25 hw = pi->hw; 26 27 root = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*root), GFP_KERNEL); 28 if (!root) 29 return -ENOMEM; 30 31 root->children = devm_kcalloc(ice_hw_to_dev(hw), hw->max_children[0], 32 sizeof(*root->children), GFP_KERNEL); 33 if (!root->children) { 34 devm_kfree(ice_hw_to_dev(hw), root); 35 return -ENOMEM; 36 } 37 38 memcpy(&root->info, info, sizeof(*info)); 39 pi->root = root; 40 return 0; 41 } 42 43 /** 44 * ice_sched_find_node_by_teid - Find the Tx scheduler node in SW DB 45 * @start_node: pointer to the starting ice_sched_node struct in a sub-tree 46 * @teid: node TEID to search 47 * 48 * This function searches for a node matching the TEID in the scheduling tree 49 * from the SW DB. The search is recursive and is restricted by the number of 50 * layers it has searched through; stopping at the max supported layer. 51 * 52 * This function needs to be called when holding the port_info->sched_lock 53 */ 54 struct ice_sched_node * 55 ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid) 56 { 57 u16 i; 58 59 /* The TEID is same as that of the start_node */ 60 if (ICE_TXSCHED_GET_NODE_TEID(start_node) == teid) 61 return start_node; 62 63 /* The node has no children or is at the max layer */ 64 if (!start_node->num_children || 65 start_node->tx_sched_layer >= ICE_AQC_TOPO_MAX_LEVEL_NUM || 66 start_node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF) 67 return NULL; 68 69 /* Check if TEID matches to any of the children nodes */ 70 for (i = 0; i < start_node->num_children; i++) 71 if (ICE_TXSCHED_GET_NODE_TEID(start_node->children[i]) == teid) 72 return start_node->children[i]; 73 74 /* Search within each child's sub-tree */ 75 for (i = 0; i < start_node->num_children; i++) { 76 struct ice_sched_node *tmp; 77 78 tmp = ice_sched_find_node_by_teid(start_node->children[i], 79 teid); 80 if (tmp) 81 return tmp; 82 } 83 84 return NULL; 85 } 86 87 /** 88 * ice_sched_find_next_vsi_node - find the next node for a given VSI 89 * @vsi_node: VSI support node to start search with 90 * 91 * Return: Next VSI support node, or NULL. 92 * 93 * The function returns a pointer to the next node from the VSI layer 94 * assigned to the given VSI, or NULL if there is no such a node. 95 */ 96 static struct ice_sched_node * 97 ice_sched_find_next_vsi_node(struct ice_sched_node *vsi_node) 98 { 99 unsigned int vsi_handle = vsi_node->vsi_handle; 100 101 while ((vsi_node = vsi_node->sibling) != NULL) 102 if (vsi_node->vsi_handle == vsi_handle) 103 break; 104 105 return vsi_node; 106 } 107 108 /** 109 * ice_aqc_send_sched_elem_cmd - send scheduling elements cmd 110 * @hw: pointer to the HW struct 111 * @cmd_opc: cmd opcode 112 * @elems_req: number of elements to request 113 * @buf: pointer to buffer 114 * @buf_size: buffer size in bytes 115 * @elems_resp: returns total number of elements response 116 * @cd: pointer to command details structure or NULL 117 * 118 * This function sends a scheduling elements cmd (cmd_opc) 119 */ 120 static int 121 ice_aqc_send_sched_elem_cmd(struct ice_hw *hw, enum ice_adminq_opc cmd_opc, 122 u16 elems_req, void *buf, u16 buf_size, 123 u16 *elems_resp, struct ice_sq_cd *cd) 124 { 125 struct ice_aqc_sched_elem_cmd *cmd; 126 struct libie_aq_desc desc; 127 int status; 128 129 cmd = libie_aq_raw(&desc); 130 ice_fill_dflt_direct_cmd_desc(&desc, cmd_opc); 131 cmd->num_elem_req = cpu_to_le16(elems_req); 132 desc.flags |= cpu_to_le16(LIBIE_AQ_FLAG_RD); 133 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 134 if (!status && elems_resp) 135 *elems_resp = le16_to_cpu(cmd->num_elem_resp); 136 137 return status; 138 } 139 140 /** 141 * ice_aq_query_sched_elems - query scheduler elements 142 * @hw: pointer to the HW struct 143 * @elems_req: number of elements to query 144 * @buf: pointer to buffer 145 * @buf_size: buffer size in bytes 146 * @elems_ret: returns total number of elements returned 147 * @cd: pointer to command details structure or NULL 148 * 149 * Query scheduling elements (0x0404) 150 */ 151 int 152 ice_aq_query_sched_elems(struct ice_hw *hw, u16 elems_req, 153 struct ice_aqc_txsched_elem_data *buf, u16 buf_size, 154 u16 *elems_ret, struct ice_sq_cd *cd) 155 { 156 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_get_sched_elems, 157 elems_req, (void *)buf, buf_size, 158 elems_ret, cd); 159 } 160 161 /** 162 * ice_sched_add_node - Insert the Tx scheduler node in SW DB 163 * @pi: port information structure 164 * @layer: Scheduler layer of the node 165 * @info: Scheduler element information from firmware 166 * @prealloc_node: preallocated ice_sched_node struct for SW DB 167 * 168 * This function inserts a scheduler node to the SW DB. 169 */ 170 int 171 ice_sched_add_node(struct ice_port_info *pi, u8 layer, 172 struct ice_aqc_txsched_elem_data *info, 173 struct ice_sched_node *prealloc_node) 174 { 175 struct ice_aqc_txsched_elem_data elem; 176 struct ice_sched_node *parent; 177 struct ice_sched_node *node; 178 struct ice_hw *hw; 179 int status; 180 181 if (!pi) 182 return -EINVAL; 183 184 hw = pi->hw; 185 186 /* A valid parent node should be there */ 187 parent = ice_sched_find_node_by_teid(pi->root, 188 le32_to_cpu(info->parent_teid)); 189 if (!parent) { 190 ice_debug(hw, ICE_DBG_SCHED, "Parent Node not found for parent_teid=0x%x\n", 191 le32_to_cpu(info->parent_teid)); 192 return -EINVAL; 193 } 194 195 /* query the current node information from FW before adding it 196 * to the SW DB 197 */ 198 status = ice_sched_query_elem(hw, le32_to_cpu(info->node_teid), &elem); 199 if (status) 200 return status; 201 202 if (prealloc_node) 203 node = prealloc_node; 204 else 205 node = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*node), GFP_KERNEL); 206 if (!node) 207 return -ENOMEM; 208 if (hw->max_children[layer]) { 209 node->children = devm_kcalloc(ice_hw_to_dev(hw), 210 hw->max_children[layer], 211 sizeof(*node->children), GFP_KERNEL); 212 if (!node->children) { 213 devm_kfree(ice_hw_to_dev(hw), node); 214 return -ENOMEM; 215 } 216 } 217 218 node->in_use = true; 219 node->parent = parent; 220 node->tx_sched_layer = layer; 221 parent->children[parent->num_children++] = node; 222 node->info = elem; 223 return 0; 224 } 225 226 /** 227 * ice_aq_delete_sched_elems - delete scheduler elements 228 * @hw: pointer to the HW struct 229 * @grps_req: number of groups to delete 230 * @buf: pointer to buffer 231 * @buf_size: buffer size in bytes 232 * @grps_del: returns total number of elements deleted 233 * @cd: pointer to command details structure or NULL 234 * 235 * Delete scheduling elements (0x040F) 236 */ 237 static int 238 ice_aq_delete_sched_elems(struct ice_hw *hw, u16 grps_req, 239 struct ice_aqc_delete_elem *buf, u16 buf_size, 240 u16 *grps_del, struct ice_sq_cd *cd) 241 { 242 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_delete_sched_elems, 243 grps_req, (void *)buf, buf_size, 244 grps_del, cd); 245 } 246 247 /** 248 * ice_sched_remove_elems - remove nodes from HW 249 * @hw: pointer to the HW struct 250 * @parent: pointer to the parent node 251 * @node_teid: node teid to be deleted 252 * 253 * This function remove nodes from HW 254 */ 255 static int 256 ice_sched_remove_elems(struct ice_hw *hw, struct ice_sched_node *parent, 257 u32 node_teid) 258 { 259 DEFINE_RAW_FLEX(struct ice_aqc_delete_elem, buf, teid, 1); 260 u16 buf_size = __struct_size(buf); 261 u16 num_groups_removed = 0; 262 int status; 263 264 buf->hdr.parent_teid = parent->info.node_teid; 265 buf->hdr.num_elems = cpu_to_le16(1); 266 buf->teid[0] = cpu_to_le32(node_teid); 267 268 status = ice_aq_delete_sched_elems(hw, 1, buf, buf_size, 269 &num_groups_removed, NULL); 270 if (status || num_groups_removed != 1) 271 ice_debug(hw, ICE_DBG_SCHED, "remove node failed FW error %d\n", 272 hw->adminq.sq_last_status); 273 274 return status; 275 } 276 277 /** 278 * ice_sched_get_first_node - get the first node of the given layer 279 * @pi: port information structure 280 * @parent: pointer the base node of the subtree 281 * @layer: layer number 282 * 283 * This function retrieves the first node of the given layer from the subtree 284 */ 285 static struct ice_sched_node * 286 ice_sched_get_first_node(struct ice_port_info *pi, 287 struct ice_sched_node *parent, u8 layer) 288 { 289 return pi->sib_head[parent->tc_num][layer]; 290 } 291 292 /** 293 * ice_sched_get_tc_node - get pointer to TC node 294 * @pi: port information structure 295 * @tc: TC number 296 * 297 * This function returns the TC node pointer 298 */ 299 struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc) 300 { 301 u8 i; 302 303 if (!pi || !pi->root) 304 return NULL; 305 for (i = 0; i < pi->root->num_children; i++) 306 if (pi->root->children[i]->tc_num == tc) 307 return pi->root->children[i]; 308 return NULL; 309 } 310 311 /** 312 * ice_free_sched_node - Free a Tx scheduler node from SW DB 313 * @pi: port information structure 314 * @node: pointer to the ice_sched_node struct 315 * 316 * This function frees up a node from SW DB as well as from HW 317 * 318 * This function needs to be called with the port_info->sched_lock held 319 */ 320 void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node) 321 { 322 struct ice_sched_node *parent; 323 struct ice_hw *hw = pi->hw; 324 u8 i, j; 325 326 /* Free the children before freeing up the parent node 327 * The parent array is updated below and that shifts the nodes 328 * in the array. So always pick the first child if num children > 0 329 */ 330 while (node->num_children) 331 ice_free_sched_node(pi, node->children[0]); 332 333 /* Leaf, TC and root nodes can't be deleted by SW */ 334 if (node->tx_sched_layer >= hw->sw_entry_point_layer && 335 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC && 336 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT && 337 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_LEAF) { 338 u32 teid = le32_to_cpu(node->info.node_teid); 339 340 ice_sched_remove_elems(hw, node->parent, teid); 341 } 342 parent = node->parent; 343 /* root has no parent */ 344 if (parent) { 345 struct ice_sched_node *p; 346 347 /* update the parent */ 348 for (i = 0; i < parent->num_children; i++) 349 if (parent->children[i] == node) { 350 for (j = i + 1; j < parent->num_children; j++) 351 parent->children[j - 1] = 352 parent->children[j]; 353 parent->num_children--; 354 break; 355 } 356 357 p = ice_sched_get_first_node(pi, node, node->tx_sched_layer); 358 while (p) { 359 if (p->sibling == node) { 360 p->sibling = node->sibling; 361 break; 362 } 363 p = p->sibling; 364 } 365 366 /* update the sibling head if head is getting removed */ 367 if (pi->sib_head[node->tc_num][node->tx_sched_layer] == node) 368 pi->sib_head[node->tc_num][node->tx_sched_layer] = 369 node->sibling; 370 } 371 372 devm_kfree(ice_hw_to_dev(hw), node->children); 373 kfree(node->name); 374 xa_erase(&pi->sched_node_ids, node->id); 375 devm_kfree(ice_hw_to_dev(hw), node); 376 } 377 378 /** 379 * ice_aq_get_dflt_topo - gets default scheduler topology 380 * @hw: pointer to the HW struct 381 * @lport: logical port number 382 * @buf: pointer to buffer 383 * @buf_size: buffer size in bytes 384 * @num_branches: returns total number of queue to port branches 385 * @cd: pointer to command details structure or NULL 386 * 387 * Get default scheduler topology (0x400) 388 */ 389 static int 390 ice_aq_get_dflt_topo(struct ice_hw *hw, u8 lport, 391 struct ice_aqc_get_topo_elem *buf, u16 buf_size, 392 u8 *num_branches, struct ice_sq_cd *cd) 393 { 394 struct ice_aqc_get_topo *cmd; 395 struct libie_aq_desc desc; 396 int status; 397 398 cmd = libie_aq_raw(&desc); 399 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_dflt_topo); 400 cmd->port_num = lport; 401 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 402 if (!status && num_branches) 403 *num_branches = cmd->num_branches; 404 405 return status; 406 } 407 408 /** 409 * ice_aq_add_sched_elems - adds scheduling element 410 * @hw: pointer to the HW struct 411 * @grps_req: the number of groups that are requested to be added 412 * @buf: pointer to buffer 413 * @buf_size: buffer size in bytes 414 * @grps_added: returns total number of groups added 415 * @cd: pointer to command details structure or NULL 416 * 417 * Add scheduling elements (0x0401) 418 */ 419 static int 420 ice_aq_add_sched_elems(struct ice_hw *hw, u16 grps_req, 421 struct ice_aqc_add_elem *buf, u16 buf_size, 422 u16 *grps_added, struct ice_sq_cd *cd) 423 { 424 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_add_sched_elems, 425 grps_req, (void *)buf, buf_size, 426 grps_added, cd); 427 } 428 429 /** 430 * ice_aq_cfg_sched_elems - configures scheduler elements 431 * @hw: pointer to the HW struct 432 * @elems_req: number of elements to configure 433 * @buf: pointer to buffer 434 * @buf_size: buffer size in bytes 435 * @elems_cfgd: returns total number of elements configured 436 * @cd: pointer to command details structure or NULL 437 * 438 * Configure scheduling elements (0x0403) 439 */ 440 static int 441 ice_aq_cfg_sched_elems(struct ice_hw *hw, u16 elems_req, 442 struct ice_aqc_txsched_elem_data *buf, u16 buf_size, 443 u16 *elems_cfgd, struct ice_sq_cd *cd) 444 { 445 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_cfg_sched_elems, 446 elems_req, (void *)buf, buf_size, 447 elems_cfgd, cd); 448 } 449 450 /** 451 * ice_aq_move_sched_elems - move scheduler element (just 1 group) 452 * @hw: pointer to the HW struct 453 * @buf: pointer to buffer 454 * @buf_size: buffer size in bytes 455 * @grps_movd: returns total number of groups moved 456 * 457 * Move scheduling elements (0x0408) 458 */ 459 int 460 ice_aq_move_sched_elems(struct ice_hw *hw, struct ice_aqc_move_elem *buf, 461 u16 buf_size, u16 *grps_movd) 462 { 463 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_move_sched_elems, 464 1, buf, buf_size, grps_movd, NULL); 465 } 466 467 /** 468 * ice_aq_suspend_sched_elems - suspend scheduler elements 469 * @hw: pointer to the HW struct 470 * @elems_req: number of elements to suspend 471 * @buf: pointer to buffer 472 * @buf_size: buffer size in bytes 473 * @elems_ret: returns total number of elements suspended 474 * @cd: pointer to command details structure or NULL 475 * 476 * Suspend scheduling elements (0x0409) 477 */ 478 static int 479 ice_aq_suspend_sched_elems(struct ice_hw *hw, u16 elems_req, __le32 *buf, 480 u16 buf_size, u16 *elems_ret, struct ice_sq_cd *cd) 481 { 482 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_suspend_sched_elems, 483 elems_req, (void *)buf, buf_size, 484 elems_ret, cd); 485 } 486 487 /** 488 * ice_aq_resume_sched_elems - resume scheduler elements 489 * @hw: pointer to the HW struct 490 * @elems_req: number of elements to resume 491 * @buf: pointer to buffer 492 * @buf_size: buffer size in bytes 493 * @elems_ret: returns total number of elements resumed 494 * @cd: pointer to command details structure or NULL 495 * 496 * resume scheduling elements (0x040A) 497 */ 498 static int 499 ice_aq_resume_sched_elems(struct ice_hw *hw, u16 elems_req, __le32 *buf, 500 u16 buf_size, u16 *elems_ret, struct ice_sq_cd *cd) 501 { 502 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_resume_sched_elems, 503 elems_req, (void *)buf, buf_size, 504 elems_ret, cd); 505 } 506 507 /** 508 * ice_aq_query_sched_res - query scheduler resource 509 * @hw: pointer to the HW struct 510 * @buf_size: buffer size in bytes 511 * @buf: pointer to buffer 512 * @cd: pointer to command details structure or NULL 513 * 514 * Query scheduler resource allocation (0x0412) 515 */ 516 static int 517 ice_aq_query_sched_res(struct ice_hw *hw, u16 buf_size, 518 struct ice_aqc_query_txsched_res_resp *buf, 519 struct ice_sq_cd *cd) 520 { 521 struct libie_aq_desc desc; 522 523 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_query_sched_res); 524 return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 525 } 526 527 /** 528 * ice_sched_suspend_resume_elems - suspend or resume HW nodes 529 * @hw: pointer to the HW struct 530 * @num_nodes: number of nodes 531 * @node_teids: array of node teids to be suspended or resumed 532 * @suspend: true means suspend / false means resume 533 * 534 * This function suspends or resumes HW nodes 535 */ 536 int 537 ice_sched_suspend_resume_elems(struct ice_hw *hw, u8 num_nodes, u32 *node_teids, 538 bool suspend) 539 { 540 u16 i, buf_size, num_elem_ret = 0; 541 __le32 *buf; 542 int status; 543 544 buf_size = sizeof(*buf) * num_nodes; 545 buf = devm_kzalloc(ice_hw_to_dev(hw), buf_size, GFP_KERNEL); 546 if (!buf) 547 return -ENOMEM; 548 549 for (i = 0; i < num_nodes; i++) 550 buf[i] = cpu_to_le32(node_teids[i]); 551 552 if (suspend) 553 status = ice_aq_suspend_sched_elems(hw, num_nodes, buf, 554 buf_size, &num_elem_ret, 555 NULL); 556 else 557 status = ice_aq_resume_sched_elems(hw, num_nodes, buf, 558 buf_size, &num_elem_ret, 559 NULL); 560 if (status || num_elem_ret != num_nodes) 561 ice_debug(hw, ICE_DBG_SCHED, "suspend/resume failed\n"); 562 563 devm_kfree(ice_hw_to_dev(hw), buf); 564 return status; 565 } 566 567 /** 568 * ice_alloc_lan_q_ctx - allocate LAN queue contexts for the given VSI and TC 569 * @hw: pointer to the HW struct 570 * @vsi_handle: VSI handle 571 * @tc: TC number 572 * @new_numqs: number of queues 573 */ 574 static int 575 ice_alloc_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 new_numqs) 576 { 577 struct ice_vsi_ctx *vsi_ctx; 578 struct ice_q_ctx *q_ctx; 579 u16 idx; 580 581 vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle); 582 if (!vsi_ctx) 583 return -EINVAL; 584 /* allocate LAN queue contexts */ 585 if (!vsi_ctx->lan_q_ctx[tc]) { 586 q_ctx = devm_kcalloc(ice_hw_to_dev(hw), new_numqs, 587 sizeof(*q_ctx), GFP_KERNEL); 588 if (!q_ctx) 589 return -ENOMEM; 590 591 for (idx = 0; idx < new_numqs; idx++) { 592 q_ctx[idx].q_handle = ICE_INVAL_Q_HANDLE; 593 q_ctx[idx].q_teid = ICE_INVAL_TEID; 594 } 595 596 vsi_ctx->lan_q_ctx[tc] = q_ctx; 597 vsi_ctx->num_lan_q_entries[tc] = new_numqs; 598 return 0; 599 } 600 /* num queues are increased, update the queue contexts */ 601 if (new_numqs > vsi_ctx->num_lan_q_entries[tc]) { 602 u16 prev_num = vsi_ctx->num_lan_q_entries[tc]; 603 604 q_ctx = devm_kcalloc(ice_hw_to_dev(hw), new_numqs, 605 sizeof(*q_ctx), GFP_KERNEL); 606 if (!q_ctx) 607 return -ENOMEM; 608 609 memcpy(q_ctx, vsi_ctx->lan_q_ctx[tc], 610 prev_num * sizeof(*q_ctx)); 611 devm_kfree(ice_hw_to_dev(hw), vsi_ctx->lan_q_ctx[tc]); 612 613 for (idx = prev_num; idx < new_numqs; idx++) { 614 q_ctx[idx].q_handle = ICE_INVAL_Q_HANDLE; 615 q_ctx[idx].q_teid = ICE_INVAL_TEID; 616 } 617 618 vsi_ctx->lan_q_ctx[tc] = q_ctx; 619 vsi_ctx->num_lan_q_entries[tc] = new_numqs; 620 } 621 return 0; 622 } 623 624 /** 625 * ice_alloc_rdma_q_ctx - allocate RDMA queue contexts for the given VSI and TC 626 * @hw: pointer to the HW struct 627 * @vsi_handle: VSI handle 628 * @tc: TC number 629 * @new_numqs: number of queues 630 */ 631 static int 632 ice_alloc_rdma_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 new_numqs) 633 { 634 struct ice_vsi_ctx *vsi_ctx; 635 struct ice_q_ctx *q_ctx; 636 637 vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle); 638 if (!vsi_ctx) 639 return -EINVAL; 640 /* allocate RDMA queue contexts */ 641 if (!vsi_ctx->rdma_q_ctx[tc]) { 642 vsi_ctx->rdma_q_ctx[tc] = devm_kcalloc(ice_hw_to_dev(hw), 643 new_numqs, 644 sizeof(*q_ctx), 645 GFP_KERNEL); 646 if (!vsi_ctx->rdma_q_ctx[tc]) 647 return -ENOMEM; 648 vsi_ctx->num_rdma_q_entries[tc] = new_numqs; 649 return 0; 650 } 651 /* num queues are increased, update the queue contexts */ 652 if (new_numqs > vsi_ctx->num_rdma_q_entries[tc]) { 653 u16 prev_num = vsi_ctx->num_rdma_q_entries[tc]; 654 655 q_ctx = devm_kcalloc(ice_hw_to_dev(hw), new_numqs, 656 sizeof(*q_ctx), GFP_KERNEL); 657 if (!q_ctx) 658 return -ENOMEM; 659 memcpy(q_ctx, vsi_ctx->rdma_q_ctx[tc], 660 prev_num * sizeof(*q_ctx)); 661 devm_kfree(ice_hw_to_dev(hw), vsi_ctx->rdma_q_ctx[tc]); 662 vsi_ctx->rdma_q_ctx[tc] = q_ctx; 663 vsi_ctx->num_rdma_q_entries[tc] = new_numqs; 664 } 665 return 0; 666 } 667 668 /** 669 * ice_aq_rl_profile - performs a rate limiting task 670 * @hw: pointer to the HW struct 671 * @opcode: opcode for add, query, or remove profile(s) 672 * @num_profiles: the number of profiles 673 * @buf: pointer to buffer 674 * @buf_size: buffer size in bytes 675 * @num_processed: number of processed add or remove profile(s) to return 676 * @cd: pointer to command details structure 677 * 678 * RL profile function to add, query, or remove profile(s) 679 */ 680 static int 681 ice_aq_rl_profile(struct ice_hw *hw, enum ice_adminq_opc opcode, 682 u16 num_profiles, struct ice_aqc_rl_profile_elem *buf, 683 u16 buf_size, u16 *num_processed, struct ice_sq_cd *cd) 684 { 685 struct ice_aqc_rl_profile *cmd; 686 struct libie_aq_desc desc; 687 int status; 688 689 cmd = libie_aq_raw(&desc); 690 691 ice_fill_dflt_direct_cmd_desc(&desc, opcode); 692 desc.flags |= cpu_to_le16(LIBIE_AQ_FLAG_RD); 693 cmd->num_profiles = cpu_to_le16(num_profiles); 694 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 695 if (!status && num_processed) 696 *num_processed = le16_to_cpu(cmd->num_processed); 697 return status; 698 } 699 700 /** 701 * ice_aq_add_rl_profile - adds rate limiting profile(s) 702 * @hw: pointer to the HW struct 703 * @num_profiles: the number of profile(s) to be add 704 * @buf: pointer to buffer 705 * @buf_size: buffer size in bytes 706 * @num_profiles_added: total number of profiles added to return 707 * @cd: pointer to command details structure 708 * 709 * Add RL profile (0x0410) 710 */ 711 static int 712 ice_aq_add_rl_profile(struct ice_hw *hw, u16 num_profiles, 713 struct ice_aqc_rl_profile_elem *buf, u16 buf_size, 714 u16 *num_profiles_added, struct ice_sq_cd *cd) 715 { 716 return ice_aq_rl_profile(hw, ice_aqc_opc_add_rl_profiles, num_profiles, 717 buf, buf_size, num_profiles_added, cd); 718 } 719 720 /** 721 * ice_aq_remove_rl_profile - removes RL profile(s) 722 * @hw: pointer to the HW struct 723 * @num_profiles: the number of profile(s) to remove 724 * @buf: pointer to buffer 725 * @buf_size: buffer size in bytes 726 * @num_profiles_removed: total number of profiles removed to return 727 * @cd: pointer to command details structure or NULL 728 * 729 * Remove RL profile (0x0415) 730 */ 731 static int 732 ice_aq_remove_rl_profile(struct ice_hw *hw, u16 num_profiles, 733 struct ice_aqc_rl_profile_elem *buf, u16 buf_size, 734 u16 *num_profiles_removed, struct ice_sq_cd *cd) 735 { 736 return ice_aq_rl_profile(hw, ice_aqc_opc_remove_rl_profiles, 737 num_profiles, buf, buf_size, 738 num_profiles_removed, cd); 739 } 740 741 /** 742 * ice_sched_del_rl_profile - remove RL profile 743 * @hw: pointer to the HW struct 744 * @rl_info: rate limit profile information 745 * 746 * If the profile ID is not referenced anymore, it removes profile ID with 747 * its associated parameters from HW DB,and locally. The caller needs to 748 * hold scheduler lock. 749 */ 750 static int 751 ice_sched_del_rl_profile(struct ice_hw *hw, 752 struct ice_aqc_rl_profile_info *rl_info) 753 { 754 struct ice_aqc_rl_profile_elem *buf; 755 u16 num_profiles_removed; 756 u16 num_profiles = 1; 757 int status; 758 759 if (rl_info->prof_id_ref != 0) 760 return -EBUSY; 761 762 /* Safe to remove profile ID */ 763 buf = &rl_info->profile; 764 status = ice_aq_remove_rl_profile(hw, num_profiles, buf, sizeof(*buf), 765 &num_profiles_removed, NULL); 766 if (status || num_profiles_removed != num_profiles) 767 return -EIO; 768 769 /* Delete stale entry now */ 770 list_del(&rl_info->list_entry); 771 devm_kfree(ice_hw_to_dev(hw), rl_info); 772 return status; 773 } 774 775 /** 776 * ice_sched_clear_rl_prof - clears RL prof entries 777 * @pi: port information structure 778 * 779 * This function removes all RL profile from HW as well as from SW DB. 780 */ 781 static void ice_sched_clear_rl_prof(struct ice_port_info *pi) 782 { 783 u16 ln; 784 785 for (ln = 0; ln < pi->hw->num_tx_sched_layers; ln++) { 786 struct ice_aqc_rl_profile_info *rl_prof_elem; 787 struct ice_aqc_rl_profile_info *rl_prof_tmp; 788 789 list_for_each_entry_safe(rl_prof_elem, rl_prof_tmp, 790 &pi->rl_prof_list[ln], list_entry) { 791 struct ice_hw *hw = pi->hw; 792 int status; 793 794 rl_prof_elem->prof_id_ref = 0; 795 status = ice_sched_del_rl_profile(hw, rl_prof_elem); 796 if (status) { 797 ice_debug(hw, ICE_DBG_SCHED, "Remove rl profile failed\n"); 798 /* On error, free mem required */ 799 list_del(&rl_prof_elem->list_entry); 800 devm_kfree(ice_hw_to_dev(hw), rl_prof_elem); 801 } 802 } 803 } 804 } 805 806 /** 807 * ice_sched_clear_agg - clears the aggregator related information 808 * @hw: pointer to the hardware structure 809 * 810 * This function removes aggregator list and free up aggregator related memory 811 * previously allocated. 812 */ 813 void ice_sched_clear_agg(struct ice_hw *hw) 814 { 815 struct ice_sched_agg_info *agg_info; 816 struct ice_sched_agg_info *atmp; 817 818 list_for_each_entry_safe(agg_info, atmp, &hw->agg_list, list_entry) { 819 struct ice_sched_agg_vsi_info *agg_vsi_info; 820 struct ice_sched_agg_vsi_info *vtmp; 821 822 list_for_each_entry_safe(agg_vsi_info, vtmp, 823 &agg_info->agg_vsi_list, list_entry) { 824 list_del(&agg_vsi_info->list_entry); 825 devm_kfree(ice_hw_to_dev(hw), agg_vsi_info); 826 } 827 list_del(&agg_info->list_entry); 828 devm_kfree(ice_hw_to_dev(hw), agg_info); 829 } 830 } 831 832 /** 833 * ice_sched_clear_tx_topo - clears the scheduler tree nodes 834 * @pi: port information structure 835 * 836 * This function removes all the nodes from HW as well as from SW DB. 837 */ 838 static void ice_sched_clear_tx_topo(struct ice_port_info *pi) 839 { 840 if (!pi) 841 return; 842 /* remove RL profiles related lists */ 843 ice_sched_clear_rl_prof(pi); 844 if (pi->root) { 845 ice_free_sched_node(pi, pi->root); 846 pi->root = NULL; 847 } 848 } 849 850 /** 851 * ice_sched_clear_port - clear the scheduler elements from SW DB for a port 852 * @pi: port information structure 853 * 854 * Cleanup scheduling elements from SW DB 855 */ 856 void ice_sched_clear_port(struct ice_port_info *pi) 857 { 858 if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY) 859 return; 860 861 pi->port_state = ICE_SCHED_PORT_STATE_INIT; 862 mutex_lock(&pi->sched_lock); 863 ice_sched_clear_tx_topo(pi); 864 mutex_unlock(&pi->sched_lock); 865 mutex_destroy(&pi->sched_lock); 866 } 867 868 /** 869 * ice_sched_cleanup_all - cleanup scheduler elements from SW DB for all ports 870 * @hw: pointer to the HW struct 871 * 872 * Cleanup scheduling elements from SW DB for all the ports 873 */ 874 void ice_sched_cleanup_all(struct ice_hw *hw) 875 { 876 if (!hw) 877 return; 878 879 devm_kfree(ice_hw_to_dev(hw), hw->layer_info); 880 hw->layer_info = NULL; 881 882 ice_sched_clear_port(hw->port_info); 883 884 hw->num_tx_sched_layers = 0; 885 hw->num_tx_sched_phys_layers = 0; 886 hw->flattened_layers = 0; 887 hw->max_cgds = 0; 888 } 889 890 /** 891 * ice_sched_add_elems - add nodes to HW and SW DB 892 * @pi: port information structure 893 * @tc_node: pointer to the branch node 894 * @parent: pointer to the parent node 895 * @layer: layer number to add nodes 896 * @num_nodes: number of nodes 897 * @num_nodes_added: pointer to num nodes added 898 * @first_node_teid: if new nodes are added then return the TEID of first node 899 * @prealloc_nodes: preallocated nodes struct for software DB 900 * 901 * This function add nodes to HW as well as to SW DB for a given layer 902 */ 903 int 904 ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node, 905 struct ice_sched_node *parent, u8 layer, u16 num_nodes, 906 u16 *num_nodes_added, u32 *first_node_teid, 907 struct ice_sched_node **prealloc_nodes) 908 { 909 struct ice_sched_node *prev, *new_node; 910 struct ice_aqc_add_elem *buf; 911 u16 i, num_groups_added = 0; 912 struct ice_hw *hw = pi->hw; 913 size_t buf_size; 914 int status = 0; 915 u32 teid; 916 917 buf_size = struct_size(buf, generic, num_nodes); 918 buf = devm_kzalloc(ice_hw_to_dev(hw), buf_size, GFP_KERNEL); 919 if (!buf) 920 return -ENOMEM; 921 922 buf->hdr.parent_teid = parent->info.node_teid; 923 buf->hdr.num_elems = cpu_to_le16(num_nodes); 924 for (i = 0; i < num_nodes; i++) { 925 buf->generic[i].parent_teid = parent->info.node_teid; 926 buf->generic[i].data.elem_type = ICE_AQC_ELEM_TYPE_SE_GENERIC; 927 buf->generic[i].data.valid_sections = 928 ICE_AQC_ELEM_VALID_GENERIC | ICE_AQC_ELEM_VALID_CIR | 929 ICE_AQC_ELEM_VALID_EIR; 930 buf->generic[i].data.generic = 0; 931 buf->generic[i].data.cir_bw.bw_profile_idx = 932 cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID); 933 buf->generic[i].data.cir_bw.bw_alloc = 934 cpu_to_le16(ICE_SCHED_DFLT_BW_WT); 935 buf->generic[i].data.eir_bw.bw_profile_idx = 936 cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID); 937 buf->generic[i].data.eir_bw.bw_alloc = 938 cpu_to_le16(ICE_SCHED_DFLT_BW_WT); 939 } 940 941 status = ice_aq_add_sched_elems(hw, 1, buf, buf_size, 942 &num_groups_added, NULL); 943 if (status || num_groups_added != 1) { 944 ice_debug(hw, ICE_DBG_SCHED, "add node failed FW Error %d\n", 945 hw->adminq.sq_last_status); 946 devm_kfree(ice_hw_to_dev(hw), buf); 947 return -EIO; 948 } 949 950 *num_nodes_added = num_nodes; 951 /* add nodes to the SW DB */ 952 for (i = 0; i < num_nodes; i++) { 953 if (prealloc_nodes) 954 status = ice_sched_add_node(pi, layer, &buf->generic[i], prealloc_nodes[i]); 955 else 956 status = ice_sched_add_node(pi, layer, &buf->generic[i], NULL); 957 958 if (status) { 959 ice_debug(hw, ICE_DBG_SCHED, "add nodes in SW DB failed status =%d\n", 960 status); 961 break; 962 } 963 964 teid = le32_to_cpu(buf->generic[i].node_teid); 965 new_node = ice_sched_find_node_by_teid(parent, teid); 966 if (!new_node) { 967 ice_debug(hw, ICE_DBG_SCHED, "Node is missing for teid =%d\n", teid); 968 break; 969 } 970 971 new_node->sibling = NULL; 972 new_node->tc_num = tc_node->tc_num; 973 new_node->tx_weight = ICE_SCHED_DFLT_BW_WT; 974 new_node->tx_share = ICE_SCHED_DFLT_BW; 975 new_node->tx_max = ICE_SCHED_DFLT_BW; 976 new_node->name = kzalloc(SCHED_NODE_NAME_MAX_LEN, GFP_KERNEL); 977 if (!new_node->name) 978 return -ENOMEM; 979 980 status = xa_alloc(&pi->sched_node_ids, &new_node->id, NULL, XA_LIMIT(0, UINT_MAX), 981 GFP_KERNEL); 982 if (status) { 983 ice_debug(hw, ICE_DBG_SCHED, "xa_alloc failed for sched node status =%d\n", 984 status); 985 break; 986 } 987 988 snprintf(new_node->name, SCHED_NODE_NAME_MAX_LEN, "node_%u", new_node->id); 989 990 /* add it to previous node sibling pointer */ 991 /* Note: siblings are not linked across branches */ 992 prev = ice_sched_get_first_node(pi, tc_node, layer); 993 if (prev && prev != new_node) { 994 while (prev->sibling) 995 prev = prev->sibling; 996 prev->sibling = new_node; 997 } 998 999 /* initialize the sibling head */ 1000 if (!pi->sib_head[tc_node->tc_num][layer]) 1001 pi->sib_head[tc_node->tc_num][layer] = new_node; 1002 1003 if (i == 0) 1004 *first_node_teid = teid; 1005 } 1006 1007 devm_kfree(ice_hw_to_dev(hw), buf); 1008 return status; 1009 } 1010 1011 /** 1012 * ice_sched_add_nodes_to_hw_layer - Add nodes to HW layer 1013 * @pi: port information structure 1014 * @tc_node: pointer to TC node 1015 * @parent: pointer to parent node 1016 * @layer: layer number to add nodes 1017 * @num_nodes: number of nodes to be added 1018 * @first_node_teid: pointer to the first node TEID 1019 * @num_nodes_added: pointer to number of nodes added 1020 * 1021 * Add nodes into specific HW layer. 1022 */ 1023 static int 1024 ice_sched_add_nodes_to_hw_layer(struct ice_port_info *pi, 1025 struct ice_sched_node *tc_node, 1026 struct ice_sched_node *parent, u8 layer, 1027 u16 num_nodes, u32 *first_node_teid, 1028 u16 *num_nodes_added) 1029 { 1030 u16 max_child_nodes; 1031 1032 *num_nodes_added = 0; 1033 1034 if (!num_nodes) 1035 return 0; 1036 1037 if (!parent || layer < pi->hw->sw_entry_point_layer) 1038 return -EINVAL; 1039 1040 /* max children per node per layer */ 1041 max_child_nodes = pi->hw->max_children[parent->tx_sched_layer]; 1042 1043 /* current number of children + required nodes exceed max children */ 1044 if ((parent->num_children + num_nodes) > max_child_nodes) { 1045 /* Fail if the parent is a TC node */ 1046 if (parent == tc_node) 1047 return -EIO; 1048 return -ENOSPC; 1049 } 1050 1051 return ice_sched_add_elems(pi, tc_node, parent, layer, num_nodes, 1052 num_nodes_added, first_node_teid, NULL); 1053 } 1054 1055 /** 1056 * ice_sched_add_nodes_to_layer - Add nodes to a given layer 1057 * @pi: port information structure 1058 * @tc_node: pointer to TC node 1059 * @parent: pointer to parent node 1060 * @layer: layer number to add nodes 1061 * @num_nodes: number of nodes to be added 1062 * @first_node_teid: pointer to the first node TEID 1063 * @num_nodes_added: pointer to number of nodes added 1064 * 1065 * This function add nodes to a given layer. 1066 */ 1067 int 1068 ice_sched_add_nodes_to_layer(struct ice_port_info *pi, 1069 struct ice_sched_node *tc_node, 1070 struct ice_sched_node *parent, u8 layer, 1071 u16 num_nodes, u32 *first_node_teid, 1072 u16 *num_nodes_added) 1073 { 1074 u32 *first_teid_ptr = first_node_teid; 1075 u16 new_num_nodes = num_nodes; 1076 int status = 0; 1077 1078 *num_nodes_added = 0; 1079 while (*num_nodes_added < num_nodes) { 1080 u16 max_child_nodes, num_added = 0; 1081 u32 temp; 1082 1083 status = ice_sched_add_nodes_to_hw_layer(pi, tc_node, parent, 1084 layer, new_num_nodes, 1085 first_teid_ptr, 1086 &num_added); 1087 if (!status) 1088 *num_nodes_added += num_added; 1089 /* added more nodes than requested ? */ 1090 if (*num_nodes_added > num_nodes) { 1091 ice_debug(pi->hw, ICE_DBG_SCHED, "added extra nodes %d %d\n", num_nodes, 1092 *num_nodes_added); 1093 status = -EIO; 1094 break; 1095 } 1096 /* break if all the nodes are added successfully */ 1097 if (!status && (*num_nodes_added == num_nodes)) 1098 break; 1099 /* break if the error is not max limit */ 1100 if (status && status != -ENOSPC) 1101 break; 1102 /* Exceeded the max children */ 1103 max_child_nodes = pi->hw->max_children[parent->tx_sched_layer]; 1104 /* utilize all the spaces if the parent is not full */ 1105 if (parent->num_children < max_child_nodes) { 1106 new_num_nodes = max_child_nodes - parent->num_children; 1107 } else { 1108 /* This parent is full, 1109 * try the next available sibling. 1110 */ 1111 parent = ice_sched_find_next_vsi_node(parent); 1112 /* Don't modify the first node TEID memory if the 1113 * first node was added already in the above call. 1114 * Instead send some temp memory for all other 1115 * recursive calls. 1116 */ 1117 if (num_added) 1118 first_teid_ptr = &temp; 1119 1120 new_num_nodes = num_nodes - *num_nodes_added; 1121 } 1122 } 1123 return status; 1124 } 1125 1126 /** 1127 * ice_sched_get_qgrp_layer - get the current queue group layer number 1128 * @hw: pointer to the HW struct 1129 * 1130 * This function returns the current queue group layer number 1131 */ 1132 static u8 ice_sched_get_qgrp_layer(struct ice_hw *hw) 1133 { 1134 /* It's always total layers - 1, the array is 0 relative so -2 */ 1135 return hw->num_tx_sched_layers - ICE_QGRP_LAYER_OFFSET; 1136 } 1137 1138 /** 1139 * ice_sched_get_vsi_layer - get the current VSI layer number 1140 * @hw: pointer to the HW struct 1141 * 1142 * This function returns the current VSI layer number 1143 */ 1144 u8 ice_sched_get_vsi_layer(struct ice_hw *hw) 1145 { 1146 /* Num Layers VSI layer 1147 * 9 6 1148 * 7 4 1149 * 5 or less sw_entry_point_layer 1150 */ 1151 /* calculate the VSI layer based on number of layers. */ 1152 if (hw->num_tx_sched_layers == ICE_SCHED_9_LAYERS) 1153 return hw->num_tx_sched_layers - ICE_VSI_LAYER_OFFSET; 1154 else if (hw->num_tx_sched_layers == ICE_SCHED_5_LAYERS) 1155 /* qgroup and VSI layers are same */ 1156 return hw->num_tx_sched_layers - ICE_QGRP_LAYER_OFFSET; 1157 return hw->sw_entry_point_layer; 1158 } 1159 1160 /** 1161 * ice_sched_get_agg_layer - get the current aggregator layer number 1162 * @hw: pointer to the HW struct 1163 * 1164 * This function returns the current aggregator layer number 1165 */ 1166 u8 ice_sched_get_agg_layer(struct ice_hw *hw) 1167 { 1168 /* Num Layers aggregator layer 1169 * 9 4 1170 * 7 or less sw_entry_point_layer 1171 */ 1172 /* calculate the aggregator layer based on number of layers. */ 1173 if (hw->num_tx_sched_layers == ICE_SCHED_9_LAYERS) 1174 return hw->num_tx_sched_layers - ICE_AGG_LAYER_OFFSET; 1175 else 1176 return hw->sw_entry_point_layer; 1177 } 1178 1179 /** 1180 * ice_rm_dflt_leaf_node - remove the default leaf node in the tree 1181 * @pi: port information structure 1182 * 1183 * This function removes the leaf node that was created by the FW 1184 * during initialization 1185 */ 1186 static void ice_rm_dflt_leaf_node(struct ice_port_info *pi) 1187 { 1188 struct ice_sched_node *node; 1189 1190 node = pi->root; 1191 while (node) { 1192 if (!node->num_children) 1193 break; 1194 node = node->children[0]; 1195 } 1196 if (node && node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF) { 1197 u32 teid = le32_to_cpu(node->info.node_teid); 1198 int status; 1199 1200 /* remove the default leaf node */ 1201 status = ice_sched_remove_elems(pi->hw, node->parent, teid); 1202 if (!status) 1203 ice_free_sched_node(pi, node); 1204 } 1205 } 1206 1207 /** 1208 * ice_sched_rm_dflt_nodes - free the default nodes in the tree 1209 * @pi: port information structure 1210 * 1211 * This function frees all the nodes except root and TC that were created by 1212 * the FW during initialization 1213 */ 1214 static void ice_sched_rm_dflt_nodes(struct ice_port_info *pi) 1215 { 1216 struct ice_sched_node *node; 1217 1218 ice_rm_dflt_leaf_node(pi); 1219 1220 /* remove the default nodes except TC and root nodes */ 1221 node = pi->root; 1222 while (node) { 1223 if (node->tx_sched_layer >= pi->hw->sw_entry_point_layer && 1224 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC && 1225 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT) { 1226 ice_free_sched_node(pi, node); 1227 break; 1228 } 1229 1230 if (!node->num_children) 1231 break; 1232 node = node->children[0]; 1233 } 1234 } 1235 1236 /** 1237 * ice_sched_init_port - Initialize scheduler by querying information from FW 1238 * @pi: port info structure for the tree to cleanup 1239 * 1240 * This function is the initial call to find the total number of Tx scheduler 1241 * resources, default topology created by firmware and storing the information 1242 * in SW DB. 1243 */ 1244 int ice_sched_init_port(struct ice_port_info *pi) 1245 { 1246 struct ice_aqc_get_topo_elem *buf; 1247 struct ice_hw *hw; 1248 u8 num_branches; 1249 u16 num_elems; 1250 int status; 1251 u8 i, j; 1252 1253 if (!pi) 1254 return -EINVAL; 1255 hw = pi->hw; 1256 1257 /* Query the Default Topology from FW */ 1258 buf = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL); 1259 if (!buf) 1260 return -ENOMEM; 1261 1262 /* Query default scheduling tree topology */ 1263 status = ice_aq_get_dflt_topo(hw, pi->lport, buf, ICE_AQ_MAX_BUF_LEN, 1264 &num_branches, NULL); 1265 if (status) 1266 goto err_init_port; 1267 1268 /* num_branches should be between 1-8 */ 1269 if (num_branches < 1 || num_branches > ICE_TXSCHED_MAX_BRANCHES) { 1270 ice_debug(hw, ICE_DBG_SCHED, "num_branches unexpected %d\n", 1271 num_branches); 1272 status = -EINVAL; 1273 goto err_init_port; 1274 } 1275 1276 /* get the number of elements on the default/first branch */ 1277 num_elems = le16_to_cpu(buf[0].hdr.num_elems); 1278 1279 /* num_elems should always be between 1-9 */ 1280 if (num_elems < 1 || num_elems > ICE_AQC_TOPO_MAX_LEVEL_NUM) { 1281 ice_debug(hw, ICE_DBG_SCHED, "num_elems unexpected %d\n", 1282 num_elems); 1283 status = -EINVAL; 1284 goto err_init_port; 1285 } 1286 1287 /* If the last node is a leaf node then the index of the queue group 1288 * layer is two less than the number of elements. 1289 */ 1290 if (num_elems > 2 && buf[0].generic[num_elems - 1].data.elem_type == 1291 ICE_AQC_ELEM_TYPE_LEAF) 1292 pi->last_node_teid = 1293 le32_to_cpu(buf[0].generic[num_elems - 2].node_teid); 1294 else 1295 pi->last_node_teid = 1296 le32_to_cpu(buf[0].generic[num_elems - 1].node_teid); 1297 1298 /* Insert the Tx Sched root node */ 1299 status = ice_sched_add_root_node(pi, &buf[0].generic[0]); 1300 if (status) 1301 goto err_init_port; 1302 1303 /* Parse the default tree and cache the information */ 1304 for (i = 0; i < num_branches; i++) { 1305 num_elems = le16_to_cpu(buf[i].hdr.num_elems); 1306 1307 /* Skip root element as already inserted */ 1308 for (j = 1; j < num_elems; j++) { 1309 /* update the sw entry point */ 1310 if (buf[0].generic[j].data.elem_type == 1311 ICE_AQC_ELEM_TYPE_ENTRY_POINT) 1312 hw->sw_entry_point_layer = j; 1313 1314 status = ice_sched_add_node(pi, j, &buf[i].generic[j], NULL); 1315 if (status) 1316 goto err_init_port; 1317 } 1318 } 1319 1320 /* Remove the default nodes. */ 1321 if (pi->root) 1322 ice_sched_rm_dflt_nodes(pi); 1323 1324 /* initialize the port for handling the scheduler tree */ 1325 pi->port_state = ICE_SCHED_PORT_STATE_READY; 1326 mutex_init(&pi->sched_lock); 1327 for (i = 0; i < ICE_AQC_TOPO_MAX_LEVEL_NUM; i++) 1328 INIT_LIST_HEAD(&pi->rl_prof_list[i]); 1329 1330 err_init_port: 1331 if (status && pi->root) { 1332 ice_free_sched_node(pi, pi->root); 1333 pi->root = NULL; 1334 } 1335 1336 kfree(buf); 1337 return status; 1338 } 1339 1340 /** 1341 * ice_sched_query_res_alloc - query the FW for num of logical sched layers 1342 * @hw: pointer to the HW struct 1343 * 1344 * query FW for allocated scheduler resources and store in HW struct 1345 */ 1346 int ice_sched_query_res_alloc(struct ice_hw *hw) 1347 { 1348 struct ice_aqc_query_txsched_res_resp *buf; 1349 __le16 max_sibl; 1350 int status = 0; 1351 u16 i; 1352 1353 if (hw->layer_info) 1354 return status; 1355 1356 buf = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*buf), GFP_KERNEL); 1357 if (!buf) 1358 return -ENOMEM; 1359 1360 status = ice_aq_query_sched_res(hw, sizeof(*buf), buf, NULL); 1361 if (status) 1362 goto sched_query_out; 1363 1364 hw->num_tx_sched_layers = le16_to_cpu(buf->sched_props.logical_levels); 1365 hw->num_tx_sched_phys_layers = 1366 le16_to_cpu(buf->sched_props.phys_levels); 1367 hw->flattened_layers = buf->sched_props.flattening_bitmap; 1368 hw->max_cgds = buf->sched_props.max_pf_cgds; 1369 1370 /* max sibling group size of current layer refers to the max children 1371 * of the below layer node. 1372 * layer 1 node max children will be layer 2 max sibling group size 1373 * layer 2 node max children will be layer 3 max sibling group size 1374 * and so on. This array will be populated from root (index 0) to 1375 * qgroup layer 7. Leaf node has no children. 1376 */ 1377 for (i = 0; i < hw->num_tx_sched_layers - 1; i++) { 1378 max_sibl = buf->layer_props[i + 1].max_sibl_grp_sz; 1379 hw->max_children[i] = le16_to_cpu(max_sibl); 1380 } 1381 1382 hw->layer_info = devm_kmemdup(ice_hw_to_dev(hw), buf->layer_props, 1383 (hw->num_tx_sched_layers * 1384 sizeof(*hw->layer_info)), 1385 GFP_KERNEL); 1386 if (!hw->layer_info) { 1387 status = -ENOMEM; 1388 goto sched_query_out; 1389 } 1390 1391 sched_query_out: 1392 devm_kfree(ice_hw_to_dev(hw), buf); 1393 return status; 1394 } 1395 1396 /** 1397 * ice_sched_get_psm_clk_freq - determine the PSM clock frequency 1398 * @hw: pointer to the HW struct 1399 * 1400 * Determine the PSM clock frequency and store in HW struct 1401 */ 1402 void ice_sched_get_psm_clk_freq(struct ice_hw *hw) 1403 { 1404 u32 val, clk_src; 1405 1406 val = rd32(hw, GLGEN_CLKSTAT_SRC); 1407 clk_src = FIELD_GET(GLGEN_CLKSTAT_SRC_PSM_CLK_SRC_M, val); 1408 1409 #define PSM_CLK_SRC_367_MHZ 0x0 1410 #define PSM_CLK_SRC_416_MHZ 0x1 1411 #define PSM_CLK_SRC_446_MHZ 0x2 1412 #define PSM_CLK_SRC_390_MHZ 0x3 1413 1414 switch (clk_src) { 1415 case PSM_CLK_SRC_367_MHZ: 1416 hw->psm_clk_freq = ICE_PSM_CLK_367MHZ_IN_HZ; 1417 break; 1418 case PSM_CLK_SRC_416_MHZ: 1419 hw->psm_clk_freq = ICE_PSM_CLK_416MHZ_IN_HZ; 1420 break; 1421 case PSM_CLK_SRC_446_MHZ: 1422 hw->psm_clk_freq = ICE_PSM_CLK_446MHZ_IN_HZ; 1423 break; 1424 case PSM_CLK_SRC_390_MHZ: 1425 hw->psm_clk_freq = ICE_PSM_CLK_390MHZ_IN_HZ; 1426 break; 1427 default: 1428 ice_debug(hw, ICE_DBG_SCHED, "PSM clk_src unexpected %u\n", 1429 clk_src); 1430 /* fall back to a safe default */ 1431 hw->psm_clk_freq = ICE_PSM_CLK_446MHZ_IN_HZ; 1432 } 1433 } 1434 1435 /** 1436 * ice_sched_find_node_in_subtree - Find node in part of base node subtree 1437 * @hw: pointer to the HW struct 1438 * @base: pointer to the base node 1439 * @node: pointer to the node to search 1440 * 1441 * This function checks whether a given node is part of the base node 1442 * subtree or not 1443 */ 1444 static bool 1445 ice_sched_find_node_in_subtree(struct ice_hw *hw, struct ice_sched_node *base, 1446 struct ice_sched_node *node) 1447 { 1448 u8 i; 1449 1450 for (i = 0; i < base->num_children; i++) { 1451 struct ice_sched_node *child = base->children[i]; 1452 1453 if (node == child) 1454 return true; 1455 1456 if (child->tx_sched_layer > node->tx_sched_layer) 1457 return false; 1458 1459 /* this recursion is intentional, and wouldn't 1460 * go more than 8 calls 1461 */ 1462 if (ice_sched_find_node_in_subtree(hw, child, node)) 1463 return true; 1464 } 1465 return false; 1466 } 1467 1468 /** 1469 * ice_sched_get_free_qgrp - Scan all queue group siblings and find a free node 1470 * @pi: port information structure 1471 * @vsi_node: software VSI handle 1472 * @qgrp_node: first queue group node identified for scanning 1473 * @owner: LAN or RDMA 1474 * 1475 * This function retrieves a free LAN or RDMA queue group node by scanning 1476 * qgrp_node and its siblings for the queue group with the fewest number 1477 * of queues currently assigned. 1478 */ 1479 static struct ice_sched_node * 1480 ice_sched_get_free_qgrp(struct ice_port_info *pi, 1481 struct ice_sched_node *vsi_node, 1482 struct ice_sched_node *qgrp_node, u8 owner) 1483 { 1484 struct ice_sched_node *min_qgrp; 1485 u8 min_children; 1486 1487 if (!qgrp_node) 1488 return qgrp_node; 1489 min_children = qgrp_node->num_children; 1490 if (!min_children) 1491 return qgrp_node; 1492 min_qgrp = qgrp_node; 1493 /* scan all queue groups until find a node which has less than the 1494 * minimum number of children. This way all queue group nodes get 1495 * equal number of shares and active. The bandwidth will be equally 1496 * distributed across all queues. 1497 */ 1498 while (qgrp_node) { 1499 /* make sure the qgroup node is part of the VSI subtree */ 1500 if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node)) 1501 if (qgrp_node->num_children < min_children && 1502 qgrp_node->owner == owner) { 1503 /* replace the new min queue group node */ 1504 min_qgrp = qgrp_node; 1505 min_children = min_qgrp->num_children; 1506 /* break if it has no children, */ 1507 if (!min_children) 1508 break; 1509 } 1510 qgrp_node = qgrp_node->sibling; 1511 } 1512 return min_qgrp; 1513 } 1514 1515 /** 1516 * ice_sched_get_free_qparent - Get a free LAN or RDMA queue group node 1517 * @pi: port information structure 1518 * @vsi_handle: software VSI handle 1519 * @tc: branch number 1520 * @owner: LAN or RDMA 1521 * 1522 * This function retrieves a free LAN or RDMA queue group node 1523 */ 1524 struct ice_sched_node * 1525 ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc, 1526 u8 owner) 1527 { 1528 struct ice_sched_node *vsi_node, *qgrp_node; 1529 struct ice_vsi_ctx *vsi_ctx; 1530 u8 qgrp_layer, vsi_layer; 1531 u16 max_children; 1532 1533 qgrp_layer = ice_sched_get_qgrp_layer(pi->hw); 1534 vsi_layer = ice_sched_get_vsi_layer(pi->hw); 1535 max_children = pi->hw->max_children[qgrp_layer]; 1536 1537 vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle); 1538 if (!vsi_ctx) 1539 return NULL; 1540 vsi_node = vsi_ctx->sched.vsi_node[tc]; 1541 /* validate invalid VSI ID */ 1542 if (!vsi_node) 1543 return NULL; 1544 1545 /* If the queue group and VSI layer are same then queues 1546 * are all attached directly to VSI 1547 */ 1548 if (qgrp_layer == vsi_layer) 1549 return vsi_node; 1550 1551 /* get the first queue group node from VSI sub-tree */ 1552 qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer); 1553 while (qgrp_node) { 1554 struct ice_sched_node *next_vsi_node; 1555 1556 /* make sure the qgroup node is part of the VSI subtree */ 1557 if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node)) 1558 if (qgrp_node->num_children < max_children && 1559 qgrp_node->owner == owner) 1560 break; 1561 qgrp_node = qgrp_node->sibling; 1562 if (qgrp_node) 1563 continue; 1564 1565 next_vsi_node = ice_sched_find_next_vsi_node(vsi_node); 1566 if (!next_vsi_node) 1567 break; 1568 1569 vsi_node = next_vsi_node; 1570 qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer); 1571 } 1572 1573 /* Select the best queue group */ 1574 return ice_sched_get_free_qgrp(pi, vsi_node, qgrp_node, owner); 1575 } 1576 1577 /** 1578 * ice_sched_get_vsi_node - Get a VSI node based on VSI ID 1579 * @pi: pointer to the port information structure 1580 * @tc_node: pointer to the TC node 1581 * @vsi_handle: software VSI handle 1582 * 1583 * This function retrieves a VSI node for a given VSI ID from a given 1584 * TC branch 1585 */ 1586 static struct ice_sched_node * 1587 ice_sched_get_vsi_node(struct ice_port_info *pi, struct ice_sched_node *tc_node, 1588 u16 vsi_handle) 1589 { 1590 struct ice_sched_node *node; 1591 u8 vsi_layer; 1592 1593 vsi_layer = ice_sched_get_vsi_layer(pi->hw); 1594 node = ice_sched_get_first_node(pi, tc_node, vsi_layer); 1595 1596 /* Check whether it already exists */ 1597 while (node) { 1598 if (node->vsi_handle == vsi_handle) 1599 return node; 1600 node = node->sibling; 1601 } 1602 1603 return node; 1604 } 1605 1606 /** 1607 * ice_sched_get_agg_node - Get an aggregator node based on aggregator ID 1608 * @pi: pointer to the port information structure 1609 * @tc_node: pointer to the TC node 1610 * @agg_id: aggregator ID 1611 * 1612 * This function retrieves an aggregator node for a given aggregator ID from 1613 * a given TC branch 1614 */ 1615 struct ice_sched_node * 1616 ice_sched_get_agg_node(struct ice_port_info *pi, struct ice_sched_node *tc_node, 1617 u32 agg_id) 1618 { 1619 struct ice_sched_node *node; 1620 struct ice_hw *hw = pi->hw; 1621 u8 agg_layer; 1622 1623 if (!hw) 1624 return NULL; 1625 agg_layer = ice_sched_get_agg_layer(hw); 1626 node = ice_sched_get_first_node(pi, tc_node, agg_layer); 1627 1628 /* Check whether it already exists */ 1629 while (node) { 1630 if (node->agg_id == agg_id) 1631 return node; 1632 node = node->sibling; 1633 } 1634 1635 return node; 1636 } 1637 1638 /** 1639 * ice_sched_calc_vsi_child_nodes - calculate number of VSI child nodes 1640 * @hw: pointer to the HW struct 1641 * @num_new_qs: number of new queues that will be added to the tree 1642 * @num_nodes: num nodes array 1643 * 1644 * This function calculates the number of VSI child nodes based on the 1645 * number of queues. 1646 */ 1647 static void 1648 ice_sched_calc_vsi_child_nodes(struct ice_hw *hw, u16 num_new_qs, u16 *num_nodes) 1649 { 1650 u16 num = num_new_qs; 1651 u8 i, qgl, vsil; 1652 1653 qgl = ice_sched_get_qgrp_layer(hw); 1654 vsil = ice_sched_get_vsi_layer(hw); 1655 1656 /* calculate num nodes from queue group to VSI layer */ 1657 for (i = qgl; i > vsil; i--) { 1658 /* round to the next integer if there is a remainder */ 1659 num = DIV_ROUND_UP(num, hw->max_children[i]); 1660 1661 /* need at least one node */ 1662 num_nodes[i] = num ? num : 1; 1663 } 1664 } 1665 1666 /** 1667 * ice_sched_add_vsi_child_nodes - add VSI child nodes to tree 1668 * @pi: port information structure 1669 * @vsi_handle: software VSI handle 1670 * @tc_node: pointer to the TC node 1671 * @num_nodes: pointer to the num nodes that needs to be added per layer 1672 * @owner: node owner (LAN or RDMA) 1673 * 1674 * This function adds the VSI child nodes to tree. It gets called for 1675 * LAN and RDMA separately. 1676 */ 1677 static int 1678 ice_sched_add_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle, 1679 struct ice_sched_node *tc_node, u16 *num_nodes, 1680 u8 owner) 1681 { 1682 struct ice_sched_node *parent, *node; 1683 struct ice_hw *hw = pi->hw; 1684 u32 first_node_teid; 1685 u16 num_added = 0; 1686 u8 i, qgl, vsil; 1687 1688 qgl = ice_sched_get_qgrp_layer(hw); 1689 vsil = ice_sched_get_vsi_layer(hw); 1690 parent = ice_sched_get_vsi_node(pi, tc_node, vsi_handle); 1691 for (i = vsil + 1; i <= qgl; i++) { 1692 int status; 1693 1694 if (!parent) 1695 return -EIO; 1696 1697 status = ice_sched_add_nodes_to_layer(pi, tc_node, parent, i, 1698 num_nodes[i], 1699 &first_node_teid, 1700 &num_added); 1701 if (status || num_nodes[i] != num_added) 1702 return -EIO; 1703 1704 /* The newly added node can be a new parent for the next 1705 * layer nodes 1706 */ 1707 if (num_added) { 1708 parent = ice_sched_find_node_by_teid(tc_node, 1709 first_node_teid); 1710 node = parent; 1711 while (node) { 1712 node->owner = owner; 1713 node = node->sibling; 1714 } 1715 } else { 1716 parent = parent->children[0]; 1717 } 1718 } 1719 1720 return 0; 1721 } 1722 1723 /** 1724 * ice_sched_calc_vsi_support_nodes - calculate number of VSI support nodes 1725 * @pi: pointer to the port info structure 1726 * @tc_node: pointer to TC node 1727 * @num_nodes: pointer to num nodes array 1728 * 1729 * This function calculates the number of supported nodes needed to add this 1730 * VSI into Tx tree including the VSI, parent and intermediate nodes in below 1731 * layers 1732 */ 1733 static void 1734 ice_sched_calc_vsi_support_nodes(struct ice_port_info *pi, 1735 struct ice_sched_node *tc_node, u16 *num_nodes) 1736 { 1737 struct ice_sched_node *node; 1738 u8 vsil; 1739 int i; 1740 1741 vsil = ice_sched_get_vsi_layer(pi->hw); 1742 for (i = vsil; i >= pi->hw->sw_entry_point_layer; i--) 1743 /* Add intermediate nodes if TC has no children and 1744 * need at least one node for VSI 1745 */ 1746 if (!tc_node->num_children || i == vsil) { 1747 num_nodes[i]++; 1748 } else { 1749 /* If intermediate nodes are reached max children 1750 * then add a new one. 1751 */ 1752 node = ice_sched_get_first_node(pi, tc_node, (u8)i); 1753 /* scan all the siblings */ 1754 while (node) { 1755 if (node->num_children < pi->hw->max_children[i]) 1756 break; 1757 node = node->sibling; 1758 } 1759 1760 /* tree has one intermediate node to add this new VSI. 1761 * So no need to calculate supported nodes for below 1762 * layers. 1763 */ 1764 if (node) 1765 break; 1766 /* all the nodes are full, allocate a new one */ 1767 num_nodes[i]++; 1768 } 1769 } 1770 1771 /** 1772 * ice_sched_add_vsi_support_nodes - add VSI supported nodes into Tx tree 1773 * @pi: port information structure 1774 * @vsi_handle: software VSI handle 1775 * @tc_node: pointer to TC node 1776 * @num_nodes: pointer to num nodes array 1777 * 1778 * This function adds the VSI supported nodes into Tx tree including the 1779 * VSI, its parent and intermediate nodes in below layers 1780 */ 1781 static int 1782 ice_sched_add_vsi_support_nodes(struct ice_port_info *pi, u16 vsi_handle, 1783 struct ice_sched_node *tc_node, u16 *num_nodes) 1784 { 1785 struct ice_sched_node *parent = tc_node; 1786 u32 first_node_teid; 1787 u16 num_added = 0; 1788 u8 i, vsil; 1789 1790 if (!pi) 1791 return -EINVAL; 1792 1793 vsil = ice_sched_get_vsi_layer(pi->hw); 1794 for (i = pi->hw->sw_entry_point_layer; i <= vsil; i++) { 1795 int status; 1796 1797 status = ice_sched_add_nodes_to_layer(pi, tc_node, parent, 1798 i, num_nodes[i], 1799 &first_node_teid, 1800 &num_added); 1801 if (status || num_nodes[i] != num_added) 1802 return -EIO; 1803 1804 /* The newly added node can be a new parent for the next 1805 * layer nodes 1806 */ 1807 if (num_added) 1808 parent = ice_sched_find_node_by_teid(tc_node, 1809 first_node_teid); 1810 else 1811 parent = parent->children[0]; 1812 1813 if (!parent) 1814 return -EIO; 1815 1816 /* Do not modify the VSI handle for already existing VSI nodes, 1817 * (if no new VSI node was added to the tree). 1818 * Assign the VSI handle only to newly added VSI nodes. 1819 */ 1820 if (i == vsil && num_added) 1821 parent->vsi_handle = vsi_handle; 1822 } 1823 1824 return 0; 1825 } 1826 1827 /** 1828 * ice_sched_add_vsi_to_topo - add a new VSI into tree 1829 * @pi: port information structure 1830 * @vsi_handle: software VSI handle 1831 * @tc: TC number 1832 * 1833 * This function adds a new VSI into scheduler tree 1834 */ 1835 static int 1836 ice_sched_add_vsi_to_topo(struct ice_port_info *pi, u16 vsi_handle, u8 tc) 1837 { 1838 u16 num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 }; 1839 struct ice_sched_node *tc_node; 1840 1841 tc_node = ice_sched_get_tc_node(pi, tc); 1842 if (!tc_node) 1843 return -EINVAL; 1844 1845 /* calculate number of supported nodes needed for this VSI */ 1846 ice_sched_calc_vsi_support_nodes(pi, tc_node, num_nodes); 1847 1848 /* add VSI supported nodes to TC subtree */ 1849 return ice_sched_add_vsi_support_nodes(pi, vsi_handle, tc_node, 1850 num_nodes); 1851 } 1852 1853 /** 1854 * ice_sched_recalc_vsi_support_nodes - recalculate VSI support nodes count 1855 * @hw: pointer to the HW struct 1856 * @vsi_node: pointer to the leftmost VSI node that needs to be extended 1857 * @new_numqs: new number of queues that has to be handled by the VSI 1858 * @new_num_nodes: pointer to nodes count table to modify the VSI layer entry 1859 * 1860 * This function recalculates the number of supported nodes that need to 1861 * be added after adding more Tx queues for a given VSI. 1862 * The number of new VSI support nodes that shall be added will be saved 1863 * to the @new_num_nodes table for the VSI layer. 1864 */ 1865 static void 1866 ice_sched_recalc_vsi_support_nodes(struct ice_hw *hw, 1867 struct ice_sched_node *vsi_node, 1868 unsigned int new_numqs, u16 *new_num_nodes) 1869 { 1870 u32 vsi_nodes_cnt = 1; 1871 u32 max_queue_cnt = 1; 1872 u32 qgl, vsil; 1873 1874 qgl = ice_sched_get_qgrp_layer(hw); 1875 vsil = ice_sched_get_vsi_layer(hw); 1876 1877 for (u32 i = vsil; i <= qgl; i++) 1878 max_queue_cnt *= hw->max_children[i]; 1879 1880 while ((vsi_node = ice_sched_find_next_vsi_node(vsi_node)) != NULL) 1881 vsi_nodes_cnt++; 1882 1883 if (new_numqs > (max_queue_cnt * vsi_nodes_cnt)) 1884 new_num_nodes[vsil] = DIV_ROUND_UP(new_numqs, max_queue_cnt) - 1885 vsi_nodes_cnt; 1886 } 1887 1888 /** 1889 * ice_sched_update_vsi_child_nodes - update VSI child nodes 1890 * @pi: port information structure 1891 * @vsi_handle: software VSI handle 1892 * @tc: TC number 1893 * @new_numqs: new number of max queues 1894 * @owner: owner of this subtree 1895 * 1896 * This function updates the VSI child nodes based on the number of queues 1897 */ 1898 static int 1899 ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle, 1900 u8 tc, u16 new_numqs, u8 owner) 1901 { 1902 u16 new_num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 }; 1903 struct ice_sched_node *vsi_node; 1904 struct ice_sched_node *tc_node; 1905 struct ice_vsi_ctx *vsi_ctx; 1906 struct ice_hw *hw = pi->hw; 1907 u16 prev_numqs; 1908 int status = 0; 1909 1910 tc_node = ice_sched_get_tc_node(pi, tc); 1911 if (!tc_node) 1912 return -EIO; 1913 1914 vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle); 1915 if (!vsi_node) 1916 return -EIO; 1917 1918 vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle); 1919 if (!vsi_ctx) 1920 return -EINVAL; 1921 1922 if (owner == ICE_SCHED_NODE_OWNER_LAN) 1923 prev_numqs = vsi_ctx->sched.max_lanq[tc]; 1924 else 1925 prev_numqs = vsi_ctx->sched.max_rdmaq[tc]; 1926 /* num queues are not changed or less than the previous number */ 1927 if (new_numqs <= prev_numqs) 1928 return status; 1929 if (owner == ICE_SCHED_NODE_OWNER_LAN) { 1930 status = ice_alloc_lan_q_ctx(hw, vsi_handle, tc, new_numqs); 1931 if (status) 1932 return status; 1933 } else { 1934 status = ice_alloc_rdma_q_ctx(hw, vsi_handle, tc, new_numqs); 1935 if (status) 1936 return status; 1937 } 1938 1939 ice_sched_recalc_vsi_support_nodes(hw, vsi_node, 1940 new_numqs, new_num_nodes); 1941 ice_sched_calc_vsi_child_nodes(hw, new_numqs - prev_numqs, 1942 new_num_nodes); 1943 1944 /* Never decrease the number of queues in the tree. Update the tree 1945 * only if number of queues > previous number of queues. This may 1946 * leave some extra nodes in the tree if number of queues < previous 1947 * number but that wouldn't harm anything. Removing those extra nodes 1948 * may complicate the code if those nodes are part of SRL or 1949 * individually rate limited. 1950 * Also, add the required VSI support nodes if the existing ones cannot 1951 * handle the requested new number of queues. 1952 */ 1953 status = ice_sched_add_vsi_support_nodes(pi, vsi_handle, tc_node, 1954 new_num_nodes); 1955 if (status) 1956 return status; 1957 1958 status = ice_sched_add_vsi_child_nodes(pi, vsi_handle, tc_node, 1959 new_num_nodes, owner); 1960 if (status) 1961 return status; 1962 if (owner == ICE_SCHED_NODE_OWNER_LAN) 1963 vsi_ctx->sched.max_lanq[tc] = new_numqs; 1964 else 1965 vsi_ctx->sched.max_rdmaq[tc] = new_numqs; 1966 1967 return 0; 1968 } 1969 1970 /** 1971 * ice_sched_cfg_vsi - configure the new/existing VSI 1972 * @pi: port information structure 1973 * @vsi_handle: software VSI handle 1974 * @tc: TC number 1975 * @maxqs: max number of queues 1976 * @owner: LAN or RDMA 1977 * @enable: TC enabled or disabled 1978 * 1979 * This function adds/updates VSI nodes based on the number of queues. If TC is 1980 * enabled and VSI is in suspended state then resume the VSI back. If TC is 1981 * disabled then suspend the VSI if it is not already. 1982 */ 1983 int 1984 ice_sched_cfg_vsi(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 maxqs, 1985 u8 owner, bool enable) 1986 { 1987 struct ice_sched_node *vsi_node, *tc_node; 1988 struct ice_vsi_ctx *vsi_ctx; 1989 struct ice_hw *hw = pi->hw; 1990 int status = 0; 1991 1992 ice_debug(pi->hw, ICE_DBG_SCHED, "add/config VSI %d\n", vsi_handle); 1993 tc_node = ice_sched_get_tc_node(pi, tc); 1994 if (!tc_node) 1995 return -EINVAL; 1996 vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle); 1997 if (!vsi_ctx) 1998 return -EINVAL; 1999 vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle); 2000 2001 /* suspend the VSI if TC is not enabled */ 2002 if (!enable) { 2003 if (vsi_node && vsi_node->in_use) { 2004 u32 teid = le32_to_cpu(vsi_node->info.node_teid); 2005 2006 status = ice_sched_suspend_resume_elems(hw, 1, &teid, 2007 true); 2008 if (!status) 2009 vsi_node->in_use = false; 2010 } 2011 return status; 2012 } 2013 2014 /* TC is enabled, if it is a new VSI then add it to the tree */ 2015 if (!vsi_node) { 2016 status = ice_sched_add_vsi_to_topo(pi, vsi_handle, tc); 2017 if (status) 2018 return status; 2019 2020 vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle); 2021 if (!vsi_node) 2022 return -EIO; 2023 2024 vsi_ctx->sched.vsi_node[tc] = vsi_node; 2025 vsi_node->in_use = true; 2026 /* invalidate the max queues whenever VSI gets added first time 2027 * into the scheduler tree (boot or after reset). We need to 2028 * recreate the child nodes all the time in these cases. 2029 */ 2030 vsi_ctx->sched.max_lanq[tc] = 0; 2031 vsi_ctx->sched.max_rdmaq[tc] = 0; 2032 } 2033 2034 /* update the VSI child nodes */ 2035 status = ice_sched_update_vsi_child_nodes(pi, vsi_handle, tc, maxqs, 2036 owner); 2037 if (status) 2038 return status; 2039 2040 /* TC is enabled, resume the VSI if it is in the suspend state */ 2041 if (!vsi_node->in_use) { 2042 u32 teid = le32_to_cpu(vsi_node->info.node_teid); 2043 2044 status = ice_sched_suspend_resume_elems(hw, 1, &teid, false); 2045 if (!status) 2046 vsi_node->in_use = true; 2047 } 2048 2049 return status; 2050 } 2051 2052 /** 2053 * ice_sched_rm_agg_vsi_info - remove aggregator related VSI info entry 2054 * @pi: port information structure 2055 * @vsi_handle: software VSI handle 2056 * 2057 * This function removes single aggregator VSI info entry from 2058 * aggregator list. 2059 */ 2060 static void ice_sched_rm_agg_vsi_info(struct ice_port_info *pi, u16 vsi_handle) 2061 { 2062 struct ice_sched_agg_info *agg_info; 2063 struct ice_sched_agg_info *atmp; 2064 2065 list_for_each_entry_safe(agg_info, atmp, &pi->hw->agg_list, 2066 list_entry) { 2067 struct ice_sched_agg_vsi_info *agg_vsi_info; 2068 struct ice_sched_agg_vsi_info *vtmp; 2069 2070 list_for_each_entry_safe(agg_vsi_info, vtmp, 2071 &agg_info->agg_vsi_list, list_entry) 2072 if (agg_vsi_info->vsi_handle == vsi_handle) { 2073 list_del(&agg_vsi_info->list_entry); 2074 devm_kfree(ice_hw_to_dev(pi->hw), 2075 agg_vsi_info); 2076 return; 2077 } 2078 } 2079 } 2080 2081 /** 2082 * ice_sched_is_leaf_node_present - check for a leaf node in the sub-tree 2083 * @node: pointer to the sub-tree node 2084 * 2085 * This function checks for a leaf node presence in a given sub-tree node. 2086 */ 2087 static bool ice_sched_is_leaf_node_present(struct ice_sched_node *node) 2088 { 2089 u8 i; 2090 2091 for (i = 0; i < node->num_children; i++) 2092 if (ice_sched_is_leaf_node_present(node->children[i])) 2093 return true; 2094 /* check for a leaf node */ 2095 return (node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF); 2096 } 2097 2098 /** 2099 * ice_sched_rm_vsi_subtree - remove all nodes assigned to a given VSI 2100 * @pi: port information structure 2101 * @vsi_node: pointer to the leftmost node of the VSI to be removed 2102 * @owner: LAN or RDMA 2103 * @tc: TC number 2104 * 2105 * Return: Zero in case of success, or -EBUSY if the VSI has leaf nodes in TC. 2106 * 2107 * This function removes all the VSI support nodes associated with a given VSI 2108 * and its LAN or RDMA children nodes from the scheduler tree. 2109 */ 2110 static int 2111 ice_sched_rm_vsi_subtree(struct ice_port_info *pi, 2112 struct ice_sched_node *vsi_node, u8 owner, u8 tc) 2113 { 2114 u16 vsi_handle = vsi_node->vsi_handle; 2115 bool all_vsi_nodes_removed = true; 2116 int j = 0; 2117 2118 while (vsi_node) { 2119 struct ice_sched_node *next_vsi_node; 2120 2121 if (ice_sched_is_leaf_node_present(vsi_node)) { 2122 ice_debug(pi->hw, ICE_DBG_SCHED, "VSI has leaf nodes in TC %d\n", tc); 2123 return -EBUSY; 2124 } 2125 while (j < vsi_node->num_children) { 2126 if (vsi_node->children[j]->owner == owner) 2127 ice_free_sched_node(pi, vsi_node->children[j]); 2128 else 2129 j++; 2130 } 2131 2132 next_vsi_node = ice_sched_find_next_vsi_node(vsi_node); 2133 2134 /* remove the VSI if it has no children */ 2135 if (!vsi_node->num_children) 2136 ice_free_sched_node(pi, vsi_node); 2137 else 2138 all_vsi_nodes_removed = false; 2139 2140 vsi_node = next_vsi_node; 2141 } 2142 2143 /* clean up aggregator related VSI info if any */ 2144 if (all_vsi_nodes_removed) 2145 ice_sched_rm_agg_vsi_info(pi, vsi_handle); 2146 2147 return 0; 2148 } 2149 2150 /** 2151 * ice_sched_rm_vsi_cfg - remove the VSI and its children nodes 2152 * @pi: port information structure 2153 * @vsi_handle: software VSI handle 2154 * @owner: LAN or RDMA 2155 * 2156 * This function removes the VSI and its LAN or RDMA children nodes from the 2157 * scheduler tree. 2158 */ 2159 static int 2160 ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner) 2161 { 2162 struct ice_vsi_ctx *vsi_ctx; 2163 int status = -EINVAL; 2164 u8 i; 2165 2166 ice_debug(pi->hw, ICE_DBG_SCHED, "removing VSI %d\n", vsi_handle); 2167 if (!ice_is_vsi_valid(pi->hw, vsi_handle)) 2168 return status; 2169 mutex_lock(&pi->sched_lock); 2170 vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle); 2171 if (!vsi_ctx) 2172 goto exit_sched_rm_vsi_cfg; 2173 2174 ice_for_each_traffic_class(i) { 2175 struct ice_sched_node *vsi_node, *tc_node; 2176 2177 tc_node = ice_sched_get_tc_node(pi, i); 2178 if (!tc_node) 2179 continue; 2180 2181 vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle); 2182 if (!vsi_node) 2183 continue; 2184 2185 status = ice_sched_rm_vsi_subtree(pi, vsi_node, owner, i); 2186 if (status) 2187 goto exit_sched_rm_vsi_cfg; 2188 2189 vsi_ctx->sched.vsi_node[i] = NULL; 2190 2191 if (owner == ICE_SCHED_NODE_OWNER_LAN) 2192 vsi_ctx->sched.max_lanq[i] = 0; 2193 else 2194 vsi_ctx->sched.max_rdmaq[i] = 0; 2195 } 2196 status = 0; 2197 2198 exit_sched_rm_vsi_cfg: 2199 mutex_unlock(&pi->sched_lock); 2200 return status; 2201 } 2202 2203 /** 2204 * ice_rm_vsi_lan_cfg - remove VSI and its LAN children nodes 2205 * @pi: port information structure 2206 * @vsi_handle: software VSI handle 2207 * 2208 * This function clears the VSI and its LAN children nodes from scheduler tree 2209 * for all TCs. 2210 */ 2211 int ice_rm_vsi_lan_cfg(struct ice_port_info *pi, u16 vsi_handle) 2212 { 2213 return ice_sched_rm_vsi_cfg(pi, vsi_handle, ICE_SCHED_NODE_OWNER_LAN); 2214 } 2215 2216 /** 2217 * ice_rm_vsi_rdma_cfg - remove VSI and its RDMA children nodes 2218 * @pi: port information structure 2219 * @vsi_handle: software VSI handle 2220 * 2221 * This function clears the VSI and its RDMA children nodes from scheduler tree 2222 * for all TCs. 2223 */ 2224 int ice_rm_vsi_rdma_cfg(struct ice_port_info *pi, u16 vsi_handle) 2225 { 2226 return ice_sched_rm_vsi_cfg(pi, vsi_handle, ICE_SCHED_NODE_OWNER_RDMA); 2227 } 2228 2229 /** 2230 * ice_get_agg_info - get the aggregator ID 2231 * @hw: pointer to the hardware structure 2232 * @agg_id: aggregator ID 2233 * 2234 * This function validates aggregator ID. The function returns info if 2235 * aggregator ID is present in list otherwise it returns null. 2236 */ 2237 static struct ice_sched_agg_info * 2238 ice_get_agg_info(struct ice_hw *hw, u32 agg_id) 2239 { 2240 struct ice_sched_agg_info *agg_info; 2241 2242 list_for_each_entry(agg_info, &hw->agg_list, list_entry) 2243 if (agg_info->agg_id == agg_id) 2244 return agg_info; 2245 2246 return NULL; 2247 } 2248 2249 /** 2250 * ice_sched_get_free_vsi_parent - Find a free parent node in aggregator subtree 2251 * @hw: pointer to the HW struct 2252 * @node: pointer to a child node 2253 * @num_nodes: num nodes count array 2254 * 2255 * This function walks through the aggregator subtree to find a free parent 2256 * node 2257 */ 2258 struct ice_sched_node * 2259 ice_sched_get_free_vsi_parent(struct ice_hw *hw, struct ice_sched_node *node, 2260 u16 *num_nodes) 2261 { 2262 u8 l = node->tx_sched_layer; 2263 u8 vsil, i; 2264 2265 vsil = ice_sched_get_vsi_layer(hw); 2266 2267 /* Is it VSI parent layer ? */ 2268 if (l == vsil - 1) 2269 return (node->num_children < hw->max_children[l]) ? node : NULL; 2270 2271 /* We have intermediate nodes. Let's walk through the subtree. If the 2272 * intermediate node has space to add a new node then clear the count 2273 */ 2274 if (node->num_children < hw->max_children[l]) 2275 num_nodes[l] = 0; 2276 /* The below recursive call is intentional and wouldn't go more than 2277 * 2 or 3 iterations. 2278 */ 2279 2280 for (i = 0; i < node->num_children; i++) { 2281 struct ice_sched_node *parent; 2282 2283 parent = ice_sched_get_free_vsi_parent(hw, node->children[i], 2284 num_nodes); 2285 if (parent) 2286 return parent; 2287 } 2288 2289 return NULL; 2290 } 2291 2292 /** 2293 * ice_sched_update_parent - update the new parent in SW DB 2294 * @new_parent: pointer to a new parent node 2295 * @node: pointer to a child node 2296 * 2297 * This function removes the child from the old parent and adds it to a new 2298 * parent 2299 */ 2300 void 2301 ice_sched_update_parent(struct ice_sched_node *new_parent, 2302 struct ice_sched_node *node) 2303 { 2304 struct ice_sched_node *old_parent; 2305 u8 i, j; 2306 2307 old_parent = node->parent; 2308 2309 /* update the old parent children */ 2310 for (i = 0; i < old_parent->num_children; i++) 2311 if (old_parent->children[i] == node) { 2312 for (j = i + 1; j < old_parent->num_children; j++) 2313 old_parent->children[j - 1] = 2314 old_parent->children[j]; 2315 old_parent->num_children--; 2316 break; 2317 } 2318 2319 /* now move the node to a new parent */ 2320 new_parent->children[new_parent->num_children++] = node; 2321 node->parent = new_parent; 2322 node->info.parent_teid = new_parent->info.node_teid; 2323 } 2324 2325 /** 2326 * ice_sched_move_nodes - move child nodes to a given parent 2327 * @pi: port information structure 2328 * @parent: pointer to parent node 2329 * @num_items: number of child nodes to be moved 2330 * @list: pointer to child node teids 2331 * 2332 * This function move the child nodes to a given parent. 2333 */ 2334 int 2335 ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent, 2336 u16 num_items, u32 *list) 2337 { 2338 DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1); 2339 u16 buf_len = __struct_size(buf); 2340 struct ice_sched_node *node; 2341 u16 i, grps_movd = 0; 2342 struct ice_hw *hw; 2343 int status = 0; 2344 2345 hw = pi->hw; 2346 2347 if (!parent || !num_items) 2348 return -EINVAL; 2349 2350 /* Does parent have enough space */ 2351 if (parent->num_children + num_items > 2352 hw->max_children[parent->tx_sched_layer]) 2353 return -ENOSPC; 2354 2355 for (i = 0; i < num_items; i++) { 2356 node = ice_sched_find_node_by_teid(pi->root, list[i]); 2357 if (!node) { 2358 status = -EINVAL; 2359 break; 2360 } 2361 2362 buf->hdr.src_parent_teid = node->info.parent_teid; 2363 buf->hdr.dest_parent_teid = parent->info.node_teid; 2364 buf->teid[0] = node->info.node_teid; 2365 buf->hdr.num_elems = cpu_to_le16(1); 2366 status = ice_aq_move_sched_elems(hw, buf, buf_len, &grps_movd); 2367 if (status && grps_movd != 1) { 2368 status = -EIO; 2369 break; 2370 } 2371 2372 /* update the SW DB */ 2373 ice_sched_update_parent(parent, node); 2374 } 2375 2376 return status; 2377 } 2378 2379 /** 2380 * ice_sched_move_vsi_to_agg - move VSI to aggregator node 2381 * @pi: port information structure 2382 * @vsi_handle: software VSI handle 2383 * @agg_id: aggregator ID 2384 * @tc: TC number 2385 * 2386 * This function moves a VSI to an aggregator node or its subtree. 2387 * Intermediate nodes may be created if required. 2388 */ 2389 static int 2390 ice_sched_move_vsi_to_agg(struct ice_port_info *pi, u16 vsi_handle, u32 agg_id, 2391 u8 tc) 2392 { 2393 struct ice_sched_node *vsi_node, *agg_node, *tc_node, *parent; 2394 u16 num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 }; 2395 u32 first_node_teid, vsi_teid; 2396 u16 num_nodes_added; 2397 u8 aggl, vsil, i; 2398 int status; 2399 2400 tc_node = ice_sched_get_tc_node(pi, tc); 2401 if (!tc_node) 2402 return -EIO; 2403 2404 agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id); 2405 if (!agg_node) 2406 return -ENOENT; 2407 2408 vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle); 2409 if (!vsi_node) 2410 return -ENOENT; 2411 2412 /* Is this VSI already part of given aggregator? */ 2413 if (ice_sched_find_node_in_subtree(pi->hw, agg_node, vsi_node)) 2414 return 0; 2415 2416 aggl = ice_sched_get_agg_layer(pi->hw); 2417 vsil = ice_sched_get_vsi_layer(pi->hw); 2418 2419 /* set intermediate node count to 1 between aggregator and VSI layers */ 2420 for (i = aggl + 1; i < vsil; i++) 2421 num_nodes[i] = 1; 2422 2423 /* Check if the aggregator subtree has any free node to add the VSI */ 2424 for (i = 0; i < agg_node->num_children; i++) { 2425 parent = ice_sched_get_free_vsi_parent(pi->hw, 2426 agg_node->children[i], 2427 num_nodes); 2428 if (parent) 2429 goto move_nodes; 2430 } 2431 2432 /* add new nodes */ 2433 parent = agg_node; 2434 for (i = aggl + 1; i < vsil; i++) { 2435 status = ice_sched_add_nodes_to_layer(pi, tc_node, parent, i, 2436 num_nodes[i], 2437 &first_node_teid, 2438 &num_nodes_added); 2439 if (status || num_nodes[i] != num_nodes_added) 2440 return -EIO; 2441 2442 /* The newly added node can be a new parent for the next 2443 * layer nodes 2444 */ 2445 if (num_nodes_added) 2446 parent = ice_sched_find_node_by_teid(tc_node, 2447 first_node_teid); 2448 else 2449 parent = parent->children[0]; 2450 2451 if (!parent) 2452 return -EIO; 2453 } 2454 2455 move_nodes: 2456 vsi_teid = le32_to_cpu(vsi_node->info.node_teid); 2457 return ice_sched_move_nodes(pi, parent, 1, &vsi_teid); 2458 } 2459 2460 /** 2461 * ice_move_all_vsi_to_dflt_agg - move all VSI(s) to default aggregator 2462 * @pi: port information structure 2463 * @agg_info: aggregator info 2464 * @tc: traffic class number 2465 * @rm_vsi_info: true or false 2466 * 2467 * This function move all the VSI(s) to the default aggregator and delete 2468 * aggregator VSI info based on passed in boolean parameter rm_vsi_info. The 2469 * caller holds the scheduler lock. 2470 */ 2471 static int 2472 ice_move_all_vsi_to_dflt_agg(struct ice_port_info *pi, 2473 struct ice_sched_agg_info *agg_info, u8 tc, 2474 bool rm_vsi_info) 2475 { 2476 struct ice_sched_agg_vsi_info *agg_vsi_info; 2477 struct ice_sched_agg_vsi_info *tmp; 2478 int status = 0; 2479 2480 list_for_each_entry_safe(agg_vsi_info, tmp, &agg_info->agg_vsi_list, 2481 list_entry) { 2482 u16 vsi_handle = agg_vsi_info->vsi_handle; 2483 2484 /* Move VSI to default aggregator */ 2485 if (!ice_is_tc_ena(agg_vsi_info->tc_bitmap[0], tc)) 2486 continue; 2487 2488 status = ice_sched_move_vsi_to_agg(pi, vsi_handle, 2489 ICE_DFLT_AGG_ID, tc); 2490 if (status) 2491 break; 2492 2493 clear_bit(tc, agg_vsi_info->tc_bitmap); 2494 if (rm_vsi_info && !agg_vsi_info->tc_bitmap[0]) { 2495 list_del(&agg_vsi_info->list_entry); 2496 devm_kfree(ice_hw_to_dev(pi->hw), agg_vsi_info); 2497 } 2498 } 2499 2500 return status; 2501 } 2502 2503 /** 2504 * ice_sched_is_agg_inuse - check whether the aggregator is in use or not 2505 * @pi: port information structure 2506 * @node: node pointer 2507 * 2508 * This function checks whether the aggregator is attached with any VSI or not. 2509 */ 2510 static bool 2511 ice_sched_is_agg_inuse(struct ice_port_info *pi, struct ice_sched_node *node) 2512 { 2513 u8 vsil, i; 2514 2515 vsil = ice_sched_get_vsi_layer(pi->hw); 2516 if (node->tx_sched_layer < vsil - 1) { 2517 for (i = 0; i < node->num_children; i++) 2518 if (ice_sched_is_agg_inuse(pi, node->children[i])) 2519 return true; 2520 return false; 2521 } else { 2522 return node->num_children ? true : false; 2523 } 2524 } 2525 2526 /** 2527 * ice_sched_rm_agg_cfg - remove the aggregator node 2528 * @pi: port information structure 2529 * @agg_id: aggregator ID 2530 * @tc: TC number 2531 * 2532 * This function removes the aggregator node and intermediate nodes if any 2533 * from the given TC 2534 */ 2535 static int 2536 ice_sched_rm_agg_cfg(struct ice_port_info *pi, u32 agg_id, u8 tc) 2537 { 2538 struct ice_sched_node *tc_node, *agg_node; 2539 struct ice_hw *hw = pi->hw; 2540 2541 tc_node = ice_sched_get_tc_node(pi, tc); 2542 if (!tc_node) 2543 return -EIO; 2544 2545 agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id); 2546 if (!agg_node) 2547 return -ENOENT; 2548 2549 /* Can't remove the aggregator node if it has children */ 2550 if (ice_sched_is_agg_inuse(pi, agg_node)) 2551 return -EBUSY; 2552 2553 /* need to remove the whole subtree if aggregator node is the 2554 * only child. 2555 */ 2556 while (agg_node->tx_sched_layer > hw->sw_entry_point_layer) { 2557 struct ice_sched_node *parent = agg_node->parent; 2558 2559 if (!parent) 2560 return -EIO; 2561 2562 if (parent->num_children > 1) 2563 break; 2564 2565 agg_node = parent; 2566 } 2567 2568 ice_free_sched_node(pi, agg_node); 2569 return 0; 2570 } 2571 2572 /** 2573 * ice_rm_agg_cfg_tc - remove aggregator configuration for TC 2574 * @pi: port information structure 2575 * @agg_info: aggregator ID 2576 * @tc: TC number 2577 * @rm_vsi_info: bool value true or false 2578 * 2579 * This function removes aggregator reference to VSI of given TC. It removes 2580 * the aggregator configuration completely for requested TC. The caller needs 2581 * to hold the scheduler lock. 2582 */ 2583 static int 2584 ice_rm_agg_cfg_tc(struct ice_port_info *pi, struct ice_sched_agg_info *agg_info, 2585 u8 tc, bool rm_vsi_info) 2586 { 2587 int status = 0; 2588 2589 /* If nothing to remove - return success */ 2590 if (!ice_is_tc_ena(agg_info->tc_bitmap[0], tc)) 2591 goto exit_rm_agg_cfg_tc; 2592 2593 status = ice_move_all_vsi_to_dflt_agg(pi, agg_info, tc, rm_vsi_info); 2594 if (status) 2595 goto exit_rm_agg_cfg_tc; 2596 2597 /* Delete aggregator node(s) */ 2598 status = ice_sched_rm_agg_cfg(pi, agg_info->agg_id, tc); 2599 if (status) 2600 goto exit_rm_agg_cfg_tc; 2601 2602 clear_bit(tc, agg_info->tc_bitmap); 2603 exit_rm_agg_cfg_tc: 2604 return status; 2605 } 2606 2607 /** 2608 * ice_save_agg_tc_bitmap - save aggregator TC bitmap 2609 * @pi: port information structure 2610 * @agg_id: aggregator ID 2611 * @tc_bitmap: 8 bits TC bitmap 2612 * 2613 * Save aggregator TC bitmap. This function needs to be called with scheduler 2614 * lock held. 2615 */ 2616 static int 2617 ice_save_agg_tc_bitmap(struct ice_port_info *pi, u32 agg_id, 2618 unsigned long *tc_bitmap) 2619 { 2620 struct ice_sched_agg_info *agg_info; 2621 2622 agg_info = ice_get_agg_info(pi->hw, agg_id); 2623 if (!agg_info) 2624 return -EINVAL; 2625 bitmap_copy(agg_info->replay_tc_bitmap, tc_bitmap, 2626 ICE_MAX_TRAFFIC_CLASS); 2627 return 0; 2628 } 2629 2630 /** 2631 * ice_sched_add_agg_cfg - create an aggregator node 2632 * @pi: port information structure 2633 * @agg_id: aggregator ID 2634 * @tc: TC number 2635 * 2636 * This function creates an aggregator node and intermediate nodes if required 2637 * for the given TC 2638 */ 2639 static int 2640 ice_sched_add_agg_cfg(struct ice_port_info *pi, u32 agg_id, u8 tc) 2641 { 2642 struct ice_sched_node *parent, *agg_node, *tc_node; 2643 u16 num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 }; 2644 struct ice_hw *hw = pi->hw; 2645 u32 first_node_teid; 2646 u16 num_nodes_added; 2647 int status = 0; 2648 u8 i, aggl; 2649 2650 tc_node = ice_sched_get_tc_node(pi, tc); 2651 if (!tc_node) 2652 return -EIO; 2653 2654 agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id); 2655 /* Does Agg node already exist ? */ 2656 if (agg_node) 2657 return status; 2658 2659 aggl = ice_sched_get_agg_layer(hw); 2660 2661 /* need one node in Agg layer */ 2662 num_nodes[aggl] = 1; 2663 2664 /* Check whether the intermediate nodes have space to add the 2665 * new aggregator. If they are full, then SW needs to allocate a new 2666 * intermediate node on those layers 2667 */ 2668 for (i = hw->sw_entry_point_layer; i < aggl; i++) { 2669 parent = ice_sched_get_first_node(pi, tc_node, i); 2670 2671 /* scan all the siblings */ 2672 while (parent) { 2673 if (parent->num_children < hw->max_children[i]) 2674 break; 2675 parent = parent->sibling; 2676 } 2677 2678 /* all the nodes are full, reserve one for this layer */ 2679 if (!parent) 2680 num_nodes[i]++; 2681 } 2682 2683 /* add the aggregator node */ 2684 parent = tc_node; 2685 for (i = hw->sw_entry_point_layer; i <= aggl; i++) { 2686 if (!parent) 2687 return -EIO; 2688 2689 status = ice_sched_add_nodes_to_layer(pi, tc_node, parent, i, 2690 num_nodes[i], 2691 &first_node_teid, 2692 &num_nodes_added); 2693 if (status || num_nodes[i] != num_nodes_added) 2694 return -EIO; 2695 2696 /* The newly added node can be a new parent for the next 2697 * layer nodes 2698 */ 2699 if (num_nodes_added) { 2700 parent = ice_sched_find_node_by_teid(tc_node, 2701 first_node_teid); 2702 /* register aggregator ID with the aggregator node */ 2703 if (parent && i == aggl) 2704 parent->agg_id = agg_id; 2705 } else { 2706 parent = parent->children[0]; 2707 } 2708 } 2709 2710 return 0; 2711 } 2712 2713 /** 2714 * ice_sched_cfg_agg - configure aggregator node 2715 * @pi: port information structure 2716 * @agg_id: aggregator ID 2717 * @agg_type: aggregator type queue, VSI, or aggregator group 2718 * @tc_bitmap: bits TC bitmap 2719 * 2720 * It registers a unique aggregator node into scheduler services. It 2721 * allows a user to register with a unique ID to track it's resources. 2722 * The aggregator type determines if this is a queue group, VSI group 2723 * or aggregator group. It then creates the aggregator node(s) for requested 2724 * TC(s) or removes an existing aggregator node including its configuration 2725 * if indicated via tc_bitmap. Call ice_rm_agg_cfg to release aggregator 2726 * resources and remove aggregator ID. 2727 * This function needs to be called with scheduler lock held. 2728 */ 2729 static int 2730 ice_sched_cfg_agg(struct ice_port_info *pi, u32 agg_id, 2731 enum ice_agg_type agg_type, unsigned long *tc_bitmap) 2732 { 2733 struct ice_sched_agg_info *agg_info; 2734 struct ice_hw *hw = pi->hw; 2735 int status = 0; 2736 u8 tc; 2737 2738 agg_info = ice_get_agg_info(hw, agg_id); 2739 if (!agg_info) { 2740 /* Create new entry for new aggregator ID */ 2741 agg_info = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*agg_info), 2742 GFP_KERNEL); 2743 if (!agg_info) 2744 return -ENOMEM; 2745 2746 agg_info->agg_id = agg_id; 2747 agg_info->agg_type = agg_type; 2748 agg_info->tc_bitmap[0] = 0; 2749 2750 /* Initialize the aggregator VSI list head */ 2751 INIT_LIST_HEAD(&agg_info->agg_vsi_list); 2752 2753 /* Add new entry in aggregator list */ 2754 list_add(&agg_info->list_entry, &hw->agg_list); 2755 } 2756 /* Create aggregator node(s) for requested TC(s) */ 2757 ice_for_each_traffic_class(tc) { 2758 if (!ice_is_tc_ena(*tc_bitmap, tc)) { 2759 /* Delete aggregator cfg TC if it exists previously */ 2760 status = ice_rm_agg_cfg_tc(pi, agg_info, tc, false); 2761 if (status) 2762 break; 2763 continue; 2764 } 2765 2766 /* Check if aggregator node for TC already exists */ 2767 if (ice_is_tc_ena(agg_info->tc_bitmap[0], tc)) 2768 continue; 2769 2770 /* Create new aggregator node for TC */ 2771 status = ice_sched_add_agg_cfg(pi, agg_id, tc); 2772 if (status) 2773 break; 2774 2775 /* Save aggregator node's TC information */ 2776 set_bit(tc, agg_info->tc_bitmap); 2777 } 2778 2779 return status; 2780 } 2781 2782 /** 2783 * ice_cfg_agg - config aggregator node 2784 * @pi: port information structure 2785 * @agg_id: aggregator ID 2786 * @agg_type: aggregator type queue, VSI, or aggregator group 2787 * @tc_bitmap: bits TC bitmap 2788 * 2789 * This function configures aggregator node(s). 2790 */ 2791 int 2792 ice_cfg_agg(struct ice_port_info *pi, u32 agg_id, enum ice_agg_type agg_type, 2793 u8 tc_bitmap) 2794 { 2795 unsigned long bitmap = tc_bitmap; 2796 int status; 2797 2798 mutex_lock(&pi->sched_lock); 2799 status = ice_sched_cfg_agg(pi, agg_id, agg_type, &bitmap); 2800 if (!status) 2801 status = ice_save_agg_tc_bitmap(pi, agg_id, &bitmap); 2802 mutex_unlock(&pi->sched_lock); 2803 return status; 2804 } 2805 2806 /** 2807 * ice_get_agg_vsi_info - get the aggregator ID 2808 * @agg_info: aggregator info 2809 * @vsi_handle: software VSI handle 2810 * 2811 * The function returns aggregator VSI info based on VSI handle. This function 2812 * needs to be called with scheduler lock held. 2813 */ 2814 static struct ice_sched_agg_vsi_info * 2815 ice_get_agg_vsi_info(struct ice_sched_agg_info *agg_info, u16 vsi_handle) 2816 { 2817 struct ice_sched_agg_vsi_info *agg_vsi_info; 2818 2819 list_for_each_entry(agg_vsi_info, &agg_info->agg_vsi_list, list_entry) 2820 if (agg_vsi_info->vsi_handle == vsi_handle) 2821 return agg_vsi_info; 2822 2823 return NULL; 2824 } 2825 2826 /** 2827 * ice_get_vsi_agg_info - get the aggregator info of VSI 2828 * @hw: pointer to the hardware structure 2829 * @vsi_handle: Sw VSI handle 2830 * 2831 * The function returns aggregator info of VSI represented via vsi_handle. The 2832 * VSI has in this case a different aggregator than the default one. This 2833 * function needs to be called with scheduler lock held. 2834 */ 2835 static struct ice_sched_agg_info * 2836 ice_get_vsi_agg_info(struct ice_hw *hw, u16 vsi_handle) 2837 { 2838 struct ice_sched_agg_info *agg_info; 2839 2840 list_for_each_entry(agg_info, &hw->agg_list, list_entry) { 2841 struct ice_sched_agg_vsi_info *agg_vsi_info; 2842 2843 agg_vsi_info = ice_get_agg_vsi_info(agg_info, vsi_handle); 2844 if (agg_vsi_info) 2845 return agg_info; 2846 } 2847 return NULL; 2848 } 2849 2850 /** 2851 * ice_save_agg_vsi_tc_bitmap - save aggregator VSI TC bitmap 2852 * @pi: port information structure 2853 * @agg_id: aggregator ID 2854 * @vsi_handle: software VSI handle 2855 * @tc_bitmap: TC bitmap of enabled TC(s) 2856 * 2857 * Save VSI to aggregator TC bitmap. This function needs to call with scheduler 2858 * lock held. 2859 */ 2860 static int 2861 ice_save_agg_vsi_tc_bitmap(struct ice_port_info *pi, u32 agg_id, u16 vsi_handle, 2862 unsigned long *tc_bitmap) 2863 { 2864 struct ice_sched_agg_vsi_info *agg_vsi_info; 2865 struct ice_sched_agg_info *agg_info; 2866 2867 agg_info = ice_get_agg_info(pi->hw, agg_id); 2868 if (!agg_info) 2869 return -EINVAL; 2870 /* check if entry already exist */ 2871 agg_vsi_info = ice_get_agg_vsi_info(agg_info, vsi_handle); 2872 if (!agg_vsi_info) 2873 return -EINVAL; 2874 bitmap_copy(agg_vsi_info->replay_tc_bitmap, tc_bitmap, 2875 ICE_MAX_TRAFFIC_CLASS); 2876 return 0; 2877 } 2878 2879 /** 2880 * ice_sched_assoc_vsi_to_agg - associate/move VSI to new/default aggregator 2881 * @pi: port information structure 2882 * @agg_id: aggregator ID 2883 * @vsi_handle: software VSI handle 2884 * @tc_bitmap: TC bitmap of enabled TC(s) 2885 * 2886 * This function moves VSI to a new or default aggregator node. If VSI is 2887 * already associated to the aggregator node then no operation is performed on 2888 * the tree. This function needs to be called with scheduler lock held. 2889 */ 2890 static int 2891 ice_sched_assoc_vsi_to_agg(struct ice_port_info *pi, u32 agg_id, 2892 u16 vsi_handle, unsigned long *tc_bitmap) 2893 { 2894 struct ice_sched_agg_vsi_info *agg_vsi_info, *iter, *old_agg_vsi_info = NULL; 2895 struct ice_sched_agg_info *agg_info, *old_agg_info; 2896 struct ice_hw *hw = pi->hw; 2897 int status = 0; 2898 u8 tc; 2899 2900 if (!ice_is_vsi_valid(pi->hw, vsi_handle)) 2901 return -EINVAL; 2902 agg_info = ice_get_agg_info(hw, agg_id); 2903 if (!agg_info) 2904 return -EINVAL; 2905 /* If the VSI is already part of another aggregator then update 2906 * its VSI info list 2907 */ 2908 old_agg_info = ice_get_vsi_agg_info(hw, vsi_handle); 2909 if (old_agg_info && old_agg_info != agg_info) { 2910 struct ice_sched_agg_vsi_info *vtmp; 2911 2912 list_for_each_entry_safe(iter, vtmp, 2913 &old_agg_info->agg_vsi_list, 2914 list_entry) 2915 if (iter->vsi_handle == vsi_handle) { 2916 old_agg_vsi_info = iter; 2917 break; 2918 } 2919 } 2920 2921 /* check if entry already exist */ 2922 agg_vsi_info = ice_get_agg_vsi_info(agg_info, vsi_handle); 2923 if (!agg_vsi_info) { 2924 /* Create new entry for VSI under aggregator list */ 2925 agg_vsi_info = devm_kzalloc(ice_hw_to_dev(hw), 2926 sizeof(*agg_vsi_info), GFP_KERNEL); 2927 if (!agg_vsi_info) 2928 return -EINVAL; 2929 2930 /* add VSI ID into the aggregator list */ 2931 agg_vsi_info->vsi_handle = vsi_handle; 2932 list_add(&agg_vsi_info->list_entry, &agg_info->agg_vsi_list); 2933 } 2934 /* Move VSI node to new aggregator node for requested TC(s) */ 2935 ice_for_each_traffic_class(tc) { 2936 if (!ice_is_tc_ena(*tc_bitmap, tc)) 2937 continue; 2938 2939 /* Move VSI to new aggregator */ 2940 status = ice_sched_move_vsi_to_agg(pi, vsi_handle, agg_id, tc); 2941 if (status) 2942 break; 2943 2944 set_bit(tc, agg_vsi_info->tc_bitmap); 2945 if (old_agg_vsi_info) 2946 clear_bit(tc, old_agg_vsi_info->tc_bitmap); 2947 } 2948 if (old_agg_vsi_info && !old_agg_vsi_info->tc_bitmap[0]) { 2949 list_del(&old_agg_vsi_info->list_entry); 2950 devm_kfree(ice_hw_to_dev(pi->hw), old_agg_vsi_info); 2951 } 2952 return status; 2953 } 2954 2955 /** 2956 * ice_sched_rm_unused_rl_prof - remove unused RL profile 2957 * @pi: port information structure 2958 * 2959 * This function removes unused rate limit profiles from the HW and 2960 * SW DB. The caller needs to hold scheduler lock. 2961 */ 2962 static void ice_sched_rm_unused_rl_prof(struct ice_port_info *pi) 2963 { 2964 u16 ln; 2965 2966 for (ln = 0; ln < pi->hw->num_tx_sched_layers; ln++) { 2967 struct ice_aqc_rl_profile_info *rl_prof_elem; 2968 struct ice_aqc_rl_profile_info *rl_prof_tmp; 2969 2970 list_for_each_entry_safe(rl_prof_elem, rl_prof_tmp, 2971 &pi->rl_prof_list[ln], list_entry) { 2972 if (!ice_sched_del_rl_profile(pi->hw, rl_prof_elem)) 2973 ice_debug(pi->hw, ICE_DBG_SCHED, "Removed rl profile\n"); 2974 } 2975 } 2976 } 2977 2978 /** 2979 * ice_sched_update_elem - update element 2980 * @hw: pointer to the HW struct 2981 * @node: pointer to node 2982 * @info: node info to update 2983 * 2984 * Update the HW DB, and local SW DB of node. Update the scheduling 2985 * parameters of node from argument info data buffer (Info->data buf) and 2986 * returns success or error on config sched element failure. The caller 2987 * needs to hold scheduler lock. 2988 */ 2989 static int 2990 ice_sched_update_elem(struct ice_hw *hw, struct ice_sched_node *node, 2991 struct ice_aqc_txsched_elem_data *info) 2992 { 2993 struct ice_aqc_txsched_elem_data buf; 2994 u16 elem_cfgd = 0; 2995 u16 num_elems = 1; 2996 int status; 2997 2998 buf = *info; 2999 /* Parent TEID is reserved field in this aq call */ 3000 buf.parent_teid = 0; 3001 /* Element type is reserved field in this aq call */ 3002 buf.data.elem_type = 0; 3003 /* Flags is reserved field in this aq call */ 3004 buf.data.flags = 0; 3005 3006 /* Update HW DB */ 3007 /* Configure element node */ 3008 status = ice_aq_cfg_sched_elems(hw, num_elems, &buf, sizeof(buf), 3009 &elem_cfgd, NULL); 3010 if (status || elem_cfgd != num_elems) { 3011 ice_debug(hw, ICE_DBG_SCHED, "Config sched elem error\n"); 3012 return -EIO; 3013 } 3014 3015 /* Config success case */ 3016 /* Now update local SW DB */ 3017 /* Only copy the data portion of info buffer */ 3018 node->info.data = info->data; 3019 return status; 3020 } 3021 3022 /** 3023 * ice_sched_cfg_node_bw_alloc - configure node BW weight/alloc params 3024 * @hw: pointer to the HW struct 3025 * @node: sched node to configure 3026 * @rl_type: rate limit type CIR, EIR, or shared 3027 * @bw_alloc: BW weight/allocation 3028 * 3029 * This function configures node element's BW allocation. 3030 */ 3031 static int 3032 ice_sched_cfg_node_bw_alloc(struct ice_hw *hw, struct ice_sched_node *node, 3033 enum ice_rl_type rl_type, u16 bw_alloc) 3034 { 3035 struct ice_aqc_txsched_elem_data buf; 3036 struct ice_aqc_txsched_elem *data; 3037 3038 buf = node->info; 3039 data = &buf.data; 3040 if (rl_type == ICE_MIN_BW) { 3041 data->valid_sections |= ICE_AQC_ELEM_VALID_CIR; 3042 data->cir_bw.bw_alloc = cpu_to_le16(bw_alloc); 3043 } else if (rl_type == ICE_MAX_BW) { 3044 data->valid_sections |= ICE_AQC_ELEM_VALID_EIR; 3045 data->eir_bw.bw_alloc = cpu_to_le16(bw_alloc); 3046 } else { 3047 return -EINVAL; 3048 } 3049 3050 /* Configure element */ 3051 return ice_sched_update_elem(hw, node, &buf); 3052 } 3053 3054 /** 3055 * ice_move_vsi_to_agg - moves VSI to new or default aggregator 3056 * @pi: port information structure 3057 * @agg_id: aggregator ID 3058 * @vsi_handle: software VSI handle 3059 * @tc_bitmap: TC bitmap of enabled TC(s) 3060 * 3061 * Move or associate VSI to a new or default aggregator node. 3062 */ 3063 int 3064 ice_move_vsi_to_agg(struct ice_port_info *pi, u32 agg_id, u16 vsi_handle, 3065 u8 tc_bitmap) 3066 { 3067 unsigned long bitmap = tc_bitmap; 3068 int status; 3069 3070 mutex_lock(&pi->sched_lock); 3071 status = ice_sched_assoc_vsi_to_agg(pi, agg_id, vsi_handle, 3072 (unsigned long *)&bitmap); 3073 if (!status) 3074 status = ice_save_agg_vsi_tc_bitmap(pi, agg_id, vsi_handle, 3075 (unsigned long *)&bitmap); 3076 mutex_unlock(&pi->sched_lock); 3077 return status; 3078 } 3079 3080 /** 3081 * ice_set_clear_cir_bw - set or clear CIR BW 3082 * @bw_t_info: bandwidth type information structure 3083 * @bw: bandwidth in Kbps - Kilo bits per sec 3084 * 3085 * Save or clear CIR bandwidth (BW) in the passed param bw_t_info. 3086 */ 3087 static void ice_set_clear_cir_bw(struct ice_bw_type_info *bw_t_info, u32 bw) 3088 { 3089 if (bw == ICE_SCHED_DFLT_BW) { 3090 clear_bit(ICE_BW_TYPE_CIR, bw_t_info->bw_t_bitmap); 3091 bw_t_info->cir_bw.bw = 0; 3092 } else { 3093 /* Save type of BW information */ 3094 set_bit(ICE_BW_TYPE_CIR, bw_t_info->bw_t_bitmap); 3095 bw_t_info->cir_bw.bw = bw; 3096 } 3097 } 3098 3099 /** 3100 * ice_set_clear_eir_bw - set or clear EIR BW 3101 * @bw_t_info: bandwidth type information structure 3102 * @bw: bandwidth in Kbps - Kilo bits per sec 3103 * 3104 * Save or clear EIR bandwidth (BW) in the passed param bw_t_info. 3105 */ 3106 static void ice_set_clear_eir_bw(struct ice_bw_type_info *bw_t_info, u32 bw) 3107 { 3108 if (bw == ICE_SCHED_DFLT_BW) { 3109 clear_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap); 3110 bw_t_info->eir_bw.bw = 0; 3111 } else { 3112 /* EIR BW and Shared BW profiles are mutually exclusive and 3113 * hence only one of them may be set for any given element. 3114 * First clear earlier saved shared BW information. 3115 */ 3116 clear_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap); 3117 bw_t_info->shared_bw = 0; 3118 /* save EIR BW information */ 3119 set_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap); 3120 bw_t_info->eir_bw.bw = bw; 3121 } 3122 } 3123 3124 /** 3125 * ice_set_clear_shared_bw - set or clear shared BW 3126 * @bw_t_info: bandwidth type information structure 3127 * @bw: bandwidth in Kbps - Kilo bits per sec 3128 * 3129 * Save or clear shared bandwidth (BW) in the passed param bw_t_info. 3130 */ 3131 static void ice_set_clear_shared_bw(struct ice_bw_type_info *bw_t_info, u32 bw) 3132 { 3133 if (bw == ICE_SCHED_DFLT_BW) { 3134 clear_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap); 3135 bw_t_info->shared_bw = 0; 3136 } else { 3137 /* EIR BW and Shared BW profiles are mutually exclusive and 3138 * hence only one of them may be set for any given element. 3139 * First clear earlier saved EIR BW information. 3140 */ 3141 clear_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap); 3142 bw_t_info->eir_bw.bw = 0; 3143 /* save shared BW information */ 3144 set_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap); 3145 bw_t_info->shared_bw = bw; 3146 } 3147 } 3148 3149 /** 3150 * ice_sched_save_vsi_bw - save VSI node's BW information 3151 * @pi: port information structure 3152 * @vsi_handle: sw VSI handle 3153 * @tc: traffic class 3154 * @rl_type: rate limit type min, max, or shared 3155 * @bw: bandwidth in Kbps - Kilo bits per sec 3156 * 3157 * Save BW information of VSI type node for post replay use. 3158 */ 3159 static int 3160 ice_sched_save_vsi_bw(struct ice_port_info *pi, u16 vsi_handle, u8 tc, 3161 enum ice_rl_type rl_type, u32 bw) 3162 { 3163 struct ice_vsi_ctx *vsi_ctx; 3164 3165 if (!ice_is_vsi_valid(pi->hw, vsi_handle)) 3166 return -EINVAL; 3167 vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle); 3168 if (!vsi_ctx) 3169 return -EINVAL; 3170 switch (rl_type) { 3171 case ICE_MIN_BW: 3172 ice_set_clear_cir_bw(&vsi_ctx->sched.bw_t_info[tc], bw); 3173 break; 3174 case ICE_MAX_BW: 3175 ice_set_clear_eir_bw(&vsi_ctx->sched.bw_t_info[tc], bw); 3176 break; 3177 case ICE_SHARED_BW: 3178 ice_set_clear_shared_bw(&vsi_ctx->sched.bw_t_info[tc], bw); 3179 break; 3180 default: 3181 return -EINVAL; 3182 } 3183 return 0; 3184 } 3185 3186 /** 3187 * ice_sched_calc_wakeup - calculate RL profile wakeup parameter 3188 * @hw: pointer to the HW struct 3189 * @bw: bandwidth in Kbps 3190 * 3191 * This function calculates the wakeup parameter of RL profile. 3192 */ 3193 static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw) 3194 { 3195 s64 bytes_per_sec, wakeup_int, wakeup_a, wakeup_b, wakeup_f; 3196 s32 wakeup_f_int; 3197 u16 wakeup = 0; 3198 3199 /* Get the wakeup integer value */ 3200 bytes_per_sec = div64_long(((s64)bw * 1000), BITS_PER_BYTE); 3201 wakeup_int = div64_long(hw->psm_clk_freq, bytes_per_sec); 3202 if (wakeup_int > 63) { 3203 wakeup = (u16)((1 << 15) | wakeup_int); 3204 } else { 3205 /* Calculate fraction value up to 4 decimals 3206 * Convert Integer value to a constant multiplier 3207 */ 3208 wakeup_b = (s64)ICE_RL_PROF_MULTIPLIER * wakeup_int; 3209 wakeup_a = div64_long((s64)ICE_RL_PROF_MULTIPLIER * 3210 hw->psm_clk_freq, bytes_per_sec); 3211 3212 /* Get Fraction value */ 3213 wakeup_f = wakeup_a - wakeup_b; 3214 3215 /* Round up the Fractional value via Ceil(Fractional value) */ 3216 if (wakeup_f > div64_long(ICE_RL_PROF_MULTIPLIER, 2)) 3217 wakeup_f += 1; 3218 3219 wakeup_f_int = (s32)div64_long(wakeup_f * ICE_RL_PROF_FRACTION, 3220 ICE_RL_PROF_MULTIPLIER); 3221 wakeup |= (u16)(wakeup_int << 9); 3222 wakeup |= (u16)(0x1ff & wakeup_f_int); 3223 } 3224 3225 return wakeup; 3226 } 3227 3228 /** 3229 * ice_sched_bw_to_rl_profile - convert BW to profile parameters 3230 * @hw: pointer to the HW struct 3231 * @bw: bandwidth in Kbps 3232 * @profile: profile parameters to return 3233 * 3234 * This function converts the BW to profile structure format. 3235 */ 3236 static int 3237 ice_sched_bw_to_rl_profile(struct ice_hw *hw, u32 bw, 3238 struct ice_aqc_rl_profile_elem *profile) 3239 { 3240 s64 bytes_per_sec, ts_rate, mv_tmp; 3241 int status = -EINVAL; 3242 bool found = false; 3243 s32 encode = 0; 3244 s64 mv = 0; 3245 s32 i; 3246 3247 /* Bw settings range is from 0.5Mb/sec to 100Gb/sec */ 3248 if (bw < ICE_SCHED_MIN_BW || bw > ICE_SCHED_MAX_BW) 3249 return status; 3250 3251 /* Bytes per second from Kbps */ 3252 bytes_per_sec = div64_long(((s64)bw * 1000), BITS_PER_BYTE); 3253 3254 /* encode is 6 bits but really useful are 5 bits */ 3255 for (i = 0; i < 64; i++) { 3256 u64 pow_result = BIT_ULL(i); 3257 3258 ts_rate = div64_long((s64)hw->psm_clk_freq, 3259 pow_result * ICE_RL_PROF_TS_MULTIPLIER); 3260 if (ts_rate <= 0) 3261 continue; 3262 3263 /* Multiplier value */ 3264 mv_tmp = div64_long(bytes_per_sec * ICE_RL_PROF_MULTIPLIER, 3265 ts_rate); 3266 3267 /* Round to the nearest ICE_RL_PROF_MULTIPLIER */ 3268 mv = round_up_64bit(mv_tmp, ICE_RL_PROF_MULTIPLIER); 3269 3270 /* First multiplier value greater than the given 3271 * accuracy bytes 3272 */ 3273 if (mv > ICE_RL_PROF_ACCURACY_BYTES) { 3274 encode = i; 3275 found = true; 3276 break; 3277 } 3278 } 3279 if (found) { 3280 u16 wm; 3281 3282 wm = ice_sched_calc_wakeup(hw, bw); 3283 profile->rl_multiply = cpu_to_le16(mv); 3284 profile->wake_up_calc = cpu_to_le16(wm); 3285 profile->rl_encode = cpu_to_le16(encode); 3286 status = 0; 3287 } else { 3288 status = -ENOENT; 3289 } 3290 3291 return status; 3292 } 3293 3294 /** 3295 * ice_sched_add_rl_profile - add RL profile 3296 * @pi: port information structure 3297 * @rl_type: type of rate limit BW - min, max, or shared 3298 * @bw: bandwidth in Kbps - Kilo bits per sec 3299 * @layer_num: specifies in which layer to create profile 3300 * 3301 * This function first checks the existing list for corresponding BW 3302 * parameter. If it exists, it returns the associated profile otherwise 3303 * it creates a new rate limit profile for requested BW, and adds it to 3304 * the HW DB and local list. It returns the new profile or null on error. 3305 * The caller needs to hold the scheduler lock. 3306 */ 3307 static struct ice_aqc_rl_profile_info * 3308 ice_sched_add_rl_profile(struct ice_port_info *pi, 3309 enum ice_rl_type rl_type, u32 bw, u8 layer_num) 3310 { 3311 struct ice_aqc_rl_profile_info *rl_prof_elem; 3312 u16 profiles_added = 0, num_profiles = 1; 3313 struct ice_aqc_rl_profile_elem *buf; 3314 struct ice_hw *hw; 3315 u8 profile_type; 3316 int status; 3317 3318 if (!pi || layer_num >= pi->hw->num_tx_sched_layers) 3319 return NULL; 3320 switch (rl_type) { 3321 case ICE_MIN_BW: 3322 profile_type = ICE_AQC_RL_PROFILE_TYPE_CIR; 3323 break; 3324 case ICE_MAX_BW: 3325 profile_type = ICE_AQC_RL_PROFILE_TYPE_EIR; 3326 break; 3327 case ICE_SHARED_BW: 3328 profile_type = ICE_AQC_RL_PROFILE_TYPE_SRL; 3329 break; 3330 default: 3331 return NULL; 3332 } 3333 3334 hw = pi->hw; 3335 list_for_each_entry(rl_prof_elem, &pi->rl_prof_list[layer_num], 3336 list_entry) 3337 if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) == 3338 profile_type && rl_prof_elem->bw == bw) 3339 /* Return existing profile ID info */ 3340 return rl_prof_elem; 3341 3342 /* Create new profile ID */ 3343 rl_prof_elem = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rl_prof_elem), 3344 GFP_KERNEL); 3345 3346 if (!rl_prof_elem) 3347 return NULL; 3348 3349 status = ice_sched_bw_to_rl_profile(hw, bw, &rl_prof_elem->profile); 3350 if (status) 3351 goto exit_add_rl_prof; 3352 3353 rl_prof_elem->bw = bw; 3354 /* layer_num is zero relative, and fw expects level from 1 to 9 */ 3355 rl_prof_elem->profile.level = layer_num + 1; 3356 rl_prof_elem->profile.flags = profile_type; 3357 rl_prof_elem->profile.max_burst_size = cpu_to_le16(hw->max_burst_size); 3358 3359 /* Create new entry in HW DB */ 3360 buf = &rl_prof_elem->profile; 3361 status = ice_aq_add_rl_profile(hw, num_profiles, buf, sizeof(*buf), 3362 &profiles_added, NULL); 3363 if (status || profiles_added != num_profiles) 3364 goto exit_add_rl_prof; 3365 3366 /* Good entry - add in the list */ 3367 rl_prof_elem->prof_id_ref = 0; 3368 list_add(&rl_prof_elem->list_entry, &pi->rl_prof_list[layer_num]); 3369 return rl_prof_elem; 3370 3371 exit_add_rl_prof: 3372 devm_kfree(ice_hw_to_dev(hw), rl_prof_elem); 3373 return NULL; 3374 } 3375 3376 /** 3377 * ice_sched_cfg_node_bw_lmt - configure node sched params 3378 * @hw: pointer to the HW struct 3379 * @node: sched node to configure 3380 * @rl_type: rate limit type CIR, EIR, or shared 3381 * @rl_prof_id: rate limit profile ID 3382 * 3383 * This function configures node element's BW limit. 3384 */ 3385 static int 3386 ice_sched_cfg_node_bw_lmt(struct ice_hw *hw, struct ice_sched_node *node, 3387 enum ice_rl_type rl_type, u16 rl_prof_id) 3388 { 3389 struct ice_aqc_txsched_elem_data buf; 3390 struct ice_aqc_txsched_elem *data; 3391 3392 buf = node->info; 3393 data = &buf.data; 3394 switch (rl_type) { 3395 case ICE_MIN_BW: 3396 data->valid_sections |= ICE_AQC_ELEM_VALID_CIR; 3397 data->cir_bw.bw_profile_idx = cpu_to_le16(rl_prof_id); 3398 break; 3399 case ICE_MAX_BW: 3400 /* EIR BW and Shared BW profiles are mutually exclusive and 3401 * hence only one of them may be set for any given element 3402 */ 3403 if (data->valid_sections & ICE_AQC_ELEM_VALID_SHARED) 3404 return -EIO; 3405 data->valid_sections |= ICE_AQC_ELEM_VALID_EIR; 3406 data->eir_bw.bw_profile_idx = cpu_to_le16(rl_prof_id); 3407 break; 3408 case ICE_SHARED_BW: 3409 /* Check for removing shared BW */ 3410 if (rl_prof_id == ICE_SCHED_NO_SHARED_RL_PROF_ID) { 3411 /* remove shared profile */ 3412 data->valid_sections &= ~ICE_AQC_ELEM_VALID_SHARED; 3413 data->srl_id = 0; /* clear SRL field */ 3414 3415 /* enable back EIR to default profile */ 3416 data->valid_sections |= ICE_AQC_ELEM_VALID_EIR; 3417 data->eir_bw.bw_profile_idx = 3418 cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID); 3419 break; 3420 } 3421 /* EIR BW and Shared BW profiles are mutually exclusive and 3422 * hence only one of them may be set for any given element 3423 */ 3424 if ((data->valid_sections & ICE_AQC_ELEM_VALID_EIR) && 3425 (le16_to_cpu(data->eir_bw.bw_profile_idx) != 3426 ICE_SCHED_DFLT_RL_PROF_ID)) 3427 return -EIO; 3428 /* EIR BW is set to default, disable it */ 3429 data->valid_sections &= ~ICE_AQC_ELEM_VALID_EIR; 3430 /* Okay to enable shared BW now */ 3431 data->valid_sections |= ICE_AQC_ELEM_VALID_SHARED; 3432 data->srl_id = cpu_to_le16(rl_prof_id); 3433 break; 3434 default: 3435 /* Unknown rate limit type */ 3436 return -EINVAL; 3437 } 3438 3439 /* Configure element */ 3440 return ice_sched_update_elem(hw, node, &buf); 3441 } 3442 3443 /** 3444 * ice_sched_get_node_rl_prof_id - get node's rate limit profile ID 3445 * @node: sched node 3446 * @rl_type: rate limit type 3447 * 3448 * If existing profile matches, it returns the corresponding rate 3449 * limit profile ID, otherwise it returns an invalid ID as error. 3450 */ 3451 static u16 3452 ice_sched_get_node_rl_prof_id(struct ice_sched_node *node, 3453 enum ice_rl_type rl_type) 3454 { 3455 u16 rl_prof_id = ICE_SCHED_INVAL_PROF_ID; 3456 struct ice_aqc_txsched_elem *data; 3457 3458 data = &node->info.data; 3459 switch (rl_type) { 3460 case ICE_MIN_BW: 3461 if (data->valid_sections & ICE_AQC_ELEM_VALID_CIR) 3462 rl_prof_id = le16_to_cpu(data->cir_bw.bw_profile_idx); 3463 break; 3464 case ICE_MAX_BW: 3465 if (data->valid_sections & ICE_AQC_ELEM_VALID_EIR) 3466 rl_prof_id = le16_to_cpu(data->eir_bw.bw_profile_idx); 3467 break; 3468 case ICE_SHARED_BW: 3469 if (data->valid_sections & ICE_AQC_ELEM_VALID_SHARED) 3470 rl_prof_id = le16_to_cpu(data->srl_id); 3471 break; 3472 default: 3473 break; 3474 } 3475 3476 return rl_prof_id; 3477 } 3478 3479 /** 3480 * ice_sched_get_rl_prof_layer - selects rate limit profile creation layer 3481 * @pi: port information structure 3482 * @rl_type: type of rate limit BW - min, max, or shared 3483 * @layer_index: layer index 3484 * 3485 * This function returns requested profile creation layer. 3486 */ 3487 static u8 3488 ice_sched_get_rl_prof_layer(struct ice_port_info *pi, enum ice_rl_type rl_type, 3489 u8 layer_index) 3490 { 3491 struct ice_hw *hw = pi->hw; 3492 3493 if (layer_index >= hw->num_tx_sched_layers) 3494 return ICE_SCHED_INVAL_LAYER_NUM; 3495 switch (rl_type) { 3496 case ICE_MIN_BW: 3497 if (hw->layer_info[layer_index].max_cir_rl_profiles) 3498 return layer_index; 3499 break; 3500 case ICE_MAX_BW: 3501 if (hw->layer_info[layer_index].max_eir_rl_profiles) 3502 return layer_index; 3503 break; 3504 case ICE_SHARED_BW: 3505 /* if current layer doesn't support SRL profile creation 3506 * then try a layer up or down. 3507 */ 3508 if (hw->layer_info[layer_index].max_srl_profiles) 3509 return layer_index; 3510 else if (layer_index < hw->num_tx_sched_layers - 1 && 3511 hw->layer_info[layer_index + 1].max_srl_profiles) 3512 return layer_index + 1; 3513 else if (layer_index > 0 && 3514 hw->layer_info[layer_index - 1].max_srl_profiles) 3515 return layer_index - 1; 3516 break; 3517 default: 3518 break; 3519 } 3520 return ICE_SCHED_INVAL_LAYER_NUM; 3521 } 3522 3523 /** 3524 * ice_sched_get_srl_node - get shared rate limit node 3525 * @node: tree node 3526 * @srl_layer: shared rate limit layer 3527 * 3528 * This function returns SRL node to be used for shared rate limit purpose. 3529 * The caller needs to hold scheduler lock. 3530 */ 3531 static struct ice_sched_node * 3532 ice_sched_get_srl_node(struct ice_sched_node *node, u8 srl_layer) 3533 { 3534 if (srl_layer > node->tx_sched_layer) 3535 return node->children[0]; 3536 else if (srl_layer < node->tx_sched_layer) 3537 /* Node can't be created without a parent. It will always 3538 * have a valid parent except root node. 3539 */ 3540 return node->parent; 3541 else 3542 return node; 3543 } 3544 3545 /** 3546 * ice_sched_rm_rl_profile - remove RL profile ID 3547 * @pi: port information structure 3548 * @layer_num: layer number where profiles are saved 3549 * @profile_type: profile type like EIR, CIR, or SRL 3550 * @profile_id: profile ID to remove 3551 * 3552 * This function removes rate limit profile from layer 'layer_num' of type 3553 * 'profile_type' and profile ID as 'profile_id'. The caller needs to hold 3554 * scheduler lock. 3555 */ 3556 static int 3557 ice_sched_rm_rl_profile(struct ice_port_info *pi, u8 layer_num, u8 profile_type, 3558 u16 profile_id) 3559 { 3560 struct ice_aqc_rl_profile_info *rl_prof_elem; 3561 int status = 0; 3562 3563 if (layer_num >= pi->hw->num_tx_sched_layers) 3564 return -EINVAL; 3565 /* Check the existing list for RL profile */ 3566 list_for_each_entry(rl_prof_elem, &pi->rl_prof_list[layer_num], 3567 list_entry) 3568 if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) == 3569 profile_type && 3570 le16_to_cpu(rl_prof_elem->profile.profile_id) == 3571 profile_id) { 3572 if (rl_prof_elem->prof_id_ref) 3573 rl_prof_elem->prof_id_ref--; 3574 3575 /* Remove old profile ID from database */ 3576 status = ice_sched_del_rl_profile(pi->hw, rl_prof_elem); 3577 if (status && status != -EBUSY) 3578 ice_debug(pi->hw, ICE_DBG_SCHED, "Remove rl profile failed\n"); 3579 break; 3580 } 3581 if (status == -EBUSY) 3582 status = 0; 3583 return status; 3584 } 3585 3586 /** 3587 * ice_sched_set_node_bw_dflt - set node's bandwidth limit to default 3588 * @pi: port information structure 3589 * @node: pointer to node structure 3590 * @rl_type: rate limit type min, max, or shared 3591 * @layer_num: layer number where RL profiles are saved 3592 * 3593 * This function configures node element's BW rate limit profile ID of 3594 * type CIR, EIR, or SRL to default. This function needs to be called 3595 * with the scheduler lock held. 3596 */ 3597 static int 3598 ice_sched_set_node_bw_dflt(struct ice_port_info *pi, 3599 struct ice_sched_node *node, 3600 enum ice_rl_type rl_type, u8 layer_num) 3601 { 3602 struct ice_hw *hw; 3603 u8 profile_type; 3604 u16 rl_prof_id; 3605 u16 old_id; 3606 int status; 3607 3608 hw = pi->hw; 3609 switch (rl_type) { 3610 case ICE_MIN_BW: 3611 profile_type = ICE_AQC_RL_PROFILE_TYPE_CIR; 3612 rl_prof_id = ICE_SCHED_DFLT_RL_PROF_ID; 3613 break; 3614 case ICE_MAX_BW: 3615 profile_type = ICE_AQC_RL_PROFILE_TYPE_EIR; 3616 rl_prof_id = ICE_SCHED_DFLT_RL_PROF_ID; 3617 break; 3618 case ICE_SHARED_BW: 3619 profile_type = ICE_AQC_RL_PROFILE_TYPE_SRL; 3620 /* No SRL is configured for default case */ 3621 rl_prof_id = ICE_SCHED_NO_SHARED_RL_PROF_ID; 3622 break; 3623 default: 3624 return -EINVAL; 3625 } 3626 /* Save existing RL prof ID for later clean up */ 3627 old_id = ice_sched_get_node_rl_prof_id(node, rl_type); 3628 /* Configure BW scheduling parameters */ 3629 status = ice_sched_cfg_node_bw_lmt(hw, node, rl_type, rl_prof_id); 3630 if (status) 3631 return status; 3632 3633 /* Remove stale RL profile ID */ 3634 if (old_id == ICE_SCHED_DFLT_RL_PROF_ID || 3635 old_id == ICE_SCHED_INVAL_PROF_ID) 3636 return 0; 3637 3638 return ice_sched_rm_rl_profile(pi, layer_num, profile_type, old_id); 3639 } 3640 3641 /** 3642 * ice_sched_set_eir_srl_excl - set EIR/SRL exclusiveness 3643 * @pi: port information structure 3644 * @node: pointer to node structure 3645 * @layer_num: layer number where rate limit profiles are saved 3646 * @rl_type: rate limit type min, max, or shared 3647 * @bw: bandwidth value 3648 * 3649 * This function prepares node element's bandwidth to SRL or EIR exclusively. 3650 * EIR BW and Shared BW profiles are mutually exclusive and hence only one of 3651 * them may be set for any given element. This function needs to be called 3652 * with the scheduler lock held. 3653 */ 3654 static int 3655 ice_sched_set_eir_srl_excl(struct ice_port_info *pi, 3656 struct ice_sched_node *node, 3657 u8 layer_num, enum ice_rl_type rl_type, u32 bw) 3658 { 3659 if (rl_type == ICE_SHARED_BW) { 3660 /* SRL node passed in this case, it may be different node */ 3661 if (bw == ICE_SCHED_DFLT_BW) 3662 /* SRL being removed, ice_sched_cfg_node_bw_lmt() 3663 * enables EIR to default. EIR is not set in this 3664 * case, so no additional action is required. 3665 */ 3666 return 0; 3667 3668 /* SRL being configured, set EIR to default here. 3669 * ice_sched_cfg_node_bw_lmt() disables EIR when it 3670 * configures SRL 3671 */ 3672 return ice_sched_set_node_bw_dflt(pi, node, ICE_MAX_BW, 3673 layer_num); 3674 } else if (rl_type == ICE_MAX_BW && 3675 node->info.data.valid_sections & ICE_AQC_ELEM_VALID_SHARED) { 3676 /* Remove Shared profile. Set default shared BW call 3677 * removes shared profile for a node. 3678 */ 3679 return ice_sched_set_node_bw_dflt(pi, node, 3680 ICE_SHARED_BW, 3681 layer_num); 3682 } 3683 return 0; 3684 } 3685 3686 /** 3687 * ice_sched_set_node_bw - set node's bandwidth 3688 * @pi: port information structure 3689 * @node: tree node 3690 * @rl_type: rate limit type min, max, or shared 3691 * @bw: bandwidth in Kbps - Kilo bits per sec 3692 * @layer_num: layer number 3693 * 3694 * This function adds new profile corresponding to requested BW, configures 3695 * node's RL profile ID of type CIR, EIR, or SRL, and removes old profile 3696 * ID from local database. The caller needs to hold scheduler lock. 3697 */ 3698 int 3699 ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node, 3700 enum ice_rl_type rl_type, u32 bw, u8 layer_num) 3701 { 3702 struct ice_aqc_rl_profile_info *rl_prof_info; 3703 struct ice_hw *hw = pi->hw; 3704 u16 old_id, rl_prof_id; 3705 int status = -EINVAL; 3706 3707 rl_prof_info = ice_sched_add_rl_profile(pi, rl_type, bw, layer_num); 3708 if (!rl_prof_info) 3709 return status; 3710 3711 rl_prof_id = le16_to_cpu(rl_prof_info->profile.profile_id); 3712 3713 /* Save existing RL prof ID for later clean up */ 3714 old_id = ice_sched_get_node_rl_prof_id(node, rl_type); 3715 /* Configure BW scheduling parameters */ 3716 status = ice_sched_cfg_node_bw_lmt(hw, node, rl_type, rl_prof_id); 3717 if (status) 3718 return status; 3719 3720 /* New changes has been applied */ 3721 /* Increment the profile ID reference count */ 3722 rl_prof_info->prof_id_ref++; 3723 3724 /* Check for old ID removal */ 3725 if ((old_id == ICE_SCHED_DFLT_RL_PROF_ID && rl_type != ICE_SHARED_BW) || 3726 old_id == ICE_SCHED_INVAL_PROF_ID || old_id == rl_prof_id) 3727 return 0; 3728 3729 return ice_sched_rm_rl_profile(pi, layer_num, 3730 rl_prof_info->profile.flags & 3731 ICE_AQC_RL_PROFILE_TYPE_M, old_id); 3732 } 3733 3734 /** 3735 * ice_sched_set_node_priority - set node's priority 3736 * @pi: port information structure 3737 * @node: tree node 3738 * @priority: number 0-7 representing priority among siblings 3739 * 3740 * This function sets priority of a node among it's siblings. 3741 */ 3742 int 3743 ice_sched_set_node_priority(struct ice_port_info *pi, struct ice_sched_node *node, 3744 u16 priority) 3745 { 3746 struct ice_aqc_txsched_elem_data buf; 3747 struct ice_aqc_txsched_elem *data; 3748 3749 buf = node->info; 3750 data = &buf.data; 3751 3752 data->valid_sections |= ICE_AQC_ELEM_VALID_GENERIC; 3753 data->generic |= FIELD_PREP(ICE_AQC_ELEM_GENERIC_PRIO_M, priority); 3754 3755 return ice_sched_update_elem(pi->hw, node, &buf); 3756 } 3757 3758 /** 3759 * ice_sched_set_node_weight - set node's weight 3760 * @pi: port information structure 3761 * @node: tree node 3762 * @weight: number 1-200 representing weight for WFQ 3763 * 3764 * This function sets weight of the node for WFQ algorithm. 3765 */ 3766 int 3767 ice_sched_set_node_weight(struct ice_port_info *pi, struct ice_sched_node *node, u16 weight) 3768 { 3769 struct ice_aqc_txsched_elem_data buf; 3770 struct ice_aqc_txsched_elem *data; 3771 3772 buf = node->info; 3773 data = &buf.data; 3774 3775 data->valid_sections = ICE_AQC_ELEM_VALID_CIR | ICE_AQC_ELEM_VALID_EIR | 3776 ICE_AQC_ELEM_VALID_GENERIC; 3777 data->cir_bw.bw_alloc = cpu_to_le16(weight); 3778 data->eir_bw.bw_alloc = cpu_to_le16(weight); 3779 3780 data->generic |= FIELD_PREP(ICE_AQC_ELEM_GENERIC_SP_M, 0x0); 3781 3782 return ice_sched_update_elem(pi->hw, node, &buf); 3783 } 3784 3785 /** 3786 * ice_sched_set_node_bw_lmt - set node's BW limit 3787 * @pi: port information structure 3788 * @node: tree node 3789 * @rl_type: rate limit type min, max, or shared 3790 * @bw: bandwidth in Kbps - Kilo bits per sec 3791 * 3792 * It updates node's BW limit parameters like BW RL profile ID of type CIR, 3793 * EIR, or SRL. The caller needs to hold scheduler lock. 3794 */ 3795 int 3796 ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node *node, 3797 enum ice_rl_type rl_type, u32 bw) 3798 { 3799 struct ice_sched_node *cfg_node = node; 3800 int status; 3801 3802 struct ice_hw *hw; 3803 u8 layer_num; 3804 3805 if (!pi) 3806 return -EINVAL; 3807 hw = pi->hw; 3808 /* Remove unused RL profile IDs from HW and SW DB */ 3809 ice_sched_rm_unused_rl_prof(pi); 3810 layer_num = ice_sched_get_rl_prof_layer(pi, rl_type, 3811 node->tx_sched_layer); 3812 if (layer_num >= hw->num_tx_sched_layers) 3813 return -EINVAL; 3814 3815 if (rl_type == ICE_SHARED_BW) { 3816 /* SRL node may be different */ 3817 cfg_node = ice_sched_get_srl_node(node, layer_num); 3818 if (!cfg_node) 3819 return -EIO; 3820 } 3821 /* EIR BW and Shared BW profiles are mutually exclusive and 3822 * hence only one of them may be set for any given element 3823 */ 3824 status = ice_sched_set_eir_srl_excl(pi, cfg_node, layer_num, rl_type, 3825 bw); 3826 if (status) 3827 return status; 3828 if (bw == ICE_SCHED_DFLT_BW) 3829 return ice_sched_set_node_bw_dflt(pi, cfg_node, rl_type, 3830 layer_num); 3831 return ice_sched_set_node_bw(pi, cfg_node, rl_type, bw, layer_num); 3832 } 3833 3834 /** 3835 * ice_sched_set_node_bw_dflt_lmt - set node's BW limit to default 3836 * @pi: port information structure 3837 * @node: pointer to node structure 3838 * @rl_type: rate limit type min, max, or shared 3839 * 3840 * This function configures node element's BW rate limit profile ID of 3841 * type CIR, EIR, or SRL to default. This function needs to be called 3842 * with the scheduler lock held. 3843 */ 3844 static int 3845 ice_sched_set_node_bw_dflt_lmt(struct ice_port_info *pi, 3846 struct ice_sched_node *node, 3847 enum ice_rl_type rl_type) 3848 { 3849 return ice_sched_set_node_bw_lmt(pi, node, rl_type, 3850 ICE_SCHED_DFLT_BW); 3851 } 3852 3853 /** 3854 * ice_sched_validate_srl_node - Check node for SRL applicability 3855 * @node: sched node to configure 3856 * @sel_layer: selected SRL layer 3857 * 3858 * This function checks if the SRL can be applied to a selected layer node on 3859 * behalf of the requested node (first argument). This function needs to be 3860 * called with scheduler lock held. 3861 */ 3862 static int 3863 ice_sched_validate_srl_node(struct ice_sched_node *node, u8 sel_layer) 3864 { 3865 /* SRL profiles are not available on all layers. Check if the 3866 * SRL profile can be applied to a node above or below the 3867 * requested node. SRL configuration is possible only if the 3868 * selected layer's node has single child. 3869 */ 3870 if (sel_layer == node->tx_sched_layer || 3871 ((sel_layer == node->tx_sched_layer + 1) && 3872 node->num_children == 1) || 3873 ((sel_layer == node->tx_sched_layer - 1) && 3874 (node->parent && node->parent->num_children == 1))) 3875 return 0; 3876 3877 return -EIO; 3878 } 3879 3880 /** 3881 * ice_sched_save_q_bw - save queue node's BW information 3882 * @q_ctx: queue context structure 3883 * @rl_type: rate limit type min, max, or shared 3884 * @bw: bandwidth in Kbps - Kilo bits per sec 3885 * 3886 * Save BW information of queue type node for post replay use. 3887 */ 3888 static int 3889 ice_sched_save_q_bw(struct ice_q_ctx *q_ctx, enum ice_rl_type rl_type, u32 bw) 3890 { 3891 switch (rl_type) { 3892 case ICE_MIN_BW: 3893 ice_set_clear_cir_bw(&q_ctx->bw_t_info, bw); 3894 break; 3895 case ICE_MAX_BW: 3896 ice_set_clear_eir_bw(&q_ctx->bw_t_info, bw); 3897 break; 3898 case ICE_SHARED_BW: 3899 ice_set_clear_shared_bw(&q_ctx->bw_t_info, bw); 3900 break; 3901 default: 3902 return -EINVAL; 3903 } 3904 return 0; 3905 } 3906 3907 /** 3908 * ice_sched_set_q_bw_lmt - sets queue BW limit 3909 * @pi: port information structure 3910 * @vsi_handle: sw VSI handle 3911 * @tc: traffic class 3912 * @q_handle: software queue handle 3913 * @rl_type: min, max, or shared 3914 * @bw: bandwidth in Kbps 3915 * 3916 * This function sets BW limit of queue scheduling node. 3917 */ 3918 static int 3919 ice_sched_set_q_bw_lmt(struct ice_port_info *pi, u16 vsi_handle, u8 tc, 3920 u16 q_handle, enum ice_rl_type rl_type, u32 bw) 3921 { 3922 struct ice_sched_node *node; 3923 struct ice_q_ctx *q_ctx; 3924 int status = -EINVAL; 3925 3926 if (!ice_is_vsi_valid(pi->hw, vsi_handle)) 3927 return -EINVAL; 3928 mutex_lock(&pi->sched_lock); 3929 q_ctx = ice_get_lan_q_ctx(pi->hw, vsi_handle, tc, q_handle); 3930 if (!q_ctx) 3931 goto exit_q_bw_lmt; 3932 node = ice_sched_find_node_by_teid(pi->root, q_ctx->q_teid); 3933 if (!node) { 3934 ice_debug(pi->hw, ICE_DBG_SCHED, "Wrong q_teid\n"); 3935 goto exit_q_bw_lmt; 3936 } 3937 3938 /* Return error if it is not a leaf node */ 3939 if (node->info.data.elem_type != ICE_AQC_ELEM_TYPE_LEAF) 3940 goto exit_q_bw_lmt; 3941 3942 /* SRL bandwidth layer selection */ 3943 if (rl_type == ICE_SHARED_BW) { 3944 u8 sel_layer; /* selected layer */ 3945 3946 sel_layer = ice_sched_get_rl_prof_layer(pi, rl_type, 3947 node->tx_sched_layer); 3948 if (sel_layer >= pi->hw->num_tx_sched_layers) { 3949 status = -EINVAL; 3950 goto exit_q_bw_lmt; 3951 } 3952 status = ice_sched_validate_srl_node(node, sel_layer); 3953 if (status) 3954 goto exit_q_bw_lmt; 3955 } 3956 3957 if (bw == ICE_SCHED_DFLT_BW) 3958 status = ice_sched_set_node_bw_dflt_lmt(pi, node, rl_type); 3959 else 3960 status = ice_sched_set_node_bw_lmt(pi, node, rl_type, bw); 3961 3962 if (!status) 3963 status = ice_sched_save_q_bw(q_ctx, rl_type, bw); 3964 3965 exit_q_bw_lmt: 3966 mutex_unlock(&pi->sched_lock); 3967 return status; 3968 } 3969 3970 /** 3971 * ice_cfg_q_bw_lmt - configure queue BW limit 3972 * @pi: port information structure 3973 * @vsi_handle: sw VSI handle 3974 * @tc: traffic class 3975 * @q_handle: software queue handle 3976 * @rl_type: min, max, or shared 3977 * @bw: bandwidth in Kbps 3978 * 3979 * This function configures BW limit of queue scheduling node. 3980 */ 3981 int 3982 ice_cfg_q_bw_lmt(struct ice_port_info *pi, u16 vsi_handle, u8 tc, 3983 u16 q_handle, enum ice_rl_type rl_type, u32 bw) 3984 { 3985 return ice_sched_set_q_bw_lmt(pi, vsi_handle, tc, q_handle, rl_type, 3986 bw); 3987 } 3988 3989 /** 3990 * ice_cfg_q_bw_dflt_lmt - configure queue BW default limit 3991 * @pi: port information structure 3992 * @vsi_handle: sw VSI handle 3993 * @tc: traffic class 3994 * @q_handle: software queue handle 3995 * @rl_type: min, max, or shared 3996 * 3997 * This function configures BW default limit of queue scheduling node. 3998 */ 3999 int 4000 ice_cfg_q_bw_dflt_lmt(struct ice_port_info *pi, u16 vsi_handle, u8 tc, 4001 u16 q_handle, enum ice_rl_type rl_type) 4002 { 4003 return ice_sched_set_q_bw_lmt(pi, vsi_handle, tc, q_handle, rl_type, 4004 ICE_SCHED_DFLT_BW); 4005 } 4006 4007 /** 4008 * ice_sched_get_node_by_id_type - get node from ID type 4009 * @pi: port information structure 4010 * @id: identifier 4011 * @agg_type: type of aggregator 4012 * @tc: traffic class 4013 * 4014 * This function returns node identified by ID of type aggregator, and 4015 * based on traffic class (TC). This function needs to be called with 4016 * the scheduler lock held. 4017 */ 4018 static struct ice_sched_node * 4019 ice_sched_get_node_by_id_type(struct ice_port_info *pi, u32 id, 4020 enum ice_agg_type agg_type, u8 tc) 4021 { 4022 struct ice_sched_node *node = NULL; 4023 4024 switch (agg_type) { 4025 case ICE_AGG_TYPE_VSI: { 4026 struct ice_vsi_ctx *vsi_ctx; 4027 u16 vsi_handle = (u16)id; 4028 4029 if (!ice_is_vsi_valid(pi->hw, vsi_handle)) 4030 break; 4031 /* Get sched_vsi_info */ 4032 vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle); 4033 if (!vsi_ctx) 4034 break; 4035 node = vsi_ctx->sched.vsi_node[tc]; 4036 break; 4037 } 4038 4039 case ICE_AGG_TYPE_AGG: { 4040 struct ice_sched_node *tc_node; 4041 4042 tc_node = ice_sched_get_tc_node(pi, tc); 4043 if (tc_node) 4044 node = ice_sched_get_agg_node(pi, tc_node, id); 4045 break; 4046 } 4047 4048 default: 4049 break; 4050 } 4051 4052 return node; 4053 } 4054 4055 /** 4056 * ice_sched_set_node_bw_lmt_per_tc - set node BW limit per TC 4057 * @pi: port information structure 4058 * @id: ID (software VSI handle or AGG ID) 4059 * @agg_type: aggregator type (VSI or AGG type node) 4060 * @tc: traffic class 4061 * @rl_type: min or max 4062 * @bw: bandwidth in Kbps 4063 * 4064 * This function sets BW limit of VSI or Aggregator scheduling node 4065 * based on TC information from passed in argument BW. 4066 */ 4067 static int 4068 ice_sched_set_node_bw_lmt_per_tc(struct ice_port_info *pi, u32 id, 4069 enum ice_agg_type agg_type, u8 tc, 4070 enum ice_rl_type rl_type, u32 bw) 4071 { 4072 struct ice_sched_node *node; 4073 int status = -EINVAL; 4074 4075 if (!pi) 4076 return status; 4077 4078 if (rl_type == ICE_UNKNOWN_BW) 4079 return status; 4080 4081 mutex_lock(&pi->sched_lock); 4082 node = ice_sched_get_node_by_id_type(pi, id, agg_type, tc); 4083 if (!node) { 4084 ice_debug(pi->hw, ICE_DBG_SCHED, "Wrong id, agg type, or tc\n"); 4085 goto exit_set_node_bw_lmt_per_tc; 4086 } 4087 if (bw == ICE_SCHED_DFLT_BW) 4088 status = ice_sched_set_node_bw_dflt_lmt(pi, node, rl_type); 4089 else 4090 status = ice_sched_set_node_bw_lmt(pi, node, rl_type, bw); 4091 4092 exit_set_node_bw_lmt_per_tc: 4093 mutex_unlock(&pi->sched_lock); 4094 return status; 4095 } 4096 4097 /** 4098 * ice_cfg_vsi_bw_lmt_per_tc - configure VSI BW limit per TC 4099 * @pi: port information structure 4100 * @vsi_handle: software VSI handle 4101 * @tc: traffic class 4102 * @rl_type: min or max 4103 * @bw: bandwidth in Kbps 4104 * 4105 * This function configures BW limit of VSI scheduling node based on TC 4106 * information. 4107 */ 4108 int 4109 ice_cfg_vsi_bw_lmt_per_tc(struct ice_port_info *pi, u16 vsi_handle, u8 tc, 4110 enum ice_rl_type rl_type, u32 bw) 4111 { 4112 int status; 4113 4114 status = ice_sched_set_node_bw_lmt_per_tc(pi, vsi_handle, 4115 ICE_AGG_TYPE_VSI, 4116 tc, rl_type, bw); 4117 if (!status) { 4118 mutex_lock(&pi->sched_lock); 4119 status = ice_sched_save_vsi_bw(pi, vsi_handle, tc, rl_type, bw); 4120 mutex_unlock(&pi->sched_lock); 4121 } 4122 return status; 4123 } 4124 4125 /** 4126 * ice_cfg_vsi_bw_dflt_lmt_per_tc - configure default VSI BW limit per TC 4127 * @pi: port information structure 4128 * @vsi_handle: software VSI handle 4129 * @tc: traffic class 4130 * @rl_type: min or max 4131 * 4132 * This function configures default BW limit of VSI scheduling node based on TC 4133 * information. 4134 */ 4135 int 4136 ice_cfg_vsi_bw_dflt_lmt_per_tc(struct ice_port_info *pi, u16 vsi_handle, u8 tc, 4137 enum ice_rl_type rl_type) 4138 { 4139 int status; 4140 4141 status = ice_sched_set_node_bw_lmt_per_tc(pi, vsi_handle, 4142 ICE_AGG_TYPE_VSI, 4143 tc, rl_type, 4144 ICE_SCHED_DFLT_BW); 4145 if (!status) { 4146 mutex_lock(&pi->sched_lock); 4147 status = ice_sched_save_vsi_bw(pi, vsi_handle, tc, rl_type, 4148 ICE_SCHED_DFLT_BW); 4149 mutex_unlock(&pi->sched_lock); 4150 } 4151 return status; 4152 } 4153 4154 /** 4155 * ice_cfg_rl_burst_size - Set burst size value 4156 * @hw: pointer to the HW struct 4157 * @bytes: burst size in bytes 4158 * 4159 * This function configures/set the burst size to requested new value. The new 4160 * burst size value is used for future rate limit calls. It doesn't change the 4161 * existing or previously created RL profiles. 4162 */ 4163 int ice_cfg_rl_burst_size(struct ice_hw *hw, u32 bytes) 4164 { 4165 u16 burst_size_to_prog; 4166 4167 if (bytes < ICE_MIN_BURST_SIZE_ALLOWED || 4168 bytes > ICE_MAX_BURST_SIZE_ALLOWED) 4169 return -EINVAL; 4170 if (ice_round_to_num(bytes, 64) <= 4171 ICE_MAX_BURST_SIZE_64_BYTE_GRANULARITY) { 4172 /* 64 byte granularity case */ 4173 /* Disable MSB granularity bit */ 4174 burst_size_to_prog = ICE_64_BYTE_GRANULARITY; 4175 /* round number to nearest 64 byte granularity */ 4176 bytes = ice_round_to_num(bytes, 64); 4177 /* The value is in 64 byte chunks */ 4178 burst_size_to_prog |= (u16)(bytes / 64); 4179 } else { 4180 /* k bytes granularity case */ 4181 /* Enable MSB granularity bit */ 4182 burst_size_to_prog = ICE_KBYTE_GRANULARITY; 4183 /* round number to nearest 1024 granularity */ 4184 bytes = ice_round_to_num(bytes, 1024); 4185 /* check rounding doesn't go beyond allowed */ 4186 if (bytes > ICE_MAX_BURST_SIZE_KBYTE_GRANULARITY) 4187 bytes = ICE_MAX_BURST_SIZE_KBYTE_GRANULARITY; 4188 /* The value is in k bytes */ 4189 burst_size_to_prog |= (u16)(bytes / 1024); 4190 } 4191 hw->max_burst_size = burst_size_to_prog; 4192 return 0; 4193 } 4194 4195 /** 4196 * ice_sched_replay_node_prio - re-configure node priority 4197 * @hw: pointer to the HW struct 4198 * @node: sched node to configure 4199 * @priority: priority value 4200 * 4201 * This function configures node element's priority value. It 4202 * needs to be called with scheduler lock held. 4203 */ 4204 static int 4205 ice_sched_replay_node_prio(struct ice_hw *hw, struct ice_sched_node *node, 4206 u8 priority) 4207 { 4208 struct ice_aqc_txsched_elem_data buf; 4209 struct ice_aqc_txsched_elem *data; 4210 int status; 4211 4212 buf = node->info; 4213 data = &buf.data; 4214 data->valid_sections |= ICE_AQC_ELEM_VALID_GENERIC; 4215 data->generic = priority; 4216 4217 /* Configure element */ 4218 status = ice_sched_update_elem(hw, node, &buf); 4219 return status; 4220 } 4221 4222 /** 4223 * ice_sched_replay_node_bw - replay node(s) BW 4224 * @hw: pointer to the HW struct 4225 * @node: sched node to configure 4226 * @bw_t_info: BW type information 4227 * 4228 * This function restores node's BW from bw_t_info. The caller needs 4229 * to hold the scheduler lock. 4230 */ 4231 static int 4232 ice_sched_replay_node_bw(struct ice_hw *hw, struct ice_sched_node *node, 4233 struct ice_bw_type_info *bw_t_info) 4234 { 4235 struct ice_port_info *pi = hw->port_info; 4236 int status = -EINVAL; 4237 u16 bw_alloc; 4238 4239 if (!node) 4240 return status; 4241 if (bitmap_empty(bw_t_info->bw_t_bitmap, ICE_BW_TYPE_CNT)) 4242 return 0; 4243 if (test_bit(ICE_BW_TYPE_PRIO, bw_t_info->bw_t_bitmap)) { 4244 status = ice_sched_replay_node_prio(hw, node, 4245 bw_t_info->generic); 4246 if (status) 4247 return status; 4248 } 4249 if (test_bit(ICE_BW_TYPE_CIR, bw_t_info->bw_t_bitmap)) { 4250 status = ice_sched_set_node_bw_lmt(pi, node, ICE_MIN_BW, 4251 bw_t_info->cir_bw.bw); 4252 if (status) 4253 return status; 4254 } 4255 if (test_bit(ICE_BW_TYPE_CIR_WT, bw_t_info->bw_t_bitmap)) { 4256 bw_alloc = bw_t_info->cir_bw.bw_alloc; 4257 status = ice_sched_cfg_node_bw_alloc(hw, node, ICE_MIN_BW, 4258 bw_alloc); 4259 if (status) 4260 return status; 4261 } 4262 if (test_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap)) { 4263 status = ice_sched_set_node_bw_lmt(pi, node, ICE_MAX_BW, 4264 bw_t_info->eir_bw.bw); 4265 if (status) 4266 return status; 4267 } 4268 if (test_bit(ICE_BW_TYPE_EIR_WT, bw_t_info->bw_t_bitmap)) { 4269 bw_alloc = bw_t_info->eir_bw.bw_alloc; 4270 status = ice_sched_cfg_node_bw_alloc(hw, node, ICE_MAX_BW, 4271 bw_alloc); 4272 if (status) 4273 return status; 4274 } 4275 if (test_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap)) 4276 status = ice_sched_set_node_bw_lmt(pi, node, ICE_SHARED_BW, 4277 bw_t_info->shared_bw); 4278 return status; 4279 } 4280 4281 /** 4282 * ice_sched_get_ena_tc_bitmap - get enabled TC bitmap 4283 * @pi: port info struct 4284 * @tc_bitmap: 8 bits TC bitmap to check 4285 * @ena_tc_bitmap: 8 bits enabled TC bitmap to return 4286 * 4287 * This function returns enabled TC bitmap in variable ena_tc_bitmap. Some TCs 4288 * may be missing, it returns enabled TCs. This function needs to be called with 4289 * scheduler lock held. 4290 */ 4291 static void 4292 ice_sched_get_ena_tc_bitmap(struct ice_port_info *pi, 4293 unsigned long *tc_bitmap, 4294 unsigned long *ena_tc_bitmap) 4295 { 4296 u8 tc; 4297 4298 /* Some TC(s) may be missing after reset, adjust for replay */ 4299 ice_for_each_traffic_class(tc) 4300 if (ice_is_tc_ena(*tc_bitmap, tc) && 4301 (ice_sched_get_tc_node(pi, tc))) 4302 set_bit(tc, ena_tc_bitmap); 4303 } 4304 4305 /** 4306 * ice_sched_replay_agg - recreate aggregator node(s) 4307 * @hw: pointer to the HW struct 4308 * 4309 * This function recreate aggregator type nodes which are not replayed earlier. 4310 * It also replay aggregator BW information. These aggregator nodes are not 4311 * associated with VSI type node yet. 4312 */ 4313 void ice_sched_replay_agg(struct ice_hw *hw) 4314 { 4315 struct ice_port_info *pi = hw->port_info; 4316 struct ice_sched_agg_info *agg_info; 4317 4318 mutex_lock(&pi->sched_lock); 4319 list_for_each_entry(agg_info, &hw->agg_list, list_entry) 4320 /* replay aggregator (re-create aggregator node) */ 4321 if (!bitmap_equal(agg_info->tc_bitmap, agg_info->replay_tc_bitmap, 4322 ICE_MAX_TRAFFIC_CLASS)) { 4323 DECLARE_BITMAP(replay_bitmap, ICE_MAX_TRAFFIC_CLASS); 4324 int status; 4325 4326 bitmap_zero(replay_bitmap, ICE_MAX_TRAFFIC_CLASS); 4327 ice_sched_get_ena_tc_bitmap(pi, 4328 agg_info->replay_tc_bitmap, 4329 replay_bitmap); 4330 status = ice_sched_cfg_agg(hw->port_info, 4331 agg_info->agg_id, 4332 ICE_AGG_TYPE_AGG, 4333 replay_bitmap); 4334 if (status) { 4335 dev_info(ice_hw_to_dev(hw), 4336 "Replay agg id[%d] failed\n", 4337 agg_info->agg_id); 4338 /* Move on to next one */ 4339 continue; 4340 } 4341 } 4342 mutex_unlock(&pi->sched_lock); 4343 } 4344 4345 /** 4346 * ice_sched_replay_agg_vsi_preinit - Agg/VSI replay pre initialization 4347 * @hw: pointer to the HW struct 4348 * 4349 * This function initialize aggregator(s) TC bitmap to zero. A required 4350 * preinit step for replaying aggregators. 4351 */ 4352 void ice_sched_replay_agg_vsi_preinit(struct ice_hw *hw) 4353 { 4354 struct ice_port_info *pi = hw->port_info; 4355 struct ice_sched_agg_info *agg_info; 4356 4357 mutex_lock(&pi->sched_lock); 4358 list_for_each_entry(agg_info, &hw->agg_list, list_entry) { 4359 struct ice_sched_agg_vsi_info *agg_vsi_info; 4360 4361 agg_info->tc_bitmap[0] = 0; 4362 list_for_each_entry(agg_vsi_info, &agg_info->agg_vsi_list, 4363 list_entry) 4364 agg_vsi_info->tc_bitmap[0] = 0; 4365 } 4366 mutex_unlock(&pi->sched_lock); 4367 } 4368 4369 /** 4370 * ice_sched_replay_vsi_agg - replay aggregator & VSI to aggregator node(s) 4371 * @hw: pointer to the HW struct 4372 * @vsi_handle: software VSI handle 4373 * 4374 * This function replays aggregator node, VSI to aggregator type nodes, and 4375 * their node bandwidth information. This function needs to be called with 4376 * scheduler lock held. 4377 */ 4378 static int ice_sched_replay_vsi_agg(struct ice_hw *hw, u16 vsi_handle) 4379 { 4380 DECLARE_BITMAP(replay_bitmap, ICE_MAX_TRAFFIC_CLASS); 4381 struct ice_sched_agg_vsi_info *agg_vsi_info; 4382 struct ice_port_info *pi = hw->port_info; 4383 struct ice_sched_agg_info *agg_info; 4384 int status; 4385 4386 bitmap_zero(replay_bitmap, ICE_MAX_TRAFFIC_CLASS); 4387 if (!ice_is_vsi_valid(hw, vsi_handle)) 4388 return -EINVAL; 4389 agg_info = ice_get_vsi_agg_info(hw, vsi_handle); 4390 if (!agg_info) 4391 return 0; /* Not present in list - default Agg case */ 4392 agg_vsi_info = ice_get_agg_vsi_info(agg_info, vsi_handle); 4393 if (!agg_vsi_info) 4394 return 0; /* Not present in list - default Agg case */ 4395 ice_sched_get_ena_tc_bitmap(pi, agg_info->replay_tc_bitmap, 4396 replay_bitmap); 4397 /* Replay aggregator node associated to vsi_handle */ 4398 status = ice_sched_cfg_agg(hw->port_info, agg_info->agg_id, 4399 ICE_AGG_TYPE_AGG, replay_bitmap); 4400 if (status) 4401 return status; 4402 4403 bitmap_zero(replay_bitmap, ICE_MAX_TRAFFIC_CLASS); 4404 ice_sched_get_ena_tc_bitmap(pi, agg_vsi_info->replay_tc_bitmap, 4405 replay_bitmap); 4406 /* Move this VSI (vsi_handle) to above aggregator */ 4407 return ice_sched_assoc_vsi_to_agg(pi, agg_info->agg_id, vsi_handle, 4408 replay_bitmap); 4409 } 4410 4411 /** 4412 * ice_replay_vsi_agg - replay VSI to aggregator node 4413 * @hw: pointer to the HW struct 4414 * @vsi_handle: software VSI handle 4415 * 4416 * This function replays association of VSI to aggregator type nodes, and 4417 * node bandwidth information. 4418 */ 4419 int ice_replay_vsi_agg(struct ice_hw *hw, u16 vsi_handle) 4420 { 4421 struct ice_port_info *pi = hw->port_info; 4422 int status; 4423 4424 mutex_lock(&pi->sched_lock); 4425 status = ice_sched_replay_vsi_agg(hw, vsi_handle); 4426 mutex_unlock(&pi->sched_lock); 4427 return status; 4428 } 4429 4430 /** 4431 * ice_sched_replay_q_bw - replay queue type node BW 4432 * @pi: port information structure 4433 * @q_ctx: queue context structure 4434 * 4435 * This function replays queue type node bandwidth. This function needs to be 4436 * called with scheduler lock held. 4437 */ 4438 int ice_sched_replay_q_bw(struct ice_port_info *pi, struct ice_q_ctx *q_ctx) 4439 { 4440 struct ice_sched_node *q_node; 4441 4442 /* Following also checks the presence of node in tree */ 4443 q_node = ice_sched_find_node_by_teid(pi->root, q_ctx->q_teid); 4444 if (!q_node) 4445 return -EINVAL; 4446 return ice_sched_replay_node_bw(pi->hw, q_node, &q_ctx->bw_t_info); 4447 } 4448