net: Fix too optimistic NETIF_F_HW_CSUM features
NETIF_F_HW_CSUM is a superset of NETIF_F_IP_CSUM+NETIF_F_IPV6_CSUM, but some drivers miss the difference. Fix this and also fix UFO dependency on checksumming offload as it makes the same mistake in assumptions. Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl> Acked-by: Jon Mason <jon.mason@exar.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
900d495a18
commit
7903264402
@ -2583,10 +2583,12 @@ static void be_netdev_init(struct net_device *netdev)
|
||||
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;
|
||||
|
@ -8957,7 +8957,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
|
||||
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);
|
||||
@ -8965,7 +8965,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
|
||||
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);
|
||||
|
@ -2076,12 +2076,11 @@ jme_change_mtu(struct net_device *netdev, int new_mtu)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -2514,10 +2513,12 @@ jme_set_tx_csum(struct net_device *netdev, u32 on)
|
||||
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;
|
||||
@ -2797,7 +2798,8 @@ jme_init_one(struct pci_dev *pdev,
|
||||
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 |
|
||||
|
@ -468,18 +468,6 @@ static int pch_gbe_set_rx_csum(struct net_device *netdev, u32 data)
|
||||
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
|
||||
@ -493,11 +481,7 @@ static int pch_gbe_set_tx_csum(struct net_device *netdev, u32 data)
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -572,7 +556,6 @@ static const struct ethtool_ops pch_gbe_ethtool_ops = {
|
||||
.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,
|
||||
|
@ -2319,7 +2319,7 @@ static int pch_gbe_probe(struct pci_dev *pdev,
|
||||
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);
|
||||
@ -2358,9 +2358,9 @@ static int pch_gbe_probe(struct pci_dev *pdev,
|
||||
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;
|
||||
|
@ -1449,7 +1449,8 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
|
||||
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;
|
||||
|
@ -197,16 +197,6 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@ -370,7 +360,7 @@ static struct ethtool_ops stmmac_ethtool_ops = {
|
||||
.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,
|
||||
|
@ -1494,7 +1494,8 @@ static int stmmac_probe(struct net_device *dev)
|
||||
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 */
|
||||
@ -1525,7 +1526,7 @@ static int stmmac_probe(struct net_device *dev)
|
||||
|
||||
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);
|
||||
|
||||
|
@ -1177,7 +1177,7 @@ static const struct ethtool_ops vxge_ethtool_ops = {
|
||||
.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,
|
||||
|
@ -3368,7 +3368,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
|
||||
|
||||
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__);
|
||||
|
||||
|
@ -5041,10 +5041,13 @@ unsigned long netdev_fix_features(unsigned long features, const char *name)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -1171,7 +1171,9 @@ static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr)
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user