int i;
 
        netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
-               NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_CSUM |
+               NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
+               NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
                NETIF_F_GRO | NETIF_F_TSO6;
 
-       netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM;
+       netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO |
+               NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 
        if (lancer_chip(adapter))
                netdev->vlan_features |= NETIF_F_TSO6;
 
        dev->netdev_ops = &bnx2x_netdev_ops;
        bnx2x_set_ethtool_ops(dev);
        dev->features |= NETIF_F_SG;
-       dev->features |= NETIF_F_HW_CSUM;
+       dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        if (bp->flags & USING_DAC_FLAG)
                dev->features |= NETIF_F_HIGHDMA;
        dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
        dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
 
        dev->vlan_features |= NETIF_F_SG;
-       dev->vlan_features |= NETIF_F_HW_CSUM;
+       dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        if (bp->flags & USING_DAC_FLAG)
                dev->vlan_features |= NETIF_F_HIGHDMA;
        dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
 
        }
 
        if (new_mtu > 1900) {
-               netdev->features &= ~(NETIF_F_HW_CSUM |
-                               NETIF_F_TSO |
-                               NETIF_F_TSO6);
+               netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+                               NETIF_F_TSO | NETIF_F_TSO6);
        } else {
                if (test_bit(JME_FLAG_TXCSUM, &jme->flags))
-                       netdev->features |= NETIF_F_HW_CSUM;
+                       netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
                if (test_bit(JME_FLAG_TSO, &jme->flags))
                        netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
        }
        if (on) {
                set_bit(JME_FLAG_TXCSUM, &jme->flags);
                if (netdev->mtu <= 1900)
-                       netdev->features |= NETIF_F_HW_CSUM;
+                       netdev->features |=
+                               NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        } else {
                clear_bit(JME_FLAG_TXCSUM, &jme->flags);
-               netdev->features &= ~NETIF_F_HW_CSUM;
+               netdev->features &=
+                               ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
        }
 
        return 0;
        netdev->netdev_ops = &jme_netdev_ops;
        netdev->ethtool_ops             = &jme_ethtool_ops;
        netdev->watchdog_timeo          = TX_TIMEOUT;
-       netdev->features                =       NETIF_F_HW_CSUM |
+       netdev->features                =       NETIF_F_IP_CSUM |
+                                               NETIF_F_IPV6_CSUM |
                                                NETIF_F_SG |
                                                NETIF_F_TSO |
                                                NETIF_F_TSO6 |
 
        return 0;
 }
 
-/**
- * pch_gbe_get_tx_csum - Report whether transmit checksums are turned on or off
- * @netdev:  Network interface device structure
- * Returns
- *     true(1):  Checksum On
- *     false(0): Checksum Off
- */
-static u32 pch_gbe_get_tx_csum(struct net_device *netdev)
-{
-       return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
 /**
  * pch_gbe_set_tx_csum - Turn transmit checksums on or off
  * @netdev: Network interface device structure
        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 
        adapter->tx_csum = data;
-       if (data)
-               netdev->features |= NETIF_F_HW_CSUM;
-       else
-               netdev->features &= ~NETIF_F_HW_CSUM;
-       return 0;
+       return ethtool_op_set_tx_ipv6_csum(netdev, data);
 }
 
 /**
        .set_pauseparam = pch_gbe_set_pauseparam,
        .get_rx_csum = pch_gbe_get_rx_csum,
        .set_rx_csum = pch_gbe_set_rx_csum,
-       .get_tx_csum = pch_gbe_get_tx_csum,
        .set_tx_csum = pch_gbe_set_tx_csum,
        .get_strings = pch_gbe_get_strings,
        .get_ethtool_stats = pch_gbe_get_ethtool_stats,
 
        netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD;
        netif_napi_add(netdev, &adapter->napi,
                       pch_gbe_napi_poll, PCH_GBE_RX_WEIGHT);
-       netdev->features = NETIF_F_HW_CSUM | NETIF_F_GRO;
+       netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO;
        pch_gbe_set_ethtool_ops(netdev);
 
        pch_gbe_mac_reset_hw(&adapter->hw);
        pch_gbe_check_options(adapter);
 
        if (adapter->tx_csum)
-               netdev->features |= NETIF_F_HW_CSUM;
+               netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        else
-               netdev->features &= ~NETIF_F_HW_CSUM;
+               netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
 
        /* initialize the wol settings based on the eeprom settings */
        adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING;
 
        dev->irq = pdev->irq;
 
        /* faked with skb_copy_and_csum_dev */
-       dev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
+       dev->features = NETIF_F_SG | NETIF_F_HIGHDMA |
+               NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 
        dev->netdev_ops         = &sc92031_netdev_ops;
        dev->watchdog_timeo     = TX_TIMEOUT;
 
        }
 }
 
