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 case ixgbe_mac_X550: 184 for (j = 0; j < netdev->addr_len; j++, i++) 185 perm_addr[i] = adapter->hw.mac.san_addr[j]; 186 break; 187 default: 188 break; 189 } 190} 191 192static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, 193 u8 prio, u8 bwg_id, u8 bw_pct, 194 u8 up_map) 195{ 196 struct ixgbe_adapter *adapter = netdev_priv(netdev); 197 198 if (prio != DCB_ATTR_VALUE_UNDEFINED) 199 adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type = prio; 200 if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) 201 adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_id = bwg_id; 202 if (bw_pct != DCB_ATTR_VALUE_UNDEFINED) 203 adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent = 204 bw_pct; 205 if (up_map != DCB_ATTR_VALUE_UNDEFINED) 206 adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap = 207 up_map; 208} 209 210static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, 211 u8 bw_pct) 212{ 213 struct ixgbe_adapter *adapter = netdev_priv(netdev); 214 215 adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct; 216} 217 218static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, 219 u8 prio, u8 bwg_id, u8 bw_pct, 220 u8 up_map) 221{ 222 struct ixgbe_adapter *adapter = netdev_priv(netdev); 223 224 if (prio != DCB_ATTR_VALUE_UNDEFINED) 225 adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type = prio; 226 if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) 227 adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_id = bwg_id; 228 if (bw_pct != DCB_ATTR_VALUE_UNDEFINED) 229 adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent = 230 bw_pct; 231 if (up_map != DCB_ATTR_VALUE_UNDEFINED) 232 adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap = 233 up_map; 234} 235 236static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, 237 u8 bw_pct) 238{ 239 struct ixgbe_adapter *adapter = netdev_priv(netdev); 240 241 adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct; 242} 243 244static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, 245 u8 *prio, u8 *bwg_id, u8 *bw_pct, 246 u8 *up_map) 247{ 248 struct ixgbe_adapter *adapter = netdev_priv(netdev); 249 250 *prio = adapter->dcb_cfg.tc_config[tc].path[0].prio_type; 251 *bwg_id = adapter->dcb_cfg.tc_config[tc].path[0].bwg_id; 252 *bw_pct = adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent; 253 *up_map = adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap; 254} 255 256static void ixgbe_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, 257 u8 *bw_pct) 258{ 259 struct ixgbe_adapter *adapter = netdev_priv(netdev); 260 261 *bw_pct = adapter->dcb_cfg.bw_percentage[0][bwg_id]; 262} 263 264static void ixgbe_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int tc, 265 u8 *prio, u8 *bwg_id, u8 *bw_pct, 266 u8 *up_map) 267{ 268 struct ixgbe_adapter *adapter = netdev_priv(netdev); 269 270 *prio = adapter->dcb_cfg.tc_config[tc].path[1].prio_type; 271 *bwg_id = adapter->dcb_cfg.tc_config[tc].path[1].bwg_id; 272 *bw_pct = adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent; 273 *up_map = adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap; 274} 275 276static void ixgbe_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, 277 u8 *bw_pct) 278{ 279 struct ixgbe_adapter *adapter = netdev_priv(netdev); 280 281 *bw_pct = adapter->dcb_cfg.bw_percentage[1][bwg_id]; 282} 283 284static void ixgbe_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority, 285 u8 setting) 286{ 287 struct ixgbe_adapter *adapter = netdev_priv(netdev); 288 289 adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc = setting; 290 if (adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc != 291 adapter->dcb_cfg.tc_config[priority].dcb_pfc) 292 adapter->temp_dcb_cfg.pfc_mode_enable = true; 293} 294 295static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, 296 u8 *setting) 297{ 298 struct ixgbe_adapter *adapter = netdev_priv(netdev); 299 300 *setting = adapter->dcb_cfg.tc_config[priority].dcb_pfc; 301} 302 303static void ixgbe_dcbnl_devreset(struct net_device *dev) 304{ 305 struct ixgbe_adapter *adapter = netdev_priv(dev); 306 307 while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) 308 usleep_range(1000, 2000); 309 310 if (netif_running(dev)) 311 dev->netdev_ops->ndo_stop(dev); 312 313 ixgbe_clear_interrupt_scheme(adapter); 314 ixgbe_init_interrupt_scheme(adapter); 315 316 if (netif_running(dev)) 317 dev->netdev_ops->ndo_open(dev); 318 319 clear_bit(__IXGBE_RESETTING, &adapter->state); 320} 321 322static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) 323{ 324 struct ixgbe_adapter *adapter = netdev_priv(netdev); 325 struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg; 326 struct ixgbe_hw *hw = &adapter->hw; 327 int ret = DCB_NO_HW_CHG; 328 int i; 329 330 /* Fail command if not in CEE mode */ 331 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 332 return DCB_NO_HW_CHG; 333 334 adapter->dcb_set_bitmap |= ixgbe_copy_dcb_cfg(adapter, 335 MAX_TRAFFIC_CLASS); 336 if (!adapter->dcb_set_bitmap) 337 return DCB_NO_HW_CHG; 338 339 if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) { 340 u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS]; 341 u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS]; 342 /* Priority to TC mapping in CEE case default to 1:1 */ 343 u8 prio_tc[MAX_USER_PRIORITY]; 344 int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; 345 346#ifdef IXGBE_FCOE 347 if (adapter->netdev->features & NETIF_F_FCOE_MTU) 348 max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); 349#endif 350 351 ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame, 352 DCB_TX_CONFIG); 353 ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame, 354 DCB_RX_CONFIG); 355 356 ixgbe_dcb_unpack_refill(dcb_cfg, DCB_TX_CONFIG, refill); 357 ixgbe_dcb_unpack_max(dcb_cfg, max); 358 ixgbe_dcb_unpack_bwgid(dcb_cfg, DCB_TX_CONFIG, bwg_id); 359 ixgbe_dcb_unpack_prio(dcb_cfg, DCB_TX_CONFIG, prio_type); 360 ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); 361 362 ixgbe_dcb_hw_ets_config(hw, refill, max, bwg_id, 363 prio_type, prio_tc); 364 365 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 366 netdev_set_prio_tc_map(netdev, i, prio_tc[i]); 367 368 ret = DCB_HW_CHG_RST; 369 } 370 371 if (adapter->dcb_set_bitmap & BIT_PFC) { 372 if (dcb_cfg->pfc_mode_enable) { 373 u8 pfc_en; 374 u8 prio_tc[MAX_USER_PRIORITY]; 375 376 ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); 377 ixgbe_dcb_unpack_pfc(dcb_cfg, &pfc_en); 378 ixgbe_dcb_hw_pfc_config(hw, pfc_en, prio_tc); 379 } else { 380 hw->mac.ops.fc_enable(hw); 381 } 382 383 ixgbe_set_rx_drop_en(adapter); 384 385 ret = DCB_HW_CHG; 386 } 387 388#ifdef IXGBE_FCOE 389 /* Reprogam FCoE hardware offloads when the traffic class 390 * FCoE is using changes. This happens if the APP info 391 * changes or the up2tc mapping is updated. 392 */ 393 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { 394 struct dcb_app app = { 395 .selector = DCB_APP_IDTYPE_ETHTYPE, 396 .protocol = ETH_P_FCOE, 397 }; 398 u8 up = dcb_getapp(netdev, &app); 399 400 adapter->fcoe.up = ffs(up) - 1; 401 ixgbe_dcbnl_devreset(netdev); 402 ret = DCB_HW_CHG_RST; 403 } 404#endif 405 406 adapter->dcb_set_bitmap = 0x00; 407 return ret; 408} 409 410static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap) 411{ 412 struct ixgbe_adapter *adapter = netdev_priv(netdev); 413 414 switch (capid) { 415 case DCB_CAP_ATTR_PG: 416 *cap = true; 417 break; 418 case DCB_CAP_ATTR_PFC: 419 *cap = true; 420 break; 421 case DCB_CAP_ATTR_UP2TC: 422 *cap = false; 423 break; 424 case DCB_CAP_ATTR_PG_TCS: 425 *cap = 0x80; 426 break; 427 case DCB_CAP_ATTR_PFC_TCS: 428 *cap = 0x80; 429 break; 430 case DCB_CAP_ATTR_GSP: 431 *cap = true; 432 break; 433 case DCB_CAP_ATTR_BCN: 434 *cap = false; 435 break; 436 case DCB_CAP_ATTR_DCBX: 437 *cap = adapter->dcbx_cap; 438 break; 439 default: 440 *cap = false; 441 break; 442 } 443 444 return 0; 445} 446 447static int ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) 448{ 449 struct ixgbe_adapter *adapter = netdev_priv(netdev); 450 451 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { 452 switch (tcid) { 453 case DCB_NUMTCS_ATTR_PG: 454 *num = adapter->dcb_cfg.num_tcs.pg_tcs; 455 break; 456 case DCB_NUMTCS_ATTR_PFC: 457 *num = adapter->dcb_cfg.num_tcs.pfc_tcs; 458 break; 459 default: 460 return -EINVAL; 461 } 462 } else { 463 return -EINVAL; 464 } 465 466 return 0; 467} 468 469static int ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num) 470{ 471 return -EINVAL; 472} 473 474static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev) 475{ 476 struct ixgbe_adapter *adapter = netdev_priv(netdev); 477 478 return adapter->dcb_cfg.pfc_mode_enable; 479} 480 481static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state) 482{ 483 struct ixgbe_adapter *adapter = netdev_priv(netdev); 484 485 adapter->temp_dcb_cfg.pfc_mode_enable = state; 486} 487 488/** 489 * ixgbe_dcbnl_getapp - retrieve the DCBX application user priority 490 * @netdev : the corresponding netdev 491 * @idtype : identifies the id as ether type or TCP/UDP port number 492 * @id: id is either ether type or TCP/UDP port number 493 * 494 * Returns : on success, returns a non-zero 802.1p user priority bitmap 495 * otherwise returns -EINVAL as the invalid user priority bitmap to indicate an 496 * error. 497 */ 498static int ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) 499{ 500 struct ixgbe_adapter *adapter = netdev_priv(netdev); 501 struct dcb_app app = { 502 .selector = idtype, 503 .protocol = id, 504 }; 505 506 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 507 return -EINVAL; 508 509 return dcb_getapp(netdev, &app); 510} 511 512static int ixgbe_dcbnl_ieee_getets(struct net_device *dev, 513 struct ieee_ets *ets) 514{ 515 struct ixgbe_adapter *adapter = netdev_priv(dev); 516 struct ieee_ets *my_ets = adapter->ixgbe_ieee_ets; 517 518 ets->ets_cap = adapter->dcb_cfg.num_tcs.pg_tcs; 519 520 /* No IEEE PFC settings available */ 521 if (!my_ets) 522 return 0; 523 524 ets->cbs = my_ets->cbs; 525 memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw)); 526 memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw)); 527 memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa)); 528 memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc)); 529 return 0; 530} 531 532static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, 533 struct ieee_ets *ets) 534{ 535 struct ixgbe_adapter *adapter = netdev_priv(dev); 536 int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; 537 int i, err; 538 __u8 max_tc = 0; 539 __u8 map_chg = 0; 540 541 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 542 return -EINVAL; 543 544 if (!adapter->ixgbe_ieee_ets) { 545 adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets), 546 GFP_KERNEL); 547 if (!adapter->ixgbe_ieee_ets) 548 return -ENOMEM; 549 550 /* initialize UP2TC mappings to invalid value */ 551 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 552 adapter->ixgbe_ieee_ets->prio_tc[i] = 553 IEEE_8021QAZ_MAX_TCS; 554 /* if possible update UP2TC mappings from HW */ 555 ixgbe_dcb_read_rtrup2tc(&adapter->hw, 556 adapter->ixgbe_ieee_ets->prio_tc); 557 } 558 559 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 560 if (ets->prio_tc[i] > max_tc) 561 max_tc = ets->prio_tc[i]; 562 if (ets->prio_tc[i] != adapter->ixgbe_ieee_ets->prio_tc[i]) 563 map_chg = 1; 564 } 565 566 memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); 567 568 if (max_tc) 569 max_tc++; 570 571 if (max_tc > adapter->dcb_cfg.num_tcs.pg_tcs) 572 return -EINVAL; 573 574 if (max_tc != netdev_get_num_tc(dev)) { 575 err = ixgbe_setup_tc(dev, max_tc); 576 if (err) 577 return err; 578 } else if (map_chg) { 579 ixgbe_dcbnl_devreset(dev); 580 } 581 582 return ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame); 583} 584 585static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev, 586 struct ieee_pfc *pfc) 587{ 588 struct ixgbe_adapter *adapter = netdev_priv(dev); 589 struct ieee_pfc *my_pfc = adapter->ixgbe_ieee_pfc; 590 int i; 591 592 pfc->pfc_cap = adapter->dcb_cfg.num_tcs.pfc_tcs; 593 594 /* No IEEE PFC settings available */ 595 if (!my_pfc) 596 return 0; 597 598 pfc->pfc_en = my_pfc->pfc_en; 599 pfc->mbc = my_pfc->mbc; 600 pfc->delay = my_pfc->delay; 601 602 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 603 pfc->requests[i] = adapter->stats.pxoffrxc[i]; 604 pfc->indications[i] = adapter->stats.pxofftxc[i]; 605 } 606 607 return 0; 608} 609 610static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, 611 struct ieee_pfc *pfc) 612{ 613 struct ixgbe_adapter *adapter = netdev_priv(dev); 614 struct ixgbe_hw *hw = &adapter->hw; 615 u8 *prio_tc; 616 int err; 617 618 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 619 return -EINVAL; 620 621 if (!adapter->ixgbe_ieee_pfc) { 622 adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), 623 GFP_KERNEL); 624 if (!adapter->ixgbe_ieee_pfc) 625 return -ENOMEM; 626 } 627 628 prio_tc = adapter->ixgbe_ieee_ets->prio_tc; 629 memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); 630 631 /* Enable link flow control parameters if PFC is disabled */ 632 if (pfc->pfc_en) 633 err = ixgbe_dcb_hw_pfc_config(hw, pfc->pfc_en, prio_tc); 634 else 635 err = hw->mac.ops.fc_enable(hw); 636 637 ixgbe_set_rx_drop_en(adapter); 638 639 return err; 640} 641 642static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, 643 struct dcb_app *app) 644{ 645 struct ixgbe_adapter *adapter = netdev_priv(dev); 646 int err; 647 648 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 649 return -EINVAL; 650 651 err = dcb_ieee_setapp(dev, app); 652 if (err) 653 return err; 654 655#ifdef IXGBE_FCOE 656 if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && 657 app->protocol == ETH_P_FCOE) { 658 u8 app_mask = dcb_ieee_getapp_mask(dev, app); 659 660 if (app_mask & (1 << adapter->fcoe.up)) 661 return 0; 662 663 adapter->fcoe.up = app->priority; 664 ixgbe_dcbnl_devreset(dev); 665 } 666#endif 667 668 /* VF devices should use default UP when available */ 669 if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && 670 app->protocol == 0) { 671 int vf; 672 673 adapter->default_up = app->priority; 674 675 for (vf = 0; vf < adapter->num_vfs; vf++) { 676 struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; 677 678 if (!vfinfo->pf_qos) 679 ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, 680 app->priority, vf); 681 } 682 } 683 684 return 0; 685} 686 687static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev, 688 struct dcb_app *app) 689{ 690 struct ixgbe_adapter *adapter = netdev_priv(dev); 691 int err; 692 693 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 694 return -EINVAL; 695 696 err = dcb_ieee_delapp(dev, app); 697 698#ifdef IXGBE_FCOE 699 if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && 700 app->protocol == ETH_P_FCOE) { 701 u8 app_mask = dcb_ieee_getapp_mask(dev, app); 702 703 if (app_mask & (1 << adapter->fcoe.up)) 704 return 0; 705 706 adapter->fcoe.up = app_mask ? 707 ffs(app_mask) - 1 : IXGBE_FCOE_DEFTC; 708 ixgbe_dcbnl_devreset(dev); 709 } 710#endif 711 /* IF default priority is being removed clear VF default UP */ 712 if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && 713 app->protocol == 0 && adapter->default_up == app->priority) { 714 int vf; 715 long unsigned int app_mask = dcb_ieee_getapp_mask(dev, app); 716 int qos = app_mask ? find_first_bit(&app_mask, 8) : 0; 717 718 adapter->default_up = qos; 719 720 for (vf = 0; vf < adapter->num_vfs; vf++) { 721 struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; 722 723 if (!vfinfo->pf_qos) 724 ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, 725 qos, vf); 726 } 727 } 728 729 return err; 730} 731 732static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev) 733{ 734 struct ixgbe_adapter *adapter = netdev_priv(dev); 735 return adapter->dcbx_cap; 736} 737 738static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode) 739{ 740 struct ixgbe_adapter *adapter = netdev_priv(dev); 741 struct ieee_ets ets = {0}; 742 struct ieee_pfc pfc = {0}; 743 int err = 0; 744 745 /* no support for LLD_MANAGED modes or CEE+IEEE */ 746 if ((mode & DCB_CAP_DCBX_LLD_MANAGED) || 747 ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) || 748 !(mode & DCB_CAP_DCBX_HOST)) 749 return 1; 750 751 if (mode == adapter->dcbx_cap) 752 return 0; 753 754 adapter->dcbx_cap = mode; 755 756 /* ETS and PFC defaults */ 757 ets.ets_cap = 8; 758 pfc.pfc_cap = 8; 759 760 if (mode & DCB_CAP_DCBX_VER_IEEE) { 761 ixgbe_dcbnl_ieee_setets(dev, &ets); 762 ixgbe_dcbnl_ieee_setpfc(dev, &pfc); 763 } else if (mode & DCB_CAP_DCBX_VER_CEE) { 764 u8 mask = BIT_PFC | BIT_PG_TX | BIT_PG_RX | BIT_APP_UPCHG; 765 766 adapter->dcb_set_bitmap |= mask; 767 ixgbe_dcbnl_set_all(dev); 768 } else { 769 /* Drop into single TC mode strict priority as this 770 * indicates CEE and IEEE versions are disabled 771 */ 772 ixgbe_dcbnl_ieee_setets(dev, &ets); 773 ixgbe_dcbnl_ieee_setpfc(dev, &pfc); 774 err = ixgbe_setup_tc(dev, 0); 775 } 776 777 return err ? 1 : 0; 778} 779 780const struct dcbnl_rtnl_ops dcbnl_ops = { 781 .ieee_getets = ixgbe_dcbnl_ieee_getets, 782 .ieee_setets = ixgbe_dcbnl_ieee_setets, 783 .ieee_getpfc = ixgbe_dcbnl_ieee_getpfc, 784 .ieee_setpfc = ixgbe_dcbnl_ieee_setpfc, 785 .ieee_setapp = ixgbe_dcbnl_ieee_setapp, 786 .ieee_delapp = ixgbe_dcbnl_ieee_delapp, 787 .getstate = ixgbe_dcbnl_get_state, 788 .setstate = ixgbe_dcbnl_set_state, 789 .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr, 790 .setpgtccfgtx = ixgbe_dcbnl_set_pg_tc_cfg_tx, 791 .setpgbwgcfgtx = ixgbe_dcbnl_set_pg_bwg_cfg_tx, 792 .setpgtccfgrx = ixgbe_dcbnl_set_pg_tc_cfg_rx, 793 .setpgbwgcfgrx = ixgbe_dcbnl_set_pg_bwg_cfg_rx, 794 .getpgtccfgtx = ixgbe_dcbnl_get_pg_tc_cfg_tx, 795 .getpgbwgcfgtx = ixgbe_dcbnl_get_pg_bwg_cfg_tx, 796 .getpgtccfgrx = ixgbe_dcbnl_get_pg_tc_cfg_rx, 797 .getpgbwgcfgrx = ixgbe_dcbnl_get_pg_bwg_cfg_rx, 798 .setpfccfg = ixgbe_dcbnl_set_pfc_cfg, 799 .getpfccfg = ixgbe_dcbnl_get_pfc_cfg, 800 .setall = ixgbe_dcbnl_set_all, 801 .getcap = ixgbe_dcbnl_getcap, 802 .getnumtcs = ixgbe_dcbnl_getnumtcs, 803 .setnumtcs = ixgbe_dcbnl_setnumtcs, 804 .getpfcstate = ixgbe_dcbnl_getpfcstate, 805 .setpfcstate = ixgbe_dcbnl_setpfcstate, 806 .getapp = ixgbe_dcbnl_getapp, 807 .getdcbx = ixgbe_dcbnl_getdcbx, 808 .setdcbx = ixgbe_dcbnl_setdcbx, 809}; 810