1 /*
2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3  *                         University Research and Technology
4  *                         Corporation.  All rights reserved.
5  * Copyright (c) 2004-2006 The University of Tennessee and The University
6  *                         of Tennessee Research Foundation.  All rights
7  *                         reserved.
8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9  *                         University of Stuttgart.  All rights reserved.
10  * Copyright (c) 2004-2005 The Regents of the University of California.
11  *                         All rights reserved.
12  * Copyright (c) 2009      IBM Corporation.  All rights reserved.
13  * Copyright (c) 2009      Los Alamos National Security, LLC.  All rights
14  *                         reserved.
15  * $COPYRIGHT$
16  *
17  * Additional copyrights may follow
18  *
19  * $HEADER$
20  */
21 
22 #ifndef _OPAL_CRC_H_
23 #define _OPAL_CRC_H_
24 
25 #include "opal_config.h"
26 
27 #include <stddef.h>
28 
29 BEGIN_C_DECLS
30 
31 #define CRC_POLYNOMIAL ((unsigned int)0x04c11db7)
32 #define CRC_INITIAL_REGISTER ((unsigned int)0xffffffff)
33 
34 
35 #define OPAL_CSUM( SRC, LEN )  opal_uicsum( SRC, LEN )
36 #define OPAL_CSUM_PARTIAL( SRC, LEN, UI1, UI2 ) \
37     opal_uicsum_partial( SRC, LEN, UI1, UI2 )
38 #define OPAL_CSUM_BCOPY_PARTIAL( SRC, DST, LEN1, LEN2, UI1, UI2 ) \
39     opal_bcopy_uicsum_partial( SRC, DST, LEN1, LEN2, UI1, UI2 )
40 #define OPAL_CSUM_ZERO  0
41 
42 
43 OPAL_DECLSPEC unsigned long
44 opal_bcopy_csum_partial(
45     const void *  source,
46     void *  destination,
47     size_t copylen,
48     size_t csumlen,
49     unsigned long*  lastPartialLong,
50     size_t*  lastPartialLength
51     );
52 
53 static inline unsigned long
opal_bcopy_csum(const void * source,void * destination,size_t copylen,size_t csumlen)54 opal_bcopy_csum (
55     const void *  source,
56     void *  destination,
57     size_t copylen,
58     size_t csumlen
59     )
60 {
61     unsigned long plong = 0;
62     size_t plength = 0;
63     return opal_bcopy_csum_partial(source, destination, copylen, csumlen, &plong, &plength);
64 }
65 
66 OPAL_DECLSPEC unsigned int
67 opal_bcopy_uicsum_partial (
68     const void *  source,
69     void *  destination,
70     size_t copylen,
71     size_t csumlen,
72     unsigned int*  lastPartialInt,
73     size_t*  lastPartialLength
74     );
75 
76 static inline unsigned int
opal_bcopy_uicsum(const void * source,void * destination,size_t copylen,size_t csumlen)77 opal_bcopy_uicsum (
78     const void *  source,
79     void *  destination,
80     size_t copylen,
81     size_t csumlen
82     )
83 {
84     unsigned int pint = 0;
85     size_t plength = 0;
86     return opal_bcopy_uicsum_partial(source, destination, copylen, csumlen, &pint, &plength);
87 }
88 
89 OPAL_DECLSPEC unsigned long
90 opal_csum_partial (
91     const void *  source,
92     size_t csumlen,
93     unsigned long*  lastPartialLong,
94     size_t*  lastPartialLength
95     );
96 
97 
98 static inline unsigned long
opal_csum(const void * source,size_t csumlen)99 opal_csum(const void *  source, size_t csumlen)
100 {
101     unsigned long lastPartialLong = 0;
102     size_t lastPartialLength = 0;
103     return opal_csum_partial(source, csumlen, &lastPartialLong, &lastPartialLength);
104 }
105 /*
106  * The buffer passed to this function is assumed to be 16-bit aligned
107  */
108 static inline uint16_t
opal_csum16(const void * source,size_t csumlen)109 opal_csum16 (const void *  source, size_t csumlen)
110 {
111     uint16_t *src = (uint16_t *) source;
112     register uint32_t csum = 0;
113 
114     while (csumlen > 1) {
115 	    csum += *src++;
116         csumlen -= 2;
117     }
118     /* Add leftover byte, if any */
119     if(csumlen > 0)
120         csum += *((unsigned char*)src);
121     /* Fold 32-bit checksum to 16 bits */
122     while(csum >> 16) {
123         csum = (csum & 0xFFFF) + (csum >> 16);
124     }
125     return csum;
126 }
127 
128 OPAL_DECLSPEC unsigned int
129 opal_uicsum_partial (
130     const void *  source,
131     size_t csumlen,
132     unsigned int *  lastPartialInt,
133     size_t*  lastPartialLength
134     );
135 
136 static inline unsigned int
opal_uicsum(const void * source,size_t csumlen)137 opal_uicsum(const void *  source, size_t csumlen)
138 {
139     unsigned int lastPartialInt = 0;
140     size_t lastPartialLength = 0;
141     return opal_uicsum_partial(source, csumlen, &lastPartialInt, &lastPartialLength);
142 }
143 
144 /*
145  * CRC Support
146  */
147 
148 void opal_initialize_crc_table(void);
149 
150 OPAL_DECLSPEC unsigned int
151 opal_bcopy_uicrc_partial(
152     const void *  source,
153     void *  destination,
154     size_t copylen,
155     size_t crclen,
156     unsigned int partial_crc);
157 
158 static inline unsigned int
opal_bcopy_uicrc(const void * source,void * destination,size_t copylen,size_t crclen)159 opal_bcopy_uicrc(
160     const void *  source,
161     void *  destination,
162     size_t copylen,
163     size_t crclen)
164 {
165     return opal_bcopy_uicrc_partial(source, destination, copylen, crclen, CRC_INITIAL_REGISTER);
166 }
167 
168 OPAL_DECLSPEC unsigned int
169 opal_uicrc_partial(
170     const void *  source,
171     size_t crclen,
172     unsigned int partial_crc);
173 
174 
175 static inline unsigned int
opal_uicrc(const void * source,size_t crclen)176 opal_uicrc(const void *  source, size_t crclen)
177 {
178     return opal_uicrc_partial(source, crclen, CRC_INITIAL_REGISTER);
179 }
180 
181 END_C_DECLS
182 
183 #endif
184 
185