From d734f887f65a9ace92514c4481cd7b4a4d9355de Mon Sep 17 00:00:00 2001
From: "Mutalik Desai, Suprasad" <suprasad.desai@intel.com>
Date: Fri, 9 Feb 2018 14:11:56 +0100
Subject: [PATCH] Merge pull request #244 in SW_PON/linux from
 bugfix/UGW_SW-22228-grx550-lro-session-addition-not-happening-if-litepath-is-disabled
 to xrx500

UGW_SW-22228-grx550-lro-session-addition-not-happening-if-litepath-is-disabled

* commit '204f0de722e33538cdb40753dc4f413060e20215':
  UGW_SW-22228: re-compute ip header checksum in LRO, otherwise ip_rcv drops it
---
 drivers/net/ethernet/lantiq/ltq_toe_drv.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/lantiq/ltq_toe_drv.c b/drivers/net/ethernet/lantiq/ltq_toe_drv.c
index 90fc33b21..34bea62b3 100644
--- a/drivers/net/ethernet/lantiq/ltq_toe_drv.c
+++ b/drivers/net/ethernet/lantiq/ltq_toe_drv.c
@@ -28,6 +28,8 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/tcp.h>
+#include <linux/if_vlan.h>
+#include <linux/ip.h>
 
 #include <lantiq.h>
 #include <lantiq_soc.h>
@@ -434,9 +436,11 @@ static void lro_process_output_context(int port, int oc_flag_no)
 #ifdef LRO_DEBUG
 	struct tcphdr *tcp_hdr;
 #endif
-
 	struct sk_buff *frag_skb = NULL, *last_frag_skb = NULL;
 	unsigned long tso_rl_flags;
+	struct iphdr	*ip_hdr;
+	struct ethhdr	*eth;
+	int network_depth = 0;
 
 	oc_flag = ltq_toe_r32(LRO_OC_FLAG(port, oc_flag_no));
 	pr_debug("LRO done and OC_FLAG: %x\n", oc_flag);
@@ -545,6 +549,16 @@ static void lro_process_output_context(int port, int oc_flag_no)
 				dbg_info[dbg_head].aggr_len = skb->len - 62;
 				dbg_head = (dbg_head + 1) % LRO_MAX_DBG_INFO;
 #endif
+				/* re-compute the IP header checksum since HW has modified
+				the IP header's total_len field */
+				eth = (struct ethhdr *)(skb->data + PMAC_HDR_SIZE);
+				skb->mac_len = ETH_HLEN + PMAC_HDR_SIZE;
+				__vlan_get_protocol(skb, eth->h_proto, &network_depth);
+				ip_hdr = (struct iphdr *)(skb->data + network_depth);
+				ip_hdr->check = 0;
+				ip_hdr->check = ip_fast_csum((unsigned char *)ip_hdr, ip_hdr->ihl);
+				skb->mac_len = 0;
+
 				/* Send it to datapath library */
 				dp_rx(skb, 0);
 	} 
-- 
GitLab