610 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// mcp251xfd - Microchip MCP251xFD Family CAN controller driver4//5// Copyright (c) 2019, 2020, 2021 Pengutronix,6// Marc Kleine-Budde <kernel@pengutronix.de>7//8 9#include "mcp251xfd.h"10 11#include <linux/unaligned.h>12 13static const struct regmap_config mcp251xfd_regmap_crc;14 15static int16mcp251xfd_regmap_nocrc_write(void *context, const void *data, size_t count)17{18 struct spi_device *spi = context;19 20 return spi_write(spi, data, count);21}22 23static int24mcp251xfd_regmap_nocrc_gather_write(void *context,25 const void *reg, size_t reg_len,26 const void *val, size_t val_len)27{28 struct spi_device *spi = context;29 struct mcp251xfd_priv *priv = spi_get_drvdata(spi);30 struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx;31 struct spi_transfer xfer[] = {32 {33 .tx_buf = buf_tx,34 .len = sizeof(buf_tx->cmd) + val_len,35 },36 };37 38 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16));39 40 if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&41 reg_len != sizeof(buf_tx->cmd.cmd))42 return -EINVAL;43 44 memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd));45 memcpy(buf_tx->data, val, val_len);46 47 return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));48}49 50static inline bool51mcp251xfd_update_bits_read_reg(const struct mcp251xfd_priv *priv,52 unsigned int reg)53{54 struct mcp251xfd_rx_ring *ring;55 int n;56 57 switch (reg) {58 case MCP251XFD_REG_INT:59 case MCP251XFD_REG_TEFCON:60 case MCP251XFD_REG_FLTCON(0):61 case MCP251XFD_REG_ECCSTAT:62 case MCP251XFD_REG_CRC:63 return false;64 case MCP251XFD_REG_CON:65 case MCP251XFD_REG_OSC:66 case MCP251XFD_REG_ECCCON:67 return true;68 default:69 mcp251xfd_for_each_rx_ring(priv, ring, n) {70 if (reg == MCP251XFD_REG_FIFOCON(ring->fifo_nr))71 return false;72 if (reg == MCP251XFD_REG_FIFOSTA(ring->fifo_nr))73 return true;74 }75 76 WARN(1, "Status of reg 0x%04x unknown.\n", reg);77 }78 79 return true;80}81 82static int83mcp251xfd_regmap_nocrc_update_bits(void *context, unsigned int reg,84 unsigned int mask, unsigned int val)85{86 struct spi_device *spi = context;87 struct mcp251xfd_priv *priv = spi_get_drvdata(spi);88 struct mcp251xfd_map_buf_nocrc *buf_rx = priv->map_buf_nocrc_rx;89 struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx;90 __le32 orig_le32 = 0, mask_le32, val_le32, tmp_le32;91 u8 first_byte, last_byte, len;92 int err;93 94 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16));95 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16));96 97 if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&98 mask == 0)99 return -EINVAL;100 101 first_byte = mcp251xfd_first_byte_set(mask);102 last_byte = mcp251xfd_last_byte_set(mask);103 len = last_byte - first_byte + 1;104 105 if (mcp251xfd_update_bits_read_reg(priv, reg)) {106 struct spi_transfer xfer[2] = { };107 struct spi_message msg;108 109 spi_message_init(&msg);110 spi_message_add_tail(&xfer[0], &msg);111 112 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) {113 xfer[0].tx_buf = buf_tx;114 xfer[0].len = sizeof(buf_tx->cmd);115 116 xfer[1].rx_buf = buf_rx->data;117 xfer[1].len = len;118 spi_message_add_tail(&xfer[1], &msg);119 } else {120 xfer[0].tx_buf = buf_tx;121 xfer[0].rx_buf = buf_rx;122 xfer[0].len = sizeof(buf_tx->cmd) + len;123 124 if (MCP251XFD_SANITIZE_SPI)125 memset(buf_tx->data, 0x0, len);126 }127 128 mcp251xfd_spi_cmd_read_nocrc(&buf_tx->cmd, reg + first_byte);129 err = spi_sync(spi, &msg);130 if (err)131 return err;132 133 memcpy(&orig_le32, buf_rx->data, len);134 }135 136 mask_le32 = cpu_to_le32(mask >> BITS_PER_BYTE * first_byte);137 val_le32 = cpu_to_le32(val >> BITS_PER_BYTE * first_byte);138 139 tmp_le32 = orig_le32 & ~mask_le32;140 tmp_le32 |= val_le32 & mask_le32;141 142 mcp251xfd_spi_cmd_write_nocrc(&buf_tx->cmd, reg + first_byte);143 memcpy(buf_tx->data, &tmp_le32, len);144 145 return spi_write(spi, buf_tx, sizeof(buf_tx->cmd) + len);146}147 148static int149mcp251xfd_regmap_nocrc_read(void *context,150 const void *reg, size_t reg_len,151 void *val_buf, size_t val_len)152{153 struct spi_device *spi = context;154 struct mcp251xfd_priv *priv = spi_get_drvdata(spi);155 struct mcp251xfd_map_buf_nocrc *buf_rx = priv->map_buf_nocrc_rx;156 struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx;157 struct spi_transfer xfer[2] = { };158 struct spi_message msg;159 int err;160 161 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16));162 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16));163 164 if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&165 reg_len != sizeof(buf_tx->cmd.cmd))166 return -EINVAL;167 168 spi_message_init(&msg);169 spi_message_add_tail(&xfer[0], &msg);170 171 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) {172 xfer[0].tx_buf = reg;173 xfer[0].len = sizeof(buf_tx->cmd);174 175 xfer[1].rx_buf = val_buf;176 xfer[1].len = val_len;177 spi_message_add_tail(&xfer[1], &msg);178 } else {179 xfer[0].tx_buf = buf_tx;180 xfer[0].rx_buf = buf_rx;181 xfer[0].len = sizeof(buf_tx->cmd) + val_len;182 183 memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd));184 if (MCP251XFD_SANITIZE_SPI)185 memset(buf_tx->data, 0x0, val_len);186 }187 188 err = spi_sync(spi, &msg);189 if (err)190 return err;191 192 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX))193 memcpy(val_buf, buf_rx->data, val_len);194 195 return 0;196}197 198static int199mcp251xfd_regmap_crc_gather_write(void *context,200 const void *reg_p, size_t reg_len,201 const void *val, size_t val_len)202{203 struct spi_device *spi = context;204 struct mcp251xfd_priv *priv = spi_get_drvdata(spi);205 struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx;206 struct spi_transfer xfer[] = {207 {208 .tx_buf = buf_tx,209 .len = sizeof(buf_tx->cmd) + val_len +210 sizeof(buf_tx->crc),211 },212 };213 u16 reg = *(u16 *)reg_p;214 u16 crc;215 216 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8));217 218 if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&219 reg_len != sizeof(buf_tx->cmd.cmd) +220 mcp251xfd_regmap_crc.pad_bits / BITS_PER_BYTE)221 return -EINVAL;222 223 mcp251xfd_spi_cmd_write_crc(&buf_tx->cmd, reg, val_len);224 memcpy(buf_tx->data, val, val_len);225 226 crc = mcp251xfd_crc16_compute(buf_tx, sizeof(buf_tx->cmd) + val_len);227 put_unaligned_be16(crc, buf_tx->data + val_len);228 229 return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));230}231 232static int233mcp251xfd_regmap_crc_write(void *context,234 const void *data, size_t count)235{236 const size_t data_offset = sizeof(__be16) +237 mcp251xfd_regmap_crc.pad_bits / BITS_PER_BYTE;238 239 return mcp251xfd_regmap_crc_gather_write(context,240 data, data_offset,241 data + data_offset,242 count - data_offset);243}244 245static int246mcp251xfd_regmap_crc_read_check_crc(const struct mcp251xfd_map_buf_crc * const buf_rx,247 const struct mcp251xfd_map_buf_crc * const buf_tx,248 unsigned int data_len)249{250 u16 crc_received, crc_calculated;251 252 crc_received = get_unaligned_be16(buf_rx->data + data_len);253 crc_calculated = mcp251xfd_crc16_compute2(&buf_tx->cmd,254 sizeof(buf_tx->cmd),255 buf_rx->data,256 data_len);257 if (crc_received != crc_calculated)258 return -EBADMSG;259 260 return 0;261}262 263static int264mcp251xfd_regmap_crc_read_one(struct mcp251xfd_priv *priv,265 struct spi_message *msg, unsigned int data_len)266{267 const struct mcp251xfd_map_buf_crc *buf_rx = priv->map_buf_crc_rx;268 const struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx;269 int err;270 271 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8));272 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8));273 274 err = spi_sync(priv->spi, msg);275 if (err)276 return err;277 278 return mcp251xfd_regmap_crc_read_check_crc(buf_rx, buf_tx, data_len);279}280 281static int282mcp251xfd_regmap_crc_read(void *context,283 const void *reg_p, size_t reg_len,284 void *val_buf, size_t val_len)285{286 struct spi_device *spi = context;287 struct mcp251xfd_priv *priv = spi_get_drvdata(spi);288 struct mcp251xfd_map_buf_crc *buf_rx = priv->map_buf_crc_rx;289 struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx;290 struct spi_transfer xfer[2] = { };291 struct spi_message msg;292 u16 reg = *(u16 *)reg_p;293 int i, err;294 295 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8));296 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8));297 298 if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&299 reg_len != sizeof(buf_tx->cmd.cmd) +300 mcp251xfd_regmap_crc.pad_bits / BITS_PER_BYTE)301 return -EINVAL;302 303 spi_message_init(&msg);304 spi_message_add_tail(&xfer[0], &msg);305 306 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) {307 xfer[0].tx_buf = buf_tx;308 xfer[0].len = sizeof(buf_tx->cmd);309 310 xfer[1].rx_buf = buf_rx->data;311 xfer[1].len = val_len + sizeof(buf_tx->crc);312 spi_message_add_tail(&xfer[1], &msg);313 } else {314 xfer[0].tx_buf = buf_tx;315 xfer[0].rx_buf = buf_rx;316 xfer[0].len = sizeof(buf_tx->cmd) + val_len +317 sizeof(buf_tx->crc);318 319 if (MCP251XFD_SANITIZE_SPI)320 memset(buf_tx->data, 0x0, val_len +321 sizeof(buf_tx->crc));322 }323 324 mcp251xfd_spi_cmd_read_crc(&buf_tx->cmd, reg, val_len);325 326 for (i = 0; i < MCP251XFD_READ_CRC_RETRIES_MAX; i++) {327 err = mcp251xfd_regmap_crc_read_one(priv, &msg, val_len);328 if (!err)329 goto out;330 if (err != -EBADMSG)331 return err;332 333 /* MCP251XFD_REG_TBC is the time base counter334 * register. It increments once per SYS clock tick,335 * which is 20 or 40 MHz.336 *337 * Observation on the mcp2518fd shows that if the338 * lowest byte (which is transferred first on the SPI339 * bus) of that register is 0x00 or 0x80 the340 * calculated CRC doesn't always match the transferred341 * one. On the mcp2517fd this problem is not limited342 * to the first byte being 0x00 or 0x80.343 *344 * If the highest bit in the lowest byte is flipped345 * the transferred CRC matches the calculated one. We346 * assume for now the CRC operates on the correct347 * data.348 */349 if (reg == MCP251XFD_REG_TBC &&350 ((buf_rx->data[0] & 0xf8) == 0x0 ||351 (buf_rx->data[0] & 0xf8) == 0x80)) {352 /* Flip highest bit in lowest byte of le32 */353 buf_rx->data[0] ^= 0x80;354 355 /* re-check CRC */356 err = mcp251xfd_regmap_crc_read_check_crc(buf_rx,357 buf_tx,358 val_len);359 if (!err) {360 /* If CRC is now correct, assume361 * flipped data is OK.362 */363 goto out;364 }365 }366 367 /* MCP251XFD_REG_OSC is the first ever reg we read from.368 *369 * The chip may be in deep sleep and this SPI transfer370 * (i.e. the assertion of the CS) will wake the chip371 * up. This takes about 3ms. The CRC of this transfer372 * is wrong.373 *374 * Or there isn't a chip at all, in this case the CRC375 * will be wrong, too.376 *377 * In both cases ignore the CRC and copy the read data378 * to the caller. It will take care of both cases.379 *380 */381 if (reg == MCP251XFD_REG_OSC && val_len == sizeof(__le32)) {382 err = 0;383 goto out;384 }385 386 netdev_info(priv->ndev,387 "CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x) retrying.\n",388 reg, val_len, (int)val_len, buf_rx->data,389 get_unaligned_be16(buf_rx->data + val_len));390 }391 392 if (err) {393 netdev_err(priv->ndev,394 "CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x).\n",395 reg, val_len, (int)val_len, buf_rx->data,396 get_unaligned_be16(buf_rx->data + val_len));397 398 return err;399 }400out:401 memcpy(val_buf, buf_rx->data, val_len);402 403 return 0;404}405 406static const struct regmap_range mcp251xfd_reg_table_yes_range[] = {407 regmap_reg_range(0x000, 0x2ec), /* CAN FD Controller Module SFR */408 regmap_reg_range(0x400, 0xbfc), /* RAM */409 regmap_reg_range(0xe00, 0xe14), /* MCP2517/18FD SFR */410};411 412static const struct regmap_access_table mcp251xfd_reg_table = {413 .yes_ranges = mcp251xfd_reg_table_yes_range,414 .n_yes_ranges = ARRAY_SIZE(mcp251xfd_reg_table_yes_range),415};416 417static const struct regmap_config mcp251xfd_regmap_nocrc = {418 .name = "nocrc",419 .reg_bits = 16,420 .reg_stride = 4,421 .pad_bits = 0,422 .val_bits = 32,423 .max_register = 0xffc,424 .wr_table = &mcp251xfd_reg_table,425 .rd_table = &mcp251xfd_reg_table,426 .cache_type = REGCACHE_NONE,427 .read_flag_mask = (__force unsigned long)428 cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_READ),429 .write_flag_mask = (__force unsigned long)430 cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE),431};432 433static const struct regmap_bus mcp251xfd_bus_nocrc = {434 .write = mcp251xfd_regmap_nocrc_write,435 .gather_write = mcp251xfd_regmap_nocrc_gather_write,436 .reg_update_bits = mcp251xfd_regmap_nocrc_update_bits,437 .read = mcp251xfd_regmap_nocrc_read,438 .reg_format_endian_default = REGMAP_ENDIAN_BIG,439 .val_format_endian_default = REGMAP_ENDIAN_LITTLE,440 .max_raw_read = sizeof_field(struct mcp251xfd_map_buf_nocrc, data),441 .max_raw_write = sizeof_field(struct mcp251xfd_map_buf_nocrc, data),442};443 444static const struct regmap_config mcp251xfd_regmap_crc = {445 .name = "crc",446 .reg_bits = 16,447 .reg_stride = 4,448 .pad_bits = 16, /* keep data bits aligned */449 .val_bits = 32,450 .max_register = 0xffc,451 .wr_table = &mcp251xfd_reg_table,452 .rd_table = &mcp251xfd_reg_table,453 .cache_type = REGCACHE_NONE,454};455 456static const struct regmap_bus mcp251xfd_bus_crc = {457 .write = mcp251xfd_regmap_crc_write,458 .gather_write = mcp251xfd_regmap_crc_gather_write,459 .read = mcp251xfd_regmap_crc_read,460 .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,461 .val_format_endian_default = REGMAP_ENDIAN_LITTLE,462 .max_raw_read = sizeof_field(struct mcp251xfd_map_buf_crc, data),463 .max_raw_write = sizeof_field(struct mcp251xfd_map_buf_crc, data),464};465 466static inline bool467mcp251xfd_regmap_use_nocrc(struct mcp251xfd_priv *priv)468{469 return (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)) ||470 (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX));471}472 473static inline bool474mcp251xfd_regmap_use_crc(struct mcp251xfd_priv *priv)475{476 return (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) ||477 (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX);478}479 480static int481mcp251xfd_regmap_init_nocrc(struct mcp251xfd_priv *priv)482{483 if (!priv->map_nocrc) {484 struct regmap *map;485 486 map = devm_regmap_init(&priv->spi->dev, &mcp251xfd_bus_nocrc,487 priv->spi, &mcp251xfd_regmap_nocrc);488 if (IS_ERR(map))489 return PTR_ERR(map);490 491 priv->map_nocrc = map;492 }493 494 if (!priv->map_buf_nocrc_rx) {495 priv->map_buf_nocrc_rx =496 devm_kzalloc(&priv->spi->dev,497 sizeof(*priv->map_buf_nocrc_rx),498 GFP_KERNEL);499 if (!priv->map_buf_nocrc_rx)500 return -ENOMEM;501 }502 503 if (!priv->map_buf_nocrc_tx) {504 priv->map_buf_nocrc_tx =505 devm_kzalloc(&priv->spi->dev,506 sizeof(*priv->map_buf_nocrc_tx),507 GFP_KERNEL);508 if (!priv->map_buf_nocrc_tx)509 return -ENOMEM;510 }511 512 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG))513 priv->map_reg = priv->map_nocrc;514 515 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX))516 priv->map_rx = priv->map_nocrc;517 518 return 0;519}520 521static void mcp251xfd_regmap_destroy_nocrc(struct mcp251xfd_priv *priv)522{523 if (priv->map_buf_nocrc_rx) {524 devm_kfree(&priv->spi->dev, priv->map_buf_nocrc_rx);525 priv->map_buf_nocrc_rx = NULL;526 }527 if (priv->map_buf_nocrc_tx) {528 devm_kfree(&priv->spi->dev, priv->map_buf_nocrc_tx);529 priv->map_buf_nocrc_tx = NULL;530 }531}532 533static int534mcp251xfd_regmap_init_crc(struct mcp251xfd_priv *priv)535{536 if (!priv->map_crc) {537 struct regmap *map;538 539 map = devm_regmap_init(&priv->spi->dev, &mcp251xfd_bus_crc,540 priv->spi, &mcp251xfd_regmap_crc);541 if (IS_ERR(map))542 return PTR_ERR(map);543 544 priv->map_crc = map;545 }546 547 if (!priv->map_buf_crc_rx) {548 priv->map_buf_crc_rx =549 devm_kzalloc(&priv->spi->dev,550 sizeof(*priv->map_buf_crc_rx),551 GFP_KERNEL);552 if (!priv->map_buf_crc_rx)553 return -ENOMEM;554 }555 556 if (!priv->map_buf_crc_tx) {557 priv->map_buf_crc_tx =558 devm_kzalloc(&priv->spi->dev,559 sizeof(*priv->map_buf_crc_tx),560 GFP_KERNEL);561 if (!priv->map_buf_crc_tx)562 return -ENOMEM;563 }564 565 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)566 priv->map_reg = priv->map_crc;567 568 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX)569 priv->map_rx = priv->map_crc;570 571 return 0;572}573 574static void mcp251xfd_regmap_destroy_crc(struct mcp251xfd_priv *priv)575{576 if (priv->map_buf_crc_rx) {577 devm_kfree(&priv->spi->dev, priv->map_buf_crc_rx);578 priv->map_buf_crc_rx = NULL;579 }580 if (priv->map_buf_crc_tx) {581 devm_kfree(&priv->spi->dev, priv->map_buf_crc_tx);582 priv->map_buf_crc_tx = NULL;583 }584}585 586int mcp251xfd_regmap_init(struct mcp251xfd_priv *priv)587{588 int err;589 590 if (mcp251xfd_regmap_use_nocrc(priv)) {591 err = mcp251xfd_regmap_init_nocrc(priv);592 593 if (err)594 return err;595 } else {596 mcp251xfd_regmap_destroy_nocrc(priv);597 }598 599 if (mcp251xfd_regmap_use_crc(priv)) {600 err = mcp251xfd_regmap_init_crc(priv);601 602 if (err)603 return err;604 } else {605 mcp251xfd_regmap_destroy_crc(priv);606 }607 608 return 0;609}610