diff options
author | John Fastabend <john.r.fastabend@intel.com> | 2011-02-10 09:40:01 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-02-11 11:47:15 -0500 |
commit | d033d526a465c4bb8a499a0b5df65b3e7cf4da6f (patch) | |
tree | 570fba34e3fe39dd158dbf38296ca486298b2548 /drivers/net/ixgbe/ixgbe_dcb_nl.c | |
parent | 55320cb58baebd1795ec92f4550a1e8b38bf9ddf (diff) |
ixgbe: DCB, implement 802.1Qaz routines
Implements 802.1Qaz support for ixgbe driver. Additionally,
this adds IEEE_8021QAZ_TSA_{} defines to dcbnl.h this is to
avoid having to use cryptic numeric codes for the TSA type.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_dcb_nl.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_dcb_nl.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 6ab1f1abaa01..e75a3c91198d 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c | |||
@@ -606,7 +606,98 @@ static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, | |||
606 | return rval; | 606 | return rval; |
607 | } | 607 | } |
608 | 608 | ||
609 | static int ixgbe_dcbnl_ieee_getets(struct net_device *dev, | ||
610 | struct ieee_ets *ets) | ||
611 | { | ||
612 | struct ixgbe_adapter *adapter = netdev_priv(dev); | ||
613 | struct ieee_ets *my_ets = adapter->ixgbe_ieee_ets; | ||
614 | |||
615 | /* No IEEE PFC settings available */ | ||
616 | if (!my_ets) | ||
617 | return -EINVAL; | ||
618 | |||
619 | ets->ets_cap = MAX_TRAFFIC_CLASS; | ||
620 | ets->cbs = my_ets->cbs; | ||
621 | memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw)); | ||
622 | memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw)); | ||
623 | memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa)); | ||
624 | memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc)); | ||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, | ||
629 | struct ieee_ets *ets) | ||
630 | { | ||
631 | struct ixgbe_adapter *adapter = netdev_priv(dev); | ||
632 | __u16 refill[IEEE_8021QAZ_MAX_TCS], max[IEEE_8021QAZ_MAX_TCS]; | ||
633 | int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; | ||
634 | int err; | ||
635 | /* naively give each TC a bwg to map onto CEE hardware */ | ||
636 | __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7}; | ||
637 | |||
638 | if (!adapter->ixgbe_ieee_ets) { | ||
639 | adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets), | ||
640 | GFP_KERNEL); | ||
641 | if (!adapter->ixgbe_ieee_ets) | ||
642 | return -ENOMEM; | ||
643 | } | ||
644 | |||
645 | |||
646 | memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); | ||
647 | |||
648 | ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame); | ||
649 | err = ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max, | ||
650 | bwg_id, ets->tc_tsa); | ||
651 | return err; | ||
652 | } | ||
653 | |||
654 | static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev, | ||
655 | struct ieee_pfc *pfc) | ||
656 | { | ||
657 | struct ixgbe_adapter *adapter = netdev_priv(dev); | ||
658 | struct ieee_pfc *my_pfc = adapter->ixgbe_ieee_pfc; | ||
659 | int i; | ||
660 | |||
661 | /* No IEEE PFC settings available */ | ||
662 | if (!my_pfc) | ||
663 | return -EINVAL; | ||
664 | |||
665 | pfc->pfc_cap = MAX_TRAFFIC_CLASS; | ||
666 | pfc->pfc_en = my_pfc->pfc_en; | ||
667 | pfc->mbc = my_pfc->mbc; | ||
668 | pfc->delay = my_pfc->delay; | ||
669 | |||
670 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||
671 | pfc->requests[i] = adapter->stats.pxoffrxc[i]; | ||
672 | pfc->indications[i] = adapter->stats.pxofftxc[i]; | ||
673 | } | ||
674 | |||
675 | return 0; | ||
676 | } | ||
677 | |||
678 | static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, | ||
679 | struct ieee_pfc *pfc) | ||
680 | { | ||
681 | struct ixgbe_adapter *adapter = netdev_priv(dev); | ||
682 | int err; | ||
683 | |||
684 | if (!adapter->ixgbe_ieee_pfc) { | ||
685 | adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), | ||
686 | GFP_KERNEL); | ||
687 | if (!adapter->ixgbe_ieee_pfc) | ||
688 | return -ENOMEM; | ||
689 | } | ||
690 | |||
691 | memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); | ||
692 | err = ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en); | ||
693 | return err; | ||
694 | } | ||
695 | |||
609 | const struct dcbnl_rtnl_ops dcbnl_ops = { | 696 | const struct dcbnl_rtnl_ops dcbnl_ops = { |
697 | .ieee_getets = ixgbe_dcbnl_ieee_getets, | ||
698 | .ieee_setets = ixgbe_dcbnl_ieee_setets, | ||
699 | .ieee_getpfc = ixgbe_dcbnl_ieee_getpfc, | ||
700 | .ieee_setpfc = ixgbe_dcbnl_ieee_setpfc, | ||
610 | .getstate = ixgbe_dcbnl_get_state, | 701 | .getstate = ixgbe_dcbnl_get_state, |
611 | .setstate = ixgbe_dcbnl_set_state, | 702 | .setstate = ixgbe_dcbnl_set_state, |
612 | .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr, | 703 | .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr, |