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