Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
x86
include
asm
checksum_64.h
Go to the documentation of this file.
1
#ifndef _ASM_X86_CHECKSUM_64_H
2
#define _ASM_X86_CHECKSUM_64_H
3
4
/*
5
* Checksums for x86-64
6
* Copyright 2002 by Andi Kleen, SuSE Labs
7
* with some code from asm-x86/checksum.h
8
*/
9
10
#include <linux/compiler.h>
11
#include <asm/uaccess.h>
12
#include <asm/byteorder.h>
13
22
static
inline
__sum16
csum_fold(
__wsum
sum
)
23
{
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));
29
return
(
__force
__sum16
)(~(
__force
u32
)sum >> 16);
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 <
[email protected]
>, adapted for linux by
37
* Arnt Gulbrandsen.
38
*/
39
45
static
inline
__sum16
ip_fast_csum
(
const
void
*iph,
unsigned
int
ihl)
46
{
47
unsigned
int
sum
;
48
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:"
66
/* Since the input registers which are loaded with iph and ihl
67
are modified, we must also specify them as outputs, or gcc
68
will assume they contain their original values. */
69
:
"=r"
(
sum
),
"=r"
(iph),
"=r"
(ihl)
70
:
"1"
(iph),
"2"
(ihl)
71
:
"memory"
);
72
return
(
__force
__sum16
)
sum
;
73
}
74
86
static
inline
__wsum
87
csum_tcpudp_nofold
(
__be32
saddr
,
__be32
daddr
,
unsigned
short
len,
88
unsigned
short
proto
,
__wsum
sum)
89
{
90
asm
(
" addl %1, %0\n"
91
" adcl %2, %0\n"
92
" adcl %3, %0\n"
93
" adcl $0, %0\n"
94
:
"=r"
(
sum
)
95
:
"g"
(daddr),
"g"
(
saddr
),
96
"g"
((len + proto)<<8),
"0"
(sum));
97
return
sum
;
98
}
99
100
112
static
inline
__sum16
csum_tcpudp_magic
(
__be32
saddr,
__be32
daddr,
113
unsigned
short
len,
114
unsigned
short
proto,
__wsum
sum)
115
{
116
return
csum_fold(
csum_tcpudp_nofold
(saddr, daddr, len, proto, sum));
117
}
118
129
extern
__wsum
csum_partial
(
const
void
*buff,
int
len,
__wsum
sum);
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 */
136
extern
__wsum
csum_partial_copy_generic
(
const
void
*
src
,
const
void
*
dst
,
137
int
len,
__wsum
sum,
138
int
*src_err_ptr,
int
*dst_err_ptr);
139
140
141
extern
__wsum
csum_partial_copy_from_user
(
const
void
__user *
src
,
void
*
dst
,
142
int
len,
__wsum
isum,
int
*errp);
143
extern
__wsum
csum_partial_copy_to_user
(
const
void
*
src
,
void
__user *
dst
,
144
int
len,
__wsum
isum,
int
*errp);
145
extern
__wsum
csum_partial_copy_nocheck
(
const
void
*
src
,
void
*
dst
,
146
int
len,
__wsum
sum);
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
160
extern
__sum16
ip_compute_csum
(
const
void
*buff,
int
len);
161
175
struct
in6_addr
;
176
177
#define _HAVE_ARCH_IPV6_CSUM 1
178
extern
__sum16
179
csum_ipv6_magic
(
const
struct
in6_addr
*saddr,
const
struct
in6_addr
*daddr,
180
__u32
len,
unsigned
short
proto,
__wsum
sum);
181
182
static
inline
unsigned
add32_with_carry(
unsigned
a
,
unsigned
b
)
183
{
184
asm
(
"addl %2,%0\n\t"
185
"adcl $0,%0"
186
:
"=r"
(
a
)
187
:
"0"
(a),
"r"
(
b
));
188
return
a
;
189
}
190
191
#endif
/* _ASM_X86_CHECKSUM_64_H */
Generated on Thu Jan 10 2013 13:18:07 for Linux Kernel by
1.8.2