~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-arm/checksum.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/include/asm-arm/checksum.h
  3  *
  4  * IP checksum routines
  5  *
  6  * Copyright (C) Original authors of ../asm-i386/checksum.h
  7  * Copyright (C) 1996-1999 Russell King
  8  */
  9 #ifndef __ASM_ARM_CHECKSUM_H
 10 #define __ASM_ARM_CHECKSUM_H
 11 
 12 /*
 13  * computes the checksum of a memory block at buff, length len,
 14  * and adds in "sum" (32-bit)
 15  *
 16  * returns a 32-bit number suitable for feeding into itself
 17  * or csum_tcpudp_magic
 18  *
 19  * this function must be called with even lengths, except
 20  * for the last fragment, which may be odd
 21  *
 22  * it's best to have buff aligned on a 32-bit boundary
 23  */
 24 unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
 25 
 26 /*
 27  * the same as csum_partial, but copies from src while it
 28  * checksums, and handles user-space pointer exceptions correctly, when needed.
 29  *
 30  * here even more important to align src and dst on a 32-bit (or even
 31  * better 64-bit) boundary
 32  */
 33 
 34 unsigned int
 35 csum_partial_copy_nocheck(const char *src, char *dst, int len, int sum);
 36 
 37 unsigned int
 38 csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr);
 39 
 40 /*
 41  * These are the old (and unsafe) way of doing checksums, a warning message will be
 42  * printed if they are used and an exception occurs.
 43  *
 44  * these functions should go away after some time.
 45  */
 46 #define csum_partial_copy(src,dst,len,sum)      csum_partial_copy_nocheck(src,dst,len,sum)
 47 
 48 /*
 49  *      This is a version of ip_compute_csum() optimized for IP headers,
 50  *      which always checksum on 4 octet boundaries.
 51  */
 52 static inline unsigned short
 53 ip_fast_csum(unsigned char * iph, unsigned int ihl)
 54 {
 55         unsigned int sum, tmp1;
 56 
 57         __asm__ __volatile__(
 58         "ldr    %0, [%1], #4            @ ip_fast_csum
 59         ldr     %3, [%1], #4
 60         sub     %2, %2, #5
 61         adds    %0, %0, %3
 62         ldr     %3, [%1], #4
 63         adcs    %0, %0, %3
 64         ldr     %3, [%1], #4
 65         adcs    %0, %0, %3
 66 1:      ldr     %3, [%1], #4
 67         adcs    %0, %0, %3
 68         tst     %2, #15
 69         subne   %2, %2, #1
 70         bne     1b
 71         adc     %0, %0, #0
 72         adds    %0, %0, %0, lsl #16
 73         addcs   %0, %0, #0x10000
 74         mvn     %0, %0
 75         mov     %0, %0, lsr #16
 76         "
 77         : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
 78         : "1" (iph), "2" (ihl)
 79         : "cc");
 80         return sum;
 81 }
 82 
 83 /*
 84  *      Fold a partial checksum without adding pseudo headers
 85  */
 86 static inline unsigned int
 87 csum_fold(unsigned int sum)
 88 {
 89         __asm__(
 90         "adds   %0, %1, %1, lsl #16     @ csum_fold
 91         addcs   %0, %0, #0x10000"
 92         : "=r" (sum)
 93         : "r" (sum)
 94         : "cc");
 95         return (~sum) >> 16;
 96 }
 97 
 98 static inline unsigned int
 99 csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
100                    unsigned int proto, unsigned int sum)
101 {
102         __asm__(
103         "adds   %0, %1, %2              @ csum_tcpudp_nofold
104         adcs    %0, %0, %3
105         adcs    %0, %0, %4
106         adcs    %0, %0, %5
107         adc     %0, %0, #0"
108         : "=&r"(sum)
109         : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len) << 16), "Ir" (proto << 8)
110         : "cc");
111         return sum;
112 }       
113 /*
114  * computes the checksum of the TCP/UDP pseudo-header
115  * returns a 16-bit checksum, already complemented
116  */
117 static inline unsigned short int
118 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
119                   unsigned int proto, unsigned int sum)
120 {
121         __asm__(
122         "adds   %0, %1, %2              @ csum_tcpudp_magic
123         adcs    %0, %0, %3
124         adcs    %0, %0, %4
125         adcs    %0, %0, %5
126         adc     %0, %0, #0
127         adds    %0, %0, %0, lsl #16
128         addcs   %0, %0, #0x10000
129         mvn     %0, %0"
130         : "=&r"(sum)
131         : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (proto << 8)
132         : "cc");
133         return sum >> 16;
134 }
135 
136 
137 /*
138  * this routine is used for miscellaneous IP-like checksums, mainly
139  * in icmp.c
140  */
141 static inline unsigned short
142 ip_compute_csum(unsigned char * buff, int len)
143 {
144         return csum_fold(csum_partial(buff, len, 0));
145 }
146 
147 #define _HAVE_ARCH_IPV6_CSUM
148 extern unsigned long
149 __csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len,
150                 __u32 proto, unsigned int sum);
151 
152 extern __inline__ unsigned short int
153 csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len,
154                 unsigned short proto, unsigned int sum)
155 {
156         return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len),
157                                            htonl(proto), sum));
158 }
159 #endif
160 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.