diff --git a/drivers/net/ethernet/lantiq/ltq_toe_drv.c b/drivers/net/ethernet/lantiq/ltq_toe_drv.c
index 90fc33b210f2644eaf9c44e16dd5da619fd5ae8e..34bea62b3c7fed6cf0f67d0f78d99f944600e579 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);
 	}