Commit | Line | Data |
---|---|---|
c16d56a3 | 1 | /* |
1da177e4 LT |
2 | * Licensed under the GPL |
3 | */ | |
4 | ||
5 | #ifndef __UM_SYSDEP_CHECKSUM_H | |
6 | #define __UM_SYSDEP_CHECKSUM_H | |
7 | ||
abf419b8 | 8 | static inline __sum16 ip_compute_csum(const void *buff, int len) |
1da177e4 LT |
9 | { |
10 | return csum_fold (csum_partial(buff, len, 0)); | |
11 | } | |
12 | ||
13 | #define _HAVE_ARCH_IPV6_CSUM | |
abf419b8 AV |
14 | static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, |
15 | const struct in6_addr *daddr, | |
1e940829 | 16 | __u32 len, __u8 proto, |
abf419b8 | 17 | __wsum sum) |
1da177e4 LT |
18 | { |
19 | __asm__( | |
20 | "addl 0(%1), %0 ;\n" | |
21 | "adcl 4(%1), %0 ;\n" | |
22 | "adcl 8(%1), %0 ;\n" | |
23 | "adcl 12(%1), %0 ;\n" | |
24 | "adcl 0(%2), %0 ;\n" | |
25 | "adcl 4(%2), %0 ;\n" | |
26 | "adcl 8(%2), %0 ;\n" | |
27 | "adcl 12(%2), %0 ;\n" | |
28 | "adcl %3, %0 ;\n" | |
29 | "adcl %4, %0 ;\n" | |
30 | "adcl $0, %0 ;\n" | |
31 | : "=&r" (sum) | |
32 | : "r" (saddr), "r" (daddr), | |
33 | "r"(htonl(len)), "r"(htonl(proto)), "0"(sum)); | |
34 | ||
35 | return csum_fold(sum); | |
36 | } | |
37 | ||
38 | /* | |
39 | * Copy and checksum to user | |
40 | */ | |
41 | #define HAVE_CSUM_COPY_USER | |
abf419b8 AV |
42 | static __inline__ __wsum csum_and_copy_to_user(const void *src, |
43 | void __user *dst, | |
44 | int len, __wsum sum, int *err_ptr) | |
1da177e4 | 45 | { |
abf419b8 AV |
46 | if (access_ok(VERIFY_WRITE, dst, len)) { |
47 | if (copy_to_user(dst, src, len)) { | |
7d37c6d5 | 48 | *err_ptr = -EFAULT; |
abf419b8 | 49 | return (__force __wsum)-1; |
7d37c6d5 BS |
50 | } |
51 | ||
52 | return csum_partial(src, len, sum); | |
53 | } | |
1da177e4 LT |
54 | |
55 | if (len) | |
56 | *err_ptr = -EFAULT; | |
57 | ||
abf419b8 | 58 | return (__force __wsum)-1; /* invalid checksum */ |
1da177e4 LT |
59 | } |
60 | ||
61 | #endif |