// 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=94 H=93 G=93
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-07)
¤
*© Formatika GbR, Deutschland