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
frv
include
asm
checksum.h
Go to the documentation of this file.
1
/* checksum.h: FRV checksumming
2
*
3
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells (
[email protected]
)
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version
9
* 2 of the License, or (at your option) any later version.
10
*/
11
12
#ifndef _ASM_CHECKSUM_H
13
#define _ASM_CHECKSUM_H
14
15
#include <linux/in6.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
__wsum
csum_partial
(
const
void
*buff,
int
len,
__wsum
sum
);
30
31
/*
32
* the same as csum_partial, but copies from src while it
33
* checksums
34
*
35
* here even more important to align src and dst on a 32-bit (or even
36
* better 64-bit) boundary
37
*/
38
__wsum
csum_partial_copy_nocheck
(
const
void
*
src
,
void
*
dst
,
int
len,
__wsum
sum
);
39
40
/*
41
* the same as csum_partial_copy, but copies from user space.
42
*
43
* here even more important to align src and dst on a 32-bit (or even
44
* better 64-bit) boundary
45
*/
46
extern
__wsum
csum_partial_copy_from_user
(
const
void
__user *
src
,
void
*
dst
,
47
int
len,
__wsum
sum
,
int
*csum_err);
48
49
/*
50
* This is a version of ip_compute_csum() optimized for IP headers,
51
* which always checksum on 4 octet boundaries.
52
*
53
*/
54
static
inline
55
__sum16
ip_fast_csum
(
const
void
*iph,
unsigned
int
ihl)
56
{
57
unsigned
int
tmp
,
inc
,
sum
= 0;
58
59
asm
(
" addcc gr0,gr0,gr0,icc0\n"
/* clear icc0.C */
60
" subi %1,#4,%1 \n"
61
"0: \n"
62
" ldu.p @(%1,%3),%4 \n"
63
" subicc %2,#1,%2,icc1 \n"
64
" addxcc.p %4,%0,%0,icc0 \n"
65
" bhi icc1,#2,0b \n"
66
67
/* fold the 33-bit result into 16-bits */
68
" addxcc gr0,%0,%0,icc0 \n"
69
" srli %0,#16,%1 \n"
70
" sethi #0,%0 \n"
71
" add %1,%0,%0 \n"
72
" srli %0,#16,%1 \n"
73
" add %1,%0,%0 \n"
74
75
:
"=r"
(
sum
),
"=r"
(iph),
"=r"
(ihl),
"=r"
(inc),
"=&r"
(
tmp
)
76
:
"0"
(sum),
"1"
(iph),
"2"
(ihl),
"3"
(4),
77
"m"
(*(
volatile
struct
{
int
_
[100]; } *)iph)
78
:
"icc0"
,
"icc1"
,
"memory"
79
);
80
81
return
(
__force
__sum16
)~sum;
82
}
83
84
/*
85
* Fold a partial checksum
86
*/
87
static
inline
__sum16
csum_fold(
__wsum
sum)
88
{
89
unsigned
int
tmp
;
90
91
asm
(
" srli %0,#16,%1 \n"
92
" sethi #0,%0 \n"
93
" add %1,%0,%0 \n"
94
" srli %0,#16,%1 \n"
95
" add %1,%0,%0 \n"
96
:
"=r"
(
sum
),
"=&r"
(tmp)
97
:
"0"
(
sum
)
98
);
99
100
return
(
__force
__sum16
)~sum;
101
}
102
103
/*
104
* computes the checksum of the TCP/UDP pseudo-header
105
* returns a 16-bit checksum, already complemented
106
*/
107
static
inline
__wsum
108
csum_tcpudp_nofold
(
__be32
saddr
,
__be32
daddr
,
unsigned
short
len,
109
unsigned
short
proto
,
__wsum
sum)
110
{
111
asm
(
" addcc %1,%0,%0,icc0 \n"
112
" addxcc %2,%0,%0,icc0 \n"
113
" addxcc %3,%0,%0,icc0 \n"
114
" addxcc gr0,%0,%0,icc0 \n"
115
:
"=r"
(
sum
)
116
:
"r"
(daddr),
"r"
(
saddr
),
"r"
(len + proto),
"0"
(
sum
)
117
:
"icc0"
118
);
119
return
sum
;
120
}
121
122
static
inline
__sum16
123
csum_tcpudp_magic
(
__be32
saddr,
__be32
daddr,
unsigned
short
len,
124
unsigned
short
proto,
__wsum
sum)
125
{
126
return
csum_fold(
csum_tcpudp_nofold
(saddr,daddr,len,proto,sum));
127
}
128
129
/*
130
* this routine is used for miscellaneous IP-like checksums, mainly
131
* in icmp.c
132
*/
133
extern
__sum16
ip_compute_csum
(
const
void
*buff,
int
len);
134
135
#define _HAVE_ARCH_IPV6_CSUM
136
static
inline
__sum16
137
csum_ipv6_magic
(
const
struct
in6_addr
*saddr,
const
struct
in6_addr
*daddr,
138
__u32
len,
unsigned
short
proto,
__wsum
sum)
139
{
140
unsigned
long
tmp
, tmp2;
141
142
asm
(
" addcc %2,%0,%0,icc0 \n"
143
144
/* add up the source addr */
145
" ldi @(%3,0),%1 \n"
146
" addxcc %1,%0,%0,icc0 \n"
147
" ldi @(%3,4),%2 \n"
148
" addxcc %2,%0,%0,icc0 \n"
149
" ldi @(%3,8),%1 \n"
150
" addxcc %1,%0,%0,icc0 \n"
151
" ldi @(%3,12),%2 \n"
152
" addxcc %2,%0,%0,icc0 \n"
153
154
/* add up the dest addr */
155
" ldi @(%4,0),%1 \n"
156
" addxcc %1,%0,%0,icc0 \n"
157
" ldi @(%4,4),%2 \n"
158
" addxcc %2,%0,%0,icc0 \n"
159
" ldi @(%4,8),%1 \n"
160
" addxcc %1,%0,%0,icc0 \n"
161
" ldi @(%4,12),%2 \n"
162
" addxcc %2,%0,%0,icc0 \n"
163
164
/* fold the 33-bit result into 16-bits */
165
" addxcc gr0,%0,%0,icc0 \n"
166
" srli %0,#16,%1 \n"
167
" sethi #0,%0 \n"
168
" add %1,%0,%0 \n"
169
" srli %0,#16,%1 \n"
170
" add %1,%0,%0 \n"
171
172
:
"=r"
(
sum
),
"=&r"
(tmp),
"=r"
(tmp2)
173
:
"r"
(saddr),
"r"
(
daddr
),
"0"
(sum),
"2"
(len +
proto
)
174
:
"icc0"
175
);
176
177
return
(
__force
__sum16
)~sum;
178
}
179
180
#endif
/* _ASM_CHECKSUM_H */
Generated on Thu Jan 10 2013 12:49:16 for Linux Kernel by
1.8.2