Commit e3d4ee7d authored by Thomas Kopp's avatar Thomas Kopp Committed by Marc Kleine-Budde

can: mcp251xfd: mcp251xfd_regmap_crc_read(): update workaround broken CRC on TBC register

The mcp251xfd compatible chips have an erratum ([1], [2]), where the
received CRC doesn't match the calculated CRC. In commit
c7eb923c ("can: mcp251xfd: mcp251xfd_regmap_crc_read(): work
around broken CRC on TBC register") the following workaround was
implementierend.

- If a CRC read error on the TBC register is detected and the first
  byte is 0x00 or 0x80, the most significant bit of the first byte is
  flipped and the CRC is calculated again.
- If the CRC now matches, the _original_ data is passed to the reader.
  For now we assume transferred data was OK.

New investigations and simulations indicate that the CRC send by the
device is calculated on correct data, and the data is incorrectly
received by the SPI host controller.

Use flipped instead of original data and update workaround description
in mcp251xfd_regmap_crc_read().

[1] mcp2517fd: DS80000792C: "Incorrect CRC for certain READ_CRC commands"
[2] mcp2518fd: DS80000789C: "Incorrect CRC for certain READ_CRC commands"

Link: https://lore.kernel.org/all/DM4PR11MB53901D49578FE265B239E55AFB7C9@DM4PR11MB5390.namprd11.prod.outlook.com
Fixes: c7eb923c ("can: mcp251xfd: mcp251xfd_regmap_crc_read(): work around broken CRC on TBC register")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarThomas Kopp <thomas.kopp@microchip.com>
[mkl: split into 2 patches, update patch description and documentation]
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 406cc9cd
...@@ -343,9 +343,8 @@ mcp251xfd_regmap_crc_read(void *context, ...@@ -343,9 +343,8 @@ mcp251xfd_regmap_crc_read(void *context,
* *
* If the highest bit in the lowest byte is flipped * If the highest bit in the lowest byte is flipped
* the transferred CRC matches the calculated one. We * the transferred CRC matches the calculated one. We
* assume for now the CRC calculation in the chip * assume for now the CRC operates on the correct
* works on wrong data and the transferred data is * data.
* correct.
*/ */
if (reg == MCP251XFD_REG_TBC && if (reg == MCP251XFD_REG_TBC &&
((buf_rx->data[0] & 0xf8) == 0x0 || ((buf_rx->data[0] & 0xf8) == 0x0 ||
...@@ -359,10 +358,8 @@ mcp251xfd_regmap_crc_read(void *context, ...@@ -359,10 +358,8 @@ mcp251xfd_regmap_crc_read(void *context,
val_len); val_len);
if (!err) { if (!err) {
/* If CRC is now correct, assume /* If CRC is now correct, assume
* transferred data was OK, flip bit * flipped data is OK.
* back to original value.
*/ */
buf_rx->data[0] ^= 0x80;
goto out; goto out;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment