xref: /netbsd-src/sys/dev/pci/ixgbe/ixgbe_dcb.c (revision 4ab64dd8558009744b547d27ef7493447654442b)
1 /* $NetBSD: ixgbe_dcb.c,v 1.15 2023/10/06 14:48:08 msaitoh Exp $ */
2 /******************************************************************************
3   SPDX-License-Identifier: BSD-3-Clause
4 
5   Copyright (c) 2001-2020, Intel Corporation
6   All rights reserved.
7 
8   Redistribution and use in source and binary forms, with or without
9   modification, are permitted provided that the following conditions are met:
10 
11    1. Redistributions of source code must retain the above copyright notice,
12       this list of conditions and the following disclaimer.
13 
14    2. Redistributions in binary form must reproduce the above copyright
15       notice, this list of conditions and the following disclaimer in the
16       documentation and/or other materials provided with the distribution.
17 
18    3. Neither the name of the Intel Corporation nor the names of its
19       contributors may be used to endorse or promote products derived from
20       this software without specific prior written permission.
21 
22   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32   POSSIBILITY OF SUCH DAMAGE.
33 
34 ******************************************************************************/
35 /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_dcb.c 331224 2018-03-19 20:55:05Z erj $*/
36 
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: ixgbe_dcb.c,v 1.15 2023/10/06 14:48:08 msaitoh Exp $");
39 
40 #include "ixgbe_type.h"
41 #include "ixgbe_dcb.h"
42 #include "ixgbe_dcb_82598.h"
43 #include "ixgbe_dcb_82599.h"
44 
45 /**
46  * ixgbe_dcb_calculate_tc_credits - This calculates the ieee traffic class
47  * credits from the configured bandwidth percentages. Credits
48  * are the smallest unit programmable into the underlying
49  * hardware. The IEEE 802.1Qaz specification do not use bandwidth
50  * groups so this is much simplified from the CEE case.
51  * @bw: bandwidth index by traffic class
52  * @refill: refill credits index by traffic class
53  * @max: max credits by traffic class
54  * @max_frame_size: maximum frame size
55  */
ixgbe_dcb_calculate_tc_credits(u8 * bw,u16 * refill,u16 * max,int max_frame_size)56 s32 ixgbe_dcb_calculate_tc_credits(u8 *bw, u16 *refill, u16 *max,
57 				   int max_frame_size)
58 {
59 	int min_percent = 100;
60 	int min_credit, multiplier;
61 	int i;
62 
63 	min_credit = ((max_frame_size / 2) + IXGBE_DCB_CREDIT_QUANTUM - 1) /
64 			IXGBE_DCB_CREDIT_QUANTUM;
65 
66 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
67 		if (bw[i] < min_percent && bw[i])
68 			min_percent = bw[i];
69 	}
70 
71 	multiplier = (min_credit / min_percent) + 1;
72 
73 	/* Find out the hw credits for each TC */
74 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
75 		int val = uimin(bw[i] * multiplier, IXGBE_DCB_MAX_CREDIT_REFILL);
76 
77 		if (val < min_credit)
78 			val = min_credit;
79 		refill[i] = (u16)val;
80 
81 		max[i] = bw[i] ? (bw[i]*IXGBE_DCB_MAX_CREDIT)/100 : min_credit;
82 	}
83 
84 	return 0;
85 }
86 
87 /**
88  * ixgbe_dcb_calculate_tc_credits_cee - Calculates traffic class credits
89  * @hw: pointer to hardware structure
90  * @dcb_config: Struct containing DCB settings
91  * @max_frame_size: Maximum frame size
92  * @direction: Configuring either Tx or Rx
93  *
94  * This function calculates the credits allocated to each traffic class.
95  * It should be called only after the rules are checked by
96  * ixgbe_dcb_check_config_cee().
97  */
ixgbe_dcb_calculate_tc_credits_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config,u32 max_frame_size,u8 direction)98 s32 ixgbe_dcb_calculate_tc_credits_cee(struct ixgbe_hw *hw,
99 				   struct ixgbe_dcb_config *dcb_config,
100 				   u32 max_frame_size, u8 direction)
101 {
102 	struct ixgbe_dcb_tc_path *p;
103 	u32 min_multiplier	= 0;
104 	u16 min_percent		= 100;
105 	s32 ret_val =		IXGBE_SUCCESS;
106 	/* Initialization values default for Tx settings */
107 	u32 min_credit		= 0;
108 	u32 credit_refill	= 0;
109 	u32 credit_max		= 0;
110 	u16 link_percentage	= 0;
111 	u8  bw_percent		= 0;
112 	u8  i;
113 
114 	if (dcb_config == NULL) {
115 		ret_val = IXGBE_ERR_CONFIG;
116 		goto out;
117 	}
118 
119 	min_credit = ((max_frame_size / 2) + IXGBE_DCB_CREDIT_QUANTUM - 1) /
120 		     IXGBE_DCB_CREDIT_QUANTUM;
121 
122 	/* Find smallest link percentage */
123 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
124 		p = &dcb_config->tc_config[i].path[direction];
125 		bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
126 		link_percentage = p->bwg_percent;
127 
128 		link_percentage = (link_percentage * bw_percent) / 100;
129 
130 		if (link_percentage && link_percentage < min_percent)
131 			min_percent = link_percentage;
132 	}
133 
134 	/*
135 	 * The ratio between traffic classes will control the bandwidth
136 	 * percentages seen on the wire. To calculate this ratio we use
137 	 * a multiplier. It is required that the refill credits must be
138 	 * larger than the max frame size so here we find the smallest
139 	 * multiplier that will allow all bandwidth percentages to be
140 	 * greater than the max frame size.
141 	 */
142 	min_multiplier = (min_credit / min_percent) + 1;
143 
144 	/* Find out the link percentage for each TC first */
145 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
146 		p = &dcb_config->tc_config[i].path[direction];
147 		bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
148 
149 		link_percentage = p->bwg_percent;
150 		/* Must be careful of integer division for very small nums */
151 		link_percentage = (link_percentage * bw_percent) / 100;
152 		if (p->bwg_percent > 0 && link_percentage == 0)
153 			link_percentage = 1;
154 
155 		/* Save link_percentage for reference */
156 		p->link_percent = (u8)link_percentage;
157 
158 		/* Calculate credit refill ratio using multiplier */
159 		credit_refill = uimin(link_percentage * min_multiplier,
160 				    (u32)IXGBE_DCB_MAX_CREDIT_REFILL);
161 
162 		/* Refill at least minimum credit */
163 		if (credit_refill < min_credit)
164 			credit_refill = min_credit;
165 
166 		p->data_credits_refill = (u16)credit_refill;
167 
168 		/* Calculate maximum credit for the TC */
169 		credit_max = (link_percentage * IXGBE_DCB_MAX_CREDIT) / 100;
170 
171 		/*
172 		 * Adjustment based on rule checking, if the percentage
173 		 * of a TC is too small, the maximum credit may not be
174 		 * enough to send out a jumbo frame in data plane arbitration.
175 		 */
176 		if (credit_max < min_credit)
177 			credit_max = min_credit;
178 
179 		if (direction == IXGBE_DCB_TX_CONFIG) {
180 			/*
181 			 * Adjustment based on rule checking, if the
182 			 * percentage of a TC is too small, the maximum
183 			 * credit may not be enough to send out a TSO
184 			 * packet in descriptor plane arbitration.
185 			 */
186 			if (credit_max && (credit_max <
187 			    IXGBE_DCB_MIN_TSO_CREDIT)
188 			    && (hw->mac.type == ixgbe_mac_82598EB))
189 				credit_max = IXGBE_DCB_MIN_TSO_CREDIT;
190 
191 			dcb_config->tc_config[i].desc_credits_max =
192 								(u16)credit_max;
193 		}
194 
195 		p->data_credits_max = (u16)credit_max;
196 	}
197 
198 out:
199 	return ret_val;
200 }
201 
202 /**
203  * ixgbe_dcb_unpack_pfc_cee - Unpack dcb_config PFC info
204  * @cfg: dcb configuration to unpack into hardware consumable fields
205  * @map: user priority to traffic class map
206  * @pfc_up: u8 to store user priority PFC bitmask
207  *
208  * This unpacks the dcb configuration PFC info which is stored per
209  * traffic class into a 8bit user priority bitmask that can be
210  * consumed by hardware routines. The priority to tc map must be
211  * updated before calling this routine to use current up-to maps.
212  */
ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config * cfg,u8 * map,u8 * pfc_up)213 void ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config *cfg, u8 *map, u8 *pfc_up)
214 {
215 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
216 	int up;
217 
218 	/*
219 	 * If the TC for this user priority has PFC enabled then set the
220 	 * matching bit in 'pfc_up' to reflect that PFC is enabled.
221 	 */
222 	for (*pfc_up = 0, up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++) {
223 		if (tc_config[map[up]].pfc != ixgbe_dcb_pfc_disabled)
224 			*pfc_up |= 1 << up;
225 	}
226 }
227 
ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config * cfg,int direction,u16 * refill)228 void ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config *cfg, int direction,
229 			     u16 *refill)
230 {
231 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
232 	int tc;
233 
234 	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
235 		refill[tc] = tc_config[tc].path[direction].data_credits_refill;
236 }
237 
ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config * cfg,u16 * max)238 void ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config *cfg, u16 *max)
239 {
240 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
241 	int tc;
242 
243 	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
244 		max[tc] = tc_config[tc].desc_credits_max;
245 }
246 
ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * bwgid)247 void ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config *cfg, int direction,
248 			    u8 *bwgid)
249 {
250 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
251 	int tc;
252 
253 	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
254 		bwgid[tc] = tc_config[tc].path[direction].bwg_id;
255 }
256 
ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * tsa)257 void ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config *cfg, int direction,
258 			   u8 *tsa)
259 {
260 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
261 	int tc;
262 
263 	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
264 		tsa[tc] = tc_config[tc].path[direction].tsa;
265 }
266 
ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config * cfg,int direction,u8 up)267 u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up)
268 {
269 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
270 	u8 prio_mask = 1 << up;
271 	u8 tc = cfg->num_tcs.pg_tcs;
272 
273 	/* If tc is 0 then DCB is likely not enabled or supported */
274 	if (!tc)
275 		goto out;
276 
277 	/*
278 	 * Test from maximum TC to 1 and report the first match we find.  If
279 	 * we find no match we can assume that the TC is 0 since the TC must
280 	 * be set for all user priorities
281 	 */
282 	for (tc--; tc; tc--) {
283 		if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap)
284 			break;
285 	}
286 out:
287 	return tc;
288 }
289 
ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * map)290 void ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config *cfg, int direction,
291 			      u8 *map)
292 {
293 	u8 up;
294 
295 	for (up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++)
296 		map[up] = ixgbe_dcb_get_tc_from_up(cfg, direction, up);
297 }
298 
299 /**
300  * ixgbe_dcb_check_config_cee - Struct containing DCB settings.
301  * @dcb_config: Pointer to DCB config structure
302  *
303  * This function checks DCB rules for DCB settings.
304  * The following rules are checked:
305  * 1. The sum of bandwidth percentages of all Bandwidth Groups must total 100%.
306  * 2. The sum of bandwidth percentages of all Traffic Classes within a Bandwidth
307  *   Group must total 100.
308  * 3. A Traffic Class should not be set to both Link Strict Priority
309  *   and Group Strict Priority.
310  * 4. Link strict Bandwidth Groups can only have link strict traffic classes
311  *   with zero bandwidth.
312  */
ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config * dcb_config)313 s32 ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config *dcb_config)
314 {
315 	struct ixgbe_dcb_tc_path *p;
316 	s32 ret_val = IXGBE_SUCCESS;
317 	u8 i, j, bw = 0, bw_id;
318 	u8 bw_sum[2][IXGBE_DCB_MAX_BW_GROUP];
319 	bool link_strict[2][IXGBE_DCB_MAX_BW_GROUP];
320 
321 	memset(bw_sum, 0, sizeof(bw_sum));
322 	memset(link_strict, 0, sizeof(link_strict));
323 
324 	/* First Tx, then Rx */
325 	for (i = 0; i < 2; i++) {
326 		/* Check each traffic class for rule violation */
327 		for (j = 0; j < IXGBE_DCB_MAX_TRAFFIC_CLASS; j++) {
328 			p = &dcb_config->tc_config[j].path[i];
329 
330 			bw = p->bwg_percent;
331 			bw_id = p->bwg_id;
332 
333 			if (bw_id >= IXGBE_DCB_MAX_BW_GROUP) {
334 				ret_val = IXGBE_ERR_CONFIG;
335 				goto err_config;
336 			}
337 			if (p->tsa == ixgbe_dcb_tsa_strict) {
338 				link_strict[i][bw_id] = TRUE;
339 				/* Link strict should have zero bandwidth */
340 				if (bw) {
341 					ret_val = IXGBE_ERR_CONFIG;
342 					goto err_config;
343 				}
344 			} else if (!bw) {
345 				/*
346 				 * Traffic classes without link strict
347 				 * should have non-zero bandwidth.
348 				 */
349 				ret_val = IXGBE_ERR_CONFIG;
350 				goto err_config;
351 			}
352 			bw_sum[i][bw_id] += bw;
353 		}
354 
355 		bw = 0;
356 
357 		/* Check each bandwidth group for rule violation */
358 		for (j = 0; j < IXGBE_DCB_MAX_BW_GROUP; j++) {
359 			bw += dcb_config->bw_percentage[i][j];
360 			/*
361 			 * Sum of bandwidth percentages of all traffic classes
362 			 * within a Bandwidth Group must total 100 except for
363 			 * link strict group (zero bandwidth).
364 			 */
365 			if (link_strict[i][j]) {
366 				if (bw_sum[i][j]) {
367 					/*
368 					 * Link strict group should have zero
369 					 * bandwidth.
370 					 */
371 					ret_val = IXGBE_ERR_CONFIG;
372 					goto err_config;
373 				}
374 			} else if (bw_sum[i][j] != IXGBE_DCB_BW_PERCENT &&
375 				   bw_sum[i][j] != 0) {
376 				ret_val = IXGBE_ERR_CONFIG;
377 				goto err_config;
378 			}
379 		}
380 
381 		if (bw != IXGBE_DCB_BW_PERCENT) {
382 			ret_val = IXGBE_ERR_CONFIG;
383 			goto err_config;
384 		}
385 	}
386 
387 err_config:
388 	DEBUGOUT2("DCB error code %d while checking %s settings.\n",
389 		  ret_val, (i == IXGBE_DCB_TX_CONFIG) ? "Tx" : "Rx");
390 
391 	return ret_val;
392 }
393 
394 /**
395  * ixgbe_dcb_get_tc_stats - Returns status of each traffic class
396  * @hw: pointer to hardware structure
397  * @stats: pointer to statistics structure
398  * @tc_count:  Number of elements in bwg_array.
399  *
400  * This function returns the status data for each of the Traffic Classes in use.
401  */
ixgbe_dcb_get_tc_stats(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)402 s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
403 			   u8 tc_count)
404 {
405 	s32 ret = IXGBE_NOT_IMPLEMENTED;
406 	switch (hw->mac.type) {
407 	case ixgbe_mac_82598EB:
408 		ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count);
409 		break;
410 	case ixgbe_mac_82599EB:
411 	case ixgbe_mac_X540:
412 	case ixgbe_mac_X550:
413 	case ixgbe_mac_X550EM_x:
414 	case ixgbe_mac_X550EM_a:
415 		ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
416 		break;
417 	default:
418 		break;
419 	}
420 	return ret;
421 }
422 
423 /**
424  * ixgbe_dcb_get_pfc_stats - Returns CBFC status of each traffic class
425  * @hw: pointer to hardware structure
426  * @stats: pointer to statistics structure
427  * @tc_count:  Number of elements in bwg_array.
428  *
429  * This function returns the CBFC status data for each of the Traffic Classes.
430  */
ixgbe_dcb_get_pfc_stats(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)431 s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
432 			    u8 tc_count)
433 {
434 	s32 ret = IXGBE_NOT_IMPLEMENTED;
435 	switch (hw->mac.type) {
436 	case ixgbe_mac_82598EB:
437 		ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count);
438 		break;
439 	case ixgbe_mac_82599EB:
440 	case ixgbe_mac_X540:
441 	case ixgbe_mac_X550:
442 	case ixgbe_mac_X550EM_x:
443 	case ixgbe_mac_X550EM_a:
444 		ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
445 		break;
446 	default:
447 		break;
448 	}
449 	return ret;
450 }
451 
452 /**
453  * ixgbe_dcb_config_rx_arbiter_cee - Config Rx arbiter
454  * @hw: pointer to hardware structure
455  * @dcb_config: pointer to ixgbe_dcb_config structure
456  *
457  * Configure Rx Data Arbiter and credits for each traffic class.
458  */
ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)459 s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw,
460 				struct ixgbe_dcb_config *dcb_config)
461 {
462 	s32 ret = IXGBE_NOT_IMPLEMENTED;
463 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
464 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
465 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY]	= { 0 };
466 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
467 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
468 
469 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
470 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
471 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
472 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
473 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
474 
475 	switch (hw->mac.type) {
476 	case ixgbe_mac_82598EB:
477 		ret = ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
478 		break;
479 	case ixgbe_mac_82599EB:
480 	case ixgbe_mac_X540:
481 	case ixgbe_mac_X550:
482 	case ixgbe_mac_X550EM_x:
483 	case ixgbe_mac_X550EM_a:
484 		ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid,
485 							tsa, map);
486 		break;
487 	default:
488 		break;
489 	}
490 	return ret;
491 }
492 
493 /**
494  * ixgbe_dcb_config_tx_desc_arbiter_cee - Config Tx Desc arbiter
495  * @hw: pointer to hardware structure
496  * @dcb_config: pointer to ixgbe_dcb_config structure
497  *
498  * Configure Tx Descriptor Arbiter and credits for each traffic class.
499  */
ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)500 s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw,
501 				     struct ixgbe_dcb_config *dcb_config)
502 {
503 	s32 ret = IXGBE_NOT_IMPLEMENTED;
504 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
505 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
506 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
507 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
508 
509 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
510 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
511 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
512 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
513 
514 	switch (hw->mac.type) {
515 	case ixgbe_mac_82598EB:
516 		ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
517 							     bwgid, tsa);
518 		break;
519 	case ixgbe_mac_82599EB:
520 	case ixgbe_mac_X540:
521 	case ixgbe_mac_X550:
522 	case ixgbe_mac_X550EM_x:
523 	case ixgbe_mac_X550EM_a:
524 		ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
525 							     bwgid, tsa);
526 		break;
527 	default:
528 		break;
529 	}
530 	return ret;
531 }
532 
533 /**
534  * ixgbe_dcb_config_tx_data_arbiter_cee - Config Tx data arbiter
535  * @hw: pointer to hardware structure
536  * @dcb_config: pointer to ixgbe_dcb_config structure
537  *
538  * Configure Tx Data Arbiter and credits for each traffic class.
539  */
ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)540 s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw,
541 				     struct ixgbe_dcb_config *dcb_config)
542 {
543 	s32 ret = IXGBE_NOT_IMPLEMENTED;
544 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
545 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
546 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
547 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
548 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
549 
550 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
551 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
552 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
553 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
554 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
555 
556 	switch (hw->mac.type) {
557 	case ixgbe_mac_82598EB:
558 		ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
559 							     bwgid, tsa);
560 		break;
561 	case ixgbe_mac_82599EB:
562 	case ixgbe_mac_X540:
563 	case ixgbe_mac_X550:
564 	case ixgbe_mac_X550EM_x:
565 	case ixgbe_mac_X550EM_a:
566 		ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max,
567 							     bwgid, tsa,
568 							     map);
569 		break;
570 	default:
571 		break;
572 	}
573 	return ret;
574 }
575 
576 /**
577  * ixgbe_dcb_config_pfc_cee - Config priority flow control
578  * @hw: pointer to hardware structure
579  * @dcb_config: pointer to ixgbe_dcb_config structure
580  *
581  * Configure Priority Flow Control for each traffic class.
582  */
ixgbe_dcb_config_pfc_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)583 s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw,
584 			 struct ixgbe_dcb_config *dcb_config)
585 {
586 	s32 ret = IXGBE_NOT_IMPLEMENTED;
587 	u8 pfc_en;
588 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
589 
590 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
591 	ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
592 
593 	switch (hw->mac.type) {
594 	case ixgbe_mac_82598EB:
595 		ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
596 		break;
597 	case ixgbe_mac_82599EB:
598 	case ixgbe_mac_X540:
599 	case ixgbe_mac_X550:
600 	case ixgbe_mac_X550EM_x:
601 	case ixgbe_mac_X550EM_a:
602 		ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
603 		break;
604 	default:
605 		break;
606 	}
607 	return ret;
608 }
609 
610 /**
611  * ixgbe_dcb_config_tc_stats - Config traffic class statistics
612  * @hw: pointer to hardware structure
613  *
614  * Configure queue statistics registers, all queues belonging to same traffic
615  * class uses a single set of queue statistics counters.
616  */
ixgbe_dcb_config_tc_stats(struct ixgbe_hw * hw)617 s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw)
618 {
619 	s32 ret = IXGBE_NOT_IMPLEMENTED;
620 	switch (hw->mac.type) {
621 	case ixgbe_mac_82598EB:
622 		ret = ixgbe_dcb_config_tc_stats_82598(hw);
623 		break;
624 	case ixgbe_mac_82599EB:
625 	case ixgbe_mac_X540:
626 	case ixgbe_mac_X550:
627 	case ixgbe_mac_X550EM_x:
628 	case ixgbe_mac_X550EM_a:
629 		ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL);
630 		break;
631 	default:
632 		break;
633 	}
634 	return ret;
635 }
636 
637 /**
638  * ixgbe_dcb_hw_config_cee - Config and enable DCB
639  * @hw: pointer to hardware structure
640  * @dcb_config: pointer to ixgbe_dcb_config structure
641  *
642  * Configure dcb settings and enable dcb mode.
643  */
ixgbe_dcb_hw_config_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)644 s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw,
645 			struct ixgbe_dcb_config *dcb_config)
646 {
647 	s32 ret = IXGBE_NOT_IMPLEMENTED;
648 	u8 pfc_en;
649 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
650 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
651 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
652 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
653 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
654 
655 	/* Unpack CEE standard containers */
656 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
657 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
658 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
659 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
660 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
661 
662 	hw->mac.ops.setup_rxpba(hw, dcb_config->num_tcs.pg_tcs,
663 				0, dcb_config->rx_pba_cfg);
664 
665 	switch (hw->mac.type) {
666 	case ixgbe_mac_82598EB:
667 		ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->link_speed,
668 						refill, max, bwgid, tsa);
669 		break;
670 	case ixgbe_mac_82599EB:
671 	case ixgbe_mac_X540:
672 	case ixgbe_mac_X550:
673 	case ixgbe_mac_X550EM_x:
674 	case ixgbe_mac_X550EM_a:
675 		ixgbe_dcb_config_82599(hw, dcb_config);
676 		ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed,
677 						refill, max, bwgid,
678 						tsa, map);
679 
680 		ixgbe_dcb_config_tc_stats_82599(hw, dcb_config);
681 		break;
682 	default:
683 		break;
684 	}
685 
686 	if (!ret && dcb_config->pfc_mode_enable) {
687 		ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
688 		ret = ixgbe_dcb_config_pfc(hw, pfc_en, map);
689 	}
690 
691 	return ret;
692 }
693 
694 /* Helper routines to abstract HW specifics from DCB netlink ops */
ixgbe_dcb_config_pfc(struct ixgbe_hw * hw,u8 pfc_en,u8 * map)695 s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map)
696 {
697 	int ret = IXGBE_ERR_PARAM;
698 
699 	switch (hw->mac.type) {
700 	case ixgbe_mac_82598EB:
701 		ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
702 		break;
703 	case ixgbe_mac_82599EB:
704 	case ixgbe_mac_X540:
705 	case ixgbe_mac_X550:
706 	case ixgbe_mac_X550EM_x:
707 	case ixgbe_mac_X550EM_a:
708 		ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
709 		break;
710 	default:
711 		break;
712 	}
713 	return ret;
714 }
715 
ixgbe_dcb_hw_config(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa,u8 * map)716 s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max,
717 			    u8 *bwg_id, u8 *tsa, u8 *map)
718 {
719 	switch (hw->mac.type) {
720 	case ixgbe_mac_82598EB:
721 		ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
722 		ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
723 						       tsa);
724 		ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
725 						       tsa);
726 		break;
727 	case ixgbe_mac_82599EB:
728 	case ixgbe_mac_X540:
729 	case ixgbe_mac_X550:
730 	case ixgbe_mac_X550EM_x:
731 	case ixgbe_mac_X550EM_a:
732 		ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id,
733 						  tsa, map);
734 		ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id,
735 						       tsa);
736 		ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
737 						       tsa, map);
738 		break;
739 	default:
740 		break;
741 	}
742 	return 0;
743 }
744