RTEMS CPU Kit with SuperCore
4.11.3
Main Page
Related Pages
Modules
+
Data Structures
Data Structures
+
Data Fields
+
All
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
+
Variables
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
+
Files
File List
+
Globals
+
All
_
a
b
c
d
e
f
g
h
i
j
l
m
n
o
p
q
r
s
t
u
v
w
x
+
Functions
_
a
b
c
d
e
f
g
i
j
l
m
n
o
p
q
r
s
t
u
v
w
+
Variables
_
b
c
d
i
r
+
Typedefs
a
b
c
d
f
h
i
m
o
p
q
r
s
t
u
w
x
+
Enumerations
b
c
d
e
h
i
m
o
p
r
s
t
w
+
Enumerator
c
i
m
p
r
s
t
w
+
Macros
_
a
b
c
d
e
f
g
h
i
l
m
n
o
p
r
s
t
w
mnt
data0
chrisj
rtems
releases
rtems-release.git
4.11.3
ws-rtems
rtems-4.11.3
cpukit
libnetworking
netinet
in_cksum_powerpc.h
Go to the documentation of this file.
1
/*
2
* Checksum routine for Internet Protocol family headers.
3
*
4
* This routine is very heavily used in the network
5
* code and should be modified for each CPU to be as fast as possible.
6
*
7
* This implementation is the PowerPC version.
8
*/
9
10
#include <stdio.h>
/* for puts */
11
12
#undef ADDCARRY
13
#define ADDCARRY(x) if ((x) > 0xffff) (x) -= 0xffff
14
#define REDUCE {sum = (sum & 0xffff) + (sum >> 16); ADDCARRY(sum);}
15
16
/*
17
* Thanks to gcc we don't have to guess
18
* which registers contain sum & w.
19
*/
20
21
#define LDTMP(n) tmp = *((u_int *)((u_char *)w + n))
22
23
#define ADD(n) \
24
LDTMP(n); \
25
__asm__ volatile("addc %0,%0,%2" : "=r" (sum) : "0" (sum), "r" (tmp))
26
27
#define ADDC(n) \
28
LDTMP(n); \
29
__asm__ volatile("adde %0,%0,%2" : "=r" (sum) : "0" (sum), "r" (tmp))
30
31
#define MOP \
32
tmp = 0; \
33
__asm__ volatile("adde %0,%0,%2" : "=r" (sum) : "0" (sum), "r" (tmp))
34
35
#define LOAD(n) junk = (u_char) *((volatile u_char *) w + n)
36
37
38
int
39
in_cksum(
40
struct
mbuf
*m,
41
int
len
42
)
43
{
44
u_char junk;
45
register
u_short *w;
46
register
unsigned
sum = 0;
47
register
unsigned
tmp;
48
register
int
mlen = 0;
49
int
byte_swapped = 0;
50
union
{
char
c[2]; u_short s; } su;
51
52
for
(;m && len; m = m->m_next) {
53
if
(m->m_len == 0)
54
continue
;
55
w = mtod(m, u_short *);
56
if
(mlen == -1) {
57
/*
58
* The first byte of this mbuf is the continuation
59
* of a word spanning between this mbuf and the
60
* last mbuf.
61
*/
62
63
/* su.c[0] is already saved when scanning previous
64
* mbuf. sum was REDUCEd when we found mlen == -1
65
*/
66
su.c[1] = *(u_char *)w;
67
sum += su.s;
68
w = (u_short *)((
char
*)w + 1);
69
mlen = m->m_len - 1;
70
len--;
71
}
else
72
mlen = m->m_len;
73
if
(len < mlen)
74
mlen = len;
75
len -= mlen;
76
/*
77
* Force to long boundary so we do longword aligned
78
* memory operations
79
*/
80
if
(3 & (
int
) w) {
81
REDUCE;
82
if
((1 & (
int
) w) && (mlen > 0)) {
83
sum <<= 8;
84
su.c[0] = *(
char
*)w;
85
w = (u_short *)((
char
*)w + 1);
86
mlen--;
87
byte_swapped = 1;
88
}
89
if
((2 & (
int
) w) && (mlen >= 2)) {
90
sum += *w++;
91
mlen -= 2;
92
}
93
}
94
95
/*
96
* Do as much of the checksum as possible 32 bits at at time.
97
* In fact, this loop is unrolled to keep overhead from
98
* branches small.
99
*/
100
while
(mlen >= 32) {
101
/*
102
* Add with carry 16 words and fold in the last
103
* carry by adding a 0 with carry.
104
*
105
* The early ADD(16) and the LOAD(32) are intended
106
* to help get the data into the cache.
107
*/
108
ADD(16);
109
ADDC(0);
110
ADDC(4);
111
ADDC(8);
112
ADDC(12);
113
LOAD(32);
114
ADDC(20);
115
ADDC(24);
116
ADDC(28);
117
MOP;
118
w += 16;
119
mlen -= 32;
120
}
121
if
(mlen >= 16) {
122
ADD(0);
123
ADDC(4);
124
ADDC(8);
125
ADDC(12);
126
MOP;
127
w += 8;
128
mlen -= 16;
129
}
130
if
(mlen >= 8) {
131
ADD(0);
132
ADDC(4);
133
MOP;
134
w += 4;
135
mlen -= 8;
136
}
137
if
(mlen == 0 && byte_swapped == 0)
138
continue
;
/* worth 1% maybe ?? */
139
REDUCE;
140
while
((mlen -= 2) >= 0) {
141
sum += *w++;
142
}
143
if
(byte_swapped) {
144
sum <<= 8;
145
byte_swapped = 0;
146
if
(mlen == -1) {
147
su.c[1] = *(
char
*)w;
148
sum += su.s;
149
mlen = 0;
150
}
else
151
mlen = -1;
152
}
else
if
(mlen == -1)
153
/*
154
* This mbuf has odd number of bytes.
155
* There could be a word split betwen
156
* this mbuf and the next mbuf.
157
* Save the last byte (to prepend to next mbuf).
158
*/
159
su.c[0] = *(
char
*)w;
160
}
161
162
if
(len)
163
puts(
"cksum: out of data"
);
164
if
(mlen == -1) {
165
/* The last mbuf has odd # of bytes. Follow the
166
standard (the odd byte is shifted left by 8 bits) */
167
su.c[1] = 0;
168
sum += su.s;
169
}
170
REDUCE;
171
return
(~sum & 0xffff);
172
}
mbuf
Definition:
mbuf.h:103
Generated by
1.8.13