OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libnetworking/] [netinet/] [in_cksum_arm.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*      $NetBSD: in_cksum_arm.c,v 1.3 2001/12/08 21:18:50 chris Exp $   */
2
 
3
/*
4
 * ARM version:
5
 *
6
 * Copyright (c) 1997 Mark Brinicome
7
 * Copyright (c) 1997 Causality Limited
8
 *
9
 * Based on the sparc version.
10
 */
11
 
12
/*
13
 * Sparc version:
14
 *
15
 * Copyright (c) 1995 Zubin Dittia.
16
 * Copyright (c) 1995 Matthew R. Green.
17
 * Copyright (c) 1994 Charles M. Hannum.
18
 * Copyright (c) 1992, 1993
19
 *      The Regents of the University of California.  All rights reserved.
20
 *
21
 * Redistribution and use in source and binary forms, with or without
22
 * modification, are permitted provided that the following conditions
23
 * are met:
24
 * 1. Redistributions of source code must retain the above copyright
25
 *    notice, this list of conditions and the following disclaimer.
26
 * 2. Redistributions in binary form must reproduce the above copyright
27
 *    notice, this list of conditions and the following disclaimer in the
28
 *    documentation and/or other materials provided with the distribution.
29
 * 3. All advertising materials mentioning features or use of this software
30
 *    must display the following acknowledgement:
31
 *      This product includes software developed by the University of
32
 *      California, Berkeley and its contributors.
33
 * 4. Neither the name of the University nor the names of its contributors
34
 *    may be used to endorse or promote products derived from this software
35
 *    without specific prior written permission.
36
 *
37
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
38
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
41
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
 * SUCH DAMAGE.
48
 *
49
 *      @(#)in_cksum.c  8.1 (Berkeley) 6/11/93
50
 */
51
 
52
#include <sys/param.h>
53
#include <sys/systm.h>
54
#include <sys/mbuf.h>
55
#include <netinet/in.h>
56
#include <netinet/in_systm.h>
57
#include <netinet/ip.h>
58
#include <netinet/ip_var.h>
59
 
60
/*
61
 * Checksum routine for Internet Protocol family headers.
62
 *
63
 * This routine is very heavily used in the network
64
 * code and should be modified for each CPU to be as fast as possible.
65
 *
66
 * ARM version.
67
 */
68
 
69
#define ADD64   __asm __volatile("      \n\
70
        ldmia   %0!, {%2, %3, %4, %5}    \n\
71
        adds    %1,%7,%2; adcs %1,%1,%3 \n\
72
        adcs    %1,%1,%4; adcs %1,%1,%5 \n\
73
        ldmia   %0!, {%2, %3, %4, %5}    \n\
74
        adcs    %1,%1,%2; adcs %1,%1,%3 \n\
75
        adcs    %1,%1,%4; adcs %1,%1,%5 \n\
76
        ldmia   %0!, {%2, %3, %4, %5}    \n\
77
        adcs    %1,%1,%2; adcs %1,%1,%3 \n\
78
        adcs    %1,%1,%4; adcs %1,%1,%5 \n\
79
        ldmia   %0!, {%2, %3, %4, %5}    \n\
80
        adcs    %1,%1,%2; adcs %1,%1,%3 \n\
81
        adcs    %1,%1,%4; adcs %1,%1,%5 \n\
82
        adcs    %1,%1,#0\n"             \
83
        : "=r" (w), "=r" (sum), "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \
84
        : "0" (w), "r" (sum)     \
85
        : "cc")
86
 
87
#define ADD32   __asm __volatile("      \n\
88
        ldmia   %0!, {%2, %3, %4, %5}    \n\
89
        adds    %1,%7,%2; adcs %1,%1,%3 \n\
90
        adcs    %1,%1,%4; adcs %1,%1,%5 \n\
91
        ldmia   %0!, {%2, %3, %4, %5}    \n\
92
        adcs    %1,%1,%2; adcs %1,%1,%3 \n\
93
        adcs    %1,%1,%4; adcs %1,%1,%5 \n\
94
        adcs    %1,%1,#0\n"             \
95
        : "=r" (w), "=r" (sum), "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \
96
        : "0" (w), "r" (sum)     \
97
        : "cc")
98
 
99
#define ADD16   __asm __volatile("      \n\
100
        ldmia   %0!, {%2, %3, %4, %5}    \n\
101
        adds    %1,%7,%2; adcs %1,%1,%3 \n\
102
        adcs    %1,%1,%4; adcs %1,%1,%5 \n\
103
        adcs    %1,%1,#0\n"             \
104
        : "=r" (w), "=r" (sum), "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \
105
        : "0" (w), "r" (sum)     \
106
        : "cc")
107
 
108
#define ADD8    __asm __volatile("      \n\
109
        ldmia   %0!, {%2, %3}            \n\
110
        adds    %1,%5,%2; adcs %1,%1,%3 \n\
111
        adcs    %1,%1,#0\n"             \
112
        : "=r" (w), "=r" (sum), "=&r" (tmp1), "=&r" (tmp2)      \
113
        : "0" (w), "r" (sum)             \
114
        : "cc" )
115
 
116
#define ADD4    __asm __volatile("      \n\
117
        ldr     %2,[%0],#4               \n\
118
        adds    %1,%4,%2                \n\
119
        adcs    %1,%1,#0\n"             \
