mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-08 23:04:35 +08:00
net/mlx4_en: Add support for inner IPv6 checksum offloads and TSO
>From what I can tell the ConnectX-3 will support an inner IPv6 checksum and segmentation offload, however it cannot support outer IPv6 headers. This assumption is based on the fact that I could see the checksum being offloaded for inner header on IPv4 tunnels, but not on IPv6 tunnels. For this reason I am adding the feature to the hw_enc_features and adding an extra check to the features_check call that will disable GSO and checksum offload in the case that the encapsulated frame has an outer IP version of that is not 4. The check in mlx4_en_features_check could be removed if at some point in the future a fix is found that allows the hardware to offload segmentation/checksum on tunnels with an outer IPv6 header. Signed-off-by: Alexander Duyck <aduyck@mirantis.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3c9346b240
commit
09067122db
@ -2357,8 +2357,10 @@ out:
|
||||
}
|
||||
|
||||
/* set offloads */
|
||||
priv->dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
|
||||
NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL |
|
||||
priv->dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
|
||||
NETIF_F_RXCSUM |
|
||||
NETIF_F_TSO | NETIF_F_TSO6 |
|
||||
NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM |
|
||||
NETIF_F_GSO_PARTIAL;
|
||||
}
|
||||
@ -2369,8 +2371,10 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
|
||||
struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
|
||||
vxlan_del_task);
|
||||
/* unset offloads */
|
||||
priv->dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
|
||||
NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL |
|
||||
priv->dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
|
||||
NETIF_F_RXCSUM |
|
||||
NETIF_F_TSO | NETIF_F_TSO6 |
|
||||
NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM |
|
||||
NETIF_F_GSO_PARTIAL);
|
||||
|
||||
@ -2431,7 +2435,18 @@ static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
|
||||
netdev_features_t features)
|
||||
{
|
||||
features = vlan_features_check(skb, features);
|
||||
return vxlan_features_check(skb, features);
|
||||
features = vxlan_features_check(skb, features);
|
||||
|
||||
/* The ConnectX-3 doesn't support outer IPv6 checksums but it does
|
||||
* support inner IPv6 checksums and segmentation so we need to
|
||||
* strip that feature if this is an IPv6 encapsulated frame.
|
||||
*/
|
||||
if (skb->encapsulation &&
|
||||
(skb->ip_summed == CHECKSUM_PARTIAL) &&
|
||||
(ip_hdr(skb)->version != 4))
|
||||
features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
|
||||
|
||||
return features;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
#include "mlx4_en.h"
|
||||
@ -920,8 +921,18 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
tx_ind, fragptr);
|
||||
|
||||
if (skb->encapsulation) {
|
||||
struct iphdr *ipv4 = (struct iphdr *)skb_inner_network_header(skb);
|
||||
if (ipv4->protocol == IPPROTO_TCP || ipv4->protocol == IPPROTO_UDP)
|
||||
union {
|
||||
struct iphdr *v4;
|
||||
struct ipv6hdr *v6;
|
||||
unsigned char *hdr;
|
||||
} ip;
|
||||
u8 proto;
|
||||
|
||||
ip.hdr = skb_inner_network_header(skb);
|
||||
proto = (ip.v4->version == 4) ? ip.v4->protocol :
|
||||
ip.v6->nexthdr;
|
||||
|
||||
if (proto == IPPROTO_TCP || proto == IPPROTO_UDP)
|
||||
op_own |= cpu_to_be32(MLX4_WQE_CTRL_IIP | MLX4_WQE_CTRL_ILP);
|
||||
else
|
||||
op_own |= cpu_to_be32(MLX4_WQE_CTRL_IIP);
|
||||
|
Loading…
Reference in New Issue
Block a user