This source file includes following definitions.
- csum_partial_copy_nocheck
- csum_partial_copy_from_user
- csum_fold
- ip_fast_csum
- csum_tcpudp_nofold
- csum_tcpudp_magic
- ip_compute_csum
- csum_ipv6_magic
- csum_and_copy_to_user
1
2
3
4
5
6
7
8
9
10
11 #ifndef _XTENSA_CHECKSUM_H
12 #define _XTENSA_CHECKSUM_H
13
14 #include <linux/in6.h>
15 #include <linux/uaccess.h>
16 #include <asm/core.h>
17
18
19
20
21
22
23
24
25
26
27
28
29
30 asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum);
31
32
33
34
35
36
37
38
39
40 asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
41 int len, __wsum sum,
42 int *src_err_ptr, int *dst_err_ptr);
43
44
45
46
47
48
49
50 static inline
51 __wsum csum_partial_copy_nocheck(const void *src, void *dst,
52 int len, __wsum sum)
53 {
54 return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL);
55 }
56
57 static inline
58 __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
59 int len, __wsum sum, int *err_ptr)
60 {
61 return csum_partial_copy_generic((__force const void *)src, dst,
62 len, sum, err_ptr, NULL);
63 }
64
65
66
67
68
69 static __inline__ __sum16 csum_fold(__wsum sum)
70 {
71 unsigned int __dummy;
72 __asm__("extui %1, %0, 16, 16\n\t"
73 "extui %0 ,%0, 0, 16\n\t"
74 "add %0, %0, %1\n\t"
75 "slli %1, %0, 16\n\t"
76 "add %0, %0, %1\n\t"
77 "extui %0, %0, 16, 16\n\t"
78 "neg %0, %0\n\t"
79 "addi %0, %0, -1\n\t"
80 "extui %0, %0, 0, 16\n\t"
81 : "=r" (sum), "=&r" (__dummy)
82 : "0" (sum));
83 return (__force __sum16)sum;
84 }
85
86
87
88
89
90 static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
91 {
92 unsigned int sum, tmp, endaddr;
93
94 __asm__ __volatile__(
95 "sub %0, %0, %0\n\t"
96 #if XCHAL_HAVE_LOOPS
97 "loopgtz %2, 2f\n\t"
98 #else
99 "beqz %2, 2f\n\t"
100 "slli %4, %2, 2\n\t"
101 "add %4, %4, %1\n\t"
102 "0:\t"
103 #endif
104 "l32i %3, %1, 0\n\t"
105 "add %0, %0, %3\n\t"
106 "bgeu %0, %3, 1f\n\t"
107 "addi %0, %0, 1\n\t"
108 "1:\t"
109 "addi %1, %1, 4\n\t"
110 #if !XCHAL_HAVE_LOOPS
111 "blt %1, %4, 0b\n\t"
112 #endif
113 "2:\t"
114
115
116
117 : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp),
118 "=&r" (endaddr)
119 : "1" (iph), "2" (ihl)
120 : "memory");
121
122 return csum_fold(sum);
123 }
124
125 static __inline__ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
126 __u32 len, __u8 proto,
127 __wsum sum)
128 {
129
130 #ifdef __XTENSA_EL__
131 unsigned long len_proto = (len + proto) << 8;
132 #elif defined(__XTENSA_EB__)
133 unsigned long len_proto = len + proto;
134 #else
135 # error processor byte order undefined!
136 #endif
137 __asm__("add %0, %0, %1\n\t"
138 "bgeu %0, %1, 1f\n\t"
139 "addi %0, %0, 1\n\t"
140 "1:\t"
141 "add %0, %0, %2\n\t"
142 "bgeu %0, %2, 1f\n\t"
143 "addi %0, %0, 1\n\t"
144 "1:\t"
145 "add %0, %0, %3\n\t"
146 "bgeu %0, %3, 1f\n\t"
147 "addi %0, %0, 1\n\t"
148 "1:\t"
149 : "=r" (sum), "=r" (len_proto)
150 : "r" (daddr), "r" (saddr), "1" (len_proto), "0" (sum));
151 return sum;
152 }
153
154
155
156
157
158 static __inline__ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
159 __u32 len, __u8 proto,
160 __wsum sum)
161 {
162 return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
163 }
164
165
166
167
168
169
170 static __inline__ __sum16 ip_compute_csum(const void *buff, int len)
171 {
172 return csum_fold (csum_partial(buff, len, 0));
173 }
174
175 #define _HAVE_ARCH_IPV6_CSUM
176 static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
177 const struct in6_addr *daddr,
178 __u32 len, __u8 proto,
179 __wsum sum)
180 {
181 unsigned int __dummy;
182 __asm__("l32i %1, %2, 0\n\t"
183 "add %0, %0, %1\n\t"
184 "bgeu %0, %1, 1f\n\t"
185 "addi %0, %0, 1\n\t"
186 "1:\t"
187 "l32i %1, %2, 4\n\t"
188 "add %0, %0, %1\n\t"
189 "bgeu %0, %1, 1f\n\t"
190 "addi %0, %0, 1\n\t"
191 "1:\t"
192 "l32i %1, %2, 8\n\t"
193 "add %0, %0, %1\n\t"
194 "bgeu %0, %1, 1f\n\t"
195 "addi %0, %0, 1\n\t"
196 "1:\t"
197 "l32i %1, %2, 12\n\t"
198 "add %0, %0, %1\n\t"
199 "bgeu %0, %1, 1f\n\t"
200 "addi %0, %0, 1\n\t"
201 "1:\t"
202 "l32i %1, %3, 0\n\t"
203 "add %0, %0, %1\n\t"
204 "bgeu %0, %1, 1f\n\t"
205 "addi %0, %0, 1\n\t"
206 "1:\t"
207 "l32i %1, %3, 4\n\t"
208 "add %0, %0, %1\n\t"
209 "bgeu %0, %1, 1f\n\t"
210 "addi %0, %0, 1\n\t"
211 "1:\t"
212 "l32i %1, %3, 8\n\t"
213 "add %0, %0, %1\n\t"
214 "bgeu %0, %1, 1f\n\t"
215 "addi %0, %0, 1\n\t"
216 "1:\t"
217 "l32i %1, %3, 12\n\t"
218 "add %0, %0, %1\n\t"
219 "bgeu %0, %1, 1f\n\t"
220 "addi %0, %0, 1\n\t"
221 "1:\t"
222 "add %0, %0, %4\n\t"
223 "bgeu %0, %4, 1f\n\t"
224 "addi %0, %0, 1\n\t"
225 "1:\t"
226 "add %0, %0, %5\n\t"
227 "bgeu %0, %5, 1f\n\t"
228 "addi %0, %0, 1\n\t"
229 "1:\t"
230 : "=r" (sum), "=&r" (__dummy)
231 : "r" (saddr), "r" (daddr),
232 "r" (htonl(len)), "r" (htonl(proto)), "0" (sum)
233 : "memory");
234
235 return csum_fold(sum);
236 }
237
238
239
240
241 #define HAVE_CSUM_COPY_USER
242 static __inline__ __wsum csum_and_copy_to_user(const void *src,
243 void __user *dst, int len,
244 __wsum sum, int *err_ptr)
245 {
246 if (access_ok(dst, len))
247 return csum_partial_copy_generic(src,dst,len,sum,NULL,err_ptr);
248
249 if (len)
250 *err_ptr = -EFAULT;
251
252 return (__force __wsum)-1;
253 }
254 #endif