// SPDX-License-Identifier: GPL-2.0
//
// mcp251xfd - Microchip MCP251xFD Family CAN controller driver
//
// Copyright (c) 2020 Pengutronix,
// Marc Kleine-Budde <kernel@pengutronix.de>
//
// Based on:
//
// CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
//
// Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
//
#include "mcp251xfd.h"
/* The standard crc16 in linux/crc16.h is unfortunately not computing
* the correct results ( left shift vs . right shift ) . So here an
* implementation with a table generated with the help of :
*
* http : //lkml.iu.edu/hypermail/linux/kernel/0508.1/1085.html
*/
static const u16 mcp251xfd_crc16_table[] = {
0 x0000, 0 x8005, 0 x800f, 0 x000a, 0 x801b, 0 x001e, 0 x0014, 0 x8011,
0 x8033, 0 x0036, 0 x003c, 0 x8039, 0 x0028, 0 x802d, 0 x8027, 0 x0022,
0 x8063, 0 x0066, 0 x006c, 0 x8069, 0 x0078, 0 x807d, 0 x8077, 0 x0072,
0 x0050, 0 x8055, 0 x805f, 0 x005a, 0 x804b, 0 x004e, 0 x0044, 0 x8041,
0 x80c3, 0 x00c6, 0 x00cc, 0 x80c9, 0 x00d8, 0 x80dd, 0 x80d7, 0 x00d2,
0 x00f0, 0 x80f5, 0 x80ff, 0 x00fa, 0 x80eb, 0 x00ee, 0 x00e4, 0 x80e1,
0 x00a0, 0 x80a5, 0 x80af, 0 x00aa, 0 x80bb, 0 x00be, 0 x00b4, 0 x80b1,
0 x8093, 0 x0096, 0 x009c, 0 x8099, 0 x0088, 0 x808d, 0 x8087, 0 x0082,
0 x8183, 0 x0186, 0 x018c, 0 x8189, 0 x0198, 0 x819d, 0 x8197, 0 x0192,
0 x01b0, 0 x81b5, 0 x81bf, 0 x01ba, 0 x81ab, 0 x01ae, 0 x01a4, 0 x81a1,
0 x01e0, 0 x81e5, 0 x81ef, 0 x01ea, 0 x81fb, 0 x01fe, 0 x01f4, 0 x81f1,
0 x81d3, 0 x01d6, 0 x01dc, 0 x81d9, 0 x01c8, 0 x81cd, 0 x81c7, 0 x01c2,
0 x0140, 0 x8145, 0 x814f, 0 x014a, 0 x815b, 0 x015e, 0 x0154, 0 x8151,
0 x8173, 0 x0176, 0 x017c, 0 x8179, 0 x0168, 0 x816d, 0 x8167, 0 x0162,
0 x8123, 0 x0126, 0 x012c, 0 x8129, 0 x0138, 0 x813d, 0 x8137, 0 x0132,
0 x0110, 0 x8115, 0 x811f, 0 x011a, 0 x810b, 0 x010e, 0 x0104, 0 x8101,
0 x8303, 0 x0306, 0 x030c, 0 x8309, 0 x0318, 0 x831d, 0 x8317, 0 x0312,
0 x0330, 0 x8335, 0 x833f, 0 x033a, 0 x832b, 0 x032e, 0 x0324, 0 x8321,
0 x0360, 0 x8365, 0 x836f, 0 x036a, 0 x837b, 0 x037e, 0 x0374, 0 x8371,
0 x8353, 0 x0356, 0 x035c, 0 x8359, 0 x0348, 0 x834d, 0 x8347, 0 x0342,
0 x03c0, 0 x83c5, 0 x83cf, 0 x03ca, 0 x83db, 0 x03de, 0 x03d4, 0 x83d1,
0 x83f3, 0 x03f6, 0 x03fc, 0 x83f9, 0 x03e8, 0 x83ed, 0 x83e7, 0 x03e2,
0 x83a3, 0 x03a6, 0 x03ac, 0 x83a9, 0 x03b8, 0 x83bd, 0 x83b7, 0 x03b2,
0 x0390, 0 x8395, 0 x839f, 0 x039a, 0 x838b, 0 x038e, 0 x0384, 0 x8381,
0 x0280, 0 x8285, 0 x828f, 0 x028a, 0 x829b, 0 x029e, 0 x0294, 0 x8291,
0 x82b3, 0 x02b6, 0 x02bc, 0 x82b9, 0 x02a8, 0 x82ad, 0 x82a7, 0 x02a2,
0 x82e3, 0 x02e6, 0 x02ec, 0 x82e9, 0 x02f8, 0 x82fd, 0 x82f7, 0 x02f2,
0 x02d0, 0 x82d5, 0 x82df, 0 x02da, 0 x82cb, 0 x02ce, 0 x02c4, 0 x82c1,
0 x8243, 0 x0246, 0 x024c, 0 x8249, 0 x0258, 0 x825d, 0 x8257, 0 x0252,
0 x0270, 0 x8275, 0 x827f, 0 x027a, 0 x826b, 0 x026e, 0 x0264, 0 x8261,
0 x0220, 0 x8225, 0 x822f, 0 x022a, 0 x823b, 0 x023e, 0 x0234, 0 x8231,
0 x8213, 0 x0216, 0 x021c, 0 x8219, 0 x0208, 0 x820d, 0 x8207, 0 x0202
};
static inline u16 mcp251xfd_crc16_byte(u16 crc, const u8 data)
{
u8 index = (crc >> 8 ) ^ data;
return (crc << 8 ) ^ mcp251xfd_crc16_table[index];
}
static u16 mcp251xfd_crc16(u16 crc, u8 const *buffer, size_t len)
{
while (len--)
crc = mcp251xfd_crc16_byte(crc, *buffer++);
return crc;
}
u16 mcp251xfd_crc16_compute(const void *data, size_t data_size)
{
u16 crc = 0 xffff;
return mcp251xfd_crc16(crc, data, data_size);
}
u16 mcp251xfd_crc16_compute2(const void *cmd, size_t cmd_size,
const void *data, size_t data_size)
{
u16 crc;
crc = mcp251xfd_crc16_compute(cmd, cmd_size);
crc = mcp251xfd_crc16(crc, data, data_size);
return crc;
}
Messung V0.5 in Prozent C=84 H=89 G=86
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-10-03)
¤
*© Formatika GbR, Deutschland