blob: b8a89947ac480e4d92ff46ac8a2404e8449306f6 [file] [log] [blame]
/*
<:copyright-BRCM:2016:DUAL/GPL:standard
Broadcom Proprietary and Confidential.(c) 2016 Broadcom
All Rights Reserved
Unless you and Broadcom execute a separate written software license
agreement governing use of this software, this software is licensed
to you under the terms of the GNU General Public License version 2
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
with the following added to such license:
As a special exception, the copyright holders of this software give
you permission to link this software with independent modules, and
to copy and distribute the resulting executable under terms of your
choice, provided that you also meet, for each linked independent
module, the terms and conditions of the license of that module.
An independent module is a module which is not derived from this
software. The special exception does not apply to any modifications
of the software.
Not withstanding the above, under no circumstances may you combine
this software in any way with any other Broadcom software provided
under a license other than the GPL, without Broadcom's express prior
written consent.
:>
*/
#include "bcmolt_utils.h"
/* HexPrint a single line */
#define BYTES_IN_LINE 16
#define b2a(c) (isprint(c)?c:'.')
static void _hexprint1(bcmos_msg_print_cb print_cb, void *context, uint16_t o, const uint8_t *p_data, uint16_t count, const char *indent)
{
int i;
if (indent)
print_cb(context, "%s", indent);
print_cb(context, "%04x: ", o);
for (i=0; i<count; i++)
{
print_cb(context, "%02x", p_data[i]);
if (!((i+1)%4))
print_cb(context, " ");
}
for (; i<BYTES_IN_LINE; i++)
{
if (!((i+1)%4))
print_cb(context, " ");
else
print_cb(context, " ");
}
for (i=0; i<count; i++)
print_cb(context, "%c", b2a(p_data[i]));
print_cb(context, "\n");
}
void bcmos_hexdump(bcmos_msg_print_cb print_cb, void *context, const void *buffer, uint32_t offset, uint32_t count, const char *indent)
{
const uint8_t *p_data = buffer;
uint16_t n;
while (count)
{
n = (count > BYTES_IN_LINE) ? BYTES_IN_LINE : count;
_hexprint1(print_cb, context, offset, p_data, n, indent);
count -= n;
p_data += n;
offset += n;
}
}
void bcmos_hexdump_one_line(const char *funcname, /* __FUNCTION__ */
uint32_t lineno, /* __LINE__ */
bcmos_msg_print_cb print_cb,
void *context,
const void *buffer, /* start of memory region to dump */
uint32_t start_offset, /* start offset into the region */
uint32_t byte_count, /* number of bytes in region to dump */
const char *prefix, /* optional prefix string */
const char *suffix) /* optional suffix string */
{
const uint8_t *p_data = buffer;
uint32_t data_offset = start_offset;
size_t max_buf_size = 8000; /* room enough to dump ~2600 bytes with shortish prefixes/suffixes */
char *out_buf = bcmos_calloc(max_buf_size);
size_t out_buf_offset = 0;
uint32_t tmp_num_chars = 0;
BUG_UNLESS(out_buf);
memset(out_buf, 0, max_buf_size);
if (prefix)
{
tmp_num_chars = snprintf(out_buf + out_buf_offset, /* out_buf start offset */
max_buf_size - out_buf_offset, /* remaining space in out_buf */
"\n%40s:%-5u %s", funcname, lineno, prefix);
}
else
{
tmp_num_chars = snprintf(out_buf + out_buf_offset, /* out_buf start offset */
max_buf_size - out_buf_offset, /* remaining space in out_buf */
"\n");
}
out_buf_offset += tmp_num_chars;
while ((data_offset < (start_offset + byte_count)) && (out_buf_offset < max_buf_size))
{
tmp_num_chars = snprintf(out_buf + out_buf_offset, /* out_buf start offset */
max_buf_size - out_buf_offset, /* remaining space in out_buf */
"%02x ",
p_data[data_offset++]); /* byte to dump */
BUG_UNLESS(3 == tmp_num_chars);
out_buf_offset += tmp_num_chars;
}
if (tmp_num_chars < max_buf_size)
{
if (suffix)
{
tmp_num_chars = snprintf(out_buf + out_buf_offset, /* out_buf start offset */
max_buf_size - out_buf_offset, /* remaining space in out_buf */
"%s", suffix);
}
else
{
tmp_num_chars = snprintf(out_buf + out_buf_offset, /* out_buf start offset */
max_buf_size - out_buf_offset, /* remaining space in out_buf */
"\n");
}
out_buf_offset += tmp_num_chars;
BUG_UNLESS(out_buf_offset < max_buf_size);
}
print_cb(context, "%s", out_buf);
bcmos_free(out_buf);
}
static uint32_t eth_crc32_tab[] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
uint32_t eth_calc_crc32(uint32_t crc, const void *buf, size_t size)
{
const uint8_t *p;
p = buf;
crc = crc ^ ~0U;
while (size--)
crc = eth_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return crc ^ ~0U;
}