]> Pileus Git - ~andy/linux/blobdiff - drivers/net/netxen/netxen_nic_ethtool.c
Merge branch 'x86-apic-cleanups-for-linus' of git://git.kernel.org/pub/scm/linux...
[~andy/linux] / drivers / net / netxen / netxen_nic_ethtool.c
index 20f7c58bd0920fefe38d5bc9fb4cc58892d9a526..587498e140bb85e746eb1882e47141fd918539d6 100644 (file)
@@ -720,7 +720,21 @@ static u32 netxen_nic_get_rx_csum(struct net_device *dev)
 static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data)
 {
        struct netxen_adapter *adapter = netdev_priv(dev);
-       adapter->rx_csum = !!data;
+
+       if (data) {
+               adapter->rx_csum = data;
+               return 0;
+       }
+
+       if (dev->features & NETIF_F_LRO) {
+               if (netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_DISABLED))
+                       return -EIO;
+
+               dev->features &= ~NETIF_F_LRO;
+               netxen_send_lro_cleanup(adapter);
+               netdev_info(dev, "disabling LRO as rx_csum is off\n");
+       }
+       adapter->rx_csum = data;
        return 0;
 }
 
@@ -887,12 +901,27 @@ static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
        struct netxen_adapter *adapter = netdev_priv(netdev);
        int hw_lro;
 
+       if (data & ~ETH_FLAG_LRO)
+               return -EINVAL;
+
        if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
                return -EINVAL;
 
-       ethtool_op_set_flags(netdev, data);
+       if (!adapter->rx_csum) {
+               netdev_info(netdev, "rx csum is off, cannot toggle LRO\n");
+               return -EINVAL;
+       }
+
+       if (!!(data & ETH_FLAG_LRO) == !!(netdev->features & NETIF_F_LRO))
+               return 0;
 
-       hw_lro = (data & ETH_FLAG_LRO) ? NETXEN_NIC_LRO_ENABLED : 0;
+       if (data & ETH_FLAG_LRO) {
+               hw_lro = NETXEN_NIC_LRO_ENABLED;
+               netdev->features |= NETIF_F_LRO;
+       } else {
+               hw_lro = NETXEN_NIC_LRO_DISABLED;
+               netdev->features &= ~NETIF_F_LRO;
+       }
 
        if (netxen_config_hw_lro(adapter, hw_lro))
                return -EIO;