csk->rcv_win = CXGBIT_10G_RCV_WIN;
        if (scale)
                csk->rcv_win *= scale;
+       csk->rcv_win = min(csk->rcv_win, RCV_BUFSIZ_M << 10);
 
 #define CXGBIT_10G_SND_WIN (256 * 1024)
        csk->snd_win = CXGBIT_10G_SND_WIN;
        if (scale)
                csk->snd_win *= scale;
+       csk->snd_win = min(csk->snd_win, 512U * 1024);
 
        pr_debug("%s snd_win %d rcv_win %d\n",
                 __func__, csk->snd_win, csk->rcv_win);
        if (!skb)
                return -1;
 
-       credit_dack = RX_DACK_CHANGE_F | RX_DACK_MODE_V(1) |
+       credit_dack = RX_DACK_CHANGE_F | RX_DACK_MODE_V(3) |
                      RX_CREDITS_V(csk->rx_credits);
 
        cxgb_mk_rx_data_ack(skb, len, csk->tid, csk->ctrlq_idx,
        if (tcph->ece && tcph->cwr)
                opt2 |= CCTRL_ECN_V(1);
 
-       opt2 |= RX_COALESCE_V(3);
        opt2 |= CONG_CNTRL_V(CONG_ALG_NEWRENO);
 
        opt2 |= T5_ISS_F;
 
        csk->rcv_nxt = rcv_isn;
 
-       if (csk->rcv_win > (RCV_BUFSIZ_M << 10))
-               csk->rx_credits = (csk->rcv_win - (RCV_BUFSIZ_M << 10));
-
        csk->snd_wscale = TCPOPT_SND_WSCALE_G(tcp_opt);
        cxgbit_set_emss(csk, tcp_opt);
        dst_confirm(csk->dst);
 
        wr_ulp_mode = FW_OFLD_TX_DATA_WR_ULPMODE_V(ULP_MODE_ISCSI) |
                                FW_OFLD_TX_DATA_WR_ULPSUBMODE_V(submode);
 
-       req->tunnel_to_proxy = htonl((wr_ulp_mode) | force |
-                FW_OFLD_TX_DATA_WR_SHOVE_V(skb_peek(&csk->txq) ? 0 : 1));
+       req->tunnel_to_proxy = htonl(wr_ulp_mode | force |
+                                    FW_OFLD_TX_DATA_WR_SHOVE_F);
 }
 
 static void cxgbit_arp_failure_skb_discard(void *handle, struct sk_buff *skb)
        return ret;
 }
 
-static int cxgbit_rx_lro_skb(struct cxgbit_sock *csk, struct sk_buff *skb)
+static int cxgbit_t5_rx_lro_skb(struct cxgbit_sock *csk, struct sk_buff *skb)
 {
        struct cxgbit_lro_cb *lro_cb = cxgbit_skb_lro_cb(skb);
        struct cxgbit_lro_pdu_cb *pdu_cb = cxgbit_skb_lro_pdu_cb(skb, 0);
        return ret;
 }
 
+static int cxgbit_rx_lro_skb(struct cxgbit_sock *csk, struct sk_buff *skb)
+{
+       struct cxgbit_lro_cb *lro_cb = cxgbit_skb_lro_cb(skb);
+       int ret;
+
+       ret = cxgbit_process_lro_skb(csk, skb);
+       if (ret)
+               return ret;
+
+       csk->rx_credits += lro_cb->pdu_totallen;
+       if (csk->rx_credits >= csk->rcv_win) {
+               csk->rx_credits = 0;
+               cxgbit_rx_data_ack(csk);
+       }
+
+       return 0;
+}
+
 static int cxgbit_rx_skb(struct cxgbit_sock *csk, struct sk_buff *skb)
 {
        struct cxgb4_lld_info *lldi = &csk->com.cdev->lldi;
 
        if (likely(cxgbit_skcb_flags(skb) & SKCBF_RX_LRO)) {
                if (is_t5(lldi->adapter_type))
-                       ret = cxgbit_rx_lro_skb(csk, skb);
+                       ret = cxgbit_t5_rx_lro_skb(csk, skb);
                else
-                       ret = cxgbit_process_lro_skb(csk, skb);
+                       ret = cxgbit_rx_lro_skb(csk, skb);
        }
 
        __kfree_skb(skb);