--- /dev/null
+From f114dca2533ca770aebebffb5ed56e5e7d1fb3fb Mon Sep 17 00:00:00 2001
+From: Alexander Duyck <alexander.h.duyck@intel.com>
+Date: Tue, 25 Oct 2016 16:08:46 -0700
+Subject: i40e: Be much more verbose about what we can and cannot offload
+
+From: Alexander Duyck <alexander.h.duyck@intel.com>
+
+commit f114dca2533ca770aebebffb5ed56e5e7d1fb3fb upstream.
+
+This change makes it so that we are much more robust about defining what we
+can and cannot offload. Previously we were just checking for the L4 tunnel
+header length, however there are other fields we should be verifying as
+there are multiple scenarios in which we cannot perform hardware offloads.
+
+In addition the device only supports GSO as long as the MSS is 64 or
+greater. We were not checking this so an MSS less than that was resulting
+in Tx hangs.
+
+Change-ID: I5e2fd5f3075c73601b4b36327b771c64fcb6c31b
+Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
+Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
+Cc: Philipp Hahn <hahn@univention.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_main.c | 52 +++++++++++++++++++++++-----
+ 1 file changed, 44 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -9059,10 +9059,6 @@ static int i40e_ndo_bridge_getlink(struc
+ 0, 0, nlflags, filter_mask, NULL);
+ }
+
+-/* Hardware supports L4 tunnel length of 128B (=2^7) which includes
+- * inner mac plus all inner ethertypes.
+- */
+-#define I40E_MAX_TUNNEL_HDR_LEN 128
+ /**
+ * i40e_features_check - Validate encapsulated packet conforms to limits
+ * @skb: skb buff
+@@ -9073,12 +9069,52 @@ static netdev_features_t i40e_features_c
+ struct net_device *dev,
+ netdev_features_t features)
+ {
+- if (skb->encapsulation &&
+- ((skb_inner_network_header(skb) - skb_transport_header(skb)) >
+- I40E_MAX_TUNNEL_HDR_LEN))
+- return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
++ size_t len;
++
++ /* No point in doing any of this if neither checksum nor GSO are
++ * being requested for this frame. We can rule out both by just
++ * checking for CHECKSUM_PARTIAL
++ */
++ if (skb->ip_summed != CHECKSUM_PARTIAL)
++ return features;
++
++ /* We cannot support GSO if the MSS is going to be less than
++ * 64 bytes. If it is then we need to drop support for GSO.
++ */
++ if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_size < 64))
++ features &= ~NETIF_F_GSO_MASK;
++
++ /* MACLEN can support at most 63 words */
++ len = skb_network_header(skb) - skb->data;
++ if (len & ~(63 * 2))
++ goto out_err;
++
++ /* IPLEN and EIPLEN can support at most 127 dwords */
++ len = skb_transport_header(skb) - skb_network_header(skb);
++ if (len & ~(127 * 4))
++ goto out_err;
++
++ if (skb->encapsulation) {
++ /* L4TUNLEN can support 127 words */
++ len = skb_inner_network_header(skb) - skb_transport_header(skb);
++ if (len & ~(127 * 2))
++ goto out_err;
++
++ /* IPLEN can support at most 127 dwords */
++ len = skb_inner_transport_header(skb) -
++ skb_inner_network_header(skb);
++ if (len & ~(127 * 4))
++ goto out_err;
++ }
++
++ /* No need to validate L4LEN as TCP is the only protocol with a
++ * a flexible value and we support all possible values supported
++ * by TCP, which is at most 15 dwords
++ */
+
+ return features;
++out_err:
++ return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
+ }
+
+ static const struct net_device_ops i40e_netdev_ops = {