checksum_32.h 1.2 KB

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