diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_dcb_nl.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_dcb_nl.c | 129 |
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) | |||
448 | static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap) | 449 | static 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 | ||
487 | static u8 ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) | 486 | static 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 | */ |
543 | static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) | 542 | static 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) | |||
571 | static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, | 574 | static 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 | ||
712 | static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev) | ||
713 | { | ||
714 | struct ixgbe_adapter *adapter = netdev_priv(dev); | ||
715 | return adapter->dcbx_cap; | ||
716 | } | ||
717 | |||
718 | static 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 | |||
701 | const struct dcbnl_rtnl_ops dcbnl_ops = { | 757 | const 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 | |||