ixgbe_dcb.c revision 295524
1/******************************************************************************
2
3  Copyright (c) 2001-2015, 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 295524 2016-02-11 16:16:10Z sbruno $*/
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#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
405		ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
406		break;
407#endif
408	default:
409		break;
410	}
411	return ret;
412}
413
414/**
415 * ixgbe_dcb_get_pfc_stats - Returns CBFC status of each traffic class
416 * @hw: pointer to hardware structure
417 * @stats: pointer to statistics structure
418 * @tc_count:  Number of elements in bwg_array.
419 *
420 * This function returns the CBFC status data for each of the Traffic Classes.
421 */
422s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
423			    u8 tc_count)
424{
425	s32 ret = IXGBE_NOT_IMPLEMENTED;
426	switch (hw->mac.type) {
427	case ixgbe_mac_82598EB:
428		ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count);
429		break;
430	case ixgbe_mac_82599EB:
431	case ixgbe_mac_X540:
432	case ixgbe_mac_X550:
433	case ixgbe_mac_X550EM_x:
434#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
435		ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
436		break;
437#endif
438	default:
439		break;
440	}
441	return ret;
442}
443
444/**
445 * ixgbe_dcb_config_rx_arbiter_cee - Config Rx arbiter
446 * @hw: pointer to hardware structure
447 * @dcb_config: pointer to ixgbe_dcb_config structure
448 *
449 * Configure Rx Data Arbiter and credits for each traffic class.
450 */
451s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw,
452				struct ixgbe_dcb_config *dcb_config)
453{
454	s32 ret = IXGBE_NOT_IMPLEMENTED;
455	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
456	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
457	u8 map[IXGBE_DCB_MAX_USER_PRIORITY]	= { 0 };
458	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
459	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
460
461	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
462	ixgbe_dcb_unpack_max_cee(dcb_config, max);
463	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
464	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
465	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
466
467	switch (hw->mac.type) {
468	case ixgbe_mac_82598EB:
469		ret = ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
470		break;
471	case ixgbe_mac_82599EB:
472	case ixgbe_mac_X540:
473	case ixgbe_mac_X550:
474	case ixgbe_mac_X550EM_x:
475#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
476		ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid,
477							tsa, map);
478		break;
479#endif
480	default:
481		break;
482	}
483	return ret;
484}
485
486/**
487 * ixgbe_dcb_config_tx_desc_arbiter_cee - Config Tx Desc arbiter
488 * @hw: pointer to hardware structure
489 * @dcb_config: pointer to ixgbe_dcb_config structure
490 *
491 * Configure Tx Descriptor Arbiter and credits for each traffic class.
492 */
493s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw,
494				     struct ixgbe_dcb_config *dcb_config)
495{
496	s32 ret = IXGBE_NOT_IMPLEMENTED;
497	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
498	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
499	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
500	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
501
502	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
503	ixgbe_dcb_unpack_max_cee(dcb_config, max);
504	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
505	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
506
507	switch (hw->mac.type) {
508	case ixgbe_mac_82598EB:
509		ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
510							     bwgid, tsa);
511		break;
512	case ixgbe_mac_82599EB:
513	case ixgbe_mac_X540:
514	case ixgbe_mac_X550:
515	case ixgbe_mac_X550EM_x:
516#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
517		ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
518							     bwgid, tsa);
519		break;
520#endif
521	default:
522		break;
523	}
524	return ret;
525}
526
527/**
528 * ixgbe_dcb_config_tx_data_arbiter_cee - Config Tx data arbiter
529 * @hw: pointer to hardware structure
530 * @dcb_config: pointer to ixgbe_dcb_config structure
531 *
532 * Configure Tx Data Arbiter and credits for each traffic class.
533 */
534s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw,
535				     struct ixgbe_dcb_config *dcb_config)
536{
537	s32 ret = IXGBE_NOT_IMPLEMENTED;
538	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
539	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
540	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
541	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
542	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
543
544	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
545	ixgbe_dcb_unpack_max_cee(dcb_config, max);
546	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
547	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
548	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
549
550	switch (hw->mac.type) {
551	case ixgbe_mac_82598EB:
552		ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
553							     bwgid, tsa);
554		break;
555	case ixgbe_mac_82599EB:
556	case ixgbe_mac_X540:
557	case ixgbe_mac_X550:
558	case ixgbe_mac_X550EM_x:
559#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
560		ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max,
561							     bwgid, tsa,
562							     map);
563		break;
564#endif
565	default:
566		break;
567	}
568	return ret;
569}
570
571/**
572 * ixgbe_dcb_config_pfc_cee - Config priority flow control
573 * @hw: pointer to hardware structure
574 * @dcb_config: pointer to ixgbe_dcb_config structure
575 *
576 * Configure Priority Flow Control for each traffic class.
577 */
578s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw,
579			 struct ixgbe_dcb_config *dcb_config)
580{
581	s32 ret = IXGBE_NOT_IMPLEMENTED;
582	u8 pfc_en;
583	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
584
585	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
586	ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
587
588	switch (hw->mac.type) {
589	case ixgbe_mac_82598EB:
590		ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
591		break;
592	case ixgbe_mac_82599EB:
593	case ixgbe_mac_X540:
594	case ixgbe_mac_X550:
595	case ixgbe_mac_X550EM_x:
596#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
597		ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
598		break;
599#endif
600	default:
601		break;
602	}
603	return ret;
604}
605
606/**
607 * ixgbe_dcb_config_tc_stats - Config traffic class statistics
608 * @hw: pointer to hardware structure
609 *
610 * Configure queue statistics registers, all queues belonging to same traffic
611 * class uses a single set of queue statistics counters.
612 */
613s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw)
614{
615	s32 ret = IXGBE_NOT_IMPLEMENTED;
616	switch (hw->mac.type) {
617	case ixgbe_mac_82598EB:
618		ret = ixgbe_dcb_config_tc_stats_82598(hw);
619		break;
620	case ixgbe_mac_82599EB:
621	case ixgbe_mac_X540:
622	case ixgbe_mac_X550:
623	case ixgbe_mac_X550EM_x:
624#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
625		ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL);
626		break;
627#endif
628	default:
629		break;
630	}
631	return ret;
632}
633
634/**
635 * ixgbe_dcb_hw_config_cee - Config and enable DCB
636 * @hw: pointer to hardware structure
637 * @dcb_config: pointer to ixgbe_dcb_config structure
638 *
639 * Configure dcb settings and enable dcb mode.
640 */
641s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw,
642			struct ixgbe_dcb_config *dcb_config)
643{
644	s32 ret = IXGBE_NOT_IMPLEMENTED;
645	u8 pfc_en;
646	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
647	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
648	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
649	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
650	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
651
652	/* Unpack CEE standard containers */
653	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
654	ixgbe_dcb_unpack_max_cee(dcb_config, max);
655	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
656	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
657	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
658
659	hw->mac.ops.setup_rxpba(hw, dcb_config->num_tcs.pg_tcs,
660				0, dcb_config->rx_pba_cfg);
661
662	switch (hw->mac.type) {
663	case ixgbe_mac_82598EB:
664		ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->link_speed,
665						refill, max, bwgid, tsa);
666		break;
667	case ixgbe_mac_82599EB:
668	case ixgbe_mac_X540:
669	case ixgbe_mac_X550:
670	case ixgbe_mac_X550EM_x:
671#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
672		ixgbe_dcb_config_82599(hw, dcb_config);
673		ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed,
674						refill, max, bwgid,
675						tsa, map);
676
677		ixgbe_dcb_config_tc_stats_82599(hw, dcb_config);
678		break;
679#endif
680	default:
681		break;
682	}
683
684	if (!ret && dcb_config->pfc_mode_enable) {
685		ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
686		ret = ixgbe_dcb_config_pfc(hw, pfc_en, map);
687	}
688
689	return ret;
690}
691
692/* Helper routines to abstract HW specifics from DCB netlink ops */
693s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map)
694{
695	int ret = IXGBE_ERR_PARAM;
696
697	switch (hw->mac.type) {
698	case ixgbe_mac_82598EB:
699		ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
700		break;
701	case ixgbe_mac_82599EB:
702	case ixgbe_mac_X540:
703	case ixgbe_mac_X550:
704	case ixgbe_mac_X550EM_x:
705#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
706		ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
707		break;
708#endif
709	default:
710		break;
711	}
712	return ret;
713}
714
715s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max,
716			    u8 *bwg_id, u8 *tsa, u8 *map)
717{
718	switch (hw->mac.type) {
719	case ixgbe_mac_82598EB:
720		ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
721		ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
722						       tsa);
723		ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
724						       tsa);
725		break;
726	case ixgbe_mac_82599EB:
727	case ixgbe_mac_X540:
728	case ixgbe_mac_X550:
729	case ixgbe_mac_X550EM_x:
730#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
731		ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id,
732						  tsa, map);
733		ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id,
734						       tsa);
735		ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
736						       tsa, map);
737		break;
738#endif
739	default:
740		break;
741	}
742	return 0;
743}
744