--- zzzz-none-000/linux-2.6.28.10/net/ipv4/inet_lro.c 2009-05-02 18:54:43.000000000 +0000 +++ fusiv-7390-686/linux-2.6.28.10/net/ipv4/inet_lro.c 2012-02-14 14:37:49.000000000 +0000 @@ -29,13 +29,14 @@ #include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jan-Bernd Themann "); MODULE_DESCRIPTION("Large Receive Offload (ipv4 / tcp)"); -#define TCP_HDR_LEN(tcph) (tcph->doff << 2) -#define IP_HDR_LEN(iph) (iph->ihl << 2) +#define TCP_HDR_LEN(tcph) (TCP_DOFF(tcph) << 2) +#define IP_HDR_LEN(iph) (IP_IHL(iph) << 2) #define TCP_PAYLOAD_LENGTH(iph, tcph) \ (ntohs(iph->tot_len) - IP_HDR_LEN(iph) - TCP_HDR_LEN(tcph)) @@ -64,9 +65,15 @@ if (iph->ihl != IPH_LEN_WO_OPTIONS) return -1; +#if defined(CONFIG_FUSIV_VX185) && defined(CONFIG_FUSIV_ALIGNMENT_FIXUPS) + /* Avoid misaligned exceptions on bitfield accesses in TCP header */ + if ((TCP_FLAGS(tcph) & 0xe7) || !TCP_ACK(tcph)) + return -1; +#else if (tcph->cwr || tcph->ece || tcph->urg || !tcph->ack || tcph->rst || tcph->syn || tcph->fin) return -1; +#endif if (INET_ECN_is_ce(ipv4_get_dsfield(iph))) return -1; @@ -106,7 +113,7 @@ __be32 *p; __wsum tcp_hdr_csum; - tcph->ack_seq = lro_desc->tcp_ack; + WR16(tcph->ack_seq, lro_desc->tcp_ack); tcph->window = lro_desc->tcp_window; if (lro_desc->tcp_saw_tstamp) { @@ -122,7 +129,7 @@ tcph->check = 0; tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), 0); lro_desc->data_csum = csum_add(lro_desc->data_csum, tcp_hdr_csum); - tcph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, + tcph->check = csum_tcpudp_magic(RD16(iph->saddr), RD16(iph->daddr), lro_desc->ip_tot_len - IP_HDR_LEN(iph), IPPROTO_TCP, lro_desc->data_csum); @@ -137,7 +144,7 @@ tcp_csum = ~csum_unfold(tcph->check); tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), tcp_csum); - tcp_ps_hdr_csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, + tcp_ps_hdr_csum = csum_tcpudp_nofold(RD16(iph->saddr), RD16(iph->daddr), len + TCP_HDR_LEN(tcph), IPPROTO_TCP, 0); @@ -158,8 +165,8 @@ lro_desc->next_frag = &(skb_shinfo(skb)->frags[nr_frags]); lro_desc->iph = iph; lro_desc->tcph = tcph; - lro_desc->tcp_next_seq = ntohl(tcph->seq) + tcp_data_len; - lro_desc->tcp_ack = tcph->ack_seq; + lro_desc->tcp_next_seq = ntohl(RD16(tcph->seq)) + tcp_data_len; + lro_desc->tcp_ack = RD16(tcph->ack_seq); lro_desc->tcp_window = tcph->window; lro_desc->pkt_aggr_cnt = 1; @@ -196,7 +203,7 @@ lro_desc->ip_tot_len += tcp_data_len; lro_desc->tcp_next_seq += tcp_data_len; lro_desc->tcp_window = tcph->window; - lro_desc->tcp_ack = tcph->ack_seq; + lro_desc->tcp_ack = RD16(tcph->ack_seq); /* don't update tcp_rcv_tsval, would not work with PAWS */ if (lro_desc->tcp_saw_tstamp) { @@ -262,8 +269,8 @@ struct iphdr *iph, struct tcphdr *tcph) { - if ((lro_desc->iph->saddr != iph->saddr) - || (lro_desc->iph->daddr != iph->daddr) + if ((RD16(lro_desc->iph->saddr) != RD16(iph->saddr)) + || (RD16(lro_desc->iph->daddr) != RD16(iph->daddr)) || (lro_desc->tcph->source != tcph->source) || (lro_desc->tcph->dest != tcph->dest)) return -1; @@ -365,7 +372,7 @@ return 0; } - if (lro_desc->tcp_next_seq != ntohl(tcph->seq)) + if (lro_desc->tcp_next_seq != ntohl(RD16(tcph->seq))) goto out2; if (lro_tcp_ip_check(iph, tcph, skb->len, lro_desc)) @@ -485,7 +492,7 @@ return NULL; } - if (lro_desc->tcp_next_seq != ntohl(tcph->seq)) + if (lro_desc->tcp_next_seq != ntohl(RD16(tcph->seq))) goto out2; if (lro_tcp_ip_check(iph, tcph, len - mac_hdr_len, lro_desc))