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