diff options
Diffstat (limited to 'lib/checksum.c')
| -rw-r--r-- | lib/checksum.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/lib/checksum.c b/lib/checksum.c index b2e2fd46846..129775eb6de 100644 --- a/lib/checksum.c +++ b/lib/checksum.c @@ -32,12 +32,13 @@ /* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most of the assembly has to go. */ -#include <linux/module.h> +#include <linux/export.h> #include <net/checksum.h> #include <asm/byteorder.h> -static inline unsigned short from32to16(unsigned long x) +#ifndef do_csum +static inline unsigned short from32to16(unsigned int x) { /* add up 16-bit and 16-bit for 16+c bit */ x = (x & 0xffff) + (x >> 16); @@ -48,40 +49,37 @@ static inline unsigned short from32to16(unsigned long x) static unsigned int do_csum(const unsigned char *buff, int len) { - int odd, count; - unsigned long result = 0; + int odd; + unsigned int result = 0; if (len <= 0) goto out; odd = 1 & (unsigned long) buff; if (odd) { #ifdef __LITTLE_ENDIAN - result = *buff; -#else result += (*buff << 8); +#else + result = *buff; #endif len--; buff++; } - count = len >> 1; /* nr of 16-bit words.. */ - if (count) { + if (len >= 2) { if (2 & (unsigned long) buff) { result += *(unsigned short *) buff; - count--; len -= 2; buff += 2; } - count >>= 1; /* nr of 32-bit words.. */ - if (count) { - unsigned long carry = 0; + if (len >= 4) { + const unsigned char *end = buff + ((unsigned)len & ~3); + unsigned int carry = 0; do { - unsigned long w = *(unsigned int *) buff; - count--; + unsigned int w = *(unsigned int *) buff; buff += 4; result += carry; result += w; carry = (w > result); - } while (count); + } while (buff < end); result += carry; result = (result & 0xffff) + (result >> 16); } @@ -102,7 +100,9 @@ static unsigned int do_csum(const unsigned char *buff, int len) out: return result; } +#endif +#ifndef ip_fast_csum /* * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. @@ -112,6 +112,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) return (__force __sum16)~do_csum(iph, ihl*4); } EXPORT_SYMBOL(ip_fast_csum); +#endif /* * computes the checksum of a memory block at buff, length len, |
