linux/include/asm-blackfin/checksum.h
<<
>>
Prefs
   1#ifndef _BFIN_CHECKSUM_H
   2#define _BFIN_CHECKSUM_H
   3
   4/*
   5 * MODIFIED FOR BFIN April 30, 2001 akbar.hussain@lineo.com
   6 *
   7 * computes the checksum of a memory block at buff, length len,
   8 * and adds in "sum" (32-bit)
   9 *
  10 * returns a 32-bit number suitable for feeding into itself
  11 * or csum_tcpudp_magic
  12 *
  13 * this function must be called with even lengths, except
  14 * for the last fragment, which may be odd
  15 *
  16 * it's best to have buff aligned on a 32-bit boundary
  17 */
  18unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum);
  19
  20/*
  21 * the same as csum_partial, but copies from src while it
  22 * checksums
  23 *
  24 * here even more important to align src and dst on a 32-bit (or even
  25 * better 64-bit) boundary
  26 */
  27
  28unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst,
  29                               int len, int sum);
  30
  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
  38extern unsigned int csum_partial_copy_from_user(const unsigned char *src,
  39                                                unsigned char *dst, int len,
  40                                                int sum, int *csum_err);
  41
  42#define csum_partial_copy_nocheck(src, dst, len, sum)   \
  43        csum_partial_copy((src), (dst), (len), (sum))
  44
  45unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl);
  46
  47/*
  48 *      Fold a partial checksum
  49 */
  50
  51static inline unsigned int csum_fold(unsigned int sum)
  52{
  53        while (sum >> 16)
  54                sum = (sum & 0xffff) + (sum >> 16);
  55        return ((~(sum << 16)) >> 16);
  56}
  57
  58/*
  59 * computes the checksum of the TCP/UDP pseudo-header
  60 * returns a 16-bit checksum, already complemented
  61 */
  62
  63static inline unsigned int
  64csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
  65                   unsigned short proto, unsigned int sum)
  66{
  67
  68        __asm__ ("%0 = %0 + %1;\n\t"
  69                 "CC = AC0;\n\t"
  70                 "if !CC jump 4;\n\t"
  71                 "%0 = %0 + %4;\n\t"
  72                 "%0 = %0 + %2;\n\t"
  73                 "CC = AC0;\n\t"
  74                 "if !CC jump 4;\n\t"
  75                 "%0 = %0 + %4;\n\t"
  76                 "%0 = %0 + %3;\n\t"
  77                 "CC = AC0;\n\t"
  78                 "if !CC jump 4;\n\t"
  79                 "%0 = %0 + %4;\n\t"
  80                 "NOP;\n\t"
  81                 : "=d" (sum)
  82                 : "d" (daddr), "d" (saddr), "d" ((ntohs(len)<<16)+proto*256), "d" (1), "0"(sum));
  83
  84        return (sum);
  85}
  86
  87static inline unsigned short int
  88csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
  89                  unsigned short proto, unsigned int sum)
  90{
  91        return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
  92}
  93
  94/*
  95 * this routine is used for miscellaneous IP-like checksums, mainly
  96 * in icmp.c
  97 */
  98
  99extern unsigned short ip_compute_csum(const unsigned char *buff, int len);
 100
 101#endif                          /* _BFIN_CHECKSUM_H */
 102