xref: /openbmc/linux/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c (revision 3eb66e91a25497065c5322b1268cbc3953642227)
1*51dce24bSJeff Kirsher // SPDX-License-Identifier: GPL-2.0
2*51dce24bSJeff Kirsher /* Copyright(c) 1999 - 2018 Intel Corporation. */
3dee1ad47SJeff Kirsher 
4dee1ad47SJeff Kirsher #include "ixgbe.h"
5dee1ad47SJeff Kirsher #include "ixgbe_type.h"
6dee1ad47SJeff Kirsher #include "ixgbe_dcb.h"
7dee1ad47SJeff Kirsher #include "ixgbe_dcb_82598.h"
8dee1ad47SJeff Kirsher #include "ixgbe_dcb_82599.h"
9dee1ad47SJeff Kirsher 
10dee1ad47SJeff Kirsher /**
11dee1ad47SJeff Kirsher  * ixgbe_ieee_credits - This calculates the ieee traffic class
12dee1ad47SJeff Kirsher  * credits from the configured bandwidth percentages. Credits
13dee1ad47SJeff Kirsher  * are the smallest unit programmable into the underlying
14dee1ad47SJeff Kirsher  * hardware. The IEEE 802.1Qaz specification do not use bandwidth
15dee1ad47SJeff Kirsher  * groups so this is much simplified from the CEE case.
165ba643c6STony Nguyen  * @bw: bandwidth index by traffic class
175ba643c6STony Nguyen  * @refill: refill credits index by traffic class
185ba643c6STony Nguyen  * @max: max credits by traffic class
195ba643c6STony Nguyen  * @max_frame: maximum frame size
20dee1ad47SJeff Kirsher  */
ixgbe_ieee_credits(__u8 * bw,__u16 * refill,__u16 * max,int max_frame)214c09f3a0SJohn Fastabend static s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill,
224c09f3a0SJohn Fastabend 			      __u16 *max, int max_frame)
23dee1ad47SJeff Kirsher {
24dee1ad47SJeff Kirsher 	int min_percent = 100;
25dee1ad47SJeff Kirsher 	int min_credit, multiplier;
26dee1ad47SJeff Kirsher 	int i;
27dee1ad47SJeff Kirsher 
28dee1ad47SJeff Kirsher 	min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
29dee1ad47SJeff Kirsher 			DCB_CREDIT_QUANTUM;
30dee1ad47SJeff Kirsher 
31dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
32dee1ad47SJeff Kirsher 		if (bw[i] < min_percent && bw[i])
33dee1ad47SJeff Kirsher 			min_percent = bw[i];
34dee1ad47SJeff Kirsher 	}
35dee1ad47SJeff Kirsher 
36dee1ad47SJeff Kirsher 	multiplier = (min_credit / min_percent) + 1;
37dee1ad47SJeff Kirsher 
38dee1ad47SJeff Kirsher 	/* Find out the hw credits for each TC */
39dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
40dee1ad47SJeff Kirsher 		int val = min(bw[i] * multiplier, MAX_CREDIT_REFILL);
41dee1ad47SJeff Kirsher 
42dee1ad47SJeff Kirsher 		if (val < min_credit)
43dee1ad47SJeff Kirsher 			val = min_credit;
44dee1ad47SJeff Kirsher 		refill[i] = val;
45dee1ad47SJeff Kirsher 
46dee1ad47SJeff Kirsher 		max[i] = bw[i] ? (bw[i] * MAX_CREDIT)/100 : min_credit;
47dee1ad47SJeff Kirsher 	}
48dee1ad47SJeff Kirsher 	return 0;
49dee1ad47SJeff Kirsher }
50dee1ad47SJeff Kirsher 
51dee1ad47SJeff Kirsher /**
52dee1ad47SJeff Kirsher  * ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits
535ba643c6STony Nguyen  * @hw: pointer to hardware structure
545ba643c6STony Nguyen  * @dcb_config: Struct containing DCB settings
555ba643c6STony Nguyen  * @max_frame: Maximum frame size
565ba643c6STony Nguyen  * @direction: Configuring either Tx or Rx
57dee1ad47SJeff Kirsher  *
58dee1ad47SJeff Kirsher  * This function calculates the credits allocated to each traffic class.
59dee1ad47SJeff Kirsher  * It should be called only after the rules are checked by
60dee1ad47SJeff Kirsher  * ixgbe_dcb_check_config().
61dee1ad47SJeff Kirsher  */
ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config,int max_frame,u8 direction)62dee1ad47SJeff Kirsher s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw,
63dee1ad47SJeff Kirsher 				   struct ixgbe_dcb_config *dcb_config,
64dee1ad47SJeff Kirsher 				   int max_frame, u8 direction)
65dee1ad47SJeff Kirsher {
66dee1ad47SJeff Kirsher 	struct tc_bw_alloc *p;
67dee1ad47SJeff Kirsher 	int min_credit;
68dee1ad47SJeff Kirsher 	int min_multiplier;
69dee1ad47SJeff Kirsher 	int min_percent = 100;
70dee1ad47SJeff Kirsher 	/* Initialization values default for Tx settings */
71dee1ad47SJeff Kirsher 	u32 credit_refill       = 0;
72dee1ad47SJeff Kirsher 	u32 credit_max          = 0;
73dee1ad47SJeff Kirsher 	u16 link_percentage     = 0;
74dee1ad47SJeff Kirsher 	u8  bw_percent          = 0;
75dee1ad47SJeff Kirsher 	u8  i;
76dee1ad47SJeff Kirsher 
77e90dd264SMark Rustad 	if (!dcb_config)
78e90dd264SMark Rustad 		return DCB_ERR_CONFIG;
79dee1ad47SJeff Kirsher 
80dee1ad47SJeff Kirsher 	min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
81dee1ad47SJeff Kirsher 			DCB_CREDIT_QUANTUM;
82dee1ad47SJeff Kirsher 
83dee1ad47SJeff Kirsher 	/* Find smallest link percentage */
84dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
85dee1ad47SJeff Kirsher 		p = &dcb_config->tc_config[i].path[direction];
86dee1ad47SJeff Kirsher 		bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
87dee1ad47SJeff Kirsher 		link_percentage = p->bwg_percent;
88dee1ad47SJeff Kirsher 
89dee1ad47SJeff Kirsher 		link_percentage = (link_percentage * bw_percent) / 100;
90dee1ad47SJeff Kirsher 
91dee1ad47SJeff Kirsher 		if (link_percentage && link_percentage < min_percent)
92dee1ad47SJeff Kirsher 			min_percent = link_percentage;
93dee1ad47SJeff Kirsher 	}
94dee1ad47SJeff Kirsher 
95dee1ad47SJeff Kirsher 	/*
96dee1ad47SJeff Kirsher 	 * The ratio between traffic classes will control the bandwidth
97dee1ad47SJeff Kirsher 	 * percentages seen on the wire. To calculate this ratio we use
98dee1ad47SJeff Kirsher 	 * a multiplier. It is required that the refill credits must be
99dee1ad47SJeff Kirsher 	 * larger than the max frame size so here we find the smallest
100dee1ad47SJeff Kirsher 	 * multiplier that will allow all bandwidth percentages to be
101dee1ad47SJeff Kirsher 	 * greater than the max frame size.
102dee1ad47SJeff Kirsher 	 */
103dee1ad47SJeff Kirsher 	min_multiplier = (min_credit / min_percent) + 1;
104dee1ad47SJeff Kirsher 
105dee1ad47SJeff Kirsher 	/* Find out the link percentage for each TC first */
106dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
107dee1ad47SJeff Kirsher 		p = &dcb_config->tc_config[i].path[direction];
108dee1ad47SJeff Kirsher 		bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
109dee1ad47SJeff Kirsher 
110dee1ad47SJeff Kirsher 		link_percentage = p->bwg_percent;
111dee1ad47SJeff Kirsher 		/* Must be careful of integer division for very small nums */
112dee1ad47SJeff Kirsher 		link_percentage = (link_percentage * bw_percent) / 100;
113dee1ad47SJeff Kirsher 		if (p->bwg_percent > 0 && link_percentage == 0)
114dee1ad47SJeff Kirsher 			link_percentage = 1;
115dee1ad47SJeff Kirsher 
116dee1ad47SJeff Kirsher 		/* Save link_percentage for reference */
117dee1ad47SJeff Kirsher 		p->link_percent = (u8)link_percentage;
118dee1ad47SJeff Kirsher 
119dee1ad47SJeff Kirsher 		/* Calculate credit refill ratio using multiplier */
120dee1ad47SJeff Kirsher 		credit_refill = min(link_percentage * min_multiplier,
121dee1ad47SJeff Kirsher 				    MAX_CREDIT_REFILL);
1223efcb86eSVasu Dev 
1233efcb86eSVasu Dev 		/* Refill at least minimum credit */
1243efcb86eSVasu Dev 		if (credit_refill < min_credit)
1253efcb86eSVasu Dev 			credit_refill = min_credit;
1263efcb86eSVasu Dev 
127dee1ad47SJeff Kirsher 		p->data_credits_refill = (u16)credit_refill;
128dee1ad47SJeff Kirsher 
129dee1ad47SJeff Kirsher 		/* Calculate maximum credit for the TC */
130dee1ad47SJeff Kirsher 		credit_max = (link_percentage * MAX_CREDIT) / 100;
131dee1ad47SJeff Kirsher 
132dee1ad47SJeff Kirsher 		/*
133dee1ad47SJeff Kirsher 		 * Adjustment based on rule checking, if the percentage
134dee1ad47SJeff Kirsher 		 * of a TC is too small, the maximum credit may not be
135dee1ad47SJeff Kirsher 		 * enough to send out a jumbo frame in data plane arbitration.
136dee1ad47SJeff Kirsher 		 */
1373efcb86eSVasu Dev 		if (credit_max < min_credit)
138dee1ad47SJeff Kirsher 			credit_max = min_credit;
139dee1ad47SJeff Kirsher 
140dee1ad47SJeff Kirsher 		if (direction == DCB_TX_CONFIG) {
141dee1ad47SJeff Kirsher 			/*
142dee1ad47SJeff Kirsher 			 * Adjustment based on rule checking, if the
143dee1ad47SJeff Kirsher 			 * percentage of a TC is too small, the maximum
144dee1ad47SJeff Kirsher 			 * credit may not be enough to send out a TSO
145dee1ad47SJeff Kirsher 			 * packet in descriptor plane arbitration.
146dee1ad47SJeff Kirsher 			 */
147dee1ad47SJeff Kirsher 			if ((hw->mac.type == ixgbe_mac_82598EB) &&
148dee1ad47SJeff Kirsher 			    credit_max &&
149dee1ad47SJeff Kirsher 			    (credit_max < MINIMUM_CREDIT_FOR_TSO))
150dee1ad47SJeff Kirsher 				credit_max = MINIMUM_CREDIT_FOR_TSO;
151dee1ad47SJeff Kirsher 
152dee1ad47SJeff Kirsher 			dcb_config->tc_config[i].desc_credits_max =
153dee1ad47SJeff Kirsher 				(u16)credit_max;
154dee1ad47SJeff Kirsher 		}
155dee1ad47SJeff Kirsher 
156dee1ad47SJeff Kirsher 		p->data_credits_max = (u16)credit_max;
157dee1ad47SJeff Kirsher 	}
158dee1ad47SJeff Kirsher 
159e90dd264SMark Rustad 	return 0;
160dee1ad47SJeff Kirsher }
161dee1ad47SJeff Kirsher 
ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config * cfg,u8 * pfc_en)162dee1ad47SJeff Kirsher void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en)
163dee1ad47SJeff Kirsher {
164df0676d1SAlexander Duyck 	struct tc_configuration *tc_config = &cfg->tc_config[0];
165df0676d1SAlexander Duyck 	int tc;
166dee1ad47SJeff Kirsher 
167df0676d1SAlexander Duyck 	for (*pfc_en = 0, tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) {
168df0676d1SAlexander Duyck 		if (tc_config[tc].dcb_pfc != pfc_disabled)
169b4f47a48SJacob Keller 			*pfc_en |= BIT(tc);
170df0676d1SAlexander Duyck 	}
171dee1ad47SJeff Kirsher }
172dee1ad47SJeff Kirsher 
ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config * cfg,int direction,u16 * refill)173dee1ad47SJeff Kirsher void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *cfg, int direction,
174dee1ad47SJeff Kirsher 			     u16 *refill)
175dee1ad47SJeff Kirsher {
176df0676d1SAlexander Duyck 	struct tc_configuration *tc_config = &cfg->tc_config[0];
177df0676d1SAlexander Duyck 	int tc;
178dee1ad47SJeff Kirsher 
179df0676d1SAlexander Duyck 	for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
180df0676d1SAlexander Duyck 		refill[tc] = tc_config[tc].path[direction].data_credits_refill;
181dee1ad47SJeff Kirsher }
182dee1ad47SJeff Kirsher 
ixgbe_dcb_unpack_max(struct ixgbe_dcb_config * cfg,u16 * max)183dee1ad47SJeff Kirsher void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *cfg, u16 *max)
184dee1ad47SJeff Kirsher {
185df0676d1SAlexander Duyck 	struct tc_configuration *tc_config = &cfg->tc_config[0];
186df0676d1SAlexander Duyck 	int tc;
187dee1ad47SJeff Kirsher 
188df0676d1SAlexander Duyck 	for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
189df0676d1SAlexander Duyck 		max[tc] = tc_config[tc].desc_credits_max;
190dee1ad47SJeff Kirsher }
191dee1ad47SJeff Kirsher 
ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config * cfg,int direction,u8 * bwgid)192dee1ad47SJeff Kirsher void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *cfg, int direction,
193dee1ad47SJeff Kirsher 			    u8 *bwgid)
194dee1ad47SJeff Kirsher {
195df0676d1SAlexander Duyck 	struct tc_configuration *tc_config = &cfg->tc_config[0];
196df0676d1SAlexander Duyck 	int tc;
197dee1ad47SJeff Kirsher 
198df0676d1SAlexander Duyck 	for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
199df0676d1SAlexander Duyck 		bwgid[tc] = tc_config[tc].path[direction].bwg_id;
200dee1ad47SJeff Kirsher }
201dee1ad47SJeff Kirsher 
ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config * cfg,int direction,u8 * ptype)202dee1ad47SJeff Kirsher void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *cfg, int direction,
203dee1ad47SJeff Kirsher 			    u8 *ptype)
204dee1ad47SJeff Kirsher {
205df0676d1SAlexander Duyck 	struct tc_configuration *tc_config = &cfg->tc_config[0];
206df0676d1SAlexander Duyck 	int tc;
207dee1ad47SJeff Kirsher 
208df0676d1SAlexander Duyck 	for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
209df0676d1SAlexander Duyck 		ptype[tc] = tc_config[tc].path[direction].prio_type;
210dee1ad47SJeff Kirsher }
211dee1ad47SJeff Kirsher 
ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config * cfg,int direction,u8 up)21202debdc9SAlexander Duyck u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up)
21315cbc70eSAlexander Duyck {
21415cbc70eSAlexander Duyck 	struct tc_configuration *tc_config = &cfg->tc_config[0];
215b4f47a48SJacob Keller 	u8 prio_mask = BIT(up);
216b92ad72dSAlexander Duyck 	u8 tc = cfg->num_tcs.pg_tcs;
217b92ad72dSAlexander Duyck 
218b92ad72dSAlexander Duyck 	/* If tc is 0 then DCB is likely not enabled or supported */
219b92ad72dSAlexander Duyck 	if (!tc)
220e90dd264SMark Rustad 		return 0;
22115cbc70eSAlexander Duyck 
22215cbc70eSAlexander Duyck 	/*
223b92ad72dSAlexander Duyck 	 * Test from maximum TC to 1 and report the first match we find.  If
22415cbc70eSAlexander Duyck 	 * we find no match we can assume that the TC is 0 since the TC must
22515cbc70eSAlexander Duyck 	 * be set for all user priorities
22615cbc70eSAlexander Duyck 	 */
227b92ad72dSAlexander Duyck 	for (tc--; tc; tc--) {
22815cbc70eSAlexander Duyck 		if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap)
22915cbc70eSAlexander Duyck 			break;
23015cbc70eSAlexander Duyck 	}
231e90dd264SMark Rustad 
23215cbc70eSAlexander Duyck 	return tc;
23315cbc70eSAlexander Duyck }
23415cbc70eSAlexander Duyck 
ixgbe_dcb_unpack_map(struct ixgbe_dcb_config * cfg,int direction,u8 * map)23532701dc2SJohn Fastabend void ixgbe_dcb_unpack_map(struct ixgbe_dcb_config *cfg, int direction, u8 *map)
23632701dc2SJohn Fastabend {
23715cbc70eSAlexander Duyck 	u8 up;
23832701dc2SJohn Fastabend 
23915cbc70eSAlexander Duyck 	for (up = 0; up < MAX_USER_PRIORITY; up++)
24015cbc70eSAlexander Duyck 		map[up] = ixgbe_dcb_get_tc_from_up(cfg, direction, up);
24132701dc2SJohn Fastabend }
24232701dc2SJohn Fastabend 
243dee1ad47SJeff Kirsher /**
244dee1ad47SJeff Kirsher  * ixgbe_dcb_hw_config - Config and enable DCB
245dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
246dee1ad47SJeff Kirsher  * @dcb_config: pointer to ixgbe_dcb_config structure
247dee1ad47SJeff Kirsher  *
248dee1ad47SJeff Kirsher  * Configure dcb settings and enable dcb mode.
249dee1ad47SJeff Kirsher  */
ixgbe_dcb_hw_config(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)250dee1ad47SJeff Kirsher s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
251dee1ad47SJeff Kirsher 			struct ixgbe_dcb_config *dcb_config)
252dee1ad47SJeff Kirsher {
253dee1ad47SJeff Kirsher 	u8 pfc_en;
254dee1ad47SJeff Kirsher 	u8 ptype[MAX_TRAFFIC_CLASS];
255dee1ad47SJeff Kirsher 	u8 bwgid[MAX_TRAFFIC_CLASS];
25632701dc2SJohn Fastabend 	u8 prio_tc[MAX_TRAFFIC_CLASS];
257dee1ad47SJeff Kirsher 	u16 refill[MAX_TRAFFIC_CLASS];
258dee1ad47SJeff Kirsher 	u16 max[MAX_TRAFFIC_CLASS];
259dee1ad47SJeff Kirsher 
260dee1ad47SJeff Kirsher 	/* Unpack CEE standard containers */
261dee1ad47SJeff Kirsher 	ixgbe_dcb_unpack_pfc(dcb_config, &pfc_en);
262dee1ad47SJeff Kirsher 	ixgbe_dcb_unpack_refill(dcb_config, DCB_TX_CONFIG, refill);
263dee1ad47SJeff Kirsher 	ixgbe_dcb_unpack_max(dcb_config, max);
264dee1ad47SJeff Kirsher 	ixgbe_dcb_unpack_bwgid(dcb_config, DCB_TX_CONFIG, bwgid);
265dee1ad47SJeff Kirsher 	ixgbe_dcb_unpack_prio(dcb_config, DCB_TX_CONFIG, ptype);
26632701dc2SJohn Fastabend 	ixgbe_dcb_unpack_map(dcb_config, DCB_TX_CONFIG, prio_tc);
267dee1ad47SJeff Kirsher 
268dee1ad47SJeff Kirsher 	switch (hw->mac.type) {
269dee1ad47SJeff Kirsher 	case ixgbe_mac_82598EB:
270e90dd264SMark Rustad 		return ixgbe_dcb_hw_config_82598(hw, pfc_en, refill, max,
271dee1ad47SJeff Kirsher 						 bwgid, ptype);
272dee1ad47SJeff Kirsher 	case ixgbe_mac_82599EB:
273dee1ad47SJeff Kirsher 	case ixgbe_mac_X540:
2749a75a1acSDon Skidmore 	case ixgbe_mac_X550:
2759a75a1acSDon Skidmore 	case ixgbe_mac_X550EM_x:
27649425dfcSMark Rustad 	case ixgbe_mac_x550em_a:
277e90dd264SMark Rustad 		return ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max,
278dee1ad47SJeff Kirsher 						 bwgid, ptype, prio_tc);
279dee1ad47SJeff Kirsher 	default:
280dee1ad47SJeff Kirsher 		break;
281dee1ad47SJeff Kirsher 	}
282e90dd264SMark Rustad 	return 0;
283dee1ad47SJeff Kirsher }
284dee1ad47SJeff Kirsher 
285dee1ad47SJeff Kirsher /* Helper routines to abstract HW specifics from DCB netlink ops */
ixgbe_dcb_hw_pfc_config(struct ixgbe_hw * hw,u8 pfc_en,u8 * prio_tc)28632701dc2SJohn Fastabend s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
287dee1ad47SJeff Kirsher {
288dee1ad47SJeff Kirsher 	switch (hw->mac.type) {
289dee1ad47SJeff Kirsher 	case ixgbe_mac_82598EB:
290e90dd264SMark Rustad 		return ixgbe_dcb_config_pfc_82598(hw, pfc_en);
291dee1ad47SJeff Kirsher 	case ixgbe_mac_82599EB:
292dee1ad47SJeff Kirsher 	case ixgbe_mac_X540:
2939a75a1acSDon Skidmore 	case ixgbe_mac_X550:
2949a75a1acSDon Skidmore 	case ixgbe_mac_X550EM_x:
29549425dfcSMark Rustad 	case ixgbe_mac_x550em_a:
296e90dd264SMark Rustad 		return ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc);
297dee1ad47SJeff Kirsher 	default:
298dee1ad47SJeff Kirsher 		break;
299dee1ad47SJeff Kirsher 	}
300e90dd264SMark Rustad 	return -EINVAL;
301dee1ad47SJeff Kirsher }
302dee1ad47SJeff Kirsher 
ixgbe_dcb_hw_ets(struct ixgbe_hw * hw,struct ieee_ets * ets,int max_frame)3034c09f3a0SJohn Fastabend s32 ixgbe_dcb_hw_ets(struct ixgbe_hw *hw, struct ieee_ets *ets, int max_frame)
3044c09f3a0SJohn Fastabend {
3054c09f3a0SJohn Fastabend 	__u16 refill[IEEE_8021QAZ_MAX_TCS], max[IEEE_8021QAZ_MAX_TCS];
3064c09f3a0SJohn Fastabend 	__u8 prio_type[IEEE_8021QAZ_MAX_TCS];
3074c09f3a0SJohn Fastabend 	int i;
3084c09f3a0SJohn Fastabend 
3094c09f3a0SJohn Fastabend 	/* naively give each TC a bwg to map onto CEE hardware */
3104c09f3a0SJohn Fastabend 	__u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7};
3114c09f3a0SJohn Fastabend 
3124c09f3a0SJohn Fastabend 	/* Map TSA onto CEE prio type */
3134c09f3a0SJohn Fastabend 	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
3144c09f3a0SJohn Fastabend 		switch (ets->tc_tsa[i]) {
3154c09f3a0SJohn Fastabend 		case IEEE_8021QAZ_TSA_STRICT:
3164c09f3a0SJohn Fastabend 			prio_type[i] = 2;
3174c09f3a0SJohn Fastabend 			break;
3184c09f3a0SJohn Fastabend 		case IEEE_8021QAZ_TSA_ETS:
3194c09f3a0SJohn Fastabend 			prio_type[i] = 0;
3204c09f3a0SJohn Fastabend 			break;
3214c09f3a0SJohn Fastabend 		default:
3224c09f3a0SJohn Fastabend 			/* Hardware only supports priority strict or
3234c09f3a0SJohn Fastabend 			 * ETS transmission selection algorithms if
3244c09f3a0SJohn Fastabend 			 * we receive some other value from dcbnl
3254c09f3a0SJohn Fastabend 			 * throw an error
3264c09f3a0SJohn Fastabend 			 */
3274c09f3a0SJohn Fastabend 			return -EINVAL;
3284c09f3a0SJohn Fastabend 		}
3294c09f3a0SJohn Fastabend 	}
3304c09f3a0SJohn Fastabend 
3314c09f3a0SJohn Fastabend 	ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame);
3324c09f3a0SJohn Fastabend 	return ixgbe_dcb_hw_ets_config(hw, refill, max,
3334c09f3a0SJohn Fastabend 				       bwg_id, prio_type, ets->prio_tc);
3344c09f3a0SJohn Fastabend }
3354c09f3a0SJohn Fastabend 
ixgbe_dcb_hw_ets_config(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * prio_type,u8 * prio_tc)336dee1ad47SJeff Kirsher s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw,
337dee1ad47SJeff Kirsher 			    u16 *refill, u16 *max, u8 *bwg_id,
338dee1ad47SJeff Kirsher 			    u8 *prio_type, u8 *prio_tc)
339dee1ad47SJeff Kirsher {
340dee1ad47SJeff Kirsher 	switch (hw->mac.type) {
341dee1ad47SJeff Kirsher 	case ixgbe_mac_82598EB:
342dee1ad47SJeff Kirsher 		ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max,
343dee1ad47SJeff Kirsher 							prio_type);
344dee1ad47SJeff Kirsher 		ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
345dee1ad47SJeff Kirsher 							     bwg_id, prio_type);
346dee1ad47SJeff Kirsher 		ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
347dee1ad47SJeff Kirsher 							     bwg_id, prio_type);
348dee1ad47SJeff Kirsher 		break;
349dee1ad47SJeff Kirsher 	case ixgbe_mac_82599EB:
350dee1ad47SJeff Kirsher 	case ixgbe_mac_X540:
3519a75a1acSDon Skidmore 	case ixgbe_mac_X550:
3529a75a1acSDon Skidmore 	case ixgbe_mac_X550EM_x:
35349425dfcSMark Rustad 	case ixgbe_mac_x550em_a:
354dee1ad47SJeff Kirsher 		ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max,
355dee1ad47SJeff Kirsher 						  bwg_id, prio_type, prio_tc);
356dee1ad47SJeff Kirsher 		ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
357dee1ad47SJeff Kirsher 						       bwg_id, prio_type);
358dee1ad47SJeff Kirsher 		ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
359dee1ad47SJeff Kirsher 						       prio_type, prio_tc);
360dee1ad47SJeff Kirsher 		break;
361dee1ad47SJeff Kirsher 	default:
362dee1ad47SJeff Kirsher 		break;
363dee1ad47SJeff Kirsher 	}
364dee1ad47SJeff Kirsher 	return 0;
365dee1ad47SJeff Kirsher }
366e8915bebSAmir Hanania 
ixgbe_dcb_read_rtrup2tc_82599(struct ixgbe_hw * hw,u8 * map)367e8915bebSAmir Hanania static void ixgbe_dcb_read_rtrup2tc_82599(struct ixgbe_hw *hw, u8 *map)
368e8915bebSAmir Hanania {
369e8915bebSAmir Hanania 	u32 reg, i;
370e8915bebSAmir Hanania 
371e8915bebSAmir Hanania 	reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC);
372e8915bebSAmir Hanania 	for (i = 0; i < MAX_USER_PRIORITY; i++)
373e8915bebSAmir Hanania 		map[i] = IXGBE_RTRUP2TC_UP_MASK &
374e8915bebSAmir Hanania 			(reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT));
375e8915bebSAmir Hanania }
376e8915bebSAmir Hanania 
ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw * hw,u8 * map)377e8915bebSAmir Hanania void ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw *hw, u8 *map)
378e8915bebSAmir Hanania {
379e8915bebSAmir Hanania 	switch (hw->mac.type) {
380e8915bebSAmir Hanania 	case ixgbe_mac_82599EB:
381e8915bebSAmir Hanania 	case ixgbe_mac_X540:
3829a75a1acSDon Skidmore 	case ixgbe_mac_X550:
3839a75a1acSDon Skidmore 	case ixgbe_mac_X550EM_x:
38449425dfcSMark Rustad 	case ixgbe_mac_x550em_a:
385e8915bebSAmir Hanania 		ixgbe_dcb_read_rtrup2tc_82599(hw, map);
386e8915bebSAmir Hanania 		break;
387e8915bebSAmir Hanania 	default:
388e8915bebSAmir Hanania 		break;
389e8915bebSAmir Hanania 	}
390e8915bebSAmir Hanania }
391