24 #include <linux/module.h>
25 #include <linux/string.h>
27 #include <asm/byteorder.h>
30 #include <asm/intrinsics.h>
34 #define SIGN(x, y) ((0x8000ULL*x)<<y)
35 #define CARRY(x, y) ((0x0002ULL*x)<<y)
36 #define SELECT(x, y) ((0x0001ULL*x)<<y)
38 #define VR_NEGATE(a, b, c, d) (SIGN(a, 48) + SIGN(b, 32) + SIGN(c, 16) \
40 #define VR_CARRY(a, b, c, d) (CARRY(a, 48) + CARRY(b, 32) + CARRY(c, 16) \
42 #define VR_SELECT(a, b, c, d) (SELECT(a, 48) + SELECT(b, 32) + SELECT(c, 16) \
47 static inline unsigned short from64to16(
u64 x)
64 unsigned short len,
unsigned short proto,
69 (
__force u64)sum + ((len + proto) << 8));
73 unsigned short len,
unsigned short proto,
84 result = (result & 0xffffffff
UL) + (result >> 32);
86 result = (result & 0xffffffff
UL) + (result >> 32);
100 unsigned int do_csum(
const void *voidptr,
int len)
102 u64 sum0, sum1, x0, x1, *ptr8_o, *ptr8_e, *ptr8;
104 const char *
ptr = voidptr;
105 unsigned short *ptr2;
111 start = 0xF & (16-(((
int) ptr) & 0xF)) ;
113 start = start &
mask ;
122 sum0 += (
u64) (ptr[0] << 8);
123 ptr2 = (
unsigned short *) &ptr[start & 1];
125 sum1 += (
u64) ptr2[0];
126 ptr4 = (
unsigned int *) &ptr[start & 3];
133 ptr8 = (
u64 *) &ptr[start & 7];
140 ptr8_o = (
u64 *) (ptr + start);
141 ptr8_e = (
u64 *) (ptr + start + 8);
144 x0 = *ptr8_e; ptr8_e += 2;
145 x1 = *ptr8_o; ptr8_o += 2;
147 for (i = 0; i < mid-1; i++) {
154 x0 = *ptr8_e; ptr8_e += 2;
155 x1 = *ptr8_o; ptr8_o += 2;
163 ptr4 = (
unsigned int *) &ptr[start + (mid * 16) + (end & 8)];
170 ptr2 = (
unsigned short *) &ptr[start + (mid * 16) + (end & 12)];
172 sum0 += (
u64) ptr2[0];
175 sum1 += (
u64) ptr[start + (mid * 16) + (end & 14)];
177 ptr8 = (
u64 *) &ptr[start + (mid * 16)];
190 sum0 = (sum0 << 8) | (0xFF & (sum0 >> 8));
192 return 0xFFFF & sum0;