diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_ethtool.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 86 |
1 files changed, 47 insertions, 39 deletions
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 2506f9eae58e..f18e3daaf4f5 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
@@ -880,17 +880,23 @@ static int ixgbe_get_coalesce(struct net_device *netdev, | |||
880 | { | 880 | { |
881 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 881 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
882 | 882 | ||
883 | if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS) | ||
884 | ec->rx_coalesce_usecs = adapter->rx_eitr; | ||
885 | else | ||
886 | ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr; | ||
887 | |||
888 | if (adapter->tx_eitr < IXGBE_MIN_ITR_USECS) | ||
889 | ec->tx_coalesce_usecs = adapter->tx_eitr; | ||
890 | else | ||
891 | ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr; | ||
892 | |||
893 | ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0].work_limit; | 883 | ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0].work_limit; |
884 | |||
885 | /* only valid if in constant ITR mode */ | ||
886 | switch (adapter->itr_setting) { | ||
887 | case 0: | ||
888 | /* throttling disabled */ | ||
889 | ec->rx_coalesce_usecs = 0; | ||
890 | break; | ||
891 | case 1: | ||
892 | /* dynamic ITR mode */ | ||
893 | ec->rx_coalesce_usecs = 1; | ||
894 | break; | ||
895 | default: | ||
896 | /* fixed interrupt rate mode */ | ||
897 | ec->rx_coalesce_usecs = 1000000/adapter->eitr_param; | ||
898 | break; | ||
899 | } | ||
894 | return 0; | 900 | return 0; |
895 | } | 901 | } |
896 | 902 | ||
@@ -898,38 +904,40 @@ static int ixgbe_set_coalesce(struct net_device *netdev, | |||
898 | struct ethtool_coalesce *ec) | 904 | struct ethtool_coalesce *ec) |
899 | { | 905 | { |
900 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 906 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
901 | 907 | struct ixgbe_hw *hw = &adapter->hw; | |
902 | if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || | 908 | int i; |
903 | ((ec->rx_coalesce_usecs != 0) && | ||
904 | (ec->rx_coalesce_usecs != 1) && | ||
905 | (ec->rx_coalesce_usecs != 3) && | ||
906 | (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) | ||
907 | return -EINVAL; | ||
908 | if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || | ||
909 | ((ec->tx_coalesce_usecs != 0) && | ||
910 | (ec->tx_coalesce_usecs != 1) && | ||
911 | (ec->tx_coalesce_usecs != 3) && | ||
912 | (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) | ||
913 | return -EINVAL; | ||
914 | |||
915 | /* convert to rate of irq's per second */ | ||
916 | if (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS) | ||
917 | adapter->rx_eitr = ec->rx_coalesce_usecs; | ||
918 | else | ||
919 | adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs); | ||
920 | |||
921 | if (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS) | ||
922 | adapter->tx_eitr = ec->rx_coalesce_usecs; | ||
923 | else | ||
924 | adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs); | ||
925 | 909 | ||
926 | if (ec->tx_max_coalesced_frames_irq) | 910 | if (ec->tx_max_coalesced_frames_irq) |
927 | adapter->tx_ring[0].work_limit = | 911 | adapter->tx_ring[0].work_limit = ec->tx_max_coalesced_frames_irq; |
928 | ec->tx_max_coalesced_frames_irq; | 912 | |
913 | if (ec->rx_coalesce_usecs > 1) { | ||
914 | /* store the value in ints/second */ | ||
915 | adapter->eitr_param = 1000000/ec->rx_coalesce_usecs; | ||
916 | |||
917 | /* static value of interrupt rate */ | ||
918 | adapter->itr_setting = adapter->eitr_param; | ||
919 | /* clear the lower bit */ | ||
920 | adapter->itr_setting &= ~1; | ||
921 | } else if (ec->rx_coalesce_usecs == 1) { | ||
922 | /* 1 means dynamic mode */ | ||
923 | adapter->eitr_param = 20000; | ||
924 | adapter->itr_setting = 1; | ||
925 | } else { | ||
926 | /* any other value means disable eitr, which is best | ||
927 | * served by setting the interrupt rate very high */ | ||
928 | adapter->eitr_param = 3000000; | ||
929 | adapter->itr_setting = 0; | ||
930 | } | ||
929 | 931 | ||
930 | if (netif_running(netdev)) { | 932 | for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { |
931 | ixgbe_down(adapter); | 933 | struct ixgbe_q_vector *q_vector = &adapter->q_vector[i]; |
932 | ixgbe_up(adapter); | 934 | if (q_vector->txr_count && !q_vector->rxr_count) |
935 | q_vector->eitr = (adapter->eitr_param >> 1); | ||
936 | else | ||
937 | /* rx only or mixed */ | ||
938 | q_vector->eitr = adapter->eitr_param; | ||
939 | IXGBE_WRITE_REG(hw, IXGBE_EITR(i), | ||
940 | EITR_INTS_PER_SEC_TO_REG(q_vector->eitr)); | ||
933 | } | 941 | } |
934 | 942 | ||
935 | return 0; | 943 | return 0; |