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