1 /* 2 * Licensed under the GPL 3 */ 4 5 #ifndef __UM_SYSDEP_CHECKSUM_H 6 #define __UM_SYSDEP_CHECKSUM_H 7 8 static inline __sum16 ip_compute_csum(const void *buff, int len) 9 { 10 return csum_fold (csum_partial(buff, len, 0)); 11 } 12 13 #define _HAVE_ARCH_IPV6_CSUM 14 static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, 15 const struct in6_addr *daddr, 16 __u32 len, __u8 proto, 17 __wsum sum) 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 42 static __inline__ __wsum csum_and_copy_to_user(const void *src, 43 void __user *dst, 44 int len, __wsum sum, int *err_ptr) 45 { 46 if (access_ok(VERIFY_WRITE, dst, len)) { 47 if (copy_to_user(dst, src, len)) { 48 *err_ptr = -EFAULT; 49 return (__force __wsum)-1; 50 } 51 52 return csum_partial(src, len, sum); 53 } 54 55 if (len) 56 *err_ptr = -EFAULT; 57 58 return (__force __wsum)-1; /* invalid checksum */ 59 } 60 61 #endif 62