1251964Sjfv/******************************************************************************
2251964Sjfv
3251964Sjfv  Copyright (c) 2001-2013, Intel Corporation
4251964Sjfv  All rights reserved.
5251964Sjfv
6251964Sjfv  Redistribution and use in source and binary forms, with or without
7251964Sjfv  modification, are permitted provided that the following conditions are met:
8251964Sjfv
9251964Sjfv   1. Redistributions of source code must retain the above copyright notice,
10251964Sjfv      this list of conditions and the following disclaimer.
11251964Sjfv
12251964Sjfv   2. Redistributions in binary form must reproduce the above copyright
13251964Sjfv      notice, this list of conditions and the following disclaimer in the
14251964Sjfv      documentation and/or other materials provided with the distribution.
15251964Sjfv
16251964Sjfv   3. Neither the name of the Intel Corporation nor the names of its
17251964Sjfv      contributors may be used to endorse or promote products derived from
18251964Sjfv      this software without specific prior written permission.
19251964Sjfv
20251964Sjfv  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21251964Sjfv  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22251964Sjfv  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23251964Sjfv  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24251964Sjfv  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25251964Sjfv  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26251964Sjfv  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27251964Sjfv  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28251964Sjfv  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29251964Sjfv  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30251964Sjfv  POSSIBILITY OF SUCH DAMAGE.
31251964Sjfv
32251964Sjfv******************************************************************************/
33251964Sjfv/*$FreeBSD$*/
34251964Sjfv
35251964Sjfv
36251964Sjfv#include "ixgbe_type.h"
37251964Sjfv#include "ixgbe_dcb.h"
38251964Sjfv#include "ixgbe_dcb_82598.h"
39251964Sjfv#include "ixgbe_dcb_82599.h"
40251964Sjfv
41251964Sjfv/**
42251964Sjfv * ixgbe_dcb_calculate_tc_credits - This calculates the ieee traffic class
43251964Sjfv * credits from the configured bandwidth percentages. Credits
44251964Sjfv * are the smallest unit programmable into the underlying
45251964Sjfv * hardware. The IEEE 802.1Qaz specification do not use bandwidth
46251964Sjfv * groups so this is much simplified from the CEE case.
47251964Sjfv */
48251964Sjfvs32 ixgbe_dcb_calculate_tc_credits(u8 *bw, u16 *refill, u16 *max,
49251964Sjfv				   int max_frame_size)
50251964Sjfv{
51251964Sjfv	int min_percent = 100;
52251964Sjfv	int min_credit, multiplier;
53251964Sjfv	int i;
54251964Sjfv
55251964Sjfv	min_credit = ((max_frame_size / 2) + IXGBE_DCB_CREDIT_QUANTUM - 1) /
56251964Sjfv			IXGBE_DCB_CREDIT_QUANTUM;
57251964Sjfv
58251964Sjfv	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
59251964Sjfv		if (bw[i] < min_percent && bw[i])
60251964Sjfv			min_percent = bw[i];
61251964Sjfv	}
62251964Sjfv
63251964Sjfv	multiplier = (min_credit / min_percent) + 1;
64251964Sjfv
65251964Sjfv	/* Find out the hw credits for each TC */
66251964Sjfv	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
67251964Sjfv		int val = min(bw[i] * multiplier, IXGBE_DCB_MAX_CREDIT_REFILL);
68251964Sjfv
69251964Sjfv		if (val < min_credit)
70251964Sjfv			val = min_credit;
71251964Sjfv		refill[i] = (u16)val;
72251964Sjfv
73251964Sjfv		max[i] = bw[i] ? (bw[i]*IXGBE_DCB_MAX_CREDIT)/100 : min_credit;
74251964Sjfv	}
75251964Sjfv
76251964Sjfv	return 0;
77251964Sjfv}
78251964Sjfv
79251964Sjfv/**
80251964Sjfv * ixgbe_dcb_calculate_tc_credits_cee - Calculates traffic class credits
81251964Sjfv * @ixgbe_dcb_config: Struct containing DCB settings.
82251964Sjfv * @direction: Configuring either Tx or Rx.
83251964Sjfv *
84251964Sjfv * This function calculates the credits allocated to each traffic class.
85251964Sjfv * It should be called only after the rules are checked by
86251964Sjfv * ixgbe_dcb_check_config_cee().
87251964Sjfv */
88251964Sjfvs32 ixgbe_dcb_calculate_tc_credits_cee(struct ixgbe_hw *hw,
89251964Sjfv				   struct ixgbe_dcb_config *dcb_config,
90251964Sjfv				   u32 max_frame_size, u8 direction)
91251964Sjfv{
92251964Sjfv	struct ixgbe_dcb_tc_path *p;
93251964Sjfv	u32 min_multiplier	= 0;
94251964Sjfv	u16 min_percent		= 100;
95251964Sjfv	s32 ret_val =		IXGBE_SUCCESS;
96251964Sjfv	/* Initialization values default for Tx settings */
97251964Sjfv	u32 min_credit		= 0;
98251964Sjfv	u32 credit_refill	= 0;
99251964Sjfv	u32 credit_max		= 0;
100251964Sjfv	u16 link_percentage	= 0;
101251964Sjfv	u8  bw_percent		= 0;
102251964Sjfv	u8  i;
103251964Sjfv
104251964Sjfv	if (dcb_config == NULL) {
105251964Sjfv		ret_val = IXGBE_ERR_CONFIG;
106251964Sjfv		goto out;
107251964Sjfv	}
108251964Sjfv
109251964Sjfv	min_credit = ((max_frame_size / 2) + IXGBE_DCB_CREDIT_QUANTUM - 1) /
110251964Sjfv		     IXGBE_DCB_CREDIT_QUANTUM;
111251964Sjfv
112251964Sjfv	/* Find smallest link percentage */
113251964Sjfv	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
114251964Sjfv		p = &dcb_config->tc_config[i].path[direction];
115251964Sjfv		bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
116251964Sjfv		link_percentage = p->bwg_percent;
117251964Sjfv
118251964Sjfv		link_percentage = (link_percentage * bw_percent) / 100;
119251964Sjfv
120251964Sjfv		if (link_percentage && link_percentage < min_percent)
121251964Sjfv			min_percent = link_percentage;
122251964Sjfv	}
123251964Sjfv
124251964Sjfv	/*
125251964Sjfv	 * The ratio between traffic classes will control the bandwidth
126251964Sjfv	 * percentages seen on the wire. To calculate this ratio we use
127251964Sjfv	 * a multiplier. It is required that the refill credits must be
128251964Sjfv	 * larger than the max frame size so here we find the smallest
129251964Sjfv	 * multiplier that will allow all bandwidth percentages to be
130251964Sjfv	 * greater than the max frame size.
131251964Sjfv	 */
132251964Sjfv	min_multiplier = (min_credit / min_percent) + 1;
133251964Sjfv
134251964Sjfv	/* Find out the link percentage for each TC first */
135251964Sjfv	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
136251964Sjfv		p = &dcb_config->tc_config[i].path[direction];
137251964Sjfv		bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
138251964Sjfv
139251964Sjfv		link_percentage = p->bwg_percent;
140251964Sjfv		/* Must be careful of integer division for very small nums */
141251964Sjfv		link_percentage = (link_percentage * bw_percent) / 100;
142251964Sjfv		if (p->bwg_percent > 0 && link_percentage == 0)
143251964Sjfv			link_percentage = 1;
144251964Sjfv
145251964Sjfv		/* Save link_percentage for reference */
146251964Sjfv		p->link_percent = (u8)link_percentage;
147251964Sjfv
148251964Sjfv		/* Calculate credit refill ratio using multiplier */
149251964Sjfv		credit_refill = min(link_percentage * min_multiplier,
150251964Sjfv				    (u32)IXGBE_DCB_MAX_CREDIT_REFILL);
151251964Sjfv		p->data_credits_refill = (u16)credit_refill;
152251964Sjfv
153251964Sjfv		/* Calculate maximum credit for the TC */
154251964Sjfv		credit_max = (link_percentage * IXGBE_DCB_MAX_CREDIT) / 100;
155251964Sjfv
156251964Sjfv		/*
157251964Sjfv		 * Adjustment based on rule checking, if the percentage
158251964Sjfv		 * of a TC is too small, the maximum credit may not be
159251964Sjfv		 * enough to send out a jumbo frame in data plane arbitration.
160251964Sjfv		 */
161251964Sjfv		if (credit_max && (credit_max < min_credit))
162251964Sjfv			credit_max = min_credit;
163251964Sjfv
164251964Sjfv		if (direction == IXGBE_DCB_TX_CONFIG) {
165251964Sjfv			/*
166251964Sjfv			 * Adjustment based on rule checking, if the
167251964Sjfv			 * percentage of a TC is too small, the maximum
168251964Sjfv			 * credit may not be enough to send out a TSO
169251964Sjfv			 * packet in descriptor plane arbitration.
170251964Sjfv			 */
171251964Sjfv			if (credit_max && (credit_max <
172251964Sjfv			    IXGBE_DCB_MIN_TSO_CREDIT)
173251964Sjfv			    && (hw->mac.type == ixgbe_mac_82598EB))
174251964Sjfv				credit_max = IXGBE_DCB_MIN_TSO_CREDIT;
175251964Sjfv
176251964Sjfv			dcb_config->tc_config[i].desc_credits_max =
177251964Sjfv								(u16)credit_max;
178251964Sjfv		}
179251964Sjfv
180251964Sjfv		p->data_credits_max = (u16)credit_max;
181251964Sjfv	}
182251964Sjfv
183251964Sjfvout:
184251964Sjfv	return ret_val;
185251964Sjfv}
186251964Sjfv
187251964Sjfv/**
188251964Sjfv * ixgbe_dcb_unpack_pfc_cee - Unpack dcb_config PFC info
189251964Sjfv * @cfg: dcb configuration to unpack into hardware consumable fields
190251964Sjfv * @map: user priority to traffic class map
191251964Sjfv * @pfc_up: u8 to store user priority PFC bitmask
192251964Sjfv *
193251964Sjfv * This unpacks the dcb configuration PFC info which is stored per
194251964Sjfv * traffic class into a 8bit user priority bitmask that can be
195251964Sjfv * consumed by hardware routines. The priority to tc map must be
196251964Sjfv * updated before calling this routine to use current up-to maps.
197251964Sjfv */
198251964Sjfvvoid ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config *cfg, u8 *map, u8 *pfc_up)
199251964Sjfv{
200251964Sjfv	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
201251964Sjfv	int up;
202251964Sjfv
203251964Sjfv	/*
204251964Sjfv	 * If the TC for this user priority has PFC enabled then set the
205251964Sjfv	 * matching bit in 'pfc_up' to reflect that PFC is enabled.
206251964Sjfv	 */
207251964Sjfv	for (*pfc_up = 0, up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++) {
208251964Sjfv		if (tc_config[map[up]].pfc != ixgbe_dcb_pfc_disabled)
209251964Sjfv			*pfc_up |= 1 << up;
210251964Sjfv	}
211251964Sjfv}
212251964Sjfv
213251964Sjfvvoid ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config *cfg, int direction,
214251964Sjfv			     u16 *refill)
215251964Sjfv{
216251964Sjfv	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
217251964Sjfv	int tc;
218251964Sjfv
219251964Sjfv	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
220251964Sjfv		refill[tc] = tc_config[tc].path[direction].data_credits_refill;
221251964Sjfv}
222251964Sjfv
223251964Sjfvvoid ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config *cfg, u16 *max)
224251964Sjfv{
225251964Sjfv	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
226251964Sjfv	int tc;
227251964Sjfv
228251964Sjfv	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
229251964Sjfv		max[tc] = tc_config[tc].desc_credits_max;
230251964Sjfv}
231251964Sjfv
232251964Sjfvvoid ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config *cfg, int direction,
233251964Sjfv			    u8 *bwgid)
234251964Sjfv{
235251964Sjfv	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
236251964Sjfv	int tc;
237251964Sjfv
238251964Sjfv	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
239251964Sjfv		bwgid[tc] = tc_config[tc].path[direction].bwg_id;
240251964Sjfv}
241251964Sjfv
242251964Sjfvvoid ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config *cfg, int direction,
243251964Sjfv			   u8 *tsa)
244251964Sjfv{
245251964Sjfv	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
246251964Sjfv	int tc;
247251964Sjfv
248251964Sjfv	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
249251964Sjfv		tsa[tc] = tc_config[tc].path[direction].tsa;
250251964Sjfv}
251251964Sjfv
252251964Sjfvu8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up)
253251964Sjfv{
254251964Sjfv	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
255251964Sjfv	u8 prio_mask = 1 << up;
256251964Sjfv	u8 tc = cfg->num_tcs.pg_tcs;
257251964Sjfv
258251964Sjfv	/* If tc is 0 then DCB is likely not enabled or supported */
259251964Sjfv	if (!tc)
260251964Sjfv		goto out;
261251964Sjfv
262251964Sjfv	/*
263251964Sjfv	 * Test from maximum TC to 1 and report the first match we find.  If
264251964Sjfv	 * we find no match we can assume that the TC is 0 since the TC must
265251964Sjfv	 * be set for all user priorities
266251964Sjfv	 */
267251964Sjfv	for (tc--; tc; tc--) {
268251964Sjfv		if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap)
269251964Sjfv			break;
270251964Sjfv	}
271251964Sjfvout:
272251964Sjfv	return tc;
273251964Sjfv}
274251964Sjfv
275251964Sjfvvoid ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config *cfg, int direction,
276251964Sjfv			      u8 *map)
277251964Sjfv{
278251964Sjfv	u8 up;
279251964Sjfv
280251964Sjfv	for (up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++)
281251964Sjfv		map[up] = ixgbe_dcb_get_tc_from_up(cfg, direction, up);
282251964Sjfv}
283251964Sjfv
284251964Sjfv/**
285251964Sjfv * ixgbe_dcb_config - Struct containing DCB settings.
286251964Sjfv * @dcb_config: Pointer to DCB config structure
287251964Sjfv *
288251964Sjfv * This function checks DCB rules for DCB settings.
289251964Sjfv * The following rules are checked:
290251964Sjfv * 1. The sum of bandwidth percentages of all Bandwidth Groups must total 100%.
291251964Sjfv * 2. The sum of bandwidth percentages of all Traffic Classes within a Bandwidth
292251964Sjfv *    Group must total 100.
293251964Sjfv * 3. A Traffic Class should not be set to both Link Strict Priority
294251964Sjfv *    and Group Strict Priority.
295251964Sjfv * 4. Link strict Bandwidth Groups can only have link strict traffic classes
296251964Sjfv *    with zero bandwidth.
297251964Sjfv */
298251964Sjfvs32 ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config *dcb_config)
299251964Sjfv{
300251964Sjfv	struct ixgbe_dcb_tc_path *p;
301251964Sjfv	s32 ret_val = IXGBE_SUCCESS;
302251964Sjfv	u8 i, j, bw = 0, bw_id;
303251964Sjfv	u8 bw_sum[2][IXGBE_DCB_MAX_BW_GROUP];
304251964Sjfv	bool link_strict[2][IXGBE_DCB_MAX_BW_GROUP];
305251964Sjfv
306251964Sjfv	memset(bw_sum, 0, sizeof(bw_sum));
307251964Sjfv	memset(link_strict, 0, sizeof(link_strict));
308251964Sjfv
309251964Sjfv	/* First Tx, then Rx */
310251964Sjfv	for (i = 0; i < 2; i++) {
311251964Sjfv		/* Check each traffic class for rule violation */
312251964Sjfv		for (j = 0; j < IXGBE_DCB_MAX_TRAFFIC_CLASS; j++) {
313251964Sjfv			p = &dcb_config->tc_config[j].path[i];
314251964Sjfv
315251964Sjfv			bw = p->bwg_percent;
316251964Sjfv			bw_id = p->bwg_id;
317251964Sjfv
318251964Sjfv			if (bw_id >= IXGBE_DCB_MAX_BW_GROUP) {
319251964Sjfv				ret_val = IXGBE_ERR_CONFIG;
320251964Sjfv				goto err_config;
321251964Sjfv			}
322251964Sjfv			if (p->tsa == ixgbe_dcb_tsa_strict) {
323251964Sjfv				link_strict[i][bw_id] = TRUE;
324251964Sjfv				/* Link strict should have zero bandwidth */
325251964Sjfv				if (bw) {
326251964Sjfv					ret_val = IXGBE_ERR_CONFIG;
327251964Sjfv					goto err_config;
328251964Sjfv				}
329251964Sjfv			} else if (!bw) {
330251964Sjfv				/*
331251964Sjfv				 * Traffic classes without link strict
332251964Sjfv				 * should have non-zero bandwidth.
333251964Sjfv				 */
334251964Sjfv				ret_val = IXGBE_ERR_CONFIG;
335251964Sjfv				goto err_config;
336251964Sjfv			}
337251964Sjfv			bw_sum[i][bw_id] += bw;
338251964Sjfv		}
339251964Sjfv
340251964Sjfv		bw = 0;
341251964Sjfv
342251964Sjfv		/* Check each bandwidth group for rule violation */
343251964Sjfv		for (j = 0; j < IXGBE_DCB_MAX_BW_GROUP; j++) {
344251964Sjfv			bw += dcb_config->bw_percentage[i][j];
345251964Sjfv			/*
346251964Sjfv			 * Sum of bandwidth percentages of all traffic classes
347251964Sjfv			 * within a Bandwidth Group must total 100 except for
348251964Sjfv			 * link strict group (zero bandwidth).
349251964Sjfv			 */
350251964Sjfv			if (link_strict[i][j]) {
351251964Sjfv				if (bw_sum[i][j]) {
352251964Sjfv					/*
353251964Sjfv					 * Link strict group should have zero
354251964Sjfv					 * bandwidth.
355251964Sjfv					 */
356251964Sjfv					ret_val = IXGBE_ERR_CONFIG;
357251964Sjfv					goto err_config;
358251964Sjfv				}
359251964Sjfv			} else if (bw_sum[i][j] != IXGBE_DCB_BW_PERCENT &&
360251964Sjfv				   bw_sum[i][j] != 0) {
361251964Sjfv				ret_val = IXGBE_ERR_CONFIG;
362251964Sjfv				goto err_config;
363251964Sjfv			}
364251964Sjfv		}
365251964Sjfv
366251964Sjfv		if (bw != IXGBE_DCB_BW_PERCENT) {
367251964Sjfv			ret_val = IXGBE_ERR_CONFIG;
368251964Sjfv			goto err_config;
369251964Sjfv		}
370251964Sjfv	}
371251964Sjfv
372251964Sjfverr_config:
373251964Sjfv	DEBUGOUT2("DCB error code %d while checking %s settings.\n",
374251964Sjfv		  ret_val, (i == IXGBE_DCB_TX_CONFIG) ? "Tx" : "Rx");
375251964Sjfv
376251964Sjfv	return ret_val;
377251964Sjfv}
378251964Sjfv
379251964Sjfv/**
380251964Sjfv * ixgbe_dcb_get_tc_stats - Returns status of each traffic class
381251964Sjfv * @hw: pointer to hardware structure
382251964Sjfv * @stats: pointer to statistics structure
383251964Sjfv * @tc_count:  Number of elements in bwg_array.
384251964Sjfv *
385251964Sjfv * This function returns the status data for each of the Traffic Classes in use.
386251964Sjfv */
387251964Sjfvs32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
388251964Sjfv			   u8 tc_count)
389251964Sjfv{
390251964Sjfv	s32 ret = IXGBE_NOT_IMPLEMENTED;
391251964Sjfv	switch (hw->mac.type) {
392251964Sjfv	case ixgbe_mac_82598EB:
393251964Sjfv		ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count);
394251964Sjfv		break;
395251964Sjfv	case ixgbe_mac_82599EB:
396251964Sjfv	case ixgbe_mac_X540:
397251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
398251964Sjfv		ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
399251964Sjfv		break;
400251964Sjfv#endif
401251964Sjfv	default:
402251964Sjfv		break;
403251964Sjfv	}
404251964Sjfv	return ret;
405251964Sjfv}
406251964Sjfv
407251964Sjfv/**
408251964Sjfv * ixgbe_dcb_get_pfc_stats - Returns CBFC status of each traffic class
409251964Sjfv * @hw: pointer to hardware structure
410251964Sjfv * @stats: pointer to statistics structure
411251964Sjfv * @tc_count:  Number of elements in bwg_array.
412251964Sjfv *
413251964Sjfv * This function returns the CBFC status data for each of the Traffic Classes.
414251964Sjfv */
415251964Sjfvs32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
416251964Sjfv			    u8 tc_count)
417251964Sjfv{
418251964Sjfv	s32 ret = IXGBE_NOT_IMPLEMENTED;
419251964Sjfv	switch (hw->mac.type) {
420251964Sjfv	case ixgbe_mac_82598EB:
421251964Sjfv		ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count);
422251964Sjfv		break;
423251964Sjfv	case ixgbe_mac_82599EB:
424251964Sjfv	case ixgbe_mac_X540:
425251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
426251964Sjfv		ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
427251964Sjfv		break;
428251964Sjfv#endif
429251964Sjfv	default:
430251964Sjfv		break;
431251964Sjfv	}
432251964Sjfv	return ret;
433251964Sjfv}
434251964Sjfv
435251964Sjfv/**
436251964Sjfv * ixgbe_dcb_config_rx_arbiter_cee - Config Rx arbiter
437251964Sjfv * @hw: pointer to hardware structure
438251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure
439251964Sjfv *
440251964Sjfv * Configure Rx Data Arbiter and credits for each traffic class.
441251964Sjfv */
442251964Sjfvs32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw,
443251964Sjfv				struct ixgbe_dcb_config *dcb_config)
444251964Sjfv{
445251964Sjfv	s32 ret = IXGBE_NOT_IMPLEMENTED;
446251964Sjfv	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
447251964Sjfv	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
448251964Sjfv	u8 map[IXGBE_DCB_MAX_USER_PRIORITY]	= { 0 };
449251964Sjfv	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
450251964Sjfv	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
451251964Sjfv
452251964Sjfv	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
453251964Sjfv	ixgbe_dcb_unpack_max_cee(dcb_config, max);
454251964Sjfv	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
455251964Sjfv	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
456251964Sjfv	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
457251964Sjfv
458251964Sjfv	switch (hw->mac.type) {
459251964Sjfv	case ixgbe_mac_82598EB:
460251964Sjfv		ret = ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
461251964Sjfv		break;
462251964Sjfv	case ixgbe_mac_82599EB:
463251964Sjfv	case ixgbe_mac_X540:
464251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
465251964Sjfv		ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid,
466251964Sjfv							tsa, map);
467251964Sjfv		break;
468251964Sjfv#endif
469251964Sjfv	default:
470251964Sjfv		break;
471251964Sjfv	}
472251964Sjfv	return ret;
473251964Sjfv}
474251964Sjfv
475251964Sjfv/**
476251964Sjfv * ixgbe_dcb_config_tx_desc_arbiter_cee - Config Tx Desc arbiter
477251964Sjfv * @hw: pointer to hardware structure
478251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure
479251964Sjfv *
480251964Sjfv * Configure Tx Descriptor Arbiter and credits for each traffic class.
481251964Sjfv */
482251964Sjfvs32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw,
483251964Sjfv				     struct ixgbe_dcb_config *dcb_config)
484251964Sjfv{
485251964Sjfv	s32 ret = IXGBE_NOT_IMPLEMENTED;
486251964Sjfv	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
487251964Sjfv	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
488251964Sjfv	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
489251964Sjfv	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
490251964Sjfv
491251964Sjfv	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
492251964Sjfv	ixgbe_dcb_unpack_max_cee(dcb_config, max);
493251964Sjfv	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
494251964Sjfv	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
495251964Sjfv
496251964Sjfv	switch (hw->mac.type) {
497251964Sjfv	case ixgbe_mac_82598EB:
498251964Sjfv		ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
499251964Sjfv							     bwgid, tsa);
500251964Sjfv		break;
501251964Sjfv	case ixgbe_mac_82599EB:
502251964Sjfv	case ixgbe_mac_X540:
503251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
504251964Sjfv		ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
505251964Sjfv							     bwgid, tsa);
506251964Sjfv		break;
507251964Sjfv#endif
508251964Sjfv	default:
509251964Sjfv		break;
510251964Sjfv	}
511251964Sjfv	return ret;
512251964Sjfv}
513251964Sjfv
514251964Sjfv/**
515251964Sjfv * ixgbe_dcb_config_tx_data_arbiter_cee - Config Tx data arbiter
516251964Sjfv * @hw: pointer to hardware structure
517251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure
518251964Sjfv *
519251964Sjfv * Configure Tx Data Arbiter and credits for each traffic class.
520251964Sjfv */
521251964Sjfvs32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw,
522251964Sjfv				     struct ixgbe_dcb_config *dcb_config)
523251964Sjfv{
524251964Sjfv	s32 ret = IXGBE_NOT_IMPLEMENTED;
525251964Sjfv	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
526251964Sjfv	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
527251964Sjfv	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
528251964Sjfv	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
529251964Sjfv	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
530251964Sjfv
531251964Sjfv	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
532251964Sjfv	ixgbe_dcb_unpack_max_cee(dcb_config, max);
533251964Sjfv	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
534251964Sjfv	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
535251964Sjfv	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
536251964Sjfv
537251964Sjfv	switch (hw->mac.type) {
538251964Sjfv	case ixgbe_mac_82598EB:
539251964Sjfv		ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
540251964Sjfv							     bwgid, tsa);
541251964Sjfv		break;
542251964Sjfv	case ixgbe_mac_82599EB:
543251964Sjfv	case ixgbe_mac_X540:
544251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
545251964Sjfv		ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max,
546251964Sjfv							     bwgid, tsa,
547251964Sjfv							     map);
548251964Sjfv		break;
549251964Sjfv#endif
550251964Sjfv	default:
551251964Sjfv		break;
552251964Sjfv	}
553251964Sjfv	return ret;
554251964Sjfv}
555251964Sjfv
556251964Sjfv/**
557251964Sjfv * ixgbe_dcb_config_pfc_cee - Config priority flow control
558251964Sjfv * @hw: pointer to hardware structure
559251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure
560251964Sjfv *
561251964Sjfv * Configure Priority Flow Control for each traffic class.
562251964Sjfv */
563251964Sjfvs32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw,
564251964Sjfv			 struct ixgbe_dcb_config *dcb_config)
565251964Sjfv{
566251964Sjfv	s32 ret = IXGBE_NOT_IMPLEMENTED;
567251964Sjfv	u8 pfc_en;
568251964Sjfv	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
569251964Sjfv
570251964Sjfv	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
571251964Sjfv	ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
572251964Sjfv
573251964Sjfv	switch (hw->mac.type) {
574251964Sjfv	case ixgbe_mac_82598EB:
575251964Sjfv		ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
576251964Sjfv		break;
577251964Sjfv	case ixgbe_mac_82599EB:
578251964Sjfv	case ixgbe_mac_X540:
579251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
580251964Sjfv		ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
581251964Sjfv		break;
582251964Sjfv#endif
583251964Sjfv	default:
584251964Sjfv		break;
585251964Sjfv	}
586251964Sjfv	return ret;
587251964Sjfv}
588251964Sjfv
589251964Sjfv/**
590251964Sjfv * ixgbe_dcb_config_tc_stats - Config traffic class statistics
591251964Sjfv * @hw: pointer to hardware structure
592251964Sjfv *
593251964Sjfv * Configure queue statistics registers, all queues belonging to same traffic
594251964Sjfv * class uses a single set of queue statistics counters.
595251964Sjfv */
596251964Sjfvs32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw)
597251964Sjfv{
598251964Sjfv	s32 ret = IXGBE_NOT_IMPLEMENTED;
599251964Sjfv	switch (hw->mac.type) {
600251964Sjfv	case ixgbe_mac_82598EB:
601251964Sjfv		ret = ixgbe_dcb_config_tc_stats_82598(hw);
602251964Sjfv		break;
603251964Sjfv	case ixgbe_mac_82599EB:
604251964Sjfv	case ixgbe_mac_X540:
605251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
606251964Sjfv		ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL);
607251964Sjfv		break;
608251964Sjfv#endif
609251964Sjfv	default:
610251964Sjfv		break;
611251964Sjfv	}
612251964Sjfv	return ret;
613251964Sjfv}
614251964Sjfv
615251964Sjfv/**
616251964Sjfv * ixgbe_dcb_hw_config_cee - Config and enable DCB
617251964Sjfv * @hw: pointer to hardware structure
618251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure
619251964Sjfv *
620251964Sjfv * Configure dcb settings and enable dcb mode.
621251964Sjfv */
622251964Sjfvs32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw,
623251964Sjfv			struct ixgbe_dcb_config *dcb_config)
624251964Sjfv{
625251964Sjfv	s32 ret = IXGBE_NOT_IMPLEMENTED;
626251964Sjfv	u8 pfc_en;
627251964Sjfv	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
628251964Sjfv	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
629251964Sjfv	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
630251964Sjfv	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
631251964Sjfv	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
632251964Sjfv
633251964Sjfv	/* Unpack CEE standard containers */
634251964Sjfv	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
635251964Sjfv	ixgbe_dcb_unpack_max_cee(dcb_config, max);
636251964Sjfv	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
637251964Sjfv	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
638251964Sjfv	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
639251964Sjfv
640251964Sjfv	hw->mac.ops.setup_rxpba(hw, dcb_config->num_tcs.pg_tcs,
641251964Sjfv				0, dcb_config->rx_pba_cfg);
642251964Sjfv
643251964Sjfv	switch (hw->mac.type) {
644251964Sjfv	case ixgbe_mac_82598EB:
645251964Sjfv		ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->link_speed,
646251964Sjfv						refill, max, bwgid, tsa);
647251964Sjfv		break;
648251964Sjfv	case ixgbe_mac_82599EB:
649251964Sjfv	case ixgbe_mac_X540:
650251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
651251964Sjfv		ixgbe_dcb_config_82599(hw, dcb_config);
652251964Sjfv		ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed,
653251964Sjfv						refill, max, bwgid,
654251964Sjfv						tsa, map);
655251964Sjfv
656251964Sjfv		ixgbe_dcb_config_tc_stats_82599(hw, dcb_config);
657251964Sjfv		break;
658251964Sjfv#endif
659251964Sjfv	default:
660251964Sjfv		break;
661251964Sjfv	}
662251964Sjfv
663251964Sjfv	if (!ret && dcb_config->pfc_mode_enable) {
664251964Sjfv		ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
665251964Sjfv		ret = ixgbe_dcb_config_pfc(hw, pfc_en, map);
666251964Sjfv	}
667251964Sjfv
668251964Sjfv	return ret;
669251964Sjfv}
670251964Sjfv
671251964Sjfv/* Helper routines to abstract HW specifics from DCB netlink ops */
672251964Sjfvs32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map)
673251964Sjfv{
674251964Sjfv	int ret = IXGBE_ERR_PARAM;
675251964Sjfv
676251964Sjfv	switch (hw->mac.type) {
677251964Sjfv	case ixgbe_mac_82598EB:
678251964Sjfv		ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
679251964Sjfv		break;
680251964Sjfv	case ixgbe_mac_82599EB:
681251964Sjfv	case ixgbe_mac_X540:
682251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
683251964Sjfv		ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
684251964Sjfv		break;
685251964Sjfv#endif
686251964Sjfv	default:
687251964Sjfv		break;
688251964Sjfv	}
689251964Sjfv	return ret;
690251964Sjfv}
691251964Sjfv
692251964Sjfvs32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max,
693251964Sjfv			    u8 *bwg_id, u8 *tsa, u8 *map)
694251964Sjfv{
695251964Sjfv	switch (hw->mac.type) {
696251964Sjfv	case ixgbe_mac_82598EB:
697251964Sjfv		ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
698251964Sjfv		ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
699251964Sjfv						       tsa);
700251964Sjfv		ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
701251964Sjfv						       tsa);
702251964Sjfv		break;
703251964Sjfv	case ixgbe_mac_82599EB:
704251964Sjfv	case ixgbe_mac_X540:
705251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
706251964Sjfv		ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id,
707251964Sjfv						  tsa, map);
708251964Sjfv		ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id,
709251964Sjfv						       tsa);
710251964Sjfv		ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
711251964Sjfv						       tsa, map);
712251964Sjfv		break;
713251964Sjfv#endif
714251964Sjfv	default:
715251964Sjfv		break;
716251964Sjfv	}
717251964Sjfv	return 0;
718251964Sjfv}
719