qlcnic: turn off lro when rxcsum is disabled.
authorSucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Tue, 17 Aug 2010 00:34:25 +0000 (00:34 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 17 Aug 2010 10:59:49 +0000 (03:59 -0700)
o Also dont allow lro to be turn on, if rx csum is disabled

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/qlcnic/qlcnic.h
drivers/net/qlcnic/qlcnic_ethtool.c
drivers/net/qlcnic/qlcnic_main.c

index 7f4e11b..f6b887d 100644 (file)
@@ -894,6 +894,7 @@ struct qlcnic_mac_req {
 #define QLCNIC_MSI_ENABLED             0x02
 #define QLCNIC_MSIX_ENABLED            0x04
 #define QLCNIC_LRO_ENABLED             0x08
+#define QLCNIC_LRO_DISABLED            0x00
 #define QLCNIC_BRIDGE_ENABLED          0X10
 #define QLCNIC_DIAG_ENABLED            0x20
 #define QLCNIC_ESWITCH_ENABLED         0x40
index 3d4655d..e38fc3d 100644 (file)
@@ -818,7 +818,21 @@ static u32 qlcnic_get_rx_csum(struct net_device *dev)
 static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
 {
        struct qlcnic_adapter *adapter = netdev_priv(dev);
+
+       if (!!data) {
+               adapter->rx_csum = !!data;
+               return 0;
+       }
+
+       if (adapter->flags & QLCNIC_LRO_ENABLED) {
+               if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED))
+                       return -EIO;
+
+               dev->features &= ~NETIF_F_LRO;
+               qlcnic_send_lro_cleanup(adapter);
+       }
        adapter->rx_csum = !!data;
+       dev_info(&adapter->pdev->dev, "disabling LRO as rx_csum is off\n");
        return 0;
 }
 
@@ -1001,6 +1015,15 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data)
        if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
                return -EINVAL;
 
+       if (!adapter->rx_csum) {
+               dev_info(&adapter->pdev->dev, "rx csum is off, "
+                       "cannot toggle lro\n");
+               return -EINVAL;
+       }
+
+       if ((data & ETH_FLAG_LRO) && (adapter->flags & QLCNIC_LRO_ENABLED))
+               return 0;
+
        if (data & ETH_FLAG_LRO) {
                hw_lro = QLCNIC_LRO_ENABLED;
                netdev->features |= NETIF_F_LRO;
index bf4077a..abd7cd6 100644 (file)
@@ -995,7 +995,7 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
 
        qlcnic_config_intr_coalesce(adapter);
 
-       if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
+       if (netdev->features & NETIF_F_LRO)
                qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED);
 
        qlcnic_napi_enable(adapter);