Merge branch 'stable/bug.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / drivers / net / netxen / netxen_nic_main.c
index e8a4b66..c0788a3 100644 (file)
@@ -485,6 +485,37 @@ static void netxen_set_multicast_list(struct net_device *dev)
        adapter->set_multi(dev);
 }
 
+static u32 netxen_fix_features(struct net_device *dev, u32 features)
+{
+       if (!(features & NETIF_F_RXCSUM)) {
+               netdev_info(dev, "disabling LRO as RXCSUM is off\n");
+
+               features &= ~NETIF_F_LRO;
+       }
+
+       return features;
+}
+
+static int netxen_set_features(struct net_device *dev, u32 features)
+{
+       struct netxen_adapter *adapter = netdev_priv(dev);
+       int hw_lro;
+
+       if (!((dev->features ^ features) & NETIF_F_LRO))
+               return 0;
+
+       hw_lro = (features & NETIF_F_LRO) ? NETXEN_NIC_LRO_ENABLED
+                : NETXEN_NIC_LRO_DISABLED;
+
+       if (netxen_config_hw_lro(adapter, hw_lro))
+               return -EIO;
+
+       if (!(features & NETIF_F_LRO) && netxen_send_lro_cleanup(adapter))
+               return -EIO;
+
+       return 0;
+}
+
 static const struct net_device_ops netxen_netdev_ops = {
        .ndo_open          = netxen_nic_open,
        .ndo_stop          = netxen_nic_close,
@@ -495,6 +526,8 @@ static const struct net_device_ops netxen_netdev_ops = {
        .ndo_set_mac_address    = netxen_nic_set_mac,
        .ndo_change_mtu    = netxen_nic_change_mtu,
        .ndo_tx_timeout    = netxen_tx_timeout,
+       .ndo_fix_features = netxen_fix_features,
+       .ndo_set_features = netxen_set_features,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller = netxen_nic_poll_controller,
 #endif
@@ -905,7 +938,7 @@ netxen_nic_request_irq(struct netxen_adapter *adapter)
        struct nx_host_sds_ring *sds_ring;
        int err, ring;
 
-       unsigned long flags = IRQF_SAMPLE_RANDOM;
+       unsigned long flags = 0;
        struct net_device *netdev = adapter->netdev;
        struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
 
@@ -1196,7 +1229,6 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
        int err = 0;
        struct pci_dev *pdev = adapter->pdev;
 
-       adapter->rx_csum = 1;
        adapter->mc_enabled = 0;
        if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
                adapter->max_mc_count = 38;
@@ -1210,14 +1242,13 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
 
        SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
 
-       netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
-       netdev->features |= (NETIF_F_GRO);
-       netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+       netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+                             NETIF_F_RXCSUM;
 
-       if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-               netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
-               netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
-       }
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               netdev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+
+       netdev->vlan_features |= netdev->hw_features;
 
        if (adapter->pci_using_dac) {
                netdev->features |= NETIF_F_HIGHDMA;
@@ -1225,10 +1256,12 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
        }
 
        if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX)
-               netdev->features |= (NETIF_F_HW_VLAN_TX);
+               netdev->hw_features |= NETIF_F_HW_VLAN_TX;
 
        if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
-               netdev->features |= NETIF_F_LRO;
+               netdev->hw_features |= NETIF_F_LRO;
+
+       netdev->features |= netdev->hw_features;
 
        netdev->irq = adapter->msix_entries[0].vector;
 
@@ -1932,11 +1965,11 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
        netxen_tso_check(netdev, tx_ring, first_desc, skb);
 
-       netxen_nic_update_cmd_producer(adapter, tx_ring);
-
        adapter->stats.txbytes += skb->len;
        adapter->stats.xmitcalled++;
 
+       netxen_nic_update_cmd_producer(adapter, tx_ring);
+
        return NETDEV_TX_OK;
 
 drop_packet: