1/* $NetBSD: ixgbe_dcb.c,v 1.15 2023/10/06 14:48:08 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.15 2023/10/06 14:48:08 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 */ 56s32 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 */ 98s32 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 198out: 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 */ 213void 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 228void 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 238void 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 247void 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 257void 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 267u8 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 } 286out: 287 return tc; 288} 289 290void 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_check_config_cee - 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 */ 313s32 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 387err_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 */ 402s32 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 ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count); 416 break; 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 */ 431s32 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 ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count); 445 break; 446 default: 447 break; 448 } 449 return ret; 450} 451 452/** 453 * ixgbe_dcb_config_rx_arbiter_cee - Config Rx arbiter 454 * @hw: pointer to hardware structure 455 * @dcb_config: pointer to ixgbe_dcb_config structure 456 * 457 * Configure Rx Data Arbiter and credits for each traffic class. 458 */ 459s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw, 460 struct ixgbe_dcb_config *dcb_config) 461{ 462 s32 ret = IXGBE_NOT_IMPLEMENTED; 463 u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; 464 u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; 465 u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; 466 u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; 467 u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; 468 469 ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); 470 ixgbe_dcb_unpack_max_cee(dcb_config, max); 471 ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); 472 ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); 473 ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); 474 475 switch (hw->mac.type) { 476 case ixgbe_mac_82598EB: 477 ret = ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa); 478 break; 479 case ixgbe_mac_82599EB: 480 case ixgbe_mac_X540: 481 case ixgbe_mac_X550: 482 case ixgbe_mac_X550EM_x: 483 case ixgbe_mac_X550EM_a: 484 ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid, 485 tsa, map); 486 break; 487 default: 488 break; 489 } 490 return ret; 491} 492 493/** 494 * ixgbe_dcb_config_tx_desc_arbiter_cee - Config Tx Desc arbiter 495 * @hw: pointer to hardware structure 496 * @dcb_config: pointer to ixgbe_dcb_config structure 497 * 498 * Configure Tx Descriptor Arbiter and credits for each traffic class. 499 */ 500s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw, 501 struct ixgbe_dcb_config *dcb_config) 502{ 503 s32 ret = IXGBE_NOT_IMPLEMENTED; 504 u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 505 u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 506 u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 507 u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 508 509 ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); 510 ixgbe_dcb_unpack_max_cee(dcb_config, max); 511 ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); 512 ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); 513 514 switch (hw->mac.type) { 515 case ixgbe_mac_82598EB: 516 ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, 517 bwgid, tsa); 518 break; 519 case ixgbe_mac_82599EB: 520 case ixgbe_mac_X540: 521 case ixgbe_mac_X550: 522 case ixgbe_mac_X550EM_x: 523 case ixgbe_mac_X550EM_a: 524 ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, 525 bwgid, tsa); 526 break; 527 default: 528 break; 529 } 530 return ret; 531} 532 533/** 534 * ixgbe_dcb_config_tx_data_arbiter_cee - Config Tx data arbiter 535 * @hw: pointer to hardware structure 536 * @dcb_config: pointer to ixgbe_dcb_config structure 537 * 538 * Configure Tx Data Arbiter and credits for each traffic class. 539 */ 540s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw, 541 struct ixgbe_dcb_config *dcb_config) 542{ 543 s32 ret = IXGBE_NOT_IMPLEMENTED; 544 u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 545 u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 546 u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; 547 u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 548 u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 549 550 ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); 551 ixgbe_dcb_unpack_max_cee(dcb_config, max); 552 ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); 553 ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); 554 ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); 555 556 switch (hw->mac.type) { 557 case ixgbe_mac_82598EB: 558 ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, 559 bwgid, tsa); 560 break; 561 case ixgbe_mac_82599EB: 562 case ixgbe_mac_X540: 563 case ixgbe_mac_X550: 564 case ixgbe_mac_X550EM_x: 565 case ixgbe_mac_X550EM_a: 566 ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, 567 bwgid, tsa, 568 map); 569 break; 570 default: 571 break; 572 } 573 return ret; 574} 575 576/** 577 * ixgbe_dcb_config_pfc_cee - Config priority flow control 578 * @hw: pointer to hardware structure 579 * @dcb_config: pointer to ixgbe_dcb_config structure 580 * 581 * Configure Priority Flow Control for each traffic class. 582 */ 583s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw, 584 struct ixgbe_dcb_config *dcb_config) 585{ 586 s32 ret = IXGBE_NOT_IMPLEMENTED; 587 u8 pfc_en; 588 u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; 589 590 ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); 591 ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en); 592 593 switch (hw->mac.type) { 594 case ixgbe_mac_82598EB: 595 ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en); 596 break; 597 case ixgbe_mac_82599EB: 598 case ixgbe_mac_X540: 599 case ixgbe_mac_X550: 600 case ixgbe_mac_X550EM_x: 601 case ixgbe_mac_X550EM_a: 602 ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); 603 break; 604 default: 605 break; 606 } 607 return ret; 608} 609 610/** 611 * ixgbe_dcb_config_tc_stats - Config traffic class statistics 612 * @hw: pointer to hardware structure 613 * 614 * Configure queue statistics registers, all queues belonging to same traffic 615 * class uses a single set of queue statistics counters. 616 */ 617s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw) 618{ 619 s32 ret = IXGBE_NOT_IMPLEMENTED; 620 switch (hw->mac.type) { 621 case ixgbe_mac_82598EB: 622 ret = ixgbe_dcb_config_tc_stats_82598(hw); 623 break; 624 case ixgbe_mac_82599EB: 625 case ixgbe_mac_X540: 626 case ixgbe_mac_X550: 627 case ixgbe_mac_X550EM_x: 628 case ixgbe_mac_X550EM_a: 629 ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL); 630 break; 631 default: 632 break; 633 } 634 return ret; 635} 636 637/** 638 * ixgbe_dcb_hw_config_cee - Config and enable DCB 639 * @hw: pointer to hardware structure 640 * @dcb_config: pointer to ixgbe_dcb_config structure 641 * 642 * Configure dcb settings and enable dcb mode. 643 */ 644s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw, 645 struct ixgbe_dcb_config *dcb_config) 646{ 647 s32 ret = IXGBE_NOT_IMPLEMENTED; 648 u8 pfc_en; 649 u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 650 u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 651 u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; 652 u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 653 u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; 654 655 /* Unpack CEE standard containers */ 656 ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); 657 ixgbe_dcb_unpack_max_cee(dcb_config, max); 658 ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); 659 ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); 660 ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); 661 662 hw->mac.ops.setup_rxpba(hw, dcb_config->num_tcs.pg_tcs, 663 0, dcb_config->rx_pba_cfg); 664 665 switch (hw->mac.type) { 666 case ixgbe_mac_82598EB: 667 ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->link_speed, 668 refill, max, bwgid, tsa); 669 break; 670 case ixgbe_mac_82599EB: 671 case ixgbe_mac_X540: 672 case ixgbe_mac_X550: 673 case ixgbe_mac_X550EM_x: 674 case ixgbe_mac_X550EM_a: 675 ixgbe_dcb_config_82599(hw, dcb_config); 676 ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed, 677 refill, max, bwgid, 678 tsa, map); 679 680 ixgbe_dcb_config_tc_stats_82599(hw, dcb_config); 681 break; 682 default: 683 break; 684 } 685 686 if (!ret && dcb_config->pfc_mode_enable) { 687 ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en); 688 ret = ixgbe_dcb_config_pfc(hw, pfc_en, map); 689 } 690 691 return ret; 692} 693 694/* Helper routines to abstract HW specifics from DCB netlink ops */ 695s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map) 696{ 697 int ret = IXGBE_ERR_PARAM; 698 699 switch (hw->mac.type) { 700 case ixgbe_mac_82598EB: 701 ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en); 702 break; 703 case ixgbe_mac_82599EB: 704 case ixgbe_mac_X540: 705 case ixgbe_mac_X550: 706 case ixgbe_mac_X550EM_x: 707 case ixgbe_mac_X550EM_a: 708 ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); 709 break; 710 default: 711 break; 712 } 713 return ret; 714} 715 716s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max, 717 u8 *bwg_id, u8 *tsa, u8 *map) 718{ 719 switch (hw->mac.type) { 720 case ixgbe_mac_82598EB: 721 ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa); 722 ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id, 723 tsa); 724 ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id, 725 tsa); 726 break; 727 case ixgbe_mac_82599EB: 728 case ixgbe_mac_X540: 729 case ixgbe_mac_X550: 730 case ixgbe_mac_X550EM_x: 731 case ixgbe_mac_X550EM_a: 732 ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, 733 tsa, map); 734 ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id, 735 tsa); 736 ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id, 737 tsa, map); 738 break; 739 default: 740 break; 741 } 742 return 0; 743} 744