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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [sctp/] [adler32.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* SCTP kernel reference Implementation
2
 * Copyright (c) 1999-2000 Cisco, Inc.
3
 * Copyright (c) 1999-2001 Motorola, Inc.
4
 * Copyright (c) 2003 International Business Machines, Corp.
5
 *
6
 * This file is part of the SCTP kernel reference Implementation
7
 *
8
 * This file has direct heritage from the SCTP user-level reference
9
 * implementation by R. Stewart, et al.  These functions implement the
10
 * Adler-32 algorithm as specified by RFC 2960.
11
 *
12
 * The SCTP reference implementation is free software;
13
 * you can redistribute it and/or modify it under the terms of
14
 * the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2, or (at your option)
16
 * any later version.
17
 *
18
 * The SCTP reference implementation is distributed in the hope that it
19
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
20
 *                 ************************
21
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22
 * See the GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with GNU CC; see the file COPYING.  If not, write to
26
 * the Free Software Foundation, 59 Temple Place - Suite 330,
27
 * Boston, MA 02111-1307, USA.
28
 *
29
 * Please send any bug reports or fixes you make to the
30
 * email address(es):
31
 *    lksctp developers <lksctp-developers@lists.sourceforge.net>
32
 *
33
 * Or submit a bug report through the following website:
34
 *    http://www.sf.net/projects/lksctp
35
 *
36
 * Written or modified by:
37
 *    Randall Stewart <rstewar1@email.mot.com>
38
 *    Ken Morneau     <kmorneau@cisco.com>
39
 *    Qiaobing Xie    <qxie1@email.mot.com>
40
 *    Sridhar Samudrala <sri@us.ibm.com>
41
 *
42
 * Any bugs reported given to us we will try to fix... any fixes shared will
43
 * be incorporated into the next SCTP release.
44
 */
45
 
46
/* This is an entry point for external calls
47
 * Define this function in the header file. This is
48
 * direct from rfc1950, ...
49
 *
50
 * The following C code computes the Adler-32 checksum of a data buffer.
51
 * It is written for clarity, not for speed.  The sample code is in the
52
 * ANSI C programming language. Non C users may find it easier to read
53
 * with these hints:
54
 *
55
 *    &      Bitwise AND operator.
56
 *    >>     Bitwise right shift operator. When applied to an
57
 *           unsigned quantity, as here, right shift inserts zero bit(s)
58
 *           at the left.
59
 *    <<     Bitwise left shift operator. Left shift inserts zero
60
 *           bit(s) at the right.
61
 *    ++     "n++" increments the variable n.
62
 *    %      modulo operator: a % b is the remainder of a divided by b.
63
 *
64
 * Well, the above is a bit of a lie, I have optimized this a small
65
 * tad, but I have commented the original lines below
66
 */
67
 
68
#include <linux/types.h>
69
#include <net/sctp/sctp.h>
70
 
71
#define BASE 65521 /* largest prime smaller than 65536 */
72
 
73
 
74
/* Performance work as shown this pig to be the
75
 * worst CPU wise guy. I have done what I could think
76
 * of on my flight to Australia but I am sure some
77
 * clever assembly could speed this up, but of
78
 * course this would require the dreaded #ifdef's for
79
 * architecture. If you can speed this up more, pass
80
 * it back and we will incorporate it :-)
81
 */
82
 
83
unsigned long update_adler32(unsigned long adler,
84
                             unsigned char *buf, int len)
85
{
86
        __u32 s1 = adler & 0xffff;
87
        __u32 s2 = (adler >> 16) & 0xffff;
88
        int n;
89
 
90
        for (n = 0; n < len; n++,buf++) {
91
                /* s1 = (s1 + buf[n]) % BASE */
92
                /* first we add */
93
                s1 = (s1 + *buf);
94
 
95
                /* Now if we need to, we do a mod by
96
                 * subtracting. It seems a bit faster
97
                 * since I really will only ever do
98
                 * one subtract at the MOST, since buf[n]
99
                 * is a max of 255.
100
                 */
101
                if (s1 >= BASE)
102
                        s1 -= BASE;
103
 
104
                /* s2 = (s2 + s1) % BASE */
105
                /* first we add */
106
                s2 = (s2 + s1);
107
 
108
                /* again, it is more efficient (it seems) to
109
                 * subtract since the most s2 will ever be
110
                 * is (BASE-1 + BASE-1) in the worse case.
111
                 * This would then be (2 * BASE) - 2, which
112
                 * will still only do one subtract. On Intel
113
                 * this is much better to do this way and
114
                 * avoid the divide. Have not -pg'd on
115
                 * sparc.
116
                 */
117
                if (s2 >= BASE) {
118
                        /*      s2 %= BASE;*/
119
                        s2 -= BASE;
120
                }
121
        }
122
 
123
        /* Return the adler32 of the bytes buf[0..len-1] */
124
        return (s2 << 16) + s1;
125
}
126
 
127
__u32 sctp_start_cksum(__u8 *ptr, __u16 count)
128
{
129
        /*
130
         * Update a running Adler-32 checksum with the bytes
131
         * buf[0..len-1] and return the updated checksum. The Adler-32
132
         * checksum should be initialized to 1.
133
         */
134
        __u32 adler = 1L;
135
        __u32 zero = 0L;
136
 
137
        /* Calculate the CRC up to the checksum field. */
138
        adler = update_adler32(adler, ptr,
139
                               sizeof(struct sctphdr) - sizeof(__u32));
140
        /* Skip over the checksum field. */
141
        adler = update_adler32(adler, (unsigned char *) &zero,
142
                               sizeof(__u32));
143
        ptr += sizeof(struct sctphdr);
144
        count -= sizeof(struct sctphdr);
145
 
146
        /* Calculate the rest of the Adler-32. */
147
        adler = update_adler32(adler, ptr, count);
148
 
149
        return adler;
150
}
151
 
152
__u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 adler)
153
{
154
        adler = update_adler32(adler, ptr, count);
155
 
156
        return adler;
157
}
158
 
159
__u32 sctp_update_copy_cksum(__u8 *to, __u8 *from, __u16 count, __u32 adler)
160
{
161
        /* Its not worth it to try harder.  Adler32 is obsolescent. */
162
        adler = update_adler32(adler, from, count);
163
        memcpy(to, from, count);
164
 
165
        return adler;
166
}
167
 
168
__u32 sctp_end_cksum(__u32 adler)
169
{
170
        return adler;
171
}

powered by: WebSVN 2.1.0

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