*/
 #define TPA_TSTAMP_OPT_LEN     12
 /**
- * bnx2x_set_lro_mss - calculate the approximate value of the MSS
+ * bnx2x_set_gro_params - compute GRO values
  *
- * @bp:                        driver handle
+ * @skb:               packet skb
  * @parsing_flags:     parsing flags from the START CQE
  * @len_on_bd:         total length of the first packet for the
  *                     aggregation.
+ * @pkt_len:           length of all segments
  *
  * Approximate value of the MSS for this aggregation calculated using
  * the first packet of it.
+ * Compute number of aggregated segments, and gso_type
  */
-static u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags,
-                            u16 len_on_bd)
+static void bnx2x_set_gro_params(struct sk_buff *skb, u16 parsing_flags,
+                                u16 len_on_bd, unsigned int pkt_len)
 {
-       /*
-        * TPA arrgregation won't have either IP options or TCP options
+       /* TPA aggregation won't have either IP options or TCP options
         * other than timestamp or IPv6 extension headers.
         */
        u16 hdrs_len = ETH_HLEN + sizeof(struct tcphdr);
 
        if (GET_FLAG(parsing_flags, PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) ==
-           PRS_FLAG_OVERETH_IPV6)
+           PRS_FLAG_OVERETH_IPV6) {
                hdrs_len += sizeof(struct ipv6hdr);
-       else /* IPv4 */
+               skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+       } else {
                hdrs_len += sizeof(struct iphdr);
-
+               skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+       }
 
        /* Check if there was a TCP timestamp, if there is it's will
         * always be 12 bytes length: nop nop kind length echo val.
        if (parsing_flags & PARSING_FLAGS_TIME_STAMP_EXIST_FLAG)
                hdrs_len += TPA_TSTAMP_OPT_LEN;
 
-       return len_on_bd - hdrs_len;
+       skb_shinfo(skb)->gso_size = len_on_bd - hdrs_len;
+
+       /* tcp_gro_complete() will copy NAPI_GRO_CB(skb)->count
+        * to skb_shinfo(skb)->gso_segs
+        */
+       NAPI_GRO_CB(skb)->count = DIV_ROUND_UP(pkt_len - hdrs_len,
+                                              skb_shinfo(skb)->gso_size);
 }
 
 static int bnx2x_alloc_rx_sge(struct bnx2x *bp,
        }
 
        /* This is needed in order to enable forwarding support */
-       if (frag_size) {
-               skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(bp,
-                                       tpa_info->parsing_flags, len_on_bd);
-
-               /* set for GRO */
-               if (fp->mode == TPA_MODE_GRO && skb_shinfo(skb)->gso_size)
-                       skb_shinfo(skb)->gso_type =
-                           (GET_FLAG(tpa_info->parsing_flags,
-                                     PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) ==
-                                               PRS_FLAG_OVERETH_IPV6) ?
-                               SKB_GSO_TCPV6 : SKB_GSO_TCPV4;
-       }
-
+       if (frag_size)
+               bnx2x_set_gro_params(skb, tpa_info->parsing_flags, len_on_bd,
+                                    le16_to_cpu(cqe->pkt_len));
 
 #ifdef BNX2X_STOP_ON_ERROR
        if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) {
                               struct sk_buff *skb)
 {
 #ifdef CONFIG_INET
-       if (fp->mode == TPA_MODE_GRO && skb_shinfo(skb)->gso_size) {
+       if (skb_shinfo(skb)->gso_size) {
                skb_set_network_header(skb, 0);
                switch (be16_to_cpu(skb->protocol)) {
                case ETH_P_IP: