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.


 drivers/net/e100/e100.h      |    2 --
 drivers/net/e100/e100_main.c |   42 +-----------------------------------------
 2 files changed, 1 insertion(+), 43 deletions(-)

diff -puN drivers/net/e100/e100.h~ppc64-e100-fix drivers/net/e100/e100.h
--- 25/drivers/net/e100/e100.h~ppc64-e100-fix	Wed Feb 19 13:13:30 2003
+++ 25-akpm/drivers/net/e100/e100.h	Wed Feb 19 13:13:30 2003
@@ -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 */
diff -puN drivers/net/e100/e100_main.c~ppc64-e100-fix drivers/net/e100/e100_main.c
--- 25/drivers/net/e100/e100_main.c~ppc64-e100-fix	Wed Feb 19 13:13:30 2003
+++ 25-akpm/drivers/net/e100/e100_main.c	Wed Feb 19 13:13:30 2003
@@ -2071,32 +2071,6 @@ e100_refresh_txthld(struct e100_private 
 }
 
 /**
- * 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
  * @skb: skb to send
@@ -2140,27 +2114,13 @@ e100_prepare_xmit_buff(struct e100_priva
 
 		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);
 		}
 	}
 

_