1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4 // 5 // Copyright (c) 2019, 2020, 2021 Pengutronix, 6 // Marc Kleine-Budde <kernel@pengutronix.de> 7 // 8 // Based on: 9 // 10 // CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface 11 // 12 // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org> 13 // 14 15 #include <asm/unaligned.h> 16 17 #include "mcp251xfd.h" 18 19 static inline u8 20 mcp251xfd_cmd_prepare_write_reg(const struct mcp251xfd_priv *priv, 21 union mcp251xfd_write_reg_buf *write_reg_buf, 22 const u16 reg, const u32 mask, const u32 val) 23 { 24 u8 first_byte, last_byte, len; 25 u8 *data; 26 __le32 val_le32; 27 28 first_byte = mcp251xfd_first_byte_set(mask); 29 last_byte = mcp251xfd_last_byte_set(mask); 30 len = last_byte - first_byte + 1; 31 32 data = mcp251xfd_spi_cmd_write(priv, write_reg_buf, reg + first_byte); 33 val_le32 = cpu_to_le32(val >> BITS_PER_BYTE * first_byte); 34 memcpy(data, &val_le32, len); 35 36 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) { 37 u16 crc; 38 39 mcp251xfd_spi_cmd_crc_set_len_in_reg(&write_reg_buf->crc.cmd, 40 len); 41 /* CRC */ 42 len += sizeof(write_reg_buf->crc.cmd); 43 crc = mcp251xfd_crc16_compute(&write_reg_buf->crc, len); 44 put_unaligned_be16(crc, (void *)write_reg_buf + len); 45 46 /* Total length */ 47 len += sizeof(write_reg_buf->crc.crc); 48 } else { 49 len += sizeof(write_reg_buf->nocrc.cmd); 50 } 51 52 return len; 53 } 54 55 static void 56 mcp251xfd_tx_ring_init_tx_obj(const struct mcp251xfd_priv *priv, 57 const struct mcp251xfd_tx_ring *ring, 58 struct mcp251xfd_tx_obj *tx_obj, 59 const u8 rts_buf_len, 60 const u8 n) 61 { 62 struct spi_transfer *xfer; 63 u16 addr; 64 65 /* FIFO load */ 66 addr = mcp251xfd_get_tx_obj_addr(ring, n); 67 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_TX) 68 mcp251xfd_spi_cmd_write_crc_set_addr(&tx_obj->buf.crc.cmd, 69 addr); 70 else 71 mcp251xfd_spi_cmd_write_nocrc(&tx_obj->buf.nocrc.cmd, 72 addr); 73 74 xfer = &tx_obj->xfer[0]; 75 xfer->tx_buf = &tx_obj->buf; 76 xfer->len = 0; /* actual len is assigned on the fly */ 77 xfer->cs_change = 1; 78 xfer->cs_change_delay.value = 0; 79 xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS; 80 81 /* FIFO request to send */ 82 xfer = &tx_obj->xfer[1]; 83 xfer->tx_buf = &ring->rts_buf; 84 xfer->len = rts_buf_len; 85 86 /* SPI message */ 87 spi_message_init_with_transfers(&tx_obj->msg, tx_obj->xfer, 88 ARRAY_SIZE(tx_obj->xfer)); 89 } 90 91 void mcp251xfd_ring_init(struct mcp251xfd_priv *priv) 92 { 93 struct mcp251xfd_tef_ring *tef_ring; 94 struct mcp251xfd_tx_ring *tx_ring; 95 struct mcp251xfd_rx_ring *rx_ring, *prev_rx_ring = NULL; 96 struct mcp251xfd_tx_obj *tx_obj; 97 struct spi_transfer *xfer; 98 u32 val; 99 u16 addr; 100 u8 len; 101 int i, j; 102 103 netdev_reset_queue(priv->ndev); 104 105 /* TEF */ 106 tef_ring = priv->tef; 107 tef_ring->head = 0; 108 tef_ring->tail = 0; 109 110 /* FIFO increment TEF tail pointer */ 111 addr = MCP251XFD_REG_TEFCON; 112 val = MCP251XFD_REG_TEFCON_UINC; 113 len = mcp251xfd_cmd_prepare_write_reg(priv, &tef_ring->uinc_buf, 114 addr, val, val); 115 116 for (j = 0; j < ARRAY_SIZE(tef_ring->uinc_xfer); j++) { 117 xfer = &tef_ring->uinc_xfer[j]; 118 xfer->tx_buf = &tef_ring->uinc_buf; 119 xfer->len = len; 120 xfer->cs_change = 1; 121 xfer->cs_change_delay.value = 0; 122 xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS; 123 } 124 125 /* "cs_change == 1" on the last transfer results in an active 126 * chip select after the complete SPI message. This causes the 127 * controller to interpret the next register access as 128 * data. Set "cs_change" of the last transfer to "0" to 129 * properly deactivate the chip select at the end of the 130 * message. 131 */ 132 xfer->cs_change = 0; 133 134 /* TX */ 135 tx_ring = priv->tx; 136 tx_ring->head = 0; 137 tx_ring->tail = 0; 138 tx_ring->base = mcp251xfd_get_tef_obj_addr(tx_ring->obj_num); 139 140 /* FIFO request to send */ 141 addr = MCP251XFD_REG_FIFOCON(MCP251XFD_TX_FIFO); 142 val = MCP251XFD_REG_FIFOCON_TXREQ | MCP251XFD_REG_FIFOCON_UINC; 143 len = mcp251xfd_cmd_prepare_write_reg(priv, &tx_ring->rts_buf, 144 addr, val, val); 145 146 mcp251xfd_for_each_tx_obj(tx_ring, tx_obj, i) 147 mcp251xfd_tx_ring_init_tx_obj(priv, tx_ring, tx_obj, len, i); 148 149 /* RX */ 150 mcp251xfd_for_each_rx_ring(priv, rx_ring, i) { 151 rx_ring->head = 0; 152 rx_ring->tail = 0; 153 rx_ring->nr = i; 154 rx_ring->fifo_nr = MCP251XFD_RX_FIFO(i); 155 156 if (!prev_rx_ring) 157 rx_ring->base = 158 mcp251xfd_get_tx_obj_addr(tx_ring, 159 tx_ring->obj_num); 160 else 161 rx_ring->base = prev_rx_ring->base + 162 prev_rx_ring->obj_size * 163 prev_rx_ring->obj_num; 164 165 prev_rx_ring = rx_ring; 166 167 /* FIFO increment RX tail pointer */ 168 addr = MCP251XFD_REG_FIFOCON(rx_ring->fifo_nr); 169 val = MCP251XFD_REG_FIFOCON_UINC; 170 len = mcp251xfd_cmd_prepare_write_reg(priv, &rx_ring->uinc_buf, 171 addr, val, val); 172 173 for (j = 0; j < ARRAY_SIZE(rx_ring->uinc_xfer); j++) { 174 xfer = &rx_ring->uinc_xfer[j]; 175 xfer->tx_buf = &rx_ring->uinc_buf; 176 xfer->len = len; 177 xfer->cs_change = 1; 178 xfer->cs_change_delay.value = 0; 179 xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS; 180 } 181 182 /* "cs_change == 1" on the last transfer results in an 183 * active chip select after the complete SPI 184 * message. This causes the controller to interpret 185 * the next register access as data. Set "cs_change" 186 * of the last transfer to "0" to properly deactivate 187 * the chip select at the end of the message. 188 */ 189 xfer->cs_change = 0; 190 } 191 } 192 193 void mcp251xfd_ring_free(struct mcp251xfd_priv *priv) 194 { 195 int i; 196 197 for (i = ARRAY_SIZE(priv->rx) - 1; i >= 0; i--) { 198 kfree(priv->rx[i]); 199 priv->rx[i] = NULL; 200 } 201 } 202 203 int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv) 204 { 205 struct mcp251xfd_tx_ring *tx_ring; 206 struct mcp251xfd_rx_ring *rx_ring; 207 int tef_obj_size, tx_obj_size, rx_obj_size; 208 int tx_obj_num; 209 int ram_free, i; 210 211 tef_obj_size = sizeof(struct mcp251xfd_hw_tef_obj); 212 if (mcp251xfd_is_fd_mode(priv)) { 213 tx_obj_num = MCP251XFD_TX_OBJ_NUM_CANFD; 214 tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_canfd); 215 rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_canfd); 216 } else { 217 tx_obj_num = MCP251XFD_TX_OBJ_NUM_CAN; 218 tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_can); 219 rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_can); 220 } 221 222 tx_ring = priv->tx; 223 tx_ring->obj_num = tx_obj_num; 224 tx_ring->obj_size = tx_obj_size; 225 226 ram_free = MCP251XFD_RAM_SIZE - tx_obj_num * 227 (tef_obj_size + tx_obj_size); 228 229 for (i = 0; 230 i < ARRAY_SIZE(priv->rx) && ram_free >= rx_obj_size; 231 i++) { 232 int rx_obj_num; 233 234 rx_obj_num = ram_free / rx_obj_size; 235 rx_obj_num = min(1 << (fls(rx_obj_num) - 1), 236 MCP251XFD_RX_OBJ_NUM_MAX); 237 238 rx_ring = kzalloc(sizeof(*rx_ring) + rx_obj_size * rx_obj_num, 239 GFP_KERNEL); 240 if (!rx_ring) { 241 mcp251xfd_ring_free(priv); 242 return -ENOMEM; 243 } 244 rx_ring->obj_num = rx_obj_num; 245 rx_ring->obj_size = rx_obj_size; 246 priv->rx[i] = rx_ring; 247 248 ram_free -= rx_ring->obj_num * rx_ring->obj_size; 249 } 250 priv->rx_ring_num = i; 251 252 netdev_dbg(priv->ndev, 253 "FIFO setup: TEF: %d*%d bytes = %d bytes, TX: %d*%d bytes = %d bytes\n", 254 tx_obj_num, tef_obj_size, tef_obj_size * tx_obj_num, 255 tx_obj_num, tx_obj_size, tx_obj_size * tx_obj_num); 256 257 mcp251xfd_for_each_rx_ring(priv, rx_ring, i) { 258 netdev_dbg(priv->ndev, 259 "FIFO setup: RX-%d: %d*%d bytes = %d bytes\n", 260 i, rx_ring->obj_num, rx_ring->obj_size, 261 rx_ring->obj_size * rx_ring->obj_num); 262 } 263 264 netdev_dbg(priv->ndev, 265 "FIFO setup: free: %d bytes\n", 266 ram_free); 267 268 return 0; 269 } 270