diff options
author | Jesse Gross <jesse@nicira.com> | 2011-01-09 01:23:35 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-10 02:35:35 -0500 |
commit | 0363466866d901fbc658f4e63dd61e7cc93dd0af (patch) | |
tree | 5d2b3f272bb00b51a310ce4fa330817b82c8d346 | |
parent | 02932ce9e2c136e6fab2571c8e0dd69ae8ec9853 (diff) |
net offloading: Convert checksums to use centrally computed features.
In order to compute the features for other offloads (primarily
scatter/gather), we need to first check the ability of the NIC to
offload the checksum for the packet. Since we have already computed
this, we can directly use the result instead of figuring it out
again.
Signed-off-by: Jesse Gross <jesse@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/core/dev.c | 40 |
1 files changed, 12 insertions, 28 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 2f838f1d222c..3fe443be4b15 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1732,33 +1732,6 @@ void netif_device_attach(struct net_device *dev) | |||
1732 | } | 1732 | } |
1733 | EXPORT_SYMBOL(netif_device_attach); | 1733 | EXPORT_SYMBOL(netif_device_attach); |
1734 | 1734 | ||
1735 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) | ||
1736 | { | ||
1737 | return ((features & NETIF_F_GEN_CSUM) || | ||
1738 | ((features & NETIF_F_V4_CSUM) && | ||
1739 | protocol == htons(ETH_P_IP)) || | ||
1740 | ((features & NETIF_F_V6_CSUM) && | ||
1741 | protocol == htons(ETH_P_IPV6)) || | ||
1742 | ((features & NETIF_F_FCOE_CRC) && | ||
1743 | protocol == htons(ETH_P_FCOE))); | ||
1744 | } | ||
1745 | |||
1746 | static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb) | ||
1747 | { | ||
1748 | __be16 protocol = skb->protocol; | ||
1749 | int features = dev->features; | ||
1750 | |||
1751 | if (vlan_tx_tag_present(skb)) { | ||
1752 | features &= dev->vlan_features; | ||
1753 | } else if (protocol == htons(ETH_P_8021Q)) { | ||
1754 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | ||
1755 | protocol = veh->h_vlan_encapsulated_proto; | ||
1756 | features &= dev->vlan_features; | ||
1757 | } | ||
1758 | |||
1759 | return can_checksum_protocol(features, protocol); | ||
1760 | } | ||
1761 | |||
1762 | /** | 1735 | /** |
1763 | * skb_dev_set -- assign a new device to a buffer | 1736 | * skb_dev_set -- assign a new device to a buffer |
1764 | * @skb: buffer for the new device | 1737 | * @skb: buffer for the new device |
@@ -2015,6 +1988,17 @@ static inline void skb_orphan_try(struct sk_buff *skb) | |||
2015 | } | 1988 | } |
2016 | } | 1989 | } |
2017 | 1990 | ||
1991 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) | ||
1992 | { | ||
1993 | return ((features & NETIF_F_GEN_CSUM) || | ||
1994 | ((features & NETIF_F_V4_CSUM) && | ||
1995 | protocol == htons(ETH_P_IP)) || | ||
1996 | ((features & NETIF_F_V6_CSUM) && | ||
1997 | protocol == htons(ETH_P_IPV6)) || | ||
1998 | ((features & NETIF_F_FCOE_CRC) && | ||
1999 | protocol == htons(ETH_P_FCOE))); | ||
2000 | } | ||
2001 | |||
2018 | static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features) | 2002 | static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features) |
2019 | { | 2003 | { |
2020 | if (!can_checksum_protocol(protocol, features)) { | 2004 | if (!can_checksum_protocol(protocol, features)) { |
@@ -2117,7 +2101,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2117 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 2101 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
2118 | skb_set_transport_header(skb, | 2102 | skb_set_transport_header(skb, |
2119 | skb_checksum_start_offset(skb)); | 2103 | skb_checksum_start_offset(skb)); |
2120 | if (!dev_can_checksum(dev, skb) && | 2104 | if (!(features & NETIF_F_ALL_CSUM) && |
2121 | skb_checksum_help(skb)) | 2105 | skb_checksum_help(skb)) |
2122 | goto out_kfree_skb; | 2106 | goto out_kfree_skb; |
2123 | } | 2107 | } |