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