8 #include <linux/compiler.h>
9 #include <linux/module.h>
10 #include <asm/checksum.h>
12 static inline unsigned short from32to16(
unsigned a)
14 unsigned short b = a >> 16;
15 asm(
"addw %w2,%w0\n\t"
34 static unsigned do_csum(
const unsigned char *buff,
unsigned len)
41 odd = 1 & (
unsigned long) buff;
49 if (2 & (
unsigned long) buff) {
50 result += *(
unsigned short *)buff;
59 if (4 & (
unsigned long) buff) {
60 result += *(
unsigned int *) buff;
71 asm(
"addq 0*8(%[src]),%[res]\n\t"
72 "adcq 1*8(%[src]),%[res]\n\t"
73 "adcq 2*8(%[src]),%[res]\n\t"
74 "adcq 3*8(%[src]),%[res]\n\t"
75 "adcq 4*8(%[src]),%[res]\n\t"
76 "adcq 5*8(%[src]),%[res]\n\t"
77 "adcq 6*8(%[src]),%[res]\n\t"
78 "adcq 7*8(%[src]),%[res]\n\t"
93 :
"m" (*(
unsigned long *)buff),
98 result = add32_with_carry(result>>32,
102 result += *(
unsigned int *) buff;
107 result += *(
unsigned short *) buff;
113 result = add32_with_carry(result>>32, result & 0xffffffff);
115 result = from32to16(result);
116 result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);