1/******************************************************************************* 2 3 Intel 10 Gigabit PCI Express Linux driver 4 Copyright(c) 1999 - 2014 Intel Corporation. 5 6 This program is free software; you can redistribute it and/or modify it 7 under the terms and conditions of the GNU General Public License, 8 version 2, as published by the Free Software Foundation. 9 10 This program is distributed in the hope it will be useful, but WITHOUT 11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 more details. 14 15 You should have received a copy of the GNU General Public License along with 16 this program; if not, write to the Free Software Foundation, Inc., 17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18 19 The full GNU General Public License is included in this distribution in 20 the file called "COPYING". 21 22 Contact Information: 23 Linux NICS <linux.nics@intel.com> 24 e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 25 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 26 27*******************************************************************************/ 28 29#include "ixgbe.h" 30#include <linux/dcbnl.h> 31#include "ixgbe_dcb_82598.h" 32#include "ixgbe_dcb_82599.h" 33#include "ixgbe_sriov.h" 34 35/* Callbacks for DCB netlink in the kernel */ 36#define BIT_DCB_MODE 0x01 37#define BIT_PFC 0x02 38#define BIT_PG_RX 0x04 39#define BIT_PG_TX 0x08 40#define BIT_APP_UPCHG 0x10 41#define BIT_LINKSPEED 0x80 42 43/* Responses for the DCB_C_SET_ALL command */ 44#define DCB_HW_CHG_RST 0 /* DCB configuration changed with reset */ 45#define DCB_NO_HW_CHG 1 /* DCB configuration did not change */ 46#define DCB_HW_CHG 2 /* DCB configuration changed, no reset */ 47 48static int ixgbe_copy_dcb_cfg(struct ixgbe_adapter *adapter, int tc_max) 49{ 50 struct ixgbe_dcb_config *scfg = &adapter->temp_dcb_cfg; 51 struct ixgbe_dcb_config *dcfg = &adapter->dcb_cfg; 52 struct tc_configuration *src = NULL; 53 struct tc_configuration *dst = NULL; 54 int i, j; 55 int tx = DCB_TX_CONFIG; 56 int rx = DCB_RX_CONFIG; 57 int changes = 0; 58#ifdef IXGBE_FCOE 59 struct dcb_app app = { 60 .selector = DCB_APP_IDTYPE_ETHTYPE, 61 .protocol = ETH_P_FCOE, 62 }; 63 u8 up = dcb_getapp(adapter->netdev, &app); 64 65 if (up && !(up & (1 << adapter->fcoe.up))) 66 changes |= BIT_APP_UPCHG; 67#endif 68 69 for (i = DCB_PG_ATTR_TC_0; i < tc_max + DCB_PG_ATTR_TC_0; i++) { 70 src = &scfg->tc_config[i - DCB_PG_ATTR_TC_0]; 71 dst = &dcfg->tc_config[i - DCB_PG_ATTR_TC_0]; 72 73 if (dst->path[tx].prio_type != src->path[tx].prio_type) { 74 dst->path[tx].prio_type = src->path[tx].prio_type; 75 changes |= BIT_PG_TX; 76 } 77 78 if (dst->path[tx].bwg_id != src->path[tx].bwg_id) { 79 dst->path[tx].bwg_id = src->path[tx].bwg_id; 80 changes |= BIT_PG_TX; 81 } 82 83 if (dst->path[tx].bwg_percent != src->path[tx].bwg_percent) { 84 dst->path[tx].bwg_percent = src->path[tx].bwg_percent; 85 changes |= BIT_PG_TX; 86 } 87 88 if (dst->path[tx].up_to_tc_bitmap != 89 src->path[tx].up_to_tc_bitmap) { 90 dst->path[tx].up_to_tc_bitmap = 91 src->path[tx].up_to_tc_bitmap; 92 changes |= (BIT_PG_TX | BIT_PFC | BIT_APP_UPCHG); 93 } 94 95 if (dst->path[rx].prio_type != src->path[rx].prio_type) { 96 dst->path[rx].prio_type = src->path[rx].prio_type; 97 changes |= BIT_PG_RX; 98 } 99 100 if (dst->path[rx].bwg_id != src->path[rx].bwg_id) { 101 dst->path[rx].bwg_id = src->path[rx].bwg_id; 102 changes |= BIT_PG_RX; 103 } 104 105 if (dst->path[rx].bwg_percent != src->path[rx].bwg_percent) { 106 dst->path[rx].bwg_percent = src->path[rx].bwg_percent; 107 changes |= BIT_PG_RX; 108 } 109 110 if (dst->path[rx].up_to_tc_bitmap != 111 src->path[rx].up_to_tc_bitmap) { 112 dst->path[rx].up_to_tc_bitmap = 113 src->path[rx].up_to_tc_bitmap; 114 changes |= (BIT_PG_RX | BIT_PFC | BIT_APP_UPCHG); 115 } 116 } 117 118 for (i = DCB_PG_ATTR_BW_ID_0; i < DCB_PG_ATTR_BW_ID_MAX; i++) { 119 j = i - DCB_PG_ATTR_BW_ID_0; 120 if (dcfg->bw_percentage[tx][j] != scfg->bw_percentage[tx][j]) { 121 dcfg->bw_percentage[tx][j] = scfg->bw_percentage[tx][j]; 122 changes |= BIT_PG_TX; 123 } 124 if (dcfg->bw_percentage[rx][j] != scfg->bw_percentage[rx][j]) { 125 dcfg->bw_percentage[rx][j] = scfg->bw_percentage[rx][j]; 126 changes |= BIT_PG_RX; 127 } 128 } 129 130 for (i = DCB_PFC_UP_ATTR_0; i < DCB_PFC_UP_ATTR_MAX; i++) { 131 j = i - DCB_PFC_UP_ATTR_0; 132 if (dcfg->tc_config[j].dcb_pfc != scfg->tc_config[j].dcb_pfc) { 133 dcfg->tc_config[j].dcb_pfc = scfg->tc_config[j].dcb_pfc; 134 changes |= BIT_PFC; 135 } 136 } 137 138 if (dcfg->pfc_mode_enable != scfg->pfc_mode_enable) { 139 dcfg->pfc_mode_enable = scfg->pfc_mode_enable; 140 changes |= BIT_PFC; 141 } 142 143 return changes; 144} 145 146static u8 ixgbe_dcbnl_get_state(struct net_device *netdev) 147{ 148 struct ixgbe_adapter *adapter = netdev_priv(netdev); 149 150 return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED); 151} 152 153static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) 154{ 155 struct ixgbe_adapter *adapter = netdev_priv(netdev); 156 157 /* Fail command if not in CEE mode */ 158 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 159 return 1; 160 161 /* verify there is something to do, if not then exit */ 162 if (!state == !(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) 163 return 0; 164 165 return !!ixgbe_setup_tc(netdev, 166 state ? adapter->dcb_cfg.num_tcs.pg_tcs : 0); 167} 168 169static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev, 170 u8 *perm_addr) 171{ 172 struct ixgbe_adapter *adapter = netdev_priv(netdev); 173 int i, j; 174 175 memset(perm_addr, 0xff, MAX_ADDR_LEN); 176 177 for (i = 0; i < netdev->addr_len; i++) 178 perm_addr[i] = adapter->hw.mac.perm_addr[i]; 179 180 switch (adapter->hw.mac.type) { 181 case ixgbe_mac_82599EB: 182 case ixgbe_mac_X540: 183 for (j = 0; j < netdev->addr_len; j++, i++) 184 perm_addr[i] = adapter->hw.mac.san_addr[j]; 185 break; 186 default: 187 break; 188 } 189} 190 191static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, 192 u8 prio, u8 bwg_id, u8 bw_pct, 193 u8 up_map) 194{ 195 struct ixgbe_adapter *adapter = netdev_priv(netdev); 196 197 if (prio != DCB_ATTR_VALUE_UNDEFINED) 198 adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type = prio; 199 if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) 200 adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_id = bwg_id; 201 if (bw_pct != DCB_ATTR_VALUE_UNDEFINED) 202 adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent = 203 bw_pct; 204 if (up_map != DCB_ATTR_VALUE_UNDEFINED) 205 adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap = 206 up_map; 207} 208 209static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, 210 u8 bw_pct) 211{ 212 struct ixgbe_adapter *adapter = netdev_priv(netdev); 213 214 adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct; 215} 216 217static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, 218 u8 prio, u8 bwg_id, u8 bw_pct, 219 u8 up_map) 220{ 221 struct ixgbe_adapter *adapter = netdev_priv(netdev); 222 223 if (prio != DCB_ATTR_VALUE_UNDEFINED) 224 adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type = prio; 225 if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) 226 adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_id = bwg_id; 227 if (bw_pct != DCB_ATTR_VALUE_UNDEFINED) 228 adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent = 229 bw_pct; 230 if (up_map != DCB_ATTR_VALUE_UNDEFINED) 231 adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap = 232 up_map; 233} 234 235static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, 236 u8 bw_pct) 237{ 238 struct ixgbe_adapter *adapter = netdev_priv(netdev); 239 240 adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct; 241} 242 243static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, 244 u8 *prio, u8 *bwg_id, u8 *bw_pct, 245 u8 *up_map) 246{ 247 struct ixgbe_adapter *adapter = netdev_priv(netdev); 248 249 *prio = adapter->dcb_cfg.tc_config[tc].path[0].prio_type; 250 *bwg_id = adapter->dcb_cfg.tc_config[tc].path[0].bwg_id; 251 *bw_pct = adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent; 252 *up_map = adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap; 253} 254 255static void ixgbe_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, 256 u8 *bw_pct) 257{ 258 struct ixgbe_adapter *adapter = netdev_priv(netdev); 259 260 *bw_pct = adapter->dcb_cfg.bw_percentage[0][bwg_id]; 261} 262 263static void ixgbe_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int tc, 264 u8 *prio, u8 *bwg_id, u8 *bw_pct, 265 u8 *up_map) 266{ 267 struct ixgbe_adapter *adapter = netdev_priv(netdev); 268 269 *prio = adapter->dcb_cfg.tc_config[tc].path[1].prio_type; 270 *bwg_id = adapter->dcb_cfg.tc_config[tc].path[1].bwg_id; 271 *bw_pct = adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent; 272 *up_map = adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap; 273} 274 275static void ixgbe_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, 276 u8 *bw_pct) 277{ 278 struct ixgbe_adapter *adapter = netdev_priv(netdev); 279 280 *bw_pct = adapter->dcb_cfg.bw_percentage[1][bwg_id]; 281} 282 283static void ixgbe_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority, 284 u8 setting) 285{ 286 struct ixgbe_adapter *adapter = netdev_priv(netdev); 287 288 adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc = setting; 289 if (adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc != 290 adapter->dcb_cfg.tc_config[priority].dcb_pfc) 291 adapter->temp_dcb_cfg.pfc_mode_enable = true; 292} 293 294static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, 295 u8 *setting) 296{ 297 struct ixgbe_adapter *adapter = netdev_priv(netdev); 298 299 *setting = adapter->dcb_cfg.tc_config[priority].dcb_pfc; 300} 301 302static void ixgbe_dcbnl_devreset(struct net_device *dev) 303{ 304 struct ixgbe_adapter *adapter = netdev_priv(dev); 305 306 while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) 307 usleep_range(1000, 2000); 308 309 if (netif_running(dev)) 310 dev->netdev_ops->ndo_stop(dev); 311 312 ixgbe_clear_interrupt_scheme(adapter); 313 ixgbe_init_interrupt_scheme(adapter); 314 315 if (netif_running(dev)) 316 dev->netdev_ops->ndo_open(dev); 317 318 clear_bit(__IXGBE_RESETTING, &adapter->state); 319} 320 321static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) 322{ 323 struct ixgbe_adapter *adapter = netdev_priv(netdev); 324 struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg; 325 struct ixgbe_hw *hw = &adapter->hw; 326 int ret = DCB_NO_HW_CHG; 327 int i; 328 329 /* Fail command if not in CEE mode */ 330 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 331 return DCB_NO_HW_CHG; 332 333 adapter->dcb_set_bitmap |= ixgbe_copy_dcb_cfg(adapter, 334 MAX_TRAFFIC_CLASS); 335 if (!adapter->dcb_set_bitmap) 336 return DCB_NO_HW_CHG; 337 338 if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) { 339 u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS]; 340 u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS]; 341 /* Priority to TC mapping in CEE case default to 1:1 */ 342 u8 prio_tc[MAX_USER_PRIORITY]; 343 int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; 344 345#ifdef IXGBE_FCOE 346 if (adapter->netdev->features & NETIF_F_FCOE_MTU) 347 max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); 348#endif 349 350 ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame, 351 DCB_TX_CONFIG); 352 ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame, 353 DCB_RX_CONFIG); 354 355 ixgbe_dcb_unpack_refill(dcb_cfg, DCB_TX_CONFIG, refill); 356 ixgbe_dcb_unpack_max(dcb_cfg, max); 357 ixgbe_dcb_unpack_bwgid(dcb_cfg, DCB_TX_CONFIG, bwg_id); 358 ixgbe_dcb_unpack_prio(dcb_cfg, DCB_TX_CONFIG, prio_type); 359 ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); 360 361 ixgbe_dcb_hw_ets_config(hw, refill, max, bwg_id, 362 prio_type, prio_tc); 363 364 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 365 netdev_set_prio_tc_map(netdev, i, prio_tc[i]); 366 367 ret = DCB_HW_CHG_RST; 368 } 369 370 if (adapter->dcb_set_bitmap & BIT_PFC) { 371 if (dcb_cfg->pfc_mode_enable) { 372 u8 pfc_en; 373 u8 prio_tc[MAX_USER_PRIORITY]; 374 375 ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); 376 ixgbe_dcb_unpack_pfc(dcb_cfg, &pfc_en); 377 ixgbe_dcb_hw_pfc_config(hw, pfc_en, prio_tc); 378 } else { 379 hw->mac.ops.fc_enable(hw); 380 } 381 382 ixgbe_set_rx_drop_en(adapter); 383 384 ret = DCB_HW_CHG; 385 } 386 387#ifdef IXGBE_FCOE 388 /* Reprogam FCoE hardware offloads when the traffic class 389 * FCoE is using changes. This happens if the APP info 390 * changes or the up2tc mapping is updated. 391 */ 392 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { 393 struct dcb_app app = { 394 .selector = DCB_APP_IDTYPE_ETHTYPE, 395 .protocol = ETH_P_FCOE, 396 }; 397 u8 up = dcb_getapp(netdev, &app); 398 399 adapter->fcoe.up = ffs(up) - 1; 400 ixgbe_dcbnl_devreset(netdev); 401 ret = DCB_HW_CHG_RST; 402 } 403#endif 404 405 adapter->dcb_set_bitmap = 0x00; 406 return ret; 407} 408 409static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap) 410{ 411 struct ixgbe_adapter *adapter = netdev_priv(netdev); 412 413 switch (capid) { 414 case DCB_CAP_ATTR_PG: 415 *cap = true; 416 break; 417 case DCB_CAP_ATTR_PFC: 418 *cap = true; 419 break; 420 case DCB_CAP_ATTR_UP2TC: 421 *cap = false; 422 break; 423 case DCB_CAP_ATTR_PG_TCS: 424 *cap = 0x80; 425 break; 426 case DCB_CAP_ATTR_PFC_TCS: 427 *cap = 0x80; 428 break; 429 case DCB_CAP_ATTR_GSP: 430 *cap = true; 431 break; 432 case DCB_CAP_ATTR_BCN: 433 *cap = false; 434 break; 435 case DCB_CAP_ATTR_DCBX: 436 *cap = adapter->dcbx_cap; 437 break; 438 default: 439 *cap = false; 440 break; 441 } 442 443 return 0; 444} 445 446static int ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) 447{ 448 struct ixgbe_adapter *adapter = netdev_priv(netdev); 449 450 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { 451 switch (tcid) { 452 case DCB_NUMTCS_ATTR_PG: 453 *num = adapter->dcb_cfg.num_tcs.pg_tcs; 454 break; 455 case DCB_NUMTCS_ATTR_PFC: 456 *num = adapter->dcb_cfg.num_tcs.pfc_tcs; 457 break; 458 default: 459 return -EINVAL; 460 } 461 } else { 462 return -EINVAL; 463 } 464 465 return 0; 466} 467 468static int ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num) 469{ 470 return -EINVAL; 471} 472 473static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev) 474{ 475 struct ixgbe_adapter *adapter = netdev_priv(netdev); 476 477 return adapter->dcb_cfg.pfc_mode_enable; 478} 479 480static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state) 481{ 482 struct ixgbe_adapter *adapter = netdev_priv(netdev); 483 484 adapter->temp_dcb_cfg.pfc_mode_enable = state; 485} 486 487/** 488 * ixgbe_dcbnl_getapp - retrieve the DCBX application user priority 489 * @netdev : the corresponding netdev 490 * @idtype : identifies the id as ether type or TCP/UDP port number 491 * @id: id is either ether type or TCP/UDP port number 492 * 493 * Returns : on success, returns a non-zero 802.1p user priority bitmap 494 * otherwise returns -EINVAL as the invalid user priority bitmap to indicate an 495 * error. 496 */ 497static int ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) 498{ 499 struct ixgbe_adapter *adapter = netdev_priv(netdev); 500 struct dcb_app app = { 501 .selector = idtype, 502 .protocol = id, 503 }; 504 505 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 506 return -EINVAL; 507 508 return dcb_getapp(netdev, &app); 509} 510 511static int ixgbe_dcbnl_ieee_getets(struct net_device *dev, 512 struct ieee_ets *ets) 513{ 514 struct ixgbe_adapter *adapter = netdev_priv(dev); 515 struct ieee_ets *my_ets = adapter->ixgbe_ieee_ets; 516 517 ets->ets_cap = adapter->dcb_cfg.num_tcs.pg_tcs; 518 519 /* No IEEE PFC settings available */ 520 if (!my_ets) 521 return 0; 522 523 ets->cbs = my_ets->cbs; 524 memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw)); 525 memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw)); 526 memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa)); 527 memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc)); 528 return 0; 529} 530 531static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, 532 struct ieee_ets *ets) 533{ 534 struct ixgbe_adapter *adapter = netdev_priv(dev); 535 int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; 536 int i, err; 537 __u8 max_tc = 0; 538 __u8 map_chg = 0; 539 540 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 541 return -EINVAL; 542 543 if (!adapter->ixgbe_ieee_ets) { 544 adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets), 545 GFP_KERNEL); 546 if (!adapter->ixgbe_ieee_ets) 547 return -ENOMEM; 548 549 /* initialize UP2TC mappings to invalid value */ 550 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 551 adapter->ixgbe_ieee_ets->prio_tc[i] = 552 IEEE_8021QAZ_MAX_TCS; 553 /* if possible update UP2TC mappings from HW */ 554 ixgbe_dcb_read_rtrup2tc(&adapter->hw, 555 adapter->ixgbe_ieee_ets->prio_tc); 556 } 557 558 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 559 if (ets->prio_tc[i] > max_tc) 560 max_tc = ets->prio_tc[i]; 561 if (ets->prio_tc[i] != adapter->ixgbe_ieee_ets->prio_tc[i]) 562 map_chg = 1; 563 } 564 565 memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); 566 567 if (max_tc) 568 max_tc++; 569 570 if (max_tc > adapter->dcb_cfg.num_tcs.pg_tcs) 571 return -EINVAL; 572 573 if (max_tc != netdev_get_num_tc(dev)) { 574 err = ixgbe_setup_tc(dev, max_tc); 575 if (err) 576 return err; 577 } else if (map_chg) { 578 ixgbe_dcbnl_devreset(dev); 579 } 580 581 return ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame); 582} 583 584static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev, 585 struct ieee_pfc *pfc) 586{ 587 struct ixgbe_adapter *adapter = netdev_priv(dev); 588 struct ieee_pfc *my_pfc = adapter->ixgbe_ieee_pfc; 589 int i; 590 591 pfc->pfc_cap = adapter->dcb_cfg.num_tcs.pfc_tcs; 592 593 /* No IEEE PFC settings available */ 594 if (!my_pfc) 595 return 0; 596 597 pfc->pfc_en = my_pfc->pfc_en; 598 pfc->mbc = my_pfc->mbc; 599 pfc->delay = my_pfc->delay; 600 601 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 602 pfc->requests[i] = adapter->stats.pxoffrxc[i]; 603 pfc->indications[i] = adapter->stats.pxofftxc[i]; 604 } 605 606 return 0; 607} 608 609static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, 610 struct ieee_pfc *pfc) 611{ 612 struct ixgbe_adapter *adapter = netdev_priv(dev); 613 struct ixgbe_hw *hw = &adapter->hw; 614 u8 *prio_tc; 615 int err; 616 617 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 618 return -EINVAL; 619 620 if (!adapter->ixgbe_ieee_pfc) { 621 adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), 622 GFP_KERNEL); 623 if (!adapter->ixgbe_ieee_pfc) 624 return -ENOMEM; 625 } 626 627 prio_tc = adapter->ixgbe_ieee_ets->prio_tc; 628 memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); 629 630 /* Enable link flow control parameters if PFC is disabled */ 631 if (pfc->pfc_en) 632 err = ixgbe_dcb_hw_pfc_config(hw, pfc->pfc_en, prio_tc); 633 else 634 err = hw->mac.ops.fc_enable(hw); 635 636 ixgbe_set_rx_drop_en(adapter); 637 638 return err; 639} 640 641static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, 642 struct dcb_app *app) 643{ 644 struct ixgbe_adapter *adapter = netdev_priv(dev); 645 int err; 646 647 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 648 return -EINVAL; 649 650 err = dcb_ieee_setapp(dev, app); 651 if (err) 652 return err; 653 654#ifdef IXGBE_FCOE 655 if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && 656 app->protocol == ETH_P_FCOE) { 657 u8 app_mask = dcb_ieee_getapp_mask(dev, app); 658 659 if (app_mask & (1 << adapter->fcoe.up)) 660 return 0; 661 662 adapter->fcoe.up = app->priority; 663 ixgbe_dcbnl_devreset(dev); 664 } 665#endif 666 667 /* VF devices should use default UP when available */ 668 if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && 669 app->protocol == 0) { 670 int vf; 671 672 adapter->default_up = app->priority; 673 674 for (vf = 0; vf < adapter->num_vfs; vf++) { 675 struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; 676 677 if (!vfinfo->pf_qos) 678 ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, 679 app->priority, vf); 680 } 681 } 682 683 return 0; 684} 685 686static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev, 687 struct dcb_app *app) 688{ 689 struct ixgbe_adapter *adapter = netdev_priv(dev); 690 int err; 691 692 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 693 return -EINVAL; 694 695 err = dcb_ieee_delapp(dev, app); 696 697#ifdef IXGBE_FCOE 698 if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && 699 app->protocol == ETH_P_FCOE) { 700 u8 app_mask = dcb_ieee_getapp_mask(dev, app); 701 702 if (app_mask & (1 << adapter->fcoe.up)) 703 return 0; 704 705 adapter->fcoe.up = app_mask ? 706 ffs(app_mask) - 1 : IXGBE_FCOE_DEFTC; 707 ixgbe_dcbnl_devreset(dev); 708 } 709#endif 710 /* IF default priority is being removed clear VF default UP */ 711 if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && 712 app->protocol == 0 && adapter->default_up == app->priority) { 713 int vf; 714 long unsigned int app_mask = dcb_ieee_getapp_mask(dev, app); 715 int qos = app_mask ? find_first_bit(&app_mask, 8) : 0; 716 717 adapter->default_up = qos; 718 719 for (vf = 0; vf < adapter->num_vfs; vf++) { 720 struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; 721 722 if (!vfinfo->pf_qos) 723 ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, 724 qos, vf); 725 } 726 } 727 728 return err; 729} 730 731static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev) 732{ 733 struct ixgbe_adapter *adapter = netdev_priv(dev); 734 return adapter->dcbx_cap; 735} 736 737static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode) 738{ 739 struct ixgbe_adapter *adapter = netdev_priv(dev); 740 struct ieee_ets ets = {0}; 741 struct ieee_pfc pfc = {0}; 742 int err = 0; 743 744 /* no support for LLD_MANAGED modes or CEE+IEEE */ 745 if ((mode & DCB_CAP_DCBX_LLD_MANAGED) || 746 ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) || 747 !(mode & DCB_CAP_DCBX_HOST)) 748 return 1; 749 750 if (mode == adapter->dcbx_cap) 751 return 0; 752 753 adapter->dcbx_cap = mode; 754 755 /* ETS and PFC defaults */ 756 ets.ets_cap = 8; 757 pfc.pfc_cap = 8; 758 759 if (mode & DCB_CAP_DCBX_VER_IEEE) { 760 ixgbe_dcbnl_ieee_setets(dev, &ets); 761 ixgbe_dcbnl_ieee_setpfc(dev, &pfc); 762 } else if (mode & DCB_CAP_DCBX_VER_CEE) { 763 u8 mask = BIT_PFC | BIT_PG_TX | BIT_PG_RX | BIT_APP_UPCHG; 764 765 adapter->dcb_set_bitmap |= mask; 766 ixgbe_dcbnl_set_all(dev); 767 } else { 768 /* Drop into single TC mode strict priority as this 769 * indicates CEE and IEEE versions are disabled 770 */ 771 ixgbe_dcbnl_ieee_setets(dev, &ets); 772 ixgbe_dcbnl_ieee_setpfc(dev, &pfc); 773 err = ixgbe_setup_tc(dev, 0); 774 } 775 776 return err ? 1 : 0; 777} 778 779const struct dcbnl_rtnl_ops dcbnl_ops = { 780 .ieee_getets = ixgbe_dcbnl_ieee_getets, 781 .ieee_setets = ixgbe_dcbnl_ieee_setets, 782 .ieee_getpfc = ixgbe_dcbnl_ieee_getpfc, 783 .ieee_setpfc = ixgbe_dcbnl_ieee_setpfc, 784 .ieee_setapp = ixgbe_dcbnl_ieee_setapp, 785 .ieee_delapp = ixgbe_dcbnl_ieee_delapp, 786 .getstate = ixgbe_dcbnl_get_state, 787 .setstate = ixgbe_dcbnl_set_state, 788 .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr, 789 .setpgtccfgtx = ixgbe_dcbnl_set_pg_tc_cfg_tx, 790 .setpgbwgcfgtx = ixgbe_dcbnl_set_pg_bwg_cfg_tx, 791 .setpgtccfgrx = ixgbe_dcbnl_set_pg_tc_cfg_rx, 792 .setpgbwgcfgrx = ixgbe_dcbnl_set_pg_bwg_cfg_rx, 793 .getpgtccfgtx = ixgbe_dcbnl_get_pg_tc_cfg_tx, 794 .getpgbwgcfgtx = ixgbe_dcbnl_get_pg_bwg_cfg_tx, 795 .getpgtccfgrx = ixgbe_dcbnl_get_pg_tc_cfg_rx, 796 .getpgbwgcfgrx = ixgbe_dcbnl_get_pg_bwg_cfg_rx, 797 .setpfccfg = ixgbe_dcbnl_set_pfc_cfg, 798 .getpfccfg = ixgbe_dcbnl_get_pfc_cfg, 799 .setall = ixgbe_dcbnl_set_all, 800 .getcap = ixgbe_dcbnl_getcap, 801 .getnumtcs = ixgbe_dcbnl_getnumtcs, 802 .setnumtcs = ixgbe_dcbnl_setnumtcs, 803 .getpfcstate = ixgbe_dcbnl_getpfcstate, 804 .setpfcstate = ixgbe_dcbnl_setpfcstate, 805 .getapp = ixgbe_dcbnl_getapp, 806 .getdcbx = ixgbe_dcbnl_getdcbx, 807 .setdcbx = ixgbe_dcbnl_setdcbx, 808}; 809