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