Pull sem2mutex-ioc4 into release branch
[linux-2.6] / include / asm-v850 / checksum.h
1 /*
2  * include/asm-v850/checksum.h -- Checksum ops
3  *
4  *  Copyright (C) 2001,2005  NEC Corporation
5  *  Copyright (C) 2001,2005  Miles Bader <miles@gnu.org>
6  *
7  * This file is subject to the terms and conditions of the GNU General
8  * Public License.  See the file COPYING in the main directory of this
9  * archive for more details.
10  *
11  * Written by Miles Bader <miles@gnu.org>
12  */
13
14 #ifndef __V850_CHECKSUM_H__
15 #define __V850_CHECKSUM_H__
16
17 /*
18  * computes the checksum of a memory block at buff, length len,
19  * and adds in "sum" (32-bit)
20  *
21  * returns a 32-bit number suitable for feeding into itself
22  * or csum_tcpudp_magic
23  *
24  * this function must be called with even lengths, except
25  * for the last fragment, which may be odd
26  *
27  * it's best to have buff aligned on a 32-bit boundary
28  */
29 extern unsigned int csum_partial (const unsigned char * buff, int len,
30                                   unsigned int sum);
31
32 /*
33  * the same as csum_partial, but copies from src while it
34  * checksums
35  *
36  * here even more important to align src and dst on a 32-bit (or even
37  * better 64-bit) boundary
38  */
39 extern unsigned csum_partial_copy (const unsigned char *src,
40                                    unsigned char *dst, int len, unsigned sum);
41
42
43 /*
44  * the same as csum_partial_copy, but copies from user space.
45  *
46  * here even more important to align src and dst on a 32-bit (or even
47  * better 64-bit) boundary
48  */
49 extern unsigned csum_partial_copy_from_user (const unsigned char *src,
50                                              unsigned char *dst,
51                                              int len, unsigned sum,
52                                              int *csum_err);
53
54 #define csum_partial_copy_nocheck(src, dst, len, sum)   \
55         csum_partial_copy ((src), (dst), (len), (sum))
56
57 unsigned short ip_fast_csum (unsigned char *iph, unsigned int ihl);
58
59 /*
60  *      Fold a partial checksum
61  */
62 static inline unsigned int csum_fold (unsigned long sum)
63 {
64         unsigned int result;
65         /*
66                                 %0              %1
67               hsw %1, %0        H     L         L     H
68               add %1, %0        H     L         H+L+C H+L
69         */
70         asm ("hsw %1, %0; add %1, %0" : "=&r" (result) : "r" (sum));
71         return (~result) >> 16;
72 }
73
74
75 /*
76  * computes the checksum of the TCP/UDP pseudo-header
77  * returns a 16-bit checksum, already complemented
78  */
79 static inline unsigned int
80 csum_tcpudp_nofold (unsigned long saddr, unsigned long daddr,
81                     unsigned short len,
82                     unsigned short proto, unsigned int sum)
83 {
84         int __carry;
85         __asm__ ("add %2, %0;"
86                  "setf c, %1;"
87                  "add %1, %0;"
88                  "add %3, %0;"
89                  "setf c, %1;"
90                  "add %1, %0;"
91                  "add %4, %0;"
92                  "setf c, %1;"
93                  "add %1, %0"
94                  : "=&r" (sum), "=&r" (__carry)
95                  : "r" (daddr), "r" (saddr),
96                  "r" (ntohs (len) + (proto << 8)),
97                  "0" (sum));
98         return sum;
99 }
100
101 static inline unsigned short int
102 csum_tcpudp_magic (unsigned long saddr, unsigned long daddr,
103                    unsigned short len,
104                    unsigned short proto, unsigned int sum)
105 {
106         return csum_fold (csum_tcpudp_nofold (saddr, daddr, len, proto, sum));
107 }
108
109 /*
110  * this routine is used for miscellaneous IP-like checksums, mainly
111  * in icmp.c
112  */
113 extern unsigned short ip_compute_csum (const unsigned char * buff, int len);
114
115
116 #endif /* __V850_CHECKSUM_H__ */