xref: /linux/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c (revision d49184b7b585f9da7ee546b744525f62117019f6)
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 <linux/bitfield.h>
16 
17 #include "mcp251xfd.h"
18 
19 static inline int
20 mcp251xfd_rx_head_get_from_chip(const struct mcp251xfd_priv *priv,
21 				const struct mcp251xfd_rx_ring *ring,
22 				u8 *rx_head, bool *fifo_empty)
23 {
24 	u32 fifo_sta;
25 	int err;
26 
27 	err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr),
28 			  &fifo_sta);
29 	if (err)
30 		return err;
31 
32 	*rx_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta);
33 	*fifo_empty = !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF);
34 
35 	return 0;
36 }
37 
38 static inline int
39 mcp251xfd_rx_tail_get_from_chip(const struct mcp251xfd_priv *priv,
40 				const struct mcp251xfd_rx_ring *ring,
41 				u8 *rx_tail)
42 {
43 	u32 fifo_ua;
44 	int err;
45 
46 	err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOUA(ring->fifo_nr),
47 			  &fifo_ua);
48 	if (err)
49 		return err;
50 
51 	fifo_ua -= ring->base - MCP251XFD_RAM_START;
52 	*rx_tail = fifo_ua / ring->obj_size;
53 
54 	return 0;
55 }
56 
57 static int
58 mcp251xfd_check_rx_tail(const struct mcp251xfd_priv *priv,
59 			const struct mcp251xfd_rx_ring *ring)
60 {
61 	u8 rx_tail_chip, rx_tail;
62 	int err;
63 
64 	if (!IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY))
65 		return 0;
66 
67 	err = mcp251xfd_rx_tail_get_from_chip(priv, ring, &rx_tail_chip);
68 	if (err)
69 		return err;
70 
71 	rx_tail = mcp251xfd_get_rx_tail(ring);
72 	if (rx_tail_chip != rx_tail) {
73 		netdev_err(priv->ndev,
74 			   "RX tail of chip (%d) and ours (%d) inconsistent.\n",
75 			   rx_tail_chip, rx_tail);
76 		return -EILSEQ;
77 	}
78 
79 	return 0;
80 }
81 
82 static int
83 mcp251xfd_rx_ring_update(const struct mcp251xfd_priv *priv,
84 			 struct mcp251xfd_rx_ring *ring)
85 {
86 	u32 new_head;
87 	u8 chip_rx_head;
88 	bool fifo_empty;
89 	int err;
90 
91 	err = mcp251xfd_rx_head_get_from_chip(priv, ring, &chip_rx_head,
92 					      &fifo_empty);
93 	if (err || fifo_empty)
94 		return err;
95 
96 	/* chip_rx_head, is the next RX-Object filled by the HW.
97 	 * The new RX head must be >= the old head.
98 	 */
99 	new_head = round_down(ring->head, ring->obj_num) + chip_rx_head;
100 	if (new_head <= ring->head)
101 		new_head += ring->obj_num;
102 
103 	ring->head = new_head;
104 
105 	return mcp251xfd_check_rx_tail(priv, ring);
106 }
107 
108 static void
109 mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv,
110 			   const struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj,
111 			   struct sk_buff *skb)
112 {
113 	struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
114 	u8 dlc;
115 
116 	if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_IDE) {
117 		u32 sid, eid;
118 
119 		eid = FIELD_GET(MCP251XFD_OBJ_ID_EID_MASK, hw_rx_obj->id);
120 		sid = FIELD_GET(MCP251XFD_OBJ_ID_SID_MASK, hw_rx_obj->id);
121 
122 		cfd->can_id = CAN_EFF_FLAG |
123 			FIELD_PREP(MCP251XFD_REG_FRAME_EFF_EID_MASK, eid) |
124 			FIELD_PREP(MCP251XFD_REG_FRAME_EFF_SID_MASK, sid);
125 	} else {
126 		cfd->can_id = FIELD_GET(MCP251XFD_OBJ_ID_SID_MASK,
127 					hw_rx_obj->id);
128 	}
129 
130 	dlc = FIELD_GET(MCP251XFD_OBJ_FLAGS_DLC_MASK, hw_rx_obj->flags);
131 
132 	/* CANFD */
133 	if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_FDF) {
134 		if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_ESI)
135 			cfd->flags |= CANFD_ESI;
136 
137 		if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_BRS)
138 			cfd->flags |= CANFD_BRS;
139 
140 		cfd->len = can_fd_dlc2len(dlc);
141 	} else {
142 		if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR)
143 			cfd->can_id |= CAN_RTR_FLAG;
144 
145 		can_frame_set_cc_len((struct can_frame *)cfd, dlc,
146 				     priv->can.ctrlmode);
147 	}
148 
149 	if (!(hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR))
150 		memcpy(cfd->data, hw_rx_obj->data, cfd->len);
151 
152 	mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_rx_obj->ts);
153 }
154 
155 static int
156 mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv,
157 			  struct mcp251xfd_rx_ring *ring,
158 			  const struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj)
159 {
160 	struct net_device_stats *stats = &priv->ndev->stats;
161 	struct sk_buff *skb;
162 	struct canfd_frame *cfd;
163 	int err;
164 
165 	if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_FDF)
166 		skb = alloc_canfd_skb(priv->ndev, &cfd);
167 	else
168 		skb = alloc_can_skb(priv->ndev, (struct can_frame **)&cfd);
169 
170 	if (!skb) {
171 		stats->rx_dropped++;
172 		return 0;
173 	}
174 
175 	mcp251xfd_hw_rx_obj_to_skb(priv, hw_rx_obj, skb);
176 	err = can_rx_offload_queue_timestamp(&priv->offload, skb, hw_rx_obj->ts);
177 	if (err)
178 		stats->rx_fifo_errors++;
179 
180 	return 0;
181 }
182 
183 static inline int
184 mcp251xfd_rx_obj_read(const struct mcp251xfd_priv *priv,
185 		      const struct mcp251xfd_rx_ring *ring,
186 		      struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj,
187 		      const u8 offset, const u8 len)
188 {
189 	const int val_bytes = regmap_get_val_bytes(priv->map_rx);
190 	int err;
191 
192 	err = regmap_bulk_read(priv->map_rx,
193 			       mcp251xfd_get_rx_obj_addr(ring, offset),
194 			       hw_rx_obj,
195 			       len * ring->obj_size / val_bytes);
196 
197 	return err;
198 }
199 
200 static int
201 mcp251xfd_handle_rxif_ring_uinc(const struct mcp251xfd_priv *priv,
202 				struct mcp251xfd_rx_ring *ring,
203 				u8 len)
204 {
205 	int offset;
206 	int err;
207 
208 	if (!len)
209 		return 0;
210 
211 	/* Increment the RX FIFO tail pointer 'len' times in a
212 	 * single SPI message.
213 	 *
214 	 * Note:
215 	 * Calculate offset, so that the SPI transfer ends on
216 	 * the last message of the uinc_xfer array, which has
217 	 * "cs_change == 0", to properly deactivate the chip
218 	 * select.
219 	 */
220 	offset = ARRAY_SIZE(ring->uinc_xfer) - len;
221 	err = spi_sync_transfer(priv->spi,
222 				ring->uinc_xfer + offset, len);
223 	if (err)
224 		return err;
225 
226 	ring->tail += len;
227 
228 	return 0;
229 }
230 
231 static int
232 mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
233 			   struct mcp251xfd_rx_ring *ring)
234 {
235 	struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj = ring->obj;
236 	u8 rx_tail, len;
237 	int err, i;
238 
239 	err = mcp251xfd_rx_ring_update(priv, ring);
240 	if (err)
241 		return err;
242 
243 	while ((len = mcp251xfd_get_rx_linear_len(ring))) {
244 		rx_tail = mcp251xfd_get_rx_tail(ring);
245 
246 		err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj,
247 					    rx_tail, len);
248 		if (err)
249 			return err;
250 
251 		for (i = 0; i < len; i++) {
252 			err = mcp251xfd_handle_rxif_one(priv, ring,
253 							(void *)hw_rx_obj +
254 							i * ring->obj_size);
255 			if (err)
256 				return err;
257 		}
258 
259 		err = mcp251xfd_handle_rxif_ring_uinc(priv, ring, len);
260 		if (err)
261 			return err;
262 	}
263 
264 	return 0;
265 }
266 
267 int mcp251xfd_handle_rxif(struct mcp251xfd_priv *priv)
268 {
269 	struct mcp251xfd_rx_ring *ring;
270 	int err, n;
271 
272 	mcp251xfd_for_each_rx_ring(priv, ring, n) {
273 		/* - if RX IRQ coalescing is active always handle ring 0
274 		 * - only handle rings if RX IRQ is active
275 		 */
276 		if ((ring->nr > 0 || !priv->rx_obj_num_coalesce_irq) &&
277 		    !(priv->regs_status.rxif & BIT(ring->fifo_nr)))
278 			continue;
279 
280 		err = mcp251xfd_handle_rxif_ring(priv, ring);
281 		if (err)
282 			return err;
283 	}
284 
285 	if (priv->rx_coalesce_usecs_irq)
286 		hrtimer_start(&priv->rx_irq_timer,
287 			      ns_to_ktime(priv->rx_coalesce_usecs_irq *
288 					  NSEC_PER_USEC),
289 			      HRTIMER_MODE_REL);
290 
291 	return 0;
292 }
293