xref: /openbmc/linux/drivers/net/ethernet/microchip/sparx5/sparx5_sdlb.c (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
1*9bf50889SDaniel Machon // SPDX-License-Identifier: GPL-2.0+
2*9bf50889SDaniel Machon /* Microchip Sparx5 Switch driver
3*9bf50889SDaniel Machon  *
4*9bf50889SDaniel Machon  * Copyright (c) 2023 Microchip Technology Inc. and its subsidiaries.
5*9bf50889SDaniel Machon  */
6*9bf50889SDaniel Machon 
7*9bf50889SDaniel Machon #include "sparx5_main_regs.h"
8*9bf50889SDaniel Machon #include "sparx5_main.h"
9*9bf50889SDaniel Machon 
10*9bf50889SDaniel Machon struct sparx5_sdlb_group sdlb_groups[SPX5_SDLB_GROUP_CNT] = {
11*9bf50889SDaniel Machon 	{ SPX5_SDLB_GROUP_RATE_MAX,    8192 / 1, 64 }, /*  25 G */
12*9bf50889SDaniel Machon 	{ 15000000000ULL,              8192 / 1, 64 }, /*  15 G */
13*9bf50889SDaniel Machon 	{ 10000000000ULL,              8192 / 1, 64 }, /*  10 G */
14*9bf50889SDaniel Machon 	{  5000000000ULL,              8192 / 1, 64 }, /*   5 G */
15*9bf50889SDaniel Machon 	{  2500000000ULL,              8192 / 1, 64 }, /* 2.5 G */
16*9bf50889SDaniel Machon 	{  1000000000ULL,              8192 / 2, 64 }, /*   1 G */
17*9bf50889SDaniel Machon 	{   500000000ULL,              8192 / 2, 64 }, /* 500 M */
18*9bf50889SDaniel Machon 	{   100000000ULL,              8192 / 4, 64 }, /* 100 M */
19*9bf50889SDaniel Machon 	{    50000000ULL,              8192 / 4, 64 }, /*  50 M */
20*9bf50889SDaniel Machon 	{     5000000ULL,              8192 / 8, 64 }  /*   5 M */
21*9bf50889SDaniel Machon };
22*9bf50889SDaniel Machon 
sparx5_sdlb_clk_hz_get(struct sparx5 * sparx5)23*9bf50889SDaniel Machon int sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5)
24*9bf50889SDaniel Machon {
25*9bf50889SDaniel Machon 	u32 clk_per_100ps;
26*9bf50889SDaniel Machon 	u64 clk_hz;
27*9bf50889SDaniel Machon 
28*9bf50889SDaniel Machon 	clk_per_100ps = HSCH_SYS_CLK_PER_100PS_GET(spx5_rd(sparx5,
29*9bf50889SDaniel Machon 							   HSCH_SYS_CLK_PER));
30*9bf50889SDaniel Machon 	if (!clk_per_100ps)
31*9bf50889SDaniel Machon 		clk_per_100ps = SPX5_CLK_PER_100PS_DEFAULT;
32*9bf50889SDaniel Machon 
33*9bf50889SDaniel Machon 	clk_hz = (10 * 1000 * 1000) / clk_per_100ps;
34*9bf50889SDaniel Machon 	return clk_hz *= 1000;
35*9bf50889SDaniel Machon }
36*9bf50889SDaniel Machon 
sparx5_sdlb_pup_interval_get(struct sparx5 * sparx5,u32 max_token,u64 max_rate)37*9bf50889SDaniel Machon static int sparx5_sdlb_pup_interval_get(struct sparx5 *sparx5, u32 max_token,
38*9bf50889SDaniel Machon 					u64 max_rate)
39*9bf50889SDaniel Machon {
40*9bf50889SDaniel Machon 	u64 clk_hz;
41*9bf50889SDaniel Machon 
42*9bf50889SDaniel Machon 	clk_hz = sparx5_sdlb_clk_hz_get(sparx5);
43*9bf50889SDaniel Machon 
44*9bf50889SDaniel Machon 	return div64_u64((8 * clk_hz * max_token), max_rate);
45*9bf50889SDaniel Machon }
46*9bf50889SDaniel Machon 
sparx5_sdlb_pup_token_get(struct sparx5 * sparx5,u32 pup_interval,u64 rate)47*9bf50889SDaniel Machon int sparx5_sdlb_pup_token_get(struct sparx5 *sparx5, u32 pup_interval, u64 rate)
48*9bf50889SDaniel Machon {
49*9bf50889SDaniel Machon 	u64 clk_hz;
50*9bf50889SDaniel Machon 
51*9bf50889SDaniel Machon 	if (!rate)
52*9bf50889SDaniel Machon 		return SPX5_SDLB_PUP_TOKEN_DISABLE;
53*9bf50889SDaniel Machon 
54*9bf50889SDaniel Machon 	clk_hz = sparx5_sdlb_clk_hz_get(sparx5);
55*9bf50889SDaniel Machon 
56*9bf50889SDaniel Machon 	return DIV64_U64_ROUND_UP((rate * pup_interval), (clk_hz * 8));
57*9bf50889SDaniel Machon }
58*9bf50889SDaniel Machon 
sparx5_sdlb_group_disable(struct sparx5 * sparx5,u32 group)59*9bf50889SDaniel Machon static void sparx5_sdlb_group_disable(struct sparx5 *sparx5, u32 group)
60*9bf50889SDaniel Machon {
61*9bf50889SDaniel Machon 	spx5_rmw(ANA_AC_SDLB_PUP_CTRL_PUP_ENA_SET(0),
62*9bf50889SDaniel Machon 		 ANA_AC_SDLB_PUP_CTRL_PUP_ENA, sparx5,
63*9bf50889SDaniel Machon 		 ANA_AC_SDLB_PUP_CTRL(group));
64*9bf50889SDaniel Machon }
65*9bf50889SDaniel Machon 
sparx5_sdlb_group_enable(struct sparx5 * sparx5,u32 group)66*9bf50889SDaniel Machon static void sparx5_sdlb_group_enable(struct sparx5 *sparx5, u32 group)
67*9bf50889SDaniel Machon {
68*9bf50889SDaniel Machon 	spx5_rmw(ANA_AC_SDLB_PUP_CTRL_PUP_ENA_SET(1),
69*9bf50889SDaniel Machon 		 ANA_AC_SDLB_PUP_CTRL_PUP_ENA, sparx5,
70*9bf50889SDaniel Machon 		 ANA_AC_SDLB_PUP_CTRL(group));
71*9bf50889SDaniel Machon }
72*9bf50889SDaniel Machon 
sparx5_sdlb_group_get_first(struct sparx5 * sparx5,u32 group)73*9bf50889SDaniel Machon static u32 sparx5_sdlb_group_get_first(struct sparx5 *sparx5, u32 group)
74*9bf50889SDaniel Machon {
75*9bf50889SDaniel Machon 	u32 val;
76*9bf50889SDaniel Machon 
77*9bf50889SDaniel Machon 	val = spx5_rd(sparx5, ANA_AC_SDLB_XLB_START(group));
78*9bf50889SDaniel Machon 
79*9bf50889SDaniel Machon 	return ANA_AC_SDLB_XLB_START_LBSET_START_GET(val);
80*9bf50889SDaniel Machon }
81*9bf50889SDaniel Machon 
sparx5_sdlb_group_get_next(struct sparx5 * sparx5,u32 group,u32 lb)82*9bf50889SDaniel Machon static u32 sparx5_sdlb_group_get_next(struct sparx5 *sparx5, u32 group,
83*9bf50889SDaniel Machon 				      u32 lb)
84*9bf50889SDaniel Machon {
85*9bf50889SDaniel Machon 	u32 val;
86*9bf50889SDaniel Machon 
87*9bf50889SDaniel Machon 	val = spx5_rd(sparx5, ANA_AC_SDLB_XLB_NEXT(lb));
88*9bf50889SDaniel Machon 
89*9bf50889SDaniel Machon 	return ANA_AC_SDLB_XLB_NEXT_LBSET_NEXT_GET(val);
90*9bf50889SDaniel Machon }
91*9bf50889SDaniel Machon 
sparx5_sdlb_group_is_first(struct sparx5 * sparx5,u32 group,u32 lb)92*9bf50889SDaniel Machon static bool sparx5_sdlb_group_is_first(struct sparx5 *sparx5, u32 group,
93*9bf50889SDaniel Machon 				       u32 lb)
94*9bf50889SDaniel Machon {
95*9bf50889SDaniel Machon 	return lb == sparx5_sdlb_group_get_first(sparx5, group);
96*9bf50889SDaniel Machon }
97*9bf50889SDaniel Machon 
sparx5_sdlb_group_is_last(struct sparx5 * sparx5,u32 group,u32 lb)98*9bf50889SDaniel Machon static bool sparx5_sdlb_group_is_last(struct sparx5 *sparx5, u32 group,
99*9bf50889SDaniel Machon 				      u32 lb)
100*9bf50889SDaniel Machon {
101*9bf50889SDaniel Machon 	return lb == sparx5_sdlb_group_get_next(sparx5, group, lb);
102*9bf50889SDaniel Machon }
103*9bf50889SDaniel Machon 
sparx5_sdlb_group_is_empty(struct sparx5 * sparx5,u32 group)104*9bf50889SDaniel Machon static bool sparx5_sdlb_group_is_empty(struct sparx5 *sparx5, u32 group)
105*9bf50889SDaniel Machon {
106*9bf50889SDaniel Machon 	u32 val;
107*9bf50889SDaniel Machon 
108*9bf50889SDaniel Machon 	val = spx5_rd(sparx5, ANA_AC_SDLB_PUP_CTRL(group));
109*9bf50889SDaniel Machon 
110*9bf50889SDaniel Machon 	return ANA_AC_SDLB_PUP_CTRL_PUP_ENA_GET(val) == 0;
111*9bf50889SDaniel Machon }
112*9bf50889SDaniel Machon 
sparx5_sdlb_group_get_last(struct sparx5 * sparx5,u32 group)113*9bf50889SDaniel Machon static u32 sparx5_sdlb_group_get_last(struct sparx5 *sparx5, u32 group)
114*9bf50889SDaniel Machon {
115*9bf50889SDaniel Machon 	u32 itr, next;
116*9bf50889SDaniel Machon 
117*9bf50889SDaniel Machon 	itr = sparx5_sdlb_group_get_first(sparx5, group);
118*9bf50889SDaniel Machon 
119*9bf50889SDaniel Machon 	for (;;) {
120*9bf50889SDaniel Machon 		next = sparx5_sdlb_group_get_next(sparx5, group, itr);
121*9bf50889SDaniel Machon 		if (itr == next)
122*9bf50889SDaniel Machon 			return itr;
123*9bf50889SDaniel Machon 
124*9bf50889SDaniel Machon 		itr = next;
125*9bf50889SDaniel Machon 	}
126*9bf50889SDaniel Machon }
127*9bf50889SDaniel Machon 
sparx5_sdlb_group_is_singular(struct sparx5 * sparx5,u32 group)128*9bf50889SDaniel Machon static bool sparx5_sdlb_group_is_singular(struct sparx5 *sparx5, u32 group)
129*9bf50889SDaniel Machon {
130*9bf50889SDaniel Machon 	if (sparx5_sdlb_group_is_empty(sparx5, group))
131*9bf50889SDaniel Machon 		return false;
132*9bf50889SDaniel Machon 
133*9bf50889SDaniel Machon 	return sparx5_sdlb_group_get_first(sparx5, group) ==
134*9bf50889SDaniel Machon 	       sparx5_sdlb_group_get_last(sparx5, group);
135*9bf50889SDaniel Machon }
136*9bf50889SDaniel Machon 
sparx5_sdlb_group_get_adjacent(struct sparx5 * sparx5,u32 group,u32 idx,u32 * prev,u32 * next,u32 * first)137*9bf50889SDaniel Machon static int sparx5_sdlb_group_get_adjacent(struct sparx5 *sparx5, u32 group,
138*9bf50889SDaniel Machon 					  u32 idx, u32 *prev, u32 *next,
139*9bf50889SDaniel Machon 					  u32 *first)
140*9bf50889SDaniel Machon {
141*9bf50889SDaniel Machon 	u32 itr;
142*9bf50889SDaniel Machon 
143*9bf50889SDaniel Machon 	*first = sparx5_sdlb_group_get_first(sparx5, group);
144*9bf50889SDaniel Machon 	*prev = *first;
145*9bf50889SDaniel Machon 	*next = *first;
146*9bf50889SDaniel Machon 	itr = *first;
147*9bf50889SDaniel Machon 
148*9bf50889SDaniel Machon 	for (;;) {
149*9bf50889SDaniel Machon 		*next = sparx5_sdlb_group_get_next(sparx5, group, itr);
150*9bf50889SDaniel Machon 
151*9bf50889SDaniel Machon 		if (itr == idx)
152*9bf50889SDaniel Machon 			return 0; /* Found it */
153*9bf50889SDaniel Machon 
154*9bf50889SDaniel Machon 		if (itr == *next)
155*9bf50889SDaniel Machon 			return -EINVAL; /* Was not found */
156*9bf50889SDaniel Machon 
157*9bf50889SDaniel Machon 		*prev = itr;
158*9bf50889SDaniel Machon 		itr = *next;
159*9bf50889SDaniel Machon 	}
160*9bf50889SDaniel Machon }
161*9bf50889SDaniel Machon 
sparx5_sdlb_group_get_count(struct sparx5 * sparx5,u32 group)162*9bf50889SDaniel Machon static int sparx5_sdlb_group_get_count(struct sparx5 *sparx5, u32 group)
163*9bf50889SDaniel Machon {
164*9bf50889SDaniel Machon 	u32 itr, next;
165*9bf50889SDaniel Machon 	int count = 0;
166*9bf50889SDaniel Machon 
167*9bf50889SDaniel Machon 	itr = sparx5_sdlb_group_get_first(sparx5, group);
168*9bf50889SDaniel Machon 
169*9bf50889SDaniel Machon 	for (;;) {
170*9bf50889SDaniel Machon 		next = sparx5_sdlb_group_get_next(sparx5, group, itr);
171*9bf50889SDaniel Machon 		if (itr == next)
172*9bf50889SDaniel Machon 			return count;
173*9bf50889SDaniel Machon 
174*9bf50889SDaniel Machon 		itr = next;
175*9bf50889SDaniel Machon 		count++;
176*9bf50889SDaniel Machon 	}
177*9bf50889SDaniel Machon }
178*9bf50889SDaniel Machon 
sparx5_sdlb_group_get_by_rate(struct sparx5 * sparx5,u32 rate,u32 burst)179*9bf50889SDaniel Machon int sparx5_sdlb_group_get_by_rate(struct sparx5 *sparx5, u32 rate, u32 burst)
180*9bf50889SDaniel Machon {
181*9bf50889SDaniel Machon 	const struct sparx5_sdlb_group *group;
182*9bf50889SDaniel Machon 	u64 rate_bps;
183*9bf50889SDaniel Machon 	int i, count;
184*9bf50889SDaniel Machon 
185*9bf50889SDaniel Machon 	rate_bps = rate * 1000;
186*9bf50889SDaniel Machon 
187*9bf50889SDaniel Machon 	for (i = SPX5_SDLB_GROUP_CNT - 1; i >= 0; i--) {
188*9bf50889SDaniel Machon 		group = &sdlb_groups[i];
189*9bf50889SDaniel Machon 
190*9bf50889SDaniel Machon 		count = sparx5_sdlb_group_get_count(sparx5, i);
191*9bf50889SDaniel Machon 
192*9bf50889SDaniel Machon 		/* Check that this group is not full.
193*9bf50889SDaniel Machon 		 * According to LB group configuration rules: the number of XLBs
194*9bf50889SDaniel Machon 		 * in a group must not exceed PUP_INTERVAL/4 - 1.
195*9bf50889SDaniel Machon 		 */
196*9bf50889SDaniel Machon 		if (count > ((group->pup_interval / 4) - 1))
197*9bf50889SDaniel Machon 			continue;
198*9bf50889SDaniel Machon 
199*9bf50889SDaniel Machon 		if (rate_bps < group->max_rate)
200*9bf50889SDaniel Machon 			return i;
201*9bf50889SDaniel Machon 	}
202*9bf50889SDaniel Machon 
203*9bf50889SDaniel Machon 	return -ENOSPC;
204*9bf50889SDaniel Machon }
205*9bf50889SDaniel Machon 
sparx5_sdlb_group_get_by_index(struct sparx5 * sparx5,u32 idx,u32 * group)206*9bf50889SDaniel Machon int sparx5_sdlb_group_get_by_index(struct sparx5 *sparx5, u32 idx, u32 *group)
207*9bf50889SDaniel Machon {
208*9bf50889SDaniel Machon 	u32 itr, next;
209*9bf50889SDaniel Machon 	int i;
210*9bf50889SDaniel Machon 
211*9bf50889SDaniel Machon 	for (i = 0; i < SPX5_SDLB_GROUP_CNT; i++) {
212*9bf50889SDaniel Machon 		if (sparx5_sdlb_group_is_empty(sparx5, i))
213*9bf50889SDaniel Machon 			continue;
214*9bf50889SDaniel Machon 
215*9bf50889SDaniel Machon 		itr = sparx5_sdlb_group_get_first(sparx5, i);
216*9bf50889SDaniel Machon 
217*9bf50889SDaniel Machon 		for (;;) {
218*9bf50889SDaniel Machon 			next = sparx5_sdlb_group_get_next(sparx5, i, itr);
219*9bf50889SDaniel Machon 
220*9bf50889SDaniel Machon 			if (itr == idx) {
221*9bf50889SDaniel Machon 				*group = i;
222*9bf50889SDaniel Machon 				return 0; /* Found it */
223*9bf50889SDaniel Machon 			}
224*9bf50889SDaniel Machon 			if (itr == next)
225*9bf50889SDaniel Machon 				break; /* Was not found */
226*9bf50889SDaniel Machon 
227*9bf50889SDaniel Machon 			itr = next;
228*9bf50889SDaniel Machon 		}
229*9bf50889SDaniel Machon 	}
230*9bf50889SDaniel Machon 
231*9bf50889SDaniel Machon 	return -EINVAL;
232*9bf50889SDaniel Machon }
233*9bf50889SDaniel Machon 
sparx5_sdlb_group_link(struct sparx5 * sparx5,u32 group,u32 idx,u32 first,u32 next,bool empty)234*9bf50889SDaniel Machon static int sparx5_sdlb_group_link(struct sparx5 *sparx5, u32 group, u32 idx,
235*9bf50889SDaniel Machon 				  u32 first, u32 next, bool empty)
236*9bf50889SDaniel Machon {
237*9bf50889SDaniel Machon 	/* Stop leaking */
238*9bf50889SDaniel Machon 	sparx5_sdlb_group_disable(sparx5, group);
239*9bf50889SDaniel Machon 
240*9bf50889SDaniel Machon 	if (empty)
241*9bf50889SDaniel Machon 		return 0;
242*9bf50889SDaniel Machon 
243*9bf50889SDaniel Machon 	/* Link insertion lb to next lb */
244*9bf50889SDaniel Machon 	spx5_wr(ANA_AC_SDLB_XLB_NEXT_LBSET_NEXT_SET(next) |
245*9bf50889SDaniel Machon 			ANA_AC_SDLB_XLB_NEXT_LBGRP_SET(group),
246*9bf50889SDaniel Machon 		sparx5, ANA_AC_SDLB_XLB_NEXT(idx));
247*9bf50889SDaniel Machon 
248*9bf50889SDaniel Machon 	/* Set the first lb */
249*9bf50889SDaniel Machon 	spx5_wr(ANA_AC_SDLB_XLB_START_LBSET_START_SET(first), sparx5,
250*9bf50889SDaniel Machon 		ANA_AC_SDLB_XLB_START(group));
251*9bf50889SDaniel Machon 
252*9bf50889SDaniel Machon 	/* Start leaking */
253*9bf50889SDaniel Machon 	sparx5_sdlb_group_enable(sparx5, group);
254*9bf50889SDaniel Machon 
255*9bf50889SDaniel Machon 	return 0;
256*9bf50889SDaniel Machon };
257*9bf50889SDaniel Machon 
sparx5_sdlb_group_add(struct sparx5 * sparx5,u32 group,u32 idx)258*9bf50889SDaniel Machon int sparx5_sdlb_group_add(struct sparx5 *sparx5, u32 group, u32 idx)
259*9bf50889SDaniel Machon {
260*9bf50889SDaniel Machon 	u32 first, next;
261*9bf50889SDaniel Machon 
262*9bf50889SDaniel Machon 	/* We always add to head of the list */
263*9bf50889SDaniel Machon 	first = idx;
264*9bf50889SDaniel Machon 
265*9bf50889SDaniel Machon 	if (sparx5_sdlb_group_is_empty(sparx5, group))
266*9bf50889SDaniel Machon 		next = idx;
267*9bf50889SDaniel Machon 	else
268*9bf50889SDaniel Machon 		next = sparx5_sdlb_group_get_first(sparx5, group);
269*9bf50889SDaniel Machon 
270*9bf50889SDaniel Machon 	return sparx5_sdlb_group_link(sparx5, group, idx, first, next, false);
271*9bf50889SDaniel Machon }
272*9bf50889SDaniel Machon 
sparx5_sdlb_group_del(struct sparx5 * sparx5,u32 group,u32 idx)273*9bf50889SDaniel Machon int sparx5_sdlb_group_del(struct sparx5 *sparx5, u32 group, u32 idx)
274*9bf50889SDaniel Machon {
275*9bf50889SDaniel Machon 	u32 first, next, prev;
276*9bf50889SDaniel Machon 	bool empty = false;
277*9bf50889SDaniel Machon 
278*9bf50889SDaniel Machon 	if (sparx5_sdlb_group_get_adjacent(sparx5, group, idx, &prev, &next,
279*9bf50889SDaniel Machon 					   &first) < 0) {
280*9bf50889SDaniel Machon 		pr_err("%s:%d Could not find idx: %d in group: %d", __func__,
281*9bf50889SDaniel Machon 		       __LINE__, idx, group);
282*9bf50889SDaniel Machon 		return -EINVAL;
283*9bf50889SDaniel Machon 	}
284*9bf50889SDaniel Machon 
285*9bf50889SDaniel Machon 	if (sparx5_sdlb_group_is_singular(sparx5, group)) {
286*9bf50889SDaniel Machon 		empty = true;
287*9bf50889SDaniel Machon 	} else if (sparx5_sdlb_group_is_last(sparx5, group, idx)) {
288*9bf50889SDaniel Machon 		/* idx is removed, prev is now last */
289*9bf50889SDaniel Machon 		idx = prev;
290*9bf50889SDaniel Machon 		next = prev;
291*9bf50889SDaniel Machon 	} else if (sparx5_sdlb_group_is_first(sparx5, group, idx)) {
292*9bf50889SDaniel Machon 		/* idx is removed and points to itself, first is next */
293*9bf50889SDaniel Machon 		first = next;
294*9bf50889SDaniel Machon 		next = idx;
295*9bf50889SDaniel Machon 	} else {
296*9bf50889SDaniel Machon 		/* Next is not touched */
297*9bf50889SDaniel Machon 		idx = prev;
298*9bf50889SDaniel Machon 	}
299*9bf50889SDaniel Machon 
300*9bf50889SDaniel Machon 	return sparx5_sdlb_group_link(sparx5, group, idx, first, next, empty);
301*9bf50889SDaniel Machon }
302*9bf50889SDaniel Machon 
sparx5_sdlb_group_init(struct sparx5 * sparx5,u64 max_rate,u32 min_burst,u32 frame_size,u32 idx)303*9bf50889SDaniel Machon void sparx5_sdlb_group_init(struct sparx5 *sparx5, u64 max_rate, u32 min_burst,
304*9bf50889SDaniel Machon 			    u32 frame_size, u32 idx)
305*9bf50889SDaniel Machon {
306*9bf50889SDaniel Machon 	u32 thres_shift, mask = 0x01, power = 0;
307*9bf50889SDaniel Machon 	struct sparx5_sdlb_group *group;
308*9bf50889SDaniel Machon 	u64 max_token;
309*9bf50889SDaniel Machon 
310*9bf50889SDaniel Machon 	group = &sdlb_groups[idx];
311*9bf50889SDaniel Machon 
312*9bf50889SDaniel Machon 	/* Number of positions to right-shift LB's threshold value. */
313*9bf50889SDaniel Machon 	while ((min_burst & mask) == 0) {
314*9bf50889SDaniel Machon 		power++;
315*9bf50889SDaniel Machon 		mask <<= 1;
316*9bf50889SDaniel Machon 	}
317*9bf50889SDaniel Machon 	thres_shift = SPX5_SDLB_2CYCLES_TYPE2_THRES_OFFSET - power;
318*9bf50889SDaniel Machon 
319*9bf50889SDaniel Machon 	max_token = (min_burst > SPX5_SDLB_PUP_TOKEN_MAX) ?
320*9bf50889SDaniel Machon 			    SPX5_SDLB_PUP_TOKEN_MAX :
321*9bf50889SDaniel Machon 			    min_burst;
322*9bf50889SDaniel Machon 	group->pup_interval =
323*9bf50889SDaniel Machon 		sparx5_sdlb_pup_interval_get(sparx5, max_token, max_rate);
324*9bf50889SDaniel Machon 
325*9bf50889SDaniel Machon 	group->frame_size = frame_size;
326*9bf50889SDaniel Machon 
327*9bf50889SDaniel Machon 	spx5_wr(ANA_AC_SDLB_PUP_INTERVAL_PUP_INTERVAL_SET(group->pup_interval),
328*9bf50889SDaniel Machon 		sparx5, ANA_AC_SDLB_PUP_INTERVAL(idx));
329*9bf50889SDaniel Machon 
330*9bf50889SDaniel Machon 	spx5_wr(ANA_AC_SDLB_FRM_RATE_TOKENS_FRM_RATE_TOKENS_SET(frame_size),
331*9bf50889SDaniel Machon 		sparx5, ANA_AC_SDLB_FRM_RATE_TOKENS(idx));
332*9bf50889SDaniel Machon 
333*9bf50889SDaniel Machon 	spx5_wr(ANA_AC_SDLB_LBGRP_MISC_THRES_SHIFT_SET(thres_shift), sparx5,
334*9bf50889SDaniel Machon 		ANA_AC_SDLB_LBGRP_MISC(idx));
335*9bf50889SDaniel Machon }
336