source: rtems/cpukit/libnetworking/netinet/in_cksum_m68k.h @ c995cd6

4.104.114.84.95
Last change on this file since c995cd6 was c995cd6, checked in by Joel Sherrill <joel.sherrill@…>, on 03/10/05 at 21:46:12

2005-03-10 Joel Sherrill <joel@…>

  • libnetworking/netinet/in_cksum_m68k.h: Change back to lcsum[12]_lbl since my fix did not fix all issues.
  • Property mode set to 100644
File size: 7.3 KB
Line 
1/*
2 * Copyright (c) 1988, 1992, 1993
3 *      The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *      This product includes software developed by the University of
16 *      California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *      @(#)in_cksum.c  8.1 (Berkeley) 6/10/93
34 * $Id$
35 */
36
37#include <sys/param.h>
38#include <sys/mbuf.h>
39
40#if (defined (__mcf5200__))
41# define IS_COLDFIRE 1
42#else
43# define IS_COLDFIRE 0
44#endif
45
46#define REDUCE { sum = (sum & 0xFFFF) + (sum >> 16); if (sum > 0xFFFF) sum -= 0xFFFF; }
47
48/*
49 * Motorola 68k version of Internet Protocol Checksum routine
50 * W. Eric Norum
51 * Saskatchewan Accelerator Laboratory
52 * August, 1998
53 */
54int
55in_cksum(m, len)
56        struct mbuf *m;
57        int len;
58{
59        unsigned short *w;
60        unsigned long sum = 0;
61        int mlen = 0;
62        int byte_swapped = 0;
63        union {
64                char    c[2];
65                u_short s;
66        } s_util;
67
68        for ( ; m && len ; m = m->m_next) {
69                if (m->m_len == 0)
70                        continue;
71                w = mtod(m, u_short *);
72                if (mlen == -1) {
73                        /*
74                         * The first byte of this mbuf is the continuation
75                         * of a word spanning between this mbuf and the
76                         * last mbuf.
77                         *
78                         * s_util.c[0] is already saved when scanning previous
79                         * mbuf.
80                         */
81                        s_util.c[1] = *(char *)w;
82                        sum += s_util.s;
83                        w = (u_short *)((char *)w + 1);
84                        mlen = m->m_len - 1;
85                        len--;
86                } else
87                        mlen = m->m_len;
88                if (len < mlen)
89                        mlen = len;
90                len -= mlen;
91
92                /*
93                 * Force to longword boundary.
94                 */
95                if (3 & (int)w) {
96                        REDUCE;
97                        if ((1 & (int) w) && (mlen > 0)) {
98                                sum <<= 8;
99                                s_util.c[0] = *(u_char *)w;
100                                w = (u_short *)((char *)w + 1);
101                                mlen--;
102                                byte_swapped = 1;
103                        }
104                        if ((2 & (int) w) && (mlen >= 2)) {
105                                sum += *w++;
106                                mlen -= 2;
107                        }
108                }
109
110                /*
111                 * Sum all the longwords in the buffer.
112                 * See RFC 1071 -- Computing the Internet Checksum.
113                 * It should work for all 68k family members.
114                 */
115                {
116                unsigned long tcnt = mlen, t1;
117                __asm__ volatile (
118                "movel   %2,%3\n\t"
119                "lsrl    #6,%2       | count/64 = # loop traversals\n\t"
120                "andl    #0x3c,%3    | Then find fractions of a chunk\n\t"
121                "negl    %3\n\t      | Each long uses 4 instruction bytes\n\t"
122#if IS_COLDFIRE
123                "addql   #1,%2       | Clear X (extended carry flag)\n\t"
124                "subql   #1,%2       | \n\t"
125#else
126                "andi    #0xf,%%cc   | Clear X (extended carry flag)\n\t"
127#endif
128                "jmp     %%pc@(lcsum2_lbl-.-2:b,%3)  | Jump into loop\n"
129                "lcsum1_lbl:         | Begin inner loop...\n\t"
130                "movel   %1@+,%3     |  0: Fetch 32-bit word\n\t"
131                "addxl   %3,%0       |    Add word + previous carry\n\t"
132                "movel   %1@+,%3     |  1: Fetch 32-bit word\n\t"
133                "addxl   %3,%0       |    Add word + previous carry\n\t"
134                "movel   %1@+,%3     |  2: Fetch 32-bit word\n\t"
135                "addxl   %3,%0       |    Add word + previous carry\n\t"
136                "movel   %1@+,%3     |  3: Fetch 32-bit word\n\t"
137                "addxl   %3,%0       |    Add word + previous carry\n\t"
138                "movel   %1@+,%3     |  4: Fetch 32-bit word\n\t"
139                "addxl   %3,%0       |    Add word + previous carry\n\t"
140                "movel   %1@+,%3     |  5: Fetch 32-bit word\n\t"
141                "addxl   %3,%0       |    Add word + previous carry\n\t"
142                "movel   %1@+,%3     |  6: Fetch 32-bit word\n\t"
143                "addxl   %3,%0       |    Add word + previous carry\n\t"
144                "movel   %1@+,%3     |  7: Fetch 32-bit word\n\t"
145                "addxl   %3,%0       |    Add word + previous carry\n\t"
146                "movel   %1@+,%3     |  8: Fetch 32-bit word\n\t"
147                "addxl   %3,%0       |    Add word + previous carry\n\t"
148                "movel   %1@+,%3     |  9: Fetch 32-bit word\n\t"
149                "addxl   %3,%0       |    Add word + previous carry\n\t"
150                "movel   %1@+,%3     |  A: Fetch 32-bit word\n\t"
151                "addxl   %3,%0       |    Add word + previous carry\n\t"
152                "movel   %1@+,%3     |  B: Fetch 32-bit word\n\t"
153                "addxl   %3,%0       |    Add word + previous carry\n\t"
154                "movel   %1@+,%3     |  C: Fetch 32-bit word\n\t"
155                "addxl   %3,%0       |    Add word + previous carry\n\t"
156                "movel   %1@+,%3     |  D: Fetch 32-bit word\n\t"
157                "addxl   %3,%0       |    Add word + previous carry\n\t"
158                "movel   %1@+,%3     |  E: Fetch 32-bit word\n\t"
159                "addxl   %3,%0       |    Add word + previous carry\n\t"
160                "movel   %1@+,%3     |  F: Fetch 32-bit word\n\t"
161                "addxl   %3,%0       |    Add word + previous carry\n"
162                "lcsum2_lbl:         |  End of unrolled loop\n\t"
163#if IS_COLDFIRE
164                "moveq   #0,%3       | Add in last carry\n\t"
165                "addxl   %3,%0       |\n\t"
166                "subql   #1,%2       | Update loop count\n\t"
167                "bplb    lcsum1_lbl  | Loop (with X clear) if not done\n\t"
168                "movel   #0xffff,%2  | Get word mask\n\t"
169                "movel   %0,%3       | Fold 32 bit sum to 16 bits\n\t"
170                "swap    %3          |\n\t"
171                "andl    %2,%0       | Mask to 16-bit sum\n\t"
172                "andl    %2,%3       | Mask to 16-bit sum\n\t"
173                "addl    %3,%0       |\n\t"
174                "movel   %0,%3       | Add in last carry\n\t"
175                "swap    %3          |\n\t"
176                "addl    %3,%0       |\n\t"
177                "andl    %2,%0       | Mask to 16-bit sum\n\t"
178#else
179                "dbf     %2,lcsum1_lbl | (NB- dbf doesn't affect X)\n\t"
180                "movel   %0,%3       | Fold 32 bit sum to 16 bits\n\t"
181                "swap    %3          | (NB- swap doesn't affect X)\n\t"
182                "addxw   %3,%0       |\n\t"
183                "moveq   #0,%3       | Add in last carry\n\t"
184                "addxw   %3,%0       |\n\t"
185                "andl    #0xffff,%0  | Mask to 16-bit sum\n"
186#endif
187                        :
188                        "=d" (sum), "=a" (w), "=d" (tcnt) , "=d" (t1) :
189                        "0" (sum), "1" (w), "2" (tcnt) :
190                        "cc", "memory");
191                }
192                mlen &= 3;
193
194                /*
195                 * Soak up the last 1, 2 or 3 bytes
196                 */
197                while ((mlen -= 2) >= 0)
198                        sum += *w++;
199                if (byte_swapped) {
200                        REDUCE;
201                        sum <<= 8;
202                        byte_swapped = 0;
203                        if (mlen == -1) {
204                                s_util.c[1] = *(char *)w;
205                                sum += s_util.s;
206                                mlen = 0;
207                        } else
208                                mlen = -1;
209                } else if (mlen == -1)
210                        s_util.c[0] = *(char *)w;
211        }
212        if (len)
213                sum = 0xDEAD;
214        if (mlen == -1) {
215                /* The last mbuf has odd # of bytes. Follow the
216                   standard (the odd byte may be shifted left by 8 bits
217                   or not as determined by endian-ness of the machine) */
218                s_util.c[1] = 0;
219                sum += s_util.s;
220        }
221        REDUCE;
222        return (~sum & 0xffff);
223}
Note: See TracBrowser for help on using the repository browser.