Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.39 844 lines 25 kB view raw
1/******************************************************************************* 2 3 Intel 10 Gigabit PCI Express Linux driver 4 Copyright(c) 1999 - 2011 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 34/* Callbacks for DCB netlink in the kernel */ 35#define BIT_DCB_MODE 0x01 36#define BIT_PFC 0x02 37#define BIT_PG_RX 0x04 38#define BIT_PG_TX 0x08 39#define BIT_APP_UPCHG 0x10 40#define BIT_LINKSPEED 0x80 41 42/* Responses for the DCB_C_SET_ALL command */ 43#define DCB_HW_CHG_RST 0 /* DCB configuration changed with reset */ 44#define DCB_NO_HW_CHG 1 /* DCB configuration did not change */ 45#define DCB_HW_CHG 2 /* DCB configuration changed, no reset */ 46 47int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg, 48 struct ixgbe_dcb_config *dst_dcb_cfg, int tc_max) 49{ 50 struct tc_configuration *src_tc_cfg = NULL; 51 struct tc_configuration *dst_tc_cfg = NULL; 52 int i; 53 54 if (!src_dcb_cfg || !dst_dcb_cfg) 55 return -EINVAL; 56 57 for (i = DCB_PG_ATTR_TC_0; i < tc_max + DCB_PG_ATTR_TC_0; i++) { 58 src_tc_cfg = &src_dcb_cfg->tc_config[i - DCB_PG_ATTR_TC_0]; 59 dst_tc_cfg = &dst_dcb_cfg->tc_config[i - DCB_PG_ATTR_TC_0]; 60 61 dst_tc_cfg->path[DCB_TX_CONFIG].prio_type = 62 src_tc_cfg->path[DCB_TX_CONFIG].prio_type; 63 64 dst_tc_cfg->path[DCB_TX_CONFIG].bwg_id = 65 src_tc_cfg->path[DCB_TX_CONFIG].bwg_id; 66 67 dst_tc_cfg->path[DCB_TX_CONFIG].bwg_percent = 68 src_tc_cfg->path[DCB_TX_CONFIG].bwg_percent; 69 70 dst_tc_cfg->path[DCB_TX_CONFIG].up_to_tc_bitmap = 71 src_tc_cfg->path[DCB_TX_CONFIG].up_to_tc_bitmap; 72 73 dst_tc_cfg->path[DCB_RX_CONFIG].prio_type = 74 src_tc_cfg->path[DCB_RX_CONFIG].prio_type; 75 76 dst_tc_cfg->path[DCB_RX_CONFIG].bwg_id = 77 src_tc_cfg->path[DCB_RX_CONFIG].bwg_id; 78 79 dst_tc_cfg->path[DCB_RX_CONFIG].bwg_percent = 80 src_tc_cfg->path[DCB_RX_CONFIG].bwg_percent; 81 82 dst_tc_cfg->path[DCB_RX_CONFIG].up_to_tc_bitmap = 83 src_tc_cfg->path[DCB_RX_CONFIG].up_to_tc_bitmap; 84 } 85 86 for (i = DCB_PG_ATTR_BW_ID_0; i < DCB_PG_ATTR_BW_ID_MAX; i++) { 87 dst_dcb_cfg->bw_percentage[DCB_TX_CONFIG] 88 [i-DCB_PG_ATTR_BW_ID_0] = src_dcb_cfg->bw_percentage 89 [DCB_TX_CONFIG][i-DCB_PG_ATTR_BW_ID_0]; 90 dst_dcb_cfg->bw_percentage[DCB_RX_CONFIG] 91 [i-DCB_PG_ATTR_BW_ID_0] = src_dcb_cfg->bw_percentage 92 [DCB_RX_CONFIG][i-DCB_PG_ATTR_BW_ID_0]; 93 } 94 95 for (i = DCB_PFC_UP_ATTR_0; i < DCB_PFC_UP_ATTR_MAX; i++) { 96 dst_dcb_cfg->tc_config[i - DCB_PFC_UP_ATTR_0].dcb_pfc = 97 src_dcb_cfg->tc_config[i - DCB_PFC_UP_ATTR_0].dcb_pfc; 98 } 99 100 dst_dcb_cfg->pfc_mode_enable = src_dcb_cfg->pfc_mode_enable; 101 102 return 0; 103} 104 105static u8 ixgbe_dcbnl_get_state(struct net_device *netdev) 106{ 107 struct ixgbe_adapter *adapter = netdev_priv(netdev); 108 109 return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED); 110} 111 112static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) 113{ 114 u8 err = 0; 115 struct ixgbe_adapter *adapter = netdev_priv(netdev); 116 117 if (state > 0) { 118 /* Turn on DCB */ 119 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) 120 goto out; 121 122 if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) { 123 e_err(drv, "Enable failed, needs MSI-X\n"); 124 err = 1; 125 goto out; 126 } 127 128 if (netif_running(netdev)) 129 netdev->netdev_ops->ndo_stop(netdev); 130 ixgbe_clear_interrupt_scheme(adapter); 131 132 switch (adapter->hw.mac.type) { 133 case ixgbe_mac_82598EB: 134 adapter->last_lfc_mode = adapter->hw.fc.current_mode; 135 adapter->hw.fc.requested_mode = ixgbe_fc_none; 136 break; 137 case ixgbe_mac_82599EB: 138 case ixgbe_mac_X540: 139 adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; 140 adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; 141 break; 142 default: 143 break; 144 } 145 146 adapter->flags |= IXGBE_FLAG_DCB_ENABLED; 147 if (!netdev_get_num_tc(netdev)) 148 ixgbe_setup_tc(netdev, MAX_TRAFFIC_CLASS); 149 150 ixgbe_init_interrupt_scheme(adapter); 151 if (netif_running(netdev)) 152 netdev->netdev_ops->ndo_open(netdev); 153 } else { 154 /* Turn off DCB */ 155 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { 156 if (netif_running(netdev)) 157 netdev->netdev_ops->ndo_stop(netdev); 158 ixgbe_clear_interrupt_scheme(adapter); 159 160 adapter->hw.fc.requested_mode = adapter->last_lfc_mode; 161 adapter->temp_dcb_cfg.pfc_mode_enable = false; 162 adapter->dcb_cfg.pfc_mode_enable = false; 163 adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; 164 switch (adapter->hw.mac.type) { 165 case ixgbe_mac_82599EB: 166 case ixgbe_mac_X540: 167 adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; 168 break; 169 default: 170 break; 171 } 172 173 ixgbe_setup_tc(netdev, 0); 174 175 ixgbe_init_interrupt_scheme(adapter); 176 if (netif_running(netdev)) 177 netdev->netdev_ops->ndo_open(netdev); 178 } 179 } 180out: 181 return err; 182} 183 184static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev, 185 u8 *perm_addr) 186{ 187 struct ixgbe_adapter *adapter = netdev_priv(netdev); 188 int i, j; 189 190 memset(perm_addr, 0xff, MAX_ADDR_LEN); 191 192 for (i = 0; i < netdev->addr_len; i++) 193 perm_addr[i] = adapter->hw.mac.perm_addr[i]; 194 195 switch (adapter->hw.mac.type) { 196 case ixgbe_mac_82599EB: 197 case ixgbe_mac_X540: 198 for (j = 0; j < netdev->addr_len; j++, i++) 199 perm_addr[i] = adapter->hw.mac.san_addr[j]; 200 break; 201 default: 202 break; 203 } 204} 205 206static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, 207 u8 prio, u8 bwg_id, u8 bw_pct, 208 u8 up_map) 209{ 210 struct ixgbe_adapter *adapter = netdev_priv(netdev); 211 212 if (prio != DCB_ATTR_VALUE_UNDEFINED) 213 adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type = prio; 214 if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) 215 adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_id = bwg_id; 216 if (bw_pct != DCB_ATTR_VALUE_UNDEFINED) 217 adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent = 218 bw_pct; 219 if (up_map != DCB_ATTR_VALUE_UNDEFINED) 220 adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap = 221 up_map; 222 223 if ((adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type != 224 adapter->dcb_cfg.tc_config[tc].path[0].prio_type) || 225 (adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_id != 226 adapter->dcb_cfg.tc_config[tc].path[0].bwg_id) || 227 (adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent != 228 adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent) || 229 (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap != 230 adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) 231 adapter->dcb_set_bitmap |= BIT_PG_TX; 232} 233 234static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, 235 u8 bw_pct) 236{ 237 struct ixgbe_adapter *adapter = netdev_priv(netdev); 238 239 adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct; 240 241 if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] != 242 adapter->dcb_cfg.bw_percentage[0][bwg_id]) 243 adapter->dcb_set_bitmap |= BIT_PG_TX; 244} 245 246static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, 247 u8 prio, u8 bwg_id, u8 bw_pct, 248 u8 up_map) 249{ 250 struct ixgbe_adapter *adapter = netdev_priv(netdev); 251 252 if (prio != DCB_ATTR_VALUE_UNDEFINED) 253 adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type = prio; 254 if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) 255 adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_id = bwg_id; 256 if (bw_pct != DCB_ATTR_VALUE_UNDEFINED) 257 adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent = 258 bw_pct; 259 if (up_map != DCB_ATTR_VALUE_UNDEFINED) 260 adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap = 261 up_map; 262 263 if ((adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type != 264 adapter->dcb_cfg.tc_config[tc].path[1].prio_type) || 265 (adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_id != 266 adapter->dcb_cfg.tc_config[tc].path[1].bwg_id) || 267 (adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent != 268 adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent) || 269 (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap != 270 adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) 271 adapter->dcb_set_bitmap |= BIT_PG_RX; 272} 273 274static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, 275 u8 bw_pct) 276{ 277 struct ixgbe_adapter *adapter = netdev_priv(netdev); 278 279 adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct; 280 281 if (adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] != 282 adapter->dcb_cfg.bw_percentage[1][bwg_id]) 283 adapter->dcb_set_bitmap |= BIT_PG_RX; 284} 285 286static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, 287 u8 *prio, u8 *bwg_id, u8 *bw_pct, 288 u8 *up_map) 289{ 290 struct ixgbe_adapter *adapter = netdev_priv(netdev); 291 292 *prio = adapter->dcb_cfg.tc_config[tc].path[0].prio_type; 293 *bwg_id = adapter->dcb_cfg.tc_config[tc].path[0].bwg_id; 294 *bw_pct = adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent; 295 *up_map = adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap; 296} 297 298static void ixgbe_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, 299 u8 *bw_pct) 300{ 301 struct ixgbe_adapter *adapter = netdev_priv(netdev); 302 303 *bw_pct = adapter->dcb_cfg.bw_percentage[0][bwg_id]; 304} 305 306static void ixgbe_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int tc, 307 u8 *prio, u8 *bwg_id, u8 *bw_pct, 308 u8 *up_map) 309{ 310 struct ixgbe_adapter *adapter = netdev_priv(netdev); 311 312 *prio = adapter->dcb_cfg.tc_config[tc].path[1].prio_type; 313 *bwg_id = adapter->dcb_cfg.tc_config[tc].path[1].bwg_id; 314 *bw_pct = adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent; 315 *up_map = adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap; 316} 317 318static void ixgbe_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, 319 u8 *bw_pct) 320{ 321 struct ixgbe_adapter *adapter = netdev_priv(netdev); 322 323 *bw_pct = adapter->dcb_cfg.bw_percentage[1][bwg_id]; 324} 325 326static void ixgbe_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority, 327 u8 setting) 328{ 329 struct ixgbe_adapter *adapter = netdev_priv(netdev); 330 331 adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc = setting; 332 if (adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc != 333 adapter->dcb_cfg.tc_config[priority].dcb_pfc) { 334 adapter->dcb_set_bitmap |= BIT_PFC; 335 adapter->temp_dcb_cfg.pfc_mode_enable = true; 336 } 337} 338 339static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, 340 u8 *setting) 341{ 342 struct ixgbe_adapter *adapter = netdev_priv(netdev); 343 344 *setting = adapter->dcb_cfg.tc_config[priority].dcb_pfc; 345} 346 347static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) 348{ 349 struct ixgbe_adapter *adapter = netdev_priv(netdev); 350 int ret; 351 352 if (!adapter->dcb_set_bitmap || 353 !(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 354 return DCB_NO_HW_CHG; 355 356 ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, 357 MAX_TRAFFIC_CLASS); 358 359 if (ret) 360 return DCB_NO_HW_CHG; 361 362 /* 363 * Only take down the adapter if an app change occurred. FCoE 364 * may shuffle tx rings in this case and this can not be done 365 * without a reset currently. 366 */ 367 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { 368 while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) 369 msleep(1); 370 371 if (netif_running(netdev)) 372 netdev->netdev_ops->ndo_stop(netdev); 373 ixgbe_clear_interrupt_scheme(adapter); 374 } 375 376 if (adapter->dcb_cfg.pfc_mode_enable) { 377 switch (adapter->hw.mac.type) { 378 case ixgbe_mac_82599EB: 379 case ixgbe_mac_X540: 380 if (adapter->hw.fc.current_mode != ixgbe_fc_pfc) 381 adapter->last_lfc_mode = 382 adapter->hw.fc.current_mode; 383 break; 384 default: 385 break; 386 } 387 adapter->hw.fc.requested_mode = ixgbe_fc_pfc; 388 } else { 389 switch (adapter->hw.mac.type) { 390 case ixgbe_mac_82598EB: 391 adapter->hw.fc.requested_mode = ixgbe_fc_none; 392 break; 393 case ixgbe_mac_82599EB: 394 case ixgbe_mac_X540: 395 adapter->hw.fc.requested_mode = adapter->last_lfc_mode; 396 break; 397 default: 398 break; 399 } 400 } 401 402 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { 403 ixgbe_init_interrupt_scheme(adapter); 404 if (netif_running(netdev)) 405 netdev->netdev_ops->ndo_open(netdev); 406 ret = DCB_HW_CHG_RST; 407 } 408 409 if (adapter->dcb_set_bitmap & BIT_PFC) { 410 u8 pfc_en; 411 ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en); 412 ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc_en); 413 ret = DCB_HW_CHG; 414 } 415 416 if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) { 417 u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS]; 418 u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS]; 419 /* Priority to TC mapping in CEE case default to 1:1 */ 420 u8 prio_tc[MAX_TRAFFIC_CLASS] = {0, 1, 2, 3, 4, 5, 6, 7}; 421 int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; 422 423#ifdef CONFIG_FCOE 424 if (adapter->netdev->features & NETIF_F_FCOE_MTU) 425 max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); 426#endif 427 428 ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg, 429 max_frame, DCB_TX_CONFIG); 430 ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg, 431 max_frame, DCB_RX_CONFIG); 432 433 ixgbe_dcb_unpack_refill(&adapter->dcb_cfg, 434 DCB_TX_CONFIG, refill); 435 ixgbe_dcb_unpack_max(&adapter->dcb_cfg, max); 436 ixgbe_dcb_unpack_bwgid(&adapter->dcb_cfg, 437 DCB_TX_CONFIG, bwg_id); 438 ixgbe_dcb_unpack_prio(&adapter->dcb_cfg, 439 DCB_TX_CONFIG, prio_type); 440 441 ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max, 442 bwg_id, prio_type, prio_tc); 443 } 444 445 if (adapter->dcb_cfg.pfc_mode_enable) 446 adapter->hw.fc.current_mode = ixgbe_fc_pfc; 447 448 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) 449 clear_bit(__IXGBE_RESETTING, &adapter->state); 450 adapter->dcb_set_bitmap = 0x00; 451 return ret; 452} 453 454static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap) 455{ 456 struct ixgbe_adapter *adapter = netdev_priv(netdev); 457 458 switch (capid) { 459 case DCB_CAP_ATTR_PG: 460 *cap = true; 461 break; 462 case DCB_CAP_ATTR_PFC: 463 *cap = true; 464 break; 465 case DCB_CAP_ATTR_UP2TC: 466 *cap = false; 467 break; 468 case DCB_CAP_ATTR_PG_TCS: 469 *cap = 0x80; 470 break; 471 case DCB_CAP_ATTR_PFC_TCS: 472 *cap = 0x80; 473 break; 474 case DCB_CAP_ATTR_GSP: 475 *cap = true; 476 break; 477 case DCB_CAP_ATTR_BCN: 478 *cap = false; 479 break; 480 case DCB_CAP_ATTR_DCBX: 481 *cap = adapter->dcbx_cap; 482 break; 483 default: 484 *cap = false; 485 break; 486 } 487 488 return 0; 489} 490 491static u8 ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) 492{ 493 struct ixgbe_adapter *adapter = netdev_priv(netdev); 494 u8 rval = 0; 495 496 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { 497 switch (tcid) { 498 case DCB_NUMTCS_ATTR_PG: 499 *num = MAX_TRAFFIC_CLASS; 500 break; 501 case DCB_NUMTCS_ATTR_PFC: 502 *num = MAX_TRAFFIC_CLASS; 503 break; 504 default: 505 rval = -EINVAL; 506 break; 507 } 508 } else { 509 rval = -EINVAL; 510 } 511 512 return rval; 513} 514 515static u8 ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num) 516{ 517 return -EINVAL; 518} 519 520static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev) 521{ 522 struct ixgbe_adapter *adapter = netdev_priv(netdev); 523 524 return adapter->dcb_cfg.pfc_mode_enable; 525} 526 527static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state) 528{ 529 struct ixgbe_adapter *adapter = netdev_priv(netdev); 530 531 adapter->temp_dcb_cfg.pfc_mode_enable = state; 532 if (adapter->temp_dcb_cfg.pfc_mode_enable != 533 adapter->dcb_cfg.pfc_mode_enable) 534 adapter->dcb_set_bitmap |= BIT_PFC; 535} 536 537/** 538 * ixgbe_dcbnl_getapp - retrieve the DCBX application user priority 539 * @netdev : the corresponding netdev 540 * @idtype : identifies the id as ether type or TCP/UDP port number 541 * @id: id is either ether type or TCP/UDP port number 542 * 543 * Returns : on success, returns a non-zero 802.1p user priority bitmap 544 * otherwise returns 0 as the invalid user priority bitmap to indicate an 545 * error. 546 */ 547static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) 548{ 549 struct ixgbe_adapter *adapter = netdev_priv(netdev); 550 struct dcb_app app = { 551 .selector = idtype, 552 .protocol = id, 553 }; 554 555 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 556 return 0; 557 558 return dcb_getapp(netdev, &app); 559} 560 561/** 562 * ixgbe_dcbnl_setapp - set the DCBX application user priority 563 * @netdev : the corresponding netdev 564 * @idtype : identifies the id as ether type or TCP/UDP port number 565 * @id: id is either ether type or TCP/UDP port number 566 * @up: the 802.1p user priority bitmap 567 * 568 * Returns : 0 on success or 1 on error 569 */ 570static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, 571 u8 idtype, u16 id, u8 up) 572{ 573 struct ixgbe_adapter *adapter = netdev_priv(netdev); 574 u8 rval = 1; 575 struct dcb_app app = { 576 .selector = idtype, 577 .protocol = id, 578 .priority = up 579 }; 580 581 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 582 return rval; 583 584 rval = dcb_setapp(netdev, &app); 585 586 switch (idtype) { 587 case DCB_APP_IDTYPE_ETHTYPE: 588#ifdef IXGBE_FCOE 589 if (id == ETH_P_FCOE) { 590 u8 old_tc; 591 592 /* Get current programmed tc */ 593 old_tc = adapter->fcoe.tc; 594 rval = ixgbe_fcoe_setapp(adapter, up); 595 596 if (rval || 597 !(adapter->flags & IXGBE_FLAG_DCB_ENABLED) || 598 !(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) 599 break; 600 601 /* The FCoE application priority may be changed multiple 602 * times in quick succession with switches that build up 603 * TLVs. To avoid creating uneeded device resets this 604 * checks the actual HW configuration and clears 605 * BIT_APP_UPCHG if a HW configuration change is not 606 * need 607 */ 608 if (old_tc == adapter->fcoe.tc) 609 adapter->dcb_set_bitmap &= ~BIT_APP_UPCHG; 610 else 611 adapter->dcb_set_bitmap |= BIT_APP_UPCHG; 612 } 613#endif 614 break; 615 case DCB_APP_IDTYPE_PORTNUM: 616 break; 617 default: 618 break; 619 } 620 return rval; 621} 622 623static int ixgbe_dcbnl_ieee_getets(struct net_device *dev, 624 struct ieee_ets *ets) 625{ 626 struct ixgbe_adapter *adapter = netdev_priv(dev); 627 struct ieee_ets *my_ets = adapter->ixgbe_ieee_ets; 628 629 /* No IEEE PFC settings available */ 630 if (!my_ets) 631 return -EINVAL; 632 633 ets->ets_cap = MAX_TRAFFIC_CLASS; 634 ets->cbs = my_ets->cbs; 635 memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw)); 636 memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw)); 637 memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa)); 638 memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc)); 639 return 0; 640} 641 642static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, 643 struct ieee_ets *ets) 644{ 645 struct ixgbe_adapter *adapter = netdev_priv(dev); 646 __u16 refill[IEEE_8021QAZ_MAX_TCS], max[IEEE_8021QAZ_MAX_TCS]; 647 __u8 prio_type[IEEE_8021QAZ_MAX_TCS]; 648 int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; 649 int i, err; 650 __u64 *p = (__u64 *) ets->prio_tc; 651 /* naively give each TC a bwg to map onto CEE hardware */ 652 __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7}; 653 654 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 655 return -EINVAL; 656 657 if (!adapter->ixgbe_ieee_ets) { 658 adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets), 659 GFP_KERNEL); 660 if (!adapter->ixgbe_ieee_ets) 661 return -ENOMEM; 662 } 663 664 memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); 665 666 /* Map TSA onto CEE prio type */ 667 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 668 switch (ets->tc_tsa[i]) { 669 case IEEE_8021QAZ_TSA_STRICT: 670 prio_type[i] = 2; 671 break; 672 case IEEE_8021QAZ_TSA_ETS: 673 prio_type[i] = 0; 674 break; 675 default: 676 /* Hardware only supports priority strict or 677 * ETS transmission selection algorithms if 678 * we receive some other value from dcbnl 679 * throw an error 680 */ 681 return -EINVAL; 682 } 683 } 684 685 if (*p) 686 ixgbe_dcbnl_set_state(dev, 1); 687 else 688 ixgbe_dcbnl_set_state(dev, 0); 689 690 ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame); 691 err = ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max, 692 bwg_id, prio_type, ets->prio_tc); 693 return err; 694} 695 696static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev, 697 struct ieee_pfc *pfc) 698{ 699 struct ixgbe_adapter *adapter = netdev_priv(dev); 700 struct ieee_pfc *my_pfc = adapter->ixgbe_ieee_pfc; 701 int i; 702 703 /* No IEEE PFC settings available */ 704 if (!my_pfc) 705 return -EINVAL; 706 707 pfc->pfc_cap = MAX_TRAFFIC_CLASS; 708 pfc->pfc_en = my_pfc->pfc_en; 709 pfc->mbc = my_pfc->mbc; 710 pfc->delay = my_pfc->delay; 711 712 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 713 pfc->requests[i] = adapter->stats.pxoffrxc[i]; 714 pfc->indications[i] = adapter->stats.pxofftxc[i]; 715 } 716 717 return 0; 718} 719 720static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, 721 struct ieee_pfc *pfc) 722{ 723 struct ixgbe_adapter *adapter = netdev_priv(dev); 724 int err; 725 726 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 727 return -EINVAL; 728 729 if (!adapter->ixgbe_ieee_pfc) { 730 adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), 731 GFP_KERNEL); 732 if (!adapter->ixgbe_ieee_pfc) 733 return -ENOMEM; 734 } 735 736 memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); 737 err = ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en); 738 return err; 739} 740 741static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, 742 struct dcb_app *app) 743{ 744 struct ixgbe_adapter *adapter = netdev_priv(dev); 745 746 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 747 return -EINVAL; 748#ifdef IXGBE_FCOE 749 if (app->selector == 1 && app->protocol == ETH_P_FCOE) { 750 if (adapter->fcoe.tc == app->priority) 751 goto setapp; 752 753 /* In IEEE mode map up to tc 1:1 */ 754 adapter->fcoe.tc = app->priority; 755 adapter->fcoe.up = app->priority; 756 757 /* Force hardware reset required to push FCoE 758 * setup on {tx|rx}_rings 759 */ 760 adapter->dcb_set_bitmap |= BIT_APP_UPCHG; 761 ixgbe_dcbnl_set_all(dev); 762 } 763 764setapp: 765#endif 766 dcb_setapp(dev, app); 767 return 0; 768} 769 770static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev) 771{ 772 struct ixgbe_adapter *adapter = netdev_priv(dev); 773 return adapter->dcbx_cap; 774} 775 776static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode) 777{ 778 struct ixgbe_adapter *adapter = netdev_priv(dev); 779 struct ieee_ets ets = {0}; 780 struct ieee_pfc pfc = {0}; 781 782 /* no support for LLD_MANAGED modes or CEE+IEEE */ 783 if ((mode & DCB_CAP_DCBX_LLD_MANAGED) || 784 ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) || 785 !(mode & DCB_CAP_DCBX_HOST)) 786 return 1; 787 788 if (mode == adapter->dcbx_cap) 789 return 0; 790 791 adapter->dcbx_cap = mode; 792 793 /* ETS and PFC defaults */ 794 ets.ets_cap = 8; 795 pfc.pfc_cap = 8; 796 797 if (mode & DCB_CAP_DCBX_VER_IEEE) { 798 ixgbe_dcbnl_ieee_setets(dev, &ets); 799 ixgbe_dcbnl_ieee_setpfc(dev, &pfc); 800 } else if (mode & DCB_CAP_DCBX_VER_CEE) { 801 adapter->dcb_set_bitmap |= (BIT_PFC & BIT_PG_TX & BIT_PG_RX); 802 ixgbe_dcbnl_set_all(dev); 803 } else { 804 /* Drop into single TC mode strict priority as this 805 * indicates CEE and IEEE versions are disabled 806 */ 807 ixgbe_dcbnl_ieee_setets(dev, &ets); 808 ixgbe_dcbnl_ieee_setpfc(dev, &pfc); 809 ixgbe_dcbnl_set_state(dev, 0); 810 } 811 812 return 0; 813} 814 815const struct dcbnl_rtnl_ops dcbnl_ops = { 816 .ieee_getets = ixgbe_dcbnl_ieee_getets, 817 .ieee_setets = ixgbe_dcbnl_ieee_setets, 818 .ieee_getpfc = ixgbe_dcbnl_ieee_getpfc, 819 .ieee_setpfc = ixgbe_dcbnl_ieee_setpfc, 820 .ieee_setapp = ixgbe_dcbnl_ieee_setapp, 821 .getstate = ixgbe_dcbnl_get_state, 822 .setstate = ixgbe_dcbnl_set_state, 823 .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr, 824 .setpgtccfgtx = ixgbe_dcbnl_set_pg_tc_cfg_tx, 825 .setpgbwgcfgtx = ixgbe_dcbnl_set_pg_bwg_cfg_tx, 826 .setpgtccfgrx = ixgbe_dcbnl_set_pg_tc_cfg_rx, 827 .setpgbwgcfgrx = ixgbe_dcbnl_set_pg_bwg_cfg_rx, 828 .getpgtccfgtx = ixgbe_dcbnl_get_pg_tc_cfg_tx, 829 .getpgbwgcfgtx = ixgbe_dcbnl_get_pg_bwg_cfg_tx, 830 .getpgtccfgrx = ixgbe_dcbnl_get_pg_tc_cfg_rx, 831 .getpgbwgcfgrx = ixgbe_dcbnl_get_pg_bwg_cfg_rx, 832 .setpfccfg = ixgbe_dcbnl_set_pfc_cfg, 833 .getpfccfg = ixgbe_dcbnl_get_pfc_cfg, 834 .setall = ixgbe_dcbnl_set_all, 835 .getcap = ixgbe_dcbnl_getcap, 836 .getnumtcs = ixgbe_dcbnl_getnumtcs, 837 .setnumtcs = ixgbe_dcbnl_setnumtcs, 838 .getpfcstate = ixgbe_dcbnl_getpfcstate, 839 .setpfcstate = ixgbe_dcbnl_setpfcstate, 840 .getapp = ixgbe_dcbnl_getapp, 841 .setapp = ixgbe_dcbnl_setapp, 842 .getdcbx = ixgbe_dcbnl_getdcbx, 843 .setdcbx = ixgbe_dcbnl_setdcbx, 844};