patch-2.1.51 linux/include/asm-ppc/checksum.h

Next file: linux/include/asm-ppc/cuda.h
Previous file: linux/include/asm-ppc/byteorder.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.50/linux/include/asm-ppc/checksum.h linux/include/asm-ppc/checksum.h
@@ -3,22 +3,6 @@
 
 
 /*
- *	This is a version of ip_compute_csum() optimized for IP headers,
- *	which always checksum on 4 octet boundaries.
- */
-extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-extern unsigned short int csum_tcpudp_magic(unsigned long saddr,
-					   unsigned long daddr,
-					   unsigned short len,
-					   unsigned short proto,
-					   unsigned int sum);
-
-/*
  * computes the checksum of a memory block at buff, length len,
  * and adds in "sum" (32-bit)
  *
@@ -30,43 +14,76 @@
  *
  * it's best to have buff aligned on a 32-bit boundary
  */
-extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+extern unsigned int csum_partial(const unsigned char * buff, int len,
+				 unsigned int sum);
 
 /*
- * the same as csum_partial, but copies from src while it
- * checksums
+ * Computes the checksum of a memory block at src, length len,
+ * and adds in "sum" (32-bit), while copying the block to dst.
+ * If an access exception occurs on src or dst, it stores -EFAULT
+ * to *src_err or *dst_err respectively (if that pointer is not
+ * NULL), and, for an error on src, zeroes the rest of dst.
  *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
+ * Like csum_partial, this must be called with even lengths,
+ * except for the last fragment.
  */
-unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
+extern unsigned int csum_partial_copy_generic(const char *src, char *dst,
+					      int len, unsigned int sum,
+					      int *src_err, int *dst_err);
+
+#define csum_partial_copy_from_user(src, dst, len, sum, errp)	\
+	csum_partial_copy_generic((src), (dst), (len), (sum), (errp), 0)
 
 /*
- * the same as csum_partial, but copies from user space (but on the alpha
- * we have just one address space, so this is identical to the above)
+ * Old versions which ignore errors.
  */
-#define csum_partial_copy_fromuser csum_partial_copy
+#define csum_partial_copy(src, dst, len, sum)	\
+	csum_partial_copy_generic((src), (dst), (len), (sum), 0, 0)
+#define csum_partial_copy_fromuser(src, dst, len, sum)	\
+	csum_partial_copy_generic((src), (dst), (len), (sum), 0, 0)
+
 
 /*
- * this is a new version of the above that records errors it finds in *errp,
- * but continues and zeros the rest of the buffer.
- *
- * right now - it just calls csum_partial_copy()
- *   -- Cort
+ * turns a 32-bit partial checksum (e.g. from csum_partial) into a
+ * 1's complement 16-bit checksum.
  */
-extern __inline__
-unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
-						int len, int sum, int *err_ptr)
+static inline unsigned int csum_fold(unsigned int sum)
 {
-	int *dst_err_ptr=NULL;
-	return csum_partial_copy( src, dst, len, sum);
+	unsigned int tmp;
+
+	/* swap the two 16-bit halves of sum */
+	__asm__("rlwinm %0,%1,16,0,31" : "=r" (tmp) : "r" (sum));
+	/* if there is a carry from adding the two 16-bit halves,
+	   it will carry from the lower half into the upper half,
+	   giving us the correct sum in the upper half. */
+	sum = ~(sum + tmp) >> 16;
+	return sum;
 }
 
 /*
  * this routine is used for miscellaneous IP-like checksums, mainly
  * in icmp.c
-A */
+ */
+static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
+{
+	return csum_fold(csum_partial(buff, len, 0));
+}
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.  ihl is the number
+ * of 32-bit words and is always >= 5.
+ */
+extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+extern unsigned short csum_tcpudp_magic(unsigned long saddr,
+					unsigned long daddr,
+					unsigned short len,
+					unsigned short proto,
+					unsigned int sum);
 
-extern unsigned short ip_compute_csum(unsigned char * buff, int len);
-extern unsigned int csum_fold(unsigned int sum);
 #endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov