1251964Sjfv/****************************************************************************** 2251964Sjfv 3315333Serj Copyright (c) 2001-2017, Intel Corporation 4251964Sjfv All rights reserved. 5315333Serj 6315333Serj Redistribution and use in source and binary forms, with or without 7251964Sjfv modification, are permitted provided that the following conditions are met: 8315333Serj 9315333Serj 1. Redistributions of source code must retain the above copyright notice, 10251964Sjfv this list of conditions and the following disclaimer. 11315333Serj 12315333Serj 2. Redistributions in binary form must reproduce the above copyright 13315333Serj notice, this list of conditions and the following disclaimer in the 14251964Sjfv documentation and/or other materials provided with the distribution. 15315333Serj 16315333Serj 3. Neither the name of the Intel Corporation nor the names of its 17315333Serj contributors may be used to endorse or promote products derived from 18251964Sjfv this software without specific prior written permission. 19315333Serj 20251964Sjfv THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21315333Serj AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22315333Serj IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23315333Serj ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24315333Serj LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25315333Serj CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26315333Serj SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27315333Serj INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28315333Serj 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: stable/10/sys/dev/ixgbe/ixgbe_dcb.c 315333 2017-03-15 21:20:17Z erj $*/ 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); 151295524Ssbruno 152295524Ssbruno /* Refill at least minimum credit */ 153295524Ssbruno if (credit_refill < min_credit) 154295524Ssbruno credit_refill = min_credit; 155295524Ssbruno 156251964Sjfv p->data_credits_refill = (u16)credit_refill; 157251964Sjfv 158251964Sjfv /* Calculate maximum credit for the TC */ 159251964Sjfv credit_max = (link_percentage * IXGBE_DCB_MAX_CREDIT) / 100; 160251964Sjfv 161251964Sjfv /* 162251964Sjfv * Adjustment based on rule checking, if the percentage 163251964Sjfv * of a TC is too small, the maximum credit may not be 164251964Sjfv * enough to send out a jumbo frame in data plane arbitration. 165251964Sjfv */ 166295524Ssbruno if (credit_max < min_credit) 167251964Sjfv credit_max = min_credit; 168251964Sjfv 169251964Sjfv if (direction == IXGBE_DCB_TX_CONFIG) { 170251964Sjfv /* 171251964Sjfv * Adjustment based on rule checking, if the 172251964Sjfv * percentage of a TC is too small, the maximum 173251964Sjfv * credit may not be enough to send out a TSO 174251964Sjfv * packet in descriptor plane arbitration. 175251964Sjfv */ 176251964Sjfv if (credit_max && (credit_max < 177251964Sjfv IXGBE_DCB_MIN_TSO_CREDIT) 178251964Sjfv && (hw->mac.type == ixgbe_mac_82598EB)) 179251964Sjfv credit_max = IXGBE_DCB_MIN_TSO_CREDIT; 180251964Sjfv 181251964Sjfv dcb_config->tc_config[i].desc_credits_max = 182251964Sjfv (u16)credit_max; 183251964Sjfv } 184251964Sjfv 185251964Sjfv p->data_credits_max = (u16)credit_max; 186251964Sjfv } 187251964Sjfv 188251964Sjfvout: 189251964Sjfv return ret_val; 190251964Sjfv} 191251964Sjfv 192251964Sjfv/** 193251964Sjfv * ixgbe_dcb_unpack_pfc_cee - Unpack dcb_config PFC info 194251964Sjfv * @cfg: dcb configuration to unpack into hardware consumable fields 195251964Sjfv * @map: user priority to traffic class map 196251964Sjfv * @pfc_up: u8 to store user priority PFC bitmask 197251964Sjfv * 198251964Sjfv * This unpacks the dcb configuration PFC info which is stored per 199251964Sjfv * traffic class into a 8bit user priority bitmask that can be 200251964Sjfv * consumed by hardware routines. The priority to tc map must be 201251964Sjfv * updated before calling this routine to use current up-to maps. 202251964Sjfv */ 203251964Sjfvvoid ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config *cfg, u8 *map, u8 *pfc_up) 204251964Sjfv{ 205251964Sjfv struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; 206251964Sjfv int up; 207251964Sjfv 208251964Sjfv /* 209251964Sjfv * If the TC for this user priority has PFC enabled then set the 210251964Sjfv * matching bit in 'pfc_up' to reflect that PFC is enabled. 211251964Sjfv */ 212251964Sjfv for (*pfc_up = 0, up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++) { 213251964Sjfv if (tc_config[map[up]].pfc != ixgbe_dcb_pfc_disabled) 214251964Sjfv *pfc_up |= 1 << up; 215251964Sjfv } 216251964Sjfv} 217251964Sjfv 218251964Sjfvvoid ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config *cfg, int direction, 219251964Sjfv u16 *refill) 220251964Sjfv{ 221251964Sjfv struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; 222251964Sjfv int tc; 223251964Sjfv 224251964Sjfv for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) 225251964Sjfv refill[tc] = tc_config[tc].path[direction].data_credits_refill; 226251964Sjfv} 227251964Sjfv 228251964Sjfvvoid ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config *cfg, u16 *max) 229251964Sjfv{ 230251964Sjfv struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; 231251964Sjfv int tc; 232251964Sjfv 233251964Sjfv for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) 234251964Sjfv max[tc] = tc_config[tc].desc_credits_max; 235251964Sjfv} 236251964Sjfv 237251964Sjfvvoid ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config *cfg, int direction, 238251964Sjfv u8 *bwgid) 239251964Sjfv{ 240251964Sjfv struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; 241251964Sjfv int tc; 242251964Sjfv 243251964Sjfv for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) 244251964Sjfv bwgid[tc] = tc_config[tc].path[direction].bwg_id; 245251964Sjfv} 246251964Sjfv 247251964Sjfvvoid ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config *cfg, int direction, 248251964Sjfv u8 *tsa) 249251964Sjfv{ 250251964Sjfv struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; 251251964Sjfv int tc; 252251964Sjfv 253251964Sjfv for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) 254251964Sjfv tsa[tc] = tc_config[tc].path[direction].tsa; 255251964Sjfv} 256251964Sjfv 257251964Sjfvu8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up) 258251964Sjfv{ 259251964Sjfv struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; 260251964Sjfv u8 prio_mask = 1 << up; 261251964Sjfv u8 tc = cfg->num_tcs.pg_tcs; 262251964Sjfv 263251964Sjfv /* If tc is 0 then DCB is likely not enabled or supported */ 264251964Sjfv if (!tc) 265251964Sjfv goto out; 266251964Sjfv 267251964Sjfv /* 268251964Sjfv * Test from maximum TC to 1 and report the first match we find. If 269251964Sjfv * we find no match we can assume that the TC is 0 since the TC must 270251964Sjfv * be set for all user priorities 271251964Sjfv */ 272251964Sjfv for (tc--; tc; tc--) { 273251964Sjfv if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap) 274251964Sjfv break; 275251964Sjfv } 276251964Sjfvout: 277251964Sjfv return tc; 278251964Sjfv} 279251964Sjfv 280251964Sjfvvoid ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config *cfg, int direction, 281251964Sjfv u8 *map) 282251964Sjfv{ 283251964Sjfv u8 up; 284251964Sjfv 285251964Sjfv for (up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++) 286251964Sjfv map[up] = ixgbe_dcb_get_tc_from_up(cfg, direction, up); 287251964Sjfv} 288251964Sjfv 289251964Sjfv/** 290251964Sjfv * ixgbe_dcb_config - Struct containing DCB settings. 291251964Sjfv * @dcb_config: Pointer to DCB config structure 292251964Sjfv * 293251964Sjfv * This function checks DCB rules for DCB settings. 294251964Sjfv * The following rules are checked: 295251964Sjfv * 1. The sum of bandwidth percentages of all Bandwidth Groups must total 100%. 296251964Sjfv * 2. The sum of bandwidth percentages of all Traffic Classes within a Bandwidth 297251964Sjfv * Group must total 100. 298251964Sjfv * 3. A Traffic Class should not be set to both Link Strict Priority 299251964Sjfv * and Group Strict Priority. 300251964Sjfv * 4. Link strict Bandwidth Groups can only have link strict traffic classes 301251964Sjfv * with zero bandwidth. 302251964Sjfv */ 303251964Sjfvs32 ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config *dcb_config) 304251964Sjfv{ 305251964Sjfv struct ixgbe_dcb_tc_path *p; 306251964Sjfv s32 ret_val = IXGBE_SUCCESS; 307251964Sjfv u8 i, j, bw = 0, bw_id; 308251964Sjfv u8 bw_sum[2][IXGBE_DCB_MAX_BW_GROUP]; 309251964Sjfv bool link_strict[2][IXGBE_DCB_MAX_BW_GROUP]; 310251964Sjfv 311251964Sjfv memset(bw_sum, 0, sizeof(bw_sum)); 312251964Sjfv memset(link_strict, 0, sizeof(link_strict)); 313251964Sjfv 314251964Sjfv /* First Tx, then Rx */ 315251964Sjfv for (i = 0; i < 2; i++) { 316251964Sjfv /* Check each traffic class for rule violation */ 317251964Sjfv for (j = 0; j < IXGBE_DCB_MAX_TRAFFIC_CLASS; j++) { 318251964Sjfv p = &dcb_config->tc_config[j].path[i]; 319251964Sjfv 320251964Sjfv bw = p->bwg_percent; 321251964Sjfv bw_id = p->bwg_id; 322251964Sjfv 323251964Sjfv if (bw_id >= IXGBE_DCB_MAX_BW_GROUP) { 324251964Sjfv ret_val = IXGBE_ERR_CONFIG; 325251964Sjfv goto err_config; 326251964Sjfv } 327251964Sjfv if (p->tsa == ixgbe_dcb_tsa_strict) { 328251964Sjfv link_strict[i][bw_id] = TRUE; 329251964Sjfv /* Link strict should have zero bandwidth */ 330251964Sjfv if (bw) { 331251964Sjfv ret_val = IXGBE_ERR_CONFIG; 332251964Sjfv goto err_config; 333251964Sjfv } 334251964Sjfv } else if (!bw) { 335251964Sjfv /* 336251964Sjfv * Traffic classes without link strict 337251964Sjfv * should have non-zero bandwidth. 338251964Sjfv */ 339251964Sjfv ret_val = IXGBE_ERR_CONFIG; 340251964Sjfv goto err_config; 341251964Sjfv } 342251964Sjfv bw_sum[i][bw_id] += bw; 343251964Sjfv } 344251964Sjfv 345251964Sjfv bw = 0; 346251964Sjfv 347251964Sjfv /* Check each bandwidth group for rule violation */ 348251964Sjfv for (j = 0; j < IXGBE_DCB_MAX_BW_GROUP; j++) { 349251964Sjfv bw += dcb_config->bw_percentage[i][j]; 350251964Sjfv /* 351251964Sjfv * Sum of bandwidth percentages of all traffic classes 352251964Sjfv * within a Bandwidth Group must total 100 except for 353251964Sjfv * link strict group (zero bandwidth). 354251964Sjfv */ 355251964Sjfv if (link_strict[i][j]) { 356251964Sjfv if (bw_sum[i][j]) { 357251964Sjfv /* 358251964Sjfv * Link strict group should have zero 359251964Sjfv * bandwidth. 360251964Sjfv */ 361251964Sjfv ret_val = IXGBE_ERR_CONFIG; 362251964Sjfv goto err_config; 363251964Sjfv } 364251964Sjfv } else if (bw_sum[i][j] != IXGBE_DCB_BW_PERCENT && 365251964Sjfv bw_sum[i][j] != 0) { 366251964Sjfv ret_val = IXGBE_ERR_CONFIG; 367251964Sjfv goto err_config; 368251964Sjfv } 369251964Sjfv } 370251964Sjfv 371251964Sjfv if (bw != IXGBE_DCB_BW_PERCENT) { 372251964Sjfv ret_val = IXGBE_ERR_CONFIG; 373251964Sjfv goto err_config; 374251964Sjfv } 375251964Sjfv } 376251964Sjfv 377251964Sjfverr_config: 378251964Sjfv DEBUGOUT2("DCB error code %d while checking %s settings.\n", 379251964Sjfv ret_val, (i == IXGBE_DCB_TX_CONFIG) ? "Tx" : "Rx"); 380251964Sjfv 381251964Sjfv return ret_val; 382251964Sjfv} 383251964Sjfv 384251964Sjfv/** 385251964Sjfv * ixgbe_dcb_get_tc_stats - Returns status of each traffic class 386251964Sjfv * @hw: pointer to hardware structure 387251964Sjfv * @stats: pointer to statistics structure 388251964Sjfv * @tc_count: Number of elements in bwg_array. 389251964Sjfv * 390251964Sjfv * This function returns the status data for each of the Traffic Classes in use. 391251964Sjfv */ 392251964Sjfvs32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, 393251964Sjfv u8 tc_count) 394251964Sjfv{ 395251964Sjfv s32 ret = IXGBE_NOT_IMPLEMENTED; 396251964Sjfv switch (hw->mac.type) { 397251964Sjfv case ixgbe_mac_82598EB: 398251964Sjfv ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count); 399251964Sjfv break; 400251964Sjfv case ixgbe_mac_82599EB: 401251964Sjfv case ixgbe_mac_X540: 402283620Serj case ixgbe_mac_X550: 403283620Serj case ixgbe_mac_X550EM_x: 404315333Serj case ixgbe_mac_X550EM_a: 405251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) 406251964Sjfv ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count); 407251964Sjfv break; 408251964Sjfv#endif 409251964Sjfv default: 410251964Sjfv break; 411251964Sjfv } 412251964Sjfv return ret; 413251964Sjfv} 414251964Sjfv 415251964Sjfv/** 416251964Sjfv * ixgbe_dcb_get_pfc_stats - Returns CBFC status of each traffic class 417251964Sjfv * @hw: pointer to hardware structure 418251964Sjfv * @stats: pointer to statistics structure 419251964Sjfv * @tc_count: Number of elements in bwg_array. 420251964Sjfv * 421251964Sjfv * This function returns the CBFC status data for each of the Traffic Classes. 422251964Sjfv */ 423251964Sjfvs32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, 424251964Sjfv u8 tc_count) 425251964Sjfv{ 426251964Sjfv s32 ret = IXGBE_NOT_IMPLEMENTED; 427251964Sjfv switch (hw->mac.type) { 428251964Sjfv case ixgbe_mac_82598EB: 429251964Sjfv ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count); 430251964Sjfv break; 431251964Sjfv case ixgbe_mac_82599EB: 432251964Sjfv case ixgbe_mac_X540: 433283620Serj case ixgbe_mac_X550: 434283620Serj case ixgbe_mac_X550EM_x: 435315333Serj case ixgbe_mac_X550EM_a: 436251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) 437251964Sjfv ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count); 438251964Sjfv break; 439251964Sjfv#endif 440251964Sjfv default: 441251964Sjfv break; 442251964Sjfv } 443251964Sjfv return ret; 444251964Sjfv} 445251964Sjfv 446251964Sjfv/** 447251964Sjfv * ixgbe_dcb_config_rx_arbiter_cee - Config Rx arbiter 448251964Sjfv * @hw: pointer to hardware structure 449251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure 450251964Sjfv * 451251964Sjfv * Configure Rx Data Arbiter and credits for each traffic class. 452251964Sjfv */ 453251964Sjfvs32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw, 454251964Sjfv struct ixgbe_dcb_config *dcb_config) 455251964Sjfv{ 456251964Sjfv s32 ret = IXGBE_NOT_IMPLEMENTED; 457251964Sjfv u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; 458251964Sjfv u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; 459251964Sjfv u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; 460251964Sjfv u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; 461251964Sjfv u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; 462251964Sjfv 463251964Sjfv ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); 464251964Sjfv ixgbe_dcb_unpack_max_cee(dcb_config, max); 465251964Sjfv ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); 466251964Sjfv ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); 467251964Sjfv ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); 468251964Sjfv 469251964Sjfv switch (hw->mac.type) { 470251964Sjfv case ixgbe_mac_82598EB: 471251964Sjfv ret = ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa); 472251964Sjfv break; 473251964Sjfv case ixgbe_mac_82599EB: 474251964Sjfv case ixgbe_mac_X540: 475283620Serj case ixgbe_mac_X550: 476283620Serj case ixgbe_mac_X550EM_x: 477315333Serj case ixgbe_mac_X550EM_a: 478251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) 479251964Sjfv ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid, 480251964Sjfv tsa, map); 481251964Sjfv break; 482251964Sjfv#endif 483251964Sjfv default: 484251964Sjfv break; 485251964Sjfv } 486251964Sjfv return ret; 487251964Sjfv} 488251964Sjfv 489251964Sjfv/** 490251964Sjfv * ixgbe_dcb_config_tx_desc_arbiter_cee - Config Tx Desc arbiter 491251964Sjfv * @hw: pointer to hardware structure 492251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure 493251964Sjfv * 494251964Sjfv * Configure Tx Descriptor Arbiter and credits for each traffic class. 495251964Sjfv */ 496251964Sjfvs32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw, 497251964Sjfv struct ixgbe_dcb_config *dcb_config) 498251964Sjfv{ 499251964Sjfv s32 ret = IXGBE_NOT_IMPLEMENTED; 500251964Sjfv u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 501251964Sjfv u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 502251964Sjfv u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 503251964Sjfv u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 504251964Sjfv 505251964Sjfv ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); 506251964Sjfv ixgbe_dcb_unpack_max_cee(dcb_config, max); 507251964Sjfv ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); 508251964Sjfv ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); 509251964Sjfv 510251964Sjfv switch (hw->mac.type) { 511251964Sjfv case ixgbe_mac_82598EB: 512251964Sjfv ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, 513251964Sjfv bwgid, tsa); 514251964Sjfv break; 515251964Sjfv case ixgbe_mac_82599EB: 516251964Sjfv case ixgbe_mac_X540: 517283620Serj case ixgbe_mac_X550: 518283620Serj case ixgbe_mac_X550EM_x: 519315333Serj case ixgbe_mac_X550EM_a: 520251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) 521251964Sjfv ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, 522251964Sjfv bwgid, tsa); 523251964Sjfv break; 524251964Sjfv#endif 525251964Sjfv default: 526251964Sjfv break; 527251964Sjfv } 528251964Sjfv return ret; 529251964Sjfv} 530251964Sjfv 531251964Sjfv/** 532251964Sjfv * ixgbe_dcb_config_tx_data_arbiter_cee - Config Tx data arbiter 533251964Sjfv * @hw: pointer to hardware structure 534251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure 535251964Sjfv * 536251964Sjfv * Configure Tx Data Arbiter and credits for each traffic class. 537251964Sjfv */ 538251964Sjfvs32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw, 539251964Sjfv struct ixgbe_dcb_config *dcb_config) 540251964Sjfv{ 541251964Sjfv s32 ret = IXGBE_NOT_IMPLEMENTED; 542251964Sjfv u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 543251964Sjfv u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 544251964Sjfv u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; 545251964Sjfv u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 546251964Sjfv u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 547251964Sjfv 548251964Sjfv ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); 549251964Sjfv ixgbe_dcb_unpack_max_cee(dcb_config, max); 550251964Sjfv ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); 551251964Sjfv ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); 552251964Sjfv ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); 553251964Sjfv 554251964Sjfv switch (hw->mac.type) { 555251964Sjfv case ixgbe_mac_82598EB: 556251964Sjfv ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, 557251964Sjfv bwgid, tsa); 558251964Sjfv break; 559251964Sjfv case ixgbe_mac_82599EB: 560251964Sjfv case ixgbe_mac_X540: 561283620Serj case ixgbe_mac_X550: 562283620Serj case ixgbe_mac_X550EM_x: 563315333Serj case ixgbe_mac_X550EM_a: 564251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) 565251964Sjfv ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, 566251964Sjfv bwgid, tsa, 567251964Sjfv map); 568251964Sjfv break; 569251964Sjfv#endif 570251964Sjfv default: 571251964Sjfv break; 572251964Sjfv } 573251964Sjfv return ret; 574251964Sjfv} 575251964Sjfv 576251964Sjfv/** 577251964Sjfv * ixgbe_dcb_config_pfc_cee - Config priority flow control 578251964Sjfv * @hw: pointer to hardware structure 579251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure 580251964Sjfv * 581251964Sjfv * Configure Priority Flow Control for each traffic class. 582251964Sjfv */ 583251964Sjfvs32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw, 584251964Sjfv struct ixgbe_dcb_config *dcb_config) 585251964Sjfv{ 586251964Sjfv s32 ret = IXGBE_NOT_IMPLEMENTED; 587251964Sjfv u8 pfc_en; 588251964Sjfv u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; 589251964Sjfv 590251964Sjfv ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); 591251964Sjfv ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en); 592251964Sjfv 593251964Sjfv switch (hw->mac.type) { 594251964Sjfv case ixgbe_mac_82598EB: 595251964Sjfv ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en); 596251964Sjfv break; 597251964Sjfv case ixgbe_mac_82599EB: 598251964Sjfv case ixgbe_mac_X540: 599283620Serj case ixgbe_mac_X550: 600283620Serj case ixgbe_mac_X550EM_x: 601315333Serj case ixgbe_mac_X550EM_a: 602251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) 603251964Sjfv ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); 604251964Sjfv break; 605251964Sjfv#endif 606251964Sjfv default: 607251964Sjfv break; 608251964Sjfv } 609251964Sjfv return ret; 610251964Sjfv} 611251964Sjfv 612251964Sjfv/** 613251964Sjfv * ixgbe_dcb_config_tc_stats - Config traffic class statistics 614251964Sjfv * @hw: pointer to hardware structure 615251964Sjfv * 616251964Sjfv * Configure queue statistics registers, all queues belonging to same traffic 617251964Sjfv * class uses a single set of queue statistics counters. 618251964Sjfv */ 619251964Sjfvs32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw) 620251964Sjfv{ 621251964Sjfv s32 ret = IXGBE_NOT_IMPLEMENTED; 622251964Sjfv switch (hw->mac.type) { 623251964Sjfv case ixgbe_mac_82598EB: 624251964Sjfv ret = ixgbe_dcb_config_tc_stats_82598(hw); 625251964Sjfv break; 626251964Sjfv case ixgbe_mac_82599EB: 627251964Sjfv case ixgbe_mac_X540: 628283620Serj case ixgbe_mac_X550: 629283620Serj case ixgbe_mac_X550EM_x: 630315333Serj case ixgbe_mac_X550EM_a: 631251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) 632251964Sjfv ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL); 633251964Sjfv break; 634251964Sjfv#endif 635251964Sjfv default: 636251964Sjfv break; 637251964Sjfv } 638251964Sjfv return ret; 639251964Sjfv} 640251964Sjfv 641251964Sjfv/** 642251964Sjfv * ixgbe_dcb_hw_config_cee - Config and enable DCB 643251964Sjfv * @hw: pointer to hardware structure 644251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure 645251964Sjfv * 646251964Sjfv * Configure dcb settings and enable dcb mode. 647251964Sjfv */ 648251964Sjfvs32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw, 649251964Sjfv struct ixgbe_dcb_config *dcb_config) 650251964Sjfv{ 651251964Sjfv s32 ret = IXGBE_NOT_IMPLEMENTED; 652251964Sjfv u8 pfc_en; 653251964Sjfv u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 654251964Sjfv u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 655251964Sjfv u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; 656251964Sjfv u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 657251964Sjfv u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 658251964Sjfv 659251964Sjfv /* Unpack CEE standard containers */ 660251964Sjfv ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); 661251964Sjfv ixgbe_dcb_unpack_max_cee(dcb_config, max); 662251964Sjfv ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); 663251964Sjfv ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); 664251964Sjfv ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); 665251964Sjfv 666251964Sjfv hw->mac.ops.setup_rxpba(hw, dcb_config->num_tcs.pg_tcs, 667251964Sjfv 0, dcb_config->rx_pba_cfg); 668251964Sjfv 669251964Sjfv switch (hw->mac.type) { 670251964Sjfv case ixgbe_mac_82598EB: 671251964Sjfv ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->link_speed, 672251964Sjfv refill, max, bwgid, tsa); 673251964Sjfv break; 674251964Sjfv case ixgbe_mac_82599EB: 675251964Sjfv case ixgbe_mac_X540: 676283620Serj case ixgbe_mac_X550: 677283620Serj case ixgbe_mac_X550EM_x: 678315333Serj case ixgbe_mac_X550EM_a: 679251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) 680251964Sjfv ixgbe_dcb_config_82599(hw, dcb_config); 681251964Sjfv ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed, 682251964Sjfv refill, max, bwgid, 683251964Sjfv tsa, map); 684251964Sjfv 685251964Sjfv ixgbe_dcb_config_tc_stats_82599(hw, dcb_config); 686251964Sjfv break; 687251964Sjfv#endif 688251964Sjfv default: 689251964Sjfv break; 690251964Sjfv } 691251964Sjfv 692251964Sjfv if (!ret && dcb_config->pfc_mode_enable) { 693251964Sjfv ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en); 694251964Sjfv ret = ixgbe_dcb_config_pfc(hw, pfc_en, map); 695251964Sjfv } 696251964Sjfv 697251964Sjfv return ret; 698251964Sjfv} 699251964Sjfv 700251964Sjfv/* Helper routines to abstract HW specifics from DCB netlink ops */ 701251964Sjfvs32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map) 702251964Sjfv{ 703251964Sjfv int ret = IXGBE_ERR_PARAM; 704251964Sjfv 705251964Sjfv switch (hw->mac.type) { 706251964Sjfv case ixgbe_mac_82598EB: 707251964Sjfv ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en); 708251964Sjfv break; 709251964Sjfv case ixgbe_mac_82599EB: 710251964Sjfv case ixgbe_mac_X540: 711283620Serj case ixgbe_mac_X550: 712283620Serj case ixgbe_mac_X550EM_x: 713315333Serj case ixgbe_mac_X550EM_a: 714251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) 715251964Sjfv ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); 716251964Sjfv break; 717251964Sjfv#endif 718251964Sjfv default: 719251964Sjfv break; 720251964Sjfv } 721251964Sjfv return ret; 722251964Sjfv} 723251964Sjfv 724251964Sjfvs32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max, 725251964Sjfv u8 *bwg_id, u8 *tsa, u8 *map) 726251964Sjfv{ 727251964Sjfv switch (hw->mac.type) { 728251964Sjfv case ixgbe_mac_82598EB: 729251964Sjfv ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa); 730251964Sjfv ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id, 731251964Sjfv tsa); 732251964Sjfv ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id, 733251964Sjfv tsa); 734251964Sjfv break; 735251964Sjfv case ixgbe_mac_82599EB: 736251964Sjfv case ixgbe_mac_X540: 737283620Serj case ixgbe_mac_X550: 738283620Serj case ixgbe_mac_X550EM_x: 739315333Serj case ixgbe_mac_X550EM_a: 740251964Sjfv#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) 741251964Sjfv ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, 742251964Sjfv tsa, map); 743251964Sjfv ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id, 744251964Sjfv tsa); 745251964Sjfv ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id, 746251964Sjfv tsa, map); 747251964Sjfv break; 748251964Sjfv#endif 749251964Sjfv default: 750251964Sjfv break; 751251964Sjfv } 752251964Sjfv return 0; 753251964Sjfv} 754