13c838a9fSAndrew Rybchenko /*-
2*929c7febSAndrew Rybchenko * Copyright (c) 2013-2016 Solarflare Communications Inc.
33c838a9fSAndrew Rybchenko * All rights reserved.
43c838a9fSAndrew Rybchenko *
53c838a9fSAndrew Rybchenko * Redistribution and use in source and binary forms, with or without
63c838a9fSAndrew Rybchenko * modification, are permitted provided that the following conditions are met:
73c838a9fSAndrew Rybchenko *
83c838a9fSAndrew Rybchenko * 1. Redistributions of source code must retain the above copyright notice,
93c838a9fSAndrew Rybchenko * this list of conditions and the following disclaimer.
103c838a9fSAndrew Rybchenko * 2. Redistributions in binary form must reproduce the above copyright notice,
113c838a9fSAndrew Rybchenko * this list of conditions and the following disclaimer in the documentation
123c838a9fSAndrew Rybchenko * and/or other materials provided with the distribution.
133c838a9fSAndrew Rybchenko *
143c838a9fSAndrew Rybchenko * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
153c838a9fSAndrew Rybchenko * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
163c838a9fSAndrew Rybchenko * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
173c838a9fSAndrew Rybchenko * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
183c838a9fSAndrew Rybchenko * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
193c838a9fSAndrew Rybchenko * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
203c838a9fSAndrew Rybchenko * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
213c838a9fSAndrew Rybchenko * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
223c838a9fSAndrew Rybchenko * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
233c838a9fSAndrew Rybchenko * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
243c838a9fSAndrew Rybchenko * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
253c838a9fSAndrew Rybchenko *
263c838a9fSAndrew Rybchenko * The views and conclusions contained in the software and documentation are
273c838a9fSAndrew Rybchenko * those of the authors and should not be interpreted as representing official
283c838a9fSAndrew Rybchenko * policies, either expressed or implied, of the FreeBSD Project.
293c838a9fSAndrew Rybchenko */
303c838a9fSAndrew Rybchenko
313c838a9fSAndrew Rybchenko #include <sys/cdefs.h>
323c838a9fSAndrew Rybchenko #include "efx.h"
333c838a9fSAndrew Rybchenko #include "efx_impl.h"
343c838a9fSAndrew Rybchenko
353c838a9fSAndrew Rybchenko /*
363c838a9fSAndrew Rybchenko * Precomputed table for computing IEEE 802.3 CRC32
373c838a9fSAndrew Rybchenko * with polynomial 0x04c11db7 (bit-reversed 0xedb88320)
383c838a9fSAndrew Rybchenko */
393c838a9fSAndrew Rybchenko
40ef13016eSAndrew Rybchenko static const uint32_t efx_crc32_table[256] = {
413c838a9fSAndrew Rybchenko 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
423c838a9fSAndrew Rybchenko 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
433c838a9fSAndrew Rybchenko 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
443c838a9fSAndrew Rybchenko 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
453c838a9fSAndrew Rybchenko 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
463c838a9fSAndrew Rybchenko 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
473c838a9fSAndrew Rybchenko 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
483c838a9fSAndrew Rybchenko 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
493c838a9fSAndrew Rybchenko 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
503c838a9fSAndrew Rybchenko 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
513c838a9fSAndrew Rybchenko 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
523c838a9fSAndrew Rybchenko 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
533c838a9fSAndrew Rybchenko 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
543c838a9fSAndrew Rybchenko 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
553c838a9fSAndrew Rybchenko 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
563c838a9fSAndrew Rybchenko 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
573c838a9fSAndrew Rybchenko 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
583c838a9fSAndrew Rybchenko 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
593c838a9fSAndrew Rybchenko 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
603c838a9fSAndrew Rybchenko 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
613c838a9fSAndrew Rybchenko 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
623c838a9fSAndrew Rybchenko 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
633c838a9fSAndrew Rybchenko 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
643c838a9fSAndrew Rybchenko 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
653c838a9fSAndrew Rybchenko 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
663c838a9fSAndrew Rybchenko 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
673c838a9fSAndrew Rybchenko 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
683c838a9fSAndrew Rybchenko 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
693c838a9fSAndrew Rybchenko 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
703c838a9fSAndrew Rybchenko 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
713c838a9fSAndrew Rybchenko 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
723c838a9fSAndrew Rybchenko 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
733c838a9fSAndrew Rybchenko 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
743c838a9fSAndrew Rybchenko 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
753c838a9fSAndrew Rybchenko 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
763c838a9fSAndrew Rybchenko 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
773c838a9fSAndrew Rybchenko 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
783c838a9fSAndrew Rybchenko 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
793c838a9fSAndrew Rybchenko 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
803c838a9fSAndrew Rybchenko 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
813c838a9fSAndrew Rybchenko 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
823c838a9fSAndrew Rybchenko 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
833c838a9fSAndrew Rybchenko 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
843c838a9fSAndrew Rybchenko 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
853c838a9fSAndrew Rybchenko 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
863c838a9fSAndrew Rybchenko 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
873c838a9fSAndrew Rybchenko 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
883c838a9fSAndrew Rybchenko 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
893c838a9fSAndrew Rybchenko 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
903c838a9fSAndrew Rybchenko 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
913c838a9fSAndrew Rybchenko 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
923c838a9fSAndrew Rybchenko 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
933c838a9fSAndrew Rybchenko 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
943c838a9fSAndrew Rybchenko 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
953c838a9fSAndrew Rybchenko 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
963c838a9fSAndrew Rybchenko 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
973c838a9fSAndrew Rybchenko 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
983c838a9fSAndrew Rybchenko 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
993c838a9fSAndrew Rybchenko 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
1003c838a9fSAndrew Rybchenko 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
1013c838a9fSAndrew Rybchenko 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
1023c838a9fSAndrew Rybchenko 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
1033c838a9fSAndrew Rybchenko 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
1043c838a9fSAndrew Rybchenko 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
1053c838a9fSAndrew Rybchenko };
1063c838a9fSAndrew Rybchenko
1073c838a9fSAndrew Rybchenko /* Calculate the IEEE 802.3 CRC32 of a MAC addr */
1083c838a9fSAndrew Rybchenko __checkReturn uint32_t
efx_crc32_calculate(__in uint32_t crc_init,__in_ecount (length)uint8_t const * input,__in int length)1093c838a9fSAndrew Rybchenko efx_crc32_calculate(
1103c838a9fSAndrew Rybchenko __in uint32_t crc_init,
1113c838a9fSAndrew Rybchenko __in_ecount(length) uint8_t const *input,
1123c838a9fSAndrew Rybchenko __in int length)
1133c838a9fSAndrew Rybchenko {
1143c838a9fSAndrew Rybchenko int index;
1153c838a9fSAndrew Rybchenko uint32_t crc = crc_init;
1163c838a9fSAndrew Rybchenko
1173c838a9fSAndrew Rybchenko for (index = 0; index < length; index++) {
1183c838a9fSAndrew Rybchenko uint32_t data = *(input++);
119ef13016eSAndrew Rybchenko crc = (crc >> 8) ^ efx_crc32_table[(crc ^ data) & 0xff];
1203c838a9fSAndrew Rybchenko }
1213c838a9fSAndrew Rybchenko
1223c838a9fSAndrew Rybchenko return (crc);
1233c838a9fSAndrew Rybchenko }
124