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