blob: a51780f60484608569ebe6b7e2a53b7a8765a6a9 [file] [log] [blame]
Bob Beers50ee11f2010-03-04 08:40:46 -05001/* Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobbs'
2 * Journal, May 1992, pp. 64-67. This algorithm generates the same CRC
3 * values as ZMODEM and PKZIP
4 *
5 * Copyright (C) 2002-2005 SBE, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/types.h>
19#include "pmcc4_sysdep.h"
20#include "sbecom_inline_linux.h"
21#include "sbe_promformat.h"
22
23/* defines */
24#define CRC32_POLYNOMIAL 0xEDB88320L
25#define CRC_TABLE_ENTRIES 256
26
27
28
29static u_int32_t crcTableInit;
30
31#ifdef STATIC_CRC_TABLE
32static u_int32_t CRCTable[CRC_TABLE_ENTRIES];
33
34#endif
35
36
37/***************************************************************************
38*
39* genCrcTable - fills in CRCTable, as used by sbeCrc()
40*
41* RETURNS: N/A
42*
43* ERRNO: N/A
44***************************************************************************/
45
46static void
Johan Meiring477953e2012-11-20 19:28:51 +020047genCrcTable(u_int32_t *CRCTable)
Bob Beers50ee11f2010-03-04 08:40:46 -050048{
Johan Meiring0b7ccbe2012-11-20 19:28:49 +020049 int ii, jj;
50 u_int32_t crc;
Bob Beers50ee11f2010-03-04 08:40:46 -050051
Johan Meiring3effcd02012-11-20 19:28:50 +020052 for (ii = 0; ii < CRC_TABLE_ENTRIES; ii++) {
Johan Meiring0b7ccbe2012-11-20 19:28:49 +020053 crc = ii;
Johan Meiring3effcd02012-11-20 19:28:50 +020054 for (jj = 8; jj > 0; jj--) {
Johan Meiring0b7ccbe2012-11-20 19:28:49 +020055 if (crc & 1)
56 crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
57 else
58 crc >>= 1;
59 }
60 CRCTable[ii] = crc;
61 }
Bob Beers50ee11f2010-03-04 08:40:46 -050062
Johan Meiring0b7ccbe2012-11-20 19:28:49 +020063 crcTableInit++;
Bob Beers50ee11f2010-03-04 08:40:46 -050064}
65
66
67/***************************************************************************
68*
69* sbeCrc - generates a CRC on a given buffer, and initial CRC
70*
71* This routine calculates the CRC for a buffer of data using the
72* table lookup method. It accepts an original value for the crc,
73* and returns the updated value. This permits "catenation" of
74* discontiguous buffers. An original value of 0 for the "first"
75* buffer is the norm.
76*
77* Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobb's
78* Journal, May 1992, pp. 64-67. This algorithm generates the same CRC
79* values as ZMODEM and PKZIP.
80*
81* RETURNS: calculated crc of block
82*
83*/
84
85void
Johan Meiring477953e2012-11-20 19:28:51 +020086sbeCrc(u_int8_t *buffer, /* data buffer to crc */
Johan Meiring0b7ccbe2012-11-20 19:28:49 +020087 u_int32_t count, /* length of block in bytes */
88 u_int32_t initialCrc, /* starting CRC */
89 u_int32_t *result)
Bob Beers50ee11f2010-03-04 08:40:46 -050090{
Sachin Kamatc11afaa2013-09-27 09:36:34 +053091 u_int32_t *tbl = NULL;
Johan Meiring0b7ccbe2012-11-20 19:28:49 +020092 u_int32_t temp1, temp2, crc;
Bob Beers50ee11f2010-03-04 08:40:46 -050093
Johan Meiring0b7ccbe2012-11-20 19:28:49 +020094 /*
95 * if table not yet created, do so. Don't care about "extra" time
96 * checking this every time sbeCrc() is called, since CRC calculations
97 * are already time consuming
98 */
Johan Meiring3effcd02012-11-20 19:28:50 +020099 if (!crcTableInit) {
Bob Beers50ee11f2010-03-04 08:40:46 -0500100#ifdef STATIC_CRC_TABLE
Johan Meiring0b7ccbe2012-11-20 19:28:49 +0200101 tbl = &CRCTable;
Johan Meiring477953e2012-11-20 19:28:51 +0200102 genCrcTable(tbl);
Bob Beers50ee11f2010-03-04 08:40:46 -0500103#else
Daeseok Youn693d9632014-04-18 09:31:35 +0900104 tbl = kzalloc(CRC_TABLE_ENTRIES * sizeof(u_int32_t),
105 GFP_KERNEL);
Sachin Kamatc11afaa2013-09-27 09:36:34 +0530106 if (!tbl) {
Johan Meiring0b7ccbe2012-11-20 19:28:49 +0200107 *result = 0; /* dummy up return value due to malloc
108 * failure */
109 return;
110 }
Johan Meiring477953e2012-11-20 19:28:51 +0200111 genCrcTable(tbl);
Bob Beers50ee11f2010-03-04 08:40:46 -0500112#endif
Johan Meiring0b7ccbe2012-11-20 19:28:49 +0200113 }
114 /* inverting bits makes ZMODEM & PKZIP compatible */
115 crc = initialCrc ^ 0xFFFFFFFFL;
Bob Beers50ee11f2010-03-04 08:40:46 -0500116
Johan Meiring3effcd02012-11-20 19:28:50 +0200117 while (count-- != 0) {
Johan Meiring0b7ccbe2012-11-20 19:28:49 +0200118 temp1 = (crc >> 8) & 0x00FFFFFFL;
119 temp2 = tbl[((int) crc ^ *buffer++) & 0xff];
120 crc = temp1 ^ temp2;
121 }
Bob Beers50ee11f2010-03-04 08:40:46 -0500122
Johan Meiring0b7ccbe2012-11-20 19:28:49 +0200123 crc ^= 0xFFFFFFFFL;
Bob Beers50ee11f2010-03-04 08:40:46 -0500124
Johan Meiring0b7ccbe2012-11-20 19:28:49 +0200125 *result = crc;
Bob Beers50ee11f2010-03-04 08:40:46 -0500126
127#ifndef STATIC_CRC_TABLE
Johan Meiring0b7ccbe2012-11-20 19:28:49 +0200128 crcTableInit = 0;
Daeseok Youn693d9632014-04-18 09:31:35 +0900129 kfree(tbl);
Bob Beers50ee11f2010-03-04 08:40:46 -0500130#endif
131}
132
133/*** End-of-File ***/