ixgbe: disable RSC when Rx checksum is off
authorEmil Tantilov <emil.s.tantilov@intel.com>
Fri, 13 May 2011 02:22:50 +0000 (02:22 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 24 Jun 2011 05:46:21 +0000 (22:46 -0700)
Disabling Rx checksumming leads to performance degradation due to
RSC causing packets to have incorrect checksums.

Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Evan Swanson <evan.swanson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ixgbe/ixgbe_ethtool.c

index bb8441e3990cdfd90b29625ae5ed464468da200e..596d7943024fa20a685a7c80fc1f0510f99ac7c0 100644 (file)
@@ -458,17 +458,6 @@ static u32 ixgbe_get_rx_csum(struct net_device *netdev)
        return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED;
 }
 
-static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data)
-{
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
-       if (data)
-               adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
-       else
-               adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
-
-       return 0;
-}
-
 static void ixgbe_set_rsc(struct ixgbe_adapter *adapter)
 {
        int i;
@@ -484,6 +473,39 @@ static void ixgbe_set_rsc(struct ixgbe_adapter *adapter)
        }
 }
 
+static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data)
+{
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       bool need_reset = false;
+
+       if (data) {
+               adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
+       } else {
+               adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
+
+               if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) {
+                       adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
+                       netdev->features &= ~NETIF_F_LRO;
+               }
+
+               switch (adapter->hw.mac.type) {
+               case ixgbe_mac_X540:
+                       ixgbe_set_rsc(adapter);
+                       break;
+               case ixgbe_mac_82599EB:
+                       need_reset = true;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if (need_reset)
+               ixgbe_do_reset(netdev);
+
+       return 0;
+}
+
 static u32 ixgbe_get_tx_csum(struct net_device *netdev)
 {
        return (netdev->features & NETIF_F_IP_CSUM) != 0;