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