Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: mcp251xfd: regmap: optimizing transfer size for CRC transfers size 1

For CRC transfers with size 1 it is more efficient to use the
write_safe command instead of the write_crc command. This saves the
length byte on the SPI transfer.

changes since v1: https://lore.kernel.org/all/20230127124258.2764-1-thomas.kopp@microchip.com
- change logic to remove 1 level of indention

Link: https://lore.kernel.org/all/20230202141811.2581795-1-mkl@pengutronix.de
Signed-off-by: Thomas Kopp <thomas.kopp@microchip.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Thomas Kopp and committed by
Marc Kleine-Budde
2e8ca20b c6adf659

+36 -8
+14 -4
drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
··· 30 30 last_byte = mcp251xfd_last_byte_set(mask); 31 31 len = last_byte - first_byte + 1; 32 32 33 - data = mcp251xfd_spi_cmd_write(priv, write_reg_buf, reg + first_byte); 33 + data = mcp251xfd_spi_cmd_write(priv, write_reg_buf, reg + first_byte, len); 34 34 val_le32 = cpu_to_le32(val >> BITS_PER_BYTE * first_byte); 35 35 memcpy(data, &val_le32, len); 36 36 37 - if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) { 37 + if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)) { 38 + len += sizeof(write_reg_buf->nocrc.cmd); 39 + } else if (len == 1) { 40 + u16 crc; 41 + 42 + /* CRC */ 43 + len += sizeof(write_reg_buf->safe.cmd); 44 + crc = mcp251xfd_crc16_compute(&write_reg_buf->safe, len); 45 + put_unaligned_be16(crc, (void *)write_reg_buf + len); 46 + 47 + /* Total length */ 48 + len += sizeof(write_reg_buf->safe.crc); 49 + } else { 38 50 u16 crc; 39 51 40 52 mcp251xfd_spi_cmd_crc_set_len_in_reg(&write_reg_buf->crc.cmd, ··· 58 46 59 47 /* Total length */ 60 48 len += sizeof(write_reg_buf->crc.crc); 61 - } else { 62 - len += sizeof(write_reg_buf->nocrc.cmd); 63 49 } 64 50 65 51 return len;
+22 -4
drivers/net/can/spi/mcp251xfd/mcp251xfd.h
··· 504 504 u8 data[4]; 505 505 __be16 crc; 506 506 } crc; 507 + struct __packed { 508 + struct mcp251xfd_buf_cmd cmd; 509 + u8 data[1]; 510 + __be16 crc; 511 + } safe; 507 512 } ____cacheline_aligned; 508 513 509 514 struct mcp251xfd_tx_obj { ··· 764 759 } 765 760 766 761 static inline void 762 + mcp251xfd_spi_cmd_write_safe_set_addr(struct mcp251xfd_buf_cmd *cmd, 763 + u16 addr) 764 + { 765 + cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE_CRC_SAFE | addr); 766 + } 767 + 768 + static inline void 767 769 mcp251xfd_spi_cmd_write_crc(struct mcp251xfd_buf_cmd_crc *cmd, 768 770 u16 addr, u16 len) 769 771 { ··· 781 769 static inline u8 * 782 770 mcp251xfd_spi_cmd_write(const struct mcp251xfd_priv *priv, 783 771 union mcp251xfd_write_reg_buf *write_reg_buf, 784 - u16 addr) 772 + u16 addr, u8 len) 785 773 { 786 774 u8 *data; 787 775 788 776 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) { 789 - mcp251xfd_spi_cmd_write_crc_set_addr(&write_reg_buf->crc.cmd, 790 - addr); 791 - data = write_reg_buf->crc.data; 777 + if (len == 1) { 778 + mcp251xfd_spi_cmd_write_safe_set_addr(&write_reg_buf->safe.cmd, 779 + addr); 780 + data = write_reg_buf->safe.data; 781 + } else { 782 + mcp251xfd_spi_cmd_write_crc_set_addr(&write_reg_buf->crc.cmd, 783 + addr); 784 + data = write_reg_buf->crc.data; 785 + } 792 786 } else { 793 787 mcp251xfd_spi_cmd_write_nocrc(&write_reg_buf->nocrc.cmd, 794 788 addr);