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