diff options
Diffstat (limited to 'drivers/net/ixgb/ixgb_ethtool.c')
-rw-r--r-- | drivers/net/ixgb/ixgb_ethtool.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index 43994c199991..cc53aa1541ba 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c | |||
@@ -706,6 +706,43 @@ ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data) | |||
706 | } | 706 | } |
707 | } | 707 | } |
708 | 708 | ||
709 | static int ixgb_set_flags(struct net_device *netdev, u32 data) | ||
710 | { | ||
711 | struct ixgb_adapter *adapter = netdev_priv(netdev); | ||
712 | bool need_reset; | ||
713 | int rc; | ||
714 | |||
715 | /* | ||
716 | * Tx VLAN insertion does not work per HW design when Rx stripping is | ||
717 | * disabled. Disable txvlan when rxvlan is turned off, and enable | ||
718 | * rxvlan when txvlan is turned on. | ||
719 | */ | ||
720 | if (!(data & ETH_FLAG_RXVLAN) && | ||
721 | (netdev->features & NETIF_F_HW_VLAN_TX)) | ||
722 | data &= ~ETH_FLAG_TXVLAN; | ||
723 | else if (data & ETH_FLAG_TXVLAN) | ||
724 | data |= ETH_FLAG_RXVLAN; | ||
725 | |||
726 | need_reset = (data & ETH_FLAG_RXVLAN) != | ||
727 | (netdev->features & NETIF_F_HW_VLAN_RX); | ||
728 | |||
729 | rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN | | ||
730 | ETH_FLAG_TXVLAN); | ||
731 | if (rc) | ||
732 | return rc; | ||
733 | |||
734 | if (need_reset) { | ||
735 | if (netif_running(netdev)) { | ||
736 | ixgb_down(adapter, true); | ||
737 | ixgb_up(adapter); | ||
738 | ixgb_set_speed_duplex(netdev); | ||
739 | } else | ||
740 | ixgb_reset(adapter); | ||
741 | } | ||
742 | |||
743 | return 0; | ||
744 | } | ||
745 | |||
709 | static const struct ethtool_ops ixgb_ethtool_ops = { | 746 | static const struct ethtool_ops ixgb_ethtool_ops = { |
710 | .get_settings = ixgb_get_settings, | 747 | .get_settings = ixgb_get_settings, |
711 | .set_settings = ixgb_set_settings, | 748 | .set_settings = ixgb_set_settings, |
@@ -732,6 +769,8 @@ static const struct ethtool_ops ixgb_ethtool_ops = { | |||
732 | .phys_id = ixgb_phys_id, | 769 | .phys_id = ixgb_phys_id, |
733 | .get_sset_count = ixgb_get_sset_count, | 770 | .get_sset_count = ixgb_get_sset_count, |
734 | .get_ethtool_stats = ixgb_get_ethtool_stats, | 771 | .get_ethtool_stats = ixgb_get_ethtool_stats, |
772 | .get_flags = ethtool_op_get_flags, | ||
773 | .set_flags = ixgb_set_flags, | ||
735 | }; | 774 | }; |
736 | 775 | ||
737 | void ixgb_set_ethtool_ops(struct net_device *netdev) | 776 | void ixgb_set_ethtool_ops(struct net_device *netdev) |