checksum.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * Copyright 2004-2009 Analog Devices Inc.
  3. * akbar.hussain@lineo.com
  4. *
  5. * Licensed under the GPL-2 or later.
  6. */
  7. #ifndef _BFIN_CHECKSUM_H
  8. #define _BFIN_CHECKSUM_H
  9. /*
  10. * computes the checksum of a memory block at buff, length len,
  11. * and adds in "sum" (32-bit)
  12. *
  13. * returns a 32-bit number suitable for feeding into itself
  14. * or csum_tcpudp_magic
  15. *
  16. * this function must be called with even lengths, except
  17. * for the last fragment, which may be odd
  18. *
  19. * it's best to have buff aligned on a 32-bit boundary
  20. */
  21. __wsum csum_partial(const void *buff, int len, __wsum sum);
  22. /*
  23. * the same as csum_partial, but copies from src while it
  24. * checksums
  25. *
  26. * here even more important to align src and dst on a 32-bit (or even
  27. * better 64-bit) boundary
  28. */
  29. __wsum csum_partial_copy(const void *src, void *dst,
  30. int len, __wsum sum);
  31. /*
  32. * the same as csum_partial_copy, but copies from user space.
  33. *
  34. * here even more important to align src and dst on a 32-bit (or even
  35. * better 64-bit) boundary
  36. */
  37. extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
  38. int len, __wsum sum, int *csum_err);
  39. #define csum_partial_copy_nocheck(src, dst, len, sum) \
  40. csum_partial_copy((src), (dst), (len), (sum))
  41. __sum16 ip_fast_csum(unsigned char *iph, unsigned int ihl);
  42. /*
  43. * Fold a partial checksum
  44. */
  45. static inline __sum16 csum_fold(__wsum sum)
  46. {
  47. while (sum >> 16)
  48. sum = (sum & 0xffff) + (sum >> 16);
  49. return ((~(sum << 16)) >> 16);
  50. }
  51. /*
  52. * computes the checksum of the TCP/UDP pseudo-header
  53. * returns a 16-bit checksum, already complemented
  54. */
  55. static inline __wsum
  56. csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
  57. unsigned short proto, __wsum sum)
  58. {
  59. unsigned int carry;
  60. __asm__ ("%0 = %0 + %2;\n\t"
  61. "CC = AC0;\n\t"
  62. "%1 = CC;\n\t"
  63. "%0 = %0 + %1;\n\t"
  64. "%0 = %0 + %3;\n\t"
  65. "CC = AC0;\n\t"
  66. "%1 = CC;\n\t"
  67. "%0 = %0 + %1;\n\t"
  68. "%0 = %0 + %4;\n\t"
  69. "CC = AC0;\n\t"
  70. "%1 = CC;\n\t"
  71. "%0 = %0 + %1;\n\t"
  72. : "=d" (sum), "=&d" (carry)
  73. : "d" (daddr), "d" (saddr), "d" ((len + proto) << 8), "0"(sum)
  74. : "CC");
  75. return (sum);
  76. }
  77. static inline __sum16
  78. csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
  79. unsigned short proto, __wsum sum)
  80. {
  81. return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
  82. }
  83. /*
  84. * this routine is used for miscellaneous IP-like checksums, mainly
  85. * in icmp.c
  86. */
  87. extern __sum16 ip_compute_csum(const void *buff, int len);
  88. #endif /* _BFIN_CHECKSUM_H */