1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018, Intel Corporation. */
7 * ice_sched_add_root_node - Insert the Tx scheduler root node in SW DB
8 * @pi: port information structure
9 * @info: Scheduler element information from firmware
11 * This function inserts the root node of the scheduling tree topology
14 static enum ice_status
15 ice_sched_add_root_node(struct ice_port_info *pi,
16 struct ice_aqc_txsched_elem_data *info)
18 struct ice_sched_node *root;
26 root = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*root), GFP_KERNEL);
28 return ICE_ERR_NO_MEMORY;
30 /* coverity[suspicious_sizeof] */
31 root->children = devm_kcalloc(ice_hw_to_dev(hw), hw->max_children[0],
32 sizeof(*root), GFP_KERNEL);
33 if (!root->children) {
34 devm_kfree(ice_hw_to_dev(hw), root);
35 return ICE_ERR_NO_MEMORY;
38 memcpy(&root->info, info, sizeof(*info));
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
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.
52 * This function needs to be called when holding the port_info->sched_lock
54 struct ice_sched_node *
55 ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid)
59 /* The TEID is same as that of the start_node */
60 if (ICE_TXSCHED_GET_NODE_TEID(start_node) == teid)
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)
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];
74 /* Search within each child's sub-tree */
75 for (i = 0; i < start_node->num_children; i++) {
76 struct ice_sched_node *tmp;
78 tmp = ice_sched_find_node_by_teid(start_node->children[i],
88 * ice_aqc_send_sched_elem_cmd - send scheduling elements cmd
89 * @hw: pointer to the HW struct
90 * @cmd_opc: cmd opcode
91 * @elems_req: number of elements to request
92 * @buf: pointer to buffer
93 * @buf_size: buffer size in bytes
94 * @elems_resp: returns total number of elements response
95 * @cd: pointer to command details structure or NULL
97 * This function sends a scheduling elements cmd (cmd_opc)
99 static enum ice_status
100 ice_aqc_send_sched_elem_cmd(struct ice_hw *hw, enum ice_adminq_opc cmd_opc,
101 u16 elems_req, void *buf, u16 buf_size,
102 u16 *elems_resp, struct ice_sq_cd *cd)
104 struct ice_aqc_sched_elem_cmd *cmd;
105 struct ice_aq_desc desc;
106 enum ice_status status;
108 cmd = &desc.params.sched_elem_cmd;
109 ice_fill_dflt_direct_cmd_desc(&desc, cmd_opc);
110 cmd->num_elem_req = cpu_to_le16(elems_req);
111 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
112 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
113 if (!status && elems_resp)
114 *elems_resp = le16_to_cpu(cmd->num_elem_resp);
120 * ice_aq_query_sched_elems - query scheduler elements
121 * @hw: pointer to the HW struct
122 * @elems_req: number of elements to query
123 * @buf: pointer to buffer
124 * @buf_size: buffer size in bytes
125 * @elems_ret: returns total number of elements returned
126 * @cd: pointer to command details structure or NULL
128 * Query scheduling elements (0x0404)
131 ice_aq_query_sched_elems(struct ice_hw *hw, u16 elems_req,
132 struct ice_aqc_get_elem *buf, u16 buf_size,
133 u16 *elems_ret, struct ice_sq_cd *cd)
135 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_get_sched_elems,
136 elems_req, (void *)buf, buf_size,
141 * ice_sched_add_node - Insert the Tx scheduler node in SW DB
142 * @pi: port information structure
143 * @layer: Scheduler layer of the node
144 * @info: Scheduler element information from firmware
146 * This function inserts a scheduler node to the SW DB.
149 ice_sched_add_node(struct ice_port_info *pi, u8 layer,
150 struct ice_aqc_txsched_elem_data *info)
152 struct ice_sched_node *parent;
153 struct ice_aqc_get_elem elem;
154 struct ice_sched_node *node;
155 enum ice_status status;
159 return ICE_ERR_PARAM;
163 /* A valid parent node should be there */
164 parent = ice_sched_find_node_by_teid(pi->root,
165 le32_to_cpu(info->parent_teid));
167 ice_debug(hw, ICE_DBG_SCHED,
168 "Parent Node not found for parent_teid=0x%x\n",
169 le32_to_cpu(info->parent_teid));
170 return ICE_ERR_PARAM;
173 /* query the current node information from FW before additing it
176 status = ice_sched_query_elem(hw, le32_to_cpu(info->node_teid), &elem);
180 node = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*node), GFP_KERNEL);
182 return ICE_ERR_NO_MEMORY;
183 if (hw->max_children[layer]) {
184 /* coverity[suspicious_sizeof] */
185 node->children = devm_kcalloc(ice_hw_to_dev(hw),
186 hw->max_children[layer],
187 sizeof(*node), GFP_KERNEL);
188 if (!node->children) {
189 devm_kfree(ice_hw_to_dev(hw), node);
190 return ICE_ERR_NO_MEMORY;
195 node->parent = parent;
196 node->tx_sched_layer = layer;
197 parent->children[parent->num_children++] = node;
198 memcpy(&node->info, &elem.generic[0], sizeof(node->info));
203 * ice_aq_delete_sched_elems - delete scheduler elements
204 * @hw: pointer to the HW struct
205 * @grps_req: number of groups to delete
206 * @buf: pointer to buffer
207 * @buf_size: buffer size in bytes
208 * @grps_del: returns total number of elements deleted
209 * @cd: pointer to command details structure or NULL
211 * Delete scheduling elements (0x040F)
213 static enum ice_status
214 ice_aq_delete_sched_elems(struct ice_hw *hw, u16 grps_req,
215 struct ice_aqc_delete_elem *buf, u16 buf_size,
216 u16 *grps_del, struct ice_sq_cd *cd)
218 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_delete_sched_elems,
219 grps_req, (void *)buf, buf_size,
224 * ice_sched_remove_elems - remove nodes from HW
225 * @hw: pointer to the HW struct
226 * @parent: pointer to the parent node
227 * @num_nodes: number of nodes
228 * @node_teids: array of node teids to be deleted
230 * This function remove nodes from HW
232 static enum ice_status
233 ice_sched_remove_elems(struct ice_hw *hw, struct ice_sched_node *parent,
234 u16 num_nodes, u32 *node_teids)
236 struct ice_aqc_delete_elem *buf;
237 u16 i, num_groups_removed = 0;
238 enum ice_status status;
241 buf_size = sizeof(*buf) + sizeof(u32) * (num_nodes - 1);
242 buf = devm_kzalloc(ice_hw_to_dev(hw), buf_size, GFP_KERNEL);
244 return ICE_ERR_NO_MEMORY;
246 buf->hdr.parent_teid = parent->info.node_teid;
247 buf->hdr.num_elems = cpu_to_le16(num_nodes);
248 for (i = 0; i < num_nodes; i++)
249 buf->teid[i] = cpu_to_le32(node_teids[i]);
251 status = ice_aq_delete_sched_elems(hw, 1, buf, buf_size,
252 &num_groups_removed, NULL);
253 if (status || num_groups_removed != 1)
254 ice_debug(hw, ICE_DBG_SCHED, "remove node failed FW error %d\n",
255 hw->adminq.sq_last_status);
257 devm_kfree(ice_hw_to_dev(hw), buf);
262 * ice_sched_get_first_node - get the first node of the given layer
263 * @hw: pointer to the HW struct
264 * @parent: pointer the base node of the subtree
265 * @layer: layer number
267 * This function retrieves the first node of the given layer from the subtree
269 static struct ice_sched_node *
270 ice_sched_get_first_node(struct ice_hw *hw, struct ice_sched_node *parent,
275 if (layer < hw->sw_entry_point_layer)
277 for (i = 0; i < parent->num_children; i++) {
278 struct ice_sched_node *node = parent->children[i];
281 if (node->tx_sched_layer == layer)
283 /* this recursion is intentional, and wouldn't
284 * go more than 9 calls
286 return ice_sched_get_first_node(hw, node, layer);
293 * ice_sched_get_tc_node - get pointer to TC node
294 * @pi: port information structure
297 * This function returns the TC node pointer
299 struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc)
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];
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
316 * This function frees up a node from SW DB as well as from HW
318 * This function needs to be called with the port_info->sched_lock held
320 void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
322 struct ice_sched_node *parent;
323 struct ice_hw *hw = pi->hw;
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
330 while (node->num_children)
331 ice_free_sched_node(pi, node->children[0]);
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);
340 ice_sched_remove_elems(hw, node->parent, 1, &teid);
342 parent = node->parent;
343 /* root has no parent */
345 struct ice_sched_node *p, *tc_node;
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] =
353 parent->num_children--;
357 /* search for previous sibling that points to this node and
358 * remove the reference
360 tc_node = ice_sched_get_tc_node(pi, node->tc_num);
362 ice_debug(hw, ICE_DBG_SCHED,
363 "Invalid TC number %d\n", node->tc_num);
366 p = ice_sched_get_first_node(hw, tc_node, node->tx_sched_layer);
368 if (p->sibling == node) {
369 p->sibling = node->sibling;
376 /* leaf nodes have no children */
378 devm_kfree(ice_hw_to_dev(hw), node->children);
379 devm_kfree(ice_hw_to_dev(hw), node);
383 * ice_aq_get_dflt_topo - gets default scheduler topology
384 * @hw: pointer to the HW struct
385 * @lport: logical port number
386 * @buf: pointer to buffer
387 * @buf_size: buffer size in bytes
388 * @num_branches: returns total number of queue to port branches
389 * @cd: pointer to command details structure or NULL
391 * Get default scheduler topology (0x400)
393 static enum ice_status
394 ice_aq_get_dflt_topo(struct ice_hw *hw, u8 lport,
395 struct ice_aqc_get_topo_elem *buf, u16 buf_size,
396 u8 *num_branches, struct ice_sq_cd *cd)
398 struct ice_aqc_get_topo *cmd;
399 struct ice_aq_desc desc;
400 enum ice_status status;
402 cmd = &desc.params.get_topo;
403 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_dflt_topo);
404 cmd->port_num = lport;
405 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
406 if (!status && num_branches)
407 *num_branches = cmd->num_branches;
413 * ice_aq_add_sched_elems - adds scheduling element
414 * @hw: pointer to the HW struct
415 * @grps_req: the number of groups that are requested to be added
416 * @buf: pointer to buffer
417 * @buf_size: buffer size in bytes
418 * @grps_added: returns total number of groups added
419 * @cd: pointer to command details structure or NULL
421 * Add scheduling elements (0x0401)
423 static enum ice_status
424 ice_aq_add_sched_elems(struct ice_hw *hw, u16 grps_req,
425 struct ice_aqc_add_elem *buf, u16 buf_size,
426 u16 *grps_added, struct ice_sq_cd *cd)
428 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_add_sched_elems,
429 grps_req, (void *)buf, buf_size,
434 * ice_aq_suspend_sched_elems - suspend scheduler elements
435 * @hw: pointer to the HW struct
436 * @elems_req: number of elements to suspend
437 * @buf: pointer to buffer
438 * @buf_size: buffer size in bytes
439 * @elems_ret: returns total number of elements suspended
440 * @cd: pointer to command details structure or NULL
442 * Suspend scheduling elements (0x0409)
444 static enum ice_status
445 ice_aq_suspend_sched_elems(struct ice_hw *hw, u16 elems_req,
446 struct ice_aqc_suspend_resume_elem *buf,
447 u16 buf_size, u16 *elems_ret, struct ice_sq_cd *cd)
449 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_suspend_sched_elems,
450 elems_req, (void *)buf, buf_size,
455 * ice_aq_resume_sched_elems - resume scheduler elements
456 * @hw: pointer to the HW struct
457 * @elems_req: number of elements to resume
458 * @buf: pointer to buffer
459 * @buf_size: buffer size in bytes
460 * @elems_ret: returns total number of elements resumed
461 * @cd: pointer to command details structure or NULL
463 * resume scheduling elements (0x040A)
465 static enum ice_status
466 ice_aq_resume_sched_elems(struct ice_hw *hw, u16 elems_req,
467 struct ice_aqc_suspend_resume_elem *buf,
468 u16 buf_size, u16 *elems_ret, struct ice_sq_cd *cd)
470 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_resume_sched_elems,
471 elems_req, (void *)buf, buf_size,
476 * ice_aq_query_sched_res - query scheduler resource
477 * @hw: pointer to the HW struct
478 * @buf_size: buffer size in bytes
479 * @buf: pointer to buffer
480 * @cd: pointer to command details structure or NULL
482 * Query scheduler resource allocation (0x0412)
484 static enum ice_status
485 ice_aq_query_sched_res(struct ice_hw *hw, u16 buf_size,
486 struct ice_aqc_query_txsched_res_resp *buf,
487 struct ice_sq_cd *cd)
489 struct ice_aq_desc desc;
491 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_query_sched_res);
492 return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
496 * ice_sched_suspend_resume_elems - suspend or resume HW nodes
497 * @hw: pointer to the HW struct
498 * @num_nodes: number of nodes
499 * @node_teids: array of node teids to be suspended or resumed
500 * @suspend: true means suspend / false means resume
502 * This function suspends or resumes HW nodes
504 static enum ice_status
505 ice_sched_suspend_resume_elems(struct ice_hw *hw, u8 num_nodes, u32 *node_teids,
508 struct ice_aqc_suspend_resume_elem *buf;
509 u16 i, buf_size, num_elem_ret = 0;
510 enum ice_status status;
512 buf_size = sizeof(*buf) * num_nodes;
513 buf = devm_kzalloc(ice_hw_to_dev(hw), buf_size, GFP_KERNEL);
515 return ICE_ERR_NO_MEMORY;
517 for (i = 0; i < num_nodes; i++)
518 buf->teid[i] = cpu_to_le32(node_teids[i]);
521 status = ice_aq_suspend_sched_elems(hw, num_nodes, buf,
522 buf_size, &num_elem_ret,
525 status = ice_aq_resume_sched_elems(hw, num_nodes, buf,
526 buf_size, &num_elem_ret,
528 if (status || num_elem_ret != num_nodes)
529 ice_debug(hw, ICE_DBG_SCHED, "suspend/resume failed\n");
531 devm_kfree(ice_hw_to_dev(hw), buf);
536 * ice_alloc_lan_q_ctx - allocate LAN queue contexts for the given VSI and TC
537 * @hw: pointer to the HW struct
538 * @vsi_handle: VSI handle
540 * @new_numqs: number of queues
542 static enum ice_status
543 ice_alloc_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 new_numqs)
545 struct ice_vsi_ctx *vsi_ctx;
546 struct ice_q_ctx *q_ctx;
548 vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
550 return ICE_ERR_PARAM;
551 /* allocate LAN queue contexts */
552 if (!vsi_ctx->lan_q_ctx[tc]) {
553 vsi_ctx->lan_q_ctx[tc] = devm_kcalloc(ice_hw_to_dev(hw),
557 if (!vsi_ctx->lan_q_ctx[tc])
558 return ICE_ERR_NO_MEMORY;
559 vsi_ctx->num_lan_q_entries[tc] = new_numqs;
562 /* num queues are increased, update the queue contexts */
563 if (new_numqs > vsi_ctx->num_lan_q_entries[tc]) {
564 u16 prev_num = vsi_ctx->num_lan_q_entries[tc];
566 q_ctx = devm_kcalloc(ice_hw_to_dev(hw), new_numqs,
567 sizeof(*q_ctx), GFP_KERNEL);
569 return ICE_ERR_NO_MEMORY;
570 memcpy(q_ctx, vsi_ctx->lan_q_ctx[tc],
571 prev_num * sizeof(*q_ctx));
572 devm_kfree(ice_hw_to_dev(hw), vsi_ctx->lan_q_ctx[tc]);
573 vsi_ctx->lan_q_ctx[tc] = q_ctx;
574 vsi_ctx->num_lan_q_entries[tc] = new_numqs;
580 * ice_sched_clear_agg - clears the aggregator related information
581 * @hw: pointer to the hardware structure
583 * This function removes aggregator list and free up aggregator related memory
584 * previously allocated.
586 void ice_sched_clear_agg(struct ice_hw *hw)
588 struct ice_sched_agg_info *agg_info;
589 struct ice_sched_agg_info *atmp;
591 list_for_each_entry_safe(agg_info, atmp, &hw->agg_list, list_entry) {
592 struct ice_sched_agg_vsi_info *agg_vsi_info;
593 struct ice_sched_agg_vsi_info *vtmp;
595 list_for_each_entry_safe(agg_vsi_info, vtmp,
596 &agg_info->agg_vsi_list, list_entry) {
597 list_del(&agg_vsi_info->list_entry);
598 devm_kfree(ice_hw_to_dev(hw), agg_vsi_info);
600 list_del(&agg_info->list_entry);
601 devm_kfree(ice_hw_to_dev(hw), agg_info);
606 * ice_sched_clear_tx_topo - clears the scheduler tree nodes
607 * @pi: port information structure
609 * This function removes all the nodes from HW as well as from SW DB.
611 static void ice_sched_clear_tx_topo(struct ice_port_info *pi)
616 ice_free_sched_node(pi, pi->root);
622 * ice_sched_clear_port - clear the scheduler elements from SW DB for a port
623 * @pi: port information structure
625 * Cleanup scheduling elements from SW DB
627 void ice_sched_clear_port(struct ice_port_info *pi)
629 if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
632 pi->port_state = ICE_SCHED_PORT_STATE_INIT;
633 mutex_lock(&pi->sched_lock);
634 ice_sched_clear_tx_topo(pi);
635 mutex_unlock(&pi->sched_lock);
636 mutex_destroy(&pi->sched_lock);
640 * ice_sched_cleanup_all - cleanup scheduler elements from SW DB for all ports
641 * @hw: pointer to the HW struct
643 * Cleanup scheduling elements from SW DB for all the ports
645 void ice_sched_cleanup_all(struct ice_hw *hw)
650 if (hw->layer_info) {
651 devm_kfree(ice_hw_to_dev(hw), hw->layer_info);
652 hw->layer_info = NULL;
656 ice_sched_clear_port(hw->port_info);
658 hw->num_tx_sched_layers = 0;
659 hw->num_tx_sched_phys_layers = 0;
660 hw->flattened_layers = 0;
665 * ice_sched_add_elems - add nodes to HW and SW DB
666 * @pi: port information structure
667 * @tc_node: pointer to the branch node
668 * @parent: pointer to the parent node
669 * @layer: layer number to add nodes
670 * @num_nodes: number of nodes
671 * @num_nodes_added: pointer to num nodes added
672 * @first_node_teid: if new nodes are added then return the TEID of first node
674 * This function add nodes to HW as well as to SW DB for a given layer
676 static enum ice_status
677 ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
678 struct ice_sched_node *parent, u8 layer, u16 num_nodes,
679 u16 *num_nodes_added, u32 *first_node_teid)
681 struct ice_sched_node *prev, *new_node;
682 struct ice_aqc_add_elem *buf;
683 u16 i, num_groups_added = 0;
684 enum ice_status status = 0;
685 struct ice_hw *hw = pi->hw;
689 buf_size = sizeof(*buf) + sizeof(*buf->generic) * (num_nodes - 1);
690 buf = devm_kzalloc(ice_hw_to_dev(hw), buf_size, GFP_KERNEL);
692 return ICE_ERR_NO_MEMORY;
694 buf->hdr.parent_teid = parent->info.node_teid;
695 buf->hdr.num_elems = cpu_to_le16(num_nodes);
696 for (i = 0; i < num_nodes; i++) {
697 buf->generic[i].parent_teid = parent->info.node_teid;
698 buf->generic[i].data.elem_type = ICE_AQC_ELEM_TYPE_SE_GENERIC;
699 buf->generic[i].data.valid_sections =
700 ICE_AQC_ELEM_VALID_GENERIC | ICE_AQC_ELEM_VALID_CIR |
701 ICE_AQC_ELEM_VALID_EIR;
702 buf->generic[i].data.generic = 0;
703 buf->generic[i].data.cir_bw.bw_profile_idx =
704 cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID);
705 buf->generic[i].data.cir_bw.bw_alloc =
706 cpu_to_le16(ICE_SCHED_DFLT_BW_WT);
707 buf->generic[i].data.eir_bw.bw_profile_idx =
708 cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID);
709 buf->generic[i].data.eir_bw.bw_alloc =
710 cpu_to_le16(ICE_SCHED_DFLT_BW_WT);
713 status = ice_aq_add_sched_elems(hw, 1, buf, buf_size,
714 &num_groups_added, NULL);
715 if (status || num_groups_added != 1) {
716 ice_debug(hw, ICE_DBG_SCHED, "add node failed FW Error %d\n",
717 hw->adminq.sq_last_status);
718 devm_kfree(ice_hw_to_dev(hw), buf);
722 *num_nodes_added = num_nodes;
723 /* add nodes to the SW DB */
724 for (i = 0; i < num_nodes; i++) {
725 status = ice_sched_add_node(pi, layer, &buf->generic[i]);
727 ice_debug(hw, ICE_DBG_SCHED,
728 "add nodes in SW DB failed status =%d\n",
733 teid = le32_to_cpu(buf->generic[i].node_teid);
734 new_node = ice_sched_find_node_by_teid(parent, teid);
736 ice_debug(hw, ICE_DBG_SCHED,
737 "Node is missing for teid =%d\n", teid);
741 new_node->sibling = NULL;
742 new_node->tc_num = tc_node->tc_num;
744 /* add it to previous node sibling pointer */
745 /* Note: siblings are not linked across branches */
746 prev = ice_sched_get_first_node(hw, tc_node, layer);
747 if (prev && prev != new_node) {
748 while (prev->sibling)
749 prev = prev->sibling;
750 prev->sibling = new_node;
754 *first_node_teid = teid;
757 devm_kfree(ice_hw_to_dev(hw), buf);
762 * ice_sched_add_nodes_to_layer - Add nodes to a given layer
763 * @pi: port information structure
764 * @tc_node: pointer to TC node
765 * @parent: pointer to parent node
766 * @layer: layer number to add nodes
767 * @num_nodes: number of nodes to be added
768 * @first_node_teid: pointer to the first node TEID
769 * @num_nodes_added: pointer to number of nodes added
771 * This function add nodes to a given layer.
773 static enum ice_status
774 ice_sched_add_nodes_to_layer(struct ice_port_info *pi,
775 struct ice_sched_node *tc_node,
776 struct ice_sched_node *parent, u8 layer,
777 u16 num_nodes, u32 *first_node_teid,
778 u16 *num_nodes_added)
780 u32 *first_teid_ptr = first_node_teid;
781 u16 new_num_nodes, max_child_nodes;
782 enum ice_status status = 0;
783 struct ice_hw *hw = pi->hw;
787 *num_nodes_added = 0;
792 if (!parent || layer < hw->sw_entry_point_layer)
793 return ICE_ERR_PARAM;
795 /* max children per node per layer */
796 max_child_nodes = hw->max_children[parent->tx_sched_layer];
798 /* current number of children + required nodes exceed max children ? */
799 if ((parent->num_children + num_nodes) > max_child_nodes) {
800 /* Fail if the parent is a TC node */
801 if (parent == tc_node)
804 /* utilize all the spaces if the parent is not full */
805 if (parent->num_children < max_child_nodes) {
806 new_num_nodes = max_child_nodes - parent->num_children;
807 /* this recursion is intentional, and wouldn't
808 * go more than 2 calls
810 status = ice_sched_add_nodes_to_layer(pi, tc_node,
818 *num_nodes_added += num_added;
820 /* Don't modify the first node TEID memory if the first node was
821 * added already in the above call. Instead send some temp
822 * memory for all other recursive calls.
825 first_teid_ptr = &temp;
827 new_num_nodes = num_nodes - num_added;
829 /* This parent is full, try the next sibling */
830 parent = parent->sibling;
832 /* this recursion is intentional, for 1024 queues
833 * per VSI, it goes max of 16 iterations.
834 * 1024 / 8 = 128 layer 8 nodes
835 * 128 /8 = 16 (add 8 nodes per iteration)
837 status = ice_sched_add_nodes_to_layer(pi, tc_node, parent,
838 layer, new_num_nodes,
841 *num_nodes_added += num_added;
845 status = ice_sched_add_elems(pi, tc_node, parent, layer, num_nodes,
846 num_nodes_added, first_node_teid);
851 * ice_sched_get_qgrp_layer - get the current queue group layer number
852 * @hw: pointer to the HW struct
854 * This function returns the current queue group layer number
856 static u8 ice_sched_get_qgrp_layer(struct ice_hw *hw)
858 /* It's always total layers - 1, the array is 0 relative so -2 */
859 return hw->num_tx_sched_layers - ICE_QGRP_LAYER_OFFSET;
863 * ice_sched_get_vsi_layer - get the current VSI layer number
864 * @hw: pointer to the HW struct
866 * This function returns the current VSI layer number
868 static u8 ice_sched_get_vsi_layer(struct ice_hw *hw)
870 /* Num Layers VSI layer
873 * 5 or less sw_entry_point_layer
875 /* calculate the VSI layer based on number of layers. */
876 if (hw->num_tx_sched_layers > ICE_VSI_LAYER_OFFSET + 1) {
877 u8 layer = hw->num_tx_sched_layers - ICE_VSI_LAYER_OFFSET;
879 if (layer > hw->sw_entry_point_layer)
882 return hw->sw_entry_point_layer;
886 * ice_rm_dflt_leaf_node - remove the default leaf node in the tree
887 * @pi: port information structure
889 * This function removes the leaf node that was created by the FW
890 * during initialization
892 static void ice_rm_dflt_leaf_node(struct ice_port_info *pi)
894 struct ice_sched_node *node;
898 if (!node->num_children)
900 node = node->children[0];
902 if (node && node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF) {
903 u32 teid = le32_to_cpu(node->info.node_teid);
904 enum ice_status status;
906 /* remove the default leaf node */
907 status = ice_sched_remove_elems(pi->hw, node->parent, 1, &teid);
909 ice_free_sched_node(pi, node);
914 * ice_sched_rm_dflt_nodes - free the default nodes in the tree
915 * @pi: port information structure
917 * This function frees all the nodes except root and TC that were created by
918 * the FW during initialization
920 static void ice_sched_rm_dflt_nodes(struct ice_port_info *pi)
922 struct ice_sched_node *node;
924 ice_rm_dflt_leaf_node(pi);
926 /* remove the default nodes except TC and root nodes */
929 if (node->tx_sched_layer >= pi->hw->sw_entry_point_layer &&
930 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC &&
931 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT) {
932 ice_free_sched_node(pi, node);
936 if (!node->num_children)
938 node = node->children[0];
943 * ice_sched_init_port - Initialize scheduler by querying information from FW
944 * @pi: port info structure for the tree to cleanup
946 * This function is the initial call to find the total number of Tx scheduler
947 * resources, default topology created by firmware and storing the information
950 enum ice_status ice_sched_init_port(struct ice_port_info *pi)
952 struct ice_aqc_get_topo_elem *buf;
953 enum ice_status status;
960 return ICE_ERR_PARAM;
963 /* Query the Default Topology from FW */
964 buf = devm_kzalloc(ice_hw_to_dev(hw), ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
966 return ICE_ERR_NO_MEMORY;
968 /* Query default scheduling tree topology */
969 status = ice_aq_get_dflt_topo(hw, pi->lport, buf, ICE_AQ_MAX_BUF_LEN,
970 &num_branches, NULL);
974 /* num_branches should be between 1-8 */
975 if (num_branches < 1 || num_branches > ICE_TXSCHED_MAX_BRANCHES) {
976 ice_debug(hw, ICE_DBG_SCHED, "num_branches unexpected %d\n",
978 status = ICE_ERR_PARAM;
982 /* get the number of elements on the default/first branch */
983 num_elems = le16_to_cpu(buf[0].hdr.num_elems);
985 /* num_elems should always be between 1-9 */
986 if (num_elems < 1 || num_elems > ICE_AQC_TOPO_MAX_LEVEL_NUM) {
987 ice_debug(hw, ICE_DBG_SCHED, "num_elems unexpected %d\n",
989 status = ICE_ERR_PARAM;
993 /* If the last node is a leaf node then the index of the queue group
994 * layer is two less than the number of elements.
996 if (num_elems > 2 && buf[0].generic[num_elems - 1].data.elem_type ==
997 ICE_AQC_ELEM_TYPE_LEAF)
999 le32_to_cpu(buf[0].generic[num_elems - 2].node_teid);
1001 pi->last_node_teid =
1002 le32_to_cpu(buf[0].generic[num_elems - 1].node_teid);
1004 /* Insert the Tx Sched root node */
1005 status = ice_sched_add_root_node(pi, &buf[0].generic[0]);
1009 /* Parse the default tree and cache the information */
1010 for (i = 0; i < num_branches; i++) {
1011 num_elems = le16_to_cpu(buf[i].hdr.num_elems);
1013 /* Skip root element as already inserted */
1014 for (j = 1; j < num_elems; j++) {
1015 /* update the sw entry point */
1016 if (buf[0].generic[j].data.elem_type ==
1017 ICE_AQC_ELEM_TYPE_ENTRY_POINT)
1018 hw->sw_entry_point_layer = j;
1020 status = ice_sched_add_node(pi, j, &buf[i].generic[j]);
1026 /* Remove the default nodes. */
1028 ice_sched_rm_dflt_nodes(pi);
1030 /* initialize the port for handling the scheduler tree */
1031 pi->port_state = ICE_SCHED_PORT_STATE_READY;
1032 mutex_init(&pi->sched_lock);
1035 if (status && pi->root) {
1036 ice_free_sched_node(pi, pi->root);
1040 devm_kfree(ice_hw_to_dev(hw), buf);
1045 * ice_sched_query_res_alloc - query the FW for num of logical sched layers
1046 * @hw: pointer to the HW struct
1048 * query FW for allocated scheduler resources and store in HW struct
1050 enum ice_status ice_sched_query_res_alloc(struct ice_hw *hw)
1052 struct ice_aqc_query_txsched_res_resp *buf;
1053 enum ice_status status = 0;
1060 buf = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*buf), GFP_KERNEL);
1062 return ICE_ERR_NO_MEMORY;
1064 status = ice_aq_query_sched_res(hw, sizeof(*buf), buf, NULL);
1066 goto sched_query_out;
1068 hw->num_tx_sched_layers = le16_to_cpu(buf->sched_props.logical_levels);
1069 hw->num_tx_sched_phys_layers =
1070 le16_to_cpu(buf->sched_props.phys_levels);
1071 hw->flattened_layers = buf->sched_props.flattening_bitmap;
1072 hw->max_cgds = buf->sched_props.max_pf_cgds;
1074 /* max sibling group size of current layer refers to the max children
1075 * of the below layer node.
1076 * layer 1 node max children will be layer 2 max sibling group size
1077 * layer 2 node max children will be layer 3 max sibling group size
1078 * and so on. This array will be populated from root (index 0) to
1079 * qgroup layer 7. Leaf node has no children.
1081 for (i = 0; i < hw->num_tx_sched_layers; i++) {
1082 max_sibl = buf->layer_props[i].max_sibl_grp_sz;
1083 hw->max_children[i] = le16_to_cpu(max_sibl);
1086 hw->layer_info = devm_kmemdup(ice_hw_to_dev(hw), buf->layer_props,
1087 (hw->num_tx_sched_layers *
1088 sizeof(*hw->layer_info)),
1090 if (!hw->layer_info) {
1091 status = ICE_ERR_NO_MEMORY;
1092 goto sched_query_out;
1096 devm_kfree(ice_hw_to_dev(hw), buf);
1101 * ice_sched_find_node_in_subtree - Find node in part of base node subtree
1102 * @hw: pointer to the HW struct
1103 * @base: pointer to the base node
1104 * @node: pointer to the node to search
1106 * This function checks whether a given node is part of the base node
1110 ice_sched_find_node_in_subtree(struct ice_hw *hw, struct ice_sched_node *base,
1111 struct ice_sched_node *node)
1115 for (i = 0; i < base->num_children; i++) {
1116 struct ice_sched_node *child = base->children[i];
1121 if (child->tx_sched_layer > node->tx_sched_layer)
1124 /* this recursion is intentional, and wouldn't
1125 * go more than 8 calls
1127 if (ice_sched_find_node_in_subtree(hw, child, node))
1134 * ice_sched_get_free_qparent - Get a free LAN or RDMA queue group node
1135 * @pi: port information structure
1136 * @vsi_handle: software VSI handle
1137 * @tc: branch number
1138 * @owner: LAN or RDMA
1140 * This function retrieves a free LAN or RDMA queue group node
1142 struct ice_sched_node *
1143 ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
1146 struct ice_sched_node *vsi_node, *qgrp_node = NULL;
1147 struct ice_vsi_ctx *vsi_ctx;
1151 qgrp_layer = ice_sched_get_qgrp_layer(pi->hw);
1152 max_children = pi->hw->max_children[qgrp_layer];
1154 vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
1157 vsi_node = vsi_ctx->sched.vsi_node[tc];
1158 /* validate invalid VSI ID */
1162 /* get the first queue group node from VSI sub-tree */
1163 qgrp_node = ice_sched_get_first_node(pi->hw, vsi_node, qgrp_layer);
1165 /* make sure the qgroup node is part of the VSI subtree */
1166 if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node))
1167 if (qgrp_node->num_children < max_children &&
1168 qgrp_node->owner == owner)
1170 qgrp_node = qgrp_node->sibling;
1178 * ice_sched_get_vsi_node - Get a VSI node based on VSI ID
1179 * @hw: pointer to the HW struct
1180 * @tc_node: pointer to the TC node
1181 * @vsi_handle: software VSI handle
1183 * This function retrieves a VSI node for a given VSI ID from a given
1186 static struct ice_sched_node *
1187 ice_sched_get_vsi_node(struct ice_hw *hw, struct ice_sched_node *tc_node,
1190 struct ice_sched_node *node;
1193 vsi_layer = ice_sched_get_vsi_layer(hw);
1194 node = ice_sched_get_first_node(hw, tc_node, vsi_layer);
1196 /* Check whether it already exists */
1198 if (node->vsi_handle == vsi_handle)
1200 node = node->sibling;
1207 * ice_sched_calc_vsi_child_nodes - calculate number of VSI child nodes
1208 * @hw: pointer to the HW struct
1209 * @num_qs: number of queues
1210 * @num_nodes: num nodes array
1212 * This function calculates the number of VSI child nodes based on the
1216 ice_sched_calc_vsi_child_nodes(struct ice_hw *hw, u16 num_qs, u16 *num_nodes)
1221 qgl = ice_sched_get_qgrp_layer(hw);
1222 vsil = ice_sched_get_vsi_layer(hw);
1224 /* calculate num nodes from queue group to VSI layer */
1225 for (i = qgl; i > vsil; i--) {
1226 /* round to the next integer if there is a remainder */
1227 num = DIV_ROUND_UP(num, hw->max_children[i]);
1229 /* need at least one node */
1230 num_nodes[i] = num ? num : 1;
1235 * ice_sched_add_vsi_child_nodes - add VSI child nodes to tree
1236 * @pi: port information structure
1237 * @vsi_handle: software VSI handle
1238 * @tc_node: pointer to the TC node
1239 * @num_nodes: pointer to the num nodes that needs to be added per layer
1240 * @owner: node owner (LAN or RDMA)
1242 * This function adds the VSI child nodes to tree. It gets called for
1243 * LAN and RDMA separately.
1245 static enum ice_status
1246 ice_sched_add_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
1247 struct ice_sched_node *tc_node, u16 *num_nodes,
1250 struct ice_sched_node *parent, *node;
1251 struct ice_hw *hw = pi->hw;
1252 enum ice_status status;
1253 u32 first_node_teid;
1257 qgl = ice_sched_get_qgrp_layer(hw);
1258 vsil = ice_sched_get_vsi_layer(hw);
1259 parent = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
1260 for (i = vsil + 1; i <= qgl; i++) {
1264 status = ice_sched_add_nodes_to_layer(pi, tc_node, parent, i,
1268 if (status || num_nodes[i] != num_added)
1271 /* The newly added node can be a new parent for the next
1275 parent = ice_sched_find_node_by_teid(tc_node,
1279 node->owner = owner;
1280 node = node->sibling;
1283 parent = parent->children[0];
1291 * ice_sched_calc_vsi_support_nodes - calculate number of VSI support nodes
1292 * @hw: pointer to the HW struct
1293 * @tc_node: pointer to TC node
1294 * @num_nodes: pointer to num nodes array
1296 * This function calculates the number of supported nodes needed to add this
1297 * VSI into Tx tree including the VSI, parent and intermediate nodes in below
1301 ice_sched_calc_vsi_support_nodes(struct ice_hw *hw,
1302 struct ice_sched_node *tc_node, u16 *num_nodes)
1304 struct ice_sched_node *node;
1308 vsil = ice_sched_get_vsi_layer(hw);
1309 for (i = vsil; i >= hw->sw_entry_point_layer; i--)
1310 /* Add intermediate nodes if TC has no children and
1311 * need at least one node for VSI
1313 if (!tc_node->num_children || i == vsil) {
1316 /* If intermediate nodes are reached max children
1317 * then add a new one.
1319 node = ice_sched_get_first_node(hw, tc_node, (u8)i);
1320 /* scan all the siblings */
1322 if (node->num_children < hw->max_children[i])
1324 node = node->sibling;
1327 /* tree has one intermediate node to add this new VSI.
1328 * So no need to calculate supported nodes for below
1333 /* all the nodes are full, allocate a new one */
1339 * ice_sched_add_vsi_support_nodes - add VSI supported nodes into Tx tree
1340 * @pi: port information structure
1341 * @vsi_handle: software VSI handle
1342 * @tc_node: pointer to TC node
1343 * @num_nodes: pointer to num nodes array
1345 * This function adds the VSI supported nodes into Tx tree including the
1346 * VSI, its parent and intermediate nodes in below layers
1348 static enum ice_status
1349 ice_sched_add_vsi_support_nodes(struct ice_port_info *pi, u16 vsi_handle,
1350 struct ice_sched_node *tc_node, u16 *num_nodes)
1352 struct ice_sched_node *parent = tc_node;
1353 enum ice_status status;
1354 u32 first_node_teid;
1359 return ICE_ERR_PARAM;
1361 vsil = ice_sched_get_vsi_layer(pi->hw);
1362 for (i = pi->hw->sw_entry_point_layer; i <= vsil; i++) {
1363 status = ice_sched_add_nodes_to_layer(pi, tc_node, parent,
1367 if (status || num_nodes[i] != num_added)
1370 /* The newly added node can be a new parent for the next
1374 parent = ice_sched_find_node_by_teid(tc_node,
1377 parent = parent->children[0];
1383 parent->vsi_handle = vsi_handle;
1390 * ice_sched_add_vsi_to_topo - add a new VSI into tree
1391 * @pi: port information structure
1392 * @vsi_handle: software VSI handle
1395 * This function adds a new VSI into scheduler tree
1397 static enum ice_status
1398 ice_sched_add_vsi_to_topo(struct ice_port_info *pi, u16 vsi_handle, u8 tc)
1400 u16 num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 };
1401 struct ice_sched_node *tc_node;
1402 struct ice_hw *hw = pi->hw;
1404 tc_node = ice_sched_get_tc_node(pi, tc);
1406 return ICE_ERR_PARAM;
1408 /* calculate number of supported nodes needed for this VSI */
1409 ice_sched_calc_vsi_support_nodes(hw, tc_node, num_nodes);
1411 /* add VSI supported nodes to TC subtree */
1412 return ice_sched_add_vsi_support_nodes(pi, vsi_handle, tc_node,
1417 * ice_sched_update_vsi_child_nodes - update VSI child nodes
1418 * @pi: port information structure
1419 * @vsi_handle: software VSI handle
1421 * @new_numqs: new number of max queues
1422 * @owner: owner of this subtree
1424 * This function updates the VSI child nodes based on the number of queues
1426 static enum ice_status
1427 ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
1428 u8 tc, u16 new_numqs, u8 owner)
1430 u16 new_num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 };
1431 struct ice_sched_node *vsi_node;
1432 struct ice_sched_node *tc_node;
1433 struct ice_vsi_ctx *vsi_ctx;
1434 enum ice_status status = 0;
1435 struct ice_hw *hw = pi->hw;
1438 tc_node = ice_sched_get_tc_node(pi, tc);
1442 vsi_node = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
1446 vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
1448 return ICE_ERR_PARAM;
1450 prev_numqs = vsi_ctx->sched.max_lanq[tc];
1451 /* num queues are not changed or less than the previous number */
1452 if (new_numqs <= prev_numqs)
1454 status = ice_alloc_lan_q_ctx(hw, vsi_handle, tc, new_numqs);
1459 ice_sched_calc_vsi_child_nodes(hw, new_numqs, new_num_nodes);
1460 /* Keep the max number of queue configuration all the time. Update the
1461 * tree only if number of queues > previous number of queues. This may
1462 * leave some extra nodes in the tree if number of queues < previous
1463 * number but that wouldn't harm anything. Removing those extra nodes
1464 * may complicate the code if those nodes are part of SRL or
1465 * individually rate limited.
1467 status = ice_sched_add_vsi_child_nodes(pi, vsi_handle, tc_node,
1468 new_num_nodes, owner);
1471 vsi_ctx->sched.max_lanq[tc] = new_numqs;
1477 * ice_sched_cfg_vsi - configure the new/existing VSI
1478 * @pi: port information structure
1479 * @vsi_handle: software VSI handle
1481 * @maxqs: max number of queues
1482 * @owner: LAN or RDMA
1483 * @enable: TC enabled or disabled
1485 * This function adds/updates VSI nodes based on the number of queues. If TC is
1486 * enabled and VSI is in suspended state then resume the VSI back. If TC is
1487 * disabled then suspend the VSI if it is not already.
1490 ice_sched_cfg_vsi(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 maxqs,
1491 u8 owner, bool enable)
1493 struct ice_sched_node *vsi_node, *tc_node;
1494 struct ice_vsi_ctx *vsi_ctx;
1495 enum ice_status status = 0;
1496 struct ice_hw *hw = pi->hw;
1498 ice_debug(pi->hw, ICE_DBG_SCHED, "add/config VSI %d\n", vsi_handle);
1499 tc_node = ice_sched_get_tc_node(pi, tc);
1501 return ICE_ERR_PARAM;
1502 vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
1504 return ICE_ERR_PARAM;
1505 vsi_node = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
1507 /* suspend the VSI if TC is not enabled */
1509 if (vsi_node && vsi_node->in_use) {
1510 u32 teid = le32_to_cpu(vsi_node->info.node_teid);
1512 status = ice_sched_suspend_resume_elems(hw, 1, &teid,
1515 vsi_node->in_use = false;
1520 /* TC is enabled, if it is a new VSI then add it to the tree */
1522 status = ice_sched_add_vsi_to_topo(pi, vsi_handle, tc);
1526 vsi_node = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
1530 vsi_ctx->sched.vsi_node[tc] = vsi_node;
1531 vsi_node->in_use = true;
1532 /* invalidate the max queues whenever VSI gets added first time
1533 * into the scheduler tree (boot or after reset). We need to
1534 * recreate the child nodes all the time in these cases.
1536 vsi_ctx->sched.max_lanq[tc] = 0;
1539 /* update the VSI child nodes */
1540 status = ice_sched_update_vsi_child_nodes(pi, vsi_handle, tc, maxqs,
1545 /* TC is enabled, resume the VSI if it is in the suspend state */
1546 if (!vsi_node->in_use) {
1547 u32 teid = le32_to_cpu(vsi_node->info.node_teid);
1549 status = ice_sched_suspend_resume_elems(hw, 1, &teid, false);
1551 vsi_node->in_use = true;
1558 * ice_sched_rm_agg_vsi_entry - remove aggregator related VSI info entry
1559 * @pi: port information structure
1560 * @vsi_handle: software VSI handle
1562 * This function removes single aggregator VSI info entry from
1566 ice_sched_rm_agg_vsi_info(struct ice_port_info *pi, u16 vsi_handle)
1568 struct ice_sched_agg_info *agg_info;
1569 struct ice_sched_agg_info *atmp;
1571 list_for_each_entry_safe(agg_info, atmp, &pi->hw->agg_list,
1573 struct ice_sched_agg_vsi_info *agg_vsi_info;
1574 struct ice_sched_agg_vsi_info *vtmp;
1576 list_for_each_entry_safe(agg_vsi_info, vtmp,
1577 &agg_info->agg_vsi_list, list_entry)
1578 if (agg_vsi_info->vsi_handle == vsi_handle) {
1579 list_del(&agg_vsi_info->list_entry);
1580 devm_kfree(ice_hw_to_dev(pi->hw),
1588 * ice_sched_is_leaf_node_present - check for a leaf node in the sub-tree
1589 * @node: pointer to the sub-tree node
1591 * This function checks for a leaf node presence in a given sub-tree node.
1593 static bool ice_sched_is_leaf_node_present(struct ice_sched_node *node)
1597 for (i = 0; i < node->num_children; i++)
1598 if (ice_sched_is_leaf_node_present(node->children[i]))
1600 /* check for a leaf node */
1601 return (node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF);
1605 * ice_sched_rm_vsi_cfg - remove the VSI and its children nodes
1606 * @pi: port information structure
1607 * @vsi_handle: software VSI handle
1608 * @owner: LAN or RDMA
1610 * This function removes the VSI and its LAN or RDMA children nodes from the
1613 static enum ice_status
1614 ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner)
1616 enum ice_status status = ICE_ERR_PARAM;
1617 struct ice_vsi_ctx *vsi_ctx;
1620 ice_debug(pi->hw, ICE_DBG_SCHED, "removing VSI %d\n", vsi_handle);
1621 if (!ice_is_vsi_valid(pi->hw, vsi_handle))
1623 mutex_lock(&pi->sched_lock);
1624 vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
1626 goto exit_sched_rm_vsi_cfg;
1628 ice_for_each_traffic_class(i) {
1629 struct ice_sched_node *vsi_node, *tc_node;
1632 tc_node = ice_sched_get_tc_node(pi, i);
1636 vsi_node = ice_sched_get_vsi_node(pi->hw, tc_node, vsi_handle);
1640 if (ice_sched_is_leaf_node_present(vsi_node)) {
1641 ice_debug(pi->hw, ICE_DBG_SCHED,
1642 "VSI has leaf nodes in TC %d\n", i);
1643 status = ICE_ERR_IN_USE;
1644 goto exit_sched_rm_vsi_cfg;
1646 while (j < vsi_node->num_children) {
1647 if (vsi_node->children[j]->owner == owner) {
1648 ice_free_sched_node(pi, vsi_node->children[j]);
1650 /* reset the counter again since the num
1651 * children will be updated after node removal
1658 /* remove the VSI if it has no children */
1659 if (!vsi_node->num_children) {
1660 ice_free_sched_node(pi, vsi_node);
1661 vsi_ctx->sched.vsi_node[i] = NULL;
1663 /* clean up aggregator related VSI info if any */
1664 ice_sched_rm_agg_vsi_info(pi, vsi_handle);
1666 if (owner == ICE_SCHED_NODE_OWNER_LAN)
1667 vsi_ctx->sched.max_lanq[i] = 0;
1671 exit_sched_rm_vsi_cfg:
1672 mutex_unlock(&pi->sched_lock);
1677 * ice_rm_vsi_lan_cfg - remove VSI and its LAN children nodes
1678 * @pi: port information structure
1679 * @vsi_handle: software VSI handle
1681 * This function clears the VSI and its LAN children nodes from scheduler tree
1684 enum ice_status ice_rm_vsi_lan_cfg(struct ice_port_info *pi, u16 vsi_handle)
1686 return ice_sched_rm_vsi_cfg(pi, vsi_handle, ICE_SCHED_NODE_OWNER_LAN);