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