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.c129
1 files changed, 93 insertions, 36 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index d7f0024014b1..d7c456f685ff 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -346,7 +346,8 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
346 struct ixgbe_adapter *adapter = netdev_priv(netdev); 346 struct ixgbe_adapter *adapter = netdev_priv(netdev);
347 int ret; 347 int ret;
348 348
349 if (!adapter->dcb_set_bitmap) 349 if (!adapter->dcb_set_bitmap ||
350 !(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
350 return DCB_NO_HW_CHG; 351 return DCB_NO_HW_CHG;
351 352
352 ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, 353 ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
@@ -448,40 +449,38 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
448static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap) 449static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap)
449{ 450{
450 struct ixgbe_adapter *adapter = netdev_priv(netdev); 451 struct ixgbe_adapter *adapter = netdev_priv(netdev);
451 u8 rval = 0;
452 452
453 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { 453 switch (capid) {
454 switch (capid) { 454 case DCB_CAP_ATTR_PG:
455 case DCB_CAP_ATTR_PG: 455 *cap = true;
456 *cap = true; 456 break;
457 break; 457 case DCB_CAP_ATTR_PFC:
458 case DCB_CAP_ATTR_PFC: 458 *cap = true;
459 *cap = true; 459 break;
460 break; 460 case DCB_CAP_ATTR_UP2TC:
461 case DCB_CAP_ATTR_UP2TC: 461 *cap = false;
462 *cap = false; 462 break;
463 break; 463 case DCB_CAP_ATTR_PG_TCS:
464 case DCB_CAP_ATTR_PG_TCS: 464 *cap = 0x80;
465 *cap = 0x80; 465 break;
466 break; 466 case DCB_CAP_ATTR_PFC_TCS:
467 case DCB_CAP_ATTR_PFC_TCS: 467 *cap = 0x80;
468 *cap = 0x80; 468 break;
469 break; 469 case DCB_CAP_ATTR_GSP:
470 case DCB_CAP_ATTR_GSP: 470 *cap = true;
471 *cap = true; 471 break;
472 break; 472 case DCB_CAP_ATTR_BCN:
473 case DCB_CAP_ATTR_BCN: 473 *cap = false;
474 *cap = false; 474 break;
475 break; 475 case DCB_CAP_ATTR_DCBX:
476 default: 476 *cap = adapter->dcbx_cap;
477 rval = -EINVAL; 477 break;
478 break; 478 default:
479 } 479 *cap = false;
480 } else { 480 break;
481 rval = -EINVAL;
482 } 481 }
483 482
484 return rval; 483 return 0;
485} 484}
486 485
487static u8 ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) 486static u8 ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
@@ -542,13 +541,17 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
542 */ 541 */
543static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) 542static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
544{ 543{
544 struct ixgbe_adapter *adapter = netdev_priv(netdev);
545 u8 rval = 0; 545 u8 rval = 0;
546 546
547 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
548 return rval;
549
547 switch (idtype) { 550 switch (idtype) {
548 case DCB_APP_IDTYPE_ETHTYPE: 551 case DCB_APP_IDTYPE_ETHTYPE:
549#ifdef IXGBE_FCOE 552#ifdef IXGBE_FCOE
550 if (id == ETH_P_FCOE) 553 if (id == ETH_P_FCOE)
551 rval = ixgbe_fcoe_getapp(netdev_priv(netdev)); 554 rval = ixgbe_fcoe_getapp(adapter);
552#endif 555#endif
553 break; 556 break;
554 case DCB_APP_IDTYPE_PORTNUM: 557 case DCB_APP_IDTYPE_PORTNUM:
@@ -571,14 +574,17 @@ static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
571static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, 574static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
572 u8 idtype, u16 id, u8 up) 575 u8 idtype, u16 id, u8 up)
573{ 576{
577 struct ixgbe_adapter *adapter = netdev_priv(netdev);
574 u8 rval = 1; 578 u8 rval = 1;
575 579
580 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
581 return rval;
582
576 switch (idtype) { 583 switch (idtype) {
577 case DCB_APP_IDTYPE_ETHTYPE: 584 case DCB_APP_IDTYPE_ETHTYPE:
578#ifdef IXGBE_FCOE 585#ifdef IXGBE_FCOE
579 if (id == ETH_P_FCOE) { 586 if (id == ETH_P_FCOE) {
580 u8 old_tc; 587 u8 old_tc;
581 struct ixgbe_adapter *adapter = netdev_priv(netdev);
582 588
583 /* Get current programmed tc */ 589 /* Get current programmed tc */
584 old_tc = adapter->fcoe.tc; 590 old_tc = adapter->fcoe.tc;
@@ -640,6 +646,9 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
640 /* naively give each TC a bwg to map onto CEE hardware */ 646 /* naively give each TC a bwg to map onto CEE hardware */
641 __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7}; 647 __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7};
642 648
649 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
650 return -EINVAL;
651
643 if (!adapter->ixgbe_ieee_ets) { 652 if (!adapter->ixgbe_ieee_ets) {
644 adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets), 653 adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets),
645 GFP_KERNEL); 654 GFP_KERNEL);
@@ -647,7 +656,6 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
647 return -ENOMEM; 656 return -ENOMEM;
648 } 657 }
649 658
650
651 memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); 659 memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets));
652 660
653 ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame); 661 ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame);
@@ -686,6 +694,9 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
686 struct ixgbe_adapter *adapter = netdev_priv(dev); 694 struct ixgbe_adapter *adapter = netdev_priv(dev);
687 int err; 695 int err;
688 696
697 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
698 return -EINVAL;
699
689 if (!adapter->ixgbe_ieee_pfc) { 700 if (!adapter->ixgbe_ieee_pfc) {
690 adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), 701 adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc),
691 GFP_KERNEL); 702 GFP_KERNEL);
@@ -698,6 +709,51 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
698 return err; 709 return err;
699} 710}
700 711
712static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev)
713{
714 struct ixgbe_adapter *adapter = netdev_priv(dev);
715 return adapter->dcbx_cap;
716}
717
718static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode)
719{
720 struct ixgbe_adapter *adapter = netdev_priv(dev);
721 struct ieee_ets ets = {0};
722 struct ieee_pfc pfc = {0};
723
724 /* no support for LLD_MANAGED modes or CEE+IEEE */
725 if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
726 ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) ||
727 !(mode & DCB_CAP_DCBX_HOST))
728 return 1;
729
730 if (mode == adapter->dcbx_cap)
731 return 0;
732
733 adapter->dcbx_cap = mode;
734
735 /* ETS and PFC defaults */
736 ets.ets_cap = 8;
737 pfc.pfc_cap = 8;
738
739 if (mode & DCB_CAP_DCBX_VER_IEEE) {
740 ixgbe_dcbnl_ieee_setets(dev, &ets);
741 ixgbe_dcbnl_ieee_setpfc(dev, &pfc);
742 } else if (mode & DCB_CAP_DCBX_VER_CEE) {
743 adapter->dcb_set_bitmap |= (BIT_PFC & BIT_PG_TX & BIT_PG_RX);
744 ixgbe_dcbnl_set_all(dev);
745 } else {
746 /* Drop into single TC mode strict priority as this
747 * indicates CEE and IEEE versions are disabled
748 */
749 ixgbe_dcbnl_ieee_setets(dev, &ets);
750 ixgbe_dcbnl_ieee_setpfc(dev, &pfc);
751 ixgbe_dcbnl_set_state(dev, 0);
752 }
753
754 return 0;
755}
756
701const struct dcbnl_rtnl_ops dcbnl_ops = { 757const struct dcbnl_rtnl_ops dcbnl_ops = {
702 .ieee_getets = ixgbe_dcbnl_ieee_getets, 758 .ieee_getets = ixgbe_dcbnl_ieee_getets,
703 .ieee_setets = ixgbe_dcbnl_ieee_setets, 759 .ieee_setets = ixgbe_dcbnl_ieee_setets,
@@ -724,5 +780,6 @@ const struct dcbnl_rtnl_ops dcbnl_ops = {
724 .setpfcstate = ixgbe_dcbnl_setpfcstate, 780 .setpfcstate = ixgbe_dcbnl_setpfcstate,
725 .getapp = ixgbe_dcbnl_getapp, 781 .getapp = ixgbe_dcbnl_getapp,
726 .setapp = ixgbe_dcbnl_setapp, 782 .setapp = ixgbe_dcbnl_setapp,
783 .getdcbx = ixgbe_dcbnl_getdcbx,
784 .setdcbx = ixgbe_dcbnl_setdcbx,
727}; 785};
728