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