Al Viro | c16d56a | 2011-08-18 20:02:09 +0100 | [diff] [blame] | 1 | /* |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 | * Licensed under the GPL |
| 3 | */ |
| 4 | |
| 5 | #ifndef __UM_SYSDEP_CHECKSUM_H |
| 6 | #define __UM_SYSDEP_CHECKSUM_H |
| 7 | |
Al Viro | abf419b | 2006-11-14 21:19:22 -0800 | [diff] [blame] | 8 | static inline __sum16 ip_compute_csum(const void *buff, int len) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 9 | { |
| 10 | return csum_fold (csum_partial(buff, len, 0)); |
| 11 | } |
| 12 | |
| 13 | #define _HAVE_ARCH_IPV6_CSUM |
Al Viro | abf419b | 2006-11-14 21:19:22 -0800 | [diff] [blame] | 14 | static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, |
| 15 | const struct in6_addr *daddr, |
| 16 | __u32 len, unsigned short proto, |
| 17 | __wsum sum) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |
Al Viro | abf419b | 2006-11-14 21:19:22 -0800 | [diff] [blame] | 42 | static __inline__ __wsum csum_and_copy_to_user(const void *src, |
| 43 | void __user *dst, |
| 44 | int len, __wsum sum, int *err_ptr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 45 | { |
Al Viro | abf419b | 2006-11-14 21:19:22 -0800 | [diff] [blame] | 46 | if (access_ok(VERIFY_WRITE, dst, len)) { |
| 47 | if (copy_to_user(dst, src, len)) { |
Bodo Stroesser | 7d37c6d | 2005-05-05 16:15:36 -0700 | [diff] [blame] | 48 | *err_ptr = -EFAULT; |
Al Viro | abf419b | 2006-11-14 21:19:22 -0800 | [diff] [blame] | 49 | return (__force __wsum)-1; |
Bodo Stroesser | 7d37c6d | 2005-05-05 16:15:36 -0700 | [diff] [blame] | 50 | } |
| 51 | |
| 52 | return csum_partial(src, len, sum); |
| 53 | } |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 54 | |
| 55 | if (len) |
| 56 | *err_ptr = -EFAULT; |
| 57 | |
Al Viro | abf419b | 2006-11-14 21:19:22 -0800 | [diff] [blame] | 58 | return (__force __wsum)-1; /* invalid checksum */ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 59 | } |
| 60 | |
| 61 | #endif |