0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "mcp251xfd.h"
0010
0011 #include <asm/unaligned.h>
0012
0013 static const struct regmap_config mcp251xfd_regmap_crc;
0014
0015 static int
0016 mcp251xfd_regmap_nocrc_write(void *context, const void *data, size_t count)
0017 {
0018 struct spi_device *spi = context;
0019
0020 return spi_write(spi, data, count);
0021 }
0022
0023 static int
0024 mcp251xfd_regmap_nocrc_gather_write(void *context,
0025 const void *reg, size_t reg_len,
0026 const void *val, size_t val_len)
0027 {
0028 struct spi_device *spi = context;
0029 struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
0030 struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx;
0031 struct spi_transfer xfer[] = {
0032 {
0033 .tx_buf = buf_tx,
0034 .len = sizeof(buf_tx->cmd) + val_len,
0035 },
0036 };
0037
0038 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16));
0039
0040 if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
0041 reg_len != sizeof(buf_tx->cmd.cmd))
0042 return -EINVAL;
0043
0044 memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd));
0045 memcpy(buf_tx->data, val, val_len);
0046
0047 return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
0048 }
0049
0050 static inline bool
0051 mcp251xfd_update_bits_read_reg(const struct mcp251xfd_priv *priv,
0052 unsigned int reg)
0053 {
0054 struct mcp251xfd_rx_ring *ring;
0055 int n;
0056
0057 switch (reg) {
0058 case MCP251XFD_REG_INT:
0059 case MCP251XFD_REG_TEFCON:
0060 case MCP251XFD_REG_FLTCON(0):
0061 case MCP251XFD_REG_ECCSTAT:
0062 case MCP251XFD_REG_CRC:
0063 return false;
0064 case MCP251XFD_REG_CON:
0065 case MCP251XFD_REG_OSC:
0066 case MCP251XFD_REG_ECCCON:
0067 return true;
0068 default:
0069 mcp251xfd_for_each_rx_ring(priv, ring, n) {
0070 if (reg == MCP251XFD_REG_FIFOCON(ring->fifo_nr))
0071 return false;
0072 if (reg == MCP251XFD_REG_FIFOSTA(ring->fifo_nr))
0073 return true;
0074 }
0075
0076 WARN(1, "Status of reg 0x%04x unknown.\n", reg);
0077 }
0078
0079 return true;
0080 }
0081
0082 static int
0083 mcp251xfd_regmap_nocrc_update_bits(void *context, unsigned int reg,
0084 unsigned int mask, unsigned int val)
0085 {
0086 struct spi_device *spi = context;
0087 struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
0088 struct mcp251xfd_map_buf_nocrc *buf_rx = priv->map_buf_nocrc_rx;
0089 struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx;
0090 __le32 orig_le32 = 0, mask_le32, val_le32, tmp_le32;
0091 u8 first_byte, last_byte, len;
0092 int err;
0093
0094 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16));
0095 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16));
0096
0097 if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
0098 mask == 0)
0099 return -EINVAL;
0100
0101 first_byte = mcp251xfd_first_byte_set(mask);
0102 last_byte = mcp251xfd_last_byte_set(mask);
0103 len = last_byte - first_byte + 1;
0104
0105 if (mcp251xfd_update_bits_read_reg(priv, reg)) {
0106 struct spi_transfer xfer[2] = { };
0107 struct spi_message msg;
0108
0109 spi_message_init(&msg);
0110 spi_message_add_tail(&xfer[0], &msg);
0111
0112 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) {
0113 xfer[0].tx_buf = buf_tx;
0114 xfer[0].len = sizeof(buf_tx->cmd);
0115
0116 xfer[1].rx_buf = buf_rx->data;
0117 xfer[1].len = len;
0118 spi_message_add_tail(&xfer[1], &msg);
0119 } else {
0120 xfer[0].tx_buf = buf_tx;
0121 xfer[0].rx_buf = buf_rx;
0122 xfer[0].len = sizeof(buf_tx->cmd) + len;
0123
0124 if (MCP251XFD_SANITIZE_SPI)
0125 memset(buf_tx->data, 0x0, len);
0126 }
0127
0128 mcp251xfd_spi_cmd_read_nocrc(&buf_tx->cmd, reg + first_byte);
0129 err = spi_sync(spi, &msg);
0130 if (err)
0131 return err;
0132
0133 memcpy(&orig_le32, buf_rx->data, len);
0134 }
0135
0136 mask_le32 = cpu_to_le32(mask >> BITS_PER_BYTE * first_byte);
0137 val_le32 = cpu_to_le32(val >> BITS_PER_BYTE * first_byte);
0138
0139 tmp_le32 = orig_le32 & ~mask_le32;
0140 tmp_le32 |= val_le32 & mask_le32;
0141
0142 mcp251xfd_spi_cmd_write_nocrc(&buf_tx->cmd, reg + first_byte);
0143 memcpy(buf_tx->data, &tmp_le32, len);
0144
0145 return spi_write(spi, buf_tx, sizeof(buf_tx->cmd) + len);
0146 }
0147
0148 static int
0149 mcp251xfd_regmap_nocrc_read(void *context,
0150 const void *reg, size_t reg_len,
0151 void *val_buf, size_t val_len)
0152 {
0153 struct spi_device *spi = context;
0154 struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
0155 struct mcp251xfd_map_buf_nocrc *buf_rx = priv->map_buf_nocrc_rx;
0156 struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx;
0157 struct spi_transfer xfer[2] = { };
0158 struct spi_message msg;
0159 int err;
0160
0161 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16));
0162 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16));
0163
0164 if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
0165 reg_len != sizeof(buf_tx->cmd.cmd))
0166 return -EINVAL;
0167
0168 spi_message_init(&msg);
0169 spi_message_add_tail(&xfer[0], &msg);
0170
0171 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) {
0172 xfer[0].tx_buf = reg;
0173 xfer[0].len = sizeof(buf_tx->cmd);
0174
0175 xfer[1].rx_buf = val_buf;
0176 xfer[1].len = val_len;
0177 spi_message_add_tail(&xfer[1], &msg);
0178 } else {
0179 xfer[0].tx_buf = buf_tx;
0180 xfer[0].rx_buf = buf_rx;
0181 xfer[0].len = sizeof(buf_tx->cmd) + val_len;
0182
0183 memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd));
0184 if (MCP251XFD_SANITIZE_SPI)
0185 memset(buf_tx->data, 0x0, val_len);
0186 }
0187
0188 err = spi_sync(spi, &msg);
0189 if (err)
0190 return err;
0191
0192 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX))
0193 memcpy(val_buf, buf_rx->data, val_len);
0194
0195 return 0;
0196 }
0197
0198 static int
0199 mcp251xfd_regmap_crc_gather_write(void *context,
0200 const void *reg_p, size_t reg_len,
0201 const void *val, size_t val_len)
0202 {
0203 struct spi_device *spi = context;
0204 struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
0205 struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx;
0206 struct spi_transfer xfer[] = {
0207 {
0208 .tx_buf = buf_tx,
0209 .len = sizeof(buf_tx->cmd) + val_len +
0210 sizeof(buf_tx->crc),
0211 },
0212 };
0213 u16 reg = *(u16 *)reg_p;
0214 u16 crc;
0215
0216 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8));
0217
0218 if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
0219 reg_len != sizeof(buf_tx->cmd.cmd) +
0220 mcp251xfd_regmap_crc.pad_bits / BITS_PER_BYTE)
0221 return -EINVAL;
0222
0223 mcp251xfd_spi_cmd_write_crc(&buf_tx->cmd, reg, val_len);
0224 memcpy(buf_tx->data, val, val_len);
0225
0226 crc = mcp251xfd_crc16_compute(buf_tx, sizeof(buf_tx->cmd) + val_len);
0227 put_unaligned_be16(crc, buf_tx->data + val_len);
0228
0229 return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
0230 }
0231
0232 static int
0233 mcp251xfd_regmap_crc_write(void *context,
0234 const void *data, size_t count)
0235 {
0236 const size_t data_offset = sizeof(__be16) +
0237 mcp251xfd_regmap_crc.pad_bits / BITS_PER_BYTE;
0238
0239 return mcp251xfd_regmap_crc_gather_write(context,
0240 data, data_offset,
0241 data + data_offset,
0242 count - data_offset);
0243 }
0244
0245 static int
0246 mcp251xfd_regmap_crc_read_check_crc(const struct mcp251xfd_map_buf_crc * const buf_rx,
0247 const struct mcp251xfd_map_buf_crc * const buf_tx,
0248 unsigned int data_len)
0249 {
0250 u16 crc_received, crc_calculated;
0251
0252 crc_received = get_unaligned_be16(buf_rx->data + data_len);
0253 crc_calculated = mcp251xfd_crc16_compute2(&buf_tx->cmd,
0254 sizeof(buf_tx->cmd),
0255 buf_rx->data,
0256 data_len);
0257 if (crc_received != crc_calculated)
0258 return -EBADMSG;
0259
0260 return 0;
0261 }
0262
0263 static int
0264 mcp251xfd_regmap_crc_read_one(struct mcp251xfd_priv *priv,
0265 struct spi_message *msg, unsigned int data_len)
0266 {
0267 const struct mcp251xfd_map_buf_crc *buf_rx = priv->map_buf_crc_rx;
0268 const struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx;
0269 int err;
0270
0271 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8));
0272 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8));
0273
0274 err = spi_sync(priv->spi, msg);
0275 if (err)
0276 return err;
0277
0278 return mcp251xfd_regmap_crc_read_check_crc(buf_rx, buf_tx, data_len);
0279 }
0280
0281 static int
0282 mcp251xfd_regmap_crc_read(void *context,
0283 const void *reg_p, size_t reg_len,
0284 void *val_buf, size_t val_len)
0285 {
0286 struct spi_device *spi = context;
0287 struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
0288 struct mcp251xfd_map_buf_crc *buf_rx = priv->map_buf_crc_rx;
0289 struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx;
0290 struct spi_transfer xfer[2] = { };
0291 struct spi_message msg;
0292 u16 reg = *(u16 *)reg_p;
0293 int i, err;
0294
0295 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8));
0296 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8));
0297
0298 if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
0299 reg_len != sizeof(buf_tx->cmd.cmd) +
0300 mcp251xfd_regmap_crc.pad_bits / BITS_PER_BYTE)
0301 return -EINVAL;
0302
0303 spi_message_init(&msg);
0304 spi_message_add_tail(&xfer[0], &msg);
0305
0306 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) {
0307 xfer[0].tx_buf = buf_tx;
0308 xfer[0].len = sizeof(buf_tx->cmd);
0309
0310 xfer[1].rx_buf = buf_rx->data;
0311 xfer[1].len = val_len + sizeof(buf_tx->crc);
0312 spi_message_add_tail(&xfer[1], &msg);
0313 } else {
0314 xfer[0].tx_buf = buf_tx;
0315 xfer[0].rx_buf = buf_rx;
0316 xfer[0].len = sizeof(buf_tx->cmd) + val_len +
0317 sizeof(buf_tx->crc);
0318
0319 if (MCP251XFD_SANITIZE_SPI)
0320 memset(buf_tx->data, 0x0, val_len +
0321 sizeof(buf_tx->crc));
0322 }
0323
0324 mcp251xfd_spi_cmd_read_crc(&buf_tx->cmd, reg, val_len);
0325
0326 for (i = 0; i < MCP251XFD_READ_CRC_RETRIES_MAX; i++) {
0327 err = mcp251xfd_regmap_crc_read_one(priv, &msg, val_len);
0328 if (!err)
0329 goto out;
0330 if (err != -EBADMSG)
0331 return err;
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349 if (reg == MCP251XFD_REG_TBC &&
0350 ((buf_rx->data[0] & 0xf8) == 0x0 ||
0351 (buf_rx->data[0] & 0xf8) == 0x80)) {
0352
0353 buf_rx->data[0] ^= 0x80;
0354
0355
0356 err = mcp251xfd_regmap_crc_read_check_crc(buf_rx,
0357 buf_tx,
0358 val_len);
0359 if (!err) {
0360
0361
0362
0363 goto out;
0364 }
0365 }
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381 if (reg == MCP251XFD_REG_OSC && val_len == sizeof(__le32)) {
0382 err = 0;
0383 goto out;
0384 }
0385
0386 netdev_info(priv->ndev,
0387 "CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x) retrying.\n",
0388 reg, val_len, (int)val_len, buf_rx->data,
0389 get_unaligned_be16(buf_rx->data + val_len));
0390 }
0391
0392 if (err) {
0393 netdev_err(priv->ndev,
0394 "CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x).\n",
0395 reg, val_len, (int)val_len, buf_rx->data,
0396 get_unaligned_be16(buf_rx->data + val_len));
0397
0398 return err;
0399 }
0400 out:
0401 memcpy(val_buf, buf_rx->data, val_len);
0402
0403 return 0;
0404 }
0405
0406 static const struct regmap_range mcp251xfd_reg_table_yes_range[] = {
0407 regmap_reg_range(0x000, 0x2ec),
0408 regmap_reg_range(0x400, 0xbfc),
0409 regmap_reg_range(0xe00, 0xe14),
0410 };
0411
0412 static const struct regmap_access_table mcp251xfd_reg_table = {
0413 .yes_ranges = mcp251xfd_reg_table_yes_range,
0414 .n_yes_ranges = ARRAY_SIZE(mcp251xfd_reg_table_yes_range),
0415 };
0416
0417 static const struct regmap_config mcp251xfd_regmap_nocrc = {
0418 .name = "nocrc",
0419 .reg_bits = 16,
0420 .reg_stride = 4,
0421 .pad_bits = 0,
0422 .val_bits = 32,
0423 .max_register = 0xffc,
0424 .wr_table = &mcp251xfd_reg_table,
0425 .rd_table = &mcp251xfd_reg_table,
0426 .cache_type = REGCACHE_NONE,
0427 .read_flag_mask = (__force unsigned long)
0428 cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_READ),
0429 .write_flag_mask = (__force unsigned long)
0430 cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE),
0431 };
0432
0433 static const struct regmap_bus mcp251xfd_bus_nocrc = {
0434 .write = mcp251xfd_regmap_nocrc_write,
0435 .gather_write = mcp251xfd_regmap_nocrc_gather_write,
0436 .reg_update_bits = mcp251xfd_regmap_nocrc_update_bits,
0437 .read = mcp251xfd_regmap_nocrc_read,
0438 .reg_format_endian_default = REGMAP_ENDIAN_BIG,
0439 .val_format_endian_default = REGMAP_ENDIAN_LITTLE,
0440 .max_raw_read = sizeof_field(struct mcp251xfd_map_buf_nocrc, data),
0441 .max_raw_write = sizeof_field(struct mcp251xfd_map_buf_nocrc, data),
0442 };
0443
0444 static const struct regmap_config mcp251xfd_regmap_crc = {
0445 .name = "crc",
0446 .reg_bits = 16,
0447 .reg_stride = 4,
0448 .pad_bits = 16,
0449 .val_bits = 32,
0450 .max_register = 0xffc,
0451 .wr_table = &mcp251xfd_reg_table,
0452 .rd_table = &mcp251xfd_reg_table,
0453 .cache_type = REGCACHE_NONE,
0454 };
0455
0456 static const struct regmap_bus mcp251xfd_bus_crc = {
0457 .write = mcp251xfd_regmap_crc_write,
0458 .gather_write = mcp251xfd_regmap_crc_gather_write,
0459 .read = mcp251xfd_regmap_crc_read,
0460 .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
0461 .val_format_endian_default = REGMAP_ENDIAN_LITTLE,
0462 .max_raw_read = sizeof_field(struct mcp251xfd_map_buf_crc, data),
0463 .max_raw_write = sizeof_field(struct mcp251xfd_map_buf_crc, data),
0464 };
0465
0466 static inline bool
0467 mcp251xfd_regmap_use_nocrc(struct mcp251xfd_priv *priv)
0468 {
0469 return (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)) ||
0470 (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX));
0471 }
0472
0473 static inline bool
0474 mcp251xfd_regmap_use_crc(struct mcp251xfd_priv *priv)
0475 {
0476 return (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) ||
0477 (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX);
0478 }
0479
0480 static int
0481 mcp251xfd_regmap_init_nocrc(struct mcp251xfd_priv *priv)
0482 {
0483 if (!priv->map_nocrc) {
0484 struct regmap *map;
0485
0486 map = devm_regmap_init(&priv->spi->dev, &mcp251xfd_bus_nocrc,
0487 priv->spi, &mcp251xfd_regmap_nocrc);
0488 if (IS_ERR(map))
0489 return PTR_ERR(map);
0490
0491 priv->map_nocrc = map;
0492 }
0493
0494 if (!priv->map_buf_nocrc_rx) {
0495 priv->map_buf_nocrc_rx =
0496 devm_kzalloc(&priv->spi->dev,
0497 sizeof(*priv->map_buf_nocrc_rx),
0498 GFP_KERNEL);
0499 if (!priv->map_buf_nocrc_rx)
0500 return -ENOMEM;
0501 }
0502
0503 if (!priv->map_buf_nocrc_tx) {
0504 priv->map_buf_nocrc_tx =
0505 devm_kzalloc(&priv->spi->dev,
0506 sizeof(*priv->map_buf_nocrc_tx),
0507 GFP_KERNEL);
0508 if (!priv->map_buf_nocrc_tx)
0509 return -ENOMEM;
0510 }
0511
0512 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG))
0513 priv->map_reg = priv->map_nocrc;
0514
0515 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX))
0516 priv->map_rx = priv->map_nocrc;
0517
0518 return 0;
0519 }
0520
0521 static void mcp251xfd_regmap_destroy_nocrc(struct mcp251xfd_priv *priv)
0522 {
0523 if (priv->map_buf_nocrc_rx) {
0524 devm_kfree(&priv->spi->dev, priv->map_buf_nocrc_rx);
0525 priv->map_buf_nocrc_rx = NULL;
0526 }
0527 if (priv->map_buf_nocrc_tx) {
0528 devm_kfree(&priv->spi->dev, priv->map_buf_nocrc_tx);
0529 priv->map_buf_nocrc_tx = NULL;
0530 }
0531 }
0532
0533 static int
0534 mcp251xfd_regmap_init_crc(struct mcp251xfd_priv *priv)
0535 {
0536 if (!priv->map_crc) {
0537 struct regmap *map;
0538
0539 map = devm_regmap_init(&priv->spi->dev, &mcp251xfd_bus_crc,
0540 priv->spi, &mcp251xfd_regmap_crc);
0541 if (IS_ERR(map))
0542 return PTR_ERR(map);
0543
0544 priv->map_crc = map;
0545 }
0546
0547 if (!priv->map_buf_crc_rx) {
0548 priv->map_buf_crc_rx =
0549 devm_kzalloc(&priv->spi->dev,
0550 sizeof(*priv->map_buf_crc_rx),
0551 GFP_KERNEL);
0552 if (!priv->map_buf_crc_rx)
0553 return -ENOMEM;
0554 }
0555
0556 if (!priv->map_buf_crc_tx) {
0557 priv->map_buf_crc_tx =
0558 devm_kzalloc(&priv->spi->dev,
0559 sizeof(*priv->map_buf_crc_tx),
0560 GFP_KERNEL);
0561 if (!priv->map_buf_crc_tx)
0562 return -ENOMEM;
0563 }
0564
0565 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)
0566 priv->map_reg = priv->map_crc;
0567
0568 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX)
0569 priv->map_rx = priv->map_crc;
0570
0571 return 0;
0572 }
0573
0574 static void mcp251xfd_regmap_destroy_crc(struct mcp251xfd_priv *priv)
0575 {
0576 if (priv->map_buf_crc_rx) {
0577 devm_kfree(&priv->spi->dev, priv->map_buf_crc_rx);
0578 priv->map_buf_crc_rx = NULL;
0579 }
0580 if (priv->map_buf_crc_tx) {
0581 devm_kfree(&priv->spi->dev, priv->map_buf_crc_tx);
0582 priv->map_buf_crc_tx = NULL;
0583 }
0584 }
0585
0586 int mcp251xfd_regmap_init(struct mcp251xfd_priv *priv)
0587 {
0588 int err;
0589
0590 if (mcp251xfd_regmap_use_nocrc(priv)) {
0591 err = mcp251xfd_regmap_init_nocrc(priv);
0592
0593 if (err)
0594 return err;
0595 } else {
0596 mcp251xfd_regmap_destroy_nocrc(priv);
0597 }
0598
0599 if (mcp251xfd_regmap_use_crc(priv)) {
0600 err = mcp251xfd_regmap_init_crc(priv);
0601
0602 if (err)
0603 return err;
0604 } else {
0605 mcp251xfd_regmap_destroy_crc(priv);
0606 }
0607
0608 return 0;
0609 }