aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_dcb_nl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_dcb_nl.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c429
1 files changed, 328 insertions, 101 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index bf566e8a455..fec4c724c37 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -1,7 +1,7 @@
1/******************************************************************************* 1/*******************************************************************************
2 2
3 Intel 10 Gigabit PCI Express Linux driver 3 Intel 10 Gigabit PCI Express Linux driver
4 Copyright(c) 1999 - 2010 Intel Corporation. 4 Copyright(c) 1999 - 2011 Intel Corporation.
5 5
6 This program is free software; you can redistribute it and/or modify it 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, 7 under the terms and conditions of the GNU General Public License,
@@ -37,7 +37,6 @@
37#define BIT_PG_RX 0x04 37#define BIT_PG_RX 0x04
38#define BIT_PG_TX 0x08 38#define BIT_PG_TX 0x08
39#define BIT_APP_UPCHG 0x10 39#define BIT_APP_UPCHG 0x10
40#define BIT_RESETLINK 0x40
41#define BIT_LINKSPEED 0x80 40#define BIT_LINKSPEED 0x80
42 41
43/* Responses for the DCB_C_SET_ALL command */ 42/* Responses for the DCB_C_SET_ALL command */
@@ -130,7 +129,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
130 netdev->netdev_ops->ndo_stop(netdev); 129 netdev->netdev_ops->ndo_stop(netdev);
131 ixgbe_clear_interrupt_scheme(adapter); 130 ixgbe_clear_interrupt_scheme(adapter);
132 131
133 adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
134 switch (adapter->hw.mac.type) { 132 switch (adapter->hw.mac.type) {
135 case ixgbe_mac_82598EB: 133 case ixgbe_mac_82598EB:
136 adapter->last_lfc_mode = adapter->hw.fc.current_mode; 134 adapter->last_lfc_mode = adapter->hw.fc.current_mode;
@@ -146,6 +144,9 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
146 } 144 }
147 145
148 adapter->flags |= IXGBE_FLAG_DCB_ENABLED; 146 adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
147 if (!netdev_get_num_tc(netdev))
148 ixgbe_setup_tc(netdev, MAX_TRAFFIC_CLASS);
149
149 ixgbe_init_interrupt_scheme(adapter); 150 ixgbe_init_interrupt_scheme(adapter);
150 if (netif_running(netdev)) 151 if (netif_running(netdev))
151 netdev->netdev_ops->ndo_open(netdev); 152 netdev->netdev_ops->ndo_open(netdev);
@@ -160,7 +161,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
160 adapter->temp_dcb_cfg.pfc_mode_enable = false; 161 adapter->temp_dcb_cfg.pfc_mode_enable = false;
161 adapter->dcb_cfg.pfc_mode_enable = false; 162 adapter->dcb_cfg.pfc_mode_enable = false;
162 adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; 163 adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
163 adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
164 switch (adapter->hw.mac.type) { 164 switch (adapter->hw.mac.type) {
165 case ixgbe_mac_82599EB: 165 case ixgbe_mac_82599EB:
166 case ixgbe_mac_X540: 166 case ixgbe_mac_X540:
@@ -170,6 +170,8 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
170 break; 170 break;
171 } 171 }
172 172
173 ixgbe_setup_tc(netdev, 0);
174
173 ixgbe_init_interrupt_scheme(adapter); 175 ixgbe_init_interrupt_scheme(adapter);
174 if (netif_running(netdev)) 176 if (netif_running(netdev))
175 netdev->netdev_ops->ndo_open(netdev); 177 netdev->netdev_ops->ndo_open(netdev);
@@ -225,10 +227,8 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
225 (adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent != 227 (adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent !=
226 adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent) || 228 adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent) ||
227 (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap != 229 (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap !=
228 adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) { 230 adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap))
229 adapter->dcb_set_bitmap |= BIT_PG_TX; 231 adapter->dcb_set_bitmap |= BIT_PG_TX;
230 adapter->dcb_set_bitmap |= BIT_RESETLINK;
231 }
232} 232}
233 233
234static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, 234static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
@@ -239,10 +239,8 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
239 adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct; 239 adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct;
240 240
241 if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] != 241 if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] !=
242 adapter->dcb_cfg.bw_percentage[0][bwg_id]) { 242 adapter->dcb_cfg.bw_percentage[0][bwg_id])
243 adapter->dcb_set_bitmap |= BIT_PG_TX; 243 adapter->dcb_set_bitmap |= BIT_PG_TX;
244 adapter->dcb_set_bitmap |= BIT_RESETLINK;
245 }
246} 244}
247 245
248static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, 246static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
@@ -269,10 +267,8 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
269 (adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent != 267 (adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent !=
270 adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent) || 268 adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent) ||
271 (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap != 269 (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap !=
272 adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) { 270 adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap))
273 adapter->dcb_set_bitmap |= BIT_PG_RX; 271 adapter->dcb_set_bitmap |= BIT_PG_RX;
274 adapter->dcb_set_bitmap |= BIT_RESETLINK;
275 }
276} 272}
277 273
278static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, 274static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
@@ -283,10 +279,8 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
283 adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct; 279 adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct;
284 280
285 if (adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] != 281 if (adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] !=
286 adapter->dcb_cfg.bw_percentage[1][bwg_id]) { 282 adapter->dcb_cfg.bw_percentage[1][bwg_id])
287 adapter->dcb_set_bitmap |= BIT_PG_RX; 283 adapter->dcb_set_bitmap |= BIT_PG_RX;
288 adapter->dcb_set_bitmap |= BIT_RESETLINK;
289 }
290} 284}
291 285
292static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, 286static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc,
@@ -355,31 +349,28 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
355 struct ixgbe_adapter *adapter = netdev_priv(netdev); 349 struct ixgbe_adapter *adapter = netdev_priv(netdev);
356 int ret; 350 int ret;
357 351
358 if (!adapter->dcb_set_bitmap) 352 if (!adapter->dcb_set_bitmap ||
353 !(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
359 return DCB_NO_HW_CHG; 354 return DCB_NO_HW_CHG;
360 355
361 ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, 356 ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
362 adapter->ring_feature[RING_F_DCB].indices); 357 MAX_TRAFFIC_CLASS);
363 358
364 if (ret) 359 if (ret)
365 return DCB_NO_HW_CHG; 360 return DCB_NO_HW_CHG;
366 361
367 /* 362 /*
368 * Only take down the adapter if the configuration change 363 * Only take down the adapter if an app change occured. FCoE
369 * requires a reset. 364 * may shuffle tx rings in this case and this can not be done
365 * without a reset currently.
370 */ 366 */
371 if (adapter->dcb_set_bitmap & BIT_RESETLINK) { 367 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
372 while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) 368 while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
373 msleep(1); 369 msleep(1);
374 370
375 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { 371 if (netif_running(netdev))
376 if (netif_running(netdev)) 372 netdev->netdev_ops->ndo_stop(netdev);
377 netdev->netdev_ops->ndo_stop(netdev); 373 ixgbe_clear_interrupt_scheme(adapter);
378 ixgbe_clear_interrupt_scheme(adapter);
379 } else {
380 if (netif_running(netdev))
381 ixgbe_down(adapter);
382 }
383 } 374 }
384 375
385 if (adapter->dcb_cfg.pfc_mode_enable) { 376 if (adapter->dcb_cfg.pfc_mode_enable) {
@@ -408,29 +399,53 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
408 } 399 }
409 } 400 }
410 401
411 if (adapter->dcb_set_bitmap & BIT_RESETLINK) { 402 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
412 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { 403 ixgbe_init_interrupt_scheme(adapter);
413 ixgbe_init_interrupt_scheme(adapter); 404 if (netif_running(netdev))
414 if (netif_running(netdev)) 405 netdev->netdev_ops->ndo_open(netdev);
415 netdev->netdev_ops->ndo_open(netdev);
416 } else {
417 if (netif_running(netdev))
418 ixgbe_up(adapter);
419 }
420 ret = DCB_HW_CHG_RST; 406 ret = DCB_HW_CHG_RST;
421 } else if (adapter->dcb_set_bitmap & BIT_PFC) { 407 }
422 if (adapter->hw.mac.type == ixgbe_mac_82598EB) 408
423 ixgbe_dcb_config_pfc_82598(&adapter->hw, 409 if (adapter->dcb_set_bitmap & BIT_PFC) {
424 &adapter->dcb_cfg); 410 u8 pfc_en;
425 else if (adapter->hw.mac.type == ixgbe_mac_82599EB) 411 ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en);
426 ixgbe_dcb_config_pfc_82599(&adapter->hw, 412 ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc_en);
427 &adapter->dcb_cfg);
428 ret = DCB_HW_CHG; 413 ret = DCB_HW_CHG;
429 } 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
430 if (adapter->dcb_cfg.pfc_mode_enable) 445 if (adapter->dcb_cfg.pfc_mode_enable)
431 adapter->hw.fc.current_mode = ixgbe_fc_pfc; 446 adapter->hw.fc.current_mode = ixgbe_fc_pfc;
432 447
433 if (adapter->dcb_set_bitmap & BIT_RESETLINK) 448 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG)
434 clear_bit(__IXGBE_RESETTING, &adapter->state); 449 clear_bit(__IXGBE_RESETTING, &adapter->state);
435 adapter->dcb_set_bitmap = 0x00; 450 adapter->dcb_set_bitmap = 0x00;
436 return ret; 451 return ret;
@@ -439,40 +454,38 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
439static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap) 454static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap)
440{ 455{
441 struct ixgbe_adapter *adapter = netdev_priv(netdev); 456 struct ixgbe_adapter *adapter = netdev_priv(netdev);
442 u8 rval = 0;
443 457
444 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { 458 switch (capid) {
445 switch (capid) { 459 case DCB_CAP_ATTR_PG:
446 case DCB_CAP_ATTR_PG: 460 *cap = true;
447 *cap = true; 461 break;
448 break; 462 case DCB_CAP_ATTR_PFC:
449 case DCB_CAP_ATTR_PFC: 463 *cap = true;
450 *cap = true; 464 break;
451 break; 465 case DCB_CAP_ATTR_UP2TC:
452 case DCB_CAP_ATTR_UP2TC: 466 *cap = false;
453 *cap = false; 467 break;
454 break; 468 case DCB_CAP_ATTR_PG_TCS:
455 case DCB_CAP_ATTR_PG_TCS: 469 *cap = 0x80;
456 *cap = 0x80; 470 break;
457 break; 471 case DCB_CAP_ATTR_PFC_TCS:
458 case DCB_CAP_ATTR_PFC_TCS: 472 *cap = 0x80;
459 *cap = 0x80; 473 break;
460 break; 474 case DCB_CAP_ATTR_GSP:
461 case DCB_CAP_ATTR_GSP: 475 *cap = true;
462 *cap = true; 476 break;
463 break; 477 case DCB_CAP_ATTR_BCN:
464 case DCB_CAP_ATTR_BCN: 478 *cap = false;
465 *cap = false; 479 break;
466 break; 480 case DCB_CAP_ATTR_DCBX:
467 default: 481 *cap = adapter->dcbx_cap;
468 rval = -EINVAL; 482 break;
469 break; 483 default:
470 } 484 *cap = false;
471 } else { 485 break;
472 rval = -EINVAL;
473 } 486 }
474 487
475 return rval; 488 return 0;
476} 489}
477 490
478static u8 ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) 491static u8 ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
@@ -533,21 +546,16 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
533 */ 546 */
534static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) 547static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
535{ 548{
536 u8 rval = 0; 549 struct ixgbe_adapter *adapter = netdev_priv(netdev);
550 struct dcb_app app = {
551 .selector = idtype,
552 .protocol = id,
553 };
537 554
538 switch (idtype) { 555 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
539 case DCB_APP_IDTYPE_ETHTYPE: 556 return 0;
540#ifdef IXGBE_FCOE 557
541 if (id == ETH_P_FCOE) 558 return dcb_getapp(netdev, &app);
542 rval = ixgbe_fcoe_getapp(netdev_priv(netdev));
543#endif
544 break;
545 case DCB_APP_IDTYPE_PORTNUM:
546 break;
547 default:
548 break;
549 }
550 return rval;
551} 559}
552 560
553/** 561/**
@@ -562,24 +570,45 @@ static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
562static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, 570static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
563 u8 idtype, u16 id, u8 up) 571 u8 idtype, u16 id, u8 up)
564{ 572{
573 struct ixgbe_adapter *adapter = netdev_priv(netdev);
565 u8 rval = 1; 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);
566 585
567 switch (idtype) { 586 switch (idtype) {
568 case DCB_APP_IDTYPE_ETHTYPE: 587 case DCB_APP_IDTYPE_ETHTYPE:
569#ifdef IXGBE_FCOE 588#ifdef IXGBE_FCOE
570 if (id == ETH_P_FCOE) { 589 if (id == ETH_P_FCOE) {
571 u8 tc; 590 u8 old_tc;
572 struct ixgbe_adapter *adapter;
573 591
574 adapter = netdev_priv(netdev); 592 /* Get current programmed tc */
575 tc = adapter->fcoe.tc; 593 old_tc = adapter->fcoe.tc;
576 rval = ixgbe_fcoe_setapp(adapter, up); 594 rval = ixgbe_fcoe_setapp(adapter, up);
577 if ((!rval) && (tc != adapter->fcoe.tc) && 595
578 (adapter->flags & IXGBE_FLAG_DCB_ENABLED) && 596 if (rval ||
579 (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) { 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 sucession 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
580 adapter->dcb_set_bitmap |= BIT_APP_UPCHG; 611 adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
581 adapter->dcb_set_bitmap |= BIT_RESETLINK;
582 }
583 } 612 }
584#endif 613#endif
585 break; 614 break;
@@ -591,7 +620,204 @@ static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
591 return rval; 620 return rval;
592} 621}
593 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
594const struct dcbnl_rtnl_ops dcbnl_ops = { 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,
595 .getstate = ixgbe_dcbnl_get_state, 821 .getstate = ixgbe_dcbnl_get_state,
596 .setstate = ixgbe_dcbnl_set_state, 822 .setstate = ixgbe_dcbnl_set_state,
597 .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr, 823 .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr,
@@ -613,5 +839,6 @@ const struct dcbnl_rtnl_ops dcbnl_ops = {
613 .setpfcstate = ixgbe_dcbnl_setpfcstate, 839 .setpfcstate = ixgbe_dcbnl_setpfcstate,
614 .getapp = ixgbe_dcbnl_getapp, 840 .getapp = ixgbe_dcbnl_getapp,
615 .setapp = ixgbe_dcbnl_setapp, 841 .setapp = ixgbe_dcbnl_setapp,
842 .getdcbx = ixgbe_dcbnl_getdcbx,
843 .setdcbx = ixgbe_dcbnl_setdcbx,
616}; 844};
617