Commit 361b3b62 authored by Andrew Morton's avatar Andrew Morton Committed by David S. Miller

[PATCH] fix e100 for big-endian machines

Patch from Anton Blanchard <anton@samba.org>

e100 is performing a header checksum calculation which is

a) duplication of the core kernel's calculation of the same and

b) incorrect on big-endian machines.

This fix has been tested on ia32 and pppc64 and acked by davem, jgarzik
and Scott Feldman
parent 5f10a0b4
......@@ -706,8 +706,6 @@ typedef enum _non_tx_cmd_state_t {
#define IPCB_INSERTVLAN_ENABLE BIT_1
#define IPCB_IP_ACTIVATION_DEFAULT IPCB_HARDWAREPARSING_ENABLE
#define FOLD_CSUM(_XSUM) ((((_XSUM << 16) | (_XSUM >> 16)) + _XSUM) >> 16)
/* Transmit Buffer Descriptor (TBD)*/
typedef struct _tbd_t {
u32 tbd_buf_addr; /* Physical Transmit Buffer Address */
......
......@@ -2070,32 +2070,6 @@ e100_refresh_txthld(struct e100_private *bdp)
} /* end underrun check */
}
/**
* e100_pseudo_hdr_csum - compute IP pseudo-header checksum
* @ip: points to the header of the IP packet
*
* Return the 16 bit checksum of the IP pseudo-header.,which is computed
* on the fields: IP src, IP dst, next protocol, payload length.
* The checksum vaule is returned in network byte order.
*/
static inline u16
e100_pseudo_hdr_csum(const struct iphdr *ip)
{
u32 pseudo = 0;
u32 payload_len = 0;
payload_len = ntohs(ip->tot_len) - (ip->ihl * 4);
pseudo += htons(payload_len);
pseudo += (ip->protocol << 8);
pseudo += ip->saddr & 0x0000ffff;
pseudo += (ip->saddr & 0xffff0000) >> 16;
pseudo += ip->daddr & 0x0000ffff;
pseudo += (ip->daddr & 0xffff0000) >> 16;
return FOLD_CSUM(pseudo);
}
/**
* e100_prepare_xmit_buff - prepare a buffer for transmission
* @bdp: atapter's private data struct
......@@ -2140,27 +2114,13 @@ e100_prepare_xmit_buff(struct e100_private *bdp, struct sk_buff *skb)
if ((ip->protocol == IPPROTO_TCP) ||
(ip->protocol == IPPROTO_UDP)) {
u16 *chksum;
tcb->tcbu.ipcb.ip_activation_high =
IPCB_HARDWAREPARSING_ENABLE;
tcb->tcbu.ipcb.ip_schedule |=
IPCB_TCPUDP_CHECKSUM_ENABLE;
if (ip->protocol == IPPROTO_TCP) {
struct tcphdr *tcp;
tcp = (struct tcphdr *) ((u32 *) ip + ip->ihl);
chksum = &(tcp->check);
if (ip->protocol == IPPROTO_TCP)
tcb->tcbu.ipcb.ip_schedule |= IPCB_TCP_PACKET;
} else {
struct udphdr *udp;
udp = (struct udphdr *) ((u32 *) ip + ip->ihl);
chksum = &(udp->check);
}
*chksum = e100_pseudo_hdr_csum(ip);
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment