diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-01-07 02:33:00 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1997-01-07 02:33:00 +0000 |
commit | beb116954b9b7f3bb56412b2494b562f02b864b1 (patch) | |
tree | 120e997879884e1b9d93b265221b939d2ef1ade1 /include/net/checksum.h | |
parent | 908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff) |
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'include/net/checksum.h')
-rw-r--r-- | include/net/checksum.h | 273 |
1 files changed, 64 insertions, 209 deletions
diff --git a/include/net/checksum.h b/include/net/checksum.h index 7f9492328..2fb596b13 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h @@ -15,223 +15,78 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#ifndef _CHECKSUM_H -#define _CHECKSUM_H - -#include <asm/byteorder.h> -#include "ip.h" /* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. + * Fixes: * - * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by - * Arnt Gulbrandsen. + * Ralf Baechle : generic ipv6 checksum + * <ralf@waldorf-gmbh.de> */ -static inline unsigned short ip_fast_csum(unsigned char * iph, - unsigned int ihl) { - unsigned short int sum; - -#ifdef __i386__ - __asm__(" - movl (%%esi), %%eax - andl $15, %%ecx - subl $4, %%ecx - jbe 2f - addl 4(%%esi), %%eax - adcl 8(%%esi), %%eax - adcl 12(%%esi), %%eax -1: adcl 16(%%esi), %%eax - lea 4(%%esi), %%esi - decl %%ecx - jne 1b - adcl $0, %%eax - movl %%eax, %%ecx - shrl $16, %%eax - addw %%ecx, %%eax - adcl $0, %%eax - notl %%eax - andl $65535, %%eax -2: - " - : "=a" (sum) - : "S" (iph), "c"(ihl) - : "ax", "cx", "si"); -#elif defined (__mips__) - unsigned long dummy1, dummy2; - /* - * This is optimized for 32-bit MIPS processors. - * I tried it in plain C but the generated code looks to bad to - * use with old first generation MIPS CPUs. - * Using 64-bit code could even further improve these routines. - */ - __asm__(" - .set noreorder - .set noat - lw %0,(%3) - subu %1,4 - blez %1,2f - sll %1,%4,2 # delay slot - lw %2,4(%3) - addu %1,%3 # delay slot - addu %0,%2 - sltu $1,%0,%2 - lw %2,8(%3) - addu %0,$1 - addu %0,%2 - sltu $1,%0,%2 - lw %2,12(%3) - addu %0,$1 - addu %0,%2 - sltu $1,%0,%2 - addu %0,$1 -1: lw %2,16(%3) - addu %1,4 - addu %0,%2 - sltu $1,%0,%2 - bne %1,%3,1b - addu %0,$1 # delay slot - srl $1,%0,16 - addu %0,$1 - sltu $1,%0,$1 - addu %0,$1 - nor %0,$0,%0 - andi %0,0xffff -2: .set at - .set reorder" - : "=r" (sum), "=r" (dummy1), "=r" (dummy2) - : "r" (iph), "r"(ihl) - : "$1"); -#else -#error Not implemented for this CPU -#endif - return(sum); -} - - +#ifndef _CHECKSUM_H +#define _CHECKSUM_H -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ - -static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, - unsigned long daddr, - unsigned short len, - unsigned short proto, - unsigned int sum) { -#ifdef __i386__ - __asm__(" - addl %2, %0 - adcl %3, %0 - adcl %4, %0 - adcl $0, %0 - movl %0, %2 - shrl $16, %2 - addw %2, %0 - adcl $0, %0 - notl %0 - andl $65535, %0 - " - : "=r" (sum) - : "0" (daddr), "S"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum) - : "si" ); -#elif defined (__mips__) - __asm__(" - .set noat - addu %0,%2 - sltu $1,%0,%2 - addu %0,$1 - addu %0,%3 - sltu $1,%0,%3 - addu %0,$1 - addu %0,%4 - sltu $1,%0,%4 - addu %0,$1 - srl $1,%0,16 - addu %0,$1 - sltu $1,%0,$1 - addu %0,$1 - nor %0,$0,%0 - andi %0,0xffff - .set at" - : "=r" (sum) - : "0" (daddr), "r"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum) - : "$1"); -#else -#error Not implemented for this CPU -#endif - return((unsigned short)sum); +#include <asm/byteorder.h> +#include <net/ip.h> +#include <asm/checksum.h> + +#ifndef _HAVE_ARCH_IPV6_CSUM + +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u16 len, + unsigned short proto, + unsigned int csum) +{ + int carry; + __u32 ulen; + __u32 uproto; + + csum += saddr->s6_addr32[0]; + carry = (csum < saddr->s6_addr32[0]); + csum += carry; + + csum += saddr->s6_addr32[1]; + carry = (csum < saddr->s6_addr32[1]); + csum += carry; + + csum += saddr->s6_addr32[2]; + carry = (csum < saddr->s6_addr32[2]); + csum += carry; + + csum += saddr->s6_addr32[3]; + carry = (csum < saddr->s6_addr32[3]); + csum += carry; + + csum += daddr->s6_addr32[0]; + carry = (csum < daddr->s6_addr32[0]); + csum += carry; + + csum += daddr->s6_addr32[1]; + carry = (csum < daddr->s6_addr32[1]); + csum += carry; + + csum += daddr->s6_addr32[2]; + carry = (csum < daddr->s6_addr32[2]); + csum += carry; + + csum += daddr->s6_addr32[3]; + carry = (csum < daddr->s6_addr32[3]); + csum += carry; + + ulen = htonl((__u32) len); + csum += ulen; + carry = (csum < ulen); + csum += carry; + + uproto = htonl(proto); + csum += uproto; + carry = (csum < uproto); + csum += carry; + + return csum_fold(csum); } - - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum); - - - -/* - * the same as csum_partial, but copies from fs:src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -unsigned int csum_partial_copyffs( char *src, char *dst, int len, int sum); - - - - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -static inline unsigned short ip_compute_csum(unsigned char * buff, int len) { - unsigned short int sum; - -#ifdef __i386__ - __asm__(" - movl %%eax, %%ecx - shrl $16, %%ecx - addw %%cx, %%ax - adcl $0, %%eax - notl %%eax - andl $65535, %%eax - " - : "=a"(sum) - : "a" (csum_partial(buff, len, 0)) - : "cx"); -#elif defined (__mips__) - __asm__(" - .set noat - srl $1,%0,16 - addu %0,$1 - sltu $1,%0,$1 - nor %0,$0,%0 - andi %0,0xffff - .set at" - : "=r"(sum) - : "r" (csum_partial(buff, len, 0)) - : "$1"); -#else -#error Not implemented for this CPU #endif - return(sum); -} #endif |