1
2
3
4#include "ice_sched.h"
5
6
7
8
9
10
11
12
13
14static enum ice_status
15ice_sched_add_root_node(struct ice_port_info *pi,
16 struct ice_aqc_txsched_elem_data *info)
17{
18 struct ice_sched_node *root;
19 struct ice_hw *hw;
20
21 if (!pi)
22 return ICE_ERR_PARAM;
23
24 hw = pi->hw;
25
26 root = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*root), GFP_KERNEL);
27 if (!root)
28 return ICE_ERR_NO_MEMORY;
29
30
31 root->children = devm_kcalloc(ice_hw_to_dev(hw), hw->max_children[0],
32 sizeof(*root), GFP_KERNEL);
33 if (!root->children) {
34 devm_kfree(ice_hw_to_dev(hw), root);
35 return ICE_ERR_NO_MEMORY;
36 }
37
38 memcpy(&root->info, info, sizeof(*info));
39 pi->root = root;
40 return 0;
41}
42
43
44
45
46
47
48
49
50
51
52
53
54struct ice_sched_node *
55ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid)
56{
57 u16 i;
58
59
60 if (ICE_TXSCHED_GET_NODE_TEID(start_node) == teid)
61 return start_node;
62
63
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
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
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
89
90
91
92
93
94
95
96
97
98
99static enum ice_status
100ice_aqc_send_sched_elem_cmd(struct ice_hw *hw, enum ice_adminq_opc cmd_opc,
101 u16 elems_req, void *buf, u16 buf_size,
102 u16 *elems_resp, struct ice_sq_cd *cd)
103{
104 struct ice_aqc_sched_elem_cmd *cmd;
105 struct ice_aq_desc desc;
106 enum ice_status status;
107
108 cmd = &desc.params.sched_elem_cmd;
109 ice_fill_dflt_direct_cmd_desc(&desc, cmd_opc);
110 cmd->num_elem_req = cpu_to_le16(elems_req);
111 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
112 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
113 if (!status && elems_resp)
114 *elems_resp = le16_to_cpu(cmd->num_elem_resp);
115
116 return status;
117}
118
119
120
121
122
123
124
125
126
127
128
129
130enum ice_status
131ice_aq_query_sched_elems(struct ice_hw *hw, u16 elems_req,
132 struct ice_aqc_get_elem *buf, u16 buf_size,
133 u16 *elems_ret, struct ice_sq_cd *cd)
134{
135 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_get_sched_elems,
136 elems_req, (void *)buf, buf_size,
137 elems_ret, cd);
138}
139
140
141
142
143
144
145
146
147
148enum ice_status
149ice_sched_add_node(struct ice_port_info *pi, u8 layer,
150 struct ice_aqc_txsched_elem_data *info)
151{
152 struct ice_sched_node *parent;
153 struct ice_aqc_get_elem elem;
154 struct ice_sched_node *node;
155 enum ice_status status;
156 struct ice_hw *hw;
157
158 if (!pi)
159 return ICE_ERR_PARAM;
160
161 hw = pi->hw;
162
163
164 parent = ice_sched_find_node_by_teid(pi->root,
165 le32_to_cpu(info->parent_teid));
166 if (!parent) {
167 ice_debug(hw, ICE_DBG_SCHED,
168 "Parent Node not found for parent_teid=0x%x\n",
169 le32_to_cpu(info->parent_teid));
170 return ICE_ERR_PARAM;
171 }
172
173
174
175
176 status = ice_sched_query_elem(hw, le32_to_cpu(info->node_teid), &elem);
177 if (status)
178 return status;
179
180 node = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*node), GFP_KERNEL);
181 if (!node)
182 return ICE_ERR_NO_MEMORY;
183 if (hw->max_children[layer]) {
184
185 node->children = devm_kcalloc(ice_hw_to_dev(hw),
186 hw->max_children[layer],
187 sizeof(*node), GFP_KERNEL);
188 if (!node->children) {
189 devm_kfree(ice_hw_to_dev(hw), node);
190 return ICE_ERR_NO_MEMORY;
191 }
192 }
193
194 node->in_use = true;
195 node->parent = parent;
196 node->tx_sched_layer = layer;
197 parent->children[parent->num_children++] = node;
198 memcpy(&node->info, &elem.generic[0], sizeof(node->info));
199 return 0;
200}
201
202
203
204
205
206
207
208
209
210
211
212
213static enum ice_status
214ice_aq_delete_sched_elems(struct ice_hw *hw, u16 grps_req,
215 struct ice_aqc_delete_elem *buf, u16 buf_size,
216 u16 *grps_del, struct ice_sq_cd *cd)
217{
218 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_delete_sched_elems,
219 grps_req, (void *)buf, buf_size,
220 grps_del, cd);
221}
222
223
224
225
226
227
228
229
230
231
232static enum ice_status
233ice_sched_remove_elems(struct ice_hw *hw, struct ice_sched_node *parent,
234 u16 num_nodes, u32 *node_teids)
235{
236 struct ice_aqc_delete_elem *buf;
237 u16 i, num_groups_removed = 0;
238 enum ice_status status;
239 u16 buf_size;
240
241 buf_size = sizeof(*buf) + sizeof(u32) * (num_nodes - 1);
242 buf = devm_kzalloc(ice_hw_to_dev(hw), buf_size, GFP_KERNEL);
243 if (!buf)
244 return ICE_ERR_NO_MEMORY;
245
246 buf->hdr.parent_teid = parent->info.node_teid;
247 buf->hdr.num_elems = cpu_to_le16(num_nodes);
248 for (i = 0; i < num_nodes; i++)
249 buf->teid[i] = cpu_to_le32(node_teids[i]);
250
251 status = ice_aq_delete_sched_elems(hw, 1, buf, buf_size,
252 &num_groups_removed, NULL);
253 if (status || num_groups_removed != 1)
254 ice_debug(hw, ICE_DBG_SCHED, "remove node failed FW error %d\n",
255 hw->adminq.sq_last_status);
256
257 devm_kfree(ice_hw_to_dev(hw), buf);
258 return status;
259}
260
261
262
263
264
265
266
267
268
269static struct ice_sched_node *
270ice_sched_get_first_node(struct ice_hw *hw, struct ice_sched_node *parent,
271 u8 layer)
272{
273 u8 i;
274
275 if (layer < hw->sw_entry_point_layer)
276 return NULL;
277 for (i = 0; i < parent->num_children; i++) {
278 struct ice_sched_node *node = parent->children[i];
279
280 if (node) {
281 if (node->tx_sched_layer == layer)
282 return node;
283
284
285
286 return ice_sched_get_first_node(hw, node, layer);
287 }
288 }
289 return NULL;
290}
291
292
293
294
295
296
297
298
299struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc)
300{
301 u8 i;
302
303 if (!pi)
304 return NULL;
305 for (i = 0; i < pi->root->num_children; i++)
306 if (pi->root->children[i]->tc_num == tc)
307 return pi->root->children[i];
308 return NULL;
309}
310
311
312
313
314
315
316
317
318
319
320void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
321{
322 struct ice_sched_node *parent;
323 struct ice_hw *hw = pi->hw;
324 u8 i, j;
325
326
327
328
329
330 while (node->num_children)
331 ice_free_sched_node(pi, node->children[0]);
332
333
334 if (node->tx_sched_layer >= hw->sw_entry_point_layer &&
335 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC &&
336 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT &&
337 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_LEAF) {
338 u32 teid = le32_to_cpu(node->info.node_teid);
339
340 ice_sched_remove_elems(hw, node->parent, 1, &teid);
341 }
342 parent = node->parent;
343
344 if (parent) {
345 struct ice_sched_node *p, *tc_node;
346
347
348 for (i = 0; i < parent->num_children; i++)
349 if (parent->children[i] == node) {
350 for (j = i + 1; j < parent->num_children; j++)
351 parent->children[j - 1] =
352 parent->children[j];
353 parent->num_children--;
354 break;
355 }
356
357
358
359
360 tc_node = ice_sched_get_tc_node(pi, node->tc_num);
361 if (!tc_node) {
362 ice_debug(hw, ICE_DBG_SCHED,
363 "Invalid TC number %d\n", node->tc_num);
364 goto err_exit;
365 }
366 p = ice_sched_get_first_node(hw, tc_node, node->tx_sched_layer);
367 while (p) {
368 if (p->sibling == node) {
369 p->sibling = node->sibling;
370 break;
371 }
372 p = p->sibling;
373 }
374 }
375err_exit:
376
377 if (node->children)
378 devm_kfree(ice_hw_to_dev(hw), node->children);
379 devm_kfree(ice_hw_to_dev(hw), node);
380}
381
382
383
384
385
386
387
388
389
390
391
392
393static enum ice_status
394ice_aq_get_dflt_topo(struct ice_hw *hw, u8 lport,
395 struct ice_aqc_get_topo_elem *buf, u16 buf_size,
396 u8 *num_branches, struct ice_sq_cd *cd)
397{
398 struct ice_aqc_get_topo *cmd;
399 struct ice_aq_desc desc;
400 enum ice_status status;
401
402 cmd = &desc.params.get_topo;
403 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_dflt_topo);
404 cmd->port_num = lport;
405 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
406 if (!status && num_branches)
407 *num_branches = cmd->num_branches;
408
409 return status;
410}
411
412
413
414
415
416
417
418
419
420
421
422
423static enum ice_status
424ice_aq_add_sched_elems(struct ice_hw *hw, u16 grps_req,
425 struct ice_aqc_add_elem *buf, u16 buf_size,
426 u16 *grps_added, struct ice_sq_cd *cd)
427{
428 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_add_sched_elems,
429 grps_req, (void *)buf, buf_size,
430 grps_added, cd);
431}
432
433
434
435
436
437
438
439
440
441
442
443
444static enum ice_status
445ice_aq_suspend_sched_elems(struct ice_hw *hw, u16 elems_req,
446 struct ice_aqc_suspend_resume_elem *buf,
447 u16 buf_size, u16 *elems_ret, struct ice_sq_cd *cd)
448{
449 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_suspend_sched_elems,
450 elems_req, (void *)buf, buf_size,
451 elems_ret, cd);
452}
453
454
455
456
457
458
459
460
461
462
463
464
465static enum ice_status
466ice_aq_resume_sched_elems(struct ice_hw *hw, u16 elems_req,
467 struct ice_aqc_suspend_resume_elem *buf,
468 u16 buf_size, u16 *elems_ret, struct ice_sq_cd *cd)
469{
470 return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_resume_sched_elems,
471 elems_req, (void *)buf, buf_size,
472 elems_ret, cd);
473}
474
475
476
477
478
479
480
481
482
483
484static enum ice_status
485ice_aq_query_sched_res(struct ice_hw *hw, u16 buf_size,
486 struct ice_aqc_query_txsched_res_resp *buf,
487 struct ice_sq_cd *cd)
488{
489 struct ice_aq_desc desc;
490
491 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_query_sched_res);
492 return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
493}
494
495
496
497
498
499
500
501
502
503
504static enum ice_status
505ice_sched_suspend_resume_elems(struct ice_hw *hw, u8 num_nodes, u32 *node_teids,
506 bool suspend)
507{
508 struct ice_aqc_suspend_resume_elem *buf;
509 u16 i, buf_size, num_elem_ret = 0;
510 enum ice_status status;
511
512 buf_size = sizeof(*buf) * num_nodes;
513 buf = devm_kzalloc(ice_hw_to_dev(hw), buf_size, GFP_KERNEL);
514 if (!buf)
515 return ICE_ERR_NO_MEMORY;
516
517 for (i = 0; i < num_nodes; i++)
518 buf->teid[i] = cpu_to_le32(node_teids[i]);
519
520 if (suspend)
521 status = ice_aq_suspend_sched_elems(hw, num_nodes, buf,
522 buf_size, &num_elem_ret,
523 NULL);
524 else
525 status = ice_aq_resume_sched_elems(hw, num_nodes, buf,
526 buf_size, &num_elem_ret,
527 NULL);
528 if (status || num_elem_ret != num_nodes)
529 ice_debug(hw, ICE_DBG_SCHED, "suspend/resume failed\n");
530
531 devm_kfree(ice_hw_to_dev(hw), buf);
532 return status;
533}
534
535
536
537
538
539
540
541
542static enum ice_status
543ice_alloc_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 new_numqs)
544{
545 struct ice_vsi_ctx *vsi_ctx;
546 struct ice_q_ctx *q_ctx;
547
548 vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
549 if (!vsi_ctx)
550 return ICE_ERR_PARAM;
551
552 if (!vsi_ctx->lan_q_ctx[tc]) {
553 vsi_ctx->lan_q_ctx[tc] = devm_kcalloc(ice_hw_to_dev(hw),
554 new_numqs,
555 sizeof(*q_ctx),
556 GFP_KERNEL);
557 if (!vsi_ctx->lan_q_ctx[tc])
558 return ICE_ERR_NO_MEMORY;
559 vsi_ctx->num_lan_q_entries[tc] = new_numqs;
560 return 0;
561 }
562
563 if (new_numqs > vsi_ctx->num_lan_q_entries[tc]) {
564 u16 prev_num = vsi_ctx->num_lan_q_entries[tc];
565
566 q_ctx = devm_kcalloc(ice_hw_to_dev(hw), new_numqs,
567 sizeof(*q_ctx), GFP_KERNEL);
568 if (!q_ctx)
569 return ICE_ERR_NO_MEMORY;
570 memcpy(q_ctx, vsi_ctx->lan_q_ctx[tc],
571 prev_num * sizeof(*q_ctx));
572 devm_kfree(ice_hw_to_dev(hw), vsi_ctx->lan_q_ctx[tc]);
573 vsi_ctx->lan_q_ctx[tc] = q_ctx;
574 vsi_ctx->num_lan_q_entries[tc] = new_numqs;
575 }
576 return 0;
577}
578
579
580
581
582
583
584
585
586void ice_sched_clear_agg(struct ice_hw *hw)
587{
588 struct ice_sched_agg_info *agg_info;
589 struct ice_sched_agg_info *atmp;
590
591 list_for_each_entry_safe(agg_info, atmp, &hw->agg_list, list_entry) {
592 struct ice_sched_agg_vsi_info *agg_vsi_info;
593 struct ice_sched_agg_vsi_info *vtmp;
594
595 list_for_each_entry_safe(agg_vsi_info, vtmp,
596 &agg_info->agg_vsi_list, list_entry) {
597 list_del(&agg_vsi_info->list_entry);
598 devm_kfree(ice_hw_to_dev(hw), agg_vsi_info);
599 }
600 list_del(&agg_info->list_entry);
601 devm_kfree(ice_hw_to_dev(hw), agg_info);
602 }
603}
604
605
606
607
608
609
610
611static void ice_sched_clear_tx_topo(struct ice_port_info *pi)
612{
613 if (!pi)
614 return;
615 if (pi->root) {
616 ice_free_sched_node(pi, pi->root);
617 pi->root = NULL;
618 }
619}
620
621
622
623
624
625
626
627void ice_sched_clear_port(struct ice_port_info *pi)
628{
629 if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
630 return;
631
632 pi->port_state = ICE_SCHED_PORT_STATE_INIT;
633 mutex_lock(&pi->sched_lock);
634 ice_sched_clear_tx_topo(pi);
635 mutex_unlock(&pi->sched_lock);
636 mutex_destroy(&pi->sched_lock);
637}
638
639
640
641
642
643
644
645void ice_sched_cleanup_all(struct ice_hw *hw)
646{
647 if (!hw)
648 return;
649
650 if (hw->layer_info) {
651 devm_kfree(ice_hw_to_dev(hw), hw->layer_info);
652 hw->layer_info = NULL;
653 }
654
655 if (hw->port_info)
656 ice_sched_clear_port(hw->port_info);
657
658 hw->num_tx_sched_layers = 0;
659 hw->num_tx_sched_phys_layers = 0;
660 hw->flattened_layers = 0;
661 hw->max_cgds = 0;
662}
663
664
665
666
667
668
669
670
671
672
673
674
675
676static enum ice_status
677ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
678 struct ice_sched_node *parent, u8 layer, u16 num_nodes,
679 u16 *num_nodes_added, u32 *first_node_teid)
680{
681 struct ice_sched_node *prev, *new_node;
682 struct ice_aqc_add_elem *buf;
683 u16 i, num_groups_added = 0;
684 enum ice_status status = 0;
685 struct ice_hw *hw = pi->hw;
686 size_t buf_size;
687 u32 teid;
688
689 buf_size = struct_size(buf, generic, num_nodes - 1);
690 buf = devm_kzalloc(ice_hw_to_dev(hw), buf_size, GFP_KERNEL);
691 if (!buf)
692 return ICE_ERR_NO_MEMORY;
693
694 buf->hdr.parent_teid = parent->info.node_teid;
695 buf->hdr.num_elems = cpu_to_le16(num_nodes);
696 for (i = 0; i < num_nodes; i++) {
697 buf->generic[i].parent_teid = parent->info.node_teid;
698 buf->generic[i].data.elem_type = ICE_AQC_ELEM_TYPE_SE_GENERIC;
699 buf->generic[i].data.valid_sections =
700 ICE_AQC_ELEM_VALID_GENERIC | ICE_AQC_ELEM_VALID_CIR |
701 ICE_AQC_ELEM_VALID_EIR;
702 buf->generic[i].data.generic = 0;
703 buf->generic[i].data.cir_bw.bw_profile_idx =
704 cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID);
705 buf->generic[i].data.cir_bw.bw_alloc =
706 cpu_to_le16(ICE_SCHED_DFLT_BW_WT);
707 buf->generic[i].data.eir_bw.bw_profile_idx =
708 cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID);
709 buf->generic[i].data.eir_bw.bw_alloc =
710 cpu_to_le16(ICE_SCHED_DFLT_BW_WT);
711 }
712
713 status = ice_aq_add_sched_elems(hw, 1, buf, buf_size,
714 &num_groups_added, NULL);
715 if (status || num_groups_added != 1) {
716 ice_debug(hw, ICE_DBG_SCHED, "add node failed FW Error %d\n",
717 hw->adminq.sq_last_status);
718 devm_kfree(ice_hw_to_dev(hw), buf);
719 return ICE_ERR_CFG;
720 }
721
722 *num_nodes_added = num_nodes;
723
724 for (i = 0; i < num_nodes; i++) {
725 status = ice_sched_add_node(pi, layer, &buf->generic[i]);
726 if (status) {
727 ice_debug(hw, ICE_DBG_SCHED,
728 "add nodes in SW DB failed status =%d\n",
729 status);
730 break;
731 }
732
733 teid = le32_to_cpu(buf->generic[i].node_teid);
734 new_node = ice_sched_find_node_by_teid(parent, teid);
735 if (!new_node) {
736 ice_debug(hw, ICE_DBG_SCHED,
737 "Node is missing for teid =%d\n", teid);
738 break;
739 }
740
741 new_node->sibling = NULL;
742 new_node->tc_num = tc_node->tc_num;
743
744
745
746 prev = ice_sched_get_first_node(hw, tc_node, layer);
747 if (prev && prev != new_node) {
748 while (prev->sibling)
749 prev = prev->sibling;
750 prev->sibling = new_node;
751 }
752
753 if (i == 0)
754 *first_node_teid = teid;
755 }
756
757 devm_kfree(ice_hw_to_dev(hw), buf);
758 return status;
759}
760
761
762
763
764
765
766
767
768
769
770
771
772
773static enum ice_status
774ice_sched_add_nodes_to_layer(struct ice_port_info *pi,
775 struct ice_sched_node *tc_node,
776 struct ice_sched_node *parent, u8 layer,
777 u16 num_nodes, u32 *first_node_teid,
778 u16 *num_nodes_added)
779{
780 u32 *first_teid_ptr = first_node_teid;
781 u16 new_num_nodes, max_child_nodes;
782 enum ice_status status = 0;
783 struct ice_hw *hw = pi->hw;
784 u16 num_added = 0;
785 u32 temp;
786
787 *num_nodes_added = 0;
788
789 if (!num_nodes)
790 return status;
791
792 if (!parent || layer < hw->sw_entry_point_layer)
793 return ICE_ERR_PARAM;
794
795
796 max_child_nodes = hw->max_children[parent->tx_sched_layer];
797
798
799 if ((parent->num_children + num_nodes) > max_child_nodes) {
800
801 if (parent == tc_node)
802 return ICE_ERR_CFG;
803
804
805 if (parent->num_children < max_child_nodes) {
806 new_num_nodes = max_child_nodes - parent->num_children;
807
808
809
810 status = ice_sched_add_nodes_to_layer(pi, tc_node,
811 parent, layer,
812 new_num_nodes,
813 first_node_teid,
814 &num_added);
815 if (status)
816 return status;
817
818 *num_nodes_added += num_added;
819 }
820
821
822
823
824 if (num_added)
825 first_teid_ptr = &temp;
826
827 new_num_nodes = num_nodes - num_added;
828
829
830 parent = parent->sibling;
831
832
833
834
835
836
837 status = ice_sched_add_nodes_to_layer(pi, tc_node, parent,
838 layer, new_num_nodes,
839 first_teid_ptr,
840 &num_added);
841 *num_nodes_added += num_added;
842 return status;
843 }
844
845 status = ice_sched_add_elems(pi, tc_node, parent, layer, num_nodes,
846 num_nodes_added, first_node_teid);
847 return status;
848}
849
850
851
852
853
854
855
856static u8 ice_sched_get_qgrp_layer(struct ice_hw *hw)
857{
858
859 return hw->num_tx_sched_layers - ICE_QGRP_LAYER_OFFSET;
860}
861
862
863
864
865
866
867
868static u8 ice_sched_get_vsi_layer(struct ice_hw *hw)
869{
870
871
872
873
874
875
876 if (hw->num_tx_sched_layers > ICE_VSI_LAYER_OFFSET + 1) {
877 u8 layer = hw->num_tx_sched_layers - ICE_VSI_LAYER_OFFSET;
878
879 if (layer > hw->sw_entry_point_layer)
880 return layer;
881 }
882 return hw->sw_entry_point_layer;
883}
884
885
886
887
888
889
890
891
892static void ice_rm_dflt_leaf_node(struct ice_port_info *pi)
893{
894 struct ice_sched_node *node;
895
896 node = pi->root;
897 while (node) {
898 if (!node->num_children)
899 break;
900 node = node->children[0];
901 }
902 if (node && node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF) {
903 u32 teid = le32_to_cpu(node->info.node_teid);
904 enum ice_status status;
905
906
907 status = ice_sched_remove_elems(pi->hw, node->parent, 1, &teid);
908 if (!status)
909 ice_free_sched_node(pi, node);
910 }
911}
912
913
914
915
916
917
918
919
920static void ice_sched_rm_dflt_nodes(struct ice_port_info *pi)
921{
922 struct ice_sched_node *node;
923
924 ice_rm_dflt_leaf_node(pi);
925
926
927 node = pi->root;
928 while (node) {
929 if (node->tx_sched_layer >= pi->hw->sw_entry_point_layer &&
930 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC &&
931 node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT) {
932 ice_free_sched_node(pi, node);
933 break;
934 }
935
936 if (!node->num_children)
937 break;
938 node = node->children[0];
939 }
940}
941
942
943
944
945
946
947
948
949
950enum ice_status ice_sched_init_port(struct ice_port_info *pi)
951{
952 struct ice_aqc_get_topo_elem *buf;
953 enum ice_status status;
954 struct ice_hw *hw;
955 u8 num_branches;
956 u16 num_elems;
957 u8 i, j;
958
959 if (!pi)
960 return ICE_ERR_PARAM;
961 hw = pi->hw;
962
963
964 buf = devm_kzalloc(ice_hw_to_dev(hw), ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
965 if (!buf)
966 return ICE_ERR_NO_MEMORY;
967
968
969 status = ice_aq_get_dflt_topo(hw, pi->lport, buf, ICE_AQ_MAX_BUF_LEN,
970 &num_branches, NULL);
971 if (status)
972 goto err_init_port;
973
974
975 if (num_branches < 1 || num_branches > ICE_TXSCHED_MAX_BRANCHES) {
976 ice_debug(hw, ICE_DBG_SCHED, "num_branches unexpected %d\n",
977 num_branches);
978 status = ICE_ERR_PARAM;
979 goto err_init_port;
980 }
981
982
983 num_elems = le16_to_cpu(buf[0].hdr.num_elems);
984
985
986 if (num_elems < 1 || num_elems > ICE_AQC_TOPO_MAX_LEVEL_NUM) {
987 ice_debug(hw, ICE_DBG_SCHED, "num_elems unexpected %d\n",
988 num_elems);
989 status = ICE_ERR_PARAM;
990 goto err_init_port;
991 }
992
993
994
995
996 if (num_elems > 2 && buf[0].generic[num_elems - 1].data.elem_type ==
997 ICE_AQC_ELEM_TYPE_LEAF)
998 pi->last_node_teid =
999 le32_to_cpu(buf[0].generic[num_elems - 2].node_teid);
1000 else
1001 pi->last_node_teid =
1002 le32_to_cpu(buf[0].generic[num_elems - 1].node_teid);
1003
1004
1005 status = ice_sched_add_root_node(pi, &buf[0].generic[0]);
1006 if (status)
1007 goto err_init_port;
1008
1009
1010 for (i = 0; i < num_branches; i++) {
1011 num_elems = le16_to_cpu(buf[i].hdr.num_elems);
1012
1013
1014 for (j = 1; j < num_elems; j++) {
1015
1016 if (buf[0].generic[j].data.elem_type ==
1017 ICE_AQC_ELEM_TYPE_ENTRY_POINT)
1018 hw->sw_entry_point_layer = j;
1019
1020 status = ice_sched_add_node(pi, j, &buf[i].generic[j]);
1021 if (status)
1022 goto err_init_port;
1023 }
1024 }
1025
1026
1027 if (pi->root)
1028 ice_sched_rm_dflt_nodes(pi);
1029
1030
1031 pi->port_state = ICE_SCHED_PORT_STATE_READY;
1032 mutex_init(&pi->sched_lock);
1033
1034err_init_port:
1035 if (status && pi->root) {
1036 ice_free_sched_node(pi, pi->root);
1037 pi->root = NULL;
1038 }
1039
1040 devm_kfree(ice_hw_to_dev(hw), buf);
1041 return status;
1042}
1043
1044
1045
1046
1047
1048
1049
1050enum ice_status ice_sched_query_res_alloc(struct ice_hw *hw)
1051{
1052 struct ice_aqc_query_txsched_res_resp *buf;
1053 enum ice_status status = 0;
1054 __le16 max_sibl;
1055 u8 i;
1056
1057 if (hw->layer_info)
1058 return status;
1059
1060 buf = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*buf), GFP_KERNEL);
1061 if (!buf)
1062 return ICE_ERR_NO_MEMORY;
1063
1064 status = ice_aq_query_sched_res(hw, sizeof(*buf), buf, NULL);
1065 if (status)
1066 goto sched_query_out;
1067
1068 hw->num_tx_sched_layers = le16_to_cpu(buf->sched_props.logical_levels);
1069 hw->num_tx_sched_phys_layers =
1070 le16_to_cpu(buf->sched_props.phys_levels);
1071 hw->flattened_layers = buf->sched_props.flattening_bitmap;
1072 hw->max_cgds = buf->sched_props.max_pf_cgds;
1073
1074
1075
1076
1077
1078
1079
1080
1081 for (i = 0; i < hw->num_tx_sched_layers; i++) {
1082 max_sibl = buf->layer_props[i].max_sibl_grp_sz;
1083 hw->max_children[i] = le16_to_cpu(max_sibl);
1084 }
1085
1086 hw->layer_info = devm_kmemdup(ice_hw_to_dev(hw), buf->layer_props,
1087 (hw->num_tx_sched_layers *
1088 sizeof(*hw->layer_info)),
1089 GFP_KERNEL);
1090 if (!hw->layer_info) {
1091 status = ICE_ERR_NO_MEMORY;
1092 goto sched_query_out;
1093 }
1094
1095sched_query_out:
1096 devm_kfree(ice_hw_to_dev(hw), buf);
1097 return status;
1098}
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109static bool
1110ice_sched_find_node_in_subtree(struct ice_hw *hw, struct ice_sched_node *base,
1111 struct ice_sched_node *node)
1112{
1113 u8 i;
1114
1115 for (i = 0; i < base->num_children; i++) {
1116 struct ice_sched_node *child = base->children[i];
1117
1118 if (node == child)
1119 return true;
1120
1121 if (child->tx_sched_layer > node->tx_sched_layer)
1122 return false;
1123
1124
1125
1126
1127 if (ice_sched_find_node_in_subtree(hw, child, node))
1128 return true;
1129 }
1130 return false;
1131}
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142struct ice_sched_node *
1143ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
1144 u8 owner)
1145{
1146 struct ice_sched_node *vsi_node, *qgrp_node = NULL;
1147 struct ice_vsi_ctx *vsi_ctx;
1148 u16 max_children;
1149 u8 qgrp_layer;
1150
1151 qgrp_layer = ice_sched_get_qgrp_layer(pi->hw);
1152 max_children = pi->hw->max_children[qgrp_layer];
1153
1154 vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
1155 if (!vsi_ctx)
1156 return NULL;
1157 vsi_node = vsi_ctx->sched.vsi_node[tc];
1158
1159 if (!vsi_node)
1160 goto lan_q_exit;
1161
1162
1163 qgrp_node = ice_sched_get_first_node(pi->hw, vsi_node, qgrp_layer);
1164 while (qgrp_node) {
1165
1166 if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node))
1167 if (qgrp_node->num_children < max_children &&
1168 qgrp_node->owner == owner)
1169 break;
1170 qgrp_node = qgrp_node->sibling;
1171 }
1172
1173lan_q_exit:
1174 return qgrp_node;
1175}
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186static struct ice_sched_node *
1187ice_sched_get_vsi_node(struct ice_hw *hw, struct ice_sched_node *tc_node,
1188 u16 vsi_handle)
1189{
1190 struct ice_sched_node *node;
1191 u8 vsi_layer;
1192
1193 vsi_layer = ice_sched_get_vsi_layer(hw);
1194 node = ice_sched_get_first_node(hw, tc_node, vsi_layer);
1195
1196
1197 while (node) {
1198 if (node->vsi_handle == vsi_handle)
1199 return node;
1200 node = node->sibling;
1201 }
1202
1203 return node;
1204}
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215static void
1216ice_sched_calc_vsi_child_nodes(struct ice_hw *hw, u16 num_qs, u16 *num_nodes)
1217{
1218 u16 num = num_qs;
1219 u8 i, qgl, vsil;
1220
1221 qgl = ice_sched_get_qgrp_layer(hw);
1222 vsil = ice_sched_get_vsi_layer(hw);
1223
1224
1225 for (i = qgl; i > vsil; i--) {
1226
1227 num = DIV_ROUND_UP(num, hw->max_children[i]);
1228
1229
1230 num_nodes[i] = num ? num : 1;
1231 }
1232}
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245static enum ice_status
1246ice_sched_add_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
1247 struct ice_sched_node *tc_node, u16 *num_nodes,
1248 u8 owner)
1249{
1250 struct ice_sched_node *parent, *node;
1251 struct ice_hw *hw = pi->hw;
1252 enum ice_status status;
1253 u32 first_node_teid;
1254 u16 num_added = 0;
1255 u8 i, qgl, vsil;
1256
1257 qgl = ice_sched_get_qgrp_layer(hw);
1258 vsil = ice_sched_get_vsi_layer(hw);
1259 parent = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
1260 for (i = vsil + 1; i <= qgl; i++) {
1261 if (!parent)
1262 return ICE_ERR_CFG;
1263
1264 status = ice_sched_add_nodes_to_layer(pi, tc_node, parent, i,
1265 num_nodes[i],
1266 &first_node_teid,
1267 &num_added);
1268 if (status || num_nodes[i] != num_added)
1269 return ICE_ERR_CFG;
1270
1271
1272
1273
1274 if (num_added) {
1275 parent = ice_sched_find_node_by_teid(tc_node,
1276 first_node_teid);
1277 node = parent;
1278 while (node) {
1279 node->owner = owner;
1280 node = node->sibling;
1281 }
1282 } else {
1283 parent = parent->children[0];
1284 }
1285 }
1286
1287 return 0;
1288}
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300static void
1301ice_sched_calc_vsi_support_nodes(struct ice_hw *hw,
1302 struct ice_sched_node *tc_node, u16 *num_nodes)
1303{
1304 struct ice_sched_node *node;
1305 u8 vsil;
1306 int i;
1307
1308 vsil = ice_sched_get_vsi_layer(hw);
1309 for (i = vsil; i >= hw->sw_entry_point_layer; i--)
1310
1311
1312
1313 if (!tc_node->num_children || i == vsil) {
1314 num_nodes[i]++;
1315 } else {
1316
1317
1318
1319 node = ice_sched_get_first_node(hw, tc_node, (u8)i);
1320
1321 while (node) {
1322 if (node->num_children < hw->max_children[i])
1323 break;
1324 node = node->sibling;
1325 }
1326
1327
1328
1329
1330
1331 if (node)
1332 break;
1333
1334 num_nodes[i]++;
1335 }
1336}
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348static enum ice_status
1349ice_sched_add_vsi_support_nodes(struct ice_port_info *pi, u16 vsi_handle,
1350 struct ice_sched_node *tc_node, u16 *num_nodes)
1351{
1352 struct ice_sched_node *parent = tc_node;
1353 enum ice_status status;
1354 u32 first_node_teid;
1355 u16 num_added = 0;
1356 u8 i, vsil;
1357
1358 if (!pi)
1359 return ICE_ERR_PARAM;
1360
1361 vsil = ice_sched_get_vsi_layer(pi->hw);
1362 for (i = pi->hw->sw_entry_point_layer; i <= vsil; i++) {
1363 status = ice_sched_add_nodes_to_layer(pi, tc_node, parent,
1364 i, num_nodes[i],
1365 &first_node_teid,
1366 &num_added);
1367 if (status || num_nodes[i] != num_added)
1368 return ICE_ERR_CFG;
1369
1370
1371
1372
1373 if (num_added)
1374 parent = ice_sched_find_node_by_teid(tc_node,
1375 first_node_teid);
1376 else
1377 parent = parent->children[0];
1378
1379 if (!parent)
1380 return ICE_ERR_CFG;
1381
1382 if (i == vsil)
1383 parent->vsi_handle = vsi_handle;
1384 }
1385
1386 return 0;
1387}
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397static enum ice_status
1398ice_sched_add_vsi_to_topo(struct ice_port_info *pi, u16 vsi_handle, u8 tc)
1399{
1400 u16 num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 };
1401 struct ice_sched_node *tc_node;
1402 struct ice_hw *hw = pi->hw;
1403
1404 tc_node = ice_sched_get_tc_node(pi, tc);
1405 if (!tc_node)
1406 return ICE_ERR_PARAM;
1407
1408
1409 ice_sched_calc_vsi_support_nodes(hw, tc_node, num_nodes);
1410
1411
1412 return ice_sched_add_vsi_support_nodes(pi, vsi_handle, tc_node,
1413 num_nodes);
1414}
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426static enum ice_status
1427ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
1428 u8 tc, u16 new_numqs, u8 owner)
1429{
1430 u16 new_num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 };
1431 struct ice_sched_node *vsi_node;
1432 struct ice_sched_node *tc_node;
1433 struct ice_vsi_ctx *vsi_ctx;
1434 enum ice_status status = 0;
1435 struct ice_hw *hw = pi->hw;
1436 u16 prev_numqs;
1437
1438 tc_node = ice_sched_get_tc_node(pi, tc);
1439 if (!tc_node)
1440 return ICE_ERR_CFG;
1441
1442 vsi_node = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
1443 if (!vsi_node)
1444 return ICE_ERR_CFG;
1445
1446 vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
1447 if (!vsi_ctx)
1448 return ICE_ERR_PARAM;
1449
1450 prev_numqs = vsi_ctx->sched.max_lanq[tc];
1451
1452 if (new_numqs <= prev_numqs)
1453 return status;
1454 status = ice_alloc_lan_q_ctx(hw, vsi_handle, tc, new_numqs);
1455 if (status)
1456 return status;
1457
1458 if (new_numqs)
1459 ice_sched_calc_vsi_child_nodes(hw, new_numqs, new_num_nodes);
1460
1461
1462
1463
1464
1465
1466
1467 status = ice_sched_add_vsi_child_nodes(pi, vsi_handle, tc_node,
1468 new_num_nodes, owner);
1469 if (status)
1470 return status;
1471 vsi_ctx->sched.max_lanq[tc] = new_numqs;
1472
1473 return 0;
1474}
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489enum ice_status
1490ice_sched_cfg_vsi(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 maxqs,
1491 u8 owner, bool enable)
1492{
1493 struct ice_sched_node *vsi_node, *tc_node;
1494 struct ice_vsi_ctx *vsi_ctx;
1495 enum ice_status status = 0;
1496 struct ice_hw *hw = pi->hw;
1497
1498 ice_debug(pi->hw, ICE_DBG_SCHED, "add/config VSI %d\n", vsi_handle);
1499 tc_node = ice_sched_get_tc_node(pi, tc);
1500 if (!tc_node)
1501 return ICE_ERR_PARAM;
1502 vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
1503 if (!vsi_ctx)
1504 return ICE_ERR_PARAM;
1505 vsi_node = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
1506
1507
1508 if (!enable) {
1509 if (vsi_node && vsi_node->in_use) {
1510 u32 teid = le32_to_cpu(vsi_node->info.node_teid);
1511
1512 status = ice_sched_suspend_resume_elems(hw, 1, &teid,
1513 true);
1514 if (!status)
1515 vsi_node->in_use = false;
1516 }
1517 return status;
1518 }
1519
1520
1521 if (!vsi_node) {
1522 status = ice_sched_add_vsi_to_topo(pi, vsi_handle, tc);
1523 if (status)
1524 return status;
1525
1526 vsi_node = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
1527 if (!vsi_node)
1528 return ICE_ERR_CFG;
1529
1530 vsi_ctx->sched.vsi_node[tc] = vsi_node;
1531 vsi_node->in_use = true;
1532
1533
1534
1535
1536 vsi_ctx->sched.max_lanq[tc] = 0;
1537 }
1538
1539
1540 status = ice_sched_update_vsi_child_nodes(pi, vsi_handle, tc, maxqs,
1541 owner);
1542 if (status)
1543 return status;
1544
1545
1546 if (!vsi_node->in_use) {
1547 u32 teid = le32_to_cpu(vsi_node->info.node_teid);
1548
1549 status = ice_sched_suspend_resume_elems(hw, 1, &teid, false);
1550 if (!status)
1551 vsi_node->in_use = true;
1552 }
1553
1554 return status;
1555}
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565static void
1566ice_sched_rm_agg_vsi_info(struct ice_port_info *pi, u16 vsi_handle)
1567{
1568 struct ice_sched_agg_info *agg_info;
1569 struct ice_sched_agg_info *atmp;
1570
1571 list_for_each_entry_safe(agg_info, atmp, &pi->hw->agg_list,
1572 list_entry) {
1573 struct ice_sched_agg_vsi_info *agg_vsi_info;
1574 struct ice_sched_agg_vsi_info *vtmp;
1575
1576 list_for_each_entry_safe(agg_vsi_info, vtmp,
1577 &agg_info->agg_vsi_list, list_entry)
1578 if (agg_vsi_info->vsi_handle == vsi_handle) {
1579 list_del(&agg_vsi_info->list_entry);
1580 devm_kfree(ice_hw_to_dev(pi->hw),
1581 agg_vsi_info);
1582 return;
1583 }
1584 }
1585}
1586
1587
1588
1589
1590
1591
1592
1593static bool ice_sched_is_leaf_node_present(struct ice_sched_node *node)
1594{
1595 u8 i;
1596
1597 for (i = 0; i < node->num_children; i++)
1598 if (ice_sched_is_leaf_node_present(node->children[i]))
1599 return true;
1600
1601 return (node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF);
1602}
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613static enum ice_status
1614ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner)
1615{
1616 enum ice_status status = ICE_ERR_PARAM;
1617 struct ice_vsi_ctx *vsi_ctx;
1618 u8 i;
1619
1620 ice_debug(pi->hw, ICE_DBG_SCHED, "removing VSI %d\n", vsi_handle);
1621 if (!ice_is_vsi_valid(pi->hw, vsi_handle))
1622 return status;
1623 mutex_lock(&pi->sched_lock);
1624 vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
1625 if (!vsi_ctx)
1626 goto exit_sched_rm_vsi_cfg;
1627
1628 ice_for_each_traffic_class(i) {
1629 struct ice_sched_node *vsi_node, *tc_node;
1630 u8 j = 0;
1631
1632 tc_node = ice_sched_get_tc_node(pi, i);
1633 if (!tc_node)
1634 continue;
1635
1636 vsi_node = ice_sched_get_vsi_node(pi->hw, tc_node, vsi_handle);
1637 if (!vsi_node)
1638 continue;
1639
1640 if (ice_sched_is_leaf_node_present(vsi_node)) {
1641 ice_debug(pi->hw, ICE_DBG_SCHED,
1642 "VSI has leaf nodes in TC %d\n", i);
1643 status = ICE_ERR_IN_USE;
1644 goto exit_sched_rm_vsi_cfg;
1645 }
1646 while (j < vsi_node->num_children) {
1647 if (vsi_node->children[j]->owner == owner) {
1648 ice_free_sched_node(pi, vsi_node->children[j]);
1649
1650
1651
1652
1653 j = 0;
1654 } else {
1655 j++;
1656 }
1657 }
1658
1659 if (!vsi_node->num_children) {
1660 ice_free_sched_node(pi, vsi_node);
1661 vsi_ctx->sched.vsi_node[i] = NULL;
1662
1663
1664 ice_sched_rm_agg_vsi_info(pi, vsi_handle);
1665 }
1666 if (owner == ICE_SCHED_NODE_OWNER_LAN)
1667 vsi_ctx->sched.max_lanq[i] = 0;
1668 }
1669 status = 0;
1670
1671exit_sched_rm_vsi_cfg:
1672 mutex_unlock(&pi->sched_lock);
1673 return status;
1674}
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684enum ice_status ice_rm_vsi_lan_cfg(struct ice_port_info *pi, u16 vsi_handle)
1685{
1686 return ice_sched_rm_vsi_cfg(pi, vsi_handle, ICE_SCHED_NODE_OWNER_LAN);
1687}
1688