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
mcp251xfd_rx_head_get_from_chip(const struct mcp251xfd_priv * priv,const struct mcp251xfd_rx_ring * ring,u8 * rx_head,bool * fifo_empty)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
mcp251xfd_rx_tail_get_from_chip(const struct mcp251xfd_priv * priv,const struct mcp251xfd_rx_ring * ring,u8 * rx_tail)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
mcp251xfd_check_rx_tail(const struct mcp251xfd_priv * priv,const struct mcp251xfd_rx_ring * ring)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
mcp251xfd_rx_ring_update(const struct mcp251xfd_priv * priv,struct mcp251xfd_rx_ring * ring)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
mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv * priv,const struct mcp251xfd_hw_rx_obj_canfd * hw_rx_obj,struct sk_buff * skb)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(priv, skb, hw_rx_obj->ts);
153 }
154
155 static int
mcp251xfd_handle_rxif_one(struct mcp251xfd_priv * priv,struct mcp251xfd_rx_ring * ring,const struct mcp251xfd_hw_rx_obj_canfd * hw_rx_obj)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
mcp251xfd_rx_obj_read(const struct mcp251xfd_priv * priv,const struct mcp251xfd_rx_ring * ring,struct mcp251xfd_hw_rx_obj_canfd * hw_rx_obj,const u8 offset,const u8 len)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
mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv * priv,struct mcp251xfd_rx_ring * ring)201 mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
202 struct mcp251xfd_rx_ring *ring)
203 {
204 struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj = ring->obj;
205 u8 rx_tail, len;
206 int err, i;
207
208 err = mcp251xfd_rx_ring_update(priv, ring);
209 if (err)
210 return err;
211
212 while ((len = mcp251xfd_get_rx_linear_len(ring))) {
213 int offset;
214
215 rx_tail = mcp251xfd_get_rx_tail(ring);
216
217 err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj,
218 rx_tail, len);
219 if (err)
220 return err;
221
222 for (i = 0; i < len; i++) {
223 err = mcp251xfd_handle_rxif_one(priv, ring,
224 (void *)hw_rx_obj +
225 i * ring->obj_size);
226 if (err)
227 return err;
228 }
229
230 /* Increment the RX FIFO tail pointer 'len' times in a
231 * single SPI message.
232 *
233 * Note:
234 * Calculate offset, so that the SPI transfer ends on
235 * the last message of the uinc_xfer array, which has
236 * "cs_change == 0", to properly deactivate the chip
237 * select.
238 */
239 offset = ARRAY_SIZE(ring->uinc_xfer) - len;
240 err = spi_sync_transfer(priv->spi,
241 ring->uinc_xfer + offset, len);
242 if (err)
243 return err;
244
245 ring->tail += len;
246 }
247
248 return 0;
249 }
250
mcp251xfd_handle_rxif(struct mcp251xfd_priv * priv)251 int mcp251xfd_handle_rxif(struct mcp251xfd_priv *priv)
252 {
253 struct mcp251xfd_rx_ring *ring;
254 int err, n;
255
256 mcp251xfd_for_each_rx_ring(priv, ring, n) {
257 /* - if RX IRQ coalescing is active always handle ring 0
258 * - only handle rings if RX IRQ is active
259 */
260 if ((ring->nr > 0 || !priv->rx_obj_num_coalesce_irq) &&
261 !(priv->regs_status.rxif & BIT(ring->fifo_nr)))
262 continue;
263
264 err = mcp251xfd_handle_rxif_ring(priv, ring);
265 if (err)
266 return err;
267 }
268
269 if (priv->rx_coalesce_usecs_irq)
270 hrtimer_start(&priv->rx_irq_timer,
271 ns_to_ktime(priv->rx_coalesce_usecs_irq *
272 NSEC_PER_USEC),
273 HRTIMER_MODE_REL);
274
275 return 0;
276 }
277