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