Index: dev/mxge/if_mxge.c =================================================================== --- dev/mxge/if_mxge.c (revision 215675) +++ dev/mxge/if_mxge.c (working copy) @@ -1855,9 +1855,20 @@ tcp = (struct tcphdr *)((char *)ip + (ip->ip_hl << 2)); cum_len = -(ip_off + ((ip->ip_hl + tcp->th_off) << 2)); + cksum_offset = ip_off + (ip->ip_hl << 2); /* TSO implies checksum offload on this hardware */ - cksum_offset = ip_off + (ip->ip_hl << 2); + if (__predict_false((m->m_pkthdr.csum_flags & (CSUM_TCP)) == 0)) { + /* + * If packet has full TCP csum, replace it with pseudo hdr + * sum that the NIC expects, otherwise the NIC will emit + * packets with bad TCP checksums. + */ + m->m_pkthdr.csum_flags = CSUM_TCP; + m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); + tcp->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, + htons(IPPROTO_TCP + (m->m_pkthdr.len - cksum_offset))); + } flags = MXGEFW_FLAGS_TSO_HDR | MXGEFW_FLAGS_FIRST;