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