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 */
56s32 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 */
98s32 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
198out:
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 */
213void 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
228void 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
238void 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
247void 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
257void 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
267u8 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	}
286out:
287	return tc;
288}
289
290void 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 */
313s32 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
387err_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 */
402s32 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 */
431s32 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 */
459s32 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 */
500s32 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 */
540s32 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 */
583s32 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 */
617s32 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 */
644s32 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 */
695s32 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
716s32 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