120
        : "=r" (w), "=r" (sum), "=&r" (tmp1) \
121
        : "0" (w), "r" (sum)             \
122
        : "cc")
123
 
124
/*#define REDUCE        {sum = (sum & 0xffff) + (sum >> 16);}*/
125
#define REDUCE  __asm __volatile("      \n\
126
        mov     %2, #0x00ff             \n\
127
        orr     %2, %2, #0xff00         \n\
128
        and     %2, %0, %2               \n\
129
        add     %0, %2, %0, lsr #16\n"    \
130
        : "=r" (sum)                    \
131
        : "0" (sum), "r" (tmp1))
132
 
133
#define ADDCARRY        {if (sum > 0xffff) sum -= 0xffff;}
134
#define ROL             {sum = sum << 8;}       /* depends on recent REDUCE */
135
#define ADDBYTE         {ROL; sum += (*w << 8); byte_swapped ^= 1;}
136
#define ADDSHORT        {sum += *(u_short *)w;}
137
#define ADVANCE(n)      {w += n; mlen -= n;}
138
#define ADVANCEML(n)    {mlen -= n;}
139
 
140
static __inline__ int
141
in_cksum_internal(struct mbuf *m, int off, int len, u_int sum)
142
{
143
        u_char *w;
144
        int mlen = 0;
145
        int byte_swapped = 0;
146
 
147
        /*
148
         * Declare four temporary registers for use by the asm code.  We
149
         * allow the compiler to pick which specific machine registers to
150
         * use, instead of hard-coding this in the asm code above.
151
         */
152
        register u_int tmp1, tmp2, tmp3, tmp4;
153
 
154
        for (; m && len; m = m->m_next) {
155
                if (m->m_len == 0)
156
                        continue;
157
                w = mtod(m, u_char *) + off;
158
                mlen = m->m_len - off;
159
                off = 0;
160
                if (len < mlen)
161
                        mlen = len;
162
                len -= mlen;
163
 
164
                /*
165
                 * Ensure that we're aligned on a word boundary here so
166
                 * that we can do 32 bit operations below.
167
                 */
168
                if ((3 & (long)w) != 0) {
169
                        REDUCE;
170
                        if ((1 & (long)w) != 0 && mlen >= 1) {
171
                                ADDBYTE;
172
                                ADVANCE(1);
173
                        }
174
                        if ((2 & (long)w) != 0 && mlen >= 2) {
175
                                ADDSHORT;
176
                                ADVANCE(2);
177
                        }
178
                }
179
 
180
                /*
181
                 * Do as many 32 bit operations as possible using the
182
                 * 64/32/16/8/4 macro's above, using as many as possible of
183
                 * these.
184
                 */
185
 
186
                while (mlen >= 64) {
187
                        ADD64;
188
                        ADVANCEML(64);
189
                }
190
                if (mlen >= 32) {
191
                        ADD32;
192
                        ADVANCEML(32);
193
                }
194
                if (mlen >= 16) {
195
                        ADD16;
196
                        ADVANCEML(16);
197
                }
198
                if (mlen >= 8) {
199
                        ADD8;
200
                        ADVANCEML(8);
201
                }
202
                if (mlen >= 4) {
203
                        ADD4;
204
                        ADVANCEML(4)
205
                }
206
                if (mlen == 0)
207
                        continue;
208
 
209
                REDUCE;
210
                if (mlen >= 2) {
211
                        ADDSHORT;
212
                        ADVANCE(2);
213
                }
214
                if (mlen == 1) {
215
                        ADDBYTE;
216
                }
217
        }
218
        if (byte_swapped) {
219
                REDUCE;
220
                ROL;
221
        }
222
        REDUCE;
223
        ADDCARRY;
224
 
225
        return (0xffff ^ sum);
226
}
227
 
228
int
229
in_cksum(m, len)
230
    struct mbuf *m;
231
    int len;
232
{
233
    int cksum;
234
    cksum =in_cksum_internal(m, 0, len, 0);
235
    return cksum;
236
}
237
 
238
int
239
in4_cksum(m, nxt, off, len)
240
    struct mbuf *m;
241
    u_int8_t nxt;
242
    int off, len;
243
{
244
        u_int sum = 0;
245
 
246
        if (nxt != 0) {
247
            /* for ADD macros */
248
            register u_int tmp1, tmp2, tmp3, tmp4;
249
            u_char *w;
250
            struct ipovly ipov;
251
            /* pseudo header */
252
            if (off < sizeof(struct ipovly))
253
                panic("in4_cksum: offset too short");
254
            if (m->m_len < sizeof(struct ip))
255
                panic("in4_cksum: bad mbuf chain");
256
 
257
            bzero(&ipov, sizeof(ipov));
258
            ipov.ih_len = htons(len);
259
            ipov.ih_pr = nxt;
260
            ipov.ih_src = mtod(m, struct ip *)->ip_src;
261
            ipov.ih_dst = mtod(m, struct ip *)->ip_dst;
262
            w = (u_char *)&ipov;
263
 
264
            /* assumes sizeof(ipov) == 20 */
265
            ADD16;
266
            ADD4;
267
        }
268
        /* skip unnecessary part */
269
        while (m && off > 0) {
270
                if (m->m_len > off)
271
                        break;
272
                off -= m->m_len;
273
                m = m->m_next;
274
        }
275
        return (in_cksum_internal(m, off, len, sum));
276
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.