xref: /freebsd/sys/dev/ice/ice_sched.c (revision f2635e844dd138ac9dfba676f27d41750049af26)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*  Copyright (c) 2024, Intel Corporation
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above copyright notice,
9  *      this list of conditions and the following disclaimer.
10  *
11  *   2. Redistributions in binary form must reproduce the above copyright
12  *      notice, this list of conditions and the following disclaimer in the
13  *      documentation and/or other materials provided with the distribution.
14  *
15  *   3. Neither the name of the Intel Corporation nor the names of its
16  *      contributors may be used to endorse or promote products derived from
17  *      this software without specific prior written permission.
18  *
19  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  *  POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "ice_sched.h"
33 
34 /**
35  * ice_sched_add_root_node - Insert the Tx scheduler root node in SW DB
36  * @pi: port information structure
37  * @info: Scheduler element information from firmware
38  *
39  * This function inserts the root node of the scheduling tree topology
40  * to the SW DB.
41  */
42 static int
43 ice_sched_add_root_node(struct ice_port_info *pi,
44 			struct ice_aqc_txsched_elem_data *info)
45 {
46 	struct ice_sched_node *root;
47 	struct ice_hw *hw;
48 
49 	if (!pi)
50 		return ICE_ERR_PARAM;
51 
52 	hw = pi->hw;
53 
54 	root = (struct ice_sched_node *)ice_malloc(hw, sizeof(*root));
55 	if (!root)
56 		return ICE_ERR_NO_MEMORY;
57 
58 	root->children = (struct ice_sched_node **)
59 		ice_calloc(hw, hw->max_children[0], sizeof(*root->children));
60 	if (!root->children) {
61 		ice_free(hw, root);
62 		return ICE_ERR_NO_MEMORY;
63 	}
64 
65 	ice_memcpy(&root->info, info, sizeof(*info), ICE_NONDMA_TO_NONDMA);
66 	pi->root = root;
67 	return 0;
68 }
69 
70 /**
71  * ice_sched_find_node_by_teid - Find the Tx scheduler node in SW DB
72  * @start_node: pointer to the starting ice_sched_node struct in a sub-tree
73  * @teid: node TEID to search
74  *
75  * This function searches for a node matching the TEID in the scheduling tree
76  * from the SW DB. The search is recursive and is restricted by the number of
77  * layers it has searched through; stopping at the max supported layer.
78  *
79  * This function needs to be called when holding the port_info->sched_lock
80  */
81 struct ice_sched_node *
82 ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid)
83 {
84 	u16 i;
85 
86 	if (!start_node)
87 		return NULL;
88 
89 	/* The TEID is same as that of the start_node */
90 	if (ICE_TXSCHED_GET_NODE_TEID(start_node) == teid)
91 		return start_node;
92 
93 	/* The node has no children or is at the max layer */
94 	if (!start_node->num_children ||
95 	    start_node->tx_sched_layer >= ICE_AQC_TOPO_MAX_LEVEL_NUM ||
96 	    start_node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF)
97 		return NULL;
98 
99 	/* Check if TEID matches to any of the children nodes */
100 	for (i = 0; i < start_node->num_children; i++)
101 		if (ICE_TXSCHED_GET_NODE_TEID(start_node->children[i]) == teid)
102 			return start_node->children[i];
103 
104 	/* Search within each child's sub-tree */
105 	for (i = 0; i < start_node->num_children; i++) {
106 		struct ice_sched_node *tmp;
107 
108 		tmp = ice_sched_find_node_by_teid(start_node->children[i],
109 						  teid);
110 		if (tmp)
111 			return tmp;
112 	}
113 
114 	return NULL;
115 }
116 
117 /**
118  * ice_aqc_send_sched_elem_cmd - send scheduling elements cmd
119  * @hw: pointer to the HW struct
120  * @cmd_opc: cmd opcode
121  * @elems_req: number of elements to request
122  * @buf: pointer to buffer
123  * @buf_size: buffer size in bytes
124  * @elems_resp: returns total number of elements response
125  * @cd: pointer to command details structure or NULL
126  *
127  * This function sends a scheduling elements cmd (cmd_opc)
128  */
129 static int
130 ice_aqc_send_sched_elem_cmd(struct ice_hw *hw, enum ice_adminq_opc cmd_opc,
131 			    u16 elems_req, void *buf, u16 buf_size,
132 			    u16 *elems_resp, struct ice_sq_cd *cd)
133 {
134 	struct ice_aqc_sched_elem_cmd *cmd;
135 	struct ice_aq_desc desc;
136 	int status;
137 
138 	cmd = &desc.params.sched_elem_cmd;
139 	ice_fill_dflt_direct_cmd_desc(&desc, cmd_opc);
140 	cmd->num_elem_req = CPU_TO_LE16(elems_req);
141 	desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
142 	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
143 	if (!status && elems_resp)
144 		*elems_resp = LE16_TO_CPU(cmd->num_elem_resp);
145 
146 	return status;
147 }
148 
149 /**
150  * ice_aq_query_sched_elems - query scheduler elements
151  * @hw: pointer to the HW struct
152  * @elems_req: number of elements to query
153  * @buf: pointer to buffer
154  * @buf_size: buffer size in bytes
155  * @elems_ret: returns total number of elements returned
156  * @cd: pointer to command details structure or NULL
157  *
158  * Query scheduling elements (0x0404)
159  */
160 int
161 ice_aq_query_sched_elems(struct ice_hw *hw, u16 elems_req,
162 			 struct ice_aqc_txsched_elem_data *buf, u16 buf_size,
163 			 u16 *elems_ret, struct ice_sq_cd *cd)
164 {
165 	return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_get_sched_elems,
166 					   elems_req, (void *)buf, buf_size,
167 					   elems_ret, cd);
168 }
169 
170 /**
171  * ice_sched_add_node - Insert the Tx scheduler node in SW DB
172  * @pi: port information structure
173  * @layer: Scheduler layer of the node
174  * @info: Scheduler element information from firmware
175  * @prealloc_node: preallocated ice_sched_node struct for SW DB
176  *
177  * This function inserts a scheduler node to the SW DB.
178  */
179 int
180 ice_sched_add_node(struct ice_port_info *pi, u8 layer,
181 		   struct ice_aqc_txsched_elem_data *info,
182 		   struct ice_sched_node *prealloc_node)
183 {
184 	struct ice_aqc_txsched_elem_data elem;
185 	struct ice_sched_node *parent;
186 	struct ice_sched_node *node;
187 	struct ice_hw *hw;
188 	int status;
189 
190 	if (!pi)
191 		return ICE_ERR_PARAM;
192 
193 	hw = pi->hw;
194 
195 	/* A valid parent node should be there */
196 	parent = ice_sched_find_node_by_teid(pi->root,
197 					     LE32_TO_CPU(info->parent_teid));
198 	if (!parent) {
199 		ice_debug(hw, ICE_DBG_SCHED, "Parent Node not found for parent_teid=0x%x\n",
200 			  LE32_TO_CPU(info->parent_teid));
201 		return ICE_ERR_PARAM;
202 	}
203 
204 	/* query the current node information from FW before adding it
205 	 * to the SW DB
206 	 */
207 	status = ice_sched_query_elem(hw, LE32_TO_CPU(info->node_teid), &elem);
208 	if (status)
209 		return status;
210 
211 	if (prealloc_node)
212 		node = prealloc_node;
213 	else
214 		node = (struct ice_sched_node *)ice_malloc(hw, sizeof(*node));
215 	if (!node)
216 		return ICE_ERR_NO_MEMORY;
217 	if (hw->max_children[layer]) {
218 		node->children = (struct ice_sched_node **)
219 			ice_calloc(hw, hw->max_children[layer],
220 				   sizeof(*node->children));
221 		if (!node->children) {
222 			ice_free(hw, node);
223 			return ICE_ERR_NO_MEMORY;
224 		}
225 	}
226 
227 	node->in_use = true;
228 	node->parent = parent;
229 	node->tx_sched_layer = layer;
230 	parent->children[parent->num_children++] = node;
231 	node->info = elem;
232 	return 0;
233 }
234 
235 /**
236  * ice_aq_delete_sched_elems - delete scheduler elements
237  * @hw: pointer to the HW struct
238  * @grps_req: number of groups to delete
239  * @buf: pointer to buffer
240  * @buf_size: buffer size in bytes
241  * @grps_del: returns total number of elements deleted
242  * @cd: pointer to command details structure or NULL
243  *
244  * Delete scheduling elements (0x040F)
245  */
246 static int
247 ice_aq_delete_sched_elems(struct ice_hw *hw, u16 grps_req,
248 			  struct ice_aqc_delete_elem *buf, u16 buf_size,
249 			  u16 *grps_del, struct ice_sq_cd *cd)
250 {
251 	return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_delete_sched_elems,
252 					   grps_req, (void *)buf, buf_size,
253 					   grps_del, cd);
254 }
255 
256 /**
257  * ice_sched_remove_elems - remove nodes from HW
258  * @hw: pointer to the HW struct
259  * @parent: pointer to the parent node
260  * @num_nodes: number of nodes
261  * @node_teids: array of node teids to be deleted
262  *
263  * This function remove nodes from HW
264  */
265 static int
266 ice_sched_remove_elems(struct ice_hw *hw, struct ice_sched_node *parent,
267 		       u16 num_nodes, u32 *node_teids)
268 {
269 	struct ice_aqc_delete_elem *buf;
270 	u16 i, num_groups_removed = 0;
271 	u16 buf_size;
272 	int status;
273 
274 	buf_size = ice_struct_size(buf, teid, num_nodes);
275 	buf = (struct ice_aqc_delete_elem *)ice_malloc(hw, buf_size);
276 	if (!buf)
277 		return ICE_ERR_NO_MEMORY;
278 
279 	buf->hdr.parent_teid = parent->info.node_teid;
280 	buf->hdr.num_elems = CPU_TO_LE16(num_nodes);
281 	for (i = 0; i < num_nodes; i++)
282 		buf->teid[i] = CPU_TO_LE32(node_teids[i]);
283 
284 	status = ice_aq_delete_sched_elems(hw, 1, buf, buf_size,
285 					   &num_groups_removed, NULL);
286 	if (status || num_groups_removed != 1)
287 		ice_debug(hw, ICE_DBG_SCHED, "remove node failed FW error %d\n",
288 			  hw->adminq.sq_last_status);
289 
290 	ice_free(hw, buf);
291 	return status;
292 }
293 
294 /**
295  * ice_sched_get_first_node - get the first node of the given layer
296  * @pi: port information structure
297  * @parent: pointer the base node of the subtree
298  * @layer: layer number
299  *
300  * This function retrieves the first node of the given layer from the subtree
301  */
302 static struct ice_sched_node *
303 ice_sched_get_first_node(struct ice_port_info *pi,
304 			 struct ice_sched_node *parent, u8 layer)
305 {
306 	return pi->sib_head[parent->tc_num][layer];
307 }
308 
309 /**
310  * ice_sched_get_tc_node - get pointer to TC node
311  * @pi: port information structure
312  * @tc: TC number
313  *
314  * This function returns the TC node pointer
315  */
316 struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc)
317 {
318 	u8 i;
319 
320 	if (!pi || !pi->root)
321 		return NULL;
322 	for (i = 0; i < pi->root->num_children; i++)
323 		if (pi->root->children[i]->tc_num == tc)
324 			return pi->root->children[i];
325 	return NULL;
326 }
327 
328 /**
329  * ice_free_sched_node - Free a Tx scheduler node from SW DB
330  * @pi: port information structure
331  * @node: pointer to the ice_sched_node struct
332  *
333  * This function frees up a node from SW DB as well as from HW
334  *
335  * This function needs to be called with the port_info->sched_lock held
336  */
337 void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
338 {
339 	struct ice_sched_node *parent;
340 	struct ice_hw *hw = pi->hw;
341 	u8 i, j;
342 
343 	/* Free the children before freeing up the parent node
344 	 * The parent array is updated below and that shifts the nodes
345 	 * in the array. So always pick the first child if num children > 0
346 	 */
347 	while (node->num_children)
348 		ice_free_sched_node(pi, node->children[0]);
349 
350 	/* Leaf, TC and root nodes can't be deleted by SW */
351 	if (node->tx_sched_layer >= hw->sw_entry_point_layer &&
352 	    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC &&
353 	    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT &&
354 	    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_LEAF) {
355 		u32 teid = LE32_TO_CPU(node->info.node_teid);
356 
357 		ice_sched_remove_elems(hw, node->parent, 1, &teid);
358 	}
359 	parent = node->parent;
360 	/* root has no parent */
361 	if (parent) {
362 		struct ice_sched_node *p;
363 
364 		/* update the parent */
365 		for (i = 0; i < parent->num_children; i++)
366 			if (parent->children[i] == node) {
367 				for (j = i + 1; j < parent->num_children; j++)
368 					parent->children[j - 1] =
369 						parent->children[j];
370 				parent->num_children--;
371 				break;
372 			}
373 
374 		p = ice_sched_get_first_node(pi, node, node->tx_sched_layer);
375 		while (p) {
376 			if (p->sibling == node) {
377 				p->sibling = node->sibling;
378 				break;
379 			}
380 			p = p->sibling;
381 		}
382 
383 		/* update the sibling head if head is getting removed */
384 		if (pi->sib_head[node->tc_num][node->tx_sched_layer] == node)
385 			pi->sib_head[node->tc_num][node->tx_sched_layer] =
386 				node->sibling;
387 	}
388 
389 	/* leaf nodes have no children */
390 	if (node->children)
391 		ice_free(hw, node->children);
392 	ice_free(hw, node);
393 }
394 
395 /**
396  * ice_aq_get_dflt_topo - gets default scheduler topology
397  * @hw: pointer to the HW struct
398  * @lport: logical port number
399  * @buf: pointer to buffer
400  * @buf_size: buffer size in bytes
401  * @num_branches: returns total number of queue to port branches
402  * @cd: pointer to command details structure or NULL
403  *
404  * Get default scheduler topology (0x400)
405  */
406 static int
407 ice_aq_get_dflt_topo(struct ice_hw *hw, u8 lport,
408 		     struct ice_aqc_get_topo_elem *buf, u16 buf_size,
409 		     u8 *num_branches, struct ice_sq_cd *cd)
410 {
411 	struct ice_aqc_get_topo *cmd;
412 	struct ice_aq_desc desc;
413 	int status;
414 
415 	cmd = &desc.params.get_topo;
416 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_dflt_topo);
417 	cmd->port_num = lport;
418 	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
419 	if (!status && num_branches)
420 		*num_branches = cmd->num_branches;
421 
422 	return status;
423 }
424 
425 /**
426  * ice_aq_add_sched_elems - adds scheduling element
427  * @hw: pointer to the HW struct
428  * @grps_req: the number of groups that are requested to be added
429  * @buf: pointer to buffer
430  * @buf_size: buffer size in bytes
431  * @grps_added: returns total number of groups added
432  * @cd: pointer to command details structure or NULL
433  *
434  * Add scheduling elements (0x0401)
435  */
436 static int
437 ice_aq_add_sched_elems(struct ice_hw *hw, u16 grps_req,
438 		       struct ice_aqc_add_elem *buf, u16 buf_size,
439 		       u16 *grps_added, struct ice_sq_cd *cd)
440 {
441 	return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_add_sched_elems,
442 					   grps_req, (void *)buf, buf_size,
443 					   grps_added, cd);
444 }
445 
446 /**
447  * ice_aq_cfg_sched_elems - configures scheduler elements
448  * @hw: pointer to the HW struct
449  * @elems_req: number of elements to configure
450  * @buf: pointer to buffer
451  * @buf_size: buffer size in bytes
452  * @elems_cfgd: returns total number of elements configured
453  * @cd: pointer to command details structure or NULL
454  *
455  * Configure scheduling elements (0x0403)
456  */
457 static int
458 ice_aq_cfg_sched_elems(struct ice_hw *hw, u16 elems_req,
459 		       struct ice_aqc_txsched_elem_data *buf, u16 buf_size,
460 		       u16 *elems_cfgd, struct ice_sq_cd *cd)
461 {
462 	return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_cfg_sched_elems,
463 					   elems_req, (void *)buf, buf_size,
464 					   elems_cfgd, cd);
465 }
466 
467 /**
468  * ice_aq_move_sched_elems - move scheduler elements
469  * @hw: pointer to the HW struct
470  * @grps_req: number of groups to move
471  * @buf: pointer to buffer
472  * @buf_size: buffer size in bytes
473  * @grps_movd: returns total number of groups moved
474  * @cd: pointer to command details structure or NULL
475  *
476  * Move scheduling elements (0x0408)
477  */
478 int
479 ice_aq_move_sched_elems(struct ice_hw *hw, u16 grps_req,
480 			struct ice_aqc_move_elem *buf, u16 buf_size,
481 			u16 *grps_movd, struct ice_sq_cd *cd)
482 {
483 	return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_move_sched_elems,
484 					   grps_req, (void *)buf, buf_size,
485 					   grps_movd, cd);
486 }
487 
488 /**
489  * ice_aq_suspend_sched_elems - suspend scheduler elements
490  * @hw: pointer to the HW struct
491  * @elems_req: number of elements to suspend
492  * @buf: pointer to buffer
493  * @buf_size: buffer size in bytes
494  * @elems_ret: returns total number of elements suspended
495  * @cd: pointer to command details structure or NULL
496  *
497  * Suspend scheduling elements (0x0409)
498  */
499 static int
500 ice_aq_suspend_sched_elems(struct ice_hw *hw, u16 elems_req, __le32 *buf,
501 			   u16 buf_size, u16 *elems_ret, struct ice_sq_cd *cd)
502 {
503 	return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_suspend_sched_elems,
504 					   elems_req, (void *)buf, buf_size,
505 					   elems_ret, cd);
506 }
507 
508 /**
509  * ice_aq_resume_sched_elems - resume scheduler elements
510  * @hw: pointer to the HW struct
511  * @elems_req: number of elements to resume
512  * @buf: pointer to buffer
513  * @buf_size: buffer size in bytes
514  * @elems_ret: returns total number of elements resumed
515  * @cd: pointer to command details structure or NULL
516  *
517  * resume scheduling elements (0x040A)
518  */
519 static int
520 ice_aq_resume_sched_elems(struct ice_hw *hw, u16 elems_req, __le32 *buf,
521 			  u16 buf_size, u16 *elems_ret, struct ice_sq_cd *cd)
522 {
523 	return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_resume_sched_elems,
524 					   elems_req, (void *)buf, buf_size,
525 					   elems_ret, cd);
526 }
527 
528 /**
529  * ice_aq_query_sched_res - query scheduler resource
530  * @hw: pointer to the HW struct
531  * @buf_size: buffer size in bytes
532  * @buf: pointer to buffer
533  * @cd: pointer to command details structure or NULL
534  *
535  * Query scheduler resource allocation (0x0412)
536  */
537 static int
538 ice_aq_query_sched_res(struct ice_hw *hw, u16 buf_size,
539 		       struct ice_aqc_query_txsched_res_resp *buf,
540 		       struct ice_sq_cd *cd)
541 {
542 	struct ice_aq_desc desc;
543 
544 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_query_sched_res);
545 	return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
546 }
547 
548 /**
549  * ice_sched_suspend_resume_elems - suspend or resume HW nodes
550  * @hw: pointer to the HW struct
551  * @num_nodes: number of nodes
552  * @node_teids: array of node teids to be suspended or resumed
553  * @suspend: true means suspend / false means resume
554  *
555  * This function suspends or resumes HW nodes
556  */
557 static int
558 ice_sched_suspend_resume_elems(struct ice_hw *hw, u8 num_nodes, u32 *node_teids,
559 			       bool suspend)
560 {
561 	u16 i, buf_size, num_elem_ret = 0;
562 	__le32 *buf;
563 	int status;
564 
565 	buf_size = sizeof(*buf) * num_nodes;
566 	buf = (__le32 *)ice_malloc(hw, buf_size);
567 	if (!buf)
568 		return ICE_ERR_NO_MEMORY;
569 
570 	for (i = 0; i < num_nodes; i++)
571 		buf[i] = CPU_TO_LE32(node_teids[i]);
572 
573 	if (suspend)
574 		status = ice_aq_suspend_sched_elems(hw, num_nodes, buf,
575 						    buf_size, &num_elem_ret,
576 						    NULL);
577 	else
578 		status = ice_aq_resume_sched_elems(hw, num_nodes, buf,
579 						   buf_size, &num_elem_ret,
580 						   NULL);
581 	if (status || num_elem_ret != num_nodes)
582 		ice_debug(hw, ICE_DBG_SCHED, "suspend/resume failed\n");
583 
584 	ice_free(hw, buf);
585 	return status;
586 }
587 
588 /**
589  * ice_alloc_lan_q_ctx - allocate LAN queue contexts for the given VSI and TC
590  * @hw: pointer to the HW struct
591  * @vsi_handle: VSI handle
592  * @tc: TC number
593  * @new_numqs: number of queues
594  */
595 static int
596 ice_alloc_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 new_numqs)
597 {
598 	struct ice_vsi_ctx *vsi_ctx;
599 	struct ice_q_ctx *q_ctx;
600 
601 	vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
602 	if (!vsi_ctx)
603 		return ICE_ERR_PARAM;
604 	/* allocate LAN queue contexts */
605 	if (!vsi_ctx->lan_q_ctx[tc]) {
606 		vsi_ctx->lan_q_ctx[tc] = (struct ice_q_ctx *)
607 			ice_calloc(hw, new_numqs, sizeof(*q_ctx));
608 		if (!vsi_ctx->lan_q_ctx[tc])
609 			return ICE_ERR_NO_MEMORY;
610 		vsi_ctx->num_lan_q_entries[tc] = new_numqs;
611 		return 0;
612 	}
613 	/* num queues are increased, update the queue contexts */
614 	if (new_numqs > vsi_ctx->num_lan_q_entries[tc]) {
615 		u16 prev_num = vsi_ctx->num_lan_q_entries[tc];
616 
617 		q_ctx = (struct ice_q_ctx *)
618 			ice_calloc(hw, new_numqs, sizeof(*q_ctx));
619 		if (!q_ctx)
620 			return ICE_ERR_NO_MEMORY;
621 		ice_memcpy(q_ctx, vsi_ctx->lan_q_ctx[tc],
622 			   prev_num * sizeof(*q_ctx), ICE_DMA_TO_NONDMA);
623 		ice_free(hw, vsi_ctx->lan_q_ctx[tc]);
624 		vsi_ctx->lan_q_ctx[tc] = q_ctx;
625 		vsi_ctx->num_lan_q_entries[tc] = new_numqs;
626 	}
627 	return 0;
628 }
629 
630 /**
631  * ice_alloc_rdma_q_ctx - allocate RDMA queue contexts for the given VSI and TC
632  * @hw: pointer to the HW struct
633  * @vsi_handle: VSI handle
634  * @tc: TC number
635  * @new_numqs: number of queues
636  */
637 static int
638 ice_alloc_rdma_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 new_numqs)
639 {
640 	struct ice_vsi_ctx *vsi_ctx;
641 	struct ice_q_ctx *q_ctx;
642 
643 	vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
644 	if (!vsi_ctx)
645 		return ICE_ERR_PARAM;
646 	/* allocate RDMA queue contexts */
647 	if (!vsi_ctx->rdma_q_ctx[tc]) {
648 		vsi_ctx->rdma_q_ctx[tc] = (struct ice_q_ctx *)
649 			ice_calloc(hw, new_numqs, sizeof(*q_ctx));
650 		if (!vsi_ctx->rdma_q_ctx[tc])
651 			return ICE_ERR_NO_MEMORY;
652 		vsi_ctx->num_rdma_q_entries[tc] = new_numqs;
653 		return 0;
654 	}
655 	/* num queues are increased, update the queue contexts */
656 	if (new_numqs > vsi_ctx->num_rdma_q_entries[tc]) {
657 		u16 prev_num = vsi_ctx->num_rdma_q_entries[tc];
658 
659 		q_ctx = (struct ice_q_ctx *)
660 			ice_calloc(hw, new_numqs, sizeof(*q_ctx));
661 		if (!q_ctx)
662 			return ICE_ERR_NO_MEMORY;
663 		ice_memcpy(q_ctx, vsi_ctx->rdma_q_ctx[tc],
664 			   prev_num * sizeof(*q_ctx), ICE_DMA_TO_NONDMA);
665 		ice_free(hw, vsi_ctx->rdma_q_ctx[tc]);
666 		vsi_ctx->rdma_q_ctx[tc] = q_ctx;
667 		vsi_ctx->num_rdma_q_entries[tc] = new_numqs;
668 	}
669 	return 0;
670 }
671 
672 /**
673  * ice_aq_rl_profile - performs a rate limiting task
674  * @hw: pointer to the HW struct
675  * @opcode: opcode for add, query, or remove profile(s)
676  * @num_profiles: the number of profiles
677  * @buf: pointer to buffer
678  * @buf_size: buffer size in bytes
679  * @num_processed: number of processed add or remove profile(s) to return
680  * @cd: pointer to command details structure
681  *
682  * RL profile function to add, query, or remove profile(s)
683  */
684 static int
685 ice_aq_rl_profile(struct ice_hw *hw, enum ice_adminq_opc opcode,
686 		  u16 num_profiles, struct ice_aqc_rl_profile_elem *buf,
687 		  u16 buf_size, u16 *num_processed, struct ice_sq_cd *cd)
688 {
689 	struct ice_aqc_rl_profile *cmd;
690 	struct ice_aq_desc desc;
691 	int status;
692 
693 	cmd = &desc.params.rl_profile;
694 
695 	ice_fill_dflt_direct_cmd_desc(&desc, opcode);
696 	desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
697 	cmd->num_profiles = CPU_TO_LE16(num_profiles);
698 	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
699 	if (!status && num_processed)
700 		*num_processed = LE16_TO_CPU(cmd->num_processed);
701 	return status;
702 }
703 
704 /**
705  * ice_aq_add_rl_profile - adds rate limiting profile(s)
706  * @hw: pointer to the HW struct
707  * @num_profiles: the number of profile(s) to be add
708  * @buf: pointer to buffer
709  * @buf_size: buffer size in bytes
710  * @num_profiles_added: total number of profiles added to return
711  * @cd: pointer to command details structure
712  *
713  * Add RL profile (0x0410)
714  */
715 static int
716 ice_aq_add_rl_profile(struct ice_hw *hw, u16 num_profiles,
717 		      struct ice_aqc_rl_profile_elem *buf, u16 buf_size,
718 		      u16 *num_profiles_added, struct ice_sq_cd *cd)
719 {
720 	return ice_aq_rl_profile(hw, ice_aqc_opc_add_rl_profiles, num_profiles,
721 				 buf, buf_size, num_profiles_added, cd);
722 }
723 
724 /**
725  * ice_aq_query_rl_profile - query rate limiting profile(s)
726  * @hw: pointer to the HW struct
727  * @num_profiles: the number of profile(s) to query
728  * @buf: pointer to buffer
729  * @buf_size: buffer size in bytes
730  * @cd: pointer to command details structure
731  *
732  * Query RL profile (0x0411)
733  */
734 int
735 ice_aq_query_rl_profile(struct ice_hw *hw, u16 num_profiles,
736 			struct ice_aqc_rl_profile_elem *buf, u16 buf_size,
737 			struct ice_sq_cd *cd)
738 {
739 	return ice_aq_rl_profile(hw, ice_aqc_opc_query_rl_profiles,
740 				 num_profiles, buf, buf_size, NULL, cd);
741 }
742 
743 /**
744  * ice_aq_remove_rl_profile - removes RL profile(s)
745  * @hw: pointer to the HW struct
746  * @num_profiles: the number of profile(s) to remove
747  * @buf: pointer to buffer
748  * @buf_size: buffer size in bytes
749  * @num_profiles_removed: total number of profiles removed to return
750  * @cd: pointer to command details structure or NULL
751  *
752  * Remove RL profile (0x0415)
753  */
754 static int
755 ice_aq_remove_rl_profile(struct ice_hw *hw, u16 num_profiles,
756 			 struct ice_aqc_rl_profile_elem *buf, u16 buf_size,
757 			 u16 *num_profiles_removed, struct ice_sq_cd *cd)
758 {
759 	return ice_aq_rl_profile(hw, ice_aqc_opc_remove_rl_profiles,
760 				 num_profiles, buf, buf_size,
761 				 num_profiles_removed, cd);
762 }
763 
764 /**
765  * ice_sched_del_rl_profile - remove RL profile
766  * @hw: pointer to the HW struct
767  * @rl_info: rate limit profile information
768  *
769  * If the profile ID is not referenced anymore, it removes profile ID with
770  * its associated parameters from HW DB,and locally. The caller needs to
771  * hold scheduler lock.
772  */
773 static int
774 ice_sched_del_rl_profile(struct ice_hw *hw,
775 			 struct ice_aqc_rl_profile_info *rl_info)
776 {
777 	struct ice_aqc_rl_profile_elem *buf;
778 	u16 num_profiles_removed;
779 	u16 num_profiles = 1;
780 	int status;
781 
782 	if (rl_info->prof_id_ref != 0)
783 		return ICE_ERR_IN_USE;
784 
785 	/* Safe to remove profile ID */
786 	buf = &rl_info->profile;
787 	status = ice_aq_remove_rl_profile(hw, num_profiles, buf, sizeof(*buf),
788 					  &num_profiles_removed, NULL);
789 	if (status || num_profiles_removed != num_profiles)
790 		return ICE_ERR_CFG;
791 
792 	/* Delete stale entry now */
793 	LIST_DEL(&rl_info->list_entry);
794 	ice_free(hw, rl_info);
795 	return status;
796 }
797 
798 /**
799  * ice_sched_clear_rl_prof - clears RL prof entries
800  * @pi: port information structure
801  *
802  * This function removes all RL profile from HW as well as from SW DB.
803  */
804 static void ice_sched_clear_rl_prof(struct ice_port_info *pi)
805 {
806 	u16 ln;
807 	struct ice_hw *hw = pi->hw;
808 
809 	for (ln = 0; ln < hw->num_tx_sched_layers; ln++) {
810 		struct ice_aqc_rl_profile_info *rl_prof_elem;
811 		struct ice_aqc_rl_profile_info *rl_prof_tmp;
812 
813 		LIST_FOR_EACH_ENTRY_SAFE(rl_prof_elem, rl_prof_tmp,
814 					 &hw->rl_prof_list[ln],
815 					 ice_aqc_rl_profile_info, list_entry) {
816 			int status;
817 
818 			rl_prof_elem->prof_id_ref = 0;
819 			status = ice_sched_del_rl_profile(hw, rl_prof_elem);
820 			if (status) {
821 				ice_debug(hw, ICE_DBG_SCHED, "Remove rl profile failed\n");
822 				/* On error, free mem required */
823 				LIST_DEL(&rl_prof_elem->list_entry);
824 				ice_free(hw, rl_prof_elem);
825 			}
826 		}
827 	}
828 }
829 
830 /**
831  * ice_sched_clear_agg - clears the aggregator related information
832  * @hw: pointer to the hardware structure
833  *
834  * This function removes aggregator list and free up aggregator related memory
835  * previously allocated.
836  */
837 void ice_sched_clear_agg(struct ice_hw *hw)
838 {
839 	struct ice_sched_agg_info *agg_info;
840 	struct ice_sched_agg_info *atmp;
841 
842 	LIST_FOR_EACH_ENTRY_SAFE(agg_info, atmp, &hw->agg_list,
843 				 ice_sched_agg_info,
844 				 list_entry) {
845 		struct ice_sched_agg_vsi_info *agg_vsi_info;
846 		struct ice_sched_agg_vsi_info *vtmp;
847 
848 		LIST_FOR_EACH_ENTRY_SAFE(agg_vsi_info, vtmp,
849 					 &agg_info->agg_vsi_list,
850 					 ice_sched_agg_vsi_info, list_entry) {
851 			LIST_DEL(&agg_vsi_info->list_entry);
852 			ice_free(hw, agg_vsi_info);
853 		}
854 		LIST_DEL(&agg_info->list_entry);
855 		ice_free(hw, agg_info);
856 	}
857 }
858 
859 /**
860  * ice_sched_clear_tx_topo - clears the scheduler tree nodes
861  * @pi: port information structure
862  *
863  * This function removes all the nodes from HW as well as from SW DB.
864  */
865 static void ice_sched_clear_tx_topo(struct ice_port_info *pi)
866 {
867 	if (!pi)
868 		return;
869 	/* remove RL profiles related lists */
870 	ice_sched_clear_rl_prof(pi);
871 	if (pi->root) {
872 		ice_free_sched_node(pi, pi->root);
873 		pi->root = NULL;
874 	}
875 }
876 
877 /**
878  * ice_sched_clear_port - clear the scheduler elements from SW DB for a port
879  * @pi: port information structure
880  *
881  * Cleanup scheduling elements from SW DB
882  */
883 void ice_sched_clear_port(struct ice_port_info *pi)
884 {
885 	if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
886 		return;
887 
888 	pi->port_state = ICE_SCHED_PORT_STATE_INIT;
889 	ice_acquire_lock(&pi->sched_lock);
890 	ice_sched_clear_tx_topo(pi);
891 	ice_release_lock(&pi->sched_lock);
892 	ice_destroy_lock(&pi->sched_lock);
893 }
894 
895 /**
896  * ice_sched_cleanup_all - cleanup scheduler elements from SW DB for all ports
897  * @hw: pointer to the HW struct
898  *
899  * Cleanup scheduling elements from SW DB for all the ports
900  */
901 void ice_sched_cleanup_all(struct ice_hw *hw)
902 {
903 	if (!hw)
904 		return;
905 
906 	if (hw->layer_info) {
907 		ice_free(hw, hw->layer_info);
908 		hw->layer_info = NULL;
909 	}
910 
911 	ice_sched_clear_port(hw->port_info);
912 
913 	hw->num_tx_sched_layers = 0;
914 	hw->num_tx_sched_phys_layers = 0;
915 	hw->flattened_layers = 0;
916 	hw->max_cgds = 0;
917 }
918 
919 /**
920  * ice_aq_cfg_node_attr - configure nodes' per-cone flattening attributes
921  * @hw: pointer to the HW struct
922  * @num_nodes: the number of nodes whose attributes to configure
923  * @buf: pointer to buffer
924  * @buf_size: buffer size in bytes
925  * @cd: pointer to command details structure or NULL
926  *
927  * Configure Node Attributes (0x0417)
928  */
929 int
930 ice_aq_cfg_node_attr(struct ice_hw *hw, u16 num_nodes,
931 		     struct ice_aqc_node_attr_elem *buf, u16 buf_size,
932 		     struct ice_sq_cd *cd)
933 {
934 	struct ice_aqc_node_attr *cmd;
935 	struct ice_aq_desc desc;
936 
937 	cmd = &desc.params.node_attr;
938 	ice_fill_dflt_direct_cmd_desc(&desc,
939 				      ice_aqc_opc_cfg_node_attr);
940 	desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
941 
942 	cmd->num_entries = CPU_TO_LE16(num_nodes);
943 	return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
944 }
945 
946 /**
947  * ice_aq_cfg_l2_node_cgd - configures L2 node to CGD mapping
948  * @hw: pointer to the HW struct
949  * @num_l2_nodes: the number of L2 nodes whose CGDs to configure
950  * @buf: pointer to buffer
951  * @buf_size: buffer size in bytes
952  * @cd: pointer to command details structure or NULL
953  *
954  * Configure L2 Node CGD (0x0414)
955  */
956 int
957 ice_aq_cfg_l2_node_cgd(struct ice_hw *hw, u16 num_l2_nodes,
958 		       struct ice_aqc_cfg_l2_node_cgd_elem *buf,
959 		       u16 buf_size, struct ice_sq_cd *cd)
960 {
961 	struct ice_aqc_cfg_l2_node_cgd *cmd;
962 	struct ice_aq_desc desc;
963 
964 	cmd = &desc.params.cfg_l2_node_cgd;
965 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_cfg_l2_node_cgd);
966 	desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
967 
968 	cmd->num_l2_nodes = CPU_TO_LE16(num_l2_nodes);
969 	return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
970 }
971 
972 /**
973  * ice_sched_add_elems - add nodes to HW and SW DB
974  * @pi: port information structure
975  * @tc_node: pointer to the branch node
976  * @parent: pointer to the parent node
977  * @layer: layer number to add nodes
978  * @num_nodes: number of nodes
979  * @num_nodes_added: pointer to num nodes added
980  * @first_node_teid: if new nodes are added then return the TEID of first node
981  * @prealloc_nodes: preallocated nodes struct for software DB
982  *
983  * This function add nodes to HW as well as to SW DB for a given layer
984  */
985 int
986 ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
987 		    struct ice_sched_node *parent, u8 layer, u16 num_nodes,
988 		    u16 *num_nodes_added, u32 *first_node_teid,
989 		    struct ice_sched_node **prealloc_nodes)
990 {
991 	struct ice_sched_node *prev, *new_node;
992 	struct ice_aqc_add_elem *buf;
993 	u16 i, num_groups_added = 0;
994 	struct ice_hw *hw = pi->hw;
995 	int status = 0;
996 	u16 buf_size;
997 	u32 teid;
998 
999 	buf_size = ice_struct_size(buf, generic, num_nodes);
1000 	buf = (struct ice_aqc_add_elem *)ice_malloc(hw, buf_size);
1001 	if (!buf)
1002 		return ICE_ERR_NO_MEMORY;
1003 
1004 	buf->hdr.parent_teid = parent->info.node_teid;
1005 	buf->hdr.num_elems = CPU_TO_LE16(num_nodes);
1006 	for (i = 0; i < num_nodes; i++) {
1007 		buf->generic[i].parent_teid = parent->info.node_teid;
1008 		buf->generic[i].data.elem_type = ICE_AQC_ELEM_TYPE_SE_GENERIC;
1009 		buf->generic[i].data.valid_sections =
1010 			ICE_AQC_ELEM_VALID_GENERIC | ICE_AQC_ELEM_VALID_CIR |
1011 			ICE_AQC_ELEM_VALID_EIR;
1012 		buf->generic[i].data.generic = 0;
1013 		buf->generic[i].data.cir_bw.bw_profile_idx =
1014 			CPU_TO_LE16(ICE_SCHED_DFLT_RL_PROF_ID);
1015 		buf->generic[i].data.cir_bw.bw_alloc =
1016 			CPU_TO_LE16(ICE_SCHED_DFLT_BW_WT);
1017 		buf->generic[i].data.eir_bw.bw_profile_idx =
1018 			CPU_TO_LE16(ICE_SCHED_DFLT_RL_PROF_ID);
1019 		buf->generic[i].data.eir_bw.bw_alloc =
1020 			CPU_TO_LE16(ICE_SCHED_DFLT_BW_WT);
1021 	}
1022 
1023 	status = ice_aq_add_sched_elems(hw, 1, buf, buf_size,
1024 					&num_groups_added, NULL);
1025 	if (status || num_groups_added != 1) {
1026 		ice_debug(hw, ICE_DBG_SCHED, "add node failed FW Error %d\n",
1027 			  hw->adminq.sq_last_status);
1028 		ice_free(hw, buf);
1029 		return ICE_ERR_CFG;
1030 	}
1031 
1032 	*num_nodes_added = num_nodes;
1033 	/* add nodes to the SW DB */
1034 	for (i = 0; i < num_nodes; i++) {
1035 		if (prealloc_nodes)
1036 			status = ice_sched_add_node(pi, layer, &buf->generic[i], prealloc_nodes[i]);
1037 		else
1038 			status = ice_sched_add_node(pi, layer, &buf->generic[i], NULL);
1039 
1040 		if (status) {
1041 			ice_debug(hw, ICE_DBG_SCHED, "add nodes in SW DB failed status =%d\n",
1042 				  status);
1043 			break;
1044 		}
1045 
1046 		teid = LE32_TO_CPU(buf->generic[i].node_teid);
1047 		new_node = ice_sched_find_node_by_teid(parent, teid);
1048 		if (!new_node) {
1049 			ice_debug(hw, ICE_DBG_SCHED, "Node is missing for teid =%d\n", teid);
1050 			break;
1051 		}
1052 
1053 		new_node->sibling = NULL;
1054 		new_node->tc_num = tc_node->tc_num;
1055 
1056 		/* add it to previous node sibling pointer */
1057 		/* Note: siblings are not linked across branches */
1058 		prev = ice_sched_get_first_node(pi, tc_node, layer);
1059 		if (prev && prev != new_node) {
1060 			while (prev->sibling)
1061 				prev = prev->sibling;
1062 			prev->sibling = new_node;
1063 		}
1064 
1065 		/* initialize the sibling head */
1066 		if (!pi->sib_head[tc_node->tc_num][layer])
1067 			pi->sib_head[tc_node->tc_num][layer] = new_node;
1068 
1069 		if (i == 0)
1070 			*first_node_teid = teid;
1071 	}
1072 
1073 	ice_free(hw, buf);
1074 	return status;
1075 }
1076 
1077 /**
1078  * ice_sched_add_nodes_to_hw_layer - Add nodes to hw layer
1079  * @pi: port information structure
1080  * @tc_node: pointer to TC node
1081  * @parent: pointer to parent node
1082  * @layer: layer number to add nodes
1083  * @num_nodes: number of nodes to be added
1084  * @first_node_teid: pointer to the first node TEID
1085  * @num_nodes_added: pointer to number of nodes added
1086  *
1087  * Add nodes into specific hw layer.
1088  */
1089 static int
1090 ice_sched_add_nodes_to_hw_layer(struct ice_port_info *pi,
1091 				struct ice_sched_node *tc_node,
1092 				struct ice_sched_node *parent, u8 layer,
1093 				u16 num_nodes, u32 *first_node_teid,
1094 				u16 *num_nodes_added)
1095 {
1096 	u16 max_child_nodes;
1097 
1098 	*num_nodes_added = 0;
1099 
1100 	if (!num_nodes)
1101 		return 0;
1102 
1103 	if (!parent || layer < pi->hw->sw_entry_point_layer)
1104 		return ICE_ERR_PARAM;
1105 
1106 	/* max children per node per layer */
1107 	max_child_nodes = pi->hw->max_children[parent->tx_sched_layer];
1108 
1109 	/* current number of children + required nodes exceed max children */
1110 	if ((parent->num_children + num_nodes) > max_child_nodes) {
1111 		/* Fail if the parent is a TC node */
1112 		if (parent == tc_node)
1113 			return ICE_ERR_CFG;
1114 		return ICE_ERR_MAX_LIMIT;
1115 	}
1116 
1117 	return ice_sched_add_elems(pi, tc_node, parent, layer, num_nodes,
1118 				   num_nodes_added, first_node_teid, NULL);
1119 }
1120 
1121 /**
1122  * ice_sched_add_nodes_to_layer - Add nodes to a given layer
1123  * @pi: port information structure
1124  * @tc_node: pointer to TC node
1125  * @parent: pointer to parent node
1126  * @layer: layer number to add nodes
1127  * @num_nodes: number of nodes to be added
1128  * @first_node_teid: pointer to the first node TEID
1129  * @num_nodes_added: pointer to number of nodes added
1130  *
1131  * This function add nodes to a given layer.
1132  */
1133 static int
1134 ice_sched_add_nodes_to_layer(struct ice_port_info *pi,
1135 			     struct ice_sched_node *tc_node,
1136 			     struct ice_sched_node *parent, u8 layer,
1137 			     u16 num_nodes, u32 *first_node_teid,
1138 			     u16 *num_nodes_added)
1139 {
1140 	u32 *first_teid_ptr = first_node_teid;
1141 	u16 new_num_nodes = num_nodes;
1142 	int status = 0;
1143 	u32 temp;
1144 
1145 	*num_nodes_added = 0;
1146 	while (*num_nodes_added < num_nodes) {
1147 		u16 max_child_nodes, num_added = 0;
1148 
1149 		status = ice_sched_add_nodes_to_hw_layer(pi, tc_node, parent,
1150 							 layer,	new_num_nodes,
1151 							 first_teid_ptr,
1152 							 &num_added);
1153 		if (!status)
1154 			*num_nodes_added += num_added;
1155 		/* added more nodes than requested ? */
1156 		if (*num_nodes_added > num_nodes) {
1157 			ice_debug(pi->hw, ICE_DBG_SCHED, "added extra nodes %d %d\n", num_nodes,
1158 				  *num_nodes_added);
1159 			status = ICE_ERR_CFG;
1160 			break;
1161 		}
1162 		/* break if all the nodes are added successfully */
1163 		if (!status && (*num_nodes_added == num_nodes))
1164 			break;
1165 		/* break if the error is not max limit */
1166 		if (status && status != ICE_ERR_MAX_LIMIT)
1167 			break;
1168 		/* Exceeded the max children */
1169 		max_child_nodes = pi->hw->max_children[parent->tx_sched_layer];
1170 		/* utilize all the spaces if the parent is not full */
1171 		if (parent->num_children < max_child_nodes) {
1172 			new_num_nodes = max_child_nodes - parent->num_children;
1173 		} else {
1174 			/* This parent is full, try the next sibling */
1175 			parent = parent->sibling;
1176 			/* Don't modify the first node TEID memory if the
1177 			 * first node was added already in the above call.
1178 			 * Instead send some temp memory for all other
1179 			 * recursive calls.
1180 			 */
1181 			if (num_added)
1182 				first_teid_ptr = &temp;
1183 
1184 			new_num_nodes = num_nodes - *num_nodes_added;
1185 		}
1186 	}
1187 	return status;
1188 }
1189 
1190 /**
1191  * ice_sched_get_qgrp_layer - get the current queue group layer number
1192  * @hw: pointer to the HW struct
1193  *
1194  * This function returns the current queue group layer number
1195  */
1196 static u8 ice_sched_get_qgrp_layer(struct ice_hw *hw)
1197 {
1198 	/* It's always total layers - 1, the array is 0 relative so -2 */
1199 	return hw->num_tx_sched_layers - ICE_QGRP_LAYER_OFFSET;
1200 }
1201 
1202 /**
1203  * ice_sched_get_vsi_layer - get the current VSI layer number
1204  * @hw: pointer to the HW struct
1205  *
1206  * This function returns the current VSI layer number
1207  */
1208 static u8 ice_sched_get_vsi_layer(struct ice_hw *hw)
1209 {
1210 	/* Num Layers       VSI layer
1211 	 *     9               6
1212 	 *     7               4
1213 	 *     5 or less       sw_entry_point_layer
1214 	 */
1215 	/* calculate the VSI layer based on number of layers. */
1216 	if (hw->num_tx_sched_layers == ICE_SCHED_9_LAYERS)
1217 		return hw->num_tx_sched_layers - ICE_VSI_LAYER_OFFSET;
1218 	else if (hw->num_tx_sched_layers == ICE_SCHED_5_LAYERS)
1219 		/* qgroup and VSI layers are same */
1220 		return hw->num_tx_sched_layers - ICE_QGRP_LAYER_OFFSET;
1221 	return hw->sw_entry_point_layer;
1222 }
1223 
1224 /**
1225  * ice_sched_get_agg_layer - get the current aggregator layer number
1226  * @hw: pointer to the HW struct
1227  *
1228  * This function returns the current aggregator layer number
1229  */
1230 static u8 ice_sched_get_agg_layer(struct ice_hw *hw)
1231 {
1232 	/* Num Layers       aggregator layer
1233 	 *     9               4
1234 	 *     7 or less       sw_entry_point_layer
1235 	 */
1236 	/* calculate the aggregator layer based on number of layers. */
1237 	if (hw->num_tx_sched_layers == ICE_SCHED_9_LAYERS)
1238 		return hw->num_tx_sched_layers - ICE_AGG_LAYER_OFFSET;
1239 	return hw->sw_entry_point_layer;
1240 }
1241 
1242 /**
1243  * ice_rm_dflt_leaf_node - remove the default leaf node in the tree
1244  * @pi: port information structure
1245  *
1246  * This function removes the leaf node that was created by the FW
1247  * during initialization
1248  */
1249 static void ice_rm_dflt_leaf_node(struct ice_port_info *pi)
1250 {
1251 	struct ice_sched_node *node;
1252 
1253 	node = pi->root;
1254 	while (node) {
1255 		if (!node->num_children)
1256 			break;
1257 		node = node->children[0];
1258 	}
1259 	if (node && node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF) {
1260 		u32 teid = LE32_TO_CPU(node->info.node_teid);
1261 		int status;
1262 
1263 		/* remove the default leaf node */
1264 		status = ice_sched_remove_elems(pi->hw, node->parent, 1, &teid);
1265 		if (!status)
1266 			ice_free_sched_node(pi, node);
1267 	}
1268 }
1269 
1270 /**
1271  * ice_sched_rm_dflt_nodes - free the default nodes in the tree
1272  * @pi: port information structure
1273  *
1274  * This function frees all the nodes except root and TC that were created by
1275  * the FW during initialization
1276  */
1277 static void ice_sched_rm_dflt_nodes(struct ice_port_info *pi)
1278 {
1279 	struct ice_sched_node *node;
1280 
1281 	ice_rm_dflt_leaf_node(pi);
1282 
1283 	/* remove the default nodes except TC and root nodes */
1284 	node = pi->root;
1285 	while (node) {
1286 		if (node->tx_sched_layer >= pi->hw->sw_entry_point_layer &&
1287 		    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC &&
1288 		    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT) {
1289 			ice_free_sched_node(pi, node);
1290 			break;
1291 		}
1292 
1293 		if (!node->num_children)
1294 			break;
1295 		node = node->children[0];
1296 	}
1297 }
1298 
1299 /**
1300  * ice_sched_init_port - Initialize scheduler by querying information from FW
1301  * @pi: port info structure for the tree to cleanup
1302  *
1303  * This function is the initial call to find the total number of Tx scheduler
1304  * resources, default topology created by firmware and storing the information
1305  * in SW DB.
1306  */
1307 int ice_sched_init_port(struct ice_port_info *pi)
1308 {
1309 	struct ice_aqc_get_topo_elem *buf;
1310 	struct ice_hw *hw;
1311 	u8 num_branches;
1312 	u16 num_elems;
1313 	int status;
1314 	u8 i, j;
1315 
1316 	if (!pi)
1317 		return ICE_ERR_PARAM;
1318 	hw = pi->hw;
1319 
1320 	/* Query the Default Topology from FW */
1321 	buf = (struct ice_aqc_get_topo_elem *)ice_malloc(hw,
1322 							 ICE_AQ_MAX_BUF_LEN);
1323 	if (!buf)
1324 		return ICE_ERR_NO_MEMORY;
1325 
1326 	/* Query default scheduling tree topology */
1327 	status = ice_aq_get_dflt_topo(hw, pi->lport, buf, ICE_AQ_MAX_BUF_LEN,
1328 				      &num_branches, NULL);
1329 	if (status)
1330 		goto err_init_port;
1331 
1332 	/* num_branches should be between 1-8 */
1333 	if (num_branches < 1 || num_branches > ICE_TXSCHED_MAX_BRANCHES) {
1334 		ice_debug(hw, ICE_DBG_SCHED, "num_branches unexpected %d\n",
1335 			  num_branches);
1336 		status = ICE_ERR_PARAM;
1337 		goto err_init_port;
1338 	}
1339 
1340 	/* get the number of elements on the default/first branch */
1341 	num_elems = LE16_TO_CPU(buf[0].hdr.num_elems);
1342 
1343 	/* num_elems should always be between 1-9 */
1344 	if (num_elems < 1 || num_elems > ICE_AQC_TOPO_MAX_LEVEL_NUM) {
1345 		ice_debug(hw, ICE_DBG_SCHED, "num_elems unexpected %d\n",
1346 			  num_elems);
1347 		status = ICE_ERR_PARAM;
1348 		goto err_init_port;
1349 	}
1350 
1351 	/* If the last node is a leaf node then the index of the queue group
1352 	 * layer is two less than the number of elements.
1353 	 */
1354 	if (num_elems > 2 && buf[0].generic[num_elems - 1].data.elem_type ==
1355 	    ICE_AQC_ELEM_TYPE_LEAF)
1356 		pi->last_node_teid =
1357 			LE32_TO_CPU(buf[0].generic[num_elems - 2].node_teid);
1358 	else
1359 		pi->last_node_teid =
1360 			LE32_TO_CPU(buf[0].generic[num_elems - 1].node_teid);
1361 
1362 	/* Insert the Tx Sched root node */
1363 	status = ice_sched_add_root_node(pi, &buf[0].generic[0]);
1364 	if (status)
1365 		goto err_init_port;
1366 
1367 	/* Parse the default tree and cache the information */
1368 	for (i = 0; i < num_branches; i++) {
1369 		num_elems = LE16_TO_CPU(buf[i].hdr.num_elems);
1370 
1371 		/* Skip root element as already inserted */
1372 		for (j = 1; j < num_elems; j++) {
1373 			/* update the sw entry point */
1374 			if (buf[0].generic[j].data.elem_type ==
1375 			    ICE_AQC_ELEM_TYPE_ENTRY_POINT)
1376 				hw->sw_entry_point_layer = j;
1377 
1378 			status = ice_sched_add_node(pi, j, &buf[i].generic[j], NULL);
1379 			if (status)
1380 				goto err_init_port;
1381 		}
1382 	}
1383 
1384 	/* Remove the default nodes. */
1385 	if (pi->root)
1386 		ice_sched_rm_dflt_nodes(pi);
1387 
1388 	/* initialize the port for handling the scheduler tree */
1389 	pi->port_state = ICE_SCHED_PORT_STATE_READY;
1390 	ice_init_lock(&pi->sched_lock);
1391 	for (i = 0; i < ICE_AQC_TOPO_MAX_LEVEL_NUM; i++)
1392 		INIT_LIST_HEAD(&hw->rl_prof_list[i]);
1393 
1394 err_init_port:
1395 	if (status && pi->root) {
1396 		ice_free_sched_node(pi, pi->root);
1397 		pi->root = NULL;
1398 	}
1399 
1400 	ice_free(hw, buf);
1401 	return status;
1402 }
1403 
1404 /**
1405  * ice_sched_get_node - Get the struct ice_sched_node for given TEID
1406  * @pi: port information structure
1407  * @teid: Scheduler node TEID
1408  *
1409  * This function retrieves the ice_sched_node struct for given TEID from
1410  * the SW DB and returns it to the caller.
1411  */
1412 struct ice_sched_node *ice_sched_get_node(struct ice_port_info *pi, u32 teid)
1413 {
1414 	struct ice_sched_node *node;
1415 
1416 	if (!pi)
1417 		return NULL;
1418 
1419 	/* Find the node starting from root */
1420 	ice_acquire_lock(&pi->sched_lock);
1421 	node = ice_sched_find_node_by_teid(pi->root, teid);
1422 	ice_release_lock(&pi->sched_lock);
1423 
1424 	if (!node)
1425 		ice_debug(pi->hw, ICE_DBG_SCHED, "Node not found for teid=0x%x\n", teid);
1426 
1427 	return node;
1428 }
1429 
1430 /**
1431  * ice_sched_query_res_alloc - query the FW for num of logical sched layers
1432  * @hw: pointer to the HW struct
1433  *
1434  * query FW for allocated scheduler resources and store in HW struct
1435  */
1436 int ice_sched_query_res_alloc(struct ice_hw *hw)
1437 {
1438 	struct ice_aqc_query_txsched_res_resp *buf;
1439 	__le16 max_sibl;
1440 	int status = 0;
1441 	u16 i;
1442 
1443 	if (hw->layer_info)
1444 		return status;
1445 
1446 	buf = (struct ice_aqc_query_txsched_res_resp *)
1447 		ice_malloc(hw, sizeof(*buf));
1448 	if (!buf)
1449 		return ICE_ERR_NO_MEMORY;
1450 
1451 	status = ice_aq_query_sched_res(hw, sizeof(*buf), buf, NULL);
1452 	if (status)
1453 		goto sched_query_out;
1454 
1455 	hw->num_tx_sched_layers =
1456 		(u8)LE16_TO_CPU(buf->sched_props.logical_levels);
1457 	hw->num_tx_sched_phys_layers =
1458 		(u8)LE16_TO_CPU(buf->sched_props.phys_levels);
1459 	hw->flattened_layers = buf->sched_props.flattening_bitmap;
1460 	hw->max_cgds = buf->sched_props.max_pf_cgds;
1461 
1462 	/* max sibling group size of current layer refers to the max children
1463 	 * of the below layer node.
1464 	 * layer 1 node max children will be layer 2 max sibling group size
1465 	 * layer 2 node max children will be layer 3 max sibling group size
1466 	 * and so on. This array will be populated from root (index 0) to
1467 	 * qgroup layer 7. Leaf node has no children.
1468 	 */
1469 	for (i = 0; i < hw->num_tx_sched_layers - 1; i++) {
1470 		max_sibl = buf->layer_props[i + 1].max_sibl_grp_sz;
1471 		hw->max_children[i] = LE16_TO_CPU(max_sibl);
1472 	}
1473 
1474 	hw->layer_info = (struct ice_aqc_layer_props *)
1475 			 ice_memdup(hw, buf->layer_props,
1476 				    (hw->num_tx_sched_layers *
1477 				     sizeof(*hw->layer_info)),
1478 				    ICE_NONDMA_TO_NONDMA);
1479 	if (!hw->layer_info) {
1480 		status = ICE_ERR_NO_MEMORY;
1481 		goto sched_query_out;
1482 	}
1483 
1484 sched_query_out:
1485 	ice_free(hw, buf);
1486 	return status;
1487 }
1488 
1489 /**
1490  * ice_sched_get_psm_clk_freq - determine the PSM clock frequency
1491  * @hw: pointer to the HW struct
1492  *
1493  * Determine the PSM clock frequency and store in HW struct
1494  */
1495 void ice_sched_get_psm_clk_freq(struct ice_hw *hw)
1496 {
1497 	u32 val, clk_src;
1498 
1499 	val = rd32(hw, GLGEN_CLKSTAT_SRC);
1500 	clk_src = (val & GLGEN_CLKSTAT_SRC_PSM_CLK_SRC_M) >>
1501 		GLGEN_CLKSTAT_SRC_PSM_CLK_SRC_S;
1502 
1503 	switch (clk_src) {
1504 	case PSM_CLK_SRC_367_MHZ:
1505 		hw->psm_clk_freq = ICE_PSM_CLK_367MHZ_IN_HZ;
1506 		break;
1507 	case PSM_CLK_SRC_416_MHZ:
1508 		hw->psm_clk_freq = ICE_PSM_CLK_416MHZ_IN_HZ;
1509 		break;
1510 	case PSM_CLK_SRC_446_MHZ:
1511 		hw->psm_clk_freq = ICE_PSM_CLK_446MHZ_IN_HZ;
1512 		break;
1513 	case PSM_CLK_SRC_390_MHZ:
1514 		hw->psm_clk_freq = ICE_PSM_CLK_390MHZ_IN_HZ;
1515 		break;
1516 
1517 	/* default condition is not required as clk_src is restricted
1518 	 * to a 2-bit value from GLGEN_CLKSTAT_SRC_PSM_CLK_SRC_M mask.
1519 	 * The above switch statements cover the possible values of
1520 	 * this variable.
1521 	 */
1522 	}
1523 }
1524 
1525 /**
1526  * ice_sched_find_node_in_subtree - Find node in part of base node subtree
1527  * @hw: pointer to the HW struct
1528  * @base: pointer to the base node
1529  * @node: pointer to the node to search
1530  *
1531  * This function checks whether a given node is part of the base node
1532  * subtree or not
1533  */
1534 bool
1535 ice_sched_find_node_in_subtree(struct ice_hw *hw, struct ice_sched_node *base,
1536 			       struct ice_sched_node *node)
1537 {
1538 	u8 i;
1539 
1540 	for (i = 0; i < base->num_children; i++) {
1541 		struct ice_sched_node *child = base->children[i];
1542 
1543 		if (node == child)
1544 			return true;
1545 
1546 		if (child->tx_sched_layer > node->tx_sched_layer)
1547 			return false;
1548 
1549 		/* this recursion is intentional, and wouldn't
1550 		 * go more than 8 calls
1551 		 */
1552 		if (ice_sched_find_node_in_subtree(hw, child, node))
1553 			return true;
1554 	}
1555 	return false;
1556 }
1557 
1558 /**
1559  * ice_sched_get_free_qgrp - Scan all queue group siblings and find a free node
1560  * @pi: port information structure
1561  * @vsi_node: software VSI handle
1562  * @qgrp_node: first queue group node identified for scanning
1563  * @owner: LAN or RDMA
1564  *
1565  * This function retrieves a free LAN or RDMA queue group node by scanning
1566  * qgrp_node and its siblings for the queue group with the fewest number
1567  * of queues currently assigned.
1568  */
1569 static struct ice_sched_node *
1570 ice_sched_get_free_qgrp(struct ice_port_info *pi,
1571 			struct ice_sched_node *vsi_node,
1572 			struct ice_sched_node *qgrp_node, u8 owner)
1573 {
1574 	struct ice_sched_node *min_qgrp;
1575 	u8 min_children;
1576 
1577 	if (!qgrp_node)
1578 		return qgrp_node;
1579 	min_children = qgrp_node->num_children;
1580 	if (!min_children)
1581 		return qgrp_node;
1582 	min_qgrp = qgrp_node;
1583 	/* scan all queue groups until find a node which has less than the
1584 	 * minimum number of children. This way all queue group nodes get
1585 	 * equal number of shares and active. The bandwidth will be equally
1586 	 * distributed across all queues.
1587 	 */
1588 	while (qgrp_node) {
1589 		/* make sure the qgroup node is part of the VSI subtree */
1590 		if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node))
1591 			if (qgrp_node->num_children < min_children &&
1592 			    qgrp_node->owner == owner) {
1593 				/* replace the new min queue group node */
1594 				min_qgrp = qgrp_node;
1595 				min_children = min_qgrp->num_children;
1596 				/* break if it has no children, */
1597 				if (!min_children)
1598 					break;
1599 			}
1600 		qgrp_node = qgrp_node->sibling;
1601 	}
1602 	return min_qgrp;
1603 }
1604 
1605 /**
1606  * ice_sched_get_free_qparent - Get a free LAN or RDMA queue group node
1607  * @pi: port information structure
1608  * @vsi_handle: software VSI handle
1609  * @tc: branch number
1610  * @owner: LAN or RDMA
1611  *
1612  * This function retrieves a free LAN or RDMA queue group node
1613  */
1614 struct ice_sched_node *
1615 ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
1616 			   u8 owner)
1617 {
1618 	struct ice_sched_node *vsi_node, *qgrp_node;
1619 	struct ice_vsi_ctx *vsi_ctx;
1620 	u8 qgrp_layer, vsi_layer;
1621 	u16 max_children;
1622 
1623 	qgrp_layer = ice_sched_get_qgrp_layer(pi->hw);
1624 	vsi_layer = ice_sched_get_vsi_layer(pi->hw);
1625 	max_children = pi->hw->max_children[qgrp_layer];
1626 
1627 	vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
1628 	if (!vsi_ctx)
1629 		return NULL;
1630 	vsi_node = vsi_ctx->sched.vsi_node[tc];
1631 	/* validate invalid VSI ID */
1632 	if (!vsi_node)
1633 		return NULL;
1634 
1635 	/* If the queue group and vsi layer are same then queues
1636 	 * are all attached directly to VSI
1637 	 */
1638 	if (qgrp_layer == vsi_layer)
1639 		return vsi_node;
1640 
1641 	/* get the first queue group node from VSI sub-tree */
1642 	qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer);
1643 	while (qgrp_node) {
1644 		/* make sure the qgroup node is part of the VSI subtree */
1645 		if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node))
1646 			if (qgrp_node->num_children < max_children &&
1647 			    qgrp_node->owner == owner)
1648 				break;
1649 		qgrp_node = qgrp_node->sibling;
1650 	}
1651 
1652 	/* Select the best queue group */
1653 	return ice_sched_get_free_qgrp(pi, vsi_node, qgrp_node, owner);
1654 }
1655 
1656 /**
1657  * ice_sched_get_vsi_node - Get a VSI node based on VSI ID
1658  * @pi: pointer to the port information structure
1659  * @tc_node: pointer to the TC node
1660  * @vsi_handle: software VSI handle
1661  *
1662  * This function retrieves a VSI node for a given VSI ID from a given
1663  * TC branch
1664  */
1665 struct ice_sched_node *
1666 ice_sched_get_vsi_node(struct ice_port_info *pi, struct ice_sched_node *tc_node,
1667 		       u16 vsi_handle)
1668 {
1669 	struct ice_sched_node *node;
1670 	u8 vsi_layer;
1671 
1672 	vsi_layer = ice_sched_get_vsi_layer(pi->hw);
1673 	node = ice_sched_get_first_node(pi, tc_node, vsi_layer);
1674 
1675 	/* Check whether it already exists */
1676 	while (node) {
1677 		if (node->vsi_handle == vsi_handle)
1678 			return node;
1679 		node = node->sibling;
1680 	}
1681 
1682 	return node;
1683 }
1684 
1685 /**
1686  * ice_sched_get_agg_node - Get an aggregator node based on aggregator ID
1687  * @pi: pointer to the port information structure
1688  * @tc_node: pointer to the TC node
1689  * @agg_id: aggregator ID
1690  *
1691  * This function retrieves an aggregator node for a given aggregator ID from
1692  * a given TC branch
1693  */
1694 static struct ice_sched_node *
1695 ice_sched_get_agg_node(struct ice_port_info *pi, struct ice_sched_node *tc_node,
1696 		       u32 agg_id)
1697 {
1698 	struct ice_sched_node *node;
1699 	struct ice_hw *hw = pi->hw;
1700 	u8 agg_layer;
1701 
1702 	if (!hw)
1703 		return NULL;
1704 	agg_layer = ice_sched_get_agg_layer(hw);
1705 	node = ice_sched_get_first_node(pi, tc_node, agg_layer);
1706 
1707 	/* Check whether it already exists */
1708 	while (node) {
1709 		if (node->agg_id == agg_id)
1710 			return node;
1711 		node = node->sibling;
1712 	}
1713 
1714 	return node;
1715 }
1716 
1717 /**
1718  * ice_sched_check_node - Compare node parameters between SW DB and HW DB
1719  * @hw: pointer to the HW struct
1720  * @node: pointer to the ice_sched_node struct
1721  *
1722  * This function queries and compares the HW element with SW DB node parameters
1723  */
1724 static bool ice_sched_check_node(struct ice_hw *hw, struct ice_sched_node *node)
1725 {
1726 	struct ice_aqc_txsched_elem_data buf;
1727 	u32 node_teid;
1728 	int status;
1729 
1730 	node_teid = LE32_TO_CPU(node->info.node_teid);
1731 	status = ice_sched_query_elem(hw, node_teid, &buf);
1732 	if (status)
1733 		return false;
1734 
1735 	if (memcmp(&buf, &node->info, sizeof(buf))) {
1736 		ice_debug(hw, ICE_DBG_SCHED, "Node mismatch for teid=0x%x\n",
1737 			  node_teid);
1738 		return false;
1739 	}
1740 
1741 	return true;
1742 }
1743 
1744 /**
1745  * ice_sched_calc_vsi_child_nodes - calculate number of VSI child nodes
1746  * @hw: pointer to the HW struct
1747  * @num_qs: number of queues
1748  * @num_nodes: num nodes array
1749  *
1750  * This function calculates the number of VSI child nodes based on the
1751  * number of queues.
1752  */
1753 static void
1754 ice_sched_calc_vsi_child_nodes(struct ice_hw *hw, u16 num_qs, u16 *num_nodes)
1755 {
1756 	u16 num = num_qs;
1757 	u8 i, qgl, vsil;
1758 
1759 	qgl = ice_sched_get_qgrp_layer(hw);
1760 	vsil = ice_sched_get_vsi_layer(hw);
1761 
1762 	/* calculate num nodes from queue group to VSI layer */
1763 	for (i = qgl; i > vsil; i--) {
1764 		/* round to the next integer if there is a remainder */
1765 		num = DIVIDE_AND_ROUND_UP(num, hw->max_children[i]);
1766 
1767 		/* need at least one node */
1768 		num_nodes[i] = num ? num : 1;
1769 	}
1770 }
1771 
1772 /**
1773  * ice_sched_add_vsi_child_nodes - add VSI child nodes to tree
1774  * @pi: port information structure
1775  * @vsi_handle: software VSI handle
1776  * @tc_node: pointer to the TC node
1777  * @num_nodes: pointer to the num nodes that needs to be added per layer
1778  * @owner: node owner (LAN or RDMA)
1779  *
1780  * This function adds the VSI child nodes to tree. It gets called for
1781  * LAN and RDMA separately.
1782  */
1783 static int
1784 ice_sched_add_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
1785 			      struct ice_sched_node *tc_node, u16 *num_nodes,
1786 			      u8 owner)
1787 {
1788 	struct ice_sched_node *parent, *node;
1789 	struct ice_hw *hw = pi->hw;
1790 	u32 first_node_teid;
1791 	u16 num_added = 0;
1792 	u8 i, qgl, vsil;
1793 
1794 	qgl = ice_sched_get_qgrp_layer(hw);
1795 	vsil = ice_sched_get_vsi_layer(hw);
1796 	parent = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
1797 	for (i = vsil + 1; i <= qgl; i++) {
1798 		int status;
1799 
1800 		if (!parent)
1801 			return ICE_ERR_CFG;
1802 
1803 		status = ice_sched_add_nodes_to_layer(pi, tc_node, parent, i,
1804 						      num_nodes[i],
1805 						      &first_node_teid,
1806 						      &num_added);
1807 		if (status || num_nodes[i] != num_added)
1808 			return ICE_ERR_CFG;
1809 
1810 		/* The newly added node can be a new parent for the next
1811 		 * layer nodes
1812 		 */
1813 		if (num_added) {
1814 			parent = ice_sched_find_node_by_teid(tc_node,
1815 							     first_node_teid);
1816 			node = parent;
1817 			while (node) {
1818 				node->owner = owner;
1819 				node = node->sibling;
1820 			}
1821 		} else {
1822 			parent = parent->children[0];
1823 		}
1824 	}
1825 
1826 	return 0;
1827 }
1828 
1829 /**
1830  * ice_sched_calc_vsi_support_nodes - calculate number of VSI support nodes
1831  * @pi: pointer to the port info structure
1832  * @tc_node: pointer to TC node
1833  * @num_nodes: pointer to num nodes array
1834  *
1835  * This function calculates the number of supported nodes needed to add this
1836  * VSI into Tx tree including the VSI, parent and intermediate nodes in below
1837  * layers
1838  */
1839 static void
1840 ice_sched_calc_vsi_support_nodes(struct ice_port_info *pi,
1841 				 struct ice_sched_node *tc_node, u16 *num_nodes)
1842 {
1843 	struct ice_sched_node *node;
1844 	u8 vsil;
1845 	int i;
1846 
1847 	vsil = ice_sched_get_vsi_layer(pi->hw);
1848 	for (i = vsil; i >= pi->hw->sw_entry_point_layer; i--)
1849 		/* Add intermediate nodes if TC has no children and
1850 		 * need at least one node for VSI
1851 		 */
1852 		if (!tc_node->num_children || i == vsil) {
1853 			num_nodes[i]++;
1854 		} else {
1855 			/* If intermediate nodes are reached max children
1856 			 * then add a new one.
1857 			 */
1858 			node = ice_sched_get_first_node(pi, tc_node, (u8)i);
1859 			/* scan all the siblings */
1860 			while (node) {
1861 				if (node->num_children <
1862 				    pi->hw->max_children[i])
1863 					break;
1864 				node = node->sibling;
1865 			}
1866 
1867 			/* tree has one intermediate node to add this new VSI.
1868 			 * So no need to calculate supported nodes for below
1869 			 * layers.
1870 			 */
1871 			if (node)
1872 				break;
1873 			/* all the nodes are full, allocate a new one */
1874 			num_nodes[i]++;
1875 		}
1876 }
1877 
1878 /**
1879  * ice_sched_add_vsi_support_nodes - add VSI supported nodes into Tx tree
1880  * @pi: port information structure
1881  * @vsi_handle: software VSI handle
1882  * @tc_node: pointer to TC node
1883  * @num_nodes: pointer to num nodes array
1884  *
1885  * This function adds the VSI supported nodes into Tx tree including the
1886  * VSI, its parent and intermediate nodes in below layers
1887  */
1888 static int
1889 ice_sched_add_vsi_support_nodes(struct ice_port_info *pi, u16 vsi_handle,
1890 				struct ice_sched_node *tc_node, u16 *num_nodes)
1891 {
1892 	struct ice_sched_node *parent = tc_node;
1893 	u32 first_node_teid;
1894 	u16 num_added = 0;
1895 	u8 i, vsil;
1896 
1897 	if (!pi)
1898 		return ICE_ERR_PARAM;
1899 
1900 	vsil = ice_sched_get_vsi_layer(pi->hw);
1901 	for (i = pi->hw->sw_entry_point_layer; i <= vsil; i++) {
1902 		int status;
1903 
1904 		status = ice_sched_add_nodes_to_layer(pi, tc_node, parent,
1905 						      i, num_nodes[i],
1906 						      &first_node_teid,
1907 						      &num_added);
1908 		if (status || num_nodes[i] != num_added)
1909 			return ICE_ERR_CFG;
1910 
1911 		/* The newly added node can be a new parent for the next
1912 		 * layer nodes
1913 		 */
1914 		if (num_added)
1915 			parent = ice_sched_find_node_by_teid(tc_node,
1916 							     first_node_teid);
1917 		else
1918 			parent = parent->children[0];
1919 
1920 		if (!parent)
1921 			return ICE_ERR_CFG;
1922 
1923 		if (i == vsil)
1924 			parent->vsi_handle = vsi_handle;
1925 	}
1926 
1927 	return 0;
1928 }
1929 
1930 /**
1931  * ice_sched_add_vsi_to_topo - add a new VSI into tree
1932  * @pi: port information structure
1933  * @vsi_handle: software VSI handle
1934  * @tc: TC number
1935  *
1936  * This function adds a new VSI into scheduler tree
1937  */
1938 static int
1939 ice_sched_add_vsi_to_topo(struct ice_port_info *pi, u16 vsi_handle, u8 tc)
1940 {
1941 	u16 num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 };
1942 	struct ice_sched_node *tc_node;
1943 
1944 	tc_node = ice_sched_get_tc_node(pi, tc);
1945 	if (!tc_node)
1946 		return ICE_ERR_PARAM;
1947 
1948 	/* calculate number of supported nodes needed for this VSI */
1949 	ice_sched_calc_vsi_support_nodes(pi, tc_node, num_nodes);
1950 
1951 	/* add VSI supported nodes to TC subtree */
1952 	return ice_sched_add_vsi_support_nodes(pi, vsi_handle, tc_node,
1953 					       num_nodes);
1954 }
1955 
1956 /**
1957  * ice_sched_update_vsi_child_nodes - update VSI child nodes
1958  * @pi: port information structure
1959  * @vsi_handle: software VSI handle
1960  * @tc: TC number
1961  * @new_numqs: new number of max queues
1962  * @owner: owner of this subtree
1963  *
1964  * This function updates the VSI child nodes based on the number of queues
1965  */
1966 static int
1967 ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
1968 				 u8 tc, u16 new_numqs, u8 owner)
1969 {
1970 	u16 new_num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 };
1971 	struct ice_sched_node *vsi_node;
1972 	struct ice_sched_node *tc_node;
1973 	struct ice_vsi_ctx *vsi_ctx;
1974 	struct ice_hw *hw = pi->hw;
1975 	int status = 0;
1976 	u16 prev_numqs;
1977 
1978 	tc_node = ice_sched_get_tc_node(pi, tc);
1979 	if (!tc_node)
1980 		return ICE_ERR_CFG;
1981 
1982 	vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
1983 	if (!vsi_node)
1984 		return ICE_ERR_CFG;
1985 
1986 	vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
1987 	if (!vsi_ctx)
1988 		return ICE_ERR_PARAM;
1989 
1990 	if (owner == ICE_SCHED_NODE_OWNER_LAN)
1991 		prev_numqs = vsi_ctx->sched.max_lanq[tc];
1992 	else
1993 		prev_numqs = vsi_ctx->sched.max_rdmaq[tc];
1994 	/* num queues are not changed or less than the previous number */
1995 	if (new_numqs <= prev_numqs)
1996 		return status;
1997 	if (owner == ICE_SCHED_NODE_OWNER_LAN) {
1998 		status = ice_alloc_lan_q_ctx(hw, vsi_handle, tc, new_numqs);
1999 		if (status)
2000 			return status;
2001 	} else {
2002 		status = ice_alloc_rdma_q_ctx(hw, vsi_handle, tc, new_numqs);
2003 		if (status)
2004 			return status;
2005 	}
2006 
2007 	if (new_numqs)
2008 		ice_sched_calc_vsi_child_nodes(hw, new_numqs, new_num_nodes);
2009 	/* Keep the max number of queue configuration all the time. Update the
2010 	 * tree only if number of queues > previous number of queues. This may
2011 	 * leave some extra nodes in the tree if number of queues < previous
2012 	 * number but that wouldn't harm anything. Removing those extra nodes
2013 	 * may complicate the code if those nodes are part of SRL or
2014 	 * individually rate limited.
2015 	 */
2016 	status = ice_sched_add_vsi_child_nodes(pi, vsi_handle, tc_node,
2017 					       new_num_nodes, owner);
2018 	if (status)
2019 		return status;
2020 	if (owner == ICE_SCHED_NODE_OWNER_LAN)
2021 		vsi_ctx->sched.max_lanq[tc] = new_numqs;
2022 	else
2023 		vsi_ctx->sched.max_rdmaq[tc] = new_numqs;
2024 
2025 	return 0;
2026 }
2027 
2028 /**
2029  * ice_sched_cfg_vsi - configure the new/existing VSI
2030  * @pi: port information structure
2031  * @vsi_handle: software VSI handle
2032  * @tc: TC number
2033  * @maxqs: max number of queues
2034  * @owner: LAN or RDMA
2035  * @enable: TC enabled or disabled
2036  *
2037  * This function adds/updates VSI nodes based on the number of queues. If TC is
2038  * enabled and VSI is in suspended state then resume the VSI back. If TC is
2039  * disabled then suspend the VSI if it is not already.
2040  */
2041 int
2042 ice_sched_cfg_vsi(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 maxqs,
2043 		  u8 owner, bool enable)
2044 {
2045 	struct ice_sched_node *vsi_node, *tc_node;
2046 	struct ice_vsi_ctx *vsi_ctx;
2047 	struct ice_hw *hw = pi->hw;
2048 	int status = 0;
2049 
2050 	ice_debug(pi->hw, ICE_DBG_SCHED, "add/config VSI %d\n", vsi_handle);
2051 	tc_node = ice_sched_get_tc_node(pi, tc);
2052 	if (!tc_node)
2053 		return ICE_ERR_PARAM;
2054 	vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
2055 	if (!vsi_ctx)
2056 		return ICE_ERR_PARAM;
2057 	vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
2058 
2059 	/* suspend the VSI if TC is not enabled */
2060 	if (!enable) {
2061 		if (vsi_node && vsi_node->in_use) {
2062 			u32 teid = LE32_TO_CPU(vsi_node->info.node_teid);
2063 
2064 			status = ice_sched_suspend_resume_elems(hw, 1, &teid,
2065 								true);
2066 			if (!status)
2067 				vsi_node->in_use = false;
2068 		}
2069 		return status;
2070 	}
2071 
2072 	/* TC is enabled, if it is a new VSI then add it to the tree */
2073 	if (!vsi_node) {
2074 		status = ice_sched_add_vsi_to_topo(pi, vsi_handle, tc);
2075 		if (status)
2076 			return status;
2077 
2078 		vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
2079 		if (!vsi_node)
2080 			return ICE_ERR_CFG;
2081 
2082 		vsi_ctx->sched.vsi_node[tc] = vsi_node;
2083 		vsi_node->in_use = true;
2084 		/* invalidate the max queues whenever VSI gets added first time
2085 		 * into the scheduler tree (boot or after reset). We need to
2086 		 * recreate the child nodes all the time in these cases.
2087 		 */
2088 		vsi_ctx->sched.max_lanq[tc] = 0;
2089 		vsi_ctx->sched.max_rdmaq[tc] = 0;
2090 	}
2091 
2092 	/* update the VSI child nodes */
2093 	status = ice_sched_update_vsi_child_nodes(pi, vsi_handle, tc, maxqs,
2094 						  owner);
2095 	if (status)
2096 		return status;
2097 
2098 	/* TC is enabled, resume the VSI if it is in the suspend state */
2099 	if (!vsi_node->in_use) {
2100 		u32 teid = LE32_TO_CPU(vsi_node->info.node_teid);
2101 
2102 		status = ice_sched_suspend_resume_elems(hw, 1, &teid, false);
2103 		if (!status)
2104 			vsi_node->in_use = true;
2105 	}
2106 
2107 	return status;
2108 }
2109 
2110 /**
2111  * ice_sched_rm_agg_vsi_info - remove aggregator related VSI info entry
2112  * @pi: port information structure
2113  * @vsi_handle: software VSI handle
2114  *
2115  * This function removes single aggregator VSI info entry from
2116  * aggregator list.
2117  */
2118 static void ice_sched_rm_agg_vsi_info(struct ice_port_info *pi, u16 vsi_handle)
2119 {
2120 	struct ice_sched_agg_info *agg_info;
2121 	struct ice_sched_agg_info *atmp;
2122 
2123 	LIST_FOR_EACH_ENTRY_SAFE(agg_info, atmp, &pi->hw->agg_list,
2124 				 ice_sched_agg_info,
2125 				 list_entry) {
2126 		struct ice_sched_agg_vsi_info *agg_vsi_info;
2127 		struct ice_sched_agg_vsi_info *vtmp;
2128 
2129 		LIST_FOR_EACH_ENTRY_SAFE(agg_vsi_info, vtmp,
2130 					 &agg_info->agg_vsi_list,
2131 					 ice_sched_agg_vsi_info, list_entry)
2132 			if (agg_vsi_info->vsi_handle == vsi_handle) {
2133 				LIST_DEL(&agg_vsi_info->list_entry);
2134 				ice_free(pi->hw, agg_vsi_info);
2135 				return;
2136 			}
2137 	}
2138 }
2139 
2140 /**
2141  * ice_sched_is_leaf_node_present - check for a leaf node in the sub-tree
2142  * @node: pointer to the sub-tree node
2143  *
2144  * This function checks for a leaf node presence in a given sub-tree node.
2145  */
2146 static bool ice_sched_is_leaf_node_present(struct ice_sched_node *node)
2147 {
2148 	u8 i;
2149 
2150 	for (i = 0; i < node->num_children; i++)
2151 		if (ice_sched_is_leaf_node_present(node->children[i]))
2152 			return true;
2153 	/* check for a leaf node */
2154 	return (node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF);
2155 }
2156 
2157 /**
2158  * ice_sched_rm_vsi_cfg - remove the VSI and its children nodes
2159  * @pi: port information structure
2160  * @vsi_handle: software VSI handle
2161  * @owner: LAN or RDMA
2162  *
2163  * This function removes the VSI and its LAN or RDMA children nodes from the
2164  * scheduler tree.
2165  */
2166 static int
2167 ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner)
2168 {
2169 	struct ice_vsi_ctx *vsi_ctx;
2170 	int status = ICE_ERR_PARAM;
2171 	u8 i;
2172 
2173 	ice_debug(pi->hw, ICE_DBG_SCHED, "removing VSI %d\n", vsi_handle);
2174 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
2175 		return status;
2176 	ice_acquire_lock(&pi->sched_lock);
2177 	vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
2178 	if (!vsi_ctx)
2179 		goto exit_sched_rm_vsi_cfg;
2180 
2181 	ice_for_each_traffic_class(i) {
2182 		struct ice_sched_node *vsi_node, *tc_node;
2183 		u8 j = 0;
2184 
2185 		tc_node = ice_sched_get_tc_node(pi, i);
2186 		if (!tc_node)
2187 			continue;
2188 
2189 		vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
2190 		if (!vsi_node)
2191 			continue;
2192 
2193 		if (ice_sched_is_leaf_node_present(vsi_node)) {
2194 			ice_debug(pi->hw, ICE_DBG_SCHED, "VSI has leaf nodes in TC %d\n", i);
2195 			status = ICE_ERR_IN_USE;
2196 			goto exit_sched_rm_vsi_cfg;
2197 		}
2198 		while (j < vsi_node->num_children) {
2199 			if (vsi_node->children[j]->owner == owner) {
2200 				ice_free_sched_node(pi, vsi_node->children[j]);
2201 
2202 				/* reset the counter again since the num
2203 				 * children will be updated after node removal
2204 				 */
2205 				j = 0;
2206 			} else {
2207 				j++;
2208 			}
2209 		}
2210 		/* remove the VSI if it has no children */
2211 		if (!vsi_node->num_children) {
2212 			ice_free_sched_node(pi, vsi_node);
2213 			vsi_ctx->sched.vsi_node[i] = NULL;
2214 
2215 			/* clean up aggregator related VSI info if any */
2216 			ice_sched_rm_agg_vsi_info(pi, vsi_handle);
2217 		}
2218 		if (owner == ICE_SCHED_NODE_OWNER_LAN)
2219 			vsi_ctx->sched.max_lanq[i] = 0;
2220 		else
2221 			vsi_ctx->sched.max_rdmaq[i] = 0;
2222 	}
2223 	status = 0;
2224 
2225 exit_sched_rm_vsi_cfg:
2226 	ice_release_lock(&pi->sched_lock);
2227 	return status;
2228 }
2229 
2230 /**
2231  * ice_rm_vsi_lan_cfg - remove VSI and its LAN children nodes
2232  * @pi: port information structure
2233  * @vsi_handle: software VSI handle
2234  *
2235  * This function clears the VSI and its LAN children nodes from scheduler tree
2236  * for all TCs.
2237  */
2238 int ice_rm_vsi_lan_cfg(struct ice_port_info *pi, u16 vsi_handle)
2239 {
2240 	return ice_sched_rm_vsi_cfg(pi, vsi_handle, ICE_SCHED_NODE_OWNER_LAN);
2241 }
2242 
2243 /**
2244  * ice_rm_vsi_rdma_cfg - remove VSI and its RDMA children nodes
2245  * @pi: port information structure
2246  * @vsi_handle: software VSI handle
2247  *
2248  * This function clears the VSI and its RDMA children nodes from scheduler tree
2249  * for all TCs.
2250  */
2251 int ice_rm_vsi_rdma_cfg(struct ice_port_info *pi, u16 vsi_handle)
2252 {
2253 	return ice_sched_rm_vsi_cfg(pi, vsi_handle, ICE_SCHED_NODE_OWNER_RDMA);
2254 }
2255 
2256 /**
2257  * ice_sched_is_tree_balanced - Check tree nodes are identical or not
2258  * @hw: pointer to the HW struct
2259  * @node: pointer to the ice_sched_node struct
2260  *
2261  * This function compares all the nodes for a given tree against HW DB nodes
2262  * This function needs to be called with the port_info->sched_lock held
2263  */
2264 bool ice_sched_is_tree_balanced(struct ice_hw *hw, struct ice_sched_node *node)
2265 {
2266 	u8 i;
2267 
2268 	/* start from the leaf node */
2269 	for (i = 0; i < node->num_children; i++)
2270 		/* Fail if node doesn't match with the SW DB
2271 		 * this recursion is intentional, and wouldn't
2272 		 * go more than 9 calls
2273 		 */
2274 		if (!ice_sched_is_tree_balanced(hw, node->children[i]))
2275 			return false;
2276 
2277 	return ice_sched_check_node(hw, node);
2278 }
2279 
2280 /**
2281  * ice_aq_query_node_to_root - retrieve the tree topology for a given node TEID
2282  * @hw: pointer to the HW struct
2283  * @node_teid: node TEID
2284  * @buf: pointer to buffer
2285  * @buf_size: buffer size in bytes
2286  * @cd: pointer to command details structure or NULL
2287  *
2288  * This function retrieves the tree topology from the firmware for a given
2289  * node TEID to the root node.
2290  */
2291 int
2292 ice_aq_query_node_to_root(struct ice_hw *hw, u32 node_teid,
2293 			  struct ice_aqc_txsched_elem_data *buf, u16 buf_size,
2294 			  struct ice_sq_cd *cd)
2295 {
2296 	struct ice_aqc_query_node_to_root *cmd;
2297 	struct ice_aq_desc desc;
2298 
2299 	cmd = &desc.params.query_node_to_root;
2300 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_query_node_to_root);
2301 	cmd->teid = CPU_TO_LE32(node_teid);
2302 	return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
2303 }
2304 
2305 /**
2306  * ice_get_agg_info - get the aggregator ID
2307  * @hw: pointer to the hardware structure
2308  * @agg_id: aggregator ID
2309  *
2310  * This function validates aggregator ID. The function returns info if
2311  * aggregator ID is present in list otherwise it returns null.
2312  */
2313 static struct ice_sched_agg_info *
2314 ice_get_agg_info(struct ice_hw *hw, u32 agg_id)
2315 {
2316 	struct ice_sched_agg_info *agg_info;
2317 
2318 	LIST_FOR_EACH_ENTRY(agg_info, &hw->agg_list, ice_sched_agg_info,
2319 			    list_entry)
2320 		if (agg_info->agg_id == agg_id)
2321 			return agg_info;
2322 
2323 	return NULL;
2324 }
2325 
2326 /**
2327  * ice_sched_get_free_vsi_parent - Find a free parent node in aggregator subtree
2328  * @hw: pointer to the HW struct
2329  * @node: pointer to a child node
2330  * @num_nodes: num nodes count array
2331  *
2332  * This function walks through the aggregator subtree to find a free parent
2333  * node
2334  */
2335 static struct ice_sched_node *
2336 ice_sched_get_free_vsi_parent(struct ice_hw *hw, struct ice_sched_node *node,
2337 			      u16 *num_nodes)
2338 {
2339 	u8 l = node->tx_sched_layer;
2340 	u8 vsil, i;
2341 
2342 	vsil = ice_sched_get_vsi_layer(hw);
2343 
2344 	/* Is it VSI parent layer ? */
2345 	if (l == vsil - 1)
2346 		return (node->num_children < hw->max_children[l]) ? node : NULL;
2347 
2348 	/* We have intermediate nodes. Let's walk through the subtree. If the
2349 	 * intermediate node has space to add a new node then clear the count
2350 	 */
2351 	if (node->num_children < hw->max_children[l])
2352 		num_nodes[l] = 0;
2353 	/* The below recursive call is intentional and wouldn't go more than
2354 	 * 2 or 3 iterations.
2355 	 */
2356 
2357 	for (i = 0; i < node->num_children; i++) {
2358 		struct ice_sched_node *parent;
2359 
2360 		parent = ice_sched_get_free_vsi_parent(hw, node->children[i],
2361 						       num_nodes);
2362 		if (parent)
2363 			return parent;
2364 	}
2365 
2366 	return NULL;
2367 }
2368 
2369 /**
2370  * ice_sched_update_parent - update the new parent in SW DB
2371  * @new_parent: pointer to a new parent node
2372  * @node: pointer to a child node
2373  *
2374  * This function removes the child from the old parent and adds it to a new
2375  * parent
2376  */
2377 void
2378 ice_sched_update_parent(struct ice_sched_node *new_parent,
2379 			struct ice_sched_node *node)
2380 {
2381 	struct ice_sched_node *old_parent;
2382 	u8 i, j;
2383 
2384 	old_parent = node->parent;
2385 
2386 	/* update the old parent children */
2387 	for (i = 0; i < old_parent->num_children; i++)
2388 		if (old_parent->children[i] == node) {
2389 			for (j = i + 1; j < old_parent->num_children; j++)
2390 				old_parent->children[j - 1] =
2391 					old_parent->children[j];
2392 			old_parent->num_children--;
2393 			break;
2394 		}
2395 
2396 	/* now move the node to a new parent */
2397 	new_parent->children[new_parent->num_children++] = node;
2398 	node->parent = new_parent;
2399 	node->info.parent_teid = new_parent->info.node_teid;
2400 }
2401 
2402 /**
2403  * ice_sched_move_nodes - move child nodes to a given parent
2404  * @pi: port information structure
2405  * @parent: pointer to parent node
2406  * @num_items: number of child nodes to be moved
2407  * @list: pointer to child node teids
2408  *
2409  * This function move the child nodes to a given parent.
2410  */
2411 int
2412 ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent,
2413 		     u16 num_items, u32 *list)
2414 {
2415 	struct ice_aqc_move_elem *buf;
2416 	struct ice_sched_node *node;
2417 	u16 i, grps_movd = 0;
2418 	struct ice_hw *hw;
2419 	int status = 0;
2420 	u16 buf_len;
2421 
2422 	hw = pi->hw;
2423 
2424 	if (!parent || !num_items)
2425 		return ICE_ERR_PARAM;
2426 
2427 	/* Does parent have enough space */
2428 	if (parent->num_children + num_items >
2429 	    hw->max_children[parent->tx_sched_layer])
2430 		return ICE_ERR_AQ_FULL;
2431 
2432 	buf_len = ice_struct_size(buf, teid, 1);
2433 	buf = (struct ice_aqc_move_elem *)ice_malloc(hw, buf_len);
2434 	if (!buf)
2435 		return ICE_ERR_NO_MEMORY;
2436 
2437 	for (i = 0; i < num_items; i++) {
2438 		node = ice_sched_find_node_by_teid(pi->root, list[i]);
2439 		if (!node) {
2440 			status = ICE_ERR_PARAM;
2441 			goto move_err_exit;
2442 		}
2443 
2444 		buf->hdr.src_parent_teid = node->info.parent_teid;
2445 		buf->hdr.dest_parent_teid = parent->info.node_teid;
2446 		buf->teid[0] = node->info.node_teid;
2447 		buf->hdr.num_elems = CPU_TO_LE16(1);
2448 		status = ice_aq_move_sched_elems(hw, 1, buf, buf_len,
2449 						 &grps_movd, NULL);
2450 		if (status && grps_movd != 1) {
2451 			status = ICE_ERR_CFG;
2452 			goto move_err_exit;
2453 		}
2454 
2455 		/* update the SW DB */
2456 		ice_sched_update_parent(parent, node);
2457 	}
2458 
2459 move_err_exit:
2460 	ice_free(hw, buf);
2461 	return status;
2462 }
2463 
2464 /**
2465  * ice_sched_move_vsi_to_agg - move VSI to aggregator node
2466  * @pi: port information structure
2467  * @vsi_handle: software VSI handle
2468  * @agg_id: aggregator ID
2469  * @tc: TC number
2470  *
2471  * This function moves a VSI to an aggregator node or its subtree.
2472  * Intermediate nodes may be created if required.
2473  */
2474 static int
2475 ice_sched_move_vsi_to_agg(struct ice_port_info *pi, u16 vsi_handle, u32 agg_id,
2476 			  u8 tc)
2477 {
2478 	struct ice_sched_node *vsi_node, *agg_node, *tc_node, *parent;
2479 	u16 num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 };
2480 	u32 first_node_teid, vsi_teid;
2481 	u16 num_nodes_added;
2482 	u8 aggl, vsil, i;
2483 	int status;
2484 
2485 	tc_node = ice_sched_get_tc_node(pi, tc);
2486 	if (!tc_node)
2487 		return ICE_ERR_CFG;
2488 
2489 	agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
2490 	if (!agg_node)
2491 		return ICE_ERR_DOES_NOT_EXIST;
2492 
2493 	vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
2494 	if (!vsi_node)
2495 		return ICE_ERR_DOES_NOT_EXIST;
2496 
2497 	/* Is this VSI already part of given aggregator? */
2498 	if (ice_sched_find_node_in_subtree(pi->hw, agg_node, vsi_node))
2499 		return 0;
2500 
2501 	aggl = ice_sched_get_agg_layer(pi->hw);
2502 	vsil = ice_sched_get_vsi_layer(pi->hw);
2503 
2504 	/* set intermediate node count to 1 between aggregator and VSI layers */
2505 	for (i = aggl + 1; i < vsil; i++)
2506 		num_nodes[i] = 1;
2507 
2508 	/* Check if the aggregator subtree has any free node to add the VSI */
2509 	for (i = 0; i < agg_node->num_children; i++) {
2510 		parent = ice_sched_get_free_vsi_parent(pi->hw,
2511 						       agg_node->children[i],
2512 						       num_nodes);
2513 		if (parent)
2514 			goto move_nodes;
2515 	}
2516 
2517 	/* add new nodes */
2518 	parent = agg_node;
2519 	for (i = aggl + 1; i < vsil; i++) {
2520 		status = ice_sched_add_nodes_to_layer(pi, tc_node, parent, i,
2521 						      num_nodes[i],
2522 						      &first_node_teid,
2523 						      &num_nodes_added);
2524 		if (status || num_nodes[i] != num_nodes_added)
2525 			return ICE_ERR_CFG;
2526 
2527 		/* The newly added node can be a new parent for the next
2528 		 * layer nodes
2529 		 */
2530 		if (num_nodes_added)
2531 			parent = ice_sched_find_node_by_teid(tc_node,
2532 							     first_node_teid);
2533 		else
2534 			parent = parent->children[0];
2535 
2536 		if (!parent)
2537 			return ICE_ERR_CFG;
2538 	}
2539 
2540 move_nodes:
2541 	vsi_teid = LE32_TO_CPU(vsi_node->info.node_teid);
2542 	return ice_sched_move_nodes(pi, parent, 1, &vsi_teid);
2543 }
2544 
2545 /**
2546  * ice_move_all_vsi_to_dflt_agg - move all VSI(s) to default aggregator
2547  * @pi: port information structure
2548  * @agg_info: aggregator info
2549  * @tc: traffic class number
2550  * @rm_vsi_info: true or false
2551  *
2552  * This function move all the VSI(s) to the default aggregator and delete
2553  * aggregator VSI info based on passed in boolean parameter rm_vsi_info. The
2554  * caller holds the scheduler lock.
2555  */
2556 static int
2557 ice_move_all_vsi_to_dflt_agg(struct ice_port_info *pi,
2558 			     struct ice_sched_agg_info *agg_info, u8 tc,
2559 			     bool rm_vsi_info)
2560 {
2561 	struct ice_sched_agg_vsi_info *agg_vsi_info;
2562 	struct ice_sched_agg_vsi_info *tmp;
2563 	int status = 0;
2564 
2565 	LIST_FOR_EACH_ENTRY_SAFE(agg_vsi_info, tmp, &agg_info->agg_vsi_list,
2566 				 ice_sched_agg_vsi_info, list_entry) {
2567 		u16 vsi_handle = agg_vsi_info->vsi_handle;
2568 
2569 		/* Move VSI to default aggregator */
2570 		if (!ice_is_tc_ena(agg_vsi_info->tc_bitmap[0], tc))
2571 			continue;
2572 
2573 		status = ice_sched_move_vsi_to_agg(pi, vsi_handle,
2574 						   ICE_DFLT_AGG_ID, tc);
2575 		if (status)
2576 			break;
2577 
2578 		ice_clear_bit(tc, agg_vsi_info->tc_bitmap);
2579 		if (rm_vsi_info && !agg_vsi_info->tc_bitmap[0]) {
2580 			LIST_DEL(&agg_vsi_info->list_entry);
2581 			ice_free(pi->hw, agg_vsi_info);
2582 		}
2583 	}
2584 
2585 	return status;
2586 }
2587 
2588 /**
2589  * ice_sched_is_agg_inuse - check whether the aggregator is in use or not
2590  * @pi: port information structure
2591  * @node: node pointer
2592  *
2593  * This function checks whether the aggregator is attached with any VSI or not.
2594  */
2595 static bool
2596 ice_sched_is_agg_inuse(struct ice_port_info *pi, struct ice_sched_node *node)
2597 {
2598 	u8 vsil, i;
2599 
2600 	vsil = ice_sched_get_vsi_layer(pi->hw);
2601 	if (node->tx_sched_layer < vsil - 1) {
2602 		for (i = 0; i < node->num_children; i++)
2603 			if (ice_sched_is_agg_inuse(pi, node->children[i]))
2604 				return true;
2605 		return false;
2606 	} else {
2607 		return node->num_children ? true : false;
2608 	}
2609 }
2610 
2611 /**
2612  * ice_sched_rm_agg_cfg - remove the aggregator node
2613  * @pi: port information structure
2614  * @agg_id: aggregator ID
2615  * @tc: TC number
2616  *
2617  * This function removes the aggregator node and intermediate nodes if any
2618  * from the given TC
2619  */
2620 static int
2621 ice_sched_rm_agg_cfg(struct ice_port_info *pi, u32 agg_id, u8 tc)
2622 {
2623 	struct ice_sched_node *tc_node, *agg_node;
2624 	struct ice_hw *hw = pi->hw;
2625 
2626 	tc_node = ice_sched_get_tc_node(pi, tc);
2627 	if (!tc_node)
2628 		return ICE_ERR_CFG;
2629 
2630 	agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
2631 	if (!agg_node)
2632 		return ICE_ERR_DOES_NOT_EXIST;
2633 
2634 	/* Can't remove the aggregator node if it has children */
2635 	if (ice_sched_is_agg_inuse(pi, agg_node))
2636 		return ICE_ERR_IN_USE;
2637 
2638 	/* need to remove the whole subtree if aggregator node is the
2639 	 * only child.
2640 	 */
2641 	while (agg_node->tx_sched_layer > hw->sw_entry_point_layer) {
2642 		struct ice_sched_node *parent = agg_node->parent;
2643 
2644 		if (!parent)
2645 			return ICE_ERR_CFG;
2646 
2647 		if (parent->num_children > 1)
2648 			break;
2649 
2650 		agg_node = parent;
2651 	}
2652 
2653 	ice_free_sched_node(pi, agg_node);
2654 	return 0;
2655 }
2656 
2657 /**
2658  * ice_rm_agg_cfg_tc - remove aggregator configuration for TC
2659  * @pi: port information structure
2660  * @agg_info: aggregator ID
2661  * @tc: TC number
2662  * @rm_vsi_info: bool value true or false
2663  *
2664  * This function removes aggregator reference to VSI of given TC. It removes
2665  * the aggregator configuration completely for requested TC. The caller needs
2666  * to hold the scheduler lock.
2667  */
2668 static int
2669 ice_rm_agg_cfg_tc(struct ice_port_info *pi, struct ice_sched_agg_info *agg_info,
2670 		  u8 tc, bool rm_vsi_info)
2671 {
2672 	int status = 0;
2673 
2674 	/* If nothing to remove - return success */
2675 	if (!ice_is_tc_ena(agg_info->tc_bitmap[0], tc))
2676 		goto exit_rm_agg_cfg_tc;
2677 
2678 	status = ice_move_all_vsi_to_dflt_agg(pi, agg_info, tc, rm_vsi_info);
2679 	if (status)
2680 		goto exit_rm_agg_cfg_tc;
2681 
2682 	/* Delete aggregator node(s) */
2683 	status = ice_sched_rm_agg_cfg(pi, agg_info->agg_id, tc);
2684 	if (status)
2685 		goto exit_rm_agg_cfg_tc;
2686 
2687 	ice_clear_bit(tc, agg_info->tc_bitmap);
2688 exit_rm_agg_cfg_tc:
2689 	return status;
2690 }
2691 
2692 /**
2693  * ice_save_agg_tc_bitmap - save aggregator TC bitmap
2694  * @pi: port information structure
2695  * @agg_id: aggregator ID
2696  * @tc_bitmap: 8 bits TC bitmap
2697  *
2698  * Save aggregator TC bitmap. This function needs to be called with scheduler
2699  * lock held.
2700  */
2701 static int
2702 ice_save_agg_tc_bitmap(struct ice_port_info *pi, u32 agg_id,
2703 		       ice_bitmap_t *tc_bitmap)
2704 {
2705 	struct ice_sched_agg_info *agg_info;
2706 
2707 	agg_info = ice_get_agg_info(pi->hw, agg_id);
2708 	if (!agg_info)
2709 		return ICE_ERR_PARAM;
2710 	ice_cp_bitmap(agg_info->replay_tc_bitmap, tc_bitmap,
2711 		      ICE_MAX_TRAFFIC_CLASS);
2712 	return 0;
2713 }
2714 
2715 /**
2716  * ice_sched_add_agg_cfg - create an aggregator node
2717  * @pi: port information structure
2718  * @agg_id: aggregator ID
2719  * @tc: TC number
2720  *
2721  * This function creates an aggregator node and intermediate nodes if required
2722  * for the given TC
2723  */
2724 static int
2725 ice_sched_add_agg_cfg(struct ice_port_info *pi, u32 agg_id, u8 tc)
2726 {
2727 	struct ice_sched_node *parent, *agg_node, *tc_node;
2728 	u16 num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 };
2729 	struct ice_hw *hw = pi->hw;
2730 	u32 first_node_teid;
2731 	u16 num_nodes_added;
2732 	int status = 0;
2733 	u8 i, aggl;
2734 
2735 	tc_node = ice_sched_get_tc_node(pi, tc);
2736 	if (!tc_node)
2737 		return ICE_ERR_CFG;
2738 
2739 	agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
2740 	/* Does Agg node already exist ? */
2741 	if (agg_node)
2742 		return status;
2743 
2744 	aggl = ice_sched_get_agg_layer(hw);
2745 
2746 	/* need one node in Agg layer */
2747 	num_nodes[aggl] = 1;
2748 
2749 	/* Check whether the intermediate nodes have space to add the
2750 	 * new aggregator. If they are full, then SW needs to allocate a new
2751 	 * intermediate node on those layers
2752 	 */
2753 	for (i = hw->sw_entry_point_layer; i < aggl; i++) {
2754 		parent = ice_sched_get_first_node(pi, tc_node, i);
2755 
2756 		/* scan all the siblings */
2757 		while (parent) {
2758 			if (parent->num_children < hw->max_children[i])
2759 				break;
2760 			parent = parent->sibling;
2761 		}
2762 
2763 		/* all the nodes are full, reserve one for this layer */
2764 		if (!parent)
2765 			num_nodes[i]++;
2766 	}
2767 
2768 	/* add the aggregator node */
2769 	parent = tc_node;
2770 	for (i = hw->sw_entry_point_layer; i <= aggl; i++) {
2771 		if (!parent)
2772 			return ICE_ERR_CFG;
2773 
2774 		status = ice_sched_add_nodes_to_layer(pi, tc_node, parent, i,
2775 						      num_nodes[i],
2776 						      &first_node_teid,
2777 						      &num_nodes_added);
2778 		if (status || num_nodes[i] != num_nodes_added)
2779 			return ICE_ERR_CFG;
2780 
2781 		/* The newly added node can be a new parent for the next
2782 		 * layer nodes
2783 		 */
2784 		if (num_nodes_added) {
2785 			parent = ice_sched_find_node_by_teid(tc_node,
2786 							     first_node_teid);
2787 			/* register aggregator ID with the aggregator node */
2788 			if (parent && i == aggl)
2789 				parent->agg_id = agg_id;
2790 		} else {
2791 			parent = parent->children[0];
2792 		}
2793 	}
2794 
2795 	return 0;
2796 }
2797 
2798 /**
2799  * ice_sched_cfg_agg - configure aggregator node
2800  * @pi: port information structure
2801  * @agg_id: aggregator ID
2802  * @agg_type: aggregator type queue, VSI, or aggregator group
2803  * @tc_bitmap: bits TC bitmap
2804  *
2805  * It registers a unique aggregator node into scheduler services. It
2806  * allows a user to register with a unique ID to track it's resources.
2807  * The aggregator type determines if this is a queue group, VSI group
2808  * or aggregator group. It then creates the aggregator node(s) for requested
2809  * TC(s) or removes an existing aggregator node including its configuration
2810  * if indicated via tc_bitmap. Call ice_rm_agg_cfg to release aggregator
2811  * resources and remove aggregator ID.
2812  * This function needs to be called with scheduler lock held.
2813  */
2814 static int
2815 ice_sched_cfg_agg(struct ice_port_info *pi, u32 agg_id,
2816 		  enum ice_agg_type agg_type, ice_bitmap_t *tc_bitmap)
2817 {
2818 	struct ice_sched_agg_info *agg_info;
2819 	struct ice_hw *hw = pi->hw;
2820 	int status = 0;
2821 	u8 tc;
2822 
2823 	agg_info = ice_get_agg_info(hw, agg_id);
2824 	if (!agg_info) {
2825 		/* Create new entry for new aggregator ID */
2826 		agg_info = (struct ice_sched_agg_info *)
2827 			ice_malloc(hw, sizeof(*agg_info));
2828 		if (!agg_info)
2829 			return ICE_ERR_NO_MEMORY;
2830 
2831 		agg_info->agg_id = agg_id;
2832 		agg_info->agg_type = agg_type;
2833 		agg_info->tc_bitmap[0] = 0;
2834 
2835 		/* Initialize the aggregator VSI list head */
2836 		INIT_LIST_HEAD(&agg_info->agg_vsi_list);
2837 
2838 		/* Add new entry in aggregator list */
2839 		LIST_ADD(&agg_info->list_entry, &hw->agg_list);
2840 	}
2841 	/* Create aggregator node(s) for requested TC(s) */
2842 	ice_for_each_traffic_class(tc) {
2843 		if (!ice_is_tc_ena(*tc_bitmap, tc)) {
2844 			/* Delete aggregator cfg TC if it exists previously */
2845 			status = ice_rm_agg_cfg_tc(pi, agg_info, tc, false);
2846 			if (status)
2847 				break;
2848 			continue;
2849 		}
2850 
2851 		/* Check if aggregator node for TC already exists */
2852 		if (ice_is_tc_ena(agg_info->tc_bitmap[0], tc))
2853 			continue;
2854 
2855 		/* Create new aggregator node for TC */
2856 		status = ice_sched_add_agg_cfg(pi, agg_id, tc);
2857 		if (status)
2858 			break;
2859 
2860 		/* Save aggregator node's TC information */
2861 		ice_set_bit(tc, agg_info->tc_bitmap);
2862 	}
2863 
2864 	return status;
2865 }
2866 
2867 /**
2868  * ice_cfg_agg - config aggregator node
2869  * @pi: port information structure
2870  * @agg_id: aggregator ID
2871  * @agg_type: aggregator type queue, VSI, or aggregator group
2872  * @tc_bitmap: bits TC bitmap
2873  *
2874  * This function configures aggregator node(s).
2875  */
2876 int
2877 ice_cfg_agg(struct ice_port_info *pi, u32 agg_id, enum ice_agg_type agg_type,
2878 	    u8 tc_bitmap)
2879 {
2880 	ice_bitmap_t bitmap = tc_bitmap;
2881 	int status;
2882 
2883 	ice_acquire_lock(&pi->sched_lock);
2884 	status = ice_sched_cfg_agg(pi, agg_id, agg_type,
2885 				   (ice_bitmap_t *)&bitmap);
2886 	if (!status)
2887 		status = ice_save_agg_tc_bitmap(pi, agg_id,
2888 						(ice_bitmap_t *)&bitmap);
2889 	ice_release_lock(&pi->sched_lock);
2890 	return status;
2891 }
2892 
2893 /**
2894  * ice_get_agg_vsi_info - get the aggregator ID
2895  * @agg_info: aggregator info
2896  * @vsi_handle: software VSI handle
2897  *
2898  * The function returns aggregator VSI info based on VSI handle. This function
2899  * needs to be called with scheduler lock held.
2900  */
2901 static struct ice_sched_agg_vsi_info *
2902 ice_get_agg_vsi_info(struct ice_sched_agg_info *agg_info, u16 vsi_handle)
2903 {
2904 	struct ice_sched_agg_vsi_info *agg_vsi_info;
2905 
2906 	LIST_FOR_EACH_ENTRY(agg_vsi_info, &agg_info->agg_vsi_list,
2907 			    ice_sched_agg_vsi_info, list_entry)
2908 		if (agg_vsi_info->vsi_handle == vsi_handle)
2909 			return agg_vsi_info;
2910 
2911 	return NULL;
2912 }
2913 
2914 /**
2915  * ice_get_vsi_agg_info - get the aggregator info of VSI
2916  * @hw: pointer to the hardware structure
2917  * @vsi_handle: Sw VSI handle
2918  *
2919  * The function returns aggregator info of VSI represented via vsi_handle. The
2920  * VSI has in this case a different aggregator than the default one. This
2921  * function needs to be called with scheduler lock held.
2922  */
2923 static struct ice_sched_agg_info *
2924 ice_get_vsi_agg_info(struct ice_hw *hw, u16 vsi_handle)
2925 {
2926 	struct ice_sched_agg_info *agg_info;
2927 
2928 	LIST_FOR_EACH_ENTRY(agg_info, &hw->agg_list, ice_sched_agg_info,
2929 			    list_entry) {
2930 		struct ice_sched_agg_vsi_info *agg_vsi_info;
2931 
2932 		agg_vsi_info = ice_get_agg_vsi_info(agg_info, vsi_handle);
2933 		if (agg_vsi_info)
2934 			return agg_info;
2935 	}
2936 	return NULL;
2937 }
2938 
2939 /**
2940  * ice_save_agg_vsi_tc_bitmap - save aggregator VSI TC bitmap
2941  * @pi: port information structure
2942  * @agg_id: aggregator ID
2943  * @vsi_handle: software VSI handle
2944  * @tc_bitmap: TC bitmap of enabled TC(s)
2945  *
2946  * Save VSI to aggregator TC bitmap. This function needs to call with scheduler
2947  * lock held.
2948  */
2949 static int
2950 ice_save_agg_vsi_tc_bitmap(struct ice_port_info *pi, u32 agg_id, u16 vsi_handle,
2951 			   ice_bitmap_t *tc_bitmap)
2952 {
2953 	struct ice_sched_agg_vsi_info *agg_vsi_info;
2954 	struct ice_sched_agg_info *agg_info;
2955 
2956 	agg_info = ice_get_agg_info(pi->hw, agg_id);
2957 	if (!agg_info)
2958 		return ICE_ERR_PARAM;
2959 	/* check if entry already exist */
2960 	agg_vsi_info = ice_get_agg_vsi_info(agg_info, vsi_handle);
2961 	if (!agg_vsi_info)
2962 		return ICE_ERR_PARAM;
2963 	ice_cp_bitmap(agg_vsi_info->replay_tc_bitmap, tc_bitmap,
2964 		      ICE_MAX_TRAFFIC_CLASS);
2965 	return 0;
2966 }
2967 
2968 /**
2969  * ice_sched_assoc_vsi_to_agg - associate/move VSI to new/default aggregator
2970  * @pi: port information structure
2971  * @agg_id: aggregator ID
2972  * @vsi_handle: software VSI handle
2973  * @tc_bitmap: TC bitmap of enabled TC(s)
2974  *
2975  * This function moves VSI to a new or default aggregator node. If VSI is
2976  * already associated to the aggregator node then no operation is performed on
2977  * the tree. This function needs to be called with scheduler lock held.
2978  */
2979 static int
2980 ice_sched_assoc_vsi_to_agg(struct ice_port_info *pi, u32 agg_id,
2981 			   u16 vsi_handle, ice_bitmap_t *tc_bitmap)
2982 {
2983 	struct ice_sched_agg_vsi_info *agg_vsi_info, *old_agg_vsi_info = NULL;
2984 	struct ice_sched_agg_info *agg_info, *old_agg_info;
2985 	struct ice_hw *hw = pi->hw;
2986 	int status = 0;
2987 	u8 tc;
2988 
2989 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
2990 		return ICE_ERR_PARAM;
2991 	agg_info = ice_get_agg_info(hw, agg_id);
2992 	if (!agg_info)
2993 		return ICE_ERR_PARAM;
2994 	/* If the vsi is already part of another aggregator then update
2995 	 * its vsi info list
2996 	 */
2997 	old_agg_info = ice_get_vsi_agg_info(hw, vsi_handle);
2998 	if (old_agg_info && old_agg_info != agg_info) {
2999 		struct ice_sched_agg_vsi_info *vtmp;
3000 
3001 		LIST_FOR_EACH_ENTRY_SAFE(old_agg_vsi_info, vtmp,
3002 					 &old_agg_info->agg_vsi_list,
3003 					 ice_sched_agg_vsi_info, list_entry)
3004 			if (old_agg_vsi_info->vsi_handle == vsi_handle)
3005 				break;
3006 	}
3007 
3008 	/* check if entry already exist */
3009 	agg_vsi_info = ice_get_agg_vsi_info(agg_info, vsi_handle);
3010 	if (!agg_vsi_info) {
3011 		/* Create new entry for VSI under aggregator list */
3012 		agg_vsi_info = (struct ice_sched_agg_vsi_info *)
3013 			ice_malloc(hw, sizeof(*agg_vsi_info));
3014 		if (!agg_vsi_info)
3015 			return ICE_ERR_PARAM;
3016 
3017 		/* add VSI ID into the aggregator list */
3018 		agg_vsi_info->vsi_handle = vsi_handle;
3019 		LIST_ADD(&agg_vsi_info->list_entry, &agg_info->agg_vsi_list);
3020 	}
3021 	/* Move VSI node to new aggregator node for requested TC(s) */
3022 	ice_for_each_traffic_class(tc) {
3023 		if (!ice_is_tc_ena(*tc_bitmap, tc))
3024 			continue;
3025 
3026 		/* Move VSI to new aggregator */
3027 		status = ice_sched_move_vsi_to_agg(pi, vsi_handle, agg_id, tc);
3028 		if (status)
3029 			break;
3030 
3031 		ice_set_bit(tc, agg_vsi_info->tc_bitmap);
3032 		if (old_agg_vsi_info)
3033 			ice_clear_bit(tc, old_agg_vsi_info->tc_bitmap);
3034 	}
3035 	if (old_agg_vsi_info && !old_agg_vsi_info->tc_bitmap[0]) {
3036 		LIST_DEL(&old_agg_vsi_info->list_entry);
3037 		ice_free(pi->hw, old_agg_vsi_info);
3038 	}
3039 	return status;
3040 }
3041 
3042 /**
3043  * ice_sched_rm_unused_rl_prof - remove unused RL profile
3044  * @hw: pointer to the hardware structure
3045  *
3046  * This function removes unused rate limit profiles from the HW and
3047  * SW DB. The caller needs to hold scheduler lock.
3048  */
3049 static void ice_sched_rm_unused_rl_prof(struct ice_hw *hw)
3050 {
3051 	u16 ln;
3052 
3053 	for (ln = 0; ln < hw->num_tx_sched_layers; ln++) {
3054 		struct ice_aqc_rl_profile_info *rl_prof_elem;
3055 		struct ice_aqc_rl_profile_info *rl_prof_tmp;
3056 
3057 		LIST_FOR_EACH_ENTRY_SAFE(rl_prof_elem, rl_prof_tmp,
3058 					 &hw->rl_prof_list[ln],
3059 					 ice_aqc_rl_profile_info, list_entry) {
3060 			if (!ice_sched_del_rl_profile(hw, rl_prof_elem))
3061 				ice_debug(hw, ICE_DBG_SCHED, "Removed rl profile\n");
3062 		}
3063 	}
3064 }
3065 
3066 /**
3067  * ice_sched_update_elem - update element
3068  * @hw: pointer to the HW struct
3069  * @node: pointer to node
3070  * @info: node info to update
3071  *
3072  * Update the HW DB, and local SW DB of node. Update the scheduling
3073  * parameters of node from argument info data buffer (Info->data buf) and
3074  * returns success or error on config sched element failure. The caller
3075  * needs to hold scheduler lock.
3076  */
3077 static int
3078 ice_sched_update_elem(struct ice_hw *hw, struct ice_sched_node *node,
3079 		      struct ice_aqc_txsched_elem_data *info)
3080 {
3081 	struct ice_aqc_txsched_elem_data buf;
3082 	u16 elem_cfgd = 0;
3083 	u16 num_elems = 1;
3084 	int status;
3085 
3086 	buf = *info;
3087 	/* For TC nodes, CIR config is not supported */
3088 	if (node->info.data.elem_type == ICE_AQC_ELEM_TYPE_TC)
3089 		buf.data.valid_sections &= ~ICE_AQC_ELEM_VALID_CIR;
3090 	/* Parent TEID is reserved field in this aq call */
3091 	buf.parent_teid = 0;
3092 	/* Element type is reserved field in this aq call */
3093 	buf.data.elem_type = 0;
3094 	/* Flags is reserved field in this aq call */
3095 	buf.data.flags = 0;
3096 
3097 	/* Update HW DB */
3098 	/* Configure element node */
3099 	status = ice_aq_cfg_sched_elems(hw, num_elems, &buf, sizeof(buf),
3100 					&elem_cfgd, NULL);
3101 	if (status || elem_cfgd != num_elems) {
3102 		ice_debug(hw, ICE_DBG_SCHED, "Config sched elem error\n");
3103 		return ICE_ERR_CFG;
3104 	}
3105 
3106 	/* Config success case */
3107 	/* Now update local SW DB */
3108 	/* Only copy the data portion of info buffer */
3109 	node->info.data = info->data;
3110 	return status;
3111 }
3112 
3113 /**
3114  * ice_sched_cfg_node_bw_alloc - configure node BW weight/alloc params
3115  * @hw: pointer to the HW struct
3116  * @node: sched node to configure
3117  * @rl_type: rate limit type CIR, EIR, or shared
3118  * @bw_alloc: BW weight/allocation
3119  *
3120  * This function configures node element's BW allocation.
3121  */
3122 static int
3123 ice_sched_cfg_node_bw_alloc(struct ice_hw *hw, struct ice_sched_node *node,
3124 			    enum ice_rl_type rl_type, u16 bw_alloc)
3125 {
3126 	struct ice_aqc_txsched_elem_data buf;
3127 	struct ice_aqc_txsched_elem *data;
3128 	int status;
3129 
3130 	buf = node->info;
3131 	data = &buf.data;
3132 	if (rl_type == ICE_MIN_BW) {
3133 		data->valid_sections |= ICE_AQC_ELEM_VALID_CIR;
3134 		data->cir_bw.bw_alloc = CPU_TO_LE16(bw_alloc);
3135 	} else if (rl_type == ICE_MAX_BW) {
3136 		data->valid_sections |= ICE_AQC_ELEM_VALID_EIR;
3137 		data->eir_bw.bw_alloc = CPU_TO_LE16(bw_alloc);
3138 	} else {
3139 		return ICE_ERR_PARAM;
3140 	}
3141 
3142 	/* Configure element */
3143 	status = ice_sched_update_elem(hw, node, &buf);
3144 	return status;
3145 }
3146 
3147 /**
3148  * ice_move_vsi_to_agg - moves VSI to new or default aggregator
3149  * @pi: port information structure
3150  * @agg_id: aggregator ID
3151  * @vsi_handle: software VSI handle
3152  * @tc_bitmap: TC bitmap of enabled TC(s)
3153  *
3154  * Move or associate VSI to a new or default aggregator node.
3155  */
3156 int
3157 ice_move_vsi_to_agg(struct ice_port_info *pi, u32 agg_id, u16 vsi_handle,
3158 		    u8 tc_bitmap)
3159 {
3160 	ice_bitmap_t bitmap = tc_bitmap;
3161 	int status;
3162 
3163 	ice_acquire_lock(&pi->sched_lock);
3164 	status = ice_sched_assoc_vsi_to_agg(pi, agg_id, vsi_handle,
3165 					    (ice_bitmap_t *)&bitmap);
3166 	if (!status)
3167 		status = ice_save_agg_vsi_tc_bitmap(pi, agg_id, vsi_handle,
3168 						    (ice_bitmap_t *)&bitmap);
3169 	ice_release_lock(&pi->sched_lock);
3170 	return status;
3171 }
3172 
3173 /**
3174  * ice_rm_agg_cfg - remove aggregator configuration
3175  * @pi: port information structure
3176  * @agg_id: aggregator ID
3177  *
3178  * This function removes aggregator reference to VSI and delete aggregator ID
3179  * info. It removes the aggregator configuration completely.
3180  */
3181 int ice_rm_agg_cfg(struct ice_port_info *pi, u32 agg_id)
3182 {
3183 	struct ice_sched_agg_info *agg_info;
3184 	int status = 0;
3185 	u8 tc;
3186 
3187 	ice_acquire_lock(&pi->sched_lock);
3188 	agg_info = ice_get_agg_info(pi->hw, agg_id);
3189 	if (!agg_info) {
3190 		status = ICE_ERR_DOES_NOT_EXIST;
3191 		goto exit_ice_rm_agg_cfg;
3192 	}
3193 
3194 	ice_for_each_traffic_class(tc) {
3195 		status = ice_rm_agg_cfg_tc(pi, agg_info, tc, true);
3196 		if (status)
3197 			goto exit_ice_rm_agg_cfg;
3198 	}
3199 
3200 	if (ice_is_any_bit_set(agg_info->tc_bitmap, ICE_MAX_TRAFFIC_CLASS)) {
3201 		status = ICE_ERR_IN_USE;
3202 		goto exit_ice_rm_agg_cfg;
3203 	}
3204 
3205 	/* Safe to delete entry now */
3206 	LIST_DEL(&agg_info->list_entry);
3207 	ice_free(pi->hw, agg_info);
3208 
3209 	/* Remove unused RL profile IDs from HW and SW DB */
3210 	ice_sched_rm_unused_rl_prof(pi->hw);
3211 
3212 exit_ice_rm_agg_cfg:
3213 	ice_release_lock(&pi->sched_lock);
3214 	return status;
3215 }
3216 
3217 /**
3218  * ice_set_clear_cir_bw_alloc - set or clear CIR BW alloc information
3219  * @bw_t_info: bandwidth type information structure
3220  * @bw_alloc: Bandwidth allocation information
3221  *
3222  * Save or clear CIR BW alloc information (bw_alloc) in the passed param
3223  * bw_t_info.
3224  */
3225 static void
3226 ice_set_clear_cir_bw_alloc(struct ice_bw_type_info *bw_t_info, u16 bw_alloc)
3227 {
3228 	bw_t_info->cir_bw.bw_alloc = bw_alloc;
3229 	if (bw_t_info->cir_bw.bw_alloc)
3230 		ice_set_bit(ICE_BW_TYPE_CIR_WT, bw_t_info->bw_t_bitmap);
3231 	else
3232 		ice_clear_bit(ICE_BW_TYPE_CIR_WT, bw_t_info->bw_t_bitmap);
3233 }
3234 
3235 /**
3236  * ice_set_clear_eir_bw_alloc - set or clear EIR BW alloc information
3237  * @bw_t_info: bandwidth type information structure
3238  * @bw_alloc: Bandwidth allocation information
3239  *
3240  * Save or clear EIR BW alloc information (bw_alloc) in the passed param
3241  * bw_t_info.
3242  */
3243 static void
3244 ice_set_clear_eir_bw_alloc(struct ice_bw_type_info *bw_t_info, u16 bw_alloc)
3245 {
3246 	bw_t_info->eir_bw.bw_alloc = bw_alloc;
3247 	if (bw_t_info->eir_bw.bw_alloc)
3248 		ice_set_bit(ICE_BW_TYPE_EIR_WT, bw_t_info->bw_t_bitmap);
3249 	else
3250 		ice_clear_bit(ICE_BW_TYPE_EIR_WT, bw_t_info->bw_t_bitmap);
3251 }
3252 
3253 /**
3254  * ice_sched_save_vsi_bw_alloc - save VSI node's BW alloc information
3255  * @pi: port information structure
3256  * @vsi_handle: sw VSI handle
3257  * @tc: traffic class
3258  * @rl_type: rate limit type min or max
3259  * @bw_alloc: Bandwidth allocation information
3260  *
3261  * Save BW alloc information of VSI type node for post replay use.
3262  */
3263 static int
3264 ice_sched_save_vsi_bw_alloc(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
3265 			    enum ice_rl_type rl_type, u16 bw_alloc)
3266 {
3267 	struct ice_vsi_ctx *vsi_ctx;
3268 
3269 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
3270 		return ICE_ERR_PARAM;
3271 	vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
3272 	if (!vsi_ctx)
3273 		return ICE_ERR_PARAM;
3274 	switch (rl_type) {
3275 	case ICE_MIN_BW:
3276 		ice_set_clear_cir_bw_alloc(&vsi_ctx->sched.bw_t_info[tc],
3277 					   bw_alloc);
3278 		break;
3279 	case ICE_MAX_BW:
3280 		ice_set_clear_eir_bw_alloc(&vsi_ctx->sched.bw_t_info[tc],
3281 					   bw_alloc);
3282 		break;
3283 	default:
3284 		return ICE_ERR_PARAM;
3285 	}
3286 	return 0;
3287 }
3288 
3289 /**
3290  * ice_set_clear_cir_bw - set or clear CIR BW
3291  * @bw_t_info: bandwidth type information structure
3292  * @bw: bandwidth in Kbps - Kilo bits per sec
3293  *
3294  * Save or clear CIR bandwidth (BW) in the passed param bw_t_info.
3295  */
3296 static void ice_set_clear_cir_bw(struct ice_bw_type_info *bw_t_info, u32 bw)
3297 {
3298 	if (bw == ICE_SCHED_DFLT_BW) {
3299 		ice_clear_bit(ICE_BW_TYPE_CIR, bw_t_info->bw_t_bitmap);
3300 		bw_t_info->cir_bw.bw = 0;
3301 	} else {
3302 		/* Save type of BW information */
3303 		ice_set_bit(ICE_BW_TYPE_CIR, bw_t_info->bw_t_bitmap);
3304 		bw_t_info->cir_bw.bw = bw;
3305 	}
3306 }
3307 
3308 /**
3309  * ice_set_clear_eir_bw - set or clear EIR BW
3310  * @bw_t_info: bandwidth type information structure
3311  * @bw: bandwidth in Kbps - Kilo bits per sec
3312  *
3313  * Save or clear EIR bandwidth (BW) in the passed param bw_t_info.
3314  */
3315 static void ice_set_clear_eir_bw(struct ice_bw_type_info *bw_t_info, u32 bw)
3316 {
3317 	if (bw == ICE_SCHED_DFLT_BW) {
3318 		ice_clear_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap);
3319 		bw_t_info->eir_bw.bw = 0;
3320 	} else {
3321 		/* save EIR BW information */
3322 		ice_set_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap);
3323 		bw_t_info->eir_bw.bw = bw;
3324 	}
3325 }
3326 
3327 /**
3328  * ice_set_clear_shared_bw - set or clear shared BW
3329  * @bw_t_info: bandwidth type information structure
3330  * @bw: bandwidth in Kbps - Kilo bits per sec
3331  *
3332  * Save or clear shared bandwidth (BW) in the passed param bw_t_info.
3333  */
3334 static void ice_set_clear_shared_bw(struct ice_bw_type_info *bw_t_info, u32 bw)
3335 {
3336 	if (bw == ICE_SCHED_DFLT_BW) {
3337 		ice_clear_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap);
3338 		bw_t_info->shared_bw = 0;
3339 	} else {
3340 		/* save shared BW information */
3341 		ice_set_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap);
3342 		bw_t_info->shared_bw = bw;
3343 	}
3344 }
3345 
3346 /**
3347  * ice_sched_save_vsi_bw - save VSI node's BW information
3348  * @pi: port information structure
3349  * @vsi_handle: sw VSI handle
3350  * @tc: traffic class
3351  * @rl_type: rate limit type min, max, or shared
3352  * @bw: bandwidth in Kbps - Kilo bits per sec
3353  *
3354  * Save BW information of VSI type node for post replay use.
3355  */
3356 static int
3357 ice_sched_save_vsi_bw(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
3358 		      enum ice_rl_type rl_type, u32 bw)
3359 {
3360 	struct ice_vsi_ctx *vsi_ctx;
3361 
3362 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
3363 		return ICE_ERR_PARAM;
3364 	vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
3365 	if (!vsi_ctx)
3366 		return ICE_ERR_PARAM;
3367 	switch (rl_type) {
3368 	case ICE_MIN_BW:
3369 		ice_set_clear_cir_bw(&vsi_ctx->sched.bw_t_info[tc], bw);
3370 		break;
3371 	case ICE_MAX_BW:
3372 		ice_set_clear_eir_bw(&vsi_ctx->sched.bw_t_info[tc], bw);
3373 		break;
3374 	case ICE_SHARED_BW:
3375 		ice_set_clear_shared_bw(&vsi_ctx->sched.bw_t_info[tc], bw);
3376 		break;
3377 	default:
3378 		return ICE_ERR_PARAM;
3379 	}
3380 	return 0;
3381 }
3382 
3383 /**
3384  * ice_set_clear_prio - set or clear priority information
3385  * @bw_t_info: bandwidth type information structure
3386  * @prio: priority to save
3387  *
3388  * Save or clear priority (prio) in the passed param bw_t_info.
3389  */
3390 static void ice_set_clear_prio(struct ice_bw_type_info *bw_t_info, u8 prio)
3391 {
3392 	bw_t_info->generic = prio;
3393 	if (bw_t_info->generic)
3394 		ice_set_bit(ICE_BW_TYPE_PRIO, bw_t_info->bw_t_bitmap);
3395 	else
3396 		ice_clear_bit(ICE_BW_TYPE_PRIO, bw_t_info->bw_t_bitmap);
3397 }
3398 
3399 /**
3400  * ice_sched_save_vsi_prio - save VSI node's priority information
3401  * @pi: port information structure
3402  * @vsi_handle: Software VSI handle
3403  * @tc: traffic class
3404  * @prio: priority to save
3405  *
3406  * Save priority information of VSI type node for post replay use.
3407  */
3408 static int
3409 ice_sched_save_vsi_prio(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
3410 			u8 prio)
3411 {
3412 	struct ice_vsi_ctx *vsi_ctx;
3413 
3414 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
3415 		return ICE_ERR_PARAM;
3416 	vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
3417 	if (!vsi_ctx)
3418 		return ICE_ERR_PARAM;
3419 	if (tc >= ICE_MAX_TRAFFIC_CLASS)
3420 		return ICE_ERR_PARAM;
3421 	ice_set_clear_prio(&vsi_ctx->sched.bw_t_info[tc], prio);
3422 	return 0;
3423 }
3424 
3425 /**
3426  * ice_sched_save_agg_bw_alloc - save aggregator node's BW alloc information
3427  * @pi: port information structure
3428  * @agg_id: node aggregator ID
3429  * @tc: traffic class
3430  * @rl_type: rate limit type min or max
3431  * @bw_alloc: bandwidth alloc information
3432  *
3433  * Save BW alloc information of AGG type node for post replay use.
3434  */
3435 static int
3436 ice_sched_save_agg_bw_alloc(struct ice_port_info *pi, u32 agg_id, u8 tc,
3437 			    enum ice_rl_type rl_type, u16 bw_alloc)
3438 {
3439 	struct ice_sched_agg_info *agg_info;
3440 
3441 	agg_info = ice_get_agg_info(pi->hw, agg_id);
3442 	if (!agg_info)
3443 		return ICE_ERR_PARAM;
3444 	if (!ice_is_tc_ena(agg_info->tc_bitmap[0], tc))
3445 		return ICE_ERR_PARAM;
3446 	switch (rl_type) {
3447 	case ICE_MIN_BW:
3448 		ice_set_clear_cir_bw_alloc(&agg_info->bw_t_info[tc], bw_alloc);
3449 		break;
3450 	case ICE_MAX_BW:
3451 		ice_set_clear_eir_bw_alloc(&agg_info->bw_t_info[tc], bw_alloc);
3452 		break;
3453 	default:
3454 		return ICE_ERR_PARAM;
3455 	}
3456 	return 0;
3457 }
3458 
3459 /**
3460  * ice_sched_save_agg_bw - save aggregator node's BW information
3461  * @pi: port information structure
3462  * @agg_id: node aggregator ID
3463  * @tc: traffic class
3464  * @rl_type: rate limit type min, max, or shared
3465  * @bw: bandwidth in Kbps - Kilo bits per sec
3466  *
3467  * Save BW information of AGG type node for post replay use.
3468  */
3469 static int
3470 ice_sched_save_agg_bw(struct ice_port_info *pi, u32 agg_id, u8 tc,
3471 		      enum ice_rl_type rl_type, u32 bw)
3472 {
3473 	struct ice_sched_agg_info *agg_info;
3474 
3475 	agg_info = ice_get_agg_info(pi->hw, agg_id);
3476 	if (!agg_info)
3477 		return ICE_ERR_PARAM;
3478 	if (!ice_is_tc_ena(agg_info->tc_bitmap[0], tc))
3479 		return ICE_ERR_PARAM;
3480 	switch (rl_type) {
3481 	case ICE_MIN_BW:
3482 		ice_set_clear_cir_bw(&agg_info->bw_t_info[tc], bw);
3483 		break;
3484 	case ICE_MAX_BW:
3485 		ice_set_clear_eir_bw(&agg_info->bw_t_info[tc], bw);
3486 		break;
3487 	case ICE_SHARED_BW:
3488 		ice_set_clear_shared_bw(&agg_info->bw_t_info[tc], bw);
3489 		break;
3490 	default:
3491 		return ICE_ERR_PARAM;
3492 	}
3493 	return 0;
3494 }
3495 
3496 /**
3497  * ice_cfg_vsi_bw_lmt_per_tc - configure VSI BW limit per TC
3498  * @pi: port information structure
3499  * @vsi_handle: software VSI handle
3500  * @tc: traffic class
3501  * @rl_type: min or max
3502  * @bw: bandwidth in Kbps
3503  *
3504  * This function configures BW limit of VSI scheduling node based on TC
3505  * information.
3506  */
3507 int
3508 ice_cfg_vsi_bw_lmt_per_tc(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
3509 			  enum ice_rl_type rl_type, u32 bw)
3510 {
3511 	int status;
3512 
3513 	status = ice_sched_set_node_bw_lmt_per_tc(pi, vsi_handle,
3514 						  ICE_AGG_TYPE_VSI,
3515 						  tc, rl_type, bw);
3516 	if (!status) {
3517 		ice_acquire_lock(&pi->sched_lock);
3518 		status = ice_sched_save_vsi_bw(pi, vsi_handle, tc, rl_type, bw);
3519 		ice_release_lock(&pi->sched_lock);
3520 	}
3521 	return status;
3522 }
3523 
3524 /**
3525  * ice_cfg_vsi_bw_dflt_lmt_per_tc - configure default VSI BW limit per TC
3526  * @pi: port information structure
3527  * @vsi_handle: software VSI handle
3528  * @tc: traffic class
3529  * @rl_type: min or max
3530  *
3531  * This function configures default BW limit of VSI scheduling node based on TC
3532  * information.
3533  */
3534 int
3535 ice_cfg_vsi_bw_dflt_lmt_per_tc(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
3536 			       enum ice_rl_type rl_type)
3537 {
3538 	int status;
3539 
3540 	status = ice_sched_set_node_bw_lmt_per_tc(pi, vsi_handle,
3541 						  ICE_AGG_TYPE_VSI,
3542 						  tc, rl_type,
3543 						  ICE_SCHED_DFLT_BW);
3544 	if (!status) {
3545 		ice_acquire_lock(&pi->sched_lock);
3546 		status = ice_sched_save_vsi_bw(pi, vsi_handle, tc, rl_type,
3547 					       ICE_SCHED_DFLT_BW);
3548 		ice_release_lock(&pi->sched_lock);
3549 	}
3550 	return status;
3551 }
3552 
3553 /**
3554  * ice_cfg_agg_bw_lmt_per_tc - configure aggregator BW limit per TC
3555  * @pi: port information structure
3556  * @agg_id: aggregator ID
3557  * @tc: traffic class
3558  * @rl_type: min or max
3559  * @bw: bandwidth in Kbps
3560  *
3561  * This function applies BW limit to aggregator scheduling node based on TC
3562  * information.
3563  */
3564 int
3565 ice_cfg_agg_bw_lmt_per_tc(struct ice_port_info *pi, u32 agg_id, u8 tc,
3566 			  enum ice_rl_type rl_type, u32 bw)
3567 {
3568 	int status;
3569 
3570 	status = ice_sched_set_node_bw_lmt_per_tc(pi, agg_id, ICE_AGG_TYPE_AGG,
3571 						  tc, rl_type, bw);
3572 	if (!status) {
3573 		ice_acquire_lock(&pi->sched_lock);
3574 		status = ice_sched_save_agg_bw(pi, agg_id, tc, rl_type, bw);
3575 		ice_release_lock(&pi->sched_lock);
3576 	}
3577 	return status;
3578 }
3579 
3580 /**
3581  * ice_cfg_agg_bw_dflt_lmt_per_tc - configure aggregator BW default limit per TC
3582  * @pi: port information structure
3583  * @agg_id: aggregator ID
3584  * @tc: traffic class
3585  * @rl_type: min or max
3586  *
3587  * This function applies default BW limit to aggregator scheduling node based
3588  * on TC information.
3589  */
3590 int
3591 ice_cfg_agg_bw_dflt_lmt_per_tc(struct ice_port_info *pi, u32 agg_id, u8 tc,
3592 			       enum ice_rl_type rl_type)
3593 {
3594 	int status;
3595 
3596 	status = ice_sched_set_node_bw_lmt_per_tc(pi, agg_id, ICE_AGG_TYPE_AGG,
3597 						  tc, rl_type,
3598 						  ICE_SCHED_DFLT_BW);
3599 	if (!status) {
3600 		ice_acquire_lock(&pi->sched_lock);
3601 		status = ice_sched_save_agg_bw(pi, agg_id, tc, rl_type,
3602 					       ICE_SCHED_DFLT_BW);
3603 		ice_release_lock(&pi->sched_lock);
3604 	}
3605 	return status;
3606 }
3607 
3608 /**
3609  * ice_cfg_vsi_bw_shared_lmt - configure VSI BW shared limit
3610  * @pi: port information structure
3611  * @vsi_handle: software VSI handle
3612  * @min_bw: minimum bandwidth in Kbps
3613  * @max_bw: maximum bandwidth in Kbps
3614  * @shared_bw: shared bandwidth in Kbps
3615  *
3616  * Configure shared rate limiter(SRL) of all VSI type nodes across all traffic
3617  * classes for VSI matching handle.
3618  */
3619 int
3620 ice_cfg_vsi_bw_shared_lmt(struct ice_port_info *pi, u16 vsi_handle, u32 min_bw,
3621 			  u32 max_bw, u32 shared_bw)
3622 {
3623 	return ice_sched_set_vsi_bw_shared_lmt(pi, vsi_handle, min_bw, max_bw,
3624 					       shared_bw);
3625 }
3626 
3627 /**
3628  * ice_cfg_vsi_bw_no_shared_lmt - configure VSI BW for no shared limiter
3629  * @pi: port information structure
3630  * @vsi_handle: software VSI handle
3631  *
3632  * This function removes the shared rate limiter(SRL) of all VSI type nodes
3633  * across all traffic classes for VSI matching handle.
3634  */
3635 int
3636 ice_cfg_vsi_bw_no_shared_lmt(struct ice_port_info *pi, u16 vsi_handle)
3637 {
3638 	return ice_sched_set_vsi_bw_shared_lmt(pi, vsi_handle,
3639 					       ICE_SCHED_DFLT_BW,
3640 					       ICE_SCHED_DFLT_BW,
3641 					       ICE_SCHED_DFLT_BW);
3642 }
3643 
3644 /**
3645  * ice_cfg_agg_bw_shared_lmt - configure aggregator BW shared limit
3646  * @pi: port information structure
3647  * @agg_id: aggregator ID
3648  * @min_bw: minimum bandwidth in Kbps
3649  * @max_bw: maximum bandwidth in Kbps
3650  * @shared_bw: shared bandwidth in Kbps
3651  *
3652  * This function configures the shared rate limiter(SRL) of all aggregator type
3653  * nodes across all traffic classes for aggregator matching agg_id.
3654  */
3655 int
3656 ice_cfg_agg_bw_shared_lmt(struct ice_port_info *pi, u32 agg_id, u32 min_bw,
3657 			  u32 max_bw, u32 shared_bw)
3658 {
3659 	return ice_sched_set_agg_bw_shared_lmt(pi, agg_id, min_bw, max_bw,
3660 					       shared_bw);
3661 }
3662 
3663 /**
3664  * ice_cfg_agg_bw_no_shared_lmt - configure aggregator BW for no shared limiter
3665  * @pi: port information structure
3666  * @agg_id: aggregator ID
3667  *
3668  * This function removes the shared rate limiter(SRL) of all aggregator type
3669  * nodes across all traffic classes for aggregator matching agg_id.
3670  */
3671 int
3672 ice_cfg_agg_bw_no_shared_lmt(struct ice_port_info *pi, u32 agg_id)
3673 {
3674 	return ice_sched_set_agg_bw_shared_lmt(pi, agg_id, ICE_SCHED_DFLT_BW,
3675 					       ICE_SCHED_DFLT_BW,
3676 					       ICE_SCHED_DFLT_BW);
3677 }
3678 
3679 /**
3680  * ice_cfg_agg_bw_shared_lmt_per_tc - config aggregator BW shared limit per tc
3681  * @pi: port information structure
3682  * @agg_id: aggregator ID
3683  * @tc: traffic class
3684  * @min_bw: minimum bandwidth in Kbps
3685  * @max_bw: maximum bandwidth in Kbps
3686  * @shared_bw: shared bandwidth in Kbps
3687  *
3688  * This function configures the shared rate limiter(SRL) of all aggregator type
3689  * nodes across all traffic classes for aggregator matching agg_id.
3690  */
3691 int
3692 ice_cfg_agg_bw_shared_lmt_per_tc(struct ice_port_info *pi, u32 agg_id, u8 tc,
3693 				 u32 min_bw, u32 max_bw, u32 shared_bw)
3694 {
3695 	return ice_sched_set_agg_bw_shared_lmt_per_tc(pi, agg_id, tc, min_bw,
3696 						      max_bw, shared_bw);
3697 }
3698 
3699 /**
3700  * ice_cfg_agg_bw_no_shared_lmt_per_tc - cfg aggregator BW shared limit per tc
3701  * @pi: port information structure
3702  * @agg_id: aggregator ID
3703  * @tc: traffic class
3704  *
3705  * This function configures the shared rate limiter(SRL) of all aggregator type
3706  * nodes across all traffic classes for aggregator matching agg_id.
3707  */
3708 int
3709 ice_cfg_agg_bw_no_shared_lmt_per_tc(struct ice_port_info *pi, u32 agg_id, u8 tc)
3710 {
3711 	return ice_sched_set_agg_bw_shared_lmt_per_tc(pi, agg_id, tc,
3712 						      ICE_SCHED_DFLT_BW,
3713 						      ICE_SCHED_DFLT_BW,
3714 						      ICE_SCHED_DFLT_BW);
3715 }
3716 
3717 /**
3718  * ice_cfg_vsi_q_priority - config VSI queue priority of node
3719  * @pi: port information structure
3720  * @num_qs: number of VSI queues
3721  * @q_ids: queue IDs array
3722  * @q_prio: queue priority array
3723  *
3724  * This function configures the queue node priority (Sibling Priority) of the
3725  * passed in VSI's queue(s) for a given traffic class (TC).
3726  */
3727 int
3728 ice_cfg_vsi_q_priority(struct ice_port_info *pi, u16 num_qs, u32 *q_ids,
3729 		       u8 *q_prio)
3730 {
3731 	int status = ICE_ERR_PARAM;
3732 	u16 i;
3733 
3734 	ice_acquire_lock(&pi->sched_lock);
3735 
3736 	for (i = 0; i < num_qs; i++) {
3737 		struct ice_sched_node *node;
3738 
3739 		node = ice_sched_find_node_by_teid(pi->root, q_ids[i]);
3740 		if (!node || node->info.data.elem_type !=
3741 		    ICE_AQC_ELEM_TYPE_LEAF) {
3742 			status = ICE_ERR_PARAM;
3743 			break;
3744 		}
3745 		/* Configure Priority */
3746 		status = ice_sched_cfg_sibl_node_prio(pi, node, q_prio[i]);
3747 		if (status)
3748 			break;
3749 	}
3750 
3751 	ice_release_lock(&pi->sched_lock);
3752 	return status;
3753 }
3754 
3755 /**
3756  * ice_cfg_agg_vsi_priority_per_tc - config aggregator's VSI priority per TC
3757  * @pi: port information structure
3758  * @agg_id: Aggregator ID
3759  * @num_vsis: number of VSI(s)
3760  * @vsi_handle_arr: array of software VSI handles
3761  * @node_prio: pointer to node priority
3762  * @tc: traffic class
3763  *
3764  * This function configures the node priority (Sibling Priority) of the
3765  * passed in VSI's for a given traffic class (TC) of an Aggregator ID.
3766  */
3767 int
3768 ice_cfg_agg_vsi_priority_per_tc(struct ice_port_info *pi, u32 agg_id,
3769 				u16 num_vsis, u16 *vsi_handle_arr,
3770 				u8 *node_prio, u8 tc)
3771 {
3772 	struct ice_sched_agg_vsi_info *agg_vsi_info;
3773 	struct ice_sched_node *tc_node, *agg_node;
3774 	struct ice_sched_agg_info *agg_info;
3775 	bool agg_id_present = false;
3776 	struct ice_hw *hw = pi->hw;
3777 	int status = ICE_ERR_PARAM;
3778 	u16 i;
3779 
3780 	ice_acquire_lock(&pi->sched_lock);
3781 	LIST_FOR_EACH_ENTRY(agg_info, &hw->agg_list, ice_sched_agg_info,
3782 			    list_entry)
3783 		if (agg_info->agg_id == agg_id) {
3784 			agg_id_present = true;
3785 			break;
3786 		}
3787 	if (!agg_id_present)
3788 		goto exit_agg_priority_per_tc;
3789 
3790 	tc_node = ice_sched_get_tc_node(pi, tc);
3791 	if (!tc_node)
3792 		goto exit_agg_priority_per_tc;
3793 
3794 	agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
3795 	if (!agg_node)
3796 		goto exit_agg_priority_per_tc;
3797 
3798 	if (num_vsis > hw->max_children[agg_node->tx_sched_layer])
3799 		goto exit_agg_priority_per_tc;
3800 
3801 	for (i = 0; i < num_vsis; i++) {
3802 		struct ice_sched_node *vsi_node;
3803 		bool vsi_handle_valid = false;
3804 		u16 vsi_handle;
3805 
3806 		status = ICE_ERR_PARAM;
3807 		vsi_handle = vsi_handle_arr[i];
3808 		if (!ice_is_vsi_valid(hw, vsi_handle))
3809 			goto exit_agg_priority_per_tc;
3810 		/* Verify child nodes before applying settings */
3811 		LIST_FOR_EACH_ENTRY(agg_vsi_info, &agg_info->agg_vsi_list,
3812 				    ice_sched_agg_vsi_info, list_entry)
3813 			if (agg_vsi_info->vsi_handle == vsi_handle) {
3814 				vsi_handle_valid = true;
3815 				break;
3816 			}
3817 
3818 		if (!vsi_handle_valid)
3819 			goto exit_agg_priority_per_tc;
3820 
3821 		vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
3822 		if (!vsi_node)
3823 			goto exit_agg_priority_per_tc;
3824 
3825 		if (ice_sched_find_node_in_subtree(hw, agg_node, vsi_node)) {
3826 			/* Configure Priority */
3827 			status = ice_sched_cfg_sibl_node_prio(pi, vsi_node,
3828 							      node_prio[i]);
3829 			if (status)
3830 				break;
3831 			status = ice_sched_save_vsi_prio(pi, vsi_handle, tc,
3832 							 node_prio[i]);
3833 			if (status)
3834 				break;
3835 		}
3836 	}
3837 
3838 exit_agg_priority_per_tc:
3839 	ice_release_lock(&pi->sched_lock);
3840 	return status;
3841 }
3842 
3843 /**
3844  * ice_cfg_vsi_bw_alloc - config VSI BW alloc per TC
3845  * @pi: port information structure
3846  * @vsi_handle: software VSI handle
3847  * @ena_tcmap: enabled TC map
3848  * @rl_type: Rate limit type CIR/EIR
3849  * @bw_alloc: Array of BW alloc
3850  *
3851  * This function configures the BW allocation of the passed in VSI's
3852  * node(s) for enabled traffic class.
3853  */
3854 int
3855 ice_cfg_vsi_bw_alloc(struct ice_port_info *pi, u16 vsi_handle, u8 ena_tcmap,
3856 		     enum ice_rl_type rl_type, u8 *bw_alloc)
3857 {
3858 	int status = 0;
3859 	u8 tc;
3860 
3861 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
3862 		return ICE_ERR_PARAM;
3863 
3864 	ice_acquire_lock(&pi->sched_lock);
3865 
3866 	/* Return success if no nodes are present across TC */
3867 	ice_for_each_traffic_class(tc) {
3868 		struct ice_sched_node *tc_node, *vsi_node;
3869 
3870 		if (!ice_is_tc_ena(ena_tcmap, tc))
3871 			continue;
3872 
3873 		tc_node = ice_sched_get_tc_node(pi, tc);
3874 		if (!tc_node)
3875 			continue;
3876 
3877 		vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
3878 		if (!vsi_node)
3879 			continue;
3880 
3881 		status = ice_sched_cfg_node_bw_alloc(pi->hw, vsi_node, rl_type,
3882 						     bw_alloc[tc]);
3883 		if (status)
3884 			break;
3885 		status = ice_sched_save_vsi_bw_alloc(pi, vsi_handle, tc,
3886 						     rl_type, bw_alloc[tc]);
3887 		if (status)
3888 			break;
3889 	}
3890 
3891 	ice_release_lock(&pi->sched_lock);
3892 	return status;
3893 }
3894 
3895 /**
3896  * ice_cfg_agg_bw_alloc - config aggregator BW alloc
3897  * @pi: port information structure
3898  * @agg_id: aggregator ID
3899  * @ena_tcmap: enabled TC map
3900  * @rl_type: rate limit type CIR/EIR
3901  * @bw_alloc: array of BW alloc
3902  *
3903  * This function configures the BW allocation of passed in aggregator for
3904  * enabled traffic class(s).
3905  */
3906 int
3907 ice_cfg_agg_bw_alloc(struct ice_port_info *pi, u32 agg_id, u8 ena_tcmap,
3908 		     enum ice_rl_type rl_type, u8 *bw_alloc)
3909 {
3910 	struct ice_sched_agg_info *agg_info;
3911 	bool agg_id_present = false;
3912 	struct ice_hw *hw = pi->hw;
3913 	int status = 0;
3914 	u8 tc;
3915 
3916 	ice_acquire_lock(&pi->sched_lock);
3917 	LIST_FOR_EACH_ENTRY(agg_info, &hw->agg_list, ice_sched_agg_info,
3918 			    list_entry)
3919 		if (agg_info->agg_id == agg_id) {
3920 			agg_id_present = true;
3921 			break;
3922 		}
3923 	if (!agg_id_present) {
3924 		status = ICE_ERR_PARAM;
3925 		goto exit_cfg_agg_bw_alloc;
3926 	}
3927 
3928 	/* Return success if no nodes are present across TC */
3929 	ice_for_each_traffic_class(tc) {
3930 		struct ice_sched_node *tc_node, *agg_node;
3931 
3932 		if (!ice_is_tc_ena(ena_tcmap, tc))
3933 			continue;
3934 
3935 		tc_node = ice_sched_get_tc_node(pi, tc);
3936 		if (!tc_node)
3937 			continue;
3938 
3939 		agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
3940 		if (!agg_node)
3941 			continue;
3942 
3943 		status = ice_sched_cfg_node_bw_alloc(hw, agg_node, rl_type,
3944 						     bw_alloc[tc]);
3945 		if (status)
3946 			break;
3947 		status = ice_sched_save_agg_bw_alloc(pi, agg_id, tc, rl_type,
3948 						     bw_alloc[tc]);
3949 		if (status)
3950 			break;
3951 	}
3952 
3953 exit_cfg_agg_bw_alloc:
3954 	ice_release_lock(&pi->sched_lock);
3955 	return status;
3956 }
3957 
3958 /**
3959  * ice_sched_calc_wakeup - calculate RL profile wakeup parameter
3960  * @hw: pointer to the HW struct
3961  * @bw: bandwidth in Kbps
3962  *
3963  * This function calculates the wakeup parameter of RL profile.
3964  */
3965 static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw)
3966 {
3967 	s64 bytes_per_sec, wakeup_int, wakeup_a, wakeup_b, wakeup_f;
3968 	s32 wakeup_f_int;
3969 	u16 wakeup = 0;
3970 
3971 	/* Get the wakeup integer value */
3972 	bytes_per_sec = DIV_S64((s64)bw * 1000, BITS_PER_BYTE);
3973 	wakeup_int = DIV_S64(hw->psm_clk_freq, bytes_per_sec);
3974 	if (wakeup_int > 63) {
3975 		wakeup = (u16)((1 << 15) | wakeup_int);
3976 	} else {
3977 		/* Calculate fraction value up to 4 decimals
3978 		 * Convert Integer value to a constant multiplier
3979 		 */
3980 		wakeup_b = (s64)ICE_RL_PROF_MULTIPLIER * wakeup_int;
3981 		wakeup_a = DIV_S64((s64)ICE_RL_PROF_MULTIPLIER *
3982 				   hw->psm_clk_freq, bytes_per_sec);
3983 
3984 		/* Get Fraction value */
3985 		wakeup_f = wakeup_a - wakeup_b;
3986 
3987 		/* Round up the Fractional value via Ceil(Fractional value) */
3988 		if (wakeup_f > DIV_S64(ICE_RL_PROF_MULTIPLIER, 2))
3989 			wakeup_f += 1;
3990 
3991 		wakeup_f_int = (s32)DIV_S64(wakeup_f * ICE_RL_PROF_FRACTION,
3992 					    ICE_RL_PROF_MULTIPLIER);
3993 		wakeup |= (u16)(wakeup_int << 9);
3994 		wakeup |= (u16)(0x1ff & wakeup_f_int);
3995 	}
3996 
3997 	return wakeup;
3998 }
3999 
4000 /**
4001  * ice_sched_bw_to_rl_profile - convert BW to profile parameters
4002  * @hw: pointer to the HW struct
4003  * @bw: bandwidth in Kbps
4004  * @profile: profile parameters to return
4005  *
4006  * This function converts the BW to profile structure format.
4007  */
4008 static int
4009 ice_sched_bw_to_rl_profile(struct ice_hw *hw, u32 bw,
4010 			   struct ice_aqc_rl_profile_elem *profile)
4011 {
4012 	s64 bytes_per_sec, ts_rate, mv_tmp;
4013 	int status = ICE_ERR_PARAM;
4014 	bool found = false;
4015 	s32 encode = 0;
4016 	s64 mv = 0;
4017 	s32 i;
4018 
4019 	/* Bw settings range is from 0.5Mb/sec to 100Gb/sec */
4020 	if (bw < ICE_SCHED_MIN_BW || bw > ICE_SCHED_MAX_BW)
4021 		return status;
4022 
4023 	/* Bytes per second from Kbps */
4024 	bytes_per_sec = DIV_S64((s64)bw * 1000, BITS_PER_BYTE);
4025 
4026 	/* encode is 6 bits but really useful are 5 bits */
4027 	for (i = 0; i < 64; i++) {
4028 		u64 pow_result = BIT_ULL(i);
4029 
4030 		ts_rate = DIV_S64((s64)hw->psm_clk_freq,
4031 				  pow_result * ICE_RL_PROF_TS_MULTIPLIER);
4032 		if (ts_rate <= 0)
4033 			continue;
4034 
4035 		/* Multiplier value */
4036 		mv_tmp = DIV_S64(bytes_per_sec * ICE_RL_PROF_MULTIPLIER,
4037 				 ts_rate);
4038 
4039 		/* Round to the nearest ICE_RL_PROF_MULTIPLIER */
4040 		mv = round_up_64bit(mv_tmp, ICE_RL_PROF_MULTIPLIER);
4041 
4042 		/* First multiplier value greater than the given
4043 		 * accuracy bytes
4044 		 */
4045 		if (mv > ICE_RL_PROF_ACCURACY_BYTES) {
4046 			encode = i;
4047 			found = true;
4048 			break;
4049 		}
4050 	}
4051 	if (found) {
4052 		u16 wm;
4053 
4054 		wm = ice_sched_calc_wakeup(hw, bw);
4055 		profile->rl_multiply = CPU_TO_LE16(mv);
4056 		profile->wake_up_calc = CPU_TO_LE16(wm);
4057 		profile->rl_encode = CPU_TO_LE16(encode);
4058 		status = 0;
4059 	} else {
4060 		status = ICE_ERR_DOES_NOT_EXIST;
4061 	}
4062 
4063 	return status;
4064 }
4065 
4066 /**
4067  * ice_sched_add_rl_profile - add RL profile
4068  * @hw: pointer to the hardware structure
4069  * @rl_type: type of rate limit BW - min, max, or shared
4070  * @bw: bandwidth in Kbps - Kilo bits per sec
4071  * @layer_num: specifies in which layer to create profile
4072  *
4073  * This function first checks the existing list for corresponding BW
4074  * parameter. If it exists, it returns the associated profile otherwise
4075  * it creates a new rate limit profile for requested BW, and adds it to
4076  * the HW DB and local list. It returns the new profile or null on error.
4077  * The caller needs to hold the scheduler lock.
4078  */
4079 static struct ice_aqc_rl_profile_info *
4080 ice_sched_add_rl_profile(struct ice_hw *hw, enum ice_rl_type rl_type,
4081 			 u32 bw, u8 layer_num)
4082 {
4083 	struct ice_aqc_rl_profile_info *rl_prof_elem;
4084 	u16 profiles_added = 0, num_profiles = 1;
4085 	struct ice_aqc_rl_profile_elem *buf;
4086 	u8 profile_type;
4087 	int status;
4088 
4089 	if (!hw || layer_num >= hw->num_tx_sched_layers)
4090 		return NULL;
4091 	switch (rl_type) {
4092 	case ICE_MIN_BW:
4093 		profile_type = ICE_AQC_RL_PROFILE_TYPE_CIR;
4094 		break;
4095 	case ICE_MAX_BW:
4096 		profile_type = ICE_AQC_RL_PROFILE_TYPE_EIR;
4097 		break;
4098 	case ICE_SHARED_BW:
4099 		profile_type = ICE_AQC_RL_PROFILE_TYPE_SRL;
4100 		break;
4101 	default:
4102 		return NULL;
4103 	}
4104 
4105 	LIST_FOR_EACH_ENTRY(rl_prof_elem, &hw->rl_prof_list[layer_num],
4106 			    ice_aqc_rl_profile_info, list_entry)
4107 		if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) ==
4108 		    profile_type && rl_prof_elem->bw == bw)
4109 			/* Return existing profile ID info */
4110 			return rl_prof_elem;
4111 
4112 	/* Create new profile ID */
4113 	rl_prof_elem = (struct ice_aqc_rl_profile_info *)
4114 		ice_malloc(hw, sizeof(*rl_prof_elem));
4115 
4116 	if (!rl_prof_elem)
4117 		return NULL;
4118 
4119 	status = ice_sched_bw_to_rl_profile(hw, bw, &rl_prof_elem->profile);
4120 	if (status)
4121 		goto exit_add_rl_prof;
4122 
4123 	rl_prof_elem->bw = bw;
4124 	/* layer_num is zero relative, and fw expects level from 1 to 9 */
4125 	rl_prof_elem->profile.level = layer_num + 1;
4126 	rl_prof_elem->profile.flags = profile_type;
4127 	rl_prof_elem->profile.max_burst_size = CPU_TO_LE16(hw->max_burst_size);
4128 
4129 	/* Create new entry in HW DB */
4130 	buf = &rl_prof_elem->profile;
4131 	status = ice_aq_add_rl_profile(hw, num_profiles, buf, sizeof(*buf),
4132 				       &profiles_added, NULL);
4133 	if (status || profiles_added != num_profiles)
4134 		goto exit_add_rl_prof;
4135 
4136 	/* Good entry - add in the list */
4137 	rl_prof_elem->prof_id_ref = 0;
4138 	LIST_ADD(&rl_prof_elem->list_entry, &hw->rl_prof_list[layer_num]);
4139 	return rl_prof_elem;
4140 
4141 exit_add_rl_prof:
4142 	ice_free(hw, rl_prof_elem);
4143 	return NULL;
4144 }
4145 
4146 /**
4147  * ice_sched_cfg_node_bw_lmt - configure node sched params
4148  * @hw: pointer to the HW struct
4149  * @node: sched node to configure
4150  * @rl_type: rate limit type CIR, EIR, or shared
4151  * @rl_prof_id: rate limit profile ID
4152  *
4153  * This function configures node element's BW limit.
4154  */
4155 static int
4156 ice_sched_cfg_node_bw_lmt(struct ice_hw *hw, struct ice_sched_node *node,
4157 			  enum ice_rl_type rl_type, u16 rl_prof_id)
4158 {
4159 	struct ice_aqc_txsched_elem_data buf;
4160 	struct ice_aqc_txsched_elem *data;
4161 
4162 	buf = node->info;
4163 	data = &buf.data;
4164 	switch (rl_type) {
4165 	case ICE_MIN_BW:
4166 		data->valid_sections |= ICE_AQC_ELEM_VALID_CIR;
4167 		data->cir_bw.bw_profile_idx = CPU_TO_LE16(rl_prof_id);
4168 		break;
4169 	case ICE_MAX_BW:
4170 		data->valid_sections |= ICE_AQC_ELEM_VALID_EIR;
4171 		data->eir_bw.bw_profile_idx = CPU_TO_LE16(rl_prof_id);
4172 		break;
4173 	case ICE_SHARED_BW:
4174 		data->valid_sections |= ICE_AQC_ELEM_VALID_SHARED;
4175 		data->srl_id = CPU_TO_LE16(rl_prof_id);
4176 		break;
4177 	default:
4178 		/* Unknown rate limit type */
4179 		return ICE_ERR_PARAM;
4180 	}
4181 
4182 	/* Configure element */
4183 	return ice_sched_update_elem(hw, node, &buf);
4184 }
4185 
4186 /**
4187  * ice_sched_get_node_rl_prof_id - get node's rate limit profile ID
4188  * @node: sched node
4189  * @rl_type: rate limit type
4190  *
4191  * If existing profile matches, it returns the corresponding rate
4192  * limit profile ID, otherwise it returns an invalid ID as error.
4193  */
4194 static u16
4195 ice_sched_get_node_rl_prof_id(struct ice_sched_node *node,
4196 			      enum ice_rl_type rl_type)
4197 {
4198 	u16 rl_prof_id = ICE_SCHED_INVAL_PROF_ID;
4199 	struct ice_aqc_txsched_elem *data;
4200 
4201 	data = &node->info.data;
4202 	switch (rl_type) {
4203 	case ICE_MIN_BW:
4204 		if (data->valid_sections & ICE_AQC_ELEM_VALID_CIR)
4205 			rl_prof_id = LE16_TO_CPU(data->cir_bw.bw_profile_idx);
4206 		break;
4207 	case ICE_MAX_BW:
4208 		if (data->valid_sections & ICE_AQC_ELEM_VALID_EIR)
4209 			rl_prof_id = LE16_TO_CPU(data->eir_bw.bw_profile_idx);
4210 		break;
4211 	case ICE_SHARED_BW:
4212 		if (data->valid_sections & ICE_AQC_ELEM_VALID_SHARED)
4213 			rl_prof_id = LE16_TO_CPU(data->srl_id);
4214 		break;
4215 	default:
4216 		break;
4217 	}
4218 
4219 	return rl_prof_id;
4220 }
4221 
4222 /**
4223  * ice_sched_get_rl_prof_layer - selects rate limit profile creation layer
4224  * @pi: port information structure
4225  * @rl_type: type of rate limit BW - min, max, or shared
4226  * @layer_index: layer index
4227  *
4228  * This function returns requested profile creation layer.
4229  */
4230 static u8
4231 ice_sched_get_rl_prof_layer(struct ice_port_info *pi, enum ice_rl_type rl_type,
4232 			    u8 layer_index)
4233 {
4234 	struct ice_hw *hw = pi->hw;
4235 
4236 	if (layer_index >= hw->num_tx_sched_layers)
4237 		return ICE_SCHED_INVAL_LAYER_NUM;
4238 	switch (rl_type) {
4239 	case ICE_MIN_BW:
4240 		if (hw->layer_info[layer_index].max_cir_rl_profiles)
4241 			return layer_index;
4242 		break;
4243 	case ICE_MAX_BW:
4244 		if (hw->layer_info[layer_index].max_eir_rl_profiles)
4245 			return layer_index;
4246 		break;
4247 	case ICE_SHARED_BW:
4248 		/* if current layer doesn't support SRL profile creation
4249 		 * then try a layer up or down.
4250 		 */
4251 		if (hw->layer_info[layer_index].max_srl_profiles)
4252 			return layer_index;
4253 		else if (layer_index < hw->num_tx_sched_layers - 1 &&
4254 			 hw->layer_info[layer_index + 1].max_srl_profiles)
4255 			return layer_index + 1;
4256 		else if (layer_index > 0 &&
4257 			 hw->layer_info[layer_index - 1].max_srl_profiles)
4258 			return layer_index - 1;
4259 		break;
4260 	default:
4261 		break;
4262 	}
4263 	return ICE_SCHED_INVAL_LAYER_NUM;
4264 }
4265 
4266 /**
4267  * ice_sched_get_srl_node - get shared rate limit node
4268  * @node: tree node
4269  * @srl_layer: shared rate limit layer
4270  *
4271  * This function returns SRL node to be used for shared rate limit purpose.
4272  * The caller needs to hold scheduler lock.
4273  */
4274 static struct ice_sched_node *
4275 ice_sched_get_srl_node(struct ice_sched_node *node, u8 srl_layer)
4276 {
4277 	if (srl_layer > node->tx_sched_layer)
4278 		return node->children[0];
4279 	else if (srl_layer < node->tx_sched_layer)
4280 		/* Node can't be created without a parent. It will always
4281 		 * have a valid parent except root node.
4282 		 */
4283 		return node->parent;
4284 	else
4285 		return node;
4286 }
4287 
4288 /**
4289  * ice_sched_rm_rl_profile - remove RL profile ID
4290  * @hw: pointer to the hardware structure
4291  * @layer_num: layer number where profiles are saved
4292  * @profile_type: profile type like EIR, CIR, or SRL
4293  * @profile_id: profile ID to remove
4294  *
4295  * This function removes rate limit profile from layer 'layer_num' of type
4296  * 'profile_type' and profile ID as 'profile_id'. The caller needs to hold
4297  * scheduler lock.
4298  */
4299 static int
4300 ice_sched_rm_rl_profile(struct ice_hw *hw, u8 layer_num, u8 profile_type,
4301 			u16 profile_id)
4302 {
4303 	struct ice_aqc_rl_profile_info *rl_prof_elem;
4304 	int status = 0;
4305 
4306 	if (!hw || layer_num >= hw->num_tx_sched_layers)
4307 		return ICE_ERR_PARAM;
4308 	/* Check the existing list for RL profile */
4309 	LIST_FOR_EACH_ENTRY(rl_prof_elem, &hw->rl_prof_list[layer_num],
4310 			    ice_aqc_rl_profile_info, list_entry)
4311 		if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) ==
4312 		    profile_type &&
4313 		    LE16_TO_CPU(rl_prof_elem->profile.profile_id) ==
4314 		    profile_id) {
4315 			if (rl_prof_elem->prof_id_ref)
4316 				rl_prof_elem->prof_id_ref--;
4317 
4318 			/* Remove old profile ID from database */
4319 			status = ice_sched_del_rl_profile(hw, rl_prof_elem);
4320 			if (status && status != ICE_ERR_IN_USE)
4321 				ice_debug(hw, ICE_DBG_SCHED, "Remove rl profile failed\n");
4322 			break;
4323 		}
4324 	if (status == ICE_ERR_IN_USE)
4325 		status = 0;
4326 	return status;
4327 }
4328 
4329 /**
4330  * ice_sched_set_node_bw_dflt - set node's bandwidth limit to default
4331  * @pi: port information structure
4332  * @node: pointer to node structure
4333  * @rl_type: rate limit type min, max, or shared
4334  * @layer_num: layer number where RL profiles are saved
4335  *
4336  * This function configures node element's BW rate limit profile ID of
4337  * type CIR, EIR, or SRL to default. This function needs to be called
4338  * with the scheduler lock held.
4339  */
4340 static int
4341 ice_sched_set_node_bw_dflt(struct ice_port_info *pi,
4342 			   struct ice_sched_node *node,
4343 			   enum ice_rl_type rl_type, u8 layer_num)
4344 {
4345 	struct ice_hw *hw;
4346 	u8 profile_type;
4347 	u16 rl_prof_id;
4348 	int status;
4349 	u16 old_id;
4350 
4351 	hw = pi->hw;
4352 	switch (rl_type) {
4353 	case ICE_MIN_BW:
4354 		profile_type = ICE_AQC_RL_PROFILE_TYPE_CIR;
4355 		rl_prof_id = ICE_SCHED_DFLT_RL_PROF_ID;
4356 		break;
4357 	case ICE_MAX_BW:
4358 		profile_type = ICE_AQC_RL_PROFILE_TYPE_EIR;
4359 		rl_prof_id = ICE_SCHED_DFLT_RL_PROF_ID;
4360 		break;
4361 	case ICE_SHARED_BW:
4362 		profile_type = ICE_AQC_RL_PROFILE_TYPE_SRL;
4363 		/* No SRL is configured for default case */
4364 		rl_prof_id = ICE_SCHED_NO_SHARED_RL_PROF_ID;
4365 		break;
4366 	default:
4367 		return ICE_ERR_PARAM;
4368 	}
4369 	/* Save existing RL prof ID for later clean up */
4370 	old_id = ice_sched_get_node_rl_prof_id(node, rl_type);
4371 	/* Configure BW scheduling parameters */
4372 	status = ice_sched_cfg_node_bw_lmt(hw, node, rl_type, rl_prof_id);
4373 	if (status)
4374 		return status;
4375 
4376 	/* Remove stale RL profile ID */
4377 	if (old_id == ICE_SCHED_DFLT_RL_PROF_ID ||
4378 	    old_id == ICE_SCHED_INVAL_PROF_ID)
4379 		return 0;
4380 
4381 	return ice_sched_rm_rl_profile(hw, layer_num, profile_type, old_id);
4382 }
4383 
4384 /**
4385  * ice_sched_set_node_bw - set node's bandwidth
4386  * @pi: port information structure
4387  * @node: tree node
4388  * @rl_type: rate limit type min, max, or shared
4389  * @bw: bandwidth in Kbps - Kilo bits per sec
4390  * @layer_num: layer number
4391  *
4392  * This function adds new profile corresponding to requested BW, configures
4393  * node's RL profile ID of type CIR, EIR, or SRL, and removes old profile
4394  * ID from local database. The caller needs to hold scheduler lock.
4395  */
4396 int
4397 ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node,
4398 		      enum ice_rl_type rl_type, u32 bw, u8 layer_num)
4399 {
4400 	struct ice_aqc_rl_profile_info *rl_prof_info;
4401 	struct ice_hw *hw = pi->hw;
4402 	u16 old_id, rl_prof_id;
4403 	int status = ICE_ERR_PARAM;
4404 
4405 	rl_prof_info = ice_sched_add_rl_profile(hw, rl_type, bw, layer_num);
4406 	if (!rl_prof_info)
4407 		return status;
4408 
4409 	rl_prof_id = LE16_TO_CPU(rl_prof_info->profile.profile_id);
4410 
4411 	/* Save existing RL prof ID for later clean up */
4412 	old_id = ice_sched_get_node_rl_prof_id(node, rl_type);
4413 	/* Configure BW scheduling parameters */
4414 	status = ice_sched_cfg_node_bw_lmt(hw, node, rl_type, rl_prof_id);
4415 	if (status)
4416 		return status;
4417 
4418 	/* New changes has been applied */
4419 	/* Increment the profile ID reference count */
4420 	rl_prof_info->prof_id_ref++;
4421 
4422 	/* Check for old ID removal */
4423 	if ((old_id == ICE_SCHED_DFLT_RL_PROF_ID && rl_type != ICE_SHARED_BW) ||
4424 	    old_id == ICE_SCHED_INVAL_PROF_ID || old_id == rl_prof_id)
4425 		return 0;
4426 
4427 	return ice_sched_rm_rl_profile(hw, layer_num,
4428 				       rl_prof_info->profile.flags &
4429 				       ICE_AQC_RL_PROFILE_TYPE_M, old_id);
4430 }
4431 
4432 /**
4433  * ice_sched_set_node_priority - set node's priority
4434  * @pi: port information structure
4435  * @node: tree node
4436  * @priority: number 0-7 representing priority among siblings
4437  *
4438  * This function sets priority of a node among it's siblings.
4439  */
4440 int
4441 ice_sched_set_node_priority(struct ice_port_info *pi, struct ice_sched_node *node,
4442 			    u16 priority)
4443 {
4444 	struct ice_aqc_txsched_elem_data buf;
4445 	struct ice_aqc_txsched_elem *data;
4446 
4447 	buf = node->info;
4448 	data = &buf.data;
4449 
4450 	data->valid_sections |= ICE_AQC_ELEM_VALID_GENERIC;
4451 	data->generic |= ICE_AQC_ELEM_GENERIC_PRIO_M &
4452 			 (priority << ICE_AQC_ELEM_GENERIC_PRIO_S);
4453 
4454 	return ice_sched_update_elem(pi->hw, node, &buf);
4455 }
4456 
4457 /**
4458  * ice_sched_set_node_weight - set node's weight
4459  * @pi: port information structure
4460  * @node: tree node
4461  * @weight: number 1-200 representing weight for WFQ
4462  *
4463  * This function sets weight of the node for WFQ algorithm.
4464  */
4465 int
4466 ice_sched_set_node_weight(struct ice_port_info *pi, struct ice_sched_node *node, u16 weight)
4467 {
4468 	struct ice_aqc_txsched_elem_data buf;
4469 	struct ice_aqc_txsched_elem *data;
4470 
4471 	buf = node->info;
4472 	data = &buf.data;
4473 
4474 	data->valid_sections = ICE_AQC_ELEM_VALID_CIR | ICE_AQC_ELEM_VALID_EIR |
4475 			       ICE_AQC_ELEM_VALID_GENERIC;
4476 	data->cir_bw.bw_alloc = CPU_TO_LE16(weight);
4477 	data->eir_bw.bw_alloc = CPU_TO_LE16(weight);
4478 	data->generic |= ICE_AQC_ELEM_GENERIC_SP_M &
4479 			 (0x0 << ICE_AQC_ELEM_GENERIC_SP_S);
4480 
4481 	return ice_sched_update_elem(pi->hw, node, &buf);
4482 }
4483 
4484 /**
4485  * ice_sched_set_node_bw_lmt - set node's BW limit
4486  * @pi: port information structure
4487  * @node: tree node
4488  * @rl_type: rate limit type min, max, or shared
4489  * @bw: bandwidth in Kbps - Kilo bits per sec
4490  *
4491  * It updates node's BW limit parameters like BW RL profile ID of type CIR,
4492  * EIR, or SRL. The caller needs to hold scheduler lock.
4493  *
4494  * NOTE: Caller provides the correct SRL node in case of shared profile
4495  * settings.
4496  */
4497 int
4498 ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node *node,
4499 			  enum ice_rl_type rl_type, u32 bw)
4500 {
4501 	struct ice_hw *hw;
4502 	u8 layer_num;
4503 
4504 	if (!pi)
4505 		return ICE_ERR_PARAM;
4506 	hw = pi->hw;
4507 	/* Remove unused RL profile IDs from HW and SW DB */
4508 	ice_sched_rm_unused_rl_prof(hw);
4509 
4510 	layer_num = ice_sched_get_rl_prof_layer(pi, rl_type,
4511 						node->tx_sched_layer);
4512 	if (layer_num >= hw->num_tx_sched_layers)
4513 		return ICE_ERR_PARAM;
4514 
4515 	if (bw == ICE_SCHED_DFLT_BW)
4516 		return ice_sched_set_node_bw_dflt(pi, node, rl_type, layer_num);
4517 	return ice_sched_set_node_bw(pi, node, rl_type, bw, layer_num);
4518 }
4519 
4520 /**
4521  * ice_sched_set_node_bw_dflt_lmt - set node's BW limit to default
4522  * @pi: port information structure
4523  * @node: pointer to node structure
4524  * @rl_type: rate limit type min, max, or shared
4525  *
4526  * This function configures node element's BW rate limit profile ID of
4527  * type CIR, EIR, or SRL to default. This function needs to be called
4528  * with the scheduler lock held.
4529  */
4530 static int
4531 ice_sched_set_node_bw_dflt_lmt(struct ice_port_info *pi,
4532 			       struct ice_sched_node *node,
4533 			       enum ice_rl_type rl_type)
4534 {
4535 	return ice_sched_set_node_bw_lmt(pi, node, rl_type,
4536 					 ICE_SCHED_DFLT_BW);
4537 }
4538 
4539 /**
4540  * ice_sched_validate_srl_node - Check node for SRL applicability
4541  * @node: sched node to configure
4542  * @sel_layer: selected SRL layer
4543  *
4544  * This function checks if the SRL can be applied to a selceted layer node on
4545  * behalf of the requested node (first argument). This function needs to be
4546  * called with scheduler lock held.
4547  */
4548 static int
4549 ice_sched_validate_srl_node(struct ice_sched_node *node, u8 sel_layer)
4550 {
4551 	/* SRL profiles are not available on all layers. Check if the
4552 	 * SRL profile can be applied to a node above or below the
4553 	 * requested node. SRL configuration is possible only if the
4554 	 * selected layer's node has single child.
4555 	 */
4556 	if (sel_layer == node->tx_sched_layer ||
4557 	    ((sel_layer == node->tx_sched_layer + 1) &&
4558 	    node->num_children == 1) ||
4559 	    ((sel_layer == node->tx_sched_layer - 1) &&
4560 	    (node->parent && node->parent->num_children == 1)))
4561 		return 0;
4562 
4563 	return ICE_ERR_CFG;
4564 }
4565 
4566 /**
4567  * ice_sched_save_q_bw - save queue node's BW information
4568  * @q_ctx: queue context structure
4569  * @rl_type: rate limit type min, max, or shared
4570  * @bw: bandwidth in Kbps - Kilo bits per sec
4571  *
4572  * Save BW information of queue type node for post replay use.
4573  */
4574 static int
4575 ice_sched_save_q_bw(struct ice_q_ctx *q_ctx, enum ice_rl_type rl_type, u32 bw)
4576 {
4577 	switch (rl_type) {
4578 	case ICE_MIN_BW:
4579 		ice_set_clear_cir_bw(&q_ctx->bw_t_info, bw);
4580 		break;
4581 	case ICE_MAX_BW:
4582 		ice_set_clear_eir_bw(&q_ctx->bw_t_info, bw);
4583 		break;
4584 	case ICE_SHARED_BW:
4585 		ice_set_clear_shared_bw(&q_ctx->bw_t_info, bw);
4586 		break;
4587 	default:
4588 		return ICE_ERR_PARAM;
4589 	}
4590 	return 0;
4591 }
4592 
4593 /**
4594  * ice_sched_set_q_bw_lmt - sets queue BW limit
4595  * @pi: port information structure
4596  * @vsi_handle: sw VSI handle
4597  * @tc: traffic class
4598  * @q_handle: software queue handle
4599  * @rl_type: min, max, or shared
4600  * @bw: bandwidth in Kbps
4601  *
4602  * This function sets BW limit of queue scheduling node.
4603  */
4604 static int
4605 ice_sched_set_q_bw_lmt(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
4606 		       u16 q_handle, enum ice_rl_type rl_type, u32 bw)
4607 {
4608 	struct ice_sched_node *node;
4609 	struct ice_q_ctx *q_ctx;
4610 	int status = ICE_ERR_PARAM;
4611 
4612 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
4613 		return ICE_ERR_PARAM;
4614 	ice_acquire_lock(&pi->sched_lock);
4615 	q_ctx = ice_get_lan_q_ctx(pi->hw, vsi_handle, tc, q_handle);
4616 	if (!q_ctx)
4617 		goto exit_q_bw_lmt;
4618 	node = ice_sched_find_node_by_teid(pi->root, q_ctx->q_teid);
4619 	if (!node) {
4620 		ice_debug(pi->hw, ICE_DBG_SCHED, "Wrong q_teid\n");
4621 		goto exit_q_bw_lmt;
4622 	}
4623 
4624 	/* Return error if it is not a leaf node */
4625 	if (node->info.data.elem_type != ICE_AQC_ELEM_TYPE_LEAF)
4626 		goto exit_q_bw_lmt;
4627 
4628 	/* SRL bandwidth layer selection */
4629 	if (rl_type == ICE_SHARED_BW) {
4630 		u8 sel_layer; /* selected layer */
4631 
4632 		sel_layer = ice_sched_get_rl_prof_layer(pi, rl_type,
4633 							node->tx_sched_layer);
4634 		if (sel_layer >= pi->hw->num_tx_sched_layers) {
4635 			status = ICE_ERR_PARAM;
4636 			goto exit_q_bw_lmt;
4637 		}
4638 		status = ice_sched_validate_srl_node(node, sel_layer);
4639 		if (status)
4640 			goto exit_q_bw_lmt;
4641 	}
4642 
4643 	if (bw == ICE_SCHED_DFLT_BW)
4644 		status = ice_sched_set_node_bw_dflt_lmt(pi, node, rl_type);
4645 	else
4646 		status = ice_sched_set_node_bw_lmt(pi, node, rl_type, bw);
4647 
4648 	if (!status)
4649 		status = ice_sched_save_q_bw(q_ctx, rl_type, bw);
4650 
4651 exit_q_bw_lmt:
4652 	ice_release_lock(&pi->sched_lock);
4653 	return status;
4654 }
4655 
4656 /**
4657  * ice_cfg_q_bw_lmt - configure queue BW limit
4658  * @pi: port information structure
4659  * @vsi_handle: sw VSI handle
4660  * @tc: traffic class
4661  * @q_handle: software queue handle
4662  * @rl_type: min, max, or shared
4663  * @bw: bandwidth in Kbps
4664  *
4665  * This function configures BW limit of queue scheduling node.
4666  */
4667 int
4668 ice_cfg_q_bw_lmt(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
4669 		 u16 q_handle, enum ice_rl_type rl_type, u32 bw)
4670 {
4671 	return ice_sched_set_q_bw_lmt(pi, vsi_handle, tc, q_handle, rl_type,
4672 				      bw);
4673 }
4674 
4675 /**
4676  * ice_cfg_q_bw_dflt_lmt - configure queue BW default limit
4677  * @pi: port information structure
4678  * @vsi_handle: sw VSI handle
4679  * @tc: traffic class
4680  * @q_handle: software queue handle
4681  * @rl_type: min, max, or shared
4682  *
4683  * This function configures BW default limit of queue scheduling node.
4684  */
4685 int
4686 ice_cfg_q_bw_dflt_lmt(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
4687 		      u16 q_handle, enum ice_rl_type rl_type)
4688 {
4689 	return ice_sched_set_q_bw_lmt(pi, vsi_handle, tc, q_handle, rl_type,
4690 				      ICE_SCHED_DFLT_BW);
4691 }
4692 
4693 /**
4694  * ice_sched_save_tc_node_bw - save TC node BW limit
4695  * @pi: port information structure
4696  * @tc: TC number
4697  * @rl_type: min or max
4698  * @bw: bandwidth in Kbps
4699  *
4700  * This function saves the modified values of bandwidth settings for later
4701  * replay purpose (restore) after reset.
4702  */
4703 static int
4704 ice_sched_save_tc_node_bw(struct ice_port_info *pi, u8 tc,
4705 			  enum ice_rl_type rl_type, u32 bw)
4706 {
4707 	if (tc >= ICE_MAX_TRAFFIC_CLASS)
4708 		return ICE_ERR_PARAM;
4709 	switch (rl_type) {
4710 	case ICE_MIN_BW:
4711 		ice_set_clear_cir_bw(&pi->tc_node_bw_t_info[tc], bw);
4712 		break;
4713 	case ICE_MAX_BW:
4714 		ice_set_clear_eir_bw(&pi->tc_node_bw_t_info[tc], bw);
4715 		break;
4716 	case ICE_SHARED_BW:
4717 		ice_set_clear_shared_bw(&pi->tc_node_bw_t_info[tc], bw);
4718 		break;
4719 	default:
4720 		return ICE_ERR_PARAM;
4721 	}
4722 	return 0;
4723 }
4724 
4725 #define ICE_SCHED_GENERIC_STRICT_MODE		BIT(4)
4726 #define ICE_SCHED_GENERIC_PRIO_S		1
4727 
4728 /**
4729  * ice_sched_set_tc_node_bw_lmt - sets TC node BW limit
4730  * @pi: port information structure
4731  * @tc: TC number
4732  * @rl_type: min or max
4733  * @bw: bandwidth in Kbps
4734  *
4735  * This function configures bandwidth limit of TC node.
4736  */
4737 static int
4738 ice_sched_set_tc_node_bw_lmt(struct ice_port_info *pi, u8 tc,
4739 			     enum ice_rl_type rl_type, u32 bw)
4740 {
4741 	struct ice_aqc_txsched_elem_data buf;
4742 	struct ice_aqc_txsched_elem *data;
4743 	struct ice_sched_node *tc_node;
4744 	int status = ICE_ERR_PARAM;
4745 
4746 	if (tc >= ICE_MAX_TRAFFIC_CLASS)
4747 		return status;
4748 	ice_acquire_lock(&pi->sched_lock);
4749 	tc_node = ice_sched_get_tc_node(pi, tc);
4750 	if (!tc_node)
4751 		goto exit_set_tc_node_bw;
4752 
4753 	/* update node's generic field */
4754 	buf = tc_node->info;
4755 	data = &buf.data;
4756 	data->valid_sections = ICE_AQC_ELEM_VALID_GENERIC;
4757 	data->generic = (tc << ICE_SCHED_GENERIC_PRIO_S) |
4758 		ICE_SCHED_GENERIC_STRICT_MODE;
4759 	status = ice_sched_update_elem(pi->hw, tc_node, &buf);
4760 	if (status)
4761 		goto exit_set_tc_node_bw;
4762 
4763 	if (bw == ICE_SCHED_DFLT_BW)
4764 		status = ice_sched_set_node_bw_dflt_lmt(pi, tc_node, rl_type);
4765 	else
4766 		status = ice_sched_set_node_bw_lmt(pi, tc_node, rl_type, bw);
4767 	if (!status)
4768 		status = ice_sched_save_tc_node_bw(pi, tc, rl_type, bw);
4769 
4770 exit_set_tc_node_bw:
4771 	ice_release_lock(&pi->sched_lock);
4772 	return status;
4773 }
4774 
4775 /**
4776  * ice_cfg_tc_node_bw_lmt - configure TC node BW limit
4777  * @pi: port information structure
4778  * @tc: TC number
4779  * @rl_type: min or max
4780  * @bw: bandwidth in Kbps
4781  *
4782  * This function configures BW limit of TC node.
4783  * Note: The minimum guaranteed reservation is done via DCBX.
4784  */
4785 int
4786 ice_cfg_tc_node_bw_lmt(struct ice_port_info *pi, u8 tc,
4787 		       enum ice_rl_type rl_type, u32 bw)
4788 {
4789 	return ice_sched_set_tc_node_bw_lmt(pi, tc, rl_type, bw);
4790 }
4791 
4792 /**
4793  * ice_cfg_tc_node_bw_dflt_lmt - configure TC node BW default limit
4794  * @pi: port information structure
4795  * @tc: TC number
4796  * @rl_type: min or max
4797  *
4798  * This function configures BW default limit of TC node.
4799  */
4800 int
4801 ice_cfg_tc_node_bw_dflt_lmt(struct ice_port_info *pi, u8 tc,
4802 			    enum ice_rl_type rl_type)
4803 {
4804 	return ice_sched_set_tc_node_bw_lmt(pi, tc, rl_type, ICE_SCHED_DFLT_BW);
4805 }
4806 
4807 /**
4808  * ice_sched_save_tc_node_bw_alloc - save TC node's BW alloc information
4809  * @pi: port information structure
4810  * @tc: traffic class
4811  * @rl_type: rate limit type min or max
4812  * @bw_alloc: Bandwidth allocation information
4813  *
4814  * Save BW alloc information of VSI type node for post replay use.
4815  */
4816 static int
4817 ice_sched_save_tc_node_bw_alloc(struct ice_port_info *pi, u8 tc,
4818 				enum ice_rl_type rl_type, u16 bw_alloc)
4819 {
4820 	if (tc >= ICE_MAX_TRAFFIC_CLASS)
4821 		return ICE_ERR_PARAM;
4822 	switch (rl_type) {
4823 	case ICE_MIN_BW:
4824 		ice_set_clear_cir_bw_alloc(&pi->tc_node_bw_t_info[tc],
4825 					   bw_alloc);
4826 		break;
4827 	case ICE_MAX_BW:
4828 		ice_set_clear_eir_bw_alloc(&pi->tc_node_bw_t_info[tc],
4829 					   bw_alloc);
4830 		break;
4831 	default:
4832 		return ICE_ERR_PARAM;
4833 	}
4834 	return 0;
4835 }
4836 
4837 /**
4838  * ice_sched_set_tc_node_bw_alloc - set TC node BW alloc
4839  * @pi: port information structure
4840  * @tc: TC number
4841  * @rl_type: min or max
4842  * @bw_alloc: bandwidth alloc
4843  *
4844  * This function configures bandwidth alloc of TC node, also saves the
4845  * changed settings for replay purpose, and return success if it succeeds
4846  * in modifying bandwidth alloc setting.
4847  */
4848 static int
4849 ice_sched_set_tc_node_bw_alloc(struct ice_port_info *pi, u8 tc,
4850 			       enum ice_rl_type rl_type, u8 bw_alloc)
4851 {
4852 	struct ice_sched_node *tc_node;
4853 	int status = ICE_ERR_PARAM;
4854 
4855 	if (tc >= ICE_MAX_TRAFFIC_CLASS)
4856 		return status;
4857 	ice_acquire_lock(&pi->sched_lock);
4858 	tc_node = ice_sched_get_tc_node(pi, tc);
4859 	if (!tc_node)
4860 		goto exit_set_tc_node_bw_alloc;
4861 	status = ice_sched_cfg_node_bw_alloc(pi->hw, tc_node, rl_type,
4862 					     bw_alloc);
4863 	if (status)
4864 		goto exit_set_tc_node_bw_alloc;
4865 	status = ice_sched_save_tc_node_bw_alloc(pi, tc, rl_type, bw_alloc);
4866 
4867 exit_set_tc_node_bw_alloc:
4868 	ice_release_lock(&pi->sched_lock);
4869 	return status;
4870 }
4871 
4872 /**
4873  * ice_cfg_tc_node_bw_alloc - configure TC node BW alloc
4874  * @pi: port information structure
4875  * @tc: TC number
4876  * @rl_type: min or max
4877  * @bw_alloc: bandwidth alloc
4878  *
4879  * This function configures BW limit of TC node.
4880  * Note: The minimum guaranteed reservation is done via DCBX.
4881  */
4882 int
4883 ice_cfg_tc_node_bw_alloc(struct ice_port_info *pi, u8 tc,
4884 			 enum ice_rl_type rl_type, u8 bw_alloc)
4885 {
4886 	return ice_sched_set_tc_node_bw_alloc(pi, tc, rl_type, bw_alloc);
4887 }
4888 
4889 /**
4890  * ice_sched_set_agg_bw_dflt_lmt - set aggregator node's BW limit to default
4891  * @pi: port information structure
4892  * @vsi_handle: software VSI handle
4893  *
4894  * This function retrieves the aggregator ID based on VSI ID and TC,
4895  * and sets node's BW limit to default. This function needs to be
4896  * called with the scheduler lock held.
4897  */
4898 int
4899 ice_sched_set_agg_bw_dflt_lmt(struct ice_port_info *pi, u16 vsi_handle)
4900 {
4901 	struct ice_vsi_ctx *vsi_ctx;
4902 	int status = 0;
4903 	u8 tc;
4904 
4905 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
4906 		return ICE_ERR_PARAM;
4907 	vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
4908 	if (!vsi_ctx)
4909 		return ICE_ERR_PARAM;
4910 
4911 	ice_for_each_traffic_class(tc) {
4912 		struct ice_sched_node *node;
4913 
4914 		node = vsi_ctx->sched.ag_node[tc];
4915 		if (!node)
4916 			continue;
4917 
4918 		/* Set min profile to default */
4919 		status = ice_sched_set_node_bw_dflt_lmt(pi, node, ICE_MIN_BW);
4920 		if (status)
4921 			break;
4922 
4923 		/* Set max profile to default */
4924 		status = ice_sched_set_node_bw_dflt_lmt(pi, node, ICE_MAX_BW);
4925 		if (status)
4926 			break;
4927 
4928 		/* Remove shared profile, if there is one */
4929 		status = ice_sched_set_node_bw_dflt_lmt(pi, node,
4930 							ICE_SHARED_BW);
4931 		if (status)
4932 			break;
4933 	}
4934 
4935 	return status;
4936 }
4937 
4938 /**
4939  * ice_sched_get_node_by_id_type - get node from ID type
4940  * @pi: port information structure
4941  * @id: identifier
4942  * @agg_type: type of aggregator
4943  * @tc: traffic class
4944  *
4945  * This function returns node identified by ID of type aggregator, and
4946  * based on traffic class (TC). This function needs to be called with
4947  * the scheduler lock held.
4948  */
4949 static struct ice_sched_node *
4950 ice_sched_get_node_by_id_type(struct ice_port_info *pi, u32 id,
4951 			      enum ice_agg_type agg_type, u8 tc)
4952 {
4953 	struct ice_sched_node *node = NULL;
4954 
4955 	switch (agg_type) {
4956 	case ICE_AGG_TYPE_VSI: {
4957 		struct ice_vsi_ctx *vsi_ctx;
4958 		u16 vsi_handle = (u16)id;
4959 
4960 		if (!ice_is_vsi_valid(pi->hw, vsi_handle))
4961 			break;
4962 		/* Get sched_vsi_info */
4963 		vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
4964 		if (!vsi_ctx)
4965 			break;
4966 		node = vsi_ctx->sched.vsi_node[tc];
4967 		break;
4968 	}
4969 
4970 	case ICE_AGG_TYPE_AGG: {
4971 		struct ice_sched_node *tc_node;
4972 
4973 		tc_node = ice_sched_get_tc_node(pi, tc);
4974 		if (tc_node)
4975 			node = ice_sched_get_agg_node(pi, tc_node, id);
4976 		break;
4977 	}
4978 
4979 	case ICE_AGG_TYPE_Q:
4980 		/* The current implementation allows single queue to modify */
4981 		node = ice_sched_find_node_by_teid(pi->root, id);
4982 		break;
4983 
4984 	case ICE_AGG_TYPE_QG: {
4985 		struct ice_sched_node *child_node;
4986 
4987 		/* The current implementation allows single qg to modify */
4988 		child_node = ice_sched_find_node_by_teid(pi->root, id);
4989 		if (!child_node)
4990 			break;
4991 		node = child_node->parent;
4992 		break;
4993 	}
4994 
4995 	default:
4996 		break;
4997 	}
4998 
4999 	return node;
5000 }
5001 
5002 /**
5003  * ice_sched_set_node_bw_lmt_per_tc - set node BW limit per TC
5004  * @pi: port information structure
5005  * @id: ID (software VSI handle or AGG ID)
5006  * @agg_type: aggregator type (VSI or AGG type node)
5007  * @tc: traffic class
5008  * @rl_type: min or max
5009  * @bw: bandwidth in Kbps
5010  *
5011  * This function sets BW limit of VSI or Aggregator scheduling node
5012  * based on TC information from passed in argument BW.
5013  */
5014 int
5015 ice_sched_set_node_bw_lmt_per_tc(struct ice_port_info *pi, u32 id,
5016 				 enum ice_agg_type agg_type, u8 tc,
5017 				 enum ice_rl_type rl_type, u32 bw)
5018 {
5019 	struct ice_sched_node *node;
5020 	int status = ICE_ERR_PARAM;
5021 
5022 	if (!pi)
5023 		return status;
5024 
5025 	if (rl_type == ICE_UNKNOWN_BW)
5026 		return status;
5027 
5028 	ice_acquire_lock(&pi->sched_lock);
5029 	node = ice_sched_get_node_by_id_type(pi, id, agg_type, tc);
5030 	if (!node) {
5031 		ice_debug(pi->hw, ICE_DBG_SCHED, "Wrong id, agg type, or tc\n");
5032 		goto exit_set_node_bw_lmt_per_tc;
5033 	}
5034 	if (bw == ICE_SCHED_DFLT_BW)
5035 		status = ice_sched_set_node_bw_dflt_lmt(pi, node, rl_type);
5036 	else
5037 		status = ice_sched_set_node_bw_lmt(pi, node, rl_type, bw);
5038 
5039 exit_set_node_bw_lmt_per_tc:
5040 	ice_release_lock(&pi->sched_lock);
5041 	return status;
5042 }
5043 
5044 /**
5045  * ice_sched_validate_vsi_srl_node - validate VSI SRL node
5046  * @pi: port information structure
5047  * @vsi_handle: software VSI handle
5048  *
5049  * This function validates SRL node of the VSI node if available SRL layer is
5050  * different than the VSI node layer on all TC(s).This function needs to be
5051  * called with scheduler lock held.
5052  */
5053 static int
5054 ice_sched_validate_vsi_srl_node(struct ice_port_info *pi, u16 vsi_handle)
5055 {
5056 	u8 sel_layer = ICE_SCHED_INVAL_LAYER_NUM;
5057 	u8 tc;
5058 
5059 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
5060 		return ICE_ERR_PARAM;
5061 
5062 	/* Return success if no nodes are present across TC */
5063 	ice_for_each_traffic_class(tc) {
5064 		struct ice_sched_node *tc_node, *vsi_node;
5065 		enum ice_rl_type rl_type = ICE_SHARED_BW;
5066 		int status;
5067 
5068 		tc_node = ice_sched_get_tc_node(pi, tc);
5069 		if (!tc_node)
5070 			continue;
5071 
5072 		vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
5073 		if (!vsi_node)
5074 			continue;
5075 
5076 		/* SRL bandwidth layer selection */
5077 		if (sel_layer == ICE_SCHED_INVAL_LAYER_NUM) {
5078 			u8 node_layer = vsi_node->tx_sched_layer;
5079 			u8 layer_num;
5080 
5081 			layer_num = ice_sched_get_rl_prof_layer(pi, rl_type,
5082 								node_layer);
5083 			if (layer_num >= pi->hw->num_tx_sched_layers)
5084 				return ICE_ERR_PARAM;
5085 			sel_layer = layer_num;
5086 		}
5087 
5088 		status = ice_sched_validate_srl_node(vsi_node, sel_layer);
5089 		if (status)
5090 			return status;
5091 	}
5092 	return 0;
5093 }
5094 
5095 /**
5096  * ice_sched_set_save_vsi_srl_node_bw - set VSI shared limit values
5097  * @pi: port information structure
5098  * @vsi_handle: software VSI handle
5099  * @tc: traffic class
5100  * @srl_node: sched node to configure
5101  * @rl_type: rate limit type minimum, maximum, or shared
5102  * @bw: minimum, maximum, or shared bandwidth in Kbps
5103  *
5104  * Configure shared rate limiter(SRL) of VSI type nodes across given traffic
5105  * class, and saves those value for later use for replaying purposes. The
5106  * caller holds the scheduler lock.
5107  */
5108 static int
5109 ice_sched_set_save_vsi_srl_node_bw(struct ice_port_info *pi, u16 vsi_handle,
5110 				   u8 tc, struct ice_sched_node *srl_node,
5111 				   enum ice_rl_type rl_type, u32 bw)
5112 {
5113 	int status;
5114 
5115 	if (bw == ICE_SCHED_DFLT_BW) {
5116 		status = ice_sched_set_node_bw_dflt_lmt(pi, srl_node, rl_type);
5117 	} else {
5118 		status = ice_sched_set_node_bw_lmt(pi, srl_node, rl_type, bw);
5119 		if (status)
5120 			return status;
5121 		status = ice_sched_save_vsi_bw(pi, vsi_handle, tc, rl_type, bw);
5122 	}
5123 	return status;
5124 }
5125 
5126 /**
5127  * ice_sched_set_vsi_node_srl_per_tc - set VSI node BW shared limit for tc
5128  * @pi: port information structure
5129  * @vsi_handle: software VSI handle
5130  * @tc: traffic class
5131  * @min_bw: minimum bandwidth in Kbps
5132  * @max_bw: maximum bandwidth in Kbps
5133  * @shared_bw: shared bandwidth in Kbps
5134  *
5135  * Configure shared rate limiter(SRL) of  VSI type nodes across requested
5136  * traffic class for VSI matching handle. When BW value of ICE_SCHED_DFLT_BW
5137  * is passed, it removes the corresponding bw from the node. The caller
5138  * holds scheduler lock.
5139  */
5140 static int
5141 ice_sched_set_vsi_node_srl_per_tc(struct ice_port_info *pi, u16 vsi_handle,
5142 				  u8 tc, u32 min_bw, u32 max_bw, u32 shared_bw)
5143 {
5144 	struct ice_sched_node *tc_node, *vsi_node, *cfg_node;
5145 	u8 layer_num;
5146 	int status;
5147 
5148 	tc_node = ice_sched_get_tc_node(pi, tc);
5149 	if (!tc_node)
5150 		return ICE_ERR_CFG;
5151 
5152 	vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
5153 	if (!vsi_node)
5154 		return ICE_ERR_CFG;
5155 
5156 	layer_num = ice_sched_get_rl_prof_layer(pi, ICE_SHARED_BW,
5157 						vsi_node->tx_sched_layer);
5158 	if (layer_num >= pi->hw->num_tx_sched_layers)
5159 		return ICE_ERR_PARAM;
5160 
5161 	/* SRL node may be different */
5162 	cfg_node = ice_sched_get_srl_node(vsi_node, layer_num);
5163 	if (!cfg_node)
5164 		return ICE_ERR_CFG;
5165 
5166 	status = ice_sched_set_save_vsi_srl_node_bw(pi, vsi_handle, tc,
5167 						    cfg_node, ICE_MIN_BW,
5168 						    min_bw);
5169 	if (status)
5170 		return status;
5171 
5172 	status = ice_sched_set_save_vsi_srl_node_bw(pi, vsi_handle, tc,
5173 						    cfg_node, ICE_MAX_BW,
5174 						    max_bw);
5175 	if (status)
5176 		return status;
5177 
5178 	return ice_sched_set_save_vsi_srl_node_bw(pi, vsi_handle, tc, cfg_node,
5179 						  ICE_SHARED_BW, shared_bw);
5180 }
5181 
5182 /**
5183  * ice_sched_set_vsi_bw_shared_lmt - set VSI BW shared limit
5184  * @pi: port information structure
5185  * @vsi_handle: software VSI handle
5186  * @min_bw: minimum bandwidth in Kbps
5187  * @max_bw: maximum bandwidth in Kbps
5188  * @shared_bw: shared bandwidth in Kbps
5189  *
5190  * Configure shared rate limiter(SRL) of all VSI type nodes across all traffic
5191  * classes for VSI matching handle. When BW value of ICE_SCHED_DFLT_BW is
5192  * passed, it removes those value(s) from the node.
5193  */
5194 int
5195 ice_sched_set_vsi_bw_shared_lmt(struct ice_port_info *pi, u16 vsi_handle,
5196 				u32 min_bw, u32 max_bw, u32 shared_bw)
5197 {
5198 	int status = 0;
5199 	u8 tc;
5200 
5201 	if (!pi)
5202 		return ICE_ERR_PARAM;
5203 
5204 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
5205 		return ICE_ERR_PARAM;
5206 
5207 	ice_acquire_lock(&pi->sched_lock);
5208 	status = ice_sched_validate_vsi_srl_node(pi, vsi_handle);
5209 	if (status)
5210 		goto exit_set_vsi_bw_shared_lmt;
5211 	/* Return success if no nodes are present across TC */
5212 	ice_for_each_traffic_class(tc) {
5213 		struct ice_sched_node *tc_node, *vsi_node;
5214 
5215 		tc_node = ice_sched_get_tc_node(pi, tc);
5216 		if (!tc_node)
5217 			continue;
5218 
5219 		vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
5220 		if (!vsi_node)
5221 			continue;
5222 
5223 		status = ice_sched_set_vsi_node_srl_per_tc(pi, vsi_handle, tc,
5224 							   min_bw, max_bw,
5225 							   shared_bw);
5226 		if (status)
5227 			break;
5228 	}
5229 
5230 exit_set_vsi_bw_shared_lmt:
5231 	ice_release_lock(&pi->sched_lock);
5232 	return status;
5233 }
5234 
5235 /**
5236  * ice_sched_validate_agg_srl_node - validate AGG SRL node
5237  * @pi: port information structure
5238  * @agg_id: aggregator ID
5239  *
5240  * This function validates SRL node of the AGG node if available SRL layer is
5241  * different than the AGG node layer on all TC(s).This function needs to be
5242  * called with scheduler lock held.
5243  */
5244 static int
5245 ice_sched_validate_agg_srl_node(struct ice_port_info *pi, u32 agg_id)
5246 {
5247 	u8 sel_layer = ICE_SCHED_INVAL_LAYER_NUM;
5248 	struct ice_sched_agg_info *agg_info;
5249 	bool agg_id_present = false;
5250 	int status = 0;
5251 	u8 tc;
5252 
5253 	LIST_FOR_EACH_ENTRY(agg_info, &pi->hw->agg_list, ice_sched_agg_info,
5254 			    list_entry)
5255 		if (agg_info->agg_id == agg_id) {
5256 			agg_id_present = true;
5257 			break;
5258 		}
5259 	if (!agg_id_present)
5260 		return ICE_ERR_PARAM;
5261 	/* Return success if no nodes are present across TC */
5262 	ice_for_each_traffic_class(tc) {
5263 		struct ice_sched_node *tc_node, *agg_node;
5264 		enum ice_rl_type rl_type = ICE_SHARED_BW;
5265 
5266 		tc_node = ice_sched_get_tc_node(pi, tc);
5267 		if (!tc_node)
5268 			continue;
5269 
5270 		agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
5271 		if (!agg_node)
5272 			continue;
5273 		/* SRL bandwidth layer selection */
5274 		if (sel_layer == ICE_SCHED_INVAL_LAYER_NUM) {
5275 			u8 node_layer = agg_node->tx_sched_layer;
5276 			u8 layer_num;
5277 
5278 			layer_num = ice_sched_get_rl_prof_layer(pi, rl_type,
5279 								node_layer);
5280 			if (layer_num >= pi->hw->num_tx_sched_layers)
5281 				return ICE_ERR_PARAM;
5282 			sel_layer = layer_num;
5283 		}
5284 
5285 		status = ice_sched_validate_srl_node(agg_node, sel_layer);
5286 		if (status)
5287 			break;
5288 	}
5289 	return status;
5290 }
5291 
5292 /**
5293  * ice_sched_validate_agg_id - Validate aggregator id
5294  * @pi: port information structure
5295  * @agg_id: aggregator ID
5296  *
5297  * This function validates aggregator id. Caller holds the scheduler lock.
5298  */
5299 static int
5300 ice_sched_validate_agg_id(struct ice_port_info *pi, u32 agg_id)
5301 {
5302 	struct ice_sched_agg_info *agg_info;
5303 	struct ice_sched_agg_info *tmp;
5304 	bool agg_id_present = false;
5305 	int status;
5306 
5307 	status = ice_sched_validate_agg_srl_node(pi, agg_id);
5308 	if (status)
5309 		return status;
5310 
5311 	LIST_FOR_EACH_ENTRY_SAFE(agg_info, tmp, &pi->hw->agg_list,
5312 				 ice_sched_agg_info, list_entry)
5313 		if (agg_info->agg_id == agg_id) {
5314 			agg_id_present = true;
5315 			break;
5316 		}
5317 
5318 	if (!agg_id_present)
5319 		return ICE_ERR_PARAM;
5320 
5321 	return 0;
5322 }
5323 
5324 /**
5325  * ice_sched_set_save_agg_srl_node_bw - set aggregator shared limit values
5326  * @pi: port information structure
5327  * @agg_id: aggregator ID
5328  * @tc: traffic class
5329  * @srl_node: sched node to configure
5330  * @rl_type: rate limit type minimum, maximum, or shared
5331  * @bw: minimum, maximum, or shared bandwidth in Kbps
5332  *
5333  * Configure shared rate limiter(SRL) of aggregator type nodes across
5334  * requested traffic class, and saves those value for later use for
5335  * replaying purposes. The caller holds the scheduler lock.
5336  */
5337 static int
5338 ice_sched_set_save_agg_srl_node_bw(struct ice_port_info *pi, u32 agg_id, u8 tc,
5339 				   struct ice_sched_node *srl_node,
5340 				   enum ice_rl_type rl_type, u32 bw)
5341 {
5342 	int status;
5343 
5344 	if (bw == ICE_SCHED_DFLT_BW) {
5345 		status = ice_sched_set_node_bw_dflt_lmt(pi, srl_node, rl_type);
5346 	} else {
5347 		status = ice_sched_set_node_bw_lmt(pi, srl_node, rl_type, bw);
5348 		if (status)
5349 			return status;
5350 		status = ice_sched_save_agg_bw(pi, agg_id, tc, rl_type, bw);
5351 	}
5352 	return status;
5353 }
5354 
5355 /**
5356  * ice_sched_set_agg_node_srl_per_tc - set aggregator SRL per tc
5357  * @pi: port information structure
5358  * @agg_id: aggregator ID
5359  * @tc: traffic class
5360  * @min_bw: minimum bandwidth in Kbps
5361  * @max_bw: maximum bandwidth in Kbps
5362  * @shared_bw: shared bandwidth in Kbps
5363  *
5364  * This function configures the shared rate limiter(SRL) of aggregator type
5365  * node for a given traffic class for aggregator matching agg_id. When BW
5366  * value of ICE_SCHED_DFLT_BW is passed, it removes SRL from the node. Caller
5367  * holds the scheduler lock.
5368  */
5369 static int
5370 ice_sched_set_agg_node_srl_per_tc(struct ice_port_info *pi, u32 agg_id,
5371 				  u8 tc, u32 min_bw, u32 max_bw, u32 shared_bw)
5372 {
5373 	struct ice_sched_node *tc_node, *agg_node, *cfg_node;
5374 	enum ice_rl_type rl_type = ICE_SHARED_BW;
5375 	int status = ICE_ERR_CFG;
5376 	u8 layer_num;
5377 
5378 	tc_node = ice_sched_get_tc_node(pi, tc);
5379 	if (!tc_node)
5380 		return ICE_ERR_CFG;
5381 
5382 	agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
5383 	if (!agg_node)
5384 		return ICE_ERR_CFG;
5385 
5386 	layer_num = ice_sched_get_rl_prof_layer(pi, rl_type,
5387 						agg_node->tx_sched_layer);
5388 	if (layer_num >= pi->hw->num_tx_sched_layers)
5389 		return ICE_ERR_PARAM;
5390 
5391 	/* SRL node may be different */
5392 	cfg_node = ice_sched_get_srl_node(agg_node, layer_num);
5393 	if (!cfg_node)
5394 		return ICE_ERR_CFG;
5395 
5396 	status = ice_sched_set_save_agg_srl_node_bw(pi, agg_id, tc, cfg_node,
5397 						    ICE_MIN_BW, min_bw);
5398 	if (status)
5399 		return status;
5400 
5401 	status = ice_sched_set_save_agg_srl_node_bw(pi, agg_id, tc, cfg_node,
5402 						    ICE_MAX_BW, max_bw);
5403 	if (status)
5404 		return status;
5405 
5406 	status = ice_sched_set_save_agg_srl_node_bw(pi, agg_id, tc, cfg_node,
5407 						    ICE_SHARED_BW, shared_bw);
5408 	return status;
5409 }
5410 
5411 /**
5412  * ice_sched_set_agg_bw_shared_lmt - set aggregator BW shared limit
5413  * @pi: port information structure
5414  * @agg_id: aggregator ID
5415  * @min_bw: minimum bandwidth in Kbps
5416  * @max_bw: maximum bandwidth in Kbps
5417  * @shared_bw: shared bandwidth in Kbps
5418  *
5419  * This function configures the shared rate limiter(SRL) of all aggregator type
5420  * nodes across all traffic classes for aggregator matching agg_id. When
5421  * BW value of ICE_SCHED_DFLT_BW is passed, it removes SRL from the
5422  * node(s).
5423  */
5424 int
5425 ice_sched_set_agg_bw_shared_lmt(struct ice_port_info *pi, u32 agg_id,
5426 				u32 min_bw, u32 max_bw, u32 shared_bw)
5427 {
5428 	int status;
5429 	u8 tc;
5430 
5431 	if (!pi)
5432 		return ICE_ERR_PARAM;
5433 
5434 	ice_acquire_lock(&pi->sched_lock);
5435 	status = ice_sched_validate_agg_id(pi, agg_id);
5436 	if (status)
5437 		goto exit_agg_bw_shared_lmt;
5438 
5439 	/* Return success if no nodes are present across TC */
5440 	ice_for_each_traffic_class(tc) {
5441 		struct ice_sched_node *tc_node, *agg_node;
5442 
5443 		tc_node = ice_sched_get_tc_node(pi, tc);
5444 		if (!tc_node)
5445 			continue;
5446 
5447 		agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
5448 		if (!agg_node)
5449 			continue;
5450 
5451 		status = ice_sched_set_agg_node_srl_per_tc(pi, agg_id, tc,
5452 							   min_bw, max_bw,
5453 							   shared_bw);
5454 		if (status)
5455 			break;
5456 	}
5457 
5458 exit_agg_bw_shared_lmt:
5459 	ice_release_lock(&pi->sched_lock);
5460 	return status;
5461 }
5462 
5463 /**
5464  * ice_sched_set_agg_bw_shared_lmt_per_tc - set aggregator BW shared lmt per tc
5465  * @pi: port information structure
5466  * @agg_id: aggregator ID
5467  * @tc: traffic class
5468  * @min_bw: minimum bandwidth in Kbps
5469  * @max_bw: maximum bandwidth in Kbps
5470  * @shared_bw: shared bandwidth in Kbps
5471  *
5472  * This function configures the shared rate limiter(SRL) of aggregator type
5473  * node for a given traffic class for aggregator matching agg_id. When BW
5474  * value of ICE_SCHED_DFLT_BW is passed, it removes SRL from the node.
5475  */
5476 int
5477 ice_sched_set_agg_bw_shared_lmt_per_tc(struct ice_port_info *pi, u32 agg_id,
5478 				       u8 tc, u32 min_bw, u32 max_bw,
5479 				       u32 shared_bw)
5480 {
5481 	int status;
5482 
5483 	if (!pi)
5484 		return ICE_ERR_PARAM;
5485 	ice_acquire_lock(&pi->sched_lock);
5486 	status = ice_sched_validate_agg_id(pi, agg_id);
5487 	if (status)
5488 		goto exit_agg_bw_shared_lmt_per_tc;
5489 
5490 	status = ice_sched_set_agg_node_srl_per_tc(pi, agg_id, tc, min_bw,
5491 						   max_bw, shared_bw);
5492 
5493 exit_agg_bw_shared_lmt_per_tc:
5494 	ice_release_lock(&pi->sched_lock);
5495 	return status;
5496 }
5497 
5498 /**
5499  * ice_sched_cfg_sibl_node_prio - configure node sibling priority
5500  * @pi: port information structure
5501  * @node: sched node to configure
5502  * @priority: sibling priority
5503  *
5504  * This function configures node element's sibling priority only. This
5505  * function needs to be called with scheduler lock held.
5506  */
5507 int
5508 ice_sched_cfg_sibl_node_prio(struct ice_port_info *pi,
5509 			     struct ice_sched_node *node, u8 priority)
5510 {
5511 	struct ice_aqc_txsched_elem_data buf;
5512 	struct ice_aqc_txsched_elem *data;
5513 	struct ice_hw *hw = pi->hw;
5514 	int status;
5515 
5516 	if (!hw)
5517 		return ICE_ERR_PARAM;
5518 	buf = node->info;
5519 	data = &buf.data;
5520 	data->valid_sections |= ICE_AQC_ELEM_VALID_GENERIC;
5521 	priority = (priority << ICE_AQC_ELEM_GENERIC_PRIO_S) &
5522 		   ICE_AQC_ELEM_GENERIC_PRIO_M;
5523 	data->generic &= ~ICE_AQC_ELEM_GENERIC_PRIO_M;
5524 	data->generic |= priority;
5525 
5526 	/* Configure element */
5527 	status = ice_sched_update_elem(hw, node, &buf);
5528 	return status;
5529 }
5530 
5531 /**
5532  * ice_cfg_rl_burst_size - Set burst size value
5533  * @hw: pointer to the HW struct
5534  * @bytes: burst size in bytes
5535  *
5536  * This function configures/set the burst size to requested new value. The new
5537  * burst size value is used for future rate limit calls. It doesn't change the
5538  * existing or previously created RL profiles.
5539  */
5540 int ice_cfg_rl_burst_size(struct ice_hw *hw, u32 bytes)
5541 {
5542 	u16 burst_size_to_prog;
5543 
5544 	if (bytes < ICE_MIN_BURST_SIZE_ALLOWED ||
5545 	    bytes > ICE_MAX_BURST_SIZE_ALLOWED)
5546 		return ICE_ERR_PARAM;
5547 	if (ice_round_to_num(bytes, 64) <=
5548 	    ICE_MAX_BURST_SIZE_64_BYTE_GRANULARITY) {
5549 		/* 64 byte granularity case */
5550 		/* Disable MSB granularity bit */
5551 		burst_size_to_prog = ICE_64_BYTE_GRANULARITY;
5552 		/* round number to nearest 64 byte granularity */
5553 		bytes = ice_round_to_num(bytes, 64);
5554 		/* The value is in 64 byte chunks */
5555 		burst_size_to_prog |= (u16)(bytes / 64);
5556 	} else {
5557 		/* k bytes granularity case */
5558 		/* Enable MSB granularity bit */
5559 		burst_size_to_prog = ICE_KBYTE_GRANULARITY;
5560 		/* round number to nearest 1024 granularity */
5561 		bytes = ice_round_to_num(bytes, 1024);
5562 		/* check rounding doesn't go beyond allowed */
5563 		if (bytes > ICE_MAX_BURST_SIZE_KBYTE_GRANULARITY)
5564 			bytes = ICE_MAX_BURST_SIZE_KBYTE_GRANULARITY;
5565 		/* The value is in k bytes */
5566 		burst_size_to_prog |= (u16)(bytes / 1024);
5567 	}
5568 	hw->max_burst_size = burst_size_to_prog;
5569 	return 0;
5570 }
5571 
5572 /**
5573  * ice_sched_replay_node_prio - re-configure node priority
5574  * @hw: pointer to the HW struct
5575  * @node: sched node to configure
5576  * @priority: priority value
5577  *
5578  * This function configures node element's priority value. It
5579  * needs to be called with scheduler lock held.
5580  */
5581 static int
5582 ice_sched_replay_node_prio(struct ice_hw *hw, struct ice_sched_node *node,
5583 			   u8 priority)
5584 {
5585 	struct ice_aqc_txsched_elem_data buf;
5586 	struct ice_aqc_txsched_elem *data;
5587 	int status;
5588 
5589 	buf = node->info;
5590 	data = &buf.data;
5591 	data->valid_sections |= ICE_AQC_ELEM_VALID_GENERIC;
5592 	data->generic = priority;
5593 
5594 	/* Configure element */
5595 	status = ice_sched_update_elem(hw, node, &buf);
5596 	return status;
5597 }
5598 
5599 /**
5600  * ice_sched_replay_node_bw - replay node(s) BW
5601  * @hw: pointer to the HW struct
5602  * @node: sched node to configure
5603  * @bw_t_info: BW type information
5604  *
5605  * This function restores node's BW from bw_t_info. The caller needs
5606  * to hold the scheduler lock.
5607  */
5608 static int
5609 ice_sched_replay_node_bw(struct ice_hw *hw, struct ice_sched_node *node,
5610 			 struct ice_bw_type_info *bw_t_info)
5611 {
5612 	struct ice_port_info *pi = hw->port_info;
5613 	int status = ICE_ERR_PARAM;
5614 	u16 bw_alloc;
5615 
5616 	if (!node)
5617 		return status;
5618 	if (!ice_is_any_bit_set(bw_t_info->bw_t_bitmap, ICE_BW_TYPE_CNT))
5619 		return 0;
5620 	if (ice_is_bit_set(bw_t_info->bw_t_bitmap, ICE_BW_TYPE_PRIO)) {
5621 		status = ice_sched_replay_node_prio(hw, node,
5622 						    bw_t_info->generic);
5623 		if (status)
5624 			return status;
5625 	}
5626 	if (ice_is_bit_set(bw_t_info->bw_t_bitmap, ICE_BW_TYPE_CIR)) {
5627 		status = ice_sched_set_node_bw_lmt(pi, node, ICE_MIN_BW,
5628 						   bw_t_info->cir_bw.bw);
5629 		if (status)
5630 			return status;
5631 	}
5632 	if (ice_is_bit_set(bw_t_info->bw_t_bitmap, ICE_BW_TYPE_CIR_WT)) {
5633 		bw_alloc = bw_t_info->cir_bw.bw_alloc;
5634 		status = ice_sched_cfg_node_bw_alloc(hw, node, ICE_MIN_BW,
5635 						     bw_alloc);
5636 		if (status)
5637 			return status;
5638 	}
5639 	if (ice_is_bit_set(bw_t_info->bw_t_bitmap, ICE_BW_TYPE_EIR)) {
5640 		status = ice_sched_set_node_bw_lmt(pi, node, ICE_MAX_BW,
5641 						   bw_t_info->eir_bw.bw);
5642 		if (status)
5643 			return status;
5644 	}
5645 	if (ice_is_bit_set(bw_t_info->bw_t_bitmap, ICE_BW_TYPE_EIR_WT)) {
5646 		bw_alloc = bw_t_info->eir_bw.bw_alloc;
5647 		status = ice_sched_cfg_node_bw_alloc(hw, node, ICE_MAX_BW,
5648 						     bw_alloc);
5649 		if (status)
5650 			return status;
5651 	}
5652 	if (ice_is_bit_set(bw_t_info->bw_t_bitmap, ICE_BW_TYPE_SHARED))
5653 		status = ice_sched_set_node_bw_lmt(pi, node, ICE_SHARED_BW,
5654 						   bw_t_info->shared_bw);
5655 	return status;
5656 }
5657 
5658 /**
5659  * ice_sched_replay_agg_bw - replay aggregator node(s) BW
5660  * @hw: pointer to the HW struct
5661  * @agg_info: aggregator data structure
5662  *
5663  * This function re-creates aggregator type nodes. The caller needs to hold
5664  * the scheduler lock.
5665  */
5666 static int
5667 ice_sched_replay_agg_bw(struct ice_hw *hw, struct ice_sched_agg_info *agg_info)
5668 {
5669 	struct ice_sched_node *tc_node, *agg_node;
5670 	int status = 0;
5671 	u8 tc;
5672 
5673 	if (!agg_info)
5674 		return ICE_ERR_PARAM;
5675 	ice_for_each_traffic_class(tc) {
5676 		if (!ice_is_any_bit_set(agg_info->bw_t_info[tc].bw_t_bitmap,
5677 					ICE_BW_TYPE_CNT))
5678 			continue;
5679 		tc_node = ice_sched_get_tc_node(hw->port_info, tc);
5680 		if (!tc_node) {
5681 			status = ICE_ERR_PARAM;
5682 			break;
5683 		}
5684 		agg_node = ice_sched_get_agg_node(hw->port_info, tc_node,
5685 						  agg_info->agg_id);
5686 		if (!agg_node) {
5687 			status = ICE_ERR_PARAM;
5688 			break;
5689 		}
5690 		status = ice_sched_replay_node_bw(hw, agg_node,
5691 						  &agg_info->bw_t_info[tc]);
5692 		if (status)
5693 			break;
5694 	}
5695 	return status;
5696 }
5697 
5698 /**
5699  * ice_sched_get_ena_tc_bitmap - get enabled TC bitmap
5700  * @pi: port info struct
5701  * @tc_bitmap: 8 bits TC bitmap to check
5702  * @ena_tc_bitmap: 8 bits enabled TC bitmap to return
5703  *
5704  * This function returns enabled TC bitmap in variable ena_tc_bitmap. Some TCs
5705  * may be missing, it returns enabled TCs. This function needs to be called with
5706  * scheduler lock held.
5707  */
5708 static void
5709 ice_sched_get_ena_tc_bitmap(struct ice_port_info *pi, ice_bitmap_t *tc_bitmap,
5710 			    ice_bitmap_t *ena_tc_bitmap)
5711 {
5712 	u8 tc;
5713 
5714 	/* Some TC(s) may be missing after reset, adjust for replay */
5715 	ice_for_each_traffic_class(tc)
5716 		if (ice_is_tc_ena(*tc_bitmap, tc) &&
5717 		    (ice_sched_get_tc_node(pi, tc)))
5718 			ice_set_bit(tc, ena_tc_bitmap);
5719 }
5720 
5721 /**
5722  * ice_sched_replay_agg - recreate aggregator node(s)
5723  * @hw: pointer to the HW struct
5724  *
5725  * This function recreate aggregator type nodes which are not replayed earlier.
5726  * It also replay aggregator BW information. These aggregator nodes are not
5727  * associated with VSI type node yet.
5728  */
5729 void ice_sched_replay_agg(struct ice_hw *hw)
5730 {
5731 	struct ice_port_info *pi = hw->port_info;
5732 	struct ice_sched_agg_info *agg_info;
5733 
5734 	ice_acquire_lock(&pi->sched_lock);
5735 	LIST_FOR_EACH_ENTRY(agg_info, &hw->agg_list, ice_sched_agg_info,
5736 			    list_entry)
5737 		/* replay aggregator (re-create aggregator node) */
5738 		if (!ice_cmp_bitmap(agg_info->tc_bitmap,
5739 				    agg_info->replay_tc_bitmap,
5740 				    ICE_MAX_TRAFFIC_CLASS)) {
5741 			ice_declare_bitmap(replay_bitmap,
5742 					   ICE_MAX_TRAFFIC_CLASS);
5743 			int status;
5744 
5745 			ice_zero_bitmap(replay_bitmap, ICE_MAX_TRAFFIC_CLASS);
5746 			ice_sched_get_ena_tc_bitmap(pi,
5747 						    agg_info->replay_tc_bitmap,
5748 						    replay_bitmap);
5749 			status = ice_sched_cfg_agg(hw->port_info,
5750 						   agg_info->agg_id,
5751 						   ICE_AGG_TYPE_AGG,
5752 						   replay_bitmap);
5753 			if (status) {
5754 				ice_info(hw, "Replay agg id[%d] failed\n",
5755 					 agg_info->agg_id);
5756 				/* Move on to next one */
5757 				continue;
5758 			}
5759 			/* Replay aggregator node BW (restore aggregator BW) */
5760 			status = ice_sched_replay_agg_bw(hw, agg_info);
5761 			if (status)
5762 				ice_info(hw, "Replay agg bw [id=%d] failed\n",
5763 					 agg_info->agg_id);
5764 		}
5765 	ice_release_lock(&pi->sched_lock);
5766 }
5767 
5768 /**
5769  * ice_sched_replay_agg_vsi_preinit - Agg/VSI replay pre initialization
5770  * @hw: pointer to the HW struct
5771  *
5772  * This function initialize aggregator(s) TC bitmap to zero. A required
5773  * preinit step for replaying aggregators.
5774  */
5775 void ice_sched_replay_agg_vsi_preinit(struct ice_hw *hw)
5776 {
5777 	struct ice_port_info *pi = hw->port_info;
5778 	struct ice_sched_agg_info *agg_info;
5779 
5780 	ice_acquire_lock(&pi->sched_lock);
5781 	LIST_FOR_EACH_ENTRY(agg_info, &hw->agg_list, ice_sched_agg_info,
5782 			    list_entry) {
5783 		struct ice_sched_agg_vsi_info *agg_vsi_info;
5784 
5785 		agg_info->tc_bitmap[0] = 0;
5786 		LIST_FOR_EACH_ENTRY(agg_vsi_info, &agg_info->agg_vsi_list,
5787 				    ice_sched_agg_vsi_info, list_entry)
5788 			agg_vsi_info->tc_bitmap[0] = 0;
5789 	}
5790 	ice_release_lock(&pi->sched_lock);
5791 }
5792 
5793 /**
5794  * ice_sched_replay_root_node_bw - replay root node BW
5795  * @pi: port information structure
5796  *
5797  * Replay root node BW settings.
5798  */
5799 int ice_sched_replay_root_node_bw(struct ice_port_info *pi)
5800 {
5801 	int status = 0;
5802 
5803 	if (!pi->hw)
5804 		return ICE_ERR_PARAM;
5805 	ice_acquire_lock(&pi->sched_lock);
5806 
5807 	status = ice_sched_replay_node_bw(pi->hw, pi->root,
5808 					  &pi->root_node_bw_t_info);
5809 	ice_release_lock(&pi->sched_lock);
5810 	return status;
5811 }
5812 
5813 /**
5814  * ice_sched_replay_tc_node_bw - replay TC node(s) BW
5815  * @pi: port information structure
5816  *
5817  * This function replay TC nodes.
5818  */
5819 int ice_sched_replay_tc_node_bw(struct ice_port_info *pi)
5820 {
5821 	int status = 0;
5822 	u8 tc;
5823 
5824 	if (!pi->hw)
5825 		return ICE_ERR_PARAM;
5826 	ice_acquire_lock(&pi->sched_lock);
5827 	ice_for_each_traffic_class(tc) {
5828 		struct ice_sched_node *tc_node;
5829 
5830 		tc_node = ice_sched_get_tc_node(pi, tc);
5831 		if (!tc_node)
5832 			continue; /* TC not present */
5833 		status = ice_sched_replay_node_bw(pi->hw, tc_node,
5834 						  &pi->tc_node_bw_t_info[tc]);
5835 		if (status)
5836 			break;
5837 	}
5838 	ice_release_lock(&pi->sched_lock);
5839 	return status;
5840 }
5841 
5842 /**
5843  * ice_sched_replay_vsi_bw - replay VSI type node(s) BW
5844  * @hw: pointer to the HW struct
5845  * @vsi_handle: software VSI handle
5846  * @tc_bitmap: 8 bits TC bitmap
5847  *
5848  * This function replays VSI type nodes bandwidth. This function needs to be
5849  * called with scheduler lock held.
5850  */
5851 static int
5852 ice_sched_replay_vsi_bw(struct ice_hw *hw, u16 vsi_handle,
5853 			ice_bitmap_t *tc_bitmap)
5854 {
5855 	struct ice_sched_node *vsi_node, *tc_node;
5856 	struct ice_port_info *pi = hw->port_info;
5857 	struct ice_bw_type_info *bw_t_info;
5858 	struct ice_vsi_ctx *vsi_ctx;
5859 	int status = 0;
5860 	u8 tc;
5861 
5862 	vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
5863 	if (!vsi_ctx)
5864 		return ICE_ERR_PARAM;
5865 	ice_for_each_traffic_class(tc) {
5866 		if (!ice_is_tc_ena(*tc_bitmap, tc))
5867 			continue;
5868 		tc_node = ice_sched_get_tc_node(pi, tc);
5869 		if (!tc_node)
5870 			continue;
5871 		vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
5872 		if (!vsi_node)
5873 			continue;
5874 		bw_t_info = &vsi_ctx->sched.bw_t_info[tc];
5875 		status = ice_sched_replay_node_bw(hw, vsi_node, bw_t_info);
5876 		if (status)
5877 			break;
5878 	}
5879 	return status;
5880 }
5881 
5882 /**
5883  * ice_sched_replay_vsi_agg - replay aggregator & VSI to aggregator node(s)
5884  * @hw: pointer to the HW struct
5885  * @vsi_handle: software VSI handle
5886  *
5887  * This function replays aggregator node, VSI to aggregator type nodes, and
5888  * their node bandwidth information. This function needs to be called with
5889  * scheduler lock held.
5890  */
5891 static int
5892 ice_sched_replay_vsi_agg(struct ice_hw *hw, u16 vsi_handle)
5893 {
5894 	ice_declare_bitmap(replay_bitmap, ICE_MAX_TRAFFIC_CLASS);
5895 	struct ice_sched_agg_vsi_info *agg_vsi_info;
5896 	struct ice_port_info *pi = hw->port_info;
5897 	struct ice_sched_agg_info *agg_info;
5898 	int status;
5899 
5900 	ice_zero_bitmap(replay_bitmap, ICE_MAX_TRAFFIC_CLASS);
5901 	if (!ice_is_vsi_valid(hw, vsi_handle))
5902 		return ICE_ERR_PARAM;
5903 	agg_info = ice_get_vsi_agg_info(hw, vsi_handle);
5904 	if (!agg_info)
5905 		return 0; /* Not present in list - default Agg case */
5906 	agg_vsi_info = ice_get_agg_vsi_info(agg_info, vsi_handle);
5907 	if (!agg_vsi_info)
5908 		return 0; /* Not present in list - default Agg case */
5909 	ice_sched_get_ena_tc_bitmap(pi, agg_info->replay_tc_bitmap,
5910 				    replay_bitmap);
5911 	/* Replay aggregator node associated to vsi_handle */
5912 	status = ice_sched_cfg_agg(hw->port_info, agg_info->agg_id,
5913 				   ICE_AGG_TYPE_AGG, replay_bitmap);
5914 	if (status)
5915 		return status;
5916 	/* Replay aggregator node BW (restore aggregator BW) */
5917 	status = ice_sched_replay_agg_bw(hw, agg_info);
5918 	if (status)
5919 		return status;
5920 
5921 	ice_zero_bitmap(replay_bitmap, ICE_MAX_TRAFFIC_CLASS);
5922 	ice_sched_get_ena_tc_bitmap(pi, agg_vsi_info->replay_tc_bitmap,
5923 				    replay_bitmap);
5924 	/* Move this VSI (vsi_handle) to above aggregator */
5925 	status = ice_sched_assoc_vsi_to_agg(pi, agg_info->agg_id, vsi_handle,
5926 					    replay_bitmap);
5927 	if (status)
5928 		return status;
5929 	/* Replay VSI BW (restore VSI BW) */
5930 	return ice_sched_replay_vsi_bw(hw, vsi_handle,
5931 				       agg_vsi_info->tc_bitmap);
5932 }
5933 
5934 /**
5935  * ice_replay_vsi_agg - replay VSI to aggregator node
5936  * @hw: pointer to the HW struct
5937  * @vsi_handle: software VSI handle
5938  *
5939  * This function replays association of VSI to aggregator type nodes, and
5940  * node bandwidth information.
5941  */
5942 int ice_replay_vsi_agg(struct ice_hw *hw, u16 vsi_handle)
5943 {
5944 	struct ice_port_info *pi = hw->port_info;
5945 	int status;
5946 
5947 	ice_acquire_lock(&pi->sched_lock);
5948 	status = ice_sched_replay_vsi_agg(hw, vsi_handle);
5949 	ice_release_lock(&pi->sched_lock);
5950 	return status;
5951 }
5952 
5953 /**
5954  * ice_sched_replay_q_bw - replay queue type node BW
5955  * @pi: port information structure
5956  * @q_ctx: queue context structure
5957  *
5958  * This function replays queue type node bandwidth. This function needs to be
5959  * called with scheduler lock held.
5960  */
5961 int
5962 ice_sched_replay_q_bw(struct ice_port_info *pi, struct ice_q_ctx *q_ctx)
5963 {
5964 	struct ice_sched_node *q_node;
5965 
5966 	/* Following also checks the presence of node in tree */
5967 	q_node = ice_sched_find_node_by_teid(pi->root, q_ctx->q_teid);
5968 	if (!q_node)
5969 		return ICE_ERR_PARAM;
5970 	return ice_sched_replay_node_bw(pi->hw, q_node, &q_ctx->bw_t_info);
5971 }
5972