xref: /linux/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c (revision 6015fb905d89063231ed33bc15be19ef0fc339b8)
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_ring_init_tef(struct mcp251xfd_priv *priv, u16 *base)
57 {
58 	struct mcp251xfd_tef_ring *tef_ring;
59 	struct spi_transfer *xfer;
60 	u32 val;
61 	u16 addr;
62 	u8 len;
63 	int i;
64 
65 	/* TEF */
66 	tef_ring = priv->tef;
67 	tef_ring->head = 0;
68 	tef_ring->tail = 0;
69 
70 	/* TEF- and TX-FIFO have same number of objects */
71 	*base = mcp251xfd_get_tef_obj_addr(priv->tx->obj_num);
72 
73 	/* FIFO increment TEF tail pointer */
74 	addr = MCP251XFD_REG_TEFCON;
75 	val = MCP251XFD_REG_TEFCON_UINC;
76 	len = mcp251xfd_cmd_prepare_write_reg(priv, &tef_ring->uinc_buf,
77 					      addr, val, val);
78 
79 	for (i = 0; i < ARRAY_SIZE(tef_ring->uinc_xfer); i++) {
80 		xfer = &tef_ring->uinc_xfer[i];
81 		xfer->tx_buf = &tef_ring->uinc_buf;
82 		xfer->len = len;
83 		xfer->cs_change = 1;
84 		xfer->cs_change_delay.value = 0;
85 		xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
86 	}
87 
88 	/* "cs_change == 1" on the last transfer results in an active
89 	 * chip select after the complete SPI message. This causes the
90 	 * controller to interpret the next register access as
91 	 * data. Set "cs_change" of the last transfer to "0" to
92 	 * properly deactivate the chip select at the end of the
93 	 * message.
94 	 */
95 	xfer->cs_change = 0;
96 }
97 
98 static void
99 mcp251xfd_tx_ring_init_tx_obj(const struct mcp251xfd_priv *priv,
100 			      const struct mcp251xfd_tx_ring *ring,
101 			      struct mcp251xfd_tx_obj *tx_obj,
102 			      const u8 rts_buf_len,
103 			      const u8 n)
104 {
105 	struct spi_transfer *xfer;
106 	u16 addr;
107 
108 	/* FIFO load */
109 	addr = mcp251xfd_get_tx_obj_addr(ring, n);
110 	if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_TX)
111 		mcp251xfd_spi_cmd_write_crc_set_addr(&tx_obj->buf.crc.cmd,
112 						     addr);
113 	else
114 		mcp251xfd_spi_cmd_write_nocrc(&tx_obj->buf.nocrc.cmd,
115 					      addr);
116 
117 	xfer = &tx_obj->xfer[0];
118 	xfer->tx_buf = &tx_obj->buf;
119 	xfer->len = 0;	/* actual len is assigned on the fly */
120 	xfer->cs_change = 1;
121 	xfer->cs_change_delay.value = 0;
122 	xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
123 
124 	/* FIFO request to send */
125 	xfer = &tx_obj->xfer[1];
126 	xfer->tx_buf = &ring->rts_buf;
127 	xfer->len = rts_buf_len;
128 
129 	/* SPI message */
130 	spi_message_init_with_transfers(&tx_obj->msg, tx_obj->xfer,
131 					ARRAY_SIZE(tx_obj->xfer));
132 }
133 
134 static void
135 mcp251xfd_ring_init_tx(struct mcp251xfd_priv *priv, u16 *base, u8 *fifo_nr)
136 {
137 	struct mcp251xfd_tx_ring *tx_ring;
138 	struct mcp251xfd_tx_obj *tx_obj;
139 	u32 val;
140 	u16 addr;
141 	u8 len;
142 	int i;
143 
144 	tx_ring = priv->tx;
145 	tx_ring->head = 0;
146 	tx_ring->tail = 0;
147 	tx_ring->base = *base;
148 	tx_ring->nr = 0;
149 	tx_ring->fifo_nr = *fifo_nr;
150 
151 	*base = mcp251xfd_get_tx_obj_addr(tx_ring, tx_ring->obj_num);
152 	*fifo_nr += 1;
153 
154 	/* FIFO request to send */
155 	addr = MCP251XFD_REG_FIFOCON(tx_ring->fifo_nr);
156 	val = MCP251XFD_REG_FIFOCON_TXREQ | MCP251XFD_REG_FIFOCON_UINC;
157 	len = mcp251xfd_cmd_prepare_write_reg(priv, &tx_ring->rts_buf,
158 					      addr, val, val);
159 
160 	mcp251xfd_for_each_tx_obj(tx_ring, tx_obj, i)
161 		mcp251xfd_tx_ring_init_tx_obj(priv, tx_ring, tx_obj, len, i);
162 }
163 
164 static void
165 mcp251xfd_ring_init_rx(struct mcp251xfd_priv *priv, u16 *base, u8 *fifo_nr)
166 {
167 	struct mcp251xfd_rx_ring *rx_ring;
168 	struct spi_transfer *xfer;
169 	u32 val;
170 	u16 addr;
171 	u8 len;
172 	int i, j;
173 
174 	mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
175 		rx_ring->head = 0;
176 		rx_ring->tail = 0;
177 		rx_ring->base = *base;
178 		rx_ring->nr = i;
179 		rx_ring->fifo_nr = *fifo_nr;
180 
181 		*base = mcp251xfd_get_rx_obj_addr(rx_ring, rx_ring->obj_num);
182 		*fifo_nr += 1;
183 
184 		/* FIFO increment RX tail pointer */
185 		addr = MCP251XFD_REG_FIFOCON(rx_ring->fifo_nr);
186 		val = MCP251XFD_REG_FIFOCON_UINC;
187 		len = mcp251xfd_cmd_prepare_write_reg(priv, &rx_ring->uinc_buf,
188 						      addr, val, val);
189 
190 		for (j = 0; j < ARRAY_SIZE(rx_ring->uinc_xfer); j++) {
191 			xfer = &rx_ring->uinc_xfer[j];
192 			xfer->tx_buf = &rx_ring->uinc_buf;
193 			xfer->len = len;
194 			xfer->cs_change = 1;
195 			xfer->cs_change_delay.value = 0;
196 			xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
197 		}
198 
199 		/* "cs_change == 1" on the last transfer results in an
200 		 * active chip select after the complete SPI
201 		 * message. This causes the controller to interpret
202 		 * the next register access as data. Set "cs_change"
203 		 * of the last transfer to "0" to properly deactivate
204 		 * the chip select at the end of the message.
205 		 */
206 		xfer->cs_change = 0;
207 	}
208 }
209 
210 int mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
211 {
212 	const struct mcp251xfd_rx_ring *rx_ring;
213 	u16 base = 0, ram_used;
214 	u8 fifo_nr = 1;
215 	int i;
216 
217 	netdev_reset_queue(priv->ndev);
218 
219 	mcp251xfd_ring_init_tef(priv, &base);
220 	mcp251xfd_ring_init_rx(priv, &base, &fifo_nr);
221 	mcp251xfd_ring_init_tx(priv, &base, &fifo_nr);
222 
223 	/* mcp251xfd_handle_rxif() will iterate over all RX rings.
224 	 * Rings with their corresponding bit set in
225 	 * priv->regs_status.rxif are read out.
226 	 *
227 	 * If the chip is configured for only 1 RX-FIFO, and if there
228 	 * is an RX interrupt pending (RXIF in INT register is set),
229 	 * it must be the 1st RX-FIFO.
230 	 *
231 	 * We mark the RXIF of the 1st FIFO as pending here, so that
232 	 * we can skip the read of the RXIF register in
233 	 * mcp251xfd_read_regs_status() for the 1 RX-FIFO only case.
234 	 *
235 	 * If we use more than 1 RX-FIFO, this value gets overwritten
236 	 * in mcp251xfd_read_regs_status(), so set it unconditionally
237 	 * here.
238 	 */
239 	priv->regs_status.rxif = BIT(priv->rx[0]->fifo_nr);
240 
241 	netdev_dbg(priv->ndev,
242 		   "FIFO setup: TEF:         0x%03x: %2d*%zu bytes = %4zu bytes\n",
243 		   mcp251xfd_get_tef_obj_addr(0),
244 		   priv->tx->obj_num, sizeof(struct mcp251xfd_hw_tef_obj),
245 		   priv->tx->obj_num * sizeof(struct mcp251xfd_hw_tef_obj));
246 
247 	mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
248 		netdev_dbg(priv->ndev,
249 			   "FIFO setup: RX-%u: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n",
250 			   rx_ring->nr, rx_ring->fifo_nr,
251 			   mcp251xfd_get_rx_obj_addr(rx_ring, 0),
252 			   rx_ring->obj_num, rx_ring->obj_size,
253 			   rx_ring->obj_num * rx_ring->obj_size);
254 	}
255 
256 	netdev_dbg(priv->ndev,
257 		   "FIFO setup: TX:   FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n",
258 		   priv->tx->fifo_nr,
259 		   mcp251xfd_get_tx_obj_addr(priv->tx, 0),
260 		   priv->tx->obj_num, priv->tx->obj_size,
261 		   priv->tx->obj_num * priv->tx->obj_size);
262 
263 	netdev_dbg(priv->ndev,
264 		   "FIFO setup: free:                             %4u bytes\n",
265 		   MCP251XFD_RAM_SIZE - (base - MCP251XFD_RAM_START));
266 
267 	ram_used = base - MCP251XFD_RAM_START;
268 	if (ram_used > MCP251XFD_RAM_SIZE) {
269 		netdev_err(priv->ndev,
270 			   "Error during ring configuration, using more RAM (%u bytes) than available (%u bytes).\n",
271 			   ram_used, MCP251XFD_RAM_SIZE);
272 		return -ENOMEM;
273 	}
274 
275 	return 0;
276 }
277 
278 void mcp251xfd_ring_free(struct mcp251xfd_priv *priv)
279 {
280 	int i;
281 
282 	for (i = ARRAY_SIZE(priv->rx) - 1; i >= 0; i--) {
283 		kfree(priv->rx[i]);
284 		priv->rx[i] = NULL;
285 	}
286 }
287 
288 int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)
289 {
290 	struct mcp251xfd_tx_ring *tx_ring;
291 	struct mcp251xfd_rx_ring *rx_ring;
292 	int tef_obj_size, tx_obj_size, rx_obj_size;
293 	int tx_obj_num;
294 	int ram_free, i;
295 
296 	tef_obj_size = sizeof(struct mcp251xfd_hw_tef_obj);
297 	if (mcp251xfd_is_fd_mode(priv)) {
298 		tx_obj_num = MCP251XFD_TX_OBJ_NUM_CANFD;
299 		tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_canfd);
300 		rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_canfd);
301 	} else {
302 		tx_obj_num = MCP251XFD_TX_OBJ_NUM_CAN;
303 		tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_can);
304 		rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_can);
305 	}
306 
307 	tx_ring = priv->tx;
308 	tx_ring->obj_num = tx_obj_num;
309 	tx_ring->obj_size = tx_obj_size;
310 
311 	ram_free = MCP251XFD_RAM_SIZE - tx_obj_num *
312 		(tef_obj_size + tx_obj_size);
313 
314 	for (i = 0;
315 	     i < ARRAY_SIZE(priv->rx) && ram_free >= rx_obj_size;
316 	     i++) {
317 		int rx_obj_num;
318 
319 		rx_obj_num = ram_free / rx_obj_size;
320 		rx_obj_num = min(1 << (fls(rx_obj_num) - 1),
321 				 MCP251XFD_RX_OBJ_NUM_MAX);
322 
323 		rx_ring = kzalloc(sizeof(*rx_ring) + rx_obj_size * rx_obj_num,
324 				  GFP_KERNEL);
325 		if (!rx_ring) {
326 			mcp251xfd_ring_free(priv);
327 			return -ENOMEM;
328 		}
329 		rx_ring->obj_num = rx_obj_num;
330 		rx_ring->obj_size = rx_obj_size;
331 		priv->rx[i] = rx_ring;
332 
333 		ram_free -= rx_ring->obj_num * rx_ring->obj_size;
334 	}
335 	priv->rx_ring_num = i;
336 
337 	return 0;
338 }
339