-static int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data)
-{
-       if (data)
-               netdev->features |= NETIF_F_HW_CSUM;
-       else
-               netdev->features &= ~NETIF_F_HW_CSUM;
-
-       return 0;
-}
-
 static u32 stmmac_ethtool_get_rx_csum(struct net_device *dev)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
        .get_link = ethtool_op_get_link,
        .get_rx_csum = stmmac_ethtool_get_rx_csum,
        .get_tx_csum = ethtool_op_get_tx_csum,
-       .set_tx_csum = stmmac_ethtool_set_tx_csum,
+       .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
        .get_sg = ethtool_op_get_sg,
        .set_sg = ethtool_op_set_sg,
        .get_pauseparam = stmmac_get_pauseparam,
 
        dev->netdev_ops = &stmmac_netdev_ops;
        stmmac_set_ethtool_ops(dev);
 
-       dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA);
+       dev->features |= NETIF_F_SG | NETIF_F_HIGHDMA |
+               NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        dev->watchdog_timeo = msecs_to_jiffies(watchdog);
 #ifdef STMMAC_VLAN_TAG_USED
        /* Both mac100 and gmac support receive VLAN tag detection */
 
        DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n",
            dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
-           (dev->features & NETIF_F_HW_CSUM) ? "on" : "off");
+           (dev->features & NETIF_F_IP_CSUM) ? "on" : "off");
 
        spin_lock_init(&priv->lock);
 
 
        .get_rx_csum            = vxge_get_rx_csum,
        .set_rx_csum            = vxge_set_rx_csum,
        .get_tx_csum            = ethtool_op_get_tx_csum,
-       .set_tx_csum            = ethtool_op_set_tx_hw_csum,
+       .set_tx_csum            = ethtool_op_set_tx_ipv6_csum,
        .get_sg                 = ethtool_op_get_sg,
        .set_sg                 = ethtool_op_set_sg,
        .get_tso                = ethtool_op_get_tso,
 
 
        ndev->features |= NETIF_F_SG;
 
-       ndev->features |= NETIF_F_HW_CSUM;
+       ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
                "%s : checksuming enabled", __func__);
 
 
        }
 
        if (features & NETIF_F_UFO) {
-               if (!(features & NETIF_F_GEN_CSUM)) {
+               /* maybe split UFO into V4 and V6? */
+               if (!((features & NETIF_F_GEN_CSUM) ||
+                   (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
+                           == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
                        if (name)
                                printk(KERN_ERR "%s: Dropping NETIF_F_UFO "
-                                      "since no NETIF_F_HW_CSUM feature.\n",
+                                      "since no checksum offload features.\n",
                                       name);
                        features &= ~NETIF_F_UFO;
                }
 
                return -EFAULT;
        if (edata.data && !(dev->features & NETIF_F_SG))
                return -EINVAL;
-       if (edata.data && !(dev->features & NETIF_F_HW_CSUM))
+       if (edata.data && !((dev->features & NETIF_F_GEN_CSUM) ||
+               (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
+                       == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)))
                return -EINVAL;
        return dev->ethtool_ops->set_ufo(dev, edata.data);
 }