1#ifndef __UM_CHECKSUM_H
2#define __UM_CHECKSUM_H
3
4#include <linux/string.h>
5#include <linux/in6.h>
6#include <linux/uaccess.h>
7
8
9
10
11
12
13
14
15
16
17
18
19
20extern __wsum csum_partial(const void *buff, int len, __wsum sum);
21
22
23
24
25
26
27
28
29
30static __inline__
31__wsum csum_partial_copy_nocheck(const void *src, void *dst,
32 int len, __wsum sum)
33{
34 memcpy(dst, src, len);
35 return csum_partial(dst, len, sum);
36}
37
38
39
40
41
42
43
44
45
46static __inline__
47__wsum csum_partial_copy_from_user(const void __user *src, void *dst,
48 int len, __wsum sum, int *err_ptr)
49{
50 if (copy_from_user(dst, src, len)) {
51 *err_ptr = -EFAULT;
52 return (__force __wsum)-1;
53 }
54
55 return csum_partial(dst, len, sum);
56}
57
58
59
60
61
62
63
64
65
66static inline __sum16 csum_fold(__wsum sum)
67{
68 __asm__(
69 " addl %1,%0\n"
70 " adcl $0xffff,%0"
71 : "=r" (sum)
72 : "r" ((__force u32)sum << 16),
73 "0" ((__force u32)sum & 0xffff0000)
74 );
75 return (__force __sum16)(~(__force u32)sum >> 16);
76}
77
78
79
80
81
82
83
84
85
86
87
88
89static inline __wsum
90csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
91 __u8 proto, __wsum sum)
92{
93 asm(" addl %1, %0\n"
94 " adcl %2, %0\n"
95 " adcl %3, %0\n"
96 " adcl $0, %0\n"
97 : "=r" (sum)
98 : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum));
99 return sum;
100}
101
102
103
104
105
106static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
107 __u32 len, __u8 proto,
108 __wsum sum)
109{
110 return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
111}
112
113
114
115
116
117
118static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
119{
120 unsigned int sum;
121
122 asm( " movl (%1), %0\n"
123 " subl $4, %2\n"
124 " jbe 2f\n"
125 " addl 4(%1), %0\n"
126 " adcl 8(%1), %0\n"
127 " adcl 12(%1), %0\n"
128 "1: adcl 16(%1), %0\n"
129 " lea 4(%1), %1\n"
130 " decl %2\n"
131 " jne 1b\n"
132 " adcl $0, %0\n"
133 " movl %0, %2\n"
134 " shrl $16, %0\n"
135 " addw %w2, %w0\n"
136 " adcl $0, %0\n"
137 " notl %0\n"
138 "2:"
139
140
141
142 : "=r" (sum), "=r" (iph), "=r" (ihl)
143 : "1" (iph), "2" (ihl)
144 : "memory");
145 return (__force __sum16)sum;
146}
147
148#ifdef CONFIG_X86_32
149# include "checksum_32.h"
150#else
151# include "checksum_64.h"
152#endif
153
154#endif
155