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

TOMOYO Linux Cross Reference
Linux/include/asm-arm26/checksum.h

Version: ~ [ linux-5.13-rc7 ] ~ [ linux-5.12.12 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.45 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.127 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.195 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.237 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.273 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.273 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
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          \n\
 59         ldr     %3, [%1], #4                                    \n\
 60         sub     %2, %2, #5                                      \n\
 61         adds    %0, %0, %3                                      \n\
 62         ldr     %3, [%1], #4                                    \n\
 63         adcs    %0, %0, %3                                      \n\
 64         ldr     %3, [%1], #4                                    \n\
 65 1:      adcs    %0, %0, %3                                      \n\
 66         ldr     %3, [%1], #4                                    \n\
 67         tst     %2, #15                 @ do this carefully     \n\
 68         subne   %2, %2, #1              @ without destroying    \n\
 69         bne     1b                      @ the carry flag        \n\
 70         adcs    %0, %0, %3                                      \n\
 71         adc     %0, %0, #0                                      \n\
 72         adds    %0, %0, %0, lsl #16                             \n\
 73         addcs   %0, %0, #0x10000                                \n\
 74         mvn     %0, %0                                          \n\
 75         mov     %0, %0, lsr #16"
 76         : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
 77         : "1" (iph), "2" (ihl)
 78         : "cc");
 79         return sum;
 80 }
 81 
 82 /*
 83  *      Fold a partial checksum without adding pseudo headers
 84  */
 85 static inline unsigned int
 86 csum_fold(unsigned int sum)
 87 {
 88         __asm__(
 89         "adds   %0, %1, %1, lsl #16     @ csum_fold             \n\
 90         addcs   %0, %0, #0x10000"
 91         : "=r" (sum)
 92         : "r" (sum)
 93         : "cc");
 94         return (~sum) >> 16;
 95 }
 96 
 97 static inline unsigned int
 98 csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
 99                    unsigned int proto, unsigned int sum)
100 {
101         __asm__(
102         "adds   %0, %1, %2              @ csum_tcpudp_nofold    \n\
103         adcs    %0, %0, %3                                      \n\
104         adcs    %0, %0, %4                                      \n\
105         adcs    %0, %0, %5                                      \n\
106         adc     %0, %0, #0"
107         : "=&r"(sum)
108         : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len) << 16), "Ir" (proto << 8)
109         : "cc");
110         return sum;
111 }       
112 /*
113  * computes the checksum of the TCP/UDP pseudo-header
114  * returns a 16-bit checksum, already complemented
115  */
116 static inline unsigned short int
117 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
118                   unsigned int proto, unsigned int sum)
119 {
120         __asm__(
121         "adds   %0, %1, %2              @ csum_tcpudp_magic     \n\
122         adcs    %0, %0, %3                                      \n\
123         adcs    %0, %0, %4                                      \n\
124         adcs    %0, %0, %5                                      \n\
125         adc     %0, %0, #0                                      \n\
126         adds    %0, %0, %0, lsl #16                             \n\
127         addcs   %0, %0, #0x10000                                \n\
128         mvn     %0, %0"
129         : "=&r"(sum)
130         : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (proto << 8)
131         : "cc");
132         return sum >> 16;
133 }
134 
135 
136 /*
137  * this routine is used for miscellaneous IP-like checksums, mainly
138  * in icmp.c
139  */
140 static inline unsigned short
141 ip_compute_csum(unsigned char * buff, int len)
142 {
143         return csum_fold(csum_partial(buff, len, 0));
144 }
145 
146 #define _HAVE_ARCH_IPV6_CSUM
147 extern unsigned long
148 __csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len,
149                 __u32 proto, unsigned int sum);
150 
151 static inline unsigned short int
152 csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len,
153                 unsigned short proto, unsigned int sum)
154 {
155         return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len),
156                                            htonl(proto), sum));
157 }
158 #endif
159 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp