drm/vc4: mark vc4_bo_cache_purge() static
[linux-2.6-block.git] / arch / x86 / include / asm / checksum_64.h
CommitLineData
1965aae3
PA
1#ifndef _ASM_X86_CHECKSUM_64_H
2#define _ASM_X86_CHECKSUM_64_H
1da177e4 3
3d3c6e10
JP
4/*
5 * Checksums for x86-64
6 * Copyright 2002 by Andi Kleen, SuSE Labs
99122a3f 7 * with some code from asm-x86/checksum.h
3d3c6e10 8 */
1da177e4
LT
9
10#include <linux/compiler.h>
11#include <asm/uaccess.h>
12#include <asm/byteorder.h>
13
3d3c6e10 14/**
1da177e4
LT
15 * csum_fold - Fold and invert a 32bit checksum.
16 * sum: 32bit unfolded sum
3d3c6e10 17 *
1da177e4
LT
18 * Fold a 32bit running checksum to 16bit and invert it. This is usually
19 * the last step before putting a checksum into a packet.
20 * Make sure not to mix with 64bit checksums.
21 */
a4f89fb7 22static inline __sum16 csum_fold(__wsum sum)
1da177e4 23{
3d3c6e10
JP
24 asm(" addl %1,%0\n"
25 " adcl $0xffff,%0"
26 : "=r" (sum)
27 : "r" ((__force u32)sum << 16),
28 "0" ((__force u32)sum & 0xffff0000));
a4f89fb7 29 return (__force __sum16)(~(__force u32)sum >> 16);
1da177e4
LT
30}
31
32/*
33 * This is a version of ip_compute_csum() optimized for IP headers,
34 * which always checksum on 4 octet boundaries.
35 *
36 * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
37 * Arnt Gulbrandsen.
38 */
39
40/**
41 * ip_fast_csum - Compute the IPv4 header checksum efficiently.
42 * iph: ipv4 header
43 * ihl: length of header / 4
3d3c6e10 44 */
a4f89fb7 45static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
1da177e4
LT
46{
47 unsigned int sum;
48
3d3c6e10
JP
49 asm(" movl (%1), %0\n"
50 " subl $4, %2\n"
51 " jbe 2f\n"
52 " addl 4(%1), %0\n"
53 " adcl 8(%1), %0\n"
54 " adcl 12(%1), %0\n"
55 "1: adcl 16(%1), %0\n"
56 " lea 4(%1), %1\n"
57 " decl %2\n"
58 " jne 1b\n"
59 " adcl $0, %0\n"
60 " movl %0, %2\n"
61 " shrl $16, %0\n"
62 " addw %w2, %w0\n"
63 " adcl $0, %0\n"
64 " notl %0\n"
65 "2:"
2c656491 66 /* Since the input registers which are loaded with iph and ihl
1da177e4
LT
67 are modified, we must also specify them as outputs, or gcc
68 will assume they contain their original values. */
3d3c6e10
JP
69 : "=r" (sum), "=r" (iph), "=r" (ihl)
70 : "1" (iph), "2" (ihl)
71 : "memory");
a4f89fb7 72 return (__force __sum16)sum;
1da177e4
LT
73}
74
3d3c6e10 75/**
1da177e4
LT
76 * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
77 * @saddr: source address
78 * @daddr: destination address
79 * @len: length of packet
80 * @proto: ip protocol of packet
3d3c6e10
JP
81 * @sum: initial sum to be added in (32bit unfolded)
82 *
83 * Returns the pseudo header checksum the input data. Result is
1da177e4
LT
84 * 32bit unfolded.
85 */
a4f89fb7 86static inline __wsum
01cfbad7
AD
87csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
88 __u8 proto, __wsum sum)
1da177e4
LT
89{
90 asm(" addl %1, %0\n"
91 " adcl %2, %0\n"
92 " adcl %3, %0\n"
93 " adcl $0, %0\n"
3d3c6e10 94 : "=r" (sum)
a4f89fb7
AV
95 : "g" (daddr), "g" (saddr),
96 "g" ((len + proto)<<8), "0" (sum));
3d3c6e10 97 return sum;
1da177e4
LT
98}
99
100
3d3c6e10 101/**
1da177e4
LT
102 * csum_tcpup_magic - Compute an IPv4 pseudo header checksum.
103 * @saddr: source address
104 * @daddr: destination address
105 * @len: length of packet
106 * @proto: ip protocol of packet
3d3c6e10
JP
107 * @sum: initial sum to be added in (32bit unfolded)
108 *
1da177e4
LT
109 * Returns the 16bit pseudo header checksum the input data already
110 * complemented and ready to be filled in.
111 */
3d3c6e10 112static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
01cfbad7
AD
113 __u32 len, __u8 proto,
114 __wsum sum)
1da177e4 115{
3d3c6e10 116 return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
1da177e4
LT
117}
118
3d3c6e10 119/**
1da177e4
LT
120 * csum_partial - Compute an internet checksum.
121 * @buff: buffer to be checksummed
122 * @len: length of buffer.
123 * @sum: initial sum to be added in (32bit unfolded)
124 *
125 * Returns the 32bit unfolded internet checksum of the buffer.
126 * Before filling it in it needs to be csum_fold()'ed.
127 * buff should be aligned to a 64bit boundary if possible.
3d3c6e10 128 */
a4f89fb7 129extern __wsum csum_partial(const void *buff, int len, __wsum sum);
1da177e4
LT
130
131#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 1
132#define HAVE_CSUM_COPY_USER 1
133
134
135/* Do not call this directly. Use the wrappers below */
4a335c06 136extern __visible __wsum csum_partial_copy_generic(const void *src, const void *dst,
3d3c6e10
JP
137 int len, __wsum sum,
138 int *src_err_ptr, int *dst_err_ptr);
1da177e4
LT
139
140
a4f89fb7 141extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
3d3c6e10 142 int len, __wsum isum, int *errp);
a4f89fb7 143extern __wsum csum_partial_copy_to_user(const void *src, void __user *dst,
3d3c6e10
JP
144 int len, __wsum isum, int *errp);
145extern __wsum csum_partial_copy_nocheck(const void *src, void *dst,
146 int len, __wsum sum);
1da177e4
LT
147
148/* Old names. To be removed. */
149#define csum_and_copy_to_user csum_partial_copy_to_user
150#define csum_and_copy_from_user csum_partial_copy_from_user
151
3d3c6e10 152/**
1da177e4
LT
153 * ip_compute_csum - Compute an 16bit IP checksum.
154 * @buff: buffer address.
155 * @len: length of buffer.
156 *
157 * Returns the 16bit folded/inverted checksum of the passed buffer.
158 * Ready to fill in.
159 */
a4f89fb7 160extern __sum16 ip_compute_csum(const void *buff, int len);
1da177e4
LT
161
162/**
163 * csum_ipv6_magic - Compute checksum of an IPv6 pseudo header.
164 * @saddr: source address
165 * @daddr: destination address
166 * @len: length of packet
167 * @proto: protocol of packet
168 * @sum: initial sum (32bit unfolded) to be added in
169 *
3d3c6e10 170 * Computes an IPv6 pseudo header checksum. This sum is added the checksum
1da177e4
LT
171 * into UDP/TCP packets and contains some link layer information.
172 * Returns the unfolded 32bit checksum.
173 */
174
175struct in6_addr;
176
177#define _HAVE_ARCH_IPV6_CSUM 1
a4f89fb7
AV
178extern __sum16
179csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
1e940829 180 __u32 len, __u8 proto, __wsum sum);
1da177e4
LT
181
182static inline unsigned add32_with_carry(unsigned a, unsigned b)
183{
184 asm("addl %2,%0\n\t"
3d3c6e10
JP
185 "adcl $0,%0"
186 : "=r" (a)
4405b4d6 187 : "0" (a), "rm" (b));
1da177e4
LT
188 return a;
189}
190
a2785344
TH
191#define HAVE_ARCH_CSUM_ADD
192static inline __wsum csum_add(__wsum csum, __wsum addend)
193{
194 return (__force __wsum)add32_with_carry((__force unsigned)csum,
195 (__force unsigned)addend);
196}
197
1965aae3 198#endif /* _ASM_X86_CHECKSUM_64_